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