Wednesday, 8 May 2019

WebAssembly Update

Somehow the other day I came across some article talking about WebAssembly. I had some far memories of having read about this thing some years ago and even posting about it. Well, it seems like in this 4 years WebAssembly has changed and evolved a lot. What I explain in that post about the webassembly binaries describing an AST that at runtime would be compiled into bytecodes for the same Virtual Machine that runs the JavaScript code no longer applies at all. Now the WebAssembly binaries contain bytecodes for a stack based VM, that is different from the VM that runs the JavaScript code. Notice that all modern JavaScript engines are register based.

This series about JavaScript and WebAssembly is a really excellent reading, particularly this entry.

Once it reaches the browser, JavaScript source gets parsed into an Abstract Syntax Tree.

Browsers often do this lazily, only parsing what they really need to at first and just creating stubs for functions which haven’t been called yet.

From there, the AST is converted to an intermediate representation (called bytecode) that is specific to that JS engine.

In contrast, WebAssembly doesn’t need to go through this transformation because it is already an intermediate representation. It just needs to be decoded and validated to make sure there aren’t any errors in it.

In my first paragraph I've just said that all modern JavaScript engines/VMs are register based. So far for me the term engine and VM were interchangeable. The thing is that after reading this article, maybe that's not always correct. The article is mainly about V8 adding an interpreter to its combination of baseline and optimized JIT compilers, but what I find really important is the picture where it seems to say that when not using the interpreter the JavaScript code gets parsed and JIT compiled to native code without passing through a bytecode representation. So I guess we should not talk about a VM. This has quite surprised me cause it's a new scenario to add to the 2 ones that were familiar to me:

  • Source code (C#, java) gets compiled to bytecodes for a stack based virtual machine (and stored in an assembly or javac file) before running the code. Then the runtime either interprets and JIT's (JVM HotSpot) or only JIT's (.NET) those bytecodes.
  • The runtime parses the (JavaScript) sourcecode into a bytecodes representation (for a register based VM), and then interprets or JITs those bytecodes.

And now we have that the V8 runtime can directly JIT compile from JavaScript to Native code without going through a bytecodes Intermediate Representation, interesting... By the way, in this post from some years ago I explain the interpreter, basic/optimized JIT combinations that JavaScript runtimes were using at that time.

No comments:

Post a Comment