WebAssembly overview
Background
Emscripten
I first heard of Emscripten in the mid-2010s. At the time, you could compile C code to an optimizability-focused subset of JavaScript known as asm.js. This meant that, given the source code to a native app and appropriate implementations of system APIs, you could run formerly native-only programs in the browser--convenient, if you don't want to install anything.
Enter WebAssembly
In the intervening years, WebAssembly appeared. WebAssembly is a binary format for programs that run on a portable virtual machine. This VM can be hosted in your browser, but non-browser runtimes have also sprung up (e.g. wasmtime).
WebAssembly, to me, seems like the Holy Grail of compilation targets. I wouldn't be surprised if, thanks to browser support, WebAssembly is the most broadly supported binary program format. What other binary format works on my desktop, phone, Raspberry Pi?
Note that WebAssembly runtimes seem to be standardizing on an in-development system interface named WASI. You probably can't write a GUI app solely with WebAssembly and WASI today, but I'm sure that day is coming (in the distant future).
One note on Emscripten
If you just want to port native programs to the browser, Emscripten is an environment for doing that. It even converts OpenGL to WebGL and handles the SDL API. Unfortunately, just installing Emscripten requires Python. For now, I refuse to setup bloated software just to install the software I actually want, so I'm skipping Emscripten.
WebAssembly concepts
Mozilla's documentation has a great overview of WebAssembly concepts. There's also an approachable series of WebAssembly articles on Mozilla Hacks. I'll try to summarize:
- Module: a compiled WebAssembly binary (declaring imports and exports)
- Instance: a module along with its state (memory, table, imports)
- Memory: a read/write, resizable buffer provided to the instance
- Table: array of references that aren't directly stored in WebAssembly-accessible memory (for security reasons)
- The example I've seen for this is to be able to pass function pointers into C/C++ code
WebAssembly formats
WebAssembly defines two formats:
- .wasm: Binary format
- .wat: Text format (assembly)
The WebAssembly Binary Toolkit contains tools for converting between these formats. Specifically, wat2wasm
is analogous to a very simple assembler, and wasm2wat
to a disassembler.
WebAssembly browser interface
Within the browser, WebAssembly currently needs to be loaded using JavaScript (it sounds like there are plans to support loading using script tags and import statements in the future). Sadly, as of today, the recommended way to load WebAssembly (WebAssembly.instantiateStreaming()) is only supported by 75% of browsers. The more broadly supported WebAssembly.instantiate() seems cumbersome. I'm hopeful that WebAssembly's ergonomics will improve, but I suppose this is just the price you pay when using new technology.
Next steps
Armed with the above information, I think I'm ready to dive in and test out WebAssembly with a trivial example. I'll report my findings in a subsequent update.