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