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 ResumeThrowRef(ResumeThrowRef<'a>) : [0xe5] : "resume_throw_ref",
1199 Switch(Switch<'a>) : [0xe6] : "switch",
1200
1201 I64Add128 : [0xfc, 19] : "i64.add128",
1203 I64Sub128 : [0xfc, 20] : "i64.sub128",
1204 I64MulWideS : [0xfc, 21] : "i64.mul_wide_s",
1205 I64MulWideU : [0xfc, 22] : "i64.mul_wide_u",
1206
1207 StructNewDesc(Index<'a>) : [0xfb, 32] : "struct.new_desc",
1209 StructNewDefaultDesc(Index<'a>) : [0xfb, 33] : "struct.new_default_desc",
1210 RefGetDesc(Index<'a>): [0xfb, 34] : "ref.get_desc",
1211 RefCastDescEq(RefCastDescEq<'a>) : [] : "ref.cast_desc_eq",
1212 BrOnCastDescEq(Box<BrOnCastDescEq<'a>>) : [] : "br_on_cast_desc_eq",
1213 BrOnCastDescEqFail(Box<BrOnCastDescEqFail<'a>>) : [] : "br_on_cast_desc_eq_fail",
1214 }
1215}
1216
1217#[test]
1222fn assert_instruction_not_too_large() {
1223 let size = std::mem::size_of::<Instruction<'_>>();
1224 let pointer = std::mem::size_of::<u64>();
1225 assert!(size <= pointer * 11);
1226}
1227
1228impl<'a> Instruction<'a> {
1229 pub(crate) fn needs_data_count(&self) -> bool {
1230 match self {
1231 Instruction::MemoryInit(_)
1232 | Instruction::DataDrop(_)
1233 | Instruction::ArrayNewData(_)
1234 | Instruction::ArrayInitData(_) => true,
1235 _ => false,
1236 }
1237 }
1238}
1239
1240#[derive(Debug, Clone)]
1245#[allow(missing_docs)]
1246pub struct BlockType<'a> {
1247 pub label: Option<Id<'a>>,
1248 pub label_name: Option<NameAnnotation<'a>>,
1249 pub ty: TypeUse<'a, FunctionType<'a>>,
1250}
1251
1252impl<'a> Parse<'a> for BlockType<'a> {
1253 fn parse(parser: Parser<'a>) -> Result<Self> {
1254 Ok(BlockType {
1255 label: parser.parse()?,
1256 label_name: parser.parse()?,
1257 ty: parser
1258 .parse::<TypeUse<'a, FunctionTypeNoNames<'a>>>()?
1259 .into(),
1260 })
1261 }
1262}
1263
1264#[derive(Debug, Clone)]
1266#[allow(missing_docs)]
1267pub struct ContBind<'a> {
1268 pub argument_index: Index<'a>,
1269 pub result_index: Index<'a>,
1270}
1271
1272impl<'a> Parse<'a> for ContBind<'a> {
1273 fn parse(parser: Parser<'a>) -> Result<Self> {
1274 Ok(ContBind {
1275 argument_index: parser.parse()?,
1276 result_index: parser.parse()?,
1277 })
1278 }
1279}
1280
1281#[derive(Debug, Clone)]
1283#[allow(missing_docs)]
1284pub struct Resume<'a> {
1285 pub type_index: Index<'a>,
1286 pub table: ResumeTable<'a>,
1287}
1288
1289impl<'a> Parse<'a> for Resume<'a> {
1290 fn parse(parser: Parser<'a>) -> Result<Self> {
1291 Ok(Resume {
1292 type_index: parser.parse()?,
1293 table: parser.parse()?,
1294 })
1295 }
1296}
1297
1298#[derive(Debug, Clone)]
1300#[allow(missing_docs)]
1301pub struct ResumeThrow<'a> {
1302 pub type_index: Index<'a>,
1303 pub tag_index: Index<'a>,
1304 pub table: ResumeTable<'a>,
1305}
1306
1307impl<'a> Parse<'a> for ResumeThrow<'a> {
1308 fn parse(parser: Parser<'a>) -> Result<Self> {
1309 Ok(ResumeThrow {
1310 type_index: parser.parse()?,
1311 tag_index: parser.parse()?,
1312 table: parser.parse()?,
1313 })
1314 }
1315}
1316
1317#[derive(Debug, Clone)]
1319#[allow(missing_docs)]
1320pub struct ResumeThrowRef<'a> {
1321 pub type_index: Index<'a>,
1322 pub table: ResumeTable<'a>,
1323}
1324
1325impl<'a> Parse<'a> for ResumeThrowRef<'a> {
1326 fn parse(parser: Parser<'a>) -> Result<Self> {
1327 Ok(ResumeThrowRef {
1328 type_index: parser.parse()?,
1329 table: parser.parse()?,
1330 })
1331 }
1332}
1333
1334#[derive(Debug, Clone)]
1336#[allow(missing_docs)]
1337pub struct Switch<'a> {
1338 pub type_index: Index<'a>,
1339 pub tag_index: Index<'a>,
1340}
1341
1342impl<'a> Parse<'a> for Switch<'a> {
1343 fn parse(parser: Parser<'a>) -> Result<Self> {
1344 Ok(Switch {
1345 type_index: parser.parse()?,
1346 tag_index: parser.parse()?,
1347 })
1348 }
1349}
1350
1351#[derive(Debug, Clone)]
1353#[allow(missing_docs)]
1354pub struct ResumeTable<'a> {
1355 pub handlers: Vec<Handle<'a>>,
1356}
1357
1358#[derive(Debug, Clone)]
1360#[allow(missing_docs)]
1361pub enum Handle<'a> {
1362 OnLabel { tag: Index<'a>, label: Index<'a> },
1363 OnSwitch { tag: Index<'a> },
1364}
1365
1366impl<'a> Parse<'a> for ResumeTable<'a> {
1367 fn parse(parser: Parser<'a>) -> Result<Self> {
1368 let mut handlers = Vec::new();
1369 while parser.peek::<LParen>()? && parser.peek2::<kw::on>()? {
1370 handlers.push(parser.parens(|p| {
1371 p.parse::<kw::on>()?;
1372 let tag: Index<'a> = p.parse()?;
1373 if p.peek::<kw::switch>()? {
1374 p.parse::<kw::switch>()?;
1375 Ok(Handle::OnSwitch { tag })
1376 } else {
1377 Ok(Handle::OnLabel {
1378 tag,
1379 label: p.parse()?,
1380 })
1381 }
1382 })?);
1383 }
1384 Ok(ResumeTable { handlers })
1385 }
1386}
1387
1388#[derive(Debug, Clone)]
1389#[allow(missing_docs)]
1390pub struct TryTable<'a> {
1391 pub block: Box<BlockType<'a>>,
1392 pub catches: Vec<TryTableCatch<'a>>,
1393}
1394
1395impl<'a> Parse<'a> for TryTable<'a> {
1396 fn parse(parser: Parser<'a>) -> Result<Self> {
1397 let block = parser.parse()?;
1398
1399 let mut catches = Vec::new();
1400 while parser.peek::<LParen>()?
1401 && (parser.peek2::<kw::catch>()?
1402 || parser.peek2::<kw::catch_ref>()?
1403 || parser.peek2::<kw::catch_all>()?
1404 || parser.peek2::<kw::catch_all_ref>()?)
1405 {
1406 catches.push(parser.parens(|p| {
1407 let kind = if parser.peek::<kw::catch_ref>()? {
1408 p.parse::<kw::catch_ref>()?;
1409 TryTableCatchKind::CatchRef(p.parse()?)
1410 } else if parser.peek::<kw::catch>()? {
1411 p.parse::<kw::catch>()?;
1412 TryTableCatchKind::Catch(p.parse()?)
1413 } else if parser.peek::<kw::catch_all>()? {
1414 p.parse::<kw::catch_all>()?;
1415 TryTableCatchKind::CatchAll
1416 } else {
1417 p.parse::<kw::catch_all_ref>()?;
1418 TryTableCatchKind::CatchAllRef
1419 };
1420
1421 Ok(TryTableCatch {
1422 kind,
1423 label: p.parse()?,
1424 })
1425 })?);
1426 }
1427
1428 Ok(TryTable { block, catches })
1429 }
1430}
1431
1432#[derive(Debug, Clone)]
1433#[allow(missing_docs)]
1434pub enum TryTableCatchKind<'a> {
1435 Catch(Index<'a>),
1437 CatchRef(Index<'a>),
1439 CatchAll,
1441 CatchAllRef,
1443}
1444
1445impl<'a> TryTableCatchKind<'a> {
1446 #[allow(missing_docs)]
1447 pub fn tag_index_mut(&mut self) -> Option<&mut Index<'a>> {
1448 match self {
1449 TryTableCatchKind::Catch(tag) | TryTableCatchKind::CatchRef(tag) => Some(tag),
1450 TryTableCatchKind::CatchAll | TryTableCatchKind::CatchAllRef => None,
1451 }
1452 }
1453}
1454
1455#[derive(Debug, Clone)]
1456#[allow(missing_docs)]
1457pub struct TryTableCatch<'a> {
1458 pub kind: TryTableCatchKind<'a>,
1459 pub label: Index<'a>,
1460}
1461
1462#[allow(missing_docs)]
1464#[derive(Debug, Clone)]
1465pub struct BrTableIndices<'a> {
1466 pub labels: Vec<Index<'a>>,
1467 pub default: Index<'a>,
1468}
1469
1470impl<'a> Parse<'a> for BrTableIndices<'a> {
1471 fn parse(parser: Parser<'a>) -> Result<Self> {
1472 let mut labels = vec![parser.parse()?];
1473 while parser.peek::<Index>()? {
1474 labels.push(parser.parse()?);
1475 }
1476 let default = labels.pop().unwrap();
1477 Ok(BrTableIndices { labels, default })
1478 }
1479}
1480
1481#[derive(Debug, Clone)]
1483pub struct LaneArg {
1484 pub lane: u8,
1486}
1487
1488impl<'a> Parse<'a> for LaneArg {
1489 fn parse(parser: Parser<'a>) -> Result<Self> {
1490 let lane = parser.step(|c| {
1491 if let Some((i, rest)) = c.integer()? {
1492 if i.sign() == None {
1493 let (src, radix) = i.val();
1494 let val = u8::from_str_radix(src, radix)
1495 .map_err(|_| c.error("malformed lane index"))?;
1496 Ok((val, rest))
1497 } else {
1498 Err(c.error("unexpected token"))
1499 }
1500 } else {
1501 Err(c.error("expected a lane index"))
1502 }
1503 })?;
1504 Ok(LaneArg { lane })
1505 }
1506}
1507
1508#[derive(Debug, Clone)]
1511pub struct MemArg<'a> {
1512 pub align: u64,
1517 pub offset: u64,
1519 pub memory: Index<'a>,
1521}
1522
1523impl<'a> MemArg<'a> {
1524 fn parse(parser: Parser<'a>, default_align: u64) -> Result<Self> {
1525 fn parse_field(name: &str, parser: Parser<'_>) -> Result<Option<u64>> {
1526 parser.step(|c| {
1527 let (kw, rest) = match c.keyword()? {
1528 Some(p) => p,
1529 None => return Ok((None, c)),
1530 };
1531 if !kw.starts_with(name) {
1532 return Ok((None, c));
1533 }
1534 let kw = &kw[name.len()..];
1535 if !kw.starts_with('=') {
1536 return Ok((None, c));
1537 }
1538 let num = &kw[1..];
1539 let lexer = Lexer::new(num);
1540 let mut pos = 0;
1541 if let Ok(Some(
1542 token @ Token {
1543 kind: TokenKind::Integer(integer_kind),
1544 ..
1545 },
1546 )) = lexer.parse(&mut pos)
1547 {
1548 let int = token.integer(lexer.input(), integer_kind);
1549 let (s, base) = int.val();
1550 let value = u64::from_str_radix(s, base);
1551 return match value {
1552 Ok(n) => Ok((Some(n), rest)),
1553 Err(_) => Err(c.error("u64 constant out of range")),
1554 };
1555 }
1556 Err(c.error("expected u64 integer constant"))
1557 })
1558 }
1559
1560 let memory = parser
1561 .parse::<Option<_>>()?
1562 .unwrap_or_else(|| Index::Num(0, parser.prev_span()));
1563 let offset = parse_field("offset", parser)?.unwrap_or(0);
1564 let align = match parse_field("align", parser)? {
1565 Some(n) if !n.is_power_of_two() => {
1566 return Err(parser.error("alignment must be a power of two"));
1567 }
1568 n => n.unwrap_or(default_align),
1569 };
1570
1571 Ok(MemArg {
1572 offset,
1573 align,
1574 memory,
1575 })
1576 }
1577}
1578
1579#[derive(Debug, Clone)]
1581pub struct LoadOrStoreLane<'a> {
1582 pub memarg: MemArg<'a>,
1584 pub lane: LaneArg,
1586}
1587
1588impl<'a> LoadOrStoreLane<'a> {
1589 fn parse(parser: Parser<'a>, default_align: u64) -> Result<Self> {
1590 let has_memarg = parser.step(|c| match c.integer()? {
1594 Some((_, after_int)) => {
1595 if after_int.integer()?.is_some() {
1598 return Ok((true, c));
1599 }
1600
1601 if let Some((kw, _)) = after_int.keyword()? {
1604 if kw.starts_with("offset=") || kw.starts_with("align=") {
1605 return Ok((true, c));
1606 }
1607 }
1608
1609 Ok((false, c))
1612 }
1613
1614 None => Ok((true, c)),
1617 })?;
1618 Ok(LoadOrStoreLane {
1619 memarg: if has_memarg {
1620 MemArg::parse(parser, default_align)?
1621 } else {
1622 MemArg {
1623 align: default_align,
1624 offset: 0,
1625 memory: Index::Num(0, parser.prev_span()),
1626 }
1627 },
1628 lane: LaneArg::parse(parser)?,
1629 })
1630 }
1631}
1632
1633#[derive(Debug, Clone)]
1635pub struct CallIndirect<'a> {
1636 pub table: Index<'a>,
1638 pub ty: TypeUse<'a, FunctionType<'a>>,
1640}
1641
1642impl<'a> Parse<'a> for CallIndirect<'a> {
1643 fn parse(parser: Parser<'a>) -> Result<Self> {
1644 let prev_span = parser.prev_span();
1645 let table: Option<_> = parser.parse()?;
1646 let ty = parser.parse::<TypeUse<'a, FunctionTypeNoNames<'a>>>()?;
1647 Ok(CallIndirect {
1648 table: table.unwrap_or(Index::Num(0, prev_span)),
1649 ty: ty.into(),
1650 })
1651 }
1652}
1653
1654#[derive(Debug, Clone)]
1656pub struct TableInit<'a> {
1657 pub table: Index<'a>,
1659 pub elem: Index<'a>,
1661}
1662
1663impl<'a> Parse<'a> for TableInit<'a> {
1664 fn parse(parser: Parser<'a>) -> Result<Self> {
1665 let prev_span = parser.prev_span();
1666 let (elem, table) = if parser.peek2::<Index>()? {
1667 let table = parser.parse()?;
1668 (parser.parse()?, table)
1669 } else {
1670 (parser.parse()?, Index::Num(0, prev_span))
1671 };
1672 Ok(TableInit { table, elem })
1673 }
1674}
1675
1676#[derive(Debug, Clone)]
1678pub struct TableCopy<'a> {
1679 pub dst: Index<'a>,
1681 pub src: Index<'a>,
1683}
1684
1685impl<'a> Parse<'a> for TableCopy<'a> {
1686 fn parse(parser: Parser<'a>) -> Result<Self> {
1687 let (dst, src) = match parser.parse::<Option<_>>()? {
1688 Some(dst) => (dst, parser.parse()?),
1689 None => (
1690 Index::Num(0, parser.prev_span()),
1691 Index::Num(0, parser.prev_span()),
1692 ),
1693 };
1694 Ok(TableCopy { dst, src })
1695 }
1696}
1697
1698#[derive(Debug, Clone)]
1700pub struct TableArg<'a> {
1701 pub dst: Index<'a>,
1703}
1704
1705impl<'a> Parse<'a> for TableArg<'a> {
1708 fn parse(parser: Parser<'a>) -> Result<Self> {
1709 let dst = if let Some(dst) = parser.parse()? {
1710 dst
1711 } else {
1712 Index::Num(0, parser.prev_span())
1713 };
1714 Ok(TableArg { dst })
1715 }
1716}
1717
1718#[derive(Debug, Clone)]
1720pub struct MemoryArg<'a> {
1721 pub mem: Index<'a>,
1723}
1724
1725impl<'a> Parse<'a> for MemoryArg<'a> {
1726 fn parse(parser: Parser<'a>) -> Result<Self> {
1727 let mem = if let Some(mem) = parser.parse()? {
1728 mem
1729 } else {
1730 Index::Num(0, parser.prev_span())
1731 };
1732 Ok(MemoryArg { mem })
1733 }
1734}
1735
1736#[derive(Debug, Clone)]
1738pub struct MemoryInit<'a> {
1739 pub data: Index<'a>,
1741 pub mem: Index<'a>,
1743}
1744
1745impl<'a> Parse<'a> for MemoryInit<'a> {
1746 fn parse(parser: Parser<'a>) -> Result<Self> {
1747 let prev_span = parser.prev_span();
1748 let (data, mem) = if parser.peek2::<Index>()? {
1749 let memory = parser.parse()?;
1750 (parser.parse()?, memory)
1751 } else {
1752 (parser.parse()?, Index::Num(0, prev_span))
1753 };
1754 Ok(MemoryInit { data, mem })
1755 }
1756}
1757
1758#[derive(Debug, Clone)]
1760pub struct MemoryCopy<'a> {
1761 pub src: Index<'a>,
1763 pub dst: Index<'a>,
1765}
1766
1767impl<'a> Parse<'a> for MemoryCopy<'a> {
1768 fn parse(parser: Parser<'a>) -> Result<Self> {
1769 let (src, dst) = match parser.parse()? {
1770 Some(dst) => (parser.parse()?, dst),
1771 None => (
1772 Index::Num(0, parser.prev_span()),
1773 Index::Num(0, parser.prev_span()),
1774 ),
1775 };
1776 Ok(MemoryCopy { src, dst })
1777 }
1778}
1779
1780#[derive(Debug, Clone)]
1782pub struct StructAccess<'a> {
1783 pub r#struct: Index<'a>,
1785 pub field: Index<'a>,
1787}
1788
1789impl<'a> Parse<'a> for StructAccess<'a> {
1790 fn parse(parser: Parser<'a>) -> Result<Self> {
1791 Ok(StructAccess {
1792 r#struct: parser.parse()?,
1793 field: parser.parse()?,
1794 })
1795 }
1796}
1797
1798#[derive(Debug, Clone)]
1800pub struct ArrayFill<'a> {
1801 pub array: Index<'a>,
1803}
1804
1805impl<'a> Parse<'a> for ArrayFill<'a> {
1806 fn parse(parser: Parser<'a>) -> Result<Self> {
1807 Ok(ArrayFill {
1808 array: parser.parse()?,
1809 })
1810 }
1811}
1812
1813#[derive(Debug, Clone)]
1815pub struct ArrayCopy<'a> {
1816 pub dest_array: Index<'a>,
1818 pub src_array: Index<'a>,
1820}
1821
1822impl<'a> Parse<'a> for ArrayCopy<'a> {
1823 fn parse(parser: Parser<'a>) -> Result<Self> {
1824 Ok(ArrayCopy {
1825 dest_array: parser.parse()?,
1826 src_array: parser.parse()?,
1827 })
1828 }
1829}
1830
1831#[derive(Debug, Clone)]
1833pub struct ArrayInit<'a> {
1834 pub array: Index<'a>,
1836 pub segment: Index<'a>,
1838}
1839
1840impl<'a> Parse<'a> for ArrayInit<'a> {
1841 fn parse(parser: Parser<'a>) -> Result<Self> {
1842 Ok(ArrayInit {
1843 array: parser.parse()?,
1844 segment: parser.parse()?,
1845 })
1846 }
1847}
1848
1849#[derive(Debug, Clone)]
1851pub struct ArrayNewFixed<'a> {
1852 pub array: Index<'a>,
1854 pub length: u32,
1856}
1857
1858impl<'a> Parse<'a> for ArrayNewFixed<'a> {
1859 fn parse(parser: Parser<'a>) -> Result<Self> {
1860 Ok(ArrayNewFixed {
1861 array: parser.parse()?,
1862 length: parser.parse()?,
1863 })
1864 }
1865}
1866
1867#[derive(Debug, Clone)]
1869pub struct ArrayNewData<'a> {
1870 pub array: Index<'a>,
1872 pub data_idx: Index<'a>,
1874}
1875
1876impl<'a> Parse<'a> for ArrayNewData<'a> {
1877 fn parse(parser: Parser<'a>) -> Result<Self> {
1878 Ok(ArrayNewData {
1879 array: parser.parse()?,
1880 data_idx: parser.parse()?,
1881 })
1882 }
1883}
1884
1885#[derive(Debug, Clone)]
1887pub struct ArrayNewElem<'a> {
1888 pub array: Index<'a>,
1890 pub elem_idx: Index<'a>,
1892}
1893
1894impl<'a> Parse<'a> for ArrayNewElem<'a> {
1895 fn parse(parser: Parser<'a>) -> Result<Self> {
1896 Ok(ArrayNewElem {
1897 array: parser.parse()?,
1898 elem_idx: parser.parse()?,
1899 })
1900 }
1901}
1902
1903#[derive(Debug, Clone)]
1905pub struct RefCast<'a> {
1906 pub r#type: RefType<'a>,
1908}
1909
1910impl<'a> Parse<'a> for RefCast<'a> {
1911 fn parse(parser: Parser<'a>) -> Result<Self> {
1912 Ok(RefCast {
1913 r#type: parser.parse()?,
1914 })
1915 }
1916}
1917
1918#[derive(Debug, Clone)]
1920pub struct RefTest<'a> {
1921 pub r#type: RefType<'a>,
1923}
1924
1925impl<'a> Parse<'a> for RefTest<'a> {
1926 fn parse(parser: Parser<'a>) -> Result<Self> {
1927 Ok(RefTest {
1928 r#type: parser.parse()?,
1929 })
1930 }
1931}
1932
1933#[derive(Debug, Clone)]
1935pub struct BrOnCast<'a> {
1936 pub label: Index<'a>,
1938 pub from_type: RefType<'a>,
1940 pub to_type: RefType<'a>,
1942}
1943
1944impl<'a> Parse<'a> for BrOnCast<'a> {
1945 fn parse(parser: Parser<'a>) -> Result<Self> {
1946 Ok(BrOnCast {
1947 label: parser.parse()?,
1948 from_type: parser.parse()?,
1949 to_type: parser.parse()?,
1950 })
1951 }
1952}
1953
1954#[derive(Debug, Clone)]
1956pub struct BrOnCastFail<'a> {
1957 pub label: Index<'a>,
1959 pub from_type: RefType<'a>,
1961 pub to_type: RefType<'a>,
1963}
1964
1965impl<'a> Parse<'a> for BrOnCastFail<'a> {
1966 fn parse(parser: Parser<'a>) -> Result<Self> {
1967 Ok(BrOnCastFail {
1968 label: parser.parse()?,
1969 from_type: parser.parse()?,
1970 to_type: parser.parse()?,
1971 })
1972 }
1973}
1974
1975#[derive(Debug, Clone)]
1977pub struct RefCastDescEq<'a> {
1978 pub r#type: RefType<'a>,
1980}
1981
1982impl<'a> Parse<'a> for RefCastDescEq<'a> {
1983 fn parse(parser: Parser<'a>) -> Result<Self> {
1984 Ok(RefCastDescEq {
1985 r#type: parser.parse()?,
1986 })
1987 }
1988}
1989
1990#[derive(Debug, Clone)]
1992pub struct BrOnCastDescEq<'a> {
1993 pub label: Index<'a>,
1995 pub from_type: RefType<'a>,
1997 pub to_type: RefType<'a>,
1999}
2000
2001impl<'a> Parse<'a> for BrOnCastDescEq<'a> {
2002 fn parse(parser: Parser<'a>) -> Result<Self> {
2003 Ok(BrOnCastDescEq {
2004 label: parser.parse()?,
2005 from_type: parser.parse()?,
2006 to_type: parser.parse()?,
2007 })
2008 }
2009}
2010
2011#[derive(Debug, Clone)]
2013pub struct BrOnCastDescEqFail<'a> {
2014 pub label: Index<'a>,
2016 pub from_type: RefType<'a>,
2018 pub to_type: RefType<'a>,
2020}
2021
2022impl<'a> Parse<'a> for BrOnCastDescEqFail<'a> {
2023 fn parse(parser: Parser<'a>) -> Result<Self> {
2024 Ok(BrOnCastDescEqFail {
2025 label: parser.parse()?,
2026 from_type: parser.parse()?,
2027 to_type: parser.parse()?,
2028 })
2029 }
2030}
2031
2032#[derive(Clone, Debug)]
2040pub enum Ordering {
2041 AcqRel,
2044 SeqCst,
2048}
2049
2050impl<'a> Parse<'a> for Ordering {
2051 fn parse(parser: Parser<'a>) -> Result<Self> {
2052 if parser.peek::<kw::seq_cst>()? {
2053 parser.parse::<kw::seq_cst>()?;
2054 Ok(Ordering::SeqCst)
2055 } else if parser.peek::<kw::acq_rel>()? {
2056 parser.parse::<kw::acq_rel>()?;
2057 Ok(Ordering::AcqRel)
2058 } else {
2059 Err(parser.error("expected a memory ordering: `seq_cst` or `acq_rel`"))
2060 }
2061 }
2062}
2063
2064#[derive(Clone, Debug)]
2070pub struct Ordered<T> {
2071 pub ordering: Ordering,
2073 pub inner: T,
2075}
2076
2077impl<'a, T> Parse<'a> for Ordered<T>
2078where
2079 T: Parse<'a>,
2080{
2081 fn parse(parser: Parser<'a>) -> Result<Self> {
2082 let ordering = parser.parse()?;
2083 let inner = parser.parse()?;
2084 Ok(Ordered { ordering, inner })
2085 }
2086}
2087
2088#[derive(Clone, Debug)]
2090#[allow(missing_docs)]
2091pub enum V128Const {
2092 I8x16([i8; 16]),
2093 I16x8([i16; 8]),
2094 I32x4([i32; 4]),
2095 I64x2([i64; 2]),
2096 F32x4([F32; 4]),
2097 F64x2([F64; 2]),
2098}
2099
2100impl V128Const {
2101 #[rustfmt::skip]
2107 pub fn to_le_bytes(&self) -> [u8; 16] {
2108 match self {
2109 V128Const::I8x16(arr) => [
2110 arr[0] as u8,
2111 arr[1] as u8,
2112 arr[2] as u8,
2113 arr[3] as u8,
2114 arr[4] as u8,
2115 arr[5] as u8,
2116 arr[6] as u8,
2117 arr[7] as u8,
2118 arr[8] as u8,
2119 arr[9] as u8,
2120 arr[10] as u8,
2121 arr[11] as u8,
2122 arr[12] as u8,
2123 arr[13] as u8,
2124 arr[14] as u8,
2125 arr[15] as u8,
2126 ],
2127 V128Const::I16x8(arr) => {
2128 let a1 = arr[0].to_le_bytes();
2129 let a2 = arr[1].to_le_bytes();
2130 let a3 = arr[2].to_le_bytes();
2131 let a4 = arr[3].to_le_bytes();
2132 let a5 = arr[4].to_le_bytes();
2133 let a6 = arr[5].to_le_bytes();
2134 let a7 = arr[6].to_le_bytes();
2135 let a8 = arr[7].to_le_bytes();
2136 [
2137 a1[0], a1[1],
2138 a2[0], a2[1],
2139 a3[0], a3[1],
2140 a4[0], a4[1],
2141 a5[0], a5[1],
2142 a6[0], a6[1],
2143 a7[0], a7[1],
2144 a8[0], a8[1],
2145 ]
2146 }
2147 V128Const::I32x4(arr) => {
2148 let a1 = arr[0].to_le_bytes();
2149 let a2 = arr[1].to_le_bytes();
2150 let a3 = arr[2].to_le_bytes();
2151 let a4 = arr[3].to_le_bytes();
2152 [
2153 a1[0], a1[1], a1[2], a1[3],
2154 a2[0], a2[1], a2[2], a2[3],
2155 a3[0], a3[1], a3[2], a3[3],
2156 a4[0], a4[1], a4[2], a4[3],
2157 ]
2158 }
2159 V128Const::I64x2(arr) => {
2160 let a1 = arr[0].to_le_bytes();
2161 let a2 = arr[1].to_le_bytes();
2162 [
2163 a1[0], a1[1], a1[2], a1[3], a1[4], a1[5], a1[6], a1[7],
2164 a2[0], a2[1], a2[2], a2[3], a2[4], a2[5], a2[6], a2[7],
2165 ]
2166 }
2167 V128Const::F32x4(arr) => {
2168 let a1 = arr[0].bits.to_le_bytes();
2169 let a2 = arr[1].bits.to_le_bytes();
2170 let a3 = arr[2].bits.to_le_bytes();
2171 let a4 = arr[3].bits.to_le_bytes();
2172 [
2173 a1[0], a1[1], a1[2], a1[3],
2174 a2[0], a2[1], a2[2], a2[3],
2175 a3[0], a3[1], a3[2], a3[3],
2176 a4[0], a4[1], a4[2], a4[3],
2177 ]
2178 }
2179 V128Const::F64x2(arr) => {
2180 let a1 = arr[0].bits.to_le_bytes();
2181 let a2 = arr[1].bits.to_le_bytes();
2182 [
2183 a1[0], a1[1], a1[2], a1[3], a1[4], a1[5], a1[6], a1[7],
2184 a2[0], a2[1], a2[2], a2[3], a2[4], a2[5], a2[6], a2[7],
2185 ]
2186 }
2187 }
2188 }
2189}
2190
2191impl<'a> Parse<'a> for V128Const {
2192 fn parse(parser: Parser<'a>) -> Result<Self> {
2193 let mut l = parser.lookahead1();
2194 if l.peek::<kw::i8x16>()? {
2195 parser.parse::<kw::i8x16>()?;
2196 Ok(V128Const::I8x16([
2197 parser.parse()?,
2198 parser.parse()?,
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 parser.parse()?,
2208 parser.parse()?,
2209 parser.parse()?,
2210 parser.parse()?,
2211 parser.parse()?,
2212 parser.parse()?,
2213 ]))
2214 } else if l.peek::<kw::i16x8>()? {
2215 parser.parse::<kw::i16x8>()?;
2216 Ok(V128Const::I16x8([
2217 parser.parse()?,
2218 parser.parse()?,
2219 parser.parse()?,
2220 parser.parse()?,
2221 parser.parse()?,
2222 parser.parse()?,
2223 parser.parse()?,
2224 parser.parse()?,
2225 ]))
2226 } else if l.peek::<kw::i32x4>()? {
2227 parser.parse::<kw::i32x4>()?;
2228 Ok(V128Const::I32x4([
2229 parser.parse()?,
2230 parser.parse()?,
2231 parser.parse()?,
2232 parser.parse()?,
2233 ]))
2234 } else if l.peek::<kw::i64x2>()? {
2235 parser.parse::<kw::i64x2>()?;
2236 Ok(V128Const::I64x2([parser.parse()?, parser.parse()?]))
2237 } else if l.peek::<kw::f32x4>()? {
2238 parser.parse::<kw::f32x4>()?;
2239 Ok(V128Const::F32x4([
2240 parser.parse()?,
2241 parser.parse()?,
2242 parser.parse()?,
2243 parser.parse()?,
2244 ]))
2245 } else if l.peek::<kw::f64x2>()? {
2246 parser.parse::<kw::f64x2>()?;
2247 Ok(V128Const::F64x2([parser.parse()?, parser.parse()?]))
2248 } else {
2249 Err(l.error())
2250 }
2251 }
2252}
2253
2254#[derive(Debug, Clone)]
2256pub struct I8x16Shuffle {
2257 #[allow(missing_docs)]
2258 pub lanes: [u8; 16],
2259}
2260
2261impl<'a> Parse<'a> for I8x16Shuffle {
2262 fn parse(parser: Parser<'a>) -> Result<Self> {
2263 Ok(I8x16Shuffle {
2264 lanes: [
2265 parser.parse()?,
2266 parser.parse()?,
2267 parser.parse()?,
2268 parser.parse()?,
2269 parser.parse()?,
2270 parser.parse()?,
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 ],
2282 })
2283 }
2284}
2285
2286#[derive(Debug, Clone)]
2288pub struct SelectTypes<'a> {
2289 #[allow(missing_docs)]
2290 pub tys: Option<Vec<ValType<'a>>>,
2291}
2292
2293impl<'a> Parse<'a> for SelectTypes<'a> {
2294 fn parse(parser: Parser<'a>) -> Result<Self> {
2295 let mut found = false;
2296 let mut list = Vec::new();
2297 while parser.peek2::<kw::result>()? {
2298 found = true;
2299 parser.parens(|p| {
2300 p.parse::<kw::result>()?;
2301 while !p.is_empty() {
2302 list.push(p.parse()?);
2303 }
2304 Ok(())
2305 })?;
2306 }
2307 Ok(SelectTypes {
2308 tys: if found { Some(list) } else { None },
2309 })
2310 }
2311}