diff --git a/src/backend/mod.rs b/src/backend/mod.rs index a289527..dd6da27 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -519,7 +519,7 @@ pub fn compile(module: &Module<'_>) -> anyhow::Result> { let mut into_mod = wasm_encoder::Module::new(); let mut types = wasm_encoder::TypeSection::new(); - for (_sig, sig_data) in module.signatures() { + for sig_data in module.signatures.values() { let params = sig_data .params .iter() @@ -537,16 +537,16 @@ pub fn compile(module: &Module<'_>) -> anyhow::Result> { let mut num_table_imports = 0; let mut num_global_imports = 0; let mut num_mem_imports = 0; - for import in module.imports() { + for import in &module.imports { let entity = match &import.kind { &ImportKind::Func(func) => { num_func_imports += 1; - let func = module.func(func); + let func = &module.funcs[func]; wasm_encoder::EntityType::Function(func.sig().index() as u32) } &ImportKind::Table(table) => { num_table_imports += 1; - let table = module.table(table); + let table = &module.tables[table]; wasm_encoder::EntityType::Table(wasm_encoder::TableType { element_type: wasm_encoder::ValType::from(table.ty), minimum: table @@ -559,7 +559,7 @@ pub fn compile(module: &Module<'_>) -> anyhow::Result> { } &ImportKind::Global(global) => { num_global_imports += 1; - let global = module.global(global); + let global = &module.globals[global]; wasm_encoder::EntityType::Global(wasm_encoder::GlobalType { val_type: wasm_encoder::ValType::from(global.ty), mutable: global.mutable, @@ -567,7 +567,7 @@ pub fn compile(module: &Module<'_>) -> anyhow::Result> { } &ImportKind::Memory(mem) => { num_mem_imports += 1; - let mem = module.memory(mem); + let mem = &module.memories[mem]; wasm_encoder::EntityType::Memory(wasm_encoder::MemoryType { memory64: false, shared: false, @@ -582,7 +582,7 @@ pub fn compile(module: &Module<'_>) -> anyhow::Result> { into_mod.section(&imports); let mut funcs = wasm_encoder::FunctionSection::new(); - for (func, func_decl) in module.funcs().skip(num_func_imports) { + for (func, func_decl) in module.funcs.entries().skip(num_func_imports) { match func_decl { FuncDecl::Import(_) => anyhow::bail!("Import comes after func with body: {}", func), FuncDecl::Body(sig, _) => { @@ -593,7 +593,7 @@ pub fn compile(module: &Module<'_>) -> anyhow::Result> { into_mod.section(&funcs); let mut tables = wasm_encoder::TableSection::new(); - for (_table, table_data) in module.tables().skip(num_table_imports) { + for table_data in module.tables.values().skip(num_table_imports) { tables.table(wasm_encoder::TableType { element_type: wasm_encoder::ValType::from(table_data.ty), minimum: table_data @@ -607,7 +607,7 @@ pub fn compile(module: &Module<'_>) -> anyhow::Result> { into_mod.section(&tables); let mut memories = wasm_encoder::MemorySection::new(); - for (_mem, mem_data) in module.memories().skip(num_mem_imports) { + for mem_data in module.memories.values().skip(num_mem_imports) { memories.memory(wasm_encoder::MemoryType { minimum: mem_data.initial_pages as u64, maximum: mem_data.maximum_pages.map(|val| val as u64), @@ -618,7 +618,7 @@ pub fn compile(module: &Module<'_>) -> anyhow::Result> { into_mod.section(&memories); let mut globals = wasm_encoder::GlobalSection::new(); - for (_global, global_data) in module.globals().skip(num_global_imports) { + for global_data in module.globals.values().skip(num_global_imports) { globals.global( wasm_encoder::GlobalType { val_type: wasm_encoder::ValType::from(global_data.ty), @@ -630,7 +630,7 @@ pub fn compile(module: &Module<'_>) -> anyhow::Result> { into_mod.section(&globals); let mut exports = wasm_encoder::ExportSection::new(); - for export in module.exports() { + for export in &module.exports { match &export.kind { &ExportKind::Table(table) => { exports.export( @@ -672,7 +672,7 @@ pub fn compile(module: &Module<'_>) -> anyhow::Result> { } let mut elem = wasm_encoder::ElementSection::new(); - for (table, table_data) in module.tables() { + for (table, table_data) in module.tables.entries() { if let Some(elts) = &table_data.func_elements { for (i, &elt) in elts.iter().enumerate() { if elt.is_valid() { @@ -690,7 +690,8 @@ pub fn compile(module: &Module<'_>) -> anyhow::Result> { let mut code = wasm_encoder::CodeSection::new(); let bodies = module - .funcs() + .funcs + .entries() .skip(num_func_imports) .collect::>() .par_iter() @@ -707,7 +708,7 @@ pub fn compile(module: &Module<'_>) -> anyhow::Result> { into_mod.section(&code); let mut data = wasm_encoder::DataSection::new(); - for (mem, mem_data) in module.memories() { + for (mem, mem_data) in module.memories.entries() { for segment in &mem_data.segments { data.active( mem.index() as u32, diff --git a/src/frontend.rs b/src/frontend.rs index d16464b..8c9f262 100644 --- a/src/frontend.rs +++ b/src/frontend.rs @@ -62,7 +62,7 @@ fn handle_payload<'a>( for ty in reader { let ty = ty?; let wasmparser::Type::Func(fty) = ty; - module.frontend_add_signature(fty.into()); + module.signatures.push(fty.into()); } } Payload::ImportSection(reader) => { @@ -72,15 +72,16 @@ fn handle_payload<'a>( let name = import.name.to_owned(); let kind = match import.ty { TypeRef::Func(sig_idx) => { - let func = - module.frontend_add_func(FuncDecl::Import(Signature::from(sig_idx))); + let func = module + .funcs + .push(FuncDecl::Import(Signature::from(sig_idx))); *next_func += 1; ImportKind::Func(func) } TypeRef::Global(ty) => { let mutable = ty.mutable; let ty = ty.content_type.into(); - let global = module.frontend_add_global(GlobalData { + let global = module.globals.push(GlobalData { ty, value: None, mutable, @@ -92,7 +93,7 @@ fn handle_payload<'a>( ImportKind::Table(table) } TypeRef::Memory(mem) => { - let mem = module.frontend_add_memory(MemoryData { + let mem = module.memories.push(MemoryData { initial_pages: mem.initial as usize, maximum_pages: mem.maximum.map(|max| max as usize), segments: vec![], @@ -106,7 +107,7 @@ fn handle_payload<'a>( ))); } }; - module.frontend_add_import(Import { + module.imports.push(Import { module: module_name, name, kind, @@ -119,7 +120,7 @@ fn handle_payload<'a>( let mutable = global.ty.mutable; let ty = global.ty.content_type.into(); let init_expr = parse_init_expr(&global.init_expr)?; - module.frontend_add_global(GlobalData { + module.globals.push(GlobalData { ty, value: init_expr, mutable, @@ -135,17 +136,19 @@ fn handle_payload<'a>( Payload::FunctionSection(reader) => { for sig_idx in reader { let sig_idx = Signature::from(sig_idx?); - module.frontend_add_func(FuncDecl::Body(sig_idx, FunctionBody::default())); + module + .funcs + .push(FuncDecl::Body(sig_idx, FunctionBody::default())); } } Payload::CodeSectionEntry(body) => { let func_idx = Func::new(*next_func); *next_func += 1; - let my_sig = module.func(func_idx).sig(); + let my_sig = module.funcs[func_idx].sig(); let body = parse_body(module, my_sig, body)?; - let existing_body = module.func_mut(func_idx).body_mut().unwrap(); + let existing_body = module.funcs[func_idx].body_mut().unwrap(); *existing_body = body; } Payload::ExportSection(reader) => { @@ -160,14 +163,14 @@ fn handle_payload<'a>( _ => None, }; if let Some(kind) = kind { - module.frontend_add_export(Export { name, kind }); + module.exports.push(Export { name, kind }); } } } Payload::MemorySection(reader) => { for memory in reader { let memory = memory?; - module.frontend_add_memory(MemoryData { + module.memories.push(MemoryData { initial_pages: memory.initial as usize, maximum_pages: memory.maximum.map(|max| max as usize), segments: vec![], @@ -186,8 +189,7 @@ fn handle_payload<'a>( let data = segment.data.to_vec(); let memory = Memory::from(*memory_index); let offset = parse_init_expr(offset_expr)?.unwrap_or(0) as usize; - module - .memory_mut(memory) + module.memories[memory] .segments .push(MemorySegment { offset, data }); } @@ -232,7 +234,7 @@ fn handle_payload<'a>( funcs.push(func); } - let table_items = module.table_mut(table).func_elements.as_mut().unwrap(); + let table_items = module.tables[table].func_elements.as_mut().unwrap(); let new_size = offset.checked_add(funcs.len()).ok_or_else(|| { FrontendError::TooLarge(format!( "Overflowing element offset + length: {} + {}", @@ -274,11 +276,11 @@ fn parse_body<'a>( ) -> Result { let mut ret: FunctionBody = FunctionBody::default(); - for ¶m in &module.signature(my_sig).params[..] { + for ¶m in &module.signatures[my_sig].params[..] { ret.locals.push(param.into()); } - ret.n_params = module.signature(my_sig).params.len(); - for &r in &module.signature(my_sig).returns[..] { + ret.n_params = module.signatures[my_sig].params.len(); + for &r in &module.signatures[my_sig].returns[..] { ret.rets.push(r.into()); } @@ -294,7 +296,7 @@ fn parse_body<'a>( trace!( "Parsing function body: locals = {:?} sig = {:?}", ret.locals, - module.signature(my_sig) + module.signatures[my_sig] ); let mut builder = FunctionBodyBuilder::new(module, my_sig, &mut ret); @@ -303,7 +305,7 @@ fn parse_body<'a>( builder.locals.seal_block_preds(entry, &mut builder.body); builder.locals.start_block(entry); - for (arg_idx, &arg_ty) in module.signature(my_sig).params.iter().enumerate() { + for (arg_idx, &arg_ty) in module.signatures[my_sig].params.iter().enumerate() { let local_idx = Local::new(arg_idx); builder.body.add_blockparam(entry, arg_ty); let value = builder.body.blocks[entry].params.last().unwrap().1; @@ -312,7 +314,7 @@ fn parse_body<'a>( builder.locals.set(local_idx, value); } - let n_args = module.signature(my_sig).params.len(); + let n_args = module.signatures[my_sig].params.len(); for (offset, local_ty) in locals.values().enumerate() { let local_idx = Local::new(n_args + offset); builder.locals.declare(local_idx, *local_ty); @@ -746,7 +748,7 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> { }; // Push initial implicit Block. - let results = module.signature(my_sig).returns.to_vec(); + let results = module.signatures[my_sig].returns.to_vec(); let out = ret.body.add_block(); ret.add_block_params(out, &results[..]); ret.ctrl_stack.push(Frame::Block { @@ -1073,7 +1075,7 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> { } wasmparser::Operator::Return => { - let retvals = self.pop_n(self.module.signature(self.my_sig).returns.len()); + let retvals = self.pop_n(self.module.signatures[self.my_sig].returns.len()); self.emit_ret(&retvals[..]); self.reachable = false; } @@ -1114,7 +1116,7 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> { None => { if self.reachable { let retvals = - self.pop_n(self.module.signature(self.my_sig).returns.len()); + self.pop_n(self.module.signatures[self.my_sig].returns.len()); self.emit_ret(&retvals[..]); } else { self.emit_unreachable(); @@ -1369,7 +1371,7 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> { 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)); + let sig = &self.module.signatures[Signature::from(sig_idx)]; ( Vec::from(sig.params.clone()), Vec::from(sig.returns.clone()), diff --git a/src/ir/display.rs b/src/ir/display.rs index c3fa77a..c998105 100644 --- a/src/ir/display.rs +++ b/src/ir/display.rs @@ -151,7 +151,7 @@ impl<'a> Display for ModuleDisplay<'a> { writeln!(f, " start = {}", func)?; } let mut sig_strs = HashMap::new(); - for (sig, sig_data) in self.0.signatures() { + for (sig, sig_data) in self.0.signatures.entries() { let arg_tys = sig_data .params .iter() @@ -166,14 +166,14 @@ impl<'a> Display for ModuleDisplay<'a> { sig_strs.insert(sig, sig_str.clone()); writeln!(f, " {}: {}", sig, sig_str)?; } - for (global, global_data) in self.0.globals() { + for (global, global_data) in self.0.globals.entries() { writeln!( f, " {}: {:?} # {}", global, global_data.value, global_data.ty )?; } - for (table, table_data) in self.0.tables() { + for (table, table_data) in self.0.tables.entries() { writeln!(f, " {}: {}", table, table_data.ty)?; if let Some(funcs) = &table_data.func_elements { for (i, &func) in funcs.iter().enumerate() { @@ -181,7 +181,7 @@ impl<'a> Display for ModuleDisplay<'a> { } } } - for (memory, memory_data) in self.0.memories() { + for (memory, memory_data) in self.0.memories.entries() { writeln!( f, " {}: initial {} max {:?}", @@ -201,17 +201,17 @@ impl<'a> Display for ModuleDisplay<'a> { )?; } } - for import in self.0.imports() { + for import in &self.0.imports { writeln!( f, " import \"{}\".\"{}\": {}", import.module, import.name, import.kind )?; } - for export in self.0.exports() { + for export in &self.0.exports { writeln!(f, " export \"{}\": {}", export.name, export.kind)?; } - for (func, func_decl) in self.0.funcs() { + for (func, func_decl) in self.0.funcs.entries() { match func_decl { FuncDecl::Body(sig, body) => { writeln!(f, " {}: {} = # {}", func, sig, sig_strs.get(&sig).unwrap())?; diff --git a/src/ir/func.rs b/src/ir/func.rs index 13ced6c..f1bcdfa 100644 --- a/src/ir/func.rs +++ b/src/ir/func.rs @@ -54,9 +54,9 @@ pub struct FunctionBody { impl FunctionBody { pub fn new(module: &Module, sig: Signature) -> FunctionBody { - let locals = EntityVec::from(module.signature(sig).params.clone()); + let locals = EntityVec::from(module.signatures[sig].params.clone()); let n_params = locals.len(); - let rets = module.signature(sig).returns.clone(); + let rets = module.signatures[sig].returns.clone(); let mut blocks = EntityVec::default(); let entry = blocks.push(BlockDef::default()); let mut values = EntityVec::default(); diff --git a/src/ir/module.rs b/src/ir/module.rs index ad430b7..ead764c 100644 --- a/src/ir/module.rs +++ b/src/ir/module.rs @@ -6,14 +6,14 @@ use anyhow::Result; #[derive(Clone, Debug)] pub struct Module<'a> { - orig_bytes: &'a [u8], - funcs: EntityVec, - signatures: EntityVec, - globals: EntityVec, - tables: EntityVec, - imports: Vec, - exports: Vec, - memories: EntityVec, + pub orig_bytes: &'a [u8], + pub funcs: EntityVec, + pub signatures: EntityVec, + pub globals: EntityVec, + pub tables: EntityVec, + pub imports: Vec, + pub exports: Vec, + pub memories: EntityVec, pub start_func: Option, } @@ -142,59 +142,6 @@ impl<'a> Module<'a> { } impl<'a> Module<'a> { - pub fn func<'b>(&'b self, id: Func) -> &'b FuncDecl { - &self.funcs[id] - } - pub fn func_mut<'b>(&'b mut self, id: Func) -> &'b mut FuncDecl { - &mut self.funcs[id] - } - pub fn funcs<'b>(&'b self) -> impl Iterator { - self.funcs.entries() - } - pub fn signature<'b>(&'b self, id: Signature) -> &'b SignatureData { - &self.signatures[id] - } - pub fn signatures<'b>(&'b self) -> impl Iterator { - self.signatures.entries() - } - pub fn global<'b>(&'b self, id: Global) -> &'b GlobalData { - &self.globals[id] - } - pub fn globals<'b>(&'b self) -> impl Iterator + 'b { - self.globals.entries() - } - pub fn table<'b>(&'b self, id: Table) -> &'b TableData { - &self.tables[id] - } - pub fn tables<'b>(&'b self) -> impl Iterator + 'b { - self.tables.entries() - } - pub fn memories<'b>(&'b self) -> impl Iterator + 'b { - self.memories.entries() - } - pub fn imports<'b>(&'b self) -> impl Iterator + 'b { - self.imports.iter() - } - pub fn exports<'b>(&'b self) -> impl Iterator + 'b { - self.exports.iter() - } - pub fn table_mut<'b>(&'b mut self, table: Table) -> &'b mut TableData { - &mut self.tables[table] - } - pub fn memory<'b>(&'b self, memory: Memory) -> &'b MemoryData { - &self.memories[memory] - } - - pub 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); - } - pub(crate) fn frontend_add_func(&mut self, body: FuncDecl) -> Func { - self.funcs.push(body) - } pub(crate) fn frontend_add_table(&mut self, ty: Type, max: Option) -> Table { let func_elements = if ty == Type::FuncRef { Some(vec![]) @@ -207,18 +154,6 @@ impl<'a> Module<'a> { max, }) } - 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); - } - pub(crate) fn frontend_add_export(&mut self, export: Export) { - self.exports.push(export); - } - pub(crate) fn frontend_add_memory(&mut self, memory: MemoryData) -> Memory { - self.memories.push(memory) - } pub fn from_wasm_bytes(bytes: &'a [u8]) -> Result { frontend::wasm_to_ir(bytes) @@ -257,8 +192,4 @@ impl<'a> Module<'a> { { ModuleDisplay(self) } - - pub fn add_func(&mut self, sig: Signature, func: FunctionBody) -> Func { - self.funcs.push(FuncDecl::Body(sig, func)) - } } diff --git a/src/op_traits.rs b/src/op_traits.rs index 12ba0ae..663e57f 100644 --- a/src/op_traits.rs +++ b/src/op_traits.rs @@ -14,11 +14,11 @@ pub fn op_inputs( &Operator::Unreachable | &Operator::Nop => Ok(Cow::Borrowed(&[])), &Operator::Call { function_index } => { - let sig = module.func(function_index).sig(); - Ok(Vec::from(module.signature(sig).params.clone()).into()) + let sig = module.funcs[function_index].sig(); + Ok(Vec::from(module.signatures[sig].params.clone()).into()) } &Operator::CallIndirect { sig_index, .. } => { - let mut params = module.signature(sig_index).params.to_vec(); + let mut params = module.signatures[sig_index].params.to_vec(); params.push(Type::I32); Ok(params.into()) } @@ -30,7 +30,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(global_index).ty].into()), + &Operator::GlobalSet { global_index } => Ok(vec![module.globals[global_index].ty].into()), Operator::I32Load { .. } | Operator::I64Load { .. } @@ -213,10 +213,10 @@ pub fn op_inputs( Operator::I64ReinterpretF64 => Ok(Cow::Borrowed(&[Type::F64])), Operator::TableGet { .. } => Ok(Cow::Borrowed(&[Type::I32])), Operator::TableSet { table_index } => { - Ok(vec![Type::I32, module.table(*table_index).ty].into()) + Ok(vec![Type::I32, module.tables[*table_index].ty].into()) } Operator::TableGrow { table_index } => { - Ok(vec![Type::I32, module.table(*table_index).ty].into()) + Ok(vec![Type::I32, module.tables[*table_index].ty].into()) } Operator::TableSize { .. } => Ok(Cow::Borrowed(&[])), Operator::MemorySize { .. } => Ok(Cow::Borrowed(&[])), @@ -233,11 +233,11 @@ pub fn op_outputs( &Operator::Unreachable | &Operator::Nop => Ok(Cow::Borrowed(&[])), &Operator::Call { function_index } => { - let sig = module.func(function_index).sig(); - Ok(Vec::from(module.signature(sig).returns.clone()).into()) + let sig = module.funcs[function_index].sig(); + Ok(Vec::from(module.signatures[sig].returns.clone()).into()) } &Operator::CallIndirect { sig_index, .. } => { - Ok(Vec::from(module.signature(sig_index).returns.clone()).into()) + Ok(Vec::from(module.signatures[sig_index].returns.clone()).into()) } &Operator::Select => { @@ -245,7 +245,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(global_index).ty].into()), + &Operator::GlobalGet { global_index } => Ok(vec![module.globals[global_index].ty].into()), &Operator::GlobalSet { .. } => Ok(Cow::Borrowed(&[])), Operator::I32Load { .. } @@ -419,7 +419,7 @@ pub fn op_outputs( Operator::F64ReinterpretI64 => Ok(Cow::Borrowed(&[Type::F64])), Operator::I32ReinterpretF32 => Ok(Cow::Borrowed(&[Type::I32])), Operator::I64ReinterpretF64 => Ok(Cow::Borrowed(&[Type::I64])), - Operator::TableGet { table_index } => Ok(vec![module.table(*table_index).ty].into()), + Operator::TableGet { table_index } => Ok(vec![module.tables[*table_index].ty].into()), Operator::TableSet { .. } => Ok(Cow::Borrowed(&[])), Operator::TableGrow { .. } => Ok(Cow::Borrowed(&[])), Operator::TableSize { .. } => Ok(Cow::Borrowed(&[Type::I32])),