Wax instructions are expression-oriented.
Binary and unary operations use standard mathematical operators. Signedness is often explicit in the operator.
Wasm Wax
i32.add / i64.add+
i32.sub / i64.sub-
i32.mul / i64.mul*
i32.div_s / i64.div_s/s
i32.div_u / i64.div_u/u
i32.rem_s / i64.rem_s%s
i32.rem_u / i64.rem_u%u
i32.and / i64.and&
i32.or / i64.or|
i32.xor / i64.xor^
i32.shl / i64.shl<<
i32.shr_s / i64.shr_s>>s
i32.shr_u / i64.shr_u>>u
i32.eqz / i64.eqz!x (logical not)
Wasm Wax
f32.add / f64.add+
f32.sub / f64.sub-
f32.mul / f64.mul*
f32.div / f64.div/
f32.abs … f64.sqrtval.abs, val.neg, val.ceil, val.floor, val.trunc, val.nearest, val.sqrt
f32.min … f64.copysignmin(v1, v2), max(v1, v2), copysign(v1, v2)
Wasm Wax
i32.clz … i64.popcntval.clz, val.ctz, val.popcnt
i32.rotl … i64.rotrrotl(v1, v2), rotr(v1, v2)
Wasm Wax
i32.wrap_i64val as i32
i64.extend_i32_sval as i64_s
i64.extend_i32_uval as i64_u
i32.trunc_f32_sval as i32_s
f32.convert_i32_sval as f32_s
f32.demote_f64val as f32
f64.promote_f32val as f64
i32.reinterpret_f32val.to_bits
f32.reinterpret_i32val.from_bits
Wasm Wax
eq==
ne!=
lt_s / lt<s / <
lt_u<u
le_s / le<=s / <=
le_u<=u
gt_s / gt>s / >
gt_u>u
ge_s / ge>=s / >=
ge_u>=u
Wasm Wax
local.get $xx
local.set $xx = val
local.tee $xx := val
global.get $gg
global.set $gg = val
(local $x t)let x : t
Wasm Wax
blockdo { ... } or { ... }
looploop { ... }
if ... else ...if cond { ... } else { ... }
br $lbr 'l
br_if $lbr_if 'l cond
br_table $l* $ldbr_table ['l* else 'ld] val
br_on_null $lbr_on_null 'l val
br_on_non_null $lbr_on_non_null 'l val
br_on_cast $l $t1 $t2br_on_cast 'l t2 val
br_on_cast_fail $l $t1 $t2br_on_cast_fail 'l t2 val
returnreturn val
call $ff(args)
call_ref $t(val as &?t)(args)
return_call $fbecome f(args)
return_call_ref $tbecome (val as &?t)(args)
unreachableunreachable
nopnop
selectcond ? v1 : v2
Blocks, loops, and ifs can be labeled and typed.
Labels are identifiers starting with ' followed by a colon.
'my_block: do { ... }
'my_loop: loop { ... }
Block types (signatures) can be specified using (param) -> result syntax or a single value type.
If no type is specified, the do keyword is optional.
do (i32) -> i32 { ... }
do i32 { ... }
{ ... } ;; equivalent to do { ... }
if cond => (i32) -> i32 { ... } else { ... }
Wasm Wax
ref.nullnull
ref.is_null!val
ref.as_non_nullval!
ref.i31val as &i31
i31.get_sval as i32_s
i31.get_uval as i32_u
ref.castval as &type
ref.testval is &type
Wasm Wax
struct.new $t{t| field: val, ... }
struct.new_default $t{t| .. }
struct.get $t $fval.field
struct.set $t $fval.field = new_val
array.new $t[t| val; len]
array.new_default $t[t| ..; len]
array.new_fixed $t[t| val, ...]
array.get $tarr[idx]
array.get_s $tarr[idx] as i32_s
array.get_u $tarr[idx] as i32_u
array.set $tarr[idx] = val
array.lenarr.length
Wasm Wax
throw $tagthrow tag(args)
throw_refthrow_ref
try_table ... catch $tag $l ...try { ... } catch [ tag -> 'l, ... ]
try_table ... catch_ref $tag $l ...try { ... } catch [ tag & -> 'l, ... ]
try_table ... catch_all $l ...try { ... } catch [ _ -> 'l, ... ]
try_table ... catch_all_ref $l ...try { ... } catch [ _ & -> 'l, ... ]
try ... catch $tag ...try { ... } catch { tag => { ... } ... }
try ... catch_all ...try { ... } catch { _ => { ... } }
The try { ... } catch [ ... ] syntax compiles to WebAssembly’s try_table instruction (the current standard). The try { ... } catch { tag => { ... } } syntax compiles to the older try/catch instructions (deprecated but still supported for compatibility).
The following WebAssembly features do not have dedicated Wax syntax. When converting from WAT/WASM to Wax, these instructions are preserved as-is or may be dropped:
Linear Memory : memory.size, memory.grow, load, store (all variants). Wax focuses on GC-based memory management using structs and arrays.
Tables : table.get, table.set, call_indirect (and related instructions). Use typed function references instead.
SIMD : All v128 vector instructions. The v128 type exists but operations are not exposed.
Indirect Calls via Tables : return_call_indirect, call_indirect. Use call_ref with function references instead.