1use super::{
2 BlockType, CountedList, CountedListWriter, Deserialize, Error, Serialize, Uint32, Uint64,
3 Uint8, VarInt32, VarInt64, VarUint32,
4};
5use crate::io;
6use alloc::{boxed::Box, vec::Vec};
7use core::fmt;
8
9#[derive(Debug, Clone, PartialEq)]
11pub struct Instructions(Vec<Instruction>);
12
13impl Instructions {
14 pub fn new(elements: Vec<Instruction>) -> Self {
16 Instructions(elements)
17 }
18
19 pub fn empty() -> Self {
21 Instructions(vec![Instruction::End])
22 }
23
24 pub fn elements(&self) -> &[Instruction] {
26 &self.0
27 }
28
29 pub fn elements_mut(&mut self) -> &mut Vec<Instruction> {
31 &mut self.0
32 }
33}
34
35impl Deserialize for Instructions {
36 type Error = Error;
37
38 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
39 let mut instructions = Vec::new();
40 let mut block_count = 1usize;
41
42 loop {
43 let instruction = Instruction::deserialize(reader)?;
44 if instruction.is_terminal() {
45 block_count -= 1;
46 } else if instruction.is_block() {
47 block_count =
48 block_count.checked_add(1).ok_or(Error::Other("too many instructions"))?;
49 }
50
51 instructions.push(instruction);
52 if block_count == 0 {
53 break;
54 }
55 }
56
57 Ok(Instructions(instructions))
58 }
59}
60
61#[derive(Debug, Clone, PartialEq)]
63pub struct InitExpr(Vec<Instruction>);
64
65impl InitExpr {
66 pub fn new(code: Vec<Instruction>) -> Self {
70 InitExpr(code)
71 }
72
73 pub fn empty() -> Self {
75 InitExpr(vec![Instruction::End])
76 }
77
78 pub fn code(&self) -> &[Instruction] {
80 &self.0
81 }
82
83 pub fn code_mut(&mut self) -> &mut Vec<Instruction> {
85 &mut self.0
86 }
87}
88
89impl Deserialize for InitExpr {
90 type Error = Error;
91
92 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
93 let mut instructions = Vec::new();
94
95 loop {
96 let instruction = Instruction::deserialize(reader)?;
97 let is_terminal = instruction.is_terminal();
98 instructions.push(instruction);
99 if is_terminal {
100 break;
101 }
102 }
103
104 Ok(InitExpr(instructions))
105 }
106}
107
108#[derive(Clone, Debug, PartialEq, Eq, Hash)]
110#[allow(missing_docs)]
111pub enum Instruction {
112 Unreachable,
113 Nop,
114 Block(BlockType),
115 Loop(BlockType),
116 If(BlockType),
117 Else,
118 End,
119 Br(u32),
120 BrIf(u32),
121 BrTable(Box<BrTableData>),
122 Return,
123
124 Call(u32),
125 CallIndirect(u32, u32),
126
127 Drop,
128 Select,
129
130 GetLocal(u32),
131 SetLocal(u32),
132 TeeLocal(u32),
133 GetGlobal(u32),
134 SetGlobal(u32),
135
136 I32Load(u32, u32),
139 I64Load(u32, u32),
140 F32Load(u32, u32),
141 F64Load(u32, u32),
142 I32Load8S(u32, u32),
143 I32Load8U(u32, u32),
144 I32Load16S(u32, u32),
145 I32Load16U(u32, u32),
146 I64Load8S(u32, u32),
147 I64Load8U(u32, u32),
148 I64Load16S(u32, u32),
149 I64Load16U(u32, u32),
150 I64Load32S(u32, u32),
151 I64Load32U(u32, u32),
152 I32Store(u32, u32),
153 I64Store(u32, u32),
154 F32Store(u32, u32),
155 F64Store(u32, u32),
156 I32Store8(u32, u32),
157 I32Store16(u32, u32),
158 I64Store8(u32, u32),
159 I64Store16(u32, u32),
160 I64Store32(u32, u32),
161
162 CurrentMemory(u8),
163 GrowMemory(u8),
164
165 I32Const(i32),
166 I64Const(i64),
167 F32Const(u32),
168 F64Const(u64),
169
170 I32Eqz,
171 I32Eq,
172 I32Ne,
173 I32LtS,
174 I32LtU,
175 I32GtS,
176 I32GtU,
177 I32LeS,
178 I32LeU,
179 I32GeS,
180 I32GeU,
181
182 I64Eqz,
183 I64Eq,
184 I64Ne,
185 I64LtS,
186 I64LtU,
187 I64GtS,
188 I64GtU,
189 I64LeS,
190 I64LeU,
191 I64GeS,
192 I64GeU,
193
194 F32Eq,
195 F32Ne,
196 F32Lt,
197 F32Gt,
198 F32Le,
199 F32Ge,
200
201 F64Eq,
202 F64Ne,
203 F64Lt,
204 F64Gt,
205 F64Le,
206 F64Ge,
207
208 I32Clz,
209 I32Ctz,
210 I32Popcnt,
211 I32Add,
212 I32Sub,
213 I32Mul,
214 I32DivS,
215 I32DivU,
216 I32RemS,
217 I32RemU,
218 I32And,
219 I32Or,
220 I32Xor,
221 I32Shl,
222 I32ShrS,
223 I32ShrU,
224 I32Rotl,
225 I32Rotr,
226
227 I64Clz,
228 I64Ctz,
229 I64Popcnt,
230 I64Add,
231 I64Sub,
232 I64Mul,
233 I64DivS,
234 I64DivU,
235 I64RemS,
236 I64RemU,
237 I64And,
238 I64Or,
239 I64Xor,
240 I64Shl,
241 I64ShrS,
242 I64ShrU,
243 I64Rotl,
244 I64Rotr,
245 F32Abs,
246 F32Neg,
247 F32Ceil,
248 F32Floor,
249 F32Trunc,
250 F32Nearest,
251 F32Sqrt,
252 F32Add,
253 F32Sub,
254 F32Mul,
255 F32Div,
256 F32Min,
257 F32Max,
258 F32Copysign,
259 F64Abs,
260 F64Neg,
261 F64Ceil,
262 F64Floor,
263 F64Trunc,
264 F64Nearest,
265 F64Sqrt,
266 F64Add,
267 F64Sub,
268 F64Mul,
269 F64Div,
270 F64Min,
271 F64Max,
272 F64Copysign,
273
274 I32WrapI64,
275 I32TruncSF32,
276 I32TruncUF32,
277 I32TruncSF64,
278 I32TruncUF64,
279 I64ExtendSI32,
280 I64ExtendUI32,
281 I64TruncSF32,
282 I64TruncUF32,
283 I64TruncSF64,
284 I64TruncUF64,
285 F32ConvertSI32,
286 F32ConvertUI32,
287 F32ConvertSI64,
288 F32ConvertUI64,
289 F32DemoteF64,
290 F64ConvertSI32,
291 F64ConvertUI32,
292 F64ConvertSI64,
293 F64ConvertUI64,
294 F64PromoteF32,
295
296 I32ReinterpretF32,
297 I64ReinterpretF64,
298 F32ReinterpretI32,
299 F64ReinterpretI64,
300
301 #[cfg(feature = "atomics")]
302 Atomics(AtomicsInstruction),
303
304 #[cfg(feature = "simd")]
305 Simd(SimdInstruction),
306
307 #[cfg(feature = "sign_ext")]
308 SignExt(SignExtInstruction),
309
310 #[cfg(feature = "bulk")]
311 Bulk(BulkInstruction),
312}
313
314#[allow(missing_docs)]
315#[cfg(feature = "atomics")]
316#[derive(Clone, Debug, PartialEq, Eq, Hash)]
317pub enum AtomicsInstruction {
318 AtomicWake(MemArg),
319 I32AtomicWait(MemArg),
320 I64AtomicWait(MemArg),
321
322 I32AtomicLoad(MemArg),
323 I64AtomicLoad(MemArg),
324 I32AtomicLoad8u(MemArg),
325 I32AtomicLoad16u(MemArg),
326 I64AtomicLoad8u(MemArg),
327 I64AtomicLoad16u(MemArg),
328 I64AtomicLoad32u(MemArg),
329 I32AtomicStore(MemArg),
330 I64AtomicStore(MemArg),
331 I32AtomicStore8u(MemArg),
332 I32AtomicStore16u(MemArg),
333 I64AtomicStore8u(MemArg),
334 I64AtomicStore16u(MemArg),
335 I64AtomicStore32u(MemArg),
336
337 I32AtomicRmwAdd(MemArg),
338 I64AtomicRmwAdd(MemArg),
339 I32AtomicRmwAdd8u(MemArg),
340 I32AtomicRmwAdd16u(MemArg),
341 I64AtomicRmwAdd8u(MemArg),
342 I64AtomicRmwAdd16u(MemArg),
343 I64AtomicRmwAdd32u(MemArg),
344
345 I32AtomicRmwSub(MemArg),
346 I64AtomicRmwSub(MemArg),
347 I32AtomicRmwSub8u(MemArg),
348 I32AtomicRmwSub16u(MemArg),
349 I64AtomicRmwSub8u(MemArg),
350 I64AtomicRmwSub16u(MemArg),
351 I64AtomicRmwSub32u(MemArg),
352
353 I32AtomicRmwAnd(MemArg),
354 I64AtomicRmwAnd(MemArg),
355 I32AtomicRmwAnd8u(MemArg),
356 I32AtomicRmwAnd16u(MemArg),
357 I64AtomicRmwAnd8u(MemArg),
358 I64AtomicRmwAnd16u(MemArg),
359 I64AtomicRmwAnd32u(MemArg),
360
361 I32AtomicRmwOr(MemArg),
362 I64AtomicRmwOr(MemArg),
363 I32AtomicRmwOr8u(MemArg),
364 I32AtomicRmwOr16u(MemArg),
365 I64AtomicRmwOr8u(MemArg),
366 I64AtomicRmwOr16u(MemArg),
367 I64AtomicRmwOr32u(MemArg),
368
369 I32AtomicRmwXor(MemArg),
370 I64AtomicRmwXor(MemArg),
371 I32AtomicRmwXor8u(MemArg),
372 I32AtomicRmwXor16u(MemArg),
373 I64AtomicRmwXor8u(MemArg),
374 I64AtomicRmwXor16u(MemArg),
375 I64AtomicRmwXor32u(MemArg),
376
377 I32AtomicRmwXchg(MemArg),
378 I64AtomicRmwXchg(MemArg),
379 I32AtomicRmwXchg8u(MemArg),
380 I32AtomicRmwXchg16u(MemArg),
381 I64AtomicRmwXchg8u(MemArg),
382 I64AtomicRmwXchg16u(MemArg),
383 I64AtomicRmwXchg32u(MemArg),
384
385 I32AtomicRmwCmpxchg(MemArg),
386 I64AtomicRmwCmpxchg(MemArg),
387 I32AtomicRmwCmpxchg8u(MemArg),
388 I32AtomicRmwCmpxchg16u(MemArg),
389 I64AtomicRmwCmpxchg8u(MemArg),
390 I64AtomicRmwCmpxchg16u(MemArg),
391 I64AtomicRmwCmpxchg32u(MemArg),
392}
393
394#[allow(missing_docs)]
395#[cfg(feature = "simd")]
396#[derive(Clone, Debug, PartialEq, Eq, Hash)]
397pub enum SimdInstruction {
398 V128Const(Box<[u8; 16]>),
399 V128Load(MemArg),
400 V128Store(MemArg),
401 I8x16Splat,
402 I16x8Splat,
403 I32x4Splat,
404 I64x2Splat,
405 F32x4Splat,
406 F64x2Splat,
407 I8x16ExtractLaneS(u8),
408 I8x16ExtractLaneU(u8),
409 I16x8ExtractLaneS(u8),
410 I16x8ExtractLaneU(u8),
411 I32x4ExtractLane(u8),
412 I64x2ExtractLane(u8),
413 F32x4ExtractLane(u8),
414 F64x2ExtractLane(u8),
415 I8x16ReplaceLane(u8),
416 I16x8ReplaceLane(u8),
417 I32x4ReplaceLane(u8),
418 I64x2ReplaceLane(u8),
419 F32x4ReplaceLane(u8),
420 F64x2ReplaceLane(u8),
421 V8x16Shuffle(Box<[u8; 16]>),
422 I8x16Add,
423 I16x8Add,
424 I32x4Add,
425 I64x2Add,
426 I8x16Sub,
427 I16x8Sub,
428 I32x4Sub,
429 I64x2Sub,
430 I8x16Mul,
431 I16x8Mul,
432 I32x4Mul,
433 I8x16Neg,
435 I16x8Neg,
436 I32x4Neg,
437 I64x2Neg,
438 I8x16AddSaturateS,
439 I8x16AddSaturateU,
440 I16x8AddSaturateS,
441 I16x8AddSaturateU,
442 I8x16SubSaturateS,
443 I8x16SubSaturateU,
444 I16x8SubSaturateS,
445 I16x8SubSaturateU,
446 I8x16Shl,
447 I16x8Shl,
448 I32x4Shl,
449 I64x2Shl,
450 I8x16ShrS,
451 I8x16ShrU,
452 I16x8ShrS,
453 I16x8ShrU,
454 I32x4ShrS,
455 I32x4ShrU,
456 I64x2ShrS,
457 I64x2ShrU,
458 V128And,
459 V128Or,
460 V128Xor,
461 V128Not,
462 V128Bitselect,
463 I8x16AnyTrue,
464 I16x8AnyTrue,
465 I32x4AnyTrue,
466 I64x2AnyTrue,
467 I8x16AllTrue,
468 I16x8AllTrue,
469 I32x4AllTrue,
470 I64x2AllTrue,
471 I8x16Eq,
472 I16x8Eq,
473 I32x4Eq,
474 F32x4Eq,
476 F64x2Eq,
477 I8x16Ne,
478 I16x8Ne,
479 I32x4Ne,
480 F32x4Ne,
482 F64x2Ne,
483 I8x16LtS,
484 I8x16LtU,
485 I16x8LtS,
486 I16x8LtU,
487 I32x4LtS,
488 I32x4LtU,
489 F32x4Lt,
492 F64x2Lt,
493 I8x16LeS,
494 I8x16LeU,
495 I16x8LeS,
496 I16x8LeU,
497 I32x4LeS,
498 I32x4LeU,
499 F32x4Le,
502 F64x2Le,
503 I8x16GtS,
504 I8x16GtU,
505 I16x8GtS,
506 I16x8GtU,
507 I32x4GtS,
508 I32x4GtU,
509 F32x4Gt,
512 F64x2Gt,
513 I8x16GeS,
514 I8x16GeU,
515 I16x8GeS,
516 I16x8GeU,
517 I32x4GeS,
518 I32x4GeU,
519 F32x4Ge,
522 F64x2Ge,
523 F32x4Neg,
524 F64x2Neg,
525 F32x4Abs,
526 F64x2Abs,
527 F32x4Min,
528 F64x2Min,
529 F32x4Max,
530 F64x2Max,
531 F32x4Add,
532 F64x2Add,
533 F32x4Sub,
534 F64x2Sub,
535 F32x4Div,
536 F64x2Div,
537 F32x4Mul,
538 F64x2Mul,
539 F32x4Sqrt,
540 F64x2Sqrt,
541 F32x4ConvertSI32x4,
542 F32x4ConvertUI32x4,
543 F64x2ConvertSI64x2,
544 F64x2ConvertUI64x2,
545 I32x4TruncSF32x4Sat,
546 I32x4TruncUF32x4Sat,
547 I64x2TruncSF64x2Sat,
548 I64x2TruncUF64x2Sat,
549}
550
551#[allow(missing_docs)]
552#[cfg(feature = "sign_ext")]
553#[derive(Clone, Debug, PartialEq, Eq, Hash)]
554pub enum SignExtInstruction {
555 I32Extend8S,
556 I32Extend16S,
557 I64Extend8S,
558 I64Extend16S,
559 I64Extend32S,
560}
561
562#[allow(missing_docs)]
563#[cfg(feature = "bulk")]
564#[derive(Clone, Debug, PartialEq, Eq, Hash)]
565pub enum BulkInstruction {
566 MemoryInit(u32),
567 MemoryDrop(u32),
568 MemoryCopy,
569 MemoryFill,
570 TableInit(u32),
571 TableDrop(u32),
572 TableCopy,
573}
574
575#[cfg(any(feature = "simd", feature = "atomics"))]
576#[derive(Clone, Debug, PartialEq, Eq, Hash)]
577#[allow(missing_docs)]
578pub struct MemArg {
579 pub align: u8,
580 pub offset: u32,
581}
582
583#[derive(Clone, Debug, PartialEq, Eq, Hash)]
584#[allow(missing_docs)]
585pub struct BrTableData {
586 pub table: Box<[u32]>,
587 pub default: u32,
588}
589
590impl Instruction {
591 pub fn is_block(&self) -> bool {
593 matches!(self, &Instruction::Block(_) | &Instruction::Loop(_) | &Instruction::If(_))
594 }
595
596 pub fn is_terminal(&self) -> bool {
600 matches!(self, &Instruction::End)
601 }
602}
603
604#[allow(missing_docs)]
605pub mod opcodes {
606 pub const UNREACHABLE: u8 = 0x00;
607 pub const NOP: u8 = 0x01;
608 pub const BLOCK: u8 = 0x02;
609 pub const LOOP: u8 = 0x03;
610 pub const IF: u8 = 0x04;
611 pub const ELSE: u8 = 0x05;
612 pub const END: u8 = 0x0b;
613 pub const BR: u8 = 0x0c;
614 pub const BRIF: u8 = 0x0d;
615 pub const BRTABLE: u8 = 0x0e;
616 pub const RETURN: u8 = 0x0f;
617 pub const CALL: u8 = 0x10;
618 pub const CALLINDIRECT: u8 = 0x11;
619 pub const DROP: u8 = 0x1a;
620 pub const SELECT: u8 = 0x1b;
621 pub const GETLOCAL: u8 = 0x20;
622 pub const SETLOCAL: u8 = 0x21;
623 pub const TEELOCAL: u8 = 0x22;
624 pub const GETGLOBAL: u8 = 0x23;
625 pub const SETGLOBAL: u8 = 0x24;
626 pub const I32LOAD: u8 = 0x28;
627 pub const I64LOAD: u8 = 0x29;
628 pub const F32LOAD: u8 = 0x2a;
629 pub const F64LOAD: u8 = 0x2b;
630 pub const I32LOAD8S: u8 = 0x2c;
631 pub const I32LOAD8U: u8 = 0x2d;
632 pub const I32LOAD16S: u8 = 0x2e;
633 pub const I32LOAD16U: u8 = 0x2f;
634 pub const I64LOAD8S: u8 = 0x30;
635 pub const I64LOAD8U: u8 = 0x31;
636 pub const I64LOAD16S: u8 = 0x32;
637 pub const I64LOAD16U: u8 = 0x33;
638 pub const I64LOAD32S: u8 = 0x34;
639 pub const I64LOAD32U: u8 = 0x35;
640 pub const I32STORE: u8 = 0x36;
641 pub const I64STORE: u8 = 0x37;
642 pub const F32STORE: u8 = 0x38;
643 pub const F64STORE: u8 = 0x39;
644 pub const I32STORE8: u8 = 0x3a;
645 pub const I32STORE16: u8 = 0x3b;
646 pub const I64STORE8: u8 = 0x3c;
647 pub const I64STORE16: u8 = 0x3d;
648 pub const I64STORE32: u8 = 0x3e;
649 pub const CURRENTMEMORY: u8 = 0x3f;
650 pub const GROWMEMORY: u8 = 0x40;
651 pub const I32CONST: u8 = 0x41;
652 pub const I64CONST: u8 = 0x42;
653 pub const F32CONST: u8 = 0x43;
654 pub const F64CONST: u8 = 0x44;
655 pub const I32EQZ: u8 = 0x45;
656 pub const I32EQ: u8 = 0x46;
657 pub const I32NE: u8 = 0x47;
658 pub const I32LTS: u8 = 0x48;
659 pub const I32LTU: u8 = 0x49;
660 pub const I32GTS: u8 = 0x4a;
661 pub const I32GTU: u8 = 0x4b;
662 pub const I32LES: u8 = 0x4c;
663 pub const I32LEU: u8 = 0x4d;
664 pub const I32GES: u8 = 0x4e;
665 pub const I32GEU: u8 = 0x4f;
666 pub const I64EQZ: u8 = 0x50;
667 pub const I64EQ: u8 = 0x51;
668 pub const I64NE: u8 = 0x52;
669 pub const I64LTS: u8 = 0x53;
670 pub const I64LTU: u8 = 0x54;
671 pub const I64GTS: u8 = 0x55;
672 pub const I64GTU: u8 = 0x56;
673 pub const I64LES: u8 = 0x57;
674 pub const I64LEU: u8 = 0x58;
675 pub const I64GES: u8 = 0x59;
676 pub const I64GEU: u8 = 0x5a;
677
678 pub const F32EQ: u8 = 0x5b;
679 pub const F32NE: u8 = 0x5c;
680 pub const F32LT: u8 = 0x5d;
681 pub const F32GT: u8 = 0x5e;
682 pub const F32LE: u8 = 0x5f;
683 pub const F32GE: u8 = 0x60;
684
685 pub const F64EQ: u8 = 0x61;
686 pub const F64NE: u8 = 0x62;
687 pub const F64LT: u8 = 0x63;
688 pub const F64GT: u8 = 0x64;
689 pub const F64LE: u8 = 0x65;
690 pub const F64GE: u8 = 0x66;
691
692 pub const I32CLZ: u8 = 0x67;
693 pub const I32CTZ: u8 = 0x68;
694 pub const I32POPCNT: u8 = 0x69;
695 pub const I32ADD: u8 = 0x6a;
696 pub const I32SUB: u8 = 0x6b;
697 pub const I32MUL: u8 = 0x6c;
698 pub const I32DIVS: u8 = 0x6d;
699 pub const I32DIVU: u8 = 0x6e;
700 pub const I32REMS: u8 = 0x6f;
701 pub const I32REMU: u8 = 0x70;
702 pub const I32AND: u8 = 0x71;
703 pub const I32OR: u8 = 0x72;
704 pub const I32XOR: u8 = 0x73;
705 pub const I32SHL: u8 = 0x74;
706 pub const I32SHRS: u8 = 0x75;
707 pub const I32SHRU: u8 = 0x76;
708 pub const I32ROTL: u8 = 0x77;
709 pub const I32ROTR: u8 = 0x78;
710
711 pub const I64CLZ: u8 = 0x79;
712 pub const I64CTZ: u8 = 0x7a;
713 pub const I64POPCNT: u8 = 0x7b;
714 pub const I64ADD: u8 = 0x7c;
715 pub const I64SUB: u8 = 0x7d;
716 pub const I64MUL: u8 = 0x7e;
717 pub const I64DIVS: u8 = 0x7f;
718 pub const I64DIVU: u8 = 0x80;
719 pub const I64REMS: u8 = 0x81;
720 pub const I64REMU: u8 = 0x82;
721 pub const I64AND: u8 = 0x83;
722 pub const I64OR: u8 = 0x84;
723 pub const I64XOR: u8 = 0x85;
724 pub const I64SHL: u8 = 0x86;
725 pub const I64SHRS: u8 = 0x87;
726 pub const I64SHRU: u8 = 0x88;
727 pub const I64ROTL: u8 = 0x89;
728 pub const I64ROTR: u8 = 0x8a;
729 pub const F32ABS: u8 = 0x8b;
730 pub const F32NEG: u8 = 0x8c;
731 pub const F32CEIL: u8 = 0x8d;
732 pub const F32FLOOR: u8 = 0x8e;
733 pub const F32TRUNC: u8 = 0x8f;
734 pub const F32NEAREST: u8 = 0x90;
735 pub const F32SQRT: u8 = 0x91;
736 pub const F32ADD: u8 = 0x92;
737 pub const F32SUB: u8 = 0x93;
738 pub const F32MUL: u8 = 0x94;
739 pub const F32DIV: u8 = 0x95;
740 pub const F32MIN: u8 = 0x96;
741 pub const F32MAX: u8 = 0x97;
742 pub const F32COPYSIGN: u8 = 0x98;
743 pub const F64ABS: u8 = 0x99;
744 pub const F64NEG: u8 = 0x9a;
745 pub const F64CEIL: u8 = 0x9b;
746 pub const F64FLOOR: u8 = 0x9c;
747 pub const F64TRUNC: u8 = 0x9d;
748 pub const F64NEAREST: u8 = 0x9e;
749 pub const F64SQRT: u8 = 0x9f;
750 pub const F64ADD: u8 = 0xa0;
751 pub const F64SUB: u8 = 0xa1;
752 pub const F64MUL: u8 = 0xa2;
753 pub const F64DIV: u8 = 0xa3;
754 pub const F64MIN: u8 = 0xa4;
755 pub const F64MAX: u8 = 0xa5;
756 pub const F64COPYSIGN: u8 = 0xa6;
757
758 pub const I32WRAPI64: u8 = 0xa7;
759 pub const I32TRUNCSF32: u8 = 0xa8;
760 pub const I32TRUNCUF32: u8 = 0xa9;
761 pub const I32TRUNCSF64: u8 = 0xaa;
762 pub const I32TRUNCUF64: u8 = 0xab;
763 pub const I64EXTENDSI32: u8 = 0xac;
764 pub const I64EXTENDUI32: u8 = 0xad;
765 pub const I64TRUNCSF32: u8 = 0xae;
766 pub const I64TRUNCUF32: u8 = 0xaf;
767 pub const I64TRUNCSF64: u8 = 0xb0;
768 pub const I64TRUNCUF64: u8 = 0xb1;
769 pub const F32CONVERTSI32: u8 = 0xb2;
770 pub const F32CONVERTUI32: u8 = 0xb3;
771 pub const F32CONVERTSI64: u8 = 0xb4;
772 pub const F32CONVERTUI64: u8 = 0xb5;
773 pub const F32DEMOTEF64: u8 = 0xb6;
774 pub const F64CONVERTSI32: u8 = 0xb7;
775 pub const F64CONVERTUI32: u8 = 0xb8;
776 pub const F64CONVERTSI64: u8 = 0xb9;
777 pub const F64CONVERTUI64: u8 = 0xba;
778 pub const F64PROMOTEF32: u8 = 0xbb;
779
780 pub const I32REINTERPRETF32: u8 = 0xbc;
781 pub const I64REINTERPRETF64: u8 = 0xbd;
782 pub const F32REINTERPRETI32: u8 = 0xbe;
783 pub const F64REINTERPRETI64: u8 = 0xbf;
784
785 #[cfg(feature = "sign_ext")]
786 pub mod sign_ext {
787 pub const I32_EXTEND8_S: u8 = 0xc0;
788 pub const I32_EXTEND16_S: u8 = 0xc1;
789 pub const I64_EXTEND8_S: u8 = 0xc2;
790 pub const I64_EXTEND16_S: u8 = 0xc3;
791 pub const I64_EXTEND32_S: u8 = 0xc4;
792 }
793
794 #[cfg(feature = "atomics")]
795 pub mod atomics {
796 pub const ATOMIC_PREFIX: u8 = 0xfe;
797 pub const ATOMIC_WAKE: u8 = 0x00;
798 pub const I32_ATOMIC_WAIT: u8 = 0x01;
799 pub const I64_ATOMIC_WAIT: u8 = 0x02;
800
801 pub const I32_ATOMIC_LOAD: u8 = 0x10;
802 pub const I64_ATOMIC_LOAD: u8 = 0x11;
803 pub const I32_ATOMIC_LOAD8U: u8 = 0x12;
804 pub const I32_ATOMIC_LOAD16U: u8 = 0x13;
805 pub const I64_ATOMIC_LOAD8U: u8 = 0x14;
806 pub const I64_ATOMIC_LOAD16U: u8 = 0x15;
807 pub const I64_ATOMIC_LOAD32U: u8 = 0x16;
808 pub const I32_ATOMIC_STORE: u8 = 0x17;
809 pub const I64_ATOMIC_STORE: u8 = 0x18;
810 pub const I32_ATOMIC_STORE8U: u8 = 0x19;
811 pub const I32_ATOMIC_STORE16U: u8 = 0x1a;
812 pub const I64_ATOMIC_STORE8U: u8 = 0x1b;
813 pub const I64_ATOMIC_STORE16U: u8 = 0x1c;
814 pub const I64_ATOMIC_STORE32U: u8 = 0x1d;
815
816 pub const I32_ATOMIC_RMW_ADD: u8 = 0x1e;
817 pub const I64_ATOMIC_RMW_ADD: u8 = 0x1f;
818 pub const I32_ATOMIC_RMW_ADD8U: u8 = 0x20;
819 pub const I32_ATOMIC_RMW_ADD16U: u8 = 0x21;
820 pub const I64_ATOMIC_RMW_ADD8U: u8 = 0x22;
821 pub const I64_ATOMIC_RMW_ADD16U: u8 = 0x23;
822 pub const I64_ATOMIC_RMW_ADD32U: u8 = 0x24;
823
824 pub const I32_ATOMIC_RMW_SUB: u8 = 0x25;
825 pub const I64_ATOMIC_RMW_SUB: u8 = 0x26;
826 pub const I32_ATOMIC_RMW_SUB8U: u8 = 0x27;
827 pub const I32_ATOMIC_RMW_SUB16U: u8 = 0x28;
828 pub const I64_ATOMIC_RMW_SUB8U: u8 = 0x29;
829 pub const I64_ATOMIC_RMW_SUB16U: u8 = 0x2a;
830 pub const I64_ATOMIC_RMW_SUB32U: u8 = 0x2b;
831
832 pub const I32_ATOMIC_RMW_AND: u8 = 0x2c;
833 pub const I64_ATOMIC_RMW_AND: u8 = 0x2d;
834 pub const I32_ATOMIC_RMW_AND8U: u8 = 0x2e;
835 pub const I32_ATOMIC_RMW_AND16U: u8 = 0x2f;
836 pub const I64_ATOMIC_RMW_AND8U: u8 = 0x30;
837 pub const I64_ATOMIC_RMW_AND16U: u8 = 0x31;
838 pub const I64_ATOMIC_RMW_AND32U: u8 = 0x32;
839
840 pub const I32_ATOMIC_RMW_OR: u8 = 0x33;
841 pub const I64_ATOMIC_RMW_OR: u8 = 0x34;
842 pub const I32_ATOMIC_RMW_OR8U: u8 = 0x35;
843 pub const I32_ATOMIC_RMW_OR16U: u8 = 0x36;
844 pub const I64_ATOMIC_RMW_OR8U: u8 = 0x37;
845 pub const I64_ATOMIC_RMW_OR16U: u8 = 0x38;
846 pub const I64_ATOMIC_RMW_OR32U: u8 = 0x39;
847
848 pub const I32_ATOMIC_RMW_XOR: u8 = 0x3a;
849 pub const I64_ATOMIC_RMW_XOR: u8 = 0x3b;
850 pub const I32_ATOMIC_RMW_XOR8U: u8 = 0x3c;
851 pub const I32_ATOMIC_RMW_XOR16U: u8 = 0x3d;
852 pub const I64_ATOMIC_RMW_XOR8U: u8 = 0x3e;
853 pub const I64_ATOMIC_RMW_XOR16U: u8 = 0x3f;
854 pub const I64_ATOMIC_RMW_XOR32U: u8 = 0x40;
855
856 pub const I32_ATOMIC_RMW_XCHG: u8 = 0x41;
857 pub const I64_ATOMIC_RMW_XCHG: u8 = 0x42;
858 pub const I32_ATOMIC_RMW_XCHG8U: u8 = 0x43;
859 pub const I32_ATOMIC_RMW_XCHG16U: u8 = 0x44;
860 pub const I64_ATOMIC_RMW_XCHG8U: u8 = 0x45;
861 pub const I64_ATOMIC_RMW_XCHG16U: u8 = 0x46;
862 pub const I64_ATOMIC_RMW_XCHG32U: u8 = 0x47;
863
864 pub const I32_ATOMIC_RMW_CMPXCHG: u8 = 0x48;
865 pub const I64_ATOMIC_RMW_CMPXCHG: u8 = 0x49;
866 pub const I32_ATOMIC_RMW_CMPXCHG8U: u8 = 0x4a;
867 pub const I32_ATOMIC_RMW_CMPXCHG16U: u8 = 0x4b;
868 pub const I64_ATOMIC_RMW_CMPXCHG8U: u8 = 0x4c;
869 pub const I64_ATOMIC_RMW_CMPXCHG16U: u8 = 0x4d;
870 pub const I64_ATOMIC_RMW_CMPXCHG32U: u8 = 0x4e;
871 }
872
873 #[cfg(feature = "simd")]
874 pub mod simd {
875 pub const SIMD_PREFIX: u8 = 0xfd;
877
878 pub const V128_LOAD: u32 = 0x00;
879 pub const V128_STORE: u32 = 0x01;
880 pub const V128_CONST: u32 = 0x02;
881 pub const V8X16_SHUFFLE: u32 = 0x03;
882
883 pub const I8X16_SPLAT: u32 = 0x04;
884 pub const I8X16_EXTRACT_LANE_S: u32 = 0x05;
885 pub const I8X16_EXTRACT_LANE_U: u32 = 0x06;
886 pub const I8X16_REPLACE_LANE: u32 = 0x07;
887 pub const I16X8_SPLAT: u32 = 0x08;
888 pub const I16X8_EXTRACT_LANE_S: u32 = 0x09;
889 pub const I16X8_EXTRACT_LANE_U: u32 = 0xa;
890 pub const I16X8_REPLACE_LANE: u32 = 0x0b;
891 pub const I32X4_SPLAT: u32 = 0x0c;
892 pub const I32X4_EXTRACT_LANE: u32 = 0x0d;
893 pub const I32X4_REPLACE_LANE: u32 = 0x0e;
894 pub const I64X2_SPLAT: u32 = 0x0f;
895 pub const I64X2_EXTRACT_LANE: u32 = 0x10;
896 pub const I64X2_REPLACE_LANE: u32 = 0x11;
897 pub const F32X4_SPLAT: u32 = 0x12;
898 pub const F32X4_EXTRACT_LANE: u32 = 0x13;
899 pub const F32X4_REPLACE_LANE: u32 = 0x14;
900 pub const F64X2_SPLAT: u32 = 0x15;
901 pub const F64X2_EXTRACT_LANE: u32 = 0x16;
902 pub const F64X2_REPLACE_LANE: u32 = 0x17;
903
904 pub const I8X16_EQ: u32 = 0x18;
905 pub const I8X16_NE: u32 = 0x19;
906 pub const I8X16_LT_S: u32 = 0x1a;
907 pub const I8X16_LT_U: u32 = 0x1b;
908 pub const I8X16_GT_S: u32 = 0x1c;
909 pub const I8X16_GT_U: u32 = 0x1d;
910 pub const I8X16_LE_S: u32 = 0x1e;
911 pub const I8X16_LE_U: u32 = 0x1f;
912 pub const I8X16_GE_S: u32 = 0x20;
913 pub const I8X16_GE_U: u32 = 0x21;
914
915 pub const I16X8_EQ: u32 = 0x22;
916 pub const I16X8_NE: u32 = 0x23;
917 pub const I16X8_LT_S: u32 = 0x24;
918 pub const I16X8_LT_U: u32 = 0x25;
919 pub const I16X8_GT_S: u32 = 0x26;
920 pub const I16X8_GT_U: u32 = 0x27;
921 pub const I16X8_LE_S: u32 = 0x28;
922 pub const I16X8_LE_U: u32 = 0x29;
923 pub const I16X8_GE_S: u32 = 0x2a;
924 pub const I16X8_GE_U: u32 = 0x2b;
925
926 pub const I32X4_EQ: u32 = 0x2c;
927 pub const I32X4_NE: u32 = 0x2d;
928 pub const I32X4_LT_S: u32 = 0x2e;
929 pub const I32X4_LT_U: u32 = 0x2f;
930 pub const I32X4_GT_S: u32 = 0x30;
931 pub const I32X4_GT_U: u32 = 0x31;
932 pub const I32X4_LE_S: u32 = 0x32;
933 pub const I32X4_LE_U: u32 = 0x33;
934 pub const I32X4_GE_S: u32 = 0x34;
935 pub const I32X4_GE_U: u32 = 0x35;
936
937 pub const F32X4_EQ: u32 = 0x40;
938 pub const F32X4_NE: u32 = 0x41;
939 pub const F32X4_LT: u32 = 0x42;
940 pub const F32X4_GT: u32 = 0x43;
941 pub const F32X4_LE: u32 = 0x44;
942 pub const F32X4_GE: u32 = 0x45;
943
944 pub const F64X2_EQ: u32 = 0x46;
945 pub const F64X2_NE: u32 = 0x47;
946 pub const F64X2_LT: u32 = 0x48;
947 pub const F64X2_GT: u32 = 0x49;
948 pub const F64X2_LE: u32 = 0x4a;
949 pub const F64X2_GE: u32 = 0x4b;
950
951 pub const V128_NOT: u32 = 0x4c;
952 pub const V128_AND: u32 = 0x4d;
953 pub const V128_OR: u32 = 0x4e;
954 pub const V128_XOR: u32 = 0x4f;
955 pub const V128_BITSELECT: u32 = 0x50;
956
957 pub const I8X16_NEG: u32 = 0x51;
958 pub const I8X16_ANY_TRUE: u32 = 0x52;
959 pub const I8X16_ALL_TRUE: u32 = 0x53;
960 pub const I8X16_SHL: u32 = 0x54;
961 pub const I8X16_SHR_S: u32 = 0x55;
962 pub const I8X16_SHR_U: u32 = 0x56;
963 pub const I8X16_ADD: u32 = 0x57;
964 pub const I8X16_ADD_SATURATE_S: u32 = 0x58;
965 pub const I8X16_ADD_SATURATE_U: u32 = 0x59;
966 pub const I8X16_SUB: u32 = 0x5a;
967 pub const I8X16_SUB_SATURATE_S: u32 = 0x5b;
968 pub const I8X16_SUB_SATURATE_U: u32 = 0x5c;
969 pub const I8X16_MUL: u32 = 0x5d;
970
971 pub const I16X8_NEG: u32 = 0x62;
972 pub const I16X8_ANY_TRUE: u32 = 0x63;
973 pub const I16X8_ALL_TRUE: u32 = 0x64;
974 pub const I16X8_SHL: u32 = 0x65;
975 pub const I16X8_SHR_S: u32 = 0x66;
976 pub const I16X8_SHR_U: u32 = 0x67;
977 pub const I16X8_ADD: u32 = 0x68;
978 pub const I16X8_ADD_SATURATE_S: u32 = 0x69;
979 pub const I16X8_ADD_SATURATE_U: u32 = 0x6a;
980 pub const I16X8_SUB: u32 = 0x6b;
981 pub const I16X8_SUB_SATURATE_S: u32 = 0x6c;
982 pub const I16X8_SUB_SATURATE_U: u32 = 0x6d;
983 pub const I16X8_MUL: u32 = 0x6e;
984
985 pub const I32X4_NEG: u32 = 0x73;
986 pub const I32X4_ANY_TRUE: u32 = 0x74;
987 pub const I32X4_ALL_TRUE: u32 = 0x75;
988 pub const I32X4_SHL: u32 = 0x76;
989 pub const I32X4_SHR_S: u32 = 0x77;
990 pub const I32X4_SHR_U: u32 = 0x78;
991 pub const I32X4_ADD: u32 = 0x79;
992 pub const I32X4_ADD_SATURATE_S: u32 = 0x7a;
993 pub const I32X4_ADD_SATURATE_U: u32 = 0x7b;
994 pub const I32X4_SUB: u32 = 0x7c;
995 pub const I32X4_SUB_SATURATE_S: u32 = 0x7d;
996 pub const I32X4_SUB_SATURATE_U: u32 = 0x7e;
997 pub const I32X4_MUL: u32 = 0x7f;
998
999 pub const I64X2_NEG: u32 = 0x84;
1000 pub const I64X2_ANY_TRUE: u32 = 0x85;
1001 pub const I64X2_ALL_TRUE: u32 = 0x86;
1002 pub const I64X2_SHL: u32 = 0x87;
1003 pub const I64X2_SHR_S: u32 = 0x88;
1004 pub const I64X2_SHR_U: u32 = 0x89;
1005 pub const I64X2_ADD: u32 = 0x8a;
1006 pub const I64X2_SUB: u32 = 0x8d;
1007
1008 pub const F32X4_ABS: u32 = 0x95;
1009 pub const F32X4_NEG: u32 = 0x96;
1010 pub const F32X4_SQRT: u32 = 0x97;
1011 pub const F32X4_ADD: u32 = 0x9a;
1012 pub const F32X4_SUB: u32 = 0x9b;
1013 pub const F32X4_MUL: u32 = 0x9c;
1014 pub const F32X4_DIV: u32 = 0x9d;
1015 pub const F32X4_MIN: u32 = 0x9e;
1016 pub const F32X4_MAX: u32 = 0x9f;
1017
1018 pub const F64X2_ABS: u32 = 0xa0;
1019 pub const F64X2_NEG: u32 = 0xa1;
1020 pub const F64X2_SQRT: u32 = 0xa2;
1021 pub const F64X2_ADD: u32 = 0xa5;
1022 pub const F64X2_SUB: u32 = 0xa6;
1023 pub const F64X2_MUL: u32 = 0xa7;
1024 pub const F64X2_DIV: u32 = 0xa8;
1025 pub const F64X2_MIN: u32 = 0xa9;
1026 pub const F64X2_MAX: u32 = 0xaa;
1027
1028 pub const I32X4_TRUNC_S_F32X4_SAT: u32 = 0xab;
1029 pub const I32X4_TRUNC_U_F32X4_SAT: u32 = 0xac;
1030 pub const I64X2_TRUNC_S_F64X2_SAT: u32 = 0xad;
1031 pub const I64X2_TRUNC_U_F64X2_SAT: u32 = 0xae;
1032
1033 pub const F32X4_CONVERT_S_I32X4: u32 = 0xaf;
1034 pub const F32X4_CONVERT_U_I32X4: u32 = 0xb0;
1035 pub const F64X2_CONVERT_S_I64X2: u32 = 0xb1;
1036 pub const F64X2_CONVERT_U_I64X2: u32 = 0xb2;
1037 }
1038
1039 #[cfg(feature = "bulk")]
1040 pub mod bulk {
1041 pub const BULK_PREFIX: u8 = 0xfc;
1042 pub const MEMORY_INIT: u8 = 0x08;
1043 pub const MEMORY_DROP: u8 = 0x09;
1044 pub const MEMORY_COPY: u8 = 0x0a;
1045 pub const MEMORY_FILL: u8 = 0x0b;
1046 pub const TABLE_INIT: u8 = 0x0c;
1047 pub const TABLE_DROP: u8 = 0x0d;
1048 pub const TABLE_COPY: u8 = 0x0e;
1049 }
1050}
1051
1052impl Deserialize for Instruction {
1053 type Error = Error;
1054
1055 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
1056 use self::{opcodes::*, Instruction::*};
1057
1058 #[cfg(feature = "sign_ext")]
1059 use self::opcodes::sign_ext::*;
1060
1061 let val: u8 = Uint8::deserialize(reader)?.into();
1062
1063 Ok(match val {
1064 UNREACHABLE => Unreachable,
1065 NOP => Nop,
1066 BLOCK => Block(BlockType::deserialize(reader)?),
1067 LOOP => Loop(BlockType::deserialize(reader)?),
1068 IF => If(BlockType::deserialize(reader)?),
1069 ELSE => Else,
1070 END => End,
1071
1072 BR => Br(VarUint32::deserialize(reader)?.into()),
1073 BRIF => BrIf(VarUint32::deserialize(reader)?.into()),
1074 BRTABLE => {
1075 let t1: Vec<u32> = CountedList::<VarUint32>::deserialize(reader)?
1076 .into_inner()
1077 .into_iter()
1078 .map(Into::into)
1079 .collect();
1080
1081 BrTable(Box::new(BrTableData {
1082 table: t1.into_boxed_slice(),
1083 default: VarUint32::deserialize(reader)?.into(),
1084 }))
1085 },
1086 RETURN => Return,
1087 CALL => Call(VarUint32::deserialize(reader)?.into()),
1088 CALLINDIRECT => {
1089 let signature: u32 = VarUint32::deserialize(reader)?.into();
1090 let table_ref_lead: u8 = Uint8::deserialize(reader)?.into();
1091
1092 #[cfg(feature = "call_indirect_overlong")]
1093 let table_ref = if table_ref_lead & 0x80 == 0 {
1094 u32::from(table_ref_lead)
1097 } else {
1098 VarUint32::deserialize_with_first(reader, table_ref_lead)?.into()
1101 };
1102
1103 #[cfg(not(feature = "call_indirect_overlong"))]
1104 let table_ref = {
1105 if table_ref_lead != 0 {
1106 return Err(Error::InvalidTableReference(table_ref_lead));
1107 }
1108 u32::from(table_ref_lead)
1109 };
1110
1111 CallIndirect(signature, table_ref)
1112 },
1113 DROP => Drop,
1114 SELECT => Select,
1115
1116 GETLOCAL => GetLocal(VarUint32::deserialize(reader)?.into()),
1117 SETLOCAL => SetLocal(VarUint32::deserialize(reader)?.into()),
1118 TEELOCAL => TeeLocal(VarUint32::deserialize(reader)?.into()),
1119 GETGLOBAL => GetGlobal(VarUint32::deserialize(reader)?.into()),
1120 SETGLOBAL => SetGlobal(VarUint32::deserialize(reader)?.into()),
1121
1122 I32LOAD => I32Load(
1123 VarUint32::deserialize(reader)?.into(),
1124 VarUint32::deserialize(reader)?.into(),
1125 ),
1126
1127 I64LOAD => I64Load(
1128 VarUint32::deserialize(reader)?.into(),
1129 VarUint32::deserialize(reader)?.into(),
1130 ),
1131
1132 F32LOAD => F32Load(
1133 VarUint32::deserialize(reader)?.into(),
1134 VarUint32::deserialize(reader)?.into(),
1135 ),
1136
1137 F64LOAD => F64Load(
1138 VarUint32::deserialize(reader)?.into(),
1139 VarUint32::deserialize(reader)?.into(),
1140 ),
1141
1142 I32LOAD8S => I32Load8S(
1143 VarUint32::deserialize(reader)?.into(),
1144 VarUint32::deserialize(reader)?.into(),
1145 ),
1146
1147 I32LOAD8U => I32Load8U(
1148 VarUint32::deserialize(reader)?.into(),
1149 VarUint32::deserialize(reader)?.into(),
1150 ),
1151
1152 I32LOAD16S => I32Load16S(
1153 VarUint32::deserialize(reader)?.into(),
1154 VarUint32::deserialize(reader)?.into(),
1155 ),
1156
1157 I32LOAD16U => I32Load16U(
1158 VarUint32::deserialize(reader)?.into(),
1159 VarUint32::deserialize(reader)?.into(),
1160 ),
1161
1162 I64LOAD8S => I64Load8S(
1163 VarUint32::deserialize(reader)?.into(),
1164 VarUint32::deserialize(reader)?.into(),
1165 ),
1166
1167 I64LOAD8U => I64Load8U(
1168 VarUint32::deserialize(reader)?.into(),
1169 VarUint32::deserialize(reader)?.into(),
1170 ),
1171
1172 I64LOAD16S => I64Load16S(
1173 VarUint32::deserialize(reader)?.into(),
1174 VarUint32::deserialize(reader)?.into(),
1175 ),
1176
1177 I64LOAD16U => I64Load16U(
1178 VarUint32::deserialize(reader)?.into(),
1179 VarUint32::deserialize(reader)?.into(),
1180 ),
1181
1182 I64LOAD32S => I64Load32S(
1183 VarUint32::deserialize(reader)?.into(),
1184 VarUint32::deserialize(reader)?.into(),
1185 ),
1186
1187 I64LOAD32U => I64Load32U(
1188 VarUint32::deserialize(reader)?.into(),
1189 VarUint32::deserialize(reader)?.into(),
1190 ),
1191
1192 I32STORE => I32Store(
1193 VarUint32::deserialize(reader)?.into(),
1194 VarUint32::deserialize(reader)?.into(),
1195 ),
1196
1197 I64STORE => I64Store(
1198 VarUint32::deserialize(reader)?.into(),
1199 VarUint32::deserialize(reader)?.into(),
1200 ),
1201
1202 F32STORE => F32Store(
1203 VarUint32::deserialize(reader)?.into(),
1204 VarUint32::deserialize(reader)?.into(),
1205 ),
1206
1207 F64STORE => F64Store(
1208 VarUint32::deserialize(reader)?.into(),
1209 VarUint32::deserialize(reader)?.into(),
1210 ),
1211
1212 I32STORE8 => I32Store8(
1213 VarUint32::deserialize(reader)?.into(),
1214 VarUint32::deserialize(reader)?.into(),
1215 ),
1216
1217 I32STORE16 => I32Store16(
1218 VarUint32::deserialize(reader)?.into(),
1219 VarUint32::deserialize(reader)?.into(),
1220 ),
1221
1222 I64STORE8 => I64Store8(
1223 VarUint32::deserialize(reader)?.into(),
1224 VarUint32::deserialize(reader)?.into(),
1225 ),
1226
1227 I64STORE16 => I64Store16(
1228 VarUint32::deserialize(reader)?.into(),
1229 VarUint32::deserialize(reader)?.into(),
1230 ),
1231
1232 I64STORE32 => I64Store32(
1233 VarUint32::deserialize(reader)?.into(),
1234 VarUint32::deserialize(reader)?.into(),
1235 ),
1236
1237 CURRENTMEMORY => {
1238 let mem_ref: u8 = Uint8::deserialize(reader)?.into();
1239 if mem_ref != 0 {
1240 return Err(Error::InvalidMemoryReference(mem_ref));
1241 }
1242 CurrentMemory(mem_ref)
1243 },
1244 GROWMEMORY => {
1245 let mem_ref: u8 = Uint8::deserialize(reader)?.into();
1246 if mem_ref != 0 {
1247 return Err(Error::InvalidMemoryReference(mem_ref));
1248 }
1249 GrowMemory(mem_ref)
1250 },
1251
1252 I32CONST => I32Const(VarInt32::deserialize(reader)?.into()),
1253 I64CONST => I64Const(VarInt64::deserialize(reader)?.into()),
1254 F32CONST => F32Const(Uint32::deserialize(reader)?.into()),
1255 F64CONST => F64Const(Uint64::deserialize(reader)?.into()),
1256 I32EQZ => I32Eqz,
1257 I32EQ => I32Eq,
1258 I32NE => I32Ne,
1259 I32LTS => I32LtS,
1260 I32LTU => I32LtU,
1261 I32GTS => I32GtS,
1262 I32GTU => I32GtU,
1263 I32LES => I32LeS,
1264 I32LEU => I32LeU,
1265 I32GES => I32GeS,
1266 I32GEU => I32GeU,
1267
1268 I64EQZ => I64Eqz,
1269 I64EQ => I64Eq,
1270 I64NE => I64Ne,
1271 I64LTS => I64LtS,
1272 I64LTU => I64LtU,
1273 I64GTS => I64GtS,
1274 I64GTU => I64GtU,
1275 I64LES => I64LeS,
1276 I64LEU => I64LeU,
1277 I64GES => I64GeS,
1278 I64GEU => I64GeU,
1279
1280 F32EQ => F32Eq,
1281 F32NE => F32Ne,
1282 F32LT => F32Lt,
1283 F32GT => F32Gt,
1284 F32LE => F32Le,
1285 F32GE => F32Ge,
1286
1287 F64EQ => F64Eq,
1288 F64NE => F64Ne,
1289 F64LT => F64Lt,
1290 F64GT => F64Gt,
1291 F64LE => F64Le,
1292 F64GE => F64Ge,
1293
1294 I32CLZ => I32Clz,
1295 I32CTZ => I32Ctz,
1296 I32POPCNT => I32Popcnt,
1297 I32ADD => I32Add,
1298 I32SUB => I32Sub,
1299 I32MUL => I32Mul,
1300 I32DIVS => I32DivS,
1301 I32DIVU => I32DivU,
1302 I32REMS => I32RemS,
1303 I32REMU => I32RemU,
1304 I32AND => I32And,
1305 I32OR => I32Or,
1306 I32XOR => I32Xor,
1307 I32SHL => I32Shl,
1308 I32SHRS => I32ShrS,
1309 I32SHRU => I32ShrU,
1310 I32ROTL => I32Rotl,
1311 I32ROTR => I32Rotr,
1312
1313 I64CLZ => I64Clz,
1314 I64CTZ => I64Ctz,
1315 I64POPCNT => I64Popcnt,
1316 I64ADD => I64Add,
1317 I64SUB => I64Sub,
1318 I64MUL => I64Mul,
1319 I64DIVS => I64DivS,
1320 I64DIVU => I64DivU,
1321 I64REMS => I64RemS,
1322 I64REMU => I64RemU,
1323 I64AND => I64And,
1324 I64OR => I64Or,
1325 I64XOR => I64Xor,
1326 I64SHL => I64Shl,
1327 I64SHRS => I64ShrS,
1328 I64SHRU => I64ShrU,
1329 I64ROTL => I64Rotl,
1330 I64ROTR => I64Rotr,
1331 F32ABS => F32Abs,
1332 F32NEG => F32Neg,
1333 F32CEIL => F32Ceil,
1334 F32FLOOR => F32Floor,
1335 F32TRUNC => F32Trunc,
1336 F32NEAREST => F32Nearest,
1337 F32SQRT => F32Sqrt,
1338 F32ADD => F32Add,
1339 F32SUB => F32Sub,
1340 F32MUL => F32Mul,
1341 F32DIV => F32Div,
1342 F32MIN => F32Min,
1343 F32MAX => F32Max,
1344 F32COPYSIGN => F32Copysign,
1345 F64ABS => F64Abs,
1346 F64NEG => F64Neg,
1347 F64CEIL => F64Ceil,
1348 F64FLOOR => F64Floor,
1349 F64TRUNC => F64Trunc,
1350 F64NEAREST => F64Nearest,
1351 F64SQRT => F64Sqrt,
1352 F64ADD => F64Add,
1353 F64SUB => F64Sub,
1354 F64MUL => F64Mul,
1355 F64DIV => F64Div,
1356 F64MIN => F64Min,
1357 F64MAX => F64Max,
1358 F64COPYSIGN => F64Copysign,
1359
1360 I32WRAPI64 => I32WrapI64,
1361 I32TRUNCSF32 => I32TruncSF32,
1362 I32TRUNCUF32 => I32TruncUF32,
1363 I32TRUNCSF64 => I32TruncSF64,
1364 I32TRUNCUF64 => I32TruncUF64,
1365 I64EXTENDSI32 => I64ExtendSI32,
1366 I64EXTENDUI32 => I64ExtendUI32,
1367 I64TRUNCSF32 => I64TruncSF32,
1368 I64TRUNCUF32 => I64TruncUF32,
1369 I64TRUNCSF64 => I64TruncSF64,
1370 I64TRUNCUF64 => I64TruncUF64,
1371 F32CONVERTSI32 => F32ConvertSI32,
1372 F32CONVERTUI32 => F32ConvertUI32,
1373 F32CONVERTSI64 => F32ConvertSI64,
1374 F32CONVERTUI64 => F32ConvertUI64,
1375 F32DEMOTEF64 => F32DemoteF64,
1376 F64CONVERTSI32 => F64ConvertSI32,
1377 F64CONVERTUI32 => F64ConvertUI32,
1378 F64CONVERTSI64 => F64ConvertSI64,
1379 F64CONVERTUI64 => F64ConvertUI64,
1380 F64PROMOTEF32 => F64PromoteF32,
1381
1382 I32REINTERPRETF32 => I32ReinterpretF32,
1383 I64REINTERPRETF64 => I64ReinterpretF64,
1384 F32REINTERPRETI32 => F32ReinterpretI32,
1385 F64REINTERPRETI64 => F64ReinterpretI64,
1386
1387 #[cfg(feature = "sign_ext")]
1388 I32_EXTEND8_S | I32_EXTEND16_S | I64_EXTEND8_S | I64_EXTEND16_S | I64_EXTEND32_S => match val {
1389 I32_EXTEND8_S => SignExt(SignExtInstruction::I32Extend8S),
1390 I32_EXTEND16_S => SignExt(SignExtInstruction::I32Extend16S),
1391 I64_EXTEND8_S => SignExt(SignExtInstruction::I64Extend8S),
1392 I64_EXTEND16_S => SignExt(SignExtInstruction::I64Extend16S),
1393 I64_EXTEND32_S => SignExt(SignExtInstruction::I64Extend32S),
1394 _ => return Err(Error::UnknownOpcode(val)),
1395 },
1396
1397 #[cfg(feature = "atomics")]
1398 atomics::ATOMIC_PREFIX => return deserialize_atomic(reader),
1399
1400 #[cfg(feature = "simd")]
1401 simd::SIMD_PREFIX => return deserialize_simd(reader),
1402
1403 #[cfg(feature = "bulk")]
1404 bulk::BULK_PREFIX => return deserialize_bulk(reader),
1405
1406 _ => return Err(Error::UnknownOpcode(val)),
1407 })
1408 }
1409}
1410
1411#[cfg(feature = "atomics")]
1412fn deserialize_atomic<R: io::Read>(reader: &mut R) -> Result<Instruction, Error> {
1413 use self::{opcodes::atomics::*, AtomicsInstruction::*};
1414
1415 let val: u8 = Uint8::deserialize(reader)?.into();
1416 let mem = MemArg::deserialize(reader)?;
1417 Ok(Instruction::Atomics(match val {
1418 ATOMIC_WAKE => AtomicWake(mem),
1419 I32_ATOMIC_WAIT => I32AtomicWait(mem),
1420 I64_ATOMIC_WAIT => I64AtomicWait(mem),
1421
1422 I32_ATOMIC_LOAD => I32AtomicLoad(mem),
1423 I64_ATOMIC_LOAD => I64AtomicLoad(mem),
1424 I32_ATOMIC_LOAD8U => I32AtomicLoad8u(mem),
1425 I32_ATOMIC_LOAD16U => I32AtomicLoad16u(mem),
1426 I64_ATOMIC_LOAD8U => I64AtomicLoad8u(mem),
1427 I64_ATOMIC_LOAD16U => I64AtomicLoad16u(mem),
1428 I64_ATOMIC_LOAD32U => I64AtomicLoad32u(mem),
1429 I32_ATOMIC_STORE => I32AtomicStore(mem),
1430 I64_ATOMIC_STORE => I64AtomicStore(mem),
1431 I32_ATOMIC_STORE8U => I32AtomicStore8u(mem),
1432 I32_ATOMIC_STORE16U => I32AtomicStore16u(mem),
1433 I64_ATOMIC_STORE8U => I64AtomicStore8u(mem),
1434 I64_ATOMIC_STORE16U => I64AtomicStore16u(mem),
1435 I64_ATOMIC_STORE32U => I64AtomicStore32u(mem),
1436
1437 I32_ATOMIC_RMW_ADD => I32AtomicRmwAdd(mem),
1438 I64_ATOMIC_RMW_ADD => I64AtomicRmwAdd(mem),
1439 I32_ATOMIC_RMW_ADD8U => I32AtomicRmwAdd8u(mem),
1440 I32_ATOMIC_RMW_ADD16U => I32AtomicRmwAdd16u(mem),
1441 I64_ATOMIC_RMW_ADD8U => I64AtomicRmwAdd8u(mem),
1442 I64_ATOMIC_RMW_ADD16U => I64AtomicRmwAdd16u(mem),
1443 I64_ATOMIC_RMW_ADD32U => I64AtomicRmwAdd32u(mem),
1444
1445 I32_ATOMIC_RMW_SUB => I32AtomicRmwSub(mem),
1446 I64_ATOMIC_RMW_SUB => I64AtomicRmwSub(mem),
1447 I32_ATOMIC_RMW_SUB8U => I32AtomicRmwSub8u(mem),
1448 I32_ATOMIC_RMW_SUB16U => I32AtomicRmwSub16u(mem),
1449 I64_ATOMIC_RMW_SUB8U => I64AtomicRmwSub8u(mem),
1450 I64_ATOMIC_RMW_SUB16U => I64AtomicRmwSub16u(mem),
1451 I64_ATOMIC_RMW_SUB32U => I64AtomicRmwSub32u(mem),
1452
1453 I32_ATOMIC_RMW_AND => I32AtomicRmwAnd(mem),
1454 I64_ATOMIC_RMW_AND => I64AtomicRmwAnd(mem),
1455 I32_ATOMIC_RMW_AND8U => I32AtomicRmwAnd8u(mem),
1456 I32_ATOMIC_RMW_AND16U => I32AtomicRmwAnd16u(mem),
1457 I64_ATOMIC_RMW_AND8U => I64AtomicRmwAnd8u(mem),
1458 I64_ATOMIC_RMW_AND16U => I64AtomicRmwAnd16u(mem),
1459 I64_ATOMIC_RMW_AND32U => I64AtomicRmwAnd32u(mem),
1460
1461 I32_ATOMIC_RMW_OR => I32AtomicRmwOr(mem),
1462 I64_ATOMIC_RMW_OR => I64AtomicRmwOr(mem),
1463 I32_ATOMIC_RMW_OR8U => I32AtomicRmwOr8u(mem),
1464 I32_ATOMIC_RMW_OR16U => I32AtomicRmwOr16u(mem),
1465 I64_ATOMIC_RMW_OR8U => I64AtomicRmwOr8u(mem),
1466 I64_ATOMIC_RMW_OR16U => I64AtomicRmwOr16u(mem),
1467 I64_ATOMIC_RMW_OR32U => I64AtomicRmwOr32u(mem),
1468
1469 I32_ATOMIC_RMW_XOR => I32AtomicRmwXor(mem),
1470 I64_ATOMIC_RMW_XOR => I64AtomicRmwXor(mem),
1471 I32_ATOMIC_RMW_XOR8U => I32AtomicRmwXor8u(mem),
1472 I32_ATOMIC_RMW_XOR16U => I32AtomicRmwXor16u(mem),
1473 I64_ATOMIC_RMW_XOR8U => I64AtomicRmwXor8u(mem),
1474 I64_ATOMIC_RMW_XOR16U => I64AtomicRmwXor16u(mem),
1475 I64_ATOMIC_RMW_XOR32U => I64AtomicRmwXor32u(mem),
1476
1477 I32_ATOMIC_RMW_XCHG => I32AtomicRmwXchg(mem),
1478 I64_ATOMIC_RMW_XCHG => I64AtomicRmwXchg(mem),
1479 I32_ATOMIC_RMW_XCHG8U => I32AtomicRmwXchg8u(mem),
1480 I32_ATOMIC_RMW_XCHG16U => I32AtomicRmwXchg16u(mem),
1481 I64_ATOMIC_RMW_XCHG8U => I64AtomicRmwXchg8u(mem),
1482 I64_ATOMIC_RMW_XCHG16U => I64AtomicRmwXchg16u(mem),
1483 I64_ATOMIC_RMW_XCHG32U => I64AtomicRmwXchg32u(mem),
1484
1485 I32_ATOMIC_RMW_CMPXCHG => I32AtomicRmwCmpxchg(mem),
1486 I64_ATOMIC_RMW_CMPXCHG => I64AtomicRmwCmpxchg(mem),
1487 I32_ATOMIC_RMW_CMPXCHG8U => I32AtomicRmwCmpxchg8u(mem),
1488 I32_ATOMIC_RMW_CMPXCHG16U => I32AtomicRmwCmpxchg16u(mem),
1489 I64_ATOMIC_RMW_CMPXCHG8U => I64AtomicRmwCmpxchg8u(mem),
1490 I64_ATOMIC_RMW_CMPXCHG16U => I64AtomicRmwCmpxchg16u(mem),
1491 I64_ATOMIC_RMW_CMPXCHG32U => I64AtomicRmwCmpxchg32u(mem),
1492
1493 _ => return Err(Error::UnknownOpcode(val)),
1494 }))
1495}
1496
1497#[cfg(feature = "simd")]
1498fn deserialize_simd<R: io::Read>(reader: &mut R) -> Result<Instruction, Error> {
1499 use self::{opcodes::simd::*, SimdInstruction::*};
1500
1501 let val = VarUint32::deserialize(reader)?.into();
1502 Ok(Instruction::Simd(match val {
1503 V128_CONST => {
1504 let mut buf = [0; 16];
1505 reader.read(&mut buf)?;
1506 V128Const(Box::new(buf))
1507 },
1508 V128_LOAD => V128Load(MemArg::deserialize(reader)?),
1509 V128_STORE => V128Store(MemArg::deserialize(reader)?),
1510 I8X16_SPLAT => I8x16Splat,
1511 I16X8_SPLAT => I16x8Splat,
1512 I32X4_SPLAT => I32x4Splat,
1513 I64X2_SPLAT => I64x2Splat,
1514 F32X4_SPLAT => F32x4Splat,
1515 F64X2_SPLAT => F64x2Splat,
1516 I8X16_EXTRACT_LANE_S => I8x16ExtractLaneS(Uint8::deserialize(reader)?.into()),
1517 I8X16_EXTRACT_LANE_U => I8x16ExtractLaneU(Uint8::deserialize(reader)?.into()),
1518 I16X8_EXTRACT_LANE_S => I16x8ExtractLaneS(Uint8::deserialize(reader)?.into()),
1519 I16X8_EXTRACT_LANE_U => I16x8ExtractLaneU(Uint8::deserialize(reader)?.into()),
1520 I32X4_EXTRACT_LANE => I32x4ExtractLane(Uint8::deserialize(reader)?.into()),
1521 I64X2_EXTRACT_LANE => I64x2ExtractLane(Uint8::deserialize(reader)?.into()),
1522 F32X4_EXTRACT_LANE => F32x4ExtractLane(Uint8::deserialize(reader)?.into()),
1523 F64X2_EXTRACT_LANE => F64x2ExtractLane(Uint8::deserialize(reader)?.into()),
1524 I8X16_REPLACE_LANE => I8x16ReplaceLane(Uint8::deserialize(reader)?.into()),
1525 I16X8_REPLACE_LANE => I16x8ReplaceLane(Uint8::deserialize(reader)?.into()),
1526 I32X4_REPLACE_LANE => I32x4ReplaceLane(Uint8::deserialize(reader)?.into()),
1527 I64X2_REPLACE_LANE => I64x2ReplaceLane(Uint8::deserialize(reader)?.into()),
1528 F32X4_REPLACE_LANE => F32x4ReplaceLane(Uint8::deserialize(reader)?.into()),
1529 F64X2_REPLACE_LANE => F64x2ReplaceLane(Uint8::deserialize(reader)?.into()),
1530 V8X16_SHUFFLE => {
1531 let mut buf = [0; 16];
1532 reader.read(&mut buf)?;
1533 V8x16Shuffle(Box::new(buf))
1534 },
1535 I8X16_ADD => I8x16Add,
1536 I16X8_ADD => I16x8Add,
1537 I32X4_ADD => I32x4Add,
1538 I64X2_ADD => I64x2Add,
1539 I8X16_SUB => I8x16Sub,
1540 I16X8_SUB => I16x8Sub,
1541 I32X4_SUB => I32x4Sub,
1542 I64X2_SUB => I64x2Sub,
1543 I8X16_MUL => I8x16Mul,
1544 I16X8_MUL => I16x8Mul,
1545 I32X4_MUL => I32x4Mul,
1546 I8X16_NEG => I8x16Neg,
1548 I16X8_NEG => I16x8Neg,
1549 I32X4_NEG => I32x4Neg,
1550 I64X2_NEG => I64x2Neg,
1551
1552 I8X16_ADD_SATURATE_S => I8x16AddSaturateS,
1553 I8X16_ADD_SATURATE_U => I8x16AddSaturateU,
1554 I16X8_ADD_SATURATE_S => I16x8AddSaturateS,
1555 I16X8_ADD_SATURATE_U => I16x8AddSaturateU,
1556 I8X16_SUB_SATURATE_S => I8x16SubSaturateS,
1557 I8X16_SUB_SATURATE_U => I8x16SubSaturateU,
1558 I16X8_SUB_SATURATE_S => I16x8SubSaturateS,
1559 I16X8_SUB_SATURATE_U => I16x8SubSaturateU,
1560 I8X16_SHL => I8x16Shl,
1561 I16X8_SHL => I16x8Shl,
1562 I32X4_SHL => I32x4Shl,
1563 I64X2_SHL => I64x2Shl,
1564 I8X16_SHR_S => I8x16ShrS,
1565 I8X16_SHR_U => I8x16ShrU,
1566 I16X8_SHR_S => I16x8ShrS,
1567 I16X8_SHR_U => I16x8ShrU,
1568 I32X4_SHR_S => I32x4ShrS,
1569 I32X4_SHR_U => I32x4ShrU,
1570 I64X2_SHR_S => I64x2ShrS,
1571 I64X2_SHR_U => I64x2ShrU,
1572 V128_AND => V128And,
1573 V128_OR => V128Or,
1574 V128_XOR => V128Xor,
1575 V128_NOT => V128Not,
1576 V128_BITSELECT => V128Bitselect,
1577 I8X16_ANY_TRUE => I8x16AnyTrue,
1578 I16X8_ANY_TRUE => I16x8AnyTrue,
1579 I32X4_ANY_TRUE => I32x4AnyTrue,
1580 I64X2_ANY_TRUE => I64x2AnyTrue,
1581 I8X16_ALL_TRUE => I8x16AllTrue,
1582 I16X8_ALL_TRUE => I16x8AllTrue,
1583 I32X4_ALL_TRUE => I32x4AllTrue,
1584 I64X2_ALL_TRUE => I64x2AllTrue,
1585 I8X16_EQ => I8x16Eq,
1586 I16X8_EQ => I16x8Eq,
1587 I32X4_EQ => I32x4Eq,
1588 F32X4_EQ => F32x4Eq,
1590 F64X2_EQ => F64x2Eq,
1591 I8X16_NE => I8x16Ne,
1592 I16X8_NE => I16x8Ne,
1593 I32X4_NE => I32x4Ne,
1594 F32X4_NE => F32x4Ne,
1596 F64X2_NE => F64x2Ne,
1597 I8X16_LT_S => I8x16LtS,
1598 I8X16_LT_U => I8x16LtU,
1599 I16X8_LT_S => I16x8LtS,
1600 I16X8_LT_U => I16x8LtU,
1601 I32X4_LT_S => I32x4LtS,
1602 I32X4_LT_U => I32x4LtU,
1603 F32X4_LT => F32x4Lt,
1606 F64X2_LT => F64x2Lt,
1607 I8X16_LE_S => I8x16LeS,
1608 I8X16_LE_U => I8x16LeU,
1609 I16X8_LE_S => I16x8LeS,
1610 I16X8_LE_U => I16x8LeU,
1611 I32X4_LE_S => I32x4LeS,
1612 I32X4_LE_U => I32x4LeU,
1613 F32X4_LE => F32x4Le,
1616 F64X2_LE => F64x2Le,
1617 I8X16_GT_S => I8x16GtS,
1618 I8X16_GT_U => I8x16GtU,
1619 I16X8_GT_S => I16x8GtS,
1620 I16X8_GT_U => I16x8GtU,
1621 I32X4_GT_S => I32x4GtS,
1622 I32X4_GT_U => I32x4GtU,
1623 F32X4_GT => F32x4Gt,
1626 F64X2_GT => F64x2Gt,
1627 I8X16_GE_S => I8x16GeS,
1628 I8X16_GE_U => I8x16GeU,
1629 I16X8_GE_S => I16x8GeS,
1630 I16X8_GE_U => I16x8GeU,
1631 I32X4_GE_S => I32x4GeS,
1632 I32X4_GE_U => I32x4GeU,
1633 F32X4_GE => F32x4Ge,
1636 F64X2_GE => F64x2Ge,
1637 F32X4_NEG => F32x4Neg,
1638 F64X2_NEG => F64x2Neg,
1639 F32X4_ABS => F32x4Abs,
1640 F64X2_ABS => F64x2Abs,
1641 F32X4_MIN => F32x4Min,
1642 F64X2_MIN => F64x2Min,
1643 F32X4_MAX => F32x4Max,
1644 F64X2_MAX => F64x2Max,
1645 F32X4_ADD => F32x4Add,
1646 F64X2_ADD => F64x2Add,
1647 F32X4_SUB => F32x4Sub,
1648 F64X2_SUB => F64x2Sub,
1649 F32X4_DIV => F32x4Div,
1650 F64X2_DIV => F64x2Div,
1651 F32X4_MUL => F32x4Mul,
1652 F64X2_MUL => F64x2Mul,
1653 F32X4_SQRT => F32x4Sqrt,
1654 F64X2_SQRT => F64x2Sqrt,
1655 F32X4_CONVERT_S_I32X4 => F32x4ConvertSI32x4,
1656 F32X4_CONVERT_U_I32X4 => F32x4ConvertUI32x4,
1657 F64X2_CONVERT_S_I64X2 => F64x2ConvertSI64x2,
1658 F64X2_CONVERT_U_I64X2 => F64x2ConvertUI64x2,
1659 I32X4_TRUNC_S_F32X4_SAT => I32x4TruncSF32x4Sat,
1660 I32X4_TRUNC_U_F32X4_SAT => I32x4TruncUF32x4Sat,
1661 I64X2_TRUNC_S_F64X2_SAT => I64x2TruncSF64x2Sat,
1662 I64X2_TRUNC_U_F64X2_SAT => I64x2TruncUF64x2Sat,
1663
1664 _ => return Err(Error::UnknownSimdOpcode(val)),
1665 }))
1666}
1667
1668#[cfg(feature = "bulk")]
1669fn deserialize_bulk<R: io::Read>(reader: &mut R) -> Result<Instruction, Error> {
1670 use self::{opcodes::bulk::*, BulkInstruction::*};
1671
1672 let val: u8 = Uint8::deserialize(reader)?.into();
1673 Ok(Instruction::Bulk(match val {
1674 MEMORY_INIT => {
1675 if u8::from(Uint8::deserialize(reader)?) != 0 {
1676 return Err(Error::UnknownOpcode(val));
1677 }
1678 MemoryInit(VarUint32::deserialize(reader)?.into())
1679 },
1680 MEMORY_DROP => MemoryDrop(VarUint32::deserialize(reader)?.into()),
1681 MEMORY_FILL => {
1682 if u8::from(Uint8::deserialize(reader)?) != 0 {
1683 return Err(Error::UnknownOpcode(val));
1684 }
1685 MemoryFill
1686 },
1687 MEMORY_COPY => {
1688 if u8::from(Uint8::deserialize(reader)?) != 0 {
1689 return Err(Error::UnknownOpcode(val));
1690 }
1691 MemoryCopy
1692 },
1693
1694 TABLE_INIT => {
1695 if u8::from(Uint8::deserialize(reader)?) != 0 {
1696 return Err(Error::UnknownOpcode(val));
1697 }
1698 TableInit(VarUint32::deserialize(reader)?.into())
1699 },
1700 TABLE_DROP => TableDrop(VarUint32::deserialize(reader)?.into()),
1701 TABLE_COPY => {
1702 if u8::from(Uint8::deserialize(reader)?) != 0 {
1703 return Err(Error::UnknownOpcode(val));
1704 }
1705 TableCopy
1706 },
1707
1708 _ => return Err(Error::UnknownOpcode(val)),
1709 }))
1710}
1711
1712#[cfg(any(feature = "simd", feature = "atomics"))]
1713impl Deserialize for MemArg {
1714 type Error = Error;
1715
1716 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
1717 let align = Uint8::deserialize(reader)?;
1718 let offset = VarUint32::deserialize(reader)?;
1719 Ok(MemArg { align: align.into(), offset: offset.into() })
1720 }
1721}
1722
1723macro_rules! op {
1724 ($writer: expr, $byte: expr) => {{
1725 let b: u8 = $byte;
1726 $writer.write(&[b])?;
1727 }};
1728 ($writer: expr, $byte: expr, $s: block) => {{
1729 op!($writer, $byte);
1730 $s;
1731 }};
1732}
1733
1734#[cfg(feature = "atomics")]
1735macro_rules! atomic {
1736 ($writer: expr, $byte: expr, $mem:expr) => {{
1737 $writer.write(&[ATOMIC_PREFIX, $byte])?;
1738 MemArg::serialize($mem, $writer)?;
1739 }};
1740}
1741
1742#[cfg(feature = "simd")]
1743macro_rules! simd {
1744 ($writer: expr, $byte: expr, $other:expr) => {{
1745 $writer.write(&[SIMD_PREFIX])?;
1746 VarUint32::from($byte).serialize($writer)?;
1747 $other;
1748 }};
1749}
1750
1751#[cfg(feature = "bulk")]
1752macro_rules! bulk {
1753 ($writer: expr, $byte: expr) => {{
1754 $writer.write(&[BULK_PREFIX, $byte])?;
1755 }};
1756 ($writer: expr, $byte: expr, $remaining:expr) => {{
1757 bulk!($writer, $byte);
1758 $remaining;
1759 }};
1760}
1761
1762impl Serialize for Instruction {
1763 type Error = Error;
1764
1765 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
1766 use self::{opcodes::*, Instruction::*};
1767
1768 match self {
1769 Unreachable => op!(writer, UNREACHABLE),
1770 Nop => op!(writer, NOP),
1771 Block(block_type) => op!(writer, BLOCK, {
1772 block_type.serialize(writer)?;
1773 }),
1774 Loop(block_type) => op!(writer, LOOP, {
1775 block_type.serialize(writer)?;
1776 }),
1777 If(block_type) => op!(writer, IF, {
1778 block_type.serialize(writer)?;
1779 }),
1780 Else => op!(writer, ELSE),
1781 End => op!(writer, END),
1782 Br(idx) => op!(writer, BR, {
1783 VarUint32::from(idx).serialize(writer)?;
1784 }),
1785 BrIf(idx) => op!(writer, BRIF, {
1786 VarUint32::from(idx).serialize(writer)?;
1787 }),
1788 BrTable(ref table) => op!(writer, BRTABLE, {
1789 let list_writer = CountedListWriter::<VarUint32, _>(
1790 table.table.len(),
1791 table.table.iter().map(|x| VarUint32::from(*x)),
1792 );
1793 list_writer.serialize(writer)?;
1794 VarUint32::from(table.default).serialize(writer)?;
1795 }),
1796 Return => op!(writer, RETURN),
1797 Call(index) => op!(writer, CALL, {
1798 VarUint32::from(index).serialize(writer)?;
1799 }),
1800 CallIndirect(index, reserved) => op!(writer, CALLINDIRECT, {
1801 VarUint32::from(index).serialize(writer)?;
1802 VarUint32::from(reserved).serialize(writer)?;
1803 }),
1804 Drop => op!(writer, DROP),
1805 Select => op!(writer, SELECT),
1806 GetLocal(index) => op!(writer, GETLOCAL, {
1807 VarUint32::from(index).serialize(writer)?;
1808 }),
1809 SetLocal(index) => op!(writer, SETLOCAL, {
1810 VarUint32::from(index).serialize(writer)?;
1811 }),
1812 TeeLocal(index) => op!(writer, TEELOCAL, {
1813 VarUint32::from(index).serialize(writer)?;
1814 }),
1815 GetGlobal(index) => op!(writer, GETGLOBAL, {
1816 VarUint32::from(index).serialize(writer)?;
1817 }),
1818 SetGlobal(index) => op!(writer, SETGLOBAL, {
1819 VarUint32::from(index).serialize(writer)?;
1820 }),
1821 I32Load(flags, offset) => op!(writer, I32LOAD, {
1822 VarUint32::from(flags).serialize(writer)?;
1823 VarUint32::from(offset).serialize(writer)?;
1824 }),
1825 I64Load(flags, offset) => op!(writer, I64LOAD, {
1826 VarUint32::from(flags).serialize(writer)?;
1827 VarUint32::from(offset).serialize(writer)?;
1828 }),
1829 F32Load(flags, offset) => op!(writer, F32LOAD, {
1830 VarUint32::from(flags).serialize(writer)?;
1831 VarUint32::from(offset).serialize(writer)?;
1832 }),
1833 F64Load(flags, offset) => op!(writer, F64LOAD, {
1834 VarUint32::from(flags).serialize(writer)?;
1835 VarUint32::from(offset).serialize(writer)?;
1836 }),
1837 I32Load8S(flags, offset) => op!(writer, I32LOAD8S, {
1838 VarUint32::from(flags).serialize(writer)?;
1839 VarUint32::from(offset).serialize(writer)?;
1840 }),
1841 I32Load8U(flags, offset) => op!(writer, I32LOAD8U, {
1842 VarUint32::from(flags).serialize(writer)?;
1843 VarUint32::from(offset).serialize(writer)?;
1844 }),
1845 I32Load16S(flags, offset) => op!(writer, I32LOAD16S, {
1846 VarUint32::from(flags).serialize(writer)?;
1847 VarUint32::from(offset).serialize(writer)?;
1848 }),
1849 I32Load16U(flags, offset) => op!(writer, I32LOAD16U, {
1850 VarUint32::from(flags).serialize(writer)?;
1851 VarUint32::from(offset).serialize(writer)?;
1852 }),
1853 I64Load8S(flags, offset) => op!(writer, I64LOAD8S, {
1854 VarUint32::from(flags).serialize(writer)?;
1855 VarUint32::from(offset).serialize(writer)?;
1856 }),
1857 I64Load8U(flags, offset) => op!(writer, I64LOAD8U, {
1858 VarUint32::from(flags).serialize(writer)?;
1859 VarUint32::from(offset).serialize(writer)?;
1860 }),
1861 I64Load16S(flags, offset) => op!(writer, I64LOAD16S, {
1862 VarUint32::from(flags).serialize(writer)?;
1863 VarUint32::from(offset).serialize(writer)?;
1864 }),
1865 I64Load16U(flags, offset) => op!(writer, I64LOAD16U, {
1866 VarUint32::from(flags).serialize(writer)?;
1867 VarUint32::from(offset).serialize(writer)?;
1868 }),
1869 I64Load32S(flags, offset) => op!(writer, I64LOAD32S, {
1870 VarUint32::from(flags).serialize(writer)?;
1871 VarUint32::from(offset).serialize(writer)?;
1872 }),
1873 I64Load32U(flags, offset) => op!(writer, I64LOAD32U, {
1874 VarUint32::from(flags).serialize(writer)?;
1875 VarUint32::from(offset).serialize(writer)?;
1876 }),
1877 I32Store(flags, offset) => op!(writer, I32STORE, {
1878 VarUint32::from(flags).serialize(writer)?;
1879 VarUint32::from(offset).serialize(writer)?;
1880 }),
1881 I64Store(flags, offset) => op!(writer, I64STORE, {
1882 VarUint32::from(flags).serialize(writer)?;
1883 VarUint32::from(offset).serialize(writer)?;
1884 }),
1885 F32Store(flags, offset) => op!(writer, F32STORE, {
1886 VarUint32::from(flags).serialize(writer)?;
1887 VarUint32::from(offset).serialize(writer)?;
1888 }),
1889 F64Store(flags, offset) => op!(writer, F64STORE, {
1890 VarUint32::from(flags).serialize(writer)?;
1891 VarUint32::from(offset).serialize(writer)?;
1892 }),
1893 I32Store8(flags, offset) => op!(writer, I32STORE8, {
1894 VarUint32::from(flags).serialize(writer)?;
1895 VarUint32::from(offset).serialize(writer)?;
1896 }),
1897 I32Store16(flags, offset) => op!(writer, I32STORE16, {
1898 VarUint32::from(flags).serialize(writer)?;
1899 VarUint32::from(offset).serialize(writer)?;
1900 }),
1901 I64Store8(flags, offset) => op!(writer, I64STORE8, {
1902 VarUint32::from(flags).serialize(writer)?;
1903 VarUint32::from(offset).serialize(writer)?;
1904 }),
1905 I64Store16(flags, offset) => op!(writer, I64STORE16, {
1906 VarUint32::from(flags).serialize(writer)?;
1907 VarUint32::from(offset).serialize(writer)?;
1908 }),
1909 I64Store32(flags, offset) => op!(writer, I64STORE32, {
1910 VarUint32::from(flags).serialize(writer)?;
1911 VarUint32::from(offset).serialize(writer)?;
1912 }),
1913 CurrentMemory(flag) => op!(writer, CURRENTMEMORY, {
1914 Uint8::from(flag).serialize(writer)?;
1915 }),
1916 GrowMemory(flag) => op!(writer, GROWMEMORY, {
1917 Uint8::from(flag).serialize(writer)?;
1918 }),
1919 I32Const(def) => op!(writer, I32CONST, {
1920 VarInt32::from(def).serialize(writer)?;
1921 }),
1922 I64Const(def) => op!(writer, I64CONST, {
1923 VarInt64::from(def).serialize(writer)?;
1924 }),
1925 F32Const(def) => op!(writer, F32CONST, {
1926 Uint32::from(def).serialize(writer)?;
1927 }),
1928 F64Const(def) => op!(writer, F64CONST, {
1929 Uint64::from(def).serialize(writer)?;
1930 }),
1931 I32Eqz => op!(writer, I32EQZ),
1932 I32Eq => op!(writer, I32EQ),
1933 I32Ne => op!(writer, I32NE),
1934 I32LtS => op!(writer, I32LTS),
1935 I32LtU => op!(writer, I32LTU),
1936 I32GtS => op!(writer, I32GTS),
1937 I32GtU => op!(writer, I32GTU),
1938 I32LeS => op!(writer, I32LES),
1939 I32LeU => op!(writer, I32LEU),
1940 I32GeS => op!(writer, I32GES),
1941 I32GeU => op!(writer, I32GEU),
1942
1943 I64Eqz => op!(writer, I64EQZ),
1944 I64Eq => op!(writer, I64EQ),
1945 I64Ne => op!(writer, I64NE),
1946 I64LtS => op!(writer, I64LTS),
1947 I64LtU => op!(writer, I64LTU),
1948 I64GtS => op!(writer, I64GTS),
1949 I64GtU => op!(writer, I64GTU),
1950 I64LeS => op!(writer, I64LES),
1951 I64LeU => op!(writer, I64LEU),
1952 I64GeS => op!(writer, I64GES),
1953 I64GeU => op!(writer, I64GEU),
1954
1955 F32Eq => op!(writer, F32EQ),
1956 F32Ne => op!(writer, F32NE),
1957 F32Lt => op!(writer, F32LT),
1958 F32Gt => op!(writer, F32GT),
1959 F32Le => op!(writer, F32LE),
1960 F32Ge => op!(writer, F32GE),
1961
1962 F64Eq => op!(writer, F64EQ),
1963 F64Ne => op!(writer, F64NE),
1964 F64Lt => op!(writer, F64LT),
1965 F64Gt => op!(writer, F64GT),
1966 F64Le => op!(writer, F64LE),
1967 F64Ge => op!(writer, F64GE),
1968
1969 I32Clz => op!(writer, I32CLZ),
1970 I32Ctz => op!(writer, I32CTZ),
1971 I32Popcnt => op!(writer, I32POPCNT),
1972 I32Add => op!(writer, I32ADD),
1973 I32Sub => op!(writer, I32SUB),
1974 I32Mul => op!(writer, I32MUL),
1975 I32DivS => op!(writer, I32DIVS),
1976 I32DivU => op!(writer, I32DIVU),
1977 I32RemS => op!(writer, I32REMS),
1978 I32RemU => op!(writer, I32REMU),
1979 I32And => op!(writer, I32AND),
1980 I32Or => op!(writer, I32OR),
1981 I32Xor => op!(writer, I32XOR),
1982 I32Shl => op!(writer, I32SHL),
1983 I32ShrS => op!(writer, I32SHRS),
1984 I32ShrU => op!(writer, I32SHRU),
1985 I32Rotl => op!(writer, I32ROTL),
1986 I32Rotr => op!(writer, I32ROTR),
1987
1988 I64Clz => op!(writer, I64CLZ),
1989 I64Ctz => op!(writer, I64CTZ),
1990 I64Popcnt => op!(writer, I64POPCNT),
1991 I64Add => op!(writer, I64ADD),
1992 I64Sub => op!(writer, I64SUB),
1993 I64Mul => op!(writer, I64MUL),
1994 I64DivS => op!(writer, I64DIVS),
1995 I64DivU => op!(writer, I64DIVU),
1996 I64RemS => op!(writer, I64REMS),
1997 I64RemU => op!(writer, I64REMU),
1998 I64And => op!(writer, I64AND),
1999 I64Or => op!(writer, I64OR),
2000 I64Xor => op!(writer, I64XOR),
2001 I64Shl => op!(writer, I64SHL),
2002 I64ShrS => op!(writer, I64SHRS),
2003 I64ShrU => op!(writer, I64SHRU),
2004 I64Rotl => op!(writer, I64ROTL),
2005 I64Rotr => op!(writer, I64ROTR),
2006 F32Abs => op!(writer, F32ABS),
2007 F32Neg => op!(writer, F32NEG),
2008 F32Ceil => op!(writer, F32CEIL),
2009 F32Floor => op!(writer, F32FLOOR),
2010 F32Trunc => op!(writer, F32TRUNC),
2011 F32Nearest => op!(writer, F32NEAREST),
2012 F32Sqrt => op!(writer, F32SQRT),
2013 F32Add => op!(writer, F32ADD),
2014 F32Sub => op!(writer, F32SUB),
2015 F32Mul => op!(writer, F32MUL),
2016 F32Div => op!(writer, F32DIV),
2017 F32Min => op!(writer, F32MIN),
2018 F32Max => op!(writer, F32MAX),
2019 F32Copysign => op!(writer, F32COPYSIGN),
2020 F64Abs => op!(writer, F64ABS),
2021 F64Neg => op!(writer, F64NEG),
2022 F64Ceil => op!(writer, F64CEIL),
2023 F64Floor => op!(writer, F64FLOOR),
2024 F64Trunc => op!(writer, F64TRUNC),
2025 F64Nearest => op!(writer, F64NEAREST),
2026 F64Sqrt => op!(writer, F64SQRT),
2027 F64Add => op!(writer, F64ADD),
2028 F64Sub => op!(writer, F64SUB),
2029 F64Mul => op!(writer, F64MUL),
2030 F64Div => op!(writer, F64DIV),
2031 F64Min => op!(writer, F64MIN),
2032 F64Max => op!(writer, F64MAX),
2033 F64Copysign => op!(writer, F64COPYSIGN),
2034
2035 I32WrapI64 => op!(writer, I32WRAPI64),
2036 I32TruncSF32 => op!(writer, I32TRUNCSF32),
2037 I32TruncUF32 => op!(writer, I32TRUNCUF32),
2038 I32TruncSF64 => op!(writer, I32TRUNCSF64),
2039 I32TruncUF64 => op!(writer, I32TRUNCUF64),
2040 I64ExtendSI32 => op!(writer, I64EXTENDSI32),
2041 I64ExtendUI32 => op!(writer, I64EXTENDUI32),
2042 I64TruncSF32 => op!(writer, I64TRUNCSF32),
2043 I64TruncUF32 => op!(writer, I64TRUNCUF32),
2044 I64TruncSF64 => op!(writer, I64TRUNCSF64),
2045 I64TruncUF64 => op!(writer, I64TRUNCUF64),
2046 F32ConvertSI32 => op!(writer, F32CONVERTSI32),
2047 F32ConvertUI32 => op!(writer, F32CONVERTUI32),
2048 F32ConvertSI64 => op!(writer, F32CONVERTSI64),
2049 F32ConvertUI64 => op!(writer, F32CONVERTUI64),
2050 F32DemoteF64 => op!(writer, F32DEMOTEF64),
2051 F64ConvertSI32 => op!(writer, F64CONVERTSI32),
2052 F64ConvertUI32 => op!(writer, F64CONVERTUI32),
2053 F64ConvertSI64 => op!(writer, F64CONVERTSI64),
2054 F64ConvertUI64 => op!(writer, F64CONVERTUI64),
2055 F64PromoteF32 => op!(writer, F64PROMOTEF32),
2056
2057 I32ReinterpretF32 => op!(writer, I32REINTERPRETF32),
2058 I64ReinterpretF64 => op!(writer, I64REINTERPRETF64),
2059 F32ReinterpretI32 => op!(writer, F32REINTERPRETI32),
2060 F64ReinterpretI64 => op!(writer, F64REINTERPRETI64),
2061
2062 #[cfg(feature = "sign_ext")]
2063 SignExt(ref a) => match *a {
2064 SignExtInstruction::I32Extend8S => op!(writer, sign_ext::I32_EXTEND8_S),
2065 SignExtInstruction::I32Extend16S => op!(writer, sign_ext::I32_EXTEND16_S),
2066 SignExtInstruction::I64Extend8S => op!(writer, sign_ext::I64_EXTEND8_S),
2067 SignExtInstruction::I64Extend16S => op!(writer, sign_ext::I64_EXTEND16_S),
2068 SignExtInstruction::I64Extend32S => op!(writer, sign_ext::I64_EXTEND32_S),
2069 },
2070
2071 #[cfg(feature = "atomics")]
2072 Atomics(a) => return a.serialize(writer),
2073
2074 #[cfg(feature = "simd")]
2075 Simd(a) => return a.serialize(writer),
2076
2077 #[cfg(feature = "bulk")]
2078 Bulk(a) => return a.serialize(writer),
2079 }
2080
2081 Ok(())
2082 }
2083}
2084
2085#[cfg(feature = "atomics")]
2086impl Serialize for AtomicsInstruction {
2087 type Error = Error;
2088
2089 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
2090 use self::{opcodes::atomics::*, AtomicsInstruction::*};
2091
2092 match self {
2093 AtomicWake(m) => atomic!(writer, ATOMIC_WAKE, m),
2094 I32AtomicWait(m) => atomic!(writer, I32_ATOMIC_WAIT, m),
2095 I64AtomicWait(m) => atomic!(writer, I64_ATOMIC_WAIT, m),
2096
2097 I32AtomicLoad(m) => atomic!(writer, I32_ATOMIC_LOAD, m),
2098 I64AtomicLoad(m) => atomic!(writer, I64_ATOMIC_LOAD, m),
2099 I32AtomicLoad8u(m) => atomic!(writer, I32_ATOMIC_LOAD8U, m),
2100 I32AtomicLoad16u(m) => atomic!(writer, I32_ATOMIC_LOAD16U, m),
2101 I64AtomicLoad8u(m) => atomic!(writer, I64_ATOMIC_LOAD8U, m),
2102 I64AtomicLoad16u(m) => atomic!(writer, I64_ATOMIC_LOAD16U, m),
2103 I64AtomicLoad32u(m) => atomic!(writer, I64_ATOMIC_LOAD32U, m),
2104 I32AtomicStore(m) => atomic!(writer, I32_ATOMIC_STORE, m),
2105 I64AtomicStore(m) => atomic!(writer, I64_ATOMIC_STORE, m),
2106 I32AtomicStore8u(m) => atomic!(writer, I32_ATOMIC_STORE8U, m),
2107 I32AtomicStore16u(m) => atomic!(writer, I32_ATOMIC_STORE16U, m),
2108 I64AtomicStore8u(m) => atomic!(writer, I64_ATOMIC_STORE8U, m),
2109 I64AtomicStore16u(m) => atomic!(writer, I64_ATOMIC_STORE16U, m),
2110 I64AtomicStore32u(m) => atomic!(writer, I64_ATOMIC_STORE32U, m),
2111
2112 I32AtomicRmwAdd(m) => atomic!(writer, I32_ATOMIC_RMW_ADD, m),
2113 I64AtomicRmwAdd(m) => atomic!(writer, I64_ATOMIC_RMW_ADD, m),
2114 I32AtomicRmwAdd8u(m) => atomic!(writer, I32_ATOMIC_RMW_ADD8U, m),
2115 I32AtomicRmwAdd16u(m) => atomic!(writer, I32_ATOMIC_RMW_ADD16U, m),
2116 I64AtomicRmwAdd8u(m) => atomic!(writer, I64_ATOMIC_RMW_ADD8U, m),
2117 I64AtomicRmwAdd16u(m) => atomic!(writer, I64_ATOMIC_RMW_ADD16U, m),
2118 I64AtomicRmwAdd32u(m) => atomic!(writer, I64_ATOMIC_RMW_ADD32U, m),
2119
2120 I32AtomicRmwSub(m) => atomic!(writer, I32_ATOMIC_RMW_SUB, m),
2121 I64AtomicRmwSub(m) => atomic!(writer, I64_ATOMIC_RMW_SUB, m),
2122 I32AtomicRmwSub8u(m) => atomic!(writer, I32_ATOMIC_RMW_SUB8U, m),
2123 I32AtomicRmwSub16u(m) => atomic!(writer, I32_ATOMIC_RMW_SUB16U, m),
2124 I64AtomicRmwSub8u(m) => atomic!(writer, I64_ATOMIC_RMW_SUB8U, m),
2125 I64AtomicRmwSub16u(m) => atomic!(writer, I64_ATOMIC_RMW_SUB16U, m),
2126 I64AtomicRmwSub32u(m) => atomic!(writer, I64_ATOMIC_RMW_SUB32U, m),
2127
2128 I32AtomicRmwAnd(m) => atomic!(writer, I32_ATOMIC_RMW_AND, m),
2129 I64AtomicRmwAnd(m) => atomic!(writer, I64_ATOMIC_RMW_AND, m),
2130 I32AtomicRmwAnd8u(m) => atomic!(writer, I32_ATOMIC_RMW_AND8U, m),
2131 I32AtomicRmwAnd16u(m) => atomic!(writer, I32_ATOMIC_RMW_AND16U, m),
2132 I64AtomicRmwAnd8u(m) => atomic!(writer, I64_ATOMIC_RMW_AND8U, m),
2133 I64AtomicRmwAnd16u(m) => atomic!(writer, I64_ATOMIC_RMW_AND16U, m),
2134 I64AtomicRmwAnd32u(m) => atomic!(writer, I64_ATOMIC_RMW_AND32U, m),
2135
2136 I32AtomicRmwOr(m) => atomic!(writer, I32_ATOMIC_RMW_OR, m),
2137 I64AtomicRmwOr(m) => atomic!(writer, I64_ATOMIC_RMW_OR, m),
2138 I32AtomicRmwOr8u(m) => atomic!(writer, I32_ATOMIC_RMW_OR8U, m),
2139 I32AtomicRmwOr16u(m) => atomic!(writer, I32_ATOMIC_RMW_OR16U, m),
2140 I64AtomicRmwOr8u(m) => atomic!(writer, I64_ATOMIC_RMW_OR8U, m),
2141 I64AtomicRmwOr16u(m) => atomic!(writer, I64_ATOMIC_RMW_OR16U, m),
2142 I64AtomicRmwOr32u(m) => atomic!(writer, I64_ATOMIC_RMW_OR32U, m),
2143
2144 I32AtomicRmwXor(m) => atomic!(writer, I32_ATOMIC_RMW_XOR, m),
2145 I64AtomicRmwXor(m) => atomic!(writer, I64_ATOMIC_RMW_XOR, m),
2146 I32AtomicRmwXor8u(m) => atomic!(writer, I32_ATOMIC_RMW_XOR8U, m),
2147 I32AtomicRmwXor16u(m) => atomic!(writer, I32_ATOMIC_RMW_XOR16U, m),
2148 I64AtomicRmwXor8u(m) => atomic!(writer, I64_ATOMIC_RMW_XOR8U, m),
2149 I64AtomicRmwXor16u(m) => atomic!(writer, I64_ATOMIC_RMW_XOR16U, m),
2150 I64AtomicRmwXor32u(m) => atomic!(writer, I64_ATOMIC_RMW_XOR32U, m),
2151
2152 I32AtomicRmwXchg(m) => atomic!(writer, I32_ATOMIC_RMW_XCHG, m),
2153 I64AtomicRmwXchg(m) => atomic!(writer, I64_ATOMIC_RMW_XCHG, m),
2154 I32AtomicRmwXchg8u(m) => atomic!(writer, I32_ATOMIC_RMW_XCHG8U, m),
2155 I32AtomicRmwXchg16u(m) => atomic!(writer, I32_ATOMIC_RMW_XCHG16U, m),
2156 I64AtomicRmwXchg8u(m) => atomic!(writer, I64_ATOMIC_RMW_XCHG8U, m),
2157 I64AtomicRmwXchg16u(m) => atomic!(writer, I64_ATOMIC_RMW_XCHG16U, m),
2158 I64AtomicRmwXchg32u(m) => atomic!(writer, I64_ATOMIC_RMW_XCHG32U, m),
2159
2160 I32AtomicRmwCmpxchg(m) => atomic!(writer, I32_ATOMIC_RMW_CMPXCHG, m),
2161 I64AtomicRmwCmpxchg(m) => atomic!(writer, I64_ATOMIC_RMW_CMPXCHG, m),
2162 I32AtomicRmwCmpxchg8u(m) => atomic!(writer, I32_ATOMIC_RMW_CMPXCHG8U, m),
2163 I32AtomicRmwCmpxchg16u(m) => atomic!(writer, I32_ATOMIC_RMW_CMPXCHG16U, m),
2164 I64AtomicRmwCmpxchg8u(m) => atomic!(writer, I64_ATOMIC_RMW_CMPXCHG8U, m),
2165 I64AtomicRmwCmpxchg16u(m) => atomic!(writer, I64_ATOMIC_RMW_CMPXCHG16U, m),
2166 I64AtomicRmwCmpxchg32u(m) => atomic!(writer, I64_ATOMIC_RMW_CMPXCHG32U, m),
2167 }
2168
2169 Ok(())
2170 }
2171}
2172
2173#[cfg(feature = "simd")]
2174impl Serialize for SimdInstruction {
2175 type Error = Error;
2176
2177 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
2178 use self::{opcodes::simd::*, SimdInstruction::*};
2179
2180 match self {
2181 V128Const(ref c) => simd!(writer, V128_CONST, writer.write(&c[..])?),
2182 V128Load(m) => simd!(writer, V128_LOAD, MemArg::serialize(m, writer)?),
2183 V128Store(m) => simd!(writer, V128_STORE, MemArg::serialize(m, writer)?),
2184 I8x16Splat => simd!(writer, I8X16_SPLAT, {}),
2185 I16x8Splat => simd!(writer, I16X8_SPLAT, {}),
2186 I32x4Splat => simd!(writer, I32X4_SPLAT, {}),
2187 I64x2Splat => simd!(writer, I64X2_SPLAT, {}),
2188 F32x4Splat => simd!(writer, F32X4_SPLAT, {}),
2189 F64x2Splat => simd!(writer, F64X2_SPLAT, {}),
2190 I8x16ExtractLaneS(i) => simd!(writer, I8X16_EXTRACT_LANE_S, writer.write(&[i])?),
2191 I8x16ExtractLaneU(i) => simd!(writer, I8X16_EXTRACT_LANE_U, writer.write(&[i])?),
2192 I16x8ExtractLaneS(i) => simd!(writer, I16X8_EXTRACT_LANE_S, writer.write(&[i])?),
2193 I16x8ExtractLaneU(i) => simd!(writer, I16X8_EXTRACT_LANE_U, writer.write(&[i])?),
2194 I32x4ExtractLane(i) => simd!(writer, I32X4_EXTRACT_LANE, writer.write(&[i])?),
2195 I64x2ExtractLane(i) => simd!(writer, I64X2_EXTRACT_LANE, writer.write(&[i])?),
2196 F32x4ExtractLane(i) => simd!(writer, F32X4_EXTRACT_LANE, writer.write(&[i])?),
2197 F64x2ExtractLane(i) => simd!(writer, F64X2_EXTRACT_LANE, writer.write(&[i])?),
2198 I8x16ReplaceLane(i) => simd!(writer, I8X16_REPLACE_LANE, writer.write(&[i])?),
2199 I16x8ReplaceLane(i) => simd!(writer, I16X8_REPLACE_LANE, writer.write(&[i])?),
2200 I32x4ReplaceLane(i) => simd!(writer, I32X4_REPLACE_LANE, writer.write(&[i])?),
2201 I64x2ReplaceLane(i) => simd!(writer, I64X2_REPLACE_LANE, writer.write(&[i])?),
2202 F32x4ReplaceLane(i) => simd!(writer, F32X4_REPLACE_LANE, writer.write(&[i])?),
2203 F64x2ReplaceLane(i) => simd!(writer, F64X2_REPLACE_LANE, writer.write(&[i])?),
2204 V8x16Shuffle(ref i) => simd!(writer, V8X16_SHUFFLE, writer.write(&i[..])?),
2205 I8x16Add => simd!(writer, I8X16_ADD, {}),
2206 I16x8Add => simd!(writer, I16X8_ADD, {}),
2207 I32x4Add => simd!(writer, I32X4_ADD, {}),
2208 I64x2Add => simd!(writer, I64X2_ADD, {}),
2209 I8x16Sub => simd!(writer, I8X16_SUB, {}),
2210 I16x8Sub => simd!(writer, I16X8_SUB, {}),
2211 I32x4Sub => simd!(writer, I32X4_SUB, {}),
2212 I64x2Sub => simd!(writer, I64X2_SUB, {}),
2213 I8x16Mul => simd!(writer, I8X16_MUL, {}),
2214 I16x8Mul => simd!(writer, I16X8_MUL, {}),
2215 I32x4Mul => simd!(writer, I32X4_MUL, {}),
2216 I8x16Neg => simd!(writer, I8X16_NEG, {}),
2218 I16x8Neg => simd!(writer, I16X8_NEG, {}),
2219 I32x4Neg => simd!(writer, I32X4_NEG, {}),
2220 I64x2Neg => simd!(writer, I64X2_NEG, {}),
2221 I8x16AddSaturateS => simd!(writer, I8X16_ADD_SATURATE_S, {}),
2222 I8x16AddSaturateU => simd!(writer, I8X16_ADD_SATURATE_U, {}),
2223 I16x8AddSaturateS => simd!(writer, I16X8_ADD_SATURATE_S, {}),
2224 I16x8AddSaturateU => simd!(writer, I16X8_ADD_SATURATE_U, {}),
2225 I8x16SubSaturateS => simd!(writer, I8X16_SUB_SATURATE_S, {}),
2226 I8x16SubSaturateU => simd!(writer, I8X16_SUB_SATURATE_U, {}),
2227 I16x8SubSaturateS => simd!(writer, I16X8_SUB_SATURATE_S, {}),
2228 I16x8SubSaturateU => simd!(writer, I16X8_SUB_SATURATE_U, {}),
2229 I8x16Shl => simd!(writer, I8X16_SHL, {}),
2230 I16x8Shl => simd!(writer, I16X8_SHL, {}),
2231 I32x4Shl => simd!(writer, I32X4_SHL, {}),
2232 I64x2Shl => simd!(writer, I64X2_SHL, {}),
2233 I8x16ShrS => simd!(writer, I8X16_SHR_S, {}),
2234 I8x16ShrU => simd!(writer, I8X16_SHR_U, {}),
2235 I16x8ShrS => simd!(writer, I16X8_SHR_S, {}),
2236 I16x8ShrU => simd!(writer, I16X8_SHR_U, {}),
2237 I32x4ShrU => simd!(writer, I32X4_SHR_U, {}),
2238 I32x4ShrS => simd!(writer, I32X4_SHR_S, {}),
2239 I64x2ShrU => simd!(writer, I64X2_SHR_U, {}),
2240 I64x2ShrS => simd!(writer, I64X2_SHR_S, {}),
2241 V128And => simd!(writer, V128_AND, {}),
2242 V128Or => simd!(writer, V128_OR, {}),
2243 V128Xor => simd!(writer, V128_XOR, {}),
2244 V128Not => simd!(writer, V128_NOT, {}),
2245 V128Bitselect => simd!(writer, V128_BITSELECT, {}),
2246 I8x16AnyTrue => simd!(writer, I8X16_ANY_TRUE, {}),
2247 I16x8AnyTrue => simd!(writer, I16X8_ANY_TRUE, {}),
2248 I32x4AnyTrue => simd!(writer, I32X4_ANY_TRUE, {}),
2249 I64x2AnyTrue => simd!(writer, I64X2_ANY_TRUE, {}),
2250 I8x16AllTrue => simd!(writer, I8X16_ALL_TRUE, {}),
2251 I16x8AllTrue => simd!(writer, I16X8_ALL_TRUE, {}),
2252 I32x4AllTrue => simd!(writer, I32X4_ALL_TRUE, {}),
2253 I64x2AllTrue => simd!(writer, I64X2_ALL_TRUE, {}),
2254 I8x16Eq => simd!(writer, I8X16_EQ, {}),
2255 I16x8Eq => simd!(writer, I16X8_EQ, {}),
2256 I32x4Eq => simd!(writer, I32X4_EQ, {}),
2257 F32x4Eq => simd!(writer, F32X4_EQ, {}),
2259 F64x2Eq => simd!(writer, F64X2_EQ, {}),
2260 I8x16Ne => simd!(writer, I8X16_NE, {}),
2261 I16x8Ne => simd!(writer, I16X8_NE, {}),
2262 I32x4Ne => simd!(writer, I32X4_NE, {}),
2263 F32x4Ne => simd!(writer, F32X4_NE, {}),
2265 F64x2Ne => simd!(writer, F64X2_NE, {}),
2266 I8x16LtS => simd!(writer, I8X16_LT_S, {}),
2267 I8x16LtU => simd!(writer, I8X16_LT_U, {}),
2268 I16x8LtS => simd!(writer, I16X8_LT_S, {}),
2269 I16x8LtU => simd!(writer, I16X8_LT_U, {}),
2270 I32x4LtS => simd!(writer, I32X4_LT_S, {}),
2271 I32x4LtU => simd!(writer, I32X4_LT_U, {}),
2272 F32x4Lt => simd!(writer, F32X4_LT, {}),
2275 F64x2Lt => simd!(writer, F64X2_LT, {}),
2276 I8x16LeS => simd!(writer, I8X16_LE_S, {}),
2277 I8x16LeU => simd!(writer, I8X16_LE_U, {}),
2278 I16x8LeS => simd!(writer, I16X8_LE_S, {}),
2279 I16x8LeU => simd!(writer, I16X8_LE_U, {}),
2280 I32x4LeS => simd!(writer, I32X4_LE_S, {}),
2281 I32x4LeU => simd!(writer, I32X4_LE_U, {}),
2282 F32x4Le => simd!(writer, F32X4_LE, {}),
2285 F64x2Le => simd!(writer, F64X2_LE, {}),
2286 I8x16GtS => simd!(writer, I8X16_GT_S, {}),
2287 I8x16GtU => simd!(writer, I8X16_GT_U, {}),
2288 I16x8GtS => simd!(writer, I16X8_GT_S, {}),
2289 I16x8GtU => simd!(writer, I16X8_GT_U, {}),
2290 I32x4GtS => simd!(writer, I32X4_GT_S, {}),
2291 I32x4GtU => simd!(writer, I32X4_GT_U, {}),
2292 F32x4Gt => simd!(writer, F32X4_GT, {}),
2295 F64x2Gt => simd!(writer, F64X2_GT, {}),
2296 I8x16GeS => simd!(writer, I8X16_GE_S, {}),
2297 I8x16GeU => simd!(writer, I8X16_GE_U, {}),
2298 I16x8GeS => simd!(writer, I16X8_GE_S, {}),
2299 I16x8GeU => simd!(writer, I16X8_GE_U, {}),
2300 I32x4GeS => simd!(writer, I32X4_GE_S, {}),
2301 I32x4GeU => simd!(writer, I32X4_GE_U, {}),
2302 F32x4Ge => simd!(writer, F32X4_GE, {}),
2305 F64x2Ge => simd!(writer, F64X2_GE, {}),
2306 F32x4Neg => simd!(writer, F32X4_NEG, {}),
2307 F64x2Neg => simd!(writer, F64X2_NEG, {}),
2308 F32x4Abs => simd!(writer, F32X4_ABS, {}),
2309 F64x2Abs => simd!(writer, F64X2_ABS, {}),
2310 F32x4Min => simd!(writer, F32X4_MIN, {}),
2311 F64x2Min => simd!(writer, F64X2_MIN, {}),
2312 F32x4Max => simd!(writer, F32X4_MAX, {}),
2313 F64x2Max => simd!(writer, F64X2_MAX, {}),
2314 F32x4Add => simd!(writer, F32X4_ADD, {}),
2315 F64x2Add => simd!(writer, F64X2_ADD, {}),
2316 F32x4Sub => simd!(writer, F32X4_SUB, {}),
2317 F64x2Sub => simd!(writer, F64X2_SUB, {}),
2318 F32x4Div => simd!(writer, F32X4_DIV, {}),
2319 F64x2Div => simd!(writer, F64X2_DIV, {}),
2320 F32x4Mul => simd!(writer, F32X4_MUL, {}),
2321 F64x2Mul => simd!(writer, F64X2_MUL, {}),
2322 F32x4Sqrt => simd!(writer, F32X4_SQRT, {}),
2323 F64x2Sqrt => simd!(writer, F64X2_SQRT, {}),
2324 F32x4ConvertSI32x4 => simd!(writer, F32X4_CONVERT_S_I32X4, {}),
2325 F32x4ConvertUI32x4 => simd!(writer, F32X4_CONVERT_U_I32X4, {}),
2326 F64x2ConvertSI64x2 => simd!(writer, F64X2_CONVERT_S_I64X2, {}),
2327 F64x2ConvertUI64x2 => simd!(writer, F64X2_CONVERT_U_I64X2, {}),
2328 I32x4TruncSF32x4Sat => simd!(writer, I32X4_TRUNC_S_F32X4_SAT, {}),
2329 I32x4TruncUF32x4Sat => simd!(writer, I32X4_TRUNC_U_F32X4_SAT, {}),
2330 I64x2TruncSF64x2Sat => simd!(writer, I64X2_TRUNC_S_F64X2_SAT, {}),
2331 I64x2TruncUF64x2Sat => simd!(writer, I64X2_TRUNC_U_F64X2_SAT, {}),
2332 }
2333
2334 Ok(())
2335 }
2336}
2337
2338#[cfg(feature = "bulk")]
2339impl Serialize for BulkInstruction {
2340 type Error = Error;
2341
2342 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
2343 use self::{opcodes::bulk::*, BulkInstruction::*};
2344
2345 match self {
2346 MemoryInit(seg) => bulk!(writer, MEMORY_INIT, {
2347 Uint8::from(0).serialize(writer)?;
2348 VarUint32::from(seg).serialize(writer)?;
2349 }),
2350 MemoryDrop(seg) => bulk!(writer, MEMORY_DROP, VarUint32::from(seg).serialize(writer)?),
2351 MemoryFill => bulk!(writer, MEMORY_FILL, Uint8::from(0).serialize(writer)?),
2352 MemoryCopy => bulk!(writer, MEMORY_COPY, Uint8::from(0).serialize(writer)?),
2353 TableInit(seg) => bulk!(writer, TABLE_INIT, {
2354 Uint8::from(0).serialize(writer)?;
2355 VarUint32::from(seg).serialize(writer)?;
2356 }),
2357 TableDrop(seg) => bulk!(writer, TABLE_DROP, VarUint32::from(seg).serialize(writer)?),
2358 TableCopy => bulk!(writer, TABLE_COPY, Uint8::from(0).serialize(writer)?),
2359 }
2360
2361 Ok(())
2362 }
2363}
2364
2365#[cfg(any(feature = "simd", feature = "atomics"))]
2366impl Serialize for MemArg {
2367 type Error = Error;
2368
2369 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
2370 Uint8::from(self.align).serialize(writer)?;
2371 VarUint32::from(self.offset).serialize(writer)?;
2372 Ok(())
2373 }
2374}
2375
2376macro_rules! fmt_op {
2377 ($f: expr, $mnemonic: expr) => {{
2378 write!($f, "{}", $mnemonic)
2379 }};
2380 ($f: expr, $mnemonic: expr, $immediate: expr) => {{
2381 write!($f, "{} {}", $mnemonic, $immediate)
2382 }};
2383 ($f: expr, $mnemonic: expr, $immediate1: expr, $immediate2: expr) => {{
2384 write!($f, "{} {} {}", $mnemonic, $immediate1, $immediate2)
2385 }};
2386}
2387
2388impl fmt::Display for Instruction {
2389 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2390 use self::Instruction::*;
2391
2392 match *self {
2393 Unreachable => fmt_op!(f, "unreachable"),
2394 Nop => fmt_op!(f, "nop"),
2395 Block(BlockType::NoResult) => fmt_op!(f, "block"),
2396 Block(BlockType::Value(value_type)) => fmt_op!(f, "block", value_type),
2397 #[cfg(feature = "multi_value")]
2398 Block(BlockType::TypeIndex(idx)) => write!(f, "block type_idx={}", idx),
2399 Loop(BlockType::NoResult) => fmt_op!(f, "loop"),
2400 Loop(BlockType::Value(value_type)) => fmt_op!(f, "loop", value_type),
2401 #[cfg(feature = "multi_value")]
2402 Loop(BlockType::TypeIndex(idx)) => write!(f, "loop type_idx={}", idx),
2403 If(BlockType::NoResult) => fmt_op!(f, "if"),
2404 If(BlockType::Value(value_type)) => fmt_op!(f, "if", value_type),
2405 #[cfg(feature = "multi_value")]
2406 If(BlockType::TypeIndex(idx)) => write!(f, "if type_idx={}", idx),
2407 Else => fmt_op!(f, "else"),
2408 End => fmt_op!(f, "end"),
2409 Br(idx) => fmt_op!(f, "br", idx),
2410 BrIf(idx) => fmt_op!(f, "br_if", idx),
2411 BrTable(ref table) => fmt_op!(f, "br_table", table.default),
2412 Return => fmt_op!(f, "return"),
2413 Call(index) => fmt_op!(f, "call", index),
2414 CallIndirect(index, _) => fmt_op!(f, "call_indirect", index),
2415 Drop => fmt_op!(f, "drop"),
2416 Select => fmt_op!(f, "select"),
2417 GetLocal(index) => fmt_op!(f, "get_local", index),
2418 SetLocal(index) => fmt_op!(f, "set_local", index),
2419 TeeLocal(index) => fmt_op!(f, "tee_local", index),
2420 GetGlobal(index) => fmt_op!(f, "get_global", index),
2421 SetGlobal(index) => fmt_op!(f, "set_global", index),
2422
2423 I32Load(_, 0) => write!(f, "i32.load"),
2424 I32Load(_, offset) => write!(f, "i32.load offset={}", offset),
2425
2426 I64Load(_, 0) => write!(f, "i64.load"),
2427 I64Load(_, offset) => write!(f, "i64.load offset={}", offset),
2428
2429 F32Load(_, 0) => write!(f, "f32.load"),
2430 F32Load(_, offset) => write!(f, "f32.load offset={}", offset),
2431
2432 F64Load(_, 0) => write!(f, "f64.load"),
2433 F64Load(_, offset) => write!(f, "f64.load offset={}", offset),
2434
2435 I32Load8S(_, 0) => write!(f, "i32.load8_s"),
2436 I32Load8S(_, offset) => write!(f, "i32.load8_s offset={}", offset),
2437
2438 I32Load8U(_, 0) => write!(f, "i32.load8_u"),
2439 I32Load8U(_, offset) => write!(f, "i32.load8_u offset={}", offset),
2440
2441 I32Load16S(_, 0) => write!(f, "i32.load16_s"),
2442 I32Load16S(_, offset) => write!(f, "i32.load16_s offset={}", offset),
2443
2444 I32Load16U(_, 0) => write!(f, "i32.load16_u"),
2445 I32Load16U(_, offset) => write!(f, "i32.load16_u offset={}", offset),
2446
2447 I64Load8S(_, 0) => write!(f, "i64.load8_s"),
2448 I64Load8S(_, offset) => write!(f, "i64.load8_s offset={}", offset),
2449
2450 I64Load8U(_, 0) => write!(f, "i64.load8_u"),
2451 I64Load8U(_, offset) => write!(f, "i64.load8_u offset={}", offset),
2452
2453 I64Load16S(_, 0) => write!(f, "i64.load16_s"),
2454 I64Load16S(_, offset) => write!(f, "i64.load16_s offset={}", offset),
2455
2456 I64Load16U(_, 0) => write!(f, "i64.load16_u"),
2457 I64Load16U(_, offset) => write!(f, "i64.load16_u offset={}", offset),
2458
2459 I64Load32S(_, 0) => write!(f, "i64.load32_s"),
2460 I64Load32S(_, offset) => write!(f, "i64.load32_s offset={}", offset),
2461
2462 I64Load32U(_, 0) => write!(f, "i64.load32_u"),
2463 I64Load32U(_, offset) => write!(f, "i64.load32_u offset={}", offset),
2464
2465 I32Store(_, 0) => write!(f, "i32.store"),
2466 I32Store(_, offset) => write!(f, "i32.store offset={}", offset),
2467
2468 I64Store(_, 0) => write!(f, "i64.store"),
2469 I64Store(_, offset) => write!(f, "i64.store offset={}", offset),
2470
2471 F32Store(_, 0) => write!(f, "f32.store"),
2472 F32Store(_, offset) => write!(f, "f32.store offset={}", offset),
2473
2474 F64Store(_, 0) => write!(f, "f64.store"),
2475 F64Store(_, offset) => write!(f, "f64.store offset={}", offset),
2476
2477 I32Store8(_, 0) => write!(f, "i32.store8"),
2478 I32Store8(_, offset) => write!(f, "i32.store8 offset={}", offset),
2479
2480 I32Store16(_, 0) => write!(f, "i32.store16"),
2481 I32Store16(_, offset) => write!(f, "i32.store16 offset={}", offset),
2482
2483 I64Store8(_, 0) => write!(f, "i64.store8"),
2484 I64Store8(_, offset) => write!(f, "i64.store8 offset={}", offset),
2485
2486 I64Store16(_, 0) => write!(f, "i64.store16"),
2487 I64Store16(_, offset) => write!(f, "i64.store16 offset={}", offset),
2488
2489 I64Store32(_, 0) => write!(f, "i64.store32"),
2490 I64Store32(_, offset) => write!(f, "i64.store32 offset={}", offset),
2491
2492 CurrentMemory(_) => fmt_op!(f, "current_memory"),
2493 GrowMemory(_) => fmt_op!(f, "grow_memory"),
2494
2495 I32Const(def) => fmt_op!(f, "i32.const", def),
2496 I64Const(def) => fmt_op!(f, "i64.const", def),
2497 F32Const(def) => fmt_op!(f, "f32.const", def),
2498 F64Const(def) => fmt_op!(f, "f64.const", def),
2499
2500 I32Eq => write!(f, "i32.eq"),
2501 I32Eqz => write!(f, "i32.eqz"),
2502 I32Ne => write!(f, "i32.ne"),
2503 I32LtS => write!(f, "i32.lt_s"),
2504 I32LtU => write!(f, "i32.lt_u"),
2505 I32GtS => write!(f, "i32.gt_s"),
2506 I32GtU => write!(f, "i32.gt_u"),
2507 I32LeS => write!(f, "i32.le_s"),
2508 I32LeU => write!(f, "i32.le_u"),
2509 I32GeS => write!(f, "i32.ge_s"),
2510 I32GeU => write!(f, "i32.ge_u"),
2511
2512 I64Eq => write!(f, "i64.eq"),
2513 I64Eqz => write!(f, "i64.eqz"),
2514 I64Ne => write!(f, "i64.ne"),
2515 I64LtS => write!(f, "i64.lt_s"),
2516 I64LtU => write!(f, "i64.lt_u"),
2517 I64GtS => write!(f, "i64.gt_s"),
2518 I64GtU => write!(f, "i64.gt_u"),
2519 I64LeS => write!(f, "i64.le_s"),
2520 I64LeU => write!(f, "i64.le_u"),
2521 I64GeS => write!(f, "i64.ge_s"),
2522 I64GeU => write!(f, "i64.ge_u"),
2523
2524 F32Eq => write!(f, "f32.eq"),
2525 F32Ne => write!(f, "f32.ne"),
2526 F32Lt => write!(f, "f32.lt"),
2527 F32Gt => write!(f, "f32.gt"),
2528 F32Le => write!(f, "f32.le"),
2529 F32Ge => write!(f, "f32.ge"),
2530
2531 F64Eq => write!(f, "f64.eq"),
2532 F64Ne => write!(f, "f64.ne"),
2533 F64Lt => write!(f, "f64.lt"),
2534 F64Gt => write!(f, "f64.gt"),
2535 F64Le => write!(f, "f64.le"),
2536 F64Ge => write!(f, "f64.ge"),
2537
2538 I32Clz => write!(f, "i32.clz"),
2539 I32Ctz => write!(f, "i32.ctz"),
2540 I32Popcnt => write!(f, "i32.popcnt"),
2541 I32Add => write!(f, "i32.add"),
2542 I32Sub => write!(f, "i32.sub"),
2543 I32Mul => write!(f, "i32.mul"),
2544 I32DivS => write!(f, "i32.div_s"),
2545 I32DivU => write!(f, "i32.div_u"),
2546 I32RemS => write!(f, "i32.rem_s"),
2547 I32RemU => write!(f, "i32.rem_u"),
2548 I32And => write!(f, "i32.and"),
2549 I32Or => write!(f, "i32.or"),
2550 I32Xor => write!(f, "i32.xor"),
2551 I32Shl => write!(f, "i32.shl"),
2552 I32ShrS => write!(f, "i32.shr_s"),
2553 I32ShrU => write!(f, "i32.shr_u"),
2554 I32Rotl => write!(f, "i32.rotl"),
2555 I32Rotr => write!(f, "i32.rotr"),
2556
2557 I64Clz => write!(f, "i64.clz"),
2558 I64Ctz => write!(f, "i64.ctz"),
2559 I64Popcnt => write!(f, "i64.popcnt"),
2560 I64Add => write!(f, "i64.add"),
2561 I64Sub => write!(f, "i64.sub"),
2562 I64Mul => write!(f, "i64.mul"),
2563 I64DivS => write!(f, "i64.div_s"),
2564 I64DivU => write!(f, "i64.div_u"),
2565 I64RemS => write!(f, "i64.rem_s"),
2566 I64RemU => write!(f, "i64.rem_u"),
2567 I64And => write!(f, "i64.and"),
2568 I64Or => write!(f, "i64.or"),
2569 I64Xor => write!(f, "i64.xor"),
2570 I64Shl => write!(f, "i64.shl"),
2571 I64ShrS => write!(f, "i64.shr_s"),
2572 I64ShrU => write!(f, "i64.shr_u"),
2573 I64Rotl => write!(f, "i64.rotl"),
2574 I64Rotr => write!(f, "i64.rotr"),
2575
2576 F32Abs => write!(f, "f32.abs"),
2577 F32Neg => write!(f, "f32.neg"),
2578 F32Ceil => write!(f, "f32.ceil"),
2579 F32Floor => write!(f, "f32.floor"),
2580 F32Trunc => write!(f, "f32.trunc"),
2581 F32Nearest => write!(f, "f32.nearest"),
2582 F32Sqrt => write!(f, "f32.sqrt"),
2583 F32Add => write!(f, "f32.add"),
2584 F32Sub => write!(f, "f32.sub"),
2585 F32Mul => write!(f, "f32.mul"),
2586 F32Div => write!(f, "f32.div"),
2587 F32Min => write!(f, "f32.min"),
2588 F32Max => write!(f, "f32.max"),
2589 F32Copysign => write!(f, "f32.copysign"),
2590
2591 F64Abs => write!(f, "f64.abs"),
2592 F64Neg => write!(f, "f64.neg"),
2593 F64Ceil => write!(f, "f64.ceil"),
2594 F64Floor => write!(f, "f64.floor"),
2595 F64Trunc => write!(f, "f64.trunc"),
2596 F64Nearest => write!(f, "f64.nearest"),
2597 F64Sqrt => write!(f, "f64.sqrt"),
2598 F64Add => write!(f, "f64.add"),
2599 F64Sub => write!(f, "f64.sub"),
2600 F64Mul => write!(f, "f64.mul"),
2601 F64Div => write!(f, "f64.div"),
2602 F64Min => write!(f, "f64.min"),
2603 F64Max => write!(f, "f64.max"),
2604 F64Copysign => write!(f, "f64.copysign"),
2605
2606 I32WrapI64 => write!(f, "i32.wrap/i64"),
2607 I32TruncSF32 => write!(f, "i32.trunc_s/f32"),
2608 I32TruncUF32 => write!(f, "i32.trunc_u/f32"),
2609 I32TruncSF64 => write!(f, "i32.trunc_s/f64"),
2610 I32TruncUF64 => write!(f, "i32.trunc_u/f64"),
2611
2612 I64ExtendSI32 => write!(f, "i64.extend_s/i32"),
2613 I64ExtendUI32 => write!(f, "i64.extend_u/i32"),
2614
2615 I64TruncSF32 => write!(f, "i64.trunc_s/f32"),
2616 I64TruncUF32 => write!(f, "i64.trunc_u/f32"),
2617 I64TruncSF64 => write!(f, "i64.trunc_s/f64"),
2618 I64TruncUF64 => write!(f, "i64.trunc_u/f64"),
2619
2620 F32ConvertSI32 => write!(f, "f32.convert_s/i32"),
2621 F32ConvertUI32 => write!(f, "f32.convert_u/i32"),
2622 F32ConvertSI64 => write!(f, "f32.convert_s/i64"),
2623 F32ConvertUI64 => write!(f, "f32.convert_u/i64"),
2624 F32DemoteF64 => write!(f, "f32.demote/f64"),
2625
2626 F64ConvertSI32 => write!(f, "f64.convert_s/i32"),
2627 F64ConvertUI32 => write!(f, "f64.convert_u/i32"),
2628 F64ConvertSI64 => write!(f, "f64.convert_s/i64"),
2629 F64ConvertUI64 => write!(f, "f64.convert_u/i64"),
2630 F64PromoteF32 => write!(f, "f64.promote/f32"),
2631
2632 I32ReinterpretF32 => write!(f, "i32.reinterpret/f32"),
2633 I64ReinterpretF64 => write!(f, "i64.reinterpret/f64"),
2634 F32ReinterpretI32 => write!(f, "f32.reinterpret/i32"),
2635 F64ReinterpretI64 => write!(f, "f64.reinterpret/i64"),
2636
2637 #[cfg(feature = "sign_ext")]
2638 SignExt(ref i) => match i {
2639 SignExtInstruction::I32Extend8S => write!(f, "i32.extend8_s"),
2640 SignExtInstruction::I32Extend16S => write!(f, "i32.extend16_s"),
2641 SignExtInstruction::I64Extend8S => write!(f, "i64.extend8_s"),
2642 SignExtInstruction::I64Extend16S => write!(f, "i64.extend16_s"),
2643 SignExtInstruction::I64Extend32S => write!(f, "i64.extend32_s"),
2644 },
2645
2646 #[cfg(feature = "atomics")]
2647 Atomics(ref i) => i.fmt(f),
2648
2649 #[cfg(feature = "simd")]
2650 Simd(ref i) => i.fmt(f),
2651
2652 #[cfg(feature = "bulk")]
2653 Bulk(ref i) => i.fmt(f),
2654 }
2655 }
2656}
2657
2658#[cfg(feature = "atomics")]
2659impl fmt::Display for AtomicsInstruction {
2660 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2661 use self::AtomicsInstruction::*;
2662
2663 match *self {
2664 AtomicWake(_) => write!(f, "atomic.wake"),
2665 I32AtomicWait(_) => write!(f, "i32.atomic.wait"),
2666 I64AtomicWait(_) => write!(f, "i64.atomic.wait"),
2667
2668 I32AtomicLoad(_) => write!(f, "i32.atomic.load"),
2669 I64AtomicLoad(_) => write!(f, "i64.atomic.load"),
2670 I32AtomicLoad8u(_) => write!(f, "i32.atomic.load8_u"),
2671 I32AtomicLoad16u(_) => write!(f, "i32.atomic.load16_u"),
2672 I64AtomicLoad8u(_) => write!(f, "i64.atomic.load8_u"),
2673 I64AtomicLoad16u(_) => write!(f, "i64.atomic.load16_u"),
2674 I64AtomicLoad32u(_) => write!(f, "i64.atomic.load32_u"),
2675 I32AtomicStore(_) => write!(f, "i32.atomic.store"),
2676 I64AtomicStore(_) => write!(f, "i64.atomic.store"),
2677 I32AtomicStore8u(_) => write!(f, "i32.atomic.store8_u"),
2678 I32AtomicStore16u(_) => write!(f, "i32.atomic.store16_u"),
2679 I64AtomicStore8u(_) => write!(f, "i64.atomic.store8_u"),
2680 I64AtomicStore16u(_) => write!(f, "i64.atomic.store16_u"),
2681 I64AtomicStore32u(_) => write!(f, "i64.atomic.store32_u"),
2682
2683 I32AtomicRmwAdd(_) => write!(f, "i32.atomic.rmw.add"),
2684 I64AtomicRmwAdd(_) => write!(f, "i64.atomic.rmw.add"),
2685 I32AtomicRmwAdd8u(_) => write!(f, "i32.atomic.rmw8_u.add"),
2686 I32AtomicRmwAdd16u(_) => write!(f, "i32.atomic.rmw16_u.add"),
2687 I64AtomicRmwAdd8u(_) => write!(f, "i64.atomic.rmw8_u.add"),
2688 I64AtomicRmwAdd16u(_) => write!(f, "i64.atomic.rmw16_u.add"),
2689 I64AtomicRmwAdd32u(_) => write!(f, "i64.atomic.rmw32_u.add"),
2690
2691 I32AtomicRmwSub(_) => write!(f, "i32.atomic.rmw.sub"),
2692 I64AtomicRmwSub(_) => write!(f, "i64.atomic.rmw.sub"),
2693 I32AtomicRmwSub8u(_) => write!(f, "i32.atomic.rmw8_u.sub"),
2694 I32AtomicRmwSub16u(_) => write!(f, "i32.atomic.rmw16_u.sub"),
2695 I64AtomicRmwSub8u(_) => write!(f, "i64.atomic.rmw8_u.sub"),
2696 I64AtomicRmwSub16u(_) => write!(f, "i64.atomic.rmw16_u.sub"),
2697 I64AtomicRmwSub32u(_) => write!(f, "i64.atomic.rmw32_u.sub"),
2698
2699 I32AtomicRmwAnd(_) => write!(f, "i32.atomic.rmw.and"),
2700 I64AtomicRmwAnd(_) => write!(f, "i64.atomic.rmw.and"),
2701 I32AtomicRmwAnd8u(_) => write!(f, "i32.atomic.rmw8_u.and"),
2702 I32AtomicRmwAnd16u(_) => write!(f, "i32.atomic.rmw16_u.and"),
2703 I64AtomicRmwAnd8u(_) => write!(f, "i64.atomic.rmw8_u.and"),
2704 I64AtomicRmwAnd16u(_) => write!(f, "i64.atomic.rmw16_u.and"),
2705 I64AtomicRmwAnd32u(_) => write!(f, "i64.atomic.rmw32_u.and"),
2706
2707 I32AtomicRmwOr(_) => write!(f, "i32.atomic.rmw.or"),
2708 I64AtomicRmwOr(_) => write!(f, "i64.atomic.rmw.or"),
2709 I32AtomicRmwOr8u(_) => write!(f, "i32.atomic.rmw8_u.or"),
2710 I32AtomicRmwOr16u(_) => write!(f, "i32.atomic.rmw16_u.or"),
2711 I64AtomicRmwOr8u(_) => write!(f, "i64.atomic.rmw8_u.or"),
2712 I64AtomicRmwOr16u(_) => write!(f, "i64.atomic.rmw16_u.or"),
2713 I64AtomicRmwOr32u(_) => write!(f, "i64.atomic.rmw32_u.or"),
2714
2715 I32AtomicRmwXor(_) => write!(f, "i32.atomic.rmw.xor"),
2716 I64AtomicRmwXor(_) => write!(f, "i64.atomic.rmw.xor"),
2717 I32AtomicRmwXor8u(_) => write!(f, "i32.atomic.rmw8_u.xor"),
2718 I32AtomicRmwXor16u(_) => write!(f, "i32.atomic.rmw16_u.xor"),
2719 I64AtomicRmwXor8u(_) => write!(f, "i64.atomic.rmw8_u.xor"),
2720 I64AtomicRmwXor16u(_) => write!(f, "i64.atomic.rmw16_u.xor"),
2721 I64AtomicRmwXor32u(_) => write!(f, "i64.atomic.rmw32_u.xor"),
2722
2723 I32AtomicRmwXchg(_) => write!(f, "i32.atomic.rmw.xchg"),
2724 I64AtomicRmwXchg(_) => write!(f, "i64.atomic.rmw.xchg"),
2725 I32AtomicRmwXchg8u(_) => write!(f, "i32.atomic.rmw8_u.xchg"),
2726 I32AtomicRmwXchg16u(_) => write!(f, "i32.atomic.rmw16_u.xchg"),
2727 I64AtomicRmwXchg8u(_) => write!(f, "i64.atomic.rmw8_u.xchg"),
2728 I64AtomicRmwXchg16u(_) => write!(f, "i64.atomic.rmw16_u.xchg"),
2729 I64AtomicRmwXchg32u(_) => write!(f, "i64.atomic.rmw32_u.xchg"),
2730
2731 I32AtomicRmwCmpxchg(_) => write!(f, "i32.atomic.rmw.cmpxchg"),
2732 I64AtomicRmwCmpxchg(_) => write!(f, "i64.atomic.rmw.cmpxchg"),
2733 I32AtomicRmwCmpxchg8u(_) => write!(f, "i32.atomic.rmw8_u.cmpxchg"),
2734 I32AtomicRmwCmpxchg16u(_) => write!(f, "i32.atomic.rmw16_u.cmpxchg"),
2735 I64AtomicRmwCmpxchg8u(_) => write!(f, "i64.atomic.rmw8_u.cmpxchg"),
2736 I64AtomicRmwCmpxchg16u(_) => write!(f, "i64.atomic.rmw16_u.cmpxchg"),
2737 I64AtomicRmwCmpxchg32u(_) => write!(f, "i64.atomic.rmw32_u.cmpxchg"),
2738 }
2739 }
2740}
2741
2742#[cfg(feature = "simd")]
2743impl fmt::Display for SimdInstruction {
2744 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2745 use self::SimdInstruction::*;
2746
2747 match *self {
2748 V128Const(_) => write!(f, "v128.const"),
2749 V128Load(_) => write!(f, "v128.load"),
2750 V128Store(_) => write!(f, "v128.store"),
2751 I8x16Splat => write!(f, "i8x16.splat"),
2752 I16x8Splat => write!(f, "i16x8.splat"),
2753 I32x4Splat => write!(f, "i32x4.splat"),
2754 I64x2Splat => write!(f, "i64x2.splat"),
2755 F32x4Splat => write!(f, "f32x4.splat"),
2756 F64x2Splat => write!(f, "f64x2.splat"),
2757 I8x16ExtractLaneS(_) => write!(f, "i8x16.extract_lane_s"),
2758 I8x16ExtractLaneU(_) => write!(f, "i8x16.extract_lane_u"),
2759 I16x8ExtractLaneS(_) => write!(f, "i16x8.extract_lane_s"),
2760 I16x8ExtractLaneU(_) => write!(f, "i16x8.extract_lane_u"),
2761 I32x4ExtractLane(_) => write!(f, "i32x4.extract_lane"),
2762 I64x2ExtractLane(_) => write!(f, "i64x2.extract_lane"),
2763 F32x4ExtractLane(_) => write!(f, "f32x4.extract_lane"),
2764 F64x2ExtractLane(_) => write!(f, "f64x2.extract_lane"),
2765 I8x16ReplaceLane(_) => write!(f, "i8x16.replace_lane"),
2766 I16x8ReplaceLane(_) => write!(f, "i16x8.replace_lane"),
2767 I32x4ReplaceLane(_) => write!(f, "i32x4.replace_lane"),
2768 I64x2ReplaceLane(_) => write!(f, "i64x2.replace_lane"),
2769 F32x4ReplaceLane(_) => write!(f, "f32x4.replace_lane"),
2770 F64x2ReplaceLane(_) => write!(f, "f64x2.replace_lane"),
2771 V8x16Shuffle(_) => write!(f, "v8x16.shuffle"),
2772 I8x16Add => write!(f, "i8x16.add"),
2773 I16x8Add => write!(f, "i16x8.add"),
2774 I32x4Add => write!(f, "i32x4.add"),
2775 I64x2Add => write!(f, "i64x2.add"),
2776 I8x16Sub => write!(f, "i8x16.sub"),
2777 I16x8Sub => write!(f, "i16x8.sub"),
2778 I32x4Sub => write!(f, "i32x4.sub"),
2779 I64x2Sub => write!(f, "i64x2.sub"),
2780 I8x16Mul => write!(f, "i8x16.mul"),
2781 I16x8Mul => write!(f, "i16x8.mul"),
2782 I32x4Mul => write!(f, "i32x4.mul"),
2783 I8x16Neg => write!(f, "i8x16.neg"),
2785 I16x8Neg => write!(f, "i16x8.neg"),
2786 I32x4Neg => write!(f, "i32x4.neg"),
2787 I64x2Neg => write!(f, "i64x2.neg"),
2788 I8x16AddSaturateS => write!(f, "i8x16.add_saturate_s"),
2789 I8x16AddSaturateU => write!(f, "i8x16.add_saturate_u"),
2790 I16x8AddSaturateS => write!(f, "i16x8.add_saturate_S"),
2791 I16x8AddSaturateU => write!(f, "i16x8.add_saturate_u"),
2792 I8x16SubSaturateS => write!(f, "i8x16.sub_saturate_S"),
2793 I8x16SubSaturateU => write!(f, "i8x16.sub_saturate_u"),
2794 I16x8SubSaturateS => write!(f, "i16x8.sub_saturate_S"),
2795 I16x8SubSaturateU => write!(f, "i16x8.sub_saturate_u"),
2796 I8x16Shl => write!(f, "i8x16.shl"),
2797 I16x8Shl => write!(f, "i16x8.shl"),
2798 I32x4Shl => write!(f, "i32x4.shl"),
2799 I64x2Shl => write!(f, "i64x2.shl"),
2800 I8x16ShrS => write!(f, "i8x16.shr_s"),
2801 I8x16ShrU => write!(f, "i8x16.shr_u"),
2802 I16x8ShrS => write!(f, "i16x8.shr_s"),
2803 I16x8ShrU => write!(f, "i16x8.shr_u"),
2804 I32x4ShrS => write!(f, "i32x4.shr_s"),
2805 I32x4ShrU => write!(f, "i32x4.shr_u"),
2806 I64x2ShrS => write!(f, "i64x2.shr_s"),
2807 I64x2ShrU => write!(f, "i64x2.shr_u"),
2808 V128And => write!(f, "v128.and"),
2809 V128Or => write!(f, "v128.or"),
2810 V128Xor => write!(f, "v128.xor"),
2811 V128Not => write!(f, "v128.not"),
2812 V128Bitselect => write!(f, "v128.bitselect"),
2813 I8x16AnyTrue => write!(f, "i8x16.any_true"),
2814 I16x8AnyTrue => write!(f, "i16x8.any_true"),
2815 I32x4AnyTrue => write!(f, "i32x4.any_true"),
2816 I64x2AnyTrue => write!(f, "i64x2.any_true"),
2817 I8x16AllTrue => write!(f, "i8x16.all_true"),
2818 I16x8AllTrue => write!(f, "i16x8.all_true"),
2819 I32x4AllTrue => write!(f, "i32x4.all_true"),
2820 I64x2AllTrue => write!(f, "i64x2.all_true"),
2821 I8x16Eq => write!(f, "i8x16.eq"),
2822 I16x8Eq => write!(f, "i16x8.eq"),
2823 I32x4Eq => write!(f, "i32x4.eq"),
2824 F32x4Eq => write!(f, "f32x4.eq"),
2826 F64x2Eq => write!(f, "f64x2.eq"),
2827 I8x16Ne => write!(f, "i8x16.ne"),
2828 I16x8Ne => write!(f, "i16x8.ne"),
2829 I32x4Ne => write!(f, "i32x4.ne"),
2830 F32x4Ne => write!(f, "f32x4.ne"),
2832 F64x2Ne => write!(f, "f64x2.ne"),
2833 I8x16LtS => write!(f, "i8x16.lt_s"),
2834 I8x16LtU => write!(f, "i8x16.lt_u"),
2835 I16x8LtS => write!(f, "i16x8.lt_s"),
2836 I16x8LtU => write!(f, "i16x8.lt_u"),
2837 I32x4LtS => write!(f, "i32x4.lt_s"),
2838 I32x4LtU => write!(f, "i32x4.lt_u"),
2839 F32x4Lt => write!(f, "f32x4.lt"),
2842 F64x2Lt => write!(f, "f64x2.lt"),
2843 I8x16LeS => write!(f, "i8x16.le_s"),
2844 I8x16LeU => write!(f, "i8x16.le_u"),
2845 I16x8LeS => write!(f, "i16x8.le_s"),
2846 I16x8LeU => write!(f, "i16x8.le_u"),
2847 I32x4LeS => write!(f, "i32x4.le_s"),
2848 I32x4LeU => write!(f, "i32x4.le_u"),
2849 F32x4Le => write!(f, "f32x4.le"),
2852 F64x2Le => write!(f, "f64x2.le"),
2853 I8x16GtS => write!(f, "i8x16.gt_s"),
2854 I8x16GtU => write!(f, "i8x16.gt_u"),
2855 I16x8GtS => write!(f, "i16x8.gt_s"),
2856 I16x8GtU => write!(f, "i16x8.gt_u"),
2857 I32x4GtS => write!(f, "i32x4.gt_s"),
2858 I32x4GtU => write!(f, "i32x4.gt_u"),
2859 F32x4Gt => write!(f, "f32x4.gt"),
2862 F64x2Gt => write!(f, "f64x2.gt"),
2863 I8x16GeS => write!(f, "i8x16.ge_s"),
2864 I8x16GeU => write!(f, "i8x16.ge_u"),
2865 I16x8GeS => write!(f, "i16x8.ge_s"),
2866 I16x8GeU => write!(f, "i16x8.ge_u"),
2867 I32x4GeS => write!(f, "i32x4.ge_s"),
2868 I32x4GeU => write!(f, "i32x4.ge_u"),
2869 F32x4Ge => write!(f, "f32x4.ge"),
2872 F64x2Ge => write!(f, "f64x2.ge"),
2873 F32x4Neg => write!(f, "f32x4.neg"),
2874 F64x2Neg => write!(f, "f64x2.neg"),
2875 F32x4Abs => write!(f, "f32x4.abs"),
2876 F64x2Abs => write!(f, "f64x2.abs"),
2877 F32x4Min => write!(f, "f32x4.min"),
2878 F64x2Min => write!(f, "f64x2.min"),
2879 F32x4Max => write!(f, "f32x4.max"),
2880 F64x2Max => write!(f, "f64x2.max"),
2881 F32x4Add => write!(f, "f32x4.add"),
2882 F64x2Add => write!(f, "f64x2.add"),
2883 F32x4Sub => write!(f, "f32x4.sub"),
2884 F64x2Sub => write!(f, "f64x2.sub"),
2885 F32x4Div => write!(f, "f32x4.div"),
2886 F64x2Div => write!(f, "f64x2.div"),
2887 F32x4Mul => write!(f, "f32x4.mul"),
2888 F64x2Mul => write!(f, "f64x2.mul"),
2889 F32x4Sqrt => write!(f, "f32x4.sqrt"),
2890 F64x2Sqrt => write!(f, "f64x2.sqrt"),
2891 F32x4ConvertSI32x4 => write!(f, "f32x4.convert_s/i32x4"),
2892 F32x4ConvertUI32x4 => write!(f, "f32x4.convert_u/i32x4"),
2893 F64x2ConvertSI64x2 => write!(f, "f64x2.convert_s/i64x2"),
2894 F64x2ConvertUI64x2 => write!(f, "f64x2.convert_u/i64x2"),
2895 I32x4TruncSF32x4Sat => write!(f, "i32x4.trunc_s/f32x4:sat"),
2896 I32x4TruncUF32x4Sat => write!(f, "i32x4.trunc_u/f32x4:sat"),
2897 I64x2TruncSF64x2Sat => write!(f, "i64x2.trunc_s/f64x2:sat"),
2898 I64x2TruncUF64x2Sat => write!(f, "i64x2.trunc_u/f64x2:sat"),
2899 }
2900 }
2901}
2902
2903#[cfg(feature = "bulk")]
2904impl fmt::Display for BulkInstruction {
2905 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2906 use self::BulkInstruction::*;
2907
2908 match *self {
2909 MemoryInit(_) => write!(f, "memory.init"),
2910 MemoryDrop(_) => write!(f, "memory.drop"),
2911 MemoryFill => write!(f, "memory.fill"),
2912 MemoryCopy => write!(f, "memory.copy"),
2913 TableInit(_) => write!(f, "table.init"),
2914 TableDrop(_) => write!(f, "table.drop"),
2915 TableCopy => write!(f, "table.copy"),
2916 }
2917 }
2918}
2919
2920impl Serialize for Instructions {
2921 type Error = Error;
2922
2923 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
2924 for op in self.0.into_iter() {
2925 op.serialize(writer)?;
2926 }
2927
2928 Ok(())
2929 }
2930}
2931
2932impl Serialize for InitExpr {
2933 type Error = Error;
2934
2935 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
2936 for op in self.0.into_iter() {
2937 op.serialize(writer)?;
2938 }
2939
2940 Ok(())
2941 }
2942}
2943
2944#[cfg(test)]
2945mod tests {
2946 use super::*;
2947 #[test]
2948 fn ifelse() {
2949 let instruction_list = crate::elements::deserialize_buffer::<Instructions>(&[
2951 0x04, 0x7F, 0x41, 0x05, 0x05, 0x41, 0x07, 0x0B, 0x0B,
2952 ])
2953 .expect("valid hex of if instruction");
2954 let instructions = instruction_list.elements();
2955 match instructions[0] {
2956 Instruction::If(_) => (),
2957 _ => panic!("Should be deserialized as if instruction"),
2958 }
2959 let before_else = instructions
2960 .iter()
2961 .skip(1)
2962 .take_while(|op| !matches!(**op, Instruction::Else))
2963 .count();
2964 let after_else = instructions
2965 .iter()
2966 .skip(1)
2967 .skip_while(|op| !matches!(**op, Instruction::Else))
2968 .take_while(|op| !matches!(**op, Instruction::End))
2969 .count() - 1; assert_eq!(before_else, after_else);
2971 }
2972
2973 #[test]
2974 fn display() {
2975 let instruction = Instruction::GetLocal(0);
2976 assert_eq!("get_local 0", format!("{}", instruction));
2977
2978 let instruction = Instruction::F64Store(0, 24);
2979 assert_eq!("f64.store offset=24", format!("{}", instruction));
2980
2981 let instruction = Instruction::I64Store(0, 0);
2982 assert_eq!("i64.store", format!("{}", instruction));
2983 }
2984
2985 #[test]
2986 fn size_off() {
2987 assert!(::core::mem::size_of::<Instruction>() <= 24);
2988 }
2989
2990 #[test]
2991 fn instructions_hashset() {
2992 use self::Instruction::{Block, Call, Drop};
2993 use crate::elements::types::{BlockType::Value, ValueType};
2994
2995 let set: hashbrown::HashSet<Instruction> =
2996 vec![Call(1), Block(Value(ValueType::I32)), Drop].into_iter().collect();
2997 assert!(set.contains(&Drop));
2998 }
2999}