Wasm 运行时错误

Pywasm runtime erorr

我尝试使用 pywasm(完全用 python 编写的 Web 程序集解释器)加载 Web 程序集程序:https://github.com/mohanson/pywasm 使用以下代码

    import pywasm
vm = pywasm.load('out.wasm')
r = vm.exec('fib', [10])
print(r) 

其中 out.wasm 是由 运行 emcc out.c 在以下 out.c 代码

上使用 emscripten 在以下 C 代码上生成的
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

给出了一个 out.wasm 。我再次尝试加载这个独立的 wasm 文件,但这次它显示了不同的错误

global import wasi_unstable.args_sizes_get not found

这表明 wasm 文件想要导入 wasi_unstable 模块,我用谷歌搜索并发现这里 https://www.npmjs.com/package/wasi_unstable 可用。我使用 npm install 命令安装了它,但错误仍然存​​在。有没有一种方法可以使用 emscripten 将 c 代码转换为独立的 wasm 文件,然后使用 pywasm 加载它而不会出现任何错误。

独立 emscripten 模式现在似乎 emit basic WASI API integration。因此,为了 运行 使用 emscripten 编译的代码,您需要在 JavaScript 加载程序中提供最低限度的 WASI 存根,或者 pywasm 需要实现它们。看起来最小集合是 args_sizes_getargs_getproc_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