Quelle code.rs
Sprache: unbekannt
|
|
Spracherkennung für: .rs vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]
use crate::{encode_section, Encode, HeapType, RefType, Section, SectionId, ValType};
use std::borrow::Cow;
/// An encoder for the code section.
///
/// Code sections are only supported for modules.
///
/// # Example
///
/// ```
/// use wasm_encoder::{
/// CodeSection, Function, FunctionSection, Instruction, Module,
/// TypeSection, ValType
/// };
///
/// let mut types = TypeSection::new();
/// types.ty().function(vec![], vec![ValType::I32]);
///
/// let mut functions = FunctionSection::new();
/// let type_index = 0;
/// functions.function(type_index);
///
/// let locals = vec![];
/// let mut func = Function::new(locals);
/// func.instruction(&Instruction::I32Const(42));
/// let mut code = CodeSection::new();
/// code.function(&func);
///
/// let mut module = Module::new();
/// module
/// .section(&types)
/// .section(&functions)
/// .section(&code);
///
/// let wasm_bytes = module.finish();
/// ```
#[derive(Clone, Default, Debug)]
pub struct CodeSection {
bytes: Vec<u8>,
num_added: u32,
}
impl CodeSection {
/// Create a new code section encoder.
pub fn new() -> Self {
Self::default()
}
/// The number of functions in the section.
pub fn len(&self) -> u32 {
self.num_added
}
/// The number of bytes already added to this section.
///
/// This number doesn't include the vector length that precedes the
/// code entries, since it has a variable size that isn't known until all
/// functions are added.
pub fn byte_len(&self) -> usize {
self.bytes.len()
}
/// Determines if the section is empty.
pub fn is_empty(&self) -> bool {
self.num_added == 0
}
/// Write a function body into this code section.
pub fn function(&mut self, func: &Function) -> &mut Self {
func.encode(&mut self.bytes);
self.num_added += 1;
self
}
/// Add a raw byte slice into this code section as a function body.
///
/// The length prefix of the function body will be automatically prepended,
/// and should not be included in the raw byte slice.
///
/// # Example
///
/// You can use the `raw` method to copy an already-encoded function body
/// into a new code section encoder:
///
/// ```
/// # use wasmparser::{BinaryReader, CodeSectionReader};
/// // id, size, # entries, entry
/// let code_section = [10, 6, 1, 4, 0, 65, 0, 11];
///
/// // Parse the code section.
/// let reader = BinaryReader::new(&code_section, 0);
/// let reader = CodeSectionReader::new(reader).unwrap();
/// let body = reader.into_iter().next().unwrap().unwrap();
/// let body_range = body.range();
///
/// // Add the body to a new code section encoder by copying bytes rather
/// // than re-parsing and re-encoding it.
/// let mut encoder = wasm_encoder::CodeSection::new();
/// encoder.raw(&code_section[body_range.start..body_range.end]);
/// ```
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()
}
}
/// An encoder for a function body within the code section.
///
/// # Example
///
/// ```
/// use wasm_encoder::{CodeSection, Function, Instruction};
///
/// // Define the function body for:
/// //
/// // (func (param i32 i32) (result i32)
/// // local.get 0
/// // local.get 1
/// // i32.add)
/// let locals = vec![];
/// let mut func = Function::new(locals);
/// func.instruction(&Instruction::LocalGet(0));
/// func.instruction(&Instruction::LocalGet(1));
/// func.instruction(&Instruction::I32Add);
///
/// // Add our function to the code section.
/// let mut code = CodeSection::new();
/// code.function(&func);
/// ```
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Function {
bytes: Vec<u8>,
}
impl Function {
/// Create a new function body with the given locals.
///
/// The argument is an iterator over `(N, Ty)`, which defines
/// that the next `N` locals will be of type `Ty`.
///
/// For example, a function with locals 0 and 1 of type I32 and
/// local 2 of type F32 would be created as:
///
/// ```
/// # use wasm_encoder::{Function, ValType};
/// let f = Function::new([(2, ValType::I32), (1, ValType::F32)]);
/// ```
///
/// For more information about the code section (and function definition) in the WASM binary fo rmat
/// see the [WebAssembly spec](https://webassembly.github.io/spec/core/binary/modules.html#binary-func)
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 }
}
/// Create a function from a list of locals' types.
///
/// Unlike [`Function::new`], this constructor simply takes a list of types
/// which are in order associated with locals.
///
/// For example:
///
/// ```
/// # use wasm_encoder::{Function, ValType};
/// let f = Function::new([(2, ValType::I32), (1, ValType::F32)]);
/// let g = Function::new_with_locals_types([
/// ValType::I32, ValType::I32, ValType::F32
/// ]);
///
/// assert_eq!(f, g)
/// ```
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 {
// Increment the count of consecutive locals of this type
*last_count += 1;
continue;
}
}
// If we didn't increment, a new type of local appeared
locals_collected.push((1, l));
}
Function::new(locals_collected)
}
/// Write an instruction into this function body.
pub fn instruction(&mut self, instruction: &Instruction) -> &mut Self {
instruction.encode(&mut self.bytes);
self
}
/// Add raw bytes to this function's body.
pub fn raw<B>(&mut self, bytes: B) -> &mut Self
where
B: IntoIterator<Item = u8>,
{
self.bytes.extend(bytes);
self
}
/// The number of bytes already added to this function.
///
/// This number doesn't include the variable-width size field that `encode`
/// will write before the added bytes, since the size of that field isn't
/// known until all the instructions are added to this function.
pub fn byte_len(&self) -> usize {
self.bytes.len()
}
/// Unwraps and returns the raw byte encoding of this function.
///
/// This encoding doesn't include the variable-width size field
/// that `encode` will write before the added bytes. As such, its
/// length will match the return value of [`byte_len`].
///
/// # Use Case
///
/// This raw byte form is suitable for later using with
/// [`CodeSection::raw`]. Note that it *differs* from what results
/// from [`Function::encode`] precisely due to the *lack* of the
/// length prefix; [`CodeSection::raw`] will use this. Using
/// [`Function::encode`] instead produces bytes that cannot be fed
/// into other wasm-encoder types without stripping off the length
/// prefix, which is awkward and error-prone.
///
/// This method combined with [`CodeSection::raw`] may be useful
/// together if one wants to save the result of function encoding
/// and use it later: for example, caching the result of some code
/// generation process.
///
/// For example:
///
/// ```
/// # use wasm_encoder::{CodeSection, Function, Instruction};
/// let mut f = Function::new([]);
/// f.instruction(&Instruction::End);
/// let bytes = f.into_raw_body();
/// // (save `bytes` somewhere for later use)
/// let mut code = CodeSection::new();
/// code.raw(&bytes[..]);
///
/// assert_eq!(2, bytes.len()); // Locals count, then `end`
/// assert_eq!(3, code.byte_len()); // Function length byte, function body
/// ```
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);
}
}
/// The immediate for a memory instruction.
#[derive(Clone, Copy, Debug)]
pub struct MemArg {
/// A static offset to add to the instruction's dynamic address operand.
///
/// This is a `u64` field for the memory64 proposal, but 32-bit memories
/// limit offsets to at most `u32::MAX` bytes. This will be encoded as a LEB
/// but it won't generate a valid module if an offset is specified which is
/// larger than the maximum size of the index space for the memory indicated
/// by `memory_index`.
pub offset: u64,
/// The expected alignment of the instruction's dynamic address operand
/// (expressed the exponent of a power of two).
pub align: u32,
/// The index of the memory this instruction is operating upon.
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);
}
}
}
/// The memory ordering for atomic instructions.
///
/// For an in-depth explanation of memory orderings, see the C++ documentation
/// for [`memory_order`] or the Rust documentation for [`atomic::Ordering`].
///
/// [`memory_order`]: https://en.cppreference.com/w/cpp/atomic/memory_order
/// [`atomic::Ordering`]: https://doc.rust-lang.org/std/sync/atomic/enum.Ordering.html
#[derive(Clone, Copy, Debug)]
pub enum Ordering {
/// For a load, it acquires; this orders all operations before the last
/// "releasing" store. For a store, it releases; this orders all operations
/// before it at the next "acquiring" load.
AcqRel,
/// Like `AcqRel` but all threads see all sequentially consistent operations
/// in the same order.
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);
}
}
/// Describe an unchecked SIMD lane index.
pub type Lane = u8;
/// The type for a `block`/`if`/`loop`.
#[derive(Clone, Copy, Debug)]
pub enum BlockType {
/// `[] -> []`
Empty,
/// `[] -> [t]`
Result(ValType),
/// The `n`th function type.
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),
}
}
}
/// WebAssembly instructions.
#[derive(Clone, Debug)]
#[non_exhaustive]
#[allow(missing_docs, non_camel_case_types)]
pub enum Instruction<'a> {
// Control instructions.
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,
// Deprecated exception-handling instructions
Try(BlockType),
Delegate(u32),
Catch(u32),
CatchAll,
Rethrow(u32),
// Parametric instructions.
Drop,
Select,
// Variable instructions.
LocalGet(u32),
LocalSet(u32),
LocalTee(u32),
GlobalGet(u32),
GlobalSet(u32),
// Memory instructions.
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),
// Numeric instructions.
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,
// Reference types instructions.
TypedSelect(ValType),
RefNull(HeapType),
RefIsNull,
RefFunc(u32),
RefEq,
RefAsNonNull,
// GC types instructions.
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,
// Bulk memory instructions.
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,
},
// SIMD instructions.
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,
// Relaxed simd proposal
I8x16RelaxedSwizzle,
I32x4RelaxedTruncF32x4S,
I32x4RelaxedTruncF32x4U,
I32x4RelaxedTruncF64x2SZero,
I32x4RelaxedTruncF64x2UZero,
F32x4RelaxedMadd,
F32x4RelaxedNmadd,
F64x2RelaxedMadd,
F64x2RelaxedNmadd,
I8x16RelaxedLaneselect,
I16x8RelaxedLaneselect,
I32x4RelaxedLaneselect,
I64x2RelaxedLaneselect,
F32x4RelaxedMin,
F32x4RelaxedMax,
F64x2RelaxedMin,
F64x2RelaxedMax,
I16x8RelaxedQ15mulrS,
I16x8RelaxedDotI8x16I7x16S,
I32x4RelaxedDotI8x16I7x16AddS,
// Atomic instructions (the threads proposal)
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),
// More atomic instructions (the shared-everything-threads proposal)
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,
// Stack switching
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,
},
// Wide Arithmetic
I64Add128,
I64Sub128,
I64MulWideS,
I64MulWideU,
}
impl Encode for Instruction<'_> {
fn encode(&self, sink: &mut Vec<u8>) {
match *self {
// Control instructions.
Instruction::Unreachable => sink.push(0x00),
Instruction::Nop => sink.push(0x01),
Instruction::Block(bt) => {
sink.push(0x02);
bt.encode(sink);
}
Instruction::Loop(bt) => {
sink.push(0x03);
bt.encode(sink);
}
Instruction::If(bt) => {
sink.push(0x04);
bt.encode(sink);
}
Instruction::Else => sink.push(0x05),
Instruction::Try(bt) => {
sink.push(0x06);
bt.encode(sink);
}
Instruction::Catch(t) => {
sink.push(0x07);
t.encode(sink);
}
Instruction::Throw(t) => {
sink.push(0x08);
t.encode(sink);
}
Instruction::Rethrow(l) => {
sink.push(0x09);
l.encode(sink);
}
Instruction::ThrowRef => {
sink.push(0x0A);
}
Instruction::End => sink.push(0x0B),
Instruction::Br(l) => {
sink.push(0x0C);
l.encode(sink);
}
Instruction::BrIf(l) => {
sink.push(0x0D);
l.encode(sink);
}
Instruction::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 {
type_index,
table_index,
} => {
sink.push(0x11);
type_index.encode(sink);
table_index.encode(sink);
}
Instruction::ReturnCallRef(ty) => {
sink.push(0x15);
ty.encode(sink);
}
Instruction::ReturnCall(f) => {
sink.push(0x12);
f.encode(sink);
}
Instruction::ReturnCallIndirect {
type_index,
table_index,
} => {
sink.push(0x13);
type_index.encode(sink);
table_index.encode(sink);
}
Instruction::Delegate(l) => {
sink.push(0x18);
l.encode(sink);
}
Instruction::CatchAll => {
sink.push(0x19);
}
// Parametric instructions.
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);
}
// Variable instructions.
Instruction::LocalGet(l) => {
sink.push(0x20);
l.encode(sink);
}
Instruction::LocalSet(l) => {
sink.push(0x21);
l.encode(sink);
}
Instruction::LocalTee(l) => {
sink.push(0x22);
l.encode(sink);
}
Instruction::GlobalGet(g) => {
sink.push(0x23);
g.encode(sink);
}
Instruction::GlobalSet(g) => {
sink.push(0x24);
g.encode(sink);
}
Instruction::TableGet(table) => {
sink.push(0x25);
table.encode(sink);
}
Instruction::TableSet(table) => {
sink.push(0x26);
table.encode(sink);
}
// Memory instructions.
Instruction::I32Load(m) => {
sink.push(0x28);
m.encode(sink);
}
Instruction::I64Load(m) => {
sink.push(0x29);
m.encode(sink);
}
Instruction::F32Load(m) => {
sink.push(0x2A);
m.encode(sink);
}
Instruction::F64Load(m) => {
sink.push(0x2B);
m.encode(sink);
}
Instruction::I32Load8S(m) => {
sink.push(0x2C);
m.encode(sink);
}
Instruction::I32Load8U(m) => {
sink.push(0x2D);
m.encode(sink);
}
Instruction::I32Load16S(m) => {
sink.push(0x2E);
m.encode(sink);
}
Instruction::I32Load16U(m) => {
sink.push(0x2F);
m.encode(sink);
}
Instruction::I64Load8S(m) => {
sink.push(0x30);
m.encode(sink);
}
Instruction::I64Load8U(m) => {
sink.push(0x31);
m.encode(sink);
}
Instruction::I64Load16S(m) => {
sink.push(0x32);
m.encode(sink);
}
Instruction::I64Load16U(m) => {
sink.push(0x33);
m.encode(sink);
}
Instruction::I64Load32S(m) => {
sink.push(0x34);
m.encode(sink);
}
Instruction::I64Load32U(m) => {
sink.push(0x35);
m.encode(sink);
}
Instruction::I32Store(m) => {
sink.push(0x36);
m.encode(sink);
}
Instruction::I64Store(m) => {
sink.push(0x37);
m.encode(sink);
}
Instruction::F32Store(m) => {
sink.push(0x38);
m.encode(sink);
}
Instruction::F64Store(m) => {
sink.push(0x39);
m.encode(sink);
}
Instruction::I32Store8(m) => {
sink.push(0x3A);
m.encode(sink);
}
Instruction::I32Store16(m) => {
sink.push(0x3B);
m.encode(sink);
}
Instruction::I64Store8(m) => {
sink.push(0x3C);
m.encode(sink);
}
Instruction::I64Store16(m) => {
sink.push(0x3D);
m.encode(sink);
}
Instruction::I64Store32(m) => {
sink.push(0x3E);
m.encode(sink);
}
Instruction::MemorySize(i) => {
sink.push(0x3F);
i.encode(sink);
}
Instruction::MemoryGrow(i) => {
sink.push(0x40);
i.encode(sink);
}
Instruction::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);
}
// Numeric instructions.
Instruction::I32Const(x) => {
sink.push(0x41);
x.encode(sink);
}
Instruction::I64Const(x) => {
sink.push(0x42);
x.encode(sink);
}
Instruction::F32Const(x) => {
sink.push(0x43);
let x = x.to_bits();
sink.extend(x.to_le_bytes().iter().copied());
}
Instruction::F64Const(x) => {
sink.push(0x44);
let x = x.to_bits();
sink.extend(x.to_le_bytes().iter().copied());
}
Instruction::I32Eqz => sink.push(0x45),
Instruction::I32Eq => sink.push(0x46),
Instruction::I32Ne => sink.push(0x47),
Instruction::I32LtS => sink.push(0x48),
Instruction::I32LtU => sink.push(0x49),
Instruction::I32GtS => sink.push(0x4A),
Instruction::I32GtU => sink.push(0x4B),
Instruction::I32LeS => sink.push(0x4C),
Instruction::I32LeU => sink.push(0x4D),
Instruction::I32GeS => sink.push(0x4E),
Instruction::I32GeU => sink.push(0x4F),
Instruction::I64Eqz => sink.push(0x50),
Instruction::I64Eq => sink.push(0x51),
Instruction::I64Ne => sink.push(0x52),
Instruction::I64LtS => sink.push(0x53),
Instruction::I64LtU => sink.push(0x54),
Instruction::I64GtS => sink.push(0x55),
Instruction::I64GtU => sink.push(0x56),
Instruction::I64LeS => sink.push(0x57),
Instruction::I64LeU => sink.push(0x58),
Instruction::I64GeS => sink.push(0x59),
Instruction::I64GeU => sink.push(0x5A),
Instruction::F32Eq => sink.push(0x5B),
Instruction::F32Ne => sink.push(0x5C),
Instruction::F32Lt => sink.push(0x5D),
Instruction::F32Gt => sink.push(0x5E),
Instruction::F32Le => sink.push(0x5F),
Instruction::F32Ge => sink.push(0x60),
Instruction::F64Eq => sink.push(0x61),
Instruction::F64Ne => sink.push(0x62),
Instruction::F64Lt => sink.push(0x63),
Instruction::F64Gt => sink.push(0x64),
Instruction::F64Le => sink.push(0x65),
Instruction::F64Ge => sink.push(0x66),
Instruction::I32Clz => sink.push(0x67),
Instruction::I32Ctz => sink.push(0x68),
Instruction::I32Popcnt => sink.push(0x69),
Instruction::I32Add => sink.push(0x6A),
Instruction::I32Sub => sink.push(0x6B),
Instruction::I32Mul => sink.push(0x6C),
Instruction::I32DivS => sink.push(0x6D),
Instruction::I32DivU => sink.push(0x6E),
Instruction::I32RemS => sink.push(0x6F),
Instruction::I32RemU => sink.push(0x70),
Instruction::I32And => sink.push(0x71),
Instruction::I32Or => sink.push(0x72),
Instruction::I32Xor => sink.push(0x73),
Instruction::I32Shl => sink.push(0x74),
Instruction::I32ShrS => sink.push(0x75),
Instruction::I32ShrU => sink.push(0x76),
Instruction::I32Rotl => sink.push(0x77),
Instruction::I32Rotr => sink.push(0x78),
Instruction::I64Clz => sink.push(0x79),
Instruction::I64Ctz => sink.push(0x7A),
Instruction::I64Popcnt => sink.push(0x7B),
Instruction::I64Add => sink.push(0x7C),
Instruction::I64Sub => sink.push(0x7D),
Instruction::I64Mul => sink.push(0x7E),
Instruction::I64DivS => sink.push(0x7F),
Instruction::I64DivU => sink.push(0x80),
Instruction::I64RemS => sink.push(0x81),
Instruction::I64RemU => sink.push(0x82),
Instruction::I64And => sink.push(0x83),
Instruction::I64Or => sink.push(0x84),
Instruction::I64Xor => sink.push(0x85),
Instruction::I64Shl => sink.push(0x86),
Instruction::I64ShrS => sink.push(0x87),
Instruction::I64ShrU => sink.push(0x88),
Instruction::I64Rotl => sink.push(0x89),
Instruction::I64Rotr => sink.push(0x8A),
Instruction::F32Abs => sink.push(0x8B),
Instruction::F32Neg => sink.push(0x8C),
Instruction::F32Ceil => sink.push(0x8D),
Instruction::F32Floor => sink.push(0x8E),
Instruction::F32Trunc => sink.push(0x8F),
Instruction::F32Nearest => sink.push(0x90),
Instruction::F32Sqrt => sink.push(0x91),
Instruction::F32Add => sink.push(0x92),
Instruction::F32Sub => sink.push(0x93),
Instruction::F32Mul => sink.push(0x94),
Instruction::F32Div => sink.push(0x95),
Instruction::F32Min => sink.push(0x96),
Instruction::F32Max => sink.push(0x97),
Instruction::F32Copysign => sink.push(0x98),
Instruction::F64Abs => sink.push(0x99),
Instruction::F64Neg => sink.push(0x9A),
Instruction::F64Ceil => sink.push(0x9B),
Instruction::F64Floor => sink.push(0x9C),
Instruction::F64Trunc => sink.push(0x9D),
Instruction::F64Nearest => sink.push(0x9E),
Instruction::F64Sqrt => sink.push(0x9F),
Instruction::F64Add => sink.push(0xA0),
Instruction::F64Sub => sink.push(0xA1),
Instruction::F64Mul => sink.push(0xA2),
Instruction::F64Div => sink.push(0xA3),
Instruction::F64Min => sink.push(0xA4),
Instruction::F64Max => sink.push(0xA5),
Instruction::F64Copysign => sink.push(0xA6),
Instruction::I32WrapI64 => sink.push(0xA7),
Instruction::I32TruncF32S => sink.push(0xA8),
Instruction::I32TruncF32U => sink.push(0xA9),
Instruction::I32TruncF64S => sink.push(0xAA),
Instruction::I32TruncF64U => sink.push(0xAB),
Instruction::I64ExtendI32S => sink.push(0xAC),
Instruction::I64ExtendI32U => sink.push(0xAD),
Instruction::I64TruncF32S => sink.push(0xAE),
Instruction::I64TruncF32U => sink.push(0xAF),
Instruction::I64TruncF64S => sink.push(0xB0),
Instruction::I64TruncF64U => sink.push(0xB1),
Instruction::F32ConvertI32S => sink.push(0xB2),
Instruction::F32ConvertI32U => sink.push(0xB3),
Instruction::F32ConvertI64S => sink.push(0xB4),
Instruction::F32ConvertI64U => sink.push(0xB5),
Instruction::F32DemoteF64 => sink.push(0xB6),
Instruction::F64ConvertI32S => sink.push(0xB7),
Instruction::F64ConvertI32U => sink.push(0xB8),
Instruction::F64ConvertI64S => sink.push(0xB9),
Instruction::F64ConvertI64U => sink.push(0xBA),
Instruction::F64PromoteF32 => sink.push(0xBB),
Instruction::I32ReinterpretF32 => sink.push(0xBC),
Instruction::I64ReinterpretF64 => sink.push(0xBD),
Instruction::F32ReinterpretI32 => sink.push(0xBE),
Instruction::F64ReinterpretI64 => sink.push(0xBF),
Instruction::I32Extend8S => sink.push(0xC0),
Instruction::I32Extend16S => sink.push(0xC1),
Instruction::I64Extend8S => sink.push(0xC2),
Instruction::I64Extend16S => sink.push(0xC3),
Instruction::I64Extend32S => sink.push(0xC4),
Instruction::I32TruncSatF32S => {
sink.push(0xFC);
sink.push(0x00);
}
Instruction::I32TruncSatF32U => {
sink.push(0xFC);
sink.push(0x01);
}
Instruction::I32TruncSatF64S => {
sink.push(0xFC);
sink.push(0x02);
}
Instruction::I32TruncSatF64U => {
sink.push(0xFC);
sink.push(0x03);
}
Instruction::I64TruncSatF32S => {
sink.push(0xFC);
sink.push(0x04);
}
Instruction::I64TruncSatF32U => {
sink.push(0xFC);
sink.push(0x05);
}
Instruction::I64TruncSatF64S => {
sink.push(0xFC);
sink.push(0x06);
}
Instruction::I64TruncSatF64U => {
sink.push(0xFC);
sink.push(0x07);
}
// Reference types instructions.
Instruction::RefNull(ty) => {
sink.push(0xd0);
ty.encode(sink);
}
Instruction::RefIsNull => sink.push(0xd1),
Instruction::RefFunc(f) => {
sink.push(0xd2);
f.encode(sink);
}
Instruction::RefEq => sink.push(0xd3),
Instruction::RefAsNonNull => sink.push(0xd4),
// GC instructions.
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);
}
// Bulk memory instructions.
Instruction::TableInit { elem_index, table } => {
sink.push(0xfc);
sink.push(0x0c);
elem_index.encode(sink);
table.encode(sink);
}
Instruction::ElemDrop(segment) => {
sink.push(0xfc);
sink.push(0x0d);
segment.encode(sink);
}
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);
}
// SIMD instructions.
Instruction::V128Load(memarg) => {
sink.push(0xFD);
0x00u32.encode(sink);
memarg.encode(sink);
}
Instruction::V128Load8x8S(memarg) => {
sink.push(0xFD);
0x01u32.encode(sink);
memarg.encode(sink);
}
Instruction::V128Load8x8U(memarg) => {
sink.push(0xFD);
0x02u32.encode(sink);
memarg.encode(sink);
}
Instruction::V128Load16x4S(memarg) => {
sink.push(0xFD);
0x03u32.encode(sink);
memarg.encode(sink);
}
Instruction::V128Load16x4U(memarg) => {
sink.push(0xFD);
0x04u32.encode(sink);
memarg.encode(sink);
}
Instruction::V128Load32x2S(memarg) => {
sink.push(0xFD);
0x05u32.encode(sink);
memarg.encode(sink);
}
Instruction::V128Load32x2U(memarg) => {
sink.push(0xFD);
0x06u32.encode(sink);
memarg.encode(sink);
}
Instruction::V128Load8Splat(memarg) => {
sink.push(0xFD);
0x07u32.encode(sink);
memarg.encode(sink);
}
Instruction::V128Load16Splat(memarg) => {
sink.push(0xFD);
0x08u32.encode(sink);
memarg.encode(sink);
}
Instruction::V128Load32Splat(memarg) => {
sink.push(0xFD);
0x09u32.encode(sink);
memarg.encode(sink);
}
Instruction::V128Load64Splat(memarg) => {
sink.push(0xFD);
0x0Au32.encode(sink);
memarg.encode(sink);
}
Instruction::V128Store(memarg) => {
sink.push(0xFD);
0x0Bu32.encode(sink);
memarg.encode(sink);
}
Instruction::V128Const(x) => {
sink.push(0xFD);
0x0Cu32.encode(sink);
sink.extend(x.to_le_bytes().iter().copied());
}
Instruction::I8x16Shuffle(lanes) => {
sink.push(0xFD);
0x0Du32.encode(sink);
assert!(lanes.iter().all(|l: &u8| *l < 32));
sink.extend(lanes.iter().copied());
}
Instruction::I8x16Swizzle => {
sink.push(0xFD);
0x0Eu32.encode(sink);
}
Instruction::I8x16Splat => {
sink.push(0xFD);
0x0Fu32.encode(sink);
}
Instruction::I16x8Splat => {
sink.push(0xFD);
0x10u32.encode(sink);
}
Instruction::I32x4Splat => {
sink.push(0xFD);
0x11u32.encode(sink);
}
Instruction::I64x2Splat => {
sink.push(0xFD);
0x12u32.encode(sink);
}
Instruction::F32x4Splat => {
sink.push(0xFD);
0x13u32.encode(sink);
}
Instruction::F64x2Splat => {
sink.push(0xFD);
0x14u32.encode(sink);
}
Instruction::I8x16ExtractLaneS(lane) => {
sink.push(0xFD);
0x15u32.encode(sink);
assert!(lane < 16);
sink.push(lane);
}
Instruction::I8x16ExtractLaneU(lane) => {
sink.push(0xFD);
0x16u32.encode(sink);
assert!(lane < 16);
sink.push(lane);
}
Instruction::I8x16ReplaceLane(lane) => {
sink.push(0xFD);
0x17u32.encode(sink);
assert!(lane < 16);
sink.push(lane);
}
Instruction::I16x8ExtractLaneS(lane) => {
sink.push(0xFD);
0x18u32.encode(sink);
assert!(lane < 8);
sink.push(lane);
}
Instruction::I16x8ExtractLaneU(lane) => {
sink.push(0xFD);
0x19u32.encode(sink);
assert!(lane < 8);
sink.push(lane);
}
Instruction::I16x8ReplaceLane(lane) => {
sink.push(0xFD);
0x1Au32.encode(sink);
assert!(lane < 8);
sink.push(lane);
}
Instruction::I32x4ExtractLane(lane) => {
sink.push(0xFD);
0x1Bu32.encode(sink);
assert!(lane < 4);
sink.push(lane);
}
Instruction::I32x4ReplaceLane(lane) => {
sink.push(0xFD);
0x1Cu32.encode(sink);
assert!(lane < 4);
sink.push(lane);
}
Instruction::I64x2ExtractLane(lane) => {
sink.push(0xFD);
0x1Du32.encode(sink);
assert!(lane < 2);
sink.push(lane);
}
Instruction::I64x2ReplaceLane(lane) => {
sink.push(0xFD);
0x1Eu32.encode(sink);
assert!(lane < 2);
sink.push(lane);
}
Instruction::F32x4ExtractLane(lane) => {
sink.push(0xFD);
0x1Fu32.encode(sink);
assert!(lane < 4);
sink.push(lane);
}
Instruction::F32x4ReplaceLane(lane) => {
sink.push(0xFD);
0x20u32.encode(sink);
assert!(lane < 4);
sink.push(lane);
}
Instruction::F64x2ExtractLane(lane) => {
sink.push(0xFD);
0x21u32.encode(sink);
assert!(lane < 2);
sink.push(lane);
}
Instruction::F64x2ReplaceLane(lane) => {
sink.push(0xFD);
0x22u32.encode(sink);
assert!(lane < 2);
sink.push(lane);
}
Instruction::I8x16Eq => {
sink.push(0xFD);
0x23u32.encode(sink);
}
Instruction::I8x16Ne => {
sink.push(0xFD);
0x24u32.encode(sink);
}
Instruction::I8x16LtS => {
sink.push(0xFD);
0x25u32.encode(sink);
}
Instruction::I8x16LtU => {
sink.push(0xFD);
0x26u32.encode(sink);
}
Instruction::I8x16GtS => {
sink.push(0xFD);
0x27u32.encode(sink);
}
Instruction::I8x16GtU => {
sink.push(0xFD);
0x28u32.encode(sink);
}
Instruction::I8x16LeS => {
sink.push(0xFD);
0x29u32.encode(sink);
}
Instruction::I8x16LeU => {
sink.push(0xFD);
0x2Au32.encode(sink);
}
Instruction::I8x16GeS => {
sink.push(0xFD);
0x2Bu32.encode(sink);
}
Instruction::I8x16GeU => {
sink.push(0xFD);
0x2Cu32.encode(sink);
}
Instruction::I16x8Eq => {
sink.push(0xFD);
0x2Du32.encode(sink);
}
Instruction::I16x8Ne => {
sink.push(0xFD);
0x2Eu32.encode(sink);
}
Instruction::I16x8LtS => {
sink.push(0xFD);
0x2Fu32.encode(sink);
}
Instruction::I16x8LtU => {
sink.push(0xFD);
0x30u32.encode(sink);
}
Instruction::I16x8GtS => {
sink.push(0xFD);
0x31u32.encode(sink);
}
Instruction::I16x8GtU => {
sink.push(0xFD);
0x32u32.encode(sink);
}
Instruction::I16x8LeS => {
sink.push(0xFD);
0x33u32.encode(sink);
}
Instruction::I16x8LeU => {
sink.push(0xFD);
0x34u32.encode(sink);
}
Instruction::I16x8GeS => {
sink.push(0xFD);
0x35u32.encode(sink);
}
Instruction::I16x8GeU => {
sink.push(0xFD);
0x36u32.encode(sink);
}
Instruction::I32x4Eq => {
sink.push(0xFD);
0x37u32.encode(sink);
}
Instruction::I32x4Ne => {
sink.push(0xFD);
0x38u32.encode(sink);
}
Instruction::I32x4LtS => {
sink.push(0xFD);
0x39u32.encode(sink);
}
Instruction::I32x4LtU => {
sink.push(0xFD);
0x3Au32.encode(sink);
}
Instruction::I32x4GtS => {
sink.push(0xFD);
0x3Bu32.encode(sink);
}
Instruction::I32x4GtU => {
sink.push(0xFD);
0x3Cu32.encode(sink);
}
Instruction::I32x4LeS => {
sink.push(0xFD);
0x3Du32.encode(sink);
}
Instruction::I32x4LeU => {
sink.push(0xFD);
0x3Eu32.encode(sink);
}
Instruction::I32x4GeS => {
sink.push(0xFD);
0x3Fu32.encode(sink);
}
Instruction::I32x4GeU => {
sink.push(0xFD);
0x40u32.encode(sink);
}
Instruction::F32x4Eq => {
sink.push(0xFD);
0x41u32.encode(sink);
}
Instruction::F32x4Ne => {
sink.push(0xFD);
0x42u32.encode(sink);
}
Instruction::F32x4Lt => {
sink.push(0xFD);
0x43u32.encode(sink);
}
Instruction::F32x4Gt => {
sink.push(0xFD);
0x44u32.encode(sink);
}
Instruction::F32x4Le => {
sink.push(0xFD);
0x45u32.encode(sink);
}
Instruction::F32x4Ge => {
sink.push(0xFD);
--> --------------------
--> maximum size reached
--> --------------------
[ Dauer der Verarbeitung: 0.60 Sekunden
]
|
2026-04-02
|