Skip to content
Bernard Teo edited this page May 25, 2021 · 15 revisions

Sourceror Developer Documentation

This Wiki is intended for developers. It has been written in the hope that it might help future developers navigate through Sourceror's source code.

Sourceror converts a Source ESTree to a WebAssembly binary. Converton from Source source code to a Source ESTree is not provided by Sourceror. To compile Source source code to a WebAssembly binary, Sourceror Driver should be used instead. Sourceror Driver invokes js-slang to convert Source source code into a Source ESTree, and then invokes Sourceror to convert the Source ESTree to a WebAssembly binary.

Sourceror contains a few separate components that work together. Each component is a separate crates organised in a cargo workspace.

For issues related to building the NPM package, see the Packaging wiki page instead.

For issues related to the design of the REPL, see the REPL wiki page instead.

Components

Sourceror is made out of these components:

  • Main Driver (source-compiler)
  • IR (intermediate representation) (ir)
  • Wasmgen (wasmgen)
  • Backend-Wasm (backend-wasm)
  • Frontend-ESTree (frontend-estree)
  • Project Standard Library (projstd)

Dependency structure

Sequence diagram

In the following sequence diagram, all actors are Rust modules. Serde is a third-party serialisation/deserialisation library that can parse JSON.

This is the only crate that depends on wasm-bindgen (the crate that emits bindings between the Rust code (that has been compiled to WebAssembly) and JavaScript). It has only one exported function (compile()), which transforms a Source AST (in ESTree) into a WebAssembly binary. This component is called the driver because it invokes all the other components to compile the code.

The main purpose of this crate is to define an intermediate representation of the program being compiled (see here). This intermediate representation is defined using Rust structs/enums with public fields. In other words, the struct layout is part of the public API of this component.

Most optimisations also operate on the intermediate representation, and are part of this crate.

This crate provides an ergonomic interface for constructing a WebAssembly binary. It mostly follows the binary format described in the WebAssembly specification. It also provides an interface for encoding instructions into a byte sequence. This crate is a general-purpose WebAssembly binary format encoder, and can be used on its own in other projects.

This crate converts the intermediate representation to the WebAssembly binary. It depends on the IR and Wasmgen crates. It only has one function in its public API, and that function drives the whole encoding process.

This crate is also responsible for encoding the garbage collector into the WebAssembly binary. (As WebAssembly does not provide garbage collection facilities, we need to provide our own.)

This crate converts the annotated Source AST to the intermediate representation. It depends on the IR crate. It also generates explicit closures for function definitions.

This crate contains everything we wish is in the Rust Standard Library but somehow isn't. Most things here are designed to work with standard library components. This crate doesn't depend on anything else, and can be used on its own in other projects.