Remove some very outdated text from gen_wasm readme

This commit is contained in:
Brian Carroll 2022-11-15 21:21:05 +00:00
parent 2fa4c33b77
commit dff6715a33
No known key found for this signature in database
GPG key ID: 5C7B2EC4101703C0

View file

@ -1,36 +1,5 @@
# Development backend for WebAssembly
## Plan
- Initial bringup
- [x] Get a wasm backend working for some of the number tests.
- [x] Use a separate `gen_wasm` directory for now, to avoid trying to do bringup and integration at the same time.
- Get the fundamentals working
- [x] Come up with a way to do control flow
- [x] Flesh out the details of value representations between local variables and stack memory
- [x] Set up a way to write tests with any return value rather than just i64 and f64
- [x] Implement stack memory
- [x] Push and pop stack frames
- [x] Deal with returning structs
- [x] Distinguish which variables go in locals, own stack frame, caller stack frame, etc.
- [x] Ensure early Return statements don't skip stack cleanup
- [x] Model the stack machine as a storage mechanism, to make generated code "less bad"
- [x] Switch vectors to `bumpalo::Vec` where possible
- [ ] Implement relocations
- Requires knowing the _byte_ offset of each call site. This is awkward as the backend builds a `Vec<Instruction>` rather than a `Vec<u8>`. It may be worth serialising each instruction as it is inserted.
- Refactor for code sharing with CPU backends
- [ ] Extract a trait from `WasmBackend` that looks as similar as possible to `Backend`, to prepare for code sharing
- [ ] Refactor to actually share code between `WasmBackend` and `Backend` if it seems feasible
- Integration
- Move wasm files to `gen_dev/src/wasm`
- Share tests between wasm and x64, with some way of saying which tests work on which backends, and dispatching to different eval helpers based on that.
- Get `build_module` in object_builder.rs to dispatch to the wasm generator (adding some Wasm options to the `Triple` struct)
- Get `build_module` to write to a file, or maybe return `Vec<u8>`, instead of returning an Object structure
## Structured control flow
One of the security features of WebAssembly is that it does not allow unrestricted "jumps" to anywhere you like. It does not have an instruction for that. All of the [control instructions][control-inst] can only implement "structured" control flow, and have names like `if`, `loop`, `block` that you'd normally associate with high-level languages. There are branch (`br`) instructions that can jump to labelled blocks within the same function, but the blocks have to be nested in sensible ways.
@ -41,19 +10,6 @@ This way of representing control flow is similar to parts of the Roc AST like `W
Our solution is to wrap all joinpoint/jump graphs in an outer `loop`, with nested `block`s inside it.
### Possible future optimisations
There are other algorithms available that may result in more optimised control flow. We are not focusing on that for our development backend, but here are some notes for future reference.
The WebAssembly compiler toolkit `binaryen` has an [API for control-flow graphs][cfg-api]. We're not using `binaryen` right now. It's a C++ library, though it does have a (very thin and somewhat hard-to-use) [Rust wrapper][binaryen-rs]. Binaryen's control-flow graph API implements the "Relooper" algorithm developed by the Emscripten project and described in [this paper](https://github.com/emscripten-core/emscripten/blob/main/docs/paper.pdf).
> By the way, apparently "binaryen" rhymes with "Targaryen", the family name from the "Game of Thrones" TV series
There is also an improvement on Relooper called ["Stackifier"](https://medium.com/leaningtech/solving-the-structured-control-flow-problem-once-and-for-all-5123117b1ee2). It can reorder the joinpoints and jumps to make code more efficient. (It is also has things Roc wouldn't need but C++ does, like support for "irreducible" graphs that include `goto`).
[cfg-api]: https://github.com/WebAssembly/binaryen/wiki/Compiling-to-WebAssembly-with-Binaryen#cfg-api
[binaryen-rs]: https://crates.io/crates/binaryen
## Stack machine vs register machine
Wasm's instruction set is based on a stack-machine VM. Whereas CPU instructions have named registers that they operate on, Wasm has no named registers at all. The instructions don't contain register names. Instructions can only operate on whatever data is at the top of the stack.