Lecture 5 - Interpreters and WebAssembly Runtime Semantics - Key concepts: - values: entities that can be manipulated by a program - wasm: 32- and 64-bit integers and floats, 128-bit vectors, opaque external references - java: 32- and 64-bit integers and floats, objects and arrays - ML: primitives, algebraic data types, higher-order functions, records - C: primitives, pointers (machine-level address), structs - types: organize values into sets - wasm: i32, i64, f32, f64, v128, externref (funcref) - java: byte, char, short, int, long, float, double, Lclassname; Larrayname; - operations: computations from values to values, with side-effects to state - arithmetic, load and store to memory, load/store to tables, control flow, call - state: maps names or indexed locations to values - wasm: tables, memories, local variables, execution stack - java: object fields, array elements, static fields, local variables, execution stack(s) - "current location in the code/what to do next" - dynamically-typed: values remember their types, operations inspect types - statically-typed: locations have types that prescribe which values can go in - representation: data structures in implementation language that represent program concepts - intermediate representation: between source and target machine - code and data, static and dynamic - metavalues: representation of a value in the implementation language - abstract syntax tree / expression tree - post-order tree traversal to evaluate - bytecode (byte array, list of instructions) - bytecode handlers - dispatch loop - stack machine - register machine - execution frames - global state WebAssembly Runtime Semantics - Key concepts: - modules and instances - module: static representation of code - instance: dynamic instance of program with state imports and exports - imports describe functionality needed by a module - functions, tables, memory, globals - exports expose a module (instance) state or behavior instantiating a module - imports must be supplied *bindings* - functions, tables, memory globals - may come from other modules or the host - then module-internal state is created - declared tables, memories, and globals - Memory - organization: 64KiB pages, byte-addressable - access: 1, 2, 4, 8, and 16 byte accesses, can be misaligned - can be grown a page at a time - Tables - table(s): array of opaque references (to functions or extern) - initialized via element segments before execution starts - access: table.get, table.set instructions - can be grown an element at a time - Global Variables - individual scalars not aliased by memory - initialized by the expressions in their declarations - initializers are technically instructions, but a limited set - access with global.get and global.set - Then a start function is called, we get to run some code! running an (exported) function - all functions have fixed parameters and return values (no var args) - the arguments to a function become the first local variables - locals are indexed by number starting from 0 Lecture 6: Wasm Instructions - constants: These instructions push a constant value onto the operand stack. The value is encoded inline in the bytecode as an immediate. i32.const 0x00, 0x41 I32 i64.const 0x00, 0x42 I64 f32.const 0x00, 0x43 F32 f64.const 0x00, 0x44 F64 - local access These instructions get and set local variables by their (static) index. "tee" sets a local but leaves the value on the stack. local.get 0x00, 0x20 LOCAL local.set 0x00, 0x21 LOCAL local.tee 0x00, 0x22 LOCAL - stack manipulation This instruction drops a value off the operand stack. drop 0x00, 0x1A - control flow Control flow is expressed by bytecodes that represent the delimiters of control constructs such as blocks, loops, and ifs. Blocks may take argument values and leave results on the stack. block 0x00, 0x02 BLOCKT loop 0x00, 0x03 BLOCKT if 0x00, 0x04 BLOCKT else 0x00, 0x05 end 0x00, 0x0B br 0x00, 0x0C LABEL br_if 0x00, 0x0D LABEL br_table 0x00, 0x0E LABELS select 0x00, 0x1B select 0x00, 0x1C VALTS - memory access Memory access is done through loads and stores. A static offset is added to a dynamic index that makes up the effective address to load or store from. Zero or sign extension is available built-in to the opcode, for use with loads or stores smaller than 32 bits. i32.load 0x00, 0x28 MEMARG i64.load 0x00, 0x29 MEMARG f32.load 0x00, 0x2A MEMARG f64.load 0x00, 0x2B MEMARG i32.load8_s 0x00, 0x2C MEMARG i32.load8_u 0x00, 0x2D MEMARG i32.load16_s 0x00, 0x2E MEMARG i32.load16_u 0x00, 0x2F MEMARG i64.load8_s 0x00, 0x30 MEMARG i64.load8_u 0x00, 0x31 MEMARG i64.load16_s 0x00, 0x32 MEMARG i64.load16_u 0x00, 0x33 MEMARG i64.load32_s 0x00, 0x34 MEMARG i64.load32_u 0x00, 0x35 MEMARG i32.store 0x00, 0x36 MEMARG i64.store 0x00, 0x37 MEMARG f32.store 0x00, 0x38 MEMARG f64.store 0x00, 0x39 MEMARG i32.store8 0x00, 0x3A MEMARG i32.store16 0x00, 0x3B MEMARG i64.store8 0x00, 0x3C MEMARG i64.store16 0x00, 0x3D MEMARG i64.store32 0x00, 0x3E MEMARG - global access Globals are accesses with get/set instructions specifying a static index. global.get 0x00, 0x23 GLOBAL global.set 0x00, 0x24 GLOBAL - table access Tables are accessed with dynamic indexes. table.get 0x00, 0x25 TABLE table.set 0x00, 0x26 TABLE - calls Direct calls specify the target function index statically, while indirect calls specify a dynamic index into a table and require a dynamic signature check. "return_call" is a tail call; the caller frame is popped before performing the call. call 0x00, 0x10 FUNC call_indirect 0x00, 0x11 SIG_TABLE return_call 0x00, 0x12 FUNC return_call_indirect 0x00, 0x13 SIG_TABLE return 0x00, 0x0F - misc Miscellaneous instructions related to memory. memory.size 0x00, 0x3F MEMORY memory.grow 0x00, 0x40 MEMORY unreachable 0x00, 0x00 nop 0x00, 0x01 - comparisons Comparisons of primitive types are pure operations, most with two inputs and one (i32) output. Whether to interpret integers as signed or unsigned is specified as part of the instruction. Floating point comparison uses IEEE-754 rules where NaN != NaN. i32.eqz 0x00, 0x45 i32.eq 0x00, 0x46 i32.ne 0x00, 0x47 i32.lt_s 0x00, 0x48 i32.lt_u 0x00, 0x49 i32.gt_s 0x00, 0x4A i32.gt_u 0x00, 0x4B i32.le_s 0x00, 0x4C i32.le_u 0x00, 0x4D i32.ge_s 0x00, 0x4E i32.ge_u 0x00, 0x4F i64.eqz 0x00, 0x50 i64.eq 0x00, 0x51 i64.ne 0x00, 0x52 i64.lt_s 0x00, 0x53 i64.lt_u 0x00, 0x54 i64.gt_s 0x00, 0x55 i64.gt_u 0x00, 0x56 i64.le_s 0x00, 0x57 i64.le_u 0x00, 0x58 i64.ge_s 0x00, 0x59 i64.ge_u 0x00, 0x5A f32.eq 0x00, 0x5B f32.ne 0x00, 0x5C f32.lt 0x00, 0x5D f32.gt 0x00, 0x5E f32.le 0x00, 0x5F f32.ge 0x00, 0x60 f64.eq 0x00, 0x61 f64.ne 0x00, 0x62 f64.lt 0x00, 0x63 f64.gt 0x00, 0x64 f64.le 0x00, 0x65 f64.ge 0x00, 0x66 - I32 arithmetic i32.clz 0x00, 0x67 i32.ctz 0x00, 0x68 i32.popcnt 0x00, 0x69 i32.add 0x00, 0x6A i32.sub 0x00, 0x6B i32.mul 0x00, 0x6C i32.div_s 0x00, 0x6D i32.div_u 0x00, 0x6E i32.rem_s 0x00, 0x6F i32.rem_u 0x00, 0x70 i32.and 0x00, 0x71 i32.or 0x00, 0x72 i32.xor 0x00, 0x73 i32.shl 0x00, 0x74 i32.shr_s 0x00, 0x75 i32.shr_u 0x00, 0x76 i32.rotl 0x00, 0x77 i32.rotr 0x00, 0x78 - I64 arithmetic. i64.clz 0x00, 0x79 i64.ctz 0x00, 0x7A i64.popcnt 0x00, 0x7B i64.add 0x00, 0x7C i64.sub 0x00, 0x7D i64.mul 0x00, 0x7E i64.div_s 0x00, 0x7F i64.div_u 0x00, 0x80 i64.rem_s 0x00, 0x81 i64.rem_u 0x00, 0x82 i64.and 0x00, 0x83 i64.or 0x00, 0x84 i64.xor 0x00, 0x85 i64.shl 0x00, 0x86 i64.shr_s 0x00, 0x87 i64.shr_u 0x00, 0x88 i64.rotl 0x00, 0x89 i64.rotr 0x00, 0x8A - F32 arithmetic. f32.abs 0x00, 0x8B f32.neg 0x00, 0x8C f32.ceil 0x00, 0x8D f32.floor 0x00, 0x8E f32.trunc 0x00, 0x8F f32.nearest 0x00, 0x90 f32.sqrt 0x00, 0x91 f32.add 0x00, 0x92 f32.sub 0x00, 0x93 f32.mul 0x00, 0x94 f32.div 0x00, 0x95 f32.min 0x00, 0x96 f32.max 0x00, 0x97 f32.copysign 0x00, 0x98 - F64 arithmetic. f64.abs 0x00, 0x99 f64.neg 0x00, 0x9A f64.ceil 0x00, 0x9B f64.floor 0x00, 0x9C f64.trunc 0x00, 0x9D f64.nearest 0x00, 0x9E f64.sqrt 0x00, 0x9F f64.add 0x00, 0xA0 f64.sub 0x00, 0xA1 f64.mul 0x00, 0xA2 f64.div 0x00, 0xA3 f64.min 0x00, 0xA4 f64.max 0x00, 0xA5 f64.copysign 0x00, 0xA6 - Conversions and casts. Conversions between different integer sizes and floating point to int. Note that float to int conversions may trap if the value is out of range. i32.wrap_i64 0x00, 0xA7 i32.trunc_f32_s 0x00, 0xA8 i32.trunc_f32_u 0x00, 0xA9 i32.trunc_f64_s 0x00, 0xAA i32.trunc_f64_u 0x00, 0xAB i64.extend_i32_s 0x00, 0xAC i64.extend_i32_u 0x00, 0xAD i64.trunc_f32_s 0x00, 0xAE i64.trunc_f32_u 0x00, 0xAF i64.trunc_f64_s 0x00, 0xB0 i64.trunc_f64_u 0x00, 0xB1 f32.convert_i32_s 0x00, 0xB2 f32.convert_i32_u 0x00, 0xB3 f32.convert_i64_s 0x00, 0xB4 f32.convert_i64_u 0x00, 0xB5 f32.demote_f64 0x00, 0xB6 f64.convert_i32_s 0x00, 0xB7 f64.convert_i32_u 0x00, 0xB8 f64.convert_i64_s 0x00, 0xB9 f64.convert_i64_u 0x00, 0xBA f64.promote_f32 0x00, 0xBB i32.reinterpret_f32 0x00, 0xBC i64.reinterpret_f64 0x00, 0xBD f32.reinterpret_i32 0x00, 0xBE f64.reinterpret_i64 0x00, 0xBF - explicit sign-extension instructions. i32.extend8_s 0x00, 0xC0 i32.extend16_s 0x00, 0xC1 i64.extend8_s 0x00, 0xC2 i64.extend16_s 0x00, 0xC3 i64.extend32_s 0x00, 0xC4 - reference instructions Constant instruction for null(s), testing against null, and comparing references. ref.null 0x00, 0xD0 REFNULLT ref.is_null 0x00, 0xD1 ref.func 0x00, 0xD2 FUNC ref.as_non_null 0x00, 0xD3 br_on_null 0x00, 0xD4 LABEL ref.eq 0x00, 0xD5 br_on_non_null 0x00, 0xD6 LABEL - saturating truncations Floating point to integer conversions that never fail (saturate) i32.trunc_sat_f32_s 0xFC, 0x00 i32.trunc_sat_f32_u 0xFC, 0x01 i32.trunc_sat_f64_s 0xFC, 0x02 i32.trunc_sat_f64_u 0xFC, 0x03 i64.trunc_sat_f32_s 0xFC, 0x04 i64.trunc_sat_f32_u 0xFC, 0x05 i64.trunc_sat_f64_s 0xFC, 0x06 i64.trunc_sat_f64_u 0xFC, 0x07 - bulk-memory and references Instructions to load data into memory or elements into tables dynamically. Additional instructions to do bulk memory operations. memory.init 0xFC, 0x08 DATA_MEMORY data.drop 0xFC, 0x09 DATA memory.copy 0xFC, 0x0A MEMORY_MEMORY memory.fill 0xFC, 0x0B MEMORY table.init 0xFC, 0x0C ELEM_TABLE elem.drop 0xFC, 0x0D ELEM table.copy 0xFC, 0x0E TABLE_TABLE table.grow 0xFC, 0x0F TABLE table.size 0xFC, 0x10 TABLE table.fill 0xFC, 0x11 TABLE - vector instructions Operations on 128-bit vectors. v128.load 0xFD, 0 MEMARG v128.load_8x8_s 0xFD, 1 MEMARG v128.load_8x8_u 0xFD, 2 MEMARG v128.load_16x4_s 0xFD, 3 MEMARG v128.load_16x4_u 0xFD, 4 MEMARG v128.load_32x2_s 0xFD, 5 MEMARG v128.load_32x2_u 0xFD, 6 MEMARG v128.load_8_splat 0xFD, 7 MEMARG v128.load_16_splat 0xFD, 8 MEMARG v128.load_32_splat 0xFD, 9 MEMARG v128.load_64_splat 0xFD, 10 MEMARG v128.load_32_zero 0xFD, 92 MEMARG v128.load_64_zero 0xFD, 93 MEMARG v128.store 0xFD, 11 MEMARG v128.load_8_lane 0xFD, 84 MEMARG_LANE v128.load_16_lane 0xFD, 85 MEMARG_LANE v128.load_32_lane 0xFD, 86 MEMARG_LANE v128.load_64_lane 0xFD, 87 MEMARG_LANE v128.store_8_lane 0xFD, 88 MEMARG_LANE v128.store_16_lane 0xFD, 89 MEMARG_LANE v128.store_32_lane 0xFD, 90 MEMARG_LANE v128.store_64_lane 0xFD, 91 MEMARG_LANE v128.const 0xFD, 12 V128 i8x16.shuffle 0xFD, 13 LANEx16 i8x16.extractlane_s 0xFD, 21 LANE i8x16.extractlane_u 0xFD, 22 LANE i8x16.replacelane 0xFD, 23 LANE i16x8.extractlane_s 0xFD, 24 LANE i16x8.extractlane_u 0xFD, 25 LANE i16x8.replacelane 0xFD, 26 LANE i32x4.extractlane 0xFD, 27 LANE i32x4.replacelane 0xFD, 28 LANE i64x2.extractlane 0xFD, 29 LANE i64x2.replacelane 0xFD, 30 LANE f32x4.extractlane 0xFD, 31 LANE f32x4.replacelane 0xFD, 32 LANE f64x2.extractlane 0xFD, 33 LANE f64x2.replacelane 0xFD, 34 LANE i8x16.swizzle 0xFD, 14 i8x16.splat 0xFD, 15 i16x8.splat 0xFD, 16 i32x4.splat 0xFD, 17 i64x2.splat 0xFD, 18 f32x4.splat 0xFD, 19 f64x2.splat 0xFD, 20 i8x16.eq 0xFD, 35 i8x16.ne 0xFD, 36 i8x16.lt_s 0xFD, 37 i8x16.lt_u 0xFD, 38 i8x16.gt_s 0xFD, 39 i8x16.gt_u 0xFD, 40 i8x16.le_s 0xFD, 41 i8x16.le_u 0xFD, 42 i8x16.ge_s 0xFD, 43 i8x16.ge_u 0xFD, 44 i16x8.eq 0xFD, 45 i16x8.ne 0xFD, 46 i16x8.lt_s 0xFD, 47 i16x8.lt_u 0xFD, 48 i16x8.gt_s 0xFD, 49 i16x8.gt_u 0xFD, 50 i16x8.le_s 0xFD, 51 i16x8.le_u 0xFD, 52 i16x8.ge_s 0xFD, 53 i16x8.ge_u 0xFD, 54 i32x4.eq 0xFD, 55 i32x4.ne 0xFD, 56 i32x4.lt_s 0xFD, 57 i32x4.lt_u 0xFD, 58 i32x4.gt_s 0xFD, 59 i32x4.gt_u 0xFD, 60 i32x4.le_s 0xFD, 61 i32x4.le_u 0xFD, 62 i32x4.ge_s 0xFD, 63 i32x4.ge_u 0xFD, 64 i64x2.eq 0xFD, 214 i64x2.ne 0xFD, 215 i64x2.lt_s 0xFD, 216 i64x2.gt_s 0xFD, 217 i64x2.le_s 0xFD, 218 i64x2.ge_s 0xFD, 219 f32x4.eq 0xFD, 65 f32x4.ne 0xFD, 66 f32x4.lt 0xFD, 67 f32x4.gt 0xFD, 68 f32x4.le 0xFD, 69 f32x4.ge 0xFD, 70 f64x2.eq 0xFD, 71 f64x2.ne 0xFD, 72 f64x2.lt 0xFD, 73 f64x2.gt 0xFD, 74 f64x2.le 0xFD, 75 f64x2.ge 0xFD, 76 v128.not 0xFD, 77 v128.and 0xFD, 78 v128.andnot 0xFD, 79 v128.or 0xFD, 80 v128.xor 0xFD, 81 v128.bitselect 0xFD, 82 v128.anytrue 0xFD, 83 i8x16.abs 0xFD, 96 i8x16.neg 0xFD, 97 i8x16.popcnt 0xFD, 98 i8x16.alltrue 0xFD, 99 i8x16.bitmask 0xFD, 100 i8x16.narrow_i16x8_s 0xFD, 101 i8x16.narrow_i16x8_u 0xFD, 102 i8x16.shl 0xFD, 107 i8x16.shr_s 0xFD, 108 i8x16.shr_u 0xFD, 109 i8x16.add 0xFD, 110 i8x16.add_sat_s 0xFD, 111 i8x16.add_sat_u 0xFD, 112 i8x16.sub 0xFD, 113 i8x16.sub_sat_s 0xFD, 114 i8x16.sub_sat_u 0xFD, 115 i8x16.min_s 0xFD, 118 i8x16.min_u 0xFD, 119 i8x16.max_s 0xFD, 120 i8x16.max_u 0xFD, 121 i8x16.avgr_u 0xFD, 123 i16x8.extaddpairwise_i8x16_s 0xFD, 124 i16x8.extaddpairwise_i8x16_u 0xFD, 125 i16x8.abs 0xFD, 128 i16x8.neg 0xFD, 129 i16x8.q15mulrsat_s 0xFD, 130 i16x8.alltrue 0xFD, 131 i16x8.bitmask 0xFD, 132 i16x8.narrow_i32x4_s 0xFD, 133 i16x8.narrow_i32x4_u 0xFD, 134 i16x8.extend_low_i8x16_s 0xFD, 135 i16x8.extend_high_i8x16_s 0xFD, 136 i16x8.extend_low_i8x16_u 0xFD, 137 i16x8.extend_high_i8x16_u 0xFD, 138 i16x8.shl 0xFD, 139 i16x8.shr_s 0xFD, 140 i16x8.shr_u 0xFD, 141 i16x8.add 0xFD, 142 i16x8.add_sat_s 0xFD, 143 i16x8.add_sat_u 0xFD, 144 i16x8.sub 0xFD, 145 i16x8.sub_sat_s 0xFD, 146 i16x8.sub_sat_u 0xFD, 147 i16x8.mul 0xFD, 149 i16x8.min_s 0xFD, 150 i16x8.min_u 0xFD, 151 i16x8.max_s 0xFD, 152 i16x8.max_u 0xFD, 153 i16x8.avgr_u 0xFD, 155 i16x8.extmul_low_i8x16_s 0xFD, 156 i16x8.extmul_high_i8x16_s 0xFD, 157 i16x8.extmul_low_i8x16_u 0xFD, 158 i16x8.extmul_high_i8x16_u 0xFD, 159 i32x4.extaddpairwise_i16x8_s 0xFD, 126 i32x4.extaddpairwise_i16x8_u 0xFD, 127 i32x4.abs 0xFD, 160 i32x4.neg 0xFD, 161 i32x4.alltrue 0xFD, 163 i32x4.bitmask 0xFD, 164 i32x4.extend_low_i16x8_s 0xFD, 167 i32x4.extend_high_i16x8_s 0xFD, 168 i32x4.extend_low_i16x8_u 0xFD, 169 i32x4.extend_high_i16x8_u 0xFD, 170 i32x4.shl 0xFD, 171 i32x4.shr_s 0xFD, 172 i32x4.shr_u 0xFD, 173 i32x4.add 0xFD, 174 i32x4.sub 0xFD, 177 i32x4.mul 0xFD, 181 i32x4.min_s 0xFD, 182 i32x4.min_u 0xFD, 183 i32x4.max_s 0xFD, 184 i32x4.max_u 0xFD, 185 i32x4.dot_i16x8_s 0xFD, 186 i32x4.extmul_low_i16x8_s 0xFD, 188 i32x4.extmul_high_i16x8_s 0xFD, 189 i32x4.extmul_low_i16x8_u 0xFD, 190 i32x4.extmul_high_i16x8_u 0xFD, 191 i64x2.abs 0xFD, 192 i64x2.neg 0xFD, 193 i64x2.alltrue 0xFD, 195 i64x2.bitmask 0xFD, 196 i64x2.extend_low_i32x4_s 0xFD, 199 i64x2.extend_high_i32x4_s 0xFD, 200 i64x2.extend_low_i32x4_u 0xFD, 201 i64x2.extend_high_i32x4_u 0xFD, 202 i64x2.shl 0xFD, 203 i64x2.shr_s 0xFD, 204 i64x2.shr_u 0xFD, 205 i64x2.add 0xFD, 206 i64x2.sub 0xFD, 209 i64x2.mul 0xFD, 213 i64x2.extmul_low_i32x4_s 0xFD, 220 i64x2.extmul_high_i32x4_s 0xFD, 221 i64x2.extmul_low_i32x4_u 0xFD, 222 i64x2.extmul_high_i32x4_u 0xFD, 223 f32x4.ceil 0xFD, 103 f32x4.floor 0xFD, 104 f32x4.trunc 0xFD, 105 f32x4.nearest 0xFD, 106 f32x4.abs 0xFD, 224 f32x4.neg 0xFD, 225 f32x4.sqrt 0xFD, 227 f32x4.add 0xFD, 228 f32x4.sub 0xFD, 229 f32x4.mul 0xFD, 230 f32x4.div 0xFD, 231 f32x4.min 0xFD, 232 f32x4.max 0xFD, 233 f32x4.pmin 0xFD, 234 f32x4.pmax 0xFD, 235 f64x2.ceil 0xFD, 116 f64x2.floor 0xFD, 117 f64x2.trunc 0xFD, 122 f64x2.nearest 0xFD, 148 f64x2.abs 0xFD, 236 f64x2.neg 0xFD, 237 f64x2.sqrt 0xFD, 239 f64x2.add 0xFD, 240 f64x2.sub 0xFD, 241 f64x2.mul 0xFD, 242 f64x2.div 0xFD, 243 f64x2.min 0xFD, 244 f64x2.max 0xFD, 245 f64x2.pmin 0xFD, 246 f64x2.pmax 0xFD, 247 i32x4.trunc_sat_f32x4_s 0xFD, 248 i32x4.trunc_sat_f32x4_u 0xFD, 249 f32x4.convert_i32x4_s 0xFD, 250 f32x4.convert_i32x4_u 0xFD, 251 i32x4.trunc_sat_f64x2_s_zero 0xFD, 252 i32x4.trunc_sat_f64x2_u_zero 0xFD, 253 f64x2.convert_low_i32x4_s 0xFD, 254 f64x2.convert_low_i32x4_u 0xFD, 255 f32x4.demote_f64x2_zero 0xFD, 94 f64x2.promote_low_f32x4 0xFD, 95 - atomics Instructions to operate on shared memory, where multiple threads are acessing the same location. memory.atomic.notify 0xFE, 0x00 MEMARG memory.atomic.wait32 0xFE, 0x01 MEMARG memory.atomic.wait64 0xFE, 0x02 MEMARG atomic.fence 0xFE, 0x03 ZEROB i32.atomic.load 0xFE, 0x10 MEMARG i64.atomic.load 0xFE, 0x11 MEMARG i32.atomic.load8_u 0xFE, 0x12 MEMARG i32.atomic.load16_u 0xFE, 0x13 MEMARG i64.atomic.load8_u 0xFE, 0x14 MEMARG i64.atomic.load16_u 0xFE, 0x15 MEMARG i64.atomic.load32_u 0xFE, 0x16 MEMARG i32.atomic.store 0xFE, 0x17 MEMARG i64.atomic.store 0xFE, 0x18 MEMARG i32.atomic.store8 0xFE, 0x19 MEMARG i32.atomic.store16 0xFE, 0x1A MEMARG i64.atomic.store8 0xFE, 0x1B MEMARG i64.atomic.store16 0xFE, 0x1C MEMARG i64.atomic.store32 0xFE, 0x1D MEMARG i32.atomic.rmw.add 0xFE, 0x1E MEMARG i64.atomic.rmw.add 0xFE, 0x1F MEMARG i32.atomic.rmw8.add_u 0xFE, 0x20 MEMARG i32.atomic.rmw16.add_u 0xFE, 0x21 MEMARG i64.atomic.rmw8.add_u 0xFE, 0x22 MEMARG i64.atomic.rmw16.add_u 0xFE, 0x23 MEMARG i64.atomic.rmw32.add_u 0xFE, 0x24 MEMARG i32.atomic.rmw.sub 0xFE, 0x25 MEMARG i64.atomic.rmw.sub 0xFE, 0x26 MEMARG i32.atomic.rmw8.sub_u 0xFE, 0x27 MEMARG i32.atomic.rmw16.sub_u 0xFE, 0x28 MEMARG i64.atomic.rmw8.sub_u 0xFE, 0x29 MEMARG i64.atomic.rmw16.sub_u 0xFE, 0x2A MEMARG i64.atomic.rmw32.sub_u 0xFE, 0x2B MEMARG i32.atomic.rmw.and 0xFE, 0x2C MEMARG i64.atomic.rmw.and 0xFE, 0x2D MEMARG i32.atomic.rmw8.and_u 0xFE, 0x2E MEMARG i32.atomic.rmw16.and_u 0xFE, 0x2F MEMARG i64.atomic.rmw8.and_u 0xFE, 0x30 MEMARG i64.atomic.rmw16.and_u 0xFE, 0x31 MEMARG i64.atomic.rmw32.and_u 0xFE, 0x32 MEMARG i32.atomic.rmw.or 0xFE, 0x33 MEMARG i64.atomic.rmw.or 0xFE, 0x34 MEMARG i32.atomic.rmw8.or_u 0xFE, 0x35 MEMARG i32.atomic.rmw16.or_u 0xFE, 0x36 MEMARG i64.atomic.rmw8.or_u 0xFE, 0x37 MEMARG i64.atomic.rmw16.or_u 0xFE, 0x38 MEMARG i64.atomic.rmw32.or_u 0xFE, 0x39 MEMARG i32.atomic.rmw.xor 0xFE, 0x3A MEMARG i64.atomic.rmw.xor 0xFE, 0x3B MEMARG i32.atomic.rmw8.xor_u 0xFE, 0x3C MEMARG i32.atomic.rmw16.xor_u 0xFE, 0x3D MEMARG i64.atomic.rmw8.xor_u 0xFE, 0x3E MEMARG i64.atomic.rmw16.xor_u 0xFE, 0x3F MEMARG i64.atomic.rmw32.xor_u 0xFE, 0x40 MEMARG i32.atomic.rmw.xchg 0xFE, 0x41 MEMARG i64.atomic.rmw.xchg 0xFE, 0x42 MEMARG i32.atomic.rmw8.xchg_u 0xFE, 0x43 MEMARG i32.atomic.rmw16.xchg_u 0xFE, 0x44 MEMARG i64.atomic.rmw8.xchg_u 0xFE, 0x45 MEMARG i64.atomic.rmw16.xchg_u 0xFE, 0x46 MEMARG i64.atomic.rmw32.xchg_u 0xFE, 0x47 MEMARG i32.atomic.rmw.cmpxchg 0xFE, 0x48 MEMARG i64.atomic.rmw.cmpxchg 0xFE, 0x49 MEMARG i32.atomic.rmw8.cmpxchg_u 0xFE, 0x4A MEMARG i32.atomic.rmw16.cmpxchg_u 0xFE, 0x4B MEMARG i64.atomic.rmw8.cmpxchg_u 0xFE, 0x4C MEMARG i64.atomic.rmw16.cmpxchg_u 0xFE, 0x4D MEMARG i64.atomic.rmw32.cmpxchg_u 0xFE, 0x4E MEMARG - proposed exception-handling bytecodes try 0x00, 0x06 BLOCKT catch 0x00, 0x07 TAG throw 0x00, 0x08 TAG rethrow 0x00, 0x09 delegate 0x00, 0x18 catch_all 0x00, 0x19 - proposed instructions for first-class functions call_ref 0x00, 0x14 SIG return_call_ref 0x00, 0x15 SIG - proposed instructions for new garbage-collection features. struct.new_canon 0xFB, 0x01 STRUCTT struct.new_canon_default 0xFB, 0x02 STRUCTT struct.get 0xFB, 0x03 STRUCTT_FIELD struct.get_s 0xFB, 0x04 STRUCTT_FIELD struct.get_u 0xFB, 0x05 STRUCTT_FIELD struct.set 0xFB, 0x06 STRUCTT_FIELD array.new_canon 0xFB, 0x11 ARRAYT array.new_canon_default 0xFB, 0x12 ARRAYT array.get 0xFB, 0x13 ARRAYT array.get_s 0xFB, 0x14 ARRAYT array.get_u 0xFB, 0x15 ARRAYT array.set 0xFB, 0x16 ARRAYT array.len 0xFB, 0x17 array.new_canon_fixed 0xFB, 0x19 ARRAYT_U32 array.new_canon_data 0xFB, 0x1B ARRAYT_DATA array.new_canon_elem 0xFB, 0x1C ARRAYT_ELEM i31.new 0xFB, 0x20 i31.get_s 0xFB, 0x21 i31.get_u 0xFB, 0x22 ref.test_canon 0xFB, 0x40 ref.cast_canon 0xFB, 0x41 br_on_cast_canon 0xFB, 0x42 LABEL br_on_cast_canon_fail 0xFB, 0x43 LABEL ref.is_data 0xFB, 0x51 ref.is_i31 0xFB, 0x52 ref.is_array 0xFB, 0x53 ref.as_data 0xFB, 0x59 ref.as_i31 0xFB, 0x5A ref.as_array 0xFB, 0x5B br_on_func 0xFB, 0x60 br_on_data 0xFB, 0x61 br_on_i31 0xFB, 0x62 br_on_non_func 0xFB, 0x63 br_on_non_data 0xFB, 0x64 br_on_non_i31 0xFB, 0x65 br_on_array 0xFB, 0x66 br_on_non_array 0xFB, 0x67