跳转到主要内容

未提供项目描述

项目描述

wasmbind

将您的WebAssembly导出封装,以便在Python中提供更易用的接口。目前与AssemblyScript模块以及python-ext-wasm作为加载器一起工作。

在此过程中,它试图在JavaScript中扮演与wasm-bindgenas-bind类似的角色。

使用pip install wasmbindpoetry add wasmbind进行安装。

警告:截至本文撰写时,最新发布的python-ext-wasm版本0.3不受支持;您需要运行git master。发布的版本不允许我们访问WASM内存。

功能

功能

  • ✅ 字符串、数组、映射、自定义类。
  • ✅ 与Python中的AssemblyScript对象一起工作。
  • ✅ 在Python中实例化新的AssemblyScript对象。

未来计划

  • 允许封装从WASM返回的数组。
  • 通过在RTTI中查找可用类型来改进数组分配。
  • 支持导入(需要#28
  • 改进这些文档。
  • 看看我们是否可以使用RTTI来消除手动as_的需要。我们可能不得不创建一个类似于as-bind的类注册表。
  • 研究一种在Python代码中预先定义(带有类型)类的替代方法。
  • 允许创建没有构造函数的类型。

用法

设置您的模块如下

from wasmer import Instance
wasm = Instance(open('yourscript.wasm', 'rb').read())

from wasmbind import Module
module = Module(wasm)

以下是一些示例交互。

字符串

export function helloworld(name: string): string {
    return "hello, " + name
}
>>> module.helloworld("michael", as_=str)
"hello, michael"

您会注意到您必须通过as_指定所需的返回类型。这是因为WASM只给我们一个内存位置的指针,否则我们不知道类型是什么。请参阅解析返回值部分以了解其他选项。

将值传递到AssemblyScript中是可行的,因为我们知道它的类型。在这种情况下,我们可以在AssemblyScript端分配一个string,并将指向它的指针传递到helloworld中。

注意:您将从AssemblyScript中获得真实的Python str,并且预期您将传递真实的str对象到AssemblyScript函数中。字符串在AssemblyScript和Python中都是不可变的。这意味着对于Python <-> AssemblyScript的边界,它们是通过值传递和复制的。没有引用计数。

对象 & 属性

export class File {
  constructor(
    public size: i32,
  ) {}
}
>>> dir = module.Directory(3)
>>> dir.size
3
>>> dir.size = 10
>>> dir.size
10

对象

export class Line {
  constructor(
    public s: string
  ) {}
}

export class File {
  public lines: Line[] = []

  constructor() {}
  
  addLine(line: Line): number {
    this.lines.push(line);
    return this.lines.length; 
  }
}
>>> file = module.File()
>>> line = module.Line("line 1")
>>> file.addLine(line)
1

映射和其他泛型类型

假设您有一个函数,它接受一个映射作为参数

export function getMap(): Map<string, i32> {
  return new Map();
}

首先,如果您查看此模块的导出,您会注意到只有一个getMap()Map类本身没有被导出。

现在,如果您添加export {Map},根据您的代码,您可能会看到以下导出:

'Map<~lib/string/String,~lib/string/String>#get', 'Map<i32,i32>#constructor', 'Map<i32,i32>#clear'

每个泛型Map类型的具体版本都被单独导出,名称不是很友好,最后,类是不完整的:只有您代码中某个位置使用过的方法被导出,其余的,我假设,已经被优化掉了。

目前,wasmbind对这些导出没有做任何特殊处理,这意味着您可以使用它们,但它们不是很容易访问。

到目前为止,我找到使用映射的最佳方法是这个

export class StringMap extends Map<string, string> {};

这将为您在Python中获得一个完整且完全功能的StringMap类。

处理返回值

如果您有一个内存地址,您可以这样做

module.resolve()module.resolve(as_=T)

如果您有一个不透明的AssemblyScriptObject,您可以这样做 obj.as_(T)

as_的可能值

  • 如果没有给出,我们将尝试自动检测。
  • str
  • 模块导出的任何AssemblyScriptClass
  • typing.Listtyping.List[SomeOtherType],其中SomeOtherType是任何as值。

未来的选项

# Every return value is a a Opaque Type that you can either call .native() on or .as().
module = Module(instance, value_handler=wrap_opaque)

# Every return value is auto-instantiated via the object header 
module = Module(instance, value_handler=auto_resolve)

# Using mypy to predefine the return types of each method and function call. 
module = Module(instance, class_registry={})

不透明值

有时,将数据结构传递给AssemblyScript,您只想保持原样,不希望AssemblyScript对其进行操作并返回它们,特别是在处理复杂数据结构时,这可能是很有用的。

为了支持这种情况,wasmbind支持一种机制,可以通过该机制

  • 您可以将任意的Python值放入本地注册表中。
  • 您将获得一个可以传递给AssemblyScript函数的不透明对象。
  • AssemblyScript将看到一个整数(我们从1开始计数,因此您是否想使用u8、u32等取决于您自己)。
  • 当值从AssemblyScript中出来时,您需要使用常规机制指导wasmbind将这个不透明指针解析为wasmbind.OpaqueValue实例。

以下是一个示例

export function take(val: u8): u8 { return val; }
from wasmbind import OpaqueValue
my_map = {"x": 1}
wrapped_map = module.register_opaque_value(my_map)
assert module.take(wrapped_map, as_=OpaqueValue) == {"x": 1}

说明

部分是AssemblyScript加载程序的移植。以下链接在实现中很有帮助

项目详情


下载文件

下载您平台上的文件。如果您不确定选择哪一个,请了解更多关于安装包的信息。

源分发

wasmbind-0.4.tar.gz (12.8 kB 查看哈希值)

上传于 源代码

构建分发版

wasmbind-0.4-py3-none-any.whl (10.5 kB 查看哈希值)

上传于 Python 3

由以下支持