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