5 ms·
I feel like PNaCl is the technically superior approach - define a stable set of LLVM bytecode and build an interface to run it in the browser. But the uptake i
by safetydank 13y ago
I feel like PNaCl is the technically superior approach - define a stable set of LLVM bytecode and build an interface to run it in the browser. But the uptake is a problem, no other browser maker wants to adopt a big chunk of code controlled by Google, tailored to run optimally in Chrome.
So asm.js took a beeline - leveraging existing Javascript machinery for security/JIT and shoehorning a way to run executable LLVM on top of it. The fact that it's Javascript is just a detail, a legacy of the days when one vendor (Netscape) was able to push through a standard for running code in the browser.
In today's fragmented browser landscape I find it hard to believe a consensus could be reached again. Most of the major browser makers (Google, Microsoft, Apple) have their own platform agenda to push - in that context asm.js's compatibility with existing Javascript engines gives it the best chance of adoption.
But I agree, the hoops that had to be jumped through are a damned shame.
- flohofwoe 13y agoFrom a developer's perspective PNaCl and emscripten is almost the same to work with, the difference is just a couple of hundred lines of wrapper code (less then the differences betwenn iOS and Android wrapper code) and you need to find a higher abstraction layer for threaded code. And if the differences on the surface are so small, and the performance difference is acceptable as well (it is IMHO), I don't really care how the goal is achieved under the hood. Asm.js or PNaCl are not platform-lock-ins like DirectX or Flash. It's just POSIX + OpenGL with a handful of platform-specific functions, and practically the same code compiles on any other POSIXish + OpenGLish platform.
- CmonDev 13y agoGood enough for C++, but with JVM/CLR languages running them right in the browser would be more ideal.
- hsivonen 13y agoHow is PNaCl not Chromium lock-in? Pepper is defined by the Chromium implementation.
- flohofwoe 13y agoOnly if you look at the generated binary. But the source code which created this binary can be compiled to a myriad of other platforms with only minimal changes. You can compile the (mostly) same source code to JS+WebGL, iOS, Android, OSX, Linux (SteamOS), even Windows (but not Windows Store apps), ... The differences between these platforms is about 1% or 2% of lines of code in a typical 3D game. Compared to porting a game to, say the Xbox One or WiiU this is "peanuts".
- iso-8859-1 13y agoYou're just considering the game-perspective, where you don't need anything but GL and sound. What about WebRTC? What about DOM manipulation? You can't do this from Emscripten very well.
- flohofwoe 13y agoIt's actually really easy to build C interfaces to any Javascript API or lib. Since compiled code is just JS you can just directly call from C code into JS code and vice-versa. Most of emscripten's CRT wrapper is actually implemented in hand-written JS, as well as the OpenGL-to-WebGL wrapper. For an app which mainly needs to do DOM manipulation it is probably better to write it mostly in traditional JS and only implement the performance sensitive stuff in a C library compiled to JS. Best of both worlds...
- phaker 13y ago> So asm.js took a beeline - leveraging existing Javascript machinery for security/JIT and shoehorning a way to run executable LLVM on top of it. A big advantage of asm.js over PNaCl is that it's not LLVM. On the other hand PNaCl is very tightly coupled to LLVM. Any time I find myself checking if a some $feature is available in PNaCl, the discussion revolves around what LLVM can or can't do and how LLVM does it, see [1] for most recent example. I just can't see how PNaCl could be meaningfully reimplemented. Reimplementing it from scratch would require implementing something bug-for-bug compatible with LLVM. That's a gargantuan task. On the other end of the spectrum, why not just use the original implementation? Then it would work very much like any other plugin. I don't think it's a good solution. It seems the only remaining option is implementing it on top of LLVM. But then you still share all potential limitations (e.g. in portability) and all security issues with all other LLVM-based implementations. It could end up being not that bad -- it means more work on LLVM itself, making it better -- but I'm not sure if that would offset the other problems. How many features that appeared first in chrome or webkit were then reimplemented elsewhere in a different, better way? Do we want to end up with only one browser? No, there are lots of things we wouldn't have if Firefox didn't happen, there are lots of things we wouldn't have if Chrome didn't happen. Do we want to end up with only one PNaCl runtime? [1]: https://code.google.com/p/nativeclient/issues/detail?id=3475 https://code.google.com/p/nativeclient/issues/detail?id=3475
- jfbastien 13y agoI think you're conflating frontend and back end. As they currently exist both asm.js and PNaCl frontends are LLVM, if just because it's a good C/C++ solution to parse and optimize. The backend is indeed an LLVM subset as of today for PNaCl and not asm.js, but it's a very restricted subset because the complex bitcode definition LLVM has was pruned a lot for PNaCl, both to distance it from LLVM churn and to make it implementable in another VM. It is definitely possible to implement a non LLVM back end for PNaCl. The bug you quote is quite the opposite of what you state: Mark was explaining how complex and potentially often varying LLVM's representation of atomics was. There is a need for atomics to express the full breadth of capabilities C11/C++11 has, but it has to be solved in a way that is close to the standard and no more, non of LLVM's quirks and legacy cruft (LLVM predates these standards, launched PNaCl does not). The primitives also have to be packaged portably so that they can be expressed correctly on any hardware targets (this happens to be tricky to get right, especially since Clang usually makes assumptions about the target). I think PNaCl got this one exactly right, but then again I'm the one who implemented this. :-)
- thatthatis 13y ago> asm.js's compatibility with existing Javascript engines gives it the best chance of adoption. This is the key. With asm.js the worst case is slow, not totally broken.
- pedrocr 13y agoWhich is why Google should have a PNaCl javascript implementation, so that it degrades gracefully like asm.js but the fast case is faster.
- patrickaljord 13y agoThere you go http://trypepperjs.appspot.com/ http://trypepperjs.appspot.com/
- pedrocr 13y agoAwesome. I had indeed seen this before and forgotten about it.
- pcwalton 13y ago> I feel like PNaCl is the technically superior approach - define a stable set of LLVM bytecode and build an interface to run it in the browser. I don't agree. I think that LLVM bitcode was not really designed for this either [1]. Google has not succeeded in eliminating all of the undefined behavior from LLVM [2]. At least asm.js has a fully defined semantics as specified by ECMA-262. For any hope of interoperability between browsers, that's critical. Things like order of iteration of properties were once left undefined by ECMA-262, but pages began to rely on Netscape's behavior and other browsers had to reverse engineer what Netscape did. Eventually they were added to the standard. Likewise, without all the undefined behavior removed from PNaCl, anyone who wanted a separate implementation of PNaCl would have to reverse engineer what Chrome did. There is also the issue of compilation speed: asm.js was designed to compile quickly by a backend that doesn't do much optimization. LLVM, on the other hand, was optimized for -O2, which compiles much less quickly. PNaCl at -O0 is far worse than either V8 or OdinMonkey. On the Web, compilation speed matters a lot. I think an actually technically superior approach, if backwards compatibility were not a concern, would involve: 1. A from-scratch, untyped, non-SSA bytecode, basically an isomorphism to asm.js. All operations would have fully defined semantics. This would yield fast compilation without the JavaScript syntax and would be amenable to multiple backends, like LLVM or V8. 2. A mechanism for providing a C binding to WebIDL-based Web APIs. This would eliminate the necessity of Pepper and would mean that any new Web APIs would instantly be available to native code. PNaCl, unfortunately, is neither of these. asm.js isn't either, but I think it's closer to this ideal than PNaCl is. [1]: http://lists.cs.uiuc.edu/pipermail/llvmdev/2011-October/043719.html http://lists.cs.uiuc.edu/pipermail/llvmdev/2011-October/0437... [2]: http://www.chromium.org/nativeclient/pnacl/stability-of-the-pnacl-bitcode-abi http://www.chromium.org/nativeclient/pnacl/stability-of-the-...
- diek 13y agoJust out of curiosity, what is the rationale for a non-SSA bytecode? Is the idea that each implementation will have a platform-optimized SSA format?
- pcwalton 13y agoSSA tends to result in a larger on-the-wire format since you have more values and phi nodes. Interpretation is slower because you end up with a lot of values unless you do some sort of register allocation, and you have to interpret phi nodes. If and when you need SSA, the dominance frontiers algorithm is fast in practice (as IonMonkey/Crankshaft show).
- jude- 13y agoThe other big advantage of PNaCl is that you have the option of distributing it as a signed application that the user downloads once. This is critical for doing in-browser encryption or manipulating sensitive data. You need there to be a trusted runtime that makes this possible, but this can't be done in pure Javascript (where it's too easy to insert malicious code that leaks your keys). It's not enough to simply use a crypto API in the browser either---you don't want the Javascript to touch the data at all (otherwise, it could leak the plaintext). Moreover, unlike Java and Flash, PNaCl code is compiled in such a way that the browser can do just-in-time static analysis to verify that the code cannot escape the runtime. These two features---signed code that's trust-on-first-use and JIT static analysis---make PNaCl a much more desirable runtime than asm.js in my opinion.
- azakai 13y ago> PNaCl code is compiled in such a way that the browser can do just-in-time static analysis to verify that the code cannot escape the runtime. You can (and people do) similar things to sandbox JS, by running it in an iframe or a web worker, for example, plus some static analysis. Also, the structure of asm.js ensures that the code inside it cannot access outside except through a small number of statically analyzable entry points. You can likewise verify no one modifies the asm.js data array by putting the entire codebase in a closure, and doing a trivial static analysis to see that it is not used.
- jude- 13y agoHow do I verify the integrity of the sandbox JS, especially since I potentially have to download it each time I need it? Similarly, how do I verify the integrity of the asm.js code I'm receiving? Integrity is just as important, if not more important, than static analysis---for example, a malicious JS crypto library could pass a static analysis test, but intentionally generate weak keys. There are ways to integrity checks manually, of course, but as far as I know the browser does not perform these integrity checks automatically (and it would be difficult to do so--you'd need to implement JS signing, and you'd need to implement PKI to get the right public keys to verify the JS signatures).
- 13y ago