#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BrTableData {
pub targets: Vec<u32>,
pub default: u32,
}
macro_rules! define_instruction {
($($all:tt)*) => {
define_instruction_inner!(@enum [] $($all)*);
};
}
macro_rules! define_instruction_inner {
(@enum [$($variants:tt)*]) => {
#[derive(Debug, Clone, PartialEq, Eq)]
#[allow(missing_docs, non_camel_case_types)]
pub enum Instruction {
$($variants)*
}
};
(@enum [$($v:tt)*] @$p:ident BrTable { $arg:ident : $t:ty } => $visit:ident $ann:tt $($rest:tt)*) => {
define_instruction_inner!(@enum [$($v)* BrTable { $arg: BrTableData },] $($rest)*);
};
(@enum [$($v:tt)*] @$p:ident $op:ident { $($arg:ident : $argty:ty),* } => $visit:ident $ann:tt $($rest:tt)*) => {
define_instruction_inner!(@enum [$($v)* $op { $($arg: $argty),* },] $($rest)*);
};
(@enum [$($v:tt)*] @$p:ident $op:ident => $visit:ident $ann:tt $($rest:tt)*) => {
define_instruction_inner!(@enum [$($v)* $op,] $($rest)*);
};
}
wasmparser::for_each_operator!(define_instruction);
macro_rules! define_from_operator {
($( @$proposal:ident $op:ident $({ $($arg:ident : $argty:ty),* })? => $visit:ident ($($ann:tt)*) )*) => {
#[allow(missing_docs)]
impl Instruction {
pub fn from_operator(op: &wasmparser::Operator<'_>) -> Self {
match op {
$(
wasmparser::Operator::$op $({ $($arg),* })? => {
define_from_operator!(@build $op $($($arg),*)?)
}
)*
_ => unreachable!("unknown operator"),
}
}
}
};
(@build BrTable $targets:ident) => {
Instruction::BrTable {
targets: BrTableData {
targets: $targets.targets().map(|t| t.unwrap()).collect(),
default: $targets.default(),
}
}
};
(@build $op:ident) => {
Instruction::$op
};
(@build $op:ident $($arg:ident),+) => {
Instruction::$op { $($arg: $arg.clone()),+ }
};
}
wasmparser::for_each_operator!(define_from_operator);