Although I work for Mozilla, and have met some of the WebAssembly developers, I only started reading about its semantics recently. TL;DR: Plasma should be able to generate WebAssembly however it probably won’t work until after WebAssembly’s minimum viable product (MVP) stage.
I designed Plasma’s abstract machine (PZ) with both interpretation and code generation, including LLVM in mind. Rest assured, I’m not changing my plans for where Plasma will be targeted, but if support for running in the browser via WebAssembly is relatively easy then I’ll take it too! This means that PZ uses blocks and more higher-level control flow operations than an abstract machine normally needs. That will also make porting to WebAssembly easier, since it uses some of these structures.
Specific semantic differences
A lot of the other semantics are going to be fairly similar also. But that’s mostly because almost all underlying computers are similar (using 32 or 64 bit integers with 2’s complement arithmetic for example). So those details aren’t that interesting. Instead I’ll describe some differences:
I have heard a number of language authors consider using WebAssembly cite the (current) lack of garbage collection (GC) as the reason they have not written a WebAssembly backend (yet). Depending on when the MVP arrives we could write a simple GC in WebAssembly itself and use that. I’d rather not do that if it can be helped but it is definitely achievable.
WebAssembly does plan to add GC support, but I haven’t yet read the GC proposals.
WebAssembly supports only 32 and 64 bit integers and their operations. Plasma will allow operations on much smaller integers also (8 and 16 bit). However WebAssembly allows memory operations of these sizes and can truncate and extend then to it’s native 32 and 64 bit sizes. Integer operations in the smaller sizes should be able to be emulated.
WebAssembly doesn’t yet handle tail calls, but plans to in the future. In the interim we can just use regular calls at an extra cost/risk.
Code pointers in WebAssembly aren’t like regular pointers. They’re an index into a code table rather than an offset in a memory array. I’m sure it’ll be possible do higher-order programming in WebAssembly but it’ll just take a have a few extra steps per closure creation / call.
WebAssembly is stack oriented and also has local variables for parameters and passing values between basic blocks. PZ is purely stack oriented and has looser semantics for stack operations. We will require a light function-local recompilation step to translate PZ functions into WebAssembly functions. This means that using WebAssembly won’t be as simple as transcribing PZ into WASM as I had hoped, but this is far from a blocking issue.
Higher order calls
WebAssembly’s higher order calls need to be annotated with type information. Whereas PZ allows type-unsafe higher order calls and does not include type information. PZ will need to be modified to add this type information to higher order callsites, this should be easy enough.
Plasma and PZ require multiple return values and I want to avoid tupling and heap allocation in these situations as a compile time grantee. Doing the same for tail recursion is also a good idea. However WASM won’t support this in the MVP. I suspect that this is a lower priority than garbage collection, only because I hear more people talking about GC.
The PZ→WASM translation step could add heap allocation here. But for some hard to define reason I’m more resistant to that than writing a WASM GC.
The two things preventing Plasma to work with the WebAssembly MVP are GC and multiple return. I’d like to have a WebAssembly backend but there are plenty of other things to work on right now while these features are added to WebAssembly.
I’m quite interested in WebAssembly and having better languages in the browser. And there are no major problems preventing a future version of Plasma working in future versions of browsers.