package core:rexcode/ir/wasm

⌘K
Ctrl+K
or
/

    Overview

    rexcode/ir/wasm -- the WebAssembly intermediate representation.

    WASM is a stack bytecode: a byte stream with LEB128 immediates, one encoding form per opcode, over an implicit value stack with a minimal type system. On the two axes that sort the IR family (docs/ir_design.md §2) it is table-driven on encoding -- a static opcode -> operand-layout table, exactly the ISA ENCODING_TABLE shape -- and STACK on dataflow (the one outlier among the modelled IRs; SPIR-V/LLVM are SSA).

    So this package is a sibling of the SPIR-V package under ir/: it re-exports the shared ir vocabulary (Module / Function / Block / Operation / Operand / Type / Id / ...), owns a u16 Opcode (the WASM opcode set, with the 0xFC/ 0xFD/0xFE prefix groups folded in), a static ENCODING_TABLE that drives a byte/LEB codec, the three Module-based verbs (encode / decode / print), a Relocation for object-file index fixups, and the WASM value-type model.

    This is the migration anticipated by docs/ir_design.md §4: WASM was shaped as an ISA arch package (core:rexcode/wasm); its real encode/decode already dropped the ISA verbs' label_defs/resolve/base_address (WASM has no PC-relative pass -- branches carry structured label depths), so moving it onto the ir Module/Operation/Operand model is a change of leaf shape, not of codec. The table-driven codec below is carried over intact; what changed is the leaf (ir.Operation in place of the old fixed-operand Instruction), the operand model (ir.Operand, with WASM memarg/blocktype/lane riding in aux), and the unit of work (an ir.Module of functions->blocks->operations).

    Index

    Procedures (128)
    Procedure Groups (0)

    This section is empty.

    Types

    Attr ¶

    Attr :: enum u16 {
    	NONE, 
    	BLOCKTYPE, 
    	MEMARG, 
    	REFTYPE, 
    	LANE, 
    	V128_LO,   // low 8 bytes of a v128 literal / shuffle mask
    	V128_HI,   // high 8 bytes
    }
     

    The ir.Operand.aux tag for the ATTRIBUTE-kind WASM immediates. (REF operands instead put an Index_Kind in aux; the opcode's ENCODING_TABLE form always says which of the two an operand slot is, so the two uses never collide.)

    Related Procedures With Returns

    Block ¶

    Block :: rexcode_ir.Block
    Related Procedures With Returns

    Block_Type ¶

    Block_Type :: enum i64 {
    	EMPTY     = -46, // 0x40
    	I32       = -1,  // 0x7F
    	I64       = -2,  // 0x7E
    	F32       = -3,  // 0x7D
    	F64       = -4,  // 0x7C
    	V128      = -5,  // 0x7B
    	FUNCREF   = -61, // 0x70
    	EXTERNREF = -71, // 0x6F
    }
     

    Block signature. Negative sentinels are the s33 single-byte forms; a non-negative value is a type index encoded as a positive signed LEB128.

    Related Procedures With Parameters

    Custom_Section ¶

    Custom_Section :: struct {
    	section: Section,
    	payload: []u8,
    	// borrowed, m.data[section.offset:][:section.size]
    	variant: union {
    		Custom_Section_Name, 
    		Custom_Section_Target_Features, 
    	},
    }

    Custom_Section_Name ¶

    Custom_Section_Name :: struct {
    	module_name: string,
    	functions:   []Custom_Section_Name_Function,
    	locals:      []Custom_Section_Name_Function_Locals,
    }

    Custom_Section_Name_Function ¶

    Custom_Section_Name_Function :: struct {
    	id:   u32,
    	name: string,
    }

    Custom_Section_Name_Function_Locals ¶

    Custom_Section_Name_Function_Locals :: struct {
    	func_idx: u32,
    	locals:   []Custom_Section_Name_Local,
    }

    Custom_Section_Name_Local ¶

    Custom_Section_Name_Local :: struct {
    	idx:  u32,
    	name: string,
    }

    Custom_Section_Target_Feature ¶

    Custom_Section_Target_Feature :: struct {
    	prefix:  Custom_Section_Target_Feature_Prefix,
    	feature: string,
    }

    Custom_Section_Target_Feature_Prefix ¶

    Custom_Section_Target_Feature_Prefix :: enum u8 {
    	Used       = 43, 
    	Disallowed = 45, 
    	Required   = 61, 
    }

    Custom_Section_Target_Features ¶

    Custom_Section_Target_Features :: struct {
    	features: []Custom_Section_Target_Feature,
    }

    Dataflow ¶

    Dataflow :: rexcode_ir.Dataflow

    Encoding ¶

    Encoding :: struct #packed {
    	mnemonic: Opcode,
    	// 2 -- redundant w/ table index, kept for parity
    	prefix:   u8,
    	// 1 -- PREFIX_NONE / PREFIX_MISC / PREFIX_SIMD / PREFIX_ATOM
    	opcode:   u16,
    	// 2 -- primary opcode, or sub-opcode within a prefix group
    	imm:      [2]Imm_Kind,
    	// 2 -- immediate layout, walked in order
    	flags:    Encoding_Flags,
    	// 1
    	inputs:   i8,
    	// 1 -- stack operands consumed;  -1 when it varies
    	outputs:  i8,
    }

    Encoding_Flags ¶

    Encoding_Flags :: distinct bit_field u8 {
    	control: bool | 1,
    	memory:  bool | 1,
    	_:       u8 | 6,
    }

    Error ¶

    Error :: rexcode_ir.Error

    Error_Code ¶

    Error_Code :: rexcode_ir.Error_Code

    Export ¶

    Export :: struct {
    	kind:  External_Kind,
    	name:  string,
    	index: u32,
    }

    External_Kind ¶

    External_Kind :: enum u8 {
    	FUNC   = 0, 
    	TABLE  = 1, 
    	MEMORY = 2, 
    	GLOBAL = 3, 
    }
    Related Procedures With Parameters

    Func_Type ¶

    Func_Type :: struct {
    	params:  []Value_Type,
    	results: []Value_Type,
    }
     

    A WASM function signature: value-typed params and results.

    Related Procedures With Parameters

    Function ¶

    Function :: rexcode_ir.Function
    Related Procedures With Parameters

    Global ¶

    Global :: rexcode_ir.Global

    Id ¶

    Id :: rexcode_ir.Id
    Related Procedures With Parameters
    Related Constants

    Imm_Kind ¶

    Imm_Kind :: enum u8 {
    	NONE, 
    	BLOCKTYPE, // signed LEB128 s33 (negative valtype byte, or type index)
    	I32,       // signed LEB128 (i32.const)
    	I64,       // signed LEB128 (i64.const)
    	F32,       // 4 little-endian bytes
    	F64,       // 8 little-endian bytes
    	IDX,       // unsigned LEB128 index (space comes from the operand)
    	MEMARG,    // unsigned LEB128 align, then unsigned LEB128 offset
    	REFTYPE,   // single value-type byte (ref.null)
    	BR_TABLE,  // unsigned LEB128 count, that many label depths, default depth
    	ZERO_BYTE, // a single reserved 0x00 byte (memidx placeholders)
    	LANE,      // single byte lane index (SIMD extract/replace/load/store lane)
    	LANES16,   // sixteen raw bytes (v128.const value / i8x16.shuffle mask)
    }
     

    How one immediate field is laid down after the opcode.

    Import ¶

    Import :: struct {
    	kind:        External_Kind,
    	module_name: string,
    	field_name:  string,
    	index:       u32,
    }

    Index_Kind ¶

    Index_Kind :: enum u16 {
    	NONE, 
    	LOCAL, 
    	GLOBAL, 
    	FUNC, 
    	TYPE, 
    	TABLE, 
    	MEMORY, 
    	LABEL,  // br / br_if / br_table relative depth
    	DATA, 
    	ELEM, 
    }
     

    Which WASM index space an index immediate addresses. Drives the on-wire encoding, relocation-type selection, and printer annotation. Kept in ir.Operand.aux for every REF operand so the exact space always round-trips, even where the shared ir.Ref_Space has no dedicated member (TABLE/DATA/ELEM).

    Related Procedures With Parameters
    Related Procedures With Returns

    Memarg ¶

    Memarg :: struct #packed {
    	offset: u32,
    	align:  u32,
    }
     

    Load/store immediate: alignment hint (log2 bytes) + static offset.

    Related Procedures With Parameters
    Related Procedures With Returns

    Module ¶

    Module :: struct {
    	using base:      rexcode_ir.Module,
    	// functions, globals, symbols, dataflow (= .STACK), target
    	version:         u32,
    	// --- container sections (the WASM-specific data the ir core has no slot for) ---
    	func_types:      []Func_Type,
    	// the type section; ir.Function.signature indexes here
    	imports:         []Import,
    	exports:         []Export,
    	start:           i64,
    	// -1 if absent, else the start funcidx
    	customs:         []Custom_Section,
    	// --- side tables parallel to the ir core arrays ---
    	// A WASM function's declared locals (the code section's local groups), kept
    	// parallel to base.functions since ir.Function has no locals slot.
    	function_locals: [][]Value_Type,
    	// --- preserved binary framing (so nothing decoded is lost / is re-readable) ---
    	sections:        []Section,
    	// every section header, in file order
    	relocations:     []Reloc_Group,
    	// object-file relocations, grouped by target section
    	data:            []u8,
    }
     

    The WASM module -- the unit the verbs operate on. Embeds the ir core; adds the container metadata parsed from / emitted to the binary sections.

    After decode, base.functions spans the whole WASM function index space: imported functions occupy the low indices (their blocks are empty -- an import has no body) followed by the module-defined functions (each a single ir.Block whose ops are the decoded body). ir.Function.signature is the function's typeidx (an index into func_types, by convention), and its name is resolved from the export and "name" custom sections.

    Related Procedures With Parameters
    Related Procedures With Returns

    Opcode ¶

    Opcode :: enum u16 {
    	INVALID                             = 0, 
    	// ------------------------------------------------------------------ control
    	UNREACHABLE, 
    	NOP, 
    	BLOCK, 
    	LOOP, 
    	IF, 
    	ELSE, 
    	END, 
    	BR, 
    	BR_IF, 
    	BR_TABLE, 
    	RETURN, 
    	CALL, 
    	CALL_INDIRECT, 
    	RETURN_CALL, 
    	RETURN_CALL_INDIRECT, 
    	// -------------------------------------------------------------- parametric
    	DROP, 
    	SELECT, 
    	// ---------------------------------------------------------------- variable
    	LOCAL_GET, 
    	LOCAL_SET, 
    	LOCAL_TEE, 
    	GLOBAL_GET, 
    	GLOBAL_SET, 
    	// ------------------------------------------------------------------- memory
    	I32_LOAD, 
    	I64_LOAD, 
    	F32_LOAD, 
    	F64_LOAD, 
    	I32_LOAD8_S, 
    	I32_LOAD8_U, 
    	I32_LOAD16_S, 
    	I32_LOAD16_U, 
    	I64_LOAD8_S, 
    	I64_LOAD8_U, 
    	I64_LOAD16_S, 
    	I64_LOAD16_U, 
    	I64_LOAD32_S, 
    	I64_LOAD32_U, 
    	I32_STORE, 
    	I64_STORE, 
    	F32_STORE, 
    	F64_STORE, 
    	I32_STORE8, 
    	I32_STORE16, 
    	I64_STORE8, 
    	I64_STORE16, 
    	I64_STORE32, 
    	MEMORY_SIZE, 
    	MEMORY_GROW, 
    	// ----------------------------------------------------------------- numeric
    	I32_CONST, 
    	I64_CONST, 
    	F32_CONST, 
    	F64_CONST, 
    	// i32 comparison
    	I32_EQZ, 
    	I32_EQ, 
    	I32_NE, 
    	I32_LT_S, 
    	I32_LT_U, 
    	I32_GT_S, 
    	I32_GT_U, 
    	I32_LE_S, 
    	I32_LE_U, 
    	I32_GE_S, 
    	I32_GE_U, 
    	// i64 comparison
    	I64_EQZ, 
    	I64_EQ, 
    	I64_NE, 
    	I64_LT_S, 
    	I64_LT_U, 
    	I64_GT_S, 
    	I64_GT_U, 
    	I64_LE_S, 
    	I64_LE_U, 
    	I64_GE_S, 
    	I64_GE_U, 
    	// f32 comparison
    	F32_EQ, 
    	F32_NE, 
    	F32_LT, 
    	F32_GT, 
    	F32_LE, 
    	F32_GE, 
    	// f64 comparison
    	F64_EQ, 
    	F64_NE, 
    	F64_LT, 
    	F64_GT, 
    	F64_LE, 
    	F64_GE, 
    	// i32 arithmetic
    	I32_CLZ, 
    	I32_CTZ, 
    	I32_POPCNT, 
    	I32_ADD, 
    	I32_SUB, 
    	I32_MUL, 
    	I32_DIV_S, 
    	I32_DIV_U, 
    	I32_REM_S, 
    	I32_REM_U, 
    	I32_AND, 
    	I32_OR, 
    	I32_XOR, 
    	I32_SHL, 
    	I32_SHR_S, 
    	I32_SHR_U, 
    	I32_ROTL, 
    	I32_ROTR, 
    	// i64 arithmetic
    	I64_CLZ, 
    	I64_CTZ, 
    	I64_POPCNT, 
    	I64_ADD, 
    	I64_SUB, 
    	I64_MUL, 
    	I64_DIV_S, 
    	I64_DIV_U, 
    	I64_REM_S, 
    	I64_REM_U, 
    	I64_AND, 
    	I64_OR, 
    	I64_XOR, 
    	I64_SHL, 
    	I64_SHR_S, 
    	I64_SHR_U, 
    	I64_ROTL, 
    	I64_ROTR, 
    	// f32 arithmetic
    	F32_ABS, 
    	F32_NEG, 
    	F32_CEIL, 
    	F32_FLOOR, 
    	F32_TRUNC, 
    	F32_NEAREST, 
    	F32_SQRT, 
    	F32_ADD, 
    	F32_SUB, 
    	F32_MUL, 
    	F32_DIV, 
    	F32_MIN, 
    	F32_MAX, 
    	F32_COPYSIGN, 
    	// f64 arithmetic
    	F64_ABS, 
    	F64_NEG, 
    	F64_CEIL, 
    	F64_FLOOR, 
    	F64_TRUNC, 
    	F64_NEAREST, 
    	F64_SQRT, 
    	F64_ADD, 
    	F64_SUB, 
    	F64_MUL, 
    	F64_DIV, 
    	F64_MIN, 
    	F64_MAX, 
    	F64_COPYSIGN, 
    	// conversions
    	I32_WRAP_I64, 
    	I32_TRUNC_F32_S, 
    	I32_TRUNC_F32_U, 
    	I32_TRUNC_F64_S, 
    	I32_TRUNC_F64_U, 
    	I64_EXTEND_I32_S, 
    	I64_EXTEND_I32_U, 
    	I64_TRUNC_F32_S, 
    	I64_TRUNC_F32_U, 
    	I64_TRUNC_F64_S, 
    	I64_TRUNC_F64_U, 
    	F32_CONVERT_I32_S, 
    	F32_CONVERT_I32_U, 
    	F32_CONVERT_I64_S, 
    	F32_CONVERT_I64_U, 
    	F32_DEMOTE_F64, 
    	F64_CONVERT_I32_S, 
    	F64_CONVERT_I32_U, 
    	F64_CONVERT_I64_S, 
    	F64_CONVERT_I64_U, 
    	F64_PROMOTE_F32, 
    	I32_REINTERPRET_F32, 
    	I64_REINTERPRET_F64, 
    	F32_REINTERPRET_I32, 
    	F64_REINTERPRET_I64, 
    	// sign-extension operators (0xC0..0xC4)
    	I32_EXTEND8_S, 
    	I32_EXTEND16_S, 
    	I64_EXTEND8_S, 
    	I64_EXTEND16_S, 
    	I64_EXTEND32_S, 
    	// reference types
    	REF_NULL, 
    	REF_IS_NULL, 
    	REF_FUNC, 
    	// ------------------------------------------------------- 0xFC misc prefix
    	// saturating truncation
    	I32_TRUNC_SAT_F32_S, 
    	I32_TRUNC_SAT_F32_U, 
    	I32_TRUNC_SAT_F64_S, 
    	I32_TRUNC_SAT_F64_U, 
    	I64_TRUNC_SAT_F32_S, 
    	I64_TRUNC_SAT_F32_U, 
    	I64_TRUNC_SAT_F64_S, 
    	I64_TRUNC_SAT_F64_U, 
    	// bulk memory & table
    	MEMORY_INIT, 
    	DATA_DROP, 
    	MEMORY_COPY, 
    	MEMORY_FILL, 
    	TABLE_INIT, 
    	ELEM_DROP, 
    	TABLE_COPY, 
    	TABLE_GROW, 
    	TABLE_SIZE, 
    	TABLE_FILL, 
    	// ----------------------------------------------- 0xFD SIMD (v128) prefix
    	V128_LOAD, 
    	V128_LOAD8X8_S, 
    	V128_LOAD8X8_U, 
    	V128_LOAD16X4_S, 
    	V128_LOAD16X4_U, 
    	V128_LOAD32X2_S, 
    	V128_LOAD32X2_U, 
    	V128_LOAD8_SPLAT, 
    	V128_LOAD16_SPLAT, 
    	V128_LOAD32_SPLAT, 
    	V128_LOAD64_SPLAT, 
    	V128_STORE, 
    	V128_CONST, 
    	I8X16_SHUFFLE, 
    	I8X16_SWIZZLE, 
    	I8X16_SPLAT, 
    	I16X8_SPLAT, 
    	I32X4_SPLAT, 
    	I64X2_SPLAT, 
    	F32X4_SPLAT, 
    	F64X2_SPLAT, 
    	I8X16_EXTRACT_LANE_S, 
    	I8X16_EXTRACT_LANE_U, 
    	I8X16_REPLACE_LANE, 
    	I16X8_EXTRACT_LANE_S, 
    	I16X8_EXTRACT_LANE_U, 
    	I16X8_REPLACE_LANE, 
    	I32X4_EXTRACT_LANE, 
    	I32X4_REPLACE_LANE, 
    	I64X2_EXTRACT_LANE, 
    	I64X2_REPLACE_LANE, 
    	F32X4_EXTRACT_LANE, 
    	F32X4_REPLACE_LANE, 
    	F64X2_EXTRACT_LANE, 
    	F64X2_REPLACE_LANE, 
    	I8X16_EQ, 
    	I8X16_NE, 
    	I8X16_LT_S, 
    	I8X16_LT_U, 
    	I8X16_GT_S, 
    	I8X16_GT_U, 
    	I8X16_LE_S, 
    	I8X16_LE_U, 
    	I8X16_GE_S, 
    	I8X16_GE_U, 
    	I16X8_EQ, 
    	I16X8_NE, 
    	I16X8_LT_S, 
    	I16X8_LT_U, 
    	I16X8_GT_S, 
    	I16X8_GT_U, 
    	I16X8_LE_S, 
    	I16X8_LE_U, 
    	I16X8_GE_S, 
    	I16X8_GE_U, 
    	I32X4_EQ, 
    	I32X4_NE, 
    	I32X4_LT_S, 
    	I32X4_LT_U, 
    	I32X4_GT_S, 
    	I32X4_GT_U, 
    	I32X4_LE_S, 
    	I32X4_LE_U, 
    	I32X4_GE_S, 
    	I32X4_GE_U, 
    	F32X4_EQ, 
    	F32X4_NE, 
    	F32X4_LT, 
    	F32X4_GT, 
    	F32X4_LE, 
    	F32X4_GE, 
    	F64X2_EQ, 
    	F64X2_NE, 
    	F64X2_LT, 
    	F64X2_GT, 
    	F64X2_LE, 
    	F64X2_GE, 
    	V128_NOT, 
    	V128_AND, 
    	V128_ANDNOT, 
    	V128_OR, 
    	V128_XOR, 
    	V128_BITSELECT, 
    	V128_ANY_TRUE, 
    	V128_LOAD8_LANE, 
    	V128_LOAD16_LANE, 
    	V128_LOAD32_LANE, 
    	V128_LOAD64_LANE, 
    	V128_STORE8_LANE, 
    	V128_STORE16_LANE, 
    	V128_STORE32_LANE, 
    	V128_STORE64_LANE, 
    	V128_LOAD32_ZERO, 
    	V128_LOAD64_ZERO, 
    	F32X4_DEMOTE_F64X2_ZERO, 
    	F64X2_PROMOTE_LOW_F32X4, 
    	I8X16_ABS, 
    	I8X16_NEG, 
    	I8X16_POPCNT, 
    	I8X16_ALL_TRUE, 
    	I8X16_BITMASK, 
    	I8X16_NARROW_I16X8_S, 
    	I8X16_NARROW_I16X8_U, 
    	F32X4_CEIL, 
    	F32X4_FLOOR, 
    	F32X4_TRUNC, 
    	F32X4_NEAREST, 
    	I8X16_SHL, 
    	I8X16_SHR_S, 
    	I8X16_SHR_U, 
    	I8X16_ADD, 
    	I8X16_ADD_SAT_S, 
    	I8X16_ADD_SAT_U, 
    	I8X16_SUB, 
    	I8X16_SUB_SAT_S, 
    	I8X16_SUB_SAT_U, 
    	F64X2_CEIL, 
    	F64X2_FLOOR, 
    	I8X16_MIN_S, 
    	I8X16_MIN_U, 
    	I8X16_MAX_S, 
    	I8X16_MAX_U, 
    	F64X2_TRUNC, 
    	I8X16_AVGR_U, 
    	I16X8_EXTADD_PAIRWISE_I8X16_S, 
    	I16X8_EXTADD_PAIRWISE_I8X16_U, 
    	I32X4_EXTADD_PAIRWISE_I16X8_S, 
    	I32X4_EXTADD_PAIRWISE_I16X8_U, 
    	I16X8_ABS, 
    	I16X8_NEG, 
    	I16X8_Q15MULR_SAT_S, 
    	I16X8_ALL_TRUE, 
    	I16X8_BITMASK, 
    	I16X8_NARROW_I32X4_S, 
    	I16X8_NARROW_I32X4_U, 
    	I16X8_EXTEND_LOW_I8X16_S, 
    	I16X8_EXTEND_HIGH_I8X16_S, 
    	I16X8_EXTEND_LOW_I8X16_U, 
    	I16X8_EXTEND_HIGH_I8X16_U, 
    	I16X8_SHL, 
    	I16X8_SHR_S, 
    	I16X8_SHR_U, 
    	I16X8_ADD, 
    	I16X8_ADD_SAT_S, 
    	I16X8_ADD_SAT_U, 
    	I16X8_SUB, 
    	I16X8_SUB_SAT_S, 
    	I16X8_SUB_SAT_U, 
    	F64X2_NEAREST, 
    	I16X8_MUL, 
    	I16X8_MIN_S, 
    	I16X8_MIN_U, 
    	I16X8_MAX_S, 
    	I16X8_MAX_U, 
    	I16X8_AVGR_U, 
    	I16X8_EXTMUL_LOW_I8X16_S, 
    	I16X8_EXTMUL_HIGH_I8X16_S, 
    	I16X8_EXTMUL_LOW_I8X16_U, 
    	I16X8_EXTMUL_HIGH_I8X16_U, 
    	I32X4_ABS, 
    	I32X4_NEG, 
    	I32X4_ALL_TRUE, 
    	I32X4_BITMASK, 
    	I32X4_EXTEND_LOW_I16X8_S, 
    	I32X4_EXTEND_HIGH_I16X8_S, 
    	I32X4_EXTEND_LOW_I16X8_U, 
    	I32X4_EXTEND_HIGH_I16X8_U, 
    	I32X4_SHL, 
    	I32X4_SHR_S, 
    	I32X4_SHR_U, 
    	I32X4_ADD, 
    	I32X4_SUB, 
    	I32X4_MUL, 
    	I32X4_MIN_S, 
    	I32X4_MIN_U, 
    	I32X4_MAX_S, 
    	I32X4_MAX_U, 
    	I32X4_DOT_I16X8_S, 
    	I32X4_EXTMUL_LOW_I16X8_S, 
    	I32X4_EXTMUL_HIGH_I16X8_S, 
    	I32X4_EXTMUL_LOW_I16X8_U, 
    	I32X4_EXTMUL_HIGH_I16X8_U, 
    	I64X2_ABS, 
    	I64X2_NEG, 
    	I64X2_ALL_TRUE, 
    	I64X2_BITMASK, 
    	I64X2_EXTEND_LOW_I32X4_S, 
    	I64X2_EXTEND_HIGH_I32X4_S, 
    	I64X2_EXTEND_LOW_I32X4_U, 
    	I64X2_EXTEND_HIGH_I32X4_U, 
    	I64X2_SHL, 
    	I64X2_SHR_S, 
    	I64X2_SHR_U, 
    	I64X2_ADD, 
    	I64X2_SUB, 
    	I64X2_MUL, 
    	I64X2_EQ, 
    	I64X2_NE, 
    	I64X2_LT_S, 
    	I64X2_GT_S, 
    	I64X2_LE_S, 
    	I64X2_GE_S, 
    	I64X2_EXTMUL_LOW_I32X4_S, 
    	I64X2_EXTMUL_HIGH_I32X4_S, 
    	I64X2_EXTMUL_LOW_I32X4_U, 
    	I64X2_EXTMUL_HIGH_I32X4_U, 
    	F32X4_ABS, 
    	F32X4_NEG, 
    	F32X4_SQRT, 
    	F32X4_ADD, 
    	F32X4_SUB, 
    	F32X4_MUL, 
    	F32X4_DIV, 
    	F32X4_MIN, 
    	F32X4_MAX, 
    	F32X4_PMIN, 
    	F32X4_PMAX, 
    	F64X2_ABS, 
    	F64X2_NEG, 
    	F64X2_SQRT, 
    	F64X2_ADD, 
    	F64X2_SUB, 
    	F64X2_MUL, 
    	F64X2_DIV, 
    	F64X2_MIN, 
    	F64X2_MAX, 
    	F64X2_PMIN, 
    	F64X2_PMAX, 
    	I32X4_TRUNC_SAT_F32X4_S, 
    	I32X4_TRUNC_SAT_F32X4_U, 
    	F32X4_CONVERT_I32X4_S, 
    	F32X4_CONVERT_I32X4_U, 
    	I32X4_TRUNC_SAT_F64X2_S_ZERO, 
    	I32X4_TRUNC_SAT_F64X2_U_ZERO, 
    	F64X2_CONVERT_LOW_I32X4_S, 
    	F64X2_CONVERT_LOW_I32X4_U, 
    	I8X16_RELAXED_SWIZZLE, 
    	I32X4_RELAXED_TRUNC_F32X4_S, 
    	I32X4_RELAXED_TRUNC_F32X4_U, 
    	I32X4_RELAXED_TRUNC_F64X2_S_ZERO, 
    	I32X4_RELAXED_TRUNC_F64X2_U_ZERO, 
    	F32X4_RELAXED_MADD, 
    	F32X4_RELAXED_NMADD, 
    	F64X2_RELAXED_MADD, 
    	F64X2_RELAXED_NMADD, 
    	I8X16_RELAXED_LANESELECT, 
    	I16X8_RELAXED_LANESELECT, 
    	I32X4_RELAXED_LANESELECT, 
    	I64X2_RELAXED_LANESELECT, 
    	F32X4_RELAXED_MIN, 
    	F32X4_RELAXED_MAX, 
    	F64X2_RELAXED_MIN, 
    	F64X2_RELAXED_MAX, 
    	I16X8_RELAXED_Q15MULR_S, 
    	I16X8_RELAXED_DOT_I8X16_I7X16_S, 
    	I32X4_RELAXED_DOT_I8X16_I7X16_ADD_S, 
    	// ------------------------------------------ 0xFE threads / atomics prefix
    	MEMORY_ATOMIC_NOTIFY, 
    	MEMORY_ATOMIC_WAIT32, 
    	MEMORY_ATOMIC_WAIT64, 
    	ATOMIC_FENCE, 
    	I32_ATOMIC_LOAD, 
    	I64_ATOMIC_LOAD, 
    	I32_ATOMIC_LOAD8_U, 
    	I32_ATOMIC_LOAD16_U, 
    	I64_ATOMIC_LOAD8_U, 
    	I64_ATOMIC_LOAD16_U, 
    	I64_ATOMIC_LOAD32_U, 
    	I32_ATOMIC_STORE, 
    	I64_ATOMIC_STORE, 
    	I32_ATOMIC_STORE8, 
    	I32_ATOMIC_STORE16, 
    	I64_ATOMIC_STORE8, 
    	I64_ATOMIC_STORE16, 
    	I64_ATOMIC_STORE32, 
    	I32_ATOMIC_RMW_ADD, 
    	I64_ATOMIC_RMW_ADD, 
    	I32_ATOMIC_RMW8_ADD_U, 
    	I32_ATOMIC_RMW16_ADD_U, 
    	I64_ATOMIC_RMW8_ADD_U, 
    	I64_ATOMIC_RMW16_ADD_U, 
    	I64_ATOMIC_RMW32_ADD_U, 
    	I32_ATOMIC_RMW_SUB, 
    	I64_ATOMIC_RMW_SUB, 
    	I32_ATOMIC_RMW8_SUB_U, 
    	I32_ATOMIC_RMW16_SUB_U, 
    	I64_ATOMIC_RMW8_SUB_U, 
    	I64_ATOMIC_RMW16_SUB_U, 
    	I64_ATOMIC_RMW32_SUB_U, 
    	I32_ATOMIC_RMW_AND, 
    	I64_ATOMIC_RMW_AND, 
    	I32_ATOMIC_RMW8_AND_U, 
    	I32_ATOMIC_RMW16_AND_U, 
    	I64_ATOMIC_RMW8_AND_U, 
    	I64_ATOMIC_RMW16_AND_U, 
    	I64_ATOMIC_RMW32_AND_U, 
    	I32_ATOMIC_RMW_OR, 
    	I64_ATOMIC_RMW_OR, 
    	I32_ATOMIC_RMW8_OR_U, 
    	I32_ATOMIC_RMW16_OR_U, 
    	I64_ATOMIC_RMW8_OR_U, 
    	I64_ATOMIC_RMW16_OR_U, 
    	I64_ATOMIC_RMW32_OR_U, 
    	I32_ATOMIC_RMW_XOR, 
    	I64_ATOMIC_RMW_XOR, 
    	I32_ATOMIC_RMW8_XOR_U, 
    	I32_ATOMIC_RMW16_XOR_U, 
    	I64_ATOMIC_RMW8_XOR_U, 
    	I64_ATOMIC_RMW16_XOR_U, 
    	I64_ATOMIC_RMW32_XOR_U, 
    	I32_ATOMIC_RMW_XCHG, 
    	I64_ATOMIC_RMW_XCHG, 
    	I32_ATOMIC_RMW8_XCHG_U, 
    	I32_ATOMIC_RMW16_XCHG_U, 
    	I64_ATOMIC_RMW8_XCHG_U, 
    	I64_ATOMIC_RMW16_XCHG_U, 
    	I64_ATOMIC_RMW32_XCHG_U, 
    	I32_ATOMIC_RMW_CMPXCHG, 
    	I64_ATOMIC_RMW_CMPXCHG, 
    	I32_ATOMIC_RMW8_CMPXCHG_U, 
    	I32_ATOMIC_RMW16_CMPXCHG_U, 
    	I64_ATOMIC_RMW8_CMPXCHG_U, 
    	I64_ATOMIC_RMW16_CMPXCHG_U, 
    	I64_ATOMIC_RMW32_CMPXCHG_U, 
    }
    Related Procedures With Parameters

    Operand_Kind ¶

    Operand_Kind :: rexcode_ir.Operand_Kind

    Operation ¶

    Operation :: rexcode_ir.Operation
    Related Procedures With Parameters
    Related Procedures With Returns

    Operation_Flags ¶

    Operation_Flags :: rexcode_ir.Operation_Flags
    Related Procedures With Returns

    Parse_Error ¶

    Parse_Error :: enum u8 {
    	NONE          = 0, 
    	TRUNCATED,         // read past the end of the buffer
    	BAD_MAGIC,         // not a `\0asm` module
    	BAD_TYPE_FORM,     // a functype did not start with 0x60
    	BAD_SECTION,       // section contents extend past the buffer
    	BAD_ULEB,          // a ULEB did not terminate within 10 bytes
    }
    Related Procedures With Returns
    Print_Options :: rexcode_ir.Print_Options
    Related Procedures With Parameters
    Related Constants
    Print_Result :: rexcode_ir.Print_Result

    Reader ¶

    Reader :: struct {
    	data: []u8,
    	off:  u32,
    }

    Reader_Error ¶

    Reader_Error :: union {
    	Parse_Error, 
    	runtime.Allocator_Error, 
    }
    Related Procedures With Returns

    Ref ¶

    Ref :: rexcode_ir.Ref

    Ref_Space ¶

    Ref_Space :: rexcode_ir.Ref_Space
    Related Procedures With Returns

    Reloc_Group ¶

    Reloc_Group :: struct {
    	target_section: Section_Id,
    	relocs:         []Relocation,
    }
     

    A set of relocations that apply to one section (parsed from a reloc.<name> custom section). Grouped by the section they target so the decoder can hand the CODE-section group to each function body it decodes.

    Relocation ¶

    Relocation :: struct #packed {
    	offset:   u32,
    	// byte offset of the relocatable field
    	label_id: u32,
    	// symbol / target label id
    	addend:   i32,
    	type:     Relocation_Type,
    	size:     u8,
    	// bytes occupied by the field (5 for LEB, 4 for I32)
    	inst_idx: u16,
    }

    Relocation_Type ¶

    Relocation_Type :: enum u8 {
    	NONE               = 0, 
    	FUNCTION_INDEX_LEB,     // funcidx, 5-byte ULEB (call, ref.func)
    	TABLE_INDEX_SLEB,       // 5-byte SLEB table element index
    	TABLE_INDEX_I32,        // 4-byte LE table element index
    	MEMORY_ADDR_LEB,        // linear-memory address, 5-byte ULEB
    	MEMORY_ADDR_SLEB,       // linear-memory address, 5-byte SLEB
    	MEMORY_ADDR_I32,        // linear-memory address, 4-byte LE
    	TYPE_INDEX_LEB,         // typeidx, 5-byte ULEB (call_indirect)
    	GLOBAL_INDEX_LEB,       // globalidx, 5-byte ULEB
    	TABLE_NUMBER_LEB,       // tableidx, 5-byte ULEB
    }
    Related Procedures With Parameters
    Related Procedures With Returns

    Result ¶

    Result :: rexcode_ir.Result
    Related Procedures With Returns

    Section ¶

    Section :: struct {
    	id:     Section_Id,
    	offset: u32,
    	// file offset of the section contents
    	size:   u32,
    	// contents length in bytes
    	count:  u32,
    	// declared element count (0 for CUSTOM / START)
    	name:   string,
    }
     

    A parsed binary section header: where its contents live in the file and how many entries it declares. Kept so sections the ir core does not model structurally (table/memory/global/element/data) stay re-readable from data.

    Section_Id ¶

    Section_Id :: enum u8 {
    	// Binary section ids (WebAssembly core spec §5.5.2).
    	CUSTOM     = 0, 
    	TYPE       = 1, 
    	IMPORT     = 2, 
    	FUNCTION   = 3, 
    	TABLE      = 4, 
    	MEMORY     = 5, 
    	GLOBAL     = 6, 
    	EXPORT     = 7, 
    	START      = 8, 
    	ELEMENT    = 9, 
    	CODE       = 10, 
    	DATA       = 11, 
    	DATA_COUNT = 12, 
    }
    Related Procedures With Parameters

    Symbol_Table ¶

    Symbol_Table :: rexcode_ir.Symbol_Table

    Token ¶

    Token :: rexcode_ir.Token

    Token_Kind ¶

    Token_Kind :: rexcode_ir.Token_Kind

    Type ¶

    Type :: rexcode_ir.Type

    Type_Kind ¶

    Type_Kind :: rexcode_ir.Type_Kind

    Type_Ref ¶

    Type_Ref :: rexcode_ir.Type_Ref
    Related Constants

    Value_Type ¶

    Value_Type :: enum u8 {
    	I32       = 127, 
    	I64       = 126, 
    	F32       = 125, 
    	F64       = 124, 
    	V128      = 123, 
    	FUNCREF   = 112, 
    	EXTERNREF = 111, 
    }
    Related Procedures With Parameters

    WAT_Options ¶

    WAT_Options :: struct {
    	indent_unit: string,
    }
    Related Procedures With Parameters
    Related Constants

    Constants

    DECODE_ATOMIC_COUNT ¶

    DECODE_ATOMIC_COUNT :: 0x4F
     

    0xFE sub-opcodes (0..=0x4E)

    DECODE_MAIN_COUNT ¶

    DECODE_MAIN_COUNT :: 256
     

    (0..=0xD2)

    DECODE_MISC_COUNT ¶

    DECODE_MISC_COUNT :: 32
     

    0xFC sub-opcodes (0..=17)

    DECODE_SIMD_COUNT ¶

    DECODE_SIMD_COUNT :: 0x114
     

    0xFD sub-opcodes (0..=0x113)

    DEFAULT_PRINT_OPTIONS ¶

    DEFAULT_PRINT_OPTIONS: rexcode_ir.Print_Options : ir.DEFAULT_PRINT_OPTIONS

    DEFAULT_WAT_OPTIONS ¶

    DEFAULT_WAT_OPTIONS :: WAT_Options{indent_unit = "  "}

    FLAG_SYMBOLIC ¶

    FLAG_SYMBOLIC :: u32(1)
     

    ir.Operand.flags bit: a REF whose index is a symbol id the linker fixes up (emitted as a fixed-width 5-byte LEB placeholder plus a Relocation).

    ID_NONE ¶

    ID_NONE: rexcode_ir.Id : ir.ID_NONE

    MAX_OPCODE_SIZE ¶

    MAX_OPCODE_SIZE :: 3
     

    prefix byte + two-byte unsigned-LEB sub-opcode (SIMD reaches 0x113)

    PREFIX_ATOM ¶

    PREFIX_ATOM :: u8(0xFE)
     

    threads / atomics

    PREFIX_MISC ¶

    PREFIX_MISC :: u8(0xFC)
     

    saturating truncation, bulk memory / table

    PREFIX_NONE ¶

    PREFIX_NONE :: u8(0x00)
     

    Opcode-space prefix bytes. A prefixed opcode is prefix byte then an unsigned LEB128 sub-opcode (SIMD reaches 0x113, so the sub-opcode can be two bytes).

    PREFIX_SIMD ¶

    PREFIX_SIMD :: u8(0xFD)
     

    vector (v128)

    TYPE_NONE ¶

    TYPE_NONE: rexcode_ir.Type_Ref : ir.TYPE_NONE

    WASM_MAGIC ¶

    WASM_MAGIC :: u32(0x6d73_6100)
     

    The four bytes that begin every module: "\0asm" as a little-endian u32.

    WASM_VERSION ¶

    WASM_VERSION :: u32(1)

    Variables

    DECODE_ATOMIC ¶

    @(rodata)
    DECODE_ATOMIC: [79]Opcode = …

    DECODE_MAIN ¶

    @(rodata)
    DECODE_MAIN: [256]Opcode = …

    DECODE_MISC ¶

    @(rodata)
    DECODE_MISC: [32]Opcode = …

    DECODE_SIMD ¶

    @(rodata)
    DECODE_SIMD: [276]Opcode = …

    ENCODING_TABLE ¶

    @(rodata)
    ENCODING_TABLE: [Opcode]Encoding = …

    MNEMONIC_NAMES ¶

    @(rodata)
    MNEMONIC_NAMES: [Opcode]string = …

    Procedures

    append_uleb ¶

    append_uleb :: proc(b: ^[dynamic]u8, value: u64) {…}
     

    Unsigned LEB128, appended to a [dynamic]u8

    append_uleb_name ¶

    append_uleb_name :: proc(b: ^[dynamic]u8, s: string) {…}

    aprint ¶

    aprint :: proc(ops: []rexcode_ir.Operation, options: ^rexcode_ir.Print_Options = nil, allocator := context.allocator) -> string {…}
     

    aprint: caller-allocated string of an operation stream.

    aprint_wat ¶

    aprint_wat :: proc(m: Module, opts: WAT_Options = DEFAULT_WAT_OPTIONS, allocator := context.allocator) -> string {…}
     

    Allocates the result with allocator (caller owns it).

    builder_make ¶

    builder_make :: proc(allocator := context.allocator) -> Builder {…}

    count_import_kind ¶

    count_import_kind :: proc "contextless" (m: Module, k: External_Kind) -> u32 {…}

    decode ¶

    decode :: proc(data: []u8, m: ^Module, errors: ^[dynamic]rexcode_ir.Error, allocator := context.allocator) -> (byte_count: u32, ok: bool) {…}
     

    decode: parse a whole .wasm binary module into m. Returns the number of bytes consumed (the file length on success) and whether it fully succeeded.

    decode_expr ¶

    decode_expr :: proc(data: []u8, m: ^Module, errors: ^[dynamic]rexcode_ir.Error, allocator := context.allocator) -> (byte_count: u32, ok: bool) {…}
     

    decode_expr: parse a bare WASM expr byte stream (one instruction stream, no container) into a single-function, single-block Module (dataflow = .STACK). The full-container module verb is decode (parse.odin); the reusable stream-level decoder both share is decode_ops.

    decode_one ¶

    decode_one :: proc(data: []u8, relocs: []Relocation, pc: u32, allocator: runtime.Allocator) -> (op: rexcode_ir.Operation, next: u32, ok: bool) {…}

    decode_ops ¶

    decode_ops :: proc(data: []u8, relocs: []Relocation, errors: ^[dynamic]rexcode_ir.Error, allocator := context.allocator) -> (ops: []rexcode_ir.Operation, byte_count: u32, ok: bool) {…}
     

    decode_ops: the reusable instruction-stream decoder. relocs (may be nil) are the input relocations to re-attach to symbolic index fields.

    emit ¶

    emit :: proc(b: ^Builder, opcode: Opcode, operands: ..rexcode_ir.Operand) {…}
     

    Append an operation with the given operands, allocating their backing.

    emit_block ¶

    emit_block :: proc(b: ^Builder, bt: Block_Type = .EMPTY) {…}

    emit_br ¶

    emit_br :: proc(b: ^Builder, depth: u32) {…}

    emit_br_if ¶

    emit_br_if :: proc(b: ^Builder, depth: u32) {…}

    emit_br_table ¶

    emit_br_table :: proc(b: ^Builder, targets: []u32, default_depth: u32) {…}
     

    br_table: operands are [default, case0, case1, ...], every entry a label depth.

    emit_call ¶

    emit_call :: proc(b: ^Builder, funcidx: u32) {…}

    emit_call_indirect ¶

    emit_call_indirect :: proc(b: ^Builder, typeidx: u32, tableidx: u32 = 0) {…}

    emit_else ¶

    emit_else :: proc(b: ^Builder) {…}

    emit_end ¶

    emit_end :: proc(b: ^Builder) {…}

    emit_f32 ¶

    emit_f32 :: proc(b: ^Builder, v: f32) {…}

    emit_f64 ¶

    emit_f64 :: proc(b: ^Builder, v: f64) {…}

    emit_global_get ¶

    emit_global_get :: proc(b: ^Builder, n: u32) {…}

    emit_global_set ¶

    emit_global_set :: proc(b: ^Builder, n: u32) {…}

    emit_i32 ¶

    emit_i32 :: proc(b: ^Builder, v: i32) {…}

    emit_i64 ¶

    emit_i64 :: proc(b: ^Builder, v: i64) {…}

    emit_if ¶

    emit_if :: proc(b: ^Builder, bt: Block_Type = .EMPTY) {…}

    emit_load ¶

    emit_load :: proc(b: ^Builder, opcode: Opcode, ma: Memarg) {…}

    emit_local_get ¶

    emit_local_get :: proc(b: ^Builder, n: u32) {…}

    emit_local_set ¶

    emit_local_set :: proc(b: ^Builder, n: u32) {…}

    emit_local_tee ¶

    emit_local_tee :: proc(b: ^Builder, n: u32) {…}

    emit_loop ¶

    emit_loop :: proc(b: ^Builder, bt: Block_Type = .EMPTY) {…}

    emit_none ¶

    emit_none :: proc(b: ^Builder, opcode: Opcode) {…}

    emit_return ¶

    emit_return :: proc(b: ^Builder) {…}

    emit_shuffle ¶

    emit_shuffle :: proc(b: ^Builder, lanes: [16]u8) {…}

    emit_store ¶

    emit_store :: proc(b: ^Builder, opcode: Opcode, ma: Memarg) {…}

    emit_unreachable ¶

    emit_unreachable :: proc(b: ^Builder) {…}

    emit_v128_const ¶

    emit_v128_const :: proc(b: ^Builder, value: [16]u8) {…}
     

    v128.const / i8x16.shuffle: the 16-byte immediate as two ATTRIBUTE halves.

    encode ¶

    encode :: proc(m: Module, code: []u8, relocs: ^[dynamic]Relocation, errors: ^[dynamic]rexcode_ir.Error) -> (byte_count: u32, ok: bool) {…}
     

    encode: serialize the module m into code, producing a complete .wasm binary. Returns the number of bytes written and whether it fully succeeded. Size code with encode_size(m) (or any larger buffer).

    encode_max_code_size ¶

    encode_max_code_size :: proc "contextless" (n: int) -> int {…}

    encode_max_relocation_count ¶

    encode_max_relocation_count :: proc "contextless" (n: int) -> int {…}

    encode_operation ¶

    encode_operation :: proc(
    	op:       ^rexcode_ir.Operation, 
    	pc:       u32, 
    	op_index: u16, 
    	code:     []u8, 
    	relocs:   ^[dynamic]Relocation, 
    	errors:   ^[dynamic]rexcode_ir.Error, 
    ) -> (size: u32, ok: bool) {…}

    encode_ops ¶

    encode_ops :: proc(ops: []rexcode_ir.Operation, code: []u8, relocs: ^[dynamic]Relocation, errors: ^[dynamic]rexcode_ir.Error) -> (byte_count: u32, ok: bool) {…}
     

    encode_ops: the reusable instruction-stream encoder (a WASM expr).

    encode_size ¶

    encode_size :: proc(m: Module) -> u32 {…}
     

    encode_size: the exact byte length encode(m, ...) will produce (a dry run, so callers can size the output buffer precisely). Uses the temp allocator.

    external_kind_name ¶

    external_kind_name :: proc "contextless" (k: External_Kind) -> string {…}

    fprint_wat ¶

    fprint_wat :: proc(w: io.Stream, m: Module, opts: WAT_Options = DEFAULT_WAT_OPTIONS) {…}

    make_module ¶

    make_module :: proc "contextless" () -> Module {…}
     

    A freshly-made WASM module declares STACK dataflow so the shared verbs and the printer pick the stack-machine path (no SSA results, no value refs).

    memarg ¶

    memarg :: proc "contextless" (align, offset: u32) -> Memarg {…}

    mnemonic_to_string ¶

    mnemonic_to_string :: proc(op: Opcode, uppercase: bool = false, allocator := context.temp_allocator) -> string {…}

    module_name ¶

    module_name :: proc "contextless" (m: Module) -> (string, bool) {…}

    no_result ¶

    no_result :: proc "contextless" () -> rexcode_ir.Result {…}
     

    The stack-IR result: WASM defines no SSA value, so every operation's result is empty. (Kept as a helper so the intent is explicit at every call site.)

    op_block_typeidx ¶

    op_block_typeidx :: proc "contextless" (type_index: u32) -> rexcode_ir.Operand {…}

    op_blocktype ¶

    op_blocktype :: proc "contextless" (bt: Block_Type) -> rexcode_ir.Operand {…}

    op_data ¶

    op_data :: proc "contextless" (n: u32) -> rexcode_ir.Operand {…}

    op_elem ¶

    op_elem :: proc "contextless" (n: u32) -> rexcode_ir.Operand {…}

    op_f32 ¶

    op_f32 :: proc "contextless" (v: f32) -> rexcode_ir.Operand {…}

    op_f64 ¶

    op_f64 :: proc "contextless" (v: f64) -> rexcode_ir.Operand {…}

    op_flags_for ¶

    op_flags_for :: proc "contextless" (opcode: Opcode) -> rexcode_ir.Operation_Flags {…}
     

    Operation flags derived from the opcode's ENCODING_TABLE form, plus the terminator bit for the ops that end a stack-IR region.

    op_func ¶

    op_func :: proc "contextless" (n: u32) -> rexcode_ir.Operand {…}

    op_global ¶

    op_global :: proc "contextless" (n: u32) -> rexcode_ir.Operand {…}

    op_i32 ¶

    op_i32 :: proc "contextless" (v: i32) -> rexcode_ir.Operand {…}

    op_i64 ¶

    op_i64 :: proc "contextless" (v: i64) -> rexcode_ir.Operand {…}

    op_label ¶

    op_label :: proc "contextless" (label_id: u32) -> rexcode_ir.Operand {…}
     

    Symbolic function reference: emitted as a relocatable funcidx placeholder.

    op_labelidx ¶

    op_labelidx :: proc "contextless" (depth: u32) -> rexcode_ir.Operand {…}
     

    Branch label depth (number of enclosing blocks to break out of).

    op_lane ¶

    op_lane :: proc "contextless" (n: u8) -> rexcode_ir.Operand {…}

    op_local ¶

    op_local :: proc "contextless" (n: u32) -> rexcode_ir.Operand {…}

    op_memarg ¶

    op_memarg :: proc "contextless" (ma: Memarg) -> rexcode_ir.Operand {…}

    op_memory ¶

    op_memory :: proc "contextless" (n: u32) -> rexcode_ir.Operand {…}

    op_reftype ¶

    op_reftype :: proc "contextless" (t: Value_Type) -> rexcode_ir.Operand {…}

    op_table ¶

    op_table :: proc "contextless" (n: u32) -> rexcode_ir.Operand {…}

    op_typeidx ¶

    op_typeidx :: proc "contextless" (n: u32) -> rexcode_ir.Operand {…}

    op_v128 ¶

    op_v128 :: proc "contextless" (bytes: [16]u8) -> (lo, hi: rexcode_ir.Operand) {…}
     

    A 16-byte v128 literal (v128.const) or shuffle mask (i8x16.shuffle), as two little-endian 64-bit ATTRIBUTE halves.

    op_wasm_index ¶

    op_wasm_index :: proc "contextless" (kind: Index_Kind, value: u32, symbolic: bool = false) -> rexcode_ir.Operand {…}

    opbuf ¶

    opbuf :: proc(b: ^Builder, ops: ..rexcode_ir.Operand) -> []rexcode_ir.Operand {…}
     

    Stable per-operation operand backing.

    operand_attr ¶

    operand_attr :: proc "contextless" (o: rexcode_ir.Operand) -> Attr {…}

    operand_index ¶

    operand_index :: proc "contextless" (o: rexcode_ir.Operand) -> u32 {…}

    operand_index_kind ¶

    operand_index_kind :: proc "contextless" (o: rexcode_ir.Operand) -> Index_Kind {…}

    operand_memarg ¶

    operand_memarg :: proc "contextless" (o: rexcode_ir.Operand) -> Memarg {…}

    operand_symbolic ¶

    operand_symbolic :: proc "contextless" (o: rexcode_ir.Operand) -> bool {…}

    operand_v128 ¶

    operand_v128 :: proc "contextless" (lo, hi: rexcode_ir.Operand) -> (bytes: [16]u8) {…}
     

    v128 bytes from a lo/hi ATTRIBUTE pair.

    operation ¶

    operation :: proc "contextless" (opcode: Opcode, operands: []rexcode_ir.Operand = nil) -> rexcode_ir.Operation {…}
     

    Build an Operation over an already-owned operand slice (no allocation).

    parse_container ¶

    parse_container :: proc(data: []u8, m: ^Module, errors: ^[dynamic]rexcode_ir.Error, allocator: runtime.Allocator) -> Reader_Error {…}

    print ¶

    print :: proc(m: Module, sb: ^strings.Builder, options: ^rexcode_ir.Print_Options = nil) {…}
     

    print: disassemble m into the caller-owned builder sb. The canonical ir print verb; sbprint / tprint below are thin convenience sinks over it.

    print_wat :: proc(m: Module, file: ^os.File, opts: WAT_Options = DEFAULT_WAT_OPTIONS) {…}

    read_sleb ¶

    read_sleb :: proc "contextless" (data: []u8, offset: ^u32) -> (value: i64, ok: bool) {…}
     

    Read signed LEB128 starting at *offset; advances it.

    read_u32_block ¶

    read_u32_block :: proc "contextless" (data: []u8, offset: ^u32) -> (u32, bool) {…}

    read_u64_block ¶

    read_u64_block :: proc "contextless" (data: []u8, offset: ^u32) -> (u64, bool) {…}

    read_uleb ¶

    read_uleb :: proc "contextless" (data: []u8, offset: ^u32) -> (value: u64, ok: bool) {…}
     

    Read unsigned LEB128 starting at *offset; advances it. ok is false on truncation. Reads at most max bytes (10 covers u64).

    ref_space_for ¶

    ref_space_for :: proc "contextless" (k: Index_Kind) -> rexcode_ir.Ref_Space {…}
     

    Best-fit shared space for a WASM index space (used for printer annotation and generic ir tooling). The exact Index_Kind still lives in aux, so spaces the shared enum lacks (TABLE/DATA/ELEM) map to NONE here without loss.

    reloc_field_size ¶

    reloc_field_size :: proc "contextless" (t: Relocation_Type) -> u8 {…}
     

    On-wire field width of a relocation, in bytes.

    reloc_has_addend ¶

    reloc_has_addend :: proc "contextless" (code: u8) -> bool {…}
     

    MEMORY_ADDR_ (3,4,5) and the _OFFSET_I32 forms (8,9) carry a trailing signed-LEB addend; the index-type relocations do not.

    reloc_type_from_wire ¶

    reloc_type_from_wire :: proc "contextless" (code: u8) -> (Relocation_Type, bool) {…}
     

    Decode a relocation type byte from a reloc.* custom section. ok is false for a type this codec does not model (the entry is then skipped).

    relocations_for_section ¶

    relocations_for_section :: proc "contextless" (groups: []Reloc_Group, id: Section_Id) -> []Relocation {…}
     

    The relocations (if any) that patch fields in the given section.

    sbprint ¶

    sbprint :: proc(sb: ^strings.Builder, ops: []rexcode_ir.Operation, options: ^rexcode_ir.Print_Options = nil) {…}
     

    sbprint: disassemble a bare operation stream (a WASM expr) -- the reusable core that print runs per block, and the mirror of the encoder's encode_ops / decoder's decode_ops.

    sbprint_wat ¶

    sbprint_wat :: proc(sb: ^strings.Builder, m: Module, opts: WAT_Options = DEFAULT_WAT_OPTIONS) {…}

    section_name ¶

    section_name :: proc "contextless" (id: Section_Id) -> string {…}

    sleb_size ¶

    sleb_size :: proc "contextless" (value: i64) -> u32 {…}

    take_block ¶

    take_block :: proc(b: ^Builder, label: rexcode_ir.Id = ID_NONE) -> rexcode_ir.Block {…}
     

    Detach the accumulated operations as a block body (and reset for the next).

    tprint ¶

    tprint :: proc(ops: []rexcode_ir.Operation, options: ^rexcode_ir.Print_Options = nil) -> string {…}
     

    tprint: temp-allocated string of an operation stream (spot-checks / debugging).

    tprint_wat ¶

    tprint_wat :: proc(m: Module, opts: WAT_Options = DEFAULT_WAT_OPTIONS) -> string {…}
     

    Result lives in the temp allocator.

    uleb_size ¶

    uleb_size :: proc "contextless" (value: u64) -> u32 {…}

    valtype_name ¶

    valtype_name :: proc "contextless" (t: Value_Type) -> string {…}

    value_type_is_num ¶

    value_type_is_num :: proc "contextless" (t: Value_Type) -> bool {…}

    value_type_is_ref ¶

    value_type_is_ref :: proc "contextless" (t: Value_Type) -> bool {…}

    wat_write_const_expr ¶

    wat_write_const_expr :: proc(
    	sb:        ^strings.Builder, 
    	m:         Module, 
    	relocs:    []Relocation, 
    	data:      []u8, 
    	off:       ^u32, 
    	unit:      string, 
    	allocator: runtime.Allocator, 
    ) {…}
     

    Decode and fold a constant expression at off^ (advancing past its end).

    wat_write_data ¶

    wat_write_data :: proc(sb: ^strings.Builder, m: Module, unit: string) -> Parse_Error {…}

    wat_write_elements ¶

    wat_write_elements :: proc(sb: ^strings.Builder, m: Module, unit: string) -> Parse_Error {…}

    wat_write_function ¶

    wat_write_function :: proc(sb: ^strings.Builder, m: Module, func_relocs: []Relocation, f: rexcode_ir.Function, unit: string) {…}

    wat_write_functype ¶

    wat_write_functype :: proc(sb: ^strings.Builder, t: Func_Type) {…}

    wat_write_globals ¶

    wat_write_globals :: proc(sb: ^strings.Builder, m: Module, unit: string) {…}

    wat_write_imports ¶

    wat_write_imports :: proc(sb: ^strings.Builder, m: Module, unit: string) -> Parse_Error {…}

    wat_write_memories ¶

    wat_write_memories :: proc(sb: ^strings.Builder, m: Module, unit: string) {…}

    wat_write_quoted_string ¶

    wat_write_quoted_string :: proc(sb: ^strings.Builder, bytes: []u8) {…}

    wat_write_tables ¶

    wat_write_tables :: proc(sb: ^strings.Builder, m: Module, unit: string) {…}

    write_attribute ¶

    write_attribute :: proc(sb: ^strings.Builder, o: ^rexcode_ir.Operand, opts: ^rexcode_ir.Print_Options) {…}

    write_block_type ¶

    write_block_type :: proc(sb: ^strings.Builder, v: i64) -> (printed: bool) {…}
     

    A blocktype annotation. Returns nothing meaningful; kept a proc for symmetry with the old printer. EMPTY prints nothing (the common block/loop case).

    write_float ¶

    write_float :: proc(sb: ^strings.Builder, o: ^rexcode_ir.Operand) {…}

    write_heap_type ¶

    write_heap_type :: proc(sb: ^strings.Builder, b: u8) {…}

    write_id_or_comment ¶

    write_id_or_comment :: proc(sb: ^strings.Builder, name: string, index: rexcode_ir.Id) {…}

    write_label ¶

    write_label :: proc(sb: ^strings.Builder, label_id: u32) {…}

    write_mnemonic ¶

    write_mnemonic :: proc(sb: ^strings.Builder, op: Opcode, uppercase: bool) {…}

    write_name_or_id ¶

    write_name_or_id :: proc(sb: ^strings.Builder, name: string, index: rexcode_ir.Id) {…}

    write_operand ¶

    write_operand :: proc(sb: ^strings.Builder, o: ^rexcode_ir.Operand, opcode: Opcode, opts: ^rexcode_ir.Print_Options) {…}
     

    One ir.Operand, dispatched on its shared kind (then, for ATTRIBUTE, on the WASM Attr tag in aux). A leading space separates it from the mnemonic / previous operand -- matching the old ISA printer's spacing.

    write_operation ¶

    write_operation :: proc(sb: ^strings.Builder, op: ^rexcode_ir.Operation, opts: ^rexcode_ir.Print_Options, module: runtime.Maybe($T=^Module)) {…}

    write_sleb ¶

    write_sleb :: proc "contextless" (code: []u8, offset: ^u32, value: i64) {…}
     

    Signed LEB128. Advances *offset.

    write_u32_block ¶

    write_u32_block :: proc(code: []u8, offset: ^u32, v: u32) {…}

    write_u64_block ¶

    write_u64_block :: proc(code: []u8, offset: ^u32, v: u64) {…}

    write_uleb ¶

    write_uleb :: proc "contextless" (code: []u8, offset: ^u32, value: u64) {…}
     

    Unsigned LEB128. Advances *offset. Caller guarantees buffer space.

    write_uleb_padded5 ¶

    write_uleb_padded5 :: proc "contextless" (code: []u8, offset: ^u32, value: u64) {…}
     

    Fixed 5-byte unsigned LEB128 (relocatable placeholder for 32-bit indices).

    Procedure Groups

    This section is empty.

    Source Files

    Generation Information

    Generated with odin version dev-2026-07 (vendor "odin") Windows_amd64 @ 2026-07-20 21:55:30.818753600 +0000 UTC