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