This commit is contained in:
Chris Fallin 2022-11-03 10:57:56 -07:00
parent 754492c860
commit 71bd0b399d
4 changed files with 47 additions and 30 deletions

View file

@ -27,11 +27,14 @@ pub fn wasm_to_ir(bytes: &[u8]) -> Result<Module<'_>> {
Ok(module)
}
fn parse_init_expr<'a>(init_expr: &wasmparser::InitExpr<'a>) -> Result<usize> {
fn parse_init_expr<'a>(init_expr: &wasmparser::InitExpr<'a>) -> Result<Option<u64>> {
let operators = init_expr
.get_operators_reader()
.into_iter()
.collect::<Result<Vec<wasmparser::Operator>, _>>()?;
if operators.len() == 1 && matches!(&operators[0], &wasmparser::Operator::End) {
return Ok(None);
}
if operators.len() != 2 || !matches!(&operators[1], &wasmparser::Operator::End) {
anyhow::bail!(
"Unsupported operator seq in base-address expr: {:?}",
@ -39,8 +42,10 @@ fn parse_init_expr<'a>(init_expr: &wasmparser::InitExpr<'a>) -> Result<usize> {
);
}
Ok(match &operators[0] {
&wasmparser::Operator::I32Const { value } => value as usize,
&wasmparser::Operator::I64Const { value } => value as usize,
&wasmparser::Operator::I32Const { value } => Some(value as u64),
&wasmparser::Operator::I64Const { value } => Some(value as u64),
&wasmparser::Operator::F32Const { value } => Some(value.bits() as u64),
&wasmparser::Operator::F64Const { value } => Some(value.bits()),
op => anyhow::bail!("Unsupported data segment base-address operator: {:?}", op),
})
}
@ -73,7 +78,8 @@ fn handle_payload<'a>(
Some(ImportKind::Func(func))
}
ImportSectionEntryType::Global(ty) => {
let global = module.frontend_add_global(ty.content_type.into());
let ty = ty.content_type.into();
let global = module.frontend_add_global(GlobalData { ty, value: None });
Some(ImportKind::Global(global))
}
ImportSectionEntryType::Table(ty) => {
@ -94,7 +100,12 @@ fn handle_payload<'a>(
Payload::GlobalSection(reader) => {
for global in reader {
let global = global?;
module.frontend_add_global(global.ty.content_type.into());
let ty = global.ty.content_type.into();
let init_expr = parse_init_expr(&global.init_expr)?;
module.frontend_add_global(GlobalData {
ty,
value: init_expr,
});
}
}
Payload::TableSection(reader) => {
@ -156,9 +167,9 @@ fn handle_payload<'a>(
} => {
let data = segment.data.to_vec();
let memory = Memory::from(*memory_index);
let offset = parse_init_expr(init_expr)?;
let offset = parse_init_expr(init_expr)?.unwrap_or(0) as usize;
module
.frontend_memory_mut(memory)
.memory_mut(memory)
.segments
.push(MemorySegment { offset, data });
}
@ -182,7 +193,7 @@ fn handle_payload<'a>(
init_expr,
} => {
let table = Table::from(*table_index);
let offset = parse_init_expr(&init_expr)?;
let offset = parse_init_expr(&init_expr)?.unwrap_or(0) as usize;
let items = element
.items
.get_items_reader()?
@ -197,11 +208,7 @@ fn handle_payload<'a>(
funcs.push(func);
}
let table_items = module
.frontend_table_mut(table)
.func_elements
.as_mut()
.unwrap();
let table_items = module.table_mut(table).func_elements.as_mut().unwrap();
if (offset + funcs.len()) > table_items.len() {
table_items.resize(offset + funcs.len(), Func::invalid());
}

View file

@ -155,8 +155,12 @@ impl<'a> Display for ModuleDisplay<'a> {
sig_strs.insert(sig, sig_str.clone());
writeln!(f, " {}: {}", sig, sig_str)?;
}
for (global, global_ty) in self.0.globals() {
writeln!(f, " {}: {}", global, global_ty)?;
for (global, global_data) in self.0.globals() {
writeln!(
f,
" {}: {:?} # {}",
global, global_data.value, global_data.ty
)?;
}
for (table, table_data) in self.0.tables() {
writeln!(f, " {}: {}", table, table_data.ty)?;

View file

@ -9,7 +9,7 @@ pub struct Module<'a> {
orig_bytes: &'a [u8],
funcs: EntityVec<Func, FuncDecl>,
signatures: EntityVec<Signature, SignatureData>,
globals: EntityVec<Global, Type>,
globals: EntityVec<Global, GlobalData>,
tables: EntityVec<Table, TableData>,
imports: Vec<Import>,
exports: Vec<Export>,
@ -43,6 +43,12 @@ pub struct TableData {
pub func_elements: Option<Vec<Func>>,
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct GlobalData {
pub ty: Type,
pub value: Option<u64>,
}
impl From<&wasmparser::FuncType> for SignatureData {
fn from(fty: &wasmparser::FuncType) -> Self {
Self {
@ -149,11 +155,11 @@ impl<'a> Module<'a> {
pub fn signatures<'b>(&'b self) -> impl Iterator<Item = (Signature, &'b SignatureData)> {
self.signatures.entries()
}
pub fn global_ty(&self, id: Global) -> Type {
self.globals[id]
pub fn global<'b>(&'b self, id: Global) -> &'b GlobalData {
&self.globals[id]
}
pub fn globals<'b>(&'b self) -> impl Iterator<Item = (Global, Type)> + 'b {
self.globals.entries().map(|(id, ty)| (id, *ty))
pub fn globals<'b>(&'b self) -> impl Iterator<Item = (Global, &'b GlobalData)> + 'b {
self.globals.entries()
}
pub fn table<'b>(&'b self, id: Table) -> &'b TableData {
&self.tables[id]
@ -170,6 +176,12 @@ impl<'a> Module<'a> {
pub fn exports<'b>(&'b self) -> impl Iterator<Item = &'b Export> + 'b {
self.exports.iter()
}
pub(crate) fn table_mut<'b>(&'b mut self, table: Table) -> &'b mut TableData {
&mut self.tables[table]
}
pub(crate) fn memory_mut<'b>(&'b mut self, memory: Memory) -> &'b mut MemoryData {
&mut self.memories[memory]
}
pub(crate) fn frontend_add_signature(&mut self, ty: SignatureData) {
self.signatures.push(ty);
@ -185,11 +197,8 @@ impl<'a> Module<'a> {
};
self.tables.push(TableData { ty, func_elements })
}
pub(crate) fn frontend_table_mut<'b>(&'b mut self, table: Table) -> &'b mut TableData {
&mut self.tables[table]
}
pub(crate) fn frontend_add_global(&mut self, ty: Type) -> Global {
self.globals.push(ty)
pub(crate) fn frontend_add_global(&mut self, global: GlobalData) -> Global {
self.globals.push(global)
}
pub(crate) fn frontend_add_import(&mut self, import: Import) {
self.imports.push(import);
@ -200,9 +209,6 @@ impl<'a> Module<'a> {
pub(crate) fn frontend_add_memory(&mut self, memory: MemoryData) -> Memory {
self.memories.push(memory)
}
pub(crate) fn frontend_memory_mut<'b>(&'b mut self, memory: Memory) -> &'b mut MemoryData {
&mut self.memories[memory]
}
pub fn from_wasm_bytes(bytes: &'a [u8]) -> Result<Self> {
let mut module = frontend::wasm_to_ir(bytes)?;

View file

@ -39,7 +39,7 @@ pub fn op_inputs(
&Operator::TypedSelect { ty } => Ok(vec![ty, ty, Type::I32].into()),
&Operator::GlobalGet { .. } => Ok(Cow::Borrowed(&[])),
&Operator::GlobalSet { global_index } => Ok(vec![module.global_ty(global_index)].into()),
&Operator::GlobalSet { global_index } => Ok(vec![module.global(global_index).ty].into()),
Operator::I32Load { .. }
| Operator::I64Load { .. }
@ -258,7 +258,7 @@ pub fn op_outputs(
Ok(vec![val_ty].into())
}
&Operator::TypedSelect { ty } => Ok(vec![ty].into()),
&Operator::GlobalGet { global_index } => Ok(vec![module.global_ty(global_index)].into()),
&Operator::GlobalGet { global_index } => Ok(vec![module.global(global_index).ty].into()),
&Operator::GlobalSet { .. } => Ok(Cow::Borrowed(&[])),
Operator::I32Load { .. }