我尝试使用pywasm(一个完全用python编写的web组装解释器:https://github.com/mohanson/pywasm(使用以下代码
import pywasm
vm = pywasm.load('out.wasm')
r = vm.exec('fib', [10])
print(r)
其中out.wasm是通过在以下out.C代码上运行emcc out.C在以下C代码上使用emscripten生成的
int fib(int n) {
if (n <= 1) {
return n;
}
return fib(n - 1) + fib(n - 2);
}
它生成了一个js和一个wasm文件。pywasm通过上述代码加载wasm文件时出现错误
global import env.emscripten_resize_heap not found
经过检查,我发现wasm文件试图加载的函数实际上在emcc生成的js文件中,因此我想只生成一个独立的wasm文件,我使用以下命令生成该文件
emcc out.c -o out.wasm
我再次尝试加载这个独立的wasm文件,但这次显示了不同的错误
global import wasi_unstable.args_sizes_get not found
这表明wasm文件想要导入wasi_unstatible模块,我在谷歌上搜索了它,发现它在这里可用https://www.npmjs.com/package/wasi_unstable。我使用npm install命令安装了它,但是错误仍然存在。有没有一种方法可以使用emscripten将c代码转换为独立的wasm文件,然后用pywasm加载它而不会出现任何错误。
独立emscripten模式现在似乎发出了基本的WASI API集成。因此,为了运行使用emscripten编译的代码,您需要在JavaScript加载程序中提供最少的WASI存根,或者pywasm需要实现它们。看起来最小集合是args_sizes_get
、args_get
和proc_exit
。对于简单的fib情况,这些函数不会被调用,所以只需要在导入中定义它们。以下是提供基本定义的代码更新:
import sys
import pywasm
wasi_unstable = {
'args_sizes_get': lambda x: 0,
'args_get': lambda x: 0,
'proc_exit': lambda x: 0
}
vm = pywasm.load(sys.argv[1], {'wasi_unstable': wasi_unstable})
r = vm.exec('fib', [10])
print(r)
您还需要编译fib.c
代码,这样fib
函数就不会被emscripten优化(因为emscripten认为它没有被调用(:
emcc -s "EXPORTED_FUNCTIONS=['_fib']" fib.c -o fib.wasm
有了这些变化,它对我有效:
python3.8 run.py ./fib.wasm
55