This commit is contained in:
Chris Fallin 2022-11-22 23:30:11 -08:00
parent abc46f1d14
commit 1fbbbc9637
7 changed files with 69 additions and 68 deletions

View file

@ -7,7 +7,7 @@ license = "Apache-2.0 WITH LLVM-exception"
edition = "2018"
[dependencies]
wasmparser = { git = 'https://github.com/cfallin/wasm-tools', rev = '03a81b6a6ed4d5d9730fa71bf65636a3b1538ce7' }
wasmparser = "0.95"
anyhow = "1.0"
structopt = "0.3"
log = "0.4"

View file

@ -10,10 +10,7 @@ use anyhow::{bail, Result};
use fxhash::{FxHashMap, FxHashSet};
use log::trace;
use std::convert::TryFrom;
use wasmparser::{
DataKind, ExternalKind, Ieee32, Ieee64, ImportSectionEntryType, Parser, Payload, TypeDef,
TypeOrFuncType,
};
use wasmparser::{BlockType, DataKind, ExternalKind, Parser, Payload, TypeRef};
pub fn wasm_to_ir(bytes: &[u8]) -> Result<Module<'_>> {
let mut module = Module::with_orig_bytes(bytes);
@ -27,7 +24,7 @@ pub fn wasm_to_ir(bytes: &[u8]) -> Result<Module<'_>> {
Ok(module)
}
fn parse_init_expr<'a>(init_expr: &wasmparser::InitExpr<'a>) -> Result<Option<u64>> {
fn parse_init_expr<'a>(init_expr: &wasmparser::ConstExpr<'a>) -> Result<Option<u64>> {
let operators = init_expr
.get_operators_reader()
.into_iter()
@ -60,24 +57,23 @@ fn handle_payload<'a>(
Payload::TypeSection(reader) => {
for ty in reader {
let ty = ty?;
if let TypeDef::Func(fty) = ty {
module.frontend_add_signature(fty.into());
}
let wasmparser::Type::Func(fty) = ty;
module.frontend_add_signature(fty.into());
}
}
Payload::ImportSection(reader) => {
for import in reader {
let import = import?;
let module_name = import.module.to_owned();
let name = import.field.unwrap_or("").to_owned();
let name = import.name.to_owned();
let kind = match import.ty {
ImportSectionEntryType::Function(sig_idx) => {
TypeRef::Func(sig_idx) => {
let func =
module.frontend_add_func(FuncDecl::Import(Signature::from(sig_idx)));
*next_func += 1;
Some(ImportKind::Func(func))
}
ImportSectionEntryType::Global(ty) => {
TypeRef::Global(ty) => {
let mutable = ty.mutable;
let ty = ty.content_type.into();
let global = module.frontend_add_global(GlobalData {
@ -87,7 +83,7 @@ fn handle_payload<'a>(
});
Some(ImportKind::Global(global))
}
ImportSectionEntryType::Table(ty) => {
TypeRef::Table(ty) => {
let table = module.frontend_add_table(ty.element_type.into(), None);
Some(ImportKind::Table(table))
}
@ -140,9 +136,9 @@ fn handle_payload<'a>(
Payload::ExportSection(reader) => {
for export in reader {
let export = export?;
let name = export.field.to_owned();
let name = export.name.to_owned();
let kind = match export.kind {
ExternalKind::Function => Some(ExportKind::Func(Func::from(export.index))),
ExternalKind::Func => Some(ExportKind::Func(Func::from(export.index))),
ExternalKind::Table => Some(ExportKind::Table(Table::from(export.index))),
ExternalKind::Global => Some(ExportKind::Global(Global::from(export.index))),
ExternalKind::Memory => Some(ExportKind::Memory(Memory::from(export.index))),
@ -170,11 +166,11 @@ fn handle_payload<'a>(
DataKind::Passive => {}
DataKind::Active {
memory_index,
init_expr,
offset_expr,
} => {
let data = segment.data.to_vec();
let memory = Memory::from(*memory_index);
let offset = parse_init_expr(init_expr)?.unwrap_or(0) as usize;
let offset = parse_init_expr(offset_expr)?.unwrap_or(0) as usize;
module
.memory_mut(memory)
.segments
@ -189,7 +185,7 @@ fn handle_payload<'a>(
Payload::ElementSection(reader) => {
for element in reader {
let element = element?;
if element.ty != wasmparser::Type::FuncRef {
if element.ty != wasmparser::ValType::FuncRef {
anyhow::bail!("Unsupported table type: {:?}", element.ty);
}
match &element.kind {
@ -197,10 +193,10 @@ fn handle_payload<'a>(
wasmparser::ElementKind::Declared => {}
wasmparser::ElementKind::Active {
table_index,
init_expr,
offset_expr,
} => {
let table = Table::from(*table_index);
let offset = parse_init_expr(&init_expr)?.unwrap_or(0) as usize;
let offset = parse_init_expr(&offset_expr)?.unwrap_or(0) as usize;
let items = element
.items
.get_items_reader()?
@ -224,7 +220,7 @@ fn handle_payload<'a>(
}
}
}
Payload::End => {}
Payload::End(_) => {}
payload => {
log::warn!("Skipping section: {:?}", payload);
}
@ -453,16 +449,12 @@ impl LocalTracker {
vec![ty],
)),
Type::F32 => body.add_value(ValueDef::Operator(
Operator::F32Const {
value: Ieee32::from_bits(0),
},
Operator::F32Const { value: 0 },
vec![],
vec![ty],
)),
Type::F64 => body.add_value(ValueDef::Operator(
Operator::F64Const {
value: Ieee64::from_bits(0),
},
Operator::F64Const { value: 0 },
vec![],
vec![ty],
)),
@ -1021,8 +1013,8 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
}
}
wasmparser::Operator::Block { ty } => {
let (params, results) = self.block_params_and_results(*ty);
wasmparser::Operator::Block { blockty } => {
let (params, results) = self.block_params_and_results(*blockty);
let out = self.body.add_block();
self.add_block_params(out, &results[..]);
let start_depth = self.op_stack.len() - params.len();
@ -1034,8 +1026,8 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
});
}
wasmparser::Operator::Loop { ty } => {
let (params, results) = self.block_params_and_results(*ty);
wasmparser::Operator::Loop { blockty } => {
let (params, results) = self.block_params_and_results(*blockty);
let header = self.body.add_block();
self.add_block_params(header, &params[..]);
let initial_args = self.pop_n(params.len());
@ -1055,8 +1047,8 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
});
}
wasmparser::Operator::If { ty } => {
let (params, results) = self.block_params_and_results(*ty);
wasmparser::Operator::If { blockty } => {
let (params, results) = self.block_params_and_results(*blockty);
let if_true = self.body.add_block();
let if_false = self.body.add_block();
let join = self.body.add_block();
@ -1140,20 +1132,20 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
}
}
wasmparser::Operator::BrTable { table } => {
wasmparser::Operator::BrTable { targets } => {
// Get the selector index.
let index = self.pop_1();
// Get the signature of the default frame; this tells
// us the signature of all frames (since wasmparser
// validates the input for us). Pop that many args.
let default_frame = self.relative_frame(table.default());
let default_frame = self.relative_frame(targets.default());
let default_term_target = default_frame.br_target();
let arg_len = default_frame.br_args().len();
let args = self.pop_n(arg_len);
// Generate a branch terminator with the same args for
// every branch target.
let mut term_targets = vec![];
for target in table.targets() {
for target in targets.targets() {
let target = target?;
let frame = self.relative_frame(target);
assert_eq!(frame.br_args().len(), args.len());
@ -1181,11 +1173,11 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
}
}
fn block_params_and_results(&self, ty: TypeOrFuncType) -> (Vec<Type>, Vec<Type>) {
fn block_params_and_results(&self, ty: BlockType) -> (Vec<Type>, Vec<Type>) {
match ty {
TypeOrFuncType::Type(wasmparser::Type::EmptyBlockType) => (vec![], vec![]),
TypeOrFuncType::Type(ret_ty) => (vec![], vec![ret_ty.into()]),
TypeOrFuncType::FuncType(sig_idx) => {
BlockType::Empty => (vec![], vec![]),
BlockType::Type(ret_ty) => (vec![], vec![ret_ty.into()]),
BlockType::FuncType(sig_idx) => {
let sig = &self.module.signature(Signature::from(sig_idx));
(
Vec::from(sig.params.clone()),

View file

@ -11,15 +11,15 @@ pub enum Type {
V128,
FuncRef,
}
impl From<wasmparser::Type> for Type {
fn from(ty: wasmparser::Type) -> Self {
impl From<wasmparser::ValType> for Type {
fn from(ty: wasmparser::ValType) -> Self {
match ty {
wasmparser::Type::I32 => Type::I32,
wasmparser::Type::I64 => Type::I64,
wasmparser::Type::F32 => Type::F32,
wasmparser::Type::F64 => Type::F64,
wasmparser::Type::V128 => Type::V128,
wasmparser::Type::FuncRef => Type::FuncRef,
wasmparser::ValType::I32 => Type::I32,
wasmparser::ValType::I64 => Type::I64,
wasmparser::ValType::F32 => Type::F32,
wasmparser::ValType::F64 => Type::F64,
wasmparser::ValType::V128 => Type::V128,
wasmparser::ValType::FuncRef => Type::FuncRef,
_ => panic!("Unsupported type: {:?}", ty),
}
}

View file

@ -53,12 +53,12 @@ impl From<&wasmparser::FuncType> for SignatureData {
fn from(fty: &wasmparser::FuncType) -> Self {
Self {
params: fty
.params
.params()
.iter()
.map(|&ty| ty.into())
.collect::<Vec<Type>>(),
returns: fty
.returns
.results()
.iter()
.map(|&ty| ty.into())
.collect::<Vec<Type>>(),

View file

@ -1,7 +1,7 @@
//! Metadata on operators.
use crate::entity::EntityVec;
use crate::ir::{Global, Local, Module, Signature, Table, Type, Value};
use crate::ir::{Local, Module, Signature, Type, Value};
use crate::Operator;
use anyhow::Result;
use std::borrow::Cow;
@ -711,8 +711,8 @@ impl std::fmt::Display for Operator {
Operator::I32Const { value } => write!(f, "i32const<{}>", value)?,
Operator::I64Const { value } => write!(f, "i64const<{}>", value)?,
Operator::F32Const { value } => write!(f, "f32const<{}>", value.bits())?,
Operator::F64Const { value } => write!(f, "f64const<{}>", value.bits())?,
Operator::F32Const { value } => write!(f, "f32const<{}>", value)?,
Operator::F64Const { value } => write!(f, "f64const<{}>", value)?,
Operator::I32Eqz => write!(f, "i32eqz")?,
Operator::I32Eq => write!(f, "i32eq")?,

View file

@ -2,7 +2,6 @@
use crate::{Func, Global, Local, Memory, Signature, Table, Type};
use std::convert::TryFrom;
use wasmparser::MemoryImmediate;
pub use wasmparser::{Ieee32, Ieee64};
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
@ -127,16 +126,16 @@ pub enum Operator {
},
I32Const {
value: i32,
value: u32,
},
I64Const {
value: i64,
value: u64,
},
F32Const {
value: Ieee32,
value: u32,
},
F64Const {
value: Ieee64,
value: u64,
},
I32Eqz,
@ -319,9 +318,11 @@ impl<'a, 'b> std::convert::TryFrom<&'b wasmparser::Operator<'a>> for Operator {
function_index: Func::from(function_index),
}),
&wasmparser::Operator::CallIndirect {
index, table_index, ..
type_index,
table_index,
..
} => Ok(Operator::CallIndirect {
sig_index: Signature::from(index),
sig_index: Signature::from(type_index),
table_index: Table::from(table_index),
}),
&wasmparser::Operator::Return => Ok(Operator::Return),
@ -413,10 +414,18 @@ impl<'a, 'b> std::convert::TryFrom<&'b wasmparser::Operator<'a>> for Operator {
&wasmparser::Operator::I64Store32 { memarg } => Ok(Operator::I64Store32 {
memory: memarg.into(),
}),
&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::I32Const { value } => Ok(Operator::I32Const {
value: value as u32,
}),
&wasmparser::Operator::I64Const { value } => Ok(Operator::I64Const {
value: value as u64,
}),
&wasmparser::Operator::F32Const { value } => Ok(Operator::F32Const {
value: value.bits(),
}),
&wasmparser::Operator::F64Const { value } => Ok(Operator::F64Const {
value: value.bits(),
}),
&wasmparser::Operator::I32Eqz => Ok(Operator::I32Eqz),
&wasmparser::Operator::I32Eq => Ok(Operator::I32Eq),
&wasmparser::Operator::I32Ne => Ok(Operator::I32Ne),
@ -576,8 +585,8 @@ impl<'a, 'b> std::convert::TryFrom<&'b wasmparser::Operator<'a>> for Operator {
}
}
impl std::convert::From<MemoryImmediate> for MemoryArg {
fn from(value: MemoryImmediate) -> MemoryArg {
impl std::convert::From<wasmparser::MemArg> for MemoryArg {
fn from(value: wasmparser::MemArg) -> MemoryArg {
MemoryArg {
align: value.align as u32,
offset: u32::try_from(value.offset).expect("offset too large"),

View file

@ -204,7 +204,7 @@ impl GVNPass {
match const_val {
Some(ConstVal::I32(val)) => {
value = ValueDef::Operator(
Operator::I32Const { value: val as i32 },
Operator::I32Const { value: val },
vec![],
vec![Type::I32],
);
@ -212,7 +212,7 @@ impl GVNPass {
}
Some(ConstVal::I64(val)) => {
value = ValueDef::Operator(
Operator::I64Const { value: val as i64 },
Operator::I64Const { value: val },
vec![],
vec![Type::I64],
);