From b3ae05e1879db55686d681267b54aa348db120e1 Mon Sep 17 00:00:00 2001 From: Sam Estep Date: Fri, 24 Jan 2025 16:47:55 -0500 Subject: [PATCH 1/4] Delegate `Instruction` encoding to a new type --- crates/wasm-encoder/src/core.rs | 2 + crates/wasm-encoder/src/core/code.rs | 3116 +++--------- crates/wasm-encoder/src/core/instructions.rs | 4709 ++++++++++++++++++ 3 files changed, 5493 insertions(+), 2334 deletions(-) create mode 100644 crates/wasm-encoder/src/core/instructions.rs diff --git a/crates/wasm-encoder/src/core.rs b/crates/wasm-encoder/src/core.rs index 48ce15e7b8..ddd695812c 100644 --- a/crates/wasm-encoder/src/core.rs +++ b/crates/wasm-encoder/src/core.rs @@ -8,6 +8,7 @@ mod exports; mod functions; mod globals; mod imports; +mod instructions; mod linking; mod memories; mod names; @@ -27,6 +28,7 @@ pub use exports::*; pub use functions::*; pub use globals::*; pub use imports::*; +pub use instructions::*; pub use linking::*; pub use memories::*; pub use names::*; diff --git a/crates/wasm-encoder/src/core/code.rs b/crates/wasm-encoder/src/core/code.rs index 686b33cf59..1d4184cb61 100644 --- a/crates/wasm-encoder/src/core/code.rs +++ b/crates/wasm-encoder/src/core/code.rs @@ -1,4 +1,6 @@ -use crate::{encode_section, Encode, HeapType, RefType, Section, SectionId, ValType}; +use crate::{ + encode_section, Encode, HeapType, InstructionSink, RefType, Section, SectionId, ValType, +}; use alloc::borrow::Cow; use alloc::vec; use alloc::vec::Vec; @@ -216,6 +218,11 @@ impl Function { Function::new(locals_collected) } + /// Get an instruction encoder for this function body. + pub fn instructions(&mut self) -> InstructionSink { + InstructionSink::new(&mut self.bytes) + } + /// Write an instruction into this function body. pub fn instruction(&mut self, instruction: &Instruction) -> &mut Self { instruction.encode(&mut self.bytes); @@ -286,6 +293,116 @@ impl Encode for Function { } } +/// A Wasm _typeidx_. +#[derive(Clone, Copy, Debug)] +pub struct TypeIdx(pub u32); + +/// A Wasm _funcidx_. +#[derive(Clone, Copy, Debug)] +pub struct FuncIdx(pub u32); + +/// A Wasm _tableidx_. +#[derive(Clone, Copy, Debug)] +pub struct TableIdx(pub u32); + +/// A Wasm _memidx_. +#[derive(Clone, Copy, Debug)] +pub struct MemIdx(pub u32); + +/// A Wasm _tagidx_. +#[derive(Clone, Copy, Debug)] +pub struct TagIdx(pub u32); + +/// A Wasm _globalidx_. +#[derive(Clone, Copy, Debug)] +pub struct GlobalIdx(pub u32); + +/// A Wasm _elemidx_. +#[derive(Clone, Copy, Debug)] +pub struct ElemIdx(pub u32); + +/// A Wasm _dataidx_. +#[derive(Clone, Copy, Debug)] +pub struct DataIdx(pub u32); + +/// A Wasm _localidx_. +#[derive(Clone, Copy, Debug)] +pub struct LocalIdx(pub u32); + +/// A Wasm _labelidx_. +#[derive(Clone, Copy, Debug)] +pub struct LabelIdx(pub u32); + +/// A Wasm _fieldidx_. +#[derive(Clone, Copy, Debug)] +pub struct FieldIdx(pub u32); + +impl Encode for TypeIdx { + fn encode(&self, sink: &mut Vec) { + self.0.encode(sink); + } +} + +impl Encode for FuncIdx { + fn encode(&self, sink: &mut Vec) { + self.0.encode(sink); + } +} + +impl Encode for TableIdx { + fn encode(&self, sink: &mut Vec) { + self.0.encode(sink); + } +} + +impl Encode for MemIdx { + fn encode(&self, sink: &mut Vec) { + self.0.encode(sink); + } +} + +impl Encode for TagIdx { + fn encode(&self, sink: &mut Vec) { + self.0.encode(sink); + } +} + +impl Encode for GlobalIdx { + fn encode(&self, sink: &mut Vec) { + self.0.encode(sink); + } +} + +impl Encode for ElemIdx { + fn encode(&self, sink: &mut Vec) { + self.0.encode(sink); + } +} + +impl Encode for DataIdx { + fn encode(&self, sink: &mut Vec) { + self.0.encode(sink); + } +} + +impl Encode for LocalIdx { + fn encode(&self, sink: &mut Vec) { + self.0.encode(sink); + } +} + +impl Encode for LabelIdx { + fn encode(&self, sink: &mut Vec) { + self.0.encode(sink); + } +} + +impl Encode for FieldIdx { + fn encode(&self, sink: &mut Vec) { + self.0.encode(sink); + } +} + /// The immediate for a memory instruction. #[derive(Clone, Copy, Debug)] pub struct MemArg { @@ -1234,2554 +1351,885 @@ pub enum Instruction<'a> { } impl Encode for Instruction<'_> { - fn encode(&self, sink: &mut Vec) { + fn encode(&self, bytes: &mut Vec) { + let mut sink = InstructionSink::new(bytes); match *self { // Control instructions. - Instruction::Unreachable => sink.push(0x00), - Instruction::Nop => sink.push(0x01), - Instruction::Block(bt) => { - sink.push(0x02); - bt.encode(sink); - } - Instruction::Loop(bt) => { - sink.push(0x03); - bt.encode(sink); - } - Instruction::If(bt) => { - sink.push(0x04); - bt.encode(sink); - } - Instruction::Else => sink.push(0x05), - Instruction::Try(bt) => { - sink.push(0x06); - bt.encode(sink); - } - Instruction::Catch(t) => { - sink.push(0x07); - t.encode(sink); - } - Instruction::Throw(t) => { - sink.push(0x08); - t.encode(sink); - } - Instruction::Rethrow(l) => { - sink.push(0x09); - l.encode(sink); - } - Instruction::ThrowRef => { - sink.push(0x0A); - } - Instruction::End => sink.push(0x0B), - Instruction::Br(l) => { - sink.push(0x0C); - l.encode(sink); - } - Instruction::BrIf(l) => { - sink.push(0x0D); - l.encode(sink); - } + Instruction::Unreachable => sink.unreachable(), + Instruction::Nop => sink.nop(), + Instruction::Block(bt) => sink.block(bt), + Instruction::Loop(bt) => sink.loop_(bt), + Instruction::If(bt) => sink.if_(bt), + Instruction::Else => sink.else_(), + Instruction::Try(bt) => sink.try_(bt), + Instruction::Catch(t) => sink.catch(TagIdx(t)), + Instruction::Throw(t) => sink.throw(TagIdx(t)), + Instruction::Rethrow(l) => sink.rethrow(LabelIdx(l)), + Instruction::ThrowRef => sink.throw_ref(), + Instruction::End => sink.end(), + Instruction::Br(l) => sink.br(LabelIdx(l)), + Instruction::BrIf(l) => sink.br_if(LabelIdx(l)), Instruction::BrTable(ref ls, l) => { - sink.push(0x0E); - ls.encode(sink); - l.encode(sink); - } - Instruction::BrOnNull(l) => { - sink.push(0xD5); - l.encode(sink); - } - Instruction::BrOnNonNull(l) => { - sink.push(0xD6); - l.encode(sink); - } - Instruction::Return => sink.push(0x0F), - Instruction::Call(f) => { - sink.push(0x10); - f.encode(sink); - } - Instruction::CallRef(ty) => { - sink.push(0x14); - ty.encode(sink); + sink.br_table(ls.iter().copied().map(LabelIdx), LabelIdx(l)) } + Instruction::BrOnNull(l) => sink.br_on_null(LabelIdx(l)), + Instruction::BrOnNonNull(l) => sink.br_on_non_null(LabelIdx(l)), + Instruction::Return => sink.return_(), + Instruction::Call(f) => sink.call(FuncIdx(f)), + Instruction::CallRef(ty) => sink.call_ref(TypeIdx(ty)), Instruction::CallIndirect { type_index, table_index, - } => { - sink.push(0x11); - type_index.encode(sink); - table_index.encode(sink); - } - Instruction::ReturnCallRef(ty) => { - sink.push(0x15); - ty.encode(sink); - } + } => sink.call_indirect(TableIdx(table_index), TypeIdx(type_index)), + Instruction::ReturnCallRef(ty) => sink.return_call_ref(TypeIdx(ty)), - Instruction::ReturnCall(f) => { - sink.push(0x12); - f.encode(sink); - } + Instruction::ReturnCall(f) => sink.return_call(FuncIdx(f)), Instruction::ReturnCallIndirect { type_index, table_index, - } => { - sink.push(0x13); - type_index.encode(sink); - table_index.encode(sink); - } - Instruction::Delegate(l) => { - sink.push(0x18); - l.encode(sink); - } - Instruction::CatchAll => { - sink.push(0x19); - } + } => sink.return_call_indirect(TableIdx(table_index), TypeIdx(type_index)), + Instruction::Delegate(l) => sink.delegate(LabelIdx(l)), + Instruction::CatchAll => sink.catch_all(), // Parametric instructions. - Instruction::Drop => sink.push(0x1A), - Instruction::Select => sink.push(0x1B), - Instruction::TypedSelect(ty) => { - sink.push(0x1c); - [ty].encode(sink); - } + Instruction::Drop => sink.drop(), + Instruction::Select => sink.select(), + Instruction::TypedSelect(ty) => sink.typed_select(ty), - Instruction::TryTable(ty, ref catches) => { - sink.push(0x1f); - ty.encode(sink); - catches.encode(sink); - } + Instruction::TryTable(ty, ref catches) => sink.try_table(ty, catches.iter().cloned()), // Variable instructions. - Instruction::LocalGet(l) => { - sink.push(0x20); - l.encode(sink); - } - Instruction::LocalSet(l) => { - sink.push(0x21); - l.encode(sink); - } - Instruction::LocalTee(l) => { - sink.push(0x22); - l.encode(sink); - } - Instruction::GlobalGet(g) => { - sink.push(0x23); - g.encode(sink); - } - Instruction::GlobalSet(g) => { - sink.push(0x24); - g.encode(sink); - } - Instruction::TableGet(table) => { - sink.push(0x25); - table.encode(sink); - } - Instruction::TableSet(table) => { - sink.push(0x26); - table.encode(sink); - } + Instruction::LocalGet(l) => sink.local_get(LocalIdx(l)), + Instruction::LocalSet(l) => sink.local_set(LocalIdx(l)), + Instruction::LocalTee(l) => sink.local_tee(LocalIdx(l)), + Instruction::GlobalGet(g) => sink.global_get(GlobalIdx(g)), + Instruction::GlobalSet(g) => sink.global_set(GlobalIdx(g)), + Instruction::TableGet(table) => sink.table_get(TableIdx(table)), + Instruction::TableSet(table) => sink.table_set(TableIdx(table)), // Memory instructions. - Instruction::I32Load(m) => { - sink.push(0x28); - m.encode(sink); - } - Instruction::I64Load(m) => { - sink.push(0x29); - m.encode(sink); - } - Instruction::F32Load(m) => { - sink.push(0x2A); - m.encode(sink); - } - Instruction::F64Load(m) => { - sink.push(0x2B); - m.encode(sink); - } - Instruction::I32Load8S(m) => { - sink.push(0x2C); - m.encode(sink); - } - Instruction::I32Load8U(m) => { - sink.push(0x2D); - m.encode(sink); - } - Instruction::I32Load16S(m) => { - sink.push(0x2E); - m.encode(sink); - } - Instruction::I32Load16U(m) => { - sink.push(0x2F); - m.encode(sink); - } - Instruction::I64Load8S(m) => { - sink.push(0x30); - m.encode(sink); - } - Instruction::I64Load8U(m) => { - sink.push(0x31); - m.encode(sink); - } - Instruction::I64Load16S(m) => { - sink.push(0x32); - m.encode(sink); - } - Instruction::I64Load16U(m) => { - sink.push(0x33); - m.encode(sink); - } - Instruction::I64Load32S(m) => { - sink.push(0x34); - m.encode(sink); - } - Instruction::I64Load32U(m) => { - sink.push(0x35); - m.encode(sink); - } - Instruction::I32Store(m) => { - sink.push(0x36); - m.encode(sink); - } - Instruction::I64Store(m) => { - sink.push(0x37); - m.encode(sink); - } - Instruction::F32Store(m) => { - sink.push(0x38); - m.encode(sink); - } - Instruction::F64Store(m) => { - sink.push(0x39); - m.encode(sink); - } - Instruction::I32Store8(m) => { - sink.push(0x3A); - m.encode(sink); - } - Instruction::I32Store16(m) => { - sink.push(0x3B); - m.encode(sink); - } - Instruction::I64Store8(m) => { - sink.push(0x3C); - m.encode(sink); - } - Instruction::I64Store16(m) => { - sink.push(0x3D); - m.encode(sink); - } - Instruction::I64Store32(m) => { - sink.push(0x3E); - m.encode(sink); - } - Instruction::MemorySize(i) => { - sink.push(0x3F); - i.encode(sink); - } - Instruction::MemoryGrow(i) => { - sink.push(0x40); - i.encode(sink); - } + Instruction::I32Load(m) => sink.i32_load(m), + Instruction::I64Load(m) => sink.i64_load(m), + Instruction::F32Load(m) => sink.f32_load(m), + Instruction::F64Load(m) => sink.f64_load(m), + Instruction::I32Load8S(m) => sink.i32_load8_s(m), + Instruction::I32Load8U(m) => sink.i32_load8_u(m), + Instruction::I32Load16S(m) => sink.i32_load16_s(m), + Instruction::I32Load16U(m) => sink.i32_load16_u(m), + Instruction::I64Load8S(m) => sink.i64_load8_s(m), + Instruction::I64Load8U(m) => sink.i64_load8_u(m), + Instruction::I64Load16S(m) => sink.i64_load16_s(m), + Instruction::I64Load16U(m) => sink.i64_load16_u(m), + Instruction::I64Load32S(m) => sink.i64_load32_s(m), + Instruction::I64Load32U(m) => sink.i64_load32_u(m), + Instruction::I32Store(m) => sink.i32_store(m), + Instruction::I64Store(m) => sink.i64_store(m), + Instruction::F32Store(m) => sink.f32_store(m), + Instruction::F64Store(m) => sink.f64_store(m), + Instruction::I32Store8(m) => sink.i32_store8(m), + Instruction::I32Store16(m) => sink.i32_store16(m), + Instruction::I64Store8(m) => sink.i64_store8(m), + Instruction::I64Store16(m) => sink.i64_store16(m), + Instruction::I64Store32(m) => sink.i64_store32(m), + Instruction::MemorySize(i) => sink.memory_size(MemIdx(i)), + Instruction::MemoryGrow(i) => sink.memory_grow(MemIdx(i)), Instruction::MemoryInit { mem, data_index } => { - sink.push(0xfc); - sink.push(0x08); - data_index.encode(sink); - mem.encode(sink); - } - Instruction::DataDrop(data) => { - sink.push(0xfc); - sink.push(0x09); - data.encode(sink); + sink.memory_init(MemIdx(mem), DataIdx(data_index)) } + Instruction::DataDrop(data) => sink.data_drop(DataIdx(data)), Instruction::MemoryCopy { src_mem, dst_mem } => { - sink.push(0xfc); - sink.push(0x0a); - dst_mem.encode(sink); - src_mem.encode(sink); - } - Instruction::MemoryFill(mem) => { - sink.push(0xfc); - sink.push(0x0b); - mem.encode(sink); - } - Instruction::MemoryDiscard(mem) => { - sink.push(0xfc); - sink.push(0x12); - mem.encode(sink); + sink.memory_copy(MemIdx(dst_mem), MemIdx(src_mem)) } + Instruction::MemoryFill(mem) => sink.memory_fill(MemIdx(mem)), + Instruction::MemoryDiscard(mem) => sink.memory_discard(MemIdx(mem)), // Numeric instructions. - Instruction::I32Const(x) => { - sink.push(0x41); - x.encode(sink); - } - Instruction::I64Const(x) => { - sink.push(0x42); - x.encode(sink); - } - Instruction::F32Const(x) => { - sink.push(0x43); - let x = x.to_bits(); - sink.extend(x.to_le_bytes().iter().copied()); - } - Instruction::F64Const(x) => { - sink.push(0x44); - let x = x.to_bits(); - sink.extend(x.to_le_bytes().iter().copied()); - } - Instruction::I32Eqz => sink.push(0x45), - Instruction::I32Eq => sink.push(0x46), - Instruction::I32Ne => sink.push(0x47), - Instruction::I32LtS => sink.push(0x48), - Instruction::I32LtU => sink.push(0x49), - Instruction::I32GtS => sink.push(0x4A), - Instruction::I32GtU => sink.push(0x4B), - Instruction::I32LeS => sink.push(0x4C), - Instruction::I32LeU => sink.push(0x4D), - Instruction::I32GeS => sink.push(0x4E), - Instruction::I32GeU => sink.push(0x4F), - Instruction::I64Eqz => sink.push(0x50), - Instruction::I64Eq => sink.push(0x51), - Instruction::I64Ne => sink.push(0x52), - Instruction::I64LtS => sink.push(0x53), - Instruction::I64LtU => sink.push(0x54), - Instruction::I64GtS => sink.push(0x55), - Instruction::I64GtU => sink.push(0x56), - Instruction::I64LeS => sink.push(0x57), - Instruction::I64LeU => sink.push(0x58), - Instruction::I64GeS => sink.push(0x59), - Instruction::I64GeU => sink.push(0x5A), - Instruction::F32Eq => sink.push(0x5B), - Instruction::F32Ne => sink.push(0x5C), - Instruction::F32Lt => sink.push(0x5D), - Instruction::F32Gt => sink.push(0x5E), - Instruction::F32Le => sink.push(0x5F), - Instruction::F32Ge => sink.push(0x60), - Instruction::F64Eq => sink.push(0x61), - Instruction::F64Ne => sink.push(0x62), - Instruction::F64Lt => sink.push(0x63), - Instruction::F64Gt => sink.push(0x64), - Instruction::F64Le => sink.push(0x65), - Instruction::F64Ge => sink.push(0x66), - Instruction::I32Clz => sink.push(0x67), - Instruction::I32Ctz => sink.push(0x68), - Instruction::I32Popcnt => sink.push(0x69), - Instruction::I32Add => sink.push(0x6A), - Instruction::I32Sub => sink.push(0x6B), - Instruction::I32Mul => sink.push(0x6C), - Instruction::I32DivS => sink.push(0x6D), - Instruction::I32DivU => sink.push(0x6E), - Instruction::I32RemS => sink.push(0x6F), - Instruction::I32RemU => sink.push(0x70), - Instruction::I32And => sink.push(0x71), - Instruction::I32Or => sink.push(0x72), - Instruction::I32Xor => sink.push(0x73), - Instruction::I32Shl => sink.push(0x74), - Instruction::I32ShrS => sink.push(0x75), - Instruction::I32ShrU => sink.push(0x76), - Instruction::I32Rotl => sink.push(0x77), - Instruction::I32Rotr => sink.push(0x78), - Instruction::I64Clz => sink.push(0x79), - Instruction::I64Ctz => sink.push(0x7A), - Instruction::I64Popcnt => sink.push(0x7B), - Instruction::I64Add => sink.push(0x7C), - Instruction::I64Sub => sink.push(0x7D), - Instruction::I64Mul => sink.push(0x7E), - Instruction::I64DivS => sink.push(0x7F), - Instruction::I64DivU => sink.push(0x80), - Instruction::I64RemS => sink.push(0x81), - Instruction::I64RemU => sink.push(0x82), - Instruction::I64And => sink.push(0x83), - Instruction::I64Or => sink.push(0x84), - Instruction::I64Xor => sink.push(0x85), - Instruction::I64Shl => sink.push(0x86), - Instruction::I64ShrS => sink.push(0x87), - Instruction::I64ShrU => sink.push(0x88), - Instruction::I64Rotl => sink.push(0x89), - Instruction::I64Rotr => sink.push(0x8A), - Instruction::F32Abs => sink.push(0x8B), - Instruction::F32Neg => sink.push(0x8C), - Instruction::F32Ceil => sink.push(0x8D), - Instruction::F32Floor => sink.push(0x8E), - Instruction::F32Trunc => sink.push(0x8F), - Instruction::F32Nearest => sink.push(0x90), - Instruction::F32Sqrt => sink.push(0x91), - Instruction::F32Add => sink.push(0x92), - Instruction::F32Sub => sink.push(0x93), - Instruction::F32Mul => sink.push(0x94), - Instruction::F32Div => sink.push(0x95), - Instruction::F32Min => sink.push(0x96), - Instruction::F32Max => sink.push(0x97), - Instruction::F32Copysign => sink.push(0x98), - Instruction::F64Abs => sink.push(0x99), - Instruction::F64Neg => sink.push(0x9A), - Instruction::F64Ceil => sink.push(0x9B), - Instruction::F64Floor => sink.push(0x9C), - Instruction::F64Trunc => sink.push(0x9D), - Instruction::F64Nearest => sink.push(0x9E), - Instruction::F64Sqrt => sink.push(0x9F), - Instruction::F64Add => sink.push(0xA0), - Instruction::F64Sub => sink.push(0xA1), - Instruction::F64Mul => sink.push(0xA2), - Instruction::F64Div => sink.push(0xA3), - Instruction::F64Min => sink.push(0xA4), - Instruction::F64Max => sink.push(0xA5), - Instruction::F64Copysign => sink.push(0xA6), - Instruction::I32WrapI64 => sink.push(0xA7), - Instruction::I32TruncF32S => sink.push(0xA8), - Instruction::I32TruncF32U => sink.push(0xA9), - Instruction::I32TruncF64S => sink.push(0xAA), - Instruction::I32TruncF64U => sink.push(0xAB), - Instruction::I64ExtendI32S => sink.push(0xAC), - Instruction::I64ExtendI32U => sink.push(0xAD), - Instruction::I64TruncF32S => sink.push(0xAE), - Instruction::I64TruncF32U => sink.push(0xAF), - Instruction::I64TruncF64S => sink.push(0xB0), - Instruction::I64TruncF64U => sink.push(0xB1), - Instruction::F32ConvertI32S => sink.push(0xB2), - Instruction::F32ConvertI32U => sink.push(0xB3), - Instruction::F32ConvertI64S => sink.push(0xB4), - Instruction::F32ConvertI64U => sink.push(0xB5), - Instruction::F32DemoteF64 => sink.push(0xB6), - Instruction::F64ConvertI32S => sink.push(0xB7), - Instruction::F64ConvertI32U => sink.push(0xB8), - Instruction::F64ConvertI64S => sink.push(0xB9), - Instruction::F64ConvertI64U => sink.push(0xBA), - Instruction::F64PromoteF32 => sink.push(0xBB), - Instruction::I32ReinterpretF32 => sink.push(0xBC), - Instruction::I64ReinterpretF64 => sink.push(0xBD), - Instruction::F32ReinterpretI32 => sink.push(0xBE), - Instruction::F64ReinterpretI64 => sink.push(0xBF), - Instruction::I32Extend8S => sink.push(0xC0), - Instruction::I32Extend16S => sink.push(0xC1), - Instruction::I64Extend8S => sink.push(0xC2), - Instruction::I64Extend16S => sink.push(0xC3), - Instruction::I64Extend32S => sink.push(0xC4), - - Instruction::I32TruncSatF32S => { - sink.push(0xFC); - sink.push(0x00); - } - Instruction::I32TruncSatF32U => { - sink.push(0xFC); - sink.push(0x01); - } - Instruction::I32TruncSatF64S => { - sink.push(0xFC); - sink.push(0x02); - } - Instruction::I32TruncSatF64U => { - sink.push(0xFC); - sink.push(0x03); - } - Instruction::I64TruncSatF32S => { - sink.push(0xFC); - sink.push(0x04); - } - Instruction::I64TruncSatF32U => { - sink.push(0xFC); - sink.push(0x05); - } - Instruction::I64TruncSatF64S => { - sink.push(0xFC); - sink.push(0x06); - } - Instruction::I64TruncSatF64U => { - sink.push(0xFC); - sink.push(0x07); - } + Instruction::I32Const(x) => sink.i32_const(x), + Instruction::I64Const(x) => sink.i64_const(x), + Instruction::F32Const(x) => sink.f32_const(x), + Instruction::F64Const(x) => sink.f64_const(x), + Instruction::I32Eqz => sink.i32_eqz(), + Instruction::I32Eq => sink.i32_eq(), + Instruction::I32Ne => sink.i32_ne(), + Instruction::I32LtS => sink.i32_lt_s(), + Instruction::I32LtU => sink.i32_lt_u(), + Instruction::I32GtS => sink.i32_gt_s(), + Instruction::I32GtU => sink.i32_gt_u(), + Instruction::I32LeS => sink.i32_le_s(), + Instruction::I32LeU => sink.i32_le_u(), + Instruction::I32GeS => sink.i32_ge_s(), + Instruction::I32GeU => sink.i32_ge_u(), + Instruction::I64Eqz => sink.i64_eqz(), + Instruction::I64Eq => sink.i64_eq(), + Instruction::I64Ne => sink.i64_ne(), + Instruction::I64LtS => sink.i64_lt_s(), + Instruction::I64LtU => sink.i64_lt_u(), + Instruction::I64GtS => sink.i64_gt_s(), + Instruction::I64GtU => sink.i64_gt_u(), + Instruction::I64LeS => sink.i64_le_s(), + Instruction::I64LeU => sink.i64_le_u(), + Instruction::I64GeS => sink.i64_ge_s(), + Instruction::I64GeU => sink.i64_ge_u(), + Instruction::F32Eq => sink.f32_eq(), + Instruction::F32Ne => sink.f32_ne(), + Instruction::F32Lt => sink.f32_lt(), + Instruction::F32Gt => sink.f32_gt(), + Instruction::F32Le => sink.f32_le(), + Instruction::F32Ge => sink.f32_ge(), + Instruction::F64Eq => sink.f64_eq(), + Instruction::F64Ne => sink.f64_ne(), + Instruction::F64Lt => sink.f64_lt(), + Instruction::F64Gt => sink.f64_gt(), + Instruction::F64Le => sink.f64_le(), + Instruction::F64Ge => sink.f64_ge(), + Instruction::I32Clz => sink.i32_clz(), + Instruction::I32Ctz => sink.i32_ctz(), + Instruction::I32Popcnt => sink.i32_popcnt(), + Instruction::I32Add => sink.i32_add(), + Instruction::I32Sub => sink.i32_sub(), + Instruction::I32Mul => sink.i32_mul(), + Instruction::I32DivS => sink.i32_div_s(), + Instruction::I32DivU => sink.i32_div_u(), + Instruction::I32RemS => sink.i32_rem_s(), + Instruction::I32RemU => sink.i32_rem_u(), + Instruction::I32And => sink.i32_and(), + Instruction::I32Or => sink.i32_or(), + Instruction::I32Xor => sink.i32_xor(), + Instruction::I32Shl => sink.i32_shl(), + Instruction::I32ShrS => sink.i32_shr_s(), + Instruction::I32ShrU => sink.i32_shr_u(), + Instruction::I32Rotl => sink.i32_rotl(), + Instruction::I32Rotr => sink.i32_rotr(), + Instruction::I64Clz => sink.i64_clz(), + Instruction::I64Ctz => sink.i64_ctz(), + Instruction::I64Popcnt => sink.i64_popcnt(), + Instruction::I64Add => sink.i64_add(), + Instruction::I64Sub => sink.i64_sub(), + Instruction::I64Mul => sink.i64_mul(), + Instruction::I64DivS => sink.i64_div_s(), + Instruction::I64DivU => sink.i64_div_u(), + Instruction::I64RemS => sink.i64_rem_s(), + Instruction::I64RemU => sink.i64_rem_u(), + Instruction::I64And => sink.i64_and(), + Instruction::I64Or => sink.i64_or(), + Instruction::I64Xor => sink.i64_xor(), + Instruction::I64Shl => sink.i64_shl(), + Instruction::I64ShrS => sink.i64_shr_s(), + Instruction::I64ShrU => sink.i64_shr_u(), + Instruction::I64Rotl => sink.i64_rotl(), + Instruction::I64Rotr => sink.i64_rotr(), + Instruction::F32Abs => sink.f32_abs(), + Instruction::F32Neg => sink.f32_neg(), + Instruction::F32Ceil => sink.f32_ceil(), + Instruction::F32Floor => sink.f32_floor(), + Instruction::F32Trunc => sink.f32_trunc(), + Instruction::F32Nearest => sink.f32_nearest(), + Instruction::F32Sqrt => sink.f32_sqrt(), + Instruction::F32Add => sink.f32_add(), + Instruction::F32Sub => sink.f32_sub(), + Instruction::F32Mul => sink.f32_mul(), + Instruction::F32Div => sink.f32_div(), + Instruction::F32Min => sink.f32_min(), + Instruction::F32Max => sink.f32_max(), + Instruction::F32Copysign => sink.f32_copysign(), + Instruction::F64Abs => sink.f64_abs(), + Instruction::F64Neg => sink.f64_neg(), + Instruction::F64Ceil => sink.f64_ceil(), + Instruction::F64Floor => sink.f64_floor(), + Instruction::F64Trunc => sink.f64_trunc(), + Instruction::F64Nearest => sink.f64_nearest(), + Instruction::F64Sqrt => sink.f64_sqrt(), + Instruction::F64Add => sink.f64_add(), + Instruction::F64Sub => sink.f64_sub(), + Instruction::F64Mul => sink.f64_mul(), + Instruction::F64Div => sink.f64_div(), + Instruction::F64Min => sink.f64_min(), + Instruction::F64Max => sink.f64_max(), + Instruction::F64Copysign => sink.f64_copysign(), + Instruction::I32WrapI64 => sink.i32_wrap_i64(), + Instruction::I32TruncF32S => sink.i32_trunc_f32_s(), + Instruction::I32TruncF32U => sink.i32_trunc_f32_u(), + Instruction::I32TruncF64S => sink.i32_trunc_f64_s(), + Instruction::I32TruncF64U => sink.i32_trunc_f64_u(), + Instruction::I64ExtendI32S => sink.i64_extend_i32_s(), + Instruction::I64ExtendI32U => sink.i64_extend_i32_u(), + Instruction::I64TruncF32S => sink.i64_trunc_f32_s(), + Instruction::I64TruncF32U => sink.i64_trunc_f32_u(), + Instruction::I64TruncF64S => sink.i64_trunc_f64_s(), + Instruction::I64TruncF64U => sink.i64_trunc_f64_u(), + Instruction::F32ConvertI32S => sink.f32_convert_i32_s(), + Instruction::F32ConvertI32U => sink.f32_convert_i32_u(), + Instruction::F32ConvertI64S => sink.f32_convert_i64_s(), + Instruction::F32ConvertI64U => sink.f32_convert_i64_u(), + Instruction::F32DemoteF64 => sink.f32_demote_f64(), + Instruction::F64ConvertI32S => sink.f64_convert_i32_s(), + Instruction::F64ConvertI32U => sink.f64_convert_i32_u(), + Instruction::F64ConvertI64S => sink.f64_convert_i64_s(), + Instruction::F64ConvertI64U => sink.f64_convert_i64_u(), + Instruction::F64PromoteF32 => sink.f64_promote_f32(), + Instruction::I32ReinterpretF32 => sink.i32_reinterpret_f32(), + Instruction::I64ReinterpretF64 => sink.i64_reinterpret_f64(), + Instruction::F32ReinterpretI32 => sink.f32_reinterpret_i32(), + Instruction::F64ReinterpretI64 => sink.f64_reinterpret_i64(), + Instruction::I32Extend8S => sink.i32_extend8_s(), + Instruction::I32Extend16S => sink.i32_extend16_s(), + Instruction::I64Extend8S => sink.i64_extend8_s(), + Instruction::I64Extend16S => sink.i64_extend16_s(), + Instruction::I64Extend32S => sink.i64_extend32_s(), + + Instruction::I32TruncSatF32S => sink.i32_trunc_sat_f32_s(), + Instruction::I32TruncSatF32U => sink.i32_trunc_sat_f32_u(), + Instruction::I32TruncSatF64S => sink.i32_trunc_sat_f64_s(), + Instruction::I32TruncSatF64U => sink.i32_trunc_sat_f64_u(), + Instruction::I64TruncSatF32S => sink.i64_trunc_sat_f32_s(), + Instruction::I64TruncSatF32U => sink.i64_trunc_sat_f32_u(), + Instruction::I64TruncSatF64S => sink.i64_trunc_sat_f64_s(), + Instruction::I64TruncSatF64U => sink.i64_trunc_sat_f64_u(), // Reference types instructions. - Instruction::RefNull(ty) => { - sink.push(0xd0); - ty.encode(sink); - } - Instruction::RefIsNull => sink.push(0xd1), - Instruction::RefFunc(f) => { - sink.push(0xd2); - f.encode(sink); - } - Instruction::RefEq => sink.push(0xd3), - Instruction::RefAsNonNull => sink.push(0xd4), + Instruction::RefNull(ty) => sink.ref_null(ty), + Instruction::RefIsNull => sink.ref_is_null(), + Instruction::RefFunc(f) => sink.ref_func(FuncIdx(f)), + Instruction::RefEq => sink.ref_eq(), + Instruction::RefAsNonNull => sink.ref_as_non_null(), // GC instructions. - Instruction::StructNew(type_index) => { - sink.push(0xfb); - sink.push(0x00); - type_index.encode(sink); - } + Instruction::StructNew(type_index) => sink.struct_new(TypeIdx(type_index)), Instruction::StructNewDefault(type_index) => { - sink.push(0xfb); - sink.push(0x01); - type_index.encode(sink); + sink.struct_new_default(TypeIdx(type_index)) } Instruction::StructGet { struct_type_index, field_index, - } => { - sink.push(0xfb); - sink.push(0x02); - struct_type_index.encode(sink); - field_index.encode(sink); - } + } => sink.struct_get(TypeIdx(struct_type_index), FieldIdx(field_index)), Instruction::StructGetS { struct_type_index, field_index, - } => { - sink.push(0xfb); - sink.push(0x03); - struct_type_index.encode(sink); - field_index.encode(sink); - } + } => sink.struct_get_s(TypeIdx(struct_type_index), FieldIdx(field_index)), Instruction::StructGetU { struct_type_index, field_index, - } => { - sink.push(0xfb); - sink.push(0x04); - struct_type_index.encode(sink); - field_index.encode(sink); - } + } => sink.struct_get_u(TypeIdx(struct_type_index), FieldIdx(field_index)), Instruction::StructSet { struct_type_index, field_index, - } => { - sink.push(0xfb); - sink.push(0x05); - struct_type_index.encode(sink); - field_index.encode(sink); - } - Instruction::ArrayNew(type_index) => { - sink.push(0xfb); - sink.push(0x06); - type_index.encode(sink); - } - Instruction::ArrayNewDefault(type_index) => { - sink.push(0xfb); - sink.push(0x07); - type_index.encode(sink); - } + } => sink.struct_set(TypeIdx(struct_type_index), FieldIdx(field_index)), + Instruction::ArrayNew(type_index) => sink.array_new(TypeIdx(type_index)), + Instruction::ArrayNewDefault(type_index) => sink.array_new_default(TypeIdx(type_index)), Instruction::ArrayNewFixed { array_type_index, array_size, - } => { - sink.push(0xfb); - sink.push(0x08); - array_type_index.encode(sink); - array_size.encode(sink); - } + } => sink.array_new_fixed(TypeIdx(array_type_index), array_size), Instruction::ArrayNewData { array_type_index, array_data_index, - } => { - sink.push(0xfb); - sink.push(0x09); - array_type_index.encode(sink); - array_data_index.encode(sink); - } + } => sink.array_new_data(TypeIdx(array_type_index), DataIdx(array_data_index)), Instruction::ArrayNewElem { array_type_index, array_elem_index, - } => { - sink.push(0xfb); - sink.push(0x0a); - array_type_index.encode(sink); - array_elem_index.encode(sink); - } - Instruction::ArrayGet(type_index) => { - sink.push(0xfb); - sink.push(0x0b); - type_index.encode(sink); - } - Instruction::ArrayGetS(type_index) => { - sink.push(0xfb); - sink.push(0x0c); - type_index.encode(sink); - } - Instruction::ArrayGetU(type_index) => { - sink.push(0xfb); - sink.push(0x0d); - type_index.encode(sink); - } - Instruction::ArraySet(type_index) => { - sink.push(0xfb); - sink.push(0x0e); - type_index.encode(sink); - } - Instruction::ArrayLen => { - sink.push(0xfb); - sink.push(0x0f); - } - Instruction::ArrayFill(type_index) => { - sink.push(0xfb); - sink.push(0x10); - type_index.encode(sink); - } + } => sink.array_new_elem(TypeIdx(array_type_index), ElemIdx(array_elem_index)), + Instruction::ArrayGet(type_index) => sink.array_get(TypeIdx(type_index)), + Instruction::ArrayGetS(type_index) => sink.array_get_s(TypeIdx(type_index)), + Instruction::ArrayGetU(type_index) => sink.array_get_u(TypeIdx(type_index)), + Instruction::ArraySet(type_index) => sink.array_set(TypeIdx(type_index)), + Instruction::ArrayLen => sink.array_len(), + Instruction::ArrayFill(type_index) => sink.array_fill(TypeIdx(type_index)), Instruction::ArrayCopy { array_type_index_dst, array_type_index_src, - } => { - sink.push(0xfb); - sink.push(0x11); - array_type_index_dst.encode(sink); - array_type_index_src.encode(sink); - } + } => sink.array_copy(TypeIdx(array_type_index_dst), TypeIdx(array_type_index_src)), Instruction::ArrayInitData { array_type_index, array_data_index, - } => { - sink.push(0xfb); - sink.push(0x12); - array_type_index.encode(sink); - array_data_index.encode(sink); - } + } => sink.array_init_data(TypeIdx(array_type_index), DataIdx(array_data_index)), Instruction::ArrayInitElem { array_type_index, array_elem_index, - } => { - sink.push(0xfb); - sink.push(0x13); - array_type_index.encode(sink); - array_elem_index.encode(sink); - } - Instruction::RefTestNonNull(heap_type) => { - sink.push(0xfb); - sink.push(0x14); - heap_type.encode(sink); - } - Instruction::RefTestNullable(heap_type) => { - sink.push(0xfb); - sink.push(0x15); - heap_type.encode(sink); - } - Instruction::RefCastNonNull(heap_type) => { - sink.push(0xfb); - sink.push(0x16); - heap_type.encode(sink); - } - Instruction::RefCastNullable(heap_type) => { - sink.push(0xfb); - sink.push(0x17); - heap_type.encode(sink); - } + } => sink.array_init_elem(TypeIdx(array_type_index), ElemIdx(array_elem_index)), + Instruction::RefTestNonNull(heap_type) => sink.ref_test_non_null(heap_type), + Instruction::RefTestNullable(heap_type) => sink.ref_test_nullable(heap_type), + Instruction::RefCastNonNull(heap_type) => sink.ref_cast_non_null(heap_type), + Instruction::RefCastNullable(heap_type) => sink.ref_cast_nullable(heap_type), Instruction::BrOnCast { relative_depth, from_ref_type, to_ref_type, - } => { - sink.push(0xfb); - sink.push(0x18); - let cast_flags = - (from_ref_type.nullable as u8) | ((to_ref_type.nullable as u8) << 1); - sink.push(cast_flags); - relative_depth.encode(sink); - from_ref_type.heap_type.encode(sink); - to_ref_type.heap_type.encode(sink); - } + } => sink.br_on_cast(LabelIdx(relative_depth), from_ref_type, to_ref_type), Instruction::BrOnCastFail { relative_depth, from_ref_type, to_ref_type, - } => { - sink.push(0xfb); - sink.push(0x19); - let cast_flags = - (from_ref_type.nullable as u8) | ((to_ref_type.nullable as u8) << 1); - sink.push(cast_flags); - relative_depth.encode(sink); - from_ref_type.heap_type.encode(sink); - to_ref_type.heap_type.encode(sink); - } - Instruction::AnyConvertExtern => { - sink.push(0xfb); - sink.push(0x1a); - } - Instruction::ExternConvertAny => { - sink.push(0xfb); - sink.push(0x1b); - } - Instruction::RefI31 => { - sink.push(0xfb); - sink.push(0x1c); - } - Instruction::I31GetS => { - sink.push(0xfb); - sink.push(0x1d); - } - Instruction::I31GetU => { - sink.push(0xfb); - sink.push(0x1e); - } + } => sink.br_on_cast_fail(LabelIdx(relative_depth), from_ref_type, to_ref_type), + Instruction::AnyConvertExtern => sink.any_convert_extern(), + Instruction::ExternConvertAny => sink.extern_convert_any(), + Instruction::RefI31 => sink.ref_i31(), + Instruction::I31GetS => sink.i31_get_s(), + Instruction::I31GetU => sink.i31_get_u(), // Bulk memory instructions. Instruction::TableInit { elem_index, table } => { - sink.push(0xfc); - sink.push(0x0c); - elem_index.encode(sink); - table.encode(sink); - } - Instruction::ElemDrop(segment) => { - sink.push(0xfc); - sink.push(0x0d); - segment.encode(sink); + sink.table_init(TableIdx(table), ElemIdx(elem_index)) } + Instruction::ElemDrop(segment) => sink.elem_drop(ElemIdx(segment)), Instruction::TableCopy { src_table, dst_table, - } => { - sink.push(0xfc); - sink.push(0x0e); - dst_table.encode(sink); - src_table.encode(sink); - } - Instruction::TableGrow(table) => { - sink.push(0xfc); - sink.push(0x0f); - table.encode(sink); - } - Instruction::TableSize(table) => { - sink.push(0xfc); - sink.push(0x10); - table.encode(sink); - } - Instruction::TableFill(table) => { - sink.push(0xfc); - sink.push(0x11); - table.encode(sink); - } + } => sink.table_copy(TableIdx(dst_table), TableIdx(src_table)), + Instruction::TableGrow(table) => sink.table_grow(TableIdx(table)), + Instruction::TableSize(table) => sink.table_size(TableIdx(table)), + Instruction::TableFill(table) => sink.table_fill(TableIdx(table)), // SIMD instructions. - Instruction::V128Load(memarg) => { - sink.push(0xFD); - 0x00u32.encode(sink); - memarg.encode(sink); - } - Instruction::V128Load8x8S(memarg) => { - sink.push(0xFD); - 0x01u32.encode(sink); - memarg.encode(sink); - } - Instruction::V128Load8x8U(memarg) => { - sink.push(0xFD); - 0x02u32.encode(sink); - memarg.encode(sink); - } - Instruction::V128Load16x4S(memarg) => { - sink.push(0xFD); - 0x03u32.encode(sink); - memarg.encode(sink); - } - Instruction::V128Load16x4U(memarg) => { - sink.push(0xFD); - 0x04u32.encode(sink); - memarg.encode(sink); - } - Instruction::V128Load32x2S(memarg) => { - sink.push(0xFD); - 0x05u32.encode(sink); - memarg.encode(sink); - } - Instruction::V128Load32x2U(memarg) => { - sink.push(0xFD); - 0x06u32.encode(sink); - memarg.encode(sink); - } - Instruction::V128Load8Splat(memarg) => { - sink.push(0xFD); - 0x07u32.encode(sink); - memarg.encode(sink); - } - Instruction::V128Load16Splat(memarg) => { - sink.push(0xFD); - 0x08u32.encode(sink); - memarg.encode(sink); - } - Instruction::V128Load32Splat(memarg) => { - sink.push(0xFD); - 0x09u32.encode(sink); - memarg.encode(sink); - } - Instruction::V128Load64Splat(memarg) => { - sink.push(0xFD); - 0x0Au32.encode(sink); - memarg.encode(sink); - } - Instruction::V128Store(memarg) => { - sink.push(0xFD); - 0x0Bu32.encode(sink); - memarg.encode(sink); - } - Instruction::V128Const(x) => { - sink.push(0xFD); - 0x0Cu32.encode(sink); - sink.extend(x.to_le_bytes().iter().copied()); - } - Instruction::I8x16Shuffle(lanes) => { - sink.push(0xFD); - 0x0Du32.encode(sink); - assert!(lanes.iter().all(|l: &u8| *l < 32)); - sink.extend(lanes.iter().copied()); - } - Instruction::I8x16Swizzle => { - sink.push(0xFD); - 0x0Eu32.encode(sink); - } - Instruction::I8x16Splat => { - sink.push(0xFD); - 0x0Fu32.encode(sink); - } - Instruction::I16x8Splat => { - sink.push(0xFD); - 0x10u32.encode(sink); - } - Instruction::I32x4Splat => { - sink.push(0xFD); - 0x11u32.encode(sink); - } - Instruction::I64x2Splat => { - sink.push(0xFD); - 0x12u32.encode(sink); - } - Instruction::F32x4Splat => { - sink.push(0xFD); - 0x13u32.encode(sink); - } - Instruction::F64x2Splat => { - sink.push(0xFD); - 0x14u32.encode(sink); - } - Instruction::I8x16ExtractLaneS(lane) => { - sink.push(0xFD); - 0x15u32.encode(sink); - assert!(lane < 16); - sink.push(lane); - } - Instruction::I8x16ExtractLaneU(lane) => { - sink.push(0xFD); - 0x16u32.encode(sink); - assert!(lane < 16); - sink.push(lane); - } - Instruction::I8x16ReplaceLane(lane) => { - sink.push(0xFD); - 0x17u32.encode(sink); - assert!(lane < 16); - sink.push(lane); - } - Instruction::I16x8ExtractLaneS(lane) => { - sink.push(0xFD); - 0x18u32.encode(sink); - assert!(lane < 8); - sink.push(lane); - } - Instruction::I16x8ExtractLaneU(lane) => { - sink.push(0xFD); - 0x19u32.encode(sink); - assert!(lane < 8); - sink.push(lane); - } - Instruction::I16x8ReplaceLane(lane) => { - sink.push(0xFD); - 0x1Au32.encode(sink); - assert!(lane < 8); - sink.push(lane); - } - Instruction::I32x4ExtractLane(lane) => { - sink.push(0xFD); - 0x1Bu32.encode(sink); - assert!(lane < 4); - sink.push(lane); - } - Instruction::I32x4ReplaceLane(lane) => { - sink.push(0xFD); - 0x1Cu32.encode(sink); - assert!(lane < 4); - sink.push(lane); - } - Instruction::I64x2ExtractLane(lane) => { - sink.push(0xFD); - 0x1Du32.encode(sink); - assert!(lane < 2); - sink.push(lane); - } - Instruction::I64x2ReplaceLane(lane) => { - sink.push(0xFD); - 0x1Eu32.encode(sink); - assert!(lane < 2); - sink.push(lane); - } - Instruction::F32x4ExtractLane(lane) => { - sink.push(0xFD); - 0x1Fu32.encode(sink); - assert!(lane < 4); - sink.push(lane); - } - Instruction::F32x4ReplaceLane(lane) => { - sink.push(0xFD); - 0x20u32.encode(sink); - assert!(lane < 4); - sink.push(lane); - } - Instruction::F64x2ExtractLane(lane) => { - sink.push(0xFD); - 0x21u32.encode(sink); - assert!(lane < 2); - sink.push(lane); - } - Instruction::F64x2ReplaceLane(lane) => { - sink.push(0xFD); - 0x22u32.encode(sink); - assert!(lane < 2); - sink.push(lane); - } - - Instruction::I8x16Eq => { - sink.push(0xFD); - 0x23u32.encode(sink); - } - Instruction::I8x16Ne => { - sink.push(0xFD); - 0x24u32.encode(sink); - } - Instruction::I8x16LtS => { - sink.push(0xFD); - 0x25u32.encode(sink); - } - Instruction::I8x16LtU => { - sink.push(0xFD); - 0x26u32.encode(sink); - } - Instruction::I8x16GtS => { - sink.push(0xFD); - 0x27u32.encode(sink); - } - Instruction::I8x16GtU => { - sink.push(0xFD); - 0x28u32.encode(sink); - } - Instruction::I8x16LeS => { - sink.push(0xFD); - 0x29u32.encode(sink); - } - Instruction::I8x16LeU => { - sink.push(0xFD); - 0x2Au32.encode(sink); - } - Instruction::I8x16GeS => { - sink.push(0xFD); - 0x2Bu32.encode(sink); - } - Instruction::I8x16GeU => { - sink.push(0xFD); - 0x2Cu32.encode(sink); - } - Instruction::I16x8Eq => { - sink.push(0xFD); - 0x2Du32.encode(sink); - } - Instruction::I16x8Ne => { - sink.push(0xFD); - 0x2Eu32.encode(sink); - } - Instruction::I16x8LtS => { - sink.push(0xFD); - 0x2Fu32.encode(sink); - } - Instruction::I16x8LtU => { - sink.push(0xFD); - 0x30u32.encode(sink); - } - Instruction::I16x8GtS => { - sink.push(0xFD); - 0x31u32.encode(sink); - } - Instruction::I16x8GtU => { - sink.push(0xFD); - 0x32u32.encode(sink); - } - Instruction::I16x8LeS => { - sink.push(0xFD); - 0x33u32.encode(sink); - } - Instruction::I16x8LeU => { - sink.push(0xFD); - 0x34u32.encode(sink); - } - Instruction::I16x8GeS => { - sink.push(0xFD); - 0x35u32.encode(sink); - } - Instruction::I16x8GeU => { - sink.push(0xFD); - 0x36u32.encode(sink); - } - Instruction::I32x4Eq => { - sink.push(0xFD); - 0x37u32.encode(sink); - } - Instruction::I32x4Ne => { - sink.push(0xFD); - 0x38u32.encode(sink); - } - Instruction::I32x4LtS => { - sink.push(0xFD); - 0x39u32.encode(sink); - } - Instruction::I32x4LtU => { - sink.push(0xFD); - 0x3Au32.encode(sink); - } - Instruction::I32x4GtS => { - sink.push(0xFD); - 0x3Bu32.encode(sink); - } - Instruction::I32x4GtU => { - sink.push(0xFD); - 0x3Cu32.encode(sink); - } - Instruction::I32x4LeS => { - sink.push(0xFD); - 0x3Du32.encode(sink); - } - Instruction::I32x4LeU => { - sink.push(0xFD); - 0x3Eu32.encode(sink); - } - Instruction::I32x4GeS => { - sink.push(0xFD); - 0x3Fu32.encode(sink); - } - Instruction::I32x4GeU => { - sink.push(0xFD); - 0x40u32.encode(sink); - } - Instruction::F32x4Eq => { - sink.push(0xFD); - 0x41u32.encode(sink); - } - Instruction::F32x4Ne => { - sink.push(0xFD); - 0x42u32.encode(sink); - } - Instruction::F32x4Lt => { - sink.push(0xFD); - 0x43u32.encode(sink); - } - Instruction::F32x4Gt => { - sink.push(0xFD); - 0x44u32.encode(sink); - } - Instruction::F32x4Le => { - sink.push(0xFD); - 0x45u32.encode(sink); - } - Instruction::F32x4Ge => { - sink.push(0xFD); - 0x46u32.encode(sink); - } - Instruction::F64x2Eq => { - sink.push(0xFD); - 0x47u32.encode(sink); - } - Instruction::F64x2Ne => { - sink.push(0xFD); - 0x48u32.encode(sink); - } - Instruction::F64x2Lt => { - sink.push(0xFD); - 0x49u32.encode(sink); - } - Instruction::F64x2Gt => { - sink.push(0xFD); - 0x4Au32.encode(sink); - } - Instruction::F64x2Le => { - sink.push(0xFD); - 0x4Bu32.encode(sink); - } - Instruction::F64x2Ge => { - sink.push(0xFD); - 0x4Cu32.encode(sink); - } - Instruction::V128Not => { - sink.push(0xFD); - 0x4Du32.encode(sink); - } - Instruction::V128And => { - sink.push(0xFD); - 0x4Eu32.encode(sink); - } - Instruction::V128AndNot => { - sink.push(0xFD); - 0x4Fu32.encode(sink); - } - Instruction::V128Or => { - sink.push(0xFD); - 0x50u32.encode(sink); - } - Instruction::V128Xor => { - sink.push(0xFD); - 0x51u32.encode(sink); - } - Instruction::V128Bitselect => { - sink.push(0xFD); - 0x52u32.encode(sink); - } - Instruction::V128AnyTrue => { - sink.push(0xFD); - 0x53u32.encode(sink); - } - Instruction::I8x16Abs => { - sink.push(0xFD); - 0x60u32.encode(sink); - } - Instruction::I8x16Neg => { - sink.push(0xFD); - 0x61u32.encode(sink); - } - Instruction::I8x16Popcnt => { - sink.push(0xFD); - 0x62u32.encode(sink); - } - Instruction::I8x16AllTrue => { - sink.push(0xFD); - 0x63u32.encode(sink); - } - Instruction::I8x16Bitmask => { - sink.push(0xFD); - 0x64u32.encode(sink); - } - Instruction::I8x16NarrowI16x8S => { - sink.push(0xFD); - 0x65u32.encode(sink); - } - Instruction::I8x16NarrowI16x8U => { - sink.push(0xFD); - 0x66u32.encode(sink); - } - Instruction::I8x16Shl => { - sink.push(0xFD); - 0x6bu32.encode(sink); - } - Instruction::I8x16ShrS => { - sink.push(0xFD); - 0x6cu32.encode(sink); - } - Instruction::I8x16ShrU => { - sink.push(0xFD); - 0x6du32.encode(sink); - } - Instruction::I8x16Add => { - sink.push(0xFD); - 0x6eu32.encode(sink); - } - Instruction::I8x16AddSatS => { - sink.push(0xFD); - 0x6fu32.encode(sink); - } - Instruction::I8x16AddSatU => { - sink.push(0xFD); - 0x70u32.encode(sink); - } - Instruction::I8x16Sub => { - sink.push(0xFD); - 0x71u32.encode(sink); - } - Instruction::I8x16SubSatS => { - sink.push(0xFD); - 0x72u32.encode(sink); - } - Instruction::I8x16SubSatU => { - sink.push(0xFD); - 0x73u32.encode(sink); - } - Instruction::I8x16MinS => { - sink.push(0xFD); - 0x76u32.encode(sink); - } - Instruction::I8x16MinU => { - sink.push(0xFD); - 0x77u32.encode(sink); - } - Instruction::I8x16MaxS => { - sink.push(0xFD); - 0x78u32.encode(sink); - } - Instruction::I8x16MaxU => { - sink.push(0xFD); - 0x79u32.encode(sink); - } - Instruction::I8x16AvgrU => { - sink.push(0xFD); - 0x7Bu32.encode(sink); - } - Instruction::I16x8ExtAddPairwiseI8x16S => { - sink.push(0xFD); - 0x7Cu32.encode(sink); - } - Instruction::I16x8ExtAddPairwiseI8x16U => { - sink.push(0xFD); - 0x7Du32.encode(sink); - } - Instruction::I32x4ExtAddPairwiseI16x8S => { - sink.push(0xFD); - 0x7Eu32.encode(sink); - } - Instruction::I32x4ExtAddPairwiseI16x8U => { - sink.push(0xFD); - 0x7Fu32.encode(sink); - } - Instruction::I16x8Abs => { - sink.push(0xFD); - 0x80u32.encode(sink); - } - Instruction::I16x8Neg => { - sink.push(0xFD); - 0x81u32.encode(sink); - } - Instruction::I16x8Q15MulrSatS => { - sink.push(0xFD); - 0x82u32.encode(sink); - } - Instruction::I16x8AllTrue => { - sink.push(0xFD); - 0x83u32.encode(sink); - } - Instruction::I16x8Bitmask => { - sink.push(0xFD); - 0x84u32.encode(sink); - } - Instruction::I16x8NarrowI32x4S => { - sink.push(0xFD); - 0x85u32.encode(sink); - } - Instruction::I16x8NarrowI32x4U => { - sink.push(0xFD); - 0x86u32.encode(sink); - } - Instruction::I16x8ExtendLowI8x16S => { - sink.push(0xFD); - 0x87u32.encode(sink); - } - Instruction::I16x8ExtendHighI8x16S => { - sink.push(0xFD); - 0x88u32.encode(sink); - } - Instruction::I16x8ExtendLowI8x16U => { - sink.push(0xFD); - 0x89u32.encode(sink); - } - Instruction::I16x8ExtendHighI8x16U => { - sink.push(0xFD); - 0x8Au32.encode(sink); - } - Instruction::I16x8Shl => { - sink.push(0xFD); - 0x8Bu32.encode(sink); - } - Instruction::I16x8ShrS => { - sink.push(0xFD); - 0x8Cu32.encode(sink); - } - Instruction::I16x8ShrU => { - sink.push(0xFD); - 0x8Du32.encode(sink); - } - Instruction::I16x8Add => { - sink.push(0xFD); - 0x8Eu32.encode(sink); - } - Instruction::I16x8AddSatS => { - sink.push(0xFD); - 0x8Fu32.encode(sink); - } - Instruction::I16x8AddSatU => { - sink.push(0xFD); - 0x90u32.encode(sink); - } - Instruction::I16x8Sub => { - sink.push(0xFD); - 0x91u32.encode(sink); - } - Instruction::I16x8SubSatS => { - sink.push(0xFD); - 0x92u32.encode(sink); - } - Instruction::I16x8SubSatU => { - sink.push(0xFD); - 0x93u32.encode(sink); - } - Instruction::I16x8Mul => { - sink.push(0xFD); - 0x95u32.encode(sink); - } - Instruction::I16x8MinS => { - sink.push(0xFD); - 0x96u32.encode(sink); - } - Instruction::I16x8MinU => { - sink.push(0xFD); - 0x97u32.encode(sink); - } - Instruction::I16x8MaxS => { - sink.push(0xFD); - 0x98u32.encode(sink); - } - Instruction::I16x8MaxU => { - sink.push(0xFD); - 0x99u32.encode(sink); - } - Instruction::I16x8AvgrU => { - sink.push(0xFD); - 0x9Bu32.encode(sink); - } - Instruction::I16x8ExtMulLowI8x16S => { - sink.push(0xFD); - 0x9Cu32.encode(sink); - } - Instruction::I16x8ExtMulHighI8x16S => { - sink.push(0xFD); - 0x9Du32.encode(sink); - } - Instruction::I16x8ExtMulLowI8x16U => { - sink.push(0xFD); - 0x9Eu32.encode(sink); - } - Instruction::I16x8ExtMulHighI8x16U => { - sink.push(0xFD); - 0x9Fu32.encode(sink); - } - Instruction::I32x4Abs => { - sink.push(0xFD); - 0xA0u32.encode(sink); - } - Instruction::I32x4Neg => { - sink.push(0xFD); - 0xA1u32.encode(sink); - } - Instruction::I32x4AllTrue => { - sink.push(0xFD); - 0xA3u32.encode(sink); - } - Instruction::I32x4Bitmask => { - sink.push(0xFD); - 0xA4u32.encode(sink); - } - Instruction::I32x4ExtendLowI16x8S => { - sink.push(0xFD); - 0xA7u32.encode(sink); - } - Instruction::I32x4ExtendHighI16x8S => { - sink.push(0xFD); - 0xA8u32.encode(sink); - } - Instruction::I32x4ExtendLowI16x8U => { - sink.push(0xFD); - 0xA9u32.encode(sink); - } - Instruction::I32x4ExtendHighI16x8U => { - sink.push(0xFD); - 0xAAu32.encode(sink); - } - Instruction::I32x4Shl => { - sink.push(0xFD); - 0xABu32.encode(sink); - } - Instruction::I32x4ShrS => { - sink.push(0xFD); - 0xACu32.encode(sink); - } - Instruction::I32x4ShrU => { - sink.push(0xFD); - 0xADu32.encode(sink); - } - Instruction::I32x4Add => { - sink.push(0xFD); - 0xAEu32.encode(sink); - } - Instruction::I32x4Sub => { - sink.push(0xFD); - 0xB1u32.encode(sink); - } - Instruction::I32x4Mul => { - sink.push(0xFD); - 0xB5u32.encode(sink); - } - Instruction::I32x4MinS => { - sink.push(0xFD); - 0xB6u32.encode(sink); - } - Instruction::I32x4MinU => { - sink.push(0xFD); - 0xB7u32.encode(sink); - } - Instruction::I32x4MaxS => { - sink.push(0xFD); - 0xB8u32.encode(sink); - } - Instruction::I32x4MaxU => { - sink.push(0xFD); - 0xB9u32.encode(sink); - } - Instruction::I32x4DotI16x8S => { - sink.push(0xFD); - 0xBAu32.encode(sink); - } - Instruction::I32x4ExtMulLowI16x8S => { - sink.push(0xFD); - 0xBCu32.encode(sink); - } - Instruction::I32x4ExtMulHighI16x8S => { - sink.push(0xFD); - 0xBDu32.encode(sink); - } - Instruction::I32x4ExtMulLowI16x8U => { - sink.push(0xFD); - 0xBEu32.encode(sink); - } - Instruction::I32x4ExtMulHighI16x8U => { - sink.push(0xFD); - 0xBFu32.encode(sink); - } - Instruction::I64x2Abs => { - sink.push(0xFD); - 0xC0u32.encode(sink); - } - Instruction::I64x2Neg => { - sink.push(0xFD); - 0xC1u32.encode(sink); - } - Instruction::I64x2AllTrue => { - sink.push(0xFD); - 0xC3u32.encode(sink); - } - Instruction::I64x2Bitmask => { - sink.push(0xFD); - 0xC4u32.encode(sink); - } - Instruction::I64x2ExtendLowI32x4S => { - sink.push(0xFD); - 0xC7u32.encode(sink); - } - Instruction::I64x2ExtendHighI32x4S => { - sink.push(0xFD); - 0xC8u32.encode(sink); - } - Instruction::I64x2ExtendLowI32x4U => { - sink.push(0xFD); - 0xC9u32.encode(sink); - } - Instruction::I64x2ExtendHighI32x4U => { - sink.push(0xFD); - 0xCAu32.encode(sink); - } - Instruction::I64x2Shl => { - sink.push(0xFD); - 0xCBu32.encode(sink); - } - Instruction::I64x2ShrS => { - sink.push(0xFD); - 0xCCu32.encode(sink); - } - Instruction::I64x2ShrU => { - sink.push(0xFD); - 0xCDu32.encode(sink); - } - Instruction::I64x2Add => { - sink.push(0xFD); - 0xCEu32.encode(sink); - } - Instruction::I64x2Sub => { - sink.push(0xFD); - 0xD1u32.encode(sink); - } - Instruction::I64x2Mul => { - sink.push(0xFD); - 0xD5u32.encode(sink); - } - Instruction::I64x2ExtMulLowI32x4S => { - sink.push(0xFD); - 0xDCu32.encode(sink); - } - Instruction::I64x2ExtMulHighI32x4S => { - sink.push(0xFD); - 0xDDu32.encode(sink); - } - Instruction::I64x2ExtMulLowI32x4U => { - sink.push(0xFD); - 0xDEu32.encode(sink); - } - Instruction::I64x2ExtMulHighI32x4U => { - sink.push(0xFD); - 0xDFu32.encode(sink); - } - Instruction::F32x4Ceil => { - sink.push(0xFD); - 0x67u32.encode(sink); - } - Instruction::F32x4Floor => { - sink.push(0xFD); - 0x68u32.encode(sink); - } - Instruction::F32x4Trunc => { - sink.push(0xFD); - 0x69u32.encode(sink); - } - Instruction::F32x4Nearest => { - sink.push(0xFD); - 0x6Au32.encode(sink); - } - Instruction::F32x4Abs => { - sink.push(0xFD); - 0xE0u32.encode(sink); - } - Instruction::F32x4Neg => { - sink.push(0xFD); - 0xE1u32.encode(sink); - } - Instruction::F32x4Sqrt => { - sink.push(0xFD); - 0xE3u32.encode(sink); - } - Instruction::F32x4Add => { - sink.push(0xFD); - 0xE4u32.encode(sink); - } - Instruction::F32x4Sub => { - sink.push(0xFD); - 0xE5u32.encode(sink); - } - Instruction::F32x4Mul => { - sink.push(0xFD); - 0xE6u32.encode(sink); - } - Instruction::F32x4Div => { - sink.push(0xFD); - 0xE7u32.encode(sink); - } - Instruction::F32x4Min => { - sink.push(0xFD); - 0xE8u32.encode(sink); - } - Instruction::F32x4Max => { - sink.push(0xFD); - 0xE9u32.encode(sink); - } - Instruction::F32x4PMin => { - sink.push(0xFD); - 0xEAu32.encode(sink); - } - Instruction::F32x4PMax => { - sink.push(0xFD); - 0xEBu32.encode(sink); - } - Instruction::F64x2Ceil => { - sink.push(0xFD); - 0x74u32.encode(sink); - } - Instruction::F64x2Floor => { - sink.push(0xFD); - 0x75u32.encode(sink); - } - Instruction::F64x2Trunc => { - sink.push(0xFD); - 0x7Au32.encode(sink); - } - Instruction::F64x2Nearest => { - sink.push(0xFD); - 0x94u32.encode(sink); - } - Instruction::F64x2Abs => { - sink.push(0xFD); - 0xECu32.encode(sink); - } - Instruction::F64x2Neg => { - sink.push(0xFD); - 0xEDu32.encode(sink); - } - Instruction::F64x2Sqrt => { - sink.push(0xFD); - 0xEFu32.encode(sink); - } - Instruction::F64x2Add => { - sink.push(0xFD); - 0xF0u32.encode(sink); - } - Instruction::F64x2Sub => { - sink.push(0xFD); - 0xF1u32.encode(sink); - } - Instruction::F64x2Mul => { - sink.push(0xFD); - 0xF2u32.encode(sink); - } - Instruction::F64x2Div => { - sink.push(0xFD); - 0xF3u32.encode(sink); - } - Instruction::F64x2Min => { - sink.push(0xFD); - 0xF4u32.encode(sink); - } - Instruction::F64x2Max => { - sink.push(0xFD); - 0xF5u32.encode(sink); - } - Instruction::F64x2PMin => { - sink.push(0xFD); - 0xF6u32.encode(sink); - } - Instruction::F64x2PMax => { - sink.push(0xFD); - 0xF7u32.encode(sink); - } - Instruction::I32x4TruncSatF32x4S => { - sink.push(0xFD); - 0xF8u32.encode(sink); - } - Instruction::I32x4TruncSatF32x4U => { - sink.push(0xFD); - 0xF9u32.encode(sink); - } - Instruction::F32x4ConvertI32x4S => { - sink.push(0xFD); - 0xFAu32.encode(sink); - } - Instruction::F32x4ConvertI32x4U => { - sink.push(0xFD); - 0xFBu32.encode(sink); - } - Instruction::I32x4TruncSatF64x2SZero => { - sink.push(0xFD); - 0xFCu32.encode(sink); - } - Instruction::I32x4TruncSatF64x2UZero => { - sink.push(0xFD); - 0xFDu32.encode(sink); - } - Instruction::F64x2ConvertLowI32x4S => { - sink.push(0xFD); - 0xFEu32.encode(sink); - } - Instruction::F64x2ConvertLowI32x4U => { - sink.push(0xFD); - 0xFFu32.encode(sink); - } - Instruction::F32x4DemoteF64x2Zero => { - sink.push(0xFD); - 0x5Eu32.encode(sink); - } - Instruction::F64x2PromoteLowF32x4 => { - sink.push(0xFD); - 0x5Fu32.encode(sink); - } - Instruction::V128Load32Zero(memarg) => { - sink.push(0xFD); - 0x5Cu32.encode(sink); - memarg.encode(sink); - } - Instruction::V128Load64Zero(memarg) => { - sink.push(0xFD); - 0x5Du32.encode(sink); - memarg.encode(sink); - } - Instruction::V128Load8Lane { memarg, lane } => { - sink.push(0xFD); - 0x54u32.encode(sink); - memarg.encode(sink); - assert!(lane < 16); - sink.push(lane); - } - Instruction::V128Load16Lane { memarg, lane } => { - sink.push(0xFD); - 0x55u32.encode(sink); - memarg.encode(sink); - assert!(lane < 8); - sink.push(lane); - } - Instruction::V128Load32Lane { memarg, lane } => { - sink.push(0xFD); - 0x56u32.encode(sink); - memarg.encode(sink); - assert!(lane < 4); - sink.push(lane); - } - Instruction::V128Load64Lane { memarg, lane } => { - sink.push(0xFD); - 0x57u32.encode(sink); - memarg.encode(sink); - assert!(lane < 2); - sink.push(lane); - } - Instruction::V128Store8Lane { memarg, lane } => { - sink.push(0xFD); - 0x58u32.encode(sink); - memarg.encode(sink); - assert!(lane < 16); - sink.push(lane); - } - Instruction::V128Store16Lane { memarg, lane } => { - sink.push(0xFD); - 0x59u32.encode(sink); - memarg.encode(sink); - assert!(lane < 8); - sink.push(lane); - } - Instruction::V128Store32Lane { memarg, lane } => { - sink.push(0xFD); - 0x5Au32.encode(sink); - memarg.encode(sink); - assert!(lane < 4); - sink.push(lane); - } - Instruction::V128Store64Lane { memarg, lane } => { - sink.push(0xFD); - 0x5Bu32.encode(sink); - memarg.encode(sink); - assert!(lane < 2); - sink.push(lane); - } - Instruction::I64x2Eq => { - sink.push(0xFD); - 0xD6u32.encode(sink); - } - Instruction::I64x2Ne => { - sink.push(0xFD); - 0xD7u32.encode(sink); - } - Instruction::I64x2LtS => { - sink.push(0xFD); - 0xD8u32.encode(sink); - } - Instruction::I64x2GtS => { - sink.push(0xFD); - 0xD9u32.encode(sink); - } - Instruction::I64x2LeS => { - sink.push(0xFD); - 0xDAu32.encode(sink); - } - Instruction::I64x2GeS => { - sink.push(0xFD); - 0xDBu32.encode(sink); - } - Instruction::I8x16RelaxedSwizzle => { - sink.push(0xFD); - 0x100u32.encode(sink); - } - Instruction::I32x4RelaxedTruncF32x4S => { - sink.push(0xFD); - 0x101u32.encode(sink); - } - Instruction::I32x4RelaxedTruncF32x4U => { - sink.push(0xFD); - 0x102u32.encode(sink); - } - Instruction::I32x4RelaxedTruncF64x2SZero => { - sink.push(0xFD); - 0x103u32.encode(sink); - } - Instruction::I32x4RelaxedTruncF64x2UZero => { - sink.push(0xFD); - 0x104u32.encode(sink); - } - Instruction::F32x4RelaxedMadd => { - sink.push(0xFD); - 0x105u32.encode(sink); - } - Instruction::F32x4RelaxedNmadd => { - sink.push(0xFD); - 0x106u32.encode(sink); - } - Instruction::F64x2RelaxedMadd => { - sink.push(0xFD); - 0x107u32.encode(sink); - } - Instruction::F64x2RelaxedNmadd => { - sink.push(0xFD); - 0x108u32.encode(sink); - } - Instruction::I8x16RelaxedLaneselect => { - sink.push(0xFD); - 0x109u32.encode(sink); - } - Instruction::I16x8RelaxedLaneselect => { - sink.push(0xFD); - 0x10Au32.encode(sink); - } - Instruction::I32x4RelaxedLaneselect => { - sink.push(0xFD); - 0x10Bu32.encode(sink); - } - Instruction::I64x2RelaxedLaneselect => { - sink.push(0xFD); - 0x10Cu32.encode(sink); - } - Instruction::F32x4RelaxedMin => { - sink.push(0xFD); - 0x10Du32.encode(sink); - } - Instruction::F32x4RelaxedMax => { - sink.push(0xFD); - 0x10Eu32.encode(sink); - } - Instruction::F64x2RelaxedMin => { - sink.push(0xFD); - 0x10Fu32.encode(sink); - } - Instruction::F64x2RelaxedMax => { - sink.push(0xFD); - 0x110u32.encode(sink); - } - Instruction::I16x8RelaxedQ15mulrS => { - sink.push(0xFD); - 0x111u32.encode(sink); - } - Instruction::I16x8RelaxedDotI8x16I7x16S => { - sink.push(0xFD); - 0x112u32.encode(sink); - } - Instruction::I32x4RelaxedDotI8x16I7x16AddS => { - sink.push(0xFD); - 0x113u32.encode(sink); + Instruction::V128Load(memarg) => sink.v128_load(memarg), + Instruction::V128Load8x8S(memarg) => sink.v128_load8x8_s(memarg), + Instruction::V128Load8x8U(memarg) => sink.v128_load8x8_u(memarg), + Instruction::V128Load16x4S(memarg) => sink.v128_load16x4_s(memarg), + Instruction::V128Load16x4U(memarg) => sink.v128_load16x4_u(memarg), + Instruction::V128Load32x2S(memarg) => sink.v128_load32x2_s(memarg), + Instruction::V128Load32x2U(memarg) => sink.v128_load32x2_u(memarg), + Instruction::V128Load8Splat(memarg) => sink.v128_load8_splat(memarg), + Instruction::V128Load16Splat(memarg) => sink.v128_load16_splat(memarg), + Instruction::V128Load32Splat(memarg) => sink.v128_load32_splat(memarg), + Instruction::V128Load64Splat(memarg) => sink.v128_load64_splat(memarg), + Instruction::V128Store(memarg) => sink.v128_store(memarg), + Instruction::V128Const(x) => sink.v128_const(x), + Instruction::I8x16Shuffle(lanes) => sink.i8x16_shuffle(lanes), + Instruction::I8x16Swizzle => sink.i8x16_swizzle(), + Instruction::I8x16Splat => sink.i8x16_splat(), + Instruction::I16x8Splat => sink.i16x8_splat(), + Instruction::I32x4Splat => sink.i32x4_splat(), + Instruction::I64x2Splat => sink.i64x2_splat(), + Instruction::F32x4Splat => sink.f32x4_splat(), + Instruction::F64x2Splat => sink.f64x2_splat(), + Instruction::I8x16ExtractLaneS(lane) => sink.i8x16_extract_lane_s(lane), + Instruction::I8x16ExtractLaneU(lane) => sink.i8x16_extract_lane_u(lane), + Instruction::I8x16ReplaceLane(lane) => sink.i8x16_replace_lane(lane), + Instruction::I16x8ExtractLaneS(lane) => sink.i16x8_extract_lane_s(lane), + Instruction::I16x8ExtractLaneU(lane) => sink.i16x8_extract_lane_u(lane), + Instruction::I16x8ReplaceLane(lane) => sink.i16x8_replace_lane(lane), + Instruction::I32x4ExtractLane(lane) => sink.i32x4_extract_lane(lane), + Instruction::I32x4ReplaceLane(lane) => sink.i32x4_replace_lane(lane), + Instruction::I64x2ExtractLane(lane) => sink.i64x2_extract_lane(lane), + Instruction::I64x2ReplaceLane(lane) => sink.i64x2_replace_lane(lane), + Instruction::F32x4ExtractLane(lane) => sink.f32x4_extract_lane(lane), + Instruction::F32x4ReplaceLane(lane) => sink.f32x4_replace_lane(lane), + Instruction::F64x2ExtractLane(lane) => sink.f64x2_extract_lane(lane), + Instruction::F64x2ReplaceLane(lane) => sink.f64x2_replace_lane(lane), + + Instruction::I8x16Eq => sink.i8x16_eq(), + Instruction::I8x16Ne => sink.i8x16_ne(), + Instruction::I8x16LtS => sink.i8x16_lt_s(), + Instruction::I8x16LtU => sink.i8x16_lt_u(), + Instruction::I8x16GtS => sink.i8x16_gt_s(), + Instruction::I8x16GtU => sink.i8x16_gt_u(), + Instruction::I8x16LeS => sink.i8x16_le_s(), + Instruction::I8x16LeU => sink.i8x16_le_u(), + Instruction::I8x16GeS => sink.i8x16_ge_s(), + Instruction::I8x16GeU => sink.i8x16_ge_u(), + Instruction::I16x8Eq => sink.i16x8_eq(), + Instruction::I16x8Ne => sink.i16x8_ne(), + Instruction::I16x8LtS => sink.i16x8_lt_s(), + Instruction::I16x8LtU => sink.i16x8_lt_u(), + Instruction::I16x8GtS => sink.i16x8_gt_s(), + Instruction::I16x8GtU => sink.i16x8_gt_u(), + Instruction::I16x8LeS => sink.i16x8_le_s(), + Instruction::I16x8LeU => sink.i16x8_le_u(), + Instruction::I16x8GeS => sink.i16x8_ge_s(), + Instruction::I16x8GeU => sink.i16x8_ge_u(), + Instruction::I32x4Eq => sink.i32x4_eq(), + Instruction::I32x4Ne => sink.i32x4_ne(), + Instruction::I32x4LtS => sink.i32x4_lt_s(), + Instruction::I32x4LtU => sink.i32x4_lt_u(), + Instruction::I32x4GtS => sink.i32x4_gt_s(), + Instruction::I32x4GtU => sink.i32x4_gt_u(), + Instruction::I32x4LeS => sink.i32x4_le_s(), + Instruction::I32x4LeU => sink.i32x4_le_u(), + Instruction::I32x4GeS => sink.i32x4_ge_s(), + Instruction::I32x4GeU => sink.i32x4_ge_u(), + Instruction::F32x4Eq => sink.f32x4_eq(), + Instruction::F32x4Ne => sink.f32x4_ne(), + Instruction::F32x4Lt => sink.f32x4_lt(), + Instruction::F32x4Gt => sink.f32x4_gt(), + Instruction::F32x4Le => sink.f32x4_le(), + Instruction::F32x4Ge => sink.f32x4_ge(), + Instruction::F64x2Eq => sink.f64x2_eq(), + Instruction::F64x2Ne => sink.f64x2_ne(), + Instruction::F64x2Lt => sink.f64x2_lt(), + Instruction::F64x2Gt => sink.f64x2_gt(), + Instruction::F64x2Le => sink.f64x2_le(), + Instruction::F64x2Ge => sink.f64x2_ge(), + Instruction::V128Not => sink.v128_not(), + Instruction::V128And => sink.v128_and(), + Instruction::V128AndNot => sink.v128_andnot(), + Instruction::V128Or => sink.v128_or(), + Instruction::V128Xor => sink.v128_xor(), + Instruction::V128Bitselect => sink.v128_bitselect(), + Instruction::V128AnyTrue => sink.v128_any_true(), + Instruction::I8x16Abs => sink.i8x16_abs(), + Instruction::I8x16Neg => sink.i8x16_neg(), + Instruction::I8x16Popcnt => sink.i8x16_popcnt(), + Instruction::I8x16AllTrue => sink.i8x16_all_true(), + Instruction::I8x16Bitmask => sink.i8x16_bitmask(), + Instruction::I8x16NarrowI16x8S => sink.i8x16_narrow_i16x8_s(), + Instruction::I8x16NarrowI16x8U => sink.i8x16_narrow_i16x8_u(), + Instruction::I8x16Shl => sink.i8x16_shl(), + Instruction::I8x16ShrS => sink.i8x16_shr_s(), + Instruction::I8x16ShrU => sink.i8x16_shr_u(), + Instruction::I8x16Add => sink.i8x16_add(), + Instruction::I8x16AddSatS => sink.i8x16_add_sat_s(), + Instruction::I8x16AddSatU => sink.i8x16_add_sat_u(), + Instruction::I8x16Sub => sink.i8x16_sub(), + Instruction::I8x16SubSatS => sink.i8x16_sub_sat_s(), + Instruction::I8x16SubSatU => sink.i8x16_sub_sat_u(), + Instruction::I8x16MinS => sink.i8x16_min_s(), + Instruction::I8x16MinU => sink.i8x16_min_u(), + Instruction::I8x16MaxS => sink.i8x16_max_s(), + Instruction::I8x16MaxU => sink.i8x16_max_u(), + Instruction::I8x16AvgrU => sink.i8x16_avgr_u(), + Instruction::I16x8ExtAddPairwiseI8x16S => sink.i16x8_extadd_pairwise_i8x16_s(), + Instruction::I16x8ExtAddPairwiseI8x16U => sink.i16x8_extadd_pairwise_i8x16_u(), + Instruction::I32x4ExtAddPairwiseI16x8S => sink.i32x4_extadd_pairwise_i16x8_s(), + Instruction::I32x4ExtAddPairwiseI16x8U => sink.i32x4_extadd_pairwise_i16x8_u(), + Instruction::I16x8Abs => sink.i16x8_abs(), + Instruction::I16x8Neg => sink.i16x8_neg(), + Instruction::I16x8Q15MulrSatS => sink.i16x8_q15mulr_sat_s(), + Instruction::I16x8AllTrue => sink.i16x8_all_true(), + Instruction::I16x8Bitmask => sink.i16x8_bitmask(), + Instruction::I16x8NarrowI32x4S => sink.i16x8_narrow_i32x4_s(), + Instruction::I16x8NarrowI32x4U => sink.i16x8_narrow_i32x4_u(), + Instruction::I16x8ExtendLowI8x16S => sink.i16x8_extend_low_i8x16_s(), + Instruction::I16x8ExtendHighI8x16S => sink.i16x8_extend_high_i8x16_s(), + Instruction::I16x8ExtendLowI8x16U => sink.i16x8_extend_low_i8x16_u(), + Instruction::I16x8ExtendHighI8x16U => sink.i16x8_extend_high_i8x16_u(), + Instruction::I16x8Shl => sink.i16x8_shl(), + Instruction::I16x8ShrS => sink.i16x8_shr_s(), + Instruction::I16x8ShrU => sink.i16x8_shr_u(), + Instruction::I16x8Add => sink.i16x8_add(), + Instruction::I16x8AddSatS => sink.i16x8_add_sat_s(), + Instruction::I16x8AddSatU => sink.i16x8_add_sat_u(), + Instruction::I16x8Sub => sink.i16x8_sub(), + Instruction::I16x8SubSatS => sink.i16x8_sub_sat_s(), + Instruction::I16x8SubSatU => sink.i16x8_sub_sat_u(), + Instruction::I16x8Mul => sink.i16x8_mul(), + Instruction::I16x8MinS => sink.i16x8_min_s(), + Instruction::I16x8MinU => sink.i16x8_min_u(), + Instruction::I16x8MaxS => sink.i16x8_max_s(), + Instruction::I16x8MaxU => sink.i16x8_max_u(), + Instruction::I16x8AvgrU => sink.i16x8_avgr_u(), + Instruction::I16x8ExtMulLowI8x16S => sink.i16x8_extmul_low_i8x16_s(), + Instruction::I16x8ExtMulHighI8x16S => sink.i16x8_extmul_high_i8x16_s(), + Instruction::I16x8ExtMulLowI8x16U => sink.i16x8_extmul_low_i8x16_u(), + Instruction::I16x8ExtMulHighI8x16U => sink.i16x8_extmul_high_i8x16_u(), + Instruction::I32x4Abs => sink.i32x4_abs(), + Instruction::I32x4Neg => sink.i32x4_neg(), + Instruction::I32x4AllTrue => sink.i32x4_all_true(), + Instruction::I32x4Bitmask => sink.i32x4_bitmask(), + Instruction::I32x4ExtendLowI16x8S => sink.i32x4_extend_low_i16x8_s(), + Instruction::I32x4ExtendHighI16x8S => sink.i32x4_extend_high_i16x8_s(), + Instruction::I32x4ExtendLowI16x8U => sink.i32x4_extend_low_i16x8_u(), + Instruction::I32x4ExtendHighI16x8U => sink.i32x4_extend_high_i16x8_u(), + Instruction::I32x4Shl => sink.i32x4_shl(), + Instruction::I32x4ShrS => sink.i32x4_shr_s(), + Instruction::I32x4ShrU => sink.i32x4_shr_u(), + Instruction::I32x4Add => sink.i32x4_add(), + Instruction::I32x4Sub => sink.i32x4_sub(), + Instruction::I32x4Mul => sink.i32x4_mul(), + Instruction::I32x4MinS => sink.i32x4_min_s(), + Instruction::I32x4MinU => sink.i32x4_min_u(), + Instruction::I32x4MaxS => sink.i32x4_max_s(), + Instruction::I32x4MaxU => sink.i32x4_max_u(), + Instruction::I32x4DotI16x8S => sink.i32x4_dot_i16x8_s(), + Instruction::I32x4ExtMulLowI16x8S => sink.i32x4_extmul_low_i16x8_s(), + Instruction::I32x4ExtMulHighI16x8S => sink.i32x4_extmul_high_i16x8_s(), + Instruction::I32x4ExtMulLowI16x8U => sink.i32x4_extmul_low_i16x8_u(), + Instruction::I32x4ExtMulHighI16x8U => sink.i32x4_extmul_high_i16x8_u(), + Instruction::I64x2Abs => sink.i64x2_abs(), + Instruction::I64x2Neg => sink.i64x2_neg(), + Instruction::I64x2AllTrue => sink.i64x2_all_true(), + Instruction::I64x2Bitmask => sink.i64x2_bitmask(), + Instruction::I64x2ExtendLowI32x4S => sink.i64x2_extend_low_i32x4_s(), + Instruction::I64x2ExtendHighI32x4S => sink.i64x2_extend_high_i32x4_s(), + Instruction::I64x2ExtendLowI32x4U => sink.i64x2_extend_low_i32x4_u(), + Instruction::I64x2ExtendHighI32x4U => sink.i64x2_extend_high_i32x4_u(), + Instruction::I64x2Shl => sink.i64x2_shl(), + Instruction::I64x2ShrS => sink.i64x2_shr_s(), + Instruction::I64x2ShrU => sink.i64x2_shr_u(), + Instruction::I64x2Add => sink.i64x2_add(), + Instruction::I64x2Sub => sink.i64x2_sub(), + Instruction::I64x2Mul => sink.i64x2_mul(), + Instruction::I64x2ExtMulLowI32x4S => sink.i64x2_extmul_low_i32x4_s(), + Instruction::I64x2ExtMulHighI32x4S => sink.i64x2_extmul_high_i32x4_s(), + Instruction::I64x2ExtMulLowI32x4U => sink.i64x2_extmul_low_i32x4_u(), + Instruction::I64x2ExtMulHighI32x4U => sink.i64x2_extmul_high_i32x4_u(), + Instruction::F32x4Ceil => sink.f32x4_ceil(), + Instruction::F32x4Floor => sink.f32x4_floor(), + Instruction::F32x4Trunc => sink.f32x4_trunc(), + Instruction::F32x4Nearest => sink.f32x4_nearest(), + Instruction::F32x4Abs => sink.f32x4_abs(), + Instruction::F32x4Neg => sink.f32x4_neg(), + Instruction::F32x4Sqrt => sink.f32x4_sqrt(), + Instruction::F32x4Add => sink.f32x4_add(), + Instruction::F32x4Sub => sink.f32x4_sub(), + Instruction::F32x4Mul => sink.f32x4_mul(), + Instruction::F32x4Div => sink.f32x4_div(), + Instruction::F32x4Min => sink.f32x4_min(), + Instruction::F32x4Max => sink.f32x4_max(), + Instruction::F32x4PMin => sink.f32x4_pmin(), + Instruction::F32x4PMax => sink.f32x4_pmax(), + Instruction::F64x2Ceil => sink.f64x2_ceil(), + Instruction::F64x2Floor => sink.f64x2_floor(), + Instruction::F64x2Trunc => sink.f64x2_trunc(), + Instruction::F64x2Nearest => sink.f64x2_nearest(), + Instruction::F64x2Abs => sink.f64x2_abs(), + Instruction::F64x2Neg => sink.f64x2_neg(), + Instruction::F64x2Sqrt => sink.f64x2_sqrt(), + Instruction::F64x2Add => sink.f64x2_add(), + Instruction::F64x2Sub => sink.f64x2_sub(), + Instruction::F64x2Mul => sink.f64x2_mul(), + Instruction::F64x2Div => sink.f64x2_div(), + Instruction::F64x2Min => sink.f64x2_min(), + Instruction::F64x2Max => sink.f64x2_max(), + Instruction::F64x2PMin => sink.f64x2_pmin(), + Instruction::F64x2PMax => sink.f64x2_pmax(), + Instruction::I32x4TruncSatF32x4S => sink.i32x4_trunc_sat_f32x4_s(), + Instruction::I32x4TruncSatF32x4U => sink.i32x4_trunc_sat_f32x4_u(), + Instruction::F32x4ConvertI32x4S => sink.f32x4_convert_i32x4_s(), + Instruction::F32x4ConvertI32x4U => sink.f32x4_convert_i32x4_u(), + Instruction::I32x4TruncSatF64x2SZero => sink.i32x4_trunc_sat_f64x2_s_zero(), + Instruction::I32x4TruncSatF64x2UZero => sink.i32x4_trunc_sat_f64x2_u_zero(), + Instruction::F64x2ConvertLowI32x4S => sink.f64x2_convert_low_i32x4_s(), + Instruction::F64x2ConvertLowI32x4U => sink.f64x2_convert_low_i32x4_u(), + Instruction::F32x4DemoteF64x2Zero => sink.f32x4_demote_f64x2_zero(), + Instruction::F64x2PromoteLowF32x4 => sink.f64x2_promote_low_f32x4(), + Instruction::V128Load32Zero(memarg) => sink.v128_load32_zero(memarg), + Instruction::V128Load64Zero(memarg) => sink.v128_load64_zero(memarg), + Instruction::V128Load8Lane { memarg, lane } => sink.v128_load8_lane(memarg, lane), + Instruction::V128Load16Lane { memarg, lane } => sink.v128_load16_lane(memarg, lane), + Instruction::V128Load32Lane { memarg, lane } => sink.v128_load32_lane(memarg, lane), + Instruction::V128Load64Lane { memarg, lane } => sink.v128_load64_lane(memarg, lane), + Instruction::V128Store8Lane { memarg, lane } => sink.v128_store8_lane(memarg, lane), + Instruction::V128Store16Lane { memarg, lane } => sink.v128_store16_lane(memarg, lane), + Instruction::V128Store32Lane { memarg, lane } => sink.v128_store32_lane(memarg, lane), + Instruction::V128Store64Lane { memarg, lane } => sink.v128_store64_lane(memarg, lane), + Instruction::I64x2Eq => sink.i64x2_eq(), + Instruction::I64x2Ne => sink.i64x2_ne(), + Instruction::I64x2LtS => sink.i64x2_lt_s(), + Instruction::I64x2GtS => sink.i64x2_gt_s(), + Instruction::I64x2LeS => sink.i64x2_le_s(), + Instruction::I64x2GeS => sink.i64x2_ge_s(), + Instruction::I8x16RelaxedSwizzle => sink.i8x16_relaxed_swizzle(), + Instruction::I32x4RelaxedTruncF32x4S => sink.i32x4_relaxed_trunc_f32x4_s(), + Instruction::I32x4RelaxedTruncF32x4U => sink.i32x4_relaxed_trunc_f32x4_u(), + Instruction::I32x4RelaxedTruncF64x2SZero => sink.i32x4_relaxed_trunc_f64x2_s_zero(), + Instruction::I32x4RelaxedTruncF64x2UZero => sink.i32x4_relaxed_trunc_f64x2_u_zero(), + Instruction::F32x4RelaxedMadd => sink.f32x4_relaxed_madd(), + Instruction::F32x4RelaxedNmadd => sink.f32x4_relaxed_nmadd(), + Instruction::F64x2RelaxedMadd => sink.f64x2_relaxed_madd(), + Instruction::F64x2RelaxedNmadd => sink.f64x2_relaxed_nmadd(), + Instruction::I8x16RelaxedLaneselect => sink.i8x16_relaxed_laneselect(), + Instruction::I16x8RelaxedLaneselect => sink.i16x8_relaxed_laneselect(), + Instruction::I32x4RelaxedLaneselect => sink.i32x4_relaxed_laneselect(), + Instruction::I64x2RelaxedLaneselect => sink.i64x2_relaxed_laneselect(), + Instruction::F32x4RelaxedMin => sink.f32x4_relaxed_min(), + Instruction::F32x4RelaxedMax => sink.f32x4_relaxed_max(), + Instruction::F64x2RelaxedMin => sink.f64x2_relaxed_min(), + Instruction::F64x2RelaxedMax => sink.f64x2_relaxed_max(), + Instruction::I16x8RelaxedQ15mulrS => sink.i16x8_relaxed_q15mulr_s(), + Instruction::I16x8RelaxedDotI8x16I7x16S => sink.i16x8_relaxed_dot_i8x16_i7x16_s(), + Instruction::I32x4RelaxedDotI8x16I7x16AddS => { + sink.i32x4_relaxed_dot_i8x16_i7x16_add_s() } // Atomic instructions from the thread proposal - Instruction::MemoryAtomicNotify(memarg) => { - sink.push(0xFE); - sink.push(0x00); - memarg.encode(sink); - } - Instruction::MemoryAtomicWait32(memarg) => { - sink.push(0xFE); - sink.push(0x01); - memarg.encode(sink); - } - Instruction::MemoryAtomicWait64(memarg) => { - sink.push(0xFE); - sink.push(0x02); - memarg.encode(sink); - } - Instruction::AtomicFence => { - sink.push(0xFE); - sink.push(0x03); - sink.push(0x00); - } - Instruction::I32AtomicLoad(memarg) => { - sink.push(0xFE); - sink.push(0x10); - memarg.encode(sink); - } - Instruction::I64AtomicLoad(memarg) => { - sink.push(0xFE); - sink.push(0x11); - memarg.encode(sink); - } - Instruction::I32AtomicLoad8U(memarg) => { - sink.push(0xFE); - sink.push(0x12); - memarg.encode(sink); - } - Instruction::I32AtomicLoad16U(memarg) => { - sink.push(0xFE); - sink.push(0x13); - memarg.encode(sink); - } - Instruction::I64AtomicLoad8U(memarg) => { - sink.push(0xFE); - sink.push(0x14); - memarg.encode(sink); - } - Instruction::I64AtomicLoad16U(memarg) => { - sink.push(0xFE); - sink.push(0x15); - memarg.encode(sink); - } - Instruction::I64AtomicLoad32U(memarg) => { - sink.push(0xFE); - sink.push(0x16); - memarg.encode(sink); - } - Instruction::I32AtomicStore(memarg) => { - sink.push(0xFE); - sink.push(0x17); - memarg.encode(sink); - } - Instruction::I64AtomicStore(memarg) => { - sink.push(0xFE); - sink.push(0x18); - memarg.encode(sink); - } - Instruction::I32AtomicStore8(memarg) => { - sink.push(0xFE); - sink.push(0x19); - memarg.encode(sink); - } - Instruction::I32AtomicStore16(memarg) => { - sink.push(0xFE); - sink.push(0x1A); - memarg.encode(sink); - } - Instruction::I64AtomicStore8(memarg) => { - sink.push(0xFE); - sink.push(0x1B); - memarg.encode(sink); - } - Instruction::I64AtomicStore16(memarg) => { - sink.push(0xFE); - sink.push(0x1C); - memarg.encode(sink); - } - Instruction::I64AtomicStore32(memarg) => { - sink.push(0xFE); - sink.push(0x1D); - memarg.encode(sink); - } - Instruction::I32AtomicRmwAdd(memarg) => { - sink.push(0xFE); - sink.push(0x1E); - memarg.encode(sink); - } - Instruction::I64AtomicRmwAdd(memarg) => { - sink.push(0xFE); - sink.push(0x1F); - memarg.encode(sink); - } - Instruction::I32AtomicRmw8AddU(memarg) => { - sink.push(0xFE); - sink.push(0x20); - memarg.encode(sink); - } - Instruction::I32AtomicRmw16AddU(memarg) => { - sink.push(0xFE); - sink.push(0x21); - memarg.encode(sink); - } - Instruction::I64AtomicRmw8AddU(memarg) => { - sink.push(0xFE); - sink.push(0x22); - memarg.encode(sink); - } - Instruction::I64AtomicRmw16AddU(memarg) => { - sink.push(0xFE); - sink.push(0x23); - memarg.encode(sink); - } - Instruction::I64AtomicRmw32AddU(memarg) => { - sink.push(0xFE); - sink.push(0x24); - memarg.encode(sink); - } - Instruction::I32AtomicRmwSub(memarg) => { - sink.push(0xFE); - sink.push(0x25); - memarg.encode(sink); - } - Instruction::I64AtomicRmwSub(memarg) => { - sink.push(0xFE); - sink.push(0x26); - memarg.encode(sink); - } - Instruction::I32AtomicRmw8SubU(memarg) => { - sink.push(0xFE); - sink.push(0x27); - memarg.encode(sink); - } - Instruction::I32AtomicRmw16SubU(memarg) => { - sink.push(0xFE); - sink.push(0x28); - memarg.encode(sink); - } - Instruction::I64AtomicRmw8SubU(memarg) => { - sink.push(0xFE); - sink.push(0x29); - memarg.encode(sink); - } - Instruction::I64AtomicRmw16SubU(memarg) => { - sink.push(0xFE); - sink.push(0x2A); - memarg.encode(sink); - } - Instruction::I64AtomicRmw32SubU(memarg) => { - sink.push(0xFE); - sink.push(0x2B); - memarg.encode(sink); - } - Instruction::I32AtomicRmwAnd(memarg) => { - sink.push(0xFE); - sink.push(0x2C); - memarg.encode(sink); - } - Instruction::I64AtomicRmwAnd(memarg) => { - sink.push(0xFE); - sink.push(0x2D); - memarg.encode(sink); - } - Instruction::I32AtomicRmw8AndU(memarg) => { - sink.push(0xFE); - sink.push(0x2E); - memarg.encode(sink); - } - Instruction::I32AtomicRmw16AndU(memarg) => { - sink.push(0xFE); - sink.push(0x2F); - memarg.encode(sink); - } - Instruction::I64AtomicRmw8AndU(memarg) => { - sink.push(0xFE); - sink.push(0x30); - memarg.encode(sink); - } - Instruction::I64AtomicRmw16AndU(memarg) => { - sink.push(0xFE); - sink.push(0x31); - memarg.encode(sink); - } - Instruction::I64AtomicRmw32AndU(memarg) => { - sink.push(0xFE); - sink.push(0x32); - memarg.encode(sink); - } - Instruction::I32AtomicRmwOr(memarg) => { - sink.push(0xFE); - sink.push(0x33); - memarg.encode(sink); - } - Instruction::I64AtomicRmwOr(memarg) => { - sink.push(0xFE); - sink.push(0x34); - memarg.encode(sink); - } - Instruction::I32AtomicRmw8OrU(memarg) => { - sink.push(0xFE); - sink.push(0x35); - memarg.encode(sink); - } - Instruction::I32AtomicRmw16OrU(memarg) => { - sink.push(0xFE); - sink.push(0x36); - memarg.encode(sink); - } - Instruction::I64AtomicRmw8OrU(memarg) => { - sink.push(0xFE); - sink.push(0x37); - memarg.encode(sink); - } - Instruction::I64AtomicRmw16OrU(memarg) => { - sink.push(0xFE); - sink.push(0x38); - memarg.encode(sink); - } - Instruction::I64AtomicRmw32OrU(memarg) => { - sink.push(0xFE); - sink.push(0x39); - memarg.encode(sink); - } - Instruction::I32AtomicRmwXor(memarg) => { - sink.push(0xFE); - sink.push(0x3A); - memarg.encode(sink); - } - Instruction::I64AtomicRmwXor(memarg) => { - sink.push(0xFE); - sink.push(0x3B); - memarg.encode(sink); - } - Instruction::I32AtomicRmw8XorU(memarg) => { - sink.push(0xFE); - sink.push(0x3C); - memarg.encode(sink); - } - Instruction::I32AtomicRmw16XorU(memarg) => { - sink.push(0xFE); - sink.push(0x3D); - memarg.encode(sink); - } - Instruction::I64AtomicRmw8XorU(memarg) => { - sink.push(0xFE); - sink.push(0x3E); - memarg.encode(sink); - } - Instruction::I64AtomicRmw16XorU(memarg) => { - sink.push(0xFE); - sink.push(0x3F); - memarg.encode(sink); - } - Instruction::I64AtomicRmw32XorU(memarg) => { - sink.push(0xFE); - sink.push(0x40); - memarg.encode(sink); - } - Instruction::I32AtomicRmwXchg(memarg) => { - sink.push(0xFE); - sink.push(0x41); - memarg.encode(sink); - } - Instruction::I64AtomicRmwXchg(memarg) => { - sink.push(0xFE); - sink.push(0x42); - memarg.encode(sink); - } - Instruction::I32AtomicRmw8XchgU(memarg) => { - sink.push(0xFE); - sink.push(0x43); - memarg.encode(sink); - } - Instruction::I32AtomicRmw16XchgU(memarg) => { - sink.push(0xFE); - sink.push(0x44); - memarg.encode(sink); - } - Instruction::I64AtomicRmw8XchgU(memarg) => { - sink.push(0xFE); - sink.push(0x45); - memarg.encode(sink); - } - Instruction::I64AtomicRmw16XchgU(memarg) => { - sink.push(0xFE); - sink.push(0x46); - memarg.encode(sink); - } - Instruction::I64AtomicRmw32XchgU(memarg) => { - sink.push(0xFE); - sink.push(0x47); - memarg.encode(sink); - } - Instruction::I32AtomicRmwCmpxchg(memarg) => { - sink.push(0xFE); - sink.push(0x48); - memarg.encode(sink); - } - Instruction::I64AtomicRmwCmpxchg(memarg) => { - sink.push(0xFE); - sink.push(0x49); - memarg.encode(sink); - } - Instruction::I32AtomicRmw8CmpxchgU(memarg) => { - sink.push(0xFE); - sink.push(0x4A); - memarg.encode(sink); - } - Instruction::I32AtomicRmw16CmpxchgU(memarg) => { - sink.push(0xFE); - sink.push(0x4B); - memarg.encode(sink); - } - Instruction::I64AtomicRmw8CmpxchgU(memarg) => { - sink.push(0xFE); - sink.push(0x4C); - memarg.encode(sink); - } - Instruction::I64AtomicRmw16CmpxchgU(memarg) => { - sink.push(0xFE); - sink.push(0x4D); - memarg.encode(sink); - } - Instruction::I64AtomicRmw32CmpxchgU(memarg) => { - sink.push(0xFE); - sink.push(0x4E); - memarg.encode(sink); - } + Instruction::MemoryAtomicNotify(memarg) => sink.memory_atomic_notify(memarg), + Instruction::MemoryAtomicWait32(memarg) => sink.memory_atomic_wait32(memarg), + Instruction::MemoryAtomicWait64(memarg) => sink.memory_atomic_wait64(memarg), + Instruction::AtomicFence => sink.atomic_fence(), + Instruction::I32AtomicLoad(memarg) => sink.i32_atomic_load(memarg), + Instruction::I64AtomicLoad(memarg) => sink.i64_atomic_load(memarg), + Instruction::I32AtomicLoad8U(memarg) => sink.i32_atomic_load8_u(memarg), + Instruction::I32AtomicLoad16U(memarg) => sink.i32_atomic_load16_u(memarg), + Instruction::I64AtomicLoad8U(memarg) => sink.i64_atomic_load8_u(memarg), + Instruction::I64AtomicLoad16U(memarg) => sink.i64_atomic_load16_u(memarg), + Instruction::I64AtomicLoad32U(memarg) => sink.i64_atomic_load32_u(memarg), + Instruction::I32AtomicStore(memarg) => sink.i32_atomic_store(memarg), + Instruction::I64AtomicStore(memarg) => sink.i64_atomic_store(memarg), + Instruction::I32AtomicStore8(memarg) => sink.i32_atomic_store8(memarg), + Instruction::I32AtomicStore16(memarg) => sink.i32_atomic_store16(memarg), + Instruction::I64AtomicStore8(memarg) => sink.i64_atomic_store8(memarg), + Instruction::I64AtomicStore16(memarg) => sink.i64_atomic_store16(memarg), + Instruction::I64AtomicStore32(memarg) => sink.i64_atomic_store32(memarg), + Instruction::I32AtomicRmwAdd(memarg) => sink.i32_atomic_rmw_add(memarg), + Instruction::I64AtomicRmwAdd(memarg) => sink.i64_atomic_rmw_add(memarg), + Instruction::I32AtomicRmw8AddU(memarg) => sink.i32_atomic_rmw8_add_u(memarg), + Instruction::I32AtomicRmw16AddU(memarg) => sink.i32_atomic_rmw16_add_u(memarg), + Instruction::I64AtomicRmw8AddU(memarg) => sink.i64_atomic_rmw8_add_u(memarg), + Instruction::I64AtomicRmw16AddU(memarg) => sink.i64_atomic_rmw16_add_u(memarg), + Instruction::I64AtomicRmw32AddU(memarg) => sink.i64_atomic_rmw32_add_u(memarg), + Instruction::I32AtomicRmwSub(memarg) => sink.i32_atomic_rmw_sub(memarg), + Instruction::I64AtomicRmwSub(memarg) => sink.i64_atomic_rmw_sub(memarg), + Instruction::I32AtomicRmw8SubU(memarg) => sink.i32_atomic_rmw8_sub_u(memarg), + Instruction::I32AtomicRmw16SubU(memarg) => sink.i32_atomic_rmw16_sub_u(memarg), + Instruction::I64AtomicRmw8SubU(memarg) => sink.i64_atomic_rmw8_sub_u(memarg), + Instruction::I64AtomicRmw16SubU(memarg) => sink.i64_atomic_rmw16_sub_u(memarg), + Instruction::I64AtomicRmw32SubU(memarg) => sink.i64_atomic_rmw32_sub_u(memarg), + Instruction::I32AtomicRmwAnd(memarg) => sink.i32_atomic_rmw_and(memarg), + Instruction::I64AtomicRmwAnd(memarg) => sink.i64_atomic_rmw_and(memarg), + Instruction::I32AtomicRmw8AndU(memarg) => sink.i32_atomic_rmw8_and_u(memarg), + Instruction::I32AtomicRmw16AndU(memarg) => sink.i32_atomic_rmw16_and_u(memarg), + Instruction::I64AtomicRmw8AndU(memarg) => sink.i64_atomic_rmw8_and_u(memarg), + Instruction::I64AtomicRmw16AndU(memarg) => sink.i64_atomic_rmw16_and_u(memarg), + Instruction::I64AtomicRmw32AndU(memarg) => sink.i64_atomic_rmw32_and_u(memarg), + Instruction::I32AtomicRmwOr(memarg) => sink.i32_atomic_rmw_or(memarg), + Instruction::I64AtomicRmwOr(memarg) => sink.i64_atomic_rmw_or(memarg), + Instruction::I32AtomicRmw8OrU(memarg) => sink.i32_atomic_rmw8_or_u(memarg), + Instruction::I32AtomicRmw16OrU(memarg) => sink.i32_atomic_rmw16_or_u(memarg), + Instruction::I64AtomicRmw8OrU(memarg) => sink.i64_atomic_rmw8_or_u(memarg), + Instruction::I64AtomicRmw16OrU(memarg) => sink.i64_atomic_rmw16_or_u(memarg), + Instruction::I64AtomicRmw32OrU(memarg) => sink.i64_atomic_rmw32_or_u(memarg), + Instruction::I32AtomicRmwXor(memarg) => sink.i32_atomic_rmw_xor(memarg), + Instruction::I64AtomicRmwXor(memarg) => sink.i64_atomic_rmw_xor(memarg), + Instruction::I32AtomicRmw8XorU(memarg) => sink.i32_atomic_rmw8_xor_u(memarg), + Instruction::I32AtomicRmw16XorU(memarg) => sink.i32_atomic_rmw16_xor_u(memarg), + Instruction::I64AtomicRmw8XorU(memarg) => sink.i64_atomic_rmw8_xor_u(memarg), + Instruction::I64AtomicRmw16XorU(memarg) => sink.i64_atomic_rmw16_xor_u(memarg), + Instruction::I64AtomicRmw32XorU(memarg) => sink.i64_atomic_rmw32_xor_u(memarg), + Instruction::I32AtomicRmwXchg(memarg) => sink.i32_atomic_rmw_xchg(memarg), + Instruction::I64AtomicRmwXchg(memarg) => sink.i64_atomic_rmw_xchg(memarg), + Instruction::I32AtomicRmw8XchgU(memarg) => sink.i32_atomic_rmw8_xchg_u(memarg), + Instruction::I32AtomicRmw16XchgU(memarg) => sink.i32_atomic_rmw16_xchg_u(memarg), + Instruction::I64AtomicRmw8XchgU(memarg) => sink.i64_atomic_rmw8_xchg_u(memarg), + Instruction::I64AtomicRmw16XchgU(memarg) => sink.i64_atomic_rmw16_xchg_u(memarg), + Instruction::I64AtomicRmw32XchgU(memarg) => sink.i64_atomic_rmw32_xchg_u(memarg), + Instruction::I32AtomicRmwCmpxchg(memarg) => sink.i32_atomic_rmw_cmpxchg(memarg), + Instruction::I64AtomicRmwCmpxchg(memarg) => sink.i64_atomic_rmw_cmpxchg(memarg), + Instruction::I32AtomicRmw8CmpxchgU(memarg) => sink.i32_atomic_rmw8_cmpxchg_u(memarg), + Instruction::I32AtomicRmw16CmpxchgU(memarg) => sink.i32_atomic_rmw16_cmpxchg_u(memarg), + Instruction::I64AtomicRmw8CmpxchgU(memarg) => sink.i64_atomic_rmw8_cmpxchg_u(memarg), + Instruction::I64AtomicRmw16CmpxchgU(memarg) => sink.i64_atomic_rmw16_cmpxchg_u(memarg), + Instruction::I64AtomicRmw32CmpxchgU(memarg) => sink.i64_atomic_rmw32_cmpxchg_u(memarg), // Atomic instructions from the shared-everything-threads proposal Instruction::GlobalAtomicGet { ordering, global_index, - } => { - sink.push(0xFE); - sink.push(0x4F); - ordering.encode(sink); - global_index.encode(sink); - } + } => sink.global_atomic_get(ordering, GlobalIdx(global_index)), Instruction::GlobalAtomicSet { ordering, global_index, - } => { - sink.push(0xFE); - sink.push(0x50); - ordering.encode(sink); - global_index.encode(sink); - } + } => sink.global_atomic_set(ordering, GlobalIdx(global_index)), Instruction::GlobalAtomicRmwAdd { ordering, global_index, - } => { - sink.push(0xFE); - sink.push(0x51); - ordering.encode(sink); - global_index.encode(sink); - } + } => sink.global_atomic_rmw_add(ordering, GlobalIdx(global_index)), Instruction::GlobalAtomicRmwSub { ordering, global_index, - } => { - sink.push(0xFE); - sink.push(0x52); - ordering.encode(sink); - global_index.encode(sink); - } + } => sink.global_atomic_rmw_sub(ordering, GlobalIdx(global_index)), Instruction::GlobalAtomicRmwAnd { ordering, global_index, - } => { - sink.push(0xFE); - sink.push(0x53); - ordering.encode(sink); - global_index.encode(sink); - } + } => sink.global_atomic_rmw_and(ordering, GlobalIdx(global_index)), Instruction::GlobalAtomicRmwOr { ordering, global_index, - } => { - sink.push(0xFE); - sink.push(0x54); - ordering.encode(sink); - global_index.encode(sink); - } + } => sink.global_atomic_rmw_or(ordering, GlobalIdx(global_index)), Instruction::GlobalAtomicRmwXor { ordering, global_index, - } => { - sink.push(0xFE); - sink.push(0x55); - ordering.encode(sink); - global_index.encode(sink); - } + } => sink.global_atomic_rmw_xor(ordering, GlobalIdx(global_index)), Instruction::GlobalAtomicRmwXchg { ordering, global_index, - } => { - sink.push(0xFE); - sink.push(0x56); - ordering.encode(sink); - global_index.encode(sink); - } + } => sink.global_atomic_rmw_xchg(ordering, GlobalIdx(global_index)), Instruction::GlobalAtomicRmwCmpxchg { ordering, global_index, - } => { - sink.push(0xFE); - sink.push(0x57); - ordering.encode(sink); - global_index.encode(sink); - } + } => sink.global_atomic_rmw_cmpxchg(ordering, GlobalIdx(global_index)), Instruction::TableAtomicGet { ordering, table_index, - } => { - sink.push(0xFE); - sink.push(0x58); - ordering.encode(sink); - table_index.encode(sink); - } + } => sink.table_atomic_get(ordering, TableIdx(table_index)), Instruction::TableAtomicSet { ordering, table_index, - } => { - sink.push(0xFE); - sink.push(0x59); - ordering.encode(sink); - table_index.encode(sink); - } + } => sink.table_atomic_set(ordering, TableIdx(table_index)), Instruction::TableAtomicRmwXchg { ordering, table_index, - } => { - sink.push(0xFE); - sink.push(0x5A); - ordering.encode(sink); - table_index.encode(sink); - } + } => sink.table_atomic_rmw_xchg(ordering, TableIdx(table_index)), Instruction::TableAtomicRmwCmpxchg { ordering, table_index, - } => { - sink.push(0xFE); - sink.push(0x5B); - ordering.encode(sink); - table_index.encode(sink); - } + } => sink.table_atomic_rmw_cmpxchg(ordering, TableIdx(table_index)), Instruction::StructAtomicGet { ordering, struct_type_index, field_index, } => { - sink.push(0xFE); - sink.push(0x5C); - ordering.encode(sink); - struct_type_index.encode(sink); - field_index.encode(sink); + sink.struct_atomic_get(ordering, TypeIdx(struct_type_index), FieldIdx(field_index)) } Instruction::StructAtomicGetS { ordering, struct_type_index, field_index, - } => { - sink.push(0xFE); - sink.push(0x5D); - ordering.encode(sink); - struct_type_index.encode(sink); - field_index.encode(sink); - } + } => sink.struct_atomic_get_s( + ordering, + TypeIdx(struct_type_index), + FieldIdx(field_index), + ), Instruction::StructAtomicGetU { ordering, struct_type_index, field_index, - } => { - sink.push(0xFE); - sink.push(0x5E); - ordering.encode(sink); - struct_type_index.encode(sink); - field_index.encode(sink); - } + } => sink.struct_atomic_get_u( + ordering, + TypeIdx(struct_type_index), + FieldIdx(field_index), + ), Instruction::StructAtomicSet { ordering, struct_type_index, field_index, } => { - sink.push(0xFE); - sink.push(0x5F); - ordering.encode(sink); - struct_type_index.encode(sink); - field_index.encode(sink); + sink.struct_atomic_set(ordering, TypeIdx(struct_type_index), FieldIdx(field_index)) } Instruction::StructAtomicRmwAdd { ordering, struct_type_index, field_index, - } => { - sink.push(0xFE); - sink.push(0x60); - ordering.encode(sink); - struct_type_index.encode(sink); - field_index.encode(sink); - } + } => sink.struct_atomic_rmw_add( + ordering, + TypeIdx(struct_type_index), + FieldIdx(field_index), + ), Instruction::StructAtomicRmwSub { ordering, struct_type_index, field_index, - } => { - sink.push(0xFE); - sink.push(0x61); - ordering.encode(sink); - struct_type_index.encode(sink); - field_index.encode(sink); - } + } => sink.struct_atomic_rmw_sub( + ordering, + TypeIdx(struct_type_index), + FieldIdx(field_index), + ), Instruction::StructAtomicRmwAnd { ordering, struct_type_index, field_index, - } => { - sink.push(0xFE); - sink.push(0x62); - ordering.encode(sink); - struct_type_index.encode(sink); - field_index.encode(sink); - } + } => sink.struct_atomic_rmw_and( + ordering, + TypeIdx(struct_type_index), + FieldIdx(field_index), + ), Instruction::StructAtomicRmwOr { ordering, struct_type_index, field_index, - } => { - sink.push(0xFE); - sink.push(0x63); - ordering.encode(sink); - struct_type_index.encode(sink); - field_index.encode(sink); - } + } => sink.struct_atomic_rmw_or( + ordering, + TypeIdx(struct_type_index), + FieldIdx(field_index), + ), Instruction::StructAtomicRmwXor { ordering, struct_type_index, field_index, - } => { - sink.push(0xFE); - sink.push(0x64); - ordering.encode(sink); - struct_type_index.encode(sink); - field_index.encode(sink); - } + } => sink.struct_atomic_rmw_xor( + ordering, + TypeIdx(struct_type_index), + FieldIdx(field_index), + ), Instruction::StructAtomicRmwXchg { ordering, struct_type_index, field_index, - } => { - sink.push(0xFE); - sink.push(0x65); - ordering.encode(sink); - struct_type_index.encode(sink); - field_index.encode(sink); - } + } => sink.struct_atomic_rmw_xchg( + ordering, + TypeIdx(struct_type_index), + FieldIdx(field_index), + ), Instruction::StructAtomicRmwCmpxchg { ordering, struct_type_index, field_index, - } => { - sink.push(0xFE); - sink.push(0x66); - ordering.encode(sink); - struct_type_index.encode(sink); - field_index.encode(sink); - } + } => sink.struct_atomic_rmw_cmpxchg( + ordering, + TypeIdx(struct_type_index), + FieldIdx(field_index), + ), Instruction::ArrayAtomicGet { ordering, array_type_index, - } => { - sink.push(0xFE); - sink.push(0x67); - ordering.encode(sink); - array_type_index.encode(sink); - } + } => sink.array_atomic_get(ordering, TypeIdx(array_type_index)), Instruction::ArrayAtomicGetS { ordering, array_type_index, - } => { - sink.push(0xFE); - sink.push(0x68); - ordering.encode(sink); - array_type_index.encode(sink); - } + } => sink.array_atomic_get_s(ordering, TypeIdx(array_type_index)), Instruction::ArrayAtomicGetU { ordering, array_type_index, - } => { - sink.push(0xFE); - sink.push(0x69); - ordering.encode(sink); - array_type_index.encode(sink); - } + } => sink.array_atomic_get_u(ordering, TypeIdx(array_type_index)), Instruction::ArrayAtomicSet { ordering, array_type_index, - } => { - sink.push(0xFE); - sink.push(0x6A); - ordering.encode(sink); - array_type_index.encode(sink); - } + } => sink.array_atomic_set(ordering, TypeIdx(array_type_index)), Instruction::ArrayAtomicRmwAdd { ordering, array_type_index, - } => { - sink.push(0xFE); - sink.push(0x6B); - ordering.encode(sink); - array_type_index.encode(sink); - } + } => sink.array_atomic_rmw_add(ordering, TypeIdx(array_type_index)), Instruction::ArrayAtomicRmwSub { ordering, array_type_index, - } => { - sink.push(0xFE); - sink.push(0x6C); - ordering.encode(sink); - array_type_index.encode(sink); - } + } => sink.array_atomic_rmw_sub(ordering, TypeIdx(array_type_index)), Instruction::ArrayAtomicRmwAnd { ordering, array_type_index, - } => { - sink.push(0xFE); - sink.push(0x6D); - ordering.encode(sink); - array_type_index.encode(sink); - } + } => sink.array_atomic_rmw_and(ordering, TypeIdx(array_type_index)), Instruction::ArrayAtomicRmwOr { ordering, array_type_index, - } => { - sink.push(0xFE); - sink.push(0x6E); - ordering.encode(sink); - array_type_index.encode(sink); - } + } => sink.array_atomic_rmw_or(ordering, TypeIdx(array_type_index)), Instruction::ArrayAtomicRmwXor { ordering, array_type_index, - } => { - sink.push(0xFE); - sink.push(0x6F); - ordering.encode(sink); - array_type_index.encode(sink); - } + } => sink.array_atomic_rmw_xor(ordering, TypeIdx(array_type_index)), Instruction::ArrayAtomicRmwXchg { ordering, array_type_index, - } => { - sink.push(0xFE); - sink.push(0x70); - ordering.encode(sink); - array_type_index.encode(sink); - } + } => sink.array_atomic_rmw_xchg(ordering, TypeIdx(array_type_index)), Instruction::ArrayAtomicRmwCmpxchg { ordering, array_type_index, - } => { - sink.push(0xFE); - sink.push(0x71); - ordering.encode(sink); - array_type_index.encode(sink); - } - Instruction::RefI31Shared => { - sink.push(0xFE); - sink.push(0x72); - } - Instruction::ContNew(type_index) => { - sink.push(0xE0); - type_index.encode(sink); - } + } => sink.array_atomic_rmw_cmpxchg(ordering, TypeIdx(array_type_index)), + Instruction::RefI31Shared => sink.ref_i31_shared(), + Instruction::ContNew(type_index) => sink.cont_new(TypeIdx(type_index)), Instruction::ContBind { argument_index, result_index, - } => { - sink.push(0xE1); - argument_index.encode(sink); - result_index.encode(sink); - } - Instruction::Suspend(tag_index) => { - sink.push(0xE2); - tag_index.encode(sink); - } + } => sink.cont_bind(TypeIdx(argument_index), TypeIdx(result_index)), + Instruction::Suspend(tag_index) => sink.suspend(TagIdx(tag_index)), Instruction::Resume { cont_type_index, ref resume_table, - } => { - sink.push(0xE3); - cont_type_index.encode(sink); - resume_table.encode(sink); - } + } => sink.resume(TypeIdx(cont_type_index), resume_table.iter().cloned()), Instruction::ResumeThrow { cont_type_index, tag_index, ref resume_table, - } => { - sink.push(0xE4); - cont_type_index.encode(sink); - tag_index.encode(sink); - resume_table.encode(sink); - } + } => sink.resume_throw( + TypeIdx(cont_type_index), + TagIdx(tag_index), + resume_table.iter().cloned(), + ), Instruction::Switch { cont_type_index, tag_index, - } => { - sink.push(0xE5); - cont_type_index.encode(sink); - tag_index.encode(sink); - } - Instruction::I64Add128 => { - sink.push(0xFC); - 19u32.encode(sink); - } - Instruction::I64Sub128 => { - sink.push(0xFC); - 20u32.encode(sink); - } - Instruction::I64MulWideS => { - sink.push(0xFC); - 21u32.encode(sink); - } - Instruction::I64MulWideU => { - sink.push(0xFC); - 22u32.encode(sink); - } - } + } => sink.switch(TypeIdx(cont_type_index), TagIdx(tag_index)), + Instruction::I64Add128 => sink.i64_add128(), + Instruction::I64Sub128 => sink.i64_sub128(), + Instruction::I64MulWideS => sink.i64_mul_wide_s(), + Instruction::I64MulWideU => sink.i64_mul_wide_u(), + }; } } diff --git a/crates/wasm-encoder/src/core/instructions.rs b/crates/wasm-encoder/src/core/instructions.rs new file mode 100644 index 0000000000..93e78743ea --- /dev/null +++ b/crates/wasm-encoder/src/core/instructions.rs @@ -0,0 +1,4709 @@ +#[allow(unused_imports)] +use crate::Instruction; +use crate::{ + encode_vec, BlockType, Catch, DataIdx, ElemIdx, Encode, FieldIdx, FuncIdx, GlobalIdx, Handle, + HeapType, LabelIdx, Lane, LocalIdx, MemArg, MemIdx, Ordering, RefType, TableIdx, TagIdx, + TypeIdx, ValType, +}; +use alloc::vec::Vec; + +/// An encoder for Wasm instructions. +#[derive(Debug)] +pub struct InstructionSink<'a> { + sink: &'a mut Vec, +} + +impl<'a> InstructionSink<'a> { + /// Create an instruction encoder pointing to the given byte sink. + pub fn new(sink: &'a mut Vec) -> Self { + Self { sink } + } + + // Control instructions. + + /// Encode [`Instruction::Unreachable`]. + pub fn unreachable(&mut self) -> &mut Self { + self.sink.push(0x00); + self + } + + /// Encode [`Instruction::Nop`]. + pub fn nop(&mut self) -> &mut Self { + self.sink.push(0x01); + self + } + + /// Encode [`Instruction::Block`]. + pub fn block(&mut self, bt: BlockType) -> &mut Self { + self.sink.push(0x02); + bt.encode(self.sink); + self + } + + /// Encode [`Instruction::Loop`]. + pub fn loop_(&mut self, bt: BlockType) -> &mut Self { + self.sink.push(0x03); + bt.encode(self.sink); + self + } + + /// Encode [`Instruction::If`]. + pub fn if_(&mut self, bt: BlockType) -> &mut Self { + self.sink.push(0x04); + bt.encode(self.sink); + self + } + + /// Encode [`Instruction::Else`]. + pub fn else_(&mut self) -> &mut Self { + self.sink.push(0x05); + self + } + + /// Encode [`Instruction::End`]. + pub fn end(&mut self) -> &mut Self { + self.sink.push(0x0B); + self + } + + /// Encode [`Instruction::Br`]. + pub fn br(&mut self, l: LabelIdx) -> &mut Self { + self.sink.push(0x0C); + l.encode(self.sink); + self + } + + /// Encode [`Instruction::BrIf`]. + pub fn br_if(&mut self, l: LabelIdx) -> &mut Self { + self.sink.push(0x0D); + l.encode(self.sink); + self + } + + /// Encode [`Instruction::BrTable`]. + pub fn br_table>(&mut self, ls: V, l: LabelIdx) -> &mut Self + where + V::IntoIter: ExactSizeIterator, + { + self.sink.push(0x0E); + encode_vec(ls, self.sink); + l.encode(self.sink); + self + } + + /// Encode [`Instruction::BrOnNull`]. + pub fn br_on_null(&mut self, l: LabelIdx) -> &mut Self { + self.sink.push(0xD5); + l.encode(self.sink); + self + } + + /// Encode [`Instruction::BrOnNonNull`]. + pub fn br_on_non_null(&mut self, l: LabelIdx) -> &mut Self { + self.sink.push(0xD6); + l.encode(self.sink); + self + } + + /// Encode [`Instruction::Return`]. + pub fn return_(&mut self) -> &mut Self { + self.sink.push(0x0F); + self + } + + /// Encode [`Instruction::Call`]. + pub fn call(&mut self, f: FuncIdx) -> &mut Self { + self.sink.push(0x10); + f.encode(self.sink); + self + } + + /// Encode [`Instruction::CallRef`]. + pub fn call_ref(&mut self, ty: TypeIdx) -> &mut Self { + self.sink.push(0x14); + ty.encode(self.sink); + self + } + + /// Encode [`Instruction::CallIndirect`]. + pub fn call_indirect(&mut self, table_index: TableIdx, type_index: TypeIdx) -> &mut Self { + self.sink.push(0x11); + type_index.encode(self.sink); + table_index.encode(self.sink); + self + } + + /// Encode [`Instruction::ReturnCallRef`]. + pub fn return_call_ref(&mut self, ty: TypeIdx) -> &mut Self { + self.sink.push(0x15); + ty.encode(self.sink); + self + } + + /// Encode [`Instruction::ReturnCall`]. + pub fn return_call(&mut self, f: FuncIdx) -> &mut Self { + self.sink.push(0x12); + f.encode(self.sink); + self + } + + /// Encode [`Instruction::ReturnCallIndirect`]. + pub fn return_call_indirect( + &mut self, + table_index: TableIdx, + type_index: TypeIdx, + ) -> &mut Self { + self.sink.push(0x13); + type_index.encode(self.sink); + table_index.encode(self.sink); + self + } + + /// Encode [`Instruction::TryTable`]. + pub fn try_table>( + &mut self, + ty: BlockType, + catches: V, + ) -> &mut Self + where + V::IntoIter: ExactSizeIterator, + { + self.sink.push(0x1f); + ty.encode(self.sink); + encode_vec(catches, self.sink); + self + } + + /// Encode [`Instruction::Throw`]. + pub fn throw(&mut self, t: TagIdx) -> &mut Self { + self.sink.push(0x08); + t.encode(self.sink); + self + } + + /// Encode [`Instruction::ThrowRef`]. + pub fn throw_ref(&mut self) -> &mut Self { + self.sink.push(0x0A); + self + } + + // Deprecated exception-handling instructions + + /// Encode [`Instruction::Try`]. + pub fn try_(&mut self, bt: BlockType) -> &mut Self { + self.sink.push(0x06); + bt.encode(self.sink); + self + } + + /// Encode [`Instruction::Delegate`]. + pub fn delegate(&mut self, l: LabelIdx) -> &mut Self { + self.sink.push(0x18); + l.encode(self.sink); + self + } + + /// Encode [`Instruction::Catch`]. + pub fn catch(&mut self, t: TagIdx) -> &mut Self { + self.sink.push(0x07); + t.encode(self.sink); + self + } + + /// Encode [`Instruction::CatchAll`]. + pub fn catch_all(&mut self) -> &mut Self { + self.sink.push(0x19); + self + } + + /// Encode [`Instruction::Rethrow`]. + pub fn rethrow(&mut self, l: LabelIdx) -> &mut Self { + self.sink.push(0x09); + l.encode(self.sink); + self + } + + // Parametric instructions. + + /// Encode [`Instruction::Drop`]. + pub fn drop(&mut self) -> &mut Self { + self.sink.push(0x1A); + self + } + + /// Encode [`Instruction::Select`]. + pub fn select(&mut self) -> &mut Self { + self.sink.push(0x1B); + self + } + + // Variable instructions. + + /// Encode [`Instruction::LocalGet`]. + pub fn local_get(&mut self, l: LocalIdx) -> &mut Self { + self.sink.push(0x20); + l.encode(self.sink); + self + } + + /// Encode [`Instruction::LocalSet`]. + pub fn local_set(&mut self, l: LocalIdx) -> &mut Self { + self.sink.push(0x21); + l.encode(self.sink); + self + } + + /// Encode [`Instruction::LocalTee`]. + pub fn local_tee(&mut self, l: LocalIdx) -> &mut Self { + self.sink.push(0x22); + l.encode(self.sink); + self + } + + /// Encode [`Instruction::GlobalGet`]. + pub fn global_get(&mut self, g: GlobalIdx) -> &mut Self { + self.sink.push(0x23); + g.encode(self.sink); + self + } + + /// Encode [`Instruction::GlobalSet`]. + pub fn global_set(&mut self, g: GlobalIdx) -> &mut Self { + self.sink.push(0x24); + g.encode(self.sink); + self + } + + // Memory instructions. + + /// Encode [`Instruction::I32Load`]. + pub fn i32_load(&mut self, m: MemArg) -> &mut Self { + self.sink.push(0x28); + m.encode(self.sink); + self + } + + /// Encode [`Instruction::I64Load`]. + pub fn i64_load(&mut self, m: MemArg) -> &mut Self { + self.sink.push(0x29); + m.encode(self.sink); + self + } + + /// Encode [`Instruction::F32Load`]. + pub fn f32_load(&mut self, m: MemArg) -> &mut Self { + self.sink.push(0x2A); + m.encode(self.sink); + self + } + + /// Encode [`Instruction::F64Load`]. + pub fn f64_load(&mut self, m: MemArg) -> &mut Self { + self.sink.push(0x2B); + m.encode(self.sink); + self + } + + /// Encode [`Instruction::I32Load8S`]. + pub fn i32_load8_s(&mut self, m: MemArg) -> &mut Self { + self.sink.push(0x2C); + m.encode(self.sink); + self + } + + /// Encode [`Instruction::I32Load8U`]. + pub fn i32_load8_u(&mut self, m: MemArg) -> &mut Self { + self.sink.push(0x2D); + m.encode(self.sink); + self + } + + /// Encode [`Instruction::I32Load16S`]. + pub fn i32_load16_s(&mut self, m: MemArg) -> &mut Self { + self.sink.push(0x2E); + m.encode(self.sink); + self + } + + /// Encode [`Instruction::I32Load16U`]. + pub fn i32_load16_u(&mut self, m: MemArg) -> &mut Self { + self.sink.push(0x2F); + m.encode(self.sink); + self + } + + /// Encode [`Instruction::I64Load8S`]. + pub fn i64_load8_s(&mut self, m: MemArg) -> &mut Self { + self.sink.push(0x30); + m.encode(self.sink); + self + } + + /// Encode [`Instruction::I64Load8U`]. + pub fn i64_load8_u(&mut self, m: MemArg) -> &mut Self { + self.sink.push(0x31); + m.encode(self.sink); + self + } + + /// Encode [`Instruction::I64Load16S`]. + pub fn i64_load16_s(&mut self, m: MemArg) -> &mut Self { + self.sink.push(0x32); + m.encode(self.sink); + self + } + + /// Encode [`Instruction::I64Load16U`]. + pub fn i64_load16_u(&mut self, m: MemArg) -> &mut Self { + self.sink.push(0x33); + m.encode(self.sink); + self + } + + /// Encode [`Instruction::I64Load32S`]. + pub fn i64_load32_s(&mut self, m: MemArg) -> &mut Self { + self.sink.push(0x34); + m.encode(self.sink); + self + } + + /// Encode [`Instruction::I64Load32U`]. + pub fn i64_load32_u(&mut self, m: MemArg) -> &mut Self { + self.sink.push(0x35); + m.encode(self.sink); + self + } + + /// Encode [`Instruction::I32Store`]. + pub fn i32_store(&mut self, m: MemArg) -> &mut Self { + self.sink.push(0x36); + m.encode(self.sink); + self + } + + /// Encode [`Instruction::I64Store`]. + pub fn i64_store(&mut self, m: MemArg) -> &mut Self { + self.sink.push(0x37); + m.encode(self.sink); + self + } + + /// Encode [`Instruction::F32Store`]. + pub fn f32_store(&mut self, m: MemArg) -> &mut Self { + self.sink.push(0x38); + m.encode(self.sink); + self + } + + /// Encode [`Instruction::F64Store`]. + pub fn f64_store(&mut self, m: MemArg) -> &mut Self { + self.sink.push(0x39); + m.encode(self.sink); + self + } + + /// Encode [`Instruction::I32Store8`]. + pub fn i32_store8(&mut self, m: MemArg) -> &mut Self { + self.sink.push(0x3A); + m.encode(self.sink); + self + } + + /// Encode [`Instruction::I32Store16`]. + pub fn i32_store16(&mut self, m: MemArg) -> &mut Self { + self.sink.push(0x3B); + m.encode(self.sink); + self + } + + /// Encode [`Instruction::I64Store8`]. + pub fn i64_store8(&mut self, m: MemArg) -> &mut Self { + self.sink.push(0x3C); + m.encode(self.sink); + self + } + + /// Encode [`Instruction::I64Store16`]. + pub fn i64_store16(&mut self, m: MemArg) -> &mut Self { + self.sink.push(0x3D); + m.encode(self.sink); + self + } + + /// Encode [`Instruction::I64Store32`]. + pub fn i64_store32(&mut self, m: MemArg) -> &mut Self { + self.sink.push(0x3E); + m.encode(self.sink); + self + } + + /// Encode [`Instruction::MemorySize`]. + pub fn memory_size(&mut self, i: MemIdx) -> &mut Self { + self.sink.push(0x3F); + i.encode(self.sink); + self + } + + /// Encode [`Instruction::MemoryGrow`]. + pub fn memory_grow(&mut self, i: MemIdx) -> &mut Self { + self.sink.push(0x40); + i.encode(self.sink); + self + } + + /// Encode [`Instruction::MemoryInit`]. + pub fn memory_init(&mut self, mem: MemIdx, data_index: DataIdx) -> &mut Self { + self.sink.push(0xfc); + self.sink.push(0x08); + data_index.encode(self.sink); + mem.encode(self.sink); + self + } + + /// Encode [`Instruction::DataDrop`]. + pub fn data_drop(&mut self, data: DataIdx) -> &mut Self { + self.sink.push(0xfc); + self.sink.push(0x09); + data.encode(self.sink); + self + } + + /// Encode [`Instruction::MemoryCopy`]. + pub fn memory_copy(&mut self, dst_mem: MemIdx, src_mem: MemIdx) -> &mut Self { + self.sink.push(0xfc); + self.sink.push(0x0a); + dst_mem.encode(self.sink); + src_mem.encode(self.sink); + self + } + + /// Encode [`Instruction::MemoryFill`]. + pub fn memory_fill(&mut self, mem: MemIdx) -> &mut Self { + self.sink.push(0xfc); + self.sink.push(0x0b); + mem.encode(self.sink); + self + } + + /// Encode [`Instruction::MemoryDiscard`]. + pub fn memory_discard(&mut self, mem: MemIdx) -> &mut Self { + self.sink.push(0xfc); + self.sink.push(0x12); + mem.encode(self.sink); + self + } + + // Numeric instructions. + + /// Encode [`Instruction::I32Const`]. + pub fn i32_const(&mut self, x: i32) -> &mut Self { + self.sink.push(0x41); + x.encode(self.sink); + self + } + + /// Encode [`Instruction::I64Const`]. + pub fn i64_const(&mut self, x: i64) -> &mut Self { + self.sink.push(0x42); + x.encode(self.sink); + self + } + + /// Encode [`Instruction::F32Const`]. + pub fn f32_const(&mut self, x: f32) -> &mut Self { + self.sink.push(0x43); + let x = x.to_bits(); + self.sink.extend(x.to_le_bytes().iter().copied()); + self + } + + /// Encode [`Instruction::F64Const`]. + pub fn f64_const(&mut self, x: f64) -> &mut Self { + self.sink.push(0x44); + let x = x.to_bits(); + self.sink.extend(x.to_le_bytes().iter().copied()); + self + } + + /// Encode [`Instruction::I32Eqz`]. + pub fn i32_eqz(&mut self) -> &mut Self { + self.sink.push(0x45); + self + } + + /// Encode [`Instruction::I32Eq`]. + pub fn i32_eq(&mut self) -> &mut Self { + self.sink.push(0x46); + self + } + + /// Encode [`Instruction::I32Ne`]. + pub fn i32_ne(&mut self) -> &mut Self { + self.sink.push(0x47); + self + } + + /// Encode [`Instruction::I32LtS`]. + pub fn i32_lt_s(&mut self) -> &mut Self { + self.sink.push(0x48); + self + } + + /// Encode [`Instruction::I32LtU`]. + pub fn i32_lt_u(&mut self) -> &mut Self { + self.sink.push(0x49); + self + } + + /// Encode [`Instruction::I32GtS`]. + pub fn i32_gt_s(&mut self) -> &mut Self { + self.sink.push(0x4A); + self + } + + /// Encode [`Instruction::I32GtU`]. + pub fn i32_gt_u(&mut self) -> &mut Self { + self.sink.push(0x4B); + self + } + + /// Encode [`Instruction::I32LeS`]. + pub fn i32_le_s(&mut self) -> &mut Self { + self.sink.push(0x4C); + self + } + + /// Encode [`Instruction::I32LeU`]. + pub fn i32_le_u(&mut self) -> &mut Self { + self.sink.push(0x4D); + self + } + + /// Encode [`Instruction::I32GeS`]. + pub fn i32_ge_s(&mut self) -> &mut Self { + self.sink.push(0x4E); + self + } + + /// Encode [`Instruction::I32GeU`]. + pub fn i32_ge_u(&mut self) -> &mut Self { + self.sink.push(0x4F); + self + } + + /// Encode [`Instruction::I64Eqz`]. + pub fn i64_eqz(&mut self) -> &mut Self { + self.sink.push(0x50); + self + } + + /// Encode [`Instruction::I64Eq`]. + pub fn i64_eq(&mut self) -> &mut Self { + self.sink.push(0x51); + self + } + + /// Encode [`Instruction::I64Ne`]. + pub fn i64_ne(&mut self) -> &mut Self { + self.sink.push(0x52); + self + } + + /// Encode [`Instruction::I64LtS`]. + pub fn i64_lt_s(&mut self) -> &mut Self { + self.sink.push(0x53); + self + } + + /// Encode [`Instruction::I64LtU`]. + pub fn i64_lt_u(&mut self) -> &mut Self { + self.sink.push(0x54); + self + } + + /// Encode [`Instruction::I64GtS`]. + pub fn i64_gt_s(&mut self) -> &mut Self { + self.sink.push(0x55); + self + } + + /// Encode [`Instruction::I64GtU`]. + pub fn i64_gt_u(&mut self) -> &mut Self { + self.sink.push(0x56); + self + } + + /// Encode [`Instruction::I64LeS`]. + pub fn i64_le_s(&mut self) -> &mut Self { + self.sink.push(0x57); + self + } + + /// Encode [`Instruction::I64LeU`]. + pub fn i64_le_u(&mut self) -> &mut Self { + self.sink.push(0x58); + self + } + + /// Encode [`Instruction::I64GeS`]. + pub fn i64_ge_s(&mut self) -> &mut Self { + self.sink.push(0x59); + self + } + + /// Encode [`Instruction::I64GeU`]. + pub fn i64_ge_u(&mut self) -> &mut Self { + self.sink.push(0x5A); + self + } + + /// Encode [`Instruction::F32Eq`]. + pub fn f32_eq(&mut self) -> &mut Self { + self.sink.push(0x5B); + self + } + + /// Encode [`Instruction::F32Ne`]. + pub fn f32_ne(&mut self) -> &mut Self { + self.sink.push(0x5C); + self + } + + /// Encode [`Instruction::F32Lt`]. + pub fn f32_lt(&mut self) -> &mut Self { + self.sink.push(0x5D); + self + } + + /// Encode [`Instruction::F32Gt`]. + pub fn f32_gt(&mut self) -> &mut Self { + self.sink.push(0x5E); + self + } + + /// Encode [`Instruction::F32Le`]. + pub fn f32_le(&mut self) -> &mut Self { + self.sink.push(0x5F); + self + } + + /// Encode [`Instruction::F32Ge`]. + pub fn f32_ge(&mut self) -> &mut Self { + self.sink.push(0x60); + self + } + + /// Encode [`Instruction::F64Eq`]. + pub fn f64_eq(&mut self) -> &mut Self { + self.sink.push(0x61); + self + } + + /// Encode [`Instruction::F64Ne`]. + pub fn f64_ne(&mut self) -> &mut Self { + self.sink.push(0x62); + self + } + + /// Encode [`Instruction::F64Lt`]. + pub fn f64_lt(&mut self) -> &mut Self { + self.sink.push(0x63); + self + } + + /// Encode [`Instruction::F64Gt`]. + pub fn f64_gt(&mut self) -> &mut Self { + self.sink.push(0x64); + self + } + + /// Encode [`Instruction::F64Le`]. + pub fn f64_le(&mut self) -> &mut Self { + self.sink.push(0x65); + self + } + + /// Encode [`Instruction::F64Ge`]. + pub fn f64_ge(&mut self) -> &mut Self { + self.sink.push(0x66); + self + } + + /// Encode [`Instruction::I32Clz`]. + pub fn i32_clz(&mut self) -> &mut Self { + self.sink.push(0x67); + self + } + + /// Encode [`Instruction::I32Ctz`]. + pub fn i32_ctz(&mut self) -> &mut Self { + self.sink.push(0x68); + self + } + + /// Encode [`Instruction::I32Popcnt`]. + pub fn i32_popcnt(&mut self) -> &mut Self { + self.sink.push(0x69); + self + } + + /// Encode [`Instruction::I32Add`]. + pub fn i32_add(&mut self) -> &mut Self { + self.sink.push(0x6A); + self + } + + /// Encode [`Instruction::I32Sub`]. + pub fn i32_sub(&mut self) -> &mut Self { + self.sink.push(0x6B); + self + } + + /// Encode [`Instruction::I32Mul`]. + pub fn i32_mul(&mut self) -> &mut Self { + self.sink.push(0x6C); + self + } + + /// Encode [`Instruction::I32DivS`]. + pub fn i32_div_s(&mut self) -> &mut Self { + self.sink.push(0x6D); + self + } + + /// Encode [`Instruction::I32DivU`]. + pub fn i32_div_u(&mut self) -> &mut Self { + self.sink.push(0x6E); + self + } + + /// Encode [`Instruction::I32RemS`]. + pub fn i32_rem_s(&mut self) -> &mut Self { + self.sink.push(0x6F); + self + } + + /// Encode [`Instruction::I32RemU`]. + pub fn i32_rem_u(&mut self) -> &mut Self { + self.sink.push(0x70); + self + } + + /// Encode [`Instruction::I32And`]. + pub fn i32_and(&mut self) -> &mut Self { + self.sink.push(0x71); + self + } + + /// Encode [`Instruction::I32Or`]. + pub fn i32_or(&mut self) -> &mut Self { + self.sink.push(0x72); + self + } + + /// Encode [`Instruction::I32Xor`]. + pub fn i32_xor(&mut self) -> &mut Self { + self.sink.push(0x73); + self + } + + /// Encode [`Instruction::I32Shl`]. + pub fn i32_shl(&mut self) -> &mut Self { + self.sink.push(0x74); + self + } + + /// Encode [`Instruction::I32ShrS`]. + pub fn i32_shr_s(&mut self) -> &mut Self { + self.sink.push(0x75); + self + } + + /// Encode [`Instruction::I32ShrU`]. + pub fn i32_shr_u(&mut self) -> &mut Self { + self.sink.push(0x76); + self + } + + /// Encode [`Instruction::I32Rotl`]. + pub fn i32_rotl(&mut self) -> &mut Self { + self.sink.push(0x77); + self + } + + /// Encode [`Instruction::I32Rotr`]. + pub fn i32_rotr(&mut self) -> &mut Self { + self.sink.push(0x78); + self + } + + /// Encode [`Instruction::I64Clz`]. + pub fn i64_clz(&mut self) -> &mut Self { + self.sink.push(0x79); + self + } + + /// Encode [`Instruction::I64Ctz`]. + pub fn i64_ctz(&mut self) -> &mut Self { + self.sink.push(0x7A); + self + } + + /// Encode [`Instruction::I64Popcnt`]. + pub fn i64_popcnt(&mut self) -> &mut Self { + self.sink.push(0x7B); + self + } + + /// Encode [`Instruction::I64Add`]. + pub fn i64_add(&mut self) -> &mut Self { + self.sink.push(0x7C); + self + } + + /// Encode [`Instruction::I64Sub`]. + pub fn i64_sub(&mut self) -> &mut Self { + self.sink.push(0x7D); + self + } + + /// Encode [`Instruction::I64Mul`]. + pub fn i64_mul(&mut self) -> &mut Self { + self.sink.push(0x7E); + self + } + + /// Encode [`Instruction::I64DivS`]. + pub fn i64_div_s(&mut self) -> &mut Self { + self.sink.push(0x7F); + self + } + + /// Encode [`Instruction::I64DivU`]. + pub fn i64_div_u(&mut self) -> &mut Self { + self.sink.push(0x80); + self + } + + /// Encode [`Instruction::I64RemS`]. + pub fn i64_rem_s(&mut self) -> &mut Self { + self.sink.push(0x81); + self + } + + /// Encode [`Instruction::I64RemU`]. + pub fn i64_rem_u(&mut self) -> &mut Self { + self.sink.push(0x82); + self + } + + /// Encode [`Instruction::I64And`]. + pub fn i64_and(&mut self) -> &mut Self { + self.sink.push(0x83); + self + } + + /// Encode [`Instruction::I64Or`]. + pub fn i64_or(&mut self) -> &mut Self { + self.sink.push(0x84); + self + } + + /// Encode [`Instruction::I64Xor`]. + pub fn i64_xor(&mut self) -> &mut Self { + self.sink.push(0x85); + self + } + + /// Encode [`Instruction::I64Shl`]. + pub fn i64_shl(&mut self) -> &mut Self { + self.sink.push(0x86); + self + } + + /// Encode [`Instruction::I64ShrS`]. + pub fn i64_shr_s(&mut self) -> &mut Self { + self.sink.push(0x87); + self + } + + /// Encode [`Instruction::I64ShrU`]. + pub fn i64_shr_u(&mut self) -> &mut Self { + self.sink.push(0x88); + self + } + + /// Encode [`Instruction::I64Rotl`]. + pub fn i64_rotl(&mut self) -> &mut Self { + self.sink.push(0x89); + self + } + + /// Encode [`Instruction::I64Rotr`]. + pub fn i64_rotr(&mut self) -> &mut Self { + self.sink.push(0x8A); + self + } + + /// Encode [`Instruction::F32Abs`]. + pub fn f32_abs(&mut self) -> &mut Self { + self.sink.push(0x8B); + self + } + + /// Encode [`Instruction::F32Neg`]. + pub fn f32_neg(&mut self) -> &mut Self { + self.sink.push(0x8C); + self + } + + /// Encode [`Instruction::F32Ceil`]. + pub fn f32_ceil(&mut self) -> &mut Self { + self.sink.push(0x8D); + self + } + + /// Encode [`Instruction::F32Floor`]. + pub fn f32_floor(&mut self) -> &mut Self { + self.sink.push(0x8E); + self + } + + /// Encode [`Instruction::F32Trunc`]. + pub fn f32_trunc(&mut self) -> &mut Self { + self.sink.push(0x8F); + self + } + + /// Encode [`Instruction::F32Nearest`]. + pub fn f32_nearest(&mut self) -> &mut Self { + self.sink.push(0x90); + self + } + + /// Encode [`Instruction::F32Sqrt`]. + pub fn f32_sqrt(&mut self) -> &mut Self { + self.sink.push(0x91); + self + } + + /// Encode [`Instruction::F32Add`]. + pub fn f32_add(&mut self) -> &mut Self { + self.sink.push(0x92); + self + } + + /// Encode [`Instruction::F32Sub`]. + pub fn f32_sub(&mut self) -> &mut Self { + self.sink.push(0x93); + self + } + + /// Encode [`Instruction::F32Mul`]. + pub fn f32_mul(&mut self) -> &mut Self { + self.sink.push(0x94); + self + } + + /// Encode [`Instruction::F32Div`]. + pub fn f32_div(&mut self) -> &mut Self { + self.sink.push(0x95); + self + } + + /// Encode [`Instruction::F32Min`]. + pub fn f32_min(&mut self) -> &mut Self { + self.sink.push(0x96); + self + } + + /// Encode [`Instruction::F32Max`]. + pub fn f32_max(&mut self) -> &mut Self { + self.sink.push(0x97); + self + } + + /// Encode [`Instruction::F32Copysign`]. + pub fn f32_copysign(&mut self) -> &mut Self { + self.sink.push(0x98); + self + } + + /// Encode [`Instruction::F64Abs`]. + pub fn f64_abs(&mut self) -> &mut Self { + self.sink.push(0x99); + self + } + + /// Encode [`Instruction::F64Neg`]. + pub fn f64_neg(&mut self) -> &mut Self { + self.sink.push(0x9A); + self + } + + /// Encode [`Instruction::F64Ceil`]. + pub fn f64_ceil(&mut self) -> &mut Self { + self.sink.push(0x9B); + self + } + + /// Encode [`Instruction::F64Floor`]. + pub fn f64_floor(&mut self) -> &mut Self { + self.sink.push(0x9C); + self + } + + /// Encode [`Instruction::F64Trunc`]. + pub fn f64_trunc(&mut self) -> &mut Self { + self.sink.push(0x9D); + self + } + + /// Encode [`Instruction::F64Nearest`]. + pub fn f64_nearest(&mut self) -> &mut Self { + self.sink.push(0x9E); + self + } + + /// Encode [`Instruction::F64Sqrt`]. + pub fn f64_sqrt(&mut self) -> &mut Self { + self.sink.push(0x9F); + self + } + + /// Encode [`Instruction::F64Add`]. + pub fn f64_add(&mut self) -> &mut Self { + self.sink.push(0xA0); + self + } + + /// Encode [`Instruction::F64Sub`]. + pub fn f64_sub(&mut self) -> &mut Self { + self.sink.push(0xA1); + self + } + + /// Encode [`Instruction::F64Mul`]. + pub fn f64_mul(&mut self) -> &mut Self { + self.sink.push(0xA2); + self + } + + /// Encode [`Instruction::F64Div`]. + pub fn f64_div(&mut self) -> &mut Self { + self.sink.push(0xA3); + self + } + + /// Encode [`Instruction::F64Min`]. + pub fn f64_min(&mut self) -> &mut Self { + self.sink.push(0xA4); + self + } + + /// Encode [`Instruction::F64Max`]. + pub fn f64_max(&mut self) -> &mut Self { + self.sink.push(0xA5); + self + } + + /// Encode [`Instruction::F64Copysign`]. + pub fn f64_copysign(&mut self) -> &mut Self { + self.sink.push(0xA6); + self + } + + /// Encode [`Instruction::I32WrapI64`]. + pub fn i32_wrap_i64(&mut self) -> &mut Self { + self.sink.push(0xA7); + self + } + + /// Encode [`Instruction::I32TruncF32S`]. + pub fn i32_trunc_f32_s(&mut self) -> &mut Self { + self.sink.push(0xA8); + self + } + + /// Encode [`Instruction::I32TruncF32U`]. + pub fn i32_trunc_f32_u(&mut self) -> &mut Self { + self.sink.push(0xA9); + self + } + + /// Encode [`Instruction::I32TruncF64S`]. + pub fn i32_trunc_f64_s(&mut self) -> &mut Self { + self.sink.push(0xAA); + self + } + + /// Encode [`Instruction::I32TruncF64U`]. + pub fn i32_trunc_f64_u(&mut self) -> &mut Self { + self.sink.push(0xAB); + self + } + + /// Encode [`Instruction::I64ExtendI32S`]. + pub fn i64_extend_i32_s(&mut self) -> &mut Self { + self.sink.push(0xAC); + self + } + + /// Encode [`Instruction::I64ExtendI32U`]. + pub fn i64_extend_i32_u(&mut self) -> &mut Self { + self.sink.push(0xAD); + self + } + + /// Encode [`Instruction::I64TruncF32S`]. + pub fn i64_trunc_f32_s(&mut self) -> &mut Self { + self.sink.push(0xAE); + self + } + + /// Encode [`Instruction::I64TruncF32U`]. + pub fn i64_trunc_f32_u(&mut self) -> &mut Self { + self.sink.push(0xAF); + self + } + + /// Encode [`Instruction::I64TruncF64S`]. + pub fn i64_trunc_f64_s(&mut self) -> &mut Self { + self.sink.push(0xB0); + self + } + + /// Encode [`Instruction::I64TruncF64U`]. + pub fn i64_trunc_f64_u(&mut self) -> &mut Self { + self.sink.push(0xB1); + self + } + + /// Encode [`Instruction::F32ConvertI32S`]. + pub fn f32_convert_i32_s(&mut self) -> &mut Self { + self.sink.push(0xB2); + self + } + + /// Encode [`Instruction::F32ConvertI32U`]. + pub fn f32_convert_i32_u(&mut self) -> &mut Self { + self.sink.push(0xB3); + self + } + + /// Encode [`Instruction::F32ConvertI64S`]. + pub fn f32_convert_i64_s(&mut self) -> &mut Self { + self.sink.push(0xB4); + self + } + + /// Encode [`Instruction::F32ConvertI64U`]. + pub fn f32_convert_i64_u(&mut self) -> &mut Self { + self.sink.push(0xB5); + self + } + + /// Encode [`Instruction::F32DemoteF64`]. + pub fn f32_demote_f64(&mut self) -> &mut Self { + self.sink.push(0xB6); + self + } + + /// Encode [`Instruction::F64ConvertI32S`]. + pub fn f64_convert_i32_s(&mut self) -> &mut Self { + self.sink.push(0xB7); + self + } + + /// Encode [`Instruction::F64ConvertI32U`]. + pub fn f64_convert_i32_u(&mut self) -> &mut Self { + self.sink.push(0xB8); + self + } + + /// Encode [`Instruction::F64ConvertI64S`]. + pub fn f64_convert_i64_s(&mut self) -> &mut Self { + self.sink.push(0xB9); + self + } + + /// Encode [`Instruction::F64ConvertI64U`]. + pub fn f64_convert_i64_u(&mut self) -> &mut Self { + self.sink.push(0xBA); + self + } + + /// Encode [`Instruction::F64PromoteF32`]. + pub fn f64_promote_f32(&mut self) -> &mut Self { + self.sink.push(0xBB); + self + } + + /// Encode [`Instruction::I32ReinterpretF32`]. + pub fn i32_reinterpret_f32(&mut self) -> &mut Self { + self.sink.push(0xBC); + self + } + + /// Encode [`Instruction::I64ReinterpretF64`]. + pub fn i64_reinterpret_f64(&mut self) -> &mut Self { + self.sink.push(0xBD); + self + } + + /// Encode [`Instruction::F32ReinterpretI32`]. + pub fn f32_reinterpret_i32(&mut self) -> &mut Self { + self.sink.push(0xBE); + self + } + + /// Encode [`Instruction::F64ReinterpretI64`]. + pub fn f64_reinterpret_i64(&mut self) -> &mut Self { + self.sink.push(0xBF); + self + } + + /// Encode [`Instruction::I32Extend8S`]. + pub fn i32_extend8_s(&mut self) -> &mut Self { + self.sink.push(0xC0); + self + } + + /// Encode [`Instruction::I32Extend16S`]. + pub fn i32_extend16_s(&mut self) -> &mut Self { + self.sink.push(0xC1); + self + } + + /// Encode [`Instruction::I64Extend8S`]. + pub fn i64_extend8_s(&mut self) -> &mut Self { + self.sink.push(0xC2); + self + } + + /// Encode [`Instruction::I64Extend16S`]. + pub fn i64_extend16_s(&mut self) -> &mut Self { + self.sink.push(0xC3); + self + } + + /// Encode [`Instruction::I64Extend32S`]. + pub fn i64_extend32_s(&mut self) -> &mut Self { + self.sink.push(0xC4); + self + } + + /// Encode [`Instruction::I32TruncSatF32S`]. + pub fn i32_trunc_sat_f32_s(&mut self) -> &mut Self { + self.sink.push(0xFC); + self.sink.push(0x00); + self + } + + /// Encode [`Instruction::I32TruncSatF32U`]. + pub fn i32_trunc_sat_f32_u(&mut self) -> &mut Self { + self.sink.push(0xFC); + self.sink.push(0x01); + self + } + + /// Encode [`Instruction::I32TruncSatF64S`]. + pub fn i32_trunc_sat_f64_s(&mut self) -> &mut Self { + self.sink.push(0xFC); + self.sink.push(0x02); + self + } + + /// Encode [`Instruction::I32TruncSatF64U`]. + pub fn i32_trunc_sat_f64_u(&mut self) -> &mut Self { + self.sink.push(0xFC); + self.sink.push(0x03); + self + } + + /// Encode [`Instruction::I64TruncSatF32S`]. + pub fn i64_trunc_sat_f32_s(&mut self) -> &mut Self { + self.sink.push(0xFC); + self.sink.push(0x04); + self + } + + /// Encode [`Instruction::I64TruncSatF32U`]. + pub fn i64_trunc_sat_f32_u(&mut self) -> &mut Self { + self.sink.push(0xFC); + self.sink.push(0x05); + self + } + + /// Encode [`Instruction::I64TruncSatF64S`]. + pub fn i64_trunc_sat_f64_s(&mut self) -> &mut Self { + self.sink.push(0xFC); + self.sink.push(0x06); + self + } + + /// Encode [`Instruction::I64TruncSatF64U`]. + pub fn i64_trunc_sat_f64_u(&mut self) -> &mut Self { + self.sink.push(0xFC); + self.sink.push(0x07); + self + } + + // Reference types instructions. + + /// Encode [`Instruction::TypedSelect`]. + pub fn typed_select(&mut self, ty: ValType) -> &mut Self { + self.sink.push(0x1c); + [ty].encode(self.sink); + self + } + + /// Encode [`Instruction::RefNull`]. + pub fn ref_null(&mut self, ty: HeapType) -> &mut Self { + self.sink.push(0xd0); + ty.encode(self.sink); + self + } + + /// Encode [`Instruction::RefIsNull`]. + pub fn ref_is_null(&mut self) -> &mut Self { + self.sink.push(0xd1); + self + } + + /// Encode [`Instruction::RefFunc`]. + pub fn ref_func(&mut self, f: FuncIdx) -> &mut Self { + self.sink.push(0xd2); + f.encode(self.sink); + self + } + + /// Encode [`Instruction::RefEq`]. + pub fn ref_eq(&mut self) -> &mut Self { + self.sink.push(0xd3); + self + } + + /// Encode [`Instruction::RefAsNonNull`]. + pub fn ref_as_non_null(&mut self) -> &mut Self { + self.sink.push(0xd4); + self + } + + // GC types instructions. + + /// Encode [`Instruction::StructNew`]. + pub fn struct_new(&mut self, type_index: TypeIdx) -> &mut Self { + self.sink.push(0xfb); + self.sink.push(0x00); + type_index.encode(self.sink); + self + } + + /// Encode [`Instruction::StructNewDefault`]. + pub fn struct_new_default(&mut self, type_index: TypeIdx) -> &mut Self { + self.sink.push(0xfb); + self.sink.push(0x01); + type_index.encode(self.sink); + self + } + + /// Encode [`Instruction::StructGet`]. + pub fn struct_get(&mut self, struct_type_index: TypeIdx, field_index: FieldIdx) -> &mut Self { + self.sink.push(0xfb); + self.sink.push(0x02); + struct_type_index.encode(self.sink); + field_index.encode(self.sink); + self + } + + /// Encode [`Instruction::StructGetS`]. + pub fn struct_get_s(&mut self, struct_type_index: TypeIdx, field_index: FieldIdx) -> &mut Self { + self.sink.push(0xfb); + self.sink.push(0x03); + struct_type_index.encode(self.sink); + field_index.encode(self.sink); + self + } + + /// Encode [`Instruction::StructGetU`]. + pub fn struct_get_u(&mut self, struct_type_index: TypeIdx, field_index: FieldIdx) -> &mut Self { + self.sink.push(0xfb); + self.sink.push(0x04); + struct_type_index.encode(self.sink); + field_index.encode(self.sink); + self + } + + /// Encode [`Instruction::StructSet`]. + pub fn struct_set(&mut self, struct_type_index: TypeIdx, field_index: FieldIdx) -> &mut Self { + self.sink.push(0xfb); + self.sink.push(0x05); + struct_type_index.encode(self.sink); + field_index.encode(self.sink); + self + } + + /// Encode [`Instruction::ArrayNew`]. + pub fn array_new(&mut self, type_index: TypeIdx) -> &mut Self { + self.sink.push(0xfb); + self.sink.push(0x06); + type_index.encode(self.sink); + self + } + + /// Encode [`Instruction::ArrayNewDefault`]. + pub fn array_new_default(&mut self, type_index: TypeIdx) -> &mut Self { + self.sink.push(0xfb); + self.sink.push(0x07); + type_index.encode(self.sink); + self + } + + /// Encode [`Instruction::ArrayNewFixed`]. + pub fn array_new_fixed(&mut self, array_type_index: TypeIdx, array_size: u32) -> &mut Self { + self.sink.push(0xfb); + self.sink.push(0x08); + array_type_index.encode(self.sink); + array_size.encode(self.sink); + self + } + + /// Encode [`Instruction::ArrayNewData`]. + pub fn array_new_data( + &mut self, + array_type_index: TypeIdx, + array_data_index: DataIdx, + ) -> &mut Self { + self.sink.push(0xfb); + self.sink.push(0x09); + array_type_index.encode(self.sink); + array_data_index.encode(self.sink); + self + } + + /// Encode [`Instruction::ArrayNewElem`]. + pub fn array_new_elem( + &mut self, + array_type_index: TypeIdx, + array_elem_index: ElemIdx, + ) -> &mut Self { + self.sink.push(0xfb); + self.sink.push(0x0a); + array_type_index.encode(self.sink); + array_elem_index.encode(self.sink); + self + } + + /// Encode [`Instruction::ArrayGet`]. + pub fn array_get(&mut self, type_index: TypeIdx) -> &mut Self { + self.sink.push(0xfb); + self.sink.push(0x0b); + type_index.encode(self.sink); + self + } + + /// Encode [`Instruction::ArrayGetS`]. + pub fn array_get_s(&mut self, type_index: TypeIdx) -> &mut Self { + self.sink.push(0xfb); + self.sink.push(0x0c); + type_index.encode(self.sink); + self + } + + /// Encode [`Instruction::ArrayGetU`]. + pub fn array_get_u(&mut self, type_index: TypeIdx) -> &mut Self { + self.sink.push(0xfb); + self.sink.push(0x0d); + type_index.encode(self.sink); + self + } + + /// Encode [`Instruction::ArraySet`]. + pub fn array_set(&mut self, type_index: TypeIdx) -> &mut Self { + self.sink.push(0xfb); + self.sink.push(0x0e); + type_index.encode(self.sink); + self + } + + /// Encode [`Instruction::ArrayLen`]. + pub fn array_len(&mut self) -> &mut Self { + self.sink.push(0xfb); + self.sink.push(0x0f); + self + } + + /// Encode [`Instruction::ArrayFill`]. + pub fn array_fill(&mut self, type_index: TypeIdx) -> &mut Self { + self.sink.push(0xfb); + self.sink.push(0x10); + type_index.encode(self.sink); + self + } + + /// Encode [`Instruction::ArrayCopy`]. + pub fn array_copy( + &mut self, + array_type_index_dst: TypeIdx, + array_type_index_src: TypeIdx, + ) -> &mut Self { + self.sink.push(0xfb); + self.sink.push(0x11); + array_type_index_dst.encode(self.sink); + array_type_index_src.encode(self.sink); + self + } + + /// Encode [`Instruction::ArrayInitData`]. + pub fn array_init_data( + &mut self, + array_type_index: TypeIdx, + array_data_index: DataIdx, + ) -> &mut Self { + self.sink.push(0xfb); + self.sink.push(0x12); + array_type_index.encode(self.sink); + array_data_index.encode(self.sink); + self + } + + /// Encode [`Instruction::ArrayInitElem`]. + pub fn array_init_elem( + &mut self, + array_type_index: TypeIdx, + array_elem_index: ElemIdx, + ) -> &mut Self { + self.sink.push(0xfb); + self.sink.push(0x13); + array_type_index.encode(self.sink); + array_elem_index.encode(self.sink); + self + } + + /// Encode [`Instruction::RefTestNonNull`]. + pub fn ref_test_non_null(&mut self, heap_type: HeapType) -> &mut Self { + self.sink.push(0xfb); + self.sink.push(0x14); + heap_type.encode(self.sink); + self + } + + /// Encode [`Instruction::RefTestNullable`]. + pub fn ref_test_nullable(&mut self, heap_type: HeapType) -> &mut Self { + self.sink.push(0xfb); + self.sink.push(0x15); + heap_type.encode(self.sink); + self + } + + /// Encode [`Instruction::RefCastNonNull`]. + pub fn ref_cast_non_null(&mut self, heap_type: HeapType) -> &mut Self { + self.sink.push(0xfb); + self.sink.push(0x16); + heap_type.encode(self.sink); + self + } + + /// Encode [`Instruction::RefCastNullable`]. + pub fn ref_cast_nullable(&mut self, heap_type: HeapType) -> &mut Self { + self.sink.push(0xfb); + self.sink.push(0x17); + heap_type.encode(self.sink); + self + } + + /// Encode [`Instruction::BrOnCast`]. + pub fn br_on_cast( + &mut self, + relative_depth: LabelIdx, + from_ref_type: RefType, + to_ref_type: RefType, + ) -> &mut Self { + self.sink.push(0xfb); + self.sink.push(0x18); + let cast_flags = (from_ref_type.nullable as u8) | ((to_ref_type.nullable as u8) << 1); + self.sink.push(cast_flags); + relative_depth.encode(self.sink); + from_ref_type.heap_type.encode(self.sink); + to_ref_type.heap_type.encode(self.sink); + self + } + + /// Encode [`Instruction::BrOnCastFail`]. + pub fn br_on_cast_fail( + &mut self, + relative_depth: LabelIdx, + from_ref_type: RefType, + to_ref_type: RefType, + ) -> &mut Self { + self.sink.push(0xfb); + self.sink.push(0x19); + let cast_flags = (from_ref_type.nullable as u8) | ((to_ref_type.nullable as u8) << 1); + self.sink.push(cast_flags); + relative_depth.encode(self.sink); + from_ref_type.heap_type.encode(self.sink); + to_ref_type.heap_type.encode(self.sink); + self + } + + /// Encode [`Instruction::AnyConvertExtern`]. + pub fn any_convert_extern(&mut self) -> &mut Self { + self.sink.push(0xfb); + self.sink.push(0x1a); + self + } + + /// Encode [`Instruction::ExternConvertAny`]. + pub fn extern_convert_any(&mut self) -> &mut Self { + self.sink.push(0xfb); + self.sink.push(0x1b); + self + } + + /// Encode [`Instruction::RefI31`]. + pub fn ref_i31(&mut self) -> &mut Self { + self.sink.push(0xfb); + self.sink.push(0x1c); + self + } + + /// Encode [`Instruction::I31GetS`]. + pub fn i31_get_s(&mut self) -> &mut Self { + self.sink.push(0xfb); + self.sink.push(0x1d); + self + } + + /// Encode [`Instruction::I31GetU`]. + pub fn i31_get_u(&mut self) -> &mut Self { + self.sink.push(0xfb); + self.sink.push(0x1e); + self + } + + // Bulk memory instructions. + + /// Encode [`Instruction::TableInit`]. + pub fn table_init(&mut self, table: TableIdx, elem_index: ElemIdx) -> &mut Self { + self.sink.push(0xfc); + self.sink.push(0x0c); + elem_index.encode(self.sink); + table.encode(self.sink); + self + } + + /// Encode [`Instruction::ElemDrop`]. + pub fn elem_drop(&mut self, segment: ElemIdx) -> &mut Self { + self.sink.push(0xfc); + self.sink.push(0x0d); + segment.encode(self.sink); + self + } + + /// Encode [`Instruction::TableFill`]. + pub fn table_fill(&mut self, table: TableIdx) -> &mut Self { + self.sink.push(0xfc); + self.sink.push(0x11); + table.encode(self.sink); + self + } + + /// Encode [`Instruction::TableSet`]. + pub fn table_set(&mut self, table: TableIdx) -> &mut Self { + self.sink.push(0x26); + table.encode(self.sink); + self + } + + /// Encode [`Instruction::TableGet`]. + pub fn table_get(&mut self, table: TableIdx) -> &mut Self { + self.sink.push(0x25); + table.encode(self.sink); + self + } + + /// Encode [`Instruction::TableGrow`]. + pub fn table_grow(&mut self, table: TableIdx) -> &mut Self { + self.sink.push(0xfc); + self.sink.push(0x0f); + table.encode(self.sink); + self + } + + /// Encode [`Instruction::TableSize`]. + pub fn table_size(&mut self, table: TableIdx) -> &mut Self { + self.sink.push(0xfc); + self.sink.push(0x10); + table.encode(self.sink); + self + } + + /// Encode [`Instruction::TableCopy`]. + pub fn table_copy(&mut self, dst_table: TableIdx, src_table: TableIdx) -> &mut Self { + self.sink.push(0xfc); + self.sink.push(0x0e); + dst_table.encode(self.sink); + src_table.encode(self.sink); + self + } + + // SIMD instructions. + + /// Encode [`Instruction::V128Load`]. + pub fn v128_load(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFD); + 0x00u32.encode(self.sink); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::V128Load8x8S`]. + pub fn v128_load8x8_s(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFD); + 0x01u32.encode(self.sink); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::V128Load8x8U`]. + pub fn v128_load8x8_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFD); + 0x02u32.encode(self.sink); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::V128Load16x4S`]. + pub fn v128_load16x4_s(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFD); + 0x03u32.encode(self.sink); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::V128Load16x4U`]. + pub fn v128_load16x4_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFD); + 0x04u32.encode(self.sink); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::V128Load32x2S`]. + pub fn v128_load32x2_s(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFD); + 0x05u32.encode(self.sink); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::V128Load32x2U`]. + pub fn v128_load32x2_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFD); + 0x06u32.encode(self.sink); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::V128Load8Splat`]. + pub fn v128_load8_splat(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFD); + 0x07u32.encode(self.sink); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::V128Load16Splat`]. + pub fn v128_load16_splat(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFD); + 0x08u32.encode(self.sink); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::V128Load32Splat`]. + pub fn v128_load32_splat(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFD); + 0x09u32.encode(self.sink); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::V128Load64Splat`]. + pub fn v128_load64_splat(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFD); + 0x0Au32.encode(self.sink); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::V128Load32Zero`]. + pub fn v128_load32_zero(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFD); + 0x5Cu32.encode(self.sink); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::V128Load64Zero`]. + pub fn v128_load64_zero(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFD); + 0x5Du32.encode(self.sink); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::V128Store`]. + pub fn v128_store(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFD); + 0x0Bu32.encode(self.sink); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::V128Load8Lane`]. + pub fn v128_load8_lane(&mut self, memarg: MemArg, lane: Lane) -> &mut Self { + self.sink.push(0xFD); + 0x54u32.encode(self.sink); + memarg.encode(self.sink); + assert!(lane < 16); + self.sink.push(lane); + self + } + + /// Encode [`Instruction::V128Load16Lane`]. + pub fn v128_load16_lane(&mut self, memarg: MemArg, lane: Lane) -> &mut Self { + self.sink.push(0xFD); + 0x55u32.encode(self.sink); + memarg.encode(self.sink); + assert!(lane < 8); + self.sink.push(lane); + self + } + + /// Encode [`Instruction::V128Load32Lane`]. + pub fn v128_load32_lane(&mut self, memarg: MemArg, lane: Lane) -> &mut Self { + self.sink.push(0xFD); + 0x56u32.encode(self.sink); + memarg.encode(self.sink); + assert!(lane < 4); + self.sink.push(lane); + self + } + + /// Encode [`Instruction::V128Load64Lane`]. + pub fn v128_load64_lane(&mut self, memarg: MemArg, lane: Lane) -> &mut Self { + self.sink.push(0xFD); + 0x57u32.encode(self.sink); + memarg.encode(self.sink); + assert!(lane < 2); + self.sink.push(lane); + self + } + + /// Encode [`Instruction::V128Store8Lane`]. + pub fn v128_store8_lane(&mut self, memarg: MemArg, lane: Lane) -> &mut Self { + self.sink.push(0xFD); + 0x58u32.encode(self.sink); + memarg.encode(self.sink); + assert!(lane < 16); + self.sink.push(lane); + self + } + + /// Encode [`Instruction::V128Store16Lane`]. + pub fn v128_store16_lane(&mut self, memarg: MemArg, lane: Lane) -> &mut Self { + self.sink.push(0xFD); + 0x59u32.encode(self.sink); + memarg.encode(self.sink); + assert!(lane < 8); + self.sink.push(lane); + self + } + + /// Encode [`Instruction::V128Store32Lane`]. + pub fn v128_store32_lane(&mut self, memarg: MemArg, lane: Lane) -> &mut Self { + self.sink.push(0xFD); + 0x5Au32.encode(self.sink); + memarg.encode(self.sink); + assert!(lane < 4); + self.sink.push(lane); + self + } + + /// Encode [`Instruction::V128Store64Lane`]. + pub fn v128_store64_lane(&mut self, memarg: MemArg, lane: Lane) -> &mut Self { + self.sink.push(0xFD); + 0x5Bu32.encode(self.sink); + memarg.encode(self.sink); + assert!(lane < 2); + self.sink.push(lane); + self + } + + /// Encode [`Instruction::V128Const`]. + pub fn v128_const(&mut self, x: i128) -> &mut Self { + self.sink.push(0xFD); + 0x0Cu32.encode(self.sink); + self.sink.extend(x.to_le_bytes().iter().copied()); + self + } + + /// Encode [`Instruction::I8x16Shuffle`]. + pub fn i8x16_shuffle(&mut self, lanes: [Lane; 16]) -> &mut Self { + self.sink.push(0xFD); + 0x0Du32.encode(self.sink); + assert!(lanes.iter().all(|l: &u8| *l < 32)); + self.sink.extend(lanes.iter().copied()); + self + } + + /// Encode [`Instruction::I8x16ExtractLaneS`]. + pub fn i8x16_extract_lane_s(&mut self, lane: Lane) -> &mut Self { + self.sink.push(0xFD); + 0x15u32.encode(self.sink); + assert!(lane < 16); + self.sink.push(lane); + self + } + + /// Encode [`Instruction::I8x16ExtractLaneU`]. + pub fn i8x16_extract_lane_u(&mut self, lane: Lane) -> &mut Self { + self.sink.push(0xFD); + 0x16u32.encode(self.sink); + assert!(lane < 16); + self.sink.push(lane); + self + } + + /// Encode [`Instruction::I8x16ReplaceLane`]. + pub fn i8x16_replace_lane(&mut self, lane: Lane) -> &mut Self { + self.sink.push(0xFD); + 0x17u32.encode(self.sink); + assert!(lane < 16); + self.sink.push(lane); + self + } + + /// Encode [`Instruction::I16x8ExtractLaneS`]. + pub fn i16x8_extract_lane_s(&mut self, lane: Lane) -> &mut Self { + self.sink.push(0xFD); + 0x18u32.encode(self.sink); + assert!(lane < 8); + self.sink.push(lane); + self + } + + /// Encode [`Instruction::I16x8ExtractLaneU`]. + pub fn i16x8_extract_lane_u(&mut self, lane: Lane) -> &mut Self { + self.sink.push(0xFD); + 0x19u32.encode(self.sink); + assert!(lane < 8); + self.sink.push(lane); + self + } + + /// Encode [`Instruction::I16x8ReplaceLane`]. + pub fn i16x8_replace_lane(&mut self, lane: Lane) -> &mut Self { + self.sink.push(0xFD); + 0x1Au32.encode(self.sink); + assert!(lane < 8); + self.sink.push(lane); + self + } + + /// Encode [`Instruction::I32x4ExtractLane`]. + pub fn i32x4_extract_lane(&mut self, lane: Lane) -> &mut Self { + self.sink.push(0xFD); + 0x1Bu32.encode(self.sink); + assert!(lane < 4); + self.sink.push(lane); + self + } + + /// Encode [`Instruction::I32x4ReplaceLane`]. + pub fn i32x4_replace_lane(&mut self, lane: Lane) -> &mut Self { + self.sink.push(0xFD); + 0x1Cu32.encode(self.sink); + assert!(lane < 4); + self.sink.push(lane); + self + } + + /// Encode [`Instruction::I64x2ExtractLane`]. + pub fn i64x2_extract_lane(&mut self, lane: Lane) -> &mut Self { + self.sink.push(0xFD); + 0x1Du32.encode(self.sink); + assert!(lane < 2); + self.sink.push(lane); + self + } + + /// Encode [`Instruction::I64x2ReplaceLane`]. + pub fn i64x2_replace_lane(&mut self, lane: Lane) -> &mut Self { + self.sink.push(0xFD); + 0x1Eu32.encode(self.sink); + assert!(lane < 2); + self.sink.push(lane); + self + } + + /// Encode [`Instruction::F32x4ExtractLane`]. + pub fn f32x4_extract_lane(&mut self, lane: Lane) -> &mut Self { + self.sink.push(0xFD); + 0x1Fu32.encode(self.sink); + assert!(lane < 4); + self.sink.push(lane); + self + } + + /// Encode [`Instruction::F32x4ReplaceLane`]. + pub fn f32x4_replace_lane(&mut self, lane: Lane) -> &mut Self { + self.sink.push(0xFD); + 0x20u32.encode(self.sink); + assert!(lane < 4); + self.sink.push(lane); + self + } + + /// Encode [`Instruction::F64x2ExtractLane`]. + pub fn f64x2_extract_lane(&mut self, lane: Lane) -> &mut Self { + self.sink.push(0xFD); + 0x21u32.encode(self.sink); + assert!(lane < 2); + self.sink.push(lane); + self + } + + /// Encode [`Instruction::F64x2ReplaceLane`]. + pub fn f64x2_replace_lane(&mut self, lane: Lane) -> &mut Self { + self.sink.push(0xFD); + 0x22u32.encode(self.sink); + assert!(lane < 2); + self.sink.push(lane); + self + } + + /// Encode [`Instruction::I8x16Swizzle`]. + pub fn i8x16_swizzle(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x0Eu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I8x16Splat`]. + pub fn i8x16_splat(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x0Fu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8Splat`]. + pub fn i16x8_splat(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x10u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4Splat`]. + pub fn i32x4_splat(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x11u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I64x2Splat`]. + pub fn i64x2_splat(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x12u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F32x4Splat`]. + pub fn f32x4_splat(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x13u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F64x2Splat`]. + pub fn f64x2_splat(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x14u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I8x16Eq`]. + pub fn i8x16_eq(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x23u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I8x16Ne`]. + pub fn i8x16_ne(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x24u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I8x16LtS`]. + pub fn i8x16_lt_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x25u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I8x16LtU`]. + pub fn i8x16_lt_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x26u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I8x16GtS`]. + pub fn i8x16_gt_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x27u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I8x16GtU`]. + pub fn i8x16_gt_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x28u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I8x16LeS`]. + pub fn i8x16_le_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x29u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I8x16LeU`]. + pub fn i8x16_le_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x2Au32.encode(self.sink); + self + } + + /// Encode [`Instruction::I8x16GeS`]. + pub fn i8x16_ge_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x2Bu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I8x16GeU`]. + pub fn i8x16_ge_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x2Cu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8Eq`]. + pub fn i16x8_eq(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x2Du32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8Ne`]. + pub fn i16x8_ne(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x2Eu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8LtS`]. + pub fn i16x8_lt_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x2Fu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8LtU`]. + pub fn i16x8_lt_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x30u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8GtS`]. + pub fn i16x8_gt_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x31u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8GtU`]. + pub fn i16x8_gt_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x32u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8LeS`]. + pub fn i16x8_le_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x33u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8LeU`]. + pub fn i16x8_le_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x34u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8GeS`]. + pub fn i16x8_ge_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x35u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8GeU`]. + pub fn i16x8_ge_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x36u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4Eq`]. + pub fn i32x4_eq(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x37u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4Ne`]. + pub fn i32x4_ne(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x38u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4LtS`]. + pub fn i32x4_lt_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x39u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4LtU`]. + pub fn i32x4_lt_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x3Au32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4GtS`]. + pub fn i32x4_gt_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x3Bu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4GtU`]. + pub fn i32x4_gt_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x3Cu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4LeS`]. + pub fn i32x4_le_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x3Du32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4LeU`]. + pub fn i32x4_le_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x3Eu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4GeS`]. + pub fn i32x4_ge_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x3Fu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4GeU`]. + pub fn i32x4_ge_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x40u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I64x2Eq`]. + pub fn i64x2_eq(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xD6u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I64x2Ne`]. + pub fn i64x2_ne(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xD7u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I64x2LtS`]. + pub fn i64x2_lt_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xD8u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I64x2GtS`]. + pub fn i64x2_gt_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xD9u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I64x2LeS`]. + pub fn i64x2_le_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xDAu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I64x2GeS`]. + pub fn i64x2_ge_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xDBu32.encode(self.sink); + self + } + + /// Encode [`Instruction::F32x4Eq`]. + pub fn f32x4_eq(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x41u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F32x4Ne`]. + pub fn f32x4_ne(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x42u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F32x4Lt`]. + pub fn f32x4_lt(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x43u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F32x4Gt`]. + pub fn f32x4_gt(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x44u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F32x4Le`]. + pub fn f32x4_le(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x45u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F32x4Ge`]. + pub fn f32x4_ge(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x46u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F64x2Eq`]. + pub fn f64x2_eq(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x47u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F64x2Ne`]. + pub fn f64x2_ne(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x48u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F64x2Lt`]. + pub fn f64x2_lt(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x49u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F64x2Gt`]. + pub fn f64x2_gt(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x4Au32.encode(self.sink); + self + } + + /// Encode [`Instruction::F64x2Le`]. + pub fn f64x2_le(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x4Bu32.encode(self.sink); + self + } + + /// Encode [`Instruction::F64x2Ge`]. + pub fn f64x2_ge(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x4Cu32.encode(self.sink); + self + } + + /// Encode [`Instruction::V128Not`]. + pub fn v128_not(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x4Du32.encode(self.sink); + self + } + + /// Encode [`Instruction::V128And`]. + pub fn v128_and(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x4Eu32.encode(self.sink); + self + } + + /// Encode [`Instruction::V128AndNot`]. + pub fn v128_andnot(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x4Fu32.encode(self.sink); + self + } + + /// Encode [`Instruction::V128Or`]. + pub fn v128_or(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x50u32.encode(self.sink); + self + } + + /// Encode [`Instruction::V128Xor`]. + pub fn v128_xor(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x51u32.encode(self.sink); + self + } + + /// Encode [`Instruction::V128Bitselect`]. + pub fn v128_bitselect(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x52u32.encode(self.sink); + self + } + + /// Encode [`Instruction::V128AnyTrue`]. + pub fn v128_any_true(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x53u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I8x16Abs`]. + pub fn i8x16_abs(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x60u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I8x16Neg`]. + pub fn i8x16_neg(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x61u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I8x16Popcnt`]. + pub fn i8x16_popcnt(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x62u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I8x16AllTrue`]. + pub fn i8x16_all_true(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x63u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I8x16Bitmask`]. + pub fn i8x16_bitmask(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x64u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I8x16NarrowI16x8S`]. + pub fn i8x16_narrow_i16x8_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x65u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I8x16NarrowI16x8U`]. + pub fn i8x16_narrow_i16x8_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x66u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I8x16Shl`]. + pub fn i8x16_shl(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x6bu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I8x16ShrS`]. + pub fn i8x16_shr_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x6cu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I8x16ShrU`]. + pub fn i8x16_shr_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x6du32.encode(self.sink); + self + } + + /// Encode [`Instruction::I8x16Add`]. + pub fn i8x16_add(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x6eu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I8x16AddSatS`]. + pub fn i8x16_add_sat_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x6fu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I8x16AddSatU`]. + pub fn i8x16_add_sat_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x70u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I8x16Sub`]. + pub fn i8x16_sub(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x71u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I8x16SubSatS`]. + pub fn i8x16_sub_sat_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x72u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I8x16SubSatU`]. + pub fn i8x16_sub_sat_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x73u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I8x16MinS`]. + pub fn i8x16_min_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x76u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I8x16MinU`]. + pub fn i8x16_min_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x77u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I8x16MaxS`]. + pub fn i8x16_max_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x78u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I8x16MaxU`]. + pub fn i8x16_max_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x79u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I8x16AvgrU`]. + pub fn i8x16_avgr_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x7Bu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8ExtAddPairwiseI8x16S`]. + pub fn i16x8_extadd_pairwise_i8x16_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x7Cu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8ExtAddPairwiseI8x16U`]. + pub fn i16x8_extadd_pairwise_i8x16_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x7Du32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8Abs`]. + pub fn i16x8_abs(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x80u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8Neg`]. + pub fn i16x8_neg(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x81u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8Q15MulrSatS`]. + pub fn i16x8_q15mulr_sat_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x82u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8AllTrue`]. + pub fn i16x8_all_true(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x83u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8Bitmask`]. + pub fn i16x8_bitmask(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x84u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8NarrowI32x4S`]. + pub fn i16x8_narrow_i32x4_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x85u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8NarrowI32x4U`]. + pub fn i16x8_narrow_i32x4_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x86u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8ExtendLowI8x16S`]. + pub fn i16x8_extend_low_i8x16_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x87u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8ExtendHighI8x16S`]. + pub fn i16x8_extend_high_i8x16_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x88u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8ExtendLowI8x16U`]. + pub fn i16x8_extend_low_i8x16_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x89u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8ExtendHighI8x16U`]. + pub fn i16x8_extend_high_i8x16_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x8Au32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8Shl`]. + pub fn i16x8_shl(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x8Bu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8ShrS`]. + pub fn i16x8_shr_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x8Cu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8ShrU`]. + pub fn i16x8_shr_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x8Du32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8Add`]. + pub fn i16x8_add(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x8Eu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8AddSatS`]. + pub fn i16x8_add_sat_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x8Fu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8AddSatU`]. + pub fn i16x8_add_sat_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x90u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8Sub`]. + pub fn i16x8_sub(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x91u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8SubSatS`]. + pub fn i16x8_sub_sat_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x92u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8SubSatU`]. + pub fn i16x8_sub_sat_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x93u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8Mul`]. + pub fn i16x8_mul(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x95u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8MinS`]. + pub fn i16x8_min_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x96u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8MinU`]. + pub fn i16x8_min_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x97u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8MaxS`]. + pub fn i16x8_max_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x98u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8MaxU`]. + pub fn i16x8_max_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x99u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8AvgrU`]. + pub fn i16x8_avgr_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x9Bu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8ExtMulLowI8x16S`]. + pub fn i16x8_extmul_low_i8x16_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x9Cu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8ExtMulHighI8x16S`]. + pub fn i16x8_extmul_high_i8x16_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x9Du32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8ExtMulLowI8x16U`]. + pub fn i16x8_extmul_low_i8x16_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x9Eu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8ExtMulHighI8x16U`]. + pub fn i16x8_extmul_high_i8x16_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x9Fu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4ExtAddPairwiseI16x8S`]. + pub fn i32x4_extadd_pairwise_i16x8_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x7Eu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4ExtAddPairwiseI16x8U`]. + pub fn i32x4_extadd_pairwise_i16x8_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x7Fu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4Abs`]. + pub fn i32x4_abs(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xA0u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4Neg`]. + pub fn i32x4_neg(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xA1u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4AllTrue`]. + pub fn i32x4_all_true(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xA3u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4Bitmask`]. + pub fn i32x4_bitmask(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xA4u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4ExtendLowI16x8S`]. + pub fn i32x4_extend_low_i16x8_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xA7u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4ExtendHighI16x8S`]. + pub fn i32x4_extend_high_i16x8_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xA8u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4ExtendLowI16x8U`]. + pub fn i32x4_extend_low_i16x8_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xA9u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4ExtendHighI16x8U`]. + pub fn i32x4_extend_high_i16x8_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xAAu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4Shl`]. + pub fn i32x4_shl(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xABu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4ShrS`]. + pub fn i32x4_shr_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xACu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4ShrU`]. + pub fn i32x4_shr_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xADu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4Add`]. + pub fn i32x4_add(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xAEu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4Sub`]. + pub fn i32x4_sub(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xB1u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4Mul`]. + pub fn i32x4_mul(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xB5u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4MinS`]. + pub fn i32x4_min_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xB6u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4MinU`]. + pub fn i32x4_min_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xB7u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4MaxS`]. + pub fn i32x4_max_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xB8u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4MaxU`]. + pub fn i32x4_max_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xB9u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4DotI16x8S`]. + pub fn i32x4_dot_i16x8_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xBAu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4ExtMulLowI16x8S`]. + pub fn i32x4_extmul_low_i16x8_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xBCu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4ExtMulHighI16x8S`]. + pub fn i32x4_extmul_high_i16x8_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xBDu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4ExtMulLowI16x8U`]. + pub fn i32x4_extmul_low_i16x8_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xBEu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4ExtMulHighI16x8U`]. + pub fn i32x4_extmul_high_i16x8_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xBFu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I64x2Abs`]. + pub fn i64x2_abs(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xC0u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I64x2Neg`]. + pub fn i64x2_neg(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xC1u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I64x2AllTrue`]. + pub fn i64x2_all_true(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xC3u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I64x2Bitmask`]. + pub fn i64x2_bitmask(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xC4u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I64x2ExtendLowI32x4S`]. + pub fn i64x2_extend_low_i32x4_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xC7u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I64x2ExtendHighI32x4S`]. + pub fn i64x2_extend_high_i32x4_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xC8u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I64x2ExtendLowI32x4U`]. + pub fn i64x2_extend_low_i32x4_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xC9u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I64x2ExtendHighI32x4U`]. + pub fn i64x2_extend_high_i32x4_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xCAu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I64x2Shl`]. + pub fn i64x2_shl(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xCBu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I64x2ShrS`]. + pub fn i64x2_shr_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xCCu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I64x2ShrU`]. + pub fn i64x2_shr_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xCDu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I64x2Add`]. + pub fn i64x2_add(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xCEu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I64x2Sub`]. + pub fn i64x2_sub(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xD1u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I64x2Mul`]. + pub fn i64x2_mul(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xD5u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I64x2ExtMulLowI32x4S`]. + pub fn i64x2_extmul_low_i32x4_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xDCu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I64x2ExtMulHighI32x4S`]. + pub fn i64x2_extmul_high_i32x4_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xDDu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I64x2ExtMulLowI32x4U`]. + pub fn i64x2_extmul_low_i32x4_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xDEu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I64x2ExtMulHighI32x4U`]. + pub fn i64x2_extmul_high_i32x4_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xDFu32.encode(self.sink); + self + } + + /// Encode [`Instruction::F32x4Ceil`]. + pub fn f32x4_ceil(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x67u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F32x4Floor`]. + pub fn f32x4_floor(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x68u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F32x4Trunc`]. + pub fn f32x4_trunc(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x69u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F32x4Nearest`]. + pub fn f32x4_nearest(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x6Au32.encode(self.sink); + self + } + + /// Encode [`Instruction::F32x4Abs`]. + pub fn f32x4_abs(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xE0u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F32x4Neg`]. + pub fn f32x4_neg(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xE1u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F32x4Sqrt`]. + pub fn f32x4_sqrt(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xE3u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F32x4Add`]. + pub fn f32x4_add(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xE4u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F32x4Sub`]. + pub fn f32x4_sub(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xE5u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F32x4Mul`]. + pub fn f32x4_mul(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xE6u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F32x4Div`]. + pub fn f32x4_div(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xE7u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F32x4Min`]. + pub fn f32x4_min(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xE8u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F32x4Max`]. + pub fn f32x4_max(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xE9u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F32x4PMin`]. + pub fn f32x4_pmin(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xEAu32.encode(self.sink); + self + } + + /// Encode [`Instruction::F32x4PMax`]. + pub fn f32x4_pmax(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xEBu32.encode(self.sink); + self + } + + /// Encode [`Instruction::F64x2Ceil`]. + pub fn f64x2_ceil(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x74u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F64x2Floor`]. + pub fn f64x2_floor(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x75u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F64x2Trunc`]. + pub fn f64x2_trunc(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x7Au32.encode(self.sink); + self + } + + /// Encode [`Instruction::F64x2Nearest`]. + pub fn f64x2_nearest(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x94u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F64x2Abs`]. + pub fn f64x2_abs(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xECu32.encode(self.sink); + self + } + + /// Encode [`Instruction::F64x2Neg`]. + pub fn f64x2_neg(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xEDu32.encode(self.sink); + self + } + + /// Encode [`Instruction::F64x2Sqrt`]. + pub fn f64x2_sqrt(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xEFu32.encode(self.sink); + self + } + + /// Encode [`Instruction::F64x2Add`]. + pub fn f64x2_add(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xF0u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F64x2Sub`]. + pub fn f64x2_sub(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xF1u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F64x2Mul`]. + pub fn f64x2_mul(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xF2u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F64x2Div`]. + pub fn f64x2_div(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xF3u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F64x2Min`]. + pub fn f64x2_min(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xF4u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F64x2Max`]. + pub fn f64x2_max(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xF5u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F64x2PMin`]. + pub fn f64x2_pmin(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xF6u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F64x2PMax`]. + pub fn f64x2_pmax(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xF7u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4TruncSatF32x4S`]. + pub fn i32x4_trunc_sat_f32x4_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xF8u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4TruncSatF32x4U`]. + pub fn i32x4_trunc_sat_f32x4_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xF9u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F32x4ConvertI32x4S`]. + pub fn f32x4_convert_i32x4_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xFAu32.encode(self.sink); + self + } + + /// Encode [`Instruction::F32x4ConvertI32x4U`]. + pub fn f32x4_convert_i32x4_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xFBu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4TruncSatF64x2SZero`]. + pub fn i32x4_trunc_sat_f64x2_s_zero(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xFCu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4TruncSatF64x2UZero`]. + pub fn i32x4_trunc_sat_f64x2_u_zero(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xFDu32.encode(self.sink); + self + } + + /// Encode [`Instruction::F64x2ConvertLowI32x4S`]. + pub fn f64x2_convert_low_i32x4_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xFEu32.encode(self.sink); + self + } + + /// Encode [`Instruction::F64x2ConvertLowI32x4U`]. + pub fn f64x2_convert_low_i32x4_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0xFFu32.encode(self.sink); + self + } + + /// Encode [`Instruction::F32x4DemoteF64x2Zero`]. + pub fn f32x4_demote_f64x2_zero(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x5Eu32.encode(self.sink); + self + } + + /// Encode [`Instruction::F64x2PromoteLowF32x4`]. + pub fn f64x2_promote_low_f32x4(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x5Fu32.encode(self.sink); + self + } + + // Relaxed simd proposal + + /// Encode [`Instruction::I8x16RelaxedSwizzle`]. + pub fn i8x16_relaxed_swizzle(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x100u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4RelaxedTruncF32x4S`]. + pub fn i32x4_relaxed_trunc_f32x4_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x101u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4RelaxedTruncF32x4U`]. + pub fn i32x4_relaxed_trunc_f32x4_u(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x102u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4RelaxedTruncF64x2SZero`]. + pub fn i32x4_relaxed_trunc_f64x2_s_zero(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x103u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4RelaxedTruncF64x2UZero`]. + pub fn i32x4_relaxed_trunc_f64x2_u_zero(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x104u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F32x4RelaxedMadd`]. + pub fn f32x4_relaxed_madd(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x105u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F32x4RelaxedNmadd`]. + pub fn f32x4_relaxed_nmadd(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x106u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F64x2RelaxedMadd`]. + pub fn f64x2_relaxed_madd(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x107u32.encode(self.sink); + self + } + + /// Encode [`Instruction::F64x2RelaxedNmadd`]. + pub fn f64x2_relaxed_nmadd(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x108u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I8x16RelaxedLaneselect`]. + pub fn i8x16_relaxed_laneselect(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x109u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8RelaxedLaneselect`]. + pub fn i16x8_relaxed_laneselect(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x10Au32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4RelaxedLaneselect`]. + pub fn i32x4_relaxed_laneselect(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x10Bu32.encode(self.sink); + self + } + + /// Encode [`Instruction::I64x2RelaxedLaneselect`]. + pub fn i64x2_relaxed_laneselect(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x10Cu32.encode(self.sink); + self + } + + /// Encode [`Instruction::F32x4RelaxedMin`]. + pub fn f32x4_relaxed_min(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x10Du32.encode(self.sink); + self + } + + /// Encode [`Instruction::F32x4RelaxedMax`]. + pub fn f32x4_relaxed_max(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x10Eu32.encode(self.sink); + self + } + + /// Encode [`Instruction::F64x2RelaxedMin`]. + pub fn f64x2_relaxed_min(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x10Fu32.encode(self.sink); + self + } + + /// Encode [`Instruction::F64x2RelaxedMax`]. + pub fn f64x2_relaxed_max(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x110u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8RelaxedQ15mulrS`]. + pub fn i16x8_relaxed_q15mulr_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x111u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I16x8RelaxedDotI8x16I7x16S`]. + pub fn i16x8_relaxed_dot_i8x16_i7x16_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x112u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I32x4RelaxedDotI8x16I7x16AddS`]. + pub fn i32x4_relaxed_dot_i8x16_i7x16_add_s(&mut self) -> &mut Self { + self.sink.push(0xFD); + 0x113u32.encode(self.sink); + self + } + + // Atomic instructions (the threads proposal) + + /// Encode [`Instruction::MemoryAtomicNotify`]. + pub fn memory_atomic_notify(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x00); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::MemoryAtomicWait32`]. + pub fn memory_atomic_wait32(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x01); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::MemoryAtomicWait64`]. + pub fn memory_atomic_wait64(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x02); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::AtomicFence`]. + pub fn atomic_fence(&mut self) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x03); + self.sink.push(0x00); + self + } + + /// Encode [`Instruction::I32AtomicLoad`]. + pub fn i32_atomic_load(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x10); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicLoad`]. + pub fn i64_atomic_load(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x11); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I32AtomicLoad8U`]. + pub fn i32_atomic_load8_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x12); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I32AtomicLoad16U`]. + pub fn i32_atomic_load16_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x13); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicLoad8U`]. + pub fn i64_atomic_load8_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x14); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicLoad16U`]. + pub fn i64_atomic_load16_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x15); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicLoad32U`]. + pub fn i64_atomic_load32_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x16); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I32AtomicStore`]. + pub fn i32_atomic_store(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x17); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicStore`]. + pub fn i64_atomic_store(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x18); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I32AtomicStore8`]. + pub fn i32_atomic_store8(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x19); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I32AtomicStore16`]. + pub fn i32_atomic_store16(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x1A); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicStore8`]. + pub fn i64_atomic_store8(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x1B); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicStore16`]. + pub fn i64_atomic_store16(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x1C); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicStore32`]. + pub fn i64_atomic_store32(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x1D); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I32AtomicRmwAdd`]. + pub fn i32_atomic_rmw_add(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x1E); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicRmwAdd`]. + pub fn i64_atomic_rmw_add(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x1F); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I32AtomicRmw8AddU`]. + pub fn i32_atomic_rmw8_add_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x20); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I32AtomicRmw16AddU`]. + pub fn i32_atomic_rmw16_add_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x21); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicRmw8AddU`]. + pub fn i64_atomic_rmw8_add_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x22); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicRmw16AddU`]. + pub fn i64_atomic_rmw16_add_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x23); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicRmw32AddU`]. + pub fn i64_atomic_rmw32_add_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x24); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I32AtomicRmwSub`]. + pub fn i32_atomic_rmw_sub(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x25); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicRmwSub`]. + pub fn i64_atomic_rmw_sub(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x26); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I32AtomicRmw8SubU`]. + pub fn i32_atomic_rmw8_sub_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x27); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I32AtomicRmw16SubU`]. + pub fn i32_atomic_rmw16_sub_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x28); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicRmw8SubU`]. + pub fn i64_atomic_rmw8_sub_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x29); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicRmw16SubU`]. + pub fn i64_atomic_rmw16_sub_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x2A); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicRmw32SubU`]. + pub fn i64_atomic_rmw32_sub_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x2B); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I32AtomicRmwAnd`]. + pub fn i32_atomic_rmw_and(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x2C); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicRmwAnd`]. + pub fn i64_atomic_rmw_and(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x2D); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I32AtomicRmw8AndU`]. + pub fn i32_atomic_rmw8_and_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x2E); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I32AtomicRmw16AndU`]. + pub fn i32_atomic_rmw16_and_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x2F); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicRmw8AndU`]. + pub fn i64_atomic_rmw8_and_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x30); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicRmw16AndU`]. + pub fn i64_atomic_rmw16_and_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x31); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicRmw32AndU`]. + pub fn i64_atomic_rmw32_and_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x32); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I32AtomicRmwOr`]. + pub fn i32_atomic_rmw_or(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x33); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicRmwOr`]. + pub fn i64_atomic_rmw_or(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x34); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I32AtomicRmw8OrU`]. + pub fn i32_atomic_rmw8_or_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x35); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I32AtomicRmw16OrU`]. + pub fn i32_atomic_rmw16_or_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x36); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicRmw8OrU`]. + pub fn i64_atomic_rmw8_or_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x37); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicRmw16OrU`]. + pub fn i64_atomic_rmw16_or_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x38); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicRmw32OrU`]. + pub fn i64_atomic_rmw32_or_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x39); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I32AtomicRmwXor`]. + pub fn i32_atomic_rmw_xor(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x3A); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicRmwXor`]. + pub fn i64_atomic_rmw_xor(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x3B); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I32AtomicRmw8XorU`]. + pub fn i32_atomic_rmw8_xor_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x3C); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I32AtomicRmw16XorU`]. + pub fn i32_atomic_rmw16_xor_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x3D); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicRmw8XorU`]. + pub fn i64_atomic_rmw8_xor_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x3E); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicRmw16XorU`]. + pub fn i64_atomic_rmw16_xor_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x3F); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicRmw32XorU`]. + pub fn i64_atomic_rmw32_xor_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x40); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I32AtomicRmwXchg`]. + pub fn i32_atomic_rmw_xchg(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x41); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicRmwXchg`]. + pub fn i64_atomic_rmw_xchg(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x42); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I32AtomicRmw8XchgU`]. + pub fn i32_atomic_rmw8_xchg_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x43); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I32AtomicRmw16XchgU`]. + pub fn i32_atomic_rmw16_xchg_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x44); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicRmw8XchgU`]. + pub fn i64_atomic_rmw8_xchg_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x45); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicRmw16XchgU`]. + pub fn i64_atomic_rmw16_xchg_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x46); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicRmw32XchgU`]. + pub fn i64_atomic_rmw32_xchg_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x47); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I32AtomicRmwCmpxchg`]. + pub fn i32_atomic_rmw_cmpxchg(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x48); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicRmwCmpxchg`]. + pub fn i64_atomic_rmw_cmpxchg(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x49); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I32AtomicRmw8CmpxchgU`]. + pub fn i32_atomic_rmw8_cmpxchg_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x4A); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I32AtomicRmw16CmpxchgU`]. + pub fn i32_atomic_rmw16_cmpxchg_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x4B); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicRmw8CmpxchgU`]. + pub fn i64_atomic_rmw8_cmpxchg_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x4C); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicRmw16CmpxchgU`]. + pub fn i64_atomic_rmw16_cmpxchg_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x4D); + memarg.encode(self.sink); + self + } + + /// Encode [`Instruction::I64AtomicRmw32CmpxchgU`]. + pub fn i64_atomic_rmw32_cmpxchg_u(&mut self, memarg: MemArg) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x4E); + memarg.encode(self.sink); + self + } + + // More atomic instructions (the shared-everything-threads proposal) + + /// Encode [`Instruction::GlobalAtomicGet`]. + pub fn global_atomic_get(&mut self, ordering: Ordering, global_index: GlobalIdx) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x4F); + ordering.encode(self.sink); + global_index.encode(self.sink); + self + } + + /// Encode [`Instruction::GlobalAtomicSet`]. + pub fn global_atomic_set(&mut self, ordering: Ordering, global_index: GlobalIdx) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x50); + ordering.encode(self.sink); + global_index.encode(self.sink); + self + } + + /// Encode [`Instruction::GlobalAtomicRmwAdd`]. + pub fn global_atomic_rmw_add( + &mut self, + ordering: Ordering, + global_index: GlobalIdx, + ) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x51); + ordering.encode(self.sink); + global_index.encode(self.sink); + self + } + + /// Encode [`Instruction::GlobalAtomicRmwSub`]. + pub fn global_atomic_rmw_sub( + &mut self, + ordering: Ordering, + global_index: GlobalIdx, + ) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x52); + ordering.encode(self.sink); + global_index.encode(self.sink); + self + } + + /// Encode [`Instruction::GlobalAtomicRmwAnd`]. + pub fn global_atomic_rmw_and( + &mut self, + ordering: Ordering, + global_index: GlobalIdx, + ) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x53); + ordering.encode(self.sink); + global_index.encode(self.sink); + self + } + + /// Encode [`Instruction::GlobalAtomicRmwOr`]. + pub fn global_atomic_rmw_or( + &mut self, + ordering: Ordering, + global_index: GlobalIdx, + ) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x54); + ordering.encode(self.sink); + global_index.encode(self.sink); + self + } + + /// Encode [`Instruction::GlobalAtomicRmwXor`]. + pub fn global_atomic_rmw_xor( + &mut self, + ordering: Ordering, + global_index: GlobalIdx, + ) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x55); + ordering.encode(self.sink); + global_index.encode(self.sink); + self + } + + /// Encode [`Instruction::GlobalAtomicRmwXchg`]. + pub fn global_atomic_rmw_xchg( + &mut self, + ordering: Ordering, + global_index: GlobalIdx, + ) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x56); + ordering.encode(self.sink); + global_index.encode(self.sink); + self + } + + /// Encode [`Instruction::GlobalAtomicRmwCmpxchg`]. + pub fn global_atomic_rmw_cmpxchg( + &mut self, + ordering: Ordering, + global_index: GlobalIdx, + ) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x57); + ordering.encode(self.sink); + global_index.encode(self.sink); + self + } + + /// Encode [`Instruction::TableAtomicGet`]. + pub fn table_atomic_get(&mut self, ordering: Ordering, table_index: TableIdx) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x58); + ordering.encode(self.sink); + table_index.encode(self.sink); + self + } + + /// Encode [`Instruction::TableAtomicSet`]. + pub fn table_atomic_set(&mut self, ordering: Ordering, table_index: TableIdx) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x59); + ordering.encode(self.sink); + table_index.encode(self.sink); + self + } + + /// Encode [`Instruction::TableAtomicRmwXchg`]. + pub fn table_atomic_rmw_xchg( + &mut self, + ordering: Ordering, + table_index: TableIdx, + ) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x5A); + ordering.encode(self.sink); + table_index.encode(self.sink); + self + } + + /// Encode [`Instruction::TableAtomicRmwCmpxchg`]. + pub fn table_atomic_rmw_cmpxchg( + &mut self, + ordering: Ordering, + table_index: TableIdx, + ) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x5B); + ordering.encode(self.sink); + table_index.encode(self.sink); + self + } + + /// Encode [`Instruction::StructAtomicGet`]. + pub fn struct_atomic_get( + &mut self, + ordering: Ordering, + struct_type_index: TypeIdx, + field_index: FieldIdx, + ) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x5C); + ordering.encode(self.sink); + struct_type_index.encode(self.sink); + field_index.encode(self.sink); + self + } + + /// Encode [`Instruction::StructAtomicGetS`]. + pub fn struct_atomic_get_s( + &mut self, + ordering: Ordering, + struct_type_index: TypeIdx, + field_index: FieldIdx, + ) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x5D); + ordering.encode(self.sink); + struct_type_index.encode(self.sink); + field_index.encode(self.sink); + self + } + + /// Encode [`Instruction::StructAtomicGetU`]. + pub fn struct_atomic_get_u( + &mut self, + ordering: Ordering, + struct_type_index: TypeIdx, + field_index: FieldIdx, + ) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x5E); + ordering.encode(self.sink); + struct_type_index.encode(self.sink); + field_index.encode(self.sink); + self + } + + /// Encode [`Instruction::StructAtomicSet`]. + pub fn struct_atomic_set( + &mut self, + ordering: Ordering, + struct_type_index: TypeIdx, + field_index: FieldIdx, + ) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x5F); + ordering.encode(self.sink); + struct_type_index.encode(self.sink); + field_index.encode(self.sink); + self + } + + /// Encode [`Instruction::StructAtomicRmwAdd`]. + pub fn struct_atomic_rmw_add( + &mut self, + ordering: Ordering, + struct_type_index: TypeIdx, + field_index: FieldIdx, + ) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x60); + ordering.encode(self.sink); + struct_type_index.encode(self.sink); + field_index.encode(self.sink); + self + } + + /// Encode [`Instruction::StructAtomicRmwSub`]. + pub fn struct_atomic_rmw_sub( + &mut self, + ordering: Ordering, + struct_type_index: TypeIdx, + field_index: FieldIdx, + ) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x61); + ordering.encode(self.sink); + struct_type_index.encode(self.sink); + field_index.encode(self.sink); + self + } + + /// Encode [`Instruction::StructAtomicRmwAnd`]. + pub fn struct_atomic_rmw_and( + &mut self, + ordering: Ordering, + struct_type_index: TypeIdx, + field_index: FieldIdx, + ) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x62); + ordering.encode(self.sink); + struct_type_index.encode(self.sink); + field_index.encode(self.sink); + self + } + + /// Encode [`Instruction::StructAtomicRmwOr`]. + pub fn struct_atomic_rmw_or( + &mut self, + ordering: Ordering, + struct_type_index: TypeIdx, + field_index: FieldIdx, + ) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x63); + ordering.encode(self.sink); + struct_type_index.encode(self.sink); + field_index.encode(self.sink); + self + } + + /// Encode [`Instruction::StructAtomicRmwXor`]. + pub fn struct_atomic_rmw_xor( + &mut self, + ordering: Ordering, + struct_type_index: TypeIdx, + field_index: FieldIdx, + ) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x64); + ordering.encode(self.sink); + struct_type_index.encode(self.sink); + field_index.encode(self.sink); + self + } + + /// Encode [`Instruction::StructAtomicRmwXchg`]. + pub fn struct_atomic_rmw_xchg( + &mut self, + ordering: Ordering, + struct_type_index: TypeIdx, + field_index: FieldIdx, + ) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x65); + ordering.encode(self.sink); + struct_type_index.encode(self.sink); + field_index.encode(self.sink); + self + } + + /// Encode [`Instruction::StructAtomicRmwCmpxchg`]. + pub fn struct_atomic_rmw_cmpxchg( + &mut self, + ordering: Ordering, + struct_type_index: TypeIdx, + field_index: FieldIdx, + ) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x66); + ordering.encode(self.sink); + struct_type_index.encode(self.sink); + field_index.encode(self.sink); + self + } + + /// Encode [`Instruction::ArrayAtomicGet`]. + pub fn array_atomic_get(&mut self, ordering: Ordering, array_type_index: TypeIdx) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x67); + ordering.encode(self.sink); + array_type_index.encode(self.sink); + self + } + + /// Encode [`Instruction::ArrayAtomicGetS`]. + pub fn array_atomic_get_s( + &mut self, + ordering: Ordering, + array_type_index: TypeIdx, + ) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x68); + ordering.encode(self.sink); + array_type_index.encode(self.sink); + self + } + + /// Encode [`Instruction::ArrayAtomicGetU`]. + pub fn array_atomic_get_u( + &mut self, + ordering: Ordering, + array_type_index: TypeIdx, + ) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x69); + ordering.encode(self.sink); + array_type_index.encode(self.sink); + self + } + + /// Encode [`Instruction::ArrayAtomicSet`]. + pub fn array_atomic_set(&mut self, ordering: Ordering, array_type_index: TypeIdx) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x6A); + ordering.encode(self.sink); + array_type_index.encode(self.sink); + self + } + + /// Encode [`Instruction::ArrayAtomicRmwAdd`]. + pub fn array_atomic_rmw_add( + &mut self, + ordering: Ordering, + array_type_index: TypeIdx, + ) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x6B); + ordering.encode(self.sink); + array_type_index.encode(self.sink); + self + } + + /// Encode [`Instruction::ArrayAtomicRmwSub`]. + pub fn array_atomic_rmw_sub( + &mut self, + ordering: Ordering, + array_type_index: TypeIdx, + ) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x6C); + ordering.encode(self.sink); + array_type_index.encode(self.sink); + self + } + + /// Encode [`Instruction::ArrayAtomicRmwAnd`]. + pub fn array_atomic_rmw_and( + &mut self, + ordering: Ordering, + array_type_index: TypeIdx, + ) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x6D); + ordering.encode(self.sink); + array_type_index.encode(self.sink); + self + } + + /// Encode [`Instruction::ArrayAtomicRmwOr`]. + pub fn array_atomic_rmw_or( + &mut self, + ordering: Ordering, + array_type_index: TypeIdx, + ) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x6E); + ordering.encode(self.sink); + array_type_index.encode(self.sink); + self + } + + /// Encode [`Instruction::ArrayAtomicRmwXor`]. + pub fn array_atomic_rmw_xor( + &mut self, + ordering: Ordering, + array_type_index: TypeIdx, + ) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x6F); + ordering.encode(self.sink); + array_type_index.encode(self.sink); + self + } + + /// Encode [`Instruction::ArrayAtomicRmwXchg`]. + pub fn array_atomic_rmw_xchg( + &mut self, + ordering: Ordering, + array_type_index: TypeIdx, + ) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x70); + ordering.encode(self.sink); + array_type_index.encode(self.sink); + self + } + + /// Encode [`Instruction::ArrayAtomicRmwCmpxchg`]. + pub fn array_atomic_rmw_cmpxchg( + &mut self, + ordering: Ordering, + array_type_index: TypeIdx, + ) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x71); + ordering.encode(self.sink); + array_type_index.encode(self.sink); + self + } + + /// Encode [`Instruction::RefI31Shared`]. + pub fn ref_i31_shared(&mut self) -> &mut Self { + self.sink.push(0xFE); + self.sink.push(0x72); + self + } + + // Stack switching + + /// Encode [`Instruction::ContNew`]. + pub fn cont_new(&mut self, type_index: TypeIdx) -> &mut Self { + self.sink.push(0xE0); + type_index.encode(self.sink); + self + } + + /// Encode [`Instruction::ContBind`]. + pub fn cont_bind(&mut self, argument_index: TypeIdx, result_index: TypeIdx) -> &mut Self { + self.sink.push(0xE1); + argument_index.encode(self.sink); + result_index.encode(self.sink); + self + } + + /// Encode [`Instruction::Suspend`]. + pub fn suspend(&mut self, tag_index: TagIdx) -> &mut Self { + self.sink.push(0xE2); + tag_index.encode(self.sink); + self + } + + /// Encode [`Instruction::Resume`]. + pub fn resume>( + &mut self, + cont_type_index: TypeIdx, + resume_table: V, + ) -> &mut Self + where + V::IntoIter: ExactSizeIterator, + { + self.sink.push(0xE3); + cont_type_index.encode(self.sink); + encode_vec(resume_table, self.sink); + self + } + + /// Encode [`Instruction::ResumeThrow`]. + pub fn resume_throw>( + &mut self, + cont_type_index: TypeIdx, + tag_index: TagIdx, + resume_table: V, + ) -> &mut Self + where + V::IntoIter: ExactSizeIterator, + { + self.sink.push(0xE4); + cont_type_index.encode(self.sink); + tag_index.encode(self.sink); + encode_vec(resume_table, self.sink); + self + } + + /// Encode [`Instruction::Switch`]. + pub fn switch(&mut self, cont_type_index: TypeIdx, tag_index: TagIdx) -> &mut Self { + self.sink.push(0xE5); + cont_type_index.encode(self.sink); + tag_index.encode(self.sink); + self + } + + // Wide Arithmetic + + /// Encode [`Instruction::I64Add128`]. + pub fn i64_add128(&mut self) -> &mut Self { + self.sink.push(0xFC); + 19u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I64Sub128`]. + pub fn i64_sub128(&mut self) -> &mut Self { + self.sink.push(0xFC); + 20u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I64MulWideS`]. + pub fn i64_mul_wide_s(&mut self) -> &mut Self { + self.sink.push(0xFC); + 21u32.encode(self.sink); + self + } + + /// Encode [`Instruction::I64MulWideU`]. + pub fn i64_mul_wide_u(&mut self) -> &mut Self { + self.sink.push(0xFC); + 22u32.encode(self.sink); + self + } +} From 1bd473a040293f192ab6fd87e46c188aa2c8eee8 Mon Sep 17 00:00:00 2001 From: Sam Estep Date: Mon, 27 Jan 2025 11:30:10 -0500 Subject: [PATCH 2/4] Refactor to prefer `InstructionSink` --- crates/wasm-encoder/README.md | 11 +- crates/wasm-encoder/src/core/branch_hints.rs | 9 +- crates/wasm-encoder/src/core/code.rs | 117 +- crates/wasm-encoder/src/lib.rs | 11 +- .../wasm-mutate/src/mutators/add_function.rs | 22 +- .../src/mutators/codemotion/if_complement.rs | 12 +- .../wasm-mutate/src/mutators/codemotion/ir.rs | 18 +- .../src/mutators/codemotion/loop_unrolling.rs | 16 +- .../src/mutators/function_body_unreachable.rs | 6 +- .../peephole/eggsy/encoder/expr2wasm.rs | 1054 ++++++++--------- .../src/mutators/peephole/eggsy/lang.rs | 7 +- .../wasm-mutate/src/mutators/snip_function.rs | 18 +- crates/wasm-smith/src/core/encode.rs | 2 +- crates/wasmparser/tests/big-module.rs | 6 +- crates/wast/src/core/binary.rs | 2 +- crates/wit-component/src/encoding.rs | 12 +- crates/wit-component/src/gc.rs | 136 +-- 17 files changed, 710 insertions(+), 749 deletions(-) diff --git a/crates/wasm-encoder/README.md b/crates/wasm-encoder/README.md index 86df7008da..473af42423 100644 --- a/crates/wasm-encoder/README.md +++ b/crates/wasm-encoder/README.md @@ -26,7 +26,7 @@ And then you can encode WebAssembly binaries via: ```rust use wasm_encoder::{ - CodeSection, ExportKind, ExportSection, Function, FunctionSection, Instruction, + CodeSection, ExportKind, ExportSection, Function, FunctionSection, LocalIdx, Module, TypeSection, ValType, }; @@ -54,10 +54,11 @@ module.section(&exports); let mut codes = CodeSection::new(); let locals = vec![]; let mut f = Function::new(locals); -f.instruction(&Instruction::LocalGet(0)); -f.instruction(&Instruction::LocalGet(1)); -f.instruction(&Instruction::I32Add); -f.instruction(&Instruction::End); +f.instructions() + .local_get(LocalIdx(0)) + .local_get(LocalIdx(1)) + .i32_add() + .end(); codes.function(&f); module.section(&codes); diff --git a/crates/wasm-encoder/src/core/branch_hints.rs b/crates/wasm-encoder/src/core/branch_hints.rs index 96231b11e9..098a62cf65 100644 --- a/crates/wasm-encoder/src/core/branch_hints.rs +++ b/crates/wasm-encoder/src/core/branch_hints.rs @@ -25,11 +25,12 @@ use alloc::vec::Vec; /// let mut code = CodeSection::new(); /// let mut body = Function::new([]); /// -/// body.instruction(&Instruction::I32Const(1)); +/// body.instructions().i32_const(1); /// let if_offset = body.byte_len(); -/// body.instruction(&Instruction::If(BlockType::Empty)); -/// body.instruction(&Instruction::End); -/// body.instruction(&Instruction::End); +/// body.instructions() +/// .if_(BlockType::Empty) +/// .end() +/// .end(); /// code.function(&body); /// /// let mut hints = BranchHints::new(); diff --git a/crates/wasm-encoder/src/core/code.rs b/crates/wasm-encoder/src/core/code.rs index 1d4184cb61..8d59360c78 100644 --- a/crates/wasm-encoder/src/core/code.rs +++ b/crates/wasm-encoder/src/core/code.rs @@ -13,7 +13,7 @@ use alloc::vec::Vec; /// /// ``` /// use wasm_encoder::{ -/// CodeSection, Function, FunctionSection, Instruction, Module, +/// CodeSection, Function, FunctionSection, Module, /// TypeSection, ValType /// }; /// @@ -26,7 +26,7 @@ use alloc::vec::Vec; /// /// let locals = vec![]; /// let mut func = Function::new(locals); -/// func.instruction(&Instruction::I32Const(42)); +/// func.instructions().i32_const(42); /// let mut code = CodeSection::new(); /// code.function(&func); /// @@ -126,7 +126,7 @@ impl Section for CodeSection { /// # Example /// /// ``` -/// use wasm_encoder::{CodeSection, Function, Instruction}; +/// use wasm_encoder::{CodeSection, Function, LocalIdx}; /// /// // Define the function body for: /// // @@ -136,9 +136,10 @@ impl Section for CodeSection { /// // i32.add) /// let locals = vec![]; /// let mut func = Function::new(locals); -/// func.instruction(&Instruction::LocalGet(0)); -/// func.instruction(&Instruction::LocalGet(1)); -/// func.instruction(&Instruction::I32Add); +/// func.instructions() +/// .local_get(LocalIdx(0)) +/// .local_get(LocalIdx(1)) +/// .i32_add(); /// /// // Add our function to the code section. /// let mut code = CodeSection::new(); @@ -271,9 +272,9 @@ impl Function { /// For example: /// /// ``` - /// # use wasm_encoder::{CodeSection, Function, Instruction}; + /// # use wasm_encoder::{CodeSection, Function}; /// let mut f = Function::new([]); - /// f.instruction(&Instruction::End); + /// f.instructions().end(); /// let bytes = f.into_raw_body(); /// // (save `bytes` somewhere for later use) /// let mut code = CodeSection::new(); @@ -2320,125 +2321,169 @@ impl ConstExpr { Self { bytes } } - fn new_insn(insn: Instruction) -> Self { + fn new(f: impl FnOnce(&mut InstructionSink)) -> Self { let mut bytes = vec![]; - insn.encode(&mut bytes); + f(&mut InstructionSink::new(&mut bytes)); Self { bytes } } - fn with_insn(mut self, insn: Instruction) -> Self { - insn.encode(&mut self.bytes); + fn with(mut self, f: impl FnOnce(&mut InstructionSink)) -> Self { + f(&mut InstructionSink::new(&mut self.bytes)); self } /// Create a constant expression containing a single `global.get` instruction. pub fn global_get(index: u32) -> Self { - Self::new_insn(Instruction::GlobalGet(index)) + Self::new(|insn| { + insn.global_get(GlobalIdx(index)); + }) } /// Create a constant expression containing a single `ref.null` instruction. pub fn ref_null(ty: HeapType) -> Self { - Self::new_insn(Instruction::RefNull(ty)) + Self::new(|insn| { + insn.ref_null(ty); + }) } /// Create a constant expression containing a single `ref.func` instruction. pub fn ref_func(func: u32) -> Self { - Self::new_insn(Instruction::RefFunc(func)) + Self::new(|insn| { + insn.ref_func(FuncIdx(func)); + }) } /// Create a constant expression containing a single `i32.const` instruction. pub fn i32_const(value: i32) -> Self { - Self::new_insn(Instruction::I32Const(value)) + Self::new(|insn| { + insn.i32_const(value); + }) } /// Create a constant expression containing a single `i64.const` instruction. pub fn i64_const(value: i64) -> Self { - Self::new_insn(Instruction::I64Const(value)) + Self::new(|insn| { + insn.i64_const(value); + }) } /// Create a constant expression containing a single `f32.const` instruction. pub fn f32_const(value: f32) -> Self { - Self::new_insn(Instruction::F32Const(value)) + Self::new(|insn| { + insn.f32_const(value); + }) } /// Create a constant expression containing a single `f64.const` instruction. pub fn f64_const(value: f64) -> Self { - Self::new_insn(Instruction::F64Const(value)) + Self::new(|insn| { + insn.f64_const(value); + }) } /// Create a constant expression containing a single `v128.const` instruction. pub fn v128_const(value: i128) -> Self { - Self::new_insn(Instruction::V128Const(value)) + Self::new(|insn| { + insn.v128_const(value); + }) } /// Add a `global.get` instruction to this constant expression. pub fn with_global_get(self, index: u32) -> Self { - self.with_insn(Instruction::GlobalGet(index)) + self.with(|insn| { + insn.global_get(GlobalIdx(index)); + }) } /// Add a `ref.null` instruction to this constant expression. pub fn with_ref_null(self, ty: HeapType) -> Self { - self.with_insn(Instruction::RefNull(ty)) + self.with(|insn| { + insn.ref_null(ty); + }) } /// Add a `ref.func` instruction to this constant expression. pub fn with_ref_func(self, func: u32) -> Self { - self.with_insn(Instruction::RefFunc(func)) + self.with(|insn| { + insn.ref_func(FuncIdx(func)); + }) } /// Add an `i32.const` instruction to this constant expression. pub fn with_i32_const(self, value: i32) -> Self { - self.with_insn(Instruction::I32Const(value)) + self.with(|insn| { + insn.i32_const(value); + }) } /// Add an `i64.const` instruction to this constant expression. pub fn with_i64_const(self, value: i64) -> Self { - self.with_insn(Instruction::I64Const(value)) + self.with(|insn| { + insn.i64_const(value); + }) } /// Add a `f32.const` instruction to this constant expression. pub fn with_f32_const(self, value: f32) -> Self { - self.with_insn(Instruction::F32Const(value)) + self.with(|insn| { + insn.f32_const(value); + }) } /// Add a `f64.const` instruction to this constant expression. pub fn with_f64_const(self, value: f64) -> Self { - self.with_insn(Instruction::F64Const(value)) + self.with(|insn| { + insn.f64_const(value); + }) } /// Add a `v128.const` instruction to this constant expression. pub fn with_v128_const(self, value: i128) -> Self { - self.with_insn(Instruction::V128Const(value)) + self.with(|insn| { + insn.v128_const(value); + }) } /// Add an `i32.add` instruction to this constant expression. pub fn with_i32_add(self) -> Self { - self.with_insn(Instruction::I32Add) + self.with(|insn| { + insn.i32_add(); + }) } /// Add an `i32.sub` instruction to this constant expression. pub fn with_i32_sub(self) -> Self { - self.with_insn(Instruction::I32Sub) + self.with(|insn| { + insn.i32_sub(); + }) } /// Add an `i32.mul` instruction to this constant expression. pub fn with_i32_mul(self) -> Self { - self.with_insn(Instruction::I32Mul) + self.with(|insn| { + insn.i32_mul(); + }) } /// Add an `i64.add` instruction to this constant expression. pub fn with_i64_add(self) -> Self { - self.with_insn(Instruction::I64Add) + self.with(|insn| { + insn.i64_add(); + }) } /// Add an `i64.sub` instruction to this constant expression. pub fn with_i64_sub(self) -> Self { - self.with_insn(Instruction::I64Sub) + self.with(|insn| { + insn.i64_sub(); + }) } /// Add an `i64.mul` instruction to this constant expression. pub fn with_i64_mul(self) -> Self { - self.with_insn(Instruction::I64Mul) + self.with(|insn| { + insn.i64_mul(); + }) } /// Returns the function, if any, referenced by this global. @@ -2456,7 +2501,7 @@ impl ConstExpr { impl Encode for ConstExpr { fn encode(&self, sink: &mut Vec) { sink.extend(&self.bytes); - Instruction::End.encode(sink); + InstructionSink::new(sink).end(); } } @@ -2494,7 +2539,7 @@ mod tests { use super::*; let mut f = Function::new([(1, ValType::I32), (1, ValType::F32)]); - f.instruction(&Instruction::End); + f.instructions().end(); let mut code_from_func = CodeSection::new(); code_from_func.function(&f); let bytes = f.into_raw_body(); diff --git a/crates/wasm-encoder/src/lib.rs b/crates/wasm-encoder/src/lib.rs index 2d17c3fb29..e29983e001 100644 --- a/crates/wasm-encoder/src/lib.rs +++ b/crates/wasm-encoder/src/lib.rs @@ -26,7 +26,7 @@ //! //! ``` //! use wasm_encoder::{ -//! CodeSection, ExportKind, ExportSection, Function, FunctionSection, Instruction, +//! CodeSection, ExportKind, ExportSection, Function, FunctionSection, LocalIdx, //! Module, TypeSection, ValType, //! }; //! @@ -54,10 +54,11 @@ //! let mut codes = CodeSection::new(); //! let locals = vec![]; //! let mut f = Function::new(locals); -//! f.instruction(&Instruction::LocalGet(0)); -//! f.instruction(&Instruction::LocalGet(1)); -//! f.instruction(&Instruction::I32Add); -//! f.instruction(&Instruction::End); +//! f.instructions() +//! .local_get(LocalIdx(0)) +//! .local_get(LocalIdx(1)) +//! .i32_add() +//! .end(); //! codes.function(&f); //! module.section(&codes); //! diff --git a/crates/wasm-mutate/src/mutators/add_function.rs b/crates/wasm-mutate/src/mutators/add_function.rs index 7165f367bf..5ccc36bd84 100644 --- a/crates/wasm-mutate/src/mutators/add_function.rs +++ b/crates/wasm-mutate/src/mutators/add_function.rs @@ -4,7 +4,7 @@ use super::Mutator; use crate::module::{PrimitiveTypeInfo, TypeInfo}; use crate::{Result, WasmMutate}; use rand::Rng; -use wasm_encoder::{AbstractHeapType, HeapType, Instruction, Module}; +use wasm_encoder::{AbstractHeapType, HeapType, Module}; /// Mutator that adds new, empty functions to a Wasm module. #[derive(Clone, Copy)] @@ -47,36 +47,36 @@ impl Mutator for AddFunctionMutator { for ty in &func_ty.returns { match ty { PrimitiveTypeInfo::I32 => { - func.instruction(&Instruction::I32Const(0)); + func.instructions().i32_const(0); } PrimitiveTypeInfo::I64 => { - func.instruction(&Instruction::I64Const(0)); + func.instructions().i64_const(0); } PrimitiveTypeInfo::F32 => { - func.instruction(&Instruction::F32Const(0.0)); + func.instructions().f32_const(0.0); } PrimitiveTypeInfo::F64 => { - func.instruction(&Instruction::F64Const(0.0)); + func.instructions().f64_const(0.0); } PrimitiveTypeInfo::V128 => { - func.instruction(&Instruction::V128Const(0)); + func.instructions().v128_const(0); } PrimitiveTypeInfo::FuncRef => { - func.instruction(&Instruction::RefNull(HeapType::Abstract { + func.instructions().ref_null(HeapType::Abstract { shared: false, ty: AbstractHeapType::Func, - })); + }); } PrimitiveTypeInfo::ExternRef => { - func.instruction(&Instruction::RefNull(HeapType::Abstract { + func.instructions().ref_null(HeapType::Abstract { shared: false, ty: AbstractHeapType::Extern, - })); + }); } PrimitiveTypeInfo::Empty => unreachable!(), } } - func.instruction(&Instruction::End); + func.instructions().end(); code_sec_enc.function(&func); let module = if config.info().functions.is_some() { diff --git a/crates/wasm-mutate/src/mutators/codemotion/if_complement.rs b/crates/wasm-mutate/src/mutators/codemotion/if_complement.rs index c17a7e3519..304d774462 100644 --- a/crates/wasm-mutate/src/mutators/codemotion/if_complement.rs +++ b/crates/wasm-mutate/src/mutators/codemotion/if_complement.rs @@ -3,7 +3,7 @@ //! before the mutated if structure is encoded, a "negation" of the previous operand //! in the stack is written. The "negation" is encoded with a `i32.eqz` operator. use rand::prelude::SliceRandom; -use wasm_encoder::{Function, Instruction, ValType}; +use wasm_encoder::{Function, ValType}; use crate::{ module::map_block_type, @@ -42,8 +42,8 @@ impl IfComplementWriter { ty: &wasmparser::BlockType, ) -> crate::Result<()> { // negate the value on the stack - newfunc.instruction(&Instruction::I32Eqz); - newfunc.instruction(&Instruction::If(map_block_type(*ty)?)); + newfunc.instructions().i32_eqz(); + newfunc.instructions().if_(map_block_type(*ty)?); // Swap, write alternative first if let Some(alternative) = alternative { @@ -52,13 +52,13 @@ impl IfComplementWriter { } } else { // Write an unreachable instruction - newfunc.instruction(&Instruction::Nop); + newfunc.instructions().nop(); } - newfunc.instruction(&Instruction::Else); + newfunc.instructions().else_(); for ch in then { self.write(ast, *ch, newfunc, operators, input_wasm)?; } - newfunc.instruction(&Instruction::End); + newfunc.instructions().end(); Ok(()) } diff --git a/crates/wasm-mutate/src/mutators/codemotion/ir.rs b/crates/wasm-mutate/src/mutators/codemotion/ir.rs index cea9599958..6ffd458c5d 100644 --- a/crates/wasm-mutate/src/mutators/codemotion/ir.rs +++ b/crates/wasm-mutate/src/mutators/codemotion/ir.rs @@ -5,7 +5,7 @@ use crate::{ Error, }; use std::ops::Range; -use wasm_encoder::{Function, Instruction}; +use wasm_encoder::Function; use wasmparser::{BlockType, Operator}; use self::parse_context::{Ast, Node, State}; @@ -49,11 +49,11 @@ pub trait AstWriter { input_wasm: &'a [u8], ty: &BlockType, ) -> crate::Result<()> { - newfunc.instruction(&Instruction::Loop(map_block_type(*ty)?)); + newfunc.instructions().loop_(map_block_type(*ty)?); for ch in body { self.write(ast, *ch, newfunc, operators, input_wasm)?; } - newfunc.instruction(&Instruction::End); + newfunc.instructions().end(); Ok(()) } @@ -71,11 +71,11 @@ pub trait AstWriter { input_wasm: &'a [u8], ty: &BlockType, ) -> crate::Result<()> { - newfunc.instruction(&Instruction::Block(map_block_type(*ty)?)); + newfunc.instructions().block(map_block_type(*ty)?); for ch in body { self.write(ast, *ch, newfunc, operators, input_wasm)?; } - newfunc.instruction(&Instruction::End); + newfunc.instructions().end(); Ok(()) } @@ -144,20 +144,20 @@ pub trait AstWriter { input_wasm: &'a [u8], ty: &BlockType, ) -> crate::Result<()> { - newfunc.instruction(&Instruction::If(map_block_type(*ty)?)); + newfunc.instructions().if_(map_block_type(*ty)?); for ch in then { self.write(ast, *ch, newfunc, operators, input_wasm)?; } if let Some(alternative) = alternative { - newfunc.instruction(&Instruction::Else); + newfunc.instructions().else_(); for ch in alternative { self.write(ast, *ch, newfunc, operators, input_wasm)?; } } - newfunc.instruction(&Instruction::End); + newfunc.instructions().end(); Ok(()) } @@ -230,7 +230,7 @@ pub trait AstWriter { self.write(ast, *ch, newfunc, operators, input_wasm)?; } // Closing end - newfunc.instruction(&Instruction::End); + newfunc.instructions().end(); } } Ok(()) diff --git a/crates/wasm-mutate/src/mutators/codemotion/loop_unrolling.rs b/crates/wasm-mutate/src/mutators/codemotion/loop_unrolling.rs index 7f8beb6002..73498189be 100644 --- a/crates/wasm-mutate/src/mutators/codemotion/loop_unrolling.rs +++ b/crates/wasm-mutate/src/mutators/codemotion/loop_unrolling.rs @@ -3,7 +3,7 @@ use std::{collections::HashMap, slice::Iter}; use rand::prelude::SliceRandom; -use wasm_encoder::{Function, Instruction, ValType}; +use wasm_encoder::{Function, Instruction, LabelIdx, ValType}; use wasmparser::{BlockType, Operator}; use crate::{ @@ -67,7 +67,7 @@ impl LoopUnrollWriter { match &nodes[nodeidx] { Node::Loop { body: _, ty, range } => { let chunk = &operators[range.start + 1 /* skip the loop instruction */..range.end]; - newfunc.instruction(&Instruction::Block(map_block_type(*ty)?)); + newfunc.instructions().block(map_block_type(*ty)?); for (idx, (op, _)) in chunk.iter().enumerate() { match op { Operator::Block { .. } @@ -123,7 +123,7 @@ impl LoopUnrollWriter { } // Write the unroll - newfunc.instruction(&Instruction::Block(map_block_type(*ty)?)); + newfunc.instructions().block(map_block_type(*ty)?); // Write A' br B' let including_chunk = operators[range.start + 1 /* skip the loop instruction */..range.end + 1] @@ -131,10 +131,10 @@ impl LoopUnrollWriter { self.write_and_fix_loop_body(including_chunk, &to_fix, newfunc, input_wasm)?; // Write A' br B' - newfunc.instruction(&Instruction::Br(1)); - newfunc.instruction(&Instruction::End); + newfunc.instructions().br(LabelIdx(1)); + newfunc.instructions().end(); // Write the Loop - newfunc.instruction(&Instruction::Loop(map_block_type(*ty)?)); + newfunc.instructions().loop_(map_block_type(*ty)?); // Write A' br B' let including_chunk = @@ -143,10 +143,10 @@ impl LoopUnrollWriter { self.write_and_fix_loop_body(including_chunk, &to_fix, newfunc, input_wasm)?; // Closing loop - newfunc.instruction(&Instruction::End); + newfunc.instructions().end(); // Closing end - newfunc.instruction(&Instruction::End); + newfunc.instructions().end(); } _ => unreachable!("Invalid node passed as a loop to unroll"), } diff --git a/crates/wasm-mutate/src/mutators/function_body_unreachable.rs b/crates/wasm-mutate/src/mutators/function_body_unreachable.rs index 4cc3f4bf52..d4af25f8f0 100644 --- a/crates/wasm-mutate/src/mutators/function_body_unreachable.rs +++ b/crates/wasm-mutate/src/mutators/function_body_unreachable.rs @@ -3,7 +3,7 @@ use crate::{Result, WasmMutate}; use rand::Rng; -use wasm_encoder::{CodeSection, Function, Instruction, Module}; +use wasm_encoder::{CodeSection, Function, Module}; use wasmparser::CodeSectionReader; use super::Mutator; @@ -34,8 +34,8 @@ impl Mutator for FunctionBodyUnreachable { log::trace!("Mutating function {}", i); let locals = vec![]; let mut f = Function::new(locals); - f.instruction(&Instruction::Unreachable); - f.instruction(&Instruction::End); + f.instructions().unreachable(); + f.instructions().end(); codes.function(&f); } else { diff --git a/crates/wasm-mutate/src/mutators/peephole/eggsy/encoder/expr2wasm.rs b/crates/wasm-mutate/src/mutators/peephole/eggsy/encoder/expr2wasm.rs index a400e185a3..7b99e4b936 100644 --- a/crates/wasm-mutate/src/mutators/peephole/eggsy/encoder/expr2wasm.rs +++ b/crates/wasm-mutate/src/mutators/peephole/eggsy/encoder/expr2wasm.rs @@ -8,7 +8,7 @@ use crate::{ use egg::{Id, Language, RecExpr}; use rand::Rng; use std::num::Wrapping; -use wasm_encoder::{Function, Instruction}; +use wasm_encoder::{DataIdx, ElemIdx, FuncIdx, Function, GlobalIdx, LocalIdx, MemIdx, TableIdx}; /// Some custom nodes might need special resource allocation outside the /// function. Fore xample, if a new global is needed is should be added outside @@ -74,7 +74,7 @@ pub fn expr2wasm( // example, the creation of new globals let mut resources = vec![]; // Next global idx - let mut global_idx = config.info().get_global_count() as u32; + let mut global_idx = GlobalIdx(config.info().get_global_count() as u32); // Enqueue the coding back nodes and infer types while let Some(context) = worklist.pop() { @@ -90,45 +90,38 @@ pub fn expr2wasm( } }, TraversalEvent::Exit => { - let mut insn = |i: Instruction| { - newfunc.instruction(&i); - }; + let insn = &mut newfunc.instructions(); match rootlang { - Lang::LocalGet(idx) => insn(Instruction::LocalGet(*idx as u32)), - Lang::GlobalGet(idx) => insn(Instruction::GlobalGet(*idx as u32)), - Lang::LocalSet(idx, _val) => insn(Instruction::LocalSet(*idx as u32)), - Lang::GlobalSet(idx, _val) => insn(Instruction::GlobalSet(*idx as u32)), - Lang::LocalTee(idx, _) => insn(Instruction::LocalTee(*idx as u32)), - Lang::Wrap(_) => insn(Instruction::I32WrapI64), - Lang::Call(idx, _) => insn(Instruction::Call(*idx as u32)), - Lang::Drop(_) => insn(Instruction::Drop), - Lang::I32Load(memarg, _) => insn(Instruction::I32Load(memarg.into())), - Lang::I64Load(memarg, _) => insn(Instruction::I64Load(memarg.into())), - Lang::F32Load(memarg, _) => insn(Instruction::F32Load(memarg.into())), - Lang::F64Load(memarg, _) => insn(Instruction::F64Load(memarg.into())), - Lang::I32Load8U(memarg, _) => insn(Instruction::I32Load8U(memarg.into())), - Lang::I32Load8S(memarg, _) => insn(Instruction::I32Load8S(memarg.into())), - Lang::I32Load16U(memarg, _) => insn(Instruction::I32Load16U(memarg.into())), - Lang::I32Load16S(memarg, _) => insn(Instruction::I32Load16S(memarg.into())), - Lang::I64Load8U(memarg, _) => insn(Instruction::I64Load8U(memarg.into())), - Lang::I64Load8S(memarg, _) => insn(Instruction::I64Load8S(memarg.into())), - Lang::I64Load16U(memarg, _) => insn(Instruction::I64Load16U(memarg.into())), - Lang::I64Load16S(memarg, _) => insn(Instruction::I64Load16S(memarg.into())), - Lang::I64Load32U(memarg, _) => insn(Instruction::I64Load32U(memarg.into())), - Lang::I64Load32S(memarg, _) => insn(Instruction::I64Load32S(memarg.into())), - Lang::RandI32 => insn(Instruction::I32Const(config.rng().r#gen())), - Lang::RandI64 => insn(Instruction::I64Const(config.rng().r#gen())), - Lang::RandF32 => { - newfunc.instruction(&Instruction::F32Const(f32::from_bits( - config.rng().r#gen(), - ))); - } - Lang::RandF64 => { - newfunc.instruction(&Instruction::F64Const(f64::from_bits( - config.rng().r#gen(), - ))); + Lang::LocalGet(idx) => insn.local_get(LocalIdx(*idx)), + Lang::GlobalGet(idx) => insn.global_get(GlobalIdx(*idx)), + Lang::LocalSet(idx, _val) => insn.local_set(LocalIdx(*idx)), + Lang::GlobalSet(idx, _val) => insn.global_set(GlobalIdx(*idx)), + Lang::LocalTee(idx, _) => insn.local_tee(LocalIdx(*idx)), + Lang::Wrap(_) => insn.i32_wrap_i64(), + Lang::Call(idx, _) => insn.call(FuncIdx(*idx)), + Lang::Drop(_) => insn.drop(), + Lang::I32Load(memarg, _) => insn.i32_load(memarg.into()), + Lang::I64Load(memarg, _) => insn.i64_load(memarg.into()), + Lang::F32Load(memarg, _) => insn.f32_load(memarg.into()), + Lang::F64Load(memarg, _) => insn.f64_load(memarg.into()), + Lang::I32Load8U(memarg, _) => insn.i32_load8_u(memarg.into()), + Lang::I32Load8S(memarg, _) => insn.i32_load8_s(memarg.into()), + Lang::I32Load16U(memarg, _) => insn.i32_load16_u(memarg.into()), + Lang::I32Load16S(memarg, _) => insn.i32_load16_s(memarg.into()), + Lang::I64Load8U(memarg, _) => insn.i64_load8_u(memarg.into()), + Lang::I64Load8S(memarg, _) => insn.i64_load8_s(memarg.into()), + Lang::I64Load16U(memarg, _) => insn.i64_load16_u(memarg.into()), + Lang::I64Load16S(memarg, _) => insn.i64_load16_s(memarg.into()), + Lang::I64Load32U(memarg, _) => insn.i64_load32_u(memarg.into()), + Lang::I64Load32S(memarg, _) => insn.i64_load32_s(memarg.into()), + Lang::RandI32 => insn.i32_const(config.rng().r#gen()), + Lang::RandI64 => insn.i64_const(config.rng().r#gen()), + Lang::RandF32 => insn.f32_const(f32::from_bits(config.rng().r#gen())), + Lang::RandF64 => insn.f64_const(f64::from_bits(config.rng().r#gen())), + Lang::Undef => { + // Do nothing + insn } - Lang::Undef => { /* Do nothig */ } Lang::UnfoldI32(value) => { let child = &nodes[usize::from(*value)]; match child { @@ -136,11 +129,9 @@ pub fn expr2wasm( // Getting type from eclass. let r: i32 = config.rng().r#gen(); - insn(Instruction::I32Const(r)); - insn(Instruction::I32Const( - (Wrapping(*value as i32) - Wrapping(r)).0, - )); - insn(Instruction::I32Add); + insn.i32_const(r); + insn.i32_const((Wrapping(*value as i32) - Wrapping(r)).0); + insn.i32_add(); } _ => { return Err(Error::other(format!( @@ -149,6 +140,7 @@ pub fn expr2wasm( ))); } } + insn } Lang::UnfoldI64(value) => { let child = &nodes[usize::from(*value)]; @@ -157,9 +149,9 @@ pub fn expr2wasm( // Getting type from eclass. let r: i64 = config.rng().r#gen(); - insn(Instruction::I64Const(r)); - insn(Instruction::I64Const((Wrapping(*value) - Wrapping(r)).0)); - insn(Instruction::I64Add); + insn.i64_const(r); + insn.i64_const((Wrapping(*value) - Wrapping(r)).0); + insn.i64_add(); } _ => { return Err(Error::other(format!( @@ -168,195 +160,181 @@ pub fn expr2wasm( ))) } } - } - Lang::I32(v) => insn(Instruction::I32Const(*v)), - Lang::I64(v) => insn(Instruction::I64Const(*v)), - Lang::F32(v) => insn(Instruction::F32Const(v.to_f32())), - Lang::F64(v) => insn(Instruction::F64Const(v.to_f64())), - Lang::V128(v) => insn(Instruction::V128Const(*v)), - Lang::I32Add(_) => insn(Instruction::I32Add), - Lang::I64Add(_) => insn(Instruction::I64Add), - Lang::I32Sub(_) => insn(Instruction::I32Sub), - Lang::I64Sub(_) => insn(Instruction::I64Sub), - Lang::I32Mul(_) => insn(Instruction::I32Mul), - Lang::I64Mul(_) => insn(Instruction::I64Mul), - Lang::I32And(_) => insn(Instruction::I32And), - Lang::I64And(_) => insn(Instruction::I64And), - Lang::I32Or(_) => insn(Instruction::I32Or), - Lang::I64Or(_) => insn(Instruction::I64Or), - Lang::I32Xor(_) => insn(Instruction::I32Xor), - Lang::I64Xor(_) => insn(Instruction::I64Xor), - Lang::I32Shl(_) => insn(Instruction::I32Shl), - Lang::I64Shl(_) => insn(Instruction::I64Shl), - Lang::I32ShrU(_) => insn(Instruction::I32ShrU), - Lang::I64ShrU(_) => insn(Instruction::I64ShrU), - Lang::I32DivU(_) => insn(Instruction::I32DivU), - Lang::I64DivU(_) => insn(Instruction::I64DivU), - Lang::I32DivS(_) => insn(Instruction::I32DivS), - Lang::I64DivS(_) => insn(Instruction::I64DivS), - Lang::I32ShrS(_) => insn(Instruction::I32ShrS), - Lang::I64ShrS(_) => insn(Instruction::I64ShrS), - Lang::I32RotR(_) => insn(Instruction::I32Rotr), - Lang::I64RotR(_) => insn(Instruction::I64Rotr), - Lang::I32RotL(_) => insn(Instruction::I32Rotl), - Lang::I64RotL(_) => insn(Instruction::I64Rotl), - Lang::I32RemS(_) => insn(Instruction::I32RemS), - Lang::I64RemS(_) => insn(Instruction::I64RemS), - Lang::I32RemU(_) => insn(Instruction::I32RemU), - Lang::I64RemU(_) => insn(Instruction::I64RemU), - Lang::I32Eqz(_) => insn(Instruction::I32Eqz), - Lang::I64Eqz(_) => insn(Instruction::I64Eqz), - Lang::I32Eq(_) => insn(Instruction::I32Eq), - Lang::I64Eq(_) => insn(Instruction::I64Eq), - Lang::I32Ne(_) => insn(Instruction::I32Ne), - Lang::I64Ne(_) => insn(Instruction::I64Ne), - Lang::I32LtS(_) => insn(Instruction::I32LtS), - Lang::I64LtS(_) => insn(Instruction::I64LtS), - Lang::I32LtU(_) => insn(Instruction::I32LtU), - Lang::I64LtU(_) => insn(Instruction::I64LtU), - Lang::I32GtS(_) => insn(Instruction::I32GtS), - Lang::I64GtS(_) => insn(Instruction::I64GtS), - Lang::I32GtU(_) => insn(Instruction::I32GtU), - Lang::I64GtU(_) => insn(Instruction::I64GtU), - Lang::I32LeS(_) => insn(Instruction::I32LeS), - Lang::I64LeS(_) => insn(Instruction::I64LeS), - Lang::I32LeU(_) => insn(Instruction::I32LeU), - Lang::I64LeU(_) => insn(Instruction::I64LeU), - Lang::I32GeS(_) => insn(Instruction::I32GeS), - Lang::I64GeS(_) => insn(Instruction::I64GeS), - Lang::I32GeU(_) => insn(Instruction::I32GeU), - Lang::I64GeU(_) => insn(Instruction::I64GeU), - Lang::I32Clz(_) => insn(Instruction::I32Clz), - Lang::I32Ctz(_) => insn(Instruction::I32Ctz), - Lang::I64Ctz(_) => insn(Instruction::I64Ctz), - Lang::I64Clz(_) => insn(Instruction::I64Clz), - Lang::F32Abs(_) => insn(Instruction::F32Abs), - Lang::F64Abs(_) => insn(Instruction::F64Abs), - Lang::F32Neg(_) => insn(Instruction::F32Neg), - Lang::F64Neg(_) => insn(Instruction::F64Neg), - Lang::F32Sqrt(_) => insn(Instruction::F32Sqrt), - Lang::F64Sqrt(_) => insn(Instruction::F64Sqrt), - Lang::F32Ceil(_) => insn(Instruction::F32Ceil), - Lang::F64Ceil(_) => insn(Instruction::F64Ceil), - Lang::F32Floor(_) => insn(Instruction::F32Floor), - Lang::F64Floor(_) => insn(Instruction::F64Floor), - Lang::F32Trunc(_) => insn(Instruction::F32Trunc), - Lang::F64Trunc(_) => insn(Instruction::F64Trunc), - Lang::F32Nearest(_) => insn(Instruction::F32Nearest), - Lang::F64Nearest(_) => insn(Instruction::F64Nearest), - Lang::I32TruncF32S(_) => insn(Instruction::I32TruncF32S), - Lang::I32TruncF32U(_) => insn(Instruction::I32TruncF32U), - Lang::I32TruncF64S(_) => insn(Instruction::I32TruncF64S), - Lang::I32TruncF64U(_) => insn(Instruction::I32TruncF64U), - Lang::I64TruncF32S(_) => insn(Instruction::I64TruncF32S), - Lang::I64TruncF32U(_) => insn(Instruction::I64TruncF32U), - Lang::I64TruncF64S(_) => insn(Instruction::I64TruncF64S), - Lang::I64TruncF64U(_) => insn(Instruction::I64TruncF64U), - Lang::F32ConvertI32S(_) => insn(Instruction::F32ConvertI32S), - Lang::F32ConvertI32U(_) => insn(Instruction::F32ConvertI32U), - Lang::F32ConvertI64S(_) => insn(Instruction::F32ConvertI64S), - Lang::F32ConvertI64U(_) => insn(Instruction::F32ConvertI64U), - Lang::F32DemoteF64(_) => insn(Instruction::F32DemoteF64), - Lang::F64ConvertI32S(_) => insn(Instruction::F64ConvertI32S), - Lang::F64ConvertI32U(_) => insn(Instruction::F64ConvertI32U), - Lang::F64ConvertI64S(_) => insn(Instruction::F64ConvertI64S), - Lang::F64ConvertI64U(_) => insn(Instruction::F64ConvertI64U), - Lang::F64PromoteF32(_) => insn(Instruction::F64PromoteF32), - Lang::I32ReinterpretF32(_) => insn(Instruction::I32ReinterpretF32), - Lang::I64ReinterpretF64(_) => insn(Instruction::I64ReinterpretF64), - Lang::F32ReinterpretI32(_) => insn(Instruction::F32ReinterpretI32), - Lang::F64ReinterpretI64(_) => insn(Instruction::F64ReinterpretI64), - Lang::I32TruncSatF32S(_) => insn(Instruction::I32TruncSatF32S), - Lang::I32TruncSatF32U(_) => insn(Instruction::I32TruncSatF32U), - Lang::I32TruncSatF64S(_) => insn(Instruction::I32TruncSatF64S), - Lang::I32TruncSatF64U(_) => insn(Instruction::I32TruncSatF64U), - Lang::I64TruncSatF32S(_) => insn(Instruction::I64TruncSatF32S), - Lang::I64TruncSatF32U(_) => insn(Instruction::I64TruncSatF32U), - Lang::I64TruncSatF64S(_) => insn(Instruction::I64TruncSatF64S), - Lang::I64TruncSatF64U(_) => insn(Instruction::I64TruncSatF64U), - Lang::I32Popcnt(_) => insn(Instruction::I32Popcnt), - Lang::I64Popcnt(_) => insn(Instruction::I64Popcnt), - Lang::I32Extend8S(_) => insn(Instruction::I32Extend8S), - Lang::I64Extend8S(_) => insn(Instruction::I64Extend8S), - Lang::I32Extend16S(_) => insn(Instruction::I32Extend16S), - Lang::I64Extend16S(_) => insn(Instruction::I64Extend16S), - Lang::I64Extend32S(_) => insn(Instruction::I64Extend32S), - Lang::I64ExtendI32S(_) => insn(Instruction::I64ExtendI32S), - Lang::I64ExtendI32U(_) => insn(Instruction::I64ExtendI32U), - Lang::F32Add(_) => insn(Instruction::F32Add), - Lang::F64Add(_) => insn(Instruction::F64Add), - Lang::F32Sub(_) => insn(Instruction::F32Sub), - Lang::F64Sub(_) => insn(Instruction::F64Sub), - Lang::F32Mul(_) => insn(Instruction::F32Mul), - Lang::F64Mul(_) => insn(Instruction::F64Mul), - Lang::F32Div(_) => insn(Instruction::F32Div), - Lang::F64Div(_) => insn(Instruction::F64Div), - Lang::F32Min(_) => insn(Instruction::F32Min), - Lang::F64Min(_) => insn(Instruction::F64Min), - Lang::F32Max(_) => insn(Instruction::F32Max), - Lang::F64Max(_) => insn(Instruction::F64Max), - Lang::F32Copysign(_) => insn(Instruction::F32Copysign), - Lang::F64Copysign(_) => insn(Instruction::F64Copysign), - Lang::F32Eq(_) => insn(Instruction::F32Eq), - Lang::F64Eq(_) => insn(Instruction::F64Eq), - Lang::F32Ne(_) => insn(Instruction::F32Ne), - Lang::F64Ne(_) => insn(Instruction::F64Ne), - Lang::F32Lt(_) => insn(Instruction::F32Lt), - Lang::F64Lt(_) => insn(Instruction::F64Lt), - Lang::F32Gt(_) => insn(Instruction::F32Gt), - Lang::F64Gt(_) => insn(Instruction::F64Gt), - Lang::F32Le(_) => insn(Instruction::F32Le), - Lang::F64Le(_) => insn(Instruction::F64Le), - Lang::F32Ge(_) => insn(Instruction::F32Ge), - Lang::F64Ge(_) => insn(Instruction::F64Ge), - Lang::I32Store(memarg, _) => insn(Instruction::I32Store(memarg.into())), - Lang::I64Store(memarg, _) => insn(Instruction::I64Store(memarg.into())), - Lang::F32Store(memarg, _) => insn(Instruction::F32Store(memarg.into())), - Lang::F64Store(memarg, _) => insn(Instruction::F64Store(memarg.into())), - Lang::I32Store8(memarg, _) => insn(Instruction::I32Store8(memarg.into())), - Lang::I32Store16(memarg, _) => insn(Instruction::I32Store16(memarg.into())), - Lang::I64Store8(memarg, _) => insn(Instruction::I64Store8(memarg.into())), - Lang::I64Store16(memarg, _) => insn(Instruction::I64Store16(memarg.into())), - Lang::I64Store32(memarg, _) => insn(Instruction::I64Store32(memarg.into())), - Lang::Nop => insn(Instruction::Nop), + insn + } + Lang::I32(v) => insn.i32_const(*v), + Lang::I64(v) => insn.i64_const(*v), + Lang::F32(v) => insn.f32_const(v.to_f32()), + Lang::F64(v) => insn.f64_const(v.to_f64()), + Lang::V128(v) => insn.v128_const(*v), + Lang::I32Add(_) => insn.i32_add(), + Lang::I64Add(_) => insn.i64_add(), + Lang::I32Sub(_) => insn.i32_sub(), + Lang::I64Sub(_) => insn.i64_sub(), + Lang::I32Mul(_) => insn.i32_mul(), + Lang::I64Mul(_) => insn.i64_mul(), + Lang::I32And(_) => insn.i32_and(), + Lang::I64And(_) => insn.i64_and(), + Lang::I32Or(_) => insn.i32_or(), + Lang::I64Or(_) => insn.i64_or(), + Lang::I32Xor(_) => insn.i32_xor(), + Lang::I64Xor(_) => insn.i64_xor(), + Lang::I32Shl(_) => insn.i32_shl(), + Lang::I64Shl(_) => insn.i64_shl(), + Lang::I32ShrU(_) => insn.i32_shr_u(), + Lang::I64ShrU(_) => insn.i64_shr_u(), + Lang::I32DivU(_) => insn.i32_div_u(), + Lang::I64DivU(_) => insn.i64_div_u(), + Lang::I32DivS(_) => insn.i32_div_s(), + Lang::I64DivS(_) => insn.i64_div_s(), + Lang::I32ShrS(_) => insn.i32_shr_s(), + Lang::I64ShrS(_) => insn.i64_shr_s(), + Lang::I32RotR(_) => insn.i32_rotr(), + Lang::I64RotR(_) => insn.i64_rotr(), + Lang::I32RotL(_) => insn.i32_rotl(), + Lang::I64RotL(_) => insn.i64_rotl(), + Lang::I32RemS(_) => insn.i32_rem_s(), + Lang::I64RemS(_) => insn.i64_rem_s(), + Lang::I32RemU(_) => insn.i32_rem_u(), + Lang::I64RemU(_) => insn.i64_rem_u(), + Lang::I32Eqz(_) => insn.i32_eqz(), + Lang::I64Eqz(_) => insn.i64_eqz(), + Lang::I32Eq(_) => insn.i32_eq(), + Lang::I64Eq(_) => insn.i64_eq(), + Lang::I32Ne(_) => insn.i32_ne(), + Lang::I64Ne(_) => insn.i64_ne(), + Lang::I32LtS(_) => insn.i32_lt_s(), + Lang::I64LtS(_) => insn.i64_lt_s(), + Lang::I32LtU(_) => insn.i32_lt_u(), + Lang::I64LtU(_) => insn.i64_lt_u(), + Lang::I32GtS(_) => insn.i32_gt_s(), + Lang::I64GtS(_) => insn.i64_gt_s(), + Lang::I32GtU(_) => insn.i32_gt_u(), + Lang::I64GtU(_) => insn.i64_gt_u(), + Lang::I32LeS(_) => insn.i32_le_s(), + Lang::I64LeS(_) => insn.i64_le_s(), + Lang::I32LeU(_) => insn.i32_le_u(), + Lang::I64LeU(_) => insn.i64_le_u(), + Lang::I32GeS(_) => insn.i32_ge_s(), + Lang::I64GeS(_) => insn.i64_ge_s(), + Lang::I32GeU(_) => insn.i32_ge_u(), + Lang::I64GeU(_) => insn.i64_ge_u(), + Lang::I32Clz(_) => insn.i32_clz(), + Lang::I32Ctz(_) => insn.i32_ctz(), + Lang::I64Ctz(_) => insn.i64_ctz(), + Lang::I64Clz(_) => insn.i64_clz(), + Lang::F32Abs(_) => insn.f32_abs(), + Lang::F64Abs(_) => insn.f64_abs(), + Lang::F32Neg(_) => insn.f32_neg(), + Lang::F64Neg(_) => insn.f64_neg(), + Lang::F32Sqrt(_) => insn.f32_sqrt(), + Lang::F64Sqrt(_) => insn.f64_sqrt(), + Lang::F32Ceil(_) => insn.f32_ceil(), + Lang::F64Ceil(_) => insn.f64_ceil(), + Lang::F32Floor(_) => insn.f32_floor(), + Lang::F64Floor(_) => insn.f64_floor(), + Lang::F32Trunc(_) => insn.f32_trunc(), + Lang::F64Trunc(_) => insn.f64_trunc(), + Lang::F32Nearest(_) => insn.f32_nearest(), + Lang::F64Nearest(_) => insn.f64_nearest(), + Lang::I32TruncF32S(_) => insn.i32_trunc_f32_s(), + Lang::I32TruncF32U(_) => insn.i32_trunc_f32_u(), + Lang::I32TruncF64S(_) => insn.i32_trunc_f64_s(), + Lang::I32TruncF64U(_) => insn.i32_trunc_f64_u(), + Lang::I64TruncF32S(_) => insn.i64_trunc_f32_s(), + Lang::I64TruncF32U(_) => insn.i64_trunc_f32_u(), + Lang::I64TruncF64S(_) => insn.i64_trunc_f64_s(), + Lang::I64TruncF64U(_) => insn.i64_trunc_f64_u(), + Lang::F32ConvertI32S(_) => insn.f32_convert_i32_s(), + Lang::F32ConvertI32U(_) => insn.f32_convert_i32_u(), + Lang::F32ConvertI64S(_) => insn.f32_convert_i64_s(), + Lang::F32ConvertI64U(_) => insn.f32_convert_i64_u(), + Lang::F32DemoteF64(_) => insn.f32_demote_f64(), + Lang::F64ConvertI32S(_) => insn.f64_convert_i32_s(), + Lang::F64ConvertI32U(_) => insn.f64_convert_i32_u(), + Lang::F64ConvertI64S(_) => insn.f64_convert_i64_s(), + Lang::F64ConvertI64U(_) => insn.f64_convert_i64_u(), + Lang::F64PromoteF32(_) => insn.f64_promote_f32(), + Lang::I32ReinterpretF32(_) => insn.i32_reinterpret_f32(), + Lang::I64ReinterpretF64(_) => insn.i64_reinterpret_f64(), + Lang::F32ReinterpretI32(_) => insn.f32_reinterpret_i32(), + Lang::F64ReinterpretI64(_) => insn.f64_reinterpret_i64(), + Lang::I32TruncSatF32S(_) => insn.i32_trunc_sat_f32_s(), + Lang::I32TruncSatF32U(_) => insn.i32_trunc_sat_f32_u(), + Lang::I32TruncSatF64S(_) => insn.i32_trunc_sat_f64_s(), + Lang::I32TruncSatF64U(_) => insn.i32_trunc_sat_f64_u(), + Lang::I64TruncSatF32S(_) => insn.i64_trunc_sat_f32_s(), + Lang::I64TruncSatF32U(_) => insn.i64_trunc_sat_f32_u(), + Lang::I64TruncSatF64S(_) => insn.i64_trunc_sat_f64_s(), + Lang::I64TruncSatF64U(_) => insn.i64_trunc_sat_f64_u(), + Lang::I32Popcnt(_) => insn.i32_popcnt(), + Lang::I64Popcnt(_) => insn.i64_popcnt(), + Lang::I32Extend8S(_) => insn.i32_extend8_s(), + Lang::I64Extend8S(_) => insn.i64_extend8_s(), + Lang::I32Extend16S(_) => insn.i32_extend16_s(), + Lang::I64Extend16S(_) => insn.i64_extend16_s(), + Lang::I64Extend32S(_) => insn.i64_extend32_s(), + Lang::I64ExtendI32S(_) => insn.i64_extend_i32_s(), + Lang::I64ExtendI32U(_) => insn.i64_extend_i32_u(), + Lang::F32Add(_) => insn.f32_add(), + Lang::F64Add(_) => insn.f64_add(), + Lang::F32Sub(_) => insn.f32_sub(), + Lang::F64Sub(_) => insn.f64_sub(), + Lang::F32Mul(_) => insn.f32_mul(), + Lang::F64Mul(_) => insn.f64_mul(), + Lang::F32Div(_) => insn.f32_div(), + Lang::F64Div(_) => insn.f64_div(), + Lang::F32Min(_) => insn.f32_min(), + Lang::F64Min(_) => insn.f64_min(), + Lang::F32Max(_) => insn.f32_max(), + Lang::F64Max(_) => insn.f64_max(), + Lang::F32Copysign(_) => insn.f32_copysign(), + Lang::F64Copysign(_) => insn.f64_copysign(), + Lang::F32Eq(_) => insn.f32_eq(), + Lang::F64Eq(_) => insn.f64_eq(), + Lang::F32Ne(_) => insn.f32_ne(), + Lang::F64Ne(_) => insn.f64_ne(), + Lang::F32Lt(_) => insn.f32_lt(), + Lang::F64Lt(_) => insn.f64_lt(), + Lang::F32Gt(_) => insn.f32_gt(), + Lang::F64Gt(_) => insn.f64_gt(), + Lang::F32Le(_) => insn.f32_le(), + Lang::F64Le(_) => insn.f64_le(), + Lang::F32Ge(_) => insn.f32_ge(), + Lang::F64Ge(_) => insn.f64_ge(), + Lang::I32Store(memarg, _) => insn.i32_store(memarg.into()), + Lang::I64Store(memarg, _) => insn.i64_store(memarg.into()), + Lang::F32Store(memarg, _) => insn.f32_store(memarg.into()), + Lang::F64Store(memarg, _) => insn.f64_store(memarg.into()), + Lang::I32Store8(memarg, _) => insn.i32_store8(memarg.into()), + Lang::I32Store16(memarg, _) => insn.i32_store16(memarg.into()), + Lang::I64Store8(memarg, _) => insn.i64_store8(memarg.into()), + Lang::I64Store16(memarg, _) => insn.i64_store16(memarg.into()), + Lang::I64Store32(memarg, _) => insn.i64_store32(memarg.into()), + Lang::Nop => insn.nop(), Lang::Container(_) => { // Do nothing + insn } - Lang::Select(_) => insn(Instruction::Select), - Lang::MemoryGrow(mem, _) => insn(Instruction::MemoryGrow(*mem)), - Lang::MemorySize(mem) => insn(Instruction::MemorySize(*mem)), + Lang::Select(_) => insn.select(), + Lang::MemoryGrow(mem, _) => insn.memory_grow(MemIdx(*mem)), + Lang::MemorySize(mem) => insn.memory_size(MemIdx(*mem)), Lang::MemoryInit(init, _) => { - newfunc.instruction(&Instruction::MemoryInit { - mem: init.memory, - data_index: init.segment, - }); + insn.memory_init(MemIdx(init.memory), DataIdx(init.segment)) } - Lang::MemoryCopy(cp, _) => { - newfunc.instruction(&Instruction::MemoryCopy { - src_mem: cp.src, - dst_mem: cp.dst, - }); - } - Lang::MemoryFill(mem, _) => insn(Instruction::MemoryFill(*mem)), - Lang::DataDrop(idx) => insn(Instruction::DataDrop(*idx)), + Lang::MemoryCopy(cp, _) => insn.memory_copy(MemIdx(cp.dst), MemIdx(cp.src)), + Lang::MemoryFill(mem, _) => insn.memory_fill(MemIdx(*mem)), + Lang::DataDrop(idx) => insn.data_drop(DataIdx(*idx)), Lang::TableInit(init, _) => { - newfunc.instruction(&Instruction::TableInit { - table: init.table, - elem_index: init.segment, - }); - } - Lang::TableCopy(cp, _) => { - newfunc.instruction(&Instruction::TableCopy { - src_table: cp.src, - dst_table: cp.dst, - }); - } - Lang::TableFill(table, _) => insn(Instruction::TableFill(*table)), - Lang::ElemDrop(idx) => insn(Instruction::ElemDrop(*idx)), - Lang::TableGrow(table, _) => insn(Instruction::TableGrow(*table)), - Lang::TableSize(table) => insn(Instruction::TableSize(*table)), - Lang::TableGet(table, _) => insn(Instruction::TableGet(*table)), - Lang::TableSet(table, _) => insn(Instruction::TableSet(*table)), + insn.table_init(TableIdx(init.table), ElemIdx(init.segment)) + } + Lang::TableCopy(cp, _) => insn.table_copy(TableIdx(cp.dst), TableIdx(cp.src)), + Lang::TableFill(table, _) => insn.table_fill(TableIdx(*table)), + Lang::ElemDrop(idx) => insn.elem_drop(ElemIdx(*idx)), + Lang::TableGrow(table, _) => insn.table_grow(TableIdx(*table)), + Lang::TableSize(table) => insn.table_size(TableIdx(*table)), + Lang::TableGet(table, _) => insn.table_get(TableIdx(*table)), + Lang::TableSet(table, _) => insn.table_set(TableIdx(*table)), Lang::I32UseGlobal(_) => { // Request a new global let request = ResourceRequest::Global { @@ -366,9 +344,10 @@ pub fn expr2wasm( }; resources.push(request); - insn(Instruction::GlobalSet(global_idx)); - insn(Instruction::GlobalGet(global_idx)); - global_idx += 1; + insn.global_set(global_idx); + insn.global_get(global_idx); + global_idx.0 += 1; + insn } Lang::I64UseGlobal(_) => { let request = ResourceRequest::Global { @@ -378,9 +357,10 @@ pub fn expr2wasm( }; resources.push(request); - insn(Instruction::GlobalSet(global_idx)); - insn(Instruction::GlobalGet(global_idx)); - global_idx += 1; + insn.global_set(global_idx); + insn.global_get(global_idx); + global_idx.0 += 1; + insn } Lang::F32UseGlobal(_) => { let request = ResourceRequest::Global { @@ -390,9 +370,10 @@ pub fn expr2wasm( }; resources.push(request); - insn(Instruction::GlobalSet(global_idx)); - insn(Instruction::GlobalGet(global_idx)); - global_idx += 1; + insn.global_set(global_idx); + insn.global_get(global_idx); + global_idx.0 += 1; + insn } Lang::F64UseGlobal(_) => { let request = ResourceRequest::Global { @@ -402,367 +383,300 @@ pub fn expr2wasm( }; resources.push(request); - insn(Instruction::GlobalSet(global_idx)); - insn(Instruction::GlobalGet(global_idx)); - global_idx += 1; - } - Lang::RefNull(valtype) => insn(Instruction::RefNull((*valtype).into())), - Lang::RefFunc(idx) => insn(Instruction::RefFunc(*idx)), - Lang::RefIsNull(_) => insn(Instruction::RefIsNull), + insn.global_set(global_idx); + insn.global_get(global_idx); + global_idx.0 += 1; + insn + } + Lang::RefNull(valtype) => insn.ref_null((*valtype).into()), + Lang::RefFunc(idx) => insn.ref_func(FuncIdx(*idx)), + Lang::RefIsNull(_) => insn.ref_is_null(), - Lang::V128Not(_) => insn(Instruction::V128Not), - Lang::V128And(_) => insn(Instruction::V128And), - Lang::V128AndNot(_) => insn(Instruction::V128AndNot), - Lang::V128Or(_) => insn(Instruction::V128Or), - Lang::V128Xor(_) => insn(Instruction::V128Xor), - Lang::V128AnyTrue(_) => insn(Instruction::V128AnyTrue), - Lang::V128Bitselect(_) => insn(Instruction::V128Bitselect), + Lang::V128Not(_) => insn.v128_not(), + Lang::V128And(_) => insn.v128_and(), + Lang::V128AndNot(_) => insn.v128_andnot(), + Lang::V128Or(_) => insn.v128_or(), + Lang::V128Xor(_) => insn.v128_xor(), + Lang::V128AnyTrue(_) => insn.v128_any_true(), + Lang::V128Bitselect(_) => insn.v128_bitselect(), - Lang::V128Load(memarg, _) => { - newfunc.instruction(&Instruction::V128Load(memarg.into())); - } - Lang::V128Load8x8S(memarg, _) => { - newfunc.instruction(&Instruction::V128Load8x8S(memarg.into())); - } - Lang::V128Load8x8U(memarg, _) => { - newfunc.instruction(&Instruction::V128Load8x8U(memarg.into())); - } - Lang::V128Load16x4S(memarg, _) => { - newfunc.instruction(&Instruction::V128Load16x4S(memarg.into())); - } - Lang::V128Load16x4U(memarg, _) => { - newfunc.instruction(&Instruction::V128Load16x4U(memarg.into())); - } - Lang::V128Load32x2S(memarg, _) => { - newfunc.instruction(&Instruction::V128Load32x2S(memarg.into())); - } - Lang::V128Load32x2U(memarg, _) => { - newfunc.instruction(&Instruction::V128Load32x2U(memarg.into())); - } - Lang::V128Load8Splat(memarg, _) => { - newfunc.instruction(&Instruction::V128Load8Splat(memarg.into())); - } - Lang::V128Load16Splat(memarg, _) => { - newfunc.instruction(&Instruction::V128Load16Splat(memarg.into())); - } - Lang::V128Load32Splat(memarg, _) => { - newfunc.instruction(&Instruction::V128Load32Splat(memarg.into())); - } - Lang::V128Load64Splat(memarg, _) => { - newfunc.instruction(&Instruction::V128Load64Splat(memarg.into())); - } - Lang::V128Load32Zero(memarg, _) => { - newfunc.instruction(&Instruction::V128Load32Zero(memarg.into())); - } - Lang::V128Load64Zero(memarg, _) => { - newfunc.instruction(&Instruction::V128Load64Zero(memarg.into())); - } - Lang::V128Store(memarg, _) => { - newfunc.instruction(&Instruction::V128Store(memarg.into())); - } + Lang::V128Load(memarg, _) => insn.v128_load(memarg.into()), + Lang::V128Load8x8S(memarg, _) => insn.v128_load8x8_s(memarg.into()), + Lang::V128Load8x8U(memarg, _) => insn.v128_load8x8_u(memarg.into()), + Lang::V128Load16x4S(memarg, _) => insn.v128_load16x4_s(memarg.into()), + Lang::V128Load16x4U(memarg, _) => insn.v128_load16x4_u(memarg.into()), + Lang::V128Load32x2S(memarg, _) => insn.v128_load32x2_s(memarg.into()), + Lang::V128Load32x2U(memarg, _) => insn.v128_load32x2_u(memarg.into()), + Lang::V128Load8Splat(memarg, _) => insn.v128_load8_splat(memarg.into()), + Lang::V128Load16Splat(memarg, _) => insn.v128_load16_splat(memarg.into()), + Lang::V128Load32Splat(memarg, _) => insn.v128_load32_splat(memarg.into()), + Lang::V128Load64Splat(memarg, _) => insn.v128_load64_splat(memarg.into()), + Lang::V128Load32Zero(memarg, _) => insn.v128_load32_zero(memarg.into()), + Lang::V128Load64Zero(memarg, _) => insn.v128_load64_zero(memarg.into()), + Lang::V128Store(memarg, _) => insn.v128_store(memarg.into()), Lang::V128Load8Lane(memarg, _) => { - newfunc.instruction(&Instruction::V128Load8Lane { - memarg: (&memarg.memarg).into(), - lane: memarg.lane, - }); + insn.v128_load8_lane((&memarg.memarg).into(), memarg.lane) } Lang::V128Load16Lane(memarg, _) => { - newfunc.instruction(&Instruction::V128Load16Lane { - memarg: (&memarg.memarg).into(), - lane: memarg.lane, - }); + insn.v128_load16_lane((&memarg.memarg).into(), memarg.lane) } Lang::V128Load32Lane(memarg, _) => { - newfunc.instruction(&Instruction::V128Load32Lane { - memarg: (&memarg.memarg).into(), - lane: memarg.lane, - }); + insn.v128_load32_lane((&memarg.memarg).into(), memarg.lane) } Lang::V128Load64Lane(memarg, _) => { - newfunc.instruction(&Instruction::V128Load64Lane { - memarg: (&memarg.memarg).into(), - lane: memarg.lane, - }); + insn.v128_load64_lane((&memarg.memarg).into(), memarg.lane) } Lang::V128Store8Lane(memarg, _) => { - newfunc.instruction(&Instruction::V128Store8Lane { - memarg: (&memarg.memarg).into(), - lane: memarg.lane, - }); + insn.v128_store8_lane((&memarg.memarg).into(), memarg.lane) } Lang::V128Store16Lane(memarg, _) => { - newfunc.instruction(&Instruction::V128Store16Lane { - memarg: (&memarg.memarg).into(), - lane: memarg.lane, - }); + insn.v128_store16_lane((&memarg.memarg).into(), memarg.lane) } Lang::V128Store32Lane(memarg, _) => { - newfunc.instruction(&Instruction::V128Store32Lane { - memarg: (&memarg.memarg).into(), - lane: memarg.lane, - }); + insn.v128_store32_lane((&memarg.memarg).into(), memarg.lane) } Lang::V128Store64Lane(memarg, _) => { - newfunc.instruction(&Instruction::V128Store64Lane { - memarg: (&memarg.memarg).into(), - lane: memarg.lane, - }); + insn.v128_store64_lane((&memarg.memarg).into(), memarg.lane) } - Lang::I8x16ExtractLaneS(lane, _) => insn(Instruction::I8x16ExtractLaneS(*lane)), - Lang::I8x16ExtractLaneU(lane, _) => insn(Instruction::I8x16ExtractLaneU(*lane)), - Lang::I8x16ReplaceLane(lane, _) => insn(Instruction::I8x16ReplaceLane(*lane)), - Lang::I16x8ExtractLaneS(lane, _) => insn(Instruction::I16x8ExtractLaneS(*lane)), - Lang::I16x8ExtractLaneU(lane, _) => insn(Instruction::I16x8ExtractLaneU(*lane)), - Lang::I16x8ReplaceLane(lane, _) => insn(Instruction::I16x8ReplaceLane(*lane)), - Lang::I32x4ExtractLane(lane, _) => insn(Instruction::I32x4ExtractLane(*lane)), - Lang::I32x4ReplaceLane(lane, _) => insn(Instruction::I32x4ReplaceLane(*lane)), - Lang::I64x2ExtractLane(lane, _) => insn(Instruction::I64x2ExtractLane(*lane)), - Lang::I64x2ReplaceLane(lane, _) => insn(Instruction::I64x2ReplaceLane(*lane)), - Lang::F32x4ExtractLane(lane, _) => insn(Instruction::F32x4ExtractLane(*lane)), - Lang::F32x4ReplaceLane(lane, _) => insn(Instruction::F32x4ReplaceLane(*lane)), - Lang::F64x2ExtractLane(lane, _) => insn(Instruction::F64x2ExtractLane(*lane)), - Lang::F64x2ReplaceLane(lane, _) => insn(Instruction::F64x2ReplaceLane(*lane)), + Lang::I8x16ExtractLaneS(lane, _) => insn.i8x16_extract_lane_s(*lane), + Lang::I8x16ExtractLaneU(lane, _) => insn.i8x16_extract_lane_u(*lane), + Lang::I8x16ReplaceLane(lane, _) => insn.i8x16_replace_lane(*lane), + Lang::I16x8ExtractLaneS(lane, _) => insn.i16x8_extract_lane_s(*lane), + Lang::I16x8ExtractLaneU(lane, _) => insn.i16x8_extract_lane_u(*lane), + Lang::I16x8ReplaceLane(lane, _) => insn.i16x8_replace_lane(*lane), + Lang::I32x4ExtractLane(lane, _) => insn.i32x4_extract_lane(*lane), + Lang::I32x4ReplaceLane(lane, _) => insn.i32x4_replace_lane(*lane), + Lang::I64x2ExtractLane(lane, _) => insn.i64x2_extract_lane(*lane), + Lang::I64x2ReplaceLane(lane, _) => insn.i64x2_replace_lane(*lane), + Lang::F32x4ExtractLane(lane, _) => insn.f32x4_extract_lane(*lane), + Lang::F32x4ReplaceLane(lane, _) => insn.f32x4_replace_lane(*lane), + Lang::F64x2ExtractLane(lane, _) => insn.f64x2_extract_lane(*lane), + Lang::F64x2ReplaceLane(lane, _) => insn.f64x2_replace_lane(*lane), - Lang::I8x16Swizzle(_) => insn(Instruction::I8x16Swizzle), - Lang::I8x16Shuffle(indices, _) => { - insn(Instruction::I8x16Shuffle(indices.indices)) - } - Lang::I8x16Splat(_) => insn(Instruction::I8x16Splat), - Lang::I16x8Splat(_) => insn(Instruction::I16x8Splat), - Lang::I32x4Splat(_) => insn(Instruction::I32x4Splat), - Lang::I64x2Splat(_) => insn(Instruction::I64x2Splat), - Lang::F32x4Splat(_) => insn(Instruction::F32x4Splat), - Lang::F64x2Splat(_) => insn(Instruction::F64x2Splat), + Lang::I8x16Swizzle(_) => insn.i8x16_swizzle(), + Lang::I8x16Shuffle(indices, _) => insn.i8x16_shuffle(indices.indices), + Lang::I8x16Splat(_) => insn.i8x16_splat(), + Lang::I16x8Splat(_) => insn.i16x8_splat(), + Lang::I32x4Splat(_) => insn.i32x4_splat(), + Lang::I64x2Splat(_) => insn.i64x2_splat(), + Lang::F32x4Splat(_) => insn.f32x4_splat(), + Lang::F64x2Splat(_) => insn.f64x2_splat(), - Lang::I8x16Eq(_) => insn(Instruction::I8x16Eq), - Lang::I8x16Ne(_) => insn(Instruction::I8x16Ne), - Lang::I8x16LtS(_) => insn(Instruction::I8x16LtS), - Lang::I8x16LtU(_) => insn(Instruction::I8x16LtU), - Lang::I8x16GtS(_) => insn(Instruction::I8x16GtS), - Lang::I8x16GtU(_) => insn(Instruction::I8x16GtU), - Lang::I8x16LeS(_) => insn(Instruction::I8x16LeS), - Lang::I8x16LeU(_) => insn(Instruction::I8x16LeU), - Lang::I8x16GeS(_) => insn(Instruction::I8x16GeS), - Lang::I8x16GeU(_) => insn(Instruction::I8x16GeU), - Lang::I16x8Eq(_) => insn(Instruction::I16x8Eq), - Lang::I16x8Ne(_) => insn(Instruction::I16x8Ne), - Lang::I16x8LtS(_) => insn(Instruction::I16x8LtS), - Lang::I16x8LtU(_) => insn(Instruction::I16x8LtU), - Lang::I16x8GtS(_) => insn(Instruction::I16x8GtS), - Lang::I16x8GtU(_) => insn(Instruction::I16x8GtU), - Lang::I16x8LeS(_) => insn(Instruction::I16x8LeS), - Lang::I16x8LeU(_) => insn(Instruction::I16x8LeU), - Lang::I16x8GeS(_) => insn(Instruction::I16x8GeS), - Lang::I16x8GeU(_) => insn(Instruction::I16x8GeU), - Lang::I32x4Eq(_) => insn(Instruction::I32x4Eq), - Lang::I32x4Ne(_) => insn(Instruction::I32x4Ne), - Lang::I32x4LtS(_) => insn(Instruction::I32x4LtS), - Lang::I32x4LtU(_) => insn(Instruction::I32x4LtU), - Lang::I32x4GtS(_) => insn(Instruction::I32x4GtS), - Lang::I32x4GtU(_) => insn(Instruction::I32x4GtU), - Lang::I32x4LeS(_) => insn(Instruction::I32x4LeS), - Lang::I32x4LeU(_) => insn(Instruction::I32x4LeU), - Lang::I32x4GeS(_) => insn(Instruction::I32x4GeS), - Lang::I32x4GeU(_) => insn(Instruction::I32x4GeU), - Lang::I64x2Eq(_) => insn(Instruction::I64x2Eq), - Lang::I64x2Ne(_) => insn(Instruction::I64x2Ne), - Lang::I64x2LtS(_) => insn(Instruction::I64x2LtS), - Lang::I64x2GtS(_) => insn(Instruction::I64x2GtS), - Lang::I64x2LeS(_) => insn(Instruction::I64x2LeS), - Lang::I64x2GeS(_) => insn(Instruction::I64x2GeS), - Lang::F32x4Eq(_) => insn(Instruction::F32x4Eq), - Lang::F32x4Ne(_) => insn(Instruction::F32x4Ne), - Lang::F32x4Lt(_) => insn(Instruction::F32x4Lt), - Lang::F32x4Gt(_) => insn(Instruction::F32x4Gt), - Lang::F32x4Le(_) => insn(Instruction::F32x4Le), - Lang::F32x4Ge(_) => insn(Instruction::F32x4Ge), - Lang::F64x2Eq(_) => insn(Instruction::F64x2Eq), - Lang::F64x2Ne(_) => insn(Instruction::F64x2Ne), - Lang::F64x2Lt(_) => insn(Instruction::F64x2Lt), - Lang::F64x2Gt(_) => insn(Instruction::F64x2Gt), - Lang::F64x2Le(_) => insn(Instruction::F64x2Le), - Lang::F64x2Ge(_) => insn(Instruction::F64x2Ge), + Lang::I8x16Eq(_) => insn.i8x16_eq(), + Lang::I8x16Ne(_) => insn.i8x16_ne(), + Lang::I8x16LtS(_) => insn.i8x16_lt_s(), + Lang::I8x16LtU(_) => insn.i8x16_lt_u(), + Lang::I8x16GtS(_) => insn.i8x16_gt_s(), + Lang::I8x16GtU(_) => insn.i8x16_gt_u(), + Lang::I8x16LeS(_) => insn.i8x16_le_s(), + Lang::I8x16LeU(_) => insn.i8x16_le_u(), + Lang::I8x16GeS(_) => insn.i8x16_ge_s(), + Lang::I8x16GeU(_) => insn.i8x16_ge_u(), + Lang::I16x8Eq(_) => insn.i16x8_eq(), + Lang::I16x8Ne(_) => insn.i16x8_ne(), + Lang::I16x8LtS(_) => insn.i16x8_lt_s(), + Lang::I16x8LtU(_) => insn.i16x8_lt_u(), + Lang::I16x8GtS(_) => insn.i16x8_gt_s(), + Lang::I16x8GtU(_) => insn.i16x8_gt_u(), + Lang::I16x8LeS(_) => insn.i16x8_le_s(), + Lang::I16x8LeU(_) => insn.i16x8_le_u(), + Lang::I16x8GeS(_) => insn.i16x8_ge_s(), + Lang::I16x8GeU(_) => insn.i16x8_ge_u(), + Lang::I32x4Eq(_) => insn.i32x4_eq(), + Lang::I32x4Ne(_) => insn.i32x4_ne(), + Lang::I32x4LtS(_) => insn.i32x4_lt_s(), + Lang::I32x4LtU(_) => insn.i32x4_lt_u(), + Lang::I32x4GtS(_) => insn.i32x4_gt_s(), + Lang::I32x4GtU(_) => insn.i32x4_gt_u(), + Lang::I32x4LeS(_) => insn.i32x4_le_s(), + Lang::I32x4LeU(_) => insn.i32x4_le_u(), + Lang::I32x4GeS(_) => insn.i32x4_ge_s(), + Lang::I32x4GeU(_) => insn.i32x4_ge_u(), + Lang::I64x2Eq(_) => insn.i64x2_eq(), + Lang::I64x2Ne(_) => insn.i64x2_ne(), + Lang::I64x2LtS(_) => insn.i64x2_lt_s(), + Lang::I64x2GtS(_) => insn.i64x2_gt_s(), + Lang::I64x2LeS(_) => insn.i64x2_le_s(), + Lang::I64x2GeS(_) => insn.i64x2_ge_s(), + Lang::F32x4Eq(_) => insn.f32x4_eq(), + Lang::F32x4Ne(_) => insn.f32x4_ne(), + Lang::F32x4Lt(_) => insn.f32x4_lt(), + Lang::F32x4Gt(_) => insn.f32x4_gt(), + Lang::F32x4Le(_) => insn.f32x4_le(), + Lang::F32x4Ge(_) => insn.f32x4_ge(), + Lang::F64x2Eq(_) => insn.f64x2_eq(), + Lang::F64x2Ne(_) => insn.f64x2_ne(), + Lang::F64x2Lt(_) => insn.f64x2_lt(), + Lang::F64x2Gt(_) => insn.f64x2_gt(), + Lang::F64x2Le(_) => insn.f64x2_le(), + Lang::F64x2Ge(_) => insn.f64x2_ge(), - Lang::I8x16Abs(_) => insn(Instruction::I8x16Abs), - Lang::I8x16Neg(_) => insn(Instruction::I8x16Neg), - Lang::I8x16Popcnt(_) => insn(Instruction::I8x16Popcnt), - Lang::I8x16AllTrue(_) => insn(Instruction::I8x16AllTrue), - Lang::I8x16Bitmask(_) => insn(Instruction::I8x16Bitmask), - Lang::I8x16NarrowI16x8S(_) => insn(Instruction::I8x16NarrowI16x8S), - Lang::I8x16NarrowI16x8U(_) => insn(Instruction::I8x16NarrowI16x8U), - Lang::I8x16Shl(_) => insn(Instruction::I8x16Shl), - Lang::I8x16ShrS(_) => insn(Instruction::I8x16ShrS), - Lang::I8x16ShrU(_) => insn(Instruction::I8x16ShrU), - Lang::I8x16Add(_) => insn(Instruction::I8x16Add), - Lang::I8x16AddSatS(_) => insn(Instruction::I8x16AddSatS), - Lang::I8x16AddSatU(_) => insn(Instruction::I8x16AddSatU), - Lang::I8x16Sub(_) => insn(Instruction::I8x16Sub), - Lang::I8x16SubSatS(_) => insn(Instruction::I8x16SubSatS), - Lang::I8x16SubSatU(_) => insn(Instruction::I8x16SubSatU), - Lang::I8x16MinS(_) => insn(Instruction::I8x16MinS), - Lang::I8x16MinU(_) => insn(Instruction::I8x16MinU), - Lang::I8x16MaxS(_) => insn(Instruction::I8x16MaxS), - Lang::I8x16MaxU(_) => insn(Instruction::I8x16MaxU), - Lang::I8x16AvgrU(_) => insn(Instruction::I8x16AvgrU), + Lang::I8x16Abs(_) => insn.i8x16_abs(), + Lang::I8x16Neg(_) => insn.i8x16_neg(), + Lang::I8x16Popcnt(_) => insn.i8x16_popcnt(), + Lang::I8x16AllTrue(_) => insn.i8x16_all_true(), + Lang::I8x16Bitmask(_) => insn.i8x16_bitmask(), + Lang::I8x16NarrowI16x8S(_) => insn.i8x16_narrow_i16x8_s(), + Lang::I8x16NarrowI16x8U(_) => insn.i8x16_narrow_i16x8_u(), + Lang::I8x16Shl(_) => insn.i8x16_shl(), + Lang::I8x16ShrS(_) => insn.i8x16_shr_s(), + Lang::I8x16ShrU(_) => insn.i8x16_shr_u(), + Lang::I8x16Add(_) => insn.i8x16_add(), + Lang::I8x16AddSatS(_) => insn.i8x16_add_sat_s(), + Lang::I8x16AddSatU(_) => insn.i8x16_add_sat_u(), + Lang::I8x16Sub(_) => insn.i8x16_sub(), + Lang::I8x16SubSatS(_) => insn.i8x16_sub_sat_s(), + Lang::I8x16SubSatU(_) => insn.i8x16_sub_sat_u(), + Lang::I8x16MinS(_) => insn.i8x16_min_s(), + Lang::I8x16MinU(_) => insn.i8x16_min_u(), + Lang::I8x16MaxS(_) => insn.i8x16_max_s(), + Lang::I8x16MaxU(_) => insn.i8x16_max_u(), + Lang::I8x16AvgrU(_) => insn.i8x16_avgr_u(), - Lang::I16x8ExtAddPairwiseI8x16S(_) => { - insn(Instruction::I16x8ExtAddPairwiseI8x16S) - } - Lang::I16x8ExtAddPairwiseI8x16U(_) => { - insn(Instruction::I16x8ExtAddPairwiseI8x16U) - } - Lang::I16x8Abs(_) => insn(Instruction::I16x8Abs), - Lang::I16x8Neg(_) => insn(Instruction::I16x8Neg), - Lang::I16x8Q15MulrSatS(_) => insn(Instruction::I16x8Q15MulrSatS), - Lang::I16x8AllTrue(_) => insn(Instruction::I16x8AllTrue), - Lang::I16x8Bitmask(_) => insn(Instruction::I16x8Bitmask), - Lang::I16x8NarrowI32x4S(_) => insn(Instruction::I16x8NarrowI32x4S), - Lang::I16x8NarrowI32x4U(_) => insn(Instruction::I16x8NarrowI32x4U), - Lang::I16x8ExtendLowI8x16S(_) => insn(Instruction::I16x8ExtendLowI8x16S), - Lang::I16x8ExtendHighI8x16S(_) => insn(Instruction::I16x8ExtendHighI8x16S), - Lang::I16x8ExtendLowI8x16U(_) => insn(Instruction::I16x8ExtendLowI8x16U), - Lang::I16x8ExtendHighI8x16U(_) => insn(Instruction::I16x8ExtendHighI8x16U), - Lang::I16x8Shl(_) => insn(Instruction::I16x8Shl), - Lang::I16x8ShrS(_) => insn(Instruction::I16x8ShrS), - Lang::I16x8ShrU(_) => insn(Instruction::I16x8ShrU), - Lang::I16x8Add(_) => insn(Instruction::I16x8Add), - Lang::I16x8AddSatS(_) => insn(Instruction::I16x8AddSatS), - Lang::I16x8AddSatU(_) => insn(Instruction::I16x8AddSatU), - Lang::I16x8Sub(_) => insn(Instruction::I16x8Sub), - Lang::I16x8SubSatS(_) => insn(Instruction::I16x8SubSatS), - Lang::I16x8SubSatU(_) => insn(Instruction::I16x8SubSatU), - Lang::I16x8Mul(_) => insn(Instruction::I16x8Mul), - Lang::I16x8MinS(_) => insn(Instruction::I16x8MinS), - Lang::I16x8MinU(_) => insn(Instruction::I16x8MinU), - Lang::I16x8MaxS(_) => insn(Instruction::I16x8MaxS), - Lang::I16x8MaxU(_) => insn(Instruction::I16x8MaxU), - Lang::I16x8AvgrU(_) => insn(Instruction::I16x8AvgrU), - Lang::I16x8ExtMulLowI8x16S(_) => insn(Instruction::I16x8ExtMulLowI8x16S), - Lang::I16x8ExtMulHighI8x16S(_) => insn(Instruction::I16x8ExtMulHighI8x16S), - Lang::I16x8ExtMulLowI8x16U(_) => insn(Instruction::I16x8ExtMulLowI8x16U), - Lang::I16x8ExtMulHighI8x16U(_) => insn(Instruction::I16x8ExtMulHighI8x16U), + Lang::I16x8ExtAddPairwiseI8x16S(_) => insn.i16x8_extadd_pairwise_i8x16_s(), + Lang::I16x8ExtAddPairwiseI8x16U(_) => insn.i16x8_extadd_pairwise_i8x16_u(), + Lang::I16x8Abs(_) => insn.i16x8_abs(), + Lang::I16x8Neg(_) => insn.i16x8_neg(), + Lang::I16x8Q15MulrSatS(_) => insn.i16x8_q15mulr_sat_s(), + Lang::I16x8AllTrue(_) => insn.i16x8_all_true(), + Lang::I16x8Bitmask(_) => insn.i16x8_bitmask(), + Lang::I16x8NarrowI32x4S(_) => insn.i16x8_narrow_i32x4_s(), + Lang::I16x8NarrowI32x4U(_) => insn.i16x8_narrow_i32x4_u(), + Lang::I16x8ExtendLowI8x16S(_) => insn.i16x8_extend_low_i8x16_s(), + Lang::I16x8ExtendHighI8x16S(_) => insn.i16x8_extend_high_i8x16_s(), + Lang::I16x8ExtendLowI8x16U(_) => insn.i16x8_extend_low_i8x16_u(), + Lang::I16x8ExtendHighI8x16U(_) => insn.i16x8_extend_high_i8x16_u(), + Lang::I16x8Shl(_) => insn.i16x8_shl(), + Lang::I16x8ShrS(_) => insn.i16x8_shr_s(), + Lang::I16x8ShrU(_) => insn.i16x8_shr_u(), + Lang::I16x8Add(_) => insn.i16x8_add(), + Lang::I16x8AddSatS(_) => insn.i16x8_add_sat_s(), + Lang::I16x8AddSatU(_) => insn.i16x8_add_sat_u(), + Lang::I16x8Sub(_) => insn.i16x8_sub(), + Lang::I16x8SubSatS(_) => insn.i16x8_sub_sat_s(), + Lang::I16x8SubSatU(_) => insn.i16x8_sub_sat_u(), + Lang::I16x8Mul(_) => insn.i16x8_mul(), + Lang::I16x8MinS(_) => insn.i16x8_min_s(), + Lang::I16x8MinU(_) => insn.i16x8_min_u(), + Lang::I16x8MaxS(_) => insn.i16x8_max_s(), + Lang::I16x8MaxU(_) => insn.i16x8_max_u(), + Lang::I16x8AvgrU(_) => insn.i16x8_avgr_u(), + Lang::I16x8ExtMulLowI8x16S(_) => insn.i16x8_extmul_low_i8x16_s(), + Lang::I16x8ExtMulHighI8x16S(_) => insn.i16x8_extmul_high_i8x16_s(), + Lang::I16x8ExtMulLowI8x16U(_) => insn.i16x8_extmul_low_i8x16_u(), + Lang::I16x8ExtMulHighI8x16U(_) => insn.i16x8_extmul_high_i8x16_u(), - Lang::I32x4ExtAddPairwiseI16x8S(_) => { - insn(Instruction::I32x4ExtAddPairwiseI16x8S) - } - Lang::I32x4ExtAddPairwiseI16x8U(_) => { - insn(Instruction::I32x4ExtAddPairwiseI16x8U) - } - Lang::I32x4Abs(_) => insn(Instruction::I32x4Abs), - Lang::I32x4Neg(_) => insn(Instruction::I32x4Neg), - Lang::I32x4AllTrue(_) => insn(Instruction::I32x4AllTrue), - Lang::I32x4Bitmask(_) => insn(Instruction::I32x4Bitmask), - Lang::I32x4ExtendLowI16x8S(_) => insn(Instruction::I32x4ExtendLowI16x8S), - Lang::I32x4ExtendHighI16x8S(_) => insn(Instruction::I32x4ExtendHighI16x8S), - Lang::I32x4ExtendLowI16x8U(_) => insn(Instruction::I32x4ExtendLowI16x8U), - Lang::I32x4ExtendHighI16x8U(_) => insn(Instruction::I32x4ExtendHighI16x8U), - Lang::I32x4Shl(_) => insn(Instruction::I32x4Shl), - Lang::I32x4ShrS(_) => insn(Instruction::I32x4ShrS), - Lang::I32x4ShrU(_) => insn(Instruction::I32x4ShrU), - Lang::I32x4Add(_) => insn(Instruction::I32x4Add), - Lang::I32x4Sub(_) => insn(Instruction::I32x4Sub), - Lang::I32x4Mul(_) => insn(Instruction::I32x4Mul), - Lang::I32x4MinS(_) => insn(Instruction::I32x4MinS), - Lang::I32x4MinU(_) => insn(Instruction::I32x4MinU), - Lang::I32x4MaxS(_) => insn(Instruction::I32x4MaxS), - Lang::I32x4MaxU(_) => insn(Instruction::I32x4MaxU), - Lang::I32x4DotI16x8S(_) => insn(Instruction::I32x4DotI16x8S), - Lang::I32x4ExtMulLowI16x8S(_) => insn(Instruction::I32x4ExtMulLowI16x8S), - Lang::I32x4ExtMulHighI16x8S(_) => insn(Instruction::I32x4ExtMulHighI16x8S), - Lang::I32x4ExtMulLowI16x8U(_) => insn(Instruction::I32x4ExtMulLowI16x8U), - Lang::I32x4ExtMulHighI16x8U(_) => insn(Instruction::I32x4ExtMulHighI16x8U), + Lang::I32x4ExtAddPairwiseI16x8S(_) => insn.i32x4_extadd_pairwise_i16x8_s(), + Lang::I32x4ExtAddPairwiseI16x8U(_) => insn.i32x4_extadd_pairwise_i16x8_u(), + Lang::I32x4Abs(_) => insn.i32x4_abs(), + Lang::I32x4Neg(_) => insn.i32x4_neg(), + Lang::I32x4AllTrue(_) => insn.i32x4_all_true(), + Lang::I32x4Bitmask(_) => insn.i32x4_bitmask(), + Lang::I32x4ExtendLowI16x8S(_) => insn.i32x4_extend_low_i16x8_s(), + Lang::I32x4ExtendHighI16x8S(_) => insn.i32x4_extend_high_i16x8_s(), + Lang::I32x4ExtendLowI16x8U(_) => insn.i32x4_extend_low_i16x8_u(), + Lang::I32x4ExtendHighI16x8U(_) => insn.i32x4_extend_high_i16x8_u(), + Lang::I32x4Shl(_) => insn.i32x4_shl(), + Lang::I32x4ShrS(_) => insn.i32x4_shr_s(), + Lang::I32x4ShrU(_) => insn.i32x4_shr_u(), + Lang::I32x4Add(_) => insn.i32x4_add(), + Lang::I32x4Sub(_) => insn.i32x4_sub(), + Lang::I32x4Mul(_) => insn.i32x4_mul(), + Lang::I32x4MinS(_) => insn.i32x4_min_s(), + Lang::I32x4MinU(_) => insn.i32x4_min_u(), + Lang::I32x4MaxS(_) => insn.i32x4_max_s(), + Lang::I32x4MaxU(_) => insn.i32x4_max_u(), + Lang::I32x4DotI16x8S(_) => insn.i32x4_dot_i16x8_s(), + Lang::I32x4ExtMulLowI16x8S(_) => insn.i32x4_extmul_low_i16x8_s(), + Lang::I32x4ExtMulHighI16x8S(_) => insn.i32x4_extmul_high_i16x8_s(), + Lang::I32x4ExtMulLowI16x8U(_) => insn.i32x4_extmul_low_i16x8_u(), + Lang::I32x4ExtMulHighI16x8U(_) => insn.i32x4_extmul_high_i16x8_u(), - Lang::I64x2Abs(_) => insn(Instruction::I64x2Abs), - Lang::I64x2Neg(_) => insn(Instruction::I64x2Neg), - Lang::I64x2AllTrue(_) => insn(Instruction::I64x2AllTrue), - Lang::I64x2Bitmask(_) => insn(Instruction::I64x2Bitmask), - Lang::I64x2ExtendLowI32x4S(_) => insn(Instruction::I64x2ExtendLowI32x4S), - Lang::I64x2ExtendHighI32x4S(_) => insn(Instruction::I64x2ExtendHighI32x4S), - Lang::I64x2ExtendLowI32x4U(_) => insn(Instruction::I64x2ExtendLowI32x4U), - Lang::I64x2ExtendHighI32x4U(_) => insn(Instruction::I64x2ExtendHighI32x4U), - Lang::I64x2Shl(_) => insn(Instruction::I64x2Shl), - Lang::I64x2ShrS(_) => insn(Instruction::I64x2ShrS), - Lang::I64x2ShrU(_) => insn(Instruction::I64x2ShrU), - Lang::I64x2Add(_) => insn(Instruction::I64x2Add), - Lang::I64x2Sub(_) => insn(Instruction::I64x2Sub), - Lang::I64x2Mul(_) => insn(Instruction::I64x2Mul), - Lang::I64x2ExtMulLowI32x4S(_) => insn(Instruction::I64x2ExtMulLowI32x4S), - Lang::I64x2ExtMulHighI32x4S(_) => insn(Instruction::I64x2ExtMulHighI32x4S), - Lang::I64x2ExtMulLowI32x4U(_) => insn(Instruction::I64x2ExtMulLowI32x4U), - Lang::I64x2ExtMulHighI32x4U(_) => insn(Instruction::I64x2ExtMulHighI32x4U), + Lang::I64x2Abs(_) => insn.i64x2_abs(), + Lang::I64x2Neg(_) => insn.i64x2_neg(), + Lang::I64x2AllTrue(_) => insn.i64x2_all_true(), + Lang::I64x2Bitmask(_) => insn.i64x2_bitmask(), + Lang::I64x2ExtendLowI32x4S(_) => insn.i64x2_extend_low_i32x4_s(), + Lang::I64x2ExtendHighI32x4S(_) => insn.i64x2_extend_high_i32x4_s(), + Lang::I64x2ExtendLowI32x4U(_) => insn.i64x2_extend_low_i32x4_u(), + Lang::I64x2ExtendHighI32x4U(_) => insn.i64x2_extend_high_i32x4_u(), + Lang::I64x2Shl(_) => insn.i64x2_shl(), + Lang::I64x2ShrS(_) => insn.i64x2_shr_s(), + Lang::I64x2ShrU(_) => insn.i64x2_shr_u(), + Lang::I64x2Add(_) => insn.i64x2_add(), + Lang::I64x2Sub(_) => insn.i64x2_sub(), + Lang::I64x2Mul(_) => insn.i64x2_mul(), + Lang::I64x2ExtMulLowI32x4S(_) => insn.i64x2_extmul_low_i32x4_s(), + Lang::I64x2ExtMulHighI32x4S(_) => insn.i64x2_extmul_high_i32x4_s(), + Lang::I64x2ExtMulLowI32x4U(_) => insn.i64x2_extmul_low_i32x4_u(), + Lang::I64x2ExtMulHighI32x4U(_) => insn.i64x2_extmul_high_i32x4_u(), - Lang::F32x4Ceil(_) => insn(Instruction::F32x4Ceil), - Lang::F32x4Floor(_) => insn(Instruction::F32x4Floor), - Lang::F32x4Trunc(_) => insn(Instruction::F32x4Trunc), - Lang::F32x4Nearest(_) => insn(Instruction::F32x4Nearest), - Lang::F32x4Abs(_) => insn(Instruction::F32x4Abs), - Lang::F32x4Neg(_) => insn(Instruction::F32x4Neg), - Lang::F32x4Sqrt(_) => insn(Instruction::F32x4Sqrt), - Lang::F32x4Add(_) => insn(Instruction::F32x4Add), - Lang::F32x4Sub(_) => insn(Instruction::F32x4Sub), - Lang::F32x4Mul(_) => insn(Instruction::F32x4Mul), - Lang::F32x4Div(_) => insn(Instruction::F32x4Div), - Lang::F32x4Min(_) => insn(Instruction::F32x4Min), - Lang::F32x4Max(_) => insn(Instruction::F32x4Max), - Lang::F32x4PMin(_) => insn(Instruction::F32x4PMin), - Lang::F32x4PMax(_) => insn(Instruction::F32x4PMax), - Lang::F64x2Ceil(_) => insn(Instruction::F64x2Ceil), - Lang::F64x2Floor(_) => insn(Instruction::F64x2Floor), - Lang::F64x2Trunc(_) => insn(Instruction::F64x2Trunc), - Lang::F64x2Nearest(_) => insn(Instruction::F64x2Nearest), - Lang::F64x2Abs(_) => insn(Instruction::F64x2Abs), - Lang::F64x2Neg(_) => insn(Instruction::F64x2Neg), - Lang::F64x2Sqrt(_) => insn(Instruction::F64x2Sqrt), - Lang::F64x2Add(_) => insn(Instruction::F64x2Add), - Lang::F64x2Sub(_) => insn(Instruction::F64x2Sub), - Lang::F64x2Mul(_) => insn(Instruction::F64x2Mul), - Lang::F64x2Div(_) => insn(Instruction::F64x2Div), - Lang::F64x2Min(_) => insn(Instruction::F64x2Min), - Lang::F64x2Max(_) => insn(Instruction::F64x2Max), - Lang::F64x2PMin(_) => insn(Instruction::F64x2PMin), - Lang::F64x2PMax(_) => insn(Instruction::F64x2PMax), + Lang::F32x4Ceil(_) => insn.f32x4_ceil(), + Lang::F32x4Floor(_) => insn.f32x4_floor(), + Lang::F32x4Trunc(_) => insn.f32x4_trunc(), + Lang::F32x4Nearest(_) => insn.f32x4_nearest(), + Lang::F32x4Abs(_) => insn.f32x4_abs(), + Lang::F32x4Neg(_) => insn.f32x4_neg(), + Lang::F32x4Sqrt(_) => insn.f32x4_sqrt(), + Lang::F32x4Add(_) => insn.f32x4_add(), + Lang::F32x4Sub(_) => insn.f32x4_sub(), + Lang::F32x4Mul(_) => insn.f32x4_mul(), + Lang::F32x4Div(_) => insn.f32x4_div(), + Lang::F32x4Min(_) => insn.f32x4_min(), + Lang::F32x4Max(_) => insn.f32x4_max(), + Lang::F32x4PMin(_) => insn.f32x4_pmin(), + Lang::F32x4PMax(_) => insn.f32x4_pmax(), + Lang::F64x2Ceil(_) => insn.f64x2_ceil(), + Lang::F64x2Floor(_) => insn.f64x2_floor(), + Lang::F64x2Trunc(_) => insn.f64x2_trunc(), + Lang::F64x2Nearest(_) => insn.f64x2_nearest(), + Lang::F64x2Abs(_) => insn.f64x2_abs(), + Lang::F64x2Neg(_) => insn.f64x2_neg(), + Lang::F64x2Sqrt(_) => insn.f64x2_sqrt(), + Lang::F64x2Add(_) => insn.f64x2_add(), + Lang::F64x2Sub(_) => insn.f64x2_sub(), + Lang::F64x2Mul(_) => insn.f64x2_mul(), + Lang::F64x2Div(_) => insn.f64x2_div(), + Lang::F64x2Min(_) => insn.f64x2_min(), + Lang::F64x2Max(_) => insn.f64x2_max(), + Lang::F64x2PMin(_) => insn.f64x2_pmin(), + Lang::F64x2PMax(_) => insn.f64x2_pmax(), - Lang::I32x4TruncSatF32x4S(_) => insn(Instruction::I32x4TruncSatF32x4S), - Lang::I32x4TruncSatF32x4U(_) => insn(Instruction::I32x4TruncSatF32x4U), - Lang::F32x4ConvertI32x4S(_) => insn(Instruction::F32x4ConvertI32x4S), - Lang::F32x4ConvertI32x4U(_) => insn(Instruction::F32x4ConvertI32x4U), - Lang::I32x4TruncSatF64x2SZero(_) => insn(Instruction::I32x4TruncSatF64x2SZero), - Lang::I32x4TruncSatF64x2UZero(_) => insn(Instruction::I32x4TruncSatF64x2UZero), - Lang::F64x2ConvertLowI32x4S(_) => insn(Instruction::F64x2ConvertLowI32x4S), - Lang::F64x2ConvertLowI32x4U(_) => insn(Instruction::F64x2ConvertLowI32x4U), - Lang::F32x4DemoteF64x2Zero(_) => insn(Instruction::F32x4DemoteF64x2Zero), - Lang::F64x2PromoteLowF32x4(_) => insn(Instruction::F64x2PromoteLowF32x4), + Lang::I32x4TruncSatF32x4S(_) => insn.i32x4_trunc_sat_f32x4_s(), + Lang::I32x4TruncSatF32x4U(_) => insn.i32x4_trunc_sat_f32x4_u(), + Lang::F32x4ConvertI32x4S(_) => insn.f32x4_convert_i32x4_s(), + Lang::F32x4ConvertI32x4U(_) => insn.f32x4_convert_i32x4_u(), + Lang::I32x4TruncSatF64x2SZero(_) => insn.i32x4_trunc_sat_f64x2_s_zero(), + Lang::I32x4TruncSatF64x2UZero(_) => insn.i32x4_trunc_sat_f64x2_u_zero(), + Lang::F64x2ConvertLowI32x4S(_) => insn.f64x2_convert_low_i32x4_s(), + Lang::F64x2ConvertLowI32x4U(_) => insn.f64x2_convert_low_i32x4_u(), + Lang::F32x4DemoteF64x2Zero(_) => insn.f32x4_demote_f64x2_zero(), + Lang::F64x2PromoteLowF32x4(_) => insn.f64x2_promote_low_f32x4(), - Lang::I8x16RelaxedSwizzle(_) => insn(Instruction::I8x16RelaxedSwizzle), - Lang::I32x4RelaxedTruncF32x4S(_) => insn(Instruction::I32x4RelaxedTruncF32x4S), - Lang::I32x4RelaxedTruncF32x4U(_) => insn(Instruction::I32x4RelaxedTruncF32x4U), - Lang::I32x4RelaxedTruncF64x2SZero(_) => { - insn(Instruction::I32x4RelaxedTruncF64x2SZero) - } - Lang::I32x4RelaxedTruncF64x2UZero(_) => { - insn(Instruction::I32x4RelaxedTruncF64x2UZero) - } - Lang::F32x4RelaxedMadd(_) => insn(Instruction::F32x4RelaxedMadd), - Lang::F32x4RelaxedNmadd(_) => insn(Instruction::F32x4RelaxedNmadd), - Lang::F64x2RelaxedMadd(_) => insn(Instruction::F64x2RelaxedMadd), - Lang::F64x2RelaxedNmadd(_) => insn(Instruction::F64x2RelaxedNmadd), - Lang::I8x16RelaxedLaneselect(_) => insn(Instruction::I8x16RelaxedLaneselect), - Lang::I16x8RelaxedLaneselect(_) => insn(Instruction::I16x8RelaxedLaneselect), - Lang::I32x4RelaxedLaneselect(_) => insn(Instruction::I32x4RelaxedLaneselect), - Lang::I64x2RelaxedLaneselect(_) => insn(Instruction::I64x2RelaxedLaneselect), - Lang::F32x4RelaxedMin(_) => insn(Instruction::F32x4RelaxedMin), - Lang::F32x4RelaxedMax(_) => insn(Instruction::F32x4RelaxedMax), - Lang::F64x2RelaxedMin(_) => insn(Instruction::F64x2RelaxedMin), - Lang::F64x2RelaxedMax(_) => insn(Instruction::F64x2RelaxedMax), - Lang::I16x8RelaxedQ15mulrS(_) => insn(Instruction::I16x8RelaxedQ15mulrS), - Lang::I16x8RelaxedDotI8x16I7x16S(_) => { - insn(Instruction::I16x8RelaxedDotI8x16I7x16S) - } + Lang::I8x16RelaxedSwizzle(_) => insn.i8x16_relaxed_swizzle(), + Lang::I32x4RelaxedTruncF32x4S(_) => insn.i32x4_relaxed_trunc_f32x4_s(), + Lang::I32x4RelaxedTruncF32x4U(_) => insn.i32x4_relaxed_trunc_f32x4_u(), + Lang::I32x4RelaxedTruncF64x2SZero(_) => insn.i32x4_relaxed_trunc_f64x2_s_zero(), + Lang::I32x4RelaxedTruncF64x2UZero(_) => insn.i32x4_relaxed_trunc_f64x2_u_zero(), + Lang::F32x4RelaxedMadd(_) => insn.f32x4_relaxed_madd(), + Lang::F32x4RelaxedNmadd(_) => insn.f32x4_relaxed_nmadd(), + Lang::F64x2RelaxedMadd(_) => insn.f64x2_relaxed_madd(), + Lang::F64x2RelaxedNmadd(_) => insn.f64x2_relaxed_nmadd(), + Lang::I8x16RelaxedLaneselect(_) => insn.i8x16_relaxed_laneselect(), + Lang::I16x8RelaxedLaneselect(_) => insn.i16x8_relaxed_laneselect(), + Lang::I32x4RelaxedLaneselect(_) => insn.i32x4_relaxed_laneselect(), + Lang::I64x2RelaxedLaneselect(_) => insn.i64x2_relaxed_laneselect(), + Lang::F32x4RelaxedMin(_) => insn.f32x4_relaxed_min(), + Lang::F32x4RelaxedMax(_) => insn.f32x4_relaxed_max(), + Lang::F64x2RelaxedMin(_) => insn.f64x2_relaxed_min(), + Lang::F64x2RelaxedMax(_) => insn.f64x2_relaxed_max(), + Lang::I16x8RelaxedQ15mulrS(_) => insn.i16x8_relaxed_q15mulr_s(), + Lang::I16x8RelaxedDotI8x16I7x16S(_) => insn.i16x8_relaxed_dot_i8x16_i7x16_s(), Lang::I32x4RelaxedDotI8x16I7x16AddS(_) => { - insn(Instruction::I32x4RelaxedDotI8x16I7x16AddS) + insn.i32x4_relaxed_dot_i8x16_i7x16_add_s() } - } + }; } } } diff --git a/crates/wasm-mutate/src/mutators/peephole/eggsy/lang.rs b/crates/wasm-mutate/src/mutators/peephole/eggsy/lang.rs index 34b659140e..f621bcc344 100644 --- a/crates/wasm-mutate/src/mutators/peephole/eggsy/lang.rs +++ b/crates/wasm-mutate/src/mutators/peephole/eggsy/lang.rs @@ -256,9 +256,10 @@ lang! { /// the `expr2wasm` function somehow as follow /// ```ignore /// Lang::ThreeNops => { - /// newfunc.instruction(&Instruction::Nop); - /// newfunc.instruction(&Instruction::Nop); - /// newfunc.instruction(&Instruction::Nop); + /// newfunc.instructions() + /// .nop() + /// .nop() + /// .nop(); /// } /// ``` /// * The final step is to use this node in a rewriting rule. Inside the diff --git a/crates/wasm-mutate/src/mutators/snip_function.rs b/crates/wasm-mutate/src/mutators/snip_function.rs index 00f86e9264..3f462adacf 100644 --- a/crates/wasm-mutate/src/mutators/snip_function.rs +++ b/crates/wasm-mutate/src/mutators/snip_function.rs @@ -4,7 +4,7 @@ use super::Mutator; use crate::module::{PrimitiveTypeInfo, TypeInfo}; use crate::{Result, WasmMutate}; use rand::Rng; -use wasm_encoder::{CodeSection, Function, HeapType, Instruction, Module}; +use wasm_encoder::{CodeSection, Function, HeapType, Module}; use wasmparser::CodeSectionReader; /// Mutator that replaces the body of a function with an empty body @@ -46,25 +46,25 @@ impl Mutator for SnipMutator { for primitive in t.returns.iter() { match primitive { PrimitiveTypeInfo::I32 => { - f.instruction(&Instruction::I32Const(0)); + f.instructions().i32_const(0); } PrimitiveTypeInfo::I64 => { - f.instruction(&Instruction::I64Const(0)); + f.instructions().i64_const(0); } PrimitiveTypeInfo::F32 => { - f.instruction(&Instruction::F32Const(0.0)); + f.instructions().f32_const(0.0); } PrimitiveTypeInfo::F64 => { - f.instruction(&Instruction::F64Const(0.0)); + f.instructions().f64_const(0.0); } PrimitiveTypeInfo::V128 => { - f.instruction(&Instruction::V128Const(0)); + f.instructions().v128_const(0); } PrimitiveTypeInfo::FuncRef => { - f.instruction(&Instruction::RefNull(HeapType::FUNC)); + f.instructions().ref_null(HeapType::FUNC); } PrimitiveTypeInfo::ExternRef => { - f.instruction(&Instruction::RefNull(HeapType::EXTERN)); + f.instructions().ref_null(HeapType::EXTERN); } PrimitiveTypeInfo::Empty => { unreachable!() @@ -74,7 +74,7 @@ impl Mutator for SnipMutator { } } - f.instruction(&Instruction::End); + f.instructions().end(); codes.function(&f); } diff --git a/crates/wasm-smith/src/core/encode.rs b/crates/wasm-smith/src/core/encode.rs index dd91372807..9ee31b088a 100644 --- a/crates/wasm-smith/src/core/encode.rs +++ b/crates/wasm-smith/src/core/encode.rs @@ -218,7 +218,7 @@ impl Module { for instr in instrs { func.instruction(instr); } - func.instruction(&wasm_encoder::Instruction::End); + func.instructions().end(); } Instructions::Arbitrary(body) => { func.raw(body.iter().copied()); diff --git a/crates/wasmparser/tests/big-module.rs b/crates/wasmparser/tests/big-module.rs index d6b0aece3a..04a950a6d9 100644 --- a/crates/wasmparser/tests/big-module.rs +++ b/crates/wasmparser/tests/big-module.rs @@ -20,9 +20,9 @@ fn big_type_indices() { let mut code = CodeSection::new(); let mut body = Function::new([]); - body.instruction(&Instruction::RefFunc(0)); - body.instruction(&Instruction::Drop); - body.instruction(&Instruction::End); + body.instructions().ref_func(FuncIdx(0)); + body.instructions().drop(); + body.instructions().end(); code.function(&body); module.section(&code); diff --git a/crates/wast/src/core/binary.rs b/crates/wast/src/core/binary.rs index 726691bb7f..2a9109b43f 100644 --- a/crates/wast/src/core/binary.rs +++ b/crates/wast/src/core/binary.rs @@ -795,7 +795,7 @@ impl Expression<'_> { instr.encode(&mut tmp); } func.raw(tmp.iter().copied()); - func.instruction(&wasm_encoder::Instruction::End); + func.instructions().end(); hints } diff --git a/crates/wit-component/src/encoding.rs b/crates/wit-component/src/encoding.rs index 75852bc18f..30b4a6ef7d 100644 --- a/crates/wit-component/src/encoding.rs +++ b/crates/wit-component/src/encoding.rs @@ -1183,14 +1183,12 @@ impl<'a> EncodingState<'a> { ) { let mut func = wasm_encoder::Function::new(std::iter::empty()); for i in 0..param_count { - func.instruction(&Instruction::LocalGet(i)); + func.instructions().local_get(LocalIdx(i)); } - func.instruction(&Instruction::I32Const(func_index as i32)); - func.instruction(&Instruction::CallIndirect { - type_index, - table_index: 0, - }); - func.instruction(&Instruction::End); + func.instructions().i32_const(func_index as i32); + func.instructions() + .call_indirect(TableIdx(0), TypeIdx(type_index)); + func.instructions().end(); code.function(&func); } diff --git a/crates/wit-component/src/gc.rs b/crates/wit-component/src/gc.rs index 55d3be513b..5b1aa38c1b 100644 --- a/crates/wit-component/src/gc.rs +++ b/crates/wit-component/src/gc.rs @@ -8,8 +8,9 @@ use std::{ mem, ops::Deref, }; -use wasm_encoder::reencode::Reencode; -use wasm_encoder::{Encode, EntityType, Instruction, RawCustomSection}; +use wasm_encoder::{ + reencode::Reencode, Encode, EntityType, FuncIdx, GlobalIdx, LocalIdx, MemIdx, RawCustomSection, +}; use wasmparser::*; const PAGE_SIZE: i32 = 64 * 1024; @@ -53,51 +54,49 @@ pub fn run( /// This function generates a Wasm function body which implements `cabi_realloc` in terms of `memory.grow`. It /// only accepts new, page-sized allocations. fn realloc_via_memory_grow() -> wasm_encoder::Function { - use wasm_encoder::Instruction::*; - let mut func = wasm_encoder::Function::new([(1, wasm_encoder::ValType::I32)]); // Assert `old_ptr` is null. - func.instruction(&I32Const(0)); - func.instruction(&LocalGet(0)); - func.instruction(&I32Ne); - func.instruction(&If(wasm_encoder::BlockType::Empty)); - func.instruction(&Unreachable); - func.instruction(&End); + func.instructions().i32_const(0); + func.instructions().local_get(LocalIdx(0)); + func.instructions().i32_ne(); + func.instructions().if_(wasm_encoder::BlockType::Empty); + func.instructions().unreachable(); + func.instructions().end(); // Assert `old_len` is zero. - func.instruction(&I32Const(0)); - func.instruction(&LocalGet(1)); - func.instruction(&I32Ne); - func.instruction(&If(wasm_encoder::BlockType::Empty)); - func.instruction(&Unreachable); - func.instruction(&End); + func.instructions().i32_const(0); + func.instructions().local_get(LocalIdx(1)); + func.instructions().i32_ne(); + func.instructions().if_(wasm_encoder::BlockType::Empty); + func.instructions().unreachable(); + func.instructions().end(); // Assert `new_len` is equal to the page size (which is the only value we currently support) // Note: we could easily support arbitrary multiples of PAGE_SIZE here if the need arises. - func.instruction(&I32Const(PAGE_SIZE)); - func.instruction(&LocalGet(3)); - func.instruction(&I32Ne); - func.instruction(&If(wasm_encoder::BlockType::Empty)); - func.instruction(&Unreachable); - func.instruction(&End); + func.instructions().i32_const(PAGE_SIZE); + func.instructions().local_get(LocalIdx(3)); + func.instructions().i32_ne(); + func.instructions().if_(wasm_encoder::BlockType::Empty); + func.instructions().unreachable(); + func.instructions().end(); // Grow the memory by 1 page. - func.instruction(&I32Const(1)); - func.instruction(&MemoryGrow(0)); - func.instruction(&LocalTee(4)); + func.instructions().i32_const(1); + func.instructions().memory_grow(MemIdx(0)); + func.instructions().local_tee(LocalIdx(4)); // Test if the return value of the growth was -1 and, if so, trap due to a failed allocation. - func.instruction(&I32Const(-1)); - func.instruction(&I32Eq); - func.instruction(&If(wasm_encoder::BlockType::Empty)); - func.instruction(&Unreachable); - func.instruction(&End); + func.instructions().i32_const(-1); + func.instructions().i32_eq(); + func.instructions().if_(wasm_encoder::BlockType::Empty); + func.instructions().unreachable(); + func.instructions().end(); - func.instruction(&LocalGet(4)); - func.instruction(&I32Const(16)); - func.instruction(&I32Shl); - func.instruction(&End); + func.instructions().local_get(LocalIdx(4)); + func.instructions().i32_const(16); + func.instructions().i32_shl(); + func.instructions().end(); func } @@ -111,42 +110,43 @@ enum StackAllocationState { } fn allocate_stack_via_realloc( - realloc_index: u32, - sp: u32, - allocation_state: Option, + realloc_index: FuncIdx, + sp: GlobalIdx, + allocation_state: Option, ) -> wasm_encoder::Function { - use wasm_encoder::Instruction::*; - let mut func = wasm_encoder::Function::new([]); if let Some(allocation_state) = allocation_state { // This means we're lazily allocating the stack, keeping track of state via `$allocation_state` - func.instruction(&GlobalGet(allocation_state)); - func.instruction(&I32Const(StackAllocationState::Unallocated as _)); - func.instruction(&I32Eq); - func.instruction(&If(wasm_encoder::BlockType::Empty)); - func.instruction(&I32Const(StackAllocationState::Allocating as _)); - func.instruction(&GlobalSet(allocation_state)); + func.instructions().global_get(allocation_state); + func.instructions() + .i32_const(StackAllocationState::Unallocated as _); + func.instructions().i32_eq(); + func.instructions().if_(wasm_encoder::BlockType::Empty); + func.instructions() + .i32_const(StackAllocationState::Allocating as _); + func.instructions().global_set(allocation_state); // We could also set `sp` to zero here to ensure the yet-to-be-allocated stack is empty. However, we // assume it defaults to zero anyway, in which case setting it would be redundant. } - func.instruction(&I32Const(0)); - func.instruction(&I32Const(0)); - func.instruction(&I32Const(8)); - func.instruction(&I32Const(PAGE_SIZE)); - func.instruction(&Call(realloc_index)); - func.instruction(&I32Const(PAGE_SIZE)); - func.instruction(&I32Add); - func.instruction(&GlobalSet(sp)); + func.instructions().i32_const(0); + func.instructions().i32_const(0); + func.instructions().i32_const(8); + func.instructions().i32_const(PAGE_SIZE); + func.instructions().call(realloc_index); + func.instructions().i32_const(PAGE_SIZE); + func.instructions().i32_add(); + func.instructions().global_set(sp); if let Some(allocation_state) = allocation_state { - func.instruction(&I32Const(StackAllocationState::Allocated as _)); - func.instruction(&GlobalSet(allocation_state)); - func.instruction(&End); + func.instructions() + .i32_const(StackAllocationState::Allocated as _); + func.instructions().global_set(allocation_state); + func.instructions().end(); } - func.instruction(&End); + func.instructions().end(); func } @@ -596,7 +596,7 @@ impl<'a> Module<'a> { // The adapter is importing `cabi_realloc` from the main module, and the main module // exports that function, but possibly using a different name // (e.g. `canonical_abi_realloc`). Update the name to match if necessary. - realloc_index = Some(num_func_imports); + realloc_index = Some(FuncIdx(num_func_imports)); main_module_realloc.unwrap_or(n) } else { n @@ -628,8 +628,8 @@ impl<'a> Module<'a> { type_index }; - let sp = self.find_mut_i32_global("__stack_pointer")?; - let allocation_state = self.find_mut_i32_global("allocation_state")?; + let sp = self.find_mut_i32_global("__stack_pointer")?.map(GlobalIdx); + let allocation_state = self.find_mut_i32_global("allocation_state")?.map(GlobalIdx); let mut func_names = Vec::new(); @@ -640,7 +640,7 @@ impl<'a> Module<'a> { // Tell the function remapper we're reserving a slot for our extra import: map.funcs.next += 1; - realloc_index = Some(num_func_imports); + realloc_index = Some(FuncIdx(num_func_imports)); imports.import( "__main_module__", realloc, @@ -657,7 +657,7 @@ impl<'a> Module<'a> { Definition::Import(_, _) => { // The adapter is importing `cabi_realloc` from the main module, but the main module isn't // exporting it. In this case, we need to define a local function it can call instead. - realloc_index = Some(num_func_imports + funcs.len()); + realloc_index = Some(FuncIdx(num_func_imports + funcs.len())); funcs.function(ty); code.function(&realloc_via_memory_grow()); } @@ -672,7 +672,7 @@ impl<'a> Module<'a> { // We have a stack pointer, a `cabi_realloc` function from the main module, and a global variable for // keeping track of (and short-circuiting) reentrance. That means we can (and should) do lazy stack // allocation. - let index = num_func_imports + funcs.len(); + let index = FuncIdx(num_func_imports + funcs.len()); // Tell the function remapper we're reserving a slot for our extra function: map.funcs.next += 1; @@ -704,7 +704,7 @@ impl<'a> Module<'a> { // lazily allocating the stack. (Some(lazy_stack_init_index), true) => { let mut func = map.new_function_with_parsed_locals(&body)?; - func.instruction(&Instruction::Call(lazy_stack_init_index)); + func.instructions().call(lazy_stack_init_index); let mut reader = body.get_operators_reader()?; while !reader.eof() { func.instruction(&map.parse_instruction(&mut reader)?); @@ -728,7 +728,7 @@ impl<'a> Module<'a> { if sp.is_some() && (realloc_index.is_none() || allocation_state.is_none()) { // Either the main module does _not_ export a realloc function, or it is not safe to use for stack // allocation because we have no way to short-circuit reentrance, so we'll use `memory.grow` instead. - realloc_index = Some(num_func_imports + funcs.len()); + realloc_index = Some(FuncIdx(num_func_imports + funcs.len())); funcs.function(add_realloc_type(&mut types)); code.function(&realloc_via_memory_grow()); } @@ -746,7 +746,7 @@ impl<'a> Module<'a> { bail!("adapter modules don't support multi-memory"); } - let sp = map.globals.remap(sp); + let sp = GlobalIdx(map.globals.remap(sp.0)); let function_index = num_func_imports + funcs.len(); @@ -877,10 +877,10 @@ impl<'a> Module<'a> { realloc_index, main_module_realloc.is_none() || allocation_state.is_none(), ) { - func_names.push((realloc_index, "realloc_via_memory_grow")); + func_names.push((realloc_index.0, "realloc_via_memory_grow")); } if let Some(lazy_stack_init_index) = lazy_stack_init_index { - func_names.push((lazy_stack_init_index, "allocate_stack")); + func_names.push((lazy_stack_init_index.0, "allocate_stack")); } encode_subsection(0x01, &func_names); encode_subsection(0x07, &global_names); From 6492d908a8c1fce9c86e619a2932f895a2732f87 Mon Sep 17 00:00:00 2001 From: Sam Estep Date: Tue, 11 Feb 2025 21:19:15 -0500 Subject: [PATCH 3/4] Remove the typed indices --- crates/wasm-encoder/README.md | 6 +- crates/wasm-encoder/src/core/code.rs | 374 +++++------------- crates/wasm-encoder/src/core/instructions.rs | 341 ++++++---------- crates/wasm-encoder/src/lib.rs | 6 +- .../src/mutators/codemotion/loop_unrolling.rs | 4 +- .../peephole/eggsy/encoder/expr2wasm.rs | 58 ++- crates/wasmparser/tests/big-module.rs | 2 +- crates/wit-component/src/encoding.rs | 5 +- crates/wit-component/src/gc.rs | 42 +- 9 files changed, 289 insertions(+), 549 deletions(-) diff --git a/crates/wasm-encoder/README.md b/crates/wasm-encoder/README.md index 473af42423..1c709baa28 100644 --- a/crates/wasm-encoder/README.md +++ b/crates/wasm-encoder/README.md @@ -26,7 +26,7 @@ And then you can encode WebAssembly binaries via: ```rust use wasm_encoder::{ - CodeSection, ExportKind, ExportSection, Function, FunctionSection, LocalIdx, + CodeSection, ExportKind, ExportSection, Function, FunctionSection, Module, TypeSection, ValType, }; @@ -55,8 +55,8 @@ let mut codes = CodeSection::new(); let locals = vec![]; let mut f = Function::new(locals); f.instructions() - .local_get(LocalIdx(0)) - .local_get(LocalIdx(1)) + .local_get(0) + .local_get(1) .i32_add() .end(); codes.function(&f); diff --git a/crates/wasm-encoder/src/core/code.rs b/crates/wasm-encoder/src/core/code.rs index 17817b1973..d6038ff40e 100644 --- a/crates/wasm-encoder/src/core/code.rs +++ b/crates/wasm-encoder/src/core/code.rs @@ -126,7 +126,7 @@ impl Section for CodeSection { /// # Example /// /// ``` -/// use wasm_encoder::{CodeSection, Function, LocalIdx}; +/// use wasm_encoder::{CodeSection, Function}; /// /// // Define the function body for: /// // @@ -137,8 +137,8 @@ impl Section for CodeSection { /// let locals = vec![]; /// let mut func = Function::new(locals); /// func.instructions() -/// .local_get(LocalIdx(0)) -/// .local_get(LocalIdx(1)) +/// .local_get(0) +/// .local_get(1) /// .i32_add(); /// /// // Add our function to the code section. @@ -294,116 +294,6 @@ impl Encode for Function { } } -/// A Wasm _typeidx_. -#[derive(Clone, Copy, Debug)] -pub struct TypeIdx(pub u32); - -/// A Wasm _funcidx_. -#[derive(Clone, Copy, Debug)] -pub struct FuncIdx(pub u32); - -/// A Wasm _tableidx_. -#[derive(Clone, Copy, Debug)] -pub struct TableIdx(pub u32); - -/// A Wasm _memidx_. -#[derive(Clone, Copy, Debug)] -pub struct MemIdx(pub u32); - -/// A Wasm _tagidx_. -#[derive(Clone, Copy, Debug)] -pub struct TagIdx(pub u32); - -/// A Wasm _globalidx_. -#[derive(Clone, Copy, Debug)] -pub struct GlobalIdx(pub u32); - -/// A Wasm _elemidx_. -#[derive(Clone, Copy, Debug)] -pub struct ElemIdx(pub u32); - -/// A Wasm _dataidx_. -#[derive(Clone, Copy, Debug)] -pub struct DataIdx(pub u32); - -/// A Wasm _localidx_. -#[derive(Clone, Copy, Debug)] -pub struct LocalIdx(pub u32); - -/// A Wasm _labelidx_. -#[derive(Clone, Copy, Debug)] -pub struct LabelIdx(pub u32); - -/// A Wasm _fieldidx_. -#[derive(Clone, Copy, Debug)] -pub struct FieldIdx(pub u32); - -impl Encode for TypeIdx { - fn encode(&self, sink: &mut Vec) { - self.0.encode(sink); - } -} - -impl Encode for FuncIdx { - fn encode(&self, sink: &mut Vec) { - self.0.encode(sink); - } -} - -impl Encode for TableIdx { - fn encode(&self, sink: &mut Vec) { - self.0.encode(sink); - } -} - -impl Encode for MemIdx { - fn encode(&self, sink: &mut Vec) { - self.0.encode(sink); - } -} - -impl Encode for TagIdx { - fn encode(&self, sink: &mut Vec) { - self.0.encode(sink); - } -} - -impl Encode for GlobalIdx { - fn encode(&self, sink: &mut Vec) { - self.0.encode(sink); - } -} - -impl Encode for ElemIdx { - fn encode(&self, sink: &mut Vec) { - self.0.encode(sink); - } -} - -impl Encode for DataIdx { - fn encode(&self, sink: &mut Vec) { - self.0.encode(sink); - } -} - -impl Encode for LocalIdx { - fn encode(&self, sink: &mut Vec) { - self.0.encode(sink); - } -} - -impl Encode for LabelIdx { - fn encode(&self, sink: &mut Vec) { - self.0.encode(sink); - } -} - -impl Encode for FieldIdx { - fn encode(&self, sink: &mut Vec) { - self.0.encode(sink); - } -} - /// The immediate for a memory instruction. #[derive(Clone, Copy, Debug)] pub struct MemArg { @@ -1363,33 +1253,31 @@ impl Encode for Instruction<'_> { Instruction::If(bt) => sink.if_(bt), Instruction::Else => sink.else_(), Instruction::Try(bt) => sink.try_(bt), - Instruction::Catch(t) => sink.catch(TagIdx(t)), - Instruction::Throw(t) => sink.throw(TagIdx(t)), - Instruction::Rethrow(l) => sink.rethrow(LabelIdx(l)), + Instruction::Catch(t) => sink.catch(t), + Instruction::Throw(t) => sink.throw(t), + Instruction::Rethrow(l) => sink.rethrow(l), Instruction::ThrowRef => sink.throw_ref(), Instruction::End => sink.end(), - Instruction::Br(l) => sink.br(LabelIdx(l)), - Instruction::BrIf(l) => sink.br_if(LabelIdx(l)), - Instruction::BrTable(ref ls, l) => { - sink.br_table(ls.iter().copied().map(LabelIdx), LabelIdx(l)) - } - Instruction::BrOnNull(l) => sink.br_on_null(LabelIdx(l)), - Instruction::BrOnNonNull(l) => sink.br_on_non_null(LabelIdx(l)), + Instruction::Br(l) => sink.br(l), + Instruction::BrIf(l) => sink.br_if(l), + Instruction::BrTable(ref ls, l) => sink.br_table(ls.iter().copied(), l), + Instruction::BrOnNull(l) => sink.br_on_null(l), + Instruction::BrOnNonNull(l) => sink.br_on_non_null(l), Instruction::Return => sink.return_(), - Instruction::Call(f) => sink.call(FuncIdx(f)), - Instruction::CallRef(ty) => sink.call_ref(TypeIdx(ty)), + Instruction::Call(f) => sink.call(f), + Instruction::CallRef(ty) => sink.call_ref(ty), Instruction::CallIndirect { type_index, table_index, - } => sink.call_indirect(TableIdx(table_index), TypeIdx(type_index)), - Instruction::ReturnCallRef(ty) => sink.return_call_ref(TypeIdx(ty)), + } => sink.call_indirect(table_index, type_index), + Instruction::ReturnCallRef(ty) => sink.return_call_ref(ty), - Instruction::ReturnCall(f) => sink.return_call(FuncIdx(f)), + Instruction::ReturnCall(f) => sink.return_call(f), Instruction::ReturnCallIndirect { type_index, table_index, - } => sink.return_call_indirect(TableIdx(table_index), TypeIdx(type_index)), - Instruction::Delegate(l) => sink.delegate(LabelIdx(l)), + } => sink.return_call_indirect(table_index, type_index), + Instruction::Delegate(l) => sink.delegate(l), Instruction::CatchAll => sink.catch_all(), // Parametric instructions. @@ -1400,13 +1288,13 @@ impl Encode for Instruction<'_> { Instruction::TryTable(ty, ref catches) => sink.try_table(ty, catches.iter().cloned()), // Variable instructions. - Instruction::LocalGet(l) => sink.local_get(LocalIdx(l)), - Instruction::LocalSet(l) => sink.local_set(LocalIdx(l)), - Instruction::LocalTee(l) => sink.local_tee(LocalIdx(l)), - Instruction::GlobalGet(g) => sink.global_get(GlobalIdx(g)), - Instruction::GlobalSet(g) => sink.global_set(GlobalIdx(g)), - Instruction::TableGet(table) => sink.table_get(TableIdx(table)), - Instruction::TableSet(table) => sink.table_set(TableIdx(table)), + Instruction::LocalGet(l) => sink.local_get(l), + Instruction::LocalSet(l) => sink.local_set(l), + Instruction::LocalTee(l) => sink.local_tee(l), + Instruction::GlobalGet(g) => sink.global_get(g), + Instruction::GlobalSet(g) => sink.global_set(g), + Instruction::TableGet(table) => sink.table_get(table), + Instruction::TableSet(table) => sink.table_set(table), // Memory instructions. Instruction::I32Load(m) => sink.i32_load(m), @@ -1432,17 +1320,13 @@ impl Encode for Instruction<'_> { Instruction::I64Store8(m) => sink.i64_store8(m), Instruction::I64Store16(m) => sink.i64_store16(m), Instruction::I64Store32(m) => sink.i64_store32(m), - Instruction::MemorySize(i) => sink.memory_size(MemIdx(i)), - Instruction::MemoryGrow(i) => sink.memory_grow(MemIdx(i)), - Instruction::MemoryInit { mem, data_index } => { - sink.memory_init(MemIdx(mem), DataIdx(data_index)) - } - Instruction::DataDrop(data) => sink.data_drop(DataIdx(data)), - Instruction::MemoryCopy { src_mem, dst_mem } => { - sink.memory_copy(MemIdx(dst_mem), MemIdx(src_mem)) - } - Instruction::MemoryFill(mem) => sink.memory_fill(MemIdx(mem)), - Instruction::MemoryDiscard(mem) => sink.memory_discard(MemIdx(mem)), + Instruction::MemorySize(i) => sink.memory_size(i), + Instruction::MemoryGrow(i) => sink.memory_grow(i), + Instruction::MemoryInit { mem, data_index } => sink.memory_init(mem, data_index), + Instruction::DataDrop(data) => sink.data_drop(data), + Instruction::MemoryCopy { src_mem, dst_mem } => sink.memory_copy(dst_mem, src_mem), + Instruction::MemoryFill(mem) => sink.memory_fill(mem), + Instruction::MemoryDiscard(mem) => sink.memory_discard(mem), // Numeric instructions. Instruction::I32Const(x) => sink.i32_const(x), @@ -1590,63 +1474,61 @@ impl Encode for Instruction<'_> { // Reference types instructions. Instruction::RefNull(ty) => sink.ref_null(ty), Instruction::RefIsNull => sink.ref_is_null(), - Instruction::RefFunc(f) => sink.ref_func(FuncIdx(f)), + Instruction::RefFunc(f) => sink.ref_func(f), Instruction::RefEq => sink.ref_eq(), Instruction::RefAsNonNull => sink.ref_as_non_null(), // GC instructions. - Instruction::StructNew(type_index) => sink.struct_new(TypeIdx(type_index)), - Instruction::StructNewDefault(type_index) => { - sink.struct_new_default(TypeIdx(type_index)) - } + Instruction::StructNew(type_index) => sink.struct_new(type_index), + Instruction::StructNewDefault(type_index) => sink.struct_new_default(type_index), Instruction::StructGet { struct_type_index, field_index, - } => sink.struct_get(TypeIdx(struct_type_index), FieldIdx(field_index)), + } => sink.struct_get(struct_type_index, field_index), Instruction::StructGetS { struct_type_index, field_index, - } => sink.struct_get_s(TypeIdx(struct_type_index), FieldIdx(field_index)), + } => sink.struct_get_s(struct_type_index, field_index), Instruction::StructGetU { struct_type_index, field_index, - } => sink.struct_get_u(TypeIdx(struct_type_index), FieldIdx(field_index)), + } => sink.struct_get_u(struct_type_index, field_index), Instruction::StructSet { struct_type_index, field_index, - } => sink.struct_set(TypeIdx(struct_type_index), FieldIdx(field_index)), - Instruction::ArrayNew(type_index) => sink.array_new(TypeIdx(type_index)), - Instruction::ArrayNewDefault(type_index) => sink.array_new_default(TypeIdx(type_index)), + } => sink.struct_set(struct_type_index, field_index), + Instruction::ArrayNew(type_index) => sink.array_new(type_index), + Instruction::ArrayNewDefault(type_index) => sink.array_new_default(type_index), Instruction::ArrayNewFixed { array_type_index, array_size, - } => sink.array_new_fixed(TypeIdx(array_type_index), array_size), + } => sink.array_new_fixed(array_type_index, array_size), Instruction::ArrayNewData { array_type_index, array_data_index, - } => sink.array_new_data(TypeIdx(array_type_index), DataIdx(array_data_index)), + } => sink.array_new_data(array_type_index, array_data_index), Instruction::ArrayNewElem { array_type_index, array_elem_index, - } => sink.array_new_elem(TypeIdx(array_type_index), ElemIdx(array_elem_index)), - Instruction::ArrayGet(type_index) => sink.array_get(TypeIdx(type_index)), - Instruction::ArrayGetS(type_index) => sink.array_get_s(TypeIdx(type_index)), - Instruction::ArrayGetU(type_index) => sink.array_get_u(TypeIdx(type_index)), - Instruction::ArraySet(type_index) => sink.array_set(TypeIdx(type_index)), + } => sink.array_new_elem(array_type_index, array_elem_index), + Instruction::ArrayGet(type_index) => sink.array_get(type_index), + Instruction::ArrayGetS(type_index) => sink.array_get_s(type_index), + Instruction::ArrayGetU(type_index) => sink.array_get_u(type_index), + Instruction::ArraySet(type_index) => sink.array_set(type_index), Instruction::ArrayLen => sink.array_len(), - Instruction::ArrayFill(type_index) => sink.array_fill(TypeIdx(type_index)), + Instruction::ArrayFill(type_index) => sink.array_fill(type_index), Instruction::ArrayCopy { array_type_index_dst, array_type_index_src, - } => sink.array_copy(TypeIdx(array_type_index_dst), TypeIdx(array_type_index_src)), + } => sink.array_copy(array_type_index_dst, array_type_index_src), Instruction::ArrayInitData { array_type_index, array_data_index, - } => sink.array_init_data(TypeIdx(array_type_index), DataIdx(array_data_index)), + } => sink.array_init_data(array_type_index, array_data_index), Instruction::ArrayInitElem { array_type_index, array_elem_index, - } => sink.array_init_elem(TypeIdx(array_type_index), ElemIdx(array_elem_index)), + } => sink.array_init_elem(array_type_index, array_elem_index), Instruction::RefTestNonNull(heap_type) => sink.ref_test_non_null(heap_type), Instruction::RefTestNullable(heap_type) => sink.ref_test_nullable(heap_type), Instruction::RefCastNonNull(heap_type) => sink.ref_cast_non_null(heap_type), @@ -1655,12 +1537,12 @@ impl Encode for Instruction<'_> { relative_depth, from_ref_type, to_ref_type, - } => sink.br_on_cast(LabelIdx(relative_depth), from_ref_type, to_ref_type), + } => sink.br_on_cast(relative_depth, from_ref_type, to_ref_type), Instruction::BrOnCastFail { relative_depth, from_ref_type, to_ref_type, - } => sink.br_on_cast_fail(LabelIdx(relative_depth), from_ref_type, to_ref_type), + } => sink.br_on_cast_fail(relative_depth, from_ref_type, to_ref_type), Instruction::AnyConvertExtern => sink.any_convert_extern(), Instruction::ExternConvertAny => sink.extern_convert_any(), Instruction::RefI31 => sink.ref_i31(), @@ -1668,17 +1550,15 @@ impl Encode for Instruction<'_> { Instruction::I31GetU => sink.i31_get_u(), // Bulk memory instructions. - Instruction::TableInit { elem_index, table } => { - sink.table_init(TableIdx(table), ElemIdx(elem_index)) - } - Instruction::ElemDrop(segment) => sink.elem_drop(ElemIdx(segment)), + Instruction::TableInit { elem_index, table } => sink.table_init(table, elem_index), + Instruction::ElemDrop(segment) => sink.elem_drop(segment), Instruction::TableCopy { src_table, dst_table, - } => sink.table_copy(TableIdx(dst_table), TableIdx(src_table)), - Instruction::TableGrow(table) => sink.table_grow(TableIdx(table)), - Instruction::TableSize(table) => sink.table_size(TableIdx(table)), - Instruction::TableFill(table) => sink.table_fill(TableIdx(table)), + } => sink.table_copy(dst_table, src_table), + Instruction::TableGrow(table) => sink.table_grow(table), + Instruction::TableSize(table) => sink.table_size(table), + Instruction::TableFill(table) => sink.table_fill(table), // SIMD instructions. Instruction::V128Load(memarg) => sink.v128_load(memarg), @@ -2014,218 +1894,174 @@ impl Encode for Instruction<'_> { Instruction::GlobalAtomicGet { ordering, global_index, - } => sink.global_atomic_get(ordering, GlobalIdx(global_index)), + } => sink.global_atomic_get(ordering, global_index), Instruction::GlobalAtomicSet { ordering, global_index, - } => sink.global_atomic_set(ordering, GlobalIdx(global_index)), + } => sink.global_atomic_set(ordering, global_index), Instruction::GlobalAtomicRmwAdd { ordering, global_index, - } => sink.global_atomic_rmw_add(ordering, GlobalIdx(global_index)), + } => sink.global_atomic_rmw_add(ordering, global_index), Instruction::GlobalAtomicRmwSub { ordering, global_index, - } => sink.global_atomic_rmw_sub(ordering, GlobalIdx(global_index)), + } => sink.global_atomic_rmw_sub(ordering, global_index), Instruction::GlobalAtomicRmwAnd { ordering, global_index, - } => sink.global_atomic_rmw_and(ordering, GlobalIdx(global_index)), + } => sink.global_atomic_rmw_and(ordering, global_index), Instruction::GlobalAtomicRmwOr { ordering, global_index, - } => sink.global_atomic_rmw_or(ordering, GlobalIdx(global_index)), + } => sink.global_atomic_rmw_or(ordering, global_index), Instruction::GlobalAtomicRmwXor { ordering, global_index, - } => sink.global_atomic_rmw_xor(ordering, GlobalIdx(global_index)), + } => sink.global_atomic_rmw_xor(ordering, global_index), Instruction::GlobalAtomicRmwXchg { ordering, global_index, - } => sink.global_atomic_rmw_xchg(ordering, GlobalIdx(global_index)), + } => sink.global_atomic_rmw_xchg(ordering, global_index), Instruction::GlobalAtomicRmwCmpxchg { ordering, global_index, - } => sink.global_atomic_rmw_cmpxchg(ordering, GlobalIdx(global_index)), + } => sink.global_atomic_rmw_cmpxchg(ordering, global_index), Instruction::TableAtomicGet { ordering, table_index, - } => sink.table_atomic_get(ordering, TableIdx(table_index)), + } => sink.table_atomic_get(ordering, table_index), Instruction::TableAtomicSet { ordering, table_index, - } => sink.table_atomic_set(ordering, TableIdx(table_index)), + } => sink.table_atomic_set(ordering, table_index), Instruction::TableAtomicRmwXchg { ordering, table_index, - } => sink.table_atomic_rmw_xchg(ordering, TableIdx(table_index)), + } => sink.table_atomic_rmw_xchg(ordering, table_index), Instruction::TableAtomicRmwCmpxchg { ordering, table_index, - } => sink.table_atomic_rmw_cmpxchg(ordering, TableIdx(table_index)), + } => sink.table_atomic_rmw_cmpxchg(ordering, table_index), Instruction::StructAtomicGet { ordering, struct_type_index, field_index, - } => { - sink.struct_atomic_get(ordering, TypeIdx(struct_type_index), FieldIdx(field_index)) - } + } => sink.struct_atomic_get(ordering, struct_type_index, field_index), Instruction::StructAtomicGetS { ordering, struct_type_index, field_index, - } => sink.struct_atomic_get_s( - ordering, - TypeIdx(struct_type_index), - FieldIdx(field_index), - ), + } => sink.struct_atomic_get_s(ordering, struct_type_index, field_index), Instruction::StructAtomicGetU { ordering, struct_type_index, field_index, - } => sink.struct_atomic_get_u( - ordering, - TypeIdx(struct_type_index), - FieldIdx(field_index), - ), + } => sink.struct_atomic_get_u(ordering, struct_type_index, field_index), Instruction::StructAtomicSet { ordering, struct_type_index, field_index, - } => { - sink.struct_atomic_set(ordering, TypeIdx(struct_type_index), FieldIdx(field_index)) - } + } => sink.struct_atomic_set(ordering, struct_type_index, field_index), Instruction::StructAtomicRmwAdd { ordering, struct_type_index, field_index, - } => sink.struct_atomic_rmw_add( - ordering, - TypeIdx(struct_type_index), - FieldIdx(field_index), - ), + } => sink.struct_atomic_rmw_add(ordering, struct_type_index, field_index), Instruction::StructAtomicRmwSub { ordering, struct_type_index, field_index, - } => sink.struct_atomic_rmw_sub( - ordering, - TypeIdx(struct_type_index), - FieldIdx(field_index), - ), + } => sink.struct_atomic_rmw_sub(ordering, struct_type_index, field_index), Instruction::StructAtomicRmwAnd { ordering, struct_type_index, field_index, - } => sink.struct_atomic_rmw_and( - ordering, - TypeIdx(struct_type_index), - FieldIdx(field_index), - ), + } => sink.struct_atomic_rmw_and(ordering, struct_type_index, field_index), Instruction::StructAtomicRmwOr { ordering, struct_type_index, field_index, - } => sink.struct_atomic_rmw_or( - ordering, - TypeIdx(struct_type_index), - FieldIdx(field_index), - ), + } => sink.struct_atomic_rmw_or(ordering, struct_type_index, field_index), Instruction::StructAtomicRmwXor { ordering, struct_type_index, field_index, - } => sink.struct_atomic_rmw_xor( - ordering, - TypeIdx(struct_type_index), - FieldIdx(field_index), - ), + } => sink.struct_atomic_rmw_xor(ordering, struct_type_index, field_index), Instruction::StructAtomicRmwXchg { ordering, struct_type_index, field_index, - } => sink.struct_atomic_rmw_xchg( - ordering, - TypeIdx(struct_type_index), - FieldIdx(field_index), - ), + } => sink.struct_atomic_rmw_xchg(ordering, struct_type_index, field_index), Instruction::StructAtomicRmwCmpxchg { ordering, struct_type_index, field_index, - } => sink.struct_atomic_rmw_cmpxchg( - ordering, - TypeIdx(struct_type_index), - FieldIdx(field_index), - ), + } => sink.struct_atomic_rmw_cmpxchg(ordering, struct_type_index, field_index), Instruction::ArrayAtomicGet { ordering, array_type_index, - } => sink.array_atomic_get(ordering, TypeIdx(array_type_index)), + } => sink.array_atomic_get(ordering, array_type_index), Instruction::ArrayAtomicGetS { ordering, array_type_index, - } => sink.array_atomic_get_s(ordering, TypeIdx(array_type_index)), + } => sink.array_atomic_get_s(ordering, array_type_index), Instruction::ArrayAtomicGetU { ordering, array_type_index, - } => sink.array_atomic_get_u(ordering, TypeIdx(array_type_index)), + } => sink.array_atomic_get_u(ordering, array_type_index), Instruction::ArrayAtomicSet { ordering, array_type_index, - } => sink.array_atomic_set(ordering, TypeIdx(array_type_index)), + } => sink.array_atomic_set(ordering, array_type_index), Instruction::ArrayAtomicRmwAdd { ordering, array_type_index, - } => sink.array_atomic_rmw_add(ordering, TypeIdx(array_type_index)), + } => sink.array_atomic_rmw_add(ordering, array_type_index), Instruction::ArrayAtomicRmwSub { ordering, array_type_index, - } => sink.array_atomic_rmw_sub(ordering, TypeIdx(array_type_index)), + } => sink.array_atomic_rmw_sub(ordering, array_type_index), Instruction::ArrayAtomicRmwAnd { ordering, array_type_index, - } => sink.array_atomic_rmw_and(ordering, TypeIdx(array_type_index)), + } => sink.array_atomic_rmw_and(ordering, array_type_index), Instruction::ArrayAtomicRmwOr { ordering, array_type_index, - } => sink.array_atomic_rmw_or(ordering, TypeIdx(array_type_index)), + } => sink.array_atomic_rmw_or(ordering, array_type_index), Instruction::ArrayAtomicRmwXor { ordering, array_type_index, - } => sink.array_atomic_rmw_xor(ordering, TypeIdx(array_type_index)), + } => sink.array_atomic_rmw_xor(ordering, array_type_index), Instruction::ArrayAtomicRmwXchg { ordering, array_type_index, - } => sink.array_atomic_rmw_xchg(ordering, TypeIdx(array_type_index)), + } => sink.array_atomic_rmw_xchg(ordering, array_type_index), Instruction::ArrayAtomicRmwCmpxchg { ordering, array_type_index, - } => sink.array_atomic_rmw_cmpxchg(ordering, TypeIdx(array_type_index)), + } => sink.array_atomic_rmw_cmpxchg(ordering, array_type_index), Instruction::RefI31Shared => sink.ref_i31_shared(), - Instruction::ContNew(type_index) => sink.cont_new(TypeIdx(type_index)), + Instruction::ContNew(type_index) => sink.cont_new(type_index), Instruction::ContBind { argument_index, result_index, - } => sink.cont_bind(TypeIdx(argument_index), TypeIdx(result_index)), - Instruction::Suspend(tag_index) => sink.suspend(TagIdx(tag_index)), + } => sink.cont_bind(argument_index, result_index), + Instruction::Suspend(tag_index) => sink.suspend(tag_index), Instruction::Resume { cont_type_index, ref resume_table, - } => sink.resume(TypeIdx(cont_type_index), resume_table.iter().cloned()), + } => sink.resume(cont_type_index, resume_table.iter().cloned()), Instruction::ResumeThrow { cont_type_index, tag_index, ref resume_table, - } => sink.resume_throw( - TypeIdx(cont_type_index), - TagIdx(tag_index), - resume_table.iter().cloned(), - ), + } => sink.resume_throw(cont_type_index, tag_index, resume_table.iter().cloned()), Instruction::Switch { cont_type_index, tag_index, - } => sink.switch(TypeIdx(cont_type_index), TagIdx(tag_index)), + } => sink.switch(cont_type_index, tag_index), Instruction::I64Add128 => sink.i64_add128(), Instruction::I64Sub128 => sink.i64_sub128(), Instruction::I64MulWideS => sink.i64_mul_wide_s(), @@ -2335,7 +2171,7 @@ impl ConstExpr { /// Create a constant expression containing a single `global.get` instruction. pub fn global_get(index: u32) -> Self { Self::new(|insn| { - insn.global_get(GlobalIdx(index)); + insn.global_get(index); }) } @@ -2349,7 +2185,7 @@ impl ConstExpr { /// Create a constant expression containing a single `ref.func` instruction. pub fn ref_func(func: u32) -> Self { Self::new(|insn| { - insn.ref_func(FuncIdx(func)); + insn.ref_func(func); }) } @@ -2391,7 +2227,7 @@ impl ConstExpr { /// Add a `global.get` instruction to this constant expression. pub fn with_global_get(self, index: u32) -> Self { self.with(|insn| { - insn.global_get(GlobalIdx(index)); + insn.global_get(index); }) } @@ -2405,7 +2241,7 @@ impl ConstExpr { /// Add a `ref.func` instruction to this constant expression. pub fn with_ref_func(self, func: u32) -> Self { self.with(|insn| { - insn.ref_func(FuncIdx(func)); + insn.ref_func(func); }) } diff --git a/crates/wasm-encoder/src/core/instructions.rs b/crates/wasm-encoder/src/core/instructions.rs index 93e78743ea..d327c48b1a 100644 --- a/crates/wasm-encoder/src/core/instructions.rs +++ b/crates/wasm-encoder/src/core/instructions.rs @@ -1,9 +1,8 @@ #[allow(unused_imports)] use crate::Instruction; use crate::{ - encode_vec, BlockType, Catch, DataIdx, ElemIdx, Encode, FieldIdx, FuncIdx, GlobalIdx, Handle, - HeapType, LabelIdx, Lane, LocalIdx, MemArg, MemIdx, Ordering, RefType, TableIdx, TagIdx, - TypeIdx, ValType, + encode_vec, BlockType, Catch, Encode, Handle, HeapType, Lane, MemArg, Ordering, RefType, + ValType, }; use alloc::vec::Vec; @@ -67,24 +66,25 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::Br`]. - pub fn br(&mut self, l: LabelIdx) -> &mut Self { + pub fn br(&mut self, l: u32) -> &mut Self { self.sink.push(0x0C); l.encode(self.sink); self } /// Encode [`Instruction::BrIf`]. - pub fn br_if(&mut self, l: LabelIdx) -> &mut Self { + pub fn br_if(&mut self, l: u32) -> &mut Self { self.sink.push(0x0D); l.encode(self.sink); self } /// Encode [`Instruction::BrTable`]. - pub fn br_table>(&mut self, ls: V, l: LabelIdx) -> &mut Self - where - V::IntoIter: ExactSizeIterator, - { + pub fn br_table( + &mut self, + ls: impl IntoIterator, + l: u32, + ) -> &mut Self { self.sink.push(0x0E); encode_vec(ls, self.sink); l.encode(self.sink); @@ -92,14 +92,14 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::BrOnNull`]. - pub fn br_on_null(&mut self, l: LabelIdx) -> &mut Self { + pub fn br_on_null(&mut self, l: u32) -> &mut Self { self.sink.push(0xD5); l.encode(self.sink); self } /// Encode [`Instruction::BrOnNonNull`]. - pub fn br_on_non_null(&mut self, l: LabelIdx) -> &mut Self { + pub fn br_on_non_null(&mut self, l: u32) -> &mut Self { self.sink.push(0xD6); l.encode(self.sink); self @@ -112,21 +112,21 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::Call`]. - pub fn call(&mut self, f: FuncIdx) -> &mut Self { + pub fn call(&mut self, f: u32) -> &mut Self { self.sink.push(0x10); f.encode(self.sink); self } /// Encode [`Instruction::CallRef`]. - pub fn call_ref(&mut self, ty: TypeIdx) -> &mut Self { + pub fn call_ref(&mut self, ty: u32) -> &mut Self { self.sink.push(0x14); ty.encode(self.sink); self } /// Encode [`Instruction::CallIndirect`]. - pub fn call_indirect(&mut self, table_index: TableIdx, type_index: TypeIdx) -> &mut Self { + pub fn call_indirect(&mut self, table_index: u32, type_index: u32) -> &mut Self { self.sink.push(0x11); type_index.encode(self.sink); table_index.encode(self.sink); @@ -134,25 +134,21 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::ReturnCallRef`]. - pub fn return_call_ref(&mut self, ty: TypeIdx) -> &mut Self { + pub fn return_call_ref(&mut self, ty: u32) -> &mut Self { self.sink.push(0x15); ty.encode(self.sink); self } /// Encode [`Instruction::ReturnCall`]. - pub fn return_call(&mut self, f: FuncIdx) -> &mut Self { + pub fn return_call(&mut self, f: u32) -> &mut Self { self.sink.push(0x12); f.encode(self.sink); self } /// Encode [`Instruction::ReturnCallIndirect`]. - pub fn return_call_indirect( - &mut self, - table_index: TableIdx, - type_index: TypeIdx, - ) -> &mut Self { + pub fn return_call_indirect(&mut self, table_index: u32, type_index: u32) -> &mut Self { self.sink.push(0x13); type_index.encode(self.sink); table_index.encode(self.sink); @@ -160,14 +156,11 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::TryTable`]. - pub fn try_table>( + pub fn try_table( &mut self, ty: BlockType, - catches: V, - ) -> &mut Self - where - V::IntoIter: ExactSizeIterator, - { + catches: impl IntoIterator, + ) -> &mut Self { self.sink.push(0x1f); ty.encode(self.sink); encode_vec(catches, self.sink); @@ -175,7 +168,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::Throw`]. - pub fn throw(&mut self, t: TagIdx) -> &mut Self { + pub fn throw(&mut self, t: u32) -> &mut Self { self.sink.push(0x08); t.encode(self.sink); self @@ -197,14 +190,14 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::Delegate`]. - pub fn delegate(&mut self, l: LabelIdx) -> &mut Self { + pub fn delegate(&mut self, l: u32) -> &mut Self { self.sink.push(0x18); l.encode(self.sink); self } /// Encode [`Instruction::Catch`]. - pub fn catch(&mut self, t: TagIdx) -> &mut Self { + pub fn catch(&mut self, t: u32) -> &mut Self { self.sink.push(0x07); t.encode(self.sink); self @@ -217,7 +210,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::Rethrow`]. - pub fn rethrow(&mut self, l: LabelIdx) -> &mut Self { + pub fn rethrow(&mut self, l: u32) -> &mut Self { self.sink.push(0x09); l.encode(self.sink); self @@ -240,35 +233,35 @@ impl<'a> InstructionSink<'a> { // Variable instructions. /// Encode [`Instruction::LocalGet`]. - pub fn local_get(&mut self, l: LocalIdx) -> &mut Self { + pub fn local_get(&mut self, l: u32) -> &mut Self { self.sink.push(0x20); l.encode(self.sink); self } /// Encode [`Instruction::LocalSet`]. - pub fn local_set(&mut self, l: LocalIdx) -> &mut Self { + pub fn local_set(&mut self, l: u32) -> &mut Self { self.sink.push(0x21); l.encode(self.sink); self } /// Encode [`Instruction::LocalTee`]. - pub fn local_tee(&mut self, l: LocalIdx) -> &mut Self { + pub fn local_tee(&mut self, l: u32) -> &mut Self { self.sink.push(0x22); l.encode(self.sink); self } /// Encode [`Instruction::GlobalGet`]. - pub fn global_get(&mut self, g: GlobalIdx) -> &mut Self { + pub fn global_get(&mut self, g: u32) -> &mut Self { self.sink.push(0x23); g.encode(self.sink); self } /// Encode [`Instruction::GlobalSet`]. - pub fn global_set(&mut self, g: GlobalIdx) -> &mut Self { + pub fn global_set(&mut self, g: u32) -> &mut Self { self.sink.push(0x24); g.encode(self.sink); self @@ -438,21 +431,21 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::MemorySize`]. - pub fn memory_size(&mut self, i: MemIdx) -> &mut Self { + pub fn memory_size(&mut self, i: u32) -> &mut Self { self.sink.push(0x3F); i.encode(self.sink); self } /// Encode [`Instruction::MemoryGrow`]. - pub fn memory_grow(&mut self, i: MemIdx) -> &mut Self { + pub fn memory_grow(&mut self, i: u32) -> &mut Self { self.sink.push(0x40); i.encode(self.sink); self } /// Encode [`Instruction::MemoryInit`]. - pub fn memory_init(&mut self, mem: MemIdx, data_index: DataIdx) -> &mut Self { + pub fn memory_init(&mut self, mem: u32, data_index: u32) -> &mut Self { self.sink.push(0xfc); self.sink.push(0x08); data_index.encode(self.sink); @@ -461,7 +454,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::DataDrop`]. - pub fn data_drop(&mut self, data: DataIdx) -> &mut Self { + pub fn data_drop(&mut self, data: u32) -> &mut Self { self.sink.push(0xfc); self.sink.push(0x09); data.encode(self.sink); @@ -469,7 +462,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::MemoryCopy`]. - pub fn memory_copy(&mut self, dst_mem: MemIdx, src_mem: MemIdx) -> &mut Self { + pub fn memory_copy(&mut self, dst_mem: u32, src_mem: u32) -> &mut Self { self.sink.push(0xfc); self.sink.push(0x0a); dst_mem.encode(self.sink); @@ -478,7 +471,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::MemoryFill`]. - pub fn memory_fill(&mut self, mem: MemIdx) -> &mut Self { + pub fn memory_fill(&mut self, mem: u32) -> &mut Self { self.sink.push(0xfc); self.sink.push(0x0b); mem.encode(self.sink); @@ -486,7 +479,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::MemoryDiscard`]. - pub fn memory_discard(&mut self, mem: MemIdx) -> &mut Self { + pub fn memory_discard(&mut self, mem: u32) -> &mut Self { self.sink.push(0xfc); self.sink.push(0x12); mem.encode(self.sink); @@ -1372,7 +1365,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::RefFunc`]. - pub fn ref_func(&mut self, f: FuncIdx) -> &mut Self { + pub fn ref_func(&mut self, f: u32) -> &mut Self { self.sink.push(0xd2); f.encode(self.sink); self @@ -1393,7 +1386,7 @@ impl<'a> InstructionSink<'a> { // GC types instructions. /// Encode [`Instruction::StructNew`]. - pub fn struct_new(&mut self, type_index: TypeIdx) -> &mut Self { + pub fn struct_new(&mut self, type_index: u32) -> &mut Self { self.sink.push(0xfb); self.sink.push(0x00); type_index.encode(self.sink); @@ -1401,7 +1394,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::StructNewDefault`]. - pub fn struct_new_default(&mut self, type_index: TypeIdx) -> &mut Self { + pub fn struct_new_default(&mut self, type_index: u32) -> &mut Self { self.sink.push(0xfb); self.sink.push(0x01); type_index.encode(self.sink); @@ -1409,7 +1402,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::StructGet`]. - pub fn struct_get(&mut self, struct_type_index: TypeIdx, field_index: FieldIdx) -> &mut Self { + pub fn struct_get(&mut self, struct_type_index: u32, field_index: u32) -> &mut Self { self.sink.push(0xfb); self.sink.push(0x02); struct_type_index.encode(self.sink); @@ -1418,7 +1411,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::StructGetS`]. - pub fn struct_get_s(&mut self, struct_type_index: TypeIdx, field_index: FieldIdx) -> &mut Self { + pub fn struct_get_s(&mut self, struct_type_index: u32, field_index: u32) -> &mut Self { self.sink.push(0xfb); self.sink.push(0x03); struct_type_index.encode(self.sink); @@ -1427,7 +1420,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::StructGetU`]. - pub fn struct_get_u(&mut self, struct_type_index: TypeIdx, field_index: FieldIdx) -> &mut Self { + pub fn struct_get_u(&mut self, struct_type_index: u32, field_index: u32) -> &mut Self { self.sink.push(0xfb); self.sink.push(0x04); struct_type_index.encode(self.sink); @@ -1436,7 +1429,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::StructSet`]. - pub fn struct_set(&mut self, struct_type_index: TypeIdx, field_index: FieldIdx) -> &mut Self { + pub fn struct_set(&mut self, struct_type_index: u32, field_index: u32) -> &mut Self { self.sink.push(0xfb); self.sink.push(0x05); struct_type_index.encode(self.sink); @@ -1445,7 +1438,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::ArrayNew`]. - pub fn array_new(&mut self, type_index: TypeIdx) -> &mut Self { + pub fn array_new(&mut self, type_index: u32) -> &mut Self { self.sink.push(0xfb); self.sink.push(0x06); type_index.encode(self.sink); @@ -1453,7 +1446,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::ArrayNewDefault`]. - pub fn array_new_default(&mut self, type_index: TypeIdx) -> &mut Self { + pub fn array_new_default(&mut self, type_index: u32) -> &mut Self { self.sink.push(0xfb); self.sink.push(0x07); type_index.encode(self.sink); @@ -1461,7 +1454,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::ArrayNewFixed`]. - pub fn array_new_fixed(&mut self, array_type_index: TypeIdx, array_size: u32) -> &mut Self { + pub fn array_new_fixed(&mut self, array_type_index: u32, array_size: u32) -> &mut Self { self.sink.push(0xfb); self.sink.push(0x08); array_type_index.encode(self.sink); @@ -1470,11 +1463,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::ArrayNewData`]. - pub fn array_new_data( - &mut self, - array_type_index: TypeIdx, - array_data_index: DataIdx, - ) -> &mut Self { + pub fn array_new_data(&mut self, array_type_index: u32, array_data_index: u32) -> &mut Self { self.sink.push(0xfb); self.sink.push(0x09); array_type_index.encode(self.sink); @@ -1483,11 +1472,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::ArrayNewElem`]. - pub fn array_new_elem( - &mut self, - array_type_index: TypeIdx, - array_elem_index: ElemIdx, - ) -> &mut Self { + pub fn array_new_elem(&mut self, array_type_index: u32, array_elem_index: u32) -> &mut Self { self.sink.push(0xfb); self.sink.push(0x0a); array_type_index.encode(self.sink); @@ -1496,7 +1481,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::ArrayGet`]. - pub fn array_get(&mut self, type_index: TypeIdx) -> &mut Self { + pub fn array_get(&mut self, type_index: u32) -> &mut Self { self.sink.push(0xfb); self.sink.push(0x0b); type_index.encode(self.sink); @@ -1504,7 +1489,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::ArrayGetS`]. - pub fn array_get_s(&mut self, type_index: TypeIdx) -> &mut Self { + pub fn array_get_s(&mut self, type_index: u32) -> &mut Self { self.sink.push(0xfb); self.sink.push(0x0c); type_index.encode(self.sink); @@ -1512,7 +1497,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::ArrayGetU`]. - pub fn array_get_u(&mut self, type_index: TypeIdx) -> &mut Self { + pub fn array_get_u(&mut self, type_index: u32) -> &mut Self { self.sink.push(0xfb); self.sink.push(0x0d); type_index.encode(self.sink); @@ -1520,7 +1505,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::ArraySet`]. - pub fn array_set(&mut self, type_index: TypeIdx) -> &mut Self { + pub fn array_set(&mut self, type_index: u32) -> &mut Self { self.sink.push(0xfb); self.sink.push(0x0e); type_index.encode(self.sink); @@ -1535,7 +1520,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::ArrayFill`]. - pub fn array_fill(&mut self, type_index: TypeIdx) -> &mut Self { + pub fn array_fill(&mut self, type_index: u32) -> &mut Self { self.sink.push(0xfb); self.sink.push(0x10); type_index.encode(self.sink); @@ -1545,8 +1530,8 @@ impl<'a> InstructionSink<'a> { /// Encode [`Instruction::ArrayCopy`]. pub fn array_copy( &mut self, - array_type_index_dst: TypeIdx, - array_type_index_src: TypeIdx, + array_type_index_dst: u32, + array_type_index_src: u32, ) -> &mut Self { self.sink.push(0xfb); self.sink.push(0x11); @@ -1556,11 +1541,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::ArrayInitData`]. - pub fn array_init_data( - &mut self, - array_type_index: TypeIdx, - array_data_index: DataIdx, - ) -> &mut Self { + pub fn array_init_data(&mut self, array_type_index: u32, array_data_index: u32) -> &mut Self { self.sink.push(0xfb); self.sink.push(0x12); array_type_index.encode(self.sink); @@ -1569,11 +1550,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::ArrayInitElem`]. - pub fn array_init_elem( - &mut self, - array_type_index: TypeIdx, - array_elem_index: ElemIdx, - ) -> &mut Self { + pub fn array_init_elem(&mut self, array_type_index: u32, array_elem_index: u32) -> &mut Self { self.sink.push(0xfb); self.sink.push(0x13); array_type_index.encode(self.sink); @@ -1616,7 +1593,7 @@ impl<'a> InstructionSink<'a> { /// Encode [`Instruction::BrOnCast`]. pub fn br_on_cast( &mut self, - relative_depth: LabelIdx, + relative_depth: u32, from_ref_type: RefType, to_ref_type: RefType, ) -> &mut Self { @@ -1633,7 +1610,7 @@ impl<'a> InstructionSink<'a> { /// Encode [`Instruction::BrOnCastFail`]. pub fn br_on_cast_fail( &mut self, - relative_depth: LabelIdx, + relative_depth: u32, from_ref_type: RefType, to_ref_type: RefType, ) -> &mut Self { @@ -1685,7 +1662,7 @@ impl<'a> InstructionSink<'a> { // Bulk memory instructions. /// Encode [`Instruction::TableInit`]. - pub fn table_init(&mut self, table: TableIdx, elem_index: ElemIdx) -> &mut Self { + pub fn table_init(&mut self, table: u32, elem_index: u32) -> &mut Self { self.sink.push(0xfc); self.sink.push(0x0c); elem_index.encode(self.sink); @@ -1694,7 +1671,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::ElemDrop`]. - pub fn elem_drop(&mut self, segment: ElemIdx) -> &mut Self { + pub fn elem_drop(&mut self, segment: u32) -> &mut Self { self.sink.push(0xfc); self.sink.push(0x0d); segment.encode(self.sink); @@ -1702,7 +1679,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::TableFill`]. - pub fn table_fill(&mut self, table: TableIdx) -> &mut Self { + pub fn table_fill(&mut self, table: u32) -> &mut Self { self.sink.push(0xfc); self.sink.push(0x11); table.encode(self.sink); @@ -1710,21 +1687,21 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::TableSet`]. - pub fn table_set(&mut self, table: TableIdx) -> &mut Self { + pub fn table_set(&mut self, table: u32) -> &mut Self { self.sink.push(0x26); table.encode(self.sink); self } /// Encode [`Instruction::TableGet`]. - pub fn table_get(&mut self, table: TableIdx) -> &mut Self { + pub fn table_get(&mut self, table: u32) -> &mut Self { self.sink.push(0x25); table.encode(self.sink); self } /// Encode [`Instruction::TableGrow`]. - pub fn table_grow(&mut self, table: TableIdx) -> &mut Self { + pub fn table_grow(&mut self, table: u32) -> &mut Self { self.sink.push(0xfc); self.sink.push(0x0f); table.encode(self.sink); @@ -1732,7 +1709,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::TableSize`]. - pub fn table_size(&mut self, table: TableIdx) -> &mut Self { + pub fn table_size(&mut self, table: u32) -> &mut Self { self.sink.push(0xfc); self.sink.push(0x10); table.encode(self.sink); @@ -1740,7 +1717,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::TableCopy`]. - pub fn table_copy(&mut self, dst_table: TableIdx, src_table: TableIdx) -> &mut Self { + pub fn table_copy(&mut self, dst_table: u32, src_table: u32) -> &mut Self { self.sink.push(0xfc); self.sink.push(0x0e); dst_table.encode(self.sink); @@ -4154,7 +4131,7 @@ impl<'a> InstructionSink<'a> { // More atomic instructions (the shared-everything-threads proposal) /// Encode [`Instruction::GlobalAtomicGet`]. - pub fn global_atomic_get(&mut self, ordering: Ordering, global_index: GlobalIdx) -> &mut Self { + pub fn global_atomic_get(&mut self, ordering: Ordering, global_index: u32) -> &mut Self { self.sink.push(0xFE); self.sink.push(0x4F); ordering.encode(self.sink); @@ -4163,7 +4140,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::GlobalAtomicSet`]. - pub fn global_atomic_set(&mut self, ordering: Ordering, global_index: GlobalIdx) -> &mut Self { + pub fn global_atomic_set(&mut self, ordering: Ordering, global_index: u32) -> &mut Self { self.sink.push(0xFE); self.sink.push(0x50); ordering.encode(self.sink); @@ -4172,11 +4149,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::GlobalAtomicRmwAdd`]. - pub fn global_atomic_rmw_add( - &mut self, - ordering: Ordering, - global_index: GlobalIdx, - ) -> &mut Self { + pub fn global_atomic_rmw_add(&mut self, ordering: Ordering, global_index: u32) -> &mut Self { self.sink.push(0xFE); self.sink.push(0x51); ordering.encode(self.sink); @@ -4185,11 +4158,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::GlobalAtomicRmwSub`]. - pub fn global_atomic_rmw_sub( - &mut self, - ordering: Ordering, - global_index: GlobalIdx, - ) -> &mut Self { + pub fn global_atomic_rmw_sub(&mut self, ordering: Ordering, global_index: u32) -> &mut Self { self.sink.push(0xFE); self.sink.push(0x52); ordering.encode(self.sink); @@ -4198,11 +4167,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::GlobalAtomicRmwAnd`]. - pub fn global_atomic_rmw_and( - &mut self, - ordering: Ordering, - global_index: GlobalIdx, - ) -> &mut Self { + pub fn global_atomic_rmw_and(&mut self, ordering: Ordering, global_index: u32) -> &mut Self { self.sink.push(0xFE); self.sink.push(0x53); ordering.encode(self.sink); @@ -4211,11 +4176,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::GlobalAtomicRmwOr`]. - pub fn global_atomic_rmw_or( - &mut self, - ordering: Ordering, - global_index: GlobalIdx, - ) -> &mut Self { + pub fn global_atomic_rmw_or(&mut self, ordering: Ordering, global_index: u32) -> &mut Self { self.sink.push(0xFE); self.sink.push(0x54); ordering.encode(self.sink); @@ -4224,11 +4185,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::GlobalAtomicRmwXor`]. - pub fn global_atomic_rmw_xor( - &mut self, - ordering: Ordering, - global_index: GlobalIdx, - ) -> &mut Self { + pub fn global_atomic_rmw_xor(&mut self, ordering: Ordering, global_index: u32) -> &mut Self { self.sink.push(0xFE); self.sink.push(0x55); ordering.encode(self.sink); @@ -4237,11 +4194,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::GlobalAtomicRmwXchg`]. - pub fn global_atomic_rmw_xchg( - &mut self, - ordering: Ordering, - global_index: GlobalIdx, - ) -> &mut Self { + pub fn global_atomic_rmw_xchg(&mut self, ordering: Ordering, global_index: u32) -> &mut Self { self.sink.push(0xFE); self.sink.push(0x56); ordering.encode(self.sink); @@ -4253,7 +4206,7 @@ impl<'a> InstructionSink<'a> { pub fn global_atomic_rmw_cmpxchg( &mut self, ordering: Ordering, - global_index: GlobalIdx, + global_index: u32, ) -> &mut Self { self.sink.push(0xFE); self.sink.push(0x57); @@ -4263,7 +4216,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::TableAtomicGet`]. - pub fn table_atomic_get(&mut self, ordering: Ordering, table_index: TableIdx) -> &mut Self { + pub fn table_atomic_get(&mut self, ordering: Ordering, table_index: u32) -> &mut Self { self.sink.push(0xFE); self.sink.push(0x58); ordering.encode(self.sink); @@ -4272,7 +4225,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::TableAtomicSet`]. - pub fn table_atomic_set(&mut self, ordering: Ordering, table_index: TableIdx) -> &mut Self { + pub fn table_atomic_set(&mut self, ordering: Ordering, table_index: u32) -> &mut Self { self.sink.push(0xFE); self.sink.push(0x59); ordering.encode(self.sink); @@ -4281,11 +4234,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::TableAtomicRmwXchg`]. - pub fn table_atomic_rmw_xchg( - &mut self, - ordering: Ordering, - table_index: TableIdx, - ) -> &mut Self { + pub fn table_atomic_rmw_xchg(&mut self, ordering: Ordering, table_index: u32) -> &mut Self { self.sink.push(0xFE); self.sink.push(0x5A); ordering.encode(self.sink); @@ -4294,11 +4243,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::TableAtomicRmwCmpxchg`]. - pub fn table_atomic_rmw_cmpxchg( - &mut self, - ordering: Ordering, - table_index: TableIdx, - ) -> &mut Self { + pub fn table_atomic_rmw_cmpxchg(&mut self, ordering: Ordering, table_index: u32) -> &mut Self { self.sink.push(0xFE); self.sink.push(0x5B); ordering.encode(self.sink); @@ -4310,8 +4255,8 @@ impl<'a> InstructionSink<'a> { pub fn struct_atomic_get( &mut self, ordering: Ordering, - struct_type_index: TypeIdx, - field_index: FieldIdx, + struct_type_index: u32, + field_index: u32, ) -> &mut Self { self.sink.push(0xFE); self.sink.push(0x5C); @@ -4325,8 +4270,8 @@ impl<'a> InstructionSink<'a> { pub fn struct_atomic_get_s( &mut self, ordering: Ordering, - struct_type_index: TypeIdx, - field_index: FieldIdx, + struct_type_index: u32, + field_index: u32, ) -> &mut Self { self.sink.push(0xFE); self.sink.push(0x5D); @@ -4340,8 +4285,8 @@ impl<'a> InstructionSink<'a> { pub fn struct_atomic_get_u( &mut self, ordering: Ordering, - struct_type_index: TypeIdx, - field_index: FieldIdx, + struct_type_index: u32, + field_index: u32, ) -> &mut Self { self.sink.push(0xFE); self.sink.push(0x5E); @@ -4355,8 +4300,8 @@ impl<'a> InstructionSink<'a> { pub fn struct_atomic_set( &mut self, ordering: Ordering, - struct_type_index: TypeIdx, - field_index: FieldIdx, + struct_type_index: u32, + field_index: u32, ) -> &mut Self { self.sink.push(0xFE); self.sink.push(0x5F); @@ -4370,8 +4315,8 @@ impl<'a> InstructionSink<'a> { pub fn struct_atomic_rmw_add( &mut self, ordering: Ordering, - struct_type_index: TypeIdx, - field_index: FieldIdx, + struct_type_index: u32, + field_index: u32, ) -> &mut Self { self.sink.push(0xFE); self.sink.push(0x60); @@ -4385,8 +4330,8 @@ impl<'a> InstructionSink<'a> { pub fn struct_atomic_rmw_sub( &mut self, ordering: Ordering, - struct_type_index: TypeIdx, - field_index: FieldIdx, + struct_type_index: u32, + field_index: u32, ) -> &mut Self { self.sink.push(0xFE); self.sink.push(0x61); @@ -4400,8 +4345,8 @@ impl<'a> InstructionSink<'a> { pub fn struct_atomic_rmw_and( &mut self, ordering: Ordering, - struct_type_index: TypeIdx, - field_index: FieldIdx, + struct_type_index: u32, + field_index: u32, ) -> &mut Self { self.sink.push(0xFE); self.sink.push(0x62); @@ -4415,8 +4360,8 @@ impl<'a> InstructionSink<'a> { pub fn struct_atomic_rmw_or( &mut self, ordering: Ordering, - struct_type_index: TypeIdx, - field_index: FieldIdx, + struct_type_index: u32, + field_index: u32, ) -> &mut Self { self.sink.push(0xFE); self.sink.push(0x63); @@ -4430,8 +4375,8 @@ impl<'a> InstructionSink<'a> { pub fn struct_atomic_rmw_xor( &mut self, ordering: Ordering, - struct_type_index: TypeIdx, - field_index: FieldIdx, + struct_type_index: u32, + field_index: u32, ) -> &mut Self { self.sink.push(0xFE); self.sink.push(0x64); @@ -4445,8 +4390,8 @@ impl<'a> InstructionSink<'a> { pub fn struct_atomic_rmw_xchg( &mut self, ordering: Ordering, - struct_type_index: TypeIdx, - field_index: FieldIdx, + struct_type_index: u32, + field_index: u32, ) -> &mut Self { self.sink.push(0xFE); self.sink.push(0x65); @@ -4460,8 +4405,8 @@ impl<'a> InstructionSink<'a> { pub fn struct_atomic_rmw_cmpxchg( &mut self, ordering: Ordering, - struct_type_index: TypeIdx, - field_index: FieldIdx, + struct_type_index: u32, + field_index: u32, ) -> &mut Self { self.sink.push(0xFE); self.sink.push(0x66); @@ -4472,7 +4417,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::ArrayAtomicGet`]. - pub fn array_atomic_get(&mut self, ordering: Ordering, array_type_index: TypeIdx) -> &mut Self { + pub fn array_atomic_get(&mut self, ordering: Ordering, array_type_index: u32) -> &mut Self { self.sink.push(0xFE); self.sink.push(0x67); ordering.encode(self.sink); @@ -4481,11 +4426,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::ArrayAtomicGetS`]. - pub fn array_atomic_get_s( - &mut self, - ordering: Ordering, - array_type_index: TypeIdx, - ) -> &mut Self { + pub fn array_atomic_get_s(&mut self, ordering: Ordering, array_type_index: u32) -> &mut Self { self.sink.push(0xFE); self.sink.push(0x68); ordering.encode(self.sink); @@ -4494,11 +4435,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::ArrayAtomicGetU`]. - pub fn array_atomic_get_u( - &mut self, - ordering: Ordering, - array_type_index: TypeIdx, - ) -> &mut Self { + pub fn array_atomic_get_u(&mut self, ordering: Ordering, array_type_index: u32) -> &mut Self { self.sink.push(0xFE); self.sink.push(0x69); ordering.encode(self.sink); @@ -4507,7 +4444,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::ArrayAtomicSet`]. - pub fn array_atomic_set(&mut self, ordering: Ordering, array_type_index: TypeIdx) -> &mut Self { + pub fn array_atomic_set(&mut self, ordering: Ordering, array_type_index: u32) -> &mut Self { self.sink.push(0xFE); self.sink.push(0x6A); ordering.encode(self.sink); @@ -4516,11 +4453,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::ArrayAtomicRmwAdd`]. - pub fn array_atomic_rmw_add( - &mut self, - ordering: Ordering, - array_type_index: TypeIdx, - ) -> &mut Self { + pub fn array_atomic_rmw_add(&mut self, ordering: Ordering, array_type_index: u32) -> &mut Self { self.sink.push(0xFE); self.sink.push(0x6B); ordering.encode(self.sink); @@ -4529,11 +4462,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::ArrayAtomicRmwSub`]. - pub fn array_atomic_rmw_sub( - &mut self, - ordering: Ordering, - array_type_index: TypeIdx, - ) -> &mut Self { + pub fn array_atomic_rmw_sub(&mut self, ordering: Ordering, array_type_index: u32) -> &mut Self { self.sink.push(0xFE); self.sink.push(0x6C); ordering.encode(self.sink); @@ -4542,11 +4471,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::ArrayAtomicRmwAnd`]. - pub fn array_atomic_rmw_and( - &mut self, - ordering: Ordering, - array_type_index: TypeIdx, - ) -> &mut Self { + pub fn array_atomic_rmw_and(&mut self, ordering: Ordering, array_type_index: u32) -> &mut Self { self.sink.push(0xFE); self.sink.push(0x6D); ordering.encode(self.sink); @@ -4555,11 +4480,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::ArrayAtomicRmwOr`]. - pub fn array_atomic_rmw_or( - &mut self, - ordering: Ordering, - array_type_index: TypeIdx, - ) -> &mut Self { + pub fn array_atomic_rmw_or(&mut self, ordering: Ordering, array_type_index: u32) -> &mut Self { self.sink.push(0xFE); self.sink.push(0x6E); ordering.encode(self.sink); @@ -4568,11 +4489,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::ArrayAtomicRmwXor`]. - pub fn array_atomic_rmw_xor( - &mut self, - ordering: Ordering, - array_type_index: TypeIdx, - ) -> &mut Self { + pub fn array_atomic_rmw_xor(&mut self, ordering: Ordering, array_type_index: u32) -> &mut Self { self.sink.push(0xFE); self.sink.push(0x6F); ordering.encode(self.sink); @@ -4584,7 +4501,7 @@ impl<'a> InstructionSink<'a> { pub fn array_atomic_rmw_xchg( &mut self, ordering: Ordering, - array_type_index: TypeIdx, + array_type_index: u32, ) -> &mut Self { self.sink.push(0xFE); self.sink.push(0x70); @@ -4597,7 +4514,7 @@ impl<'a> InstructionSink<'a> { pub fn array_atomic_rmw_cmpxchg( &mut self, ordering: Ordering, - array_type_index: TypeIdx, + array_type_index: u32, ) -> &mut Self { self.sink.push(0xFE); self.sink.push(0x71); @@ -4616,14 +4533,14 @@ impl<'a> InstructionSink<'a> { // Stack switching /// Encode [`Instruction::ContNew`]. - pub fn cont_new(&mut self, type_index: TypeIdx) -> &mut Self { + pub fn cont_new(&mut self, type_index: u32) -> &mut Self { self.sink.push(0xE0); type_index.encode(self.sink); self } /// Encode [`Instruction::ContBind`]. - pub fn cont_bind(&mut self, argument_index: TypeIdx, result_index: TypeIdx) -> &mut Self { + pub fn cont_bind(&mut self, argument_index: u32, result_index: u32) -> &mut Self { self.sink.push(0xE1); argument_index.encode(self.sink); result_index.encode(self.sink); @@ -4631,21 +4548,18 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::Suspend`]. - pub fn suspend(&mut self, tag_index: TagIdx) -> &mut Self { + pub fn suspend(&mut self, tag_index: u32) -> &mut Self { self.sink.push(0xE2); tag_index.encode(self.sink); self } /// Encode [`Instruction::Resume`]. - pub fn resume>( + pub fn resume( &mut self, - cont_type_index: TypeIdx, - resume_table: V, - ) -> &mut Self - where - V::IntoIter: ExactSizeIterator, - { + cont_type_index: u32, + resume_table: impl IntoIterator, + ) -> &mut Self { self.sink.push(0xE3); cont_type_index.encode(self.sink); encode_vec(resume_table, self.sink); @@ -4653,15 +4567,12 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::ResumeThrow`]. - pub fn resume_throw>( + pub fn resume_throw( &mut self, - cont_type_index: TypeIdx, - tag_index: TagIdx, - resume_table: V, - ) -> &mut Self - where - V::IntoIter: ExactSizeIterator, - { + cont_type_index: u32, + tag_index: u32, + resume_table: impl IntoIterator, + ) -> &mut Self { self.sink.push(0xE4); cont_type_index.encode(self.sink); tag_index.encode(self.sink); @@ -4670,7 +4581,7 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::Switch`]. - pub fn switch(&mut self, cont_type_index: TypeIdx, tag_index: TagIdx) -> &mut Self { + pub fn switch(&mut self, cont_type_index: u32, tag_index: u32) -> &mut Self { self.sink.push(0xE5); cont_type_index.encode(self.sink); tag_index.encode(self.sink); diff --git a/crates/wasm-encoder/src/lib.rs b/crates/wasm-encoder/src/lib.rs index e29983e001..402effa68a 100644 --- a/crates/wasm-encoder/src/lib.rs +++ b/crates/wasm-encoder/src/lib.rs @@ -26,7 +26,7 @@ //! //! ``` //! use wasm_encoder::{ -//! CodeSection, ExportKind, ExportSection, Function, FunctionSection, LocalIdx, +//! CodeSection, ExportKind, ExportSection, Function, FunctionSection, //! Module, TypeSection, ValType, //! }; //! @@ -55,8 +55,8 @@ //! let locals = vec![]; //! let mut f = Function::new(locals); //! f.instructions() -//! .local_get(LocalIdx(0)) -//! .local_get(LocalIdx(1)) +//! .local_get(0) +//! .local_get(1) //! .i32_add() //! .end(); //! codes.function(&f); diff --git a/crates/wasm-mutate/src/mutators/codemotion/loop_unrolling.rs b/crates/wasm-mutate/src/mutators/codemotion/loop_unrolling.rs index 73498189be..c30917fbcf 100644 --- a/crates/wasm-mutate/src/mutators/codemotion/loop_unrolling.rs +++ b/crates/wasm-mutate/src/mutators/codemotion/loop_unrolling.rs @@ -3,7 +3,7 @@ use std::{collections::HashMap, slice::Iter}; use rand::prelude::SliceRandom; -use wasm_encoder::{Function, Instruction, LabelIdx, ValType}; +use wasm_encoder::{Function, Instruction, ValType}; use wasmparser::{BlockType, Operator}; use crate::{ @@ -131,7 +131,7 @@ impl LoopUnrollWriter { self.write_and_fix_loop_body(including_chunk, &to_fix, newfunc, input_wasm)?; // Write A' br B' - newfunc.instructions().br(LabelIdx(1)); + newfunc.instructions().br(1); newfunc.instructions().end(); // Write the Loop newfunc.instructions().loop_(map_block_type(*ty)?); diff --git a/crates/wasm-mutate/src/mutators/peephole/eggsy/encoder/expr2wasm.rs b/crates/wasm-mutate/src/mutators/peephole/eggsy/encoder/expr2wasm.rs index 7b99e4b936..c55ace88ad 100644 --- a/crates/wasm-mutate/src/mutators/peephole/eggsy/encoder/expr2wasm.rs +++ b/crates/wasm-mutate/src/mutators/peephole/eggsy/encoder/expr2wasm.rs @@ -8,7 +8,7 @@ use crate::{ use egg::{Id, Language, RecExpr}; use rand::Rng; use std::num::Wrapping; -use wasm_encoder::{DataIdx, ElemIdx, FuncIdx, Function, GlobalIdx, LocalIdx, MemIdx, TableIdx}; +use wasm_encoder::Function; /// Some custom nodes might need special resource allocation outside the /// function. Fore xample, if a new global is needed is should be added outside @@ -74,7 +74,7 @@ pub fn expr2wasm( // example, the creation of new globals let mut resources = vec![]; // Next global idx - let mut global_idx = GlobalIdx(config.info().get_global_count() as u32); + let mut global_idx = config.info().get_global_count() as u32; // Enqueue the coding back nodes and infer types while let Some(context) = worklist.pop() { @@ -92,13 +92,13 @@ pub fn expr2wasm( TraversalEvent::Exit => { let insn = &mut newfunc.instructions(); match rootlang { - Lang::LocalGet(idx) => insn.local_get(LocalIdx(*idx)), - Lang::GlobalGet(idx) => insn.global_get(GlobalIdx(*idx)), - Lang::LocalSet(idx, _val) => insn.local_set(LocalIdx(*idx)), - Lang::GlobalSet(idx, _val) => insn.global_set(GlobalIdx(*idx)), - Lang::LocalTee(idx, _) => insn.local_tee(LocalIdx(*idx)), + Lang::LocalGet(idx) => insn.local_get(*idx), + Lang::GlobalGet(idx) => insn.global_get(*idx), + Lang::LocalSet(idx, _val) => insn.local_set(*idx), + Lang::GlobalSet(idx, _val) => insn.global_set(*idx), + Lang::LocalTee(idx, _) => insn.local_tee(*idx), Lang::Wrap(_) => insn.i32_wrap_i64(), - Lang::Call(idx, _) => insn.call(FuncIdx(*idx)), + Lang::Call(idx, _) => insn.call(*idx), Lang::Drop(_) => insn.drop(), Lang::I32Load(memarg, _) => insn.i32_load(memarg.into()), Lang::I64Load(memarg, _) => insn.i64_load(memarg.into()), @@ -317,24 +317,20 @@ pub fn expr2wasm( insn } Lang::Select(_) => insn.select(), - Lang::MemoryGrow(mem, _) => insn.memory_grow(MemIdx(*mem)), - Lang::MemorySize(mem) => insn.memory_size(MemIdx(*mem)), - Lang::MemoryInit(init, _) => { - insn.memory_init(MemIdx(init.memory), DataIdx(init.segment)) - } - Lang::MemoryCopy(cp, _) => insn.memory_copy(MemIdx(cp.dst), MemIdx(cp.src)), - Lang::MemoryFill(mem, _) => insn.memory_fill(MemIdx(*mem)), - Lang::DataDrop(idx) => insn.data_drop(DataIdx(*idx)), - Lang::TableInit(init, _) => { - insn.table_init(TableIdx(init.table), ElemIdx(init.segment)) - } - Lang::TableCopy(cp, _) => insn.table_copy(TableIdx(cp.dst), TableIdx(cp.src)), - Lang::TableFill(table, _) => insn.table_fill(TableIdx(*table)), - Lang::ElemDrop(idx) => insn.elem_drop(ElemIdx(*idx)), - Lang::TableGrow(table, _) => insn.table_grow(TableIdx(*table)), - Lang::TableSize(table) => insn.table_size(TableIdx(*table)), - Lang::TableGet(table, _) => insn.table_get(TableIdx(*table)), - Lang::TableSet(table, _) => insn.table_set(TableIdx(*table)), + Lang::MemoryGrow(mem, _) => insn.memory_grow(*mem), + Lang::MemorySize(mem) => insn.memory_size(*mem), + Lang::MemoryInit(init, _) => insn.memory_init(init.memory, init.segment), + Lang::MemoryCopy(cp, _) => insn.memory_copy(cp.dst, cp.src), + Lang::MemoryFill(mem, _) => insn.memory_fill(*mem), + Lang::DataDrop(idx) => insn.data_drop(*idx), + Lang::TableInit(init, _) => insn.table_init(init.table, init.segment), + Lang::TableCopy(cp, _) => insn.table_copy(cp.dst, cp.src), + Lang::TableFill(table, _) => insn.table_fill(*table), + Lang::ElemDrop(idx) => insn.elem_drop(*idx), + Lang::TableGrow(table, _) => insn.table_grow(*table), + Lang::TableSize(table) => insn.table_size(*table), + Lang::TableGet(table, _) => insn.table_get(*table), + Lang::TableSet(table, _) => insn.table_set(*table), Lang::I32UseGlobal(_) => { // Request a new global let request = ResourceRequest::Global { @@ -346,7 +342,7 @@ pub fn expr2wasm( insn.global_set(global_idx); insn.global_get(global_idx); - global_idx.0 += 1; + global_idx += 1; insn } Lang::I64UseGlobal(_) => { @@ -359,7 +355,7 @@ pub fn expr2wasm( insn.global_set(global_idx); insn.global_get(global_idx); - global_idx.0 += 1; + global_idx += 1; insn } Lang::F32UseGlobal(_) => { @@ -372,7 +368,7 @@ pub fn expr2wasm( insn.global_set(global_idx); insn.global_get(global_idx); - global_idx.0 += 1; + global_idx += 1; insn } Lang::F64UseGlobal(_) => { @@ -385,11 +381,11 @@ pub fn expr2wasm( insn.global_set(global_idx); insn.global_get(global_idx); - global_idx.0 += 1; + global_idx += 1; insn } Lang::RefNull(valtype) => insn.ref_null((*valtype).into()), - Lang::RefFunc(idx) => insn.ref_func(FuncIdx(*idx)), + Lang::RefFunc(idx) => insn.ref_func(*idx), Lang::RefIsNull(_) => insn.ref_is_null(), Lang::V128Not(_) => insn.v128_not(), diff --git a/crates/wasmparser/tests/big-module.rs b/crates/wasmparser/tests/big-module.rs index 04a950a6d9..9064eba88b 100644 --- a/crates/wasmparser/tests/big-module.rs +++ b/crates/wasmparser/tests/big-module.rs @@ -20,7 +20,7 @@ fn big_type_indices() { let mut code = CodeSection::new(); let mut body = Function::new([]); - body.instructions().ref_func(FuncIdx(0)); + body.instructions().ref_func(0); body.instructions().drop(); body.instructions().end(); code.function(&body); diff --git a/crates/wit-component/src/encoding.rs b/crates/wit-component/src/encoding.rs index a34c404cdb..45f0fb9b87 100644 --- a/crates/wit-component/src/encoding.rs +++ b/crates/wit-component/src/encoding.rs @@ -1183,11 +1183,10 @@ impl<'a> EncodingState<'a> { ) { let mut func = wasm_encoder::Function::new(std::iter::empty()); for i in 0..param_count { - func.instructions().local_get(LocalIdx(i)); + func.instructions().local_get(i); } func.instructions().i32_const(func_index as i32); - func.instructions() - .call_indirect(TableIdx(0), TypeIdx(type_index)); + func.instructions().call_indirect(0, type_index); func.instructions().end(); code.function(&func); } diff --git a/crates/wit-component/src/gc.rs b/crates/wit-component/src/gc.rs index 5b1aa38c1b..9a1747f93d 100644 --- a/crates/wit-component/src/gc.rs +++ b/crates/wit-component/src/gc.rs @@ -8,9 +8,7 @@ use std::{ mem, ops::Deref, }; -use wasm_encoder::{ - reencode::Reencode, Encode, EntityType, FuncIdx, GlobalIdx, LocalIdx, MemIdx, RawCustomSection, -}; +use wasm_encoder::{reencode::Reencode, Encode, EntityType, RawCustomSection}; use wasmparser::*; const PAGE_SIZE: i32 = 64 * 1024; @@ -58,7 +56,7 @@ fn realloc_via_memory_grow() -> wasm_encoder::Function { // Assert `old_ptr` is null. func.instructions().i32_const(0); - func.instructions().local_get(LocalIdx(0)); + func.instructions().local_get(0); func.instructions().i32_ne(); func.instructions().if_(wasm_encoder::BlockType::Empty); func.instructions().unreachable(); @@ -66,7 +64,7 @@ fn realloc_via_memory_grow() -> wasm_encoder::Function { // Assert `old_len` is zero. func.instructions().i32_const(0); - func.instructions().local_get(LocalIdx(1)); + func.instructions().local_get(1); func.instructions().i32_ne(); func.instructions().if_(wasm_encoder::BlockType::Empty); func.instructions().unreachable(); @@ -75,7 +73,7 @@ fn realloc_via_memory_grow() -> wasm_encoder::Function { // Assert `new_len` is equal to the page size (which is the only value we currently support) // Note: we could easily support arbitrary multiples of PAGE_SIZE here if the need arises. func.instructions().i32_const(PAGE_SIZE); - func.instructions().local_get(LocalIdx(3)); + func.instructions().local_get(3); func.instructions().i32_ne(); func.instructions().if_(wasm_encoder::BlockType::Empty); func.instructions().unreachable(); @@ -83,8 +81,8 @@ fn realloc_via_memory_grow() -> wasm_encoder::Function { // Grow the memory by 1 page. func.instructions().i32_const(1); - func.instructions().memory_grow(MemIdx(0)); - func.instructions().local_tee(LocalIdx(4)); + func.instructions().memory_grow(0); + func.instructions().local_tee(4); // Test if the return value of the growth was -1 and, if so, trap due to a failed allocation. func.instructions().i32_const(-1); @@ -93,7 +91,7 @@ fn realloc_via_memory_grow() -> wasm_encoder::Function { func.instructions().unreachable(); func.instructions().end(); - func.instructions().local_get(LocalIdx(4)); + func.instructions().local_get(4); func.instructions().i32_const(16); func.instructions().i32_shl(); func.instructions().end(); @@ -110,9 +108,9 @@ enum StackAllocationState { } fn allocate_stack_via_realloc( - realloc_index: FuncIdx, - sp: GlobalIdx, - allocation_state: Option, + realloc_index: u32, + sp: u32, + allocation_state: Option, ) -> wasm_encoder::Function { let mut func = wasm_encoder::Function::new([]); @@ -596,7 +594,7 @@ impl<'a> Module<'a> { // The adapter is importing `cabi_realloc` from the main module, and the main module // exports that function, but possibly using a different name // (e.g. `canonical_abi_realloc`). Update the name to match if necessary. - realloc_index = Some(FuncIdx(num_func_imports)); + realloc_index = Some(num_func_imports); main_module_realloc.unwrap_or(n) } else { n @@ -628,8 +626,8 @@ impl<'a> Module<'a> { type_index }; - let sp = self.find_mut_i32_global("__stack_pointer")?.map(GlobalIdx); - let allocation_state = self.find_mut_i32_global("allocation_state")?.map(GlobalIdx); + let sp = self.find_mut_i32_global("__stack_pointer")?; + let allocation_state = self.find_mut_i32_global("allocation_state")?; let mut func_names = Vec::new(); @@ -640,7 +638,7 @@ impl<'a> Module<'a> { // Tell the function remapper we're reserving a slot for our extra import: map.funcs.next += 1; - realloc_index = Some(FuncIdx(num_func_imports)); + realloc_index = Some(num_func_imports); imports.import( "__main_module__", realloc, @@ -657,7 +655,7 @@ impl<'a> Module<'a> { Definition::Import(_, _) => { // The adapter is importing `cabi_realloc` from the main module, but the main module isn't // exporting it. In this case, we need to define a local function it can call instead. - realloc_index = Some(FuncIdx(num_func_imports + funcs.len())); + realloc_index = Some(num_func_imports + funcs.len()); funcs.function(ty); code.function(&realloc_via_memory_grow()); } @@ -672,7 +670,7 @@ impl<'a> Module<'a> { // We have a stack pointer, a `cabi_realloc` function from the main module, and a global variable for // keeping track of (and short-circuiting) reentrance. That means we can (and should) do lazy stack // allocation. - let index = FuncIdx(num_func_imports + funcs.len()); + let index = num_func_imports + funcs.len(); // Tell the function remapper we're reserving a slot for our extra function: map.funcs.next += 1; @@ -728,7 +726,7 @@ impl<'a> Module<'a> { if sp.is_some() && (realloc_index.is_none() || allocation_state.is_none()) { // Either the main module does _not_ export a realloc function, or it is not safe to use for stack // allocation because we have no way to short-circuit reentrance, so we'll use `memory.grow` instead. - realloc_index = Some(FuncIdx(num_func_imports + funcs.len())); + realloc_index = Some(num_func_imports + funcs.len()); funcs.function(add_realloc_type(&mut types)); code.function(&realloc_via_memory_grow()); } @@ -746,7 +744,7 @@ impl<'a> Module<'a> { bail!("adapter modules don't support multi-memory"); } - let sp = GlobalIdx(map.globals.remap(sp.0)); + let sp = map.globals.remap(sp); let function_index = num_func_imports + funcs.len(); @@ -877,10 +875,10 @@ impl<'a> Module<'a> { realloc_index, main_module_realloc.is_none() || allocation_state.is_none(), ) { - func_names.push((realloc_index.0, "realloc_via_memory_grow")); + func_names.push((realloc_index, "realloc_via_memory_grow")); } if let Some(lazy_stack_init_index) = lazy_stack_init_index { - func_names.push((lazy_stack_init_index.0, "allocate_stack")); + func_names.push((lazy_stack_init_index, "allocate_stack")); } encode_subsection(0x01, &func_names); encode_subsection(0x07, &global_names); From 4f916da15813f72e79d633a01fdcf61846854e60 Mon Sep 17 00:00:00 2001 From: Sam Estep Date: Tue, 11 Feb 2025 21:22:42 -0500 Subject: [PATCH 4/4] Fix build --- crates/wasm-encoder/src/core/instructions.rs | 36 ++++++++++++-------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/crates/wasm-encoder/src/core/instructions.rs b/crates/wasm-encoder/src/core/instructions.rs index d327c48b1a..d372aa3258 100644 --- a/crates/wasm-encoder/src/core/instructions.rs +++ b/crates/wasm-encoder/src/core/instructions.rs @@ -80,11 +80,10 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::BrTable`]. - pub fn br_table( - &mut self, - ls: impl IntoIterator, - l: u32, - ) -> &mut Self { + pub fn br_table>(&mut self, ls: V, l: u32) -> &mut Self + where + V::IntoIter: ExactSizeIterator, + { self.sink.push(0x0E); encode_vec(ls, self.sink); l.encode(self.sink); @@ -156,11 +155,14 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::TryTable`]. - pub fn try_table( + pub fn try_table>( &mut self, ty: BlockType, - catches: impl IntoIterator, - ) -> &mut Self { + catches: V, + ) -> &mut Self + where + V::IntoIter: ExactSizeIterator, + { self.sink.push(0x1f); ty.encode(self.sink); encode_vec(catches, self.sink); @@ -4555,11 +4557,14 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::Resume`]. - pub fn resume( + pub fn resume>( &mut self, cont_type_index: u32, - resume_table: impl IntoIterator, - ) -> &mut Self { + resume_table: V, + ) -> &mut Self + where + V::IntoIter: ExactSizeIterator, + { self.sink.push(0xE3); cont_type_index.encode(self.sink); encode_vec(resume_table, self.sink); @@ -4567,12 +4572,15 @@ impl<'a> InstructionSink<'a> { } /// Encode [`Instruction::ResumeThrow`]. - pub fn resume_throw( + pub fn resume_throw>( &mut self, cont_type_index: u32, tag_index: u32, - resume_table: impl IntoIterator, - ) -> &mut Self { + resume_table: V, + ) -> &mut Self + where + V::IntoIter: ExactSizeIterator, + { self.sink.push(0xE4); cont_type_index.encode(self.sink); tag_index.encode(self.sink);