Wasmi 2.0 ships a 2.2x faster WebAssembly interpreter

The Wasmi project released version 2.0 of its WebAssembly (Wasm) interpreter, describing it as the fundamental engine overhaul promised in the project's earlier Wasmi 1.0 post. The release follows eight months of focused work, and its central claim is performance: Wasmi 2.0 runs about 2.2x faster than Wasmi 1.0, geometric mean across the wasmi-benchmarks suite, on an Apple M2 Pro. The maintainer also benchmarked Wasmi 2.0 against other fast portable Wasm interpreters, including Wasm3, Stitch and Wasmtime Pulley, across three machines: an Apple M2 Pro, an AMD EPYC 7763 and an Intel Xeon Platinum 8370C. Despite the focus on execution speed, the post reports that Wasmi 2.0's startup performance stayed largely on par with the previous version. A follow-up post is promised with the full wasmi-benchmarks results broken out by runtime.

The core change is how instructions read and write their operands. Wasmi 1.0 addressed operands and results through stack slots: an instruction handler had to decode a slot, load its value, compute, and store the result back to a slot. Wasmi 2.0 introduces three accumulator registers, ireg for integers and references, freg32 and freg64 for floating-point values, so most instructions can read and write an actual hardware register instead of going through the stack, cutting the decode-load-store overhead per instruction. Wasmi 2.0 also gained four instruction dispatch modes for tuning performance against memory use and platform support; the modes named in the post are Direct-Threaded Code (maximum performance), Indirect-Threaded Code (a balance of performance and memory) and Switch-Loop (for platforms without tail-call support), plus an auto-dispatch feature that picks a threaded-code configuration automatically where possible.

The register design created its own problem. Wasmi's instruction handlers take nine arguments, and seven of them, store, ip, sp, mem0, mem0_len, instance and ireg, need to be passed in general-purpose registers (GPRs). Common calling conventions such as sysv64 provide only up to six GPRs for integer arguments, so a seventh would have to spill to the stack on every single dispatch and hurt performance. Wasmi 2.0's fix is to move the instance argument into a floating-point register instead of a GPR; the post states that benchmarks show this integer-to-float register move is not a significant cost. For comparison, the post notes that Stitch avoids the same limit using only six GPR arguments and Wasm3 using four.

Moving results into an accumulator register instead of a stack slot also adds new overhead: sequences like local.set and local.tee, or code that needs to keep the current accumulator value before it gets overwritten by the next instruction, now require explicit copy instructions that Wasmi 1.0's stack-slot design did not need. Wasmi 2.0 addresses this with optimized copy instructions for common patterns, such as copying a register into one of a small fixed set of local slots, and with what the post calls op-code fusion, combining frequent instruction pairs, such as an arithmetic operation immediately followed by local.set or local.tee, into single fused instructions. The extracted material cuts off partway through the description of op-code fusion, before the post's conclusion.

Alongside the engine rewrite, Wasmi 2.0 adds a validate crate feature that shrinks binary artifact size, user-requested stable fuel metering, support for WebAssembly's deterministic profile, and an improved Wasmi CLI tool. The project credits the Stellar Development Foundation as a sponsor since October 2024, and Felix Kutzner for proofreading the post. The post lists Wasmi's existing users as plugin systems (Typst, Zellij, Josh), smart-contract platforms (Soroban, Ripple), cloud hosts, IoT devices and the lightweight Firefly Zero game console.

Key facts

  • Wasmi 2.0 runs about 2.2x faster than Wasmi 1.0, geometric mean across the wasmi-benchmarks suite on an Apple M2 Pro, after eight months of focused engine work.
  • The rewrite replaces Wasmi 1.0's stack-slot operand addressing with three accumulator registers, ireg, freg32 and freg64, letting most instructions read and write hardware registers directly.
  • Instruction handlers need 7 of 9 arguments in general-purpose registers, but conventions like sysv64 provide only 6, so Wasmi 2.0 moves the instance argument into a floating-point register to avoid stack spills; Stitch and Wasm3 use 6 and 4 GPRs respectively to sidestep the same limit.
  • Wasmi 2.0 ships four instruction dispatch modes, including Direct-Threaded Code, Indirect-Threaded Code and Switch-Loop, plus stable fuel metering, WebAssembly deterministic-profile support, and a validate feature that shrinks binary size.
  • The project has been sponsored by the Stellar Development Foundation since October 2024 and is used in plugin systems (Typst, Zellij, Josh), smart-contract platforms (Soroban, Ripple) and the Firefly Zero game console.

Why it matters

Wasmi is a portable, dependency-light Wasm interpreter used where a full JIT-compiling runtime is not practical: embedded and IoT devices, plugin sandboxes, smart contracts and lightweight game hardware. A 2.2x execution-speed gain, delivered by replacing stack-slot operand addressing with hardware accumulator registers, is a substantial jump for an interpreter that these systems rely on for both speed and predictable behavior, without giving up the portability a JIT-based engine would not offer in those settings.

Who it affects

Developers who embed Wasmi in plugin systems (Typst, Zellij, Josh), smart-contract platforms (Soroban, Ripple), cloud hosts and constrained hardware such as the Firefly Zero game console. Anyone comparing portable Wasm interpreters, Wasmi against Wasm3, Stitch or Wasmtime Pulley, also gets new benchmark numbers to weigh against each project's existing feature set.

How to use it

Wasmi 2.0 is a version upgrade for existing Wasmi users. New capabilities include a validate crate feature to reduce binary size, stable fuel metering for gas-style execution limits, support for WebAssembly's deterministic profile, an improved CLI tool, and an auto-dispatch feature that picks a threaded-code dispatch configuration automatically. Four dispatch modes are available for tuning performance against memory use and platform constraints, including Direct-Threaded Code, Indirect-Threaded Code, and a Switch-Loop mode for platforms without tail-call support. The source does not mention pricing or licensing terms.

How solid is it

The 2.2x figure is the maintainer's own measurement from the wasmi-benchmarks suite, run on an Apple M2 Pro, with additional results reported on an AMD EPYC 7763 and an Intel Xeon Platinum 8370C, alongside comparisons against Wasm3, Stitch and Wasmtime Pulley. The post frames Wasmi 2.0's architecture as directly inspired by Wasm3 and Stitch, and says a follow-up post will publish the full wasmi-benchmarks results and cover each compared runtime in detail, meaning the complete dataset behind the 2.2x claim is not in this post itself. The project has run through multiple release cycles and has been sponsored by the Stellar Development Foundation since October 2024.

Risks and caveats

The post states that Wasmi 2.0 offers four instruction dispatch modes, but the material reviewed here names only three: Direct-Threaded Code, Indirect-Threaded Code and Switch-Loop; the fourth is not identified in what was extracted. The per-platform comparison numbers against Wasm3, Stitch and Wasmtime Pulley are presented as charts rather than as figures in the text, so they cannot be independently restated here. The post's walkthrough of the op-code fusion optimization is also cut off partway through in the material reviewed, so its full mechanics and whatever conclusion or further benchmarks the post promises are not covered here.

“It is fair to say that Wasmi 2.0 clearly belongs to the category of the fastest portable Wasm interpreters.”

— Wasmi 2.0 release post