Skip to main content

wasm_encoder/core/
code.rs

1use crate::{
2    Encode, HeapType, InstructionSink, RefType, Section, SectionId, ValType, encode_section,
3};
4use alloc::borrow::Cow;
5use alloc::vec;
6use alloc::vec::Vec;
7
8/// An encoder for the code section.
9///
10/// Code sections are only supported for modules.
11///
12/// # Example
13///
14/// ```
15/// use wasm_encoder::{
16///     CodeSection, Function, FunctionSection, Module,
17///     TypeSection, ValType
18/// };
19///
20/// let mut types = TypeSection::new();
21/// types.ty().function(vec![], vec![ValType::I32]);
22///
23/// let mut functions = FunctionSection::new();
24/// let type_index = 0;
25/// functions.function(type_index);
26///
27/// let locals = vec![];
28/// let mut func = Function::new(locals);
29/// func.instructions().i32_const(42);
30/// let mut code = CodeSection::new();
31/// code.function(&func);
32///
33/// let mut module = Module::new();
34/// module
35///     .section(&types)
36///     .section(&functions)
37///     .section(&code);
38///
39/// let wasm_bytes = module.finish();
40/// ```
41#[derive(Clone, Default, Debug)]
42pub struct CodeSection {
43    bytes: Vec<u8>,
44    num_added: u32,
45}
46
47impl CodeSection {
48    /// Create a new code section encoder.
49    pub fn new() -> Self {
50        Self::default()
51    }
52
53    /// The number of functions in the section.
54    pub fn len(&self) -> u32 {
55        self.num_added
56    }
57
58    /// The number of bytes already added to this section.
59    ///
60    /// This number doesn't include the vector length that precedes the
61    /// code entries, since it has a variable size that isn't known until all
62    /// functions are added.
63    pub fn byte_len(&self) -> usize {
64        self.bytes.len()
65    }
66
67    /// Determines if the section is empty.
68    pub fn is_empty(&self) -> bool {
69        self.num_added == 0
70    }
71
72    /// Write a function body into this code section.
73    pub fn function(&mut self, func: &Function) -> &mut Self {
74        func.encode(&mut self.bytes);
75        self.num_added += 1;
76        self
77    }
78
79    /// Add a raw byte slice into this code section as a function body.
80    ///
81    /// The length prefix of the function body will be automatically prepended,
82    /// and should not be included in the raw byte slice.
83    ///
84    /// # Example
85    ///
86    /// You can use the `raw` method to copy an already-encoded function body
87    /// into a new code section encoder:
88    ///
89    /// ```
90    /// # use wasmparser::{BinaryReader, CodeSectionReader};
91    /// //                  id, size, # entries, entry
92    /// let code_section = [10, 6,    1,         4, 0, 65, 0, 11];
93    ///
94    /// // Parse the code section.
95    /// let reader = BinaryReader::new(&code_section, 0);
96    /// let reader = CodeSectionReader::new(reader).unwrap();
97    /// let body = reader.into_iter().next().unwrap().unwrap();
98    /// let body_range = body.range();
99    ///
100    /// // Add the body to a new code section encoder by copying bytes rather
101    /// // than re-parsing and re-encoding it.
102    /// let mut encoder = wasm_encoder::CodeSection::new();
103    /// encoder.raw(&code_section[body_range.start as usize..body_range.end as usize]);
104    /// ```
105    pub fn raw(&mut self, data: &[u8]) -> &mut Self {
106        data.encode(&mut self.bytes);
107        self.num_added += 1;
108        self
109    }
110}
111
112impl Encode for CodeSection {
113    fn encode(&self, sink: &mut Vec<u8>) {
114        encode_section(sink, self.num_added, &self.bytes);
115    }
116}
117
118impl Section for CodeSection {
119    fn id(&self) -> u8 {
120        SectionId::Code.into()
121    }
122}
123
124/// An encoder for a function body within the code section.
125///
126/// # Example
127///
128/// ```
129/// use wasm_encoder::{CodeSection, Function};
130///
131/// // Define the function body for:
132/// //
133/// //     (func (param i32 i32) (result i32)
134/// //       local.get 0
135/// //       local.get 1
136/// //       i32.add)
137/// let locals = vec![];
138/// let mut func = Function::new(locals);
139/// func.instructions()
140///     .local_get(0)
141///     .local_get(1)
142///     .i32_add();
143///
144/// // Add our function to the code section.
145/// let mut code = CodeSection::new();
146/// code.function(&func);
147/// ```
148#[derive(Clone, Debug, Eq, PartialEq)]
149pub struct Function {
150    bytes: Vec<u8>,
151}
152
153impl Function {
154    /// Create a new function body with the given locals.
155    ///
156    /// The argument is an iterator over `(N, Ty)`, which defines
157    /// that the next `N` locals will be of type `Ty`.
158    ///
159    /// For example, a function with locals 0 and 1 of type I32 and
160    /// local 2 of type F32 would be created as:
161    ///
162    /// ```
163    /// # use wasm_encoder::{Function, ValType};
164    /// let f = Function::new([(2, ValType::I32), (1, ValType::F32)]);
165    /// ```
166    ///
167    /// For more information about the code section (and function definition) in the WASM binary format
168    /// see the [WebAssembly spec](https://webassembly.github.io/spec/core/binary/modules.html#binary-func)
169    pub fn new<L>(locals: L) -> Self
170    where
171        L: IntoIterator<Item = (u32, ValType)>,
172        L::IntoIter: ExactSizeIterator,
173    {
174        let locals = locals.into_iter();
175        let mut bytes = vec![];
176        locals.len().encode(&mut bytes);
177        for (count, ty) in locals {
178            count.encode(&mut bytes);
179            ty.encode(&mut bytes);
180        }
181        Function { bytes }
182    }
183
184    /// Create a function from a list of locals' types.
185    ///
186    /// Unlike [`Function::new`], this constructor simply takes a list of types
187    /// which are in order associated with locals.
188    ///
189    /// For example:
190    ///
191    ///  ```
192    /// # use wasm_encoder::{Function, ValType};
193    /// let f = Function::new([(2, ValType::I32), (1, ValType::F32)]);
194    /// let g = Function::new_with_locals_types([
195    ///     ValType::I32, ValType::I32, ValType::F32
196    /// ]);
197    ///
198    /// assert_eq!(f, g)
199    /// ```
200    pub fn new_with_locals_types<L>(locals: L) -> Self
201    where
202        L: IntoIterator<Item = ValType>,
203    {
204        let locals = locals.into_iter();
205
206        let mut locals_collected: Vec<(u32, ValType)> = vec![];
207        for l in locals {
208            if let Some((last_count, last_type)) = locals_collected.last_mut() {
209                if l == *last_type {
210                    // Increment the count of consecutive locals of this type
211                    *last_count += 1;
212                    continue;
213                }
214            }
215            // If we didn't increment, a new type of local appeared
216            locals_collected.push((1, l));
217        }
218
219        Function::new(locals_collected)
220    }
221
222    /// Get an instruction encoder for this function body.
223    pub fn instructions(&mut self) -> InstructionSink<'_> {
224        InstructionSink::new(&mut self.bytes)
225    }
226
227    /// Write an instruction into this function body.
228    pub fn instruction(&mut self, instruction: &Instruction) -> &mut Self {
229        instruction.encode(&mut self.bytes);
230        self
231    }
232
233    /// Add raw bytes to this function's body.
234    pub fn raw<B>(&mut self, bytes: B) -> &mut Self
235    where
236        B: IntoIterator<Item = u8>,
237    {
238        self.bytes.extend(bytes);
239        self
240    }
241
242    /// The number of bytes already added to this function.
243    ///
244    /// This number doesn't include the variable-width size field that `encode`
245    /// will write before the added bytes, since the size of that field isn't
246    /// known until all the instructions are added to this function.
247    pub fn byte_len(&self) -> usize {
248        self.bytes.len()
249    }
250
251    /// Unwraps and returns the raw byte encoding of this function.
252    ///
253    /// This encoding doesn't include the variable-width size field
254    /// that `encode` will write before the added bytes. As such, its
255    /// length will match the return value of [`Function::byte_len`].
256    ///
257    /// # Use Case
258    ///
259    /// This raw byte form is suitable for later using with
260    /// [`CodeSection::raw`]. Note that it *differs* from what results
261    /// from [`Function::encode`] precisely due to the *lack* of the
262    /// length prefix; [`CodeSection::raw`] will use this. Using
263    /// [`Function::encode`] instead produces bytes that cannot be fed
264    /// into other wasm-encoder types without stripping off the length
265    /// prefix, which is awkward and error-prone.
266    ///
267    /// This method combined with [`CodeSection::raw`] may be useful
268    /// together if one wants to save the result of function encoding
269    /// and use it later: for example, caching the result of some code
270    /// generation process.
271    ///
272    /// For example:
273    ///
274    /// ```
275    /// # use wasm_encoder::{CodeSection, Function};
276    /// let mut f = Function::new([]);
277    /// f.instructions().end();
278    /// let bytes = f.into_raw_body();
279    /// // (save `bytes` somewhere for later use)
280    /// let mut code = CodeSection::new();
281    /// code.raw(&bytes[..]);
282    ///
283    /// assert_eq!(2, bytes.len());  // Locals count, then `end`
284    /// assert_eq!(3, code.byte_len()); // Function length byte, function body
285    /// ```
286    pub fn into_raw_body(self) -> Vec<u8> {
287        self.bytes
288    }
289}
290
291impl Encode for Function {
292    fn encode(&self, sink: &mut Vec<u8>) {
293        self.bytes.encode(sink);
294    }
295}
296
297/// An IEEE binary32 immediate floating point value, represented as a u32
298/// containing the bit pattern.
299///
300/// All bit patterns are allowed.
301#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
302pub struct Ieee32(pub(crate) u32);
303
304impl Ieee32 {
305    /// Creates a new Ieee32
306    pub const fn new(bits: u32) -> Self {
307        Ieee32(bits)
308    }
309
310    /// Gets the underlying bits of the 32-bit float.
311    pub const fn bits(self) -> u32 {
312        self.0
313    }
314}
315
316impl From<f32> for Ieee32 {
317    fn from(value: f32) -> Self {
318        Ieee32(u32::from_le_bytes(value.to_le_bytes()))
319    }
320}
321
322impl From<Ieee32> for f32 {
323    fn from(bits: Ieee32) -> f32 {
324        f32::from_bits(bits.bits())
325    }
326}
327
328impl Encode for Ieee32 {
329    fn encode(&self, sink: &mut Vec<u8>) {
330        let bits = self.bits();
331        sink.extend(bits.to_le_bytes())
332    }
333}
334
335/// An IEEE binary64 immediate floating point value, represented as a u64
336/// containing the bit pattern.
337///
338/// All bit patterns are allowed.
339#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
340pub struct Ieee64(pub(crate) u64);
341
342impl Ieee64 {
343    /// Creates a new Ieee64
344    pub const fn new(bits: u64) -> Self {
345        Ieee64(bits)
346    }
347
348    /// Gets the underlying bits of the 64-bit float.
349    pub const fn bits(self) -> u64 {
350        self.0
351    }
352}
353
354impl From<f64> for Ieee64 {
355    fn from(value: f64) -> Self {
356        Ieee64(u64::from_le_bytes(value.to_le_bytes()))
357    }
358}
359
360impl From<Ieee64> for f64 {
361    fn from(bits: Ieee64) -> f64 {
362        f64::from_bits(bits.bits())
363    }
364}
365
366impl Encode for Ieee64 {
367    fn encode(&self, sink: &mut Vec<u8>) {
368        let bits = self.bits();
369        sink.extend(bits.to_le_bytes())
370    }
371}
372
373/// The immediate for a memory instruction.
374#[derive(Clone, Copy, Debug)]
375pub struct MemArg {
376    /// A static offset to add to the instruction's dynamic address operand.
377    ///
378    /// This is a `u64` field for the memory64 proposal, but 32-bit memories
379    /// limit offsets to at most `u32::MAX` bytes. This will be encoded as a LEB
380    /// but it won't generate a valid module if an offset is specified which is
381    /// larger than the maximum size of the index space for the memory indicated
382    /// by `memory_index`.
383    pub offset: u64,
384    /// The expected alignment of the instruction's dynamic address operand
385    /// (expressed the exponent of a power of two).
386    pub align: u32,
387    /// What this instruction operates on: a linear memory or a GC array.
388    pub target: MemArgTarget,
389    /// The memory ordering of this instruction, from the
390    /// acquire-release-atomics proposal.
391    ///
392    /// This should be `None` for non-atomic instructions.
393    pub ordering: Option<MemArgOrdering>,
394}
395
396/// What a memory instruction's [`MemArg`] immediate operates on.
397#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
398pub enum MemArgTarget {
399    /// The instruction operates on the linear memory at this index.
400    Memory(u32),
401    /// The instruction operates on the payload of a GC array whose type is at
402    /// this index, from the multibyte-array-access proposal.
403    Array(u32),
404}
405
406impl Default for MemArgTarget {
407    fn default() -> MemArgTarget {
408        MemArgTarget::Memory(0)
409    }
410}
411
412impl Encode for MemArg {
413    fn encode(&self, sink: &mut Vec<u8>) {
414        let mut flags = self.align;
415        if self.ordering.is_some() {
416            flags |= 1 << 4;
417        }
418        match self.target {
419            MemArgTarget::Memory(0) => {}
420            MemArgTarget::Memory(_) => flags |= 1 << 6,
421            MemArgTarget::Array(_) => flags |= 1 << 5,
422        }
423        flags.encode(sink);
424        match self.target {
425            MemArgTarget::Memory(0) => {}
426            MemArgTarget::Memory(i) | MemArgTarget::Array(i) => i.encode(sink),
427        }
428        if let Some(ordering) = self.ordering {
429            ordering.encode(sink);
430        }
431        self.offset.encode(sink);
432    }
433}
434
435/// The ordering immediate of a [`MemArg`], part of the
436/// acquire-release-atomics proposal.
437#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
438pub enum MemArgOrdering {
439    /// The ordering immediate of an atomic load or store.
440    Op(Ordering),
441    /// The ordering immediate of an atomic read-modify-write instruction.
442    Rmw(Ordering),
443}
444
445impl Encode for MemArgOrdering {
446    fn encode(&self, sink: &mut Vec<u8>) {
447        let nibble = |o: Ordering| match o {
448            Ordering::SeqCst => 0x0,
449            Ordering::AcqRel => 0x1,
450        };
451        match self {
452            MemArgOrdering::Op(o) => sink.push(nibble(*o)),
453            MemArgOrdering::Rmw(o) => sink.push(nibble(*o) | (nibble(*o) << 4)),
454        }
455    }
456}
457
458/// The memory ordering for atomic instructions.
459///
460/// For an in-depth explanation of memory orderings, see the C++ documentation
461/// for [`memory_order`] or the Rust documentation for [`atomic::Ordering`].
462///
463/// [`memory_order`]: https://en.cppreference.com/w/cpp/atomic/memory_order
464/// [`atomic::Ordering`]: https://doc.rust-lang.org/std/sync/atomic/enum.Ordering.html
465#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
466pub enum Ordering {
467    /// For a load, it acquires; this orders all operations before the last
468    /// "releasing" store. For a store, it releases; this orders all operations
469    /// before it at the next "acquiring" load.
470    AcqRel,
471    /// Like `AcqRel` but all threads see all sequentially consistent operations
472    /// in the same order.
473    SeqCst,
474}
475
476impl Encode for Ordering {
477    fn encode(&self, sink: &mut Vec<u8>) {
478        let flag: u8 = match self {
479            Ordering::SeqCst => 0,
480            Ordering::AcqRel => 1,
481        };
482        sink.push(flag);
483    }
484}
485
486/// Describe an unchecked SIMD lane index.
487pub type Lane = u8;
488
489/// The type for a `block`/`if`/`loop`.
490#[derive(Clone, Copy, Debug)]
491pub enum BlockType {
492    /// `[] -> []`
493    Empty,
494    /// `[] -> [t]`
495    Result(ValType),
496    /// The `n`th function type.
497    FunctionType(u32),
498}
499
500impl Encode for BlockType {
501    fn encode(&self, sink: &mut Vec<u8>) {
502        match *self {
503            Self::Empty => sink.push(0x40),
504            Self::Result(ty) => ty.encode(sink),
505            Self::FunctionType(f) => (f as i64).encode(sink),
506        }
507    }
508}
509
510/// WebAssembly instructions.
511#[derive(Clone, Debug)]
512#[non_exhaustive]
513#[allow(missing_docs, non_camel_case_types)]
514pub enum Instruction<'a> {
515    // Control instructions.
516    Unreachable,
517    Nop,
518    Block(BlockType),
519    Loop(BlockType),
520    If(BlockType),
521    Else,
522    End,
523    Br(u32),
524    BrIf(u32),
525    BrTable(Cow<'a, [u32]>, u32),
526    BrOnNull(u32),
527    BrOnNonNull(u32),
528    Return,
529    Call(u32),
530    CallRef(u32),
531    CallIndirect {
532        type_index: u32,
533        table_index: u32,
534    },
535    ReturnCallRef(u32),
536    ReturnCall(u32),
537    ReturnCallIndirect {
538        type_index: u32,
539        table_index: u32,
540    },
541    TryTable(BlockType, Cow<'a, [Catch]>),
542    Throw(u32),
543    ThrowRef,
544
545    // Deprecated exception-handling instructions
546    Try(BlockType),
547    Delegate(u32),
548    Catch(u32),
549    CatchAll,
550    Rethrow(u32),
551
552    // Parametric instructions.
553    Drop,
554    Select,
555
556    // Variable instructions.
557    LocalGet(u32),
558    LocalSet(u32),
559    LocalTee(u32),
560    GlobalGet(u32),
561    GlobalSet(u32),
562
563    // Memory instructions.
564    I32Load(MemArg),
565    I64Load(MemArg),
566    F32Load(MemArg),
567    F64Load(MemArg),
568    I32Load8S(MemArg),
569    I32Load8U(MemArg),
570    I32Load16S(MemArg),
571    I32Load16U(MemArg),
572    I64Load8S(MemArg),
573    I64Load8U(MemArg),
574    I64Load16S(MemArg),
575    I64Load16U(MemArg),
576    I64Load32S(MemArg),
577    I64Load32U(MemArg),
578    I32Store(MemArg),
579    I64Store(MemArg),
580    F32Store(MemArg),
581    F64Store(MemArg),
582    I32Store8(MemArg),
583    I32Store16(MemArg),
584    I64Store8(MemArg),
585    I64Store16(MemArg),
586    I64Store32(MemArg),
587    MemorySize(u32),
588    MemoryGrow(u32),
589    MemoryInit {
590        mem: u32,
591        data_index: u32,
592    },
593    DataDrop(u32),
594    MemoryCopy {
595        src_mem: u32,
596        dst_mem: u32,
597    },
598    MemoryFill(u32),
599    MemoryDiscard(u32),
600
601    // Numeric instructions.
602    I32Const(i32),
603    I64Const(i64),
604    F32Const(Ieee32),
605    F64Const(Ieee64),
606    I32Eqz,
607    I32Eq,
608    I32Ne,
609    I32LtS,
610    I32LtU,
611    I32GtS,
612    I32GtU,
613    I32LeS,
614    I32LeU,
615    I32GeS,
616    I32GeU,
617    I64Eqz,
618    I64Eq,
619    I64Ne,
620    I64LtS,
621    I64LtU,
622    I64GtS,
623    I64GtU,
624    I64LeS,
625    I64LeU,
626    I64GeS,
627    I64GeU,
628    F32Eq,
629    F32Ne,
630    F32Lt,
631    F32Gt,
632    F32Le,
633    F32Ge,
634    F64Eq,
635    F64Ne,
636    F64Lt,
637    F64Gt,
638    F64Le,
639    F64Ge,
640    I32Clz,
641    I32Ctz,
642    I32Popcnt,
643    I32Add,
644    I32Sub,
645    I32Mul,
646    I32DivS,
647    I32DivU,
648    I32RemS,
649    I32RemU,
650    I32And,
651    I32Or,
652    I32Xor,
653    I32Shl,
654    I32ShrS,
655    I32ShrU,
656    I32Rotl,
657    I32Rotr,
658    I64Clz,
659    I64Ctz,
660    I64Popcnt,
661    I64Add,
662    I64Sub,
663    I64Mul,
664    I64DivS,
665    I64DivU,
666    I64RemS,
667    I64RemU,
668    I64And,
669    I64Or,
670    I64Xor,
671    I64Shl,
672    I64ShrS,
673    I64ShrU,
674    I64Rotl,
675    I64Rotr,
676    F32Abs,
677    F32Neg,
678    F32Ceil,
679    F32Floor,
680    F32Trunc,
681    F32Nearest,
682    F32Sqrt,
683    F32Add,
684    F32Sub,
685    F32Mul,
686    F32Div,
687    F32Min,
688    F32Max,
689    F32Copysign,
690    F64Abs,
691    F64Neg,
692    F64Ceil,
693    F64Floor,
694    F64Trunc,
695    F64Nearest,
696    F64Sqrt,
697    F64Add,
698    F64Sub,
699    F64Mul,
700    F64Div,
701    F64Min,
702    F64Max,
703    F64Copysign,
704    I32WrapI64,
705    I32TruncF32S,
706    I32TruncF32U,
707    I32TruncF64S,
708    I32TruncF64U,
709    I64ExtendI32S,
710    I64ExtendI32U,
711    I64TruncF32S,
712    I64TruncF32U,
713    I64TruncF64S,
714    I64TruncF64U,
715    F32ConvertI32S,
716    F32ConvertI32U,
717    F32ConvertI64S,
718    F32ConvertI64U,
719    F32DemoteF64,
720    F64ConvertI32S,
721    F64ConvertI32U,
722    F64ConvertI64S,
723    F64ConvertI64U,
724    F64PromoteF32,
725    I32ReinterpretF32,
726    I64ReinterpretF64,
727    F32ReinterpretI32,
728    F64ReinterpretI64,
729    I32Extend8S,
730    I32Extend16S,
731    I64Extend8S,
732    I64Extend16S,
733    I64Extend32S,
734    I32TruncSatF32S,
735    I32TruncSatF32U,
736    I32TruncSatF64S,
737    I32TruncSatF64U,
738    I64TruncSatF32S,
739    I64TruncSatF32U,
740    I64TruncSatF64S,
741    I64TruncSatF64U,
742
743    // Reference types instructions.
744    TypedSelect(ValType),
745    TypedSelectMulti(Cow<'a, [ValType]>),
746    RefNull(HeapType),
747    RefIsNull,
748    RefFunc(u32),
749    RefEq,
750    RefAsNonNull,
751
752    // GC types instructions.
753    StructNew(u32),
754    StructNewDefault(u32),
755    StructGet {
756        struct_type_index: u32,
757        field_index: u32,
758    },
759    StructGetS {
760        struct_type_index: u32,
761        field_index: u32,
762    },
763    StructGetU {
764        struct_type_index: u32,
765        field_index: u32,
766    },
767    StructSet {
768        struct_type_index: u32,
769        field_index: u32,
770    },
771    StructNewDesc(u32),
772    StructNewDefaultDesc(u32),
773
774    ArrayNew(u32),
775    ArrayNewDefault(u32),
776    ArrayNewFixed {
777        array_type_index: u32,
778        array_size: u32,
779    },
780    ArrayNewData {
781        array_type_index: u32,
782        array_data_index: u32,
783    },
784    ArrayNewElem {
785        array_type_index: u32,
786        array_elem_index: u32,
787    },
788    ArrayGet(u32),
789    ArrayGetS(u32),
790    ArrayGetU(u32),
791    ArraySet(u32),
792    ArrayLen,
793    ArrayFill(u32),
794    ArrayCopy {
795        array_type_index_dst: u32,
796        array_type_index_src: u32,
797    },
798    ArrayInitData {
799        array_type_index: u32,
800        array_data_index: u32,
801    },
802    ArrayInitElem {
803        array_type_index: u32,
804        array_elem_index: u32,
805    },
806    RefTestNonNull(HeapType),
807    RefTestNullable(HeapType),
808    RefCastNonNull(HeapType),
809    RefCastNullable(HeapType),
810    BrOnCast {
811        relative_depth: u32,
812        from_ref_type: RefType,
813        to_ref_type: RefType,
814    },
815    BrOnCastFail {
816        relative_depth: u32,
817        from_ref_type: RefType,
818        to_ref_type: RefType,
819    },
820    AnyConvertExtern,
821    ExternConvertAny,
822
823    RefI31,
824    I31GetS,
825    I31GetU,
826
827    // Bulk memory instructions.
828    TableInit {
829        elem_index: u32,
830        table: u32,
831    },
832    ElemDrop(u32),
833    TableFill(u32),
834    TableSet(u32),
835    TableGet(u32),
836    TableGrow(u32),
837    TableSize(u32),
838    TableCopy {
839        src_table: u32,
840        dst_table: u32,
841    },
842
843    // SIMD instructions.
844    V128Load(MemArg),
845    V128Load8x8S(MemArg),
846    V128Load8x8U(MemArg),
847    V128Load16x4S(MemArg),
848    V128Load16x4U(MemArg),
849    V128Load32x2S(MemArg),
850    V128Load32x2U(MemArg),
851    V128Load8Splat(MemArg),
852    V128Load16Splat(MemArg),
853    V128Load32Splat(MemArg),
854    V128Load64Splat(MemArg),
855    V128Load32Zero(MemArg),
856    V128Load64Zero(MemArg),
857    V128Store(MemArg),
858    V128Load8Lane {
859        memarg: MemArg,
860        lane: Lane,
861    },
862    V128Load16Lane {
863        memarg: MemArg,
864        lane: Lane,
865    },
866    V128Load32Lane {
867        memarg: MemArg,
868        lane: Lane,
869    },
870    V128Load64Lane {
871        memarg: MemArg,
872        lane: Lane,
873    },
874    V128Store8Lane {
875        memarg: MemArg,
876        lane: Lane,
877    },
878    V128Store16Lane {
879        memarg: MemArg,
880        lane: Lane,
881    },
882    V128Store32Lane {
883        memarg: MemArg,
884        lane: Lane,
885    },
886    V128Store64Lane {
887        memarg: MemArg,
888        lane: Lane,
889    },
890    V128Const(i128),
891    I8x16Shuffle([Lane; 16]),
892    I8x16ExtractLaneS(Lane),
893    I8x16ExtractLaneU(Lane),
894    I8x16ReplaceLane(Lane),
895    I16x8ExtractLaneS(Lane),
896    I16x8ExtractLaneU(Lane),
897    I16x8ReplaceLane(Lane),
898    I32x4ExtractLane(Lane),
899    I32x4ReplaceLane(Lane),
900    I64x2ExtractLane(Lane),
901    I64x2ReplaceLane(Lane),
902    F32x4ExtractLane(Lane),
903    F32x4ReplaceLane(Lane),
904    F64x2ExtractLane(Lane),
905    F64x2ReplaceLane(Lane),
906    I8x16Swizzle,
907    I8x16Splat,
908    I16x8Splat,
909    I32x4Splat,
910    I64x2Splat,
911    F32x4Splat,
912    F64x2Splat,
913    I8x16Eq,
914    I8x16Ne,
915    I8x16LtS,
916    I8x16LtU,
917    I8x16GtS,
918    I8x16GtU,
919    I8x16LeS,
920    I8x16LeU,
921    I8x16GeS,
922    I8x16GeU,
923    I16x8Eq,
924    I16x8Ne,
925    I16x8LtS,
926    I16x8LtU,
927    I16x8GtS,
928    I16x8GtU,
929    I16x8LeS,
930    I16x8LeU,
931    I16x8GeS,
932    I16x8GeU,
933    I32x4Eq,
934    I32x4Ne,
935    I32x4LtS,
936    I32x4LtU,
937    I32x4GtS,
938    I32x4GtU,
939    I32x4LeS,
940    I32x4LeU,
941    I32x4GeS,
942    I32x4GeU,
943    I64x2Eq,
944    I64x2Ne,
945    I64x2LtS,
946    I64x2GtS,
947    I64x2LeS,
948    I64x2GeS,
949    F32x4Eq,
950    F32x4Ne,
951    F32x4Lt,
952    F32x4Gt,
953    F32x4Le,
954    F32x4Ge,
955    F64x2Eq,
956    F64x2Ne,
957    F64x2Lt,
958    F64x2Gt,
959    F64x2Le,
960    F64x2Ge,
961    V128Not,
962    V128And,
963    V128AndNot,
964    V128Or,
965    V128Xor,
966    V128Bitselect,
967    V128AnyTrue,
968    I8x16Abs,
969    I8x16Neg,
970    I8x16Popcnt,
971    I8x16AllTrue,
972    I8x16Bitmask,
973    I8x16NarrowI16x8S,
974    I8x16NarrowI16x8U,
975    I8x16Shl,
976    I8x16ShrS,
977    I8x16ShrU,
978    I8x16Add,
979    I8x16AddSatS,
980    I8x16AddSatU,
981    I8x16Sub,
982    I8x16SubSatS,
983    I8x16SubSatU,
984    I8x16MinS,
985    I8x16MinU,
986    I8x16MaxS,
987    I8x16MaxU,
988    I8x16AvgrU,
989    I16x8ExtAddPairwiseI8x16S,
990    I16x8ExtAddPairwiseI8x16U,
991    I16x8Abs,
992    I16x8Neg,
993    I16x8Q15MulrSatS,
994    I16x8AllTrue,
995    I16x8Bitmask,
996    I16x8NarrowI32x4S,
997    I16x8NarrowI32x4U,
998    I16x8ExtendLowI8x16S,
999    I16x8ExtendHighI8x16S,
1000    I16x8ExtendLowI8x16U,
1001    I16x8ExtendHighI8x16U,
1002    I16x8Shl,
1003    I16x8ShrS,
1004    I16x8ShrU,
1005    I16x8Add,
1006    I16x8AddSatS,
1007    I16x8AddSatU,
1008    I16x8Sub,
1009    I16x8SubSatS,
1010    I16x8SubSatU,
1011    I16x8Mul,
1012    I16x8MinS,
1013    I16x8MinU,
1014    I16x8MaxS,
1015    I16x8MaxU,
1016    I16x8AvgrU,
1017    I16x8ExtMulLowI8x16S,
1018    I16x8ExtMulHighI8x16S,
1019    I16x8ExtMulLowI8x16U,
1020    I16x8ExtMulHighI8x16U,
1021    I32x4ExtAddPairwiseI16x8S,
1022    I32x4ExtAddPairwiseI16x8U,
1023    I32x4Abs,
1024    I32x4Neg,
1025    I32x4AllTrue,
1026    I32x4Bitmask,
1027    I32x4ExtendLowI16x8S,
1028    I32x4ExtendHighI16x8S,
1029    I32x4ExtendLowI16x8U,
1030    I32x4ExtendHighI16x8U,
1031    I32x4Shl,
1032    I32x4ShrS,
1033    I32x4ShrU,
1034    I32x4Add,
1035    I32x4Sub,
1036    I32x4Mul,
1037    I32x4MinS,
1038    I32x4MinU,
1039    I32x4MaxS,
1040    I32x4MaxU,
1041    I32x4DotI16x8S,
1042    I32x4ExtMulLowI16x8S,
1043    I32x4ExtMulHighI16x8S,
1044    I32x4ExtMulLowI16x8U,
1045    I32x4ExtMulHighI16x8U,
1046    I64x2Abs,
1047    I64x2Neg,
1048    I64x2AllTrue,
1049    I64x2Bitmask,
1050    I64x2ExtendLowI32x4S,
1051    I64x2ExtendHighI32x4S,
1052    I64x2ExtendLowI32x4U,
1053    I64x2ExtendHighI32x4U,
1054    I64x2Shl,
1055    I64x2ShrS,
1056    I64x2ShrU,
1057    I64x2Add,
1058    I64x2Sub,
1059    I64x2Mul,
1060    I64x2ExtMulLowI32x4S,
1061    I64x2ExtMulHighI32x4S,
1062    I64x2ExtMulLowI32x4U,
1063    I64x2ExtMulHighI32x4U,
1064    F32x4Ceil,
1065    F32x4Floor,
1066    F32x4Trunc,
1067    F32x4Nearest,
1068    F32x4Abs,
1069    F32x4Neg,
1070    F32x4Sqrt,
1071    F32x4Add,
1072    F32x4Sub,
1073    F32x4Mul,
1074    F32x4Div,
1075    F32x4Min,
1076    F32x4Max,
1077    F32x4PMin,
1078    F32x4PMax,
1079    F64x2Ceil,
1080    F64x2Floor,
1081    F64x2Trunc,
1082    F64x2Nearest,
1083    F64x2Abs,
1084    F64x2Neg,
1085    F64x2Sqrt,
1086    F64x2Add,
1087    F64x2Sub,
1088    F64x2Mul,
1089    F64x2Div,
1090    F64x2Min,
1091    F64x2Max,
1092    F64x2PMin,
1093    F64x2PMax,
1094    I32x4TruncSatF32x4S,
1095    I32x4TruncSatF32x4U,
1096    F32x4ConvertI32x4S,
1097    F32x4ConvertI32x4U,
1098    I32x4TruncSatF64x2SZero,
1099    I32x4TruncSatF64x2UZero,
1100    F64x2ConvertLowI32x4S,
1101    F64x2ConvertLowI32x4U,
1102    F32x4DemoteF64x2Zero,
1103    F64x2PromoteLowF32x4,
1104
1105    // Relaxed simd proposal
1106    I8x16RelaxedSwizzle,
1107    I32x4RelaxedTruncF32x4S,
1108    I32x4RelaxedTruncF32x4U,
1109    I32x4RelaxedTruncF64x2SZero,
1110    I32x4RelaxedTruncF64x2UZero,
1111    F32x4RelaxedMadd,
1112    F32x4RelaxedNmadd,
1113    F64x2RelaxedMadd,
1114    F64x2RelaxedNmadd,
1115    I8x16RelaxedLaneselect,
1116    I16x8RelaxedLaneselect,
1117    I32x4RelaxedLaneselect,
1118    I64x2RelaxedLaneselect,
1119    F32x4RelaxedMin,
1120    F32x4RelaxedMax,
1121    F64x2RelaxedMin,
1122    F64x2RelaxedMax,
1123    I16x8RelaxedQ15mulrS,
1124    I16x8RelaxedDotI8x16I7x16S,
1125    I32x4RelaxedDotI8x16I7x16AddS,
1126
1127    // Atomic instructions (the threads proposal)
1128    MemoryAtomicNotify(MemArg),
1129    MemoryAtomicWait32(MemArg),
1130    MemoryAtomicWait64(MemArg),
1131    AtomicFence(Ordering),
1132    I32AtomicLoad(MemArg),
1133    I64AtomicLoad(MemArg),
1134    I32AtomicLoad8U(MemArg),
1135    I32AtomicLoad16U(MemArg),
1136    I64AtomicLoad8U(MemArg),
1137    I64AtomicLoad16U(MemArg),
1138    I64AtomicLoad32U(MemArg),
1139    I32AtomicStore(MemArg),
1140    I64AtomicStore(MemArg),
1141    I32AtomicStore8(MemArg),
1142    I32AtomicStore16(MemArg),
1143    I64AtomicStore8(MemArg),
1144    I64AtomicStore16(MemArg),
1145    I64AtomicStore32(MemArg),
1146    I32AtomicRmwAdd(MemArg),
1147    I64AtomicRmwAdd(MemArg),
1148    I32AtomicRmw8AddU(MemArg),
1149    I32AtomicRmw16AddU(MemArg),
1150    I64AtomicRmw8AddU(MemArg),
1151    I64AtomicRmw16AddU(MemArg),
1152    I64AtomicRmw32AddU(MemArg),
1153    I32AtomicRmwSub(MemArg),
1154    I64AtomicRmwSub(MemArg),
1155    I32AtomicRmw8SubU(MemArg),
1156    I32AtomicRmw16SubU(MemArg),
1157    I64AtomicRmw8SubU(MemArg),
1158    I64AtomicRmw16SubU(MemArg),
1159    I64AtomicRmw32SubU(MemArg),
1160    I32AtomicRmwAnd(MemArg),
1161    I64AtomicRmwAnd(MemArg),
1162    I32AtomicRmw8AndU(MemArg),
1163    I32AtomicRmw16AndU(MemArg),
1164    I64AtomicRmw8AndU(MemArg),
1165    I64AtomicRmw16AndU(MemArg),
1166    I64AtomicRmw32AndU(MemArg),
1167    I32AtomicRmwOr(MemArg),
1168    I64AtomicRmwOr(MemArg),
1169    I32AtomicRmw8OrU(MemArg),
1170    I32AtomicRmw16OrU(MemArg),
1171    I64AtomicRmw8OrU(MemArg),
1172    I64AtomicRmw16OrU(MemArg),
1173    I64AtomicRmw32OrU(MemArg),
1174    I32AtomicRmwXor(MemArg),
1175    I64AtomicRmwXor(MemArg),
1176    I32AtomicRmw8XorU(MemArg),
1177    I32AtomicRmw16XorU(MemArg),
1178    I64AtomicRmw8XorU(MemArg),
1179    I64AtomicRmw16XorU(MemArg),
1180    I64AtomicRmw32XorU(MemArg),
1181    I32AtomicRmwXchg(MemArg),
1182    I64AtomicRmwXchg(MemArg),
1183    I32AtomicRmw8XchgU(MemArg),
1184    I32AtomicRmw16XchgU(MemArg),
1185    I64AtomicRmw8XchgU(MemArg),
1186    I64AtomicRmw16XchgU(MemArg),
1187    I64AtomicRmw32XchgU(MemArg),
1188    I32AtomicRmwCmpxchg(MemArg),
1189    I64AtomicRmwCmpxchg(MemArg),
1190    I32AtomicRmw8CmpxchgU(MemArg),
1191    I32AtomicRmw16CmpxchgU(MemArg),
1192    I64AtomicRmw8CmpxchgU(MemArg),
1193    I64AtomicRmw16CmpxchgU(MemArg),
1194    I64AtomicRmw32CmpxchgU(MemArg),
1195
1196    // More atomic instructions (the shared-everything-threads proposal)
1197    GlobalAtomicGet {
1198        ordering: Ordering,
1199        global_index: u32,
1200    },
1201    GlobalAtomicSet {
1202        ordering: Ordering,
1203        global_index: u32,
1204    },
1205    GlobalAtomicRmwAdd {
1206        ordering: Ordering,
1207        global_index: u32,
1208    },
1209    GlobalAtomicRmwSub {
1210        ordering: Ordering,
1211        global_index: u32,
1212    },
1213    GlobalAtomicRmwAnd {
1214        ordering: Ordering,
1215        global_index: u32,
1216    },
1217    GlobalAtomicRmwOr {
1218        ordering: Ordering,
1219        global_index: u32,
1220    },
1221    GlobalAtomicRmwXor {
1222        ordering: Ordering,
1223        global_index: u32,
1224    },
1225    GlobalAtomicRmwXchg {
1226        ordering: Ordering,
1227        global_index: u32,
1228    },
1229    GlobalAtomicRmwCmpxchg {
1230        ordering: Ordering,
1231        global_index: u32,
1232    },
1233    TableAtomicGet {
1234        ordering: Ordering,
1235        table_index: u32,
1236    },
1237    TableAtomicSet {
1238        ordering: Ordering,
1239        table_index: u32,
1240    },
1241    TableAtomicRmwXchg {
1242        ordering: Ordering,
1243        table_index: u32,
1244    },
1245    TableAtomicRmwCmpxchg {
1246        ordering: Ordering,
1247        table_index: u32,
1248    },
1249    StructAtomicGet {
1250        ordering: Ordering,
1251        struct_type_index: u32,
1252        field_index: u32,
1253    },
1254    StructAtomicGetS {
1255        ordering: Ordering,
1256        struct_type_index: u32,
1257        field_index: u32,
1258    },
1259    StructAtomicGetU {
1260        ordering: Ordering,
1261        struct_type_index: u32,
1262        field_index: u32,
1263    },
1264    StructAtomicSet {
1265        ordering: Ordering,
1266        struct_type_index: u32,
1267        field_index: u32,
1268    },
1269    StructAtomicRmwAdd {
1270        ordering: Ordering,
1271        struct_type_index: u32,
1272        field_index: u32,
1273    },
1274    StructAtomicRmwSub {
1275        ordering: Ordering,
1276        struct_type_index: u32,
1277        field_index: u32,
1278    },
1279    StructAtomicRmwAnd {
1280        ordering: Ordering,
1281        struct_type_index: u32,
1282        field_index: u32,
1283    },
1284    StructAtomicRmwOr {
1285        ordering: Ordering,
1286        struct_type_index: u32,
1287        field_index: u32,
1288    },
1289    StructAtomicRmwXor {
1290        ordering: Ordering,
1291        struct_type_index: u32,
1292        field_index: u32,
1293    },
1294    StructAtomicRmwXchg {
1295        ordering: Ordering,
1296        struct_type_index: u32,
1297        field_index: u32,
1298    },
1299    StructAtomicRmwCmpxchg {
1300        ordering: Ordering,
1301        struct_type_index: u32,
1302        field_index: u32,
1303    },
1304    ArrayAtomicGet {
1305        ordering: Ordering,
1306        array_type_index: u32,
1307    },
1308    ArrayAtomicGetS {
1309        ordering: Ordering,
1310        array_type_index: u32,
1311    },
1312    ArrayAtomicGetU {
1313        ordering: Ordering,
1314        array_type_index: u32,
1315    },
1316    ArrayAtomicSet {
1317        ordering: Ordering,
1318        array_type_index: u32,
1319    },
1320    ArrayAtomicRmwAdd {
1321        ordering: Ordering,
1322        array_type_index: u32,
1323    },
1324    ArrayAtomicRmwSub {
1325        ordering: Ordering,
1326        array_type_index: u32,
1327    },
1328    ArrayAtomicRmwAnd {
1329        ordering: Ordering,
1330        array_type_index: u32,
1331    },
1332    ArrayAtomicRmwOr {
1333        ordering: Ordering,
1334        array_type_index: u32,
1335    },
1336    ArrayAtomicRmwXor {
1337        ordering: Ordering,
1338        array_type_index: u32,
1339    },
1340    ArrayAtomicRmwXchg {
1341        ordering: Ordering,
1342        array_type_index: u32,
1343    },
1344    ArrayAtomicRmwCmpxchg {
1345        ordering: Ordering,
1346        array_type_index: u32,
1347    },
1348    RefI31Shared,
1349    // Stack switching
1350    ContNew(u32),
1351    ContBind {
1352        argument_index: u32,
1353        result_index: u32,
1354    },
1355    Suspend(u32),
1356    Resume {
1357        cont_type_index: u32,
1358        resume_table: Cow<'a, [Handle]>,
1359    },
1360    ResumeThrow {
1361        cont_type_index: u32,
1362        tag_index: u32,
1363        resume_table: Cow<'a, [Handle]>,
1364    },
1365    ResumeThrowRef {
1366        cont_type_index: u32,
1367        resume_table: Cow<'a, [Handle]>,
1368    },
1369    Switch {
1370        cont_type_index: u32,
1371        tag_index: u32,
1372    },
1373
1374    // Wide Arithmetic
1375    I64Add128,
1376    I64Sub128,
1377    I64MulWideS,
1378    I64MulWideU,
1379
1380    // Acquire-release atomics
1381    Pause,
1382
1383    RefGetDesc(u32),
1384    RefCastDescEqNonNull(HeapType),
1385    RefCastDescEqNullable(HeapType),
1386    BrOnCastDescEq {
1387        relative_depth: u32,
1388        from_ref_type: RefType,
1389        to_ref_type: RefType,
1390    },
1391    BrOnCastDescEqFail {
1392        relative_depth: u32,
1393        from_ref_type: RefType,
1394        to_ref_type: RefType,
1395    },
1396}
1397
1398impl Encode for Instruction<'_> {
1399    fn encode(&self, bytes: &mut Vec<u8>) {
1400        let mut sink = InstructionSink::new(bytes);
1401        match *self {
1402            // Control instructions.
1403            Instruction::Unreachable => sink.unreachable(),
1404            Instruction::Nop => sink.nop(),
1405            Instruction::Block(bt) => sink.block(bt),
1406            Instruction::Loop(bt) => sink.loop_(bt),
1407            Instruction::If(bt) => sink.if_(bt),
1408            Instruction::Else => sink.else_(),
1409            Instruction::Try(bt) => sink.try_(bt),
1410            Instruction::Catch(t) => sink.catch(t),
1411            Instruction::Throw(t) => sink.throw(t),
1412            Instruction::Rethrow(l) => sink.rethrow(l),
1413            Instruction::ThrowRef => sink.throw_ref(),
1414            Instruction::End => sink.end(),
1415            Instruction::Br(l) => sink.br(l),
1416            Instruction::BrIf(l) => sink.br_if(l),
1417            Instruction::BrTable(ref ls, l) => sink.br_table(ls.iter().copied(), l),
1418            Instruction::BrOnNull(l) => sink.br_on_null(l),
1419            Instruction::BrOnNonNull(l) => sink.br_on_non_null(l),
1420            Instruction::Return => sink.return_(),
1421            Instruction::Call(f) => sink.call(f),
1422            Instruction::CallRef(ty) => sink.call_ref(ty),
1423            Instruction::CallIndirect {
1424                type_index,
1425                table_index,
1426            } => sink.call_indirect(table_index, type_index),
1427            Instruction::ReturnCallRef(ty) => sink.return_call_ref(ty),
1428
1429            Instruction::ReturnCall(f) => sink.return_call(f),
1430            Instruction::ReturnCallIndirect {
1431                type_index,
1432                table_index,
1433            } => sink.return_call_indirect(table_index, type_index),
1434            Instruction::Delegate(l) => sink.delegate(l),
1435            Instruction::CatchAll => sink.catch_all(),
1436
1437            // Parametric instructions.
1438            Instruction::Drop => sink.drop(),
1439            Instruction::Select => sink.select(),
1440            Instruction::TypedSelect(ty) => sink.typed_select(ty),
1441            Instruction::TypedSelectMulti(ref tys) => sink.typed_select_multi(tys.as_ref()),
1442
1443            Instruction::TryTable(ty, ref catches) => sink.try_table(ty, catches.iter().cloned()),
1444
1445            // Variable instructions.
1446            Instruction::LocalGet(l) => sink.local_get(l),
1447            Instruction::LocalSet(l) => sink.local_set(l),
1448            Instruction::LocalTee(l) => sink.local_tee(l),
1449            Instruction::GlobalGet(g) => sink.global_get(g),
1450            Instruction::GlobalSet(g) => sink.global_set(g),
1451            Instruction::TableGet(table) => sink.table_get(table),
1452            Instruction::TableSet(table) => sink.table_set(table),
1453
1454            // Memory instructions.
1455            Instruction::I32Load(m) => sink.i32_load(m),
1456            Instruction::I64Load(m) => sink.i64_load(m),
1457            Instruction::F32Load(m) => sink.f32_load(m),
1458            Instruction::F64Load(m) => sink.f64_load(m),
1459            Instruction::I32Load8S(m) => sink.i32_load8_s(m),
1460            Instruction::I32Load8U(m) => sink.i32_load8_u(m),
1461            Instruction::I32Load16S(m) => sink.i32_load16_s(m),
1462            Instruction::I32Load16U(m) => sink.i32_load16_u(m),
1463            Instruction::I64Load8S(m) => sink.i64_load8_s(m),
1464            Instruction::I64Load8U(m) => sink.i64_load8_u(m),
1465            Instruction::I64Load16S(m) => sink.i64_load16_s(m),
1466            Instruction::I64Load16U(m) => sink.i64_load16_u(m),
1467            Instruction::I64Load32S(m) => sink.i64_load32_s(m),
1468            Instruction::I64Load32U(m) => sink.i64_load32_u(m),
1469            Instruction::I32Store(m) => sink.i32_store(m),
1470            Instruction::I64Store(m) => sink.i64_store(m),
1471            Instruction::F32Store(m) => sink.f32_store(m),
1472            Instruction::F64Store(m) => sink.f64_store(m),
1473            Instruction::I32Store8(m) => sink.i32_store8(m),
1474            Instruction::I32Store16(m) => sink.i32_store16(m),
1475            Instruction::I64Store8(m) => sink.i64_store8(m),
1476            Instruction::I64Store16(m) => sink.i64_store16(m),
1477            Instruction::I64Store32(m) => sink.i64_store32(m),
1478            Instruction::MemorySize(i) => sink.memory_size(i),
1479            Instruction::MemoryGrow(i) => sink.memory_grow(i),
1480            Instruction::MemoryInit { mem, data_index } => sink.memory_init(mem, data_index),
1481            Instruction::DataDrop(data) => sink.data_drop(data),
1482            Instruction::MemoryCopy { src_mem, dst_mem } => sink.memory_copy(dst_mem, src_mem),
1483            Instruction::MemoryFill(mem) => sink.memory_fill(mem),
1484            Instruction::MemoryDiscard(mem) => sink.memory_discard(mem),
1485
1486            // Numeric instructions.
1487            Instruction::I32Const(x) => sink.i32_const(x),
1488            Instruction::I64Const(x) => sink.i64_const(x),
1489            Instruction::F32Const(x) => sink.f32_const(x),
1490            Instruction::F64Const(x) => sink.f64_const(x),
1491            Instruction::I32Eqz => sink.i32_eqz(),
1492            Instruction::I32Eq => sink.i32_eq(),
1493            Instruction::I32Ne => sink.i32_ne(),
1494            Instruction::I32LtS => sink.i32_lt_s(),
1495            Instruction::I32LtU => sink.i32_lt_u(),
1496            Instruction::I32GtS => sink.i32_gt_s(),
1497            Instruction::I32GtU => sink.i32_gt_u(),
1498            Instruction::I32LeS => sink.i32_le_s(),
1499            Instruction::I32LeU => sink.i32_le_u(),
1500            Instruction::I32GeS => sink.i32_ge_s(),
1501            Instruction::I32GeU => sink.i32_ge_u(),
1502            Instruction::I64Eqz => sink.i64_eqz(),
1503            Instruction::I64Eq => sink.i64_eq(),
1504            Instruction::I64Ne => sink.i64_ne(),
1505            Instruction::I64LtS => sink.i64_lt_s(),
1506            Instruction::I64LtU => sink.i64_lt_u(),
1507            Instruction::I64GtS => sink.i64_gt_s(),
1508            Instruction::I64GtU => sink.i64_gt_u(),
1509            Instruction::I64LeS => sink.i64_le_s(),
1510            Instruction::I64LeU => sink.i64_le_u(),
1511            Instruction::I64GeS => sink.i64_ge_s(),
1512            Instruction::I64GeU => sink.i64_ge_u(),
1513            Instruction::F32Eq => sink.f32_eq(),
1514            Instruction::F32Ne => sink.f32_ne(),
1515            Instruction::F32Lt => sink.f32_lt(),
1516            Instruction::F32Gt => sink.f32_gt(),
1517            Instruction::F32Le => sink.f32_le(),
1518            Instruction::F32Ge => sink.f32_ge(),
1519            Instruction::F64Eq => sink.f64_eq(),
1520            Instruction::F64Ne => sink.f64_ne(),
1521            Instruction::F64Lt => sink.f64_lt(),
1522            Instruction::F64Gt => sink.f64_gt(),
1523            Instruction::F64Le => sink.f64_le(),
1524            Instruction::F64Ge => sink.f64_ge(),
1525            Instruction::I32Clz => sink.i32_clz(),
1526            Instruction::I32Ctz => sink.i32_ctz(),
1527            Instruction::I32Popcnt => sink.i32_popcnt(),
1528            Instruction::I32Add => sink.i32_add(),
1529            Instruction::I32Sub => sink.i32_sub(),
1530            Instruction::I32Mul => sink.i32_mul(),
1531            Instruction::I32DivS => sink.i32_div_s(),
1532            Instruction::I32DivU => sink.i32_div_u(),
1533            Instruction::I32RemS => sink.i32_rem_s(),
1534            Instruction::I32RemU => sink.i32_rem_u(),
1535            Instruction::I32And => sink.i32_and(),
1536            Instruction::I32Or => sink.i32_or(),
1537            Instruction::I32Xor => sink.i32_xor(),
1538            Instruction::I32Shl => sink.i32_shl(),
1539            Instruction::I32ShrS => sink.i32_shr_s(),
1540            Instruction::I32ShrU => sink.i32_shr_u(),
1541            Instruction::I32Rotl => sink.i32_rotl(),
1542            Instruction::I32Rotr => sink.i32_rotr(),
1543            Instruction::I64Clz => sink.i64_clz(),
1544            Instruction::I64Ctz => sink.i64_ctz(),
1545            Instruction::I64Popcnt => sink.i64_popcnt(),
1546            Instruction::I64Add => sink.i64_add(),
1547            Instruction::I64Sub => sink.i64_sub(),
1548            Instruction::I64Mul => sink.i64_mul(),
1549            Instruction::I64DivS => sink.i64_div_s(),
1550            Instruction::I64DivU => sink.i64_div_u(),
1551            Instruction::I64RemS => sink.i64_rem_s(),
1552            Instruction::I64RemU => sink.i64_rem_u(),
1553            Instruction::I64And => sink.i64_and(),
1554            Instruction::I64Or => sink.i64_or(),
1555            Instruction::I64Xor => sink.i64_xor(),
1556            Instruction::I64Shl => sink.i64_shl(),
1557            Instruction::I64ShrS => sink.i64_shr_s(),
1558            Instruction::I64ShrU => sink.i64_shr_u(),
1559            Instruction::I64Rotl => sink.i64_rotl(),
1560            Instruction::I64Rotr => sink.i64_rotr(),
1561            Instruction::F32Abs => sink.f32_abs(),
1562            Instruction::F32Neg => sink.f32_neg(),
1563            Instruction::F32Ceil => sink.f32_ceil(),
1564            Instruction::F32Floor => sink.f32_floor(),
1565            Instruction::F32Trunc => sink.f32_trunc(),
1566            Instruction::F32Nearest => sink.f32_nearest(),
1567            Instruction::F32Sqrt => sink.f32_sqrt(),
1568            Instruction::F32Add => sink.f32_add(),
1569            Instruction::F32Sub => sink.f32_sub(),
1570            Instruction::F32Mul => sink.f32_mul(),
1571            Instruction::F32Div => sink.f32_div(),
1572            Instruction::F32Min => sink.f32_min(),
1573            Instruction::F32Max => sink.f32_max(),
1574            Instruction::F32Copysign => sink.f32_copysign(),
1575            Instruction::F64Abs => sink.f64_abs(),
1576            Instruction::F64Neg => sink.f64_neg(),
1577            Instruction::F64Ceil => sink.f64_ceil(),
1578            Instruction::F64Floor => sink.f64_floor(),
1579            Instruction::F64Trunc => sink.f64_trunc(),
1580            Instruction::F64Nearest => sink.f64_nearest(),
1581            Instruction::F64Sqrt => sink.f64_sqrt(),
1582            Instruction::F64Add => sink.f64_add(),
1583            Instruction::F64Sub => sink.f64_sub(),
1584            Instruction::F64Mul => sink.f64_mul(),
1585            Instruction::F64Div => sink.f64_div(),
1586            Instruction::F64Min => sink.f64_min(),
1587            Instruction::F64Max => sink.f64_max(),
1588            Instruction::F64Copysign => sink.f64_copysign(),
1589            Instruction::I32WrapI64 => sink.i32_wrap_i64(),
1590            Instruction::I32TruncF32S => sink.i32_trunc_f32_s(),
1591            Instruction::I32TruncF32U => sink.i32_trunc_f32_u(),
1592            Instruction::I32TruncF64S => sink.i32_trunc_f64_s(),
1593            Instruction::I32TruncF64U => sink.i32_trunc_f64_u(),
1594            Instruction::I64ExtendI32S => sink.i64_extend_i32_s(),
1595            Instruction::I64ExtendI32U => sink.i64_extend_i32_u(),
1596            Instruction::I64TruncF32S => sink.i64_trunc_f32_s(),
1597            Instruction::I64TruncF32U => sink.i64_trunc_f32_u(),
1598            Instruction::I64TruncF64S => sink.i64_trunc_f64_s(),
1599            Instruction::I64TruncF64U => sink.i64_trunc_f64_u(),
1600            Instruction::F32ConvertI32S => sink.f32_convert_i32_s(),
1601            Instruction::F32ConvertI32U => sink.f32_convert_i32_u(),
1602            Instruction::F32ConvertI64S => sink.f32_convert_i64_s(),
1603            Instruction::F32ConvertI64U => sink.f32_convert_i64_u(),
1604            Instruction::F32DemoteF64 => sink.f32_demote_f64(),
1605            Instruction::F64ConvertI32S => sink.f64_convert_i32_s(),
1606            Instruction::F64ConvertI32U => sink.f64_convert_i32_u(),
1607            Instruction::F64ConvertI64S => sink.f64_convert_i64_s(),
1608            Instruction::F64ConvertI64U => sink.f64_convert_i64_u(),
1609            Instruction::F64PromoteF32 => sink.f64_promote_f32(),
1610            Instruction::I32ReinterpretF32 => sink.i32_reinterpret_f32(),
1611            Instruction::I64ReinterpretF64 => sink.i64_reinterpret_f64(),
1612            Instruction::F32ReinterpretI32 => sink.f32_reinterpret_i32(),
1613            Instruction::F64ReinterpretI64 => sink.f64_reinterpret_i64(),
1614            Instruction::I32Extend8S => sink.i32_extend8_s(),
1615            Instruction::I32Extend16S => sink.i32_extend16_s(),
1616            Instruction::I64Extend8S => sink.i64_extend8_s(),
1617            Instruction::I64Extend16S => sink.i64_extend16_s(),
1618            Instruction::I64Extend32S => sink.i64_extend32_s(),
1619
1620            Instruction::I32TruncSatF32S => sink.i32_trunc_sat_f32_s(),
1621            Instruction::I32TruncSatF32U => sink.i32_trunc_sat_f32_u(),
1622            Instruction::I32TruncSatF64S => sink.i32_trunc_sat_f64_s(),
1623            Instruction::I32TruncSatF64U => sink.i32_trunc_sat_f64_u(),
1624            Instruction::I64TruncSatF32S => sink.i64_trunc_sat_f32_s(),
1625            Instruction::I64TruncSatF32U => sink.i64_trunc_sat_f32_u(),
1626            Instruction::I64TruncSatF64S => sink.i64_trunc_sat_f64_s(),
1627            Instruction::I64TruncSatF64U => sink.i64_trunc_sat_f64_u(),
1628
1629            // Reference types instructions.
1630            Instruction::RefNull(ty) => sink.ref_null(ty),
1631            Instruction::RefIsNull => sink.ref_is_null(),
1632            Instruction::RefFunc(f) => sink.ref_func(f),
1633            Instruction::RefEq => sink.ref_eq(),
1634            Instruction::RefAsNonNull => sink.ref_as_non_null(),
1635
1636            // GC instructions.
1637            Instruction::StructNew(type_index) => sink.struct_new(type_index),
1638            Instruction::StructNewDefault(type_index) => sink.struct_new_default(type_index),
1639            Instruction::StructGet {
1640                struct_type_index,
1641                field_index,
1642            } => sink.struct_get(struct_type_index, field_index),
1643            Instruction::StructGetS {
1644                struct_type_index,
1645                field_index,
1646            } => sink.struct_get_s(struct_type_index, field_index),
1647            Instruction::StructGetU {
1648                struct_type_index,
1649                field_index,
1650            } => sink.struct_get_u(struct_type_index, field_index),
1651            Instruction::StructSet {
1652                struct_type_index,
1653                field_index,
1654            } => sink.struct_set(struct_type_index, field_index),
1655            Instruction::StructNewDesc(type_index) => sink.struct_new_desc(type_index),
1656            Instruction::StructNewDefaultDesc(type_index) => {
1657                sink.struct_new_default_desc(type_index)
1658            }
1659            Instruction::ArrayNew(type_index) => sink.array_new(type_index),
1660            Instruction::ArrayNewDefault(type_index) => sink.array_new_default(type_index),
1661            Instruction::ArrayNewFixed {
1662                array_type_index,
1663                array_size,
1664            } => sink.array_new_fixed(array_type_index, array_size),
1665            Instruction::ArrayNewData {
1666                array_type_index,
1667                array_data_index,
1668            } => sink.array_new_data(array_type_index, array_data_index),
1669            Instruction::ArrayNewElem {
1670                array_type_index,
1671                array_elem_index,
1672            } => sink.array_new_elem(array_type_index, array_elem_index),
1673            Instruction::ArrayGet(type_index) => sink.array_get(type_index),
1674            Instruction::ArrayGetS(type_index) => sink.array_get_s(type_index),
1675            Instruction::ArrayGetU(type_index) => sink.array_get_u(type_index),
1676            Instruction::ArraySet(type_index) => sink.array_set(type_index),
1677            Instruction::ArrayLen => sink.array_len(),
1678            Instruction::ArrayFill(type_index) => sink.array_fill(type_index),
1679            Instruction::ArrayCopy {
1680                array_type_index_dst,
1681                array_type_index_src,
1682            } => sink.array_copy(array_type_index_dst, array_type_index_src),
1683            Instruction::ArrayInitData {
1684                array_type_index,
1685                array_data_index,
1686            } => sink.array_init_data(array_type_index, array_data_index),
1687            Instruction::ArrayInitElem {
1688                array_type_index,
1689                array_elem_index,
1690            } => sink.array_init_elem(array_type_index, array_elem_index),
1691            Instruction::RefTestNonNull(heap_type) => sink.ref_test_non_null(heap_type),
1692            Instruction::RefTestNullable(heap_type) => sink.ref_test_nullable(heap_type),
1693            Instruction::RefCastNonNull(heap_type) => sink.ref_cast_non_null(heap_type),
1694            Instruction::RefCastNullable(heap_type) => sink.ref_cast_nullable(heap_type),
1695            Instruction::BrOnCast {
1696                relative_depth,
1697                from_ref_type,
1698                to_ref_type,
1699            } => sink.br_on_cast(relative_depth, from_ref_type, to_ref_type),
1700            Instruction::BrOnCastFail {
1701                relative_depth,
1702                from_ref_type,
1703                to_ref_type,
1704            } => sink.br_on_cast_fail(relative_depth, from_ref_type, to_ref_type),
1705            Instruction::AnyConvertExtern => sink.any_convert_extern(),
1706            Instruction::ExternConvertAny => sink.extern_convert_any(),
1707            Instruction::RefI31 => sink.ref_i31(),
1708            Instruction::I31GetS => sink.i31_get_s(),
1709            Instruction::I31GetU => sink.i31_get_u(),
1710
1711            // Bulk memory instructions.
1712            Instruction::TableInit { elem_index, table } => sink.table_init(table, elem_index),
1713            Instruction::ElemDrop(segment) => sink.elem_drop(segment),
1714            Instruction::TableCopy {
1715                src_table,
1716                dst_table,
1717            } => sink.table_copy(dst_table, src_table),
1718            Instruction::TableGrow(table) => sink.table_grow(table),
1719            Instruction::TableSize(table) => sink.table_size(table),
1720            Instruction::TableFill(table) => sink.table_fill(table),
1721
1722            // SIMD instructions.
1723            Instruction::V128Load(memarg) => sink.v128_load(memarg),
1724            Instruction::V128Load8x8S(memarg) => sink.v128_load8x8_s(memarg),
1725            Instruction::V128Load8x8U(memarg) => sink.v128_load8x8_u(memarg),
1726            Instruction::V128Load16x4S(memarg) => sink.v128_load16x4_s(memarg),
1727            Instruction::V128Load16x4U(memarg) => sink.v128_load16x4_u(memarg),
1728            Instruction::V128Load32x2S(memarg) => sink.v128_load32x2_s(memarg),
1729            Instruction::V128Load32x2U(memarg) => sink.v128_load32x2_u(memarg),
1730            Instruction::V128Load8Splat(memarg) => sink.v128_load8_splat(memarg),
1731            Instruction::V128Load16Splat(memarg) => sink.v128_load16_splat(memarg),
1732            Instruction::V128Load32Splat(memarg) => sink.v128_load32_splat(memarg),
1733            Instruction::V128Load64Splat(memarg) => sink.v128_load64_splat(memarg),
1734            Instruction::V128Store(memarg) => sink.v128_store(memarg),
1735            Instruction::V128Const(x) => sink.v128_const(x),
1736            Instruction::I8x16Shuffle(lanes) => sink.i8x16_shuffle(lanes),
1737            Instruction::I8x16Swizzle => sink.i8x16_swizzle(),
1738            Instruction::I8x16Splat => sink.i8x16_splat(),
1739            Instruction::I16x8Splat => sink.i16x8_splat(),
1740            Instruction::I32x4Splat => sink.i32x4_splat(),
1741            Instruction::I64x2Splat => sink.i64x2_splat(),
1742            Instruction::F32x4Splat => sink.f32x4_splat(),
1743            Instruction::F64x2Splat => sink.f64x2_splat(),
1744            Instruction::I8x16ExtractLaneS(lane) => sink.i8x16_extract_lane_s(lane),
1745            Instruction::I8x16ExtractLaneU(lane) => sink.i8x16_extract_lane_u(lane),
1746            Instruction::I8x16ReplaceLane(lane) => sink.i8x16_replace_lane(lane),
1747            Instruction::I16x8ExtractLaneS(lane) => sink.i16x8_extract_lane_s(lane),
1748            Instruction::I16x8ExtractLaneU(lane) => sink.i16x8_extract_lane_u(lane),
1749            Instruction::I16x8ReplaceLane(lane) => sink.i16x8_replace_lane(lane),
1750            Instruction::I32x4ExtractLane(lane) => sink.i32x4_extract_lane(lane),
1751            Instruction::I32x4ReplaceLane(lane) => sink.i32x4_replace_lane(lane),
1752            Instruction::I64x2ExtractLane(lane) => sink.i64x2_extract_lane(lane),
1753            Instruction::I64x2ReplaceLane(lane) => sink.i64x2_replace_lane(lane),
1754            Instruction::F32x4ExtractLane(lane) => sink.f32x4_extract_lane(lane),
1755            Instruction::F32x4ReplaceLane(lane) => sink.f32x4_replace_lane(lane),
1756            Instruction::F64x2ExtractLane(lane) => sink.f64x2_extract_lane(lane),
1757            Instruction::F64x2ReplaceLane(lane) => sink.f64x2_replace_lane(lane),
1758
1759            Instruction::I8x16Eq => sink.i8x16_eq(),
1760            Instruction::I8x16Ne => sink.i8x16_ne(),
1761            Instruction::I8x16LtS => sink.i8x16_lt_s(),
1762            Instruction::I8x16LtU => sink.i8x16_lt_u(),
1763            Instruction::I8x16GtS => sink.i8x16_gt_s(),
1764            Instruction::I8x16GtU => sink.i8x16_gt_u(),
1765            Instruction::I8x16LeS => sink.i8x16_le_s(),
1766            Instruction::I8x16LeU => sink.i8x16_le_u(),
1767            Instruction::I8x16GeS => sink.i8x16_ge_s(),
1768            Instruction::I8x16GeU => sink.i8x16_ge_u(),
1769            Instruction::I16x8Eq => sink.i16x8_eq(),
1770            Instruction::I16x8Ne => sink.i16x8_ne(),
1771            Instruction::I16x8LtS => sink.i16x8_lt_s(),
1772            Instruction::I16x8LtU => sink.i16x8_lt_u(),
1773            Instruction::I16x8GtS => sink.i16x8_gt_s(),
1774            Instruction::I16x8GtU => sink.i16x8_gt_u(),
1775            Instruction::I16x8LeS => sink.i16x8_le_s(),
1776            Instruction::I16x8LeU => sink.i16x8_le_u(),
1777            Instruction::I16x8GeS => sink.i16x8_ge_s(),
1778            Instruction::I16x8GeU => sink.i16x8_ge_u(),
1779            Instruction::I32x4Eq => sink.i32x4_eq(),
1780            Instruction::I32x4Ne => sink.i32x4_ne(),
1781            Instruction::I32x4LtS => sink.i32x4_lt_s(),
1782            Instruction::I32x4LtU => sink.i32x4_lt_u(),
1783            Instruction::I32x4GtS => sink.i32x4_gt_s(),
1784            Instruction::I32x4GtU => sink.i32x4_gt_u(),
1785            Instruction::I32x4LeS => sink.i32x4_le_s(),
1786            Instruction::I32x4LeU => sink.i32x4_le_u(),
1787            Instruction::I32x4GeS => sink.i32x4_ge_s(),
1788            Instruction::I32x4GeU => sink.i32x4_ge_u(),
1789            Instruction::F32x4Eq => sink.f32x4_eq(),
1790            Instruction::F32x4Ne => sink.f32x4_ne(),
1791            Instruction::F32x4Lt => sink.f32x4_lt(),
1792            Instruction::F32x4Gt => sink.f32x4_gt(),
1793            Instruction::F32x4Le => sink.f32x4_le(),
1794            Instruction::F32x4Ge => sink.f32x4_ge(),
1795            Instruction::F64x2Eq => sink.f64x2_eq(),
1796            Instruction::F64x2Ne => sink.f64x2_ne(),
1797            Instruction::F64x2Lt => sink.f64x2_lt(),
1798            Instruction::F64x2Gt => sink.f64x2_gt(),
1799            Instruction::F64x2Le => sink.f64x2_le(),
1800            Instruction::F64x2Ge => sink.f64x2_ge(),
1801            Instruction::V128Not => sink.v128_not(),
1802            Instruction::V128And => sink.v128_and(),
1803            Instruction::V128AndNot => sink.v128_andnot(),
1804            Instruction::V128Or => sink.v128_or(),
1805            Instruction::V128Xor => sink.v128_xor(),
1806            Instruction::V128Bitselect => sink.v128_bitselect(),
1807            Instruction::V128AnyTrue => sink.v128_any_true(),
1808            Instruction::I8x16Abs => sink.i8x16_abs(),
1809            Instruction::I8x16Neg => sink.i8x16_neg(),
1810            Instruction::I8x16Popcnt => sink.i8x16_popcnt(),
1811            Instruction::I8x16AllTrue => sink.i8x16_all_true(),
1812            Instruction::I8x16Bitmask => sink.i8x16_bitmask(),
1813            Instruction::I8x16NarrowI16x8S => sink.i8x16_narrow_i16x8_s(),
1814            Instruction::I8x16NarrowI16x8U => sink.i8x16_narrow_i16x8_u(),
1815            Instruction::I8x16Shl => sink.i8x16_shl(),
1816            Instruction::I8x16ShrS => sink.i8x16_shr_s(),
1817            Instruction::I8x16ShrU => sink.i8x16_shr_u(),
1818            Instruction::I8x16Add => sink.i8x16_add(),
1819            Instruction::I8x16AddSatS => sink.i8x16_add_sat_s(),
1820            Instruction::I8x16AddSatU => sink.i8x16_add_sat_u(),
1821            Instruction::I8x16Sub => sink.i8x16_sub(),
1822            Instruction::I8x16SubSatS => sink.i8x16_sub_sat_s(),
1823            Instruction::I8x16SubSatU => sink.i8x16_sub_sat_u(),
1824            Instruction::I8x16MinS => sink.i8x16_min_s(),
1825            Instruction::I8x16MinU => sink.i8x16_min_u(),
1826            Instruction::I8x16MaxS => sink.i8x16_max_s(),
1827            Instruction::I8x16MaxU => sink.i8x16_max_u(),
1828            Instruction::I8x16AvgrU => sink.i8x16_avgr_u(),
1829            Instruction::I16x8ExtAddPairwiseI8x16S => sink.i16x8_extadd_pairwise_i8x16_s(),
1830            Instruction::I16x8ExtAddPairwiseI8x16U => sink.i16x8_extadd_pairwise_i8x16_u(),
1831            Instruction::I32x4ExtAddPairwiseI16x8S => sink.i32x4_extadd_pairwise_i16x8_s(),
1832            Instruction::I32x4ExtAddPairwiseI16x8U => sink.i32x4_extadd_pairwise_i16x8_u(),
1833            Instruction::I16x8Abs => sink.i16x8_abs(),
1834            Instruction::I16x8Neg => sink.i16x8_neg(),
1835            Instruction::I16x8Q15MulrSatS => sink.i16x8_q15mulr_sat_s(),
1836            Instruction::I16x8AllTrue => sink.i16x8_all_true(),
1837            Instruction::I16x8Bitmask => sink.i16x8_bitmask(),
1838            Instruction::I16x8NarrowI32x4S => sink.i16x8_narrow_i32x4_s(),
1839            Instruction::I16x8NarrowI32x4U => sink.i16x8_narrow_i32x4_u(),
1840            Instruction::I16x8ExtendLowI8x16S => sink.i16x8_extend_low_i8x16_s(),
1841            Instruction::I16x8ExtendHighI8x16S => sink.i16x8_extend_high_i8x16_s(),
1842            Instruction::I16x8ExtendLowI8x16U => sink.i16x8_extend_low_i8x16_u(),
1843            Instruction::I16x8ExtendHighI8x16U => sink.i16x8_extend_high_i8x16_u(),
1844            Instruction::I16x8Shl => sink.i16x8_shl(),
1845            Instruction::I16x8ShrS => sink.i16x8_shr_s(),
1846            Instruction::I16x8ShrU => sink.i16x8_shr_u(),
1847            Instruction::I16x8Add => sink.i16x8_add(),
1848            Instruction::I16x8AddSatS => sink.i16x8_add_sat_s(),
1849            Instruction::I16x8AddSatU => sink.i16x8_add_sat_u(),
1850            Instruction::I16x8Sub => sink.i16x8_sub(),
1851            Instruction::I16x8SubSatS => sink.i16x8_sub_sat_s(),
1852            Instruction::I16x8SubSatU => sink.i16x8_sub_sat_u(),
1853            Instruction::I16x8Mul => sink.i16x8_mul(),
1854            Instruction::I16x8MinS => sink.i16x8_min_s(),
1855            Instruction::I16x8MinU => sink.i16x8_min_u(),
1856            Instruction::I16x8MaxS => sink.i16x8_max_s(),
1857            Instruction::I16x8MaxU => sink.i16x8_max_u(),
1858            Instruction::I16x8AvgrU => sink.i16x8_avgr_u(),
1859            Instruction::I16x8ExtMulLowI8x16S => sink.i16x8_extmul_low_i8x16_s(),
1860            Instruction::I16x8ExtMulHighI8x16S => sink.i16x8_extmul_high_i8x16_s(),
1861            Instruction::I16x8ExtMulLowI8x16U => sink.i16x8_extmul_low_i8x16_u(),
1862            Instruction::I16x8ExtMulHighI8x16U => sink.i16x8_extmul_high_i8x16_u(),
1863            Instruction::I32x4Abs => sink.i32x4_abs(),
1864            Instruction::I32x4Neg => sink.i32x4_neg(),
1865            Instruction::I32x4AllTrue => sink.i32x4_all_true(),
1866            Instruction::I32x4Bitmask => sink.i32x4_bitmask(),
1867            Instruction::I32x4ExtendLowI16x8S => sink.i32x4_extend_low_i16x8_s(),
1868            Instruction::I32x4ExtendHighI16x8S => sink.i32x4_extend_high_i16x8_s(),
1869            Instruction::I32x4ExtendLowI16x8U => sink.i32x4_extend_low_i16x8_u(),
1870            Instruction::I32x4ExtendHighI16x8U => sink.i32x4_extend_high_i16x8_u(),
1871            Instruction::I32x4Shl => sink.i32x4_shl(),
1872            Instruction::I32x4ShrS => sink.i32x4_shr_s(),
1873            Instruction::I32x4ShrU => sink.i32x4_shr_u(),
1874            Instruction::I32x4Add => sink.i32x4_add(),
1875            Instruction::I32x4Sub => sink.i32x4_sub(),
1876            Instruction::I32x4Mul => sink.i32x4_mul(),
1877            Instruction::I32x4MinS => sink.i32x4_min_s(),
1878            Instruction::I32x4MinU => sink.i32x4_min_u(),
1879            Instruction::I32x4MaxS => sink.i32x4_max_s(),
1880            Instruction::I32x4MaxU => sink.i32x4_max_u(),
1881            Instruction::I32x4DotI16x8S => sink.i32x4_dot_i16x8_s(),
1882            Instruction::I32x4ExtMulLowI16x8S => sink.i32x4_extmul_low_i16x8_s(),
1883            Instruction::I32x4ExtMulHighI16x8S => sink.i32x4_extmul_high_i16x8_s(),
1884            Instruction::I32x4ExtMulLowI16x8U => sink.i32x4_extmul_low_i16x8_u(),
1885            Instruction::I32x4ExtMulHighI16x8U => sink.i32x4_extmul_high_i16x8_u(),
1886            Instruction::I64x2Abs => sink.i64x2_abs(),
1887            Instruction::I64x2Neg => sink.i64x2_neg(),
1888            Instruction::I64x2AllTrue => sink.i64x2_all_true(),
1889            Instruction::I64x2Bitmask => sink.i64x2_bitmask(),
1890            Instruction::I64x2ExtendLowI32x4S => sink.i64x2_extend_low_i32x4_s(),
1891            Instruction::I64x2ExtendHighI32x4S => sink.i64x2_extend_high_i32x4_s(),
1892            Instruction::I64x2ExtendLowI32x4U => sink.i64x2_extend_low_i32x4_u(),
1893            Instruction::I64x2ExtendHighI32x4U => sink.i64x2_extend_high_i32x4_u(),
1894            Instruction::I64x2Shl => sink.i64x2_shl(),
1895            Instruction::I64x2ShrS => sink.i64x2_shr_s(),
1896            Instruction::I64x2ShrU => sink.i64x2_shr_u(),
1897            Instruction::I64x2Add => sink.i64x2_add(),
1898            Instruction::I64x2Sub => sink.i64x2_sub(),
1899            Instruction::I64x2Mul => sink.i64x2_mul(),
1900            Instruction::I64x2ExtMulLowI32x4S => sink.i64x2_extmul_low_i32x4_s(),
1901            Instruction::I64x2ExtMulHighI32x4S => sink.i64x2_extmul_high_i32x4_s(),
1902            Instruction::I64x2ExtMulLowI32x4U => sink.i64x2_extmul_low_i32x4_u(),
1903            Instruction::I64x2ExtMulHighI32x4U => sink.i64x2_extmul_high_i32x4_u(),
1904            Instruction::F32x4Ceil => sink.f32x4_ceil(),
1905            Instruction::F32x4Floor => sink.f32x4_floor(),
1906            Instruction::F32x4Trunc => sink.f32x4_trunc(),
1907            Instruction::F32x4Nearest => sink.f32x4_nearest(),
1908            Instruction::F32x4Abs => sink.f32x4_abs(),
1909            Instruction::F32x4Neg => sink.f32x4_neg(),
1910            Instruction::F32x4Sqrt => sink.f32x4_sqrt(),
1911            Instruction::F32x4Add => sink.f32x4_add(),
1912            Instruction::F32x4Sub => sink.f32x4_sub(),
1913            Instruction::F32x4Mul => sink.f32x4_mul(),
1914            Instruction::F32x4Div => sink.f32x4_div(),
1915            Instruction::F32x4Min => sink.f32x4_min(),
1916            Instruction::F32x4Max => sink.f32x4_max(),
1917            Instruction::F32x4PMin => sink.f32x4_pmin(),
1918            Instruction::F32x4PMax => sink.f32x4_pmax(),
1919            Instruction::F64x2Ceil => sink.f64x2_ceil(),
1920            Instruction::F64x2Floor => sink.f64x2_floor(),
1921            Instruction::F64x2Trunc => sink.f64x2_trunc(),
1922            Instruction::F64x2Nearest => sink.f64x2_nearest(),
1923            Instruction::F64x2Abs => sink.f64x2_abs(),
1924            Instruction::F64x2Neg => sink.f64x2_neg(),
1925            Instruction::F64x2Sqrt => sink.f64x2_sqrt(),
1926            Instruction::F64x2Add => sink.f64x2_add(),
1927            Instruction::F64x2Sub => sink.f64x2_sub(),
1928            Instruction::F64x2Mul => sink.f64x2_mul(),
1929            Instruction::F64x2Div => sink.f64x2_div(),
1930            Instruction::F64x2Min => sink.f64x2_min(),
1931            Instruction::F64x2Max => sink.f64x2_max(),
1932            Instruction::F64x2PMin => sink.f64x2_pmin(),
1933            Instruction::F64x2PMax => sink.f64x2_pmax(),
1934            Instruction::I32x4TruncSatF32x4S => sink.i32x4_trunc_sat_f32x4_s(),
1935            Instruction::I32x4TruncSatF32x4U => sink.i32x4_trunc_sat_f32x4_u(),
1936            Instruction::F32x4ConvertI32x4S => sink.f32x4_convert_i32x4_s(),
1937            Instruction::F32x4ConvertI32x4U => sink.f32x4_convert_i32x4_u(),
1938            Instruction::I32x4TruncSatF64x2SZero => sink.i32x4_trunc_sat_f64x2_s_zero(),
1939            Instruction::I32x4TruncSatF64x2UZero => sink.i32x4_trunc_sat_f64x2_u_zero(),
1940            Instruction::F64x2ConvertLowI32x4S => sink.f64x2_convert_low_i32x4_s(),
1941            Instruction::F64x2ConvertLowI32x4U => sink.f64x2_convert_low_i32x4_u(),
1942            Instruction::F32x4DemoteF64x2Zero => sink.f32x4_demote_f64x2_zero(),
1943            Instruction::F64x2PromoteLowF32x4 => sink.f64x2_promote_low_f32x4(),
1944            Instruction::V128Load32Zero(memarg) => sink.v128_load32_zero(memarg),
1945            Instruction::V128Load64Zero(memarg) => sink.v128_load64_zero(memarg),
1946            Instruction::V128Load8Lane { memarg, lane } => sink.v128_load8_lane(memarg, lane),
1947            Instruction::V128Load16Lane { memarg, lane } => sink.v128_load16_lane(memarg, lane),
1948            Instruction::V128Load32Lane { memarg, lane } => sink.v128_load32_lane(memarg, lane),
1949            Instruction::V128Load64Lane { memarg, lane } => sink.v128_load64_lane(memarg, lane),
1950            Instruction::V128Store8Lane { memarg, lane } => sink.v128_store8_lane(memarg, lane),
1951            Instruction::V128Store16Lane { memarg, lane } => sink.v128_store16_lane(memarg, lane),
1952            Instruction::V128Store32Lane { memarg, lane } => sink.v128_store32_lane(memarg, lane),
1953            Instruction::V128Store64Lane { memarg, lane } => sink.v128_store64_lane(memarg, lane),
1954            Instruction::I64x2Eq => sink.i64x2_eq(),
1955            Instruction::I64x2Ne => sink.i64x2_ne(),
1956            Instruction::I64x2LtS => sink.i64x2_lt_s(),
1957            Instruction::I64x2GtS => sink.i64x2_gt_s(),
1958            Instruction::I64x2LeS => sink.i64x2_le_s(),
1959            Instruction::I64x2GeS => sink.i64x2_ge_s(),
1960            Instruction::I8x16RelaxedSwizzle => sink.i8x16_relaxed_swizzle(),
1961            Instruction::I32x4RelaxedTruncF32x4S => sink.i32x4_relaxed_trunc_f32x4_s(),
1962            Instruction::I32x4RelaxedTruncF32x4U => sink.i32x4_relaxed_trunc_f32x4_u(),
1963            Instruction::I32x4RelaxedTruncF64x2SZero => sink.i32x4_relaxed_trunc_f64x2_s_zero(),
1964            Instruction::I32x4RelaxedTruncF64x2UZero => sink.i32x4_relaxed_trunc_f64x2_u_zero(),
1965            Instruction::F32x4RelaxedMadd => sink.f32x4_relaxed_madd(),
1966            Instruction::F32x4RelaxedNmadd => sink.f32x4_relaxed_nmadd(),
1967            Instruction::F64x2RelaxedMadd => sink.f64x2_relaxed_madd(),
1968            Instruction::F64x2RelaxedNmadd => sink.f64x2_relaxed_nmadd(),
1969            Instruction::I8x16RelaxedLaneselect => sink.i8x16_relaxed_laneselect(),
1970            Instruction::I16x8RelaxedLaneselect => sink.i16x8_relaxed_laneselect(),
1971            Instruction::I32x4RelaxedLaneselect => sink.i32x4_relaxed_laneselect(),
1972            Instruction::I64x2RelaxedLaneselect => sink.i64x2_relaxed_laneselect(),
1973            Instruction::F32x4RelaxedMin => sink.f32x4_relaxed_min(),
1974            Instruction::F32x4RelaxedMax => sink.f32x4_relaxed_max(),
1975            Instruction::F64x2RelaxedMin => sink.f64x2_relaxed_min(),
1976            Instruction::F64x2RelaxedMax => sink.f64x2_relaxed_max(),
1977            Instruction::I16x8RelaxedQ15mulrS => sink.i16x8_relaxed_q15mulr_s(),
1978            Instruction::I16x8RelaxedDotI8x16I7x16S => sink.i16x8_relaxed_dot_i8x16_i7x16_s(),
1979            Instruction::I32x4RelaxedDotI8x16I7x16AddS => {
1980                sink.i32x4_relaxed_dot_i8x16_i7x16_add_s()
1981            }
1982
1983            // Atomic instructions from the thread proposal
1984            Instruction::MemoryAtomicNotify(memarg) => sink.memory_atomic_notify(memarg),
1985            Instruction::MemoryAtomicWait32(memarg) => sink.memory_atomic_wait32(memarg),
1986            Instruction::MemoryAtomicWait64(memarg) => sink.memory_atomic_wait64(memarg),
1987            Instruction::AtomicFence(ordering) => sink.atomic_fence(ordering),
1988            Instruction::I32AtomicLoad(memarg) => sink.i32_atomic_load(memarg),
1989            Instruction::I64AtomicLoad(memarg) => sink.i64_atomic_load(memarg),
1990            Instruction::I32AtomicLoad8U(memarg) => sink.i32_atomic_load8_u(memarg),
1991            Instruction::I32AtomicLoad16U(memarg) => sink.i32_atomic_load16_u(memarg),
1992            Instruction::I64AtomicLoad8U(memarg) => sink.i64_atomic_load8_u(memarg),
1993            Instruction::I64AtomicLoad16U(memarg) => sink.i64_atomic_load16_u(memarg),
1994            Instruction::I64AtomicLoad32U(memarg) => sink.i64_atomic_load32_u(memarg),
1995            Instruction::I32AtomicStore(memarg) => sink.i32_atomic_store(memarg),
1996            Instruction::I64AtomicStore(memarg) => sink.i64_atomic_store(memarg),
1997            Instruction::I32AtomicStore8(memarg) => sink.i32_atomic_store8(memarg),
1998            Instruction::I32AtomicStore16(memarg) => sink.i32_atomic_store16(memarg),
1999            Instruction::I64AtomicStore8(memarg) => sink.i64_atomic_store8(memarg),
2000            Instruction::I64AtomicStore16(memarg) => sink.i64_atomic_store16(memarg),
2001            Instruction::I64AtomicStore32(memarg) => sink.i64_atomic_store32(memarg),
2002            Instruction::I32AtomicRmwAdd(memarg) => sink.i32_atomic_rmw_add(memarg),
2003            Instruction::I64AtomicRmwAdd(memarg) => sink.i64_atomic_rmw_add(memarg),
2004            Instruction::I32AtomicRmw8AddU(memarg) => sink.i32_atomic_rmw8_add_u(memarg),
2005            Instruction::I32AtomicRmw16AddU(memarg) => sink.i32_atomic_rmw16_add_u(memarg),
2006            Instruction::I64AtomicRmw8AddU(memarg) => sink.i64_atomic_rmw8_add_u(memarg),
2007            Instruction::I64AtomicRmw16AddU(memarg) => sink.i64_atomic_rmw16_add_u(memarg),
2008            Instruction::I64AtomicRmw32AddU(memarg) => sink.i64_atomic_rmw32_add_u(memarg),
2009            Instruction::I32AtomicRmwSub(memarg) => sink.i32_atomic_rmw_sub(memarg),
2010            Instruction::I64AtomicRmwSub(memarg) => sink.i64_atomic_rmw_sub(memarg),
2011            Instruction::I32AtomicRmw8SubU(memarg) => sink.i32_atomic_rmw8_sub_u(memarg),
2012            Instruction::I32AtomicRmw16SubU(memarg) => sink.i32_atomic_rmw16_sub_u(memarg),
2013            Instruction::I64AtomicRmw8SubU(memarg) => sink.i64_atomic_rmw8_sub_u(memarg),
2014            Instruction::I64AtomicRmw16SubU(memarg) => sink.i64_atomic_rmw16_sub_u(memarg),
2015            Instruction::I64AtomicRmw32SubU(memarg) => sink.i64_atomic_rmw32_sub_u(memarg),
2016            Instruction::I32AtomicRmwAnd(memarg) => sink.i32_atomic_rmw_and(memarg),
2017            Instruction::I64AtomicRmwAnd(memarg) => sink.i64_atomic_rmw_and(memarg),
2018            Instruction::I32AtomicRmw8AndU(memarg) => sink.i32_atomic_rmw8_and_u(memarg),
2019            Instruction::I32AtomicRmw16AndU(memarg) => sink.i32_atomic_rmw16_and_u(memarg),
2020            Instruction::I64AtomicRmw8AndU(memarg) => sink.i64_atomic_rmw8_and_u(memarg),
2021            Instruction::I64AtomicRmw16AndU(memarg) => sink.i64_atomic_rmw16_and_u(memarg),
2022            Instruction::I64AtomicRmw32AndU(memarg) => sink.i64_atomic_rmw32_and_u(memarg),
2023            Instruction::I32AtomicRmwOr(memarg) => sink.i32_atomic_rmw_or(memarg),
2024            Instruction::I64AtomicRmwOr(memarg) => sink.i64_atomic_rmw_or(memarg),
2025            Instruction::I32AtomicRmw8OrU(memarg) => sink.i32_atomic_rmw8_or_u(memarg),
2026            Instruction::I32AtomicRmw16OrU(memarg) => sink.i32_atomic_rmw16_or_u(memarg),
2027            Instruction::I64AtomicRmw8OrU(memarg) => sink.i64_atomic_rmw8_or_u(memarg),
2028            Instruction::I64AtomicRmw16OrU(memarg) => sink.i64_atomic_rmw16_or_u(memarg),
2029            Instruction::I64AtomicRmw32OrU(memarg) => sink.i64_atomic_rmw32_or_u(memarg),
2030            Instruction::I32AtomicRmwXor(memarg) => sink.i32_atomic_rmw_xor(memarg),
2031            Instruction::I64AtomicRmwXor(memarg) => sink.i64_atomic_rmw_xor(memarg),
2032            Instruction::I32AtomicRmw8XorU(memarg) => sink.i32_atomic_rmw8_xor_u(memarg),
2033            Instruction::I32AtomicRmw16XorU(memarg) => sink.i32_atomic_rmw16_xor_u(memarg),
2034            Instruction::I64AtomicRmw8XorU(memarg) => sink.i64_atomic_rmw8_xor_u(memarg),
2035            Instruction::I64AtomicRmw16XorU(memarg) => sink.i64_atomic_rmw16_xor_u(memarg),
2036            Instruction::I64AtomicRmw32XorU(memarg) => sink.i64_atomic_rmw32_xor_u(memarg),
2037            Instruction::I32AtomicRmwXchg(memarg) => sink.i32_atomic_rmw_xchg(memarg),
2038            Instruction::I64AtomicRmwXchg(memarg) => sink.i64_atomic_rmw_xchg(memarg),
2039            Instruction::I32AtomicRmw8XchgU(memarg) => sink.i32_atomic_rmw8_xchg_u(memarg),
2040            Instruction::I32AtomicRmw16XchgU(memarg) => sink.i32_atomic_rmw16_xchg_u(memarg),
2041            Instruction::I64AtomicRmw8XchgU(memarg) => sink.i64_atomic_rmw8_xchg_u(memarg),
2042            Instruction::I64AtomicRmw16XchgU(memarg) => sink.i64_atomic_rmw16_xchg_u(memarg),
2043            Instruction::I64AtomicRmw32XchgU(memarg) => sink.i64_atomic_rmw32_xchg_u(memarg),
2044            Instruction::I32AtomicRmwCmpxchg(memarg) => sink.i32_atomic_rmw_cmpxchg(memarg),
2045            Instruction::I64AtomicRmwCmpxchg(memarg) => sink.i64_atomic_rmw_cmpxchg(memarg),
2046            Instruction::I32AtomicRmw8CmpxchgU(memarg) => sink.i32_atomic_rmw8_cmpxchg_u(memarg),
2047            Instruction::I32AtomicRmw16CmpxchgU(memarg) => sink.i32_atomic_rmw16_cmpxchg_u(memarg),
2048            Instruction::I64AtomicRmw8CmpxchgU(memarg) => sink.i64_atomic_rmw8_cmpxchg_u(memarg),
2049            Instruction::I64AtomicRmw16CmpxchgU(memarg) => sink.i64_atomic_rmw16_cmpxchg_u(memarg),
2050            Instruction::I64AtomicRmw32CmpxchgU(memarg) => sink.i64_atomic_rmw32_cmpxchg_u(memarg),
2051
2052            // Atomic instructions from the shared-everything-threads proposal
2053            Instruction::GlobalAtomicGet {
2054                ordering,
2055                global_index,
2056            } => sink.global_atomic_get(ordering, global_index),
2057            Instruction::GlobalAtomicSet {
2058                ordering,
2059                global_index,
2060            } => sink.global_atomic_set(ordering, global_index),
2061            Instruction::GlobalAtomicRmwAdd {
2062                ordering,
2063                global_index,
2064            } => sink.global_atomic_rmw_add(ordering, global_index),
2065            Instruction::GlobalAtomicRmwSub {
2066                ordering,
2067                global_index,
2068            } => sink.global_atomic_rmw_sub(ordering, global_index),
2069            Instruction::GlobalAtomicRmwAnd {
2070                ordering,
2071                global_index,
2072            } => sink.global_atomic_rmw_and(ordering, global_index),
2073            Instruction::GlobalAtomicRmwOr {
2074                ordering,
2075                global_index,
2076            } => sink.global_atomic_rmw_or(ordering, global_index),
2077            Instruction::GlobalAtomicRmwXor {
2078                ordering,
2079                global_index,
2080            } => sink.global_atomic_rmw_xor(ordering, global_index),
2081            Instruction::GlobalAtomicRmwXchg {
2082                ordering,
2083                global_index,
2084            } => sink.global_atomic_rmw_xchg(ordering, global_index),
2085            Instruction::GlobalAtomicRmwCmpxchg {
2086                ordering,
2087                global_index,
2088            } => sink.global_atomic_rmw_cmpxchg(ordering, global_index),
2089            Instruction::TableAtomicGet {
2090                ordering,
2091                table_index,
2092            } => sink.table_atomic_get(ordering, table_index),
2093            Instruction::TableAtomicSet {
2094                ordering,
2095                table_index,
2096            } => sink.table_atomic_set(ordering, table_index),
2097            Instruction::TableAtomicRmwXchg {
2098                ordering,
2099                table_index,
2100            } => sink.table_atomic_rmw_xchg(ordering, table_index),
2101            Instruction::TableAtomicRmwCmpxchg {
2102                ordering,
2103                table_index,
2104            } => sink.table_atomic_rmw_cmpxchg(ordering, table_index),
2105            Instruction::StructAtomicGet {
2106                ordering,
2107                struct_type_index,
2108                field_index,
2109            } => sink.struct_atomic_get(ordering, struct_type_index, field_index),
2110            Instruction::StructAtomicGetS {
2111                ordering,
2112                struct_type_index,
2113                field_index,
2114            } => sink.struct_atomic_get_s(ordering, struct_type_index, field_index),
2115            Instruction::StructAtomicGetU {
2116                ordering,
2117                struct_type_index,
2118                field_index,
2119            } => sink.struct_atomic_get_u(ordering, struct_type_index, field_index),
2120            Instruction::StructAtomicSet {
2121                ordering,
2122                struct_type_index,
2123                field_index,
2124            } => sink.struct_atomic_set(ordering, struct_type_index, field_index),
2125            Instruction::StructAtomicRmwAdd {
2126                ordering,
2127                struct_type_index,
2128                field_index,
2129            } => sink.struct_atomic_rmw_add(ordering, struct_type_index, field_index),
2130            Instruction::StructAtomicRmwSub {
2131                ordering,
2132                struct_type_index,
2133                field_index,
2134            } => sink.struct_atomic_rmw_sub(ordering, struct_type_index, field_index),
2135            Instruction::StructAtomicRmwAnd {
2136                ordering,
2137                struct_type_index,
2138                field_index,
2139            } => sink.struct_atomic_rmw_and(ordering, struct_type_index, field_index),
2140            Instruction::StructAtomicRmwOr {
2141                ordering,
2142                struct_type_index,
2143                field_index,
2144            } => sink.struct_atomic_rmw_or(ordering, struct_type_index, field_index),
2145            Instruction::StructAtomicRmwXor {
2146                ordering,
2147                struct_type_index,
2148                field_index,
2149            } => sink.struct_atomic_rmw_xor(ordering, struct_type_index, field_index),
2150            Instruction::StructAtomicRmwXchg {
2151                ordering,
2152                struct_type_index,
2153                field_index,
2154            } => sink.struct_atomic_rmw_xchg(ordering, struct_type_index, field_index),
2155            Instruction::StructAtomicRmwCmpxchg {
2156                ordering,
2157                struct_type_index,
2158                field_index,
2159            } => sink.struct_atomic_rmw_cmpxchg(ordering, struct_type_index, field_index),
2160            Instruction::ArrayAtomicGet {
2161                ordering,
2162                array_type_index,
2163            } => sink.array_atomic_get(ordering, array_type_index),
2164            Instruction::ArrayAtomicGetS {
2165                ordering,
2166                array_type_index,
2167            } => sink.array_atomic_get_s(ordering, array_type_index),
2168            Instruction::ArrayAtomicGetU {
2169                ordering,
2170                array_type_index,
2171            } => sink.array_atomic_get_u(ordering, array_type_index),
2172            Instruction::ArrayAtomicSet {
2173                ordering,
2174                array_type_index,
2175            } => sink.array_atomic_set(ordering, array_type_index),
2176            Instruction::ArrayAtomicRmwAdd {
2177                ordering,
2178                array_type_index,
2179            } => sink.array_atomic_rmw_add(ordering, array_type_index),
2180            Instruction::ArrayAtomicRmwSub {
2181                ordering,
2182                array_type_index,
2183            } => sink.array_atomic_rmw_sub(ordering, array_type_index),
2184            Instruction::ArrayAtomicRmwAnd {
2185                ordering,
2186                array_type_index,
2187            } => sink.array_atomic_rmw_and(ordering, array_type_index),
2188            Instruction::ArrayAtomicRmwOr {
2189                ordering,
2190                array_type_index,
2191            } => sink.array_atomic_rmw_or(ordering, array_type_index),
2192            Instruction::ArrayAtomicRmwXor {
2193                ordering,
2194                array_type_index,
2195            } => sink.array_atomic_rmw_xor(ordering, array_type_index),
2196            Instruction::ArrayAtomicRmwXchg {
2197                ordering,
2198                array_type_index,
2199            } => sink.array_atomic_rmw_xchg(ordering, array_type_index),
2200            Instruction::ArrayAtomicRmwCmpxchg {
2201                ordering,
2202                array_type_index,
2203            } => sink.array_atomic_rmw_cmpxchg(ordering, array_type_index),
2204            Instruction::RefI31Shared => sink.ref_i31_shared(),
2205            Instruction::ContNew(type_index) => sink.cont_new(type_index),
2206            Instruction::ContBind {
2207                argument_index,
2208                result_index,
2209            } => sink.cont_bind(argument_index, result_index),
2210            Instruction::Suspend(tag_index) => sink.suspend(tag_index),
2211            Instruction::Resume {
2212                cont_type_index,
2213                ref resume_table,
2214            } => sink.resume(cont_type_index, resume_table.iter().cloned()),
2215            Instruction::ResumeThrow {
2216                cont_type_index,
2217                tag_index,
2218                ref resume_table,
2219            } => sink.resume_throw(cont_type_index, tag_index, resume_table.iter().cloned()),
2220            Instruction::ResumeThrowRef {
2221                cont_type_index,
2222                ref resume_table,
2223            } => sink.resume_throw_ref(cont_type_index, resume_table.iter().cloned()),
2224            Instruction::Switch {
2225                cont_type_index,
2226                tag_index,
2227            } => sink.switch(cont_type_index, tag_index),
2228            Instruction::I64Add128 => sink.i64_add128(),
2229            Instruction::I64Sub128 => sink.i64_sub128(),
2230            Instruction::I64MulWideS => sink.i64_mul_wide_s(),
2231            Instruction::I64MulWideU => sink.i64_mul_wide_u(),
2232
2233            // Acquire-release atomics
2234            Instruction::Pause => sink.pause(),
2235            Instruction::RefGetDesc(type_index) => sink.ref_get_desc(type_index),
2236            Instruction::RefCastDescEqNonNull(hty) => sink.ref_cast_desc_eq_non_null(hty),
2237            Instruction::RefCastDescEqNullable(hty) => sink.ref_cast_desc_eq_nullable(hty),
2238            Instruction::BrOnCastDescEq {
2239                relative_depth,
2240                from_ref_type,
2241                to_ref_type,
2242            } => sink.br_on_cast_desc_eq(relative_depth, from_ref_type, to_ref_type),
2243            Instruction::BrOnCastDescEqFail {
2244                relative_depth,
2245                from_ref_type,
2246                to_ref_type,
2247            } => sink.br_on_cast_desc_eq_fail(relative_depth, from_ref_type, to_ref_type),
2248        };
2249    }
2250}
2251
2252#[derive(Clone, Debug)]
2253#[allow(missing_docs)]
2254pub enum Catch {
2255    One { tag: u32, label: u32 },
2256    OneRef { tag: u32, label: u32 },
2257    All { label: u32 },
2258    AllRef { label: u32 },
2259}
2260
2261impl Encode for Catch {
2262    fn encode(&self, sink: &mut Vec<u8>) {
2263        match self {
2264            Catch::One { tag, label } => {
2265                sink.push(0x00);
2266                tag.encode(sink);
2267                label.encode(sink);
2268            }
2269            Catch::OneRef { tag, label } => {
2270                sink.push(0x01);
2271                tag.encode(sink);
2272                label.encode(sink);
2273            }
2274            Catch::All { label } => {
2275                sink.push(0x02);
2276                label.encode(sink);
2277            }
2278            Catch::AllRef { label } => {
2279                sink.push(0x03);
2280                label.encode(sink);
2281            }
2282        }
2283    }
2284}
2285
2286#[derive(Clone, Debug)]
2287#[allow(missing_docs)]
2288pub enum Handle {
2289    OnLabel { tag: u32, label: u32 },
2290    OnSwitch { tag: u32 },
2291}
2292
2293impl Encode for Handle {
2294    fn encode(&self, sink: &mut Vec<u8>) {
2295        match self {
2296            Handle::OnLabel { tag, label } => {
2297                sink.push(0x00);
2298                tag.encode(sink);
2299                label.encode(sink);
2300            }
2301            Handle::OnSwitch { tag } => {
2302                sink.push(0x01);
2303                tag.encode(sink);
2304            }
2305        }
2306    }
2307}
2308
2309/// A constant expression.
2310///
2311/// Usable in contexts such as offsets or initializers.
2312#[derive(Clone, Debug)]
2313pub struct ConstExpr {
2314    bytes: Vec<u8>,
2315}
2316
2317impl ConstExpr {
2318    /// Create a new empty constant expression builder.
2319    pub fn empty() -> Self {
2320        Self { bytes: Vec::new() }
2321    }
2322
2323    /// Create a constant expression with the specified raw encoding of instructions.
2324    pub fn raw(bytes: impl IntoIterator<Item = u8>) -> Self {
2325        Self {
2326            bytes: bytes.into_iter().collect(),
2327        }
2328    }
2329
2330    /// Create a constant expression with the sequence of instructions
2331    pub fn extended<'a>(insns: impl IntoIterator<Item = Instruction<'a>>) -> Self {
2332        let mut bytes = vec![];
2333        for insn in insns {
2334            insn.encode(&mut bytes);
2335        }
2336        Self { bytes }
2337    }
2338
2339    fn new<F>(f: F) -> Self
2340    where
2341        for<'a, 'b> F: FnOnce(&'a mut InstructionSink<'b>) -> &'a mut InstructionSink<'b>,
2342    {
2343        let mut bytes = vec![];
2344        f(&mut InstructionSink::new(&mut bytes));
2345        Self { bytes }
2346    }
2347
2348    fn with<F>(mut self, f: F) -> Self
2349    where
2350        for<'a, 'b> F: FnOnce(&'a mut InstructionSink<'b>) -> &'a mut InstructionSink<'b>,
2351    {
2352        f(&mut InstructionSink::new(&mut self.bytes));
2353        self
2354    }
2355
2356    /// Create a constant expression containing a single `global.get` instruction.
2357    pub fn global_get(index: u32) -> Self {
2358        Self::new(|insn| insn.global_get(index))
2359    }
2360
2361    /// Create a constant expression containing a single `ref.null` instruction.
2362    pub fn ref_null(ty: HeapType) -> Self {
2363        Self::new(|insn| insn.ref_null(ty))
2364    }
2365
2366    /// Create a constant expression containing a single `ref.func` instruction.
2367    pub fn ref_func(func: u32) -> Self {
2368        Self::new(|insn| insn.ref_func(func))
2369    }
2370
2371    /// Create a constant expression containing a single `i32.const` instruction.
2372    pub fn i32_const(value: i32) -> Self {
2373        Self::new(|insn| insn.i32_const(value))
2374    }
2375
2376    /// Create a constant expression containing a single `i64.const` instruction.
2377    pub fn i64_const(value: i64) -> Self {
2378        Self::new(|insn| insn.i64_const(value))
2379    }
2380
2381    /// Create a constant expression containing a single `f32.const` instruction.
2382    pub fn f32_const(value: Ieee32) -> Self {
2383        Self::new(|insn| insn.f32_const(value))
2384    }
2385
2386    /// Create a constant expression containing a single `f64.const` instruction.
2387    pub fn f64_const(value: Ieee64) -> Self {
2388        Self::new(|insn| insn.f64_const(value))
2389    }
2390
2391    /// Create a constant expression containing a single `v128.const` instruction.
2392    pub fn v128_const(value: i128) -> Self {
2393        Self::new(|insn| insn.v128_const(value))
2394    }
2395
2396    /// Add a `global.get` instruction to this constant expression.
2397    pub fn with_global_get(self, index: u32) -> Self {
2398        self.with(|insn| insn.global_get(index))
2399    }
2400
2401    /// Add a `ref.null` instruction to this constant expression.
2402    pub fn with_ref_null(self, ty: HeapType) -> Self {
2403        self.with(|insn| insn.ref_null(ty))
2404    }
2405
2406    /// Add a `ref.func` instruction to this constant expression.
2407    pub fn with_ref_func(self, func: u32) -> Self {
2408        self.with(|insn| insn.ref_func(func))
2409    }
2410
2411    /// Add an `i32.const` instruction to this constant expression.
2412    pub fn with_i32_const(self, value: i32) -> Self {
2413        self.with(|insn| insn.i32_const(value))
2414    }
2415
2416    /// Add an `i64.const` instruction to this constant expression.
2417    pub fn with_i64_const(self, value: i64) -> Self {
2418        self.with(|insn| insn.i64_const(value))
2419    }
2420
2421    /// Add a `f32.const` instruction to this constant expression.
2422    pub fn with_f32_const(self, value: Ieee32) -> Self {
2423        self.with(|insn| insn.f32_const(value))
2424    }
2425
2426    /// Add a `f64.const` instruction to this constant expression.
2427    pub fn with_f64_const(self, value: Ieee64) -> Self {
2428        self.with(|insn| insn.f64_const(value))
2429    }
2430
2431    /// Add a `v128.const` instruction to this constant expression.
2432    pub fn with_v128_const(self, value: i128) -> Self {
2433        self.with(|insn| insn.v128_const(value))
2434    }
2435
2436    /// Add an `i32.add` instruction to this constant expression.
2437    pub fn with_i32_add(self) -> Self {
2438        self.with(|insn| insn.i32_add())
2439    }
2440
2441    /// Add an `i32.sub` instruction to this constant expression.
2442    pub fn with_i32_sub(self) -> Self {
2443        self.with(|insn| insn.i32_sub())
2444    }
2445
2446    /// Add an `i32.mul` instruction to this constant expression.
2447    pub fn with_i32_mul(self) -> Self {
2448        self.with(|insn| insn.i32_mul())
2449    }
2450
2451    /// Add an `i64.add` instruction to this constant expression.
2452    pub fn with_i64_add(self) -> Self {
2453        self.with(|insn| insn.i64_add())
2454    }
2455
2456    /// Add an `i64.sub` instruction to this constant expression.
2457    pub fn with_i64_sub(self) -> Self {
2458        self.with(|insn| insn.i64_sub())
2459    }
2460
2461    /// Add an `i64.mul` instruction to this constant expression.
2462    pub fn with_i64_mul(self) -> Self {
2463        self.with(|insn| insn.i64_mul())
2464    }
2465
2466    /// Returns the function, if any, referenced by this global.
2467    pub fn get_ref_func(&self) -> Option<u32> {
2468        let prefix = *self.bytes.get(0)?;
2469        // 0xd2 == `ref.func` opcode, and if that's found then load the leb
2470        // corresponding to the function index.
2471        if prefix != 0xd2 {
2472            return None;
2473        }
2474        leb128fmt::decode_uint_slice::<u32, 32>(&self.bytes[1..], &mut 0).ok()
2475    }
2476}
2477
2478impl Encode for ConstExpr {
2479    fn encode(&self, sink: &mut Vec<u8>) {
2480        sink.extend(&self.bytes);
2481        InstructionSink::new(sink).end();
2482    }
2483}
2484
2485#[cfg(test)]
2486mod tests {
2487    #[test]
2488    fn function_new_with_locals_test() {
2489        use super::*;
2490
2491        // Test the algorithm for conversion is correct
2492        let f1 = Function::new_with_locals_types([
2493            ValType::I32,
2494            ValType::I32,
2495            ValType::I64,
2496            ValType::F32,
2497            ValType::F32,
2498            ValType::F32,
2499            ValType::I32,
2500            ValType::I64,
2501            ValType::I64,
2502        ]);
2503        let f2 = Function::new([
2504            (2, ValType::I32),
2505            (1, ValType::I64),
2506            (3, ValType::F32),
2507            (1, ValType::I32),
2508            (2, ValType::I64),
2509        ]);
2510
2511        assert_eq!(f1.bytes, f2.bytes)
2512    }
2513
2514    #[test]
2515    fn func_raw_bytes() {
2516        use super::*;
2517
2518        let mut f = Function::new([(1, ValType::I32), (1, ValType::F32)]);
2519        f.instructions().end();
2520        let mut code_from_func = CodeSection::new();
2521        code_from_func.function(&f);
2522        let bytes = f.into_raw_body();
2523        let mut code_from_raw = CodeSection::new();
2524        code_from_raw.raw(&bytes[..]);
2525
2526        let mut c1 = vec![];
2527        code_from_func.encode(&mut c1);
2528        let mut c2 = vec![];
2529        code_from_raw.encode(&mut c2);
2530        assert_eq!(c1, c2);
2531    }
2532}