无法使用 wasmer 执行独立的 webassembly 文件

Cannot execute standalone webassembly file with wasmer

我用 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 将这个可执行文件翻译成 file.Then 我发现 (export "_start" (func 6)) 的 wat file.Then。顺便说一句,我没有找到任何关于导出矩阵函数的代码。然后我用命令执行了 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 将其编译为两种目标,即 wasm32-unknown-unknown 和 wasm32-wasi。我将它们编译成 wat 文件。这次我找到了(export "add" (func $add.command_export))。当我用

执行 wasm32-wasi 程序时

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 文件中。谢谢!

编译器通常会内联函数并删除未使用的代码,这就是为什么您的 C 程序最终会在 _start 函数中包含所有内容。作为 explained in the FAQ,您可以使用 emcc -s EXPORTED_FUNCTIONS=_main,_matrix 列出要导出的函数,以防止它们被内联或删除。添加它会导致 wasm 模块正确导出函数。

至于 运行ning 直接运行,source code for wasmer run 具有确定应向模块公开哪个 运行 时间环境的逻辑。但是,如果您传递 -i function,它会完全跳过环境设置并直接 运行 执行您的函数。在这种情况下,模块无法初始化,因为它从 WASI 导入函数(以便将内容写入控制台,并获取当前时钟时间)。

我相信 wasm32-unknown-unknown 工作的原因是它不会 link 任何 运行 时间,并为它无法模拟的东西实现虚拟接口(所有文件系统调用导致错误等)

总而言之,wasmer run -i function 并不意味着 运行 来自具有导入功能的模块的功能,可能可以为此修补 wasmer-cli,但我不确定如果它适用于所有 运行 时间环境。