Thoughts on asm.js vs PNaCl

2013-06-01

Google has been working on Native Client (NaCl) and Portable Native Client (PNaCl) for a while now. Firefox recently announced and released asm.js. Here's a few random personal thoughts with no particular conclusion

First off a bunch of disclaimers. (1) I work on the Chrome team. (2) I'm speaking for myself, not Google nor the Chrome team. In fact I'm pretty sure some other people on the Chrome team will 100% disagree with some of these opinions. So, these opinions / thoughts are my own and in no way represent Google or the Chrome Team.

Second, let's spell out what NaCl, PNaCl, PPAPI, NPAPI and asm.js are

NaCl is a PPAPI plugin that allows untrusted native code to run in the browser securely. It only supports x86 code. It provides access to PPAPI APIs, sometimes called Pepper APIs.

PNaCl is the portable version of NaCl. Instead of being x86 only it translates LLVM bytecode to the host processor.

NPAPI is the Netscape Plugin API that was developed in the mid 90s to allow browser plugins. It is massively insecure and is the #1 vector for browser exploits. All it defines is how a plugin can talk to a browser. Otherwise the plugin is free to do whatever it wants with your entire machine. An NPAPI plugin can read any file, call any OS function, do any networking or nasty things it wants.

PPAPI is a new plugin standard originally co−developed by Mozilla and Google but apparently Mozilla stopped participating. It provides *cross−platform* out of process APIs for most common system functions. In other words, it lets a plugin do things like audio, graphics, networking and file i/o in a cross platform way. This means a plugin developed for PPAPI should run on every OS and Browser that supports PPAPI. It would have to be recompiled but since the APIs are the same on all platforms it should work with no code changes. This is in contrast to NPAPI plugins which are specific to each OS since they themselves call OS level services.

The combination of PPAPI and PNaCl provides a 100% portable and secure way to run native code in a browser.

asm.js is the specification of subset of javascript that can optionally be compiled directly into assembly language. It works by allocating a single large TypedArray which it treats as the memory of a virtual computer. It then uses a small subset of JavaScript as an assembly language to manipulate the contents of that TypedArray. There's an C/C++ compiler called Emscripten will generate asm.js from C and C++.

asm.js is an amazing hack. It's a hack because it's absolutely the worst idea if you want performance. C++−>JavaScript−>Asm. It's amazing because it's actually a solution that works in all browsers that support TypedArrays.

Here's what I find funny about asm.js vs PNaCl. As more and more people try to use asm.js they'll find the size of their executable explodes. Instead of a bytecode it's outputting source code so the size of executables is HUGE. This will put pressure to just ship the bytecode and skip the JavaScript step. Hmmm, sounds like PNaCl.

Then there will be a push for other features like say pthreads but pthreads can not be implemented in JavaScript given its design constraints inside the browser. Maybe there is some creative way to remove those constraints by executing all the asm.js in a special type of "asm.js worker" so no direct access to the DOM and shared memory between "asm.js workers". Hmm, sounds like PNaCl.

The problem now is you'll need to add support for graphics, audio, file i/o, keyboard and mouse input, networking, etc from workers in ways that meet the needs of these special "asm.js workers" and legacy C++ code. Hmmm, sounds like PPAPI.

I don't know if we'll actually get there. It just seems like asm.js and PNaCl are closer than people are admitting.

Comments
O3D Post Mortem thoughts
Is Free Lunch a Positive?