A WebAssembly Compiler tale

How we abstracted our API to be independent of the IR, allowing Wasmer to support multiple compiler backends.

Syrus Akbary
Apr 12, 2019 · 3 min read

Originally, the Wasmer runtime was designed around Cranelift, a compiler framework written in Rust.

Wasmer old API

Over time, we realized that different user-cases needed different compiler characteristics, so we’ve expanded our backend repertoire.

We now support selecting multiple compiler backends while exposing the same, familiar, simple API to the user.

Why would you want multiple compiler backends? Each backend offers a different tradeoff between compilation speed and runtime performance.

Wasmer new Runtime API, with support for multiple backends

Today, we are super happy to announce that Wasmer 0.3.0 just shipped two more compiler backends 🎉:

Let’s review the tradeoffs of each of this compiler backend:

PS: for now, only the Cranelift backend ships with caching support, LLVM will support caching soon
PPS: At the moment, all of our backends only support x86_64, but we will support others, namely AArch64 (ARM) and possibly RISCV soon.

Single-pass backend

The single-pass compilation backend emits machine code as the WebAssembly bytecode is being parsed.
Because there is no post-processing or analysis involved in generating the machine code, the compilation times are very fast. 🔥

Single-pass compilation can almost as fast as just validating a WebAssembly module

However, very few optimizations are performed, runtime performance is generally slower than either of the two other backends (Cranelift or LLVM).

To generate the machine code, we are using a macroassembler, currently the dynasm library, allowing us to emit machine code efficiently at runtime.

When to use Single-pass

Cranelift backend

The Cranelift backend uses Cranelift to generate machine code.

Cranelift is a pure-Rust compiler infrastructure, similar to LLVM.
It’s compromise between compilation speed and runtime performance, situated roughly in the middle between our two other backends.

When to use Cranelift

LLVM backend

The LLVM backend uses the LLVM compiler framework to generate highly-optimized machine code from the inputted WebAssembly bytecode.

Compilation times with the LLVM backend are generally quite slow, but the runtime performance is roughly equal to native code.

When to use LLVM

Hope you enjoyed this article!

You can visit our website: https://wasmer.io
Our Github: https://github.com/wasmerio/wasmer
Or our Twitter: https://twitter.com/wasmerio


Universal WebAssembly runtime


Universal WebAssembly runtime

Syrus Akbary

Written by

Entrepreneur. Developer. Mathematician


Universal WebAssembly runtime