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