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