wamrx
Safe, Wasmi/Wasmtime-inspired Rust bindings for the WebAssembly Micro Runtime (WAMR) fast interpreter.
These bindings deliberately target only WAMR's fast interpreter — no classic
interpreter, no AOT, and no JIT tiers. As a result, no LLVM toolchain is ever
required to build them; just cmake and a C compiler.
What this is
wamrx is a standalone Cargo workspace with two crates:
crates/wamrx-sys— rawbindgenFFI. Itsbuild.rscompiles the vendored WAMR git submodule into a staticlibiwasm.a(via thecmakecrate'svmlibtarget) and generates bindings fromwasm_export.h.crates/wamrx— a safe, Wasmi/Wasmtime-inspired API built on top:Engine/Module/Linker/Instance/Func/Global, plus the value typesVal/ValType/FuncType/GlobalType/Mutability.
Requirements & first-time setup
The WAMR sources are a git submodule; the build fails without it:
Building also requires cmake and a C compiler on PATH (WAMR is built
from C). The first build compiles WAMR from source and is therefore slow;
subsequent builds are cached.
Quick start
Instantiate a module and call an exported function:
use ;
let engine = new?;
let wasm = parse_str?;
let module = new?;
let linker = new;
let instance = linker.instantiate?;
let mut results = ;
instance.get_func?.call?;
assert_eq!;
# Ok::
For a version that also links a host function, see
crates/wamrx/examples/hello.rs:
API overview
| Type | Role |
|---|---|
Engine |
Owns a reference to the process-global WAMR runtime. |
Module |
A loaded, validated Wasm module (owns its bytes). |
Linker |
Defines host functions and instantiates modules. |
Instance |
An instantiated module; look up its exports. |
Func |
A callable exported function. |
Global |
An exported global; read/write its value. |
Val / ValType |
Runtime values / value types (i32, i64, f32, f64). |
FuncType / GlobalType / Mutability |
Type descriptions. |
InstanceConfig |
Per-instance stack/heap configuration. |
Error / Result |
Crate error type and result alias. |
How it differs from Wasmtime / Wasmi
wamrx surfaces WAMR's actual model honestly rather than faking Wasmtime
semantics. Keep these in mind:
- Imports resolve at module load time, not at instantiate time. Host
functions must be defined via
Linker::define_funcbefore the importing module is created withModule::new. - Process-global runtime and native registry. The runtime is a singleton
ref-counted by
Engine; host functions live in a process-global registry keyed by module name, owned by theLinker. - Host functions are limited by WAMR's raw calling convention. They accept only the four numeric types (i32/i64/f32/f64) and return at most one result.
- Single-threaded.
Engineis intentionally neitherSendnorSync. - Values are the four numeric MVP types only. The type is
Val(notValue);v128,funcref, andexternrefare not modeled as values.
Cargo features
Default: bulk-memory, reference-types. Each wamrx feature is a
pass-through to the identically named wamrx-sys feature, which build.rs maps
1:1 to a WAMR CMake toggle. Only fast-interpreter-compatible options are
exposed.
| Feature | Notes |
|---|---|
bulk-memory, reference-types |
Enabled by default. |
simd, gc, tail-call, shared-memory, extended-const |
Additional Wasm proposals. |
custom-name-section, load-custom-section, dump-call-stack, multi-module, thread-mgr, perf-profiling |
Runtime / embedding toggles. |
libc-builtin, libc-wasi |
libc flavors for host imports (off by default). |
hw-bound-check |
WAMR's signal-based bounds checking. Off by default: it is fragile across host threads and can abort on the main thread (e.g. under criterion). The default software bounds-check path is portable. |
Deliberately absent (WAMR forbids them together with the fast interpreter): exception-handling, memory64, multi-memory, stringref.
Common commands
Integration tests live in
crates/wamrx/tests/integration.rs.
License
Licensed under either of MIT or Apache-2.0 at your
option. (wamrx-sys and WAMR itself are Apache-2.0-licensed.)