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, u8),
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: u8 = Uint8::deserialize(reader)?.into();
1091 if table_ref != 0 {
1092 return Err(Error::InvalidTableReference(table_ref))
1093 }
1094
1095 CallIndirect(signature, table_ref)
1096 },
1097 DROP => Drop,
1098 SELECT => Select,
1099
1100 GETLOCAL => GetLocal(VarUint32::deserialize(reader)?.into()),
1101 SETLOCAL => SetLocal(VarUint32::deserialize(reader)?.into()),
1102 TEELOCAL => TeeLocal(VarUint32::deserialize(reader)?.into()),
1103 GETGLOBAL => GetGlobal(VarUint32::deserialize(reader)?.into()),
1104 SETGLOBAL => SetGlobal(VarUint32::deserialize(reader)?.into()),
1105
1106 I32LOAD => I32Load(
1107 VarUint32::deserialize(reader)?.into(),
1108 VarUint32::deserialize(reader)?.into(),
1109 ),
1110
1111 I64LOAD => I64Load(
1112 VarUint32::deserialize(reader)?.into(),
1113 VarUint32::deserialize(reader)?.into(),
1114 ),
1115
1116 F32LOAD => F32Load(
1117 VarUint32::deserialize(reader)?.into(),
1118 VarUint32::deserialize(reader)?.into(),
1119 ),
1120
1121 F64LOAD => F64Load(
1122 VarUint32::deserialize(reader)?.into(),
1123 VarUint32::deserialize(reader)?.into(),
1124 ),
1125
1126 I32LOAD8S => I32Load8S(
1127 VarUint32::deserialize(reader)?.into(),
1128 VarUint32::deserialize(reader)?.into(),
1129 ),
1130
1131 I32LOAD8U => I32Load8U(
1132 VarUint32::deserialize(reader)?.into(),
1133 VarUint32::deserialize(reader)?.into(),
1134 ),
1135
1136 I32LOAD16S => I32Load16S(
1137 VarUint32::deserialize(reader)?.into(),
1138 VarUint32::deserialize(reader)?.into(),
1139 ),
1140
1141 I32LOAD16U => I32Load16U(
1142 VarUint32::deserialize(reader)?.into(),
1143 VarUint32::deserialize(reader)?.into(),
1144 ),
1145
1146 I64LOAD8S => I64Load8S(
1147 VarUint32::deserialize(reader)?.into(),
1148 VarUint32::deserialize(reader)?.into(),
1149 ),
1150
1151 I64LOAD8U => I64Load8U(
1152 VarUint32::deserialize(reader)?.into(),
1153 VarUint32::deserialize(reader)?.into(),
1154 ),
1155
1156 I64LOAD16S => I64Load16S(
1157 VarUint32::deserialize(reader)?.into(),
1158 VarUint32::deserialize(reader)?.into(),
1159 ),
1160
1161 I64LOAD16U => I64Load16U(
1162 VarUint32::deserialize(reader)?.into(),
1163 VarUint32::deserialize(reader)?.into(),
1164 ),
1165
1166 I64LOAD32S => I64Load32S(
1167 VarUint32::deserialize(reader)?.into(),
1168 VarUint32::deserialize(reader)?.into(),
1169 ),
1170
1171 I64LOAD32U => I64Load32U(
1172 VarUint32::deserialize(reader)?.into(),
1173 VarUint32::deserialize(reader)?.into(),
1174 ),
1175
1176 I32STORE => I32Store(
1177 VarUint32::deserialize(reader)?.into(),
1178 VarUint32::deserialize(reader)?.into(),
1179 ),
1180
1181 I64STORE => I64Store(
1182 VarUint32::deserialize(reader)?.into(),
1183 VarUint32::deserialize(reader)?.into(),
1184 ),
1185
1186 F32STORE => F32Store(
1187 VarUint32::deserialize(reader)?.into(),
1188 VarUint32::deserialize(reader)?.into(),
1189 ),
1190
1191 F64STORE => F64Store(
1192 VarUint32::deserialize(reader)?.into(),
1193 VarUint32::deserialize(reader)?.into(),
1194 ),
1195
1196 I32STORE8 => I32Store8(
1197 VarUint32::deserialize(reader)?.into(),
1198 VarUint32::deserialize(reader)?.into(),
1199 ),
1200
1201 I32STORE16 => I32Store16(
1202 VarUint32::deserialize(reader)?.into(),
1203 VarUint32::deserialize(reader)?.into(),
1204 ),
1205
1206 I64STORE8 => I64Store8(
1207 VarUint32::deserialize(reader)?.into(),
1208 VarUint32::deserialize(reader)?.into(),
1209 ),
1210
1211 I64STORE16 => I64Store16(
1212 VarUint32::deserialize(reader)?.into(),
1213 VarUint32::deserialize(reader)?.into(),
1214 ),
1215
1216 I64STORE32 => I64Store32(
1217 VarUint32::deserialize(reader)?.into(),
1218 VarUint32::deserialize(reader)?.into(),
1219 ),
1220
1221 CURRENTMEMORY => {
1222 let mem_ref: u8 = Uint8::deserialize(reader)?.into();
1223 if mem_ref != 0 {
1224 return Err(Error::InvalidMemoryReference(mem_ref))
1225 }
1226 CurrentMemory(mem_ref)
1227 },
1228 GROWMEMORY => {
1229 let mem_ref: u8 = Uint8::deserialize(reader)?.into();
1230 if mem_ref != 0 {
1231 return Err(Error::InvalidMemoryReference(mem_ref))
1232 }
1233 GrowMemory(mem_ref)
1234 },
1235
1236 I32CONST => I32Const(VarInt32::deserialize(reader)?.into()),
1237 I64CONST => I64Const(VarInt64::deserialize(reader)?.into()),
1238 F32CONST => F32Const(Uint32::deserialize(reader)?.into()),
1239 F64CONST => F64Const(Uint64::deserialize(reader)?.into()),
1240 I32EQZ => I32Eqz,
1241 I32EQ => I32Eq,
1242 I32NE => I32Ne,
1243 I32LTS => I32LtS,
1244 I32LTU => I32LtU,
1245 I32GTS => I32GtS,
1246 I32GTU => I32GtU,
1247 I32LES => I32LeS,
1248 I32LEU => I32LeU,
1249 I32GES => I32GeS,
1250 I32GEU => I32GeU,
1251
1252 I64EQZ => I64Eqz,
1253 I64EQ => I64Eq,
1254 I64NE => I64Ne,
1255 I64LTS => I64LtS,
1256 I64LTU => I64LtU,
1257 I64GTS => I64GtS,
1258 I64GTU => I64GtU,
1259 I64LES => I64LeS,
1260 I64LEU => I64LeU,
1261 I64GES => I64GeS,
1262 I64GEU => I64GeU,
1263
1264 F32EQ => F32Eq,
1265 F32NE => F32Ne,
1266 F32LT => F32Lt,
1267 F32GT => F32Gt,
1268 F32LE => F32Le,
1269 F32GE => F32Ge,
1270
1271 F64EQ => F64Eq,
1272 F64NE => F64Ne,
1273 F64LT => F64Lt,
1274 F64GT => F64Gt,
1275 F64LE => F64Le,
1276 F64GE => F64Ge,
1277
1278 I32CLZ => I32Clz,
1279 I32CTZ => I32Ctz,
1280 I32POPCNT => I32Popcnt,
1281 I32ADD => I32Add,
1282 I32SUB => I32Sub,
1283 I32MUL => I32Mul,
1284 I32DIVS => I32DivS,
1285 I32DIVU => I32DivU,
1286 I32REMS => I32RemS,
1287 I32REMU => I32RemU,
1288 I32AND => I32And,
1289 I32OR => I32Or,
1290 I32XOR => I32Xor,
1291 I32SHL => I32Shl,
1292 I32SHRS => I32ShrS,
1293 I32SHRU => I32ShrU,
1294 I32ROTL => I32Rotl,
1295 I32ROTR => I32Rotr,
1296
1297 I64CLZ => I64Clz,
1298 I64CTZ => I64Ctz,
1299 I64POPCNT => I64Popcnt,
1300 I64ADD => I64Add,
1301 I64SUB => I64Sub,
1302 I64MUL => I64Mul,
1303 I64DIVS => I64DivS,
1304 I64DIVU => I64DivU,
1305 I64REMS => I64RemS,
1306 I64REMU => I64RemU,
1307 I64AND => I64And,
1308 I64OR => I64Or,
1309 I64XOR => I64Xor,
1310 I64SHL => I64Shl,
1311 I64SHRS => I64ShrS,
1312 I64SHRU => I64ShrU,
1313 I64ROTL => I64Rotl,
1314 I64ROTR => I64Rotr,
1315 F32ABS => F32Abs,
1316 F32NEG => F32Neg,
1317 F32CEIL => F32Ceil,
1318 F32FLOOR => F32Floor,
1319 F32TRUNC => F32Trunc,
1320 F32NEAREST => F32Nearest,
1321 F32SQRT => F32Sqrt,
1322 F32ADD => F32Add,
1323 F32SUB => F32Sub,
1324 F32MUL => F32Mul,
1325 F32DIV => F32Div,
1326 F32MIN => F32Min,
1327 F32MAX => F32Max,
1328 F32COPYSIGN => F32Copysign,
1329 F64ABS => F64Abs,
1330 F64NEG => F64Neg,
1331 F64CEIL => F64Ceil,
1332 F64FLOOR => F64Floor,
1333 F64TRUNC => F64Trunc,
1334 F64NEAREST => F64Nearest,
1335 F64SQRT => F64Sqrt,
1336 F64ADD => F64Add,
1337 F64SUB => F64Sub,
1338 F64MUL => F64Mul,
1339 F64DIV => F64Div,
1340 F64MIN => F64Min,
1341 F64MAX => F64Max,
1342 F64COPYSIGN => F64Copysign,
1343
1344 I32WRAPI64 => I32WrapI64,
1345 I32TRUNCSF32 => I32TruncSF32,
1346 I32TRUNCUF32 => I32TruncUF32,
1347 I32TRUNCSF64 => I32TruncSF64,
1348 I32TRUNCUF64 => I32TruncUF64,
1349 I64EXTENDSI32 => I64ExtendSI32,
1350 I64EXTENDUI32 => I64ExtendUI32,
1351 I64TRUNCSF32 => I64TruncSF32,
1352 I64TRUNCUF32 => I64TruncUF32,
1353 I64TRUNCSF64 => I64TruncSF64,
1354 I64TRUNCUF64 => I64TruncUF64,
1355 F32CONVERTSI32 => F32ConvertSI32,
1356 F32CONVERTUI32 => F32ConvertUI32,
1357 F32CONVERTSI64 => F32ConvertSI64,
1358 F32CONVERTUI64 => F32ConvertUI64,
1359 F32DEMOTEF64 => F32DemoteF64,
1360 F64CONVERTSI32 => F64ConvertSI32,
1361 F64CONVERTUI32 => F64ConvertUI32,
1362 F64CONVERTSI64 => F64ConvertSI64,
1363 F64CONVERTUI64 => F64ConvertUI64,
1364 F64PROMOTEF32 => F64PromoteF32,
1365
1366 I32REINTERPRETF32 => I32ReinterpretF32,
1367 I64REINTERPRETF64 => I64ReinterpretF64,
1368 F32REINTERPRETI32 => F32ReinterpretI32,
1369 F64REINTERPRETI64 => F64ReinterpretI64,
1370
1371 #[cfg(feature = "sign_ext")]
1372 I32_EXTEND8_S | I32_EXTEND16_S | I64_EXTEND8_S | I64_EXTEND16_S | I64_EXTEND32_S => match val {
1373 I32_EXTEND8_S => SignExt(SignExtInstruction::I32Extend8S),
1374 I32_EXTEND16_S => SignExt(SignExtInstruction::I32Extend16S),
1375 I64_EXTEND8_S => SignExt(SignExtInstruction::I64Extend8S),
1376 I64_EXTEND16_S => SignExt(SignExtInstruction::I64Extend16S),
1377 I64_EXTEND32_S => SignExt(SignExtInstruction::I64Extend32S),
1378 _ => return Err(Error::UnknownOpcode(val)),
1379 },
1380
1381 #[cfg(feature = "atomics")]
1382 atomics::ATOMIC_PREFIX => return deserialize_atomic(reader),
1383
1384 #[cfg(feature = "simd")]
1385 simd::SIMD_PREFIX => return deserialize_simd(reader),
1386
1387 #[cfg(feature = "bulk")]
1388 bulk::BULK_PREFIX => return deserialize_bulk(reader),
1389
1390 _ => return Err(Error::UnknownOpcode(val)),
1391 })
1392 }
1393}
1394
1395#[cfg(feature = "atomics")]
1396fn deserialize_atomic<R: io::Read>(reader: &mut R) -> Result<Instruction, Error> {
1397 use self::{opcodes::atomics::*, AtomicsInstruction::*};
1398
1399 let val: u8 = Uint8::deserialize(reader)?.into();
1400 let mem = MemArg::deserialize(reader)?;
1401 Ok(Instruction::Atomics(match val {
1402 ATOMIC_WAKE => AtomicWake(mem),
1403 I32_ATOMIC_WAIT => I32AtomicWait(mem),
1404 I64_ATOMIC_WAIT => I64AtomicWait(mem),
1405
1406 I32_ATOMIC_LOAD => I32AtomicLoad(mem),
1407 I64_ATOMIC_LOAD => I64AtomicLoad(mem),
1408 I32_ATOMIC_LOAD8U => I32AtomicLoad8u(mem),
1409 I32_ATOMIC_LOAD16U => I32AtomicLoad16u(mem),
1410 I64_ATOMIC_LOAD8U => I64AtomicLoad8u(mem),
1411 I64_ATOMIC_LOAD16U => I64AtomicLoad16u(mem),
1412 I64_ATOMIC_LOAD32U => I64AtomicLoad32u(mem),
1413 I32_ATOMIC_STORE => I32AtomicStore(mem),
1414 I64_ATOMIC_STORE => I64AtomicStore(mem),
1415 I32_ATOMIC_STORE8U => I32AtomicStore8u(mem),
1416 I32_ATOMIC_STORE16U => I32AtomicStore16u(mem),
1417 I64_ATOMIC_STORE8U => I64AtomicStore8u(mem),
1418 I64_ATOMIC_STORE16U => I64AtomicStore16u(mem),
1419 I64_ATOMIC_STORE32U => I64AtomicStore32u(mem),
1420
1421 I32_ATOMIC_RMW_ADD => I32AtomicRmwAdd(mem),
1422 I64_ATOMIC_RMW_ADD => I64AtomicRmwAdd(mem),
1423 I32_ATOMIC_RMW_ADD8U => I32AtomicRmwAdd8u(mem),
1424 I32_ATOMIC_RMW_ADD16U => I32AtomicRmwAdd16u(mem),
1425 I64_ATOMIC_RMW_ADD8U => I64AtomicRmwAdd8u(mem),
1426 I64_ATOMIC_RMW_ADD16U => I64AtomicRmwAdd16u(mem),
1427 I64_ATOMIC_RMW_ADD32U => I64AtomicRmwAdd32u(mem),
1428
1429 I32_ATOMIC_RMW_SUB => I32AtomicRmwSub(mem),
1430 I64_ATOMIC_RMW_SUB => I64AtomicRmwSub(mem),
1431 I32_ATOMIC_RMW_SUB8U => I32AtomicRmwSub8u(mem),
1432 I32_ATOMIC_RMW_SUB16U => I32AtomicRmwSub16u(mem),
1433 I64_ATOMIC_RMW_SUB8U => I64AtomicRmwSub8u(mem),
1434 I64_ATOMIC_RMW_SUB16U => I64AtomicRmwSub16u(mem),
1435 I64_ATOMIC_RMW_SUB32U => I64AtomicRmwSub32u(mem),
1436
1437 I32_ATOMIC_RMW_AND => I32AtomicRmwAnd(mem),
1438 I64_ATOMIC_RMW_AND => I64AtomicRmwAnd(mem),
1439 I32_ATOMIC_RMW_AND8U => I32AtomicRmwAnd8u(mem),
1440 I32_ATOMIC_RMW_AND16U => I32AtomicRmwAnd16u(mem),
1441 I64_ATOMIC_RMW_AND8U => I64AtomicRmwAnd8u(mem),
1442 I64_ATOMIC_RMW_AND16U => I64AtomicRmwAnd16u(mem),
1443 I64_ATOMIC_RMW_AND32U => I64AtomicRmwAnd32u(mem),
1444
1445 I32_ATOMIC_RMW_OR => I32AtomicRmwOr(mem),
1446 I64_ATOMIC_RMW_OR => I64AtomicRmwOr(mem),
1447 I32_ATOMIC_RMW_OR8U => I32AtomicRmwOr8u(mem),
1448 I32_ATOMIC_RMW_OR16U => I32AtomicRmwOr16u(mem),
1449 I64_ATOMIC_RMW_OR8U => I64AtomicRmwOr8u(mem),
1450 I64_ATOMIC_RMW_OR16U => I64AtomicRmwOr16u(mem),
1451 I64_ATOMIC_RMW_OR32U => I64AtomicRmwOr32u(mem),
1452
1453 I32_ATOMIC_RMW_XOR => I32AtomicRmwXor(mem),
1454 I64_ATOMIC_RMW_XOR => I64AtomicRmwXor(mem),
1455 I32_ATOMIC_RMW_XOR8U => I32AtomicRmwXor8u(mem),
1456 I32_ATOMIC_RMW_XOR16U => I32AtomicRmwXor16u(mem),
1457 I64_ATOMIC_RMW_XOR8U => I64AtomicRmwXor8u(mem),
1458 I64_ATOMIC_RMW_XOR16U => I64AtomicRmwXor16u(mem),
1459 I64_ATOMIC_RMW_XOR32U => I64AtomicRmwXor32u(mem),
1460
1461 I32_ATOMIC_RMW_XCHG => I32AtomicRmwXchg(mem),
1462 I64_ATOMIC_RMW_XCHG => I64AtomicRmwXchg(mem),
1463 I32_ATOMIC_RMW_XCHG8U => I32AtomicRmwXchg8u(mem),
1464 I32_ATOMIC_RMW_XCHG16U => I32AtomicRmwXchg16u(mem),
1465 I64_ATOMIC_RMW_XCHG8U => I64AtomicRmwXchg8u(mem),
1466 I64_ATOMIC_RMW_XCHG16U => I64AtomicRmwXchg16u(mem),
1467 I64_ATOMIC_RMW_XCHG32U => I64AtomicRmwXchg32u(mem),
1468
1469 I32_ATOMIC_RMW_CMPXCHG => I32AtomicRmwCmpxchg(mem),
1470 I64_ATOMIC_RMW_CMPXCHG => I64AtomicRmwCmpxchg(mem),
1471 I32_ATOMIC_RMW_CMPXCHG8U => I32AtomicRmwCmpxchg8u(mem),
1472 I32_ATOMIC_RMW_CMPXCHG16U => I32AtomicRmwCmpxchg16u(mem),
1473 I64_ATOMIC_RMW_CMPXCHG8U => I64AtomicRmwCmpxchg8u(mem),
1474 I64_ATOMIC_RMW_CMPXCHG16U => I64AtomicRmwCmpxchg16u(mem),
1475 I64_ATOMIC_RMW_CMPXCHG32U => I64AtomicRmwCmpxchg32u(mem),
1476
1477 _ => return Err(Error::UnknownOpcode(val)),
1478 }))
1479}
1480
1481#[cfg(feature = "simd")]
1482fn deserialize_simd<R: io::Read>(reader: &mut R) -> Result<Instruction, Error> {
1483 use self::{opcodes::simd::*, SimdInstruction::*};
1484
1485 let val = VarUint32::deserialize(reader)?.into();
1486 Ok(Instruction::Simd(match val {
1487 V128_CONST => {
1488 let mut buf = [0; 16];
1489 reader.read(&mut buf)?;
1490 V128Const(Box::new(buf))
1491 },
1492 V128_LOAD => V128Load(MemArg::deserialize(reader)?),
1493 V128_STORE => V128Store(MemArg::deserialize(reader)?),
1494 I8X16_SPLAT => I8x16Splat,
1495 I16X8_SPLAT => I16x8Splat,
1496 I32X4_SPLAT => I32x4Splat,
1497 I64X2_SPLAT => I64x2Splat,
1498 F32X4_SPLAT => F32x4Splat,
1499 F64X2_SPLAT => F64x2Splat,
1500 I8X16_EXTRACT_LANE_S => I8x16ExtractLaneS(Uint8::deserialize(reader)?.into()),
1501 I8X16_EXTRACT_LANE_U => I8x16ExtractLaneU(Uint8::deserialize(reader)?.into()),
1502 I16X8_EXTRACT_LANE_S => I16x8ExtractLaneS(Uint8::deserialize(reader)?.into()),
1503 I16X8_EXTRACT_LANE_U => I16x8ExtractLaneU(Uint8::deserialize(reader)?.into()),
1504 I32X4_EXTRACT_LANE => I32x4ExtractLane(Uint8::deserialize(reader)?.into()),
1505 I64X2_EXTRACT_LANE => I64x2ExtractLane(Uint8::deserialize(reader)?.into()),
1506 F32X4_EXTRACT_LANE => F32x4ExtractLane(Uint8::deserialize(reader)?.into()),
1507 F64X2_EXTRACT_LANE => F64x2ExtractLane(Uint8::deserialize(reader)?.into()),
1508 I8X16_REPLACE_LANE => I8x16ReplaceLane(Uint8::deserialize(reader)?.into()),
1509 I16X8_REPLACE_LANE => I16x8ReplaceLane(Uint8::deserialize(reader)?.into()),
1510 I32X4_REPLACE_LANE => I32x4ReplaceLane(Uint8::deserialize(reader)?.into()),
1511 I64X2_REPLACE_LANE => I64x2ReplaceLane(Uint8::deserialize(reader)?.into()),
1512 F32X4_REPLACE_LANE => F32x4ReplaceLane(Uint8::deserialize(reader)?.into()),
1513 F64X2_REPLACE_LANE => F64x2ReplaceLane(Uint8::deserialize(reader)?.into()),
1514 V8X16_SHUFFLE => {
1515 let mut buf = [0; 16];
1516 reader.read(&mut buf)?;
1517 V8x16Shuffle(Box::new(buf))
1518 },
1519 I8X16_ADD => I8x16Add,
1520 I16X8_ADD => I16x8Add,
1521 I32X4_ADD => I32x4Add,
1522 I64X2_ADD => I64x2Add,
1523 I8X16_SUB => I8x16Sub,
1524 I16X8_SUB => I16x8Sub,
1525 I32X4_SUB => I32x4Sub,
1526 I64X2_SUB => I64x2Sub,
1527 I8X16_MUL => I8x16Mul,
1528 I16X8_MUL => I16x8Mul,
1529 I32X4_MUL => I32x4Mul,
1530 I8X16_NEG => I8x16Neg,
1532 I16X8_NEG => I16x8Neg,
1533 I32X4_NEG => I32x4Neg,
1534 I64X2_NEG => I64x2Neg,
1535
1536 I8X16_ADD_SATURATE_S => I8x16AddSaturateS,
1537 I8X16_ADD_SATURATE_U => I8x16AddSaturateU,
1538 I16X8_ADD_SATURATE_S => I16x8AddSaturateS,
1539 I16X8_ADD_SATURATE_U => I16x8AddSaturateU,
1540 I8X16_SUB_SATURATE_S => I8x16SubSaturateS,
1541 I8X16_SUB_SATURATE_U => I8x16SubSaturateU,
1542 I16X8_SUB_SATURATE_S => I16x8SubSaturateS,
1543 I16X8_SUB_SATURATE_U => I16x8SubSaturateU,
1544 I8X16_SHL => I8x16Shl,
1545 I16X8_SHL => I16x8Shl,
1546 I32X4_SHL => I32x4Shl,
1547 I64X2_SHL => I64x2Shl,
1548 I8X16_SHR_S => I8x16ShrS,
1549 I8X16_SHR_U => I8x16ShrU,
1550 I16X8_SHR_S => I16x8ShrS,
1551 I16X8_SHR_U => I16x8ShrU,
1552 I32X4_SHR_S => I32x4ShrS,
1553 I32X4_SHR_U => I32x4ShrU,
1554 I64X2_SHR_S => I64x2ShrS,
1555 I64X2_SHR_U => I64x2ShrU,
1556 V128_AND => V128And,
1557 V128_OR => V128Or,
1558 V128_XOR => V128Xor,
1559 V128_NOT => V128Not,
1560 V128_BITSELECT => V128Bitselect,
1561 I8X16_ANY_TRUE => I8x16AnyTrue,
1562 I16X8_ANY_TRUE => I16x8AnyTrue,
1563 I32X4_ANY_TRUE => I32x4AnyTrue,
1564 I64X2_ANY_TRUE => I64x2AnyTrue,
1565 I8X16_ALL_TRUE => I8x16AllTrue,
1566 I16X8_ALL_TRUE => I16x8AllTrue,
1567 I32X4_ALL_TRUE => I32x4AllTrue,
1568 I64X2_ALL_TRUE => I64x2AllTrue,
1569 I8X16_EQ => I8x16Eq,
1570 I16X8_EQ => I16x8Eq,
1571 I32X4_EQ => I32x4Eq,
1572 F32X4_EQ => F32x4Eq,
1574 F64X2_EQ => F64x2Eq,
1575 I8X16_NE => I8x16Ne,
1576 I16X8_NE => I16x8Ne,
1577 I32X4_NE => I32x4Ne,
1578 F32X4_NE => F32x4Ne,
1580 F64X2_NE => F64x2Ne,
1581 I8X16_LT_S => I8x16LtS,
1582 I8X16_LT_U => I8x16LtU,
1583 I16X8_LT_S => I16x8LtS,
1584 I16X8_LT_U => I16x8LtU,
1585 I32X4_LT_S => I32x4LtS,
1586 I32X4_LT_U => I32x4LtU,
1587 F32X4_LT => F32x4Lt,
1590 F64X2_LT => F64x2Lt,
1591 I8X16_LE_S => I8x16LeS,
1592 I8X16_LE_U => I8x16LeU,
1593 I16X8_LE_S => I16x8LeS,
1594 I16X8_LE_U => I16x8LeU,
1595 I32X4_LE_S => I32x4LeS,
1596 I32X4_LE_U => I32x4LeU,
1597 F32X4_LE => F32x4Le,
1600 F64X2_LE => F64x2Le,
1601 I8X16_GT_S => I8x16GtS,
1602 I8X16_GT_U => I8x16GtU,
1603 I16X8_GT_S => I16x8GtS,
1604 I16X8_GT_U => I16x8GtU,
1605 I32X4_GT_S => I32x4GtS,
1606 I32X4_GT_U => I32x4GtU,
1607 F32X4_GT => F32x4Gt,
1610 F64X2_GT => F64x2Gt,
1611 I8X16_GE_S => I8x16GeS,
1612 I8X16_GE_U => I8x16GeU,
1613 I16X8_GE_S => I16x8GeS,
1614 I16X8_GE_U => I16x8GeU,
1615 I32X4_GE_S => I32x4GeS,
1616 I32X4_GE_U => I32x4GeU,
1617 F32X4_GE => F32x4Ge,
1620 F64X2_GE => F64x2Ge,
1621 F32X4_NEG => F32x4Neg,
1622 F64X2_NEG => F64x2Neg,
1623 F32X4_ABS => F32x4Abs,
1624 F64X2_ABS => F64x2Abs,
1625 F32X4_MIN => F32x4Min,
1626 F64X2_MIN => F64x2Min,
1627 F32X4_MAX => F32x4Max,
1628 F64X2_MAX => F64x2Max,
1629 F32X4_ADD => F32x4Add,
1630 F64X2_ADD => F64x2Add,
1631 F32X4_SUB => F32x4Sub,
1632 F64X2_SUB => F64x2Sub,
1633 F32X4_DIV => F32x4Div,
1634 F64X2_DIV => F64x2Div,
1635 F32X4_MUL => F32x4Mul,
1636 F64X2_MUL => F64x2Mul,
1637 F32X4_SQRT => F32x4Sqrt,
1638 F64X2_SQRT => F64x2Sqrt,
1639 F32X4_CONVERT_S_I32X4 => F32x4ConvertSI32x4,
1640 F32X4_CONVERT_U_I32X4 => F32x4ConvertUI32x4,
1641 F64X2_CONVERT_S_I64X2 => F64x2ConvertSI64x2,
1642 F64X2_CONVERT_U_I64X2 => F64x2ConvertUI64x2,
1643 I32X4_TRUNC_S_F32X4_SAT => I32x4TruncSF32x4Sat,
1644 I32X4_TRUNC_U_F32X4_SAT => I32x4TruncUF32x4Sat,
1645 I64X2_TRUNC_S_F64X2_SAT => I64x2TruncSF64x2Sat,
1646 I64X2_TRUNC_U_F64X2_SAT => I64x2TruncUF64x2Sat,
1647
1648 _ => return Err(Error::UnknownSimdOpcode(val)),
1649 }))
1650}
1651
1652#[cfg(feature = "bulk")]
1653fn deserialize_bulk<R: io::Read>(reader: &mut R) -> Result<Instruction, Error> {
1654 use self::{opcodes::bulk::*, BulkInstruction::*};
1655
1656 let val: u8 = Uint8::deserialize(reader)?.into();
1657 Ok(Instruction::Bulk(match val {
1658 MEMORY_INIT => {
1659 if u8::from(Uint8::deserialize(reader)?) != 0 {
1660 return Err(Error::UnknownOpcode(val))
1661 }
1662 MemoryInit(VarUint32::deserialize(reader)?.into())
1663 },
1664 MEMORY_DROP => MemoryDrop(VarUint32::deserialize(reader)?.into()),
1665 MEMORY_FILL => {
1666 if u8::from(Uint8::deserialize(reader)?) != 0 {
1667 return Err(Error::UnknownOpcode(val))
1668 }
1669 MemoryFill
1670 },
1671 MEMORY_COPY => {
1672 if u8::from(Uint8::deserialize(reader)?) != 0 {
1673 return Err(Error::UnknownOpcode(val))
1674 }
1675 MemoryCopy
1676 },
1677
1678 TABLE_INIT => {
1679 if u8::from(Uint8::deserialize(reader)?) != 0 {
1680 return Err(Error::UnknownOpcode(val))
1681 }
1682 TableInit(VarUint32::deserialize(reader)?.into())
1683 },
1684 TABLE_DROP => TableDrop(VarUint32::deserialize(reader)?.into()),
1685 TABLE_COPY => {
1686 if u8::from(Uint8::deserialize(reader)?) != 0 {
1687 return Err(Error::UnknownOpcode(val))
1688 }
1689 TableCopy
1690 },
1691
1692 _ => return Err(Error::UnknownOpcode(val)),
1693 }))
1694}
1695
1696#[cfg(any(feature = "simd", feature = "atomics"))]
1697impl Deserialize for MemArg {
1698 type Error = Error;
1699
1700 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
1701 let align = Uint8::deserialize(reader)?;
1702 let offset = VarUint32::deserialize(reader)?;
1703 Ok(MemArg { align: align.into(), offset: offset.into() })
1704 }
1705}
1706
1707macro_rules! op {
1708 ($writer: expr, $byte: expr) => {{
1709 let b: u8 = $byte;
1710 $writer.write(&[b])?;
1711 }};
1712 ($writer: expr, $byte: expr, $s: block) => {{
1713 op!($writer, $byte);
1714 $s;
1715 }};
1716}
1717
1718#[cfg(feature = "atomics")]
1719macro_rules! atomic {
1720 ($writer: expr, $byte: expr, $mem:expr) => {{
1721 $writer.write(&[ATOMIC_PREFIX, $byte])?;
1722 MemArg::serialize($mem, $writer)?;
1723 }};
1724}
1725
1726#[cfg(feature = "simd")]
1727macro_rules! simd {
1728 ($writer: expr, $byte: expr, $other:expr) => {{
1729 $writer.write(&[SIMD_PREFIX])?;
1730 VarUint32::from($byte).serialize($writer)?;
1731 $other;
1732 }};
1733}
1734
1735#[cfg(feature = "bulk")]
1736macro_rules! bulk {
1737 ($writer: expr, $byte: expr) => {{
1738 $writer.write(&[BULK_PREFIX, $byte])?;
1739 }};
1740 ($writer: expr, $byte: expr, $remaining:expr) => {{
1741 bulk!($writer, $byte);
1742 $remaining;
1743 }};
1744}
1745
1746impl Serialize for Instruction {
1747 type Error = Error;
1748
1749 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
1750 use self::{opcodes::*, Instruction::*};
1751
1752 match self {
1753 Unreachable => op!(writer, UNREACHABLE),
1754 Nop => op!(writer, NOP),
1755 Block(block_type) => op!(writer, BLOCK, {
1756 block_type.serialize(writer)?;
1757 }),
1758 Loop(block_type) => op!(writer, LOOP, {
1759 block_type.serialize(writer)?;
1760 }),
1761 If(block_type) => op!(writer, IF, {
1762 block_type.serialize(writer)?;
1763 }),
1764 Else => op!(writer, ELSE),
1765 End => op!(writer, END),
1766 Br(idx) => op!(writer, BR, {
1767 VarUint32::from(idx).serialize(writer)?;
1768 }),
1769 BrIf(idx) => op!(writer, BRIF, {
1770 VarUint32::from(idx).serialize(writer)?;
1771 }),
1772 BrTable(ref table) => op!(writer, BRTABLE, {
1773 let list_writer = CountedListWriter::<VarUint32, _>(
1774 table.table.len(),
1775 table.table.iter().map(|x| VarUint32::from(*x)),
1776 );
1777 list_writer.serialize(writer)?;
1778 VarUint32::from(table.default).serialize(writer)?;
1779 }),
1780 Return => op!(writer, RETURN),
1781 Call(index) => op!(writer, CALL, {
1782 VarUint32::from(index).serialize(writer)?;
1783 }),
1784 CallIndirect(index, reserved) => op!(writer, CALLINDIRECT, {
1785 VarUint32::from(index).serialize(writer)?;
1786 Uint8::from(reserved).serialize(writer)?;
1787 }),
1788 Drop => op!(writer, DROP),
1789 Select => op!(writer, SELECT),
1790 GetLocal(index) => op!(writer, GETLOCAL, {
1791 VarUint32::from(index).serialize(writer)?;
1792 }),
1793 SetLocal(index) => op!(writer, SETLOCAL, {
1794 VarUint32::from(index).serialize(writer)?;
1795 }),
1796 TeeLocal(index) => op!(writer, TEELOCAL, {
1797 VarUint32::from(index).serialize(writer)?;
1798 }),
1799 GetGlobal(index) => op!(writer, GETGLOBAL, {
1800 VarUint32::from(index).serialize(writer)?;
1801 }),
1802 SetGlobal(index) => op!(writer, SETGLOBAL, {
1803 VarUint32::from(index).serialize(writer)?;
1804 }),
1805 I32Load(flags, offset) => op!(writer, I32LOAD, {
1806 VarUint32::from(flags).serialize(writer)?;
1807 VarUint32::from(offset).serialize(writer)?;
1808 }),
1809 I64Load(flags, offset) => op!(writer, I64LOAD, {
1810 VarUint32::from(flags).serialize(writer)?;
1811 VarUint32::from(offset).serialize(writer)?;
1812 }),
1813 F32Load(flags, offset) => op!(writer, F32LOAD, {
1814 VarUint32::from(flags).serialize(writer)?;
1815 VarUint32::from(offset).serialize(writer)?;
1816 }),
1817 F64Load(flags, offset) => op!(writer, F64LOAD, {
1818 VarUint32::from(flags).serialize(writer)?;
1819 VarUint32::from(offset).serialize(writer)?;
1820 }),
1821 I32Load8S(flags, offset) => op!(writer, I32LOAD8S, {
1822 VarUint32::from(flags).serialize(writer)?;
1823 VarUint32::from(offset).serialize(writer)?;
1824 }),
1825 I32Load8U(flags, offset) => op!(writer, I32LOAD8U, {
1826 VarUint32::from(flags).serialize(writer)?;
1827 VarUint32::from(offset).serialize(writer)?;
1828 }),
1829 I32Load16S(flags, offset) => op!(writer, I32LOAD16S, {
1830 VarUint32::from(flags).serialize(writer)?;
1831 VarUint32::from(offset).serialize(writer)?;
1832 }),
1833 I32Load16U(flags, offset) => op!(writer, I32LOAD16U, {
1834 VarUint32::from(flags).serialize(writer)?;
1835 VarUint32::from(offset).serialize(writer)?;
1836 }),
1837 I64Load8S(flags, offset) => op!(writer, I64LOAD8S, {
1838 VarUint32::from(flags).serialize(writer)?;
1839 VarUint32::from(offset).serialize(writer)?;
1840 }),
1841 I64Load8U(flags, offset) => op!(writer, I64LOAD8U, {
1842 VarUint32::from(flags).serialize(writer)?;
1843 VarUint32::from(offset).serialize(writer)?;
1844 }),
1845 I64Load16S(flags, offset) => op!(writer, I64LOAD16S, {
1846 VarUint32::from(flags).serialize(writer)?;
1847 VarUint32::from(offset).serialize(writer)?;
1848 }),
1849 I64Load16U(flags, offset) => op!(writer, I64LOAD16U, {
1850 VarUint32::from(flags).serialize(writer)?;
1851 VarUint32::from(offset).serialize(writer)?;
1852 }),
1853 I64Load32S(flags, offset) => op!(writer, I64LOAD32S, {
1854 VarUint32::from(flags).serialize(writer)?;
1855 VarUint32::from(offset).serialize(writer)?;
1856 }),
1857 I64Load32U(flags, offset) => op!(writer, I64LOAD32U, {
1858 VarUint32::from(flags).serialize(writer)?;
1859 VarUint32::from(offset).serialize(writer)?;
1860 }),
1861 I32Store(flags, offset) => op!(writer, I32STORE, {
1862 VarUint32::from(flags).serialize(writer)?;
1863 VarUint32::from(offset).serialize(writer)?;
1864 }),
1865 I64Store(flags, offset) => op!(writer, I64STORE, {
1866 VarUint32::from(flags).serialize(writer)?;
1867 VarUint32::from(offset).serialize(writer)?;
1868 }),
1869 F32Store(flags, offset) => op!(writer, F32STORE, {
1870 VarUint32::from(flags).serialize(writer)?;
1871 VarUint32::from(offset).serialize(writer)?;
1872 }),
1873 F64Store(flags, offset) => op!(writer, F64STORE, {
1874 VarUint32::from(flags).serialize(writer)?;
1875 VarUint32::from(offset).serialize(writer)?;
1876 }),
1877 I32Store8(flags, offset) => op!(writer, I32STORE8, {
1878 VarUint32::from(flags).serialize(writer)?;
1879 VarUint32::from(offset).serialize(writer)?;
1880 }),
1881 I32Store16(flags, offset) => op!(writer, I32STORE16, {
1882 VarUint32::from(flags).serialize(writer)?;
1883 VarUint32::from(offset).serialize(writer)?;
1884 }),
1885 I64Store8(flags, offset) => op!(writer, I64STORE8, {
1886 VarUint32::from(flags).serialize(writer)?;
1887 VarUint32::from(offset).serialize(writer)?;
1888 }),
1889 I64Store16(flags, offset) => op!(writer, I64STORE16, {
1890 VarUint32::from(flags).serialize(writer)?;
1891 VarUint32::from(offset).serialize(writer)?;
1892 }),
1893 I64Store32(flags, offset) => op!(writer, I64STORE32, {
1894 VarUint32::from(flags).serialize(writer)?;
1895 VarUint32::from(offset).serialize(writer)?;
1896 }),
1897 CurrentMemory(flag) => op!(writer, CURRENTMEMORY, {
1898 Uint8::from(flag).serialize(writer)?;
1899 }),
1900 GrowMemory(flag) => op!(writer, GROWMEMORY, {
1901 Uint8::from(flag).serialize(writer)?;
1902 }),
1903 I32Const(def) => op!(writer, I32CONST, {
1904 VarInt32::from(def).serialize(writer)?;
1905 }),
1906 I64Const(def) => op!(writer, I64CONST, {
1907 VarInt64::from(def).serialize(writer)?;
1908 }),
1909 F32Const(def) => op!(writer, F32CONST, {
1910 Uint32::from(def).serialize(writer)?;
1911 }),
1912 F64Const(def) => op!(writer, F64CONST, {
1913 Uint64::from(def).serialize(writer)?;
1914 }),
1915 I32Eqz => op!(writer, I32EQZ),
1916 I32Eq => op!(writer, I32EQ),
1917 I32Ne => op!(writer, I32NE),
1918 I32LtS => op!(writer, I32LTS),
1919 I32LtU => op!(writer, I32LTU),
1920 I32GtS => op!(writer, I32GTS),
1921 I32GtU => op!(writer, I32GTU),
1922 I32LeS => op!(writer, I32LES),
1923 I32LeU => op!(writer, I32LEU),
1924 I32GeS => op!(writer, I32GES),
1925 I32GeU => op!(writer, I32GEU),
1926
1927 I64Eqz => op!(writer, I64EQZ),
1928 I64Eq => op!(writer, I64EQ),
1929 I64Ne => op!(writer, I64NE),
1930 I64LtS => op!(writer, I64LTS),
1931 I64LtU => op!(writer, I64LTU),
1932 I64GtS => op!(writer, I64GTS),
1933 I64GtU => op!(writer, I64GTU),
1934 I64LeS => op!(writer, I64LES),
1935 I64LeU => op!(writer, I64LEU),
1936 I64GeS => op!(writer, I64GES),
1937 I64GeU => op!(writer, I64GEU),
1938
1939 F32Eq => op!(writer, F32EQ),
1940 F32Ne => op!(writer, F32NE),
1941 F32Lt => op!(writer, F32LT),
1942 F32Gt => op!(writer, F32GT),
1943 F32Le => op!(writer, F32LE),
1944 F32Ge => op!(writer, F32GE),
1945
1946 F64Eq => op!(writer, F64EQ),
1947 F64Ne => op!(writer, F64NE),
1948 F64Lt => op!(writer, F64LT),
1949 F64Gt => op!(writer, F64GT),
1950 F64Le => op!(writer, F64LE),
1951 F64Ge => op!(writer, F64GE),
1952
1953 I32Clz => op!(writer, I32CLZ),
1954 I32Ctz => op!(writer, I32CTZ),
1955 I32Popcnt => op!(writer, I32POPCNT),
1956 I32Add => op!(writer, I32ADD),
1957 I32Sub => op!(writer, I32SUB),
1958 I32Mul => op!(writer, I32MUL),
1959 I32DivS => op!(writer, I32DIVS),
1960 I32DivU => op!(writer, I32DIVU),
1961 I32RemS => op!(writer, I32REMS),
1962 I32RemU => op!(writer, I32REMU),
1963 I32And => op!(writer, I32AND),
1964 I32Or => op!(writer, I32OR),
1965 I32Xor => op!(writer, I32XOR),
1966 I32Shl => op!(writer, I32SHL),
1967 I32ShrS => op!(writer, I32SHRS),
1968 I32ShrU => op!(writer, I32SHRU),
1969 I32Rotl => op!(writer, I32ROTL),
1970 I32Rotr => op!(writer, I32ROTR),
1971
1972 I64Clz => op!(writer, I64CLZ),
1973 I64Ctz => op!(writer, I64CTZ),
1974 I64Popcnt => op!(writer, I64POPCNT),
1975 I64Add => op!(writer, I64ADD),
1976 I64Sub => op!(writer, I64SUB),
1977 I64Mul => op!(writer, I64MUL),
1978 I64DivS => op!(writer, I64DIVS),
1979 I64DivU => op!(writer, I64DIVU),
1980 I64RemS => op!(writer, I64REMS),
1981 I64RemU => op!(writer, I64REMU),
1982 I64And => op!(writer, I64AND),
1983 I64Or => op!(writer, I64OR),
1984 I64Xor => op!(writer, I64XOR),
1985 I64Shl => op!(writer, I64SHL),
1986 I64ShrS => op!(writer, I64SHRS),
1987 I64ShrU => op!(writer, I64SHRU),
1988 I64Rotl => op!(writer, I64ROTL),
1989 I64Rotr => op!(writer, I64ROTR),
1990 F32Abs => op!(writer, F32ABS),
1991 F32Neg => op!(writer, F32NEG),
1992 F32Ceil => op!(writer, F32CEIL),
1993 F32Floor => op!(writer, F32FLOOR),
1994 F32Trunc => op!(writer, F32TRUNC),
1995 F32Nearest => op!(writer, F32NEAREST),
1996 F32Sqrt => op!(writer, F32SQRT),
1997 F32Add => op!(writer, F32ADD),
1998 F32Sub => op!(writer, F32SUB),
1999 F32Mul => op!(writer, F32MUL),
2000 F32Div => op!(writer, F32DIV),
2001 F32Min => op!(writer, F32MIN),
2002 F32Max => op!(writer, F32MAX),
2003 F32Copysign => op!(writer, F32COPYSIGN),
2004 F64Abs => op!(writer, F64ABS),
2005 F64Neg => op!(writer, F64NEG),
2006 F64Ceil => op!(writer, F64CEIL),
2007 F64Floor => op!(writer, F64FLOOR),
2008 F64Trunc => op!(writer, F64TRUNC),
2009 F64Nearest => op!(writer, F64NEAREST),
2010 F64Sqrt => op!(writer, F64SQRT),
2011 F64Add => op!(writer, F64ADD),
2012 F64Sub => op!(writer, F64SUB),
2013 F64Mul => op!(writer, F64MUL),
2014 F64Div => op!(writer, F64DIV),
2015 F64Min => op!(writer, F64MIN),
2016 F64Max => op!(writer, F64MAX),
2017 F64Copysign => op!(writer, F64COPYSIGN),
2018
2019 I32WrapI64 => op!(writer, I32WRAPI64),
2020 I32TruncSF32 => op!(writer, I32TRUNCSF32),
2021 I32TruncUF32 => op!(writer, I32TRUNCUF32),
2022 I32TruncSF64 => op!(writer, I32TRUNCSF64),
2023 I32TruncUF64 => op!(writer, I32TRUNCUF64),
2024 I64ExtendSI32 => op!(writer, I64EXTENDSI32),
2025 I64ExtendUI32 => op!(writer, I64EXTENDUI32),
2026 I64TruncSF32 => op!(writer, I64TRUNCSF32),
2027 I64TruncUF32 => op!(writer, I64TRUNCUF32),
2028 I64TruncSF64 => op!(writer, I64TRUNCSF64),
2029 I64TruncUF64 => op!(writer, I64TRUNCUF64),
2030 F32ConvertSI32 => op!(writer, F32CONVERTSI32),
2031 F32ConvertUI32 => op!(writer, F32CONVERTUI32),
2032 F32ConvertSI64 => op!(writer, F32CONVERTSI64),
2033 F32ConvertUI64 => op!(writer, F32CONVERTUI64),
2034 F32DemoteF64 => op!(writer, F32DEMOTEF64),
2035 F64ConvertSI32 => op!(writer, F64CONVERTSI32),
2036 F64ConvertUI32 => op!(writer, F64CONVERTUI32),
2037 F64ConvertSI64 => op!(writer, F64CONVERTSI64),
2038 F64ConvertUI64 => op!(writer, F64CONVERTUI64),
2039 F64PromoteF32 => op!(writer, F64PROMOTEF32),
2040
2041 I32ReinterpretF32 => op!(writer, I32REINTERPRETF32),
2042 I64ReinterpretF64 => op!(writer, I64REINTERPRETF64),
2043 F32ReinterpretI32 => op!(writer, F32REINTERPRETI32),
2044 F64ReinterpretI64 => op!(writer, F64REINTERPRETI64),
2045
2046 #[cfg(feature = "sign_ext")]
2047 SignExt(ref a) => match *a {
2048 SignExtInstruction::I32Extend8S => op!(writer, sign_ext::I32_EXTEND8_S),
2049 SignExtInstruction::I32Extend16S => op!(writer, sign_ext::I32_EXTEND16_S),
2050 SignExtInstruction::I64Extend8S => op!(writer, sign_ext::I64_EXTEND8_S),
2051 SignExtInstruction::I64Extend16S => op!(writer, sign_ext::I64_EXTEND16_S),
2052 SignExtInstruction::I64Extend32S => op!(writer, sign_ext::I64_EXTEND32_S),
2053 },
2054
2055 #[cfg(feature = "atomics")]
2056 Atomics(a) => return a.serialize(writer),
2057
2058 #[cfg(feature = "simd")]
2059 Simd(a) => return a.serialize(writer),
2060
2061 #[cfg(feature = "bulk")]
2062 Bulk(a) => return a.serialize(writer),
2063 }
2064
2065 Ok(())
2066 }
2067}
2068
2069#[cfg(feature = "atomics")]
2070impl Serialize for AtomicsInstruction {
2071 type Error = Error;
2072
2073 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
2074 use self::{opcodes::atomics::*, AtomicsInstruction::*};
2075
2076 match self {
2077 AtomicWake(m) => atomic!(writer, ATOMIC_WAKE, m),
2078 I32AtomicWait(m) => atomic!(writer, I32_ATOMIC_WAIT, m),
2079 I64AtomicWait(m) => atomic!(writer, I64_ATOMIC_WAIT, m),
2080
2081 I32AtomicLoad(m) => atomic!(writer, I32_ATOMIC_LOAD, m),
2082 I64AtomicLoad(m) => atomic!(writer, I64_ATOMIC_LOAD, m),
2083 I32AtomicLoad8u(m) => atomic!(writer, I32_ATOMIC_LOAD8U, m),
2084 I32AtomicLoad16u(m) => atomic!(writer, I32_ATOMIC_LOAD16U, m),
2085 I64AtomicLoad8u(m) => atomic!(writer, I64_ATOMIC_LOAD8U, m),
2086 I64AtomicLoad16u(m) => atomic!(writer, I64_ATOMIC_LOAD16U, m),
2087 I64AtomicLoad32u(m) => atomic!(writer, I64_ATOMIC_LOAD32U, m),
2088 I32AtomicStore(m) => atomic!(writer, I32_ATOMIC_STORE, m),
2089 I64AtomicStore(m) => atomic!(writer, I64_ATOMIC_STORE, m),
2090 I32AtomicStore8u(m) => atomic!(writer, I32_ATOMIC_STORE8U, m),
2091 I32AtomicStore16u(m) => atomic!(writer, I32_ATOMIC_STORE16U, m),
2092 I64AtomicStore8u(m) => atomic!(writer, I64_ATOMIC_STORE8U, m),
2093 I64AtomicStore16u(m) => atomic!(writer, I64_ATOMIC_STORE16U, m),
2094 I64AtomicStore32u(m) => atomic!(writer, I64_ATOMIC_STORE32U, m),
2095
2096 I32AtomicRmwAdd(m) => atomic!(writer, I32_ATOMIC_RMW_ADD, m),
2097 I64AtomicRmwAdd(m) => atomic!(writer, I64_ATOMIC_RMW_ADD, m),
2098 I32AtomicRmwAdd8u(m) => atomic!(writer, I32_ATOMIC_RMW_ADD8U, m),
2099 I32AtomicRmwAdd16u(m) => atomic!(writer, I32_ATOMIC_RMW_ADD16U, m),
2100 I64AtomicRmwAdd8u(m) => atomic!(writer, I64_ATOMIC_RMW_ADD8U, m),
2101 I64AtomicRmwAdd16u(m) => atomic!(writer, I64_ATOMIC_RMW_ADD16U, m),
2102 I64AtomicRmwAdd32u(m) => atomic!(writer, I64_ATOMIC_RMW_ADD32U, m),
2103
2104 I32AtomicRmwSub(m) => atomic!(writer, I32_ATOMIC_RMW_SUB, m),
2105 I64AtomicRmwSub(m) => atomic!(writer, I64_ATOMIC_RMW_SUB, m),
2106 I32AtomicRmwSub8u(m) => atomic!(writer, I32_ATOMIC_RMW_SUB8U, m),
2107 I32AtomicRmwSub16u(m) => atomic!(writer, I32_ATOMIC_RMW_SUB16U, m),
2108 I64AtomicRmwSub8u(m) => atomic!(writer, I64_ATOMIC_RMW_SUB8U, m),
2109 I64AtomicRmwSub16u(m) => atomic!(writer, I64_ATOMIC_RMW_SUB16U, m),
2110 I64AtomicRmwSub32u(m) => atomic!(writer, I64_ATOMIC_RMW_SUB32U, m),
2111
2112 I32AtomicRmwAnd(m) => atomic!(writer, I32_ATOMIC_RMW_AND, m),
2113 I64AtomicRmwAnd(m) => atomic!(writer, I64_ATOMIC_RMW_AND, m),
2114 I32AtomicRmwAnd8u(m) => atomic!(writer, I32_ATOMIC_RMW_AND8U, m),
2115 I32AtomicRmwAnd16u(m) => atomic!(writer, I32_ATOMIC_RMW_AND16U, m),
2116 I64AtomicRmwAnd8u(m) => atomic!(writer, I64_ATOMIC_RMW_AND8U, m),
2117 I64AtomicRmwAnd16u(m) => atomic!(writer, I64_ATOMIC_RMW_AND16U, m),
2118 I64AtomicRmwAnd32u(m) => atomic!(writer, I64_ATOMIC_RMW_AND32U, m),
2119
2120 I32AtomicRmwOr(m) => atomic!(writer, I32_ATOMIC_RMW_OR, m),
2121 I64AtomicRmwOr(m) => atomic!(writer, I64_ATOMIC_RMW_OR, m),
2122 I32AtomicRmwOr8u(m) => atomic!(writer, I32_ATOMIC_RMW_OR8U, m),
2123 I32AtomicRmwOr16u(m) => atomic!(writer, I32_ATOMIC_RMW_OR16U, m),
2124 I64AtomicRmwOr8u(m) => atomic!(writer, I64_ATOMIC_RMW_OR8U, m),
2125 I64AtomicRmwOr16u(m) => atomic!(writer, I64_ATOMIC_RMW_OR16U, m),
2126 I64AtomicRmwOr32u(m) => atomic!(writer, I64_ATOMIC_RMW_OR32U, m),
2127
2128 I32AtomicRmwXor(m) => atomic!(writer, I32_ATOMIC_RMW_XOR, m),
2129 I64AtomicRmwXor(m) => atomic!(writer, I64_ATOMIC_RMW_XOR, m),
2130 I32AtomicRmwXor8u(m) => atomic!(writer, I32_ATOMIC_RMW_XOR8U, m),
2131 I32AtomicRmwXor16u(m) => atomic!(writer, I32_ATOMIC_RMW_XOR16U, m),
2132 I64AtomicRmwXor8u(m) => atomic!(writer, I64_ATOMIC_RMW_XOR8U, m),
2133 I64AtomicRmwXor16u(m) => atomic!(writer, I64_ATOMIC_RMW_XOR16U, m),
2134 I64AtomicRmwXor32u(m) => atomic!(writer, I64_ATOMIC_RMW_XOR32U, m),
2135
2136 I32AtomicRmwXchg(m) => atomic!(writer, I32_ATOMIC_RMW_XCHG, m),
2137 I64AtomicRmwXchg(m) => atomic!(writer, I64_ATOMIC_RMW_XCHG, m),
2138 I32AtomicRmwXchg8u(m) => atomic!(writer, I32_ATOMIC_RMW_XCHG8U, m),
2139 I32AtomicRmwXchg16u(m) => atomic!(writer, I32_ATOMIC_RMW_XCHG16U, m),
2140 I64AtomicRmwXchg8u(m) => atomic!(writer, I64_ATOMIC_RMW_XCHG8U, m),
2141 I64AtomicRmwXchg16u(m) => atomic!(writer, I64_ATOMIC_RMW_XCHG16U, m),
2142 I64AtomicRmwXchg32u(m) => atomic!(writer, I64_ATOMIC_RMW_XCHG32U, m),
2143
2144 I32AtomicRmwCmpxchg(m) => atomic!(writer, I32_ATOMIC_RMW_CMPXCHG, m),
2145 I64AtomicRmwCmpxchg(m) => atomic!(writer, I64_ATOMIC_RMW_CMPXCHG, m),
2146 I32AtomicRmwCmpxchg8u(m) => atomic!(writer, I32_ATOMIC_RMW_CMPXCHG8U, m),
2147 I32AtomicRmwCmpxchg16u(m) => atomic!(writer, I32_ATOMIC_RMW_CMPXCHG16U, m),
2148 I64AtomicRmwCmpxchg8u(m) => atomic!(writer, I64_ATOMIC_RMW_CMPXCHG8U, m),
2149 I64AtomicRmwCmpxchg16u(m) => atomic!(writer, I64_ATOMIC_RMW_CMPXCHG16U, m),
2150 I64AtomicRmwCmpxchg32u(m) => atomic!(writer, I64_ATOMIC_RMW_CMPXCHG32U, m),
2151 }
2152
2153 Ok(())
2154 }
2155}
2156
2157#[cfg(feature = "simd")]
2158impl Serialize for SimdInstruction {
2159 type Error = Error;
2160
2161 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
2162 use self::{opcodes::simd::*, SimdInstruction::*};
2163
2164 match self {
2165 V128Const(ref c) => simd!(writer, V128_CONST, writer.write(&c[..])?),
2166 V128Load(m) => simd!(writer, V128_LOAD, MemArg::serialize(m, writer)?),
2167 V128Store(m) => simd!(writer, V128_STORE, MemArg::serialize(m, writer)?),
2168 I8x16Splat => simd!(writer, I8X16_SPLAT, {}),
2169 I16x8Splat => simd!(writer, I16X8_SPLAT, {}),
2170 I32x4Splat => simd!(writer, I32X4_SPLAT, {}),
2171 I64x2Splat => simd!(writer, I64X2_SPLAT, {}),
2172 F32x4Splat => simd!(writer, F32X4_SPLAT, {}),
2173 F64x2Splat => simd!(writer, F64X2_SPLAT, {}),
2174 I8x16ExtractLaneS(i) => simd!(writer, I8X16_EXTRACT_LANE_S, writer.write(&[i])?),
2175 I8x16ExtractLaneU(i) => simd!(writer, I8X16_EXTRACT_LANE_U, writer.write(&[i])?),
2176 I16x8ExtractLaneS(i) => simd!(writer, I16X8_EXTRACT_LANE_S, writer.write(&[i])?),
2177 I16x8ExtractLaneU(i) => simd!(writer, I16X8_EXTRACT_LANE_U, writer.write(&[i])?),
2178 I32x4ExtractLane(i) => simd!(writer, I32X4_EXTRACT_LANE, writer.write(&[i])?),
2179 I64x2ExtractLane(i) => simd!(writer, I64X2_EXTRACT_LANE, writer.write(&[i])?),
2180 F32x4ExtractLane(i) => simd!(writer, F32X4_EXTRACT_LANE, writer.write(&[i])?),
2181 F64x2ExtractLane(i) => simd!(writer, F64X2_EXTRACT_LANE, writer.write(&[i])?),
2182 I8x16ReplaceLane(i) => simd!(writer, I8X16_REPLACE_LANE, writer.write(&[i])?),
2183 I16x8ReplaceLane(i) => simd!(writer, I16X8_REPLACE_LANE, writer.write(&[i])?),
2184 I32x4ReplaceLane(i) => simd!(writer, I32X4_REPLACE_LANE, writer.write(&[i])?),
2185 I64x2ReplaceLane(i) => simd!(writer, I64X2_REPLACE_LANE, writer.write(&[i])?),
2186 F32x4ReplaceLane(i) => simd!(writer, F32X4_REPLACE_LANE, writer.write(&[i])?),
2187 F64x2ReplaceLane(i) => simd!(writer, F64X2_REPLACE_LANE, writer.write(&[i])?),
2188 V8x16Shuffle(ref i) => simd!(writer, V8X16_SHUFFLE, writer.write(&i[..])?),
2189 I8x16Add => simd!(writer, I8X16_ADD, {}),
2190 I16x8Add => simd!(writer, I16X8_ADD, {}),
2191 I32x4Add => simd!(writer, I32X4_ADD, {}),
2192 I64x2Add => simd!(writer, I64X2_ADD, {}),
2193 I8x16Sub => simd!(writer, I8X16_SUB, {}),
2194 I16x8Sub => simd!(writer, I16X8_SUB, {}),
2195 I32x4Sub => simd!(writer, I32X4_SUB, {}),
2196 I64x2Sub => simd!(writer, I64X2_SUB, {}),
2197 I8x16Mul => simd!(writer, I8X16_MUL, {}),
2198 I16x8Mul => simd!(writer, I16X8_MUL, {}),
2199 I32x4Mul => simd!(writer, I32X4_MUL, {}),
2200 I8x16Neg => simd!(writer, I8X16_NEG, {}),
2202 I16x8Neg => simd!(writer, I16X8_NEG, {}),
2203 I32x4Neg => simd!(writer, I32X4_NEG, {}),
2204 I64x2Neg => simd!(writer, I64X2_NEG, {}),
2205 I8x16AddSaturateS => simd!(writer, I8X16_ADD_SATURATE_S, {}),
2206 I8x16AddSaturateU => simd!(writer, I8X16_ADD_SATURATE_U, {}),
2207 I16x8AddSaturateS => simd!(writer, I16X8_ADD_SATURATE_S, {}),
2208 I16x8AddSaturateU => simd!(writer, I16X8_ADD_SATURATE_U, {}),
2209 I8x16SubSaturateS => simd!(writer, I8X16_SUB_SATURATE_S, {}),
2210 I8x16SubSaturateU => simd!(writer, I8X16_SUB_SATURATE_U, {}),
2211 I16x8SubSaturateS => simd!(writer, I16X8_SUB_SATURATE_S, {}),
2212 I16x8SubSaturateU => simd!(writer, I16X8_SUB_SATURATE_U, {}),
2213 I8x16Shl => simd!(writer, I8X16_SHL, {}),
2214 I16x8Shl => simd!(writer, I16X8_SHL, {}),
2215 I32x4Shl => simd!(writer, I32X4_SHL, {}),
2216 I64x2Shl => simd!(writer, I64X2_SHL, {}),
2217 I8x16ShrS => simd!(writer, I8X16_SHR_S, {}),
2218 I8x16ShrU => simd!(writer, I8X16_SHR_U, {}),
2219 I16x8ShrS => simd!(writer, I16X8_SHR_S, {}),
2220 I16x8ShrU => simd!(writer, I16X8_SHR_U, {}),
2221 I32x4ShrU => simd!(writer, I32X4_SHR_U, {}),
2222 I32x4ShrS => simd!(writer, I32X4_SHR_S, {}),
2223 I64x2ShrU => simd!(writer, I64X2_SHR_U, {}),
2224 I64x2ShrS => simd!(writer, I64X2_SHR_S, {}),
2225 V128And => simd!(writer, V128_AND, {}),
2226 V128Or => simd!(writer, V128_OR, {}),
2227 V128Xor => simd!(writer, V128_XOR, {}),
2228 V128Not => simd!(writer, V128_NOT, {}),
2229 V128Bitselect => simd!(writer, V128_BITSELECT, {}),
2230 I8x16AnyTrue => simd!(writer, I8X16_ANY_TRUE, {}),
2231 I16x8AnyTrue => simd!(writer, I16X8_ANY_TRUE, {}),
2232 I32x4AnyTrue => simd!(writer, I32X4_ANY_TRUE, {}),
2233 I64x2AnyTrue => simd!(writer, I64X2_ANY_TRUE, {}),
2234 I8x16AllTrue => simd!(writer, I8X16_ALL_TRUE, {}),
2235 I16x8AllTrue => simd!(writer, I16X8_ALL_TRUE, {}),
2236 I32x4AllTrue => simd!(writer, I32X4_ALL_TRUE, {}),
2237 I64x2AllTrue => simd!(writer, I64X2_ALL_TRUE, {}),
2238 I8x16Eq => simd!(writer, I8X16_EQ, {}),
2239 I16x8Eq => simd!(writer, I16X8_EQ, {}),
2240 I32x4Eq => simd!(writer, I32X4_EQ, {}),
2241 F32x4Eq => simd!(writer, F32X4_EQ, {}),
2243 F64x2Eq => simd!(writer, F64X2_EQ, {}),
2244 I8x16Ne => simd!(writer, I8X16_NE, {}),
2245 I16x8Ne => simd!(writer, I16X8_NE, {}),
2246 I32x4Ne => simd!(writer, I32X4_NE, {}),
2247 F32x4Ne => simd!(writer, F32X4_NE, {}),
2249 F64x2Ne => simd!(writer, F64X2_NE, {}),
2250 I8x16LtS => simd!(writer, I8X16_LT_S, {}),
2251 I8x16LtU => simd!(writer, I8X16_LT_U, {}),
2252 I16x8LtS => simd!(writer, I16X8_LT_S, {}),
2253 I16x8LtU => simd!(writer, I16X8_LT_U, {}),
2254 I32x4LtS => simd!(writer, I32X4_LT_S, {}),
2255 I32x4LtU => simd!(writer, I32X4_LT_U, {}),
2256 F32x4Lt => simd!(writer, F32X4_LT, {}),
2259 F64x2Lt => simd!(writer, F64X2_LT, {}),
2260 I8x16LeS => simd!(writer, I8X16_LE_S, {}),
2261 I8x16LeU => simd!(writer, I8X16_LE_U, {}),
2262 I16x8LeS => simd!(writer, I16X8_LE_S, {}),
2263 I16x8LeU => simd!(writer, I16X8_LE_U, {}),
2264 I32x4LeS => simd!(writer, I32X4_LE_S, {}),
2265 I32x4LeU => simd!(writer, I32X4_LE_U, {}),
2266 F32x4Le => simd!(writer, F32X4_LE, {}),
2269 F64x2Le => simd!(writer, F64X2_LE, {}),
2270 I8x16GtS => simd!(writer, I8X16_GT_S, {}),
2271 I8x16GtU => simd!(writer, I8X16_GT_U, {}),
2272 I16x8GtS => simd!(writer, I16X8_GT_S, {}),
2273 I16x8GtU => simd!(writer, I16X8_GT_U, {}),
2274 I32x4GtS => simd!(writer, I32X4_GT_S, {}),
2275 I32x4GtU => simd!(writer, I32X4_GT_U, {}),
2276 F32x4Gt => simd!(writer, F32X4_GT, {}),
2279 F64x2Gt => simd!(writer, F64X2_GT, {}),
2280 I8x16GeS => simd!(writer, I8X16_GE_S, {}),
2281 I8x16GeU => simd!(writer, I8X16_GE_U, {}),
2282 I16x8GeS => simd!(writer, I16X8_GE_S, {}),
2283 I16x8GeU => simd!(writer, I16X8_GE_U, {}),
2284 I32x4GeS => simd!(writer, I32X4_GE_S, {}),
2285 I32x4GeU => simd!(writer, I32X4_GE_U, {}),
2286 F32x4Ge => simd!(writer, F32X4_GE, {}),
2289 F64x2Ge => simd!(writer, F64X2_GE, {}),
2290 F32x4Neg => simd!(writer, F32X4_NEG, {}),
2291 F64x2Neg => simd!(writer, F64X2_NEG, {}),
2292 F32x4Abs => simd!(writer, F32X4_ABS, {}),
2293 F64x2Abs => simd!(writer, F64X2_ABS, {}),
2294 F32x4Min => simd!(writer, F32X4_MIN, {}),
2295 F64x2Min => simd!(writer, F64X2_MIN, {}),
2296 F32x4Max => simd!(writer, F32X4_MAX, {}),
2297 F64x2Max => simd!(writer, F64X2_MAX, {}),
2298 F32x4Add => simd!(writer, F32X4_ADD, {}),
2299 F64x2Add => simd!(writer, F64X2_ADD, {}),
2300 F32x4Sub => simd!(writer, F32X4_SUB, {}),
2301 F64x2Sub => simd!(writer, F64X2_SUB, {}),
2302 F32x4Div => simd!(writer, F32X4_DIV, {}),
2303 F64x2Div => simd!(writer, F64X2_DIV, {}),
2304 F32x4Mul => simd!(writer, F32X4_MUL, {}),
2305 F64x2Mul => simd!(writer, F64X2_MUL, {}),
2306 F32x4Sqrt => simd!(writer, F32X4_SQRT, {}),
2307 F64x2Sqrt => simd!(writer, F64X2_SQRT, {}),
2308 F32x4ConvertSI32x4 => simd!(writer, F32X4_CONVERT_S_I32X4, {}),
2309 F32x4ConvertUI32x4 => simd!(writer, F32X4_CONVERT_U_I32X4, {}),
2310 F64x2ConvertSI64x2 => simd!(writer, F64X2_CONVERT_S_I64X2, {}),
2311 F64x2ConvertUI64x2 => simd!(writer, F64X2_CONVERT_U_I64X2, {}),
2312 I32x4TruncSF32x4Sat => simd!(writer, I32X4_TRUNC_S_F32X4_SAT, {}),
2313 I32x4TruncUF32x4Sat => simd!(writer, I32X4_TRUNC_U_F32X4_SAT, {}),
2314 I64x2TruncSF64x2Sat => simd!(writer, I64X2_TRUNC_S_F64X2_SAT, {}),
2315 I64x2TruncUF64x2Sat => simd!(writer, I64X2_TRUNC_U_F64X2_SAT, {}),
2316 }
2317
2318 Ok(())
2319 }
2320}
2321
2322#[cfg(feature = "bulk")]
2323impl Serialize for BulkInstruction {
2324 type Error = Error;
2325
2326 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
2327 use self::{opcodes::bulk::*, BulkInstruction::*};
2328
2329 match self {
2330 MemoryInit(seg) => bulk!(writer, MEMORY_INIT, {
2331 Uint8::from(0).serialize(writer)?;
2332 VarUint32::from(seg).serialize(writer)?;
2333 }),
2334 MemoryDrop(seg) => bulk!(writer, MEMORY_DROP, VarUint32::from(seg).serialize(writer)?),
2335 MemoryFill => bulk!(writer, MEMORY_FILL, Uint8::from(0).serialize(writer)?),
2336 MemoryCopy => bulk!(writer, MEMORY_COPY, Uint8::from(0).serialize(writer)?),
2337 TableInit(seg) => bulk!(writer, TABLE_INIT, {
2338 Uint8::from(0).serialize(writer)?;
2339 VarUint32::from(seg).serialize(writer)?;
2340 }),
2341 TableDrop(seg) => bulk!(writer, TABLE_DROP, VarUint32::from(seg).serialize(writer)?),
2342 TableCopy => bulk!(writer, TABLE_COPY, Uint8::from(0).serialize(writer)?),
2343 }
2344
2345 Ok(())
2346 }
2347}
2348
2349#[cfg(any(feature = "simd", feature = "atomics"))]
2350impl Serialize for MemArg {
2351 type Error = Error;
2352
2353 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
2354 Uint8::from(self.align).serialize(writer)?;
2355 VarUint32::from(self.offset).serialize(writer)?;
2356 Ok(())
2357 }
2358}
2359
2360macro_rules! fmt_op {
2361 ($f: expr, $mnemonic: expr) => {{
2362 write!($f, "{}", $mnemonic)
2363 }};
2364 ($f: expr, $mnemonic: expr, $immediate: expr) => {{
2365 write!($f, "{} {}", $mnemonic, $immediate)
2366 }};
2367 ($f: expr, $mnemonic: expr, $immediate1: expr, $immediate2: expr) => {{
2368 write!($f, "{} {} {}", $mnemonic, $immediate1, $immediate2)
2369 }};
2370}
2371
2372impl fmt::Display for Instruction {
2373 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2374 use self::Instruction::*;
2375
2376 match *self {
2377 Unreachable => fmt_op!(f, "unreachable"),
2378 Nop => fmt_op!(f, "nop"),
2379 Block(BlockType::NoResult) => fmt_op!(f, "block"),
2380 Block(BlockType::Value(value_type)) => fmt_op!(f, "block", value_type),
2381 #[cfg(feature = "multi_value")]
2382 Block(BlockType::TypeIndex(idx)) => write!(f, "block type_idx={}", idx),
2383 Loop(BlockType::NoResult) => fmt_op!(f, "loop"),
2384 Loop(BlockType::Value(value_type)) => fmt_op!(f, "loop", value_type),
2385 #[cfg(feature = "multi_value")]
2386 Loop(BlockType::TypeIndex(idx)) => write!(f, "loop type_idx={}", idx),
2387 If(BlockType::NoResult) => fmt_op!(f, "if"),
2388 If(BlockType::Value(value_type)) => fmt_op!(f, "if", value_type),
2389 #[cfg(feature = "multi_value")]
2390 If(BlockType::TypeIndex(idx)) => write!(f, "if type_idx={}", idx),
2391 Else => fmt_op!(f, "else"),
2392 End => fmt_op!(f, "end"),
2393 Br(idx) => fmt_op!(f, "br", idx),
2394 BrIf(idx) => fmt_op!(f, "br_if", idx),
2395 BrTable(ref table) => fmt_op!(f, "br_table", table.default),
2396 Return => fmt_op!(f, "return"),
2397 Call(index) => fmt_op!(f, "call", index),
2398 CallIndirect(index, _) => fmt_op!(f, "call_indirect", index),
2399 Drop => fmt_op!(f, "drop"),
2400 Select => fmt_op!(f, "select"),
2401 GetLocal(index) => fmt_op!(f, "get_local", index),
2402 SetLocal(index) => fmt_op!(f, "set_local", index),
2403 TeeLocal(index) => fmt_op!(f, "tee_local", index),
2404 GetGlobal(index) => fmt_op!(f, "get_global", index),
2405 SetGlobal(index) => fmt_op!(f, "set_global", index),
2406
2407 I32Load(_, 0) => write!(f, "i32.load"),
2408 I32Load(_, offset) => write!(f, "i32.load offset={}", offset),
2409
2410 I64Load(_, 0) => write!(f, "i64.load"),
2411 I64Load(_, offset) => write!(f, "i64.load offset={}", offset),
2412
2413 F32Load(_, 0) => write!(f, "f32.load"),
2414 F32Load(_, offset) => write!(f, "f32.load offset={}", offset),
2415
2416 F64Load(_, 0) => write!(f, "f64.load"),
2417 F64Load(_, offset) => write!(f, "f64.load offset={}", offset),
2418
2419 I32Load8S(_, 0) => write!(f, "i32.load8_s"),
2420 I32Load8S(_, offset) => write!(f, "i32.load8_s offset={}", offset),
2421
2422 I32Load8U(_, 0) => write!(f, "i32.load8_u"),
2423 I32Load8U(_, offset) => write!(f, "i32.load8_u offset={}", offset),
2424
2425 I32Load16S(_, 0) => write!(f, "i32.load16_s"),
2426 I32Load16S(_, offset) => write!(f, "i32.load16_s offset={}", offset),
2427
2428 I32Load16U(_, 0) => write!(f, "i32.load16_u"),
2429 I32Load16U(_, offset) => write!(f, "i32.load16_u offset={}", offset),
2430
2431 I64Load8S(_, 0) => write!(f, "i64.load8_s"),
2432 I64Load8S(_, offset) => write!(f, "i64.load8_s offset={}", offset),
2433
2434 I64Load8U(_, 0) => write!(f, "i64.load8_u"),
2435 I64Load8U(_, offset) => write!(f, "i64.load8_u offset={}", offset),
2436
2437 I64Load16S(_, 0) => write!(f, "i64.load16_s"),
2438 I64Load16S(_, offset) => write!(f, "i64.load16_s offset={}", offset),
2439
2440 I64Load16U(_, 0) => write!(f, "i64.load16_u"),
2441 I64Load16U(_, offset) => write!(f, "i64.load16_u offset={}", offset),
2442
2443 I64Load32S(_, 0) => write!(f, "i64.load32_s"),
2444 I64Load32S(_, offset) => write!(f, "i64.load32_s offset={}", offset),
2445
2446 I64Load32U(_, 0) => write!(f, "i64.load32_u"),
2447 I64Load32U(_, offset) => write!(f, "i64.load32_u offset={}", offset),
2448
2449 I32Store(_, 0) => write!(f, "i32.store"),
2450 I32Store(_, offset) => write!(f, "i32.store offset={}", offset),
2451
2452 I64Store(_, 0) => write!(f, "i64.store"),
2453 I64Store(_, offset) => write!(f, "i64.store offset={}", offset),
2454
2455 F32Store(_, 0) => write!(f, "f32.store"),
2456 F32Store(_, offset) => write!(f, "f32.store offset={}", offset),
2457
2458 F64Store(_, 0) => write!(f, "f64.store"),
2459 F64Store(_, offset) => write!(f, "f64.store offset={}", offset),
2460
2461 I32Store8(_, 0) => write!(f, "i32.store8"),
2462 I32Store8(_, offset) => write!(f, "i32.store8 offset={}", offset),
2463
2464 I32Store16(_, 0) => write!(f, "i32.store16"),
2465 I32Store16(_, offset) => write!(f, "i32.store16 offset={}", offset),
2466
2467 I64Store8(_, 0) => write!(f, "i64.store8"),
2468 I64Store8(_, offset) => write!(f, "i64.store8 offset={}", offset),
2469
2470 I64Store16(_, 0) => write!(f, "i64.store16"),
2471 I64Store16(_, offset) => write!(f, "i64.store16 offset={}", offset),
2472
2473 I64Store32(_, 0) => write!(f, "i64.store32"),
2474 I64Store32(_, offset) => write!(f, "i64.store32 offset={}", offset),
2475
2476 CurrentMemory(_) => fmt_op!(f, "current_memory"),
2477 GrowMemory(_) => fmt_op!(f, "grow_memory"),
2478
2479 I32Const(def) => fmt_op!(f, "i32.const", def),
2480 I64Const(def) => fmt_op!(f, "i64.const", def),
2481 F32Const(def) => fmt_op!(f, "f32.const", def),
2482 F64Const(def) => fmt_op!(f, "f64.const", def),
2483
2484 I32Eq => write!(f, "i32.eq"),
2485 I32Eqz => write!(f, "i32.eqz"),
2486 I32Ne => write!(f, "i32.ne"),
2487 I32LtS => write!(f, "i32.lt_s"),
2488 I32LtU => write!(f, "i32.lt_u"),
2489 I32GtS => write!(f, "i32.gt_s"),
2490 I32GtU => write!(f, "i32.gt_u"),
2491 I32LeS => write!(f, "i32.le_s"),
2492 I32LeU => write!(f, "i32.le_u"),
2493 I32GeS => write!(f, "i32.ge_s"),
2494 I32GeU => write!(f, "i32.ge_u"),
2495
2496 I64Eq => write!(f, "i64.eq"),
2497 I64Eqz => write!(f, "i64.eqz"),
2498 I64Ne => write!(f, "i64.ne"),
2499 I64LtS => write!(f, "i64.lt_s"),
2500 I64LtU => write!(f, "i64.lt_u"),
2501 I64GtS => write!(f, "i64.gt_s"),
2502 I64GtU => write!(f, "i64.gt_u"),
2503 I64LeS => write!(f, "i64.le_s"),
2504 I64LeU => write!(f, "i64.le_u"),
2505 I64GeS => write!(f, "i64.ge_s"),
2506 I64GeU => write!(f, "i64.ge_u"),
2507
2508 F32Eq => write!(f, "f32.eq"),
2509 F32Ne => write!(f, "f32.ne"),
2510 F32Lt => write!(f, "f32.lt"),
2511 F32Gt => write!(f, "f32.gt"),
2512 F32Le => write!(f, "f32.le"),
2513 F32Ge => write!(f, "f32.ge"),
2514
2515 F64Eq => write!(f, "f64.eq"),
2516 F64Ne => write!(f, "f64.ne"),
2517 F64Lt => write!(f, "f64.lt"),
2518 F64Gt => write!(f, "f64.gt"),
2519 F64Le => write!(f, "f64.le"),
2520 F64Ge => write!(f, "f64.ge"),
2521
2522 I32Clz => write!(f, "i32.clz"),
2523 I32Ctz => write!(f, "i32.ctz"),
2524 I32Popcnt => write!(f, "i32.popcnt"),
2525 I32Add => write!(f, "i32.add"),
2526 I32Sub => write!(f, "i32.sub"),
2527 I32Mul => write!(f, "i32.mul"),
2528 I32DivS => write!(f, "i32.div_s"),
2529 I32DivU => write!(f, "i32.div_u"),
2530 I32RemS => write!(f, "i32.rem_s"),
2531 I32RemU => write!(f, "i32.rem_u"),
2532 I32And => write!(f, "i32.and"),
2533 I32Or => write!(f, "i32.or"),
2534 I32Xor => write!(f, "i32.xor"),
2535 I32Shl => write!(f, "i32.shl"),
2536 I32ShrS => write!(f, "i32.shr_s"),
2537 I32ShrU => write!(f, "i32.shr_u"),
2538 I32Rotl => write!(f, "i32.rotl"),
2539 I32Rotr => write!(f, "i32.rotr"),
2540
2541 I64Clz => write!(f, "i64.clz"),
2542 I64Ctz => write!(f, "i64.ctz"),
2543 I64Popcnt => write!(f, "i64.popcnt"),
2544 I64Add => write!(f, "i64.add"),
2545 I64Sub => write!(f, "i64.sub"),
2546 I64Mul => write!(f, "i64.mul"),
2547 I64DivS => write!(f, "i64.div_s"),
2548 I64DivU => write!(f, "i64.div_u"),
2549 I64RemS => write!(f, "i64.rem_s"),
2550 I64RemU => write!(f, "i64.rem_u"),
2551 I64And => write!(f, "i64.and"),
2552 I64Or => write!(f, "i64.or"),
2553 I64Xor => write!(f, "i64.xor"),
2554 I64Shl => write!(f, "i64.shl"),
2555 I64ShrS => write!(f, "i64.shr_s"),
2556 I64ShrU => write!(f, "i64.shr_u"),
2557 I64Rotl => write!(f, "i64.rotl"),
2558 I64Rotr => write!(f, "i64.rotr"),
2559
2560 F32Abs => write!(f, "f32.abs"),
2561 F32Neg => write!(f, "f32.neg"),
2562 F32Ceil => write!(f, "f32.ceil"),
2563 F32Floor => write!(f, "f32.floor"),
2564 F32Trunc => write!(f, "f32.trunc"),
2565 F32Nearest => write!(f, "f32.nearest"),
2566 F32Sqrt => write!(f, "f32.sqrt"),
2567 F32Add => write!(f, "f32.add"),
2568 F32Sub => write!(f, "f32.sub"),
2569 F32Mul => write!(f, "f32.mul"),
2570 F32Div => write!(f, "f32.div"),
2571 F32Min => write!(f, "f32.min"),
2572 F32Max => write!(f, "f32.max"),
2573 F32Copysign => write!(f, "f32.copysign"),
2574
2575 F64Abs => write!(f, "f64.abs"),
2576 F64Neg => write!(f, "f64.neg"),
2577 F64Ceil => write!(f, "f64.ceil"),
2578 F64Floor => write!(f, "f64.floor"),
2579 F64Trunc => write!(f, "f64.trunc"),
2580 F64Nearest => write!(f, "f64.nearest"),
2581 F64Sqrt => write!(f, "f64.sqrt"),
2582 F64Add => write!(f, "f64.add"),
2583 F64Sub => write!(f, "f64.sub"),
2584 F64Mul => write!(f, "f64.mul"),
2585 F64Div => write!(f, "f64.div"),
2586 F64Min => write!(f, "f64.min"),
2587 F64Max => write!(f, "f64.max"),
2588 F64Copysign => write!(f, "f64.copysign"),
2589
2590 I32WrapI64 => write!(f, "i32.wrap/i64"),
2591 I32TruncSF32 => write!(f, "i32.trunc_s/f32"),
2592 I32TruncUF32 => write!(f, "i32.trunc_u/f32"),
2593 I32TruncSF64 => write!(f, "i32.trunc_s/f64"),
2594 I32TruncUF64 => write!(f, "i32.trunc_u/f64"),
2595
2596 I64ExtendSI32 => write!(f, "i64.extend_s/i32"),
2597 I64ExtendUI32 => write!(f, "i64.extend_u/i32"),
2598
2599 I64TruncSF32 => write!(f, "i64.trunc_s/f32"),
2600 I64TruncUF32 => write!(f, "i64.trunc_u/f32"),
2601 I64TruncSF64 => write!(f, "i64.trunc_s/f64"),
2602 I64TruncUF64 => write!(f, "i64.trunc_u/f64"),
2603
2604 F32ConvertSI32 => write!(f, "f32.convert_s/i32"),
2605 F32ConvertUI32 => write!(f, "f32.convert_u/i32"),
2606 F32ConvertSI64 => write!(f, "f32.convert_s/i64"),
2607 F32ConvertUI64 => write!(f, "f32.convert_u/i64"),
2608 F32DemoteF64 => write!(f, "f32.demote/f64"),
2609
2610 F64ConvertSI32 => write!(f, "f64.convert_s/i32"),
2611 F64ConvertUI32 => write!(f, "f64.convert_u/i32"),
2612 F64ConvertSI64 => write!(f, "f64.convert_s/i64"),
2613 F64ConvertUI64 => write!(f, "f64.convert_u/i64"),
2614 F64PromoteF32 => write!(f, "f64.promote/f32"),
2615
2616 I32ReinterpretF32 => write!(f, "i32.reinterpret/f32"),
2617 I64ReinterpretF64 => write!(f, "i64.reinterpret/f64"),
2618 F32ReinterpretI32 => write!(f, "f32.reinterpret/i32"),
2619 F64ReinterpretI64 => write!(f, "f64.reinterpret/i64"),
2620
2621 #[cfg(feature = "sign_ext")]
2622 SignExt(ref i) => match i {
2623 SignExtInstruction::I32Extend8S => write!(f, "i32.extend8_s"),
2624 SignExtInstruction::I32Extend16S => write!(f, "i32.extend16_s"),
2625 SignExtInstruction::I64Extend8S => write!(f, "i64.extend8_s"),
2626 SignExtInstruction::I64Extend16S => write!(f, "i64.extend16_s"),
2627 SignExtInstruction::I64Extend32S => write!(f, "i64.extend32_s"),
2628 },
2629
2630 #[cfg(feature = "atomics")]
2631 Atomics(ref i) => i.fmt(f),
2632
2633 #[cfg(feature = "simd")]
2634 Simd(ref i) => i.fmt(f),
2635
2636 #[cfg(feature = "bulk")]
2637 Bulk(ref i) => i.fmt(f),
2638 }
2639 }
2640}
2641
2642#[cfg(feature = "atomics")]
2643impl fmt::Display for AtomicsInstruction {
2644 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2645 use self::AtomicsInstruction::*;
2646
2647 match *self {
2648 AtomicWake(_) => write!(f, "atomic.wake"),
2649 I32AtomicWait(_) => write!(f, "i32.atomic.wait"),
2650 I64AtomicWait(_) => write!(f, "i64.atomic.wait"),
2651
2652 I32AtomicLoad(_) => write!(f, "i32.atomic.load"),
2653 I64AtomicLoad(_) => write!(f, "i64.atomic.load"),
2654 I32AtomicLoad8u(_) => write!(f, "i32.atomic.load8_u"),
2655 I32AtomicLoad16u(_) => write!(f, "i32.atomic.load16_u"),
2656 I64AtomicLoad8u(_) => write!(f, "i64.atomic.load8_u"),
2657 I64AtomicLoad16u(_) => write!(f, "i64.atomic.load16_u"),
2658 I64AtomicLoad32u(_) => write!(f, "i64.atomic.load32_u"),
2659 I32AtomicStore(_) => write!(f, "i32.atomic.store"),
2660 I64AtomicStore(_) => write!(f, "i64.atomic.store"),
2661 I32AtomicStore8u(_) => write!(f, "i32.atomic.store8_u"),
2662 I32AtomicStore16u(_) => write!(f, "i32.atomic.store16_u"),
2663 I64AtomicStore8u(_) => write!(f, "i64.atomic.store8_u"),
2664 I64AtomicStore16u(_) => write!(f, "i64.atomic.store16_u"),
2665 I64AtomicStore32u(_) => write!(f, "i64.atomic.store32_u"),
2666
2667 I32AtomicRmwAdd(_) => write!(f, "i32.atomic.rmw.add"),
2668 I64AtomicRmwAdd(_) => write!(f, "i64.atomic.rmw.add"),
2669 I32AtomicRmwAdd8u(_) => write!(f, "i32.atomic.rmw8_u.add"),
2670 I32AtomicRmwAdd16u(_) => write!(f, "i32.atomic.rmw16_u.add"),
2671 I64AtomicRmwAdd8u(_) => write!(f, "i64.atomic.rmw8_u.add"),
2672 I64AtomicRmwAdd16u(_) => write!(f, "i64.atomic.rmw16_u.add"),
2673 I64AtomicRmwAdd32u(_) => write!(f, "i64.atomic.rmw32_u.add"),
2674
2675 I32AtomicRmwSub(_) => write!(f, "i32.atomic.rmw.sub"),
2676 I64AtomicRmwSub(_) => write!(f, "i64.atomic.rmw.sub"),
2677 I32AtomicRmwSub8u(_) => write!(f, "i32.atomic.rmw8_u.sub"),
2678 I32AtomicRmwSub16u(_) => write!(f, "i32.atomic.rmw16_u.sub"),
2679 I64AtomicRmwSub8u(_) => write!(f, "i64.atomic.rmw8_u.sub"),
2680 I64AtomicRmwSub16u(_) => write!(f, "i64.atomic.rmw16_u.sub"),
2681 I64AtomicRmwSub32u(_) => write!(f, "i64.atomic.rmw32_u.sub"),
2682
2683 I32AtomicRmwAnd(_) => write!(f, "i32.atomic.rmw.and"),
2684 I64AtomicRmwAnd(_) => write!(f, "i64.atomic.rmw.and"),
2685 I32AtomicRmwAnd8u(_) => write!(f, "i32.atomic.rmw8_u.and"),
2686 I32AtomicRmwAnd16u(_) => write!(f, "i32.atomic.rmw16_u.and"),
2687 I64AtomicRmwAnd8u(_) => write!(f, "i64.atomic.rmw8_u.and"),
2688 I64AtomicRmwAnd16u(_) => write!(f, "i64.atomic.rmw16_u.and"),
2689 I64AtomicRmwAnd32u(_) => write!(f, "i64.atomic.rmw32_u.and"),
2690
2691 I32AtomicRmwOr(_) => write!(f, "i32.atomic.rmw.or"),
2692 I64AtomicRmwOr(_) => write!(f, "i64.atomic.rmw.or"),
2693 I32AtomicRmwOr8u(_) => write!(f, "i32.atomic.rmw8_u.or"),
2694 I32AtomicRmwOr16u(_) => write!(f, "i32.atomic.rmw16_u.or"),
2695 I64AtomicRmwOr8u(_) => write!(f, "i64.atomic.rmw8_u.or"),
2696 I64AtomicRmwOr16u(_) => write!(f, "i64.atomic.rmw16_u.or"),
2697 I64AtomicRmwOr32u(_) => write!(f, "i64.atomic.rmw32_u.or"),
2698
2699 I32AtomicRmwXor(_) => write!(f, "i32.atomic.rmw.xor"),
2700 I64AtomicRmwXor(_) => write!(f, "i64.atomic.rmw.xor"),
2701 I32AtomicRmwXor8u(_) => write!(f, "i32.atomic.rmw8_u.xor"),
2702 I32AtomicRmwXor16u(_) => write!(f, "i32.atomic.rmw16_u.xor"),
2703 I64AtomicRmwXor8u(_) => write!(f, "i64.atomic.rmw8_u.xor"),
2704 I64AtomicRmwXor16u(_) => write!(f, "i64.atomic.rmw16_u.xor"),
2705 I64AtomicRmwXor32u(_) => write!(f, "i64.atomic.rmw32_u.xor"),
2706
2707 I32AtomicRmwXchg(_) => write!(f, "i32.atomic.rmw.xchg"),
2708 I64AtomicRmwXchg(_) => write!(f, "i64.atomic.rmw.xchg"),
2709 I32AtomicRmwXchg8u(_) => write!(f, "i32.atomic.rmw8_u.xchg"),
2710 I32AtomicRmwXchg16u(_) => write!(f, "i32.atomic.rmw16_u.xchg"),
2711 I64AtomicRmwXchg8u(_) => write!(f, "i64.atomic.rmw8_u.xchg"),
2712 I64AtomicRmwXchg16u(_) => write!(f, "i64.atomic.rmw16_u.xchg"),
2713 I64AtomicRmwXchg32u(_) => write!(f, "i64.atomic.rmw32_u.xchg"),
2714
2715 I32AtomicRmwCmpxchg(_) => write!(f, "i32.atomic.rmw.cmpxchg"),
2716 I64AtomicRmwCmpxchg(_) => write!(f, "i64.atomic.rmw.cmpxchg"),
2717 I32AtomicRmwCmpxchg8u(_) => write!(f, "i32.atomic.rmw8_u.cmpxchg"),
2718 I32AtomicRmwCmpxchg16u(_) => write!(f, "i32.atomic.rmw16_u.cmpxchg"),
2719 I64AtomicRmwCmpxchg8u(_) => write!(f, "i64.atomic.rmw8_u.cmpxchg"),
2720 I64AtomicRmwCmpxchg16u(_) => write!(f, "i64.atomic.rmw16_u.cmpxchg"),
2721 I64AtomicRmwCmpxchg32u(_) => write!(f, "i64.atomic.rmw32_u.cmpxchg"),
2722 }
2723 }
2724}
2725
2726#[cfg(feature = "simd")]
2727impl fmt::Display for SimdInstruction {
2728 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2729 use self::SimdInstruction::*;
2730
2731 match *self {
2732 V128Const(_) => write!(f, "v128.const"),
2733 V128Load(_) => write!(f, "v128.load"),
2734 V128Store(_) => write!(f, "v128.store"),
2735 I8x16Splat => write!(f, "i8x16.splat"),
2736 I16x8Splat => write!(f, "i16x8.splat"),
2737 I32x4Splat => write!(f, "i32x4.splat"),
2738 I64x2Splat => write!(f, "i64x2.splat"),
2739 F32x4Splat => write!(f, "f32x4.splat"),
2740 F64x2Splat => write!(f, "f64x2.splat"),
2741 I8x16ExtractLaneS(_) => write!(f, "i8x16.extract_lane_s"),
2742 I8x16ExtractLaneU(_) => write!(f, "i8x16.extract_lane_u"),
2743 I16x8ExtractLaneS(_) => write!(f, "i16x8.extract_lane_s"),
2744 I16x8ExtractLaneU(_) => write!(f, "i16x8.extract_lane_u"),
2745 I32x4ExtractLane(_) => write!(f, "i32x4.extract_lane"),
2746 I64x2ExtractLane(_) => write!(f, "i64x2.extract_lane"),
2747 F32x4ExtractLane(_) => write!(f, "f32x4.extract_lane"),
2748 F64x2ExtractLane(_) => write!(f, "f64x2.extract_lane"),
2749 I8x16ReplaceLane(_) => write!(f, "i8x16.replace_lane"),
2750 I16x8ReplaceLane(_) => write!(f, "i16x8.replace_lane"),
2751 I32x4ReplaceLane(_) => write!(f, "i32x4.replace_lane"),
2752 I64x2ReplaceLane(_) => write!(f, "i64x2.replace_lane"),
2753 F32x4ReplaceLane(_) => write!(f, "f32x4.replace_lane"),
2754 F64x2ReplaceLane(_) => write!(f, "f64x2.replace_lane"),
2755 V8x16Shuffle(_) => write!(f, "v8x16.shuffle"),
2756 I8x16Add => write!(f, "i8x16.add"),
2757 I16x8Add => write!(f, "i16x8.add"),
2758 I32x4Add => write!(f, "i32x4.add"),
2759 I64x2Add => write!(f, "i64x2.add"),
2760 I8x16Sub => write!(f, "i8x16.sub"),
2761 I16x8Sub => write!(f, "i16x8.sub"),
2762 I32x4Sub => write!(f, "i32x4.sub"),
2763 I64x2Sub => write!(f, "i64x2.sub"),
2764 I8x16Mul => write!(f, "i8x16.mul"),
2765 I16x8Mul => write!(f, "i16x8.mul"),
2766 I32x4Mul => write!(f, "i32x4.mul"),
2767 I8x16Neg => write!(f, "i8x16.neg"),
2769 I16x8Neg => write!(f, "i16x8.neg"),
2770 I32x4Neg => write!(f, "i32x4.neg"),
2771 I64x2Neg => write!(f, "i64x2.neg"),
2772 I8x16AddSaturateS => write!(f, "i8x16.add_saturate_s"),
2773 I8x16AddSaturateU => write!(f, "i8x16.add_saturate_u"),
2774 I16x8AddSaturateS => write!(f, "i16x8.add_saturate_S"),
2775 I16x8AddSaturateU => write!(f, "i16x8.add_saturate_u"),
2776 I8x16SubSaturateS => write!(f, "i8x16.sub_saturate_S"),
2777 I8x16SubSaturateU => write!(f, "i8x16.sub_saturate_u"),
2778 I16x8SubSaturateS => write!(f, "i16x8.sub_saturate_S"),
2779 I16x8SubSaturateU => write!(f, "i16x8.sub_saturate_u"),
2780 I8x16Shl => write!(f, "i8x16.shl"),
2781 I16x8Shl => write!(f, "i16x8.shl"),
2782 I32x4Shl => write!(f, "i32x4.shl"),
2783 I64x2Shl => write!(f, "i64x2.shl"),
2784 I8x16ShrS => write!(f, "i8x16.shr_s"),
2785 I8x16ShrU => write!(f, "i8x16.shr_u"),
2786 I16x8ShrS => write!(f, "i16x8.shr_s"),
2787 I16x8ShrU => write!(f, "i16x8.shr_u"),
2788 I32x4ShrS => write!(f, "i32x4.shr_s"),
2789 I32x4ShrU => write!(f, "i32x4.shr_u"),
2790 I64x2ShrS => write!(f, "i64x2.shr_s"),
2791 I64x2ShrU => write!(f, "i64x2.shr_u"),
2792 V128And => write!(f, "v128.and"),
2793 V128Or => write!(f, "v128.or"),
2794 V128Xor => write!(f, "v128.xor"),
2795 V128Not => write!(f, "v128.not"),
2796 V128Bitselect => write!(f, "v128.bitselect"),
2797 I8x16AnyTrue => write!(f, "i8x16.any_true"),
2798 I16x8AnyTrue => write!(f, "i16x8.any_true"),
2799 I32x4AnyTrue => write!(f, "i32x4.any_true"),
2800 I64x2AnyTrue => write!(f, "i64x2.any_true"),
2801 I8x16AllTrue => write!(f, "i8x16.all_true"),
2802 I16x8AllTrue => write!(f, "i16x8.all_true"),
2803 I32x4AllTrue => write!(f, "i32x4.all_true"),
2804 I64x2AllTrue => write!(f, "i64x2.all_true"),
2805 I8x16Eq => write!(f, "i8x16.eq"),
2806 I16x8Eq => write!(f, "i16x8.eq"),
2807 I32x4Eq => write!(f, "i32x4.eq"),
2808 F32x4Eq => write!(f, "f32x4.eq"),
2810 F64x2Eq => write!(f, "f64x2.eq"),
2811 I8x16Ne => write!(f, "i8x16.ne"),
2812 I16x8Ne => write!(f, "i16x8.ne"),
2813 I32x4Ne => write!(f, "i32x4.ne"),
2814 F32x4Ne => write!(f, "f32x4.ne"),
2816 F64x2Ne => write!(f, "f64x2.ne"),
2817 I8x16LtS => write!(f, "i8x16.lt_s"),
2818 I8x16LtU => write!(f, "i8x16.lt_u"),
2819 I16x8LtS => write!(f, "i16x8.lt_s"),
2820 I16x8LtU => write!(f, "i16x8.lt_u"),
2821 I32x4LtS => write!(f, "i32x4.lt_s"),
2822 I32x4LtU => write!(f, "i32x4.lt_u"),
2823 F32x4Lt => write!(f, "f32x4.lt"),
2826 F64x2Lt => write!(f, "f64x2.lt"),
2827 I8x16LeS => write!(f, "i8x16.le_s"),
2828 I8x16LeU => write!(f, "i8x16.le_u"),
2829 I16x8LeS => write!(f, "i16x8.le_s"),
2830 I16x8LeU => write!(f, "i16x8.le_u"),
2831 I32x4LeS => write!(f, "i32x4.le_s"),
2832 I32x4LeU => write!(f, "i32x4.le_u"),
2833 F32x4Le => write!(f, "f32x4.le"),
2836 F64x2Le => write!(f, "f64x2.le"),
2837 I8x16GtS => write!(f, "i8x16.gt_s"),
2838 I8x16GtU => write!(f, "i8x16.gt_u"),
2839 I16x8GtS => write!(f, "i16x8.gt_s"),
2840 I16x8GtU => write!(f, "i16x8.gt_u"),
2841 I32x4GtS => write!(f, "i32x4.gt_s"),
2842 I32x4GtU => write!(f, "i32x4.gt_u"),
2843 F32x4Gt => write!(f, "f32x4.gt"),
2846 F64x2Gt => write!(f, "f64x2.gt"),
2847 I8x16GeS => write!(f, "i8x16.ge_s"),
2848 I8x16GeU => write!(f, "i8x16.ge_u"),
2849 I16x8GeS => write!(f, "i16x8.ge_s"),
2850 I16x8GeU => write!(f, "i16x8.ge_u"),
2851 I32x4GeS => write!(f, "i32x4.ge_s"),
2852 I32x4GeU => write!(f, "i32x4.ge_u"),
2853 F32x4Ge => write!(f, "f32x4.ge"),
2856 F64x2Ge => write!(f, "f64x2.ge"),
2857 F32x4Neg => write!(f, "f32x4.neg"),
2858 F64x2Neg => write!(f, "f64x2.neg"),
2859 F32x4Abs => write!(f, "f32x4.abs"),
2860 F64x2Abs => write!(f, "f64x2.abs"),
2861 F32x4Min => write!(f, "f32x4.min"),
2862 F64x2Min => write!(f, "f64x2.min"),
2863 F32x4Max => write!(f, "f32x4.max"),
2864 F64x2Max => write!(f, "f64x2.max"),
2865 F32x4Add => write!(f, "f32x4.add"),
2866 F64x2Add => write!(f, "f64x2.add"),
2867 F32x4Sub => write!(f, "f32x4.sub"),
2868 F64x2Sub => write!(f, "f64x2.sub"),
2869 F32x4Div => write!(f, "f32x4.div"),
2870 F64x2Div => write!(f, "f64x2.div"),
2871 F32x4Mul => write!(f, "f32x4.mul"),
2872 F64x2Mul => write!(f, "f64x2.mul"),
2873 F32x4Sqrt => write!(f, "f32x4.sqrt"),
2874 F64x2Sqrt => write!(f, "f64x2.sqrt"),
2875 F32x4ConvertSI32x4 => write!(f, "f32x4.convert_s/i32x4"),
2876 F32x4ConvertUI32x4 => write!(f, "f32x4.convert_u/i32x4"),
2877 F64x2ConvertSI64x2 => write!(f, "f64x2.convert_s/i64x2"),
2878 F64x2ConvertUI64x2 => write!(f, "f64x2.convert_u/i64x2"),
2879 I32x4TruncSF32x4Sat => write!(f, "i32x4.trunc_s/f32x4:sat"),
2880 I32x4TruncUF32x4Sat => write!(f, "i32x4.trunc_u/f32x4:sat"),
2881 I64x2TruncSF64x2Sat => write!(f, "i64x2.trunc_s/f64x2:sat"),
2882 I64x2TruncUF64x2Sat => write!(f, "i64x2.trunc_u/f64x2:sat"),
2883 }
2884 }
2885}
2886
2887#[cfg(feature = "bulk")]
2888impl fmt::Display for BulkInstruction {
2889 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2890 use self::BulkInstruction::*;
2891
2892 match *self {
2893 MemoryInit(_) => write!(f, "memory.init"),
2894 MemoryDrop(_) => write!(f, "memory.drop"),
2895 MemoryFill => write!(f, "memory.fill"),
2896 MemoryCopy => write!(f, "memory.copy"),
2897 TableInit(_) => write!(f, "table.init"),
2898 TableDrop(_) => write!(f, "table.drop"),
2899 TableCopy => write!(f, "table.copy"),
2900 }
2901 }
2902}
2903
2904impl Serialize for Instructions {
2905 type Error = Error;
2906
2907 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
2908 for op in self.0.into_iter() {
2909 op.serialize(writer)?;
2910 }
2911
2912 Ok(())
2913 }
2914}
2915
2916impl Serialize for InitExpr {
2917 type Error = Error;
2918
2919 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
2920 for op in self.0.into_iter() {
2921 op.serialize(writer)?;
2922 }
2923
2924 Ok(())
2925 }
2926}
2927
2928#[test]
2929fn ifelse() {
2930 let instruction_list = super::deserialize_buffer::<Instructions>(&[
2932 0x04, 0x7F, 0x41, 0x05, 0x05, 0x41, 0x07, 0x0B, 0x0B,
2933 ])
2934 .expect("valid hex of if instruction");
2935 let instructions = instruction_list.elements();
2936 match instructions[0] {
2937 Instruction::If(_) => (),
2938 _ => panic!("Should be deserialized as if instruction"),
2939 }
2940 let before_else = instructions
2941 .iter()
2942 .skip(1)
2943 .take_while(|op| !matches!(**op, Instruction::Else))
2944 .count();
2945 let after_else = instructions
2946 .iter()
2947 .skip(1)
2948 .skip_while(|op| !matches!(**op, Instruction::Else))
2949 .take_while(|op| !matches!(**op, Instruction::End))
2950 .count() - 1; assert_eq!(before_else, after_else);
2952}
2953
2954#[test]
2955fn display() {
2956 let instruction = Instruction::GetLocal(0);
2957 assert_eq!("get_local 0", format!("{}", instruction));
2958
2959 let instruction = Instruction::F64Store(0, 24);
2960 assert_eq!("f64.store offset=24", format!("{}", instruction));
2961
2962 let instruction = Instruction::I64Store(0, 0);
2963 assert_eq!("i64.store", format!("{}", instruction));
2964}
2965
2966#[test]
2967fn size_off() {
2968 assert!(::std::mem::size_of::<Instruction>() <= 24);
2969}
2970
2971#[test]
2972fn instructions_hashset() {
2973 use self::Instruction::{Block, Call, Drop};
2974 use super::types::{BlockType::Value, ValueType};
2975
2976 let set: std::collections::HashSet<Instruction> =
2977 vec![Call(1), Block(Value(ValueType::I32)), Drop].into_iter().collect();
2978 assert!(set.contains(&Drop));
2979}