Refactor IR and frontend SSA construction.

This commit is contained in:
Chris Fallin 2021-12-11 21:46:14 -08:00
parent 3750e0b570
commit 498f5008d6
5 changed files with 956 additions and 546 deletions

View file

@ -30,10 +30,10 @@ impl CFGInfo {
let mut block_preds = vec![SmallVec::new(); f.blocks.len()];
let mut block_succs = vec![SmallVec::new(); f.blocks.len()];
for block in 0..f.blocks.len() {
for succ in f.blocks[block].successors() {
f.blocks[block].terminator.visit_successors(|succ| {
block_preds[succ].push(block);
block_succs[block].push(succ);
}
});
}
let mut return_blocks = vec![];

File diff suppressed because it is too large Load diff

232
src/ir.rs
View file

@ -1,5 +1,7 @@
//! Intermediate representation for Wasm.
use std::collections::hash_map::Entry;
use crate::{backend::Shape, cfg::CFGInfo, frontend, Operator};
use anyhow::Result;
use fxhash::FxHashMap;
@ -68,10 +70,72 @@ impl FunctionBody {
}
pub fn add_value(&mut self, value: ValueDef, ty: Option<Type>) -> Value {
let id = Value(self.values.len() as u32);
self.values.push(value);
match self.value_dedup.entry(value.clone()) {
Entry::Occupied(o) => *o.get(),
Entry::Vacant(v) => {
let id = Value(self.values.len() as u32);
self.values.push(value);
self.types.push(ty);
v.insert(id);
id
}
}
}
pub fn set_alias(&mut self, value: Value, to: Value) {
// Resolve the `to` value through all existing aliases.
let to = self.resolve_alias(to);
// Disallow cycles.
if to == value {
panic!("Cannot create an alias cycle");
}
self.values[value.index()] = ValueDef::Alias(to);
}
pub fn resolve_alias(&self, value: Value) -> Value {
let mut result = value;
loop {
if let &ValueDef::Alias(to) = &self.values[result.index()] {
result = to;
} else {
break;
}
}
result
}
pub fn add_mutable_inst(&mut self, ty: Option<Type>, def: ValueDef) -> Value {
let value = Value(self.values.len() as u32);
self.types.push(ty);
id
self.values.push(def);
value
}
pub fn add_blockparam(&mut self, block: BlockId, ty: Type) {
self.blocks[block].params.push(ty);
}
pub fn add_placeholder(&mut self, ty: Type) -> Value {
self.add_mutable_inst(Some(ty), ValueDef::Placeholder)
}
pub fn replace_placeholder_with_blockparam(&mut self, block: BlockId, value: Value) {
assert!(self.values[value.index()] == ValueDef::Placeholder);
let ty = self.types[value.index()].unwrap();
let index = self.blocks[block].params.len();
self.blocks[block].params.push(ty);
self.values[value.index()] = ValueDef::BlockParam(block, index);
}
pub fn resolve_and_update_alias(&mut self, value: Value) -> Value {
let to = self.resolve_alias(value);
// Short-circuit the chain, union-find-style.
if let &ValueDef::Alias(orig_to) = &self.values[value.index()] {
if orig_to != to {
self.values[value.index()] = ValueDef::Alias(to);
}
}
to
}
pub fn append_to_block(&mut self, block: BlockId, value: Value) {
@ -130,11 +194,19 @@ pub struct Block {
pub preds: Vec<BlockId>,
/// For each predecessor block, our index in its `succs` array.
pub pos_in_pred_succ: Vec<usize>,
/// Type of each blockparam.
pub params: Vec<Type>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Value(u32);
impl std::fmt::Display for Value {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "v{}", self.0)
}
}
impl Value {
pub fn undef() -> Self {
Value(u32::MAX)
@ -157,10 +229,12 @@ impl std::default::Default for Value {
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum ValueDef {
Arg { index: usize },
BlockParam { block: BlockId, index: usize },
Operator { op: Operator, args: Vec<Value> },
PickOutput { from: Value, index: usize },
Arg(usize),
BlockParam(BlockId, usize),
Operator(Operator, Vec<Value>),
PickOutput(Value, usize),
Alias(Value),
Placeholder,
}
impl ValueDef {
@ -168,12 +242,14 @@ impl ValueDef {
match self {
&ValueDef::Arg { .. } => {}
&ValueDef::BlockParam { .. } => {}
&ValueDef::Operator { ref args, .. } => {
&ValueDef::Operator(_, ref args) => {
for &arg in args {
f(arg);
}
}
&ValueDef::PickOutput { from, .. } => f(from),
&ValueDef::PickOutput(from, ..) => f(from),
&ValueDef::Alias(value) => f(value),
&ValueDef::Placeholder => {}
}
}
@ -181,30 +257,38 @@ impl ValueDef {
match self {
&mut ValueDef::Arg { .. } => {}
&mut ValueDef::BlockParam { .. } => {}
&mut ValueDef::Operator { ref mut args, .. } => {
&mut ValueDef::Operator(_, ref mut args) => {
for arg in args {
f(arg);
}
}
&mut ValueDef::PickOutput { ref mut from, .. } => f(from),
&mut ValueDef::PickOutput(ref mut from, ..) => f(from),
&mut ValueDef::Alias(ref mut value) => f(value),
&mut ValueDef::Placeholder => {}
}
}
}
#[derive(Clone, Debug)]
pub struct BlockTarget {
pub block: BlockId,
pub args: Vec<Value>,
}
#[derive(Clone, Debug)]
pub enum Terminator {
Br {
target: BlockId,
target: BlockTarget,
},
CondBr {
cond: Value,
if_true: BlockId,
if_false: BlockId,
if_true: BlockTarget,
if_false: BlockTarget,
},
Select {
value: Value,
targets: Vec<BlockId>,
default: BlockId,
targets: Vec<BlockTarget>,
default: BlockTarget,
},
Return {
values: Vec<Value>,
@ -219,31 +303,126 @@ impl std::default::Default for Terminator {
}
impl Terminator {
pub fn visit_successors<F: FnMut(BlockId)>(&self, mut f: F) {
pub fn visit_targets<F: FnMut(&BlockTarget)>(&self, mut f: F) {
match self {
Terminator::Return { .. } => {}
Terminator::Br { target, .. } => f(*target),
Terminator::Br { ref target, .. } => f(target),
Terminator::CondBr {
if_true, if_false, ..
ref if_true,
ref if_false,
..
} => {
f(*if_true);
f(*if_false);
f(if_true);
f(if_false);
}
Terminator::Select {
ref targets,
default,
ref default,
..
} => {
for &target in targets {
f(default);
for target in targets {
f(target);
}
f(*default);
}
Terminator::None => {}
}
}
pub fn update_targets<F: FnMut(&mut BlockTarget)>(&mut self, mut f: F) {
match self {
Terminator::Return { .. } => {}
Terminator::Br { ref mut target, .. } => f(target),
Terminator::CondBr {
ref mut if_true,
ref mut if_false,
..
} => {
f(if_true);
f(if_false);
}
Terminator::Select {
ref mut targets,
ref mut default,
..
} => {
f(default);
for target in targets {
f(target);
}
}
Terminator::None => {}
}
}
pub fn visit_target<F: FnMut(&BlockTarget)>(&self, index: usize, mut f: F) {
match (index, self) {
(0, Terminator::Br { ref target, .. }) => f(target),
(0, Terminator::CondBr { ref if_true, .. }) => {
f(if_true);
}
(1, Terminator::CondBr { ref if_false, .. }) => {
f(if_false);
}
(0, Terminator::Select { ref default, .. }) => {
f(default);
}
(i, Terminator::Select { ref targets, .. }) if i <= targets.len() => {
f(&targets[i - 1]);
}
_ => panic!("out of bounds"),
}
}
pub fn update_target<F: FnMut(&mut BlockTarget)>(&mut self, index: usize, mut f: F) {
match (index, self) {
(0, Terminator::Br { ref mut target, .. }) => f(target),
(
0,
Terminator::CondBr {
ref mut if_true, ..
},
) => {
f(if_true);
}
(
1,
Terminator::CondBr {
ref mut if_false, ..
},
) => {
f(if_false);
}
(
0,
Terminator::Select {
ref mut default, ..
},
) => {
f(default);
}
(
i,
Terminator::Select {
ref mut targets, ..
},
) if i <= targets.len() => {
f(&mut targets[i - 1]);
}
_ => panic!("out of bounds"),
}
}
pub fn visit_successors<F: FnMut(BlockId)>(&self, mut f: F) {
self.visit_targets(|target| f(target.block));
}
pub fn visit_uses<F: FnMut(Value)>(&self, mut f: F) {
self.visit_targets(|target| {
for &arg in &target.args {
f(arg);
}
});
match self {
&Terminator::CondBr { cond, .. } => f(cond),
&Terminator::Select { value, .. } => f(value),
@ -257,6 +436,11 @@ impl Terminator {
}
pub fn update_uses<F: FnMut(&mut Value)>(&mut self, mut f: F) {
self.update_targets(|target| {
for arg in &mut target.args {
f(arg);
}
});
match self {
&mut Terminator::CondBr { ref mut cond, .. } => f(cond),
&mut Terminator::Select { ref mut value, .. } => f(value),

View file

@ -2,7 +2,7 @@
use crate::ir::{Module, SignatureId, Value};
use crate::Operator;
use anyhow::{bail, Result};
use anyhow::Result;
use wasmparser::Type;
pub fn op_inputs(
@ -221,8 +221,6 @@ pub fn op_inputs(
Operator::TableSize { .. } => Ok(vec![]),
Operator::MemorySize { .. } => Ok(vec![]),
Operator::MemoryGrow { .. } => Ok(vec![Type::I32]),
_ => bail!("Unknown operator in op_inputs(): {:?}", op),
}
}
@ -433,8 +431,6 @@ pub fn op_outputs(
Operator::TableSize { .. } => Ok(vec![Type::I32]),
Operator::MemorySize { .. } => Ok(vec![Type::I32]),
Operator::MemoryGrow { .. } => Ok(vec![Type::I32]),
_ => bail!("Unknown operator in op_outputs(): {:?}", op),
}
}
@ -652,7 +648,5 @@ pub fn op_effects(op: &Operator) -> Result<Vec<SideEffect>> {
Operator::TableSize { table, .. } => Ok(vec![ReadTable(*table as usize)]),
Operator::MemorySize { .. } => Ok(vec![ReadMem]),
Operator::MemoryGrow { .. } => Ok(vec![WriteMem, Trap]),
_ => bail!("Unknown operator in op_outputs(): {:?}", op),
}
}

View file

@ -214,260 +214,263 @@ pub enum Operator {
MemoryGrow { mem: MemoryId },
}
impl<'a> std::convert::TryFrom<wasmparser::Operator<'a>> for Operator {
fn try_from(op: &wasmparser::Operator<'a>) -> Option<Operator> {
impl<'a, 'b> std::convert::TryFrom<&'b wasmparser::Operator<'a>> for Operator {
type Error = ();
fn try_from(op: &'b wasmparser::Operator<'a>) -> Result<Operator, Self::Error> {
match op {
&wasmparser::Operator::Unreachable => Some(Operator::Unreachable),
&wasmparser::Operator::Nop => Some(Operator::Nop),
&wasmparser::Operator::Call { function_index } => Some(Operator::Call {
&wasmparser::Operator::Unreachable => Ok(Operator::Unreachable),
&wasmparser::Operator::Nop => Ok(Operator::Nop),
&wasmparser::Operator::Call { function_index } => Ok(Operator::Call {
function_index: function_index as usize,
}),
&wasmparser::Operator::CallIndirect { index, table_index } => {
Some(Operator::CallIndirect {
Ok(Operator::CallIndirect {
index: index as usize,
table_index,
})
}
&wasmparser::Operator::Return => Some(Operator::Return),
&wasmparser::Operator::Return => Ok(Operator::Return),
&wasmparser::Operator::LocalSet { local_index } => {
Some(Operator::LocalSet { local_index })
Ok(Operator::LocalSet { local_index })
}
&wasmparser::Operator::LocalTee { local_index } => {
Some(Operator::LocalTee { local_index })
Ok(Operator::LocalTee { local_index })
}
&wasmparser::Operator::LocalGet { local_index } => {
Some(Operator::LocalGet { local_index })
Ok(Operator::LocalGet { local_index })
}
&wasmparser::Operator::Select => Some(Operator::Select),
&wasmparser::Operator::TypedSelect { ty } => Some(Operator::TypedSelect { ty }),
&wasmparser::Operator::Select => Ok(Operator::Select),
&wasmparser::Operator::TypedSelect { ty } => Ok(Operator::TypedSelect { ty }),
&wasmparser::Operator::GlobalGet { global_index } => {
Some(Operator::GlobalGet { global_index })
Ok(Operator::GlobalGet { global_index })
}
&wasmparser::Operator::GlobalSet { global_index } => {
Some(Operator::GlobalSet { global_index })
Ok(Operator::GlobalSet { global_index })
}
&wasmparser::Operator::I32Load { memarg } => Some(Operator::I32Load {
&wasmparser::Operator::I32Load { memarg } => Ok(Operator::I32Load {
memory: memarg.into(),
}),
&wasmparser::Operator::I64Load { memarg } => Some(Operator::I64Load {
&wasmparser::Operator::I64Load { memarg } => Ok(Operator::I64Load {
memory: memarg.into(),
}),
&wasmparser::Operator::F32Load { memarg } => Some(Operator::F32Load {
&wasmparser::Operator::F32Load { memarg } => Ok(Operator::F32Load {
memory: memarg.into(),
}),
&wasmparser::Operator::F64Load { memarg } => Some(Operator::F64Load {
&wasmparser::Operator::F64Load { memarg } => Ok(Operator::F64Load {
memory: memarg.into(),
}),
&wasmparser::Operator::I32Load8S { memarg } => Some(Operator::I32Load8S {
&wasmparser::Operator::I32Load8S { memarg } => Ok(Operator::I32Load8S {
memory: memarg.into(),
}),
&wasmparser::Operator::I32Load8U { memarg } => Some(Operator::I32Load8U {
&wasmparser::Operator::I32Load8U { memarg } => Ok(Operator::I32Load8U {
memory: memarg.into(),
}),
&wasmparser::Operator::I32Load16S { memarg } => Some(Operator::I32Load16S {
&wasmparser::Operator::I32Load16S { memarg } => Ok(Operator::I32Load16S {
memory: memarg.into(),
}),
&wasmparser::Operator::I32Load16U { memarg } => Some(Operator::I32Load16U {
&wasmparser::Operator::I32Load16U { memarg } => Ok(Operator::I32Load16U {
memory: memarg.into(),
}),
&wasmparser::Operator::I64Load8S { memarg } => Some(Operator::I64Load8S {
&wasmparser::Operator::I64Load8S { memarg } => Ok(Operator::I64Load8S {
memory: memarg.into(),
}),
&wasmparser::Operator::I64Load8U { memarg } => Some(Operator::I64Load8U {
&wasmparser::Operator::I64Load8U { memarg } => Ok(Operator::I64Load8U {
memory: memarg.into(),
}),
&wasmparser::Operator::I64Load16S { memarg } => Some(Operator::I64Load16S {
&wasmparser::Operator::I64Load16S { memarg } => Ok(Operator::I64Load16S {
memory: memarg.into(),
}),
&wasmparser::Operator::I64Load16U { memarg } => Some(Operator::I64Load16U {
&wasmparser::Operator::I64Load16U { memarg } => Ok(Operator::I64Load16U {
memory: memarg.into(),
}),
&wasmparser::Operator::I64Load32S { memarg } => Some(Operator::I64Load32S {
&wasmparser::Operator::I64Load32S { memarg } => Ok(Operator::I64Load32S {
memory: memarg.into(),
}),
&wasmparser::Operator::I64Load32U { memarg } => Some(Operator::I64Load32U {
&wasmparser::Operator::I64Load32U { memarg } => Ok(Operator::I64Load32U {
memory: memarg.into(),
}),
&wasmparser::Operator::I32Store { memarg } => Some(Operator::I32Store {
&wasmparser::Operator::I32Store { memarg } => Ok(Operator::I32Store {
memory: memarg.into(),
}),
&wasmparser::Operator::I64Store { memarg } => Some(Operator::I64Store {
&wasmparser::Operator::I64Store { memarg } => Ok(Operator::I64Store {
memory: memarg.into(),
}),
&wasmparser::Operator::F32Store { memarg } => Some(Operator::F32Store {
&wasmparser::Operator::F32Store { memarg } => Ok(Operator::F32Store {
memory: memarg.into(),
}),
&wasmparser::Operator::F64Store { memarg } => Some(Operator::F64Store {
&wasmparser::Operator::F64Store { memarg } => Ok(Operator::F64Store {
memory: memarg.into(),
}),
&wasmparser::Operator::I32Store8 { memarg } => Some(Operator::I32Store8 {
&wasmparser::Operator::I32Store8 { memarg } => Ok(Operator::I32Store8 {
memory: memarg.into(),
}),
&wasmparser::Operator::I32Store16 { memarg } => Some(Operator::I32Store16 {
&wasmparser::Operator::I32Store16 { memarg } => Ok(Operator::I32Store16 {
memory: memarg.into(),
}),
&wasmparser::Operator::I64Store8 { memarg } => Some(Operator::I64Store8 {
&wasmparser::Operator::I64Store8 { memarg } => Ok(Operator::I64Store8 {
memory: memarg.into(),
}),
&wasmparser::Operator::I64Store16 { memarg } => Some(Operator::I64Store16 {
&wasmparser::Operator::I64Store16 { memarg } => Ok(Operator::I64Store16 {
memory: memarg.into(),
}),
&wasmparser::Operator::I64Store32 { memarg } => Some(Operator::I64Store32 {
&wasmparser::Operator::I64Store32 { memarg } => Ok(Operator::I64Store32 {
memory: memarg.into(),
}),
&wasmparser::Operator::I32Const { value } => Some(Operator::I32Const { value }),
&wasmparser::Operator::I64Const { value } => Some(Operator::I64Const { value }),
&wasmparser::Operator::F32Const { value } => Some(Operator::F32Const { value }),
&wasmparser::Operator::F64Const { value } => Some(Operator::F64Const { value }),
&wasmparser::Operator::I32Eqz => Some(Operator::I32Eqz),
&wasmparser::Operator::I32Eq => Some(Operator::I32Eq),
&wasmparser::Operator::I32Ne => Some(Operator::I32Ne),
&wasmparser::Operator::I32LtS => Some(Operator::I32LtS),
&wasmparser::Operator::I32LtU => Some(Operator::I32LtU),
&wasmparser::Operator::I32GtS => Some(Operator::I32GtS),
&wasmparser::Operator::I32GtU => Some(Operator::I32GtU),
&wasmparser::Operator::I32LeS => Some(Operator::I32LeS),
&wasmparser::Operator::I32LeU => Some(Operator::I32LeU),
&wasmparser::Operator::I32GeS => Some(Operator::I32GeS),
&wasmparser::Operator::I32GeU => Some(Operator::I32GeU),
&wasmparser::Operator::I64Eqz => Some(Operator::I64Eqz),
&wasmparser::Operator::I64Eq => Some(Operator::I64Eq),
&wasmparser::Operator::I64Ne => Some(Operator::I64Ne),
&wasmparser::Operator::I64LtS => Some(Operator::I64LtS),
&wasmparser::Operator::I64LtU => Some(Operator::I64LtU),
&wasmparser::Operator::I64GtU => Some(Operator::I64GtU),
&wasmparser::Operator::I64GtS => Some(Operator::I64GtS),
&wasmparser::Operator::I64LeS => Some(Operator::I64LeS),
&wasmparser::Operator::I64LeU => Some(Operator::I64LeU),
&wasmparser::Operator::I64GeS => Some(Operator::I64GeS),
&wasmparser::Operator::I64GeU => Some(Operator::I64GeU),
&wasmparser::Operator::F32Eq => Some(Operator::F32Eq),
&wasmparser::Operator::F32Ne => Some(Operator::F32Ne),
&wasmparser::Operator::F32Lt => Some(Operator::F32Lt),
&wasmparser::Operator::F32Gt => Some(Operator::F32Gt),
&wasmparser::Operator::F32Le => Some(Operator::F32Le),
&wasmparser::Operator::F32Ge => Some(Operator::F32Ge),
&wasmparser::Operator::F64Eq => Some(Operator::F64Eq),
&wasmparser::Operator::F64Ne => Some(Operator::F64Ne),
&wasmparser::Operator::F64Lt => Some(Operator::F64Lt),
&wasmparser::Operator::F64Gt => Some(Operator::F64Gt),
&wasmparser::Operator::F64Le => Some(Operator::F64Le),
&wasmparser::Operator::F64Ge => Some(Operator::F64Ge),
&wasmparser::Operator::I32Clz => Some(Operator::I32Clz),
&wasmparser::Operator::I32Ctz => Some(Operator::I32Ctz),
&wasmparser::Operator::I32Popcnt => Some(Operator::I32Popcnt),
&wasmparser::Operator::I32Add => Some(Operator::I32Add),
&wasmparser::Operator::I32Sub => Some(Operator::I32Sub),
&wasmparser::Operator::I32Mul => Some(Operator::I32Mul),
&wasmparser::Operator::I32DivS => Some(Operator::I32DivS),
&wasmparser::Operator::I32DivU => Some(Operator::I32DivU),
&wasmparser::Operator::I32RemS => Some(Operator::I32RemS),
&wasmparser::Operator::I32RemU => Some(Operator::I32RemU),
&wasmparser::Operator::I32And => Some(Operator::I32And),
&wasmparser::Operator::I32Or => Some(Operator::I32Or),
&wasmparser::Operator::I32Xor => Some(Operator::I32Xor),
&wasmparser::Operator::I32Shl => Some(Operator::I32Shl),
&wasmparser::Operator::I32ShrS => Some(Operator::I32ShrS),
&wasmparser::Operator::I32ShrU => Some(Operator::I32ShrU),
&wasmparser::Operator::I32Rotl => Some(Operator::I32Rotl),
&wasmparser::Operator::I32Rotr => Some(Operator::I32Rotr),
&wasmparser::Operator::I64Clz => Some(Operator::I64Clz),
&wasmparser::Operator::I64Ctz => Some(Operator::I64Ctz),
&wasmparser::Operator::I64Popcnt => Some(Operator::I64Popcnt),
&wasmparser::Operator::I64Add => Some(Operator::I64Add),
&wasmparser::Operator::I64Sub => Some(Operator::I64Sub),
&wasmparser::Operator::I64Mul => Some(Operator::I64Mul),
&wasmparser::Operator::I64DivS => Some(Operator::I64DivS),
&wasmparser::Operator::I64DivU => Some(Operator::I64DivU),
&wasmparser::Operator::I64RemS => Some(Operator::I64RemS),
&wasmparser::Operator::I64RemU => Some(Operator::I64RemU),
&wasmparser::Operator::I64And => Some(Operator::I64And),
&wasmparser::Operator::I64Or => Some(Operator::I64Or),
&wasmparser::Operator::I64Xor => Some(Operator::I64Xor),
&wasmparser::Operator::I64Shl => Some(Operator::I64Shl),
&wasmparser::Operator::I64ShrS => Some(Operator::I64ShrS),
&wasmparser::Operator::I64ShrU => Some(Operator::I64ShrU),
&wasmparser::Operator::I64Rotl => Some(Operator::I64Rotl),
&wasmparser::Operator::I64Rotr => Some(Operator::I64Rotr),
&wasmparser::Operator::F32Abs => Some(Operator::F32Abs),
&wasmparser::Operator::F32Neg => Some(Operator::F32Neg),
&wasmparser::Operator::F32Ceil => Some(Operator::F32Ceil),
&wasmparser::Operator::F32Floor => Some(Operator::F32Floor),
&wasmparser::Operator::F32Trunc => Some(Operator::F32Trunc),
&wasmparser::Operator::F32Nearest => Some(Operator::F32Nearest),
&wasmparser::Operator::F32Sqrt => Some(Operator::F32Sqrt),
&wasmparser::Operator::F32Add => Some(Operator::F32Add),
&wasmparser::Operator::F32Sub => Some(Operator::F32Sub),
&wasmparser::Operator::F32Mul => Some(Operator::F32Mul),
&wasmparser::Operator::F32Div => Some(Operator::F32Div),
&wasmparser::Operator::F32Min => Some(Operator::F32Min),
&wasmparser::Operator::F32Max => Some(Operator::F32Max),
&wasmparser::Operator::F32Copysign => Some(Operator::F32Copysign),
&wasmparser::Operator::F64Abs => Some(Operator::F64Abs),
&wasmparser::Operator::F64Neg => Some(Operator::F64Neg),
&wasmparser::Operator::F64Ceil => Some(Operator::F64Ceil),
&wasmparser::Operator::F64Floor => Some(Operator::F64Floor),
&wasmparser::Operator::F64Trunc => Some(Operator::F64Trunc),
&wasmparser::Operator::F64Nearest => Some(Operator::F64Nearest),
&wasmparser::Operator::F64Sqrt => Some(Operator::F64Sqrt),
&wasmparser::Operator::F64Add => Some(Operator::F64Add),
&wasmparser::Operator::F64Sub => Some(Operator::F64Sub),
&wasmparser::Operator::F64Mul => Some(Operator::F64Mul),
&wasmparser::Operator::F64Div => Some(Operator::F64Div),
&wasmparser::Operator::F64Min => Some(Operator::F64Min),
&wasmparser::Operator::F64Max => Some(Operator::F64Max),
&wasmparser::Operator::F64Copysign => Some(Operator::F64Copysign),
&wasmparser::Operator::I32WrapI64 => Some(Operator::I32WrapI64),
&wasmparser::Operator::I32TruncF32S => Some(Operator::I32TruncF32S),
&wasmparser::Operator::I32TruncF32U => Some(Operator::I32TruncF32U),
&wasmparser::Operator::I32TruncF64S => Some(Operator::I32TruncF64S),
&wasmparser::Operator::I32TruncF64U => Some(Operator::I32TruncF64U),
&wasmparser::Operator::I64ExtendI32S => Some(Operator::I64ExtendI32S),
&wasmparser::Operator::I64ExtendI32U => Some(Operator::I64ExtendI32U),
&wasmparser::Operator::I64TruncF32S => Some(Operator::I64TruncF32S),
&wasmparser::Operator::I64TruncF32U => Some(Operator::I64TruncF32U),
&wasmparser::Operator::I64TruncF64S => Some(Operator::I64TruncF64S),
&wasmparser::Operator::I64TruncF64U => Some(Operator::I64TruncF64U),
&wasmparser::Operator::F32ConvertI32S => Some(Operator::F32ConvertI32S),
&wasmparser::Operator::F32ConvertI32U => Some(Operator::F32ConvertI32U),
&wasmparser::Operator::F32ConvertI64S => Some(Operator::F32ConvertI64S),
&wasmparser::Operator::F32ConvertI64U => Some(Operator::F32ConvertI64U),
&wasmparser::Operator::F32DemoteF64 => Some(Operator::F32DemoteF64),
&wasmparser::Operator::F64ConvertI32S => Some(Operator::F64ConvertI32S),
&wasmparser::Operator::F64ConvertI32U => Some(Operator::F64ConvertI32U),
&wasmparser::Operator::F64ConvertI64S => Some(Operator::F64ConvertI64S),
&wasmparser::Operator::F64ConvertI64U => Some(Operator::F64ConvertI64U),
&wasmparser::Operator::F64PromoteF32 => Some(Operator::F64PromoteF32),
&wasmparser::Operator::I32Extend8S => Some(Operator::I32Extend8S),
&wasmparser::Operator::I32Extend16S => Some(Operator::I32Extend16S),
&wasmparser::Operator::I64Extend8S => Some(Operator::I64Extend8S),
&wasmparser::Operator::I64Extend16S => Some(Operator::I64Extend16S),
&wasmparser::Operator::I64Extend32S => Some(Operator::I64Extend32S),
&wasmparser::Operator::I32TruncSatF32S => Some(Operator::I32TruncSatF32S),
&wasmparser::Operator::I32TruncSatF32U => Some(Operator::I32TruncSatF32U),
&wasmparser::Operator::I32TruncSatF64S => Some(Operator::I32TruncSatF64S),
&wasmparser::Operator::I32TruncSatF64U => Some(Operator::I32TruncSatF64U),
&wasmparser::Operator::I64TruncSatF32S => Some(Operator::I64TruncSatF32S),
&wasmparser::Operator::I64TruncSatF32U => Some(Operator::I64TruncSatF32U),
&wasmparser::Operator::I64TruncSatF64S => Some(Operator::I64TruncSatF64S),
&wasmparser::Operator::I64TruncSatF64U => Some(Operator::I64TruncSatF64U),
&wasmparser::Operator::F32ReinterpretI32 => Some(Operator::F32ReinterpretI32),
&wasmparser::Operator::F64ReinterpretI64 => Some(Operator::F64ReinterpretI64),
&wasmparser::Operator::I32ReinterpretF32 => Some(Operator::I32ReinterpretF32),
&wasmparser::Operator::I64ReinterpretF64 => Some(Operator::I64ReinterpretF64),
&wasmparser::Operator::TableGet { table } => Some(Operator::TableGet { table }),
&wasmparser::Operator::TableSet { table } => Some(Operator::TableSet { table }),
&wasmparser::Operator::TableGrow { table } => Some(Operator::TableGrow { table }),
&wasmparser::Operator::TableSize { table } => Some(Operator::TableSize { table }),
&wasmparser::Operator::MemorySize { mem, .. } => Some(Operator::MemorySize { mem }),
&wasmparser::Operator::MemoryGrow { mem, .. } => Some(Operator::MemoryGrow { mem }),
&wasmparser::Operator::I32Const { value } => Ok(Operator::I32Const { value }),
&wasmparser::Operator::I64Const { value } => Ok(Operator::I64Const { value }),
&wasmparser::Operator::F32Const { value } => Ok(Operator::F32Const { value }),
&wasmparser::Operator::F64Const { value } => Ok(Operator::F64Const { value }),
&wasmparser::Operator::I32Eqz => Ok(Operator::I32Eqz),
&wasmparser::Operator::I32Eq => Ok(Operator::I32Eq),
&wasmparser::Operator::I32Ne => Ok(Operator::I32Ne),
&wasmparser::Operator::I32LtS => Ok(Operator::I32LtS),
&wasmparser::Operator::I32LtU => Ok(Operator::I32LtU),
&wasmparser::Operator::I32GtS => Ok(Operator::I32GtS),
&wasmparser::Operator::I32GtU => Ok(Operator::I32GtU),
&wasmparser::Operator::I32LeS => Ok(Operator::I32LeS),
&wasmparser::Operator::I32LeU => Ok(Operator::I32LeU),
&wasmparser::Operator::I32GeS => Ok(Operator::I32GeS),
&wasmparser::Operator::I32GeU => Ok(Operator::I32GeU),
&wasmparser::Operator::I64Eqz => Ok(Operator::I64Eqz),
&wasmparser::Operator::I64Eq => Ok(Operator::I64Eq),
&wasmparser::Operator::I64Ne => Ok(Operator::I64Ne),
&wasmparser::Operator::I64LtS => Ok(Operator::I64LtS),
&wasmparser::Operator::I64LtU => Ok(Operator::I64LtU),
&wasmparser::Operator::I64GtU => Ok(Operator::I64GtU),
&wasmparser::Operator::I64GtS => Ok(Operator::I64GtS),
&wasmparser::Operator::I64LeS => Ok(Operator::I64LeS),
&wasmparser::Operator::I64LeU => Ok(Operator::I64LeU),
&wasmparser::Operator::I64GeS => Ok(Operator::I64GeS),
&wasmparser::Operator::I64GeU => Ok(Operator::I64GeU),
&wasmparser::Operator::F32Eq => Ok(Operator::F32Eq),
&wasmparser::Operator::F32Ne => Ok(Operator::F32Ne),
&wasmparser::Operator::F32Lt => Ok(Operator::F32Lt),
&wasmparser::Operator::F32Gt => Ok(Operator::F32Gt),
&wasmparser::Operator::F32Le => Ok(Operator::F32Le),
&wasmparser::Operator::F32Ge => Ok(Operator::F32Ge),
&wasmparser::Operator::F64Eq => Ok(Operator::F64Eq),
&wasmparser::Operator::F64Ne => Ok(Operator::F64Ne),
&wasmparser::Operator::F64Lt => Ok(Operator::F64Lt),
&wasmparser::Operator::F64Gt => Ok(Operator::F64Gt),
&wasmparser::Operator::F64Le => Ok(Operator::F64Le),
&wasmparser::Operator::F64Ge => Ok(Operator::F64Ge),
&wasmparser::Operator::I32Clz => Ok(Operator::I32Clz),
&wasmparser::Operator::I32Ctz => Ok(Operator::I32Ctz),
&wasmparser::Operator::I32Popcnt => Ok(Operator::I32Popcnt),
&wasmparser::Operator::I32Add => Ok(Operator::I32Add),
&wasmparser::Operator::I32Sub => Ok(Operator::I32Sub),
&wasmparser::Operator::I32Mul => Ok(Operator::I32Mul),
&wasmparser::Operator::I32DivS => Ok(Operator::I32DivS),
&wasmparser::Operator::I32DivU => Ok(Operator::I32DivU),
&wasmparser::Operator::I32RemS => Ok(Operator::I32RemS),
&wasmparser::Operator::I32RemU => Ok(Operator::I32RemU),
&wasmparser::Operator::I32And => Ok(Operator::I32And),
&wasmparser::Operator::I32Or => Ok(Operator::I32Or),
&wasmparser::Operator::I32Xor => Ok(Operator::I32Xor),
&wasmparser::Operator::I32Shl => Ok(Operator::I32Shl),
&wasmparser::Operator::I32ShrS => Ok(Operator::I32ShrS),
&wasmparser::Operator::I32ShrU => Ok(Operator::I32ShrU),
&wasmparser::Operator::I32Rotl => Ok(Operator::I32Rotl),
&wasmparser::Operator::I32Rotr => Ok(Operator::I32Rotr),
&wasmparser::Operator::I64Clz => Ok(Operator::I64Clz),
&wasmparser::Operator::I64Ctz => Ok(Operator::I64Ctz),
&wasmparser::Operator::I64Popcnt => Ok(Operator::I64Popcnt),
&wasmparser::Operator::I64Add => Ok(Operator::I64Add),
&wasmparser::Operator::I64Sub => Ok(Operator::I64Sub),
&wasmparser::Operator::I64Mul => Ok(Operator::I64Mul),
&wasmparser::Operator::I64DivS => Ok(Operator::I64DivS),
&wasmparser::Operator::I64DivU => Ok(Operator::I64DivU),
&wasmparser::Operator::I64RemS => Ok(Operator::I64RemS),
&wasmparser::Operator::I64RemU => Ok(Operator::I64RemU),
&wasmparser::Operator::I64And => Ok(Operator::I64And),
&wasmparser::Operator::I64Or => Ok(Operator::I64Or),
&wasmparser::Operator::I64Xor => Ok(Operator::I64Xor),
&wasmparser::Operator::I64Shl => Ok(Operator::I64Shl),
&wasmparser::Operator::I64ShrS => Ok(Operator::I64ShrS),
&wasmparser::Operator::I64ShrU => Ok(Operator::I64ShrU),
&wasmparser::Operator::I64Rotl => Ok(Operator::I64Rotl),
&wasmparser::Operator::I64Rotr => Ok(Operator::I64Rotr),
&wasmparser::Operator::F32Abs => Ok(Operator::F32Abs),
&wasmparser::Operator::F32Neg => Ok(Operator::F32Neg),
&wasmparser::Operator::F32Ceil => Ok(Operator::F32Ceil),
&wasmparser::Operator::F32Floor => Ok(Operator::F32Floor),
&wasmparser::Operator::F32Trunc => Ok(Operator::F32Trunc),
&wasmparser::Operator::F32Nearest => Ok(Operator::F32Nearest),
&wasmparser::Operator::F32Sqrt => Ok(Operator::F32Sqrt),
&wasmparser::Operator::F32Add => Ok(Operator::F32Add),
&wasmparser::Operator::F32Sub => Ok(Operator::F32Sub),
&wasmparser::Operator::F32Mul => Ok(Operator::F32Mul),
&wasmparser::Operator::F32Div => Ok(Operator::F32Div),
&wasmparser::Operator::F32Min => Ok(Operator::F32Min),
&wasmparser::Operator::F32Max => Ok(Operator::F32Max),
&wasmparser::Operator::F32Copysign => Ok(Operator::F32Copysign),
&wasmparser::Operator::F64Abs => Ok(Operator::F64Abs),
&wasmparser::Operator::F64Neg => Ok(Operator::F64Neg),
&wasmparser::Operator::F64Ceil => Ok(Operator::F64Ceil),
&wasmparser::Operator::F64Floor => Ok(Operator::F64Floor),
&wasmparser::Operator::F64Trunc => Ok(Operator::F64Trunc),
&wasmparser::Operator::F64Nearest => Ok(Operator::F64Nearest),
&wasmparser::Operator::F64Sqrt => Ok(Operator::F64Sqrt),
&wasmparser::Operator::F64Add => Ok(Operator::F64Add),
&wasmparser::Operator::F64Sub => Ok(Operator::F64Sub),
&wasmparser::Operator::F64Mul => Ok(Operator::F64Mul),
&wasmparser::Operator::F64Div => Ok(Operator::F64Div),
&wasmparser::Operator::F64Min => Ok(Operator::F64Min),
&wasmparser::Operator::F64Max => Ok(Operator::F64Max),
&wasmparser::Operator::F64Copysign => Ok(Operator::F64Copysign),
&wasmparser::Operator::I32WrapI64 => Ok(Operator::I32WrapI64),
&wasmparser::Operator::I32TruncF32S => Ok(Operator::I32TruncF32S),
&wasmparser::Operator::I32TruncF32U => Ok(Operator::I32TruncF32U),
&wasmparser::Operator::I32TruncF64S => Ok(Operator::I32TruncF64S),
&wasmparser::Operator::I32TruncF64U => Ok(Operator::I32TruncF64U),
&wasmparser::Operator::I64ExtendI32S => Ok(Operator::I64ExtendI32S),
&wasmparser::Operator::I64ExtendI32U => Ok(Operator::I64ExtendI32U),
&wasmparser::Operator::I64TruncF32S => Ok(Operator::I64TruncF32S),
&wasmparser::Operator::I64TruncF32U => Ok(Operator::I64TruncF32U),
&wasmparser::Operator::I64TruncF64S => Ok(Operator::I64TruncF64S),
&wasmparser::Operator::I64TruncF64U => Ok(Operator::I64TruncF64U),
&wasmparser::Operator::F32ConvertI32S => Ok(Operator::F32ConvertI32S),
&wasmparser::Operator::F32ConvertI32U => Ok(Operator::F32ConvertI32U),
&wasmparser::Operator::F32ConvertI64S => Ok(Operator::F32ConvertI64S),
&wasmparser::Operator::F32ConvertI64U => Ok(Operator::F32ConvertI64U),
&wasmparser::Operator::F32DemoteF64 => Ok(Operator::F32DemoteF64),
&wasmparser::Operator::F64ConvertI32S => Ok(Operator::F64ConvertI32S),
&wasmparser::Operator::F64ConvertI32U => Ok(Operator::F64ConvertI32U),
&wasmparser::Operator::F64ConvertI64S => Ok(Operator::F64ConvertI64S),
&wasmparser::Operator::F64ConvertI64U => Ok(Operator::F64ConvertI64U),
&wasmparser::Operator::F64PromoteF32 => Ok(Operator::F64PromoteF32),
&wasmparser::Operator::I32Extend8S => Ok(Operator::I32Extend8S),
&wasmparser::Operator::I32Extend16S => Ok(Operator::I32Extend16S),
&wasmparser::Operator::I64Extend8S => Ok(Operator::I64Extend8S),
&wasmparser::Operator::I64Extend16S => Ok(Operator::I64Extend16S),
&wasmparser::Operator::I64Extend32S => Ok(Operator::I64Extend32S),
&wasmparser::Operator::I32TruncSatF32S => Ok(Operator::I32TruncSatF32S),
&wasmparser::Operator::I32TruncSatF32U => Ok(Operator::I32TruncSatF32U),
&wasmparser::Operator::I32TruncSatF64S => Ok(Operator::I32TruncSatF64S),
&wasmparser::Operator::I32TruncSatF64U => Ok(Operator::I32TruncSatF64U),
&wasmparser::Operator::I64TruncSatF32S => Ok(Operator::I64TruncSatF32S),
&wasmparser::Operator::I64TruncSatF32U => Ok(Operator::I64TruncSatF32U),
&wasmparser::Operator::I64TruncSatF64S => Ok(Operator::I64TruncSatF64S),
&wasmparser::Operator::I64TruncSatF64U => Ok(Operator::I64TruncSatF64U),
&wasmparser::Operator::F32ReinterpretI32 => Ok(Operator::F32ReinterpretI32),
&wasmparser::Operator::F64ReinterpretI64 => Ok(Operator::F64ReinterpretI64),
&wasmparser::Operator::I32ReinterpretF32 => Ok(Operator::I32ReinterpretF32),
&wasmparser::Operator::I64ReinterpretF64 => Ok(Operator::I64ReinterpretF64),
&wasmparser::Operator::TableGet { table } => Ok(Operator::TableGet { table }),
&wasmparser::Operator::TableSet { table } => Ok(Operator::TableSet { table }),
&wasmparser::Operator::TableGrow { table } => Ok(Operator::TableGrow { table }),
&wasmparser::Operator::TableSize { table } => Ok(Operator::TableSize { table }),
&wasmparser::Operator::MemorySize { mem, .. } => Ok(Operator::MemorySize { mem }),
&wasmparser::Operator::MemoryGrow { mem, .. } => Ok(Operator::MemoryGrow { mem }),
_ => Err(()),
}
}
}
impl<'a> std::convert::Into<wasmparser::Operator<'a>> for Operator {
fn into(self) -> wasmparser::Operator<'a> {
match op {
match &self {
&Operator::Unreachable => wasmparser::Operator::Unreachable,
&Operator::Nop => wasmparser::Operator::Nop,
&Operator::Call { function_index } => wasmparser::Operator::Call {
@ -715,7 +718,7 @@ impl<'a> std::convert::Into<wasmparser::Operator<'a>> for Operator {
}
impl std::convert::From<MemoryImmediate> for Memory {
fn from(value: &MemoryImmediate) -> Memory {
fn from(value: MemoryImmediate) -> Memory {
Memory {
align: value.align,
offset: value.offset,