WebAssembly is an emerging standard whose goal is to define a safe, portable, size- and load-time efficient binary compiler target which offers near-native performance—a virtual CPU for the Web. WebAssembly is being developed in a W3C Community Group (CG) whose members include Mozilla, Microsoft, Google and Apple.
I’m excited to announce that WebAssembly has reached an important milestone: there are now multiple, interoperable, experimental browser implementations. We still have a lot of work left on the standard implementation before shipping, but this is a good occasion to present our progress so far, talk about what’s coming next, and invite feedback.
Finally, we’ve been able to draw on our years1,2,3,4,5,6,7 of experience with Emscripten and asm.js to guide and focus the initial design of WebAssembly. And crucially, with the great performance of asm.js code on modern browsers, the creation of polyfills will allow developers to begin using WebAssembly even before native implementations have reached saturation in the browser market.
Fast forward to today, and the CG has already made a remarkable amount of progress. Within the WebAssembly GitHub organization, the group has produced:
- a description and rationale of the initial feature set and planned future features;
- a specification and reference interpreter;
- 13,000 lines of tests used to validate both the spec interpreter and browsers;
- a first draft of the binary format.
What’s more, engineers on four browser engines have implemented prototype WebAssembly implementations1,2,3,4. Within Firefox, we refactored our existing asm.js optimization pipeline to use WebAssembly’s binary format as the representation of asm.js code sent from the main parsing thread to the background compiler threads.
This change ended up significantly improving asm.js parallel compilation performance by moving two costly steps, MIR and code generation, off the sequential critical path. With this refactored pipeline, native WebAssembly decoding only requires the addition of a small new frontend to validate the untrusted bytes:
For definitions of these terms and more background on JS and asm.js compilation, see this previous blog post.
Experimenting with WebAssembly
With all these pieces in place, it’s now possible to build WebAssembly demos that run on multiple experimental implementations. We do mean “experimental”: both the binary format and JS bindings for WebAssembly will likely change incompatibly over the next months until the first edition is stabilized. And we don’t expect implementations to be mature enough for stress tests or benchmarking for some time yet. Rather, the importance of this milestone is getting all the browsers on the same page so we can continue to iterate in sync.
With all that said, it’s gratifying for us to see a real, working demo that will run in multiple browsers:
This particular demo actually has some nostalgic value: AngryBots is a Unity tutorial project which was used as a smoke test while bringing up Unity’s WebGL export. Good memories! :)
To run the demo, download a Nightly build, open
about:config and set
Path To Release
So what’s next? There’s more to do before we have a stable, shippable first edition. In the CG, some big remaining tasks are:
- Define the official WebAssembly text format.
- Further reduce binary format size. While the current binary format is 42% smaller than asm.js uncompressed (12% smaller after gzip), we know from previous prototype binary format work that further significant size reductions are available.
Wasm.instantiateModule, that does both compilation and instantiation. There are tentative plans to break these steps apart and provide both synchronous and asynchronous functions that produce a structured-cloneable code object. This gives developers more control over both compilation and machine-code caching than current implicit machine-code caching for asm.js in Firefox.
- Create more approachable documentation for compiler writers, tool authors, hackers, and students.
- Add a bunch more tests to the test suite.
In Firefox we’re also planning to:
- Further reduce cold load time. Measuring AngryBots compile time on a 16×2.4Ghz core Linux desktop, WebAssembly reduces compile time by about 52%. That’s a good start and leverages the fact that WebAssembly decoding is currently about 10× faster than asm.js parsing, but cold load time can be significantly further reduced by working on the other parts of the compilation pipeline.
- Finish adding the full set of WebAssembly operators and import the test suite.
Full Speed Ahead
The progress on WebAssembly so far has been exhilarating. I continue to be impressed and appreciative of the collaborative atmosphere of the whole WebAssembly Community Group. If you want to learn more, the GitHub org page is a good starting point. Happy hacking!
About Luke Wagner