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