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