1use crate::{encode_section, Encode, HeapType, RefType, Section, SectionId, ValType};
2use alloc::borrow::Cow;
3use alloc::vec;
4use alloc::vec::Vec;
5
6/// An encoder for the code section.
7///
8/// Code sections are only supported for modules.
9///
10/// # Example
11///
12/// ```
13/// use wasm_encoder::{
14/// CodeSection, Function, FunctionSection, Instruction, Module,
15/// TypeSection, ValType
16/// };
17///
18/// let mut types = TypeSection::new();
19/// types.ty().function(vec![], vec![ValType::I32]);
20///
21/// let mut functions = FunctionSection::new();
22/// let type_index = 0;
23/// functions.function(type_index);
24///
25/// let locals = vec![];
26/// let mut func = Function::new(locals);
27/// func.instruction(&Instruction::I32Const(42));
28/// let mut code = CodeSection::new();
29/// code.function(&func);
30///
31/// let mut module = Module::new();
32/// module
33/// .section(&types)
34/// .section(&functions)
35/// .section(&code);
36///
37/// let wasm_bytes = module.finish();
38/// ```
39#[derive(Clone, Default, Debug)]
40pub struct CodeSection {
41 bytes: Vec<u8>,
42 num_added: u32,
43}
44
45impl CodeSection {
46 /// Create a new code section encoder.
47 pub fn new() -> Self {
48 Self::default()
49 }
50
51 /// The number of functions in the section.
52 pub fn len(&self) -> u32 {
53 self.num_added
54 }
55
56 /// The number of bytes already added to this section.
57 ///
58 /// This number doesn't include the vector length that precedes the
59 /// code entries, since it has a variable size that isn't known until all
60 /// functions are added.
61 pub fn byte_len(&self) -> usize {
62 self.bytes.len()
63 }
64
65 /// Determines if the section is empty.
66 pub fn is_empty(&self) -> bool {
67 self.num_added == 0
68 }
69
70 /// Write a function body into this code section.
71 pub fn function(&mut self, func: &Function) -> &mut Self {
72 func.encode(&mut self.bytes);
73 self.num_added += 1;
74 self
75 }
76
77 /// Add a raw byte slice into this code section as a function body.
78 ///
79 /// The length prefix of the function body will be automatically prepended,
80 /// and should not be included in the raw byte slice.
81 ///
82 /// # Example
83 ///
84 /// You can use the `raw` method to copy an already-encoded function body
85 /// into a new code section encoder:
86 ///
87 /// ```
88 /// # use wasmparser::{BinaryReader, CodeSectionReader};
89 /// // id, size, # entries, entry
90 /// let code_section = [10, 6, 1, 4, 0, 65, 0, 11];
91 ///
92 /// // Parse the code section.
93 /// let reader = BinaryReader::new(&code_section, 0);
94 /// let reader = CodeSectionReader::new(reader).unwrap();
95 /// let body = reader.into_iter().next().unwrap().unwrap();
96 /// let body_range = body.range();
97 ///
98 /// // Add the body to a new code section encoder by copying bytes rather
99 /// // than re-parsing and re-encoding it.
100 /// let mut encoder = wasm_encoder::CodeSection::new();
101 /// encoder.raw(&code_section[body_range.start..body_range.end]);
102 /// ```
103 pub fn raw(&mut self, data: &[u8]) -> &mut Self {
104 data.encode(&mut self.bytes);
105 self.num_added += 1;
106 self
107 }
108}
109
110impl Encode for CodeSection {
111 fn encode(&self, sink: &mut Vec<u8>) {
112 encode_section(sink, self.num_added, &self.bytes);
113 }
114}
115
116impl Section for CodeSection {
117 fn id(&self) -> u8 {
118 SectionId::Code.into()
119 }
120}
121
122/// An encoder for a function body within the code section.
123///
124/// # Example
125///
126/// ```
127/// use wasm_encoder::{CodeSection, Function, Instruction};
128///
129/// // Define the function body for:
130/// //
131/// // (func (param i32 i32) (result i32)
132/// // local.get 0
133/// // local.get 1
134/// // i32.add)
135/// let locals = vec![];
136/// let mut func = Function::new(locals);
137/// func.instruction(&Instruction::LocalGet(0));
138/// func.instruction(&Instruction::LocalGet(1));
139/// func.instruction(&Instruction::I32Add);
140///
141/// // Add our function to the code section.
142/// let mut code = CodeSection::new();
143/// code.function(&func);
144/// ```
145#[derive(Clone, Debug, Eq, PartialEq)]
146pub struct Function {
147 bytes: Vec<u8>,
148}
149
150impl Function {
151 /// Create a new function body with the given locals.
152 ///
153 /// The argument is an iterator over `(N, Ty)`, which defines
154 /// that the next `N` locals will be of type `Ty`.
155 ///
156 /// For example, a function with locals 0 and 1 of type I32 and
157 /// local 2 of type F32 would be created as:
158 ///
159 /// ```
160 /// # use wasm_encoder::{Function, ValType};
161 /// let f = Function::new([(2, ValType::I32), (1, ValType::F32)]);
162 /// ```
163 ///
164 /// For more information about the code section (and function definition) in the WASM binary format
165 /// see the [WebAssembly spec](https://webassembly.github.io/spec/core/binary/modules.html#binary-func)
166 pub fn new<L>(locals: L) -> Self
167 where
168 L: IntoIterator<Item = (u32, ValType)>,
169 L::IntoIter: ExactSizeIterator,
170 {
171 let locals = locals.into_iter();
172 let mut bytes = vec![];
173 locals.len().encode(&mut bytes);
174 for (count, ty) in locals {
175 count.encode(&mut bytes);
176 ty.encode(&mut bytes);
177 }
178 Function { bytes }
179 }
180
181 /// Create a function from a list of locals' types.
182 ///
183 /// Unlike [`Function::new`], this constructor simply takes a list of types
184 /// which are in order associated with locals.
185 ///
186 /// For example:
187 ///
188 /// ```
189 /// # use wasm_encoder::{Function, ValType};
190 /// let f = Function::new([(2, ValType::I32), (1, ValType::F32)]);
191 /// let g = Function::new_with_locals_types([
192 /// ValType::I32, ValType::I32, ValType::F32
193 /// ]);
194 ///
195 /// assert_eq!(f, g)
196 /// ```
197 pub fn new_with_locals_types<L>(locals: L) -> Self
198 where
199 L: IntoIterator<Item = ValType>,
200 {
201 let locals = locals.into_iter();
202
203 let mut locals_collected: Vec<(u32, ValType)> = vec![];
204 for l in locals {
205 if let Some((last_count, last_type)) = locals_collected.last_mut() {
206 if l == *last_type {
207 // Increment the count of consecutive locals of this type
208 *last_count += 1;
209 continue;
210 }
211 }
212 // If we didn't increment, a new type of local appeared
213 locals_collected.push((1, l));
214 }
215
216 Function::new(locals_collected)
217 }
218
219 /// Write an instruction into this function body.
220 pub fn instruction(&mut self, instruction: &Instruction) -> &mut Self {
221 instruction.encode(&mut self.bytes);
222 self
223 }
224
225 /// Add raw bytes to this function's body.
226 pub fn raw<B>(&mut self, bytes: B) -> &mut Self
227 where
228 B: IntoIterator<Item = u8>,
229 {
230 self.bytes.extend(bytes);
231 self
232 }
233
234 /// The number of bytes already added to this function.
235 ///
236 /// This number doesn't include the variable-width size field that `encode`
237 /// will write before the added bytes, since the size of that field isn't
238 /// known until all the instructions are added to this function.
239 pub fn byte_len(&self) -> usize {
240 self.bytes.len()
241 }
242
243 /// Unwraps and returns the raw byte encoding of this function.
244 ///
245 /// This encoding doesn't include the variable-width size field
246 /// that `encode` will write before the added bytes. As such, its
247 /// length will match the return value of [`byte_len`].
248 ///
249 /// # Use Case
250 ///
251 /// This raw byte form is suitable for later using with
252 /// [`CodeSection::raw`]. Note that it *differs* from what results
253 /// from [`Function::encode`] precisely due to the *lack* of the
254 /// length prefix; [`CodeSection::raw`] will use this. Using
255 /// [`Function::encode`] instead produces bytes that cannot be fed
256 /// into other wasm-encoder types without stripping off the length
257 /// prefix, which is awkward and error-prone.
258 ///
259 /// This method combined with [`CodeSection::raw`] may be useful
260 /// together if one wants to save the result of function encoding
261 /// and use it later: for example, caching the result of some code
262 /// generation process.
263 ///
264 /// For example:
265 ///
266 /// ```
267 /// # use wasm_encoder::{CodeSection, Function, Instruction};
268 /// let mut f = Function::new([]);
269 /// f.instruction(&Instruction::End);
270 /// let bytes = f.into_raw_body();
271 /// // (save `bytes` somewhere for later use)
272 /// let mut code = CodeSection::new();
273 /// code.raw(&bytes[..]);
274 ///
275 /// assert_eq!(2, bytes.len()); // Locals count, then `end`
276 /// assert_eq!(3, code.byte_len()); // Function length byte, function body
277 /// ```
278 pub fn into_raw_body(self) -> Vec<u8> {
279 self.bytes
280 }
281}
282
283impl Encode for Function {
284 fn encode(&self, sink: &mut Vec<u8>) {
285 self.bytes.encode(sink);
286 }
287}
288
289/// The immediate for a memory instruction.
290#[derive(Clone, Copy, Debug)]
291pub struct MemArg {
292 /// A static offset to add to the instruction's dynamic address operand.
293 ///
294 /// This is a `u64` field for the memory64 proposal, but 32-bit memories
295 /// limit offsets to at most `u32::MAX` bytes. This will be encoded as a LEB
296 /// but it won't generate a valid module if an offset is specified which is
297 /// larger than the maximum size of the index space for the memory indicated
298 /// by `memory_index`.
299 pub offset: u64,
300 /// The expected alignment of the instruction's dynamic address operand
301 /// (expressed the exponent of a power of two).
302 pub align: u32,
303 /// The index of the memory this instruction is operating upon.
304 pub memory_index: u32,
305}
306
307impl Encode for MemArg {
308 fn encode(&self, sink: &mut Vec<u8>) {
309 if self.memory_index == 0 {
310 self.align.encode(sink);
311 self.offset.encode(sink);
312 } else {
313 (self.align | (1 << 6)).encode(sink);
314 self.memory_index.encode(sink);
315 self.offset.encode(sink);
316 }
317 }
318}
319
320/// The memory ordering for atomic instructions.
321///
322/// For an in-depth explanation of memory orderings, see the C++ documentation
323/// for [`memory_order`] or the Rust documentation for [`atomic::Ordering`].
324///
325/// [`memory_order`]: https://en.cppreference.com/w/cpp/atomic/memory_order
326/// [`atomic::Ordering`]: https://doc.rust-lang.org/std/sync/atomic/enum.Ordering.html
327#[derive(Clone, Copy, Debug)]
328pub enum Ordering {
329 /// For a load, it acquires; this orders all operations before the last
330 /// "releasing" store. For a store, it releases; this orders all operations
331 /// before it at the next "acquiring" load.
332 AcqRel,
333 /// Like `AcqRel` but all threads see all sequentially consistent operations
334 /// in the same order.
335 SeqCst,
336}
337
338impl Encode for Ordering {
339 fn encode(&self, sink: &mut Vec<u8>) {
340 let flag: u8 = match self {
341 Ordering::SeqCst => 0,
342 Ordering::AcqRel => 1,
343 };
344 sink.push(flag);
345 }
346}
347
348/// Describe an unchecked SIMD lane index.
349pub type Lane = u8;
350
351/// The type for a `block`/`if`/`loop`.
352#[derive(Clone, Copy, Debug)]
353pub enum BlockType {
354 /// `[] -> []`
355 Empty,
356 /// `[] -> [t]`
357 Result(ValType),
358 /// The `n`th function type.
359 FunctionType(u32),
360}
361
362impl Encode for BlockType {
363 fn encode(&self, sink: &mut Vec<u8>) {
364 match *self {
365 Self::Empty => sink.push(0x40),
366 Self::Result(ty: ValType) => ty.encode(sink),
367 Self::FunctionType(f: u32) => (f as i64).encode(sink),
368 }
369 }
370}
371
372/// WebAssembly instructions.
373#[derive(Clone, Debug)]
374#[non_exhaustive]
375#[allow(missing_docs, non_camel_case_types)]
376pub enum Instruction<'a> {
377 // Control instructions.
378 Unreachable,
379 Nop,
380 Block(BlockType),
381 Loop(BlockType),
382 If(BlockType),
383 Else,
384 End,
385 Br(u32),
386 BrIf(u32),
387 BrTable(Cow<'a, [u32]>, u32),
388 BrOnNull(u32),
389 BrOnNonNull(u32),
390 Return,
391 Call(u32),
392 CallRef(u32),
393 CallIndirect {
394 type_index: u32,
395 table_index: u32,
396 },
397 ReturnCallRef(u32),
398 ReturnCall(u32),
399 ReturnCallIndirect {
400 type_index: u32,
401 table_index: u32,
402 },
403 TryTable(BlockType, Cow<'a, [Catch]>),
404 Throw(u32),
405 ThrowRef,
406
407 // Deprecated exception-handling instructions
408 Try(BlockType),
409 Delegate(u32),
410 Catch(u32),
411 CatchAll,
412 Rethrow(u32),
413
414 // Parametric instructions.
415 Drop,
416 Select,
417
418 // Variable instructions.
419 LocalGet(u32),
420 LocalSet(u32),
421 LocalTee(u32),
422 GlobalGet(u32),
423 GlobalSet(u32),
424
425 // Memory instructions.
426 I32Load(MemArg),
427 I64Load(MemArg),
428 F32Load(MemArg),
429 F64Load(MemArg),
430 I32Load8S(MemArg),
431 I32Load8U(MemArg),
432 I32Load16S(MemArg),
433 I32Load16U(MemArg),
434 I64Load8S(MemArg),
435 I64Load8U(MemArg),
436 I64Load16S(MemArg),
437 I64Load16U(MemArg),
438 I64Load32S(MemArg),
439 I64Load32U(MemArg),
440 I32Store(MemArg),
441 I64Store(MemArg),
442 F32Store(MemArg),
443 F64Store(MemArg),
444 I32Store8(MemArg),
445 I32Store16(MemArg),
446 I64Store8(MemArg),
447 I64Store16(MemArg),
448 I64Store32(MemArg),
449 MemorySize(u32),
450 MemoryGrow(u32),
451 MemoryInit {
452 mem: u32,
453 data_index: u32,
454 },
455 DataDrop(u32),
456 MemoryCopy {
457 src_mem: u32,
458 dst_mem: u32,
459 },
460 MemoryFill(u32),
461 MemoryDiscard(u32),
462
463 // Numeric instructions.
464 I32Const(i32),
465 I64Const(i64),
466 F32Const(f32),
467 F64Const(f64),
468 I32Eqz,
469 I32Eq,
470 I32Ne,
471 I32LtS,
472 I32LtU,
473 I32GtS,
474 I32GtU,
475 I32LeS,
476 I32LeU,
477 I32GeS,
478 I32GeU,
479 I64Eqz,
480 I64Eq,
481 I64Ne,
482 I64LtS,
483 I64LtU,
484 I64GtS,
485 I64GtU,
486 I64LeS,
487 I64LeU,
488 I64GeS,
489 I64GeU,
490 F32Eq,
491 F32Ne,
492 F32Lt,
493 F32Gt,
494 F32Le,
495 F32Ge,
496 F64Eq,
497 F64Ne,
498 F64Lt,
499 F64Gt,
500 F64Le,
501 F64Ge,
502 I32Clz,
503 I32Ctz,
504 I32Popcnt,
505 I32Add,
506 I32Sub,
507 I32Mul,
508 I32DivS,
509 I32DivU,
510 I32RemS,
511 I32RemU,
512 I32And,
513 I32Or,
514 I32Xor,
515 I32Shl,
516 I32ShrS,
517 I32ShrU,
518 I32Rotl,
519 I32Rotr,
520 I64Clz,
521 I64Ctz,
522 I64Popcnt,
523 I64Add,
524 I64Sub,
525 I64Mul,
526 I64DivS,
527 I64DivU,
528 I64RemS,
529 I64RemU,
530 I64And,
531 I64Or,
532 I64Xor,
533 I64Shl,
534 I64ShrS,
535 I64ShrU,
536 I64Rotl,
537 I64Rotr,
538 F32Abs,
539 F32Neg,
540 F32Ceil,
541 F32Floor,
542 F32Trunc,
543 F32Nearest,
544 F32Sqrt,
545 F32Add,
546 F32Sub,
547 F32Mul,
548 F32Div,
549 F32Min,
550 F32Max,
551 F32Copysign,
552 F64Abs,
553 F64Neg,
554 F64Ceil,
555 F64Floor,
556 F64Trunc,
557 F64Nearest,
558 F64Sqrt,
559 F64Add,
560 F64Sub,
561 F64Mul,
562 F64Div,
563 F64Min,
564 F64Max,
565 F64Copysign,
566 I32WrapI64,
567 I32TruncF32S,
568 I32TruncF32U,
569 I32TruncF64S,
570 I32TruncF64U,
571 I64ExtendI32S,
572 I64ExtendI32U,
573 I64TruncF32S,
574 I64TruncF32U,
575 I64TruncF64S,
576 I64TruncF64U,
577 F32ConvertI32S,
578 F32ConvertI32U,
579 F32ConvertI64S,
580 F32ConvertI64U,
581 F32DemoteF64,
582 F64ConvertI32S,
583 F64ConvertI32U,
584 F64ConvertI64S,
585 F64ConvertI64U,
586 F64PromoteF32,
587 I32ReinterpretF32,
588 I64ReinterpretF64,
589 F32ReinterpretI32,
590 F64ReinterpretI64,
591 I32Extend8S,
592 I32Extend16S,
593 I64Extend8S,
594 I64Extend16S,
595 I64Extend32S,
596 I32TruncSatF32S,
597 I32TruncSatF32U,
598 I32TruncSatF64S,
599 I32TruncSatF64U,
600 I64TruncSatF32S,
601 I64TruncSatF32U,
602 I64TruncSatF64S,
603 I64TruncSatF64U,
604
605 // Reference types instructions.
606 TypedSelect(ValType),
607 RefNull(HeapType),
608 RefIsNull,
609 RefFunc(u32),
610 RefEq,
611 RefAsNonNull,
612
613 // GC types instructions.
614 StructNew(u32),
615 StructNewDefault(u32),
616 StructGet {
617 struct_type_index: u32,
618 field_index: u32,
619 },
620 StructGetS {
621 struct_type_index: u32,
622 field_index: u32,
623 },
624 StructGetU {
625 struct_type_index: u32,
626 field_index: u32,
627 },
628 StructSet {
629 struct_type_index: u32,
630 field_index: u32,
631 },
632
633 ArrayNew(u32),
634 ArrayNewDefault(u32),
635 ArrayNewFixed {
636 array_type_index: u32,
637 array_size: u32,
638 },
639 ArrayNewData {
640 array_type_index: u32,
641 array_data_index: u32,
642 },
643 ArrayNewElem {
644 array_type_index: u32,
645 array_elem_index: u32,
646 },
647 ArrayGet(u32),
648 ArrayGetS(u32),
649 ArrayGetU(u32),
650 ArraySet(u32),
651 ArrayLen,
652 ArrayFill(u32),
653 ArrayCopy {
654 array_type_index_dst: u32,
655 array_type_index_src: u32,
656 },
657 ArrayInitData {
658 array_type_index: u32,
659 array_data_index: u32,
660 },
661 ArrayInitElem {
662 array_type_index: u32,
663 array_elem_index: u32,
664 },
665 RefTestNonNull(HeapType),
666 RefTestNullable(HeapType),
667 RefCastNonNull(HeapType),
668 RefCastNullable(HeapType),
669 BrOnCast {
670 relative_depth: u32,
671 from_ref_type: RefType,
672 to_ref_type: RefType,
673 },
674 BrOnCastFail {
675 relative_depth: u32,
676 from_ref_type: RefType,
677 to_ref_type: RefType,
678 },
679 AnyConvertExtern,
680 ExternConvertAny,
681
682 RefI31,
683 I31GetS,
684 I31GetU,
685
686 // Bulk memory instructions.
687 TableInit {
688 elem_index: u32,
689 table: u32,
690 },
691 ElemDrop(u32),
692 TableFill(u32),
693 TableSet(u32),
694 TableGet(u32),
695 TableGrow(u32),
696 TableSize(u32),
697 TableCopy {
698 src_table: u32,
699 dst_table: u32,
700 },
701
702 // SIMD instructions.
703 V128Load(MemArg),
704 V128Load8x8S(MemArg),
705 V128Load8x8U(MemArg),
706 V128Load16x4S(MemArg),
707 V128Load16x4U(MemArg),
708 V128Load32x2S(MemArg),
709 V128Load32x2U(MemArg),
710 V128Load8Splat(MemArg),
711 V128Load16Splat(MemArg),
712 V128Load32Splat(MemArg),
713 V128Load64Splat(MemArg),
714 V128Load32Zero(MemArg),
715 V128Load64Zero(MemArg),
716 V128Store(MemArg),
717 V128Load8Lane {
718 memarg: MemArg,
719 lane: Lane,
720 },
721 V128Load16Lane {
722 memarg: MemArg,
723 lane: Lane,
724 },
725 V128Load32Lane {
726 memarg: MemArg,
727 lane: Lane,
728 },
729 V128Load64Lane {
730 memarg: MemArg,
731 lane: Lane,
732 },
733 V128Store8Lane {
734 memarg: MemArg,
735 lane: Lane,
736 },
737 V128Store16Lane {
738 memarg: MemArg,
739 lane: Lane,
740 },
741 V128Store32Lane {
742 memarg: MemArg,
743 lane: Lane,
744 },
745 V128Store64Lane {
746 memarg: MemArg,
747 lane: Lane,
748 },
749 V128Const(i128),
750 I8x16Shuffle([Lane; 16]),
751 I8x16ExtractLaneS(Lane),
752 I8x16ExtractLaneU(Lane),
753 I8x16ReplaceLane(Lane),
754 I16x8ExtractLaneS(Lane),
755 I16x8ExtractLaneU(Lane),
756 I16x8ReplaceLane(Lane),
757 I32x4ExtractLane(Lane),
758 I32x4ReplaceLane(Lane),
759 I64x2ExtractLane(Lane),
760 I64x2ReplaceLane(Lane),
761 F32x4ExtractLane(Lane),
762 F32x4ReplaceLane(Lane),
763 F64x2ExtractLane(Lane),
764 F64x2ReplaceLane(Lane),
765 I8x16Swizzle,
766 I8x16Splat,
767 I16x8Splat,
768 I32x4Splat,
769 I64x2Splat,
770 F32x4Splat,
771 F64x2Splat,
772 I8x16Eq,
773 I8x16Ne,
774 I8x16LtS,
775 I8x16LtU,
776 I8x16GtS,
777 I8x16GtU,
778 I8x16LeS,
779 I8x16LeU,
780 I8x16GeS,
781 I8x16GeU,
782 I16x8Eq,
783 I16x8Ne,
784 I16x8LtS,
785 I16x8LtU,
786 I16x8GtS,
787 I16x8GtU,
788 I16x8LeS,
789 I16x8LeU,
790 I16x8GeS,
791 I16x8GeU,
792 I32x4Eq,
793 I32x4Ne,
794 I32x4LtS,
795 I32x4LtU,
796 I32x4GtS,
797 I32x4GtU,
798 I32x4LeS,
799 I32x4LeU,
800 I32x4GeS,
801 I32x4GeU,
802 I64x2Eq,
803 I64x2Ne,
804 I64x2LtS,
805 I64x2GtS,
806 I64x2LeS,
807 I64x2GeS,
808 F32x4Eq,
809 F32x4Ne,
810 F32x4Lt,
811 F32x4Gt,
812 F32x4Le,
813 F32x4Ge,
814 F64x2Eq,
815 F64x2Ne,
816 F64x2Lt,
817 F64x2Gt,
818 F64x2Le,
819 F64x2Ge,
820 V128Not,
821 V128And,
822 V128AndNot,
823 V128Or,
824 V128Xor,
825 V128Bitselect,
826 V128AnyTrue,
827 I8x16Abs,
828 I8x16Neg,
829 I8x16Popcnt,
830 I8x16AllTrue,
831 I8x16Bitmask,
832 I8x16NarrowI16x8S,
833 I8x16NarrowI16x8U,
834 I8x16Shl,
835 I8x16ShrS,
836 I8x16ShrU,
837 I8x16Add,
838 I8x16AddSatS,
839 I8x16AddSatU,
840 I8x16Sub,
841 I8x16SubSatS,
842 I8x16SubSatU,
843 I8x16MinS,
844 I8x16MinU,
845 I8x16MaxS,
846 I8x16MaxU,
847 I8x16AvgrU,
848 I16x8ExtAddPairwiseI8x16S,
849 I16x8ExtAddPairwiseI8x16U,
850 I16x8Abs,
851 I16x8Neg,
852 I16x8Q15MulrSatS,
853 I16x8AllTrue,
854 I16x8Bitmask,
855 I16x8NarrowI32x4S,
856 I16x8NarrowI32x4U,
857 I16x8ExtendLowI8x16S,
858 I16x8ExtendHighI8x16S,
859 I16x8ExtendLowI8x16U,
860 I16x8ExtendHighI8x16U,
861 I16x8Shl,
862 I16x8ShrS,
863 I16x8ShrU,
864 I16x8Add,
865 I16x8AddSatS,
866 I16x8AddSatU,
867 I16x8Sub,
868 I16x8SubSatS,
869 I16x8SubSatU,
870 I16x8Mul,
871 I16x8MinS,
872 I16x8MinU,
873 I16x8MaxS,
874 I16x8MaxU,
875 I16x8AvgrU,
876 I16x8ExtMulLowI8x16S,
877 I16x8ExtMulHighI8x16S,
878 I16x8ExtMulLowI8x16U,
879 I16x8ExtMulHighI8x16U,
880 I32x4ExtAddPairwiseI16x8S,
881 I32x4ExtAddPairwiseI16x8U,
882 I32x4Abs,
883 I32x4Neg,
884 I32x4AllTrue,
885 I32x4Bitmask,
886 I32x4ExtendLowI16x8S,
887 I32x4ExtendHighI16x8S,
888 I32x4ExtendLowI16x8U,
889 I32x4ExtendHighI16x8U,
890 I32x4Shl,
891 I32x4ShrS,
892 I32x4ShrU,
893 I32x4Add,
894 I32x4Sub,
895 I32x4Mul,
896 I32x4MinS,
897 I32x4MinU,
898 I32x4MaxS,
899 I32x4MaxU,
900 I32x4DotI16x8S,
901 I32x4ExtMulLowI16x8S,
902 I32x4ExtMulHighI16x8S,
903 I32x4ExtMulLowI16x8U,
904 I32x4ExtMulHighI16x8U,
905 I64x2Abs,
906 I64x2Neg,
907 I64x2AllTrue,
908 I64x2Bitmask,
909 I64x2ExtendLowI32x4S,
910 I64x2ExtendHighI32x4S,
911 I64x2ExtendLowI32x4U,
912 I64x2ExtendHighI32x4U,
913 I64x2Shl,
914 I64x2ShrS,
915 I64x2ShrU,
916 I64x2Add,
917 I64x2Sub,
918 I64x2Mul,
919 I64x2ExtMulLowI32x4S,
920 I64x2ExtMulHighI32x4S,
921 I64x2ExtMulLowI32x4U,
922 I64x2ExtMulHighI32x4U,
923 F32x4Ceil,
924 F32x4Floor,
925 F32x4Trunc,
926 F32x4Nearest,
927 F32x4Abs,
928 F32x4Neg,
929 F32x4Sqrt,
930 F32x4Add,
931 F32x4Sub,
932 F32x4Mul,
933 F32x4Div,
934 F32x4Min,
935 F32x4Max,
936 F32x4PMin,
937 F32x4PMax,
938 F64x2Ceil,
939 F64x2Floor,
940 F64x2Trunc,
941 F64x2Nearest,
942 F64x2Abs,
943 F64x2Neg,
944 F64x2Sqrt,
945 F64x2Add,
946 F64x2Sub,
947 F64x2Mul,
948 F64x2Div,
949 F64x2Min,
950 F64x2Max,
951 F64x2PMin,
952 F64x2PMax,
953 I32x4TruncSatF32x4S,
954 I32x4TruncSatF32x4U,
955 F32x4ConvertI32x4S,
956 F32x4ConvertI32x4U,
957 I32x4TruncSatF64x2SZero,
958 I32x4TruncSatF64x2UZero,
959 F64x2ConvertLowI32x4S,
960 F64x2ConvertLowI32x4U,
961 F32x4DemoteF64x2Zero,
962 F64x2PromoteLowF32x4,
963
964 // Relaxed simd proposal
965 I8x16RelaxedSwizzle,
966 I32x4RelaxedTruncF32x4S,
967 I32x4RelaxedTruncF32x4U,
968 I32x4RelaxedTruncF64x2SZero,
969 I32x4RelaxedTruncF64x2UZero,
970 F32x4RelaxedMadd,
971 F32x4RelaxedNmadd,
972 F64x2RelaxedMadd,
973 F64x2RelaxedNmadd,
974 I8x16RelaxedLaneselect,
975 I16x8RelaxedLaneselect,
976 I32x4RelaxedLaneselect,
977 I64x2RelaxedLaneselect,
978 F32x4RelaxedMin,
979 F32x4RelaxedMax,
980 F64x2RelaxedMin,
981 F64x2RelaxedMax,
982 I16x8RelaxedQ15mulrS,
983 I16x8RelaxedDotI8x16I7x16S,
984 I32x4RelaxedDotI8x16I7x16AddS,
985
986 // Atomic instructions (the threads proposal)
987 MemoryAtomicNotify(MemArg),
988 MemoryAtomicWait32(MemArg),
989 MemoryAtomicWait64(MemArg),
990 AtomicFence,
991 I32AtomicLoad(MemArg),
992 I64AtomicLoad(MemArg),
993 I32AtomicLoad8U(MemArg),
994 I32AtomicLoad16U(MemArg),
995 I64AtomicLoad8U(MemArg),
996 I64AtomicLoad16U(MemArg),
997 I64AtomicLoad32U(MemArg),
998 I32AtomicStore(MemArg),
999 I64AtomicStore(MemArg),
1000 I32AtomicStore8(MemArg),
1001 I32AtomicStore16(MemArg),
1002 I64AtomicStore8(MemArg),
1003 I64AtomicStore16(MemArg),
1004 I64AtomicStore32(MemArg),
1005 I32AtomicRmwAdd(MemArg),
1006 I64AtomicRmwAdd(MemArg),
1007 I32AtomicRmw8AddU(MemArg),
1008 I32AtomicRmw16AddU(MemArg),
1009 I64AtomicRmw8AddU(MemArg),
1010 I64AtomicRmw16AddU(MemArg),
1011 I64AtomicRmw32AddU(MemArg),
1012 I32AtomicRmwSub(MemArg),
1013 I64AtomicRmwSub(MemArg),
1014 I32AtomicRmw8SubU(MemArg),
1015 I32AtomicRmw16SubU(MemArg),
1016 I64AtomicRmw8SubU(MemArg),
1017 I64AtomicRmw16SubU(MemArg),
1018 I64AtomicRmw32SubU(MemArg),
1019 I32AtomicRmwAnd(MemArg),
1020 I64AtomicRmwAnd(MemArg),
1021 I32AtomicRmw8AndU(MemArg),
1022 I32AtomicRmw16AndU(MemArg),
1023 I64AtomicRmw8AndU(MemArg),
1024 I64AtomicRmw16AndU(MemArg),
1025 I64AtomicRmw32AndU(MemArg),
1026 I32AtomicRmwOr(MemArg),
1027 I64AtomicRmwOr(MemArg),
1028 I32AtomicRmw8OrU(MemArg),
1029 I32AtomicRmw16OrU(MemArg),
1030 I64AtomicRmw8OrU(MemArg),
1031 I64AtomicRmw16OrU(MemArg),
1032 I64AtomicRmw32OrU(MemArg),
1033 I32AtomicRmwXor(MemArg),
1034 I64AtomicRmwXor(MemArg),
1035 I32AtomicRmw8XorU(MemArg),
1036 I32AtomicRmw16XorU(MemArg),
1037 I64AtomicRmw8XorU(MemArg),
1038 I64AtomicRmw16XorU(MemArg),
1039 I64AtomicRmw32XorU(MemArg),
1040 I32AtomicRmwXchg(MemArg),
1041 I64AtomicRmwXchg(MemArg),
1042 I32AtomicRmw8XchgU(MemArg),
1043 I32AtomicRmw16XchgU(MemArg),
1044 I64AtomicRmw8XchgU(MemArg),
1045 I64AtomicRmw16XchgU(MemArg),
1046 I64AtomicRmw32XchgU(MemArg),
1047 I32AtomicRmwCmpxchg(MemArg),
1048 I64AtomicRmwCmpxchg(MemArg),
1049 I32AtomicRmw8CmpxchgU(MemArg),
1050 I32AtomicRmw16CmpxchgU(MemArg),
1051 I64AtomicRmw8CmpxchgU(MemArg),
1052 I64AtomicRmw16CmpxchgU(MemArg),
1053 I64AtomicRmw32CmpxchgU(MemArg),
1054
1055 // More atomic instructions (the shared-everything-threads proposal)
1056 GlobalAtomicGet {
1057 ordering: Ordering,
1058 global_index: u32,
1059 },
1060 GlobalAtomicSet {
1061 ordering: Ordering,
1062 global_index: u32,
1063 },
1064 GlobalAtomicRmwAdd {
1065 ordering: Ordering,
1066 global_index: u32,
1067 },
1068 GlobalAtomicRmwSub {
1069 ordering: Ordering,
1070 global_index: u32,
1071 },
1072 GlobalAtomicRmwAnd {
1073 ordering: Ordering,
1074 global_index: u32,
1075 },
1076 GlobalAtomicRmwOr {
1077 ordering: Ordering,
1078 global_index: u32,
1079 },
1080 GlobalAtomicRmwXor {
1081 ordering: Ordering,
1082 global_index: u32,
1083 },
1084 GlobalAtomicRmwXchg {
1085 ordering: Ordering,
1086 global_index: u32,
1087 },
1088 GlobalAtomicRmwCmpxchg {
1089 ordering: Ordering,
1090 global_index: u32,
1091 },
1092 TableAtomicGet {
1093 ordering: Ordering,
1094 table_index: u32,
1095 },
1096 TableAtomicSet {
1097 ordering: Ordering,
1098 table_index: u32,
1099 },
1100 TableAtomicRmwXchg {
1101 ordering: Ordering,
1102 table_index: u32,
1103 },
1104 TableAtomicRmwCmpxchg {
1105 ordering: Ordering,
1106 table_index: u32,
1107 },
1108 StructAtomicGet {
1109 ordering: Ordering,
1110 struct_type_index: u32,
1111 field_index: u32,
1112 },
1113 StructAtomicGetS {
1114 ordering: Ordering,
1115 struct_type_index: u32,
1116 field_index: u32,
1117 },
1118 StructAtomicGetU {
1119 ordering: Ordering,
1120 struct_type_index: u32,
1121 field_index: u32,
1122 },
1123 StructAtomicSet {
1124 ordering: Ordering,
1125 struct_type_index: u32,
1126 field_index: u32,
1127 },
1128 StructAtomicRmwAdd {
1129 ordering: Ordering,
1130 struct_type_index: u32,
1131 field_index: u32,
1132 },
1133 StructAtomicRmwSub {
1134 ordering: Ordering,
1135 struct_type_index: u32,
1136 field_index: u32,
1137 },
1138 StructAtomicRmwAnd {
1139 ordering: Ordering,
1140 struct_type_index: u32,
1141 field_index: u32,
1142 },
1143 StructAtomicRmwOr {
1144 ordering: Ordering,
1145 struct_type_index: u32,
1146 field_index: u32,
1147 },
1148 StructAtomicRmwXor {
1149 ordering: Ordering,
1150 struct_type_index: u32,
1151 field_index: u32,
1152 },
1153 StructAtomicRmwXchg {
1154 ordering: Ordering,
1155 struct_type_index: u32,
1156 field_index: u32,
1157 },
1158 StructAtomicRmwCmpxchg {
1159 ordering: Ordering,
1160 struct_type_index: u32,
1161 field_index: u32,
1162 },
1163 ArrayAtomicGet {
1164 ordering: Ordering,
1165 array_type_index: u32,
1166 },
1167 ArrayAtomicGetS {
1168 ordering: Ordering,
1169 array_type_index: u32,
1170 },
1171 ArrayAtomicGetU {
1172 ordering: Ordering,
1173 array_type_index: u32,
1174 },
1175 ArrayAtomicSet {
1176 ordering: Ordering,
1177 array_type_index: u32,
1178 },
1179 ArrayAtomicRmwAdd {
1180 ordering: Ordering,
1181 array_type_index: u32,
1182 },
1183 ArrayAtomicRmwSub {
1184 ordering: Ordering,
1185 array_type_index: u32,
1186 },
1187 ArrayAtomicRmwAnd {
1188 ordering: Ordering,
1189 array_type_index: u32,
1190 },
1191 ArrayAtomicRmwOr {
1192 ordering: Ordering,
1193 array_type_index: u32,
1194 },
1195 ArrayAtomicRmwXor {
1196 ordering: Ordering,
1197 array_type_index: u32,
1198 },
1199 ArrayAtomicRmwXchg {
1200 ordering: Ordering,
1201 array_type_index: u32,
1202 },
1203 ArrayAtomicRmwCmpxchg {
1204 ordering: Ordering,
1205 array_type_index: u32,
1206 },
1207 RefI31Shared,
1208 // Stack switching
1209 ContNew(u32),
1210 ContBind {
1211 argument_index: u32,
1212 result_index: u32,
1213 },
1214 Suspend(u32),
1215 Resume {
1216 cont_type_index: u32,
1217 resume_table: Cow<'a, [Handle]>,
1218 },
1219 ResumeThrow {
1220 cont_type_index: u32,
1221 tag_index: u32,
1222 resume_table: Cow<'a, [Handle]>,
1223 },
1224 Switch {
1225 cont_type_index: u32,
1226 tag_index: u32,
1227 },
1228
1229 // Wide Arithmetic
1230 I64Add128,
1231 I64Sub128,
1232 I64MulWideS,
1233 I64MulWideU,
1234}
1235
1236impl Encode for Instruction<'_> {
1237 fn encode(&self, sink: &mut Vec<u8>) {
1238 match *self {
1239 // Control instructions.
1240 Instruction::Unreachable => sink.push(0x00),
1241 Instruction::Nop => sink.push(0x01),
1242 Instruction::Block(bt) => {
1243 sink.push(0x02);
1244 bt.encode(sink);
1245 }
1246 Instruction::Loop(bt) => {
1247 sink.push(0x03);
1248 bt.encode(sink);
1249 }
1250 Instruction::If(bt) => {
1251 sink.push(0x04);
1252 bt.encode(sink);
1253 }
1254 Instruction::Else => sink.push(0x05),
1255 Instruction::Try(bt) => {
1256 sink.push(0x06);
1257 bt.encode(sink);
1258 }
1259 Instruction::Catch(t) => {
1260 sink.push(0x07);
1261 t.encode(sink);
1262 }
1263 Instruction::Throw(t) => {
1264 sink.push(0x08);
1265 t.encode(sink);
1266 }
1267 Instruction::Rethrow(l) => {
1268 sink.push(0x09);
1269 l.encode(sink);
1270 }
1271 Instruction::ThrowRef => {
1272 sink.push(0x0A);
1273 }
1274 Instruction::End => sink.push(0x0B),
1275 Instruction::Br(l) => {
1276 sink.push(0x0C);
1277 l.encode(sink);
1278 }
1279 Instruction::BrIf(l) => {
1280 sink.push(0x0D);
1281 l.encode(sink);
1282 }
1283 Instruction::BrTable(ref ls, l) => {
1284 sink.push(0x0E);
1285 ls.encode(sink);
1286 l.encode(sink);
1287 }
1288 Instruction::BrOnNull(l) => {
1289 sink.push(0xD5);
1290 l.encode(sink);
1291 }
1292 Instruction::BrOnNonNull(l) => {
1293 sink.push(0xD6);
1294 l.encode(sink);
1295 }
1296 Instruction::Return => sink.push(0x0F),
1297 Instruction::Call(f) => {
1298 sink.push(0x10);
1299 f.encode(sink);
1300 }
1301 Instruction::CallRef(ty) => {
1302 sink.push(0x14);
1303 ty.encode(sink);
1304 }
1305 Instruction::CallIndirect {
1306 type_index,
1307 table_index,
1308 } => {
1309 sink.push(0x11);
1310 type_index.encode(sink);
1311 table_index.encode(sink);
1312 }
1313 Instruction::ReturnCallRef(ty) => {
1314 sink.push(0x15);
1315 ty.encode(sink);
1316 }
1317
1318 Instruction::ReturnCall(f) => {
1319 sink.push(0x12);
1320 f.encode(sink);
1321 }
1322 Instruction::ReturnCallIndirect {
1323 type_index,
1324 table_index,
1325 } => {
1326 sink.push(0x13);
1327 type_index.encode(sink);
1328 table_index.encode(sink);
1329 }
1330 Instruction::Delegate(l) => {
1331 sink.push(0x18);
1332 l.encode(sink);
1333 }
1334 Instruction::CatchAll => {
1335 sink.push(0x19);
1336 }
1337
1338 // Parametric instructions.
1339 Instruction::Drop => sink.push(0x1A),
1340 Instruction::Select => sink.push(0x1B),
1341 Instruction::TypedSelect(ty) => {
1342 sink.push(0x1c);
1343 [ty].encode(sink);
1344 }
1345
1346 Instruction::TryTable(ty, ref catches) => {
1347 sink.push(0x1f);
1348 ty.encode(sink);
1349 catches.encode(sink);
1350 }
1351
1352 // Variable instructions.
1353 Instruction::LocalGet(l) => {
1354 sink.push(0x20);
1355 l.encode(sink);
1356 }
1357 Instruction::LocalSet(l) => {
1358 sink.push(0x21);
1359 l.encode(sink);
1360 }
1361 Instruction::LocalTee(l) => {
1362 sink.push(0x22);
1363 l.encode(sink);
1364 }
1365 Instruction::GlobalGet(g) => {
1366 sink.push(0x23);
1367 g.encode(sink);
1368 }
1369 Instruction::GlobalSet(g) => {
1370 sink.push(0x24);
1371 g.encode(sink);
1372 }
1373 Instruction::TableGet(table) => {
1374 sink.push(0x25);
1375 table.encode(sink);
1376 }
1377 Instruction::TableSet(table) => {
1378 sink.push(0x26);
1379 table.encode(sink);
1380 }
1381
1382 // Memory instructions.
1383 Instruction::I32Load(m) => {
1384 sink.push(0x28);
1385 m.encode(sink);
1386 }
1387 Instruction::I64Load(m) => {
1388 sink.push(0x29);
1389 m.encode(sink);
1390 }
1391 Instruction::F32Load(m) => {
1392 sink.push(0x2A);
1393 m.encode(sink);
1394 }
1395 Instruction::F64Load(m) => {
1396 sink.push(0x2B);
1397 m.encode(sink);
1398 }
1399 Instruction::I32Load8S(m) => {
1400 sink.push(0x2C);
1401 m.encode(sink);
1402 }
1403 Instruction::I32Load8U(m) => {
1404 sink.push(0x2D);
1405 m.encode(sink);
1406 }
1407 Instruction::I32Load16S(m) => {
1408 sink.push(0x2E);
1409 m.encode(sink);
1410 }
1411 Instruction::I32Load16U(m) => {
1412 sink.push(0x2F);
1413 m.encode(sink);
1414 }
1415 Instruction::I64Load8S(m) => {
1416 sink.push(0x30);
1417 m.encode(sink);
1418 }
1419 Instruction::I64Load8U(m) => {
1420 sink.push(0x31);
1421 m.encode(sink);
1422 }
1423 Instruction::I64Load16S(m) => {
1424 sink.push(0x32);
1425 m.encode(sink);
1426 }
1427 Instruction::I64Load16U(m) => {
1428 sink.push(0x33);
1429 m.encode(sink);
1430 }
1431 Instruction::I64Load32S(m) => {
1432 sink.push(0x34);
1433 m.encode(sink);
1434 }
1435 Instruction::I64Load32U(m) => {
1436 sink.push(0x35);
1437 m.encode(sink);
1438 }
1439 Instruction::I32Store(m) => {
1440 sink.push(0x36);
1441 m.encode(sink);
1442 }
1443 Instruction::I64Store(m) => {
1444 sink.push(0x37);
1445 m.encode(sink);
1446 }
1447 Instruction::F32Store(m) => {
1448 sink.push(0x38);
1449 m.encode(sink);
1450 }
1451 Instruction::F64Store(m) => {
1452 sink.push(0x39);
1453 m.encode(sink);
1454 }
1455 Instruction::I32Store8(m) => {
1456 sink.push(0x3A);
1457 m.encode(sink);
1458 }
1459 Instruction::I32Store16(m) => {
1460 sink.push(0x3B);
1461 m.encode(sink);
1462 }
1463 Instruction::I64Store8(m) => {
1464 sink.push(0x3C);
1465 m.encode(sink);
1466 }
1467 Instruction::I64Store16(m) => {
1468 sink.push(0x3D);
1469 m.encode(sink);
1470 }
1471 Instruction::I64Store32(m) => {
1472 sink.push(0x3E);
1473 m.encode(sink);
1474 }
1475 Instruction::MemorySize(i) => {
1476 sink.push(0x3F);
1477 i.encode(sink);
1478 }
1479 Instruction::MemoryGrow(i) => {
1480 sink.push(0x40);
1481 i.encode(sink);
1482 }
1483 Instruction::MemoryInit { mem, data_index } => {
1484 sink.push(0xfc);
1485 sink.push(0x08);
1486 data_index.encode(sink);
1487 mem.encode(sink);
1488 }
1489 Instruction::DataDrop(data) => {
1490 sink.push(0xfc);
1491 sink.push(0x09);
1492 data.encode(sink);
1493 }
1494 Instruction::MemoryCopy { src_mem, dst_mem } => {
1495 sink.push(0xfc);
1496 sink.push(0x0a);
1497 dst_mem.encode(sink);
1498 src_mem.encode(sink);
1499 }
1500 Instruction::MemoryFill(mem) => {
1501 sink.push(0xfc);
1502 sink.push(0x0b);
1503 mem.encode(sink);
1504 }
1505 Instruction::MemoryDiscard(mem) => {
1506 sink.push(0xfc);
1507 sink.push(0x12);
1508 mem.encode(sink);
1509 }
1510
1511 // Numeric instructions.
1512 Instruction::I32Const(x) => {
1513 sink.push(0x41);
1514 x.encode(sink);
1515 }
1516 Instruction::I64Const(x) => {
1517 sink.push(0x42);
1518 x.encode(sink);
1519 }
1520 Instruction::F32Const(x) => {
1521 sink.push(0x43);
1522 let x = x.to_bits();
1523 sink.extend(x.to_le_bytes().iter().copied());
1524 }
1525 Instruction::F64Const(x) => {
1526 sink.push(0x44);
1527 let x = x.to_bits();
1528 sink.extend(x.to_le_bytes().iter().copied());
1529 }
1530 Instruction::I32Eqz => sink.push(0x45),
1531 Instruction::I32Eq => sink.push(0x46),
1532 Instruction::I32Ne => sink.push(0x47),
1533 Instruction::I32LtS => sink.push(0x48),
1534 Instruction::I32LtU => sink.push(0x49),
1535 Instruction::I32GtS => sink.push(0x4A),
1536 Instruction::I32GtU => sink.push(0x4B),
1537 Instruction::I32LeS => sink.push(0x4C),
1538 Instruction::I32LeU => sink.push(0x4D),
1539 Instruction::I32GeS => sink.push(0x4E),
1540 Instruction::I32GeU => sink.push(0x4F),
1541 Instruction::I64Eqz => sink.push(0x50),
1542 Instruction::I64Eq => sink.push(0x51),
1543 Instruction::I64Ne => sink.push(0x52),
1544 Instruction::I64LtS => sink.push(0x53),
1545 Instruction::I64LtU => sink.push(0x54),
1546 Instruction::I64GtS => sink.push(0x55),
1547 Instruction::I64GtU => sink.push(0x56),
1548 Instruction::I64LeS => sink.push(0x57),
1549 Instruction::I64LeU => sink.push(0x58),
1550 Instruction::I64GeS => sink.push(0x59),
1551 Instruction::I64GeU => sink.push(0x5A),
1552 Instruction::F32Eq => sink.push(0x5B),
1553 Instruction::F32Ne => sink.push(0x5C),
1554 Instruction::F32Lt => sink.push(0x5D),
1555 Instruction::F32Gt => sink.push(0x5E),
1556 Instruction::F32Le => sink.push(0x5F),
1557 Instruction::F32Ge => sink.push(0x60),
1558 Instruction::F64Eq => sink.push(0x61),
1559 Instruction::F64Ne => sink.push(0x62),
1560 Instruction::F64Lt => sink.push(0x63),
1561 Instruction::F64Gt => sink.push(0x64),
1562 Instruction::F64Le => sink.push(0x65),
1563 Instruction::F64Ge => sink.push(0x66),
1564 Instruction::I32Clz => sink.push(0x67),
1565 Instruction::I32Ctz => sink.push(0x68),
1566 Instruction::I32Popcnt => sink.push(0x69),
1567 Instruction::I32Add => sink.push(0x6A),
1568 Instruction::I32Sub => sink.push(0x6B),
1569 Instruction::I32Mul => sink.push(0x6C),
1570 Instruction::I32DivS => sink.push(0x6D),
1571 Instruction::I32DivU => sink.push(0x6E),
1572 Instruction::I32RemS => sink.push(0x6F),
1573 Instruction::I32RemU => sink.push(0x70),
1574 Instruction::I32And => sink.push(0x71),
1575 Instruction::I32Or => sink.push(0x72),
1576 Instruction::I32Xor => sink.push(0x73),
1577 Instruction::I32Shl => sink.push(0x74),
1578 Instruction::I32ShrS => sink.push(0x75),
1579 Instruction::I32ShrU => sink.push(0x76),
1580 Instruction::I32Rotl => sink.push(0x77),
1581 Instruction::I32Rotr => sink.push(0x78),
1582 Instruction::I64Clz => sink.push(0x79),
1583 Instruction::I64Ctz => sink.push(0x7A),
1584 Instruction::I64Popcnt => sink.push(0x7B),
1585 Instruction::I64Add => sink.push(0x7C),
1586 Instruction::I64Sub => sink.push(0x7D),
1587 Instruction::I64Mul => sink.push(0x7E),
1588 Instruction::I64DivS => sink.push(0x7F),
1589 Instruction::I64DivU => sink.push(0x80),
1590 Instruction::I64RemS => sink.push(0x81),
1591 Instruction::I64RemU => sink.push(0x82),
1592 Instruction::I64And => sink.push(0x83),
1593 Instruction::I64Or => sink.push(0x84),
1594 Instruction::I64Xor => sink.push(0x85),
1595 Instruction::I64Shl => sink.push(0x86),
1596 Instruction::I64ShrS => sink.push(0x87),
1597 Instruction::I64ShrU => sink.push(0x88),
1598 Instruction::I64Rotl => sink.push(0x89),
1599 Instruction::I64Rotr => sink.push(0x8A),
1600 Instruction::F32Abs => sink.push(0x8B),
1601 Instruction::F32Neg => sink.push(0x8C),
1602 Instruction::F32Ceil => sink.push(0x8D),
1603 Instruction::F32Floor => sink.push(0x8E),
1604 Instruction::F32Trunc => sink.push(0x8F),
1605 Instruction::F32Nearest => sink.push(0x90),
1606 Instruction::F32Sqrt => sink.push(0x91),
1607 Instruction::F32Add => sink.push(0x92),
1608 Instruction::F32Sub => sink.push(0x93),
1609 Instruction::F32Mul => sink.push(0x94),
1610 Instruction::F32Div => sink.push(0x95),
1611 Instruction::F32Min => sink.push(0x96),
1612 Instruction::F32Max => sink.push(0x97),
1613 Instruction::F32Copysign => sink.push(0x98),
1614 Instruction::F64Abs => sink.push(0x99),
1615 Instruction::F64Neg => sink.push(0x9A),
1616 Instruction::F64Ceil => sink.push(0x9B),
1617 Instruction::F64Floor => sink.push(0x9C),
1618 Instruction::F64Trunc => sink.push(0x9D),
1619 Instruction::F64Nearest => sink.push(0x9E),
1620 Instruction::F64Sqrt => sink.push(0x9F),
1621 Instruction::F64Add => sink.push(0xA0),
1622 Instruction::F64Sub => sink.push(0xA1),
1623 Instruction::F64Mul => sink.push(0xA2),
1624 Instruction::F64Div => sink.push(0xA3),
1625 Instruction::F64Min => sink.push(0xA4),
1626 Instruction::F64Max => sink.push(0xA5),
1627 Instruction::F64Copysign => sink.push(0xA6),
1628 Instruction::I32WrapI64 => sink.push(0xA7),
1629 Instruction::I32TruncF32S => sink.push(0xA8),
1630 Instruction::I32TruncF32U => sink.push(0xA9),
1631 Instruction::I32TruncF64S => sink.push(0xAA),
1632 Instruction::I32TruncF64U => sink.push(0xAB),
1633 Instruction::I64ExtendI32S => sink.push(0xAC),
1634 Instruction::I64ExtendI32U => sink.push(0xAD),
1635 Instruction::I64TruncF32S => sink.push(0xAE),
1636 Instruction::I64TruncF32U => sink.push(0xAF),
1637 Instruction::I64TruncF64S => sink.push(0xB0),
1638 Instruction::I64TruncF64U => sink.push(0xB1),
1639 Instruction::F32ConvertI32S => sink.push(0xB2),
1640 Instruction::F32ConvertI32U => sink.push(0xB3),
1641 Instruction::F32ConvertI64S => sink.push(0xB4),
1642 Instruction::F32ConvertI64U => sink.push(0xB5),
1643 Instruction::F32DemoteF64 => sink.push(0xB6),
1644 Instruction::F64ConvertI32S => sink.push(0xB7),
1645 Instruction::F64ConvertI32U => sink.push(0xB8),
1646 Instruction::F64ConvertI64S => sink.push(0xB9),
1647 Instruction::F64ConvertI64U => sink.push(0xBA),
1648 Instruction::F64PromoteF32 => sink.push(0xBB),
1649 Instruction::I32ReinterpretF32 => sink.push(0xBC),
1650 Instruction::I64ReinterpretF64 => sink.push(0xBD),
1651 Instruction::F32ReinterpretI32 => sink.push(0xBE),
1652 Instruction::F64ReinterpretI64 => sink.push(0xBF),
1653 Instruction::I32Extend8S => sink.push(0xC0),
1654 Instruction::I32Extend16S => sink.push(0xC1),
1655 Instruction::I64Extend8S => sink.push(0xC2),
1656 Instruction::I64Extend16S => sink.push(0xC3),
1657 Instruction::I64Extend32S => sink.push(0xC4),
1658
1659 Instruction::I32TruncSatF32S => {
1660 sink.push(0xFC);
1661 sink.push(0x00);
1662 }
1663 Instruction::I32TruncSatF32U => {
1664 sink.push(0xFC);
1665 sink.push(0x01);
1666 }
1667 Instruction::I32TruncSatF64S => {
1668 sink.push(0xFC);
1669 sink.push(0x02);
1670 }
1671 Instruction::I32TruncSatF64U => {
1672 sink.push(0xFC);
1673 sink.push(0x03);
1674 }
1675 Instruction::I64TruncSatF32S => {
1676 sink.push(0xFC);
1677 sink.push(0x04);
1678 }
1679 Instruction::I64TruncSatF32U => {
1680 sink.push(0xFC);
1681 sink.push(0x05);
1682 }
1683 Instruction::I64TruncSatF64S => {
1684 sink.push(0xFC);
1685 sink.push(0x06);
1686 }
1687 Instruction::I64TruncSatF64U => {
1688 sink.push(0xFC);
1689 sink.push(0x07);
1690 }
1691
1692 // Reference types instructions.
1693 Instruction::RefNull(ty) => {
1694 sink.push(0xd0);
1695 ty.encode(sink);
1696 }
1697 Instruction::RefIsNull => sink.push(0xd1),
1698 Instruction::RefFunc(f) => {
1699 sink.push(0xd2);
1700 f.encode(sink);
1701 }
1702 Instruction::RefEq => sink.push(0xd3),
1703 Instruction::RefAsNonNull => sink.push(0xd4),
1704
1705 // GC instructions.
1706 Instruction::StructNew(type_index) => {
1707 sink.push(0xfb);
1708 sink.push(0x00);
1709 type_index.encode(sink);
1710 }
1711 Instruction::StructNewDefault(type_index) => {
1712 sink.push(0xfb);
1713 sink.push(0x01);
1714 type_index.encode(sink);
1715 }
1716 Instruction::StructGet {
1717 struct_type_index,
1718 field_index,
1719 } => {
1720 sink.push(0xfb);
1721 sink.push(0x02);
1722 struct_type_index.encode(sink);
1723 field_index.encode(sink);
1724 }
1725 Instruction::StructGetS {
1726 struct_type_index,
1727 field_index,
1728 } => {
1729 sink.push(0xfb);
1730 sink.push(0x03);
1731 struct_type_index.encode(sink);
1732 field_index.encode(sink);
1733 }
1734 Instruction::StructGetU {
1735 struct_type_index,
1736 field_index,
1737 } => {
1738 sink.push(0xfb);
1739 sink.push(0x04);
1740 struct_type_index.encode(sink);
1741 field_index.encode(sink);
1742 }
1743 Instruction::StructSet {
1744 struct_type_index,
1745 field_index,
1746 } => {
1747 sink.push(0xfb);
1748 sink.push(0x05);
1749 struct_type_index.encode(sink);
1750 field_index.encode(sink);
1751 }
1752 Instruction::ArrayNew(type_index) => {
1753 sink.push(0xfb);
1754 sink.push(0x06);
1755 type_index.encode(sink);
1756 }
1757 Instruction::ArrayNewDefault(type_index) => {
1758 sink.push(0xfb);
1759 sink.push(0x07);
1760 type_index.encode(sink);
1761 }
1762 Instruction::ArrayNewFixed {
1763 array_type_index,
1764 array_size,
1765 } => {
1766 sink.push(0xfb);
1767 sink.push(0x08);
1768 array_type_index.encode(sink);
1769 array_size.encode(sink);
1770 }
1771 Instruction::ArrayNewData {
1772 array_type_index,
1773 array_data_index,
1774 } => {
1775 sink.push(0xfb);
1776 sink.push(0x09);
1777 array_type_index.encode(sink);
1778 array_data_index.encode(sink);
1779 }
1780 Instruction::ArrayNewElem {
1781 array_type_index,
1782 array_elem_index,
1783 } => {
1784 sink.push(0xfb);
1785 sink.push(0x0a);
1786 array_type_index.encode(sink);
1787 array_elem_index.encode(sink);
1788 }
1789 Instruction::ArrayGet(type_index) => {
1790 sink.push(0xfb);
1791 sink.push(0x0b);
1792 type_index.encode(sink);
1793 }
1794 Instruction::ArrayGetS(type_index) => {
1795 sink.push(0xfb);
1796 sink.push(0x0c);
1797 type_index.encode(sink);
1798 }
1799 Instruction::ArrayGetU(type_index) => {
1800 sink.push(0xfb);
1801 sink.push(0x0d);
1802 type_index.encode(sink);
1803 }
1804 Instruction::ArraySet(type_index) => {
1805 sink.push(0xfb);
1806 sink.push(0x0e);
1807 type_index.encode(sink);
1808 }
1809 Instruction::ArrayLen => {
1810 sink.push(0xfb);
1811 sink.push(0x0f);
1812 }
1813 Instruction::ArrayFill(type_index) => {
1814 sink.push(0xfb);
1815 sink.push(0x10);
1816 type_index.encode(sink);
1817 }
1818 Instruction::ArrayCopy {
1819 array_type_index_dst,
1820 array_type_index_src,
1821 } => {
1822 sink.push(0xfb);
1823 sink.push(0x11);
1824 array_type_index_dst.encode(sink);
1825 array_type_index_src.encode(sink);
1826 }
1827 Instruction::ArrayInitData {
1828 array_type_index,
1829 array_data_index,
1830 } => {
1831 sink.push(0xfb);
1832 sink.push(0x12);
1833 array_type_index.encode(sink);
1834 array_data_index.encode(sink);
1835 }
1836 Instruction::ArrayInitElem {
1837 array_type_index,
1838 array_elem_index,
1839 } => {
1840 sink.push(0xfb);
1841 sink.push(0x13);
1842 array_type_index.encode(sink);
1843 array_elem_index.encode(sink);
1844 }
1845 Instruction::RefTestNonNull(heap_type) => {
1846 sink.push(0xfb);
1847 sink.push(0x14);
1848 heap_type.encode(sink);
1849 }
1850 Instruction::RefTestNullable(heap_type) => {
1851 sink.push(0xfb);
1852 sink.push(0x15);
1853 heap_type.encode(sink);
1854 }
1855 Instruction::RefCastNonNull(heap_type) => {
1856 sink.push(0xfb);
1857 sink.push(0x16);
1858 heap_type.encode(sink);
1859 }
1860 Instruction::RefCastNullable(heap_type) => {
1861 sink.push(0xfb);
1862 sink.push(0x17);
1863 heap_type.encode(sink);
1864 }
1865 Instruction::BrOnCast {
1866 relative_depth,
1867 from_ref_type,
1868 to_ref_type,
1869 } => {
1870 sink.push(0xfb);
1871 sink.push(0x18);
1872 let cast_flags =
1873 (from_ref_type.nullable as u8) | ((to_ref_type.nullable as u8) << 1);
1874 sink.push(cast_flags);
1875 relative_depth.encode(sink);
1876 from_ref_type.heap_type.encode(sink);
1877 to_ref_type.heap_type.encode(sink);
1878 }
1879 Instruction::BrOnCastFail {
1880 relative_depth,
1881 from_ref_type,
1882 to_ref_type,
1883 } => {
1884 sink.push(0xfb);
1885 sink.push(0x19);
1886 let cast_flags =
1887 (from_ref_type.nullable as u8) | ((to_ref_type.nullable as u8) << 1);
1888 sink.push(cast_flags);
1889 relative_depth.encode(sink);
1890 from_ref_type.heap_type.encode(sink);
1891 to_ref_type.heap_type.encode(sink);
1892 }
1893 Instruction::AnyConvertExtern => {
1894 sink.push(0xfb);
1895 sink.push(0x1a);
1896 }
1897 Instruction::ExternConvertAny => {
1898 sink.push(0xfb);
1899 sink.push(0x1b);
1900 }
1901 Instruction::RefI31 => {
1902 sink.push(0xfb);
1903 sink.push(0x1c);
1904 }
1905 Instruction::I31GetS => {
1906 sink.push(0xfb);
1907 sink.push(0x1d);
1908 }
1909 Instruction::I31GetU => {
1910 sink.push(0xfb);
1911 sink.push(0x1e);
1912 }
1913
1914 // Bulk memory instructions.
1915 Instruction::TableInit { elem_index, table } => {
1916 sink.push(0xfc);
1917 sink.push(0x0c);
1918 elem_index.encode(sink);
1919 table.encode(sink);
1920 }
1921 Instruction::ElemDrop(segment) => {
1922 sink.push(0xfc);
1923 sink.push(0x0d);
1924 segment.encode(sink);
1925 }
1926 Instruction::TableCopy {
1927 src_table,
1928 dst_table,
1929 } => {
1930 sink.push(0xfc);
1931 sink.push(0x0e);
1932 dst_table.encode(sink);
1933 src_table.encode(sink);
1934 }
1935 Instruction::TableGrow(table) => {
1936 sink.push(0xfc);
1937 sink.push(0x0f);
1938 table.encode(sink);
1939 }
1940 Instruction::TableSize(table) => {
1941 sink.push(0xfc);
1942 sink.push(0x10);
1943 table.encode(sink);
1944 }
1945 Instruction::TableFill(table) => {
1946 sink.push(0xfc);
1947 sink.push(0x11);
1948 table.encode(sink);
1949 }
1950
1951 // SIMD instructions.
1952 Instruction::V128Load(memarg) => {
1953 sink.push(0xFD);
1954 0x00u32.encode(sink);
1955 memarg.encode(sink);
1956 }
1957 Instruction::V128Load8x8S(memarg) => {
1958 sink.push(0xFD);
1959 0x01u32.encode(sink);
1960 memarg.encode(sink);
1961 }
1962 Instruction::V128Load8x8U(memarg) => {
1963 sink.push(0xFD);
1964 0x02u32.encode(sink);
1965 memarg.encode(sink);
1966 }
1967 Instruction::V128Load16x4S(memarg) => {
1968 sink.push(0xFD);
1969 0x03u32.encode(sink);
1970 memarg.encode(sink);
1971 }
1972 Instruction::V128Load16x4U(memarg) => {
1973 sink.push(0xFD);
1974 0x04u32.encode(sink);
1975 memarg.encode(sink);
1976 }
1977 Instruction::V128Load32x2S(memarg) => {
1978 sink.push(0xFD);
1979 0x05u32.encode(sink);
1980 memarg.encode(sink);
1981 }
1982 Instruction::V128Load32x2U(memarg) => {
1983 sink.push(0xFD);
1984 0x06u32.encode(sink);
1985 memarg.encode(sink);
1986 }
1987 Instruction::V128Load8Splat(memarg) => {
1988 sink.push(0xFD);
1989 0x07u32.encode(sink);
1990 memarg.encode(sink);
1991 }
1992 Instruction::V128Load16Splat(memarg) => {
1993 sink.push(0xFD);
1994 0x08u32.encode(sink);
1995 memarg.encode(sink);
1996 }
1997 Instruction::V128Load32Splat(memarg) => {
1998 sink.push(0xFD);
1999 0x09u32.encode(sink);
2000 memarg.encode(sink);
2001 }
2002 Instruction::V128Load64Splat(memarg) => {
2003 sink.push(0xFD);
2004 0x0Au32.encode(sink);
2005 memarg.encode(sink);
2006 }
2007 Instruction::V128Store(memarg) => {
2008 sink.push(0xFD);
2009 0x0Bu32.encode(sink);
2010 memarg.encode(sink);
2011 }
2012 Instruction::V128Const(x) => {
2013 sink.push(0xFD);
2014 0x0Cu32.encode(sink);
2015 sink.extend(x.to_le_bytes().iter().copied());
2016 }
2017 Instruction::I8x16Shuffle(lanes) => {
2018 sink.push(0xFD);
2019 0x0Du32.encode(sink);
2020 assert!(lanes.iter().all(|l: &u8| *l < 32));
2021 sink.extend(lanes.iter().copied());
2022 }
2023 Instruction::I8x16Swizzle => {
2024 sink.push(0xFD);
2025 0x0Eu32.encode(sink);
2026 }
2027 Instruction::I8x16Splat => {
2028 sink.push(0xFD);
2029 0x0Fu32.encode(sink);
2030 }
2031 Instruction::I16x8Splat => {
2032 sink.push(0xFD);
2033 0x10u32.encode(sink);
2034 }
2035 Instruction::I32x4Splat => {
2036 sink.push(0xFD);
2037 0x11u32.encode(sink);
2038 }
2039 Instruction::I64x2Splat => {
2040 sink.push(0xFD);
2041 0x12u32.encode(sink);
2042 }
2043 Instruction::F32x4Splat => {
2044 sink.push(0xFD);
2045 0x13u32.encode(sink);
2046 }
2047 Instruction::F64x2Splat => {
2048 sink.push(0xFD);
2049 0x14u32.encode(sink);
2050 }
2051 Instruction::I8x16ExtractLaneS(lane) => {
2052 sink.push(0xFD);
2053 0x15u32.encode(sink);
2054 assert!(lane < 16);
2055 sink.push(lane);
2056 }
2057 Instruction::I8x16ExtractLaneU(lane) => {
2058 sink.push(0xFD);
2059 0x16u32.encode(sink);
2060 assert!(lane < 16);
2061 sink.push(lane);
2062 }
2063 Instruction::I8x16ReplaceLane(lane) => {
2064 sink.push(0xFD);
2065 0x17u32.encode(sink);
2066 assert!(lane < 16);
2067 sink.push(lane);
2068 }
2069 Instruction::I16x8ExtractLaneS(lane) => {
2070 sink.push(0xFD);
2071 0x18u32.encode(sink);
2072 assert!(lane < 8);
2073 sink.push(lane);
2074 }
2075 Instruction::I16x8ExtractLaneU(lane) => {
2076 sink.push(0xFD);
2077 0x19u32.encode(sink);
2078 assert!(lane < 8);
2079 sink.push(lane);
2080 }
2081 Instruction::I16x8ReplaceLane(lane) => {
2082 sink.push(0xFD);
2083 0x1Au32.encode(sink);
2084 assert!(lane < 8);
2085 sink.push(lane);
2086 }
2087 Instruction::I32x4ExtractLane(lane) => {
2088 sink.push(0xFD);
2089 0x1Bu32.encode(sink);
2090 assert!(lane < 4);
2091 sink.push(lane);
2092 }
2093 Instruction::I32x4ReplaceLane(lane) => {
2094 sink.push(0xFD);
2095 0x1Cu32.encode(sink);
2096 assert!(lane < 4);
2097 sink.push(lane);
2098 }
2099 Instruction::I64x2ExtractLane(lane) => {
2100 sink.push(0xFD);
2101 0x1Du32.encode(sink);
2102 assert!(lane < 2);
2103 sink.push(lane);
2104 }
2105 Instruction::I64x2ReplaceLane(lane) => {
2106 sink.push(0xFD);
2107 0x1Eu32.encode(sink);
2108 assert!(lane < 2);
2109 sink.push(lane);
2110 }
2111 Instruction::F32x4ExtractLane(lane) => {
2112 sink.push(0xFD);
2113 0x1Fu32.encode(sink);
2114 assert!(lane < 4);
2115 sink.push(lane);
2116 }
2117 Instruction::F32x4ReplaceLane(lane) => {
2118 sink.push(0xFD);
2119 0x20u32.encode(sink);
2120 assert!(lane < 4);
2121 sink.push(lane);
2122 }
2123 Instruction::F64x2ExtractLane(lane) => {
2124 sink.push(0xFD);
2125 0x21u32.encode(sink);
2126 assert!(lane < 2);
2127 sink.push(lane);
2128 }
2129 Instruction::F64x2ReplaceLane(lane) => {
2130 sink.push(0xFD);
2131 0x22u32.encode(sink);
2132 assert!(lane < 2);
2133 sink.push(lane);
2134 }
2135
2136 Instruction::I8x16Eq => {
2137 sink.push(0xFD);
2138 0x23u32.encode(sink);
2139 }
2140 Instruction::I8x16Ne => {
2141 sink.push(0xFD);
2142 0x24u32.encode(sink);
2143 }
2144 Instruction::I8x16LtS => {
2145 sink.push(0xFD);
2146 0x25u32.encode(sink);
2147 }
2148 Instruction::I8x16LtU => {
2149 sink.push(0xFD);
2150 0x26u32.encode(sink);
2151 }
2152 Instruction::I8x16GtS => {
2153 sink.push(0xFD);
2154 0x27u32.encode(sink);
2155 }
2156 Instruction::I8x16GtU => {
2157 sink.push(0xFD);
2158 0x28u32.encode(sink);
2159 }
2160 Instruction::I8x16LeS => {
2161 sink.push(0xFD);
2162 0x29u32.encode(sink);
2163 }
2164 Instruction::I8x16LeU => {
2165 sink.push(0xFD);
2166 0x2Au32.encode(sink);
2167 }
2168 Instruction::I8x16GeS => {
2169 sink.push(0xFD);
2170 0x2Bu32.encode(sink);
2171 }
2172 Instruction::I8x16GeU => {
2173 sink.push(0xFD);
2174 0x2Cu32.encode(sink);
2175 }
2176 Instruction::I16x8Eq => {
2177 sink.push(0xFD);
2178 0x2Du32.encode(sink);
2179 }
2180 Instruction::I16x8Ne => {
2181 sink.push(0xFD);
2182 0x2Eu32.encode(sink);
2183 }
2184 Instruction::I16x8LtS => {
2185 sink.push(0xFD);
2186 0x2Fu32.encode(sink);
2187 }
2188 Instruction::I16x8LtU => {
2189 sink.push(0xFD);
2190 0x30u32.encode(sink);
2191 }
2192 Instruction::I16x8GtS => {
2193 sink.push(0xFD);
2194 0x31u32.encode(sink);
2195 }
2196 Instruction::I16x8GtU => {
2197 sink.push(0xFD);
2198 0x32u32.encode(sink);
2199 }
2200 Instruction::I16x8LeS => {
2201 sink.push(0xFD);
2202 0x33u32.encode(sink);
2203 }
2204 Instruction::I16x8LeU => {
2205 sink.push(0xFD);
2206 0x34u32.encode(sink);
2207 }
2208 Instruction::I16x8GeS => {
2209 sink.push(0xFD);
2210 0x35u32.encode(sink);
2211 }
2212 Instruction::I16x8GeU => {
2213 sink.push(0xFD);
2214 0x36u32.encode(sink);
2215 }
2216 Instruction::I32x4Eq => {
2217 sink.push(0xFD);
2218 0x37u32.encode(sink);
2219 }
2220 Instruction::I32x4Ne => {
2221 sink.push(0xFD);
2222 0x38u32.encode(sink);
2223 }
2224 Instruction::I32x4LtS => {
2225 sink.push(0xFD);
2226 0x39u32.encode(sink);
2227 }
2228 Instruction::I32x4LtU => {
2229 sink.push(0xFD);
2230 0x3Au32.encode(sink);
2231 }
2232 Instruction::I32x4GtS => {
2233 sink.push(0xFD);
2234 0x3Bu32.encode(sink);
2235 }
2236 Instruction::I32x4GtU => {
2237 sink.push(0xFD);
2238 0x3Cu32.encode(sink);
2239 }
2240 Instruction::I32x4LeS => {
2241 sink.push(0xFD);
2242 0x3Du32.encode(sink);
2243 }
2244 Instruction::I32x4LeU => {
2245 sink.push(0xFD);
2246 0x3Eu32.encode(sink);
2247 }
2248 Instruction::I32x4GeS => {
2249 sink.push(0xFD);
2250 0x3Fu32.encode(sink);
2251 }
2252 Instruction::I32x4GeU => {
2253 sink.push(0xFD);
2254 0x40u32.encode(sink);
2255 }
2256 Instruction::F32x4Eq => {
2257 sink.push(0xFD);
2258 0x41u32.encode(sink);
2259 }
2260 Instruction::F32x4Ne => {
2261 sink.push(0xFD);
2262 0x42u32.encode(sink);
2263 }
2264 Instruction::F32x4Lt => {
2265 sink.push(0xFD);
2266 0x43u32.encode(sink);
2267 }
2268 Instruction::F32x4Gt => {
2269 sink.push(0xFD);
2270 0x44u32.encode(sink);
2271 }
2272 Instruction::F32x4Le => {
2273 sink.push(0xFD);
2274 0x45u32.encode(sink);
2275 }
2276 Instruction::F32x4Ge => {
2277 sink.push(0xFD);
2278 0x46u32.encode(sink);
2279 }
2280 Instruction::F64x2Eq => {
2281 sink.push(0xFD);
2282 0x47u32.encode(sink);
2283 }
2284 Instruction::F64x2Ne => {
2285 sink.push(0xFD);
2286 0x48u32.encode(sink);
2287 }
2288 Instruction::F64x2Lt => {
2289 sink.push(0xFD);
2290 0x49u32.encode(sink);
2291 }
2292 Instruction::F64x2Gt => {
2293 sink.push(0xFD);
2294 0x4Au32.encode(sink);
2295 }
2296 Instruction::F64x2Le => {
2297 sink.push(0xFD);
2298 0x4Bu32.encode(sink);
2299 }
2300 Instruction::F64x2Ge => {
2301 sink.push(0xFD);
2302 0x4Cu32.encode(sink);
2303 }
2304 Instruction::V128Not => {
2305 sink.push(0xFD);
2306 0x4Du32.encode(sink);
2307 }
2308 Instruction::V128And => {
2309 sink.push(0xFD);
2310 0x4Eu32.encode(sink);
2311 }
2312 Instruction::V128AndNot => {
2313 sink.push(0xFD);
2314 0x4Fu32.encode(sink);
2315 }
2316 Instruction::V128Or => {
2317 sink.push(0xFD);
2318 0x50u32.encode(sink);
2319 }
2320 Instruction::V128Xor => {
2321 sink.push(0xFD);
2322 0x51u32.encode(sink);
2323 }
2324 Instruction::V128Bitselect => {
2325 sink.push(0xFD);
2326 0x52u32.encode(sink);
2327 }
2328 Instruction::V128AnyTrue => {
2329 sink.push(0xFD);
2330 0x53u32.encode(sink);
2331 }
2332 Instruction::I8x16Abs => {
2333 sink.push(0xFD);
2334 0x60u32.encode(sink);
2335 }
2336 Instruction::I8x16Neg => {
2337 sink.push(0xFD);
2338 0x61u32.encode(sink);
2339 }
2340 Instruction::I8x16Popcnt => {
2341 sink.push(0xFD);
2342 0x62u32.encode(sink);
2343 }
2344 Instruction::I8x16AllTrue => {
2345 sink.push(0xFD);
2346 0x63u32.encode(sink);
2347 }
2348 Instruction::I8x16Bitmask => {
2349 sink.push(0xFD);
2350 0x64u32.encode(sink);
2351 }
2352 Instruction::I8x16NarrowI16x8S => {
2353 sink.push(0xFD);
2354 0x65u32.encode(sink);
2355 }
2356 Instruction::I8x16NarrowI16x8U => {
2357 sink.push(0xFD);
2358 0x66u32.encode(sink);
2359 }
2360 Instruction::I8x16Shl => {
2361 sink.push(0xFD);
2362 0x6bu32.encode(sink);
2363 }
2364 Instruction::I8x16ShrS => {
2365 sink.push(0xFD);
2366 0x6cu32.encode(sink);
2367 }
2368 Instruction::I8x16ShrU => {
2369 sink.push(0xFD);
2370 0x6du32.encode(sink);
2371 }
2372 Instruction::I8x16Add => {
2373 sink.push(0xFD);
2374 0x6eu32.encode(sink);
2375 }
2376 Instruction::I8x16AddSatS => {
2377 sink.push(0xFD);
2378 0x6fu32.encode(sink);
2379 }
2380 Instruction::I8x16AddSatU => {
2381 sink.push(0xFD);
2382 0x70u32.encode(sink);
2383 }
2384 Instruction::I8x16Sub => {
2385 sink.push(0xFD);
2386 0x71u32.encode(sink);
2387 }
2388 Instruction::I8x16SubSatS => {
2389 sink.push(0xFD);
2390 0x72u32.encode(sink);
2391 }
2392 Instruction::I8x16SubSatU => {
2393 sink.push(0xFD);
2394 0x73u32.encode(sink);
2395 }
2396 Instruction::I8x16MinS => {
2397 sink.push(0xFD);
2398 0x76u32.encode(sink);
2399 }
2400 Instruction::I8x16MinU => {
2401 sink.push(0xFD);
2402 0x77u32.encode(sink);
2403 }
2404 Instruction::I8x16MaxS => {
2405 sink.push(0xFD);
2406 0x78u32.encode(sink);
2407 }
2408 Instruction::I8x16MaxU => {
2409 sink.push(0xFD);
2410 0x79u32.encode(sink);
2411 }
2412 Instruction::I8x16AvgrU => {
2413 sink.push(0xFD);
2414 0x7Bu32.encode(sink);
2415 }
2416 Instruction::I16x8ExtAddPairwiseI8x16S => {
2417 sink.push(0xFD);
2418 0x7Cu32.encode(sink);
2419 }
2420 Instruction::I16x8ExtAddPairwiseI8x16U => {
2421 sink.push(0xFD);
2422 0x7Du32.encode(sink);
2423 }
2424 Instruction::I32x4ExtAddPairwiseI16x8S => {
2425 sink.push(0xFD);
2426 0x7Eu32.encode(sink);
2427 }
2428 Instruction::I32x4ExtAddPairwiseI16x8U => {
2429 sink.push(0xFD);
2430 0x7Fu32.encode(sink);
2431 }
2432 Instruction::I16x8Abs => {
2433 sink.push(0xFD);
2434 0x80u32.encode(sink);
2435 }
2436 Instruction::I16x8Neg => {
2437 sink.push(0xFD);
2438 0x81u32.encode(sink);
2439 }
2440 Instruction::I16x8Q15MulrSatS => {
2441 sink.push(0xFD);
2442 0x82u32.encode(sink);
2443 }
2444 Instruction::I16x8AllTrue => {
2445 sink.push(0xFD);
2446 0x83u32.encode(sink);
2447 }
2448 Instruction::I16x8Bitmask => {
2449 sink.push(0xFD);
2450 0x84u32.encode(sink);
2451 }
2452 Instruction::I16x8NarrowI32x4S => {
2453 sink.push(0xFD);
2454 0x85u32.encode(sink);
2455 }
2456 Instruction::I16x8NarrowI32x4U => {
2457 sink.push(0xFD);
2458 0x86u32.encode(sink);
2459 }
2460 Instruction::I16x8ExtendLowI8x16S => {
2461 sink.push(0xFD);
2462 0x87u32.encode(sink);
2463 }
2464 Instruction::I16x8ExtendHighI8x16S => {
2465 sink.push(0xFD);
2466 0x88u32.encode(sink);
2467 }
2468 Instruction::I16x8ExtendLowI8x16U => {
2469 sink.push(0xFD);
2470 0x89u32.encode(sink);
2471 }
2472 Instruction::I16x8ExtendHighI8x16U => {
2473 sink.push(0xFD);
2474 0x8Au32.encode(sink);
2475 }
2476 Instruction::I16x8Shl => {
2477 sink.push(0xFD);
2478 0x8Bu32.encode(sink);
2479 }
2480 Instruction::I16x8ShrS => {
2481 sink.push(0xFD);
2482 0x8Cu32.encode(sink);
2483 }
2484 Instruction::I16x8ShrU => {
2485 sink.push(0xFD);
2486 0x8Du32.encode(sink);
2487 }
2488 Instruction::I16x8Add => {
2489 sink.push(0xFD);
2490 0x8Eu32.encode(sink);
2491 }
2492 Instruction::I16x8AddSatS => {
2493 sink.push(0xFD);
2494 0x8Fu32.encode(sink);
2495 }
2496 Instruction::I16x8AddSatU => {
2497 sink.push(0xFD);
2498 0x90u32.encode(sink);
2499 }
2500 Instruction::I16x8Sub => {
2501 sink.push(0xFD);
2502 0x91u32.encode(sink);
2503 }
2504 Instruction::I16x8SubSatS => {
2505 sink.push(0xFD);
2506 0x92u32.encode(sink);
2507 }
2508 Instruction::I16x8SubSatU => {
2509 sink.push(0xFD);
2510 0x93u32.encode(sink);
2511 }
2512 Instruction::I16x8Mul => {
2513 sink.push(0xFD);
2514 0x95u32.encode(sink);
2515 }
2516 Instruction::I16x8MinS => {
2517 sink.push(0xFD);
2518 0x96u32.encode(sink);
2519 }
2520 Instruction::I16x8MinU => {
2521 sink.push(0xFD);
2522 0x97u32.encode(sink);
2523 }
2524 Instruction::I16x8MaxS => {
2525 sink.push(0xFD);
2526 0x98u32.encode(sink);
2527 }
2528 Instruction::I16x8MaxU => {
2529 sink.push(0xFD);
2530 0x99u32.encode(sink);
2531 }
2532 Instruction::I16x8AvgrU => {
2533 sink.push(0xFD);
2534 0x9Bu32.encode(sink);
2535 }
2536 Instruction::I16x8ExtMulLowI8x16S => {
2537 sink.push(0xFD);
2538 0x9Cu32.encode(sink);
2539 }
2540 Instruction::I16x8ExtMulHighI8x16S => {
2541 sink.push(0xFD);
2542 0x9Du32.encode(sink);
2543 }
2544 Instruction::I16x8ExtMulLowI8x16U => {
2545 sink.push(0xFD);
2546 0x9Eu32.encode(sink);
2547 }
2548 Instruction::I16x8ExtMulHighI8x16U => {
2549 sink.push(0xFD);
2550 0x9Fu32.encode(sink);
2551 }
2552 Instruction::I32x4Abs => {
2553 sink.push(0xFD);
2554 0xA0u32.encode(sink);
2555 }
2556 Instruction::I32x4Neg => {
2557 sink.push(0xFD);
2558 0xA1u32.encode(sink);
2559 }
2560 Instruction::I32x4AllTrue => {
2561 sink.push(0xFD);
2562 0xA3u32.encode(sink);
2563 }
2564 Instruction::I32x4Bitmask => {
2565 sink.push(0xFD);
2566 0xA4u32.encode(sink);
2567 }
2568 Instruction::I32x4ExtendLowI16x8S => {
2569 sink.push(0xFD);
2570 0xA7u32.encode(sink);
2571 }
2572 Instruction::I32x4ExtendHighI16x8S => {
2573 sink.push(0xFD);
2574 0xA8u32.encode(sink);
2575 }
2576 Instruction::I32x4ExtendLowI16x8U => {
2577 sink.push(0xFD);
2578 0xA9u32.encode(sink);
2579 }
2580 Instruction::I32x4ExtendHighI16x8U => {
2581 sink.push(0xFD);
2582 0xAAu32.encode(sink);
2583 }
2584 Instruction::I32x4Shl => {
2585 sink.push(0xFD);
2586 0xABu32.encode(sink);
2587 }
2588 Instruction::I32x4ShrS => {
2589 sink.push(0xFD);
2590 0xACu32.encode(sink);
2591 }
2592 Instruction::I32x4ShrU => {
2593 sink.push(0xFD);
2594 0xADu32.encode(sink);
2595 }
2596 Instruction::I32x4Add => {
2597 sink.push(0xFD);
2598 0xAEu32.encode(sink);
2599 }
2600 Instruction::I32x4Sub => {
2601 sink.push(0xFD);
2602 0xB1u32.encode(sink);
2603 }
2604 Instruction::I32x4Mul => {
2605 sink.push(0xFD);
2606 0xB5u32.encode(sink);
2607 }
2608 Instruction::I32x4MinS => {
2609 sink.push(0xFD);
2610 0xB6u32.encode(sink);
2611 }
2612 Instruction::I32x4MinU => {
2613 sink.push(0xFD);
2614 0xB7u32.encode(sink);
2615 }
2616 Instruction::I32x4MaxS => {
2617 sink.push(0xFD);
2618 0xB8u32.encode(sink);
2619 }
2620 Instruction::I32x4MaxU => {
2621 sink.push(0xFD);
2622 0xB9u32.encode(sink);
2623 }
2624 Instruction::I32x4DotI16x8S => {
2625 sink.push(0xFD);
2626 0xBAu32.encode(sink);
2627 }
2628 Instruction::I32x4ExtMulLowI16x8S => {
2629 sink.push(0xFD);
2630 0xBCu32.encode(sink);
2631 }
2632 Instruction::I32x4ExtMulHighI16x8S => {
2633 sink.push(0xFD);
2634 0xBDu32.encode(sink);
2635 }
2636 Instruction::I32x4ExtMulLowI16x8U => {
2637 sink.push(0xFD);
2638 0xBEu32.encode(sink);
2639 }
2640 Instruction::I32x4ExtMulHighI16x8U => {
2641 sink.push(0xFD);
2642 0xBFu32.encode(sink);
2643 }
2644 Instruction::I64x2Abs => {
2645 sink.push(0xFD);
2646 0xC0u32.encode(sink);
2647 }
2648 Instruction::I64x2Neg => {
2649 sink.push(0xFD);
2650 0xC1u32.encode(sink);
2651 }
2652 Instruction::I64x2AllTrue => {
2653 sink.push(0xFD);
2654 0xC3u32.encode(sink);
2655 }
2656 Instruction::I64x2Bitmask => {
2657 sink.push(0xFD);
2658 0xC4u32.encode(sink);
2659 }
2660 Instruction::I64x2ExtendLowI32x4S => {
2661 sink.push(0xFD);
2662 0xC7u32.encode(sink);
2663 }
2664 Instruction::I64x2ExtendHighI32x4S => {
2665 sink.push(0xFD);
2666 0xC8u32.encode(sink);
2667 }
2668 Instruction::I64x2ExtendLowI32x4U => {
2669 sink.push(0xFD);
2670 0xC9u32.encode(sink);
2671 }
2672 Instruction::I64x2ExtendHighI32x4U => {
2673 sink.push(0xFD);
2674 0xCAu32.encode(sink);
2675 }
2676 Instruction::I64x2Shl => {
2677 sink.push(0xFD);
2678 0xCBu32.encode(sink);
2679 }
2680 Instruction::I64x2ShrS => {
2681 sink.push(0xFD);
2682 0xCCu32.encode(sink);
2683 }
2684 Instruction::I64x2ShrU => {
2685 sink.push(0xFD);
2686 0xCDu32.encode(sink);
2687 }
2688 Instruction::I64x2Add => {
2689 sink.push(0xFD);
2690 0xCEu32.encode(sink);
2691 }
2692 Instruction::I64x2Sub => {
2693 sink.push(0xFD);
2694 0xD1u32.encode(sink);
2695 }
2696 Instruction::I64x2Mul => {
2697 sink.push(0xFD);
2698 0xD5u32.encode(sink);
2699 }
2700 Instruction::I64x2ExtMulLowI32x4S => {
2701 sink.push(0xFD);
2702 0xDCu32.encode(sink);
2703 }
2704 Instruction::I64x2ExtMulHighI32x4S => {
2705 sink.push(0xFD);
2706 0xDDu32.encode(sink);
2707 }
2708 Instruction::I64x2ExtMulLowI32x4U => {
2709 sink.push(0xFD);
2710 0xDEu32.encode(sink);
2711 }
2712 Instruction::I64x2ExtMulHighI32x4U => {
2713 sink.push(0xFD);
2714 0xDFu32.encode(sink);
2715 }
2716 Instruction::F32x4Ceil => {
2717 sink.push(0xFD);
2718 0x67u32.encode(sink);
2719 }
2720 Instruction::F32x4Floor => {
2721 sink.push(0xFD);
2722 0x68u32.encode(sink);
2723 }
2724 Instruction::F32x4Trunc => {
2725 sink.push(0xFD);
2726 0x69u32.encode(sink);
2727 }
2728 Instruction::F32x4Nearest => {
2729 sink.push(0xFD);
2730 0x6Au32.encode(sink);
2731 }
2732 Instruction::F32x4Abs => {
2733 sink.push(0xFD);
2734 0xE0u32.encode(sink);
2735 }
2736 Instruction::F32x4Neg => {
2737 sink.push(0xFD);
2738 0xE1u32.encode(sink);
2739 }
2740 Instruction::F32x4Sqrt => {
2741 sink.push(0xFD);
2742 0xE3u32.encode(sink);
2743 }
2744 Instruction::F32x4Add => {
2745 sink.push(0xFD);
2746 0xE4u32.encode(sink);
2747 }
2748 Instruction::F32x4Sub => {
2749 sink.push(0xFD);
2750 0xE5u32.encode(sink);
2751 }
2752 Instruction::F32x4Mul => {
2753 sink.push(0xFD);
2754 0xE6u32.encode(sink);
2755 }
2756 Instruction::F32x4Div => {
2757 sink.push(0xFD);
2758 0xE7u32.encode(sink);
2759 }
2760 Instruction::F32x4Min => {
2761 sink.push(0xFD);
2762 0xE8u32.encode(sink);
2763 }
2764 Instruction::F32x4Max => {
2765 sink.push(0xFD);
2766 0xE9u32.encode(sink);
2767 }
2768 Instruction::F32x4PMin => {
2769 sink.push(0xFD);
2770 0xEAu32.encode(sink);
2771 }
2772 Instruction::F32x4PMax => {
2773 sink.push(0xFD);
2774 0xEBu32.encode(sink);
2775 }
2776 Instruction::F64x2Ceil => {
2777 sink.push(0xFD);
2778 0x74u32.encode(sink);
2779 }
2780 Instruction::F64x2Floor => {
2781 sink.push(0xFD);
2782 0x75u32.encode(sink);
2783 }
2784 Instruction::F64x2Trunc => {
2785 sink.push(0xFD);
2786 0x7Au32.encode(sink);
2787 }
2788 Instruction::F64x2Nearest => {
2789 sink.push(0xFD);
2790 0x94u32.encode(sink);
2791 }
2792 Instruction::F64x2Abs => {
2793 sink.push(0xFD);
2794 0xECu32.encode(sink);
2795 }
2796 Instruction::F64x2Neg => {
2797 sink.push(0xFD);
2798 0xEDu32.encode(sink);
2799 }
2800 Instruction::F64x2Sqrt => {
2801 sink.push(0xFD);
2802 0xEFu32.encode(sink);
2803 }
2804 Instruction::F64x2Add => {
2805 sink.push(0xFD);
2806 0xF0u32.encode(sink);
2807 }
2808 Instruction::F64x2Sub => {
2809 sink.push(0xFD);
2810 0xF1u32.encode(sink);
2811 }
2812 Instruction::F64x2Mul => {
2813 sink.push(0xFD);
2814 0xF2u32.encode(sink);
2815 }
2816 Instruction::F64x2Div => {
2817 sink.push(0xFD);
2818 0xF3u32.encode(sink);
2819 }
2820 Instruction::F64x2Min => {
2821 sink.push(0xFD);
2822 0xF4u32.encode(sink);
2823 }
2824 Instruction::F64x2Max => {
2825 sink.push(0xFD);
2826 0xF5u32.encode(sink);
2827 }
2828 Instruction::F64x2PMin => {
2829 sink.push(0xFD);
2830 0xF6u32.encode(sink);
2831 }
2832 Instruction::F64x2PMax => {
2833 sink.push(0xFD);
2834 0xF7u32.encode(sink);
2835 }
2836 Instruction::I32x4TruncSatF32x4S => {
2837 sink.push(0xFD);
2838 0xF8u32.encode(sink);
2839 }
2840 Instruction::I32x4TruncSatF32x4U => {
2841 sink.push(0xFD);
2842 0xF9u32.encode(sink);
2843 }
2844 Instruction::F32x4ConvertI32x4S => {
2845 sink.push(0xFD);
2846 0xFAu32.encode(sink);
2847 }
2848 Instruction::F32x4ConvertI32x4U => {
2849 sink.push(0xFD);
2850 0xFBu32.encode(sink);
2851 }
2852 Instruction::I32x4TruncSatF64x2SZero => {
2853 sink.push(0xFD);
2854 0xFCu32.encode(sink);
2855 }
2856 Instruction::I32x4TruncSatF64x2UZero => {
2857 sink.push(0xFD);
2858 0xFDu32.encode(sink);
2859 }
2860 Instruction::F64x2ConvertLowI32x4S => {
2861 sink.push(0xFD);
2862 0xFEu32.encode(sink);
2863 }
2864 Instruction::F64x2ConvertLowI32x4U => {
2865 sink.push(0xFD);
2866 0xFFu32.encode(sink);
2867 }
2868 Instruction::F32x4DemoteF64x2Zero => {
2869 sink.push(0xFD);
2870 0x5Eu32.encode(sink);
2871 }
2872 Instruction::F64x2PromoteLowF32x4 => {
2873 sink.push(0xFD);
2874 0x5Fu32.encode(sink);
2875 }
2876 Instruction::V128Load32Zero(memarg) => {
2877 sink.push(0xFD);
2878 0x5Cu32.encode(sink);
2879 memarg.encode(sink);
2880 }
2881 Instruction::V128Load64Zero(memarg) => {
2882 sink.push(0xFD);
2883 0x5Du32.encode(sink);
2884 memarg.encode(sink);
2885 }
2886 Instruction::V128Load8Lane { memarg, lane } => {
2887 sink.push(0xFD);
2888 0x54u32.encode(sink);
2889 memarg.encode(sink);
2890 assert!(lane < 16);
2891 sink.push(lane);
2892 }
2893 Instruction::V128Load16Lane { memarg, lane } => {
2894 sink.push(0xFD);
2895 0x55u32.encode(sink);
2896 memarg.encode(sink);
2897 assert!(lane < 8);
2898 sink.push(lane);
2899 }
2900 Instruction::V128Load32Lane { memarg, lane } => {
2901 sink.push(0xFD);
2902 0x56u32.encode(sink);
2903 memarg.encode(sink);
2904 assert!(lane < 4);
2905 sink.push(lane);
2906 }
2907 Instruction::V128Load64Lane { memarg, lane } => {
2908 sink.push(0xFD);
2909 0x57u32.encode(sink);
2910 memarg.encode(sink);
2911 assert!(lane < 2);
2912 sink.push(lane);
2913 }
2914 Instruction::V128Store8Lane { memarg, lane } => {
2915 sink.push(0xFD);
2916 0x58u32.encode(sink);
2917 memarg.encode(sink);
2918 assert!(lane < 16);
2919 sink.push(lane);
2920 }
2921 Instruction::V128Store16Lane { memarg, lane } => {
2922 sink.push(0xFD);
2923 0x59u32.encode(sink);
2924 memarg.encode(sink);
2925 assert!(lane < 8);
2926 sink.push(lane);
2927 }
2928 Instruction::V128Store32Lane { memarg, lane } => {
2929 sink.push(0xFD);
2930 0x5Au32.encode(sink);
2931 memarg.encode(sink);
2932 assert!(lane < 4);
2933 sink.push(lane);
2934 }
2935 Instruction::V128Store64Lane { memarg, lane } => {
2936 sink.push(0xFD);
2937 0x5Bu32.encode(sink);
2938 memarg.encode(sink);
2939 assert!(lane < 2);
2940 sink.push(lane);
2941 }
2942 Instruction::I64x2Eq => {
2943 sink.push(0xFD);
2944 0xD6u32.encode(sink);
2945 }
2946 Instruction::I64x2Ne => {
2947 sink.push(0xFD);
2948 0xD7u32.encode(sink);
2949 }
2950 Instruction::I64x2LtS => {
2951 sink.push(0xFD);
2952 0xD8u32.encode(sink);
2953 }
2954 Instruction::I64x2GtS => {
2955 sink.push(0xFD);
2956 0xD9u32.encode(sink);
2957 }
2958 Instruction::I64x2LeS => {
2959 sink.push(0xFD);
2960 0xDAu32.encode(sink);
2961 }
2962 Instruction::I64x2GeS => {
2963 sink.push(0xFD);
2964 0xDBu32.encode(sink);
2965 }
2966 Instruction::I8x16RelaxedSwizzle => {
2967 sink.push(0xFD);
2968 0x100u32.encode(sink);
2969 }
2970 Instruction::I32x4RelaxedTruncF32x4S => {
2971 sink.push(0xFD);
2972 0x101u32.encode(sink);
2973 }
2974 Instruction::I32x4RelaxedTruncF32x4U => {
2975 sink.push(0xFD);
2976 0x102u32.encode(sink);
2977 }
2978 Instruction::I32x4RelaxedTruncF64x2SZero => {
2979 sink.push(0xFD);
2980 0x103u32.encode(sink);
2981 }
2982 Instruction::I32x4RelaxedTruncF64x2UZero => {
2983 sink.push(0xFD);
2984 0x104u32.encode(sink);
2985 }
2986 Instruction::F32x4RelaxedMadd => {
2987 sink.push(0xFD);
2988 0x105u32.encode(sink);
2989 }
2990 Instruction::F32x4RelaxedNmadd => {
2991 sink.push(0xFD);
2992 0x106u32.encode(sink);
2993 }
2994 Instruction::F64x2RelaxedMadd => {
2995 sink.push(0xFD);
2996 0x107u32.encode(sink);
2997 }
2998 Instruction::F64x2RelaxedNmadd => {
2999 sink.push(0xFD);
3000 0x108u32.encode(sink);
3001 }
3002 Instruction::I8x16RelaxedLaneselect => {
3003 sink.push(0xFD);
3004 0x109u32.encode(sink);
3005 }
3006 Instruction::I16x8RelaxedLaneselect => {
3007 sink.push(0xFD);
3008 0x10Au32.encode(sink);
3009 }
3010 Instruction::I32x4RelaxedLaneselect => {
3011 sink.push(0xFD);
3012 0x10Bu32.encode(sink);
3013 }
3014 Instruction::I64x2RelaxedLaneselect => {
3015 sink.push(0xFD);
3016 0x10Cu32.encode(sink);
3017 }
3018 Instruction::F32x4RelaxedMin => {
3019 sink.push(0xFD);
3020 0x10Du32.encode(sink);
3021 }
3022 Instruction::F32x4RelaxedMax => {
3023 sink.push(0xFD);
3024 0x10Eu32.encode(sink);
3025 }
3026 Instruction::F64x2RelaxedMin => {
3027 sink.push(0xFD);
3028 0x10Fu32.encode(sink);
3029 }
3030 Instruction::F64x2RelaxedMax => {
3031 sink.push(0xFD);
3032 0x110u32.encode(sink);
3033 }
3034 Instruction::I16x8RelaxedQ15mulrS => {
3035 sink.push(0xFD);
3036 0x111u32.encode(sink);
3037 }
3038 Instruction::I16x8RelaxedDotI8x16I7x16S => {
3039 sink.push(0xFD);
3040 0x112u32.encode(sink);
3041 }
3042 Instruction::I32x4RelaxedDotI8x16I7x16AddS => {
3043 sink.push(0xFD);
3044 0x113u32.encode(sink);
3045 }
3046
3047 // Atomic instructions from the thread proposal
3048 Instruction::MemoryAtomicNotify(memarg) => {
3049 sink.push(0xFE);
3050 sink.push(0x00);
3051 memarg.encode(sink);
3052 }
3053 Instruction::MemoryAtomicWait32(memarg) => {
3054 sink.push(0xFE);
3055 sink.push(0x01);
3056 memarg.encode(sink);
3057 }
3058 Instruction::MemoryAtomicWait64(memarg) => {
3059 sink.push(0xFE);
3060 sink.push(0x02);
3061 memarg.encode(sink);
3062 }
3063 Instruction::AtomicFence => {
3064 sink.push(0xFE);
3065 sink.push(0x03);
3066 sink.push(0x00);
3067 }
3068 Instruction::I32AtomicLoad(memarg) => {
3069 sink.push(0xFE);
3070 sink.push(0x10);
3071 memarg.encode(sink);
3072 }
3073 Instruction::I64AtomicLoad(memarg) => {
3074 sink.push(0xFE);
3075 sink.push(0x11);
3076 memarg.encode(sink);
3077 }
3078 Instruction::I32AtomicLoad8U(memarg) => {
3079 sink.push(0xFE);
3080 sink.push(0x12);
3081 memarg.encode(sink);
3082 }
3083 Instruction::I32AtomicLoad16U(memarg) => {
3084 sink.push(0xFE);
3085 sink.push(0x13);
3086 memarg.encode(sink);
3087 }
3088 Instruction::I64AtomicLoad8U(memarg) => {
3089 sink.push(0xFE);
3090 sink.push(0x14);
3091 memarg.encode(sink);
3092 }
3093 Instruction::I64AtomicLoad16U(memarg) => {
3094 sink.push(0xFE);
3095 sink.push(0x15);
3096 memarg.encode(sink);
3097 }
3098 Instruction::I64AtomicLoad32U(memarg) => {
3099 sink.push(0xFE);
3100 sink.push(0x16);
3101 memarg.encode(sink);
3102 }
3103 Instruction::I32AtomicStore(memarg) => {
3104 sink.push(0xFE);
3105 sink.push(0x17);
3106 memarg.encode(sink);
3107 }
3108 Instruction::I64AtomicStore(memarg) => {
3109 sink.push(0xFE);
3110 sink.push(0x18);
3111 memarg.encode(sink);
3112 }
3113 Instruction::I32AtomicStore8(memarg) => {
3114 sink.push(0xFE);
3115 sink.push(0x19);
3116 memarg.encode(sink);
3117 }
3118 Instruction::I32AtomicStore16(memarg) => {
3119 sink.push(0xFE);
3120 sink.push(0x1A);
3121 memarg.encode(sink);
3122 }
3123 Instruction::I64AtomicStore8(memarg) => {
3124 sink.push(0xFE);
3125 sink.push(0x1B);
3126 memarg.encode(sink);
3127 }
3128 Instruction::I64AtomicStore16(memarg) => {
3129 sink.push(0xFE);
3130 sink.push(0x1C);
3131 memarg.encode(sink);
3132 }
3133 Instruction::I64AtomicStore32(memarg) => {
3134 sink.push(0xFE);
3135 sink.push(0x1D);
3136 memarg.encode(sink);
3137 }
3138 Instruction::I32AtomicRmwAdd(memarg) => {
3139 sink.push(0xFE);
3140 sink.push(0x1E);
3141 memarg.encode(sink);
3142 }
3143 Instruction::I64AtomicRmwAdd(memarg) => {
3144 sink.push(0xFE);
3145 sink.push(0x1F);
3146 memarg.encode(sink);
3147 }
3148 Instruction::I32AtomicRmw8AddU(memarg) => {
3149 sink.push(0xFE);
3150 sink.push(0x20);
3151 memarg.encode(sink);
3152 }
3153 Instruction::I32AtomicRmw16AddU(memarg) => {
3154 sink.push(0xFE);
3155 sink.push(0x21);
3156 memarg.encode(sink);
3157 }
3158 Instruction::I64AtomicRmw8AddU(memarg) => {
3159 sink.push(0xFE);
3160 sink.push(0x22);
3161 memarg.encode(sink);
3162 }
3163 Instruction::I64AtomicRmw16AddU(memarg) => {
3164 sink.push(0xFE);
3165 sink.push(0x23);
3166 memarg.encode(sink);
3167 }
3168 Instruction::I64AtomicRmw32AddU(memarg) => {
3169 sink.push(0xFE);
3170 sink.push(0x24);
3171 memarg.encode(sink);
3172 }
3173 Instruction::I32AtomicRmwSub(memarg) => {
3174 sink.push(0xFE);
3175 sink.push(0x25);
3176 memarg.encode(sink);
3177 }
3178 Instruction::I64AtomicRmwSub(memarg) => {
3179 sink.push(0xFE);
3180 sink.push(0x26);
3181 memarg.encode(sink);
3182 }
3183 Instruction::I32AtomicRmw8SubU(memarg) => {
3184 sink.push(0xFE);
3185 sink.push(0x27);
3186 memarg.encode(sink);
3187 }
3188 Instruction::I32AtomicRmw16SubU(memarg) => {
3189 sink.push(0xFE);
3190 sink.push(0x28);
3191 memarg.encode(sink);
3192 }
3193 Instruction::I64AtomicRmw8SubU(memarg) => {
3194 sink.push(0xFE);
3195 sink.push(0x29);
3196 memarg.encode(sink);
3197 }
3198 Instruction::I64AtomicRmw16SubU(memarg) => {
3199 sink.push(0xFE);
3200 sink.push(0x2A);
3201 memarg.encode(sink);
3202 }
3203 Instruction::I64AtomicRmw32SubU(memarg) => {
3204 sink.push(0xFE);
3205 sink.push(0x2B);
3206 memarg.encode(sink);
3207 }
3208 Instruction::I32AtomicRmwAnd(memarg) => {
3209 sink.push(0xFE);
3210 sink.push(0x2C);
3211 memarg.encode(sink);
3212 }
3213 Instruction::I64AtomicRmwAnd(memarg) => {
3214 sink.push(0xFE);
3215 sink.push(0x2D);
3216 memarg.encode(sink);
3217 }
3218 Instruction::I32AtomicRmw8AndU(memarg) => {
3219 sink.push(0xFE);
3220 sink.push(0x2E);
3221 memarg.encode(sink);
3222 }
3223 Instruction::I32AtomicRmw16AndU(memarg) => {
3224 sink.push(0xFE);
3225 sink.push(0x2F);
3226 memarg.encode(sink);
3227 }
3228 Instruction::I64AtomicRmw8AndU(memarg) => {
3229 sink.push(0xFE);
3230 sink.push(0x30);
3231 memarg.encode(sink);
3232 }
3233 Instruction::I64AtomicRmw16AndU(memarg) => {
3234 sink.push(0xFE);
3235 sink.push(0x31);
3236 memarg.encode(sink);
3237 }
3238 Instruction::I64AtomicRmw32AndU(memarg) => {
3239 sink.push(0xFE);
3240 sink.push(0x32);
3241 memarg.encode(sink);
3242 }
3243 Instruction::I32AtomicRmwOr(memarg) => {
3244 sink.push(0xFE);
3245 sink.push(0x33);
3246 memarg.encode(sink);
3247 }
3248 Instruction::I64AtomicRmwOr(memarg) => {
3249 sink.push(0xFE);
3250 sink.push(0x34);
3251 memarg.encode(sink);
3252 }
3253 Instruction::I32AtomicRmw8OrU(memarg) => {
3254 sink.push(0xFE);
3255 sink.push(0x35);
3256 memarg.encode(sink);
3257 }
3258 Instruction::I32AtomicRmw16OrU(memarg) => {
3259 sink.push(0xFE);
3260 sink.push(0x36);
3261 memarg.encode(sink);
3262 }
3263 Instruction::I64AtomicRmw8OrU(memarg) => {
3264 sink.push(0xFE);
3265 sink.push(0x37);
3266 memarg.encode(sink);
3267 }
3268 Instruction::I64AtomicRmw16OrU(memarg) => {
3269 sink.push(0xFE);
3270 sink.push(0x38);
3271 memarg.encode(sink);
3272 }
3273 Instruction::I64AtomicRmw32OrU(memarg) => {
3274 sink.push(0xFE);
3275 sink.push(0x39);
3276 memarg.encode(sink);
3277 }
3278 Instruction::I32AtomicRmwXor(memarg) => {
3279 sink.push(0xFE);
3280 sink.push(0x3A);
3281 memarg.encode(sink);
3282 }
3283 Instruction::I64AtomicRmwXor(memarg) => {
3284 sink.push(0xFE);
3285 sink.push(0x3B);
3286 memarg.encode(sink);
3287 }
3288 Instruction::I32AtomicRmw8XorU(memarg) => {
3289 sink.push(0xFE);
3290 sink.push(0x3C);
3291 memarg.encode(sink);
3292 }
3293 Instruction::I32AtomicRmw16XorU(memarg) => {
3294 sink.push(0xFE);
3295 sink.push(0x3D);
3296 memarg.encode(sink);
3297 }
3298 Instruction::I64AtomicRmw8XorU(memarg) => {
3299 sink.push(0xFE);
3300 sink.push(0x3E);
3301 memarg.encode(sink);
3302 }
3303 Instruction::I64AtomicRmw16XorU(memarg) => {
3304 sink.push(0xFE);
3305 sink.push(0x3F);
3306 memarg.encode(sink);
3307 }
3308 Instruction::I64AtomicRmw32XorU(memarg) => {
3309 sink.push(0xFE);
3310 sink.push(0x40);
3311 memarg.encode(sink);
3312 }
3313 Instruction::I32AtomicRmwXchg(memarg) => {
3314 sink.push(0xFE);
3315 sink.push(0x41);
3316 memarg.encode(sink);
3317 }
3318 Instruction::I64AtomicRmwXchg(memarg) => {
3319 sink.push(0xFE);
3320 sink.push(0x42);
3321 memarg.encode(sink);
3322 }
3323 Instruction::I32AtomicRmw8XchgU(memarg) => {
3324 sink.push(0xFE);
3325 sink.push(0x43);
3326 memarg.encode(sink);
3327 }
3328 Instruction::I32AtomicRmw16XchgU(memarg) => {
3329 sink.push(0xFE);
3330 sink.push(0x44);
3331 memarg.encode(sink);
3332 }
3333 Instruction::I64AtomicRmw8XchgU(memarg) => {
3334 sink.push(0xFE);
3335 sink.push(0x45);
3336 memarg.encode(sink);
3337 }
3338 Instruction::I64AtomicRmw16XchgU(memarg) => {
3339 sink.push(0xFE);
3340 sink.push(0x46);
3341 memarg.encode(sink);
3342 }
3343 Instruction::I64AtomicRmw32XchgU(memarg) => {
3344 sink.push(0xFE);
3345 sink.push(0x47);
3346 memarg.encode(sink);
3347 }
3348 Instruction::I32AtomicRmwCmpxchg(memarg) => {
3349 sink.push(0xFE);
3350 sink.push(0x48);
3351 memarg.encode(sink);
3352 }
3353 Instruction::I64AtomicRmwCmpxchg(memarg) => {
3354 sink.push(0xFE);
3355 sink.push(0x49);
3356 memarg.encode(sink);
3357 }
3358 Instruction::I32AtomicRmw8CmpxchgU(memarg) => {
3359 sink.push(0xFE);
3360 sink.push(0x4A);
3361 memarg.encode(sink);
3362 }
3363 Instruction::I32AtomicRmw16CmpxchgU(memarg) => {
3364 sink.push(0xFE);
3365 sink.push(0x4B);
3366 memarg.encode(sink);
3367 }
3368 Instruction::I64AtomicRmw8CmpxchgU(memarg) => {
3369 sink.push(0xFE);
3370 sink.push(0x4C);
3371 memarg.encode(sink);
3372 }
3373 Instruction::I64AtomicRmw16CmpxchgU(memarg) => {
3374 sink.push(0xFE);
3375 sink.push(0x4D);
3376 memarg.encode(sink);
3377 }
3378 Instruction::I64AtomicRmw32CmpxchgU(memarg) => {
3379 sink.push(0xFE);
3380 sink.push(0x4E);
3381 memarg.encode(sink);
3382 }
3383
3384 // Atomic instructions from the shared-everything-threads proposal
3385 Instruction::GlobalAtomicGet {
3386 ordering,
3387 global_index,
3388 } => {
3389 sink.push(0xFE);
3390 sink.push(0x4F);
3391 ordering.encode(sink);
3392 global_index.encode(sink);
3393 }
3394 Instruction::GlobalAtomicSet {
3395 ordering,
3396 global_index,
3397 } => {
3398 sink.push(0xFE);
3399 sink.push(0x50);
3400 ordering.encode(sink);
3401 global_index.encode(sink);
3402 }
3403 Instruction::GlobalAtomicRmwAdd {
3404 ordering,
3405 global_index,
3406 } => {
3407 sink.push(0xFE);
3408 sink.push(0x51);
3409 ordering.encode(sink);
3410 global_index.encode(sink);
3411 }
3412 Instruction::GlobalAtomicRmwSub {
3413 ordering,
3414 global_index,
3415 } => {
3416 sink.push(0xFE);
3417 sink.push(0x52);
3418 ordering.encode(sink);
3419 global_index.encode(sink);
3420 }
3421 Instruction::GlobalAtomicRmwAnd {
3422 ordering,
3423 global_index,
3424 } => {
3425 sink.push(0xFE);
3426 sink.push(0x53);
3427 ordering.encode(sink);
3428 global_index.encode(sink);
3429 }
3430 Instruction::GlobalAtomicRmwOr {
3431 ordering,
3432 global_index,
3433 } => {
3434 sink.push(0xFE);
3435 sink.push(0x54);
3436 ordering.encode(sink);
3437 global_index.encode(sink);
3438 }
3439 Instruction::GlobalAtomicRmwXor {
3440 ordering,
3441 global_index,
3442 } => {
3443 sink.push(0xFE);
3444 sink.push(0x55);
3445 ordering.encode(sink);
3446 global_index.encode(sink);
3447 }
3448 Instruction::GlobalAtomicRmwXchg {
3449 ordering,
3450 global_index,
3451 } => {
3452 sink.push(0xFE);
3453 sink.push(0x56);
3454 ordering.encode(sink);
3455 global_index.encode(sink);
3456 }
3457 Instruction::GlobalAtomicRmwCmpxchg {
3458 ordering,
3459 global_index,
3460 } => {
3461 sink.push(0xFE);
3462 sink.push(0x57);
3463 ordering.encode(sink);
3464 global_index.encode(sink);
3465 }
3466 Instruction::TableAtomicGet {
3467 ordering,
3468 table_index,
3469 } => {
3470 sink.push(0xFE);
3471 sink.push(0x58);
3472 ordering.encode(sink);
3473 table_index.encode(sink);
3474 }
3475 Instruction::TableAtomicSet {
3476 ordering,
3477 table_index,
3478 } => {
3479 sink.push(0xFE);
3480 sink.push(0x59);
3481 ordering.encode(sink);
3482 table_index.encode(sink);
3483 }
3484 Instruction::TableAtomicRmwXchg {
3485 ordering,
3486 table_index,
3487 } => {
3488 sink.push(0xFE);
3489 sink.push(0x5A);
3490 ordering.encode(sink);
3491 table_index.encode(sink);
3492 }
3493 Instruction::TableAtomicRmwCmpxchg {
3494 ordering,
3495 table_index,
3496 } => {
3497 sink.push(0xFE);
3498 sink.push(0x5B);
3499 ordering.encode(sink);
3500 table_index.encode(sink);
3501 }
3502 Instruction::StructAtomicGet {
3503 ordering,
3504 struct_type_index,
3505 field_index,
3506 } => {
3507 sink.push(0xFE);
3508 sink.push(0x5C);
3509 ordering.encode(sink);
3510 struct_type_index.encode(sink);
3511 field_index.encode(sink);
3512 }
3513 Instruction::StructAtomicGetS {
3514 ordering,
3515 struct_type_index,
3516 field_index,
3517 } => {
3518 sink.push(0xFE);
3519 sink.push(0x5D);
3520 ordering.encode(sink);
3521 struct_type_index.encode(sink);
3522 field_index.encode(sink);
3523 }
3524 Instruction::StructAtomicGetU {
3525 ordering,
3526 struct_type_index,
3527 field_index,
3528 } => {
3529 sink.push(0xFE);
3530 sink.push(0x5E);
3531 ordering.encode(sink);
3532 struct_type_index.encode(sink);
3533 field_index.encode(sink);
3534 }
3535 Instruction::StructAtomicSet {
3536 ordering,
3537 struct_type_index,
3538 field_index,
3539 } => {
3540 sink.push(0xFE);
3541 sink.push(0x5F);
3542 ordering.encode(sink);
3543 struct_type_index.encode(sink);
3544 field_index.encode(sink);
3545 }
3546 Instruction::StructAtomicRmwAdd {
3547 ordering,
3548 struct_type_index,
3549 field_index,
3550 } => {
3551 sink.push(0xFE);
3552 sink.push(0x60);
3553 ordering.encode(sink);
3554 struct_type_index.encode(sink);
3555 field_index.encode(sink);
3556 }
3557 Instruction::StructAtomicRmwSub {
3558 ordering,
3559 struct_type_index,
3560 field_index,
3561 } => {
3562 sink.push(0xFE);
3563 sink.push(0x61);
3564 ordering.encode(sink);
3565 struct_type_index.encode(sink);
3566 field_index.encode(sink);
3567 }
3568 Instruction::StructAtomicRmwAnd {
3569 ordering,
3570 struct_type_index,
3571 field_index,
3572 } => {
3573 sink.push(0xFE);
3574 sink.push(0x62);
3575 ordering.encode(sink);
3576 struct_type_index.encode(sink);
3577 field_index.encode(sink);
3578 }
3579 Instruction::StructAtomicRmwOr {
3580 ordering,
3581 struct_type_index,
3582 field_index,
3583 } => {
3584 sink.push(0xFE);
3585 sink.push(0x63);
3586 ordering.encode(sink);
3587 struct_type_index.encode(sink);
3588 field_index.encode(sink);
3589 }
3590 Instruction::StructAtomicRmwXor {
3591 ordering,
3592 struct_type_index,
3593 field_index,
3594 } => {
3595 sink.push(0xFE);
3596 sink.push(0x64);
3597 ordering.encode(sink);
3598 struct_type_index.encode(sink);
3599 field_index.encode(sink);
3600 }
3601 Instruction::StructAtomicRmwXchg {
3602 ordering,
3603 struct_type_index,
3604 field_index,
3605 } => {
3606 sink.push(0xFE);
3607 sink.push(0x65);
3608 ordering.encode(sink);
3609 struct_type_index.encode(sink);
3610 field_index.encode(sink);
3611 }
3612 Instruction::StructAtomicRmwCmpxchg {
3613 ordering,
3614 struct_type_index,
3615 field_index,
3616 } => {
3617 sink.push(0xFE);
3618 sink.push(0x66);
3619 ordering.encode(sink);
3620 struct_type_index.encode(sink);
3621 field_index.encode(sink);
3622 }
3623 Instruction::ArrayAtomicGet {
3624 ordering,
3625 array_type_index,
3626 } => {
3627 sink.push(0xFE);
3628 sink.push(0x67);
3629 ordering.encode(sink);
3630 array_type_index.encode(sink);
3631 }
3632 Instruction::ArrayAtomicGetS {
3633 ordering,
3634 array_type_index,
3635 } => {
3636 sink.push(0xFE);
3637 sink.push(0x68);
3638 ordering.encode(sink);
3639 array_type_index.encode(sink);
3640 }
3641 Instruction::ArrayAtomicGetU {
3642 ordering,
3643 array_type_index,
3644 } => {
3645 sink.push(0xFE);
3646 sink.push(0x69);
3647 ordering.encode(sink);
3648 array_type_index.encode(sink);
3649 }
3650 Instruction::ArrayAtomicSet {
3651 ordering,
3652 array_type_index,
3653 } => {
3654 sink.push(0xFE);
3655 sink.push(0x6A);
3656 ordering.encode(sink);
3657 array_type_index.encode(sink);
3658 }
3659 Instruction::ArrayAtomicRmwAdd {
3660 ordering,
3661 array_type_index,
3662 } => {
3663 sink.push(0xFE);
3664 sink.push(0x6B);
3665 ordering.encode(sink);
3666 array_type_index.encode(sink);
3667 }
3668 Instruction::ArrayAtomicRmwSub {
3669 ordering,
3670 array_type_index,
3671 } => {
3672 sink.push(0xFE);
3673 sink.push(0x6C);
3674 ordering.encode(sink);
3675 array_type_index.encode(sink);
3676 }
3677 Instruction::ArrayAtomicRmwAnd {
3678 ordering,
3679 array_type_index,
3680 } => {
3681 sink.push(0xFE);
3682 sink.push(0x6D);
3683 ordering.encode(sink);
3684 array_type_index.encode(sink);
3685 }
3686 Instruction::ArrayAtomicRmwOr {
3687 ordering,
3688 array_type_index,
3689 } => {
3690 sink.push(0xFE);
3691 sink.push(0x6E);
3692 ordering.encode(sink);
3693 array_type_index.encode(sink);
3694 }
3695 Instruction::ArrayAtomicRmwXor {
3696 ordering,
3697 array_type_index,
3698 } => {
3699 sink.push(0xFE);
3700 sink.push(0x6F);
3701 ordering.encode(sink);
3702 array_type_index.encode(sink);
3703 }
3704 Instruction::ArrayAtomicRmwXchg {
3705 ordering,
3706 array_type_index,
3707 } => {
3708 sink.push(0xFE);
3709 sink.push(0x70);
3710 ordering.encode(sink);
3711 array_type_index.encode(sink);
3712 }
3713 Instruction::ArrayAtomicRmwCmpxchg {
3714 ordering,
3715 array_type_index,
3716 } => {
3717 sink.push(0xFE);
3718 sink.push(0x71);
3719 ordering.encode(sink);
3720 array_type_index.encode(sink);
3721 }
3722 Instruction::RefI31Shared => {
3723 sink.push(0xFE);
3724 sink.push(0x72);
3725 }
3726 Instruction::ContNew(type_index) => {
3727 sink.push(0xE0);
3728 type_index.encode(sink);
3729 }
3730 Instruction::ContBind {
3731 argument_index,
3732 result_index,
3733 } => {
3734 sink.push(0xE1);
3735 argument_index.encode(sink);
3736 result_index.encode(sink);
3737 }
3738 Instruction::Suspend(tag_index) => {
3739 sink.push(0xE2);
3740 tag_index.encode(sink);
3741 }
3742 Instruction::Resume {
3743 cont_type_index,
3744 ref resume_table,
3745 } => {
3746 sink.push(0xE3);
3747 cont_type_index.encode(sink);
3748 resume_table.encode(sink);
3749 }
3750 Instruction::ResumeThrow {
3751 cont_type_index,
3752 tag_index,
3753 ref resume_table,
3754 } => {
3755 sink.push(0xE4);
3756 cont_type_index.encode(sink);
3757 tag_index.encode(sink);
3758 resume_table.encode(sink);
3759 }
3760 Instruction::Switch {
3761 cont_type_index,
3762 tag_index,
3763 } => {
3764 sink.push(0xE5);
3765 cont_type_index.encode(sink);
3766 tag_index.encode(sink);
3767 }
3768 Instruction::I64Add128 => {
3769 sink.push(0xFC);
3770 19u32.encode(sink);
3771 }
3772 Instruction::I64Sub128 => {
3773 sink.push(0xFC);
3774 20u32.encode(sink);
3775 }
3776 Instruction::I64MulWideS => {
3777 sink.push(0xFC);
3778 21u32.encode(sink);
3779 }
3780 Instruction::I64MulWideU => {
3781 sink.push(0xFC);
3782 22u32.encode(sink);
3783 }
3784 }
3785 }
3786}
3787
3788#[derive(Clone, Debug)]
3789#[allow(missing_docs)]
3790pub enum Catch {
3791 One { tag: u32, label: u32 },
3792 OneRef { tag: u32, label: u32 },
3793 All { label: u32 },
3794 AllRef { label: u32 },
3795}
3796
3797impl Encode for Catch {
3798 fn encode(&self, sink: &mut Vec<u8>) {
3799 match self {
3800 Catch::One { tag: &u32, label: &u32 } => {
3801 sink.push(0x00);
3802 tag.encode(sink);
3803 label.encode(sink);
3804 }
3805 Catch::OneRef { tag: &u32, label: &u32 } => {
3806 sink.push(0x01);
3807 tag.encode(sink);
3808 label.encode(sink);
3809 }
3810 Catch::All { label: &u32 } => {
3811 sink.push(0x02);
3812 label.encode(sink);
3813 }
3814 Catch::AllRef { label: &u32 } => {
3815 sink.push(0x03);
3816 label.encode(sink);
3817 }
3818 }
3819 }
3820}
3821
3822#[derive(Clone, Debug)]
3823#[allow(missing_docs)]
3824pub enum Handle {
3825 OnLabel { tag: u32, label: u32 },
3826 OnSwitch { tag: u32 },
3827}
3828
3829impl Encode for Handle {
3830 fn encode(&self, sink: &mut Vec<u8>) {
3831 match self {
3832 Handle::OnLabel { tag: &u32, label: &u32 } => {
3833 sink.push(0x00);
3834 tag.encode(sink);
3835 label.encode(sink);
3836 }
3837 Handle::OnSwitch { tag: &u32 } => {
3838 sink.push(0x01);
3839 tag.encode(sink);
3840 }
3841 }
3842 }
3843}
3844
3845/// A constant expression.
3846///
3847/// Usable in contexts such as offsets or initializers.
3848#[derive(Clone, Debug)]
3849pub struct ConstExpr {
3850 bytes: Vec<u8>,
3851}
3852
3853impl ConstExpr {
3854 /// Create a new empty constant expression builder.
3855 pub fn empty() -> Self {
3856 Self { bytes: Vec::new() }
3857 }
3858
3859 /// Create a constant expression with the specified raw encoding of instructions.
3860 pub fn raw(bytes: impl IntoIterator<Item = u8>) -> Self {
3861 Self {
3862 bytes: bytes.into_iter().collect(),
3863 }
3864 }
3865
3866 /// Create a constant expression with the sequence of instructions
3867 pub fn extended<'a>(insns: impl IntoIterator<Item = Instruction<'a>>) -> Self {
3868 let mut bytes = vec![];
3869 for insn in insns {
3870 insn.encode(&mut bytes);
3871 }
3872 Self { bytes }
3873 }
3874
3875 fn new_insn(insn: Instruction) -> Self {
3876 let mut bytes = vec![];
3877 insn.encode(&mut bytes);
3878 Self { bytes }
3879 }
3880
3881 fn with_insn(mut self, insn: Instruction) -> Self {
3882 insn.encode(&mut self.bytes);
3883 self
3884 }
3885
3886 /// Create a constant expression containing a single `global.get` instruction.
3887 pub fn global_get(index: u32) -> Self {
3888 Self::new_insn(Instruction::GlobalGet(index))
3889 }
3890
3891 /// Create a constant expression containing a single `ref.null` instruction.
3892 pub fn ref_null(ty: HeapType) -> Self {
3893 Self::new_insn(Instruction::RefNull(ty))
3894 }
3895
3896 /// Create a constant expression containing a single `ref.func` instruction.
3897 pub fn ref_func(func: u32) -> Self {
3898 Self::new_insn(Instruction::RefFunc(func))
3899 }
3900
3901 /// Create a constant expression containing a single `i32.const` instruction.
3902 pub fn i32_const(value: i32) -> Self {
3903 Self::new_insn(Instruction::I32Const(value))
3904 }
3905
3906 /// Create a constant expression containing a single `i64.const` instruction.
3907 pub fn i64_const(value: i64) -> Self {
3908 Self::new_insn(Instruction::I64Const(value))
3909 }
3910
3911 /// Create a constant expression containing a single `f32.const` instruction.
3912 pub fn f32_const(value: f32) -> Self {
3913 Self::new_insn(Instruction::F32Const(value))
3914 }
3915
3916 /// Create a constant expression containing a single `f64.const` instruction.
3917 pub fn f64_const(value: f64) -> Self {
3918 Self::new_insn(Instruction::F64Const(value))
3919 }
3920
3921 /// Create a constant expression containing a single `v128.const` instruction.
3922 pub fn v128_const(value: i128) -> Self {
3923 Self::new_insn(Instruction::V128Const(value))
3924 }
3925
3926 /// Add a `global.get` instruction to this constant expression.
3927 pub fn with_global_get(self, index: u32) -> Self {
3928 self.with_insn(Instruction::GlobalGet(index))
3929 }
3930
3931 /// Add a `ref.null` instruction to this constant expression.
3932 pub fn with_ref_null(self, ty: HeapType) -> Self {
3933 self.with_insn(Instruction::RefNull(ty))
3934 }
3935
3936 /// Add a `ref.func` instruction to this constant expression.
3937 pub fn with_ref_func(self, func: u32) -> Self {
3938 self.with_insn(Instruction::RefFunc(func))
3939 }
3940
3941 /// Add an `i32.const` instruction to this constant expression.
3942 pub fn with_i32_const(self, value: i32) -> Self {
3943 self.with_insn(Instruction::I32Const(value))
3944 }
3945
3946 /// Add an `i64.const` instruction to this constant expression.
3947 pub fn with_i64_const(self, value: i64) -> Self {
3948 self.with_insn(Instruction::I64Const(value))
3949 }
3950
3951 /// Add a `f32.const` instruction to this constant expression.
3952 pub fn with_f32_const(self, value: f32) -> Self {
3953 self.with_insn(Instruction::F32Const(value))
3954 }
3955
3956 /// Add a `f64.const` instruction to this constant expression.
3957 pub fn with_f64_const(self, value: f64) -> Self {
3958 self.with_insn(Instruction::F64Const(value))
3959 }
3960
3961 /// Add a `v128.const` instruction to this constant expression.
3962 pub fn with_v128_const(self, value: i128) -> Self {
3963 self.with_insn(Instruction::V128Const(value))
3964 }
3965
3966 /// Add an `i32.add` instruction to this constant expression.
3967 pub fn with_i32_add(self) -> Self {
3968 self.with_insn(Instruction::I32Add)
3969 }
3970
3971 /// Add an `i32.sub` instruction to this constant expression.
3972 pub fn with_i32_sub(self) -> Self {
3973 self.with_insn(Instruction::I32Sub)
3974 }
3975
3976 /// Add an `i32.mul` instruction to this constant expression.
3977 pub fn with_i32_mul(self) -> Self {
3978 self.with_insn(Instruction::I32Mul)
3979 }
3980
3981 /// Add an `i64.add` instruction to this constant expression.
3982 pub fn with_i64_add(self) -> Self {
3983 self.with_insn(Instruction::I64Add)
3984 }
3985
3986 /// Add an `i64.sub` instruction to this constant expression.
3987 pub fn with_i64_sub(self) -> Self {
3988 self.with_insn(Instruction::I64Sub)
3989 }
3990
3991 /// Add an `i64.mul` instruction to this constant expression.
3992 pub fn with_i64_mul(self) -> Self {
3993 self.with_insn(Instruction::I64Mul)
3994 }
3995
3996 /// Returns the function, if any, referenced by this global.
3997 pub fn get_ref_func(&self) -> Option<u32> {
3998 let prefix = *self.bytes.get(0)?;
3999 // 0xd2 == `ref.func` opcode, and if that's found then load the leb
4000 // corresponding to the function index.
4001 if prefix != 0xd2 {
4002 return None;
4003 }
4004 leb128::read::unsigned(&mut &self.bytes[1..])
4005 .ok()?
4006 .try_into()
4007 .ok()
4008 }
4009}
4010
4011impl Encode for ConstExpr {
4012 fn encode(&self, sink: &mut Vec<u8>) {
4013 sink.extend(&self.bytes);
4014 Instruction::End.encode(sink);
4015 }
4016}
4017
4018#[cfg(test)]
4019mod tests {
4020 #[test]
4021 fn function_new_with_locals_test() {
4022 use super::*;
4023
4024 // Test the algorithm for conversion is correct
4025 let f1 = Function::new_with_locals_types([
4026 ValType::I32,
4027 ValType::I32,
4028 ValType::I64,
4029 ValType::F32,
4030 ValType::F32,
4031 ValType::F32,
4032 ValType::I32,
4033 ValType::I64,
4034 ValType::I64,
4035 ]);
4036 let f2 = Function::new([
4037 (2, ValType::I32),
4038 (1, ValType::I64),
4039 (3, ValType::F32),
4040 (1, ValType::I32),
4041 (2, ValType::I64),
4042 ]);
4043
4044 assert_eq!(f1.bytes, f2.bytes)
4045 }
4046
4047 #[test]
4048 fn func_raw_bytes() {
4049 use super::*;
4050
4051 let mut f = Function::new([(1, ValType::I32), (1, ValType::F32)]);
4052 f.instruction(&Instruction::End);
4053 let mut code_from_func = CodeSection::new();
4054 code_from_func.function(&f);
4055 let bytes = f.into_raw_body();
4056 let mut code_from_raw = CodeSection::new();
4057 code_from_raw.raw(&bytes[..]);
4058
4059 let mut c1 = vec![];
4060 code_from_func.encode(&mut c1);
4061 let mut c2 = vec![];
4062 code_from_raw.encode(&mut c2);
4063 assert_eq!(c1, c2);
4064 }
4065}
4066