javascript - 我可以以某种方式构建 webassembly 代码*没有* emscripten "glue"吗?

标签 javascript emscripten webassembly

我能否以某种方式创建一个 wasm 文件,该文件将按照 in MDN here 的描述自行工作(通过实例化对象并调用它们的函数)?

我能找到的所有指南(such as this one on MDN)都推荐使用 emscripten;然而,这也将包括约 70kB 的“胶水代码”(带有约 50kB 的可选文件系统仿真),具有额外的逻辑(如检测节点/浏览器环境和自动获取等),可能还有其他一些仿真。

如果我不想要那个“胶水代码”并且只想直接创建 WASM(可能来自 C 代码,但也可能是其他东西)怎么办?现在有可能吗?

最佳答案

您可以使用 emscripten 生成相当少的代码输出。

考虑以下琐碎文件adder.c :

int adder (int a, int b) {
    return a + b;
}

像这样编译它(需要一个相当新的 emscripten):
emcc -O2 -s WASM=1 -s SIDE_MODULE=1 -o adder.wasm

要查看它生成了什么,请使用 binaryen 的 wasm-dis 将其反汇编为浪费文本形式。 (您也可以使用 wabt 的 wasm2wast):
wasm-dis adder.wasm -o adder.wast

反汇编的源代码应如下所示:
(module
 (type $0 (func (param i32 i32) (result i32)))
 (type $1 (func))
 (import "env" "memoryBase" (global $import$0 i32))
 (import "env" "memory" (memory $0 256))
 (import "env" "table" (table 0 anyfunc))
 (import "env" "tableBase" (global $import$3 i32))
 (global $global$0 (mut i32) (i32.const 0))
 (global $global$1 (mut i32) (i32.const 0))
 (export "__post_instantiate" (func $2))
 (export "runPostSets" (func $1))
 (export "_adder" (func $0))
 (func $0 (type $0) (param $var$0 i32) (param $var$1 i32) (result i32)
  (i32.add
   (get_local $var$1)
   (get_local $var$0)
  )
 )
 (func $1 (type $1)
  (nop)
 )
 (func $2 (type $1)
  (block $label$0
   (set_global $global$0
    (get_global $import$0)
   )
   (set_global $global$1
    (i32.add
     (get_global $global$0)
     (i32.const 5242880)
    )
   )
   (call $1)
  )
 )
 ;; custom section "dylink", size 5
)

然后,您可以像这样在节点(v8.X 或更高版本)中运行它:
const WA = WebAssembly,
      env = {memoryBase: 0,
             tableBase: 0,
             memory: new WA.Memory({initial: 256}),
             table: new WA.Table({initial: 0, element: 'anyfunc'})},
      code = new Uint8Array(require('fs').readFileSync('adder.wasm'))
WA.compile(code).then(m => {
    return new WA.Instance(m, {env: env})
}).then(i => {
    console.log(i.exports._adder(7, 8))
})

请注意,如果您想支持使用堆栈和/或堆内存的代码,事情会变得更加复杂。 IE。您至少需要设置 memoryBase 并调用 __post_instantiate在调用任何其他导出之前从您的主机环境中调用。

如果你想在没有 JavaScript 环境的情况下解释 WebAssembly 代码,你可以使用 wac/wace 运行它。 (完全披露:我创建了这个项目)。请注意 wace假设您定义了“_main”或“main”函数。

关于javascript - 我可以以某种方式构建 webassembly 代码*没有* emscripten "glue"吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45295339/

相关文章:

javascript - 禁用 angularjs 数据表中的排序不起作用

opengl-es - 编译着色器后程序停止绘制

emscripten - 如何控制或读取最大 wasm 表大小?

c++ - 没有 SDL 的 Emscripten

javascript - Emscripten - 编译为 WASM 并在胶水代码中保留原始可调用函数名称

javascript - 如何解析 Rust 和 WebAssembly 中的函数指针

javascript - 如何使用 Raycaster 和 GLTF 加载器选择单一 Material

javascript - 如何显示 JSON 字符串中的特定数据?

javascript - 如何将 $resource 转换为 $http?

javascript - 如何找到 WebAssembly 缓冲区的地址并将其返回给 Javascript?