qbe-wasm [ Home ] [ Demos ] [ Source ]

qbe-wasm

Compile QBE input files into wat or wasm. Uses QBE internals and binaryen. ISC licensed.

Usage: qbe-wasm [-h]
     [-o <file>]
     [-t <target>]
     [-d <flags>]
     [-O <level>]
     files...

-h: print this help text
-o <file>: output to file
-t <target>: generate wasm (default) or wat
-d <flags>: currently ignored
-O <level>: 0 to disable optimizations

Status

While still in active development, qbe-wasm is able to compile 100% of cproc's test suite and 95% of QBE's test suite.

Both QBE and cproc are vendored so their tests can be leveraged during development. The tests are compiled to either wat or wasm depending on if they can be successfully run. Helping to convert tests from wat to wasm could be a good first issue.

A few of the QBE tests require patches since wasm won't allow some things QBE does, such as a variable on the lhs of a void function call. Patches are used as a last resort but seemed better than just skipping the test entirely.

Demos

In addition to the tests, there are also live web-based demos including the Game of Life written in C (cproc) and Hare, QBE's mandel test and some code borrowed from around the web - requires js.

Development

Git submodules are used, so clone recursive.

I currently develop this on Alpine. cproc and QBE need to come from testing at the time of writing. See the Dockerfile for required packages.

You can also use the Dockerfile to make a dev container if you make img then make sh.

Once all development dependencies are installed, running make will build the code, examples and run tests. If you need to change how the tests are built, change scripts/tgen and then make tgen.

Using qbe-wasm

qbe-wasm can be used as a drop-in replacement for QBE. It supports the wat and wasm targets, and defaults to wasm if an unknown target is specified. This allows, based on the tool, using qbe-wasm instead of QBE while still accepting the tool's internally set flags.

If this does not work, getting the tool to emit the QBE textual format then feeding that into qbe-wasm works as well.

Using with hare

a) QBE=qbe-wasm hare build -t s -o some.wasm some/module will build some module as some.wasm using qbe-wasm.

b) hare build -t ssa -o some.ssa some/module will emit QBE's textual format which can then be fed to qbe-wasm.

Using with cproc

cproc -emit-qbe -o some.ssa -c some.c will emit QBE's textual format which can then be fed to qbe-wasm.

Likely Gotchas

No wasi support.

In a scenario like vendor/cproc/test/func-noreturn.qbe, there doesn't seem to be a way to get the return type of main, so a void type is inferred due to no return statements.

wasm is much stricter in its output requirements than QBE, so some issues may arise.

Function pointers don't work.

Compiling a wasm blob from multiple hare modules does not currently work.