2
11
Fork
You've already forked wastrel
0
WebAssembly-to-C compiler
  • C 53.9%
  • Scheme 42.8%
  • M4 1.9%
  • Makefile 0.9%
  • Python 0.4%
2026年01月16日 13:36:36 +01:00
bin Fix script license 2025年10月27日 21:21:30 +01:00
module Renumber types for more optimal run-time checks 2026年01月16日 13:36:36 +01:00
resource Fix wasip1_environ_get 2025年10月29日 21:39:36 +01:00
whippet Merge remote-tracking branch 'whippet/main' 2026年01月15日 10:41:05 +01:00
.gitignore Initial commit 2025年10月10日 16:54:45 +02:00
acinclude.m4 Initial commit 2025年10月10日 16:54:45 +02:00
bootstrap.sh Initial commit 2025年10月10日 16:54:45 +02:00
configure.ac Capture C compiler at configure-time. Cope with multi-token $CC. 2025年10月15日 09:59:43 +02:00
guix.scm Remove lttng-tools from guix.scm 2026年01月15日 10:43:57 +01:00
LICENSE.txt Add README.md and LICENSE.txt 2025年10月10日 21:48:48 +02:00
Makefile.am Switch to load prelude, wasi from resource header files 2025年10月23日 16:59:27 +02:00
pre-inst-env.in Switch to load prelude, wasi from resource header files 2025年10月23日 16:59:27 +02:00
README.md Fix Debian build dependencies 2025年11月06日 11:59:32 +01:00
test.c Initial compiler 2025年10月10日 16:54:48 +02:00
test.wasm Initial compiler 2025年10月10日 16:54:48 +02:00

Wastrel, a research WebAssembly-to-C compiler

Wastrel is an implementation of WebAssembly. It compiles Wasm modules to C, and thence to native code.

Wastrel is a whole-program ahead-of-time compiler, designed to compile one Wasm module into one executable. It currently compiles in a straightforward way, emitting C that looks like the Wasm source, and relies on the C compiler to do appropriate optimizations. It has two virtues:

  • It's fairly easy to use: it's like Wasmtime's command-line interface, except that it takes longer in the compile phase.

  • The resulting code is quite fast! Compiling via GCC or Clang is slow but the output binaries have best-in-class performance.

  • Security is OK? The wastrel compiler itself is written in a memory-safe language, the output code uses C's type system as well as we can to avoid signedness, type confusion, and pointer construction bugs, and the output uses Linux's memory protection and filesystem namespace isolation facilities to prevent bugs by construction.

  • Wastrel aims to support experimental extensions: GC, stack switching, all that hot mess.

  • Wastrel aims to serve as a test bed for Whippet, a garbage collection library.

If a module needs some bespoke imports, Wastrel can accomodate that by including C runtime support files. If an import would be better provided by another Wasm module, then those modules should be linked in a Wasm-to-Wasm pass before compiling with Wastrel.

Wastrel implements WASI 0.1. If a module imports interfaces from the wasi_snapshot_preview1 module, Wastrel will provide implementations. Additionally, if the module exports a nullary procedure named _start, or otherwise exports any nullary procedure, that procedure will be called as part of the compiled main function.

There are newer versions of WASI, notably version 1.0 that is coming out sometime early in 2026. Newer versions of WASI specify mechanisms to compose components into a whole, which involves some amount of run-time linking support. Wastrel should be able to be a part of that world somehow, but hopefully in the same way it implements WASI 0.1: by requiring that some other tool link components together and lower from component-model types to a conventional ABI, and Wastrel just provides the WASI standard library.

That said, one goal of Wastrel is to experiment with garbage collection as a compositional paradigm. Culturally speaking, WASI's thesis is that shared-nothing architectures allow one to robustly build larger systems from smaller pieces. This is at the same time obviously true but also limiting: for the size of system that can stay within an address space, we can avoid copies if we can pass immutable data by reference. This might not simply be more efficient, as it may result in systems with a completely different flavor, relative to the shared-nothing discipline. We should find out!

Wastrel is not currently intended to allow Wasm modules to be instantiated multiple times in a process, or to be included as a library in a larger program. Would you like this? We should talk!

Building

The only dependencies of Wastrel are Guile 3.0.x for the Wasm-to-C translation, a Linux system on which to run, and a C compiler. Wastrel is mainly tested on GCC.

Checking out the git repo

git clone https://codeberg.org/andywingo/wastrel
cd wastrel

Building on Guix

On Guix:

guix shell
./bootstrap.sh && ./configure && make -j

Building on Debian/Ubuntu

Something like this should work to install dependencies:

sudo apt install guile-3.0 guile-3.0-dev pkg-config gcc automake autoconf make

Building on some other Linux distro

You need Guile! And a C compiler of course. And pkg-config and automake and autoconf and make so that the build works. Godspeed!

Building on MacOS or Windows

Firstly, what are you doing with your life? I cannot imagine developing software on a platform controlled by one company. What a drag. You do you, though!

But here's the thing. Compiling plain Wasm files to C should work fine on these targets, but a plain Wasm file can't do much. Mostly you will be compiling Wasm binaries that use WASI interfaces because that's what gives you, like, the ability to print to the console and access files. But you don't want to let the binaries access any file, and indeed WASI provides for some sandboxing. But despite the capabilities-oriented security veneer, in practice many WASI implementations effectively implement the sandbox via a permissions layer: for example the WASI implementation has capabilities to access the parents of preopened directories via .., but has to actively prevent this capability from leaking to the compiled module via run-time checks.

Wastrel takes a different approach, which is to use Linux's filesystem namespaces to build a tree in which only the exposed files are accessible. No run-time checks are necessary; the system is secure by construction. I do not want to implement file sandboxing any other way.

So is there a nice way to do this on MacOS? Well let's talk, surely it isn't too much code. But if not, we're back to my first point: what are you doing with your life?

Usage

$ ./pre-inst-env bin/wastrel test.wasm
Hello, world from ./test.wasm.YkJpch!

Neat, right? Just running wastrel my-wasm-file.wasm is short for running wastrel run my-wasm-file.wasm. You can instead stop with creating a binary with wastrel compile:

$ ./pre-inst-env bin/wastrel compile -o test test.wasm
$ ./test
Hello, world from ./test!

Or at creating a C file:

$ ./pre-inst-env bin/wastrel compile -S -o test-out.c test.wasm
$ gcc -O2 -o test -lm -Wall -Wno-unused-label -Wno-unused-variable test-out.c
$ ./test
Hello, world from ./test!

Performance

Well, comparisons are fraught. I have looked at the Coremark benchmark and Wastrel's speed is the same as native (slightly faster actually?), a tiny bit faster than w2c2, and some 40% faster than Wasmtime. A proper evaluation will take more time.

Other Wasm implementations have virtues that Wastrel will probably never have. Like, use something else if you need to run on Windows, right? Our goal is to be a test bed for experimentation. Having state of the art performance is necessary; portability to HaikuOS is not.

Acknowledgements

Wastrel uses the WebAssembly support libraries from Spritely's Hoot Scheme-to-WebAssembly compiler. Thanks especially to David Thompson for his work on these libraries.

Wastrel is Free Software, and can be run, distributed, and modified in accordance with the Apache License, version 2.0. See LICENSE.txt, for full details.