dfwasm
is a compiler that compiles WebAssembly (WASM) to DiamondFire (DF) templates. It is designed to translate WASM modules into several templates, which can be used within DiamondFire code.
This allows you to write code in a language that compiles to WASM, and then use that code within DiamondFire.
Yes, that means you can run blazingly fast Rust in DiamondFire.
Note
This compiler does not support floating point numbers. Numbers in DiamondFire are represented as fixed-point integers with a 1/1000 scale, so supporting floats would require implementing fixed-point math from scratch. While this would be possible, it would not be performant within DiamondFire.
While I haven't looked into it, a concept called "soft floats" may be used to get around this.
You will first need a .wasm
file. There are several ways to compile to WASM. Here are a few options:
-
Rust: A systems programming language (that this project is written in) that can compile to WASM.
An example Rust to DF project can be found at github.com/fallow64/dfwasm-example-project.
-
AssemblyScript: A TypeScript-like language that compiles to WASM.
-
C/C++: You can use Emscripten or clang to compile C/C++ code to WASM.
-
Many more options are available. Here is a list of languages that can compile to WASM.
Whichever option you choose, I highly recommend using a language with a small runtime and features to disable the standard library. This will help reduce the size of the generated WASM file and let it fit within a DiamondFire plot.
For some examples that already work, check out the examples
directory.
In the root directory, run cargo run
to run the compiler CLI.
The arguments are as follows (may be updated, check dfwasm --help
for help):
Usage: dfwasm [OPTIONS] <--code-client|--link> <PATH>
Arguments:
<PATH> The path to the WebAssembly file (or .wat)
Options:
-d, --debugger Include debugger function calls
-s, --size <SIZE> The DiamondFire plot size [default: 301]
-b, --batch-data <BATCH_DATA> Batch data section memory initializations by a certain size [default: 26]
-c, --code-client Send templates via CodeClient API
-l, --link Send templates via dfonline.dev links
-m, --module <MODULE> The module name to use for the template
-w, --wait Whether to include calls to wasm.internal.small_wait
-h, --help Print help
-V, --version Print version
The project is divided into several Cargo packages:
dfwasm
: The CLI to interface with the compiler.dfwasm-compiler
: The core compiler that handles the translation from WASM to DF.dfwasm-template
: A serde_json serializer/deserializer for DF templates, including an optionalcodeclient
feature to send templates via the CodeClient API.dfwasm-test-runner
: A test runner that compiles many modules, runs them, and compares the output towasmer
(a WASM runtime).
- An automated test suite.
- Add the utility functions to the compiler.
- Allow multiple modules to be initialized and ran at once.
- Extract commonly used lists of instructions into a different function to reduce code duplication.
- Combine multiple small templates into one large template that fits within the size limit. This will lessen the burden of CodeClient's template placer.
- Run doom in DiamondFire (the inspiration for this project).
- Add support for WASM floats. (stretch goal)
This project is heavily inspired by MichiganTypeScript's typescript-types-only-wasm-runtime, which is a marvel of a TypeScript project that runs WASM entirely within the TypeScript type system. Many ideas, concepts, and tests were taken from that project.
This project is licensed under the MIT License.