运行webassembly二进制文件的python扩展
wasmer的Python项目详细描述
wasmer是一个用于执行webassembly二进制文件的python库:
- 易于使用:该
wasmer
api模拟标准webassembly api, - fast:
wasmer
以最快的速度执行webassembly模块 可能,接近native speed, - safe:对webassembly的所有调用都将很快,但更多 重要的是,完全安全和沙盒。
安装
要安装wasmer
python库,只需在
外壳:
$ pip install wasmer
note:到目前为止,发布的控制盘数量有限。更多是 来了。
示例
在examples/simple.rs
中有一个玩具程序,用rust(或
编译为WebAssembly的任何其他语言):
#[no_mangle]pubexternfnsum(x: i32,y: i32)-> i32{x+y}
编译到webassembly之后,
^{
然后,我们可以在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
类
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
所有导出的函数都可以在exports
getter上访问。
这些函数的参数将自动转换为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.memory
getter访问。
Memory.grow
方法允许通过
页(每个65KB)。
instance.memory.grow(1)
Memory
类提供了创建内存视图的方法
内部缓冲区,例如uint8_view
,int8_view
,uint16_view
所有这些方法都接受一个参数:offset
,以将
特定偏移量的内存缓冲区。这些方法返回
分别是*Array
对象,即uint8_view
返回
Uint8Array
对象等。
offset=7view=instance.memory.uint8_view(offset)print(view[0])
*Array
类
这些类表示实例的内存缓冲区上的视图。
Class | View 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.b₂b₁┌┬┬┬┬┬┬┐┌┬┬┬┬┬┬┐assertint16[0]==0b00000100_00000001b₄b₃┌┬┬┬┬┬┬┐┌┬┬┬┬┬┬┐assertint16[1]==0b01000000_00010000//The`int32`viewreads4bytes.b₄b₃b₂b₁┌┬┬┬┬┬┬┐┌┬┬┬┬┬┬┐┌┬┬┬┬┬┬┐┌┬┬┬┬┬┬┐assertint32[0]==0b01000000_00010000_00000100_00000001
开发
设置您的环境,只运行一次:
$ 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?
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
^{