Repository navigation
WebAssembly
WebAssembly is a new binary format for executing code on the web. The overall plan is
- Once browsers support WebAssembly, that will allow much faster start times (small download, much faster parsing) for Emscripten projects.
- Emscripten will support compiling to WebAssembly with a compiler flag, so it'll be easy for projects to switch between WebAssembly and the current asm.js mode.
- Binaryen is a new C++ library for WebAssembly that will help Emscripten in this area. It's being written as a separate project so others can use it too.
For more background, see
Things are still in progress, so the processing for building WebAssembly is not yet fully optimized. When things get more stable, we'll bundle Binaryen into Emscripten, etc., so things will be a lot easier. For now, here are the current steps:
- Get Binaryen, and build it according to the instructions there.
- Get emscripten's
incomingbranch. - Define
BINARYEN_ROOTin your~/.emscriptenfile to point to Binaryen (runemcconce if you never have, to generate that file).
If you want to run programs in a compiled WebAssembly interpreter, you can then do
emcc [..args..] -s BINARYEN=1
and then just run the output js or html file.
If you also want to run using the current WIP native WebAssembly support in browsers, you also need to
- Get mozilla-inbound and build the JS engine under
js/src. That provides a tool to build text to binary. - Make sure
SPIDERMONKEY_ENGINEin~/.emscriptenpoints to the js shell that was built.
and then build with
emcc [..args..] -s BINARYEN=1 -s 'BINARYEN_SCRIPTS="spidermonkify.py"'
The extra steps for native WebAssembly support are needed because the binary format is still in flux, and Binaryen's binary output is not identical to browsers. At the time of writing this, you should be able to use the SpiderMonkey binary tools or sexpr-wasm-prototype, and things should work in both Firefox and Chrome. However, until the binary format is finalized, and support for it is complete, there will be times when things don't work right.
When using Binaryen with Emscripten, it can load the compiled code using one of several methods. By setting -s BINARYEN_METHOD='..' you can specify those methods, as a comma-separated list. It will try them one by one, which allows fallbacks.
By default, it will try native support, and if not present, it will load a .wast and run that the polyfill interpreter. This is the same as if you specify native-wasm,wasm-s-parser. The full list of methods is
-
wasm-native: Use native binary wasm support in the browser. -
wasm-s-parser: Load a.wast, which contains wasm in s-expression format, and interpret it. -
wasm-binary: Load a.wasm, which contains wasm in binary format and interpreter it. -
asm2wasm: Load.asm.js, compile to wasm on the fly, and interpret that. -
just-asm: Load.asm.jsand just run it, no wasm. Useful for comparisons.
For more details, see src/js/wasm.js-post.js in the Binaryen repo. The function integrateWasmJS is where all the integration between JavaScript and WebAssembly happens.
Note that the methods you specify affect what is emmitted. For example, -s BINARYEN_METHOD='native-wasm,just-asm' will try native support, and if that fails, will use asm.js. This avoids using the WebAssembly polyfill interpreter in both cases, so the interpreter won't be linked in to your code.
The steps in the previous section all use Binaryen's asm2wasm tool to compile asm.js to WebAssembly. This option should fairly well, as it passes the passes the test suite. However, you should still expect issues here and there.
There is a new LLVM backend being developed for WebAssembly. It will eventually provide better results, but is not yet ready, see the new wasm backend web page.