wasm-opcode-table 0.1.0

Typed parser for the WebAssembly instruction opcode table in TOML
Documentation
# WebAssembly Opcode Table (TOML)

This repository contains a structured reference of the WebAssembly instruction set and its opcodes, formatted as a [TOML](https://toml.io) file.


## Overview

The [instructions.toml](./instructions.toml) file lists all instructions as an array-of-tables under the key `[[instructions]]`.

Each entry represents a single instruction (or more precisely, a single opcode) and includes details such as its name, category, binary opcode, immediate arguments, and stack signature.

| Key          | Type              | Value                                                                     |
| ------------ | ----------------- | ------------------------------------------------------------------------- |
| `name`       | string            | The name of the instruction.                                              |
| `variant`    | string (optional) | A unique identifier for a specific variant of the instruction, if needed. |
| `opcode`     | number or array   | The binary opcode for the instruction.                                    |
| `category`   | string            | The category of the instruction as defined in the spec.                   |
| `immediates` | array (optional)  | The immediate arguments, if any.                                          |
| `stack-type` | table (optional)  | The instruction type, describing stack input and output types.            |
| `feature`    | string (optional) | The feature proposal to which the instruction belongs, if any.            |
| `since`      | string (optional) | The first major version of WebAssembly that includes the instruction.     |

## Examples

```toml
[[instructions]]
name = "i32.add"
opcode = 0x6A
category = "numeric"
stack-type = { from = [ { type = "i32" }, { type = "i32" } ], to = [ { type = "i32" } ] }
since = "1"
```

```toml
[[instructions]]
name = "table.fill"
opcode = [0xFC, 17]
category = "table"
immediates = [ { type = "tableidx", name = "x" } ]
stack-type = { from = [ { type = "i32" }, { type-of = "x" }, { type = "i32" } ], to = [] }
feature = "reference-types"
since = "2"
```

### Source of data
Original source of data is [ohorn/wasm-opcode-table-toml](https://github.com/ohorn/wasm-opcode-table-toml).
Later updated using LLM with spec from [WebAssembly Spec](https://github.com/WebAssembly/spec).

## Rust crate (`wasm-opcode-table`)

This repository is also the [`wasm-opcode-table`](https://crates.io/crates/wasm-opcode-table) crate — a typed schema and parser for `instructions.toml`. Use it in tools, validators, or codegen without hand-maintaining opcode tables.

**Always available:**

- Structs for instructions, opcodes, immediates, and stack signatures (`StackEntry`, `ControlFrame`, …)
- [`parse_instructions_toml`]https://docs.rs/wasm-opcode-table/latest/wasm_opcode_table/fn.parse_instructions_toml.html to parse any TOML string
- [`validate_instructions_table`]https://docs.rs/wasm-opcode-table/latest/wasm_opcode_table/fn.validate_instructions_table.html for control-frame invariants

**Optional feature `instructions-toml`:** embeds `instructions.toml` from the crate package at compile time via `include_str!` and exposes [`instructions()`](https://docs.rs/wasm-opcode-table/latest/wasm_opcode_table/fn.instructions.html) for a lazily parsed `&'static InstructionsTable`.

## Usage


```toml
[dependencies]
wasm-opcode-table = { version = "0.1", features = ["instructions-toml"] }
```

```rust
use std::fs;
use wasm_opcode_table::{instructions, parse_instructions_toml, Instruction, StackEntry};

// Load and parse from a file (no embed feature required)
let source = fs::read_to_string("instructions.toml")?;
let table = parse_instructions_toml(&source)?;

// Or use the bundled table (requires `instructions-toml`)
let table = instructions();
let add = table.instructions.iter().find(|i| i.name == "i32.add").unwrap();
```


# Contributing 

Feel free to create an issue if you find any mistake, or didn't find an instruction you expected.
Or create a pull request directly if you want to fix something.

Please avoid storing editors/llms configs in the repository.

## Finding missing instructions (`script/diff-spectec.rs`)

The [rust-script](https://github.com/fornwall/rust-script) in [`script/diff-spectec.rs`](./script/diff-spectec.rs) compares opcode keys in [`instructions.toml`](./instructions.toml) against a Spectec grammar file from the [WebAssembly spec](https://github.com/WebAssembly/spec/blob/main/specification/wasm-latest/5.3-binary.instructions.spectec). Use it to see which rows still need to be added to the table.

```bash
# One-time: install rust-script
cargo install rust-script

# Fetch the latest binary-instructions grammar (optional)
curl -sL -o spec.instructions.spectec \
  https://raw.githubusercontent.com/WebAssembly/spec/main/specification/wasm-latest/5.3-binary.instructions.spectec

# Compare against the bundled instructions.toml (default second argument)
./script/diff-spectec.rs script/latest-binary-instr.spectec

# Threads atomics (subopcode is varuint, not a second hex byte — see script/threads-binary-instr.spectec)
./script/diff-spectec.rs script/threads-binary-instr.spectec
```

Prefixed opcodes in TOML use the **subopcode value** encoded as a varuint after the prefix byte (e.g. `[0xFE, 16]` for `i32.atomic.load`, matching [wasmparser](https://docs.rs/wasmparser/latest/src/wasmparser/binary_reader.rs.html#1830)), not the raw LEB128 wire bytes. Spectec grammars should write `0xFE 16:Bu32`, not `0xFE 0x10`.

Example output (truncated):

```
opcode          spectec                              section
--------------  -----------------------------------  ----------------
0x08            THROW x                              control instructions
[0xFB, 24]      BR_ON_CAST l (REF null_1? ht_1) ...  control instructions

Exit code `2` means there are missing opcodes; `0` means the table covers every rule in the Spectec file.

## Tests
Run tests from the repository root: `cargo test --features instructions-toml`.