为什么在这个 wasm 模块中有“wasi_snapshot_preview_1”导入?

最近我尝试使用尽可能少的助手来试验 webassembly。

所以我创建了 ac 项目,包含了一些库 ( stb_image.h) 并尝试编译它。

这是一个简短的可重现示例:

#include <emscripten.h>
#define STBI_NO_STDIO
#define STBI_NO_FAILURE_STRINGS
#define STB_IMAGE_IMPLEMENTATION

#include "stb_image.h"

EMSCRIPTEN_KEEPALIVE
void test(){
    stbi_load_from_memory(NULL, 0, NULL, NULL, NULL, 0);
}

这是我使用的命令:

emcc converter.c -s STANDALONE_WASM -o converter.wasm --no-entry

这工作正常,并给了我一个有效的 wasm 文件。

但是后来我尝试使用 javascript 在浏览器中实例化它,没有别的:

let wasm = await Webassembly.instantiateStreaming(fetch('converter.wasm'), {});

但我收到此错误:

Uncaught (in promise) TypeError: WebAssembly.instantiate(): Import #0 module="wasi_snapshot_preview1" 错误:模块不是对象或函数

我检查了 webassembly,确实我的 webassembly 需要这些功能:

  (func $wasi_snapshot_preview1.fd_close (;0;) (import "wasi_snapshot_preview1" "fd_close") (param i32) (result i32))
  (func $wasi_snapshot_preview1.fd_seek (;1;) (import "wasi_snapshot_preview1" "fd_seek") (param i32 i64 i32 i32) (result i32))
  (func $wasi_snapshot_preview1.fd_write (;2;) (import "wasi_snapshot_preview1" "fd_write") (param i32 i32 i32 i32) (result i32))
  (func $wasi_snapshot_preview1.proc_exit (;3;) (import "wasi_snapshot_preview1" "proc_exit") (param i32))

我知道这些函数在纯 wasm 模块中不受支持(比如 os 调用?),但我找不到任何关于它们的确切含义的文档。

所以我的问题是:

  • 为什么是这些功能?
  • 如果stb_image头应该只是在没有 i/o 的情况下操作 ram 中的位,为什么我需要这些导入的函数
  • 我怎么能告诉我的编译器不要使用这些函数(阻止 stdio 库可以工作,但我不知道该怎么做)
  • 我必须在“import”变量中放入什么才能使用模拟函数加载模块?

任何指示都值得赞赏!

编辑

在尝试编译 c 标准库之后,我明白了这些函数的用途:

  • fd_write 用于打印(通常到操作系统中的标准输出)
  • fd_seekfd_close对于文件操作

还有fd_read读取文件,但我不需要在这段代码中

  • proc_exit 终止进程并可能引发错误

但我真的不明白为什么在我的情况下需要它们:程序不打印任何内容并且代码中没有“退出”:(

sbc100

首先,我建议使用-Oz或至少进行构建,-O2以便工具链尝试最大程度地缩小生成的二进制。

我建议构建-Oz --profiling-funcs然后使用wasm-objdumpwasm-decompile查看为什么这些导入并最终被使用。

当我这样做时很明显proc_exit正在使用assert_fail......确实看起来它们都是由于使用了断言宏并且添加-DNDEBUG使所有这些导入消失。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

什么是WebAssembly(Wasm)模块?

为什么我在这个div中没有滚动?

为什么在这个 IF 语句的代码行中有这个矛盾?

为什么这个跨度不在这个h1的中心?

为什么 Blazor WASM 中只有少数时区可用?

我现在没有,为什么我在这个 sql 请求中有错误

为什么在这个方法调用中有一个 NullPointerException?

为什么在这个解散的 std::string dtor 中有一个锁定的 xadd 指令?

为什么在这个例子中委托中有 Qt::UserRole ?

WASI 和 proxy-wasm 是什么关系?

为什么在这个不相交的联合中这里1和2

为什么在这个 highcharter 图上没有预期的标签 - R

为什么在这个SpringAOP语法错误@Pointcut没有弹出任何错误?

为什么我在这个无效的 Laravel 8 表单中没有任何验证错误?

为什么在这个例子中我会收到带有 argv 的崩溃报告?

为什么在这个“try...except”块中没有捕获/处理错误?

为什么在这个基本的Spring应用程序中没有调用这些函数?

为什么在这个简单的 jsfiddle 演示中没有触发 click 事件?

为什么在这个 apt install 命令上有反斜杠 `\` 换行符?

为什么在这个函数中变量没有被更新和正确返回?

为什么在这个 React 代码的末尾有一个逗号“,”

为什么我的 QLabel 小部件没有出现在这个线程中?

为什么在这个实例化类的例子中没有“new”关键字?

为什么方块没有出现在这个 socket.io html 文件中?

为什么我在这个 if-test 中不能有 IndexOutOfBoundsException?

为什么我在这个 Bash 脚本中收到“没有这样的文件或目录”错误?

为什么我的 while 循环在这个 switch 案例中没有重复?

为什么我的代码在这个异步函数中没有等待输出?

为什么我的函数没有在这个类中定义?