A stack machine in bytecode
WebAssembly is a compact, typed stack machine. Each instruction pops a fixed set of operands off the value stack and pushes its results back, which makes the bytecode easy to validate and fast to compile. This reference groups the core MVP and WebAssembly 2.0 instructions into control, parametric, variable, memory and numeric categories, each with its opcode, stack type signature and a short description.
How it works
Every instruction is described by a signature [args] → [results]. Numeric
instructions like i32.add consume their operands and push a typed result; the
integer ops use two’s-complement wrapping while float ops follow IEEE-754. Control
instructions (block, loop, if, br, br_table, call) manage labelled scopes
and jumps — branches target blocks by depth, not by name, in the binary format.
Variable instructions move values between the stack and locals or globals, and memory
instructions read and write the single linear memory using an address on the stack
plus an alignment hint and offset immediate. Opcodes are single bytes for the MVP;
later extensions such as bulk-memory use a 0xFC prefix and a sub-opcode. Filter the
list above by name, opcode or category to find what you need.
Notes and gotchas
- Signed division (
i32.div_s) and the float-to-int truncations trap on divide by zero and on out-of-range conversions; use the saturating*_satvariants to clamp instead of trapping. local.teeislocal.setthat leaves the value on the stack — handy for chaining.- Memory addresses are byte offsets into one flat array starting at zero; out-of-bounds access traps deterministically.
- The text format (
.wat) names blocks and locals for readability, but the binary format resolves those to numeric indices and branch depths.