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