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_preds = vec![SmallVec::new(); f.blocks.len()];
let mut block_succs = vec![SmallVec::new(); f.blocks.len()]; let mut block_succs = vec![SmallVec::new(); f.blocks.len()];
for block in 0..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_preds[succ].push(block);
block_succs[block].push(succ); block_succs[block].push(succ);
} });
} }
let mut return_blocks = vec![]; 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. //! Intermediate representation for Wasm.
use std::collections::hash_map::Entry;
use crate::{backend::Shape, cfg::CFGInfo, frontend, Operator}; use crate::{backend::Shape, cfg::CFGInfo, frontend, Operator};
use anyhow::Result; use anyhow::Result;
use fxhash::FxHashMap; use fxhash::FxHashMap;
@ -68,10 +70,72 @@ impl FunctionBody {
} }
pub fn add_value(&mut self, value: ValueDef, ty: Option<Type>) -> Value { pub fn add_value(&mut self, value: ValueDef, ty: Option<Type>) -> Value {
let id = Value(self.values.len() as u32); match self.value_dedup.entry(value.clone()) {
self.values.push(value); 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); 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) { pub fn append_to_block(&mut self, block: BlockId, value: Value) {
@ -130,11 +194,19 @@ pub struct Block {
pub preds: Vec<BlockId>, pub preds: Vec<BlockId>,
/// For each predecessor block, our index in its `succs` array. /// For each predecessor block, our index in its `succs` array.
pub pos_in_pred_succ: Vec<usize>, pub pos_in_pred_succ: Vec<usize>,
/// Type of each blockparam.
pub params: Vec<Type>,
} }
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Value(u32); 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 { impl Value {
pub fn undef() -> Self { pub fn undef() -> Self {
Value(u32::MAX) Value(u32::MAX)
@ -157,10 +229,12 @@ impl std::default::Default for Value {
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum ValueDef { pub enum ValueDef {
Arg { index: usize }, Arg(usize),
BlockParam { block: BlockId, index: usize }, BlockParam(BlockId, usize),
Operator { op: Operator, args: Vec<Value> }, Operator(Operator, Vec<Value>),
PickOutput { from: Value, index: usize }, PickOutput(Value, usize),
Alias(Value),
Placeholder,
} }
impl ValueDef { impl ValueDef {
@ -168,12 +242,14 @@ impl ValueDef {
match self { match self {
&ValueDef::Arg { .. } => {} &ValueDef::Arg { .. } => {}
&ValueDef::BlockParam { .. } => {} &ValueDef::BlockParam { .. } => {}
&ValueDef::Operator { ref args, .. } => { &ValueDef::Operator(_, ref args) => {
for &arg in args { for &arg in args {
f(arg); 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 { match self {
&mut ValueDef::Arg { .. } => {} &mut ValueDef::Arg { .. } => {}
&mut ValueDef::BlockParam { .. } => {} &mut ValueDef::BlockParam { .. } => {}
&mut ValueDef::Operator { ref mut args, .. } => { &mut ValueDef::Operator(_, ref mut args) => {
for arg in args { for arg in args {
f(arg); 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)] #[derive(Clone, Debug)]
pub enum Terminator { pub enum Terminator {
Br { Br {
target: BlockId, target: BlockTarget,
}, },
CondBr { CondBr {
cond: Value, cond: Value,
if_true: BlockId, if_true: BlockTarget,
if_false: BlockId, if_false: BlockTarget,
}, },
Select { Select {
value: Value, value: Value,
targets: Vec<BlockId>, targets: Vec<BlockTarget>,
default: BlockId, default: BlockTarget,
}, },
Return { Return {
values: Vec<Value>, values: Vec<Value>,
@ -219,31 +303,126 @@ impl std::default::Default for Terminator {
} }
impl 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 { match self {
Terminator::Return { .. } => {} Terminator::Return { .. } => {}
Terminator::Br { target, .. } => f(*target), Terminator::Br { ref target, .. } => f(target),
Terminator::CondBr { Terminator::CondBr {
if_true, if_false, .. ref if_true,
ref if_false,
..
} => { } => {
f(*if_true); f(if_true);
f(*if_false); f(if_false);
} }
Terminator::Select { Terminator::Select {
ref targets, ref targets,
default, ref default,
.. ..
} => { } => {
for &target in targets { f(default);
for target in targets {
f(target); f(target);
} }
f(*default);
} }
Terminator::None => {} 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) { pub fn visit_uses<F: FnMut(Value)>(&self, mut f: F) {
self.visit_targets(|target| {
for &arg in &target.args {
f(arg);
}
});
match self { match self {
&Terminator::CondBr { cond, .. } => f(cond), &Terminator::CondBr { cond, .. } => f(cond),
&Terminator::Select { value, .. } => f(value), &Terminator::Select { value, .. } => f(value),
@ -257,6 +436,11 @@ impl Terminator {
} }
pub fn update_uses<F: FnMut(&mut Value)>(&mut self, mut f: F) { 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 { match self {
&mut Terminator::CondBr { ref mut cond, .. } => f(cond), &mut Terminator::CondBr { ref mut cond, .. } => f(cond),
&mut Terminator::Select { ref mut value, .. } => f(value), &mut Terminator::Select { ref mut value, .. } => f(value),

View file

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