我可以以某种方式构建webassembly代码*而不用emscripten“glue”吗? [英] Can I somehow build webassembly code *without* the emscripten "glue"?

查看:124
本文介绍了我可以以某种方式构建webassembly代码*而不用emscripten“glue”吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以以某种方式创建一个ism文件,它将按照描述 (通过实例化对象并调用它们上的函数)?

Can I somehow create a wasm file, that will work on its own as described in MDN here (by instatiating the objects and calling functions on them)?

我能找到的所有指南(例如MDN上的这个)建议使用emscripten;但是,它还包括~70kB胶水代码(~50 kB可选文件系统仿真),它具有额外的逻辑(如检测节点/浏览器环境和自动提取等),可能还有其他一些仿真。

All the guides I can find (such as this one on MDN) recommend using emscripten; that will, however, also include ~70kB "glue code" (with ~50 kB optional filesystem emulation), that has additional logic (like detection node/browser environment and automatic fetching etc), and probably some other emulation.

如果我不想要胶水代码并且想直接创建WASM(可能来自C代码,但可能是其他东西)怎么办?这可能吗?

What if I don't want that "glue code" and want to just create WASM directly (probably from C code, but maybe something else)? Is that possible right now?

推荐答案

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

You can use emscripten to generate fairly minimal code output.

考虑以下简单文件 adder.c

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

像这样编译(需要一个相当新的emscripten):

Compile it like this (requires a fairly recent emscripten):

emcc -O2 -s WASM=1 -s SIDE_MODULE=1 -o adder.wasm

要查看它生成的内容,请使用binaryen的 wasm-dis 将其反汇编为文本格式(您可以也使用来自wabt的wasm2wast):

To see what it generated, disassemble it to wast textual form using binaryen's wasm-dis (you can also use wasm2wast from wabt):

wasm-dis adder.wasm -o adder.wast

反汇编的来源应如下所示:

The disassembled source should look something like this:

(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或更高版本)像这样:

You can then run this in node (v8.X or later) like this:

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))
})

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

Note that if you want to support code that uses the stack and/or heap memory things get more complicated. I.e. you'll at least need to set memoryBase and call __post_instantiate from your host environment before you call any other exports.

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

If you want to interpret WebAssembly code without a JavaScript environment you can run it using wac/wace (full disclosure: I created this project). Note that wace assumes you have a "_main" or "main" function defined.

这篇关于我可以以某种方式构建webassembly代码*而不用emscripten“glue”吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆