无法使用 wasmer 执行独立的 webassembly 文件
Posted
技术标签:
【中文标题】无法使用 wasmer 执行独立的 webassembly 文件【英文标题】:Cannot execute standalone webassembly file with wasmer 【发布时间】:2021-07-06 06:54:02 【问题描述】:我用 C 语言编写了一个矩阵乘法程序,并使用 Emscripten 使用以下命令对其进行编译
emcc matrix.c -o matrix.wasm -s STANDALONE_WASM
而C程序如下,
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
int matrix()
int a[101][101];
int b[101][101];
int r[101][101];
for(int i = 0; i<101; i++)
for(int j = 0; j<101; j++)
a[i][j] = rand()%1000+1;
b[i][j] = rand()%1000+1;
for(int i = 0; i<101; i++)
for(int j = 0; j<101; j++)
r[i][j] = 0;
for(int k = 0; k<101; k++)
r[i][j] += a[i][k] * b[k][j];
return 0;
int main()
clock_t start, finish;
double duration;
start = clock();
matrix();
finish = clock();
duration = (double)(finish - start) / CLOCKS_PER_SEC;
printf("computing duration: %fs\n", duration);
return 0;
然后我用wasmer直接运行这个webassembly文件:
wasmer matrix.wasm
.
它返回了预期的结果。然后我想用一个特定的函数来执行这个文件,即webassembly文件中的导出函数。
我用wasm2wat把这个可执行文件翻译成wat文件,然后找到(export "_start" (func 6))
。顺便说一句,我没有找到任何关于导出矩阵函数的代码。然后我用命令执行了matrix.wasm:
wasmer matrix.wasm -i _start
但是,错误出现了。它说:
error: failed to run `matrix.wasm`
╰─> 1: Error while importing "wasi_snapshot_preview1"."clock_time_get": unknown import. Expected Function(FunctionType params: [I32, I64, I32], results: [I32] )
然后我尝试用 Rust 编写一个简单的程序,它只包含一个 main 函数和一个 add 函数。我用cargo编译成两种target,分别是wasm32-unknown-unknown和wasm32-wasi。我将它们编译成 wat 文件。这次我找到了(export "add" (func $add.command_export))
。当我使用
wasmer add.wasm -i add
也出现了错误。它说:
error: failed to run `hello.wasm`
╰─> 1: Error while importing "wasi_snapshot_preview1"."args_get": unknown import. Expected Function(FunctionType params: [I32, I32], results: [I32] )
我可以正确执行目标为wasm32-unknown-unknown的文件,但我不能在这种目标中使用lib函数。
我认为我的 wasm32-wasi 文件有问题,但我不知道为什么以及如何处理它。您能否告诉我如何在 wasm32-wasi 文件中调用导出函数以及如何在 wasm32-unknown-unknown 文件中调用 lib 函数。我还有一些关于为什么我使用 Emscripten 编译 C 文件但矩阵函数没有导出到 wat 文件中的问题。谢谢!
【问题讨论】:
您是否可能必须指定一些选项才能启用 WASI? 【参考方案1】:编译器通常会内联函数并删除未使用的代码,这就是为什么您的 C 程序最终会在 _start
函数中包含所有内容。作为explained in the FAQ,您可以使用emcc -s EXPORTED_FUNCTIONS=_main,_matrix
列出要导出的函数,以防止它们被内联或删除。添加它会生成一个带有正确导出函数的 wasm 模块。
至于直接运行函数,source code for wasmer run 具有确定应该向模块公开哪个运行时环境的逻辑。但是,如果您通过-i function
,它会完全跳过环境设置并直接运行您的函数。在这种情况下,模块无法初始化,因为它从 WASI 导入函数(以便将内容写入控制台,并获取当前时钟时间)。
我相信wasm32-unknown-unknown
工作的原因是它没有链接到任何运行时,并且为它无法模拟的东西实现了虚拟接口(所有文件系统调用都会导致错误等)
总而言之,wasmer run -i function
并不是要从具有导入的模块运行函数,可以为此修补 wasmer-cli
,但我不确定它是否适用于所有运行时环境。
【讨论】:
感谢您的回答。我发现Wasmtime可以成功执行导入的函数。以上是关于无法使用 wasmer 执行独立的 webassembly 文件的主要内容,如果未能解决你的问题,请参考以下文章
Can some one explain the difference between the Wasmer and Wasmtime projects