use crate::{
encode_section, Encode, HeapType, InstructionSink, RefType, Section, SectionId, ValType,
};
use alloc::borrow::Cow;
use alloc::vec;
use alloc::vec::Vec;
#[derive(Clone, Default, Debug)]
pub struct CodeSection {
bytes: Vec<u8>,
num_added: u32,
}
impl CodeSection {
pub fn new() -> Self {
Self::default()
}
pub fn len(&self) -> u32 {
self.num_added
}
pub fn byte_len(&self) -> usize {
self.bytes.len()
}
pub fn is_empty(&self) -> bool {
self.num_added == 0
}
pub fn function(&mut self, func: &Function) -> &mut Self {
func.encode(&mut self.bytes);
self.num_added += 1;
self
}
pub fn raw(&mut self, data: &[u8]) -> &mut Self {
data.encode(&mut self.bytes);
self.num_added += 1;
self
}
}
impl Encode for CodeSection {
fn encode(&self, sink: &mut Vec<u8>) {
encode_section(sink, self.num_added, &self.bytes);
}
}
impl Section for CodeSection {
fn id(&self) -> u8 {
SectionId::Code.into()
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Function {
bytes: Vec<u8>,
}
impl Function {
pub fn new<L>(locals: L) -> Self
where
L: IntoIterator<Item = (u32, ValType)>,
L::IntoIter: ExactSizeIterator,
{
let locals = locals.into_iter();
let mut bytes = vec![];
locals.len().encode(&mut bytes);
for (count, ty) in locals {
count.encode(&mut bytes);
ty.encode(&mut bytes);
}
Function { bytes }
}
pub fn new_with_locals_types<L>(locals: L) -> Self
where
L: IntoIterator<Item = ValType>,
{
let locals = locals.into_iter();
let mut locals_collected: Vec<(u32, ValType)> = vec![];
for l in locals {
if let Some((last_count, last_type)) = locals_collected.last_mut() {
if l == *last_type {
*last_count += 1;
continue;
}
}
locals_collected.push((1, l));
}
Function::new(locals_collected)
}
pub fn instructions(&mut self) -> InstructionSink {
InstructionSink::new(&mut self.bytes)
}
pub fn instruction(&mut self, instruction: &Instruction) -> &mut Self {
instruction.encode(&mut self.bytes);
self
}
pub fn raw<B>(&mut self, bytes: B) -> &mut Self
where
B: IntoIterator<Item = u8>,
{
self.bytes.extend(bytes);
self
}
pub fn byte_len(&self) -> usize {
self.bytes.len()
}
pub fn into_raw_body(self) -> Vec<u8> {
self.bytes
}
}
impl Encode for Function {
fn encode(&self, sink: &mut Vec<u8>) {
self.bytes.encode(sink);
}
}
#[derive(Clone, Copy, Debug)]
pub struct MemArg {
pub offset: u64,
pub align: u32,
pub memory_index: u32,
}
impl Encode for MemArg {
fn encode(&self, sink: &mut Vec<u8>) {
if self.memory_index == 0 {
self.align.encode(sink);
self.offset.encode(sink);
} else {
(self.align | (1 << 6)).encode(sink);
self.memory_index.encode(sink);
self.offset.encode(sink);
}
}
}
#[derive(Clone, Copy, Debug)]
pub enum Ordering {
AcqRel,
SeqCst,
}
impl Encode for Ordering {
fn encode(&self, sink: &mut Vec<u8>) {
let flag: u8 = match self {
Ordering::SeqCst => 0,
Ordering::AcqRel => 1,
};
sink.push(flag);
}
}
pub type Lane = u8;
#[derive(Clone, Copy, Debug)]
pub enum BlockType {
Empty,
Result(ValType),
FunctionType(u32),
}
impl Encode for BlockType {
fn encode(&self, sink: &mut Vec<u8>) {
match *self {
Self::Empty => sink.push(0x40),
Self::Result(ty) => ty.encode(sink),
Self::FunctionType(f) => (f as i64).encode(sink),
}
}
}
#[derive(Clone, Debug)]
#[non_exhaustive]
#[allow(missing_docs, non_camel_case_types)]
pub enum Instruction<'a> {
Unreachable,
Nop,
Block(BlockType),
Loop(BlockType),
If(BlockType),
Else,
End,
Br(u32),
BrIf(u32),
BrTable(Cow<'a, [u32]>, u32),
BrOnNull(u32),
BrOnNonNull(u32),
Return,
Call(u32),
CallRef(u32),
CallIndirect {
type_index: u32,
table_index: u32,
},
ReturnCallRef(u32),
ReturnCall(u32),
ReturnCallIndirect {
type_index: u32,
table_index: u32,
},
TryTable(BlockType, Cow<'a, [Catch]>),
Throw(u32),
ThrowRef,
Try(BlockType),
Delegate(u32),
Catch(u32),
CatchAll,
Rethrow(u32),
Drop,
Select,
LocalGet(u32),
LocalSet(u32),
LocalTee(u32),
GlobalGet(u32),
GlobalSet(u32),
I32Load(MemArg),
I64Load(MemArg),
F32Load(MemArg),
F64Load(MemArg),
I32Load8S(MemArg),
I32Load8U(MemArg),
I32Load16S(MemArg),
I32Load16U(MemArg),
I64Load8S(MemArg),
I64Load8U(MemArg),
I64Load16S(MemArg),
I64Load16U(MemArg),
I64Load32S(MemArg),
I64Load32U(MemArg),
I32Store(MemArg),
I64Store(MemArg),
F32Store(MemArg),
F64Store(MemArg),
I32Store8(MemArg),
I32Store16(MemArg),
I64Store8(MemArg),
I64Store16(MemArg),
I64Store32(MemArg),
MemorySize(u32),
MemoryGrow(u32),
MemoryInit {
mem: u32,
data_index: u32,
},
DataDrop(u32),
MemoryCopy {
src_mem: u32,
dst_mem: u32,
},
MemoryFill(u32),
MemoryDiscard(u32),
I32Const(i32),
I64Const(i64),
F32Const(f32),
F64Const(f64),
I32Eqz,
I32Eq,
I32Ne,
I32LtS,
I32LtU,
I32GtS,
I32GtU,
I32LeS,
I32LeU,
I32GeS,
I32GeU,
I64Eqz,
I64Eq,
I64Ne,
I64LtS,
I64LtU,
I64GtS,
I64GtU,
I64LeS,
I64LeU,
I64GeS,
I64GeU,
F32Eq,
F32Ne,
F32Lt,
F32Gt,
F32Le,
F32Ge,
F64Eq,
F64Ne,
F64Lt,
F64Gt,
F64Le,
F64Ge,
I32Clz,
I32Ctz,
I32Popcnt,
I32Add,
I32Sub,
I32Mul,
I32DivS,
I32DivU,
I32RemS,
I32RemU,
I32And,
I32Or,
I32Xor,
I32Shl,
I32ShrS,
I32ShrU,
I32Rotl,
I32Rotr,
I64Clz,
I64Ctz,
I64Popcnt,
I64Add,
I64Sub,
I64Mul,
I64DivS,
I64DivU,
I64RemS,
I64RemU,
I64And,
I64Or,
I64Xor,
I64Shl,
I64ShrS,
I64ShrU,
I64Rotl,
I64Rotr,
F32Abs,
F32Neg,
F32Ceil,
F32Floor,
F32Trunc,
F32Nearest,
F32Sqrt,
F32Add,
F32Sub,
F32Mul,
F32Div,
F32Min,
F32Max,
F32Copysign,
F64Abs,
F64Neg,
F64Ceil,
F64Floor,
F64Trunc,
F64Nearest,
F64Sqrt,
F64Add,
F64Sub,
F64Mul,
F64Div,
F64Min,
F64Max,
F64Copysign,
I32WrapI64,
I32TruncF32S,
I32TruncF32U,
I32TruncF64S,
I32TruncF64U,
I64ExtendI32S,
I64ExtendI32U,
I64TruncF32S,
I64TruncF32U,
I64TruncF64S,
I64TruncF64U,
F32ConvertI32S,
F32ConvertI32U,
F32ConvertI64S,
F32ConvertI64U,
F32DemoteF64,
F64ConvertI32S,
F64ConvertI32U,
F64ConvertI64S,
F64ConvertI64U,
F64PromoteF32,
I32ReinterpretF32,
I64ReinterpretF64,
F32ReinterpretI32,
F64ReinterpretI64,
I32Extend8S,
I32Extend16S,
I64Extend8S,
I64Extend16S,
I64Extend32S,
I32TruncSatF32S,
I32TruncSatF32U,
I32TruncSatF64S,
I32TruncSatF64U,
I64TruncSatF32S,
I64TruncSatF32U,
I64TruncSatF64S,
I64TruncSatF64U,
TypedSelect(ValType),
RefNull(HeapType),
RefIsNull,
RefFunc(u32),
RefEq,
RefAsNonNull,
StructNew(u32),
StructNewDefault(u32),
StructGet {
struct_type_index: u32,
field_index: u32,
},
StructGetS {
struct_type_index: u32,
field_index: u32,
},
StructGetU {
struct_type_index: u32,
field_index: u32,
},
StructSet {
struct_type_index: u32,
field_index: u32,
},
ArrayNew(u32),
ArrayNewDefault(u32),
ArrayNewFixed {
array_type_index: u32,
array_size: u32,
},
ArrayNewData {
array_type_index: u32,
array_data_index: u32,
},
ArrayNewElem {
array_type_index: u32,
array_elem_index: u32,
},
ArrayGet(u32),
ArrayGetS(u32),
ArrayGetU(u32),
ArraySet(u32),
ArrayLen,
ArrayFill(u32),
ArrayCopy {
array_type_index_dst: u32,
array_type_index_src: u32,
},
ArrayInitData {
array_type_index: u32,
array_data_index: u32,
},
ArrayInitElem {
array_type_index: u32,
array_elem_index: u32,
},
RefTestNonNull(HeapType),
RefTestNullable(HeapType),
RefCastNonNull(HeapType),
RefCastNullable(HeapType),
BrOnCast {
relative_depth: u32,
from_ref_type: RefType,
to_ref_type: RefType,
},
BrOnCastFail {
relative_depth: u32,
from_ref_type: RefType,
to_ref_type: RefType,
},
AnyConvertExtern,
ExternConvertAny,
RefI31,
I31GetS,
I31GetU,
TableInit {
elem_index: u32,
table: u32,
},
ElemDrop(u32),
TableFill(u32),
TableSet(u32),
TableGet(u32),
TableGrow(u32),
TableSize(u32),
TableCopy {
src_table: u32,
dst_table: u32,
},
V128Load(MemArg),
V128Load8x8S(MemArg),
V128Load8x8U(MemArg),
V128Load16x4S(MemArg),
V128Load16x4U(MemArg),
V128Load32x2S(MemArg),
V128Load32x2U(MemArg),
V128Load8Splat(MemArg),
V128Load16Splat(MemArg),
V128Load32Splat(MemArg),
V128Load64Splat(MemArg),
V128Load32Zero(MemArg),
V128Load64Zero(MemArg),
V128Store(MemArg),
V128Load8Lane {
memarg: MemArg,
lane: Lane,
},
V128Load16Lane {
memarg: MemArg,
lane: Lane,
},
V128Load32Lane {
memarg: MemArg,
lane: Lane,
},
V128Load64Lane {
memarg: MemArg,
lane: Lane,
},
V128Store8Lane {
memarg: MemArg,
lane: Lane,
},
V128Store16Lane {
memarg: MemArg,
lane: Lane,
},
V128Store32Lane {
memarg: MemArg,
lane: Lane,
},
V128Store64Lane {
memarg: MemArg,
lane: Lane,
},
V128Const(i128),
I8x16Shuffle([Lane; 16]),
I8x16ExtractLaneS(Lane),
I8x16ExtractLaneU(Lane),
I8x16ReplaceLane(Lane),
I16x8ExtractLaneS(Lane),
I16x8ExtractLaneU(Lane),
I16x8ReplaceLane(Lane),
I32x4ExtractLane(Lane),
I32x4ReplaceLane(Lane),
I64x2ExtractLane(Lane),
I64x2ReplaceLane(Lane),
F32x4ExtractLane(Lane),
F32x4ReplaceLane(Lane),
F64x2ExtractLane(Lane),
F64x2ReplaceLane(Lane),
I8x16Swizzle,
I8x16Splat,
I16x8Splat,
I32x4Splat,
I64x2Splat,
F32x4Splat,
F64x2Splat,
I8x16Eq,
I8x16Ne,
I8x16LtS,
I8x16LtU,
I8x16GtS,
I8x16GtU,
I8x16LeS,
I8x16LeU,
I8x16GeS,
I8x16GeU,
I16x8Eq,
I16x8Ne,
I16x8LtS,
I16x8LtU,
I16x8GtS,
I16x8GtU,
I16x8LeS,
I16x8LeU,
I16x8GeS,
I16x8GeU,
I32x4Eq,
I32x4Ne,
I32x4LtS,
I32x4LtU,
I32x4GtS,
I32x4GtU,
I32x4LeS,
I32x4LeU,
I32x4GeS,
I32x4GeU,
I64x2Eq,
I64x2Ne,
I64x2LtS,
I64x2GtS,
I64x2LeS,
I64x2GeS,
F32x4Eq,
F32x4Ne,
F32x4Lt,
F32x4Gt,
F32x4Le,
F32x4Ge,
F64x2Eq,
F64x2Ne,
F64x2Lt,
F64x2Gt,
F64x2Le,
F64x2Ge,
V128Not,
V128And,
V128AndNot,
V128Or,
V128Xor,
V128Bitselect,
V128AnyTrue,
I8x16Abs,
I8x16Neg,
I8x16Popcnt,
I8x16AllTrue,
I8x16Bitmask,
I8x16NarrowI16x8S,
I8x16NarrowI16x8U,
I8x16Shl,
I8x16ShrS,
I8x16ShrU,
I8x16Add,
I8x16AddSatS,
I8x16AddSatU,
I8x16Sub,
I8x16SubSatS,
I8x16SubSatU,
I8x16MinS,
I8x16MinU,
I8x16MaxS,
I8x16MaxU,
I8x16AvgrU,
I16x8ExtAddPairwiseI8x16S,
I16x8ExtAddPairwiseI8x16U,
I16x8Abs,
I16x8Neg,
I16x8Q15MulrSatS,
I16x8AllTrue,
I16x8Bitmask,
I16x8NarrowI32x4S,
I16x8NarrowI32x4U,
I16x8ExtendLowI8x16S,
I16x8ExtendHighI8x16S,
I16x8ExtendLowI8x16U,
I16x8ExtendHighI8x16U,
I16x8Shl,
I16x8ShrS,
I16x8ShrU,
I16x8Add,
I16x8AddSatS,
I16x8AddSatU,
I16x8Sub,
I16x8SubSatS,
I16x8SubSatU,
I16x8Mul,
I16x8MinS,
I16x8MinU,
I16x8MaxS,
I16x8MaxU,
I16x8AvgrU,
I16x8ExtMulLowI8x16S,
I16x8ExtMulHighI8x16S,
I16x8ExtMulLowI8x16U,
I16x8ExtMulHighI8x16U,
I32x4ExtAddPairwiseI16x8S,
I32x4ExtAddPairwiseI16x8U,
I32x4Abs,
I32x4Neg,
I32x4AllTrue,
I32x4Bitmask,
I32x4ExtendLowI16x8S,
I32x4ExtendHighI16x8S,
I32x4ExtendLowI16x8U,
I32x4ExtendHighI16x8U,
I32x4Shl,
I32x4ShrS,
I32x4ShrU,
I32x4Add,
I32x4Sub,
I32x4Mul,
I32x4MinS,
I32x4MinU,
I32x4MaxS,
I32x4MaxU,
I32x4DotI16x8S,
I32x4ExtMulLowI16x8S,
I32x4ExtMulHighI16x8S,
I32x4ExtMulLowI16x8U,
I32x4ExtMulHighI16x8U,
I64x2Abs,
I64x2Neg,
I64x2AllTrue,
I64x2Bitmask,
I64x2ExtendLowI32x4S,
I64x2ExtendHighI32x4S,
I64x2ExtendLowI32x4U,
I64x2ExtendHighI32x4U,
I64x2Shl,
I64x2ShrS,
I64x2ShrU,
I64x2Add,
I64x2Sub,
I64x2Mul,
I64x2ExtMulLowI32x4S,
I64x2ExtMulHighI32x4S,
I64x2ExtMulLowI32x4U,
I64x2ExtMulHighI32x4U,
F32x4Ceil,
F32x4Floor,
F32x4Trunc,
F32x4Nearest,
F32x4Abs,
F32x4Neg,
F32x4Sqrt,
F32x4Add,
F32x4Sub,
F32x4Mul,
F32x4Div,
F32x4Min,
F32x4Max,
F32x4PMin,
F32x4PMax,
F64x2Ceil,
F64x2Floor,
F64x2Trunc,
F64x2Nearest,
F64x2Abs,
F64x2Neg,
F64x2Sqrt,
F64x2Add,
F64x2Sub,
F64x2Mul,
F64x2Div,
F64x2Min,
F64x2Max,
F64x2PMin,
F64x2PMax,
I32x4TruncSatF32x4S,
I32x4TruncSatF32x4U,
F32x4ConvertI32x4S,
F32x4ConvertI32x4U,
I32x4TruncSatF64x2SZero,
I32x4TruncSatF64x2UZero,
F64x2ConvertLowI32x4S,
F64x2ConvertLowI32x4U,
F32x4DemoteF64x2Zero,
F64x2PromoteLowF32x4,
I8x16RelaxedSwizzle,
I32x4RelaxedTruncF32x4S,
I32x4RelaxedTruncF32x4U,
I32x4RelaxedTruncF64x2SZero,
I32x4RelaxedTruncF64x2UZero,
F32x4RelaxedMadd,
F32x4RelaxedNmadd,
F64x2RelaxedMadd,
F64x2RelaxedNmadd,
I8x16RelaxedLaneselect,
I16x8RelaxedLaneselect,
I32x4RelaxedLaneselect,
I64x2RelaxedLaneselect,
F32x4RelaxedMin,
F32x4RelaxedMax,
F64x2RelaxedMin,
F64x2RelaxedMax,
I16x8RelaxedQ15mulrS,
I16x8RelaxedDotI8x16I7x16S,
I32x4RelaxedDotI8x16I7x16AddS,
MemoryAtomicNotify(MemArg),
MemoryAtomicWait32(MemArg),
MemoryAtomicWait64(MemArg),
AtomicFence,
I32AtomicLoad(MemArg),
I64AtomicLoad(MemArg),
I32AtomicLoad8U(MemArg),
I32AtomicLoad16U(MemArg),
I64AtomicLoad8U(MemArg),
I64AtomicLoad16U(MemArg),
I64AtomicLoad32U(MemArg),
I32AtomicStore(MemArg),
I64AtomicStore(MemArg),
I32AtomicStore8(MemArg),
I32AtomicStore16(MemArg),
I64AtomicStore8(MemArg),
I64AtomicStore16(MemArg),
I64AtomicStore32(MemArg),
I32AtomicRmwAdd(MemArg),
I64AtomicRmwAdd(MemArg),
I32AtomicRmw8AddU(MemArg),
I32AtomicRmw16AddU(MemArg),
I64AtomicRmw8AddU(MemArg),
I64AtomicRmw16AddU(MemArg),
I64AtomicRmw32AddU(MemArg),
I32AtomicRmwSub(MemArg),
I64AtomicRmwSub(MemArg),
I32AtomicRmw8SubU(MemArg),
I32AtomicRmw16SubU(MemArg),
I64AtomicRmw8SubU(MemArg),
I64AtomicRmw16SubU(MemArg),
I64AtomicRmw32SubU(MemArg),
I32AtomicRmwAnd(MemArg),
I64AtomicRmwAnd(MemArg),
I32AtomicRmw8AndU(MemArg),
I32AtomicRmw16AndU(MemArg),
I64AtomicRmw8AndU(MemArg),
I64AtomicRmw16AndU(MemArg),
I64AtomicRmw32AndU(MemArg),
I32AtomicRmwOr(MemArg),
I64AtomicRmwOr(MemArg),
I32AtomicRmw8OrU(MemArg),
I32AtomicRmw16OrU(MemArg),
I64AtomicRmw8OrU(MemArg),
I64AtomicRmw16OrU(MemArg),
I64AtomicRmw32OrU(MemArg),
I32AtomicRmwXor(MemArg),
I64AtomicRmwXor(MemArg),
I32AtomicRmw8XorU(MemArg),
I32AtomicRmw16XorU(MemArg),
I64AtomicRmw8XorU(MemArg),
I64AtomicRmw16XorU(MemArg),
I64AtomicRmw32XorU(MemArg),
I32AtomicRmwXchg(MemArg),
I64AtomicRmwXchg(MemArg),
I32AtomicRmw8XchgU(MemArg),
I32AtomicRmw16XchgU(MemArg),
I64AtomicRmw8XchgU(MemArg),
I64AtomicRmw16XchgU(MemArg),
I64AtomicRmw32XchgU(MemArg),
I32AtomicRmwCmpxchg(MemArg),
I64AtomicRmwCmpxchg(MemArg),
I32AtomicRmw8CmpxchgU(MemArg),
I32AtomicRmw16CmpxchgU(MemArg),
I64AtomicRmw8CmpxchgU(MemArg),
I64AtomicRmw16CmpxchgU(MemArg),
I64AtomicRmw32CmpxchgU(MemArg),
GlobalAtomicGet {
ordering: Ordering,
global_index: u32,
},
GlobalAtomicSet {
ordering: Ordering,
global_index: u32,
},
GlobalAtomicRmwAdd {
ordering: Ordering,
global_index: u32,
},
GlobalAtomicRmwSub {
ordering: Ordering,
global_index: u32,
},
GlobalAtomicRmwAnd {
ordering: Ordering,
global_index: u32,
},
GlobalAtomicRmwOr {
ordering: Ordering,
global_index: u32,
},
GlobalAtomicRmwXor {
ordering: Ordering,
global_index: u32,
},
GlobalAtomicRmwXchg {
ordering: Ordering,
global_index: u32,
},
GlobalAtomicRmwCmpxchg {
ordering: Ordering,
global_index: u32,
},
TableAtomicGet {
ordering: Ordering,
table_index: u32,
},
TableAtomicSet {
ordering: Ordering,
table_index: u32,
},
TableAtomicRmwXchg {
ordering: Ordering,
table_index: u32,
},
TableAtomicRmwCmpxchg {
ordering: Ordering,
table_index: u32,
},
StructAtomicGet {
ordering: Ordering,
struct_type_index: u32,
field_index: u32,
},
StructAtomicGetS {
ordering: Ordering,
struct_type_index: u32,
field_index: u32,
},
StructAtomicGetU {
ordering: Ordering,
struct_type_index: u32,
field_index: u32,
},
StructAtomicSet {
ordering: Ordering,
struct_type_index: u32,
field_index: u32,
},
StructAtomicRmwAdd {
ordering: Ordering,
struct_type_index: u32,
field_index: u32,
},
StructAtomicRmwSub {
ordering: Ordering,
struct_type_index: u32,
field_index: u32,
},
StructAtomicRmwAnd {
ordering: Ordering,
struct_type_index: u32,
field_index: u32,
},
StructAtomicRmwOr {
ordering: Ordering,
struct_type_index: u32,
field_index: u32,
},
StructAtomicRmwXor {
ordering: Ordering,
struct_type_index: u32,
field_index: u32,
},
StructAtomicRmwXchg {
ordering: Ordering,
struct_type_index: u32,
field_index: u32,
},
StructAtomicRmwCmpxchg {
ordering: Ordering,
struct_type_index: u32,
field_index: u32,
},
ArrayAtomicGet {
ordering: Ordering,
array_type_index: u32,
},
ArrayAtomicGetS {
ordering: Ordering,
array_type_index: u32,
},
ArrayAtomicGetU {
ordering: Ordering,
array_type_index: u32,
},
ArrayAtomicSet {
ordering: Ordering,
array_type_index: u32,
},
ArrayAtomicRmwAdd {
ordering: Ordering,
array_type_index: u32,
},
ArrayAtomicRmwSub {
ordering: Ordering,
array_type_index: u32,
},
ArrayAtomicRmwAnd {
ordering: Ordering,
array_type_index: u32,
},
ArrayAtomicRmwOr {
ordering: Ordering,
array_type_index: u32,
},
ArrayAtomicRmwXor {
ordering: Ordering,
array_type_index: u32,
},
ArrayAtomicRmwXchg {
ordering: Ordering,
array_type_index: u32,
},
ArrayAtomicRmwCmpxchg {
ordering: Ordering,
array_type_index: u32,
},
RefI31Shared,
ContNew(u32),
ContBind {
argument_index: u32,
result_index: u32,
},
Suspend(u32),
Resume {
cont_type_index: u32,
resume_table: Cow<'a, [Handle]>,
},
ResumeThrow {
cont_type_index: u32,
tag_index: u32,
resume_table: Cow<'a, [Handle]>,
},
Switch {
cont_type_index: u32,
tag_index: u32,
},
I64Add128,
I64Sub128,
I64MulWideS,
I64MulWideU,
}
impl Encode for Instruction<'_> {
fn encode(&self, bytes: &mut Vec<u8>) {
let mut sink = InstructionSink::new(bytes);
match *self {
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(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(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(f),
Instruction::CallRef(ty) => sink.call_ref(ty),
Instruction::CallIndirect {
type_index,
table_index,
} => sink.call_indirect(table_index, type_index),
Instruction::ReturnCallRef(ty) => sink.return_call_ref(ty),
Instruction::ReturnCall(f) => sink.return_call(f),
Instruction::ReturnCallIndirect {
type_index,
table_index,
} => sink.return_call_indirect(table_index, type_index),
Instruction::Delegate(l) => sink.delegate(l),
Instruction::CatchAll => sink.catch_all(),
Instruction::Drop => sink.drop(),
Instruction::Select => sink.select(),
Instruction::TypedSelect(ty) => sink.typed_select(ty),
Instruction::TryTable(ty, ref catches) => sink.try_table(ty, catches.iter().cloned()),
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),
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(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),
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(),
Instruction::RefNull(ty) => sink.ref_null(ty),
Instruction::RefIsNull => sink.ref_is_null(),
Instruction::RefFunc(f) => sink.ref_func(f),
Instruction::RefEq => sink.ref_eq(),
Instruction::RefAsNonNull => sink.ref_as_non_null(),
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(struct_type_index, field_index),
Instruction::StructGetS {
struct_type_index,
field_index,
} => sink.struct_get_s(struct_type_index, field_index),
Instruction::StructGetU {
struct_type_index,
field_index,
} => sink.struct_get_u(struct_type_index, field_index),
Instruction::StructSet {
struct_type_index,
field_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(array_type_index, array_size),
Instruction::ArrayNewData {
array_type_index,
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(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(type_index),
Instruction::ArrayCopy {
array_type_index_dst,
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(array_type_index, array_data_index),
Instruction::ArrayInitElem {
array_type_index,
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),
Instruction::RefCastNullable(heap_type) => sink.ref_cast_nullable(heap_type),
Instruction::BrOnCast {
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(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(),
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(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),
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()
}
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),
Instruction::GlobalAtomicGet {
ordering,
global_index,
} => sink.global_atomic_get(ordering, global_index),
Instruction::GlobalAtomicSet {
ordering,
global_index,
} => sink.global_atomic_set(ordering, global_index),
Instruction::GlobalAtomicRmwAdd {
ordering,
global_index,
} => sink.global_atomic_rmw_add(ordering, global_index),
Instruction::GlobalAtomicRmwSub {
ordering,
global_index,
} => sink.global_atomic_rmw_sub(ordering, global_index),
Instruction::GlobalAtomicRmwAnd {
ordering,
global_index,
} => sink.global_atomic_rmw_and(ordering, global_index),
Instruction::GlobalAtomicRmwOr {
ordering,
global_index,
} => sink.global_atomic_rmw_or(ordering, global_index),
Instruction::GlobalAtomicRmwXor {
ordering,
global_index,
} => sink.global_atomic_rmw_xor(ordering, global_index),
Instruction::GlobalAtomicRmwXchg {
ordering,
global_index,
} => sink.global_atomic_rmw_xchg(ordering, global_index),
Instruction::GlobalAtomicRmwCmpxchg {
ordering,
global_index,
} => sink.global_atomic_rmw_cmpxchg(ordering, global_index),
Instruction::TableAtomicGet {
ordering,
table_index,
} => sink.table_atomic_get(ordering, table_index),
Instruction::TableAtomicSet {
ordering,
table_index,
} => sink.table_atomic_set(ordering, table_index),
Instruction::TableAtomicRmwXchg {
ordering,
table_index,
} => sink.table_atomic_rmw_xchg(ordering, table_index),
Instruction::TableAtomicRmwCmpxchg {
ordering,
table_index,
} => sink.table_atomic_rmw_cmpxchg(ordering, table_index),
Instruction::StructAtomicGet {
ordering,
struct_type_index,
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, struct_type_index, field_index),
Instruction::StructAtomicGetU {
ordering,
struct_type_index,
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, struct_type_index, field_index),
Instruction::StructAtomicRmwAdd {
ordering,
struct_type_index,
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, struct_type_index, field_index),
Instruction::StructAtomicRmwAnd {
ordering,
struct_type_index,
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, struct_type_index, field_index),
Instruction::StructAtomicRmwXor {
ordering,
struct_type_index,
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, struct_type_index, field_index),
Instruction::StructAtomicRmwCmpxchg {
ordering,
struct_type_index,
field_index,
} => sink.struct_atomic_rmw_cmpxchg(ordering, struct_type_index, field_index),
Instruction::ArrayAtomicGet {
ordering,
array_type_index,
} => sink.array_atomic_get(ordering, array_type_index),
Instruction::ArrayAtomicGetS {
ordering,
array_type_index,
} => sink.array_atomic_get_s(ordering, array_type_index),
Instruction::ArrayAtomicGetU {
ordering,
array_type_index,
} => sink.array_atomic_get_u(ordering, array_type_index),
Instruction::ArrayAtomicSet {
ordering,
array_type_index,
} => sink.array_atomic_set(ordering, array_type_index),
Instruction::ArrayAtomicRmwAdd {
ordering,
array_type_index,
} => sink.array_atomic_rmw_add(ordering, array_type_index),
Instruction::ArrayAtomicRmwSub {
ordering,
array_type_index,
} => sink.array_atomic_rmw_sub(ordering, array_type_index),
Instruction::ArrayAtomicRmwAnd {
ordering,
array_type_index,
} => sink.array_atomic_rmw_and(ordering, array_type_index),
Instruction::ArrayAtomicRmwOr {
ordering,
array_type_index,
} => sink.array_atomic_rmw_or(ordering, array_type_index),
Instruction::ArrayAtomicRmwXor {
ordering,
array_type_index,
} => sink.array_atomic_rmw_xor(ordering, array_type_index),
Instruction::ArrayAtomicRmwXchg {
ordering,
array_type_index,
} => sink.array_atomic_rmw_xchg(ordering, array_type_index),
Instruction::ArrayAtomicRmwCmpxchg {
ordering,
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(type_index),
Instruction::ContBind {
argument_index,
result_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(cont_type_index, resume_table.iter().cloned()),
Instruction::ResumeThrow {
cont_type_index,
tag_index,
ref resume_table,
} => sink.resume_throw(cont_type_index, tag_index, resume_table.iter().cloned()),
Instruction::Switch {
cont_type_index,
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(),
Instruction::I64MulWideU => sink.i64_mul_wide_u(),
};
}
}
#[derive(Clone, Debug)]
#[allow(missing_docs)]
pub enum Catch {
One { tag: u32, label: u32 },
OneRef { tag: u32, label: u32 },
All { label: u32 },
AllRef { label: u32 },
}
impl Encode for Catch {
fn encode(&self, sink: &mut Vec<u8>) {
match self {
Catch::One { tag, label } => {
sink.push(0x00);
tag.encode(sink);
label.encode(sink);
}
Catch::OneRef { tag, label } => {
sink.push(0x01);
tag.encode(sink);
label.encode(sink);
}
Catch::All { label } => {
sink.push(0x02);
label.encode(sink);
}
Catch::AllRef { label } => {
sink.push(0x03);
label.encode(sink);
}
}
}
}
#[derive(Clone, Debug)]
#[allow(missing_docs)]
pub enum Handle {
OnLabel { tag: u32, label: u32 },
OnSwitch { tag: u32 },
}
impl Encode for Handle {
fn encode(&self, sink: &mut Vec<u8>) {
match self {
Handle::OnLabel { tag, label } => {
sink.push(0x00);
tag.encode(sink);
label.encode(sink);
}
Handle::OnSwitch { tag } => {
sink.push(0x01);
tag.encode(sink);
}
}
}
}
#[derive(Clone, Debug)]
pub struct ConstExpr {
bytes: Vec<u8>,
}
impl ConstExpr {
pub fn empty() -> Self {
Self { bytes: Vec::new() }
}
pub fn raw(bytes: impl IntoIterator<Item = u8>) -> Self {
Self {
bytes: bytes.into_iter().collect(),
}
}
pub fn extended<'a>(insns: impl IntoIterator<Item = Instruction<'a>>) -> Self {
let mut bytes = vec![];
for insn in insns {
insn.encode(&mut bytes);
}
Self { bytes }
}
fn new<F>(f: F) -> Self
where
for<'a, 'b> F: FnOnce(&'a mut InstructionSink<'b>) -> &'a mut InstructionSink<'b>,
{
let mut bytes = vec![];
f(&mut InstructionSink::new(&mut bytes));
Self { bytes }
}
fn with<F>(mut self, f: F) -> Self
where
for<'a, 'b> F: FnOnce(&'a mut InstructionSink<'b>) -> &'a mut InstructionSink<'b>,
{
f(&mut InstructionSink::new(&mut self.bytes));
self
}
pub fn global_get(index: u32) -> Self {
Self::new(|insn| insn.global_get(index))
}
pub fn ref_null(ty: HeapType) -> Self {
Self::new(|insn| insn.ref_null(ty))
}
pub fn ref_func(func: u32) -> Self {
Self::new(|insn| insn.ref_func(func))
}
pub fn i32_const(value: i32) -> Self {
Self::new(|insn| insn.i32_const(value))
}
pub fn i64_const(value: i64) -> Self {
Self::new(|insn| insn.i64_const(value))
}
pub fn f32_const(value: f32) -> Self {
Self::new(|insn| insn.f32_const(value))
}
pub fn f64_const(value: f64) -> Self {
Self::new(|insn| insn.f64_const(value))
}
pub fn v128_const(value: i128) -> Self {
Self::new(|insn| insn.v128_const(value))
}
pub fn with_global_get(self, index: u32) -> Self {
self.with(|insn| insn.global_get(index))
}
pub fn with_ref_null(self, ty: HeapType) -> Self {
self.with(|insn| insn.ref_null(ty))
}
pub fn with_ref_func(self, func: u32) -> Self {
self.with(|insn| insn.ref_func(func))
}
pub fn with_i32_const(self, value: i32) -> Self {
self.with(|insn| insn.i32_const(value))
}
pub fn with_i64_const(self, value: i64) -> Self {
self.with(|insn| insn.i64_const(value))
}
pub fn with_f32_const(self, value: f32) -> Self {
self.with(|insn| insn.f32_const(value))
}
pub fn with_f64_const(self, value: f64) -> Self {
self.with(|insn| insn.f64_const(value))
}
pub fn with_v128_const(self, value: i128) -> Self {
self.with(|insn| insn.v128_const(value))
}
pub fn with_i32_add(self) -> Self {
self.with(|insn| insn.i32_add())
}
pub fn with_i32_sub(self) -> Self {
self.with(|insn| insn.i32_sub())
}
pub fn with_i32_mul(self) -> Self {
self.with(|insn| insn.i32_mul())
}
pub fn with_i64_add(self) -> Self {
self.with(|insn| insn.i64_add())
}
pub fn with_i64_sub(self) -> Self {
self.with(|insn| insn.i64_sub())
}
pub fn with_i64_mul(self) -> Self {
self.with(|insn| insn.i64_mul())
}
pub fn get_ref_func(&self) -> Option<u32> {
let prefix = *self.bytes.get(0)?;
if prefix != 0xd2 {
return None;
}
leb128fmt::decode_uint_slice::<u32, 32>(&self.bytes[1..], &mut 0).ok()
}
}
impl Encode for ConstExpr {
fn encode(&self, sink: &mut Vec<u8>) {
sink.extend(&self.bytes);
InstructionSink::new(sink).end();
}
}
#[cfg(test)]
mod tests {
#[test]
fn function_new_with_locals_test() {
use super::*;
let f1 = Function::new_with_locals_types([
ValType::I32,
ValType::I32,
ValType::I64,
ValType::F32,
ValType::F32,
ValType::F32,
ValType::I32,
ValType::I64,
ValType::I64,
]);
let f2 = Function::new([
(2, ValType::I32),
(1, ValType::I64),
(3, ValType::F32),
(1, ValType::I32),
(2, ValType::I64),
]);
assert_eq!(f1.bytes, f2.bytes)
}
#[test]
fn func_raw_bytes() {
use super::*;
let mut f = Function::new([(1, ValType::I32), (1, ValType::F32)]);
f.instructions().end();
let mut code_from_func = CodeSection::new();
code_from_func.function(&f);
let bytes = f.into_raw_body();
let mut code_from_raw = CodeSection::new();
code_from_raw.raw(&bytes[..]);
let mut c1 = vec![];
code_from_func.encode(&mut c1);
let mut c2 = vec![];
code_from_raw.encode(&mut c2);
assert_eq!(c1, c2);
}
}