The Wheel of WebAssembly is a project aiming to show the diversity of languages that compile to WebAssembly. My initial idea was to define two functions in each language:
name()
- returning the name of the language. This is used to render each part of the wheel.feelingLucky()
- returning a random integer between 1 and 100. This is used when the wheel is spun.
In theory, when compiling each language, the output wasm file should be almost identical. In practice, this is not the case. As many of the compilers are still very experimental, these two functions cannot be defined in all the languages. Some have issues with generating a random number, so I import JavaScript's Math.random()
to help them. Others cannot handle strings properly. WebAssembly defines only numeric types and strings are supposed to be put in the linear memory and accessed via a pointer from JavaScript.
- C / C++
- C#
- AssemblyScript
- Rust
- Java
- Kotlin
- Go
- PHP
- Python
- Zig
You need Docker to build each wheel part. You need to create a self-signed certificate for localhost.
npm i
npm run wasm
npm start
You can then access the site on https://localhost:8080
.
You can re-build individual wheel parts by running
npm run wasm -- [lang]
Each wheel part represents a language that can be compiled to WebAssembly. My initial idea was to use toolchain to compile each source automatically, but this turned out to be a bit more complex. That is why I am putting here how each source can be compiled individually.
Compiled by emscripten.
You would either need Mono or Visual Studio 2017+ installed on your machine to compile the source. Although Mono has an example of compiling C# directly to WebAssembly, the set-up is a bit more complicated. That is why I use Steve Sanderson's initial adjustment of DotNetAnywhere to interpret .NET into the browser. You would also need emscripten >= 1.38.12 to compile DotNetAnywhere's interpreter to WebAssembly.
AssemblyScript defines a subset of TypeScript that can be compiled to WebAssembly.
You have to install the Rust toolchain by following these instructions. Afterwards you need to add the wasm32 target.
rustup update
rustup target add wasm32-unknown-unknown
In order to compile Java into WebAssembly, I use TeaVM. The only thing you need is Maven - it will install its dependencies afterwards. You obviously need Java SDK as well.
Kotlin/Native is used to compile Kotlin to WebAssembly. Compiling Kotlin to native restricts you from importing Java libraries. In order to generate random numbers, one may use C instead (as in the C wheel part), but this requires further configuration using the cinterop
tool. I think it is easier just to import the JavaScript one.
Go 1.14 ships experimental WebAssembly support. The communication from JavaScript to Go works with callbacks, which made me change all other calls to use promises. The output file is quite large so far (~ 1.5MB), but this is already being addressed.
The PHP interpreter is compiled to WebAssembly and then using the wrapper function pib_eval
we can evaluate PHP code, which gets printed on the console.
Pyodide brings the Python 3.8 runtime to the browser via WebAssembly, along with the Python scientific stack.
Zig includes support for all WebAssembly variants (emscripten, freestanding, WASI) out of the box.
You can follow me on Twitter with @boyanio and ask me questions you might have. You can also open an issue here on GitHub. Pull requests are welcome, too :-)