-
Notifications
You must be signed in to change notification settings - Fork 0
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 process for building WebAssembly is not yet fully optimized. Here are the current steps:
- Get and use emscripten's
incoming
branch. - Build with
emcc [..args..] -s BINARYEN=1
and then just run the output js
or html
file. If you run the code in a JS engine with WebAssembly support, it will try to use that support, but since the binary format is in flux, this might fail (since what binaryen emits might not be in sync with what the browser accepts). To force usage of the interpreter, which should always work properly (but slowly), use the following additional flag:
-s "BINARYEN_METHOD='interpret-binary'"
That binary should run in browsers that support the same version of WebAssembly as Binaryen. (However, until the binary format is finalized, and support for it is complete, there will probably 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 (note: on the commandline you might need to quote twice, -s "BINARYEN_METHOD='..'"
). 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,interpret-s-expr
. The full list of methods is
-
native-wasm
: Use native binary wasm support in the browser. -
interpret-s-expr
: Load a.wast
, which contains wasm in s-expression format, and interpret it. -
interpret-binary
: Load a.wasm
, which contains wasm in binary format, and interpret it. -
interpret-asm2wasm
: Load.asm.js
, compile to wasm on the fly, and interpret that. -
asmjs
: Load.asm.js
and 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,asmjs'"
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.
WebAssembly isn't released yet, so it isn't enabled by default. But you can test it in development builds:
- In Firefox, use Nightly and set
javascript.options.wasm
inabout:config
. - In Chrome, use Canary and enable
chrome://flags/#enable-webassembly
.
- Build with
EMCC_DEBUG=1
in the env to see Emscripten's debug output as it runs the various tools, and also to save the intermediate files in/tmp/emscripten_temp
. It will save both the.s
and.wast
files there (in addition to other files it normally saves).
- Closure compiler (
--closure
to emcc) makes a few emscripten test suite cases fail with Binaryen.
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.