运行webassembly二进制文件的python扩展

wasmer的Python项目详细描述


Wasmer logo

Join the Wasmer CommunityPypiNumber of downloads on PypiLicense

wasmer是一个用于执行webassembly二进制文件的python库:

  • 易于使用:该wasmerapi模拟标准webassembly api,
  • fastwasmer以最快的速度执行webassembly模块 可能,接近native speed
  • safe:对webassembly的所有调用都将很快,但更多 重要的是,完全安全和沙盒。

安装

要安装wasmerpython库,只需在 外壳:

$ pip install wasmer

note:到目前为止,发布的控制盘数量有限。更多是 来了。

View the ^{} on Pypi

示例

examples/simple.rs中有一个玩具程序,用rust(或 编译为WebAssembly的任何其他语言):

#[no_mangle]pubexternfnsum(x: i32,y: i32)-> i32{x+y}

编译到webassembly之后, ^{} 生成二进制文件。(Download it)。

然后,我们可以在python中执行它:

fromwasmerimportInstancewasm_bytes=open('simple.wasm','rb').read()instance=Instance(wasm_bytes)result=instance.exports.sum(5,37)print(result)# 42!

最后,通过跑步来享受:

$ python examples/simple.py

扩展/模块的api

Instance

实例化由字节表示的webassembly模块,并调用 导出的功能:

fromwasmerimportInstance# Get the Wasm module as bytes.wasm_bytes=open('my_program.wasm','rb').read()# Instantiate the Wasm module.instance=Instance(wasm_bytes)# Call a function on it.result=instance.exports.sum(1,2)print(result)# 3

所有导出的函数都可以在exportsgetter上访问。 这些函数的参数将自动转换为webassembly 价值观。如果要明确地传递特定类型的值, 可以使用Value类, 例如instance.exports.sum(Value.i32(1), Value.i32(2))。注意,对于 大多数情况下,这是不必要的。

getter公开表示内存的Memory类 例如:

view=instance.memory.uint8_view()

更多信息见下文。

Module

将字节序列编译为WebAssembly模块。从这里开始 可以将其实例化:

fromwasmerimportModule# Get the Wasm bytes.wasm_bytes=open('my_program.wasm','rb').read()# Compile the bytes into a Wasm module.module=Module(wasm_bytes)# Instantiate the Wasm module.instance=module.instantiate()# Call a function on it.result=instance.exports.sum(1,2)print(result)# 3

Module.serialize方法及其补充 Module.deserialize静态方法帮助分别序列化和 反序列化已编译的webassembly模块,从而保存编译 下次使用时间:

fromwasmerimportModule# Get the Wasm bytes.wasm_bytes=open('my_program.wasm','rb').read()# Compile the bytes into a Wasm module.module1=Module(wasm_bytes)# Serialize the module.serialized_module=module1.serialize()# Let's forget about the module for this example.delmodule1# Deserialize the module.module2=Module.deserialize(serialized_module)# Instantiate and use it.result=module2.instantiate().exports.sum(1,2)print(result)# 3

序列化模块是字节序列。它们可以保存在任何 储藏室。

静态方法检查给定的字节 表示有效的webassembly字节:

fromwasmerimportModulewasm_bytes=open('my_program.wasm','rb').read()ifnotModule.validate(wasm_bytes):print('The program seems corrupted.')

Value

使用正确的类型生成WebAssembly值:

fromwasmerimportValue# Integer on 32-bits.value_i32=Value.i32(7)# Integer on 64-bits.value_i64=Value.i64(7)# Float on 32-bits.value_f32=Value.f32(7.42)# Float on 64-bits.value_f64=Value.f64(7.42)

静态方法必须视为静态的 施工人员。

__repr__方法允许获取 Value实例:

print(repr(value_i32))# I32(7)

Memory

webassembly实例有自己的内存,用Memory表示。 上课。它可由Instance.memorygetter访问。

Memory.grow方法允许通过 页(每个65KB)。

instance.memory.grow(1)

Memory类提供了创建内存视图的方法 内部缓冲区,例如uint8_viewint8_viewuint16_view 所有这些方法都接受一个参数:offset,以将 特定偏移量的内存缓冲区。这些方法返回 分别是*Array对象,即uint8_view返回 Uint8Array对象等。

offset=7view=instance.memory.uint8_view(offset)print(view[0])

*Array

这些类表示实例的内存缓冲区上的视图。

ClassView buffer as a sequence of…Bytes per element
^{}^{}1
^{}^{}1
^{}^{}2
^{}^{}2
^{}^{}4
^{}^{}4

所有这些类共享相同的实现。以 Uint8Array,类如下:

classUint8Array:@propertydefbytes_per_element()def__len__()def__getitem__(index|slice)def__setitem__(index,value)

让我们看看它的实际效果:

fromwasmerimportInstance# Get the Wasm module as bytes.wasm_bytes=open('my_program.wasm','rb').read()# Instantiate the Wasm module.instance=Instance(wasm_bytes)# Call a function that returns a pointer to a string for instance.pointer=instance.exports.return_string()# Get the memory view, with the offset set to `pointer` (default is 0).memory=instance.memory.uint8_view(pointer)memory_length=len(memory)# Read the string pointed by the pointer.nth=0;string=''whilenth<memory_length:char=memory[nth]ifchar==0:breakstring+=chr(char)nth+=1print(string)# Hello, World!

切片可以用作__getitem__方法的索引,即 当我们已经知道要读取的数据的大小时非常有用,例如:

print(''.join(map(chr,memory[0:13])))# Hello, World!

注意*Array按照 Web程序集规范,Chapter Structure, Section Instructions, Sub-Section Memory Instructions

All values are read and written in little endian byte order.

每个视图在内部共享相同的内存缓冲区。让我们玩得开心点:

int8=instance.memory.int8_view()int16=instance.memory.int16_view()int32=instance.memory.int32_view()b┌┬┬┬┬┬┬┐int8[0]=0b00000001b┌┬┬┬┬┬┬┐int8[1]=0b00000100b┌┬┬┬┬┬┬┐int8[2]=0b00010000b┌┬┬┬┬┬┬┐int8[3]=0b01000000//Nosurprisewiththefollowingassertions.b┌┬┬┬┬┬┬┐assertint8[0]==0b00000001b┌┬┬┬┬┬┬┐assertint8[1]==0b00000100b┌┬┬┬┬┬┬┐assertint8[2]==0b00010000b┌┬┬┬┬┬┬┐assertint8[3]==0b01000000//The`int16`viewreads2bytes.bb┌┬┬┬┬┬┬┐┌┬┬┬┬┬┬┐assertint16[0]==0b00000100_00000001bb┌┬┬┬┬┬┬┐┌┬┬┬┬┬┬┐assertint16[1]==0b01000000_00010000//The`int32`viewreads4bytes.bbbb┌┬┬┬┬┬┬┐┌┬┬┬┬┬┬┐┌┬┬┬┬┬┬┐┌┬┬┬┬┬┬┐assertint32[0]==0b01000000_00010000_00000100_00000001

开发

python扩展是用rust编写的,带有^{}^{}

设置您的环境,只运行一次:

$ just prelude

它将为python和rust安装pyo3-pack。它也会 安装^{}

然后,只需运行:

$ .env/bin/activate
$ just build
$ just python-run examples/simple.py

如果需要与python交互或运行特定文件,请使用 以下命令:

$ just python-run
$ just python-run file/to/run.py

最后,检查扩展;运行:

$ just inspect

(是的,你需要^{})。

测试

一旦编译并安装了扩展(只需运行just build), 运行以下命令:

$ just test

什么是webassembly?

引用the WebAssembly site

WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable target for compilation of high-level languages like C/C++/Rust, enabling deployment on the web for client and server applications.

关于速度:

WebAssembly aims to execute at native speed by taking advantage of common hardware capabilities available on a wide range of platforms.

关于安全:

WebAssembly describes a memory-safe, sandboxed execution environment […].

许可证

整个项目都在麻省理工学院的许可下。请阅读the ^{} file

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java从文件扫描二维字符串数组   java SOAP请求xml内容作为字符串:prolog中不允许内容,并且文件过早结束错误   java从db类获取列表<string>,并存储在其他类中   java libgdx progressbar未显示在主屏幕上   如何正确地为在Java中的ArrayList中实现Compariable的对象实现方法?   在JavaSwing中删除JTable中的复选框   Web请求中的java默认地址:sendRedirect:绝对路径与相对路径   java找不到符号。正在查找超类而不是子类   java如何从开放位置代码获取完整代码   java在Android中有没有一种在seekbar上画线的方法?   java如何访问索引页?   java设置POI XWPFParagraph行间距   java在使用jCo(3.x))访问SAP表时未获取数据   使用POST客户端的java JSON字符串   Raspberry Pi3b+上嵌入的java JavaFX:在触摸屏上多次按下后,错误的按钮被激活   java控制操作的奇怪形式   maven java。lang.NoSuchMethodError:在。项目实体预订预订getOrCreateDayDetail   java注释HBM的长度是多少?   持久化实体对象时发生java Hibernate IllegalArgumentException:无法将字段“id”设置为实体对象?