Badass JavaScript

A showcase of awesome JavaScript that pushes the boundaries of what's possible on the web, by @devongovett.

asm.js: A Low Level, Highly Optimizable Subset of JavaScript for Compilers

February 18th 2013

David Herman, Luke Wagner, and Alon Zakai (also the developer of Emscripten) of Mozilla have been working on the asm.js spec, which aims to be a subset of the JavaScript language that can be highly optimized after you have opted in.  It is designed mostly for compilers like Emscripten to target, but the best part is that it’s backwards compatible with the existing JS syntax since it is a strict subset.  This means that asm.js code will still run on older browsers, although not in the optimized path taken in enhanced JS engines.

You opt-in to using asm.js by including the "use asm"; string at the top of your file or individual function, just like you opt into strict mode with "use strict";.  Once you’ve done that, the ahead-of-time (AOT) optimizing compiler will kick in in supported engines, looking for type annotations and validating the code to make sure it really is optimizable.  The type annotations are interesting, and not similar at all to other attempts like Microsoft’s TypeScript since they must be backwardly compatible with normal JavaScript.  Instead, asm.js uses existing JavaScript operators as type hints, for example +a would annotate the a variable as a double.  a|0 would annotate it as an integer.

Once the engine has determined that the code is valid asm.js, it can compile it ahead of time and not have to worry about deoptimizing later on, runtime type checking, garbage collection, and bailouts.  There is no garbage collector since memory manually managed in a large HEAP typed array, using malloc and free like functions.  All of this obviously makes programs much faster since there is simply less work for the JavaScript engine to do while running your program since it has done it all ahead of time.  This will allow JavaScript programs to get closer to native code speed, and for certain classes of applications in the browser, this will be important for the platform.

If all of this sounds a bit tedious to write, I would agree, although it’s far from the worst syntax we could have.  However, it isn’t really targeted at human authors, but compilers like EmscriptenMandreelLLJS, or perhaps even TypeScript which can generate the cleverly backwards compatible but not terribly clear type annotations for you from another existing language like C, or a new language like LLJS or TypeScript.  Emscripten already generates valid asm.js output and was one of the main impetuses behind the the project, and Firefox will be landing their asm.js optimizing compiler in the near future.  The benchmarks look very impressive indeed.

These are exciting times for JavaScript application performance, and asm.js can only help.  It definitely seems like Mozilla’s response to Google’s Native Client (NaCl) project, which actually runs compiled code on the web in a sandboxed environment.  Since asm.js is actually a subset of JavaScript that is backwardly compatible, I see it as a much more likely winner in the highly optimized code space on the web.  NaCl is not available anywhere right now, but asm.js is already available everywhere even though no engines have implemented official support.

Be sure to check out the asm.js spec, David Herman’s prototype asm.js validator on Github (written in JS!), and Emscripten developer Alon Zakai’s presentation about Emscripten, asm.js and the future.  I’m looking forward to watching all of these projects as they develop!