WebAssembly- Explained

   Front End Development
WebAssembly- Explained

On June 17, Google, Microsoft, Mozilla, and members of the WebKit project announced they will cooperate on a new binary format for web applications.  It is called WebAssembly.
image00

The problem

For years, engineers working on JavaScript engines in the browsers have focused on two key stages of JavaScript running in the browser. First, it the time it takes to compile the JavaScript into machine code or bytecode (if interpreted).  And second in optimizing the compiled JavaScript so that it runs faster.

Each JavaScript engine takes a different approach to compiling JavaScript source.  If an engine compiles the source without doing much optimization as it goes, the start up time is faster but the code initially runs slower.  If it optimizes as it compiles, the start up time is slower.  

Once compiled, JavaScript engines monitor the execution paths through the program and compile the “hottest” bits into much more optimized code.  You can see this in effect with technologies built with engines like google’s V8, such as NodeJS.  NodeJS programs tend to speed up as time progresses while the application is executing.

While these strategies are quite well done, there is a certain point where the effort to achieve even small gains is prohibitive.

Working with V8, one observes that the code it generates is about as fast as unoptimized compiled C code.  While we don’t expect the performance to be as fast as C, the observed JavaScript performance is really impressive.

There are a handful of limitations to JavaScript.  For instance, there are no real binary data types in the language specification.  Sure, browsers have implemented typed binary arrays, but those are library types of Objects and methods rather than specified in the language.  Note that ES6 is the first ECMA standard to define such arrays.  

Another limitation of JavaScript is the lack of a true integer type.  The JavaScript engine can infer that your Number is an integer, but it is probably not the best idea to count on how a current JavaScript engine might optimize your code.  Graphics/image manipulation and operating on audio data are two obvious examples where JavaScript is not the fastest solution for the problem.

For the past several years, all sorts of operating system or command line applications have been ported from C/C++ or other server languages into JavaScript.  It seems to me like a whole lot of reinventing the wheel and countless man years’ worth of time that could have been spent on other things.

There have been attempts in the past to allow a WWW site to deploy native (e.g. compiled) code to the browser.  For example, Google’s Native Client.  Lacking a universal standard, it was impossible to justify using the technology without asking users to use a specific browser.

The solution

One of the more promising features recently added to some browsers is asm.js.  This is a subset of JavaScript for which the browser developers can optimize the JavaScript engines.  Along with a C/C++ compiler like emscripten, you can compile quite a bit of the existing C/C++ libraries and programs and run them in the browser.  These libraries and programs are compiled into the subset of JavaScript that is asm.js.

WebAssembly is the result of these trends and driven by the need for advanced capabilities for applications running in browsers, browser-like environments, and likely server-side environments.

How it works

You will be able to initially compile source code in C/C++ into a binary representation of an AST tree.  The binary version is what’s sent to the browser.  No translation of source to binary is required on the browser side, saving a lot of start up time.  The AST tree can be directly compiled into optimal machine code, be it x86 for computers or ARM for mobile devices.  The implementation of this translator is much more straightforward than for an interpreted language like JavaScript and the resulting code will run quite a bit faster in practice.

While C/C++ is the initial target language for WebAssembly, there is nothing that precludes implementation of virtually any language that compiles into the AST format.

One of the clever things about WebAssembly is that it allows for the late binding (or linking) of several WebAssembly modules once downloaded into the browser.  This means there can (and will) be an ecosystem of modules that you can mash together to create applications.  The late binding functionality allows a C++ module to link with and call functions in a different C module.  Or a C++ module can provide a function that can be called from a Java module (assuming a Java to AST compiler).

JavaScript won’t be going away.  Initially, shims will compile the AST modules into ASM.JS or plain old JavaScript.  Even once WebAssembly is fully implemented in all the modern browsers, JavaScript will be required to support the countless existing websites that are written in, or depend on, JavaScript.  The future will still be writing lots of websites in HTML, CSS, and JavaScript.

From what one might glean from the WebAssembly documentation and my experience writing C++ around V8, the WebAssembly modules may or may not be running within the engine JavaScript context.  Initially the only choice will be within the JavaScript environment, but the ultimate goal is to run alongside the JavaScript environment with ABI interfaces to call JavaScript from the WebAssembly context and to expose WebAssembly variables and methods to the JavaScript context.

In fact, not only will the JavaScript engine be exposed to WebAssembly modules, but so will the DOM.  This means you could, in theory, write whole web applications in C and/or C++ and/or other languages that compile into WebAssembly.  Any module in one of the languages can trivially call a module in a different language.

Two benefits of WebAssembly will be that what is sent to the browser will be smaller in binary format than comparable JavaScript or C/C++ source code, and that download being binary obfuscates the source code.

People have been porting all sorts of Unix goodies like Bison and YACC and even vi to JavaScript. A stated goal of WebAssembly is that you will be able to compile the real Bison, YACC, and vi and run them directly in the browser or from the command line.

The JavaScript language spec is silent about multithreading and the implementers have ignored the possibilities for threads, especially on the server side.  WebAssembly allows for all sorts of common programming paradigms, including lightweight pthread style threads, and most if not all of the functionality in Unix standard and 3rd party libraries.

Security

Hackers will likely figure out how to turn the binary back into source code, but the code will be relatively safe from someone altering it or reusing it in some unauthorized manner.

While this seems like a good feature, it also means you will not easily be able to see what a 3rd party WebAssembly module is doing on your behalf once you call into it.  My gut feeling is that 3rd party WebAssembly modules will come with source code that you should compile, or it will come from trusted 3rd party sources.  Developers seem willing to trust CDN hosted libraries, even though they could potentially contain malicious code, but at least you can use source maps and see the code minified, unminified, etc.

It remains to be seen how secure the WebAssembly environment can be made.  You’d think that  modules compiled as AST binaries would be safer than a traditional binary made up of machine instructions, but it sure seems like hackers will be able to find exploits.  That is, by creating the right AST binary, a hacker might be able to exercise a bug in the WebAssembly implementation.

The good news is that since the browser developers have been dealing with securing the sandbox that is JavaScript; they should end up with a secure sandbox that is WebAssembly.

Conclusion

WebAssembly is an exciting  new technology that is going to improve developer and user experience, no doubt.  It is likely to be adopted and well supported by the development community at large.  It’s too soon to say when all the browsers will fully support it to the point we can freely deploy it and expect 100% of our users to be able to use it.


Like What You See?

Got any questions?