use crate::{encode_section, Encode, HeapType, RefType, Section, SectionId, ValType};
use std::borrow::Cow;
#[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 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()
}
}
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 {
ty: u32,
table: u32,
},
ReturnCallRef(u32),
ReturnCall(u32),
ReturnCallIndirect {
ty: u32,
table: 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,
},
}
impl Encode for Instruction<'_> {
fn encode(&self, sink: &mut Vec<u8>) {
match *self {
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::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);
}
Instruction::CallIndirect { ty, table } => {
sink.push(0x11);
ty.encode(sink);
table.encode(sink);
}
Instruction::ReturnCallRef(ty) => {
sink.push(0x15);
ty.encode(sink);
}
Instruction::ReturnCall(f) => {
sink.push(0x12);
f.encode(sink);
}
Instruction::ReturnCallIndirect { ty, table } => {
sink.push(0x13);
ty.encode(sink);
table.encode(sink);
}
Instruction::Delegate(l) => {
sink.push(0x18);
l.encode(sink);
}
Instruction::CatchAll => {
sink.push(0x19);
}
Instruction::Drop => sink.push(0x1A),
Instruction::Select => sink.push(0x1B),
Instruction::TypedSelect(ty) => {
sink.push(0x1c);
[ty].encode(sink);
}
Instruction::TryTable(ty, ref catches) => {
sink.push(0x1f);
ty.encode(sink);
catches.encode(sink);
}
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::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::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);
}
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);
}
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::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::StructNew(type_index) => {
sink.push(0xfb);
sink.push(0x00);
type_index.encode(sink);
}
Instruction::StructNewDefault(type_index) => {
sink.push(0xfb);
sink.push(0x01);
type_index.encode(sink);
}
Instruction::StructGet {
struct_type_index,
field_index,
} => {
sink.push(0xfb);
sink.push(0x02);
struct_type_index.encode(sink);
field_index.encode(sink);
}
Instruction::StructGetS {
struct_type_index,
field_index,
} => {
sink.push(0xfb);
sink.push(0x03);
struct_type_index.encode(sink);
field_index.encode(sink);
}
Instruction::StructGetU {
struct_type_index,
field_index,
} => {
sink.push(0xfb);
sink.push(0x04);
struct_type_index.encode(sink);
field_index.encode(sink);
}
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);
}
Instruction::ArrayNewFixed {
array_type_index,
array_size,
} => {
sink.push(0xfb);
sink.push(0x08);
array_type_index.encode(sink);
array_size.encode(sink);
}
Instruction::ArrayNewData {
array_type_index,
array_data_index,
} => {
sink.push(0xfb);
sink.push(0x09);
array_type_index.encode(sink);
array_data_index.encode(sink);
}
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);
}
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);
}
Instruction::ArrayInitData {
array_type_index,
array_data_index,
} => {
sink.push(0xfb);
sink.push(0x12);
array_type_index.encode(sink);
array_data_index.encode(sink);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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::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::GlobalAtomicGet {
ordering,
global_index,
} => {
sink.push(0xFE);
sink.push(0x4F);
ordering.encode(sink);
global_index.encode(sink);
}
Instruction::GlobalAtomicSet {
ordering,
global_index,
} => {
sink.push(0xFE);
sink.push(0x50);
ordering.encode(sink);
global_index.encode(sink);
}
Instruction::GlobalAtomicRmwAdd {
ordering,
global_index,
} => {
sink.push(0xFE);
sink.push(0x51);
ordering.encode(sink);
global_index.encode(sink);
}
Instruction::GlobalAtomicRmwSub {
ordering,
global_index,
} => {
sink.push(0xFE);
sink.push(0x52);
ordering.encode(sink);
global_index.encode(sink);
}
Instruction::GlobalAtomicRmwAnd {
ordering,
global_index,
} => {
sink.push(0xFE);
sink.push(0x53);
ordering.encode(sink);
global_index.encode(sink);
}
Instruction::GlobalAtomicRmwOr {
ordering,
global_index,
} => {
sink.push(0xFE);
sink.push(0x54);
ordering.encode(sink);
global_index.encode(sink);
}
Instruction::GlobalAtomicRmwXor {
ordering,
global_index,
} => {
sink.push(0xFE);
sink.push(0x55);
ordering.encode(sink);
global_index.encode(sink);
}
Instruction::GlobalAtomicRmwXchg {
ordering,
global_index,
} => {
sink.push(0xFE);
sink.push(0x56);
ordering.encode(sink);
global_index.encode(sink);
}
Instruction::GlobalAtomicRmwCmpxchg {
ordering,
global_index,
} => {
sink.push(0xFE);
sink.push(0x57);
ordering.encode(sink);
global_index.encode(sink);
}
}
}
}
#[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(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(),
}
}
fn new_insn(insn: Instruction) -> Self {
let mut bytes = vec![];
insn.encode(&mut bytes);
Self { bytes }
}
fn with_insn(mut self, insn: Instruction) -> Self {
insn.encode(&mut self.bytes);
self
}
pub fn global_get(index: u32) -> Self {
Self::new_insn(Instruction::GlobalGet(index))
}
pub fn ref_null(ty: HeapType) -> Self {
Self::new_insn(Instruction::RefNull(ty))
}
pub fn ref_func(func: u32) -> Self {
Self::new_insn(Instruction::RefFunc(func))
}
pub fn i32_const(value: i32) -> Self {
Self::new_insn(Instruction::I32Const(value))
}
pub fn i64_const(value: i64) -> Self {
Self::new_insn(Instruction::I64Const(value))
}
pub fn f32_const(value: f32) -> Self {
Self::new_insn(Instruction::F32Const(value))
}
pub fn f64_const(value: f64) -> Self {
Self::new_insn(Instruction::F64Const(value))
}
pub fn v128_const(value: i128) -> Self {
Self::new_insn(Instruction::V128Const(value))
}
pub fn with_global_get(self, index: u32) -> Self {
self.with_insn(Instruction::GlobalGet(index))
}
pub fn with_ref_null(self, ty: HeapType) -> Self {
self.with_insn(Instruction::RefNull(ty))
}
pub fn with_ref_func(self, func: u32) -> Self {
self.with_insn(Instruction::RefFunc(func))
}
pub fn with_i32_const(self, value: i32) -> Self {
self.with_insn(Instruction::I32Const(value))
}
pub fn with_i64_const(self, value: i64) -> Self {
self.with_insn(Instruction::I64Const(value))
}
pub fn with_f32_const(self, value: f32) -> Self {
self.with_insn(Instruction::F32Const(value))
}
pub fn with_f64_const(self, value: f64) -> Self {
self.with_insn(Instruction::F64Const(value))
}
pub fn with_v128_const(self, value: i128) -> Self {
self.with_insn(Instruction::V128Const(value))
}
pub fn with_i32_add(self) -> Self {
self.with_insn(Instruction::I32Add)
}
pub fn with_i32_sub(self) -> Self {
self.with_insn(Instruction::I32Sub)
}
pub fn with_i32_mul(self) -> Self {
self.with_insn(Instruction::I32Mul)
}
pub fn with_i64_add(self) -> Self {
self.with_insn(Instruction::I64Add)
}
pub fn with_i64_sub(self) -> Self {
self.with_insn(Instruction::I64Sub)
}
pub fn with_i64_mul(self) -> Self {
self.with_insn(Instruction::I64Mul)
}
pub fn get_ref_func(&self) -> Option<u32> {
let prefix = *self.bytes.get(0)?;
if prefix != 0xd2 {
return None;
}
leb128::read::unsigned(&mut &self.bytes[1..])
.ok()?
.try_into()
.ok()
}
}
impl Encode for ConstExpr {
fn encode(&self, sink: &mut Vec<u8>) {
sink.extend(&self.bytes);
Instruction::End.encode(sink);
}
}
#[cfg(feature = "wasmparser")]
#[derive(Debug)]
pub enum ConstExprConversionError {
ParseError(wasmparser::BinaryReaderError),
Invalid,
CanonicalizedTypeReference,
}
#[cfg(feature = "wasmparser")]
impl std::fmt::Display for ConstExprConversionError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::ParseError(_e) => {
write!(f, "There was an error when parsing the const expression")
}
Self::Invalid => write!(f, "The const expression was invalid"),
Self::CanonicalizedTypeReference => write!(
f,
"There was a canonicalized type reference without type index information"
),
}
}
}
#[cfg(feature = "wasmparser")]
impl std::error::Error for ConstExprConversionError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::ParseError(e) => Some(e),
Self::Invalid | Self::CanonicalizedTypeReference => None,
}
}
}
#[cfg(feature = "wasmparser")]
impl<'a> TryFrom<wasmparser::ConstExpr<'a>> for ConstExpr {
type Error = ConstExprConversionError;
fn try_from(const_expr: wasmparser::ConstExpr) -> Result<Self, Self::Error> {
let mut ops = const_expr.get_operators_reader().into_iter();
let result = match ops.next() {
Some(Ok(wasmparser::Operator::I32Const { value })) => ConstExpr::i32_const(value),
Some(Ok(wasmparser::Operator::I64Const { value })) => ConstExpr::i64_const(value),
Some(Ok(wasmparser::Operator::F32Const { value })) => {
ConstExpr::f32_const(value.bits() as _)
}
Some(Ok(wasmparser::Operator::F64Const { value })) => {
ConstExpr::f64_const(value.bits() as _)
}
Some(Ok(wasmparser::Operator::V128Const { value })) => {
ConstExpr::v128_const(i128::from_le_bytes(*value.bytes()))
}
Some(Ok(wasmparser::Operator::RefNull { hty })) => ConstExpr::ref_null(
HeapType::try_from(hty)
.map_err(|_| ConstExprConversionError::CanonicalizedTypeReference)?,
),
Some(Ok(wasmparser::Operator::RefFunc { function_index })) => {
ConstExpr::ref_func(function_index)
}
Some(Ok(wasmparser::Operator::GlobalGet { global_index })) => {
ConstExpr::global_get(global_index)
}
Some(Ok(_op)) => return Err(ConstExprConversionError::Invalid),
Some(Err(e)) => return Err(ConstExprConversionError::ParseError(e)),
None => return Err(ConstExprConversionError::Invalid),
};
match (ops.next(), ops.next()) {
(Some(Ok(wasmparser::Operator::End)), None) => Ok(result),
_ => Err(ConstExprConversionError::Invalid),
}
}
}
#[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)
}
}