1use crate::annotation;
2use crate::core::*;
3use crate::encode::Encode;
4use crate::kw;
5use crate::lexer::{Lexer, Token, TokenKind};
6use crate::parser::{Parse, Parser, Result};
7use crate::token::*;
8use std::mem;
9
10#[derive(Debug)]
16#[allow(missing_docs)]
17pub struct Expression<'a> {
18 pub instrs: Box<[Instruction<'a>]>,
20
21 pub branch_hints: Box<[BranchHint]>,
23
24 pub instr_spans: Option<Box<[Span]>>,
34}
35
36#[derive(Debug)]
41pub struct BranchHint {
42 pub instr_index: usize,
45 pub value: u32,
47}
48
49impl<'a> Parse<'a> for Expression<'a> {
50 fn parse(parser: Parser<'a>) -> Result<Self> {
51 let mut exprs = ExpressionParser::new(parser);
52 exprs.parse(parser)?;
53 Ok(Expression {
54 instrs: exprs.raw_instrs.into(),
55 branch_hints: exprs.branch_hints.into(),
56 instr_spans: exprs.spans.map(|s| s.into()),
57 })
58 }
59}
60
61impl<'a> Expression<'a> {
62 pub fn one(instr: Instruction<'a>) -> Expression<'a> {
64 Expression {
65 instrs: [instr].into(),
66 branch_hints: Box::new([]),
67 instr_spans: None,
68 }
69 }
70
71 pub fn parse_folded_instruction(parser: Parser<'a>) -> Result<Self> {
87 let mut exprs = ExpressionParser::new(parser);
88 exprs.parse_folded_instruction(parser)?;
89 Ok(Expression {
90 instrs: exprs.raw_instrs.into(),
91 branch_hints: exprs.branch_hints.into(),
92 instr_spans: exprs.spans.map(|s| s.into()),
93 })
94 }
95}
96
97struct ExpressionParser<'a> {
104 raw_instrs: Vec<Instruction<'a>>,
110
111 stack: Vec<Level<'a>>,
114
115 branch_hints: Vec<BranchHint>,
119
120 pending_hint: Option<u32>,
127
128 spans: Option<Vec<Span>>,
131}
132
133enum Paren {
134 None,
135 Left,
136 Right(Span),
137}
138
139enum Level<'a> {
141 EndWith(Instruction<'a>, Option<Span>, Option<u32>),
148
149 If(If<'a>, Option<u32>),
158
159 IfArm,
163
164 BranchHint,
166}
167
168enum If<'a> {
170 Clause(Instruction<'a>, Span),
175 Then,
178 Else,
180}
181
182impl<'a> ExpressionParser<'a> {
183 fn new(parser: Parser<'a>) -> ExpressionParser<'a> {
184 ExpressionParser {
185 raw_instrs: Vec::new(),
186 stack: Vec::new(),
187 branch_hints: Vec::new(),
188 pending_hint: None,
189 spans: if parser.track_instr_spans() {
190 Some(Vec::new())
191 } else {
192 None
193 },
194 }
195 }
196
197 fn parse(&mut self, parser: Parser<'a>) -> Result<()> {
198 while !parser.is_empty() || !self.stack.is_empty() {
207 if let Some(Level::If(..)) = self.stack.last() {
211 if !parser.is_empty() && !parser.peek::<LParen>()? {
212 return Err(parser.error("expected `(`"));
213 }
214 }
215
216 match self.paren(parser)? {
217 Paren::None => {
220 let span = parser.cur_span();
221 let hint = self.pending_hint.take();
224 self.push_instr_with_hint(parser.parse()?, span, hint);
225 }
226
227 Paren::Left => {
236 if self.handle_if_lparen(parser)? {
240 continue;
241 }
242
243 if parser.peek::<annotation::metadata_code_branch_hint>()? {
245 self.parse_branch_hint(parser)?;
246 self.stack.push(Level::BranchHint);
247 continue;
248 }
249
250 let span = parser.cur_span();
251 let hint = self.pending_hint.take();
255 match parser.parse()? {
256 i @ Instruction::Block(_)
261 | i @ Instruction::Loop(_)
262 | i @ Instruction::TryTable(_) => {
263 self.push_instr_with_hint(i, span, hint);
264 self.stack
265 .push(Level::EndWith(Instruction::End(None), None, None));
266 }
267
268 i @ Instruction::If(_) => {
274 self.stack.push(Level::If(If::Clause(i, span), hint));
275 }
276
277 other => self.stack.push(Level::EndWith(other, Some(span), hint)),
282 }
283 }
284
285 Paren::Right(span) => {
289 let level = self.stack.pop().unwrap();
290 if !matches!(level, Level::BranchHint) {
294 self.check_hint_consumed(parser)?;
295 }
296 match level {
297 Level::EndWith(i, s, hint) => {
298 self.push_instr_with_hint(i, s.unwrap_or(span), hint)
299 }
300 Level::IfArm => {}
301 Level::BranchHint => {}
302
303 Level::If(If::Clause(..), _) => {
308 return Err(parser.error("previous `if` had no `then`"));
309 }
310 Level::If(_, _) => {
311 self.push_instr(Instruction::End(None), span);
312 }
313 }
314 }
315 }
316 }
317 self.check_hint_consumed(parser)?;
320 Ok(())
321 }
322
323 fn parse_folded_instruction(&mut self, parser: Parser<'a>) -> Result<()> {
324 let mut done = false;
325 while !done {
326 match self.paren(parser)? {
327 Paren::Left => {
328 let span = parser.cur_span();
329 self.stack
330 .push(Level::EndWith(parser.parse()?, Some(span), None));
331 }
332 Paren::Right(span) => {
333 let (top_instr, span) = match self.stack.pop().unwrap() {
334 Level::EndWith(i, s, _) => (i, s.unwrap_or(span)),
335 _ => panic!("unknown level type"),
336 };
337 self.push_instr(top_instr, span);
338 if self.stack.is_empty() {
339 done = true;
340 }
341 }
342 Paren::None => {
343 return Err(parser.error("expected to continue a folded instruction"));
344 }
345 }
346 }
347 Ok(())
348 }
349
350 fn paren(&self, parser: Parser<'a>) -> Result<Paren> {
352 parser.step(|cursor| {
353 Ok(match cursor.lparen()? {
354 Some(rest) => (Paren::Left, rest),
355 None if self.stack.is_empty() => (Paren::None, cursor),
356 None => match cursor.rparen()? {
357 Some(rest) => (Paren::Right(cursor.cur_span()), rest),
358 None => (Paren::None, cursor),
359 },
360 })
361 })
362 }
363
364 fn handle_if_lparen(&mut self, parser: Parser<'a>) -> Result<bool> {
379 let (i, pending) = match self.stack.last_mut() {
381 Some(Level::If(i, pending)) => (i, pending),
382 _ => return Ok(false),
383 };
384
385 match i {
386 If::Clause(if_instr, if_instr_span) => {
391 if !parser.peek::<kw::then>()? {
392 return Ok(false);
393 }
394 if self.pending_hint.is_some() {
397 return Err(Self::hint_placement_error(parser));
398 }
399 parser.parse::<kw::then>()?;
400 let instr = mem::replace(if_instr, Instruction::End(None));
401 let span = *if_instr_span;
402 let hint = pending.take();
403 *i = If::Then;
404 self.push_instr_with_hint(instr, span, hint);
405 self.stack.push(Level::IfArm);
406 Ok(true)
407 }
408
409 If::Then => {
412 let span = parser.parse::<kw::r#else>()?.0;
413 *i = If::Else;
414 self.push_instr(Instruction::Else(None), span);
415 self.stack.push(Level::IfArm);
416 Ok(true)
417 }
418
419 If::Else => Err(parser.error("unexpected token: too many payloads inside of `(if)`")),
422 }
423 }
424
425 fn parse_branch_hint(&mut self, parser: Parser<'a>) -> Result<()> {
426 parser.parse::<annotation::metadata_code_branch_hint>()?;
427
428 let hint = parser.parse::<String>()?;
429
430 let value = match hint.as_bytes() {
431 [0] => 0,
432 [1] => 1,
433 _ => return Err(parser.error("invalid value for branch hint")),
434 };
435
436 if self.pending_hint.is_some() {
440 return Err(parser.error("@metadata.code.branch_hint annotation: duplicate annotation"));
441 }
442 self.pending_hint = Some(value);
443 Ok(())
444 }
445
446 fn push_instr(&mut self, instr: Instruction<'a>, span: Span) {
447 self.raw_instrs.push(instr);
448 if let Some(spans) = &mut self.spans {
449 spans.push(span);
450 }
451 }
452
453 fn check_hint_consumed(&self, parser: Parser<'a>) -> Result<()> {
458 if self.pending_hint.is_some() {
459 return Err(Self::hint_placement_error(parser));
460 }
461 Ok(())
462 }
463
464 fn hint_placement_error(parser: Parser<'a>) -> crate::Error {
465 parser.error("@metadata.code.branch_hint annotation: must precede an instruction")
466 }
467
468 fn push_instr_with_hint(&mut self, instr: Instruction<'a>, span: Span, hint: Option<u32>) {
473 if let Some(value) = hint {
474 self.branch_hints.push(BranchHint {
475 instr_index: self.raw_instrs.len(),
476 value,
477 });
478 }
479 self.push_instr(instr, span);
480 }
481}
482
483macro_rules! instructions {
485 (pub enum Instruction<'a> {
486 $(
487 $(#[$doc:meta])*
488 $name:ident $(($($arg:tt)*))? : [$($binary:tt)*] : $instr:tt $( | $deprecated:tt )?,
489 )*
490 }) => (
491 #[derive(Debug, Clone)]
494 #[allow(missing_docs)]
495 pub enum Instruction<'a> {
496 $(
497 $(#[$doc])*
498 $name $(( instructions!(@ty $($arg)*) ))?,
499 )*
500 }
501
502 #[allow(non_snake_case)]
503 impl<'a> Parse<'a> for Instruction<'a> {
504 fn parse(parser: Parser<'a>) -> Result<Self> {
505 $(
506 fn $name<'a>(_parser: Parser<'a>) -> Result<Instruction<'a>> {
507 Ok(Instruction::$name $((
508 instructions!(@parse _parser $($arg)*)?
509 ))?)
510 }
511 )*
512 let parse_remainder = parser.step(|c| {
513 let (kw, rest) = match c.keyword() ?{
514 Some(pair) => pair,
515 None => return Err(c.error("expected an instruction")),
516 };
517 match kw {
518 $($instr $( | $deprecated )?=> Ok(($name as fn(_) -> _, rest)),)*
519 _ => return Err(c.error("unknown operator or unexpected token")),
520 }
521 })?;
522 parse_remainder(parser)
523 }
524 }
525
526 impl Encode for Instruction<'_> {
527 #[allow(non_snake_case, unused_lifetimes)]
528 fn encode(&self, v: &mut Vec<u8>) {
529 match self {
530 $(
531 Instruction::$name $((instructions!(@first x $($arg)*)))? => {
532 fn encode<'a>($(arg: &instructions!(@ty $($arg)*),)? v: &mut Vec<u8>) {
533 instructions!(@encode v $($binary)*);
534 $(<instructions!(@ty $($arg)*) as Encode>::encode(arg, v);)?
535 }
536 encode($( instructions!(@first x $($arg)*), )? v)
537 }
538 )*
539 }
540 }
541 }
542
543 impl<'a> Instruction<'a> {
544 #[allow(unused_variables, non_snake_case)]
547 pub fn memarg_mut(&mut self) -> Option<&mut MemArg<'a>> {
548 match self {
549 $(
550 Instruction::$name $((instructions!(@memarg_binding a $($arg)*)))? => {
551 instructions!(@get_memarg a $($($arg)*)?)
552 }
553 )*
554 }
555 }
556 }
557 );
558
559 (@ty MemArg<$amt:tt>) => (MemArg<'a>);
560 (@ty LoadOrStoreLane<$amt:tt>) => (LoadOrStoreLane<'a>);
561 (@ty $other:ty) => ($other);
562
563 (@first $first:ident $($t:tt)*) => ($first);
564
565 (@parse $parser:ident MemArg<$amt:tt>) => (MemArg::parse($parser, $amt));
566 (@parse $parser:ident MemArg) => (compile_error!("must specify `MemArg` default"));
567 (@parse $parser:ident LoadOrStoreLane<$amt:tt>) => (LoadOrStoreLane::parse($parser, $amt));
568 (@parse $parser:ident LoadOrStoreLane) => (compile_error!("must specify `LoadOrStoreLane` default"));
569 (@parse $parser:ident $other:ty) => ($parser.parse::<$other>());
570
571 (@encode $dst:ident 0xfd, $simd:tt) => ({
573 $dst.push(0xfd);
574 <u32 as Encode>::encode(&$simd, $dst);
575 });
576 (@encode $dst:ident $($bytes:tt)*) => ($dst.extend_from_slice(&[$($bytes)*]););
577
578 (@get_memarg $name:ident MemArg<$amt:tt>) => (Some($name));
579 (@get_memarg $name:ident LoadOrStoreLane<$amt:tt>) => (Some(&mut $name.memarg));
580 (@get_memarg $($other:tt)*) => (None);
581
582 (@memarg_binding $name:ident MemArg<$amt:tt>) => ($name);
583 (@memarg_binding $name:ident LoadOrStoreLane<$amt:tt>) => ($name);
584 (@memarg_binding $name:ident $other:ty) => (_);
585}
586
587instructions! {
588 pub enum Instruction<'a> {
589 Block(Box<BlockType<'a>>) : [0x02] : "block",
590 If(Box<BlockType<'a>>) : [0x04] : "if",
591 Else(Option<Id<'a>>) : [0x05] : "else",
592 Loop(Box<BlockType<'a>>) : [0x03] : "loop",
593 End(Option<Id<'a>>) : [0x0b] : "end",
594
595 Unreachable : [0x00] : "unreachable",
596 Nop : [0x01] : "nop",
597 Br(Index<'a>) : [0x0c] : "br",
598 BrIf(Index<'a>) : [0x0d] : "br_if",
599 BrTable(BrTableIndices<'a>) : [0x0e] : "br_table",
600 Return : [0x0f] : "return",
601 Call(Index<'a>) : [0x10] : "call",
602 CallIndirect(Box<CallIndirect<'a>>) : [0x11] : "call_indirect",
603
604 ReturnCall(Index<'a>) : [0x12] : "return_call",
606 ReturnCallIndirect(Box<CallIndirect<'a>>) : [0x13] : "return_call_indirect",
607
608 CallRef(Index<'a>) : [0x14] : "call_ref",
610 ReturnCallRef(Index<'a>) : [0x15] : "return_call_ref",
611
612 Drop : [0x1a] : "drop",
613 Select(SelectTypes<'a>) : [] : "select",
614 LocalGet(Index<'a>) : [0x20] : "local.get",
615 LocalSet(Index<'a>) : [0x21] : "local.set",
616 LocalTee(Index<'a>) : [0x22] : "local.tee",
617 GlobalGet(Index<'a>) : [0x23] : "global.get",
618 GlobalSet(Index<'a>) : [0x24] : "global.set",
619
620 TableGet(TableArg<'a>) : [0x25] : "table.get",
621 TableSet(TableArg<'a>) : [0x26] : "table.set",
622
623 I32Load(MemArg<4>) : [0x28] : "i32.load",
624 I64Load(MemArg<8>) : [0x29] : "i64.load",
625 F32Load(MemArg<4>) : [0x2a] : "f32.load",
626 F64Load(MemArg<8>) : [0x2b] : "f64.load",
627 I32Load8s(MemArg<1>) : [0x2c] : "i32.load8_s",
628 I32Load8u(MemArg<1>) : [0x2d] : "i32.load8_u",
629 I32Load16s(MemArg<2>) : [0x2e] : "i32.load16_s",
630 I32Load16u(MemArg<2>) : [0x2f] : "i32.load16_u",
631 I64Load8s(MemArg<1>) : [0x30] : "i64.load8_s",
632 I64Load8u(MemArg<1>) : [0x31] : "i64.load8_u",
633 I64Load16s(MemArg<2>) : [0x32] : "i64.load16_s",
634 I64Load16u(MemArg<2>) : [0x33] : "i64.load16_u",
635 I64Load32s(MemArg<4>) : [0x34] : "i64.load32_s",
636 I64Load32u(MemArg<4>) : [0x35] : "i64.load32_u",
637 I32Store(MemArg<4>) : [0x36] : "i32.store",
638 I64Store(MemArg<8>) : [0x37] : "i64.store",
639 F32Store(MemArg<4>) : [0x38] : "f32.store",
640 F64Store(MemArg<8>) : [0x39] : "f64.store",
641 I32Store8(MemArg<1>) : [0x3a] : "i32.store8",
642 I32Store16(MemArg<2>) : [0x3b] : "i32.store16",
643 I64Store8(MemArg<1>) : [0x3c] : "i64.store8",
644 I64Store16(MemArg<2>) : [0x3d] : "i64.store16",
645 I64Store32(MemArg<4>) : [0x3e] : "i64.store32",
646
647 MemorySize(MemoryArg<'a>) : [0x3f] : "memory.size",
649 MemoryGrow(MemoryArg<'a>) : [0x40] : "memory.grow",
650 MemoryInit(MemoryInit<'a>) : [0xfc, 0x08] : "memory.init",
651 MemoryCopy(MemoryCopy<'a>) : [0xfc, 0x0a] : "memory.copy",
652 MemoryFill(MemoryArg<'a>) : [0xfc, 0x0b] : "memory.fill",
653 MemoryDiscard(MemoryArg<'a>) : [0xfc, 0x12] : "memory.discard",
654 DataDrop(Index<'a>) : [0xfc, 0x09] : "data.drop",
655 ElemDrop(Index<'a>) : [0xfc, 0x0d] : "elem.drop",
656 TableInit(TableInit<'a>) : [0xfc, 0x0c] : "table.init",
657 TableCopy(TableCopy<'a>) : [0xfc, 0x0e] : "table.copy",
658 TableFill(TableArg<'a>) : [0xfc, 0x11] : "table.fill",
659 TableSize(TableArg<'a>) : [0xfc, 0x10] : "table.size",
660 TableGrow(TableArg<'a>) : [0xfc, 0x0f] : "table.grow",
661
662 RefNull(HeapType<'a>) : [0xd0] : "ref.null",
663 RefIsNull : [0xd1] : "ref.is_null",
664 RefFunc(Index<'a>) : [0xd2] : "ref.func",
665
666 RefAsNonNull : [0xd4] : "ref.as_non_null",
668 BrOnNull(Index<'a>) : [0xd5] : "br_on_null",
669 BrOnNonNull(Index<'a>) : [0xd6] : "br_on_non_null",
670
671 RefEq : [0xd3] : "ref.eq",
673
674 StructNew(Index<'a>) : [0xfb, 0x00] : "struct.new",
676 StructNewDefault(Index<'a>) : [0xfb, 0x01] : "struct.new_default",
677 StructGet(StructAccess<'a>) : [0xfb, 0x02] : "struct.get",
678 StructGetS(StructAccess<'a>) : [0xfb, 0x03] : "struct.get_s",
679 StructGetU(StructAccess<'a>) : [0xfb, 0x04] : "struct.get_u",
680 StructSet(StructAccess<'a>) : [0xfb, 0x05] : "struct.set",
681
682 ArrayNew(Index<'a>) : [0xfb, 0x06] : "array.new",
684 ArrayNewDefault(Index<'a>) : [0xfb, 0x07] : "array.new_default",
685 ArrayNewFixed(ArrayNewFixed<'a>) : [0xfb, 0x08] : "array.new_fixed",
686 ArrayNewData(ArrayNewData<'a>) : [0xfb, 0x09] : "array.new_data",
687 ArrayNewElem(ArrayNewElem<'a>) : [0xfb, 0x0a] : "array.new_elem",
688 ArrayGet(Index<'a>) : [0xfb, 0x0b] : "array.get",
689 ArrayGetS(Index<'a>) : [0xfb, 0x0c] : "array.get_s",
690 ArrayGetU(Index<'a>) : [0xfb, 0x0d] : "array.get_u",
691 ArraySet(Index<'a>) : [0xfb, 0x0e] : "array.set",
692 ArrayLen : [0xfb, 0x0f] : "array.len",
693 ArrayFill(ArrayFill<'a>) : [0xfb, 0x10] : "array.fill",
694 ArrayCopy(ArrayCopy<'a>) : [0xfb, 0x11] : "array.copy",
695 ArrayInitData(ArrayInit<'a>) : [0xfb, 0x12] : "array.init_data",
696 ArrayInitElem(ArrayInit<'a>) : [0xfb, 0x13] : "array.init_elem",
697
698 RefI31 : [0xfb, 0x1c] : "ref.i31",
700 I31GetS : [0xfb, 0x1d] : "i31.get_s",
701 I31GetU : [0xfb, 0x1e] : "i31.get_u",
702
703 RefTest(RefTest<'a>) : [] : "ref.test",
705 RefCast(RefCast<'a>) : [] : "ref.cast",
706 BrOnCast(Box<BrOnCast<'a>>) : [] : "br_on_cast",
707 BrOnCastFail(Box<BrOnCastFail<'a>>) : [] : "br_on_cast_fail",
708
709 AnyConvertExtern : [0xfb, 0x1a] : "any.convert_extern",
711 ExternConvertAny : [0xfb, 0x1b] : "extern.convert_any",
712
713 I32Const(i32) : [0x41] : "i32.const",
714 I64Const(i64) : [0x42] : "i64.const",
715 F32Const(F32) : [0x43] : "f32.const",
716 F64Const(F64) : [0x44] : "f64.const",
717
718 I32Clz : [0x67] : "i32.clz",
719 I32Ctz : [0x68] : "i32.ctz",
720 I32Popcnt : [0x69] : "i32.popcnt",
721 I32Add : [0x6a] : "i32.add",
722 I32Sub : [0x6b] : "i32.sub",
723 I32Mul : [0x6c] : "i32.mul",
724 I32DivS : [0x6d] : "i32.div_s",
725 I32DivU : [0x6e] : "i32.div_u",
726 I32RemS : [0x6f] : "i32.rem_s",
727 I32RemU : [0x70] : "i32.rem_u",
728 I32And : [0x71] : "i32.and",
729 I32Or : [0x72] : "i32.or",
730 I32Xor : [0x73] : "i32.xor",
731 I32Shl : [0x74] : "i32.shl",
732 I32ShrS : [0x75] : "i32.shr_s",
733 I32ShrU : [0x76] : "i32.shr_u",
734 I32Rotl : [0x77] : "i32.rotl",
735 I32Rotr : [0x78] : "i32.rotr",
736
737 I64Clz : [0x79] : "i64.clz",
738 I64Ctz : [0x7a] : "i64.ctz",
739 I64Popcnt : [0x7b] : "i64.popcnt",
740 I64Add : [0x7c] : "i64.add",
741 I64Sub : [0x7d] : "i64.sub",
742 I64Mul : [0x7e] : "i64.mul",
743 I64DivS : [0x7f] : "i64.div_s",
744 I64DivU : [0x80] : "i64.div_u",
745 I64RemS : [0x81] : "i64.rem_s",
746 I64RemU : [0x82] : "i64.rem_u",
747 I64And : [0x83] : "i64.and",
748 I64Or : [0x84] : "i64.or",
749 I64Xor : [0x85] : "i64.xor",
750 I64Shl : [0x86] : "i64.shl",
751 I64ShrS : [0x87] : "i64.shr_s",
752 I64ShrU : [0x88] : "i64.shr_u",
753 I64Rotl : [0x89] : "i64.rotl",
754 I64Rotr : [0x8a] : "i64.rotr",
755
756 F32Abs : [0x8b] : "f32.abs",
757 F32Neg : [0x8c] : "f32.neg",
758 F32Ceil : [0x8d] : "f32.ceil",
759 F32Floor : [0x8e] : "f32.floor",
760 F32Trunc : [0x8f] : "f32.trunc",
761 F32Nearest : [0x90] : "f32.nearest",
762 F32Sqrt : [0x91] : "f32.sqrt",
763 F32Add : [0x92] : "f32.add",
764 F32Sub : [0x93] : "f32.sub",
765 F32Mul : [0x94] : "f32.mul",
766 F32Div : [0x95] : "f32.div",
767 F32Min : [0x96] : "f32.min",
768 F32Max : [0x97] : "f32.max",
769 F32Copysign : [0x98] : "f32.copysign",
770
771 F64Abs : [0x99] : "f64.abs",
772 F64Neg : [0x9a] : "f64.neg",
773 F64Ceil : [0x9b] : "f64.ceil",
774 F64Floor : [0x9c] : "f64.floor",
775 F64Trunc : [0x9d] : "f64.trunc",
776 F64Nearest : [0x9e] : "f64.nearest",
777 F64Sqrt : [0x9f] : "f64.sqrt",
778 F64Add : [0xa0] : "f64.add",
779 F64Sub : [0xa1] : "f64.sub",
780 F64Mul : [0xa2] : "f64.mul",
781 F64Div : [0xa3] : "f64.div",
782 F64Min : [0xa4] : "f64.min",
783 F64Max : [0xa5] : "f64.max",
784 F64Copysign : [0xa6] : "f64.copysign",
785
786 I32Eqz : [0x45] : "i32.eqz",
787 I32Eq : [0x46] : "i32.eq",
788 I32Ne : [0x47] : "i32.ne",
789 I32LtS : [0x48] : "i32.lt_s",
790 I32LtU : [0x49] : "i32.lt_u",
791 I32GtS : [0x4a] : "i32.gt_s",
792 I32GtU : [0x4b] : "i32.gt_u",
793 I32LeS : [0x4c] : "i32.le_s",
794 I32LeU : [0x4d] : "i32.le_u",
795 I32GeS : [0x4e] : "i32.ge_s",
796 I32GeU : [0x4f] : "i32.ge_u",
797
798 I64Eqz : [0x50] : "i64.eqz",
799 I64Eq : [0x51] : "i64.eq",
800 I64Ne : [0x52] : "i64.ne",
801 I64LtS : [0x53] : "i64.lt_s",
802 I64LtU : [0x54] : "i64.lt_u",
803 I64GtS : [0x55] : "i64.gt_s",
804 I64GtU : [0x56] : "i64.gt_u",
805 I64LeS : [0x57] : "i64.le_s",
806 I64LeU : [0x58] : "i64.le_u",
807 I64GeS : [0x59] : "i64.ge_s",
808 I64GeU : [0x5a] : "i64.ge_u",
809
810 F32Eq : [0x5b] : "f32.eq",
811 F32Ne : [0x5c] : "f32.ne",
812 F32Lt : [0x5d] : "f32.lt",
813 F32Gt : [0x5e] : "f32.gt",
814 F32Le : [0x5f] : "f32.le",
815 F32Ge : [0x60] : "f32.ge",
816
817 F64Eq : [0x61] : "f64.eq",
818 F64Ne : [0x62] : "f64.ne",
819 F64Lt : [0x63] : "f64.lt",
820 F64Gt : [0x64] : "f64.gt",
821 F64Le : [0x65] : "f64.le",
822 F64Ge : [0x66] : "f64.ge",
823
824 I32WrapI64 : [0xa7] : "i32.wrap_i64",
825 I32TruncF32S : [0xa8] : "i32.trunc_f32_s",
826 I32TruncF32U : [0xa9] : "i32.trunc_f32_u",
827 I32TruncF64S : [0xaa] : "i32.trunc_f64_s",
828 I32TruncF64U : [0xab] : "i32.trunc_f64_u",
829 I64ExtendI32S : [0xac] : "i64.extend_i32_s",
830 I64ExtendI32U : [0xad] : "i64.extend_i32_u",
831 I64TruncF32S : [0xae] : "i64.trunc_f32_s",
832 I64TruncF32U : [0xaf] : "i64.trunc_f32_u",
833 I64TruncF64S : [0xb0] : "i64.trunc_f64_s",
834 I64TruncF64U : [0xb1] : "i64.trunc_f64_u",
835 F32ConvertI32S : [0xb2] : "f32.convert_i32_s",
836 F32ConvertI32U : [0xb3] : "f32.convert_i32_u",
837 F32ConvertI64S : [0xb4] : "f32.convert_i64_s",
838 F32ConvertI64U : [0xb5] : "f32.convert_i64_u",
839 F32DemoteF64 : [0xb6] : "f32.demote_f64",
840 F64ConvertI32S : [0xb7] : "f64.convert_i32_s",
841 F64ConvertI32U : [0xb8] : "f64.convert_i32_u",
842 F64ConvertI64S : [0xb9] : "f64.convert_i64_s",
843 F64ConvertI64U : [0xba] : "f64.convert_i64_u",
844 F64PromoteF32 : [0xbb] : "f64.promote_f32",
845 I32ReinterpretF32 : [0xbc] : "i32.reinterpret_f32",
846 I64ReinterpretF64 : [0xbd] : "i64.reinterpret_f64",
847 F32ReinterpretI32 : [0xbe] : "f32.reinterpret_i32",
848 F64ReinterpretI64 : [0xbf] : "f64.reinterpret_i64",
849
850 I32TruncSatF32S : [0xfc, 0x00] : "i32.trunc_sat_f32_s",
852 I32TruncSatF32U : [0xfc, 0x01] : "i32.trunc_sat_f32_u",
853 I32TruncSatF64S : [0xfc, 0x02] : "i32.trunc_sat_f64_s",
854 I32TruncSatF64U : [0xfc, 0x03] : "i32.trunc_sat_f64_u",
855 I64TruncSatF32S : [0xfc, 0x04] : "i64.trunc_sat_f32_s",
856 I64TruncSatF32U : [0xfc, 0x05] : "i64.trunc_sat_f32_u",
857 I64TruncSatF64S : [0xfc, 0x06] : "i64.trunc_sat_f64_s",
858 I64TruncSatF64U : [0xfc, 0x07] : "i64.trunc_sat_f64_u",
859
860 I32Extend8S : [0xc0] : "i32.extend8_s",
862 I32Extend16S : [0xc1] : "i32.extend16_s",
863 I64Extend8S : [0xc2] : "i64.extend8_s",
864 I64Extend16S : [0xc3] : "i64.extend16_s",
865 I64Extend32S : [0xc4] : "i64.extend32_s",
866
867 MemoryAtomicNotify(MemArg<4>) : [0xfe, 0x00] : "memory.atomic.notify",
869 MemoryAtomicWait32(MemArg<4>) : [0xfe, 0x01] : "memory.atomic.wait32",
870 MemoryAtomicWait64(MemArg<8>) : [0xfe, 0x02] : "memory.atomic.wait64",
871 AtomicFence : [0xfe, 0x03, 0x00] : "atomic.fence",
872
873 I32AtomicLoad(MemArg<4>) : [0xfe, 0x10] : "i32.atomic.load",
874 I64AtomicLoad(MemArg<8>) : [0xfe, 0x11] : "i64.atomic.load",
875 I32AtomicLoad8u(MemArg<1>) : [0xfe, 0x12] : "i32.atomic.load8_u",
876 I32AtomicLoad16u(MemArg<2>) : [0xfe, 0x13] : "i32.atomic.load16_u",
877 I64AtomicLoad8u(MemArg<1>) : [0xfe, 0x14] : "i64.atomic.load8_u",
878 I64AtomicLoad16u(MemArg<2>) : [0xfe, 0x15] : "i64.atomic.load16_u",
879 I64AtomicLoad32u(MemArg<4>) : [0xfe, 0x16] : "i64.atomic.load32_u",
880 I32AtomicStore(MemArg<4>) : [0xfe, 0x17] : "i32.atomic.store",
881 I64AtomicStore(MemArg<8>) : [0xfe, 0x18] : "i64.atomic.store",
882 I32AtomicStore8(MemArg<1>) : [0xfe, 0x19] : "i32.atomic.store8",
883 I32AtomicStore16(MemArg<2>) : [0xfe, 0x1a] : "i32.atomic.store16",
884 I64AtomicStore8(MemArg<1>) : [0xfe, 0x1b] : "i64.atomic.store8",
885 I64AtomicStore16(MemArg<2>) : [0xfe, 0x1c] : "i64.atomic.store16",
886 I64AtomicStore32(MemArg<4>) : [0xfe, 0x1d] : "i64.atomic.store32",
887
888 I32AtomicRmwAdd(MemArg<4>) : [0xfe, 0x1e] : "i32.atomic.rmw.add",
889 I64AtomicRmwAdd(MemArg<8>) : [0xfe, 0x1f] : "i64.atomic.rmw.add",
890 I32AtomicRmw8AddU(MemArg<1>) : [0xfe, 0x20] : "i32.atomic.rmw8.add_u",
891 I32AtomicRmw16AddU(MemArg<2>) : [0xfe, 0x21] : "i32.atomic.rmw16.add_u",
892 I64AtomicRmw8AddU(MemArg<1>) : [0xfe, 0x22] : "i64.atomic.rmw8.add_u",
893 I64AtomicRmw16AddU(MemArg<2>) : [0xfe, 0x23] : "i64.atomic.rmw16.add_u",
894 I64AtomicRmw32AddU(MemArg<4>) : [0xfe, 0x24] : "i64.atomic.rmw32.add_u",
895
896 I32AtomicRmwSub(MemArg<4>) : [0xfe, 0x25] : "i32.atomic.rmw.sub",
897 I64AtomicRmwSub(MemArg<8>) : [0xfe, 0x26] : "i64.atomic.rmw.sub",
898 I32AtomicRmw8SubU(MemArg<1>) : [0xfe, 0x27] : "i32.atomic.rmw8.sub_u",
899 I32AtomicRmw16SubU(MemArg<2>) : [0xfe, 0x28] : "i32.atomic.rmw16.sub_u",
900 I64AtomicRmw8SubU(MemArg<1>) : [0xfe, 0x29] : "i64.atomic.rmw8.sub_u",
901 I64AtomicRmw16SubU(MemArg<2>) : [0xfe, 0x2a] : "i64.atomic.rmw16.sub_u",
902 I64AtomicRmw32SubU(MemArg<4>) : [0xfe, 0x2b] : "i64.atomic.rmw32.sub_u",
903
904 I32AtomicRmwAnd(MemArg<4>) : [0xfe, 0x2c] : "i32.atomic.rmw.and",
905 I64AtomicRmwAnd(MemArg<8>) : [0xfe, 0x2d] : "i64.atomic.rmw.and",
906 I32AtomicRmw8AndU(MemArg<1>) : [0xfe, 0x2e] : "i32.atomic.rmw8.and_u",
907 I32AtomicRmw16AndU(MemArg<2>) : [0xfe, 0x2f] : "i32.atomic.rmw16.and_u",
908 I64AtomicRmw8AndU(MemArg<1>) : [0xfe, 0x30] : "i64.atomic.rmw8.and_u",
909 I64AtomicRmw16AndU(MemArg<2>) : [0xfe, 0x31] : "i64.atomic.rmw16.and_u",
910 I64AtomicRmw32AndU(MemArg<4>) : [0xfe, 0x32] : "i64.atomic.rmw32.and_u",
911
912 I32AtomicRmwOr(MemArg<4>) : [0xfe, 0x33] : "i32.atomic.rmw.or",
913 I64AtomicRmwOr(MemArg<8>) : [0xfe, 0x34] : "i64.atomic.rmw.or",
914 I32AtomicRmw8OrU(MemArg<1>) : [0xfe, 0x35] : "i32.atomic.rmw8.or_u",
915 I32AtomicRmw16OrU(MemArg<2>) : [0xfe, 0x36] : "i32.atomic.rmw16.or_u",
916 I64AtomicRmw8OrU(MemArg<1>) : [0xfe, 0x37] : "i64.atomic.rmw8.or_u",
917 I64AtomicRmw16OrU(MemArg<2>) : [0xfe, 0x38] : "i64.atomic.rmw16.or_u",
918 I64AtomicRmw32OrU(MemArg<4>) : [0xfe, 0x39] : "i64.atomic.rmw32.or_u",
919
920 I32AtomicRmwXor(MemArg<4>) : [0xfe, 0x3a] : "i32.atomic.rmw.xor",
921 I64AtomicRmwXor(MemArg<8>) : [0xfe, 0x3b] : "i64.atomic.rmw.xor",
922 I32AtomicRmw8XorU(MemArg<1>) : [0xfe, 0x3c] : "i32.atomic.rmw8.xor_u",
923 I32AtomicRmw16XorU(MemArg<2>) : [0xfe, 0x3d] : "i32.atomic.rmw16.xor_u",
924 I64AtomicRmw8XorU(MemArg<1>) : [0xfe, 0x3e] : "i64.atomic.rmw8.xor_u",
925 I64AtomicRmw16XorU(MemArg<2>) : [0xfe, 0x3f] : "i64.atomic.rmw16.xor_u",
926 I64AtomicRmw32XorU(MemArg<4>) : [0xfe, 0x40] : "i64.atomic.rmw32.xor_u",
927
928 I32AtomicRmwXchg(MemArg<4>) : [0xfe, 0x41] : "i32.atomic.rmw.xchg",
929 I64AtomicRmwXchg(MemArg<8>) : [0xfe, 0x42] : "i64.atomic.rmw.xchg",
930 I32AtomicRmw8XchgU(MemArg<1>) : [0xfe, 0x43] : "i32.atomic.rmw8.xchg_u",
931 I32AtomicRmw16XchgU(MemArg<2>) : [0xfe, 0x44] : "i32.atomic.rmw16.xchg_u",
932 I64AtomicRmw8XchgU(MemArg<1>) : [0xfe, 0x45] : "i64.atomic.rmw8.xchg_u",
933 I64AtomicRmw16XchgU(MemArg<2>) : [0xfe, 0x46] : "i64.atomic.rmw16.xchg_u",
934 I64AtomicRmw32XchgU(MemArg<4>) : [0xfe, 0x47] : "i64.atomic.rmw32.xchg_u",
935
936 I32AtomicRmwCmpxchg(MemArg<4>) : [0xfe, 0x48] : "i32.atomic.rmw.cmpxchg",
937 I64AtomicRmwCmpxchg(MemArg<8>) : [0xfe, 0x49] : "i64.atomic.rmw.cmpxchg",
938 I32AtomicRmw8CmpxchgU(MemArg<1>) : [0xfe, 0x4a] : "i32.atomic.rmw8.cmpxchg_u",
939 I32AtomicRmw16CmpxchgU(MemArg<2>) : [0xfe, 0x4b] : "i32.atomic.rmw16.cmpxchg_u",
940 I64AtomicRmw8CmpxchgU(MemArg<1>) : [0xfe, 0x4c] : "i64.atomic.rmw8.cmpxchg_u",
941 I64AtomicRmw16CmpxchgU(MemArg<2>) : [0xfe, 0x4d] : "i64.atomic.rmw16.cmpxchg_u",
942 I64AtomicRmw32CmpxchgU(MemArg<4>) : [0xfe, 0x4e] : "i64.atomic.rmw32.cmpxchg_u",
943
944 GlobalAtomicGet(Ordered<Index<'a>>) : [0xfe, 0x4f] : "global.atomic.get",
946 GlobalAtomicSet(Ordered<Index<'a>>) : [0xfe, 0x50] : "global.atomic.set",
947 GlobalAtomicRmwAdd(Ordered<Index<'a>>) : [0xfe, 0x51] : "global.atomic.rmw.add",
948 GlobalAtomicRmwSub(Ordered<Index<'a>>) : [0xfe, 0x52] : "global.atomic.rmw.sub",
949 GlobalAtomicRmwAnd(Ordered<Index<'a>>) : [0xfe, 0x53] : "global.atomic.rmw.and",
950 GlobalAtomicRmwOr(Ordered<Index<'a>>) : [0xfe, 0x54] : "global.atomic.rmw.or",
951 GlobalAtomicRmwXor(Ordered<Index<'a>>) : [0xfe, 0x55] : "global.atomic.rmw.xor",
952 GlobalAtomicRmwXchg(Ordered<Index<'a>>) : [0xfe, 0x56] : "global.atomic.rmw.xchg",
953 GlobalAtomicRmwCmpxchg(Ordered<Index<'a>>) : [0xfe, 0x57] : "global.atomic.rmw.cmpxchg",
954 TableAtomicGet(Ordered<TableArg<'a>>) : [0xfe, 0x58] : "table.atomic.get",
955 TableAtomicSet(Ordered<TableArg<'a>>) : [0xfe, 0x59] : "table.atomic.set",
956 TableAtomicRmwXchg(Ordered<TableArg<'a>>) : [0xfe, 0x5a] : "table.atomic.rmw.xchg",
957 TableAtomicRmwCmpxchg(Ordered<TableArg<'a>>) : [0xfe, 0x5b] : "table.atomic.rmw.cmpxchg",
958 StructAtomicGet(Ordered<StructAccess<'a>>) : [0xfe, 0x5c] : "struct.atomic.get",
959 StructAtomicGetS(Ordered<StructAccess<'a>>) : [0xfe, 0x5d] : "struct.atomic.get_s",
960 StructAtomicGetU(Ordered<StructAccess<'a>>) : [0xfe, 0x5e] : "struct.atomic.get_u",
961 StructAtomicSet(Ordered<StructAccess<'a>>) : [0xfe, 0x5f] : "struct.atomic.set",
962 StructAtomicRmwAdd(Ordered<StructAccess<'a>>) : [0xfe, 0x60] : "struct.atomic.rmw.add",
963 StructAtomicRmwSub(Ordered<StructAccess<'a>>) : [0xfe, 0x61] : "struct.atomic.rmw.sub",
964 StructAtomicRmwAnd(Ordered<StructAccess<'a>>) : [0xfe, 0x62] : "struct.atomic.rmw.and",
965 StructAtomicRmwOr(Ordered<StructAccess<'a>>) : [0xfe, 0x63] : "struct.atomic.rmw.or",
966 StructAtomicRmwXor(Ordered<StructAccess<'a>>) : [0xfe, 0x64] : "struct.atomic.rmw.xor",
967 StructAtomicRmwXchg(Ordered<StructAccess<'a>>) : [0xfe, 0x65] : "struct.atomic.rmw.xchg",
968 StructAtomicRmwCmpxchg(Ordered<StructAccess<'a>>) : [0xfe, 0x66] : "struct.atomic.rmw.cmpxchg",
969 ArrayAtomicGet(Ordered<Index<'a>>) : [0xfe, 0x67] : "array.atomic.get",
970 ArrayAtomicGetS(Ordered<Index<'a>>) : [0xfe, 0x68] : "array.atomic.get_s",
971 ArrayAtomicGetU(Ordered<Index<'a>>) : [0xfe, 0x69] : "array.atomic.get_u",
972 ArrayAtomicSet(Ordered<Index<'a>>) : [0xfe, 0x6a] : "array.atomic.set",
973 ArrayAtomicRmwAdd(Ordered<Index<'a>>) : [0xfe, 0x6b] : "array.atomic.rmw.add",
974 ArrayAtomicRmwSub(Ordered<Index<'a>>) : [0xfe, 0x6c] : "array.atomic.rmw.sub",
975 ArrayAtomicRmwAnd(Ordered<Index<'a>>) : [0xfe, 0x6d] : "array.atomic.rmw.and",
976 ArrayAtomicRmwOr(Ordered<Index<'a>>) : [0xfe, 0x6e] : "array.atomic.rmw.or",
977 ArrayAtomicRmwXor(Ordered<Index<'a>>) : [0xfe, 0x6f] : "array.atomic.rmw.xor",
978 ArrayAtomicRmwXchg(Ordered<Index<'a>>) : [0xfe, 0x70] : "array.atomic.rmw.xchg",
979 ArrayAtomicRmwCmpxchg(Ordered<Index<'a>>) : [0xfe, 0x71] : "array.atomic.rmw.cmpxchg",
980 RefI31Shared : [0xfe, 0x72] : "ref.i31_shared",
981
982 V128Load(MemArg<16>) : [0xfd, 0] : "v128.load",
986 V128Load8x8S(MemArg<8>) : [0xfd, 1] : "v128.load8x8_s",
987 V128Load8x8U(MemArg<8>) : [0xfd, 2] : "v128.load8x8_u",
988 V128Load16x4S(MemArg<8>) : [0xfd, 3] : "v128.load16x4_s",
989 V128Load16x4U(MemArg<8>) : [0xfd, 4] : "v128.load16x4_u",
990 V128Load32x2S(MemArg<8>) : [0xfd, 5] : "v128.load32x2_s",
991 V128Load32x2U(MemArg<8>) : [0xfd, 6] : "v128.load32x2_u",
992 V128Load8Splat(MemArg<1>) : [0xfd, 7] : "v128.load8_splat",
993 V128Load16Splat(MemArg<2>) : [0xfd, 8] : "v128.load16_splat",
994 V128Load32Splat(MemArg<4>) : [0xfd, 9] : "v128.load32_splat",
995 V128Load64Splat(MemArg<8>) : [0xfd, 10] : "v128.load64_splat",
996 V128Load32Zero(MemArg<4>) : [0xfd, 92] : "v128.load32_zero",
997 V128Load64Zero(MemArg<8>) : [0xfd, 93] : "v128.load64_zero",
998 V128Store(MemArg<16>) : [0xfd, 11] : "v128.store",
999
1000 V128Load8Lane(LoadOrStoreLane<1>) : [0xfd, 84] : "v128.load8_lane",
1001 V128Load16Lane(LoadOrStoreLane<2>) : [0xfd, 85] : "v128.load16_lane",
1002 V128Load32Lane(LoadOrStoreLane<4>) : [0xfd, 86] : "v128.load32_lane",
1003 V128Load64Lane(LoadOrStoreLane<8>): [0xfd, 87] : "v128.load64_lane",
1004 V128Store8Lane(LoadOrStoreLane<1>) : [0xfd, 88] : "v128.store8_lane",
1005 V128Store16Lane(LoadOrStoreLane<2>) : [0xfd, 89] : "v128.store16_lane",
1006 V128Store32Lane(LoadOrStoreLane<4>) : [0xfd, 90] : "v128.store32_lane",
1007 V128Store64Lane(LoadOrStoreLane<8>) : [0xfd, 91] : "v128.store64_lane",
1008
1009 V128Const(V128Const) : [0xfd, 12] : "v128.const",
1010 I8x16Shuffle(I8x16Shuffle) : [0xfd, 13] : "i8x16.shuffle",
1011
1012 I8x16ExtractLaneS(LaneArg) : [0xfd, 21] : "i8x16.extract_lane_s",
1013 I8x16ExtractLaneU(LaneArg) : [0xfd, 22] : "i8x16.extract_lane_u",
1014 I8x16ReplaceLane(LaneArg) : [0xfd, 23] : "i8x16.replace_lane",
1015 I16x8ExtractLaneS(LaneArg) : [0xfd, 24] : "i16x8.extract_lane_s",
1016 I16x8ExtractLaneU(LaneArg) : [0xfd, 25] : "i16x8.extract_lane_u",
1017 I16x8ReplaceLane(LaneArg) : [0xfd, 26] : "i16x8.replace_lane",
1018 I32x4ExtractLane(LaneArg) : [0xfd, 27] : "i32x4.extract_lane",
1019 I32x4ReplaceLane(LaneArg) : [0xfd, 28] : "i32x4.replace_lane",
1020 I64x2ExtractLane(LaneArg) : [0xfd, 29] : "i64x2.extract_lane",
1021 I64x2ReplaceLane(LaneArg) : [0xfd, 30] : "i64x2.replace_lane",
1022 F32x4ExtractLane(LaneArg) : [0xfd, 31] : "f32x4.extract_lane",
1023 F32x4ReplaceLane(LaneArg) : [0xfd, 32] : "f32x4.replace_lane",
1024 F64x2ExtractLane(LaneArg) : [0xfd, 33] : "f64x2.extract_lane",
1025 F64x2ReplaceLane(LaneArg) : [0xfd, 34] : "f64x2.replace_lane",
1026
1027 I8x16Swizzle : [0xfd, 14] : "i8x16.swizzle",
1028 I8x16Splat : [0xfd, 15] : "i8x16.splat",
1029 I16x8Splat : [0xfd, 16] : "i16x8.splat",
1030 I32x4Splat : [0xfd, 17] : "i32x4.splat",
1031 I64x2Splat : [0xfd, 18] : "i64x2.splat",
1032 F32x4Splat : [0xfd, 19] : "f32x4.splat",
1033 F64x2Splat : [0xfd, 20] : "f64x2.splat",
1034
1035 I8x16Eq : [0xfd, 35] : "i8x16.eq",
1036 I8x16Ne : [0xfd, 36] : "i8x16.ne",
1037 I8x16LtS : [0xfd, 37] : "i8x16.lt_s",
1038 I8x16LtU : [0xfd, 38] : "i8x16.lt_u",
1039 I8x16GtS : [0xfd, 39] : "i8x16.gt_s",
1040 I8x16GtU : [0xfd, 40] : "i8x16.gt_u",
1041 I8x16LeS : [0xfd, 41] : "i8x16.le_s",
1042 I8x16LeU : [0xfd, 42] : "i8x16.le_u",
1043 I8x16GeS : [0xfd, 43] : "i8x16.ge_s",
1044 I8x16GeU : [0xfd, 44] : "i8x16.ge_u",
1045
1046 I16x8Eq : [0xfd, 45] : "i16x8.eq",
1047 I16x8Ne : [0xfd, 46] : "i16x8.ne",
1048 I16x8LtS : [0xfd, 47] : "i16x8.lt_s",
1049 I16x8LtU : [0xfd, 48] : "i16x8.lt_u",
1050 I16x8GtS : [0xfd, 49] : "i16x8.gt_s",
1051 I16x8GtU : [0xfd, 50] : "i16x8.gt_u",
1052 I16x8LeS : [0xfd, 51] : "i16x8.le_s",
1053 I16x8LeU : [0xfd, 52] : "i16x8.le_u",
1054 I16x8GeS : [0xfd, 53] : "i16x8.ge_s",
1055 I16x8GeU : [0xfd, 54] : "i16x8.ge_u",
1056
1057 I32x4Eq : [0xfd, 55] : "i32x4.eq",
1058 I32x4Ne : [0xfd, 56] : "i32x4.ne",
1059 I32x4LtS : [0xfd, 57] : "i32x4.lt_s",
1060 I32x4LtU : [0xfd, 58] : "i32x4.lt_u",
1061 I32x4GtS : [0xfd, 59] : "i32x4.gt_s",
1062 I32x4GtU : [0xfd, 60] : "i32x4.gt_u",
1063 I32x4LeS : [0xfd, 61] : "i32x4.le_s",
1064 I32x4LeU : [0xfd, 62] : "i32x4.le_u",
1065 I32x4GeS : [0xfd, 63] : "i32x4.ge_s",
1066 I32x4GeU : [0xfd, 64] : "i32x4.ge_u",
1067
1068 I64x2Eq : [0xfd, 214] : "i64x2.eq",
1069 I64x2Ne : [0xfd, 215] : "i64x2.ne",
1070 I64x2LtS : [0xfd, 216] : "i64x2.lt_s",
1071 I64x2GtS : [0xfd, 217] : "i64x2.gt_s",
1072 I64x2LeS : [0xfd, 218] : "i64x2.le_s",
1073 I64x2GeS : [0xfd, 219] : "i64x2.ge_s",
1074
1075 F32x4Eq : [0xfd, 65] : "f32x4.eq",
1076 F32x4Ne : [0xfd, 66] : "f32x4.ne",
1077 F32x4Lt : [0xfd, 67] : "f32x4.lt",
1078 F32x4Gt : [0xfd, 68] : "f32x4.gt",
1079 F32x4Le : [0xfd, 69] : "f32x4.le",
1080 F32x4Ge : [0xfd, 70] : "f32x4.ge",
1081
1082 F64x2Eq : [0xfd, 71] : "f64x2.eq",
1083 F64x2Ne : [0xfd, 72] : "f64x2.ne",
1084 F64x2Lt : [0xfd, 73] : "f64x2.lt",
1085 F64x2Gt : [0xfd, 74] : "f64x2.gt",
1086 F64x2Le : [0xfd, 75] : "f64x2.le",
1087 F64x2Ge : [0xfd, 76] : "f64x2.ge",
1088
1089 V128Not : [0xfd, 77] : "v128.not",
1090 V128And : [0xfd, 78] : "v128.and",
1091 V128Andnot : [0xfd, 79] : "v128.andnot",
1092 V128Or : [0xfd, 80] : "v128.or",
1093 V128Xor : [0xfd, 81] : "v128.xor",
1094 V128Bitselect : [0xfd, 82] : "v128.bitselect",
1095 V128AnyTrue : [0xfd, 83] : "v128.any_true",
1096
1097 I8x16Abs : [0xfd, 96] : "i8x16.abs",
1098 I8x16Neg : [0xfd, 97] : "i8x16.neg",
1099 I8x16Popcnt : [0xfd, 98] : "i8x16.popcnt",
1100 I8x16AllTrue : [0xfd, 99] : "i8x16.all_true",
1101 I8x16Bitmask : [0xfd, 100] : "i8x16.bitmask",
1102 I8x16NarrowI16x8S : [0xfd, 101] : "i8x16.narrow_i16x8_s",
1103 I8x16NarrowI16x8U : [0xfd, 102] : "i8x16.narrow_i16x8_u",
1104 I8x16Shl : [0xfd, 107] : "i8x16.shl",
1105 I8x16ShrS : [0xfd, 108] : "i8x16.shr_s",
1106 I8x16ShrU : [0xfd, 109] : "i8x16.shr_u",
1107 I8x16Add : [0xfd, 110] : "i8x16.add",
1108 I8x16AddSatS : [0xfd, 111] : "i8x16.add_sat_s",
1109 I8x16AddSatU : [0xfd, 112] : "i8x16.add_sat_u",
1110 I8x16Sub : [0xfd, 113] : "i8x16.sub",
1111 I8x16SubSatS : [0xfd, 114] : "i8x16.sub_sat_s",
1112 I8x16SubSatU : [0xfd, 115] : "i8x16.sub_sat_u",
1113 I8x16MinS : [0xfd, 118] : "i8x16.min_s",
1114 I8x16MinU : [0xfd, 119] : "i8x16.min_u",
1115 I8x16MaxS : [0xfd, 120] : "i8x16.max_s",
1116 I8x16MaxU : [0xfd, 121] : "i8x16.max_u",
1117 I8x16AvgrU : [0xfd, 123] : "i8x16.avgr_u",
1118
1119 I16x8ExtAddPairwiseI8x16S : [0xfd, 124] : "i16x8.extadd_pairwise_i8x16_s",
1120 I16x8ExtAddPairwiseI8x16U : [0xfd, 125] : "i16x8.extadd_pairwise_i8x16_u",
1121 I16x8Abs : [0xfd, 128] : "i16x8.abs",
1122 I16x8Neg : [0xfd, 129] : "i16x8.neg",
1123 I16x8Q15MulrSatS : [0xfd, 130] : "i16x8.q15mulr_sat_s",
1124 I16x8AllTrue : [0xfd, 131] : "i16x8.all_true",
1125 I16x8Bitmask : [0xfd, 132] : "i16x8.bitmask",
1126 I16x8NarrowI32x4S : [0xfd, 133] : "i16x8.narrow_i32x4_s",
1127 I16x8NarrowI32x4U : [0xfd, 134] : "i16x8.narrow_i32x4_u",
1128 I16x8ExtendLowI8x16S : [0xfd, 135] : "i16x8.extend_low_i8x16_s",
1129 I16x8ExtendHighI8x16S : [0xfd, 136] : "i16x8.extend_high_i8x16_s",
1130 I16x8ExtendLowI8x16U : [0xfd, 137] : "i16x8.extend_low_i8x16_u",
1131 I16x8ExtendHighI8x16u : [0xfd, 138] : "i16x8.extend_high_i8x16_u",
1132 I16x8Shl : [0xfd, 139] : "i16x8.shl",
1133 I16x8ShrS : [0xfd, 140] : "i16x8.shr_s",
1134 I16x8ShrU : [0xfd, 141] : "i16x8.shr_u",
1135 I16x8Add : [0xfd, 142] : "i16x8.add",
1136 I16x8AddSatS : [0xfd, 143] : "i16x8.add_sat_s",
1137 I16x8AddSatU : [0xfd, 144] : "i16x8.add_sat_u",
1138 I16x8Sub : [0xfd, 145] : "i16x8.sub",
1139 I16x8SubSatS : [0xfd, 146] : "i16x8.sub_sat_s",
1140 I16x8SubSatU : [0xfd, 147] : "i16x8.sub_sat_u",
1141 I16x8Mul : [0xfd, 149] : "i16x8.mul",
1142 I16x8MinS : [0xfd, 150] : "i16x8.min_s",
1143 I16x8MinU : [0xfd, 151] : "i16x8.min_u",
1144 I16x8MaxS : [0xfd, 152] : "i16x8.max_s",
1145 I16x8MaxU : [0xfd, 153] : "i16x8.max_u",
1146 I16x8AvgrU : [0xfd, 155] : "i16x8.avgr_u",
1147 I16x8ExtMulLowI8x16S : [0xfd, 156] : "i16x8.extmul_low_i8x16_s",
1148 I16x8ExtMulHighI8x16S : [0xfd, 157] : "i16x8.extmul_high_i8x16_s",
1149 I16x8ExtMulLowI8x16U : [0xfd, 158] : "i16x8.extmul_low_i8x16_u",
1150 I16x8ExtMulHighI8x16U : [0xfd, 159] : "i16x8.extmul_high_i8x16_u",
1151
1152 I32x4ExtAddPairwiseI16x8S : [0xfd, 126] : "i32x4.extadd_pairwise_i16x8_s",
1153 I32x4ExtAddPairwiseI16x8U : [0xfd, 127] : "i32x4.extadd_pairwise_i16x8_u",
1154 I32x4Abs : [0xfd, 160] : "i32x4.abs",
1155 I32x4Neg : [0xfd, 161] : "i32x4.neg",
1156 I32x4AllTrue : [0xfd, 163] : "i32x4.all_true",
1157 I32x4Bitmask : [0xfd, 164] : "i32x4.bitmask",
1158 I32x4ExtendLowI16x8S : [0xfd, 167] : "i32x4.extend_low_i16x8_s",
1159 I32x4ExtendHighI16x8S : [0xfd, 168] : "i32x4.extend_high_i16x8_s",
1160 I32x4ExtendLowI16x8U : [0xfd, 169] : "i32x4.extend_low_i16x8_u",
1161 I32x4ExtendHighI16x8U : [0xfd, 170] : "i32x4.extend_high_i16x8_u",
1162 I32x4Shl : [0xfd, 171] : "i32x4.shl",
1163 I32x4ShrS : [0xfd, 172] : "i32x4.shr_s",
1164 I32x4ShrU : [0xfd, 173] : "i32x4.shr_u",
1165 I32x4Add : [0xfd, 174] : "i32x4.add",
1166 I32x4Sub : [0xfd, 177] : "i32x4.sub",
1167 I32x4Mul : [0xfd, 181] : "i32x4.mul",
1168 I32x4MinS : [0xfd, 182] : "i32x4.min_s",
1169 I32x4MinU : [0xfd, 183] : "i32x4.min_u",
1170 I32x4MaxS : [0xfd, 184] : "i32x4.max_s",
1171 I32x4MaxU : [0xfd, 185] : "i32x4.max_u",
1172 I32x4DotI16x8S : [0xfd, 186] : "i32x4.dot_i16x8_s",
1173 I32x4ExtMulLowI16x8S : [0xfd, 188] : "i32x4.extmul_low_i16x8_s",
1174 I32x4ExtMulHighI16x8S : [0xfd, 189] : "i32x4.extmul_high_i16x8_s",
1175 I32x4ExtMulLowI16x8U : [0xfd, 190] : "i32x4.extmul_low_i16x8_u",
1176 I32x4ExtMulHighI16x8U : [0xfd, 191] : "i32x4.extmul_high_i16x8_u",
1177
1178 I64x2Abs : [0xfd, 192] : "i64x2.abs",
1179 I64x2Neg : [0xfd, 193] : "i64x2.neg",
1180 I64x2AllTrue : [0xfd, 195] : "i64x2.all_true",
1181 I64x2Bitmask : [0xfd, 196] : "i64x2.bitmask",
1182 I64x2ExtendLowI32x4S : [0xfd, 199] : "i64x2.extend_low_i32x4_s",
1183 I64x2ExtendHighI32x4S : [0xfd, 200] : "i64x2.extend_high_i32x4_s",
1184 I64x2ExtendLowI32x4U : [0xfd, 201] : "i64x2.extend_low_i32x4_u",
1185 I64x2ExtendHighI32x4U : [0xfd, 202] : "i64x2.extend_high_i32x4_u",
1186 I64x2Shl : [0xfd, 203] : "i64x2.shl",
1187 I64x2ShrS : [0xfd, 204] : "i64x2.shr_s",
1188 I64x2ShrU : [0xfd, 205] : "i64x2.shr_u",
1189 I64x2Add : [0xfd, 206] : "i64x2.add",
1190 I64x2Sub : [0xfd, 209] : "i64x2.sub",
1191 I64x2Mul : [0xfd, 213] : "i64x2.mul",
1192 I64x2ExtMulLowI32x4S : [0xfd, 220] : "i64x2.extmul_low_i32x4_s",
1193 I64x2ExtMulHighI32x4S : [0xfd, 221] : "i64x2.extmul_high_i32x4_s",
1194 I64x2ExtMulLowI32x4U : [0xfd, 222] : "i64x2.extmul_low_i32x4_u",
1195 I64x2ExtMulHighI32x4U : [0xfd, 223] : "i64x2.extmul_high_i32x4_u",
1196
1197 F32x4Ceil : [0xfd, 103] : "f32x4.ceil",
1198 F32x4Floor : [0xfd, 104] : "f32x4.floor",
1199 F32x4Trunc : [0xfd, 105] : "f32x4.trunc",
1200 F32x4Nearest : [0xfd, 106] : "f32x4.nearest",
1201 F32x4Abs : [0xfd, 224] : "f32x4.abs",
1202 F32x4Neg : [0xfd, 225] : "f32x4.neg",
1203 F32x4Sqrt : [0xfd, 227] : "f32x4.sqrt",
1204 F32x4Add : [0xfd, 228] : "f32x4.add",
1205 F32x4Sub : [0xfd, 229] : "f32x4.sub",
1206 F32x4Mul : [0xfd, 230] : "f32x4.mul",
1207 F32x4Div : [0xfd, 231] : "f32x4.div",
1208 F32x4Min : [0xfd, 232] : "f32x4.min",
1209 F32x4Max : [0xfd, 233] : "f32x4.max",
1210 F32x4PMin : [0xfd, 234] : "f32x4.pmin",
1211 F32x4PMax : [0xfd, 235] : "f32x4.pmax",
1212
1213 F64x2Ceil : [0xfd, 116] : "f64x2.ceil",
1214 F64x2Floor : [0xfd, 117] : "f64x2.floor",
1215 F64x2Trunc : [0xfd, 122] : "f64x2.trunc",
1216 F64x2Nearest : [0xfd, 148] : "f64x2.nearest",
1217 F64x2Abs : [0xfd, 236] : "f64x2.abs",
1218 F64x2Neg : [0xfd, 237] : "f64x2.neg",
1219 F64x2Sqrt : [0xfd, 239] : "f64x2.sqrt",
1220 F64x2Add : [0xfd, 240] : "f64x2.add",
1221 F64x2Sub : [0xfd, 241] : "f64x2.sub",
1222 F64x2Mul : [0xfd, 242] : "f64x2.mul",
1223 F64x2Div : [0xfd, 243] : "f64x2.div",
1224 F64x2Min : [0xfd, 244] : "f64x2.min",
1225 F64x2Max : [0xfd, 245] : "f64x2.max",
1226 F64x2PMin : [0xfd, 246] : "f64x2.pmin",
1227 F64x2PMax : [0xfd, 247] : "f64x2.pmax",
1228
1229 I32x4TruncSatF32x4S : [0xfd, 248] : "i32x4.trunc_sat_f32x4_s",
1230 I32x4TruncSatF32x4U : [0xfd, 249] : "i32x4.trunc_sat_f32x4_u",
1231 F32x4ConvertI32x4S : [0xfd, 250] : "f32x4.convert_i32x4_s",
1232 F32x4ConvertI32x4U : [0xfd, 251] : "f32x4.convert_i32x4_u",
1233 I32x4TruncSatF64x2SZero : [0xfd, 252] : "i32x4.trunc_sat_f64x2_s_zero",
1234 I32x4TruncSatF64x2UZero : [0xfd, 253] : "i32x4.trunc_sat_f64x2_u_zero",
1235 F64x2ConvertLowI32x4S : [0xfd, 254] : "f64x2.convert_low_i32x4_s",
1236 F64x2ConvertLowI32x4U : [0xfd, 255] : "f64x2.convert_low_i32x4_u",
1237 F32x4DemoteF64x2Zero : [0xfd, 94] : "f32x4.demote_f64x2_zero",
1238 F64x2PromoteLowF32x4 : [0xfd, 95] : "f64x2.promote_low_f32x4",
1239
1240 ThrowRef : [0x0a] : "throw_ref",
1242 TryTable(TryTable<'a>) : [0x1f] : "try_table",
1243 Throw(Index<'a>) : [0x08] : "throw",
1244
1245 Try(Box<BlockType<'a>>) : [0x06] : "try",
1247 Catch(Index<'a>) : [0x07] : "catch",
1248 Rethrow(Index<'a>) : [0x09] : "rethrow",
1249 Delegate(Index<'a>) : [0x18] : "delegate",
1250 CatchAll : [0x19] : "catch_all",
1251
1252 I8x16RelaxedSwizzle : [0xfd, 0x100]: "i8x16.relaxed_swizzle",
1254 I32x4RelaxedTruncF32x4S : [0xfd, 0x101]: "i32x4.relaxed_trunc_f32x4_s",
1255 I32x4RelaxedTruncF32x4U : [0xfd, 0x102]: "i32x4.relaxed_trunc_f32x4_u",
1256 I32x4RelaxedTruncF64x2SZero : [0xfd, 0x103]: "i32x4.relaxed_trunc_f64x2_s_zero",
1257 I32x4RelaxedTruncF64x2UZero : [0xfd, 0x104]: "i32x4.relaxed_trunc_f64x2_u_zero",
1258 F32x4RelaxedMadd : [0xfd, 0x105]: "f32x4.relaxed_madd",
1259 F32x4RelaxedNmadd : [0xfd, 0x106]: "f32x4.relaxed_nmadd",
1260 F64x2RelaxedMadd : [0xfd, 0x107]: "f64x2.relaxed_madd",
1261 F64x2RelaxedNmadd : [0xfd, 0x108]: "f64x2.relaxed_nmadd",
1262 I8x16RelaxedLaneselect : [0xfd, 0x109]: "i8x16.relaxed_laneselect",
1263 I16x8RelaxedLaneselect : [0xfd, 0x10A]: "i16x8.relaxed_laneselect",
1264 I32x4RelaxedLaneselect : [0xfd, 0x10B]: "i32x4.relaxed_laneselect",
1265 I64x2RelaxedLaneselect : [0xfd, 0x10C]: "i64x2.relaxed_laneselect",
1266 F32x4RelaxedMin : [0xfd, 0x10D]: "f32x4.relaxed_min",
1267 F32x4RelaxedMax : [0xfd, 0x10E]: "f32x4.relaxed_max",
1268 F64x2RelaxedMin : [0xfd, 0x10F]: "f64x2.relaxed_min",
1269 F64x2RelaxedMax : [0xfd, 0x110]: "f64x2.relaxed_max",
1270 I16x8RelaxedQ15mulrS: [0xfd, 0x111]: "i16x8.relaxed_q15mulr_s",
1271 I16x8RelaxedDotI8x16I7x16S: [0xfd, 0x112]: "i16x8.relaxed_dot_i8x16_i7x16_s",
1272 I32x4RelaxedDotI8x16I7x16AddS: [0xfd, 0x113]: "i32x4.relaxed_dot_i8x16_i7x16_add_s",
1273
1274 ContNew(Index<'a>) : [0xe0] : "cont.new",
1276 ContBind(ContBind<'a>) : [0xe1] : "cont.bind",
1277 Suspend(Index<'a>) : [0xe2] : "suspend",
1278 Resume(Resume<'a>) : [0xe3] : "resume",
1279 ResumeThrow(ResumeThrow<'a>) : [0xe4] : "resume_throw",
1280 ResumeThrowRef(ResumeThrowRef<'a>) : [0xe5] : "resume_throw_ref",
1281 Switch(Switch<'a>) : [0xe6] : "switch",
1282
1283 I64Add128 : [0xfc, 19] : "i64.add128",
1285 I64Sub128 : [0xfc, 20] : "i64.sub128",
1286 I64MulWideS : [0xfc, 21] : "i64.mul_wide_s",
1287 I64MulWideU : [0xfc, 22] : "i64.mul_wide_u",
1288
1289 StructNewDesc(Index<'a>) : [0xfb, 32] : "struct.new_desc",
1291 StructNewDefaultDesc(Index<'a>) : [0xfb, 33] : "struct.new_default_desc",
1292 RefGetDesc(Index<'a>): [0xfb, 34] : "ref.get_desc",
1293 RefCastDescEq(RefCastDescEq<'a>) : [] : "ref.cast_desc_eq",
1294 BrOnCastDescEq(Box<BrOnCastDescEq<'a>>) : [] : "br_on_cast_desc_eq",
1295 BrOnCastDescEqFail(Box<BrOnCastDescEqFail<'a>>) : [] : "br_on_cast_desc_eq_fail",
1296 }
1297}
1298
1299#[test]
1304fn assert_instruction_not_too_large() {
1305 let size = std::mem::size_of::<Instruction<'_>>();
1306 let pointer = std::mem::size_of::<u64>();
1307 assert!(size <= pointer * 11);
1308}
1309
1310impl<'a> Instruction<'a> {
1311 pub(crate) fn needs_data_count(&self) -> bool {
1312 match self {
1313 Instruction::MemoryInit(_)
1314 | Instruction::DataDrop(_)
1315 | Instruction::ArrayNewData(_)
1316 | Instruction::ArrayInitData(_) => true,
1317 _ => false,
1318 }
1319 }
1320}
1321
1322#[derive(Debug, Clone)]
1327#[allow(missing_docs)]
1328pub struct BlockType<'a> {
1329 pub label: Option<Id<'a>>,
1330 pub label_name: Option<NameAnnotation<'a>>,
1331 pub ty: TypeUse<'a, FunctionType<'a>>,
1332}
1333
1334impl<'a> Parse<'a> for BlockType<'a> {
1335 fn parse(parser: Parser<'a>) -> Result<Self> {
1336 Ok(BlockType {
1337 label: parser.parse()?,
1338 label_name: parser.parse()?,
1339 ty: parser
1340 .parse::<TypeUse<'a, FunctionTypeNoNames<'a>>>()?
1341 .into(),
1342 })
1343 }
1344}
1345
1346#[derive(Debug, Clone)]
1348#[allow(missing_docs)]
1349pub struct ContBind<'a> {
1350 pub argument_index: Index<'a>,
1351 pub result_index: Index<'a>,
1352}
1353
1354impl<'a> Parse<'a> for ContBind<'a> {
1355 fn parse(parser: Parser<'a>) -> Result<Self> {
1356 Ok(ContBind {
1357 argument_index: parser.parse()?,
1358 result_index: parser.parse()?,
1359 })
1360 }
1361}
1362
1363#[derive(Debug, Clone)]
1365#[allow(missing_docs)]
1366pub struct Resume<'a> {
1367 pub type_index: Index<'a>,
1368 pub table: ResumeTable<'a>,
1369}
1370
1371impl<'a> Parse<'a> for Resume<'a> {
1372 fn parse(parser: Parser<'a>) -> Result<Self> {
1373 Ok(Resume {
1374 type_index: parser.parse()?,
1375 table: parser.parse()?,
1376 })
1377 }
1378}
1379
1380#[derive(Debug, Clone)]
1382#[allow(missing_docs)]
1383pub struct ResumeThrow<'a> {
1384 pub type_index: Index<'a>,
1385 pub tag_index: Index<'a>,
1386 pub table: ResumeTable<'a>,
1387}
1388
1389impl<'a> Parse<'a> for ResumeThrow<'a> {
1390 fn parse(parser: Parser<'a>) -> Result<Self> {
1391 Ok(ResumeThrow {
1392 type_index: parser.parse()?,
1393 tag_index: parser.parse()?,
1394 table: parser.parse()?,
1395 })
1396 }
1397}
1398
1399#[derive(Debug, Clone)]
1401#[allow(missing_docs)]
1402pub struct ResumeThrowRef<'a> {
1403 pub type_index: Index<'a>,
1404 pub table: ResumeTable<'a>,
1405}
1406
1407impl<'a> Parse<'a> for ResumeThrowRef<'a> {
1408 fn parse(parser: Parser<'a>) -> Result<Self> {
1409 Ok(ResumeThrowRef {
1410 type_index: parser.parse()?,
1411 table: parser.parse()?,
1412 })
1413 }
1414}
1415
1416#[derive(Debug, Clone)]
1418#[allow(missing_docs)]
1419pub struct Switch<'a> {
1420 pub type_index: Index<'a>,
1421 pub tag_index: Index<'a>,
1422}
1423
1424impl<'a> Parse<'a> for Switch<'a> {
1425 fn parse(parser: Parser<'a>) -> Result<Self> {
1426 Ok(Switch {
1427 type_index: parser.parse()?,
1428 tag_index: parser.parse()?,
1429 })
1430 }
1431}
1432
1433#[derive(Debug, Clone)]
1435#[allow(missing_docs)]
1436pub struct ResumeTable<'a> {
1437 pub handlers: Vec<Handle<'a>>,
1438}
1439
1440#[derive(Debug, Clone)]
1442#[allow(missing_docs)]
1443pub enum Handle<'a> {
1444 OnLabel { tag: Index<'a>, label: Index<'a> },
1445 OnSwitch { tag: Index<'a> },
1446}
1447
1448impl<'a> Parse<'a> for ResumeTable<'a> {
1449 fn parse(parser: Parser<'a>) -> Result<Self> {
1450 let mut handlers = Vec::new();
1451 while parser.peek::<LParen>()? && parser.peek2::<kw::on>()? {
1452 handlers.push(parser.parens(|p| {
1453 p.parse::<kw::on>()?;
1454 let tag: Index<'a> = p.parse()?;
1455 if p.peek::<kw::switch>()? {
1456 p.parse::<kw::switch>()?;
1457 Ok(Handle::OnSwitch { tag })
1458 } else {
1459 Ok(Handle::OnLabel {
1460 tag,
1461 label: p.parse()?,
1462 })
1463 }
1464 })?);
1465 }
1466 Ok(ResumeTable { handlers })
1467 }
1468}
1469
1470#[derive(Debug, Clone)]
1471#[allow(missing_docs)]
1472pub struct TryTable<'a> {
1473 pub block: Box<BlockType<'a>>,
1474 pub catches: Vec<TryTableCatch<'a>>,
1475}
1476
1477impl<'a> Parse<'a> for TryTable<'a> {
1478 fn parse(parser: Parser<'a>) -> Result<Self> {
1479 let block = parser.parse()?;
1480
1481 let mut catches = Vec::new();
1482 while parser.peek::<LParen>()?
1483 && (parser.peek2::<kw::catch>()?
1484 || parser.peek2::<kw::catch_ref>()?
1485 || parser.peek2::<kw::catch_all>()?
1486 || parser.peek2::<kw::catch_all_ref>()?)
1487 {
1488 catches.push(parser.parens(|p| {
1489 let kind = if parser.peek::<kw::catch_ref>()? {
1490 p.parse::<kw::catch_ref>()?;
1491 TryTableCatchKind::CatchRef(p.parse()?)
1492 } else if parser.peek::<kw::catch>()? {
1493 p.parse::<kw::catch>()?;
1494 TryTableCatchKind::Catch(p.parse()?)
1495 } else if parser.peek::<kw::catch_all>()? {
1496 p.parse::<kw::catch_all>()?;
1497 TryTableCatchKind::CatchAll
1498 } else {
1499 p.parse::<kw::catch_all_ref>()?;
1500 TryTableCatchKind::CatchAllRef
1501 };
1502
1503 Ok(TryTableCatch {
1504 kind,
1505 label: p.parse()?,
1506 })
1507 })?);
1508 }
1509
1510 Ok(TryTable { block, catches })
1511 }
1512}
1513
1514#[derive(Debug, Clone)]
1515#[allow(missing_docs)]
1516pub enum TryTableCatchKind<'a> {
1517 Catch(Index<'a>),
1519 CatchRef(Index<'a>),
1521 CatchAll,
1523 CatchAllRef,
1525}
1526
1527impl<'a> TryTableCatchKind<'a> {
1528 #[allow(missing_docs)]
1529 pub fn tag_index_mut(&mut self) -> Option<&mut Index<'a>> {
1530 match self {
1531 TryTableCatchKind::Catch(tag) | TryTableCatchKind::CatchRef(tag) => Some(tag),
1532 TryTableCatchKind::CatchAll | TryTableCatchKind::CatchAllRef => None,
1533 }
1534 }
1535}
1536
1537#[derive(Debug, Clone)]
1538#[allow(missing_docs)]
1539pub struct TryTableCatch<'a> {
1540 pub kind: TryTableCatchKind<'a>,
1541 pub label: Index<'a>,
1542}
1543
1544#[allow(missing_docs)]
1546#[derive(Debug, Clone)]
1547pub struct BrTableIndices<'a> {
1548 pub labels: Vec<Index<'a>>,
1549 pub default: Index<'a>,
1550}
1551
1552impl<'a> Parse<'a> for BrTableIndices<'a> {
1553 fn parse(parser: Parser<'a>) -> Result<Self> {
1554 let mut labels = vec![parser.parse()?];
1555 while parser.peek::<Index>()? {
1556 labels.push(parser.parse()?);
1557 }
1558 let default = labels.pop().unwrap();
1559 Ok(BrTableIndices { labels, default })
1560 }
1561}
1562
1563#[derive(Debug, Clone)]
1565pub struct LaneArg {
1566 pub lane: u8,
1568}
1569
1570impl<'a> Parse<'a> for LaneArg {
1571 fn parse(parser: Parser<'a>) -> Result<Self> {
1572 let lane = parser.step(|c| {
1573 if let Some((i, rest)) = c.integer()? {
1574 if i.sign() == None {
1575 let (src, radix) = i.val();
1576 let val = u8::from_str_radix(src, radix)
1577 .map_err(|_| c.error("malformed lane index"))?;
1578 Ok((val, rest))
1579 } else {
1580 Err(c.error("unexpected token"))
1581 }
1582 } else {
1583 Err(c.error("expected a lane index"))
1584 }
1585 })?;
1586 Ok(LaneArg { lane })
1587 }
1588}
1589
1590#[derive(Debug, Clone)]
1593pub struct MemArg<'a> {
1594 pub align: u64,
1599 pub offset: u64,
1601 pub memory: Index<'a>,
1603}
1604
1605impl<'a> MemArg<'a> {
1606 fn parse(parser: Parser<'a>, default_align: u64) -> Result<Self> {
1607 fn parse_field(name: &str, parser: Parser<'_>) -> Result<Option<u64>> {
1608 parser.step(|c| {
1609 let (kw, rest) = match c.keyword()? {
1610 Some(p) => p,
1611 None => return Ok((None, c)),
1612 };
1613 if !kw.starts_with(name) {
1614 return Ok((None, c));
1615 }
1616 let kw = &kw[name.len()..];
1617 if !kw.starts_with('=') {
1618 return Ok((None, c));
1619 }
1620 let num = &kw[1..];
1621 let lexer = Lexer::new(num);
1622 let mut pos = 0;
1623 if let Ok(Some(
1624 token @ Token {
1625 kind: TokenKind::Integer(integer_kind),
1626 ..
1627 },
1628 )) = lexer.parse(&mut pos)
1629 {
1630 let int = token.integer(lexer.input(), integer_kind);
1631 let (s, base) = int.val();
1632 let value = u64::from_str_radix(s, base);
1633 return match value {
1634 Ok(n) => Ok((Some(n), rest)),
1635 Err(_) => Err(c.error("u64 constant out of range")),
1636 };
1637 }
1638 Err(c.error("expected u64 integer constant"))
1639 })
1640 }
1641
1642 let memory = parser
1643 .parse::<Option<_>>()?
1644 .unwrap_or_else(|| Index::Num(0, parser.prev_span()));
1645 let offset = parse_field("offset", parser)?.unwrap_or(0);
1646 let align = match parse_field("align", parser)? {
1647 Some(n) if !n.is_power_of_two() => {
1648 return Err(parser.error("alignment must be a power of two"));
1649 }
1650 n => n.unwrap_or(default_align),
1651 };
1652
1653 Ok(MemArg {
1654 offset,
1655 align,
1656 memory,
1657 })
1658 }
1659}
1660
1661#[derive(Debug, Clone)]
1663pub struct LoadOrStoreLane<'a> {
1664 pub memarg: MemArg<'a>,
1666 pub lane: LaneArg,
1668}
1669
1670impl<'a> LoadOrStoreLane<'a> {
1671 fn parse(parser: Parser<'a>, default_align: u64) -> Result<Self> {
1672 let has_memarg = parser.step(|c| match c.integer()? {
1676 Some((_, after_int)) => {
1677 if after_int.integer()?.is_some() {
1680 return Ok((true, c));
1681 }
1682
1683 if let Some((kw, _)) = after_int.keyword()? {
1686 if kw.starts_with("offset=") || kw.starts_with("align=") {
1687 return Ok((true, c));
1688 }
1689 }
1690
1691 Ok((false, c))
1694 }
1695
1696 None => Ok((true, c)),
1699 })?;
1700 Ok(LoadOrStoreLane {
1701 memarg: if has_memarg {
1702 MemArg::parse(parser, default_align)?
1703 } else {
1704 MemArg {
1705 align: default_align,
1706 offset: 0,
1707 memory: Index::Num(0, parser.prev_span()),
1708 }
1709 },
1710 lane: LaneArg::parse(parser)?,
1711 })
1712 }
1713}
1714
1715#[derive(Debug, Clone)]
1717pub struct CallIndirect<'a> {
1718 pub table: Index<'a>,
1720 pub ty: TypeUse<'a, FunctionType<'a>>,
1722}
1723
1724impl<'a> Parse<'a> for CallIndirect<'a> {
1725 fn parse(parser: Parser<'a>) -> Result<Self> {
1726 let prev_span = parser.prev_span();
1727 let table: Option<_> = parser.parse()?;
1728 let ty = parser.parse::<TypeUse<'a, FunctionTypeNoNames<'a>>>()?;
1729 Ok(CallIndirect {
1730 table: table.unwrap_or(Index::Num(0, prev_span)),
1731 ty: ty.into(),
1732 })
1733 }
1734}
1735
1736#[derive(Debug, Clone)]
1738pub struct TableInit<'a> {
1739 pub table: Index<'a>,
1741 pub elem: Index<'a>,
1743}
1744
1745impl<'a> Parse<'a> for TableInit<'a> {
1746 fn parse(parser: Parser<'a>) -> Result<Self> {
1747 let prev_span = parser.prev_span();
1748 let (elem, table) = if parser.peek2::<Index>()? {
1749 let table = parser.parse()?;
1750 (parser.parse()?, table)
1751 } else {
1752 (parser.parse()?, Index::Num(0, prev_span))
1753 };
1754 Ok(TableInit { table, elem })
1755 }
1756}
1757
1758#[derive(Debug, Clone)]
1760pub struct TableCopy<'a> {
1761 pub dst: Index<'a>,
1763 pub src: Index<'a>,
1765}
1766
1767impl<'a> Parse<'a> for TableCopy<'a> {
1768 fn parse(parser: Parser<'a>) -> Result<Self> {
1769 let (dst, src) = match parser.parse::<Option<_>>()? {
1770 Some(dst) => (dst, parser.parse()?),
1771 None => (
1772 Index::Num(0, parser.prev_span()),
1773 Index::Num(0, parser.prev_span()),
1774 ),
1775 };
1776 Ok(TableCopy { dst, src })
1777 }
1778}
1779
1780#[derive(Debug, Clone)]
1782pub struct TableArg<'a> {
1783 pub dst: Index<'a>,
1785}
1786
1787impl<'a> Parse<'a> for TableArg<'a> {
1790 fn parse(parser: Parser<'a>) -> Result<Self> {
1791 let dst = if let Some(dst) = parser.parse()? {
1792 dst
1793 } else {
1794 Index::Num(0, parser.prev_span())
1795 };
1796 Ok(TableArg { dst })
1797 }
1798}
1799
1800#[derive(Debug, Clone)]
1802pub struct MemoryArg<'a> {
1803 pub mem: Index<'a>,
1805}
1806
1807impl<'a> Parse<'a> for MemoryArg<'a> {
1808 fn parse(parser: Parser<'a>) -> Result<Self> {
1809 let mem = if let Some(mem) = parser.parse()? {
1810 mem
1811 } else {
1812 Index::Num(0, parser.prev_span())
1813 };
1814 Ok(MemoryArg { mem })
1815 }
1816}
1817
1818#[derive(Debug, Clone)]
1820pub struct MemoryInit<'a> {
1821 pub data: Index<'a>,
1823 pub mem: Index<'a>,
1825}
1826
1827impl<'a> Parse<'a> for MemoryInit<'a> {
1828 fn parse(parser: Parser<'a>) -> Result<Self> {
1829 let prev_span = parser.prev_span();
1830 let (data, mem) = if parser.peek2::<Index>()? {
1831 let memory = parser.parse()?;
1832 (parser.parse()?, memory)
1833 } else {
1834 (parser.parse()?, Index::Num(0, prev_span))
1835 };
1836 Ok(MemoryInit { data, mem })
1837 }
1838}
1839
1840#[derive(Debug, Clone)]
1842pub struct MemoryCopy<'a> {
1843 pub src: Index<'a>,
1845 pub dst: Index<'a>,
1847}
1848
1849impl<'a> Parse<'a> for MemoryCopy<'a> {
1850 fn parse(parser: Parser<'a>) -> Result<Self> {
1851 let (src, dst) = match parser.parse()? {
1852 Some(dst) => (parser.parse()?, dst),
1853 None => (
1854 Index::Num(0, parser.prev_span()),
1855 Index::Num(0, parser.prev_span()),
1856 ),
1857 };
1858 Ok(MemoryCopy { src, dst })
1859 }
1860}
1861
1862#[derive(Debug, Clone)]
1864pub struct StructAccess<'a> {
1865 pub r#struct: Index<'a>,
1867 pub field: Index<'a>,
1869}
1870
1871impl<'a> Parse<'a> for StructAccess<'a> {
1872 fn parse(parser: Parser<'a>) -> Result<Self> {
1873 Ok(StructAccess {
1874 r#struct: parser.parse()?,
1875 field: parser.parse()?,
1876 })
1877 }
1878}
1879
1880#[derive(Debug, Clone)]
1882pub struct ArrayFill<'a> {
1883 pub array: Index<'a>,
1885}
1886
1887impl<'a> Parse<'a> for ArrayFill<'a> {
1888 fn parse(parser: Parser<'a>) -> Result<Self> {
1889 Ok(ArrayFill {
1890 array: parser.parse()?,
1891 })
1892 }
1893}
1894
1895#[derive(Debug, Clone)]
1897pub struct ArrayCopy<'a> {
1898 pub dest_array: Index<'a>,
1900 pub src_array: Index<'a>,
1902}
1903
1904impl<'a> Parse<'a> for ArrayCopy<'a> {
1905 fn parse(parser: Parser<'a>) -> Result<Self> {
1906 Ok(ArrayCopy {
1907 dest_array: parser.parse()?,
1908 src_array: parser.parse()?,
1909 })
1910 }
1911}
1912
1913#[derive(Debug, Clone)]
1915pub struct ArrayInit<'a> {
1916 pub array: Index<'a>,
1918 pub segment: Index<'a>,
1920}
1921
1922impl<'a> Parse<'a> for ArrayInit<'a> {
1923 fn parse(parser: Parser<'a>) -> Result<Self> {
1924 Ok(ArrayInit {
1925 array: parser.parse()?,
1926 segment: parser.parse()?,
1927 })
1928 }
1929}
1930
1931#[derive(Debug, Clone)]
1933pub struct ArrayNewFixed<'a> {
1934 pub array: Index<'a>,
1936 pub length: u32,
1938}
1939
1940impl<'a> Parse<'a> for ArrayNewFixed<'a> {
1941 fn parse(parser: Parser<'a>) -> Result<Self> {
1942 Ok(ArrayNewFixed {
1943 array: parser.parse()?,
1944 length: parser.parse()?,
1945 })
1946 }
1947}
1948
1949#[derive(Debug, Clone)]
1951pub struct ArrayNewData<'a> {
1952 pub array: Index<'a>,
1954 pub data_idx: Index<'a>,
1956}
1957
1958impl<'a> Parse<'a> for ArrayNewData<'a> {
1959 fn parse(parser: Parser<'a>) -> Result<Self> {
1960 Ok(ArrayNewData {
1961 array: parser.parse()?,
1962 data_idx: parser.parse()?,
1963 })
1964 }
1965}
1966
1967#[derive(Debug, Clone)]
1969pub struct ArrayNewElem<'a> {
1970 pub array: Index<'a>,
1972 pub elem_idx: Index<'a>,
1974}
1975
1976impl<'a> Parse<'a> for ArrayNewElem<'a> {
1977 fn parse(parser: Parser<'a>) -> Result<Self> {
1978 Ok(ArrayNewElem {
1979 array: parser.parse()?,
1980 elem_idx: parser.parse()?,
1981 })
1982 }
1983}
1984
1985#[derive(Debug, Clone)]
1987pub struct RefCast<'a> {
1988 pub r#type: RefType<'a>,
1990}
1991
1992impl<'a> Parse<'a> for RefCast<'a> {
1993 fn parse(parser: Parser<'a>) -> Result<Self> {
1994 Ok(RefCast {
1995 r#type: parser.parse()?,
1996 })
1997 }
1998}
1999
2000#[derive(Debug, Clone)]
2002pub struct RefTest<'a> {
2003 pub r#type: RefType<'a>,
2005}
2006
2007impl<'a> Parse<'a> for RefTest<'a> {
2008 fn parse(parser: Parser<'a>) -> Result<Self> {
2009 Ok(RefTest {
2010 r#type: parser.parse()?,
2011 })
2012 }
2013}
2014
2015#[derive(Debug, Clone)]
2017pub struct BrOnCast<'a> {
2018 pub label: Index<'a>,
2020 pub from_type: RefType<'a>,
2022 pub to_type: RefType<'a>,
2024}
2025
2026impl<'a> Parse<'a> for BrOnCast<'a> {
2027 fn parse(parser: Parser<'a>) -> Result<Self> {
2028 Ok(BrOnCast {
2029 label: parser.parse()?,
2030 from_type: parser.parse()?,
2031 to_type: parser.parse()?,
2032 })
2033 }
2034}
2035
2036#[derive(Debug, Clone)]
2038pub struct BrOnCastFail<'a> {
2039 pub label: Index<'a>,
2041 pub from_type: RefType<'a>,
2043 pub to_type: RefType<'a>,
2045}
2046
2047impl<'a> Parse<'a> for BrOnCastFail<'a> {
2048 fn parse(parser: Parser<'a>) -> Result<Self> {
2049 Ok(BrOnCastFail {
2050 label: parser.parse()?,
2051 from_type: parser.parse()?,
2052 to_type: parser.parse()?,
2053 })
2054 }
2055}
2056
2057#[derive(Debug, Clone)]
2059pub struct RefCastDescEq<'a> {
2060 pub r#type: RefType<'a>,
2062}
2063
2064impl<'a> Parse<'a> for RefCastDescEq<'a> {
2065 fn parse(parser: Parser<'a>) -> Result<Self> {
2066 Ok(RefCastDescEq {
2067 r#type: parser.parse()?,
2068 })
2069 }
2070}
2071
2072#[derive(Debug, Clone)]
2074pub struct BrOnCastDescEq<'a> {
2075 pub label: Index<'a>,
2077 pub from_type: RefType<'a>,
2079 pub to_type: RefType<'a>,
2081}
2082
2083impl<'a> Parse<'a> for BrOnCastDescEq<'a> {
2084 fn parse(parser: Parser<'a>) -> Result<Self> {
2085 Ok(BrOnCastDescEq {
2086 label: parser.parse()?,
2087 from_type: parser.parse()?,
2088 to_type: parser.parse()?,
2089 })
2090 }
2091}
2092
2093#[derive(Debug, Clone)]
2095pub struct BrOnCastDescEqFail<'a> {
2096 pub label: Index<'a>,
2098 pub from_type: RefType<'a>,
2100 pub to_type: RefType<'a>,
2102}
2103
2104impl<'a> Parse<'a> for BrOnCastDescEqFail<'a> {
2105 fn parse(parser: Parser<'a>) -> Result<Self> {
2106 Ok(BrOnCastDescEqFail {
2107 label: parser.parse()?,
2108 from_type: parser.parse()?,
2109 to_type: parser.parse()?,
2110 })
2111 }
2112}
2113
2114#[derive(Clone, Debug)]
2122pub enum Ordering {
2123 AcqRel,
2126 SeqCst,
2130}
2131
2132impl<'a> Parse<'a> for Ordering {
2133 fn parse(parser: Parser<'a>) -> Result<Self> {
2134 if parser.peek::<kw::seq_cst>()? {
2135 parser.parse::<kw::seq_cst>()?;
2136 Ok(Ordering::SeqCst)
2137 } else if parser.peek::<kw::acq_rel>()? {
2138 parser.parse::<kw::acq_rel>()?;
2139 Ok(Ordering::AcqRel)
2140 } else {
2141 Err(parser.error("expected a memory ordering: `seq_cst` or `acq_rel`"))
2142 }
2143 }
2144}
2145
2146#[derive(Clone, Debug)]
2152pub struct Ordered<T> {
2153 pub ordering: Ordering,
2155 pub inner: T,
2157}
2158
2159impl<'a, T> Parse<'a> for Ordered<T>
2160where
2161 T: Parse<'a>,
2162{
2163 fn parse(parser: Parser<'a>) -> Result<Self> {
2164 let ordering = parser.parse()?;
2165 let inner = parser.parse()?;
2166 Ok(Ordered { ordering, inner })
2167 }
2168}
2169
2170#[derive(Clone, Debug)]
2172#[allow(missing_docs)]
2173pub enum V128Const {
2174 I8x16([i8; 16]),
2175 I16x8([i16; 8]),
2176 I32x4([i32; 4]),
2177 I64x2([i64; 2]),
2178 F32x4([F32; 4]),
2179 F64x2([F64; 2]),
2180}
2181
2182impl V128Const {
2183 #[rustfmt::skip]
2189 pub fn to_le_bytes(&self) -> [u8; 16] {
2190 match self {
2191 V128Const::I8x16(arr) => [
2192 arr[0] as u8,
2193 arr[1] as u8,
2194 arr[2] as u8,
2195 arr[3] as u8,
2196 arr[4] as u8,
2197 arr[5] as u8,
2198 arr[6] as u8,
2199 arr[7] as u8,
2200 arr[8] as u8,
2201 arr[9] as u8,
2202 arr[10] as u8,
2203 arr[11] as u8,
2204 arr[12] as u8,
2205 arr[13] as u8,
2206 arr[14] as u8,
2207 arr[15] as u8,
2208 ],
2209 V128Const::I16x8(arr) => {
2210 let a1 = arr[0].to_le_bytes();
2211 let a2 = arr[1].to_le_bytes();
2212 let a3 = arr[2].to_le_bytes();
2213 let a4 = arr[3].to_le_bytes();
2214 let a5 = arr[4].to_le_bytes();
2215 let a6 = arr[5].to_le_bytes();
2216 let a7 = arr[6].to_le_bytes();
2217 let a8 = arr[7].to_le_bytes();
2218 [
2219 a1[0], a1[1],
2220 a2[0], a2[1],
2221 a3[0], a3[1],
2222 a4[0], a4[1],
2223 a5[0], a5[1],
2224 a6[0], a6[1],
2225 a7[0], a7[1],
2226 a8[0], a8[1],
2227 ]
2228 }
2229 V128Const::I32x4(arr) => {
2230 let a1 = arr[0].to_le_bytes();
2231 let a2 = arr[1].to_le_bytes();
2232 let a3 = arr[2].to_le_bytes();
2233 let a4 = arr[3].to_le_bytes();
2234 [
2235 a1[0], a1[1], a1[2], a1[3],
2236 a2[0], a2[1], a2[2], a2[3],
2237 a3[0], a3[1], a3[2], a3[3],
2238 a4[0], a4[1], a4[2], a4[3],
2239 ]
2240 }
2241 V128Const::I64x2(arr) => {
2242 let a1 = arr[0].to_le_bytes();
2243 let a2 = arr[1].to_le_bytes();
2244 [
2245 a1[0], a1[1], a1[2], a1[3], a1[4], a1[5], a1[6], a1[7],
2246 a2[0], a2[1], a2[2], a2[3], a2[4], a2[5], a2[6], a2[7],
2247 ]
2248 }
2249 V128Const::F32x4(arr) => {
2250 let a1 = arr[0].bits.to_le_bytes();
2251 let a2 = arr[1].bits.to_le_bytes();
2252 let a3 = arr[2].bits.to_le_bytes();
2253 let a4 = arr[3].bits.to_le_bytes();
2254 [
2255 a1[0], a1[1], a1[2], a1[3],
2256 a2[0], a2[1], a2[2], a2[3],
2257 a3[0], a3[1], a3[2], a3[3],
2258 a4[0], a4[1], a4[2], a4[3],
2259 ]
2260 }
2261 V128Const::F64x2(arr) => {
2262 let a1 = arr[0].bits.to_le_bytes();
2263 let a2 = arr[1].bits.to_le_bytes();
2264 [
2265 a1[0], a1[1], a1[2], a1[3], a1[4], a1[5], a1[6], a1[7],
2266 a2[0], a2[1], a2[2], a2[3], a2[4], a2[5], a2[6], a2[7],
2267 ]
2268 }
2269 }
2270 }
2271}
2272
2273impl<'a> Parse<'a> for V128Const {
2274 fn parse(parser: Parser<'a>) -> Result<Self> {
2275 let mut l = parser.lookahead1();
2276 if l.peek::<kw::i8x16>()? {
2277 parser.parse::<kw::i8x16>()?;
2278 Ok(V128Const::I8x16([
2279 parser.parse()?,
2280 parser.parse()?,
2281 parser.parse()?,
2282 parser.parse()?,
2283 parser.parse()?,
2284 parser.parse()?,
2285 parser.parse()?,
2286 parser.parse()?,
2287 parser.parse()?,
2288 parser.parse()?,
2289 parser.parse()?,
2290 parser.parse()?,
2291 parser.parse()?,
2292 parser.parse()?,
2293 parser.parse()?,
2294 parser.parse()?,
2295 ]))
2296 } else if l.peek::<kw::i16x8>()? {
2297 parser.parse::<kw::i16x8>()?;
2298 Ok(V128Const::I16x8([
2299 parser.parse()?,
2300 parser.parse()?,
2301 parser.parse()?,
2302 parser.parse()?,
2303 parser.parse()?,
2304 parser.parse()?,
2305 parser.parse()?,
2306 parser.parse()?,
2307 ]))
2308 } else if l.peek::<kw::i32x4>()? {
2309 parser.parse::<kw::i32x4>()?;
2310 Ok(V128Const::I32x4([
2311 parser.parse()?,
2312 parser.parse()?,
2313 parser.parse()?,
2314 parser.parse()?,
2315 ]))
2316 } else if l.peek::<kw::i64x2>()? {
2317 parser.parse::<kw::i64x2>()?;
2318 Ok(V128Const::I64x2([parser.parse()?, parser.parse()?]))
2319 } else if l.peek::<kw::f32x4>()? {
2320 parser.parse::<kw::f32x4>()?;
2321 Ok(V128Const::F32x4([
2322 parser.parse()?,
2323 parser.parse()?,
2324 parser.parse()?,
2325 parser.parse()?,
2326 ]))
2327 } else if l.peek::<kw::f64x2>()? {
2328 parser.parse::<kw::f64x2>()?;
2329 Ok(V128Const::F64x2([parser.parse()?, parser.parse()?]))
2330 } else {
2331 Err(l.error())
2332 }
2333 }
2334}
2335
2336#[derive(Debug, Clone)]
2338pub struct I8x16Shuffle {
2339 #[allow(missing_docs)]
2340 pub lanes: [u8; 16],
2341}
2342
2343impl<'a> Parse<'a> for I8x16Shuffle {
2344 fn parse(parser: Parser<'a>) -> Result<Self> {
2345 Ok(I8x16Shuffle {
2346 lanes: [
2347 parser.parse()?,
2348 parser.parse()?,
2349 parser.parse()?,
2350 parser.parse()?,
2351 parser.parse()?,
2352 parser.parse()?,
2353 parser.parse()?,
2354 parser.parse()?,
2355 parser.parse()?,
2356 parser.parse()?,
2357 parser.parse()?,
2358 parser.parse()?,
2359 parser.parse()?,
2360 parser.parse()?,
2361 parser.parse()?,
2362 parser.parse()?,
2363 ],
2364 })
2365 }
2366}
2367
2368#[derive(Debug, Clone)]
2370pub struct SelectTypes<'a> {
2371 #[allow(missing_docs)]
2372 pub tys: Option<Vec<ValType<'a>>>,
2373}
2374
2375impl<'a> Parse<'a> for SelectTypes<'a> {
2376 fn parse(parser: Parser<'a>) -> Result<Self> {
2377 let mut found = false;
2378 let mut list = Vec::new();
2379 while parser.peek2::<kw::result>()? {
2380 found = true;
2381 parser.parens(|p| {
2382 p.parse::<kw::result>()?;
2383 while !p.is_empty() {
2384 list.push(p.parse()?);
2385 }
2386 Ok(())
2387 })?;
2388 }
2389 Ok(SelectTypes {
2390 tys: if found { Some(list) } else { None },
2391 })
2392 }
2393}