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