WebAssembly Interfaces (WAI)
The WebAssembly spec that was first released in 2017 was only a minimum viable product and deliberately left several features incomplete to be iterated on by the ecosystem.
Arguably the most important functionality gap is the fact that only WebAssembly primitives can be passed between the host and guest. That means imports and exports can only use the following data types,
i32- signed 32-bit integers
i64- signed 64-bit integers
f32- a 32-bit float
f64- a 64-bit float (often called a
funcref- a reference to a WebAssembly function
externref- a reference to some opaque object owned by the WebAssembly virtual machine
You'll notice this list doesn't even include strings or boolean values!
The WebAssembly Interfaces project (WAI for short) provides a polyfill for
passing around higher-level objects. It lets developers define their imports and
exports in a
*.wai file, then uses
wai-bindgen to generate glue which
automagically passes things around within the constraints of WebAssembly.
There are four main parts to WAI:
- The WAI Bindgen code generator
- The guest
- The host
The Wasmer Pack project provides a convenient way to consume WebAssembly packages which implement a WAI interface.
Some useful links:
wasmerio/wairepository (opens in a new tab)
*.waiformat (opens in a new tab)
wai-bindgenCLI on crates.io (opens in a new tab)
WAI uses a file (or files) with the
*.wai extension to define the host-guest
interface for an application that uses WebAssembly.
The precise syntax is defined in the WAI repository (opens in a new tab) and a parser,
wai-parser (opens in a new tab), is available as a Rust crate.
In an application using WebAssembly, the "guest" is the code that has been compiled to WebAssembly and is being loaded into a WebAssembly virtual machine.
In an application using WebAssembly, the "host" is the code that uses a
WebAssembly virtual machine (like
wasmer (opens in a new tab)) to load a guest and use
functionality it provides.
The WebAssembly spec refers to the host in some places as the embedder (opens in a new tab).
The WAI Bindgen code generator consumes
*.wai files and generates glue code
that the host can use for using functionality from a WebAssembly
module or the guest can use for implementing that functionality.
There are two primary ways users will interact with WAI Bindgen, the
wai-bindgen CLI, and the
wai-bindgen-* family of crates.
wai-bindgen CLI provides a command-line interface to the
crates, and is often used for once-off investigation or integration with a
non-Rust build system.
On the other hand, the
wai-bindgen-* crates allow users to generate bindings
programmatically and give them much more control over the generation process.
wai-bindgen-gen-rust-wasm (opens in a new tab)
wai-bindgen-rust (opens in a new tab)
wai-bindgen-gen-wasmer (opens in a new tab)
wai-bindgen-wasmer (opens in a new tab)
wai-bindgen-gen-wasmtime (opens in a new tab)
wai-bindgen-wasmtime (opens in a new tab)
wai-bindgen-gen-c (opens in a new tab)
wai-bindgen-gen-js (opens in a new tab)
wai-bindgen-gen-wasmer-py (opens in a new tab)
wai-bindgen-gen-wasmtime-py (opens in a new tab)