Skip to main content

This is my blog, more about me at marianoguerra.github.io

🦋 @marianoguerra.org 🐘 @marianoguerra@hachyderm.io 🐦 @warianoguerra

Bootstrap post-collapse OOP technology with Wasm GC (Part 2)

In Bootstrap post-collapse OOP technology (Part 1) I sketched the minimal set of features a language has to provide to allow booting/bootstrapping the rest of our minimal object oriented language in itself.

But if we are bootstrapping post collapse, we have to run the bootstrapping "prelude" in some implementation on top of hardware we can find.

Collapse OS selected Z80, 8086, 6809 and 6502 machines.

In The Birth & Death of JavaScript (2014) Gary Bernhardt proposes a future where WebAssembly is the foundation of computing.

If we assume WebAssembly chips to be available we can consider writing an implementation for our language in raw WebAssembly.

If no Wasm native chips are available we can write some transpilers or emulators on top of the chips we can find while keeping a single implementation instead of multiple ones like Collapse OS does.

To bootstrap our stack we have to find/remember the language implementation, the WebAssembly bytecodes and hand translate the WebAssembly Text Format to the binary instructions, start our implementation, run the bootstrapping prelude and we are done.

The drifters are all former intellectuals. They have each memorized books should the day arrive that society comes to an end, with the survivors learning to embrace the literature of the past.

-- Fahrenheit 451

I may not be the one who remembers the whole implementation by memory, but surely I can write it again :)

Here is an implementation of the features needed to run the prelude in WebAssembly: fatt.wat.

It uses some features that are not yet part of the standard (GC, reference types) but are already available on most browsers (firefox and chrome-ish) with safari support on the way.

The implementation is ~1500 lines of Wasm Text, when compiled the wasm file weights 5.8KB, 2.9KB gzipped.

The implementation is complete and can run a slightly adapted version of the bootstrap code presented in the previous post.

The adaptation is only to split binding of values and handlers in two different messages to make the types work.

I also moved the implementation of < for () and = for Name from the primitive environment to the bootstrap code.

As a comparison, the rpython implementation described in The proof is in the meta-tracing JIT interpreter is 759 lines of rpython (excluding the parser) and the binary weights 6.3 MB with JIT and 619 KB without JIT.

If you want to play with it check the commands in the justfile, here are the tools and versions I used:

  • wasm-tools version 1.212.0 to compile the wat to wasm
  • deno version 1.45.5 to run the tests (with some V8 experimental flags)
  • wasm-opt version 116 to optimize the wasm file

Later versions should work fine, you may have to remove or modify some of the experimental flags.

If you would like to learn more about WebAssembly there's a book you may like: WebAssembly from the Ground Up