For the complete documentation index, see llms.txt. This page is also available as Markdown.

Wasm Data Types

UrWasm's inner core, +wasm-sur, contains the foundational Wasm types.

The first part implements the Structure chapter of the WebAssembly Core Specification.

The second part implements Wasm's binary-format opcodes.

$octs

+$  octs  (pair @ud @)

Pair of byte-length and octet stream data.

+wasm-sur

Wrapper arm around the Wasm types. This just makes the types addressable by limb resolution paths like num-type:wasm-sur.

$num-type

+$  num-type  ?(%i32 %i64 %f32 %f64)

Type annotation for the four types of number Wasm calls can return:

  • 32-bit integers (@F).

  • 64-bit integers (@G).

  • 32-bit floating point numbers (@rs).

  • 64-bit floating point numbers (@rd).

$vec-type

Type annotation for a 128-bit (@H) register.

$ref-type

Type annotation for references in the Wasm state, be those functions or data.

$valtype

Type annotation for all the types that Wasm can accept: numbers, vectors, and references.

$coin-wasm

Type-annotated Wasm value. A $coin-wasm is UrWasm's version of Wasm's result types, which look something like Hoon's $coin nouns.

These are the $valtype type annotation terms with extra specification for atom size and object references.

$limits

Limits the range of available storage for $memargs and $tables.

$memarg

Defines the minimum and maximum size of a memory instance. The .align and .offset values represent units of Wasm's page size, which is 128 bits (so, a @H).

$block-type

Function signature for control flow blocks (if, loop, etc.). This may be defined inline ($func-type) or referred to by its index in the $type-section.

$func-type

Function signature.

$lane-type

Type annotation for lanes (memory elements) in a 128-bit (@H) register. Includes the usual $num-types and additional %i8 and %i16 types for smaller lanes.

$instruction

Type union of all Wasm instructions.

Instructions are categorized here by their operand patterns:

$instr-dbug

Debugging instructions. The only one supported here is %print-tee, which prints a value to output with the given $term as a label.

$instr-num

Type union of all standard Wasm instructions, categorized here by arity.

$instr-num-zero

Wasm const instruction, whose value is any $coin-wasm that may represent a constant value. So...

$instr-num-one

Standard Wasm instructions with one parameter each:

  • eqz: Check if equals zero.

  • clz: Count leading zeroes.

  • ctz: Count trailing zeroes.

  • popcnt: Population count (number of set bits).

  • abs: Absolute value.

  • neg: Negate.

  • ceil: Round a float up to nearest integer.

  • floor: Round a float down to nearest integer.

  • nearest: Round a float to nearest integer.

  • sqrt: Square root.

  • trunc: Truncate float to integer (with optional saturation).

  • wrap: Wrap larger integer to smaller type.

  • extend: Extend smaller integer to larger type.

  • convert: Convert between integer and float.

  • demote: Convert f64 (@rd) to f32 (@rs).

  • promote: Convert f32 (@rs) to f64 (@rd).

  • reinterpret: Reinterpret bit pattern as different type.

$instr-num-two

Wasm's binary numeric instructions:

  • eq: Test equality.

  • ne: Test inequality.

  • lt: Less than.

  • gt: Greater than.

  • le: Less than or equal.

  • ge: Greater than or equal.

  • add: Addition.

  • sub: Subtraction.

  • mul: Multiplication.

  • div: Division.

  • rem: Remainder.

  • and: Bitwise AND.

  • or: Bitwise OR.

  • xor: Bitwise XOR.

  • shl: Shift left.

  • shr: Shift right (logical or arithmetic).

  • rotl: Rotate left.

  • rotr: Rotate right.

  • min: Minimum value.

  • max: Maximum value.

  • copysign: Copy sign bit from second operand to first.

$instr-short

Non-numeric WebAssembly instructions organized by category:

  • unreachable: Trap execution unconditionally.

  • nop: No operation.

  • block: Start a block with optional result type.

  • loop: Start a loop with optional result type.

  • if: Conditional execution with true/false branches.

  • br: Unconditional branch to label.

  • br-if: Conditional branch to label.

  • br-table: Multi-way branch (switch statement).

  • return: Return from current function.

  • call: Call function by index.

  • call-indirect: Call function indirectly through table.

  • ref-null: Create null reference.

  • ref-is-null: Test if reference is null.

  • ref-func: Get function reference.

  • drop: Remove top stack value.

  • select: Choose between two values based on condition.

  • local-get: Get local variable value.

  • local-set: Set local variable value.

  • local-tee: Set local variable and return the value.

  • global-get: Get global variable value.

  • global-set: Set global variable value.

  • table-get: Get element from table.

  • table-set: Set element in table.

  • table-init: Initialize table from element segment.

  • table-copy: Copy elements between tables.

  • table-grow: Grow table size.

  • table-size: Get table size.

  • table-fill: Fill table range with value.

  • elem-drop: Drop element segment.

  • load: Load value from memory.

  • store: Store value to memory.

  • memory-size: Get memory size in pages.

  • memory-grow: Grow memory size.

  • memory-init: Initialize memory from data segment.

  • data-drop: Drop data segment.

  • memory-copy: Copy memory regions.

  • memory-fill: Fill memory range with byte value.

$instr-vec

Wasm SIMD vector instructions for 128-bit vectors:

  • load: Load vector from memory (with optional splat/zero-extend/sign-extend).

  • load-lane: Load single value into specific lane.

  • store: Store vector to memory.

  • store-lane: Store single lane to memory.

  • const: Vector constant.

  • shuffle: Rearrange lanes by index list.

  • extract: Get value from specific lane.

  • replace: Set value in specific lane.

  • swizzle: Rearrange lanes using second vector as indices.

  • splat: Broadcast scalar to all lanes.

  • eq: Lane-wise equality comparison.

  • ne: Lane-wise inequality comparison.

  • lt: Lane-wise less than comparison.

  • gt: Lane-wise greater than comparison.

  • le: Lane-wise less than or equal comparison.

  • ge: Lane-wise greater than or equal comparison.

  • not: Bitwise NOT on entire vector.

  • and: Bitwise AND on entire vector.

  • andnot: Bitwise AND-NOT on entire vector.

  • or: Bitwise OR on entire vector.

  • xor: Bitwise XOR on entire vector.

  • bitselect: Select bits based on mask.

  • any-true: Test if any lanes are true.

  • all-true: Test if all lanes are true.

  • bitmask: Extract high bit from each lane.

  • abs: Lane-wise absolute value.

  • neg: Lane-wise negation.

  • popcnt: Population count on each lane.

  • narrow: Pack two vectors into one with narrower lanes.

  • shl: Lane-wise left bit shift.

  • shr: Lane-wise right bit shift.

  • add: Lane-wise addition (with optional saturation).

  • sub: Lane-wise subtraction (with optional saturation).

  • min: Lane-wise minimum.

  • max: Lane-wise maximum.

  • avgr: Averaging with rounding.

  • mul: Lane-wise multiplication.

  • extend: Extend lane width.

  • extmul: Extended multiplication.

  • extadd: Extended addition.

  • q15mul-r-sat: Q15 fixed-point multiplication.

  • dot: Dot product.

  • ceil: Lane-wise ceiling (round up).

  • floor: Lane-wise floor (round down).

  • nearest: Lane-wise round to nearest.

  • sqrt: Lane-wise square root.

  • div: Lane-wise division.

  • trunc: Lane-wise truncate to integer.

  • convert: Lane-wise type conversion.

  • demote: Lane-wise f64 to f32 conversion.

  • promote: Lane-wise f32 to f64 conversion.

  • pmin: Propagating minimum (NaN handling).

  • pmax: Propagating maximum (NaN handling).

$expression

An ordered sequence of $instructions.

$const-instr

Instructions that produce constant values e.g. global variables. Unlike $instr-num-zero which only handles scalar numeric constants, this includes vector constants, global variable reads, and reference constants.

$module

A Wasm module. Note code and function sections are separated here to simplify parsing.

$type-section

List of function signatures in the module.

$import-section

List of $imports this module requires from other modules.

$import

Import from another Wasm module, including:

  • .mod: Module name.

  • .name: Name for the entity in the module we'd like to import.

  • .desc: Importable definitions within the module, including functions, tables, global variables, etc.

$function-section

List of functions in this module, referenced by index.

$table-section

List of $tables in the module.

$table

Wasm table, referenced by its $ref-type and describing the $limits of its size.

$memory-section

List of the module's memory arrays, defined by the $limits of their size.

$global-section

List of the module's $global variables.

$global

Global variable, including:

  • .val: $valtype, type of the variable's value.

  • .m: Constant or variable.

  • .i: Initial value. (Note that this is a constant instruction and not a (list instruction) as Wasm has no global value type that would take multiple constant values.)

$export-section

List of $exports in the module.

$export

Element to be exportable for use in other modules:

  • .name: Name of the export.

  • .export-desk: $export-desc, type-annotated value of the export.

$export-desc

Type-annotated value of an export addressed by its index:

  • %func: Function.

  • %tabl: Table.

  • %memo: Memory.

  • %glob: Global variable.

In practice these indexes will always be 32-bit integers (@Fs).

$start-section

The initialization (or "start") function for the module, if one exists.

$elem-section

List of $elems.

$elem

Wasm element segment:

  • .t: Reference type. (Currently Wasm only supports function references (%func $ref-types).)

  • .i: Sequence of $instructions to produce function references.

  • .m: Element segment mode:

    • %pass: Passive, elements copied manually via table initialization.

    • %decl: Declarative, declares references which aren't copied to tables.

    • %acti: Active, automatically copies element data to the table .tab at offset .off when the module is instantiated.

Element segments store static data with which to populate $tables when the module is initialized.

$code-section

List of $code entries.

$code

Function implementation stored in binary format:

  • .locals: List of local variables in this function.

  • .expression: The function body as a sequence of instructions. (See $expression.)

$data-section

List of the module's $data segments.

$data

Data segment for initializing the module's state.

  • %acti: Active segments automatically copy $octs .b to the module's memory at offset .off during instantiation.

  • %pass: Passive segments are copied manually when instructed.

+datacnt-section

Data count section of the Wasm module, which may optionally contain the number of data segments ($data) in the module. This allows validators to check the index validity of the data section before trying to access it.

$opcode

Type union of all Wasm's binary instruction opcodes.

$bin-opcodes-zero-args

Wasm binary instruction opcodes that take no immediate arguments.

A few simple opcodes are defined here:

  • %0x0: unreachable - causes an unconditional trap when executed.

  • %0x1: nop - no-op, do nothing.

  • %0xf: return - return from current function with values from stack.

    • If there's nothing in the stack to return, this returns nothing.

    • If there are more values on the stack than allowed by the function's return type, the first nn values are returned (where nn is the number of values allowed) and the rest are discarded.

  • %0x1a: drop - remove top value from stack.

  • %0x1b: select - choose between two values based on condition.

  • %0xa7: i64.wrap_i32 - convert i64 to i32 by wrapping (truncating high bits).

  • %0xb6: f32.demote_f64 - convert f64 to f32.

  • %0xbb: f64.promote_f32 - convert f32 to f64.

$pseudo-opcode

Pseudo-opcodes for control flow constructs:

  • %0x5: else - marks the else branch of an if block.

  • %0xb: end - terminates blocks, loops, if-statements, and functions.

$bin-opcodes-one-arg

Instructions taking one immediate argument:

  • %0xc: br - unconditional branch to label.

  • %0xd: br_if - conditional branch to label.

  • %0x10: call - invoke function by index.

  • %0x20: local.get - read local variable.

  • %0x21: local.set - write local variable.

  • %0x22: local.tee - write local variable and return value.

  • %0x23: global.get - read global variable.

  • %0x24: global.set - write global variable.

  • %0x3f: memory.size - query memory size.

  • %0x40: memory.grow - grow memory by given delta.

  • $const-opcodes: constants for i32, i64, f32, f64.

$bin-opcodes-two-args

Instructions taking two immediate arguments:

  • %0xe: br_table - branch table for switch-like control flow.

  • %0x11: call_indirect - invoke function indirectly through table.

  • $load-opcodes: memory load operations with alignment and offset.

  • $store-opcodes: memory store operations with alignment and offset.

$bin-opcodes-blocks

Structured control flow instructions that create blocks with labels:

  • %0x2: block - creates a block construct that can be targeted by branch instructions.

  • %0x3: loop - creates a loop construct where branches target the beginning of the block.

  • %0x4: if - creates a conditional block that executes based on a condition value.

$const-opcodes

Constant value instructions that push literal values onto the stack:

  • %0x41: i32.const - push 32-bit integer constant.

  • %0x42: i64.const - push 64-bit integer constant.

  • %0x43: f32.const - push 32-bit float constant.

  • %0x44: f64.const - push 64-bit float constant.

$load-opcodes

Memory load instructions that read values from linear memory:

  • %0x28: i32.load - load 32-bit integer.

  • %0x29: i64.load - load 64-bit integer.

  • %0x2a: f32.load - load 32-bit float.

  • %0x2b: f64.load - load 64-bit float.

  • %0x2c: i32.load8_s - load 8-bit signed, extend to i32.

  • %0x2d: i32.load8_u - load 8-bit unsigned, extend to i32.

  • %0x2e: i32.load16_s - load 16-bit signed, extend to i32.

  • %0x2f: i32.load16_u - load 16-bit unsigned, extend to i32.

  • %0x30: i64.load8_s - load 8-bit signed, extend to i64.

  • %0x31: i64.load8_u - load 8-bit unsigned, extend to i64.

  • %0x32: i64.load16_s - load 16-bit signed, extend to i64.

  • %0x33: i64.load16_u - load 16-bit unsigned, extend to i64.

  • %0x34: i64.load32_s - load 32-bit signed, extend to i64.

  • %0x35: i64.load32_u - load 32-bit unsigned, extend to i64.

$store-opcodes

Memory store instructions that write values to linear memory:

  • %0x36: i32.store - store 32-bit integer.

  • %0x37: i64.store - store 64-bit integer.

  • %0x38: f32.store - store 32-bit float.

  • %0x39: f64.store - store 64-bit float.

  • %0x3a: i32.store8 - store lower 8 bits of i32.

  • %0x3b: i32.store16 - store lower 16 bits of i32.

  • %0x3c: i64.store8 - store lower 8 bits of i64.

  • %0x3d: i64.store16 - store lower 16 bits of i64.

  • %0x3e: i64.store32 - store lower 32 bits of i64.

$eqz-opcodes

Test if value equals zero:

  • %0x45: i32.eqz - test if i32 equals zero.

  • %0x50: i64.eqz - test if i64 equals zero.

$eq-opcodes

Test if two values are equal:

  • %0x46: i32.eq - i32 equality comparison.

  • %0x51: i64.eq - i64 equality comparison.

  • %0x5b: f32.eq - f32 equality comparison.

  • %0x61: f64.eq - f64 equality comparison.

$ne-opcodes

Test if two values are not equal:

  • %0x47: i32.ne - i32 inequality comparison.

  • %0x52: i64.ne - i64 inequality comparison.

  • %0x5c: f32.ne - f32 inequality comparison.

  • %0x62: f64.ne - f64 inequality comparison.

$lt-opcodes

Test if first value is less than second:

  • %0x48: i32.lt_s - i32 signed less-than.

  • %0x49: i32.lt_u - i32 unsigned less-than.

  • %0x53: i64.lt_s - i64 signed less-than.

  • %0x54: i64.lt_u - i64 unsigned less-than.

  • %0x5d: f32.lt - f32 less-than.

  • %0x63: f64.lt - f64 less-than.

$gt-opcodes

Test if first value is greater than second:

  • %0x4a: i32.gt_s - i32 signed greater-than.

  • %0x4b: i32.gt_u - i32 unsigned greater-than.

  • %0x55: i64.gt_s - i64 signed greater-than.

  • %0x56: i64.gt_u - i64 unsigned greater-than.

  • %0x5e: f32.gt - f32 greater-than.

  • %0x64: f64.gt - f64 greater-than.

$le-opcodes

Test if first value is less than or equal to second:

  • %0x4c: i32.le_s - i32 signed less-than-or-equal.

  • %0x4d: i32.le_u - i32 unsigned less-than-or-equal.

  • %0x57: i64.le_s - i64 signed less-than-or-equal.

  • %0x58: i64.le_u - i64 unsigned less-than-or-equal.

  • %0x5f: f32.le - f32 less-than-or-equal.

  • %0x65: f64.le - f64 less-than-or-equal.

$ge-opcodes

Test if first value is greater than or equal to second:

  • %0x4e: i32.ge_s - i32 signed greater-than-or-equal.

  • %0x4f: i32.ge_u - i32 unsigned greater-than-or-equal.

  • %0x59: i64.ge_s - i64 signed greater-than-or-equal.

  • %0x5a: i64.ge_u - i64 unsigned greater-than-or-equal.

  • %0x60: f32.ge - f32 greater-than-or-equal.

  • %0x66: f64.ge - f64 greater-than-or-equal.

$clz-opcodes

Count leading zeros:

  • %0x67: i32.clz - count leading zeros in i32.

  • %0x79: i64.clz - count leading zeros in i64.

$ctz-opcodes

Count trailing zeros:

  • %0x68: i32.ctz - count trailing zeros in i32.

  • %0x7a: i64.ctz - count trailing zeros in i64.

$popcnt-opcodes

Count number of set bits (population count):

  • %0x69: i32.popcnt - count set bits in i32.

  • %0x7b: i64.popcnt - count set bits in i64.

$add-opcodes

Addition operations:

  • %0x6a: i32.add - i32 addition.

  • %0x7c: i64.add - i64 addition.

  • %0x92: f32.add - f32 addition.

  • %0xa0: f64.add - f64 addition.

$sub-opcodes

Subtraction operations:

  • %0x6b: i32.sub - i32 subtraction.

  • %0x7d: i64.sub - i64 subtraction.

  • %0x93: f32.sub - f32 subtraction.

  • %0xa1: f64.sub - f64 subtraction.

$mul-opcodes

Multiplication operations:

  • %0x6c: i32.mul - i32 multiplication.

  • %0x7e: i64.mul - i64 multiplication.

  • %0x94: f32.mul - f32 multiplication.

  • %0xa2: f64.mul - f64 multiplication.

$div-opcodes

Division operations:

  • %0x6d: i32.div_s - i32 signed division.

  • %0x6e: i32.div_u - i32 unsigned division.

  • %0x7f: i64.div_s - i64 signed division.

  • %0x80: i64.div_u - i64 unsigned division.

  • %0x95: f32.div - f32 division.

  • %0xa3: f64.div - f64 division.

$rem-opcodes

Remainder operations:

  • %0x6f: i32.rem_s - i32 signed remainder.

  • %0x70: i32.rem_u - i32 unsigned remainder.

  • %0x81: i64.rem_s - i64 signed remainder.

  • %0x82: i64.rem_u - i64 unsigned remainder.

$and-opcodes

Bitwise AND operations:

  • %0x71: i32.and - i32 bitwise AND.

  • %0x83: i64.and - i64 bitwise AND.

$or-opcodes

Bitwise OR operations:

  • %0x72: i32.or - i32 bitwise OR.

  • %0x84: i64.or - i64 bitwise OR.

$xor-opcodes

Bitwise XOR operations:

  • %0x73: i32.xor - i32 bitwise exclusive OR.

  • %0x85: i64.xor - i64 bitwise exclusive OR.

$shl-opcodes

Bitwise left shift operations:

  • %0x74: i32.shl - i32 shift left.

  • %0x86: i64.shl - i64 shift left.

$shr-opcodes

Bitwise right shift operations:

  • %0x75: i32.shr_s - i32 arithmetic right shift (sign-extending).

  • %0x76: i32.shr_u - i32 logical right shift (zero-filling).

  • %0x87: i64.shr_s - i64 arithmetic right shift (sign-extending).

  • %0x88: i64.shr_u - i64 logical right shift (zero-filling).

$rotl-opcodes

Rotate left operations:

  • %0x77: i32.rotl - i32 rotate left.

  • %0x89: i64.rotl - i64 rotate left.

$rotr-opcodes

Rotate right operations:

  • %0x78: i32.rotr - i32 rotate right.

  • %0x8a: i64.rotr - i64 rotate right.

$abs-opcodes

Floating-point absolute value operations:

  • %0x8b: f32.abs - f32 absolute value.

  • %0x99: f64.abs - f64 absolute value.

$neg-opcodes

Floating-point negation operations:

  • %0x8c: f32.neg - f32 negation.

  • %0x9a: f64.neg - f64 negation.

$ceil-opcodes

Floating-point ceiling operations (round up to nearest integer):

  • %0x8d: f32.ceil - f32 ceiling.

  • %0x9b: f64.ceil - f64 ceiling.

$floor-opcodes

Floating-point floor operations (round down to nearest integer):

  • %0x8e: f32.floor - f32 floor.

  • %0x9c: f64.floor - f64 floor.

$trunc-opcodes

Truncation operations (remove fractional part):

  • %0x8f: f32.trunc - f32 truncate toward zero.

  • %0x9d: f64.trunc - f64 truncate toward zero.

  • %0xa8: i32.trunc_f32_s - convert f32 to signed i32 (truncate).

  • %0xa9: i32.trunc_f32_u - convert f32 to unsigned i32 (truncate).

  • %0xaa: i32.trunc_f64_s - convert f64 to signed i32 (truncate).

  • %0xab: i32.trunc_f64_u - convert f64 to unsigned i32 (truncate).

  • %0xae: i64.trunc_f32_s - convert f32 to signed i64 (truncate).

  • %0xaf: i64.trunc_f32_u - convert f32 to unsigned i64 (truncate).

  • %0xb0: i64.trunc_f64_s - convert f64 to signed i64 (truncate).

  • %0xb1: i64.trunc_f64_u - convert f64 to unsigned i64 (truncate).

$nearest-opcodes

Floating-point nearest integer operations (round to nearest, ties to even):

  • %0x90: f32.nearest - f32 round to nearest integer.

  • %0x9e: f64.nearest - f64 round to nearest integer.

$sqrt-opcodes

Floating-point square root operations:

  • %0x91: f32.sqrt - f32 square root.

  • %0x9f: f64.sqrt - f64 square root.

$min-opcodes

Floating-point minimum operations:

  • %0x96: f32.min - f32 minimum of two values.

  • %0xa4: f64.min - f64 minimum of two values.

$max-opcodes

Floating-point maximum operations:

  • %0x97: f32.max - f32 maximum of two values.

  • %0xa5: f64.max - f64 maximum of two values.

$copysign-opcodes

Floating-point copy sign operations (combine magnitude of first value with sign of second):

  • %0x98: f32.copysign - f32 copy sign.

  • %0xa6: f64.copysign - f64 copy sign.

$extend-opcodes

Integer extension operations (widen integer types):

  • %0xac: i64.extend_i32_s - extend signed i32 to i64.

  • %0xad: i64.extend_i32_u - extend unsigned i32 to i64.

  • %0xc0: i32.extend8_s - extend signed i8 to i32.

  • %0xc1: i32.extend16_s - extend signed i16 to i32.

  • %0xc2: i64.extend8_s - extend signed i8 to i64.

  • %0xc3: i64.extend16_s - extend signed i16 to i64.

  • %0xc4: i64.extend32_s - extend signed i32 to i64 (same as %0xac).

$convert-opcodes

Type conversion operations (integer to floating-point):

  • %0xb2: f32.convert_i32_s - convert signed i32 to f32.

  • %0xb3: f32.convert_i32_u - convert unsigned i32 to f32.

  • %0xb4: f32.convert_i64_s - convert signed i64 to f32.

  • %0xb5: f32.convert_i64_u - convert unsigned i64 to f32.

  • %0xb7: f64.convert_i32_s - convert signed i32 to f64.

  • %0xb8: f64.convert_i32_u - convert unsigned i32 to f64.

  • %0xb9: f64.convert_i64_s - convert signed i64 to f64.

  • %0xba: f64.convert_i64_u - convert unsigned i64 to f64.

$reinterpret-opcodes

Type reinterpretation operations (reinterpret bit pattern without conversion):

  • %0xbc: i32.reinterpret_f32 - reinterpret f32 bits as i32.

  • %0xbd: i64.reinterpret_f64 - reinterpret f64 bits as i64.

  • %0xbe: f32.reinterpret_i32 - reinterpret i32 bits as f32.

  • %0xbf: f64.reinterpret_i64 - reinterpret i64 bits as f64.

Last updated