diff options
Diffstat (limited to 'crates/parser/src')
| -rw-r--r-- | crates/parser/src/conversion.rs | 51 | ||||
| -rw-r--r-- | crates/parser/src/macros.rs | 87 | ||||
| -rw-r--r-- | crates/parser/src/module.rs | 197 | ||||
| -rw-r--r-- | crates/parser/src/parallel.rs | 6 | ||||
| -rw-r--r-- | crates/parser/src/visit.rs | 18 |
5 files changed, 124 insertions, 235 deletions
diff --git a/crates/parser/src/conversion.rs b/crates/parser/src/conversion.rs index fea43ba..4561974 100644 --- a/crates/parser/src/conversion.rs +++ b/crates/parser/src/conversion.rs @@ -3,13 +3,10 @@ use alloc::sync::Arc; use crate::{Result, module::FunctionCode, visit::process_operators_and_validate}; use alloc::{boxed::Box, format, string::ToString, vec::Vec}; use tinywasm_types::*; -use wasmparser::{CompositeInnerType, FuncValidator, FuncValidatorAllocations, OperatorsReader, ValidatorResources}; - -pub(crate) fn convert_module_elements<'a, T: IntoIterator<Item = wasmparser::Result<wasmparser::Element<'a>>>>( - elements: T, -) -> Result<Vec<tinywasm_types::Element>> { - elements.into_iter().map(|element| convert_module_element(element?)).collect::<Result<Vec<_>>>() -} +use wasmparser::{ + CompositeInnerType, FuncValidator, FuncValidatorAllocations, OperatorsReader, OperatorsReaderAllocations, + ValidatorResources, +}; pub(crate) fn convert_module_element(element: wasmparser::Element<'_>) -> Result<tinywasm_types::Element> { let kind = match element.kind { @@ -44,12 +41,6 @@ pub(crate) fn convert_module_element(element: wasmparser::Element<'_>) -> Result } } -pub(crate) fn convert_module_data_sections<'a, T: IntoIterator<Item = wasmparser::Result<wasmparser::Data<'a>>>>( - data_sections: T, -) -> Result<Vec<tinywasm_types::Data>> { - data_sections.into_iter().map(|data| convert_module_data(data?)).collect::<Result<Vec<_>>>() -} - pub(crate) fn convert_module_data(data: wasmparser::Data<'_>) -> Result<tinywasm_types::Data> { Ok(tinywasm_types::Data { data: data.data.to_vec().into_boxed_slice(), @@ -64,12 +55,6 @@ pub(crate) fn convert_module_data(data: wasmparser::Data<'_>) -> Result<tinywasm }) } -pub(crate) fn convert_module_imports<'a, T: IntoIterator<Item = wasmparser::Result<wasmparser::Import<'a>>>>( - imports: T, -) -> Result<Vec<Import>> { - imports.into_iter().map(|import| convert_module_import(import?)).collect::<Result<Vec<_>>>() -} - pub(crate) fn convert_module_import(import: wasmparser::Import<'_>) -> Result<Import> { let kind = match import.ty { wasmparser::TypeRef::Func(ty) => ImportKind::Function(ty), @@ -100,12 +85,6 @@ pub(crate) fn convert_module_import(import: wasmparser::Import<'_>) -> Result<Im Ok(Import { module: import.module.into(), name: import.name.into(), kind }) } -pub(crate) fn convert_module_memories<T: IntoIterator<Item = wasmparser::Result<wasmparser::MemoryType>>>( - memory_types: T, -) -> Result<Vec<MemoryType>> { - memory_types.into_iter().map(|memory| Ok(convert_module_memory(memory?))).collect::<Result<Vec<_>>>() -} - pub(crate) fn convert_module_memory(memory: wasmparser::MemoryType) -> MemoryType { MemoryType::new( if memory.memory64 { MemoryArch::I64 } else { MemoryArch::I32 }, @@ -115,12 +94,6 @@ pub(crate) fn convert_module_memory(memory: wasmparser::MemoryType) -> MemoryTyp ) } -pub(crate) fn convert_module_tables<'a, T: IntoIterator<Item = wasmparser::Result<wasmparser::Table<'a>>>>( - table_types: T, -) -> Result<Vec<TableType>> { - table_types.into_iter().map(|table| convert_module_table(table?)).collect::<Result<Vec<_>>>() -} - pub(crate) fn convert_module_table(table: wasmparser::Table<'_>) -> Result<TableType> { let size_initial = table.ty.initial.try_into().map_err(|_| { crate::ParseError::UnsupportedOperator(format!("Table size initial is too large: {}", table.ty.initial)) @@ -134,7 +107,7 @@ pub(crate) fn convert_module_table(table: wasmparser::Table<'_>) -> Result<Table pub(crate) fn convert_module_globals( globals: wasmparser::SectionLimited<'_, wasmparser::Global<'_>>, -) -> Result<Vec<Global>> { +) -> Result<Box<[Global]>> { globals .into_iter() .map(|global| { @@ -143,7 +116,7 @@ pub(crate) fn convert_module_globals( let ops = global.init_expr.get_operators_reader(); Ok(Global { init: process_const_operators(ops)?, ty: GlobalType::new(ty, global.ty.mutable) }) }) - .collect::<Result<Vec<_>>>() + .collect::<Result<Box<_>>>() } pub(crate) fn convert_module_export(export: wasmparser::Export<'_>) -> Result<Export> { @@ -163,7 +136,8 @@ pub(crate) fn convert_module_export(export: wasmparser::Export<'_>) -> Result<Ex pub(crate) fn convert_module_code( func: wasmparser::FunctionBody<'_>, mut validator: FuncValidator<ValidatorResources>, -) -> Result<(FunctionCode, FuncValidatorAllocations)> { + reader_allocs: OperatorsReaderAllocations, +) -> Result<(FunctionCode, FuncValidatorAllocations, OperatorsReaderAllocations)> { let locals_reader = func.get_locals_reader()?; let count = locals_reader.get_count(); let pos = locals_reader.original_position(); @@ -199,8 +173,13 @@ pub(crate) fn convert_module_code( } } - let (body, data, allocations) = process_operators_and_validate(validator, func, local_addr_map)?; - Ok((FunctionCode { instructions: body, data, locals: local_counts, uses_local_memory: false }, allocations)) + let (body, data, validator_allocs, reader_allocs) = + process_operators_and_validate(validator, func, local_addr_map, reader_allocs)?; + Ok(( + FunctionCode { instructions: body, data, locals: local_counts, uses_local_memory: false }, + validator_allocs, + reader_allocs, + )) } pub(crate) fn convert_module_type(ty: wasmparser::RecGroup) -> Result<Arc<FuncType>> { diff --git a/crates/parser/src/macros.rs b/crates/parser/src/macros.rs index dded6d8..b21c1e8 100644 --- a/crates/parser/src/macros.rs +++ b/crates/parser/src/macros.rs @@ -1,94 +1,19 @@ pub(crate) mod visit { macro_rules! validate_then_visit { - ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => { - $(validate_then_visit!(@@$proposal $op $({ $($arg: $argty),* })? => $visit ($($ann)*));)* - }; - - // These special-case arms exist so we only clone wasmparser's non-Copy payloads - (@@mvp BrTable { $arg:ident: $argty:ty } => $visit:ident ($($ann:tt)*)) => { - fn $visit(&mut self, $arg: $argty) -> Self::Output { - self.0.$visit($arg.clone()); - let validation = self.0.validator.visitor(self.0.position).$visit($arg); - if let Err(e) = validation { - cold_path(); - self.0.record_error(crate::ParseError::ParseError { message: e.to_string(), offset: self.0.position }); - } - } - }; - - (@@reference_types TypedSelectMulti { $arg:ident: $argty:ty } => $visit:ident ($($ann:tt)*)) => { - fn $visit(&mut self, $arg: $argty) -> Self::Output { - self.0.$visit($arg.clone()); - let validation = self.0.validator.visitor(self.0.position).$visit($arg); - if let Err(e) = validation { - cold_path(); - self.0.record_error(crate::ParseError::ParseError { message: e.to_string(), offset: self.0.position }); - } - } - }; - - (@@exceptions TryTable { $arg:ident: $argty:ty } => $visit:ident ($($ann:tt)*)) => { - fn $visit(&mut self, $arg: $argty) -> Self::Output { - self.0.$visit($arg.clone()); - let validation = self.0.validator.visitor(self.0.position).$visit($arg); - if let Err(e) = validation { - cold_path(); - self.0.record_error(crate::ParseError::ParseError { message: e.to_string(), offset: self.0.position }); - } - } - }; - - (@@stack_switching Resume { cont_type_index: $cont:ty, resume_table: $table:ty } => $visit:ident ($($ann:tt)*)) => { - fn $visit(&mut self, cont_type_index: $cont, resume_table: $table) -> Self::Output { - self.0.$visit(cont_type_index, resume_table.clone()); - let validation = self.0.validator.visitor(self.0.position).$visit(cont_type_index, resume_table); - if let Err(e) = validation { - cold_path(); - self.0.record_error(crate::ParseError::ParseError { message: e.to_string(), offset: self.0.position }); - } - } - }; - - (@@stack_switching ResumeThrow { cont_type_index: $cont:ty, tag_index: $tag:ty, resume_table: $table:ty } => $visit:ident ($($ann:tt)*)) => { - fn $visit(&mut self, cont_type_index: $cont, tag_index: $tag, resume_table: $table) -> Self::Output { - self.0.$visit(cont_type_index, tag_index, resume_table.clone()); - let validation = self.0.validator.visitor(self.0.position).$visit(cont_type_index, tag_index, resume_table); - if let Err(e) = validation { - cold_path(); - self.0.record_error(crate::ParseError::ParseError { message: e.to_string(), offset: self.0.position }); - } - } - }; - - (@@stack_switching ResumeThrowRef { cont_type_index: $cont:ty, resume_table: $table:ty } => $visit:ident ($($ann:tt)*)) => { - fn $visit(&mut self, cont_type_index: $cont, resume_table: $table) -> Self::Output { - self.0.$visit(cont_type_index, resume_table.clone()); - let validation = self.0.validator.visitor(self.0.position).$visit(cont_type_index, resume_table); - if let Err(e) = validation { - cold_path(); - self.0.record_error(crate::ParseError::ParseError { message: e.to_string(), offset: self.0.position }); - } - } - }; - - (@@$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*)) => { + ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {$( fn $visit(&mut self $($(,$arg: $argty)*)?) -> Self::Output { - self.0.$visit($($($arg),*)?); + self.0.$visit($($($arg.clone()),*)?); let validation = self.0.validator.visitor(self.0.position).$visit($($($arg),*)?); if let Err(e) = validation { cold_path(); self.0.record_error(crate::ParseError::ParseError { message: e.to_string(), offset: self.0.position }); } } - }; + )*}; } macro_rules! validate_then_visit_simd { - ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => { - $(validate_then_visit_simd!(@@$proposal $op $({ $($arg: $argty),* })? => $visit ($($ann)*));)* - }; - - (@@$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*)) => { + ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {$( fn $visit(&mut self $($(,$arg: $argty)*)?) -> Self::Output { self.0.$visit($($($arg),*)?); let validation = self.0.validator.simd_visitor(self.0.position).$visit($($($arg),*)?); @@ -97,7 +22,7 @@ pub(crate) mod visit { self.0.record_error(crate::ParseError::ParseError { message: e.to_string(), offset: self.0.position }); } } - }; + )*}; } macro_rules! define_operand { @@ -166,7 +91,7 @@ pub(crate) mod visit { (@@tail_call $($rest:tt)* ) => {}; (@@$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*)) => { - fn $visit(&mut self $($(,_: $argty)*)?) { + fn $visit(&mut self $($(,_: $argty)*)?) -> Self::Output { self.unsupported(stringify!($visit)) } }; diff --git a/crates/parser/src/module.rs b/crates/parser/src/module.rs index 5f5e5e2..fab6258 100644 --- a/crates/parser/src/module.rs +++ b/crates/parser/src/module.rs @@ -1,11 +1,11 @@ use crate::log::debug; -use crate::{ParseError, ParserOptions, Result, conversion, optimize}; +use crate::{ParseError, ParserOptions, Result, conversion::*, optimize}; use alloc::sync::Arc; -use alloc::{format, string::ToString, vec::Vec}; +use alloc::{boxed::Box, format, string::ToString, vec::Vec}; use core::marker::PhantomData; use core::ops::Range; use tinywasm_types::*; -use wasmparser::{FuncValidatorAllocations, Payload, Validator}; +use wasmparser::{FuncValidatorAllocations, OperatorsReaderAllocations, Payload, Validator}; pub(crate) struct FunctionCode { pub instructions: Vec<Instruction>, @@ -46,21 +46,23 @@ pub(crate) fn optimize_function_code( #[derive(Default)] pub(crate) struct ModuleReader<'a> { func_validator_allocations: Option<FuncValidatorAllocations>, + operators_reader_allocations: Option<OperatorsReaderAllocations>, + has_code_section: bool, marker: PhantomData<&'a [u8]>, pub(crate) version: Option<u16>, pub(crate) start_func: Option<u32>, - pub(crate) func_types: Vec<Arc<FuncType>>, - pub(crate) code_type_addrs: Vec<u32>, - pub(crate) exports: Vec<Export>, + pub(crate) func_types: Arc<[Arc<FuncType>]>, + pub(crate) code_type_addrs: Box<[u32]>, + pub(crate) exports: Arc<[Export]>, pub(crate) code: Vec<FunctionCode>, - pub(crate) globals: Vec<Global>, - pub(crate) table_types: Vec<TableType>, - pub(crate) memory_types: Vec<MemoryType>, - pub(crate) imports: Vec<Import>, - pub(crate) data: Vec<Data>, - pub(crate) elements: Vec<Element>, + pub(crate) globals: Box<[Global]>, + pub(crate) table_types: Box<[TableType]>, + pub(crate) memory_types: Box<[MemoryType]>, + pub(crate) imports: Box<[Import]>, + pub(crate) data: Box<[Data]>, + pub(crate) elements: Box<[Element]>, pub(crate) end_reached: bool, #[cfg(parallel_parser)] @@ -75,6 +77,14 @@ impl<'a> ModuleReader<'a> { } pub(crate) fn process_payload(&mut self, payload: Payload<'_>, validator: &mut Validator) -> Result<()> { + fn check_section(section: &str, duplicate: bool) -> Result<()> { + debug!("found {section} section"); + if duplicate { + return Err(ParseError::DuplicateSection(format!("{section} section"))); + } + Ok(()) + } + match payload { Payload::Version { num, encoding, range } => { validator.version(num, encoding, &range)?; @@ -84,99 +94,65 @@ impl<'a> ModuleReader<'a> { } } Payload::StartSection { func, range } => { - if self.start_func.is_some() { - return Err(ParseError::DuplicateSection("Start section".into())); - } - - debug!("Found start section"); + check_section("start", self.start_func.is_some())?; validator.start_section(func, &range)?; self.start_func = Some(func); } Payload::TypeSection(reader) => { - if !self.func_types.is_empty() { - return Err(ParseError::DuplicateSection("Type section".into())); - } - - debug!("Found type section"); + check_section("type", !self.func_types.is_empty())?; validator.type_section(&reader)?; - self.func_types = - reader.into_iter().map(|t| conversion::convert_module_type(t?)).collect::<Result<Vec<_>>>()?; + self.func_types = reader.into_iter().map(|t| convert_module_type(t?)).collect::<Result<_>>()?; } Payload::GlobalSection(reader) => { - if !self.globals.is_empty() { - return Err(ParseError::DuplicateSection("Global section".into())); - } - - debug!("Found global section"); + check_section("global", !self.globals.is_empty())?; validator.global_section(&reader)?; - self.globals = conversion::convert_module_globals(reader)?; + self.globals = convert_module_globals(reader)?; } Payload::TableSection(reader) => { - if !self.table_types.is_empty() { - return Err(ParseError::DuplicateSection("Table section".into())); - } - - debug!("Found table section"); + check_section("table", !self.table_types.is_empty())?; validator.table_section(&reader)?; - self.table_types = conversion::convert_module_tables(reader)?; + self.table_types = + reader.into_iter().map(|table| convert_module_table(table?)).collect::<Result<_>>()?; } Payload::MemorySection(reader) => { - if !self.memory_types.is_empty() { - return Err(ParseError::DuplicateSection("Memory section".into())); - } - - debug!("Found memory section"); + check_section("memory", !self.memory_types.is_empty())?; validator.memory_section(&reader)?; - self.memory_types = conversion::convert_module_memories(reader)?; + self.memory_types = + reader.into_iter().map(|memory| Ok(convert_module_memory(memory?))).collect::<Result<_>>()?; } Payload::ElementSection(reader) => { debug!("Found element section"); validator.element_section(&reader)?; - self.elements = conversion::convert_module_elements(reader)?; + self.elements = + reader.into_iter().map(|element| convert_module_element(element?)).collect::<Result<_>>()?; } Payload::DataSection(reader) => { - if !self.data.is_empty() { - return Err(ParseError::DuplicateSection("Data section".into())); - } - - debug!("Found data section"); + check_section("data", !self.data.is_empty())?; validator.data_section(&reader)?; - self.data = conversion::convert_module_data_sections(reader)?; + self.data = reader.into_iter().map(|data| convert_module_data(data?)).collect::<Result<_>>()?; } Payload::DataCountSection { count, range } => { debug!("Found data count section"); if !self.data.is_empty() { - return Err(ParseError::DuplicateSection("Data count section".into())); + return Err(ParseError::UnsupportedSection("Data count section after data section".into())); } validator.data_count_section(count, &range)?; } Payload::FunctionSection(reader) => { - if !self.code_type_addrs.is_empty() { - return Err(ParseError::DuplicateSection("Function section".into())); - } - - debug!("Found function section"); + check_section("function", !self.code_type_addrs.is_empty())?; validator.function_section(&reader)?; - self.code_type_addrs = reader.into_iter().map(|f| Ok(f?)).collect::<Result<Vec<_>>>()?; + self.code_type_addrs = reader.into_iter().map(|f| Ok(f?)).collect::<Result<_>>()?; } Payload::ImportSection(reader) => { - if !self.imports.is_empty() { - return Err(ParseError::DuplicateSection("Import section".into())); - } - - debug!("Found import section"); + check_section("import", !self.imports.is_empty())?; validator.import_section(&reader)?; - self.imports = conversion::convert_module_imports(reader.into_imports())?; + self.imports = + reader.into_imports().map(|import| convert_module_import(import?)).collect::<Result<_>>()?; } Payload::ExportSection(reader) => { - if !self.exports.is_empty() { - return Err(ParseError::DuplicateSection("Export section".into())); - } - - debug!("Found export section"); + check_section("export", !self.exports.is_empty())?; validator.export_section(&reader)?; - self.exports = - reader.into_iter().map(|e| conversion::convert_module_export(e?)).collect::<Result<Vec<_>>>()?; + self.exports = reader.into_iter().map(|e| convert_module_export(e?)).collect::<Result<_>>()?; } Payload::End(offset) => { debug!("Reached end of module"); @@ -192,7 +168,7 @@ impl<'a> ModuleReader<'a> { debug!("Skipping custom section: {:?}", _reader.name()); } Payload::CodeSectionStart { .. } | Payload::CodeSectionEntry(_) => { - return Err(ParseError::Other("code section payload handled separately".into())); + unreachable!("code section payload handled separately") } Payload::UnknownSection { .. } => return Err(ParseError::UnsupportedSection("Unknown section".into())), section => return Err(ParseError::UnsupportedSection(format!("Unsupported section: {section:?}"))), @@ -242,20 +218,26 @@ impl<'a> ModuleReader<'a> { options: &ParserOptions, ) -> Result<()> { debug!("Found code section entry"); - let ordinal = self.code.len(); + + let func_validator_allocs = self.func_validator_allocations.take().unwrap_or_default(); + let operators_reader_allocs = self.operators_reader_allocations.take().unwrap_or_default(); + let func_to_validate = validator.code_section_entry(&function)?; - let func_validator = - func_to_validate.into_validator(self.func_validator_allocations.take().unwrap_or_default()); - let (code, allocations) = conversion::convert_module_code(function, func_validator)?; - let code = optimize_function_code( + let func_validator = func_to_validate.into_validator(func_validator_allocs); + + let (code, func_validator_allocs, operators_reader_allocs) = + convert_module_code(function, func_validator, operators_reader_allocs)?; + + self.code.push(optimize_function_code( code, options, - self.function_results(ordinal), - (imported_func_count(&self.imports) + ordinal) as u32, + self.function_results(self.code.len()), + (imported_func_count(&self.imports) + self.code.len()) as u32, imported_memory_count(&self.imports), - ); - self.code.push(code); - self.func_validator_allocations = Some(allocations); + )); + + self.func_validator_allocations = Some(func_validator_allocs); + self.operators_reader_allocations = Some(operators_reader_allocs); Ok(()) } @@ -376,50 +358,51 @@ impl<'a> ModuleReader<'a> { LocalMemoryAllocation::Skip }; - let mut funcs = Vec::with_capacity(self.code.len()); - let mut func_type_idxs = self + let func_type_idxs = self .imports .iter() .filter_map(|import| match import.kind { ImportKind::Function(type_idx) => Some(type_idx), _ => None, }) - .collect::<Vec<_>>(); - func_type_idxs.extend(self.code_type_addrs.iter().copied()); + .chain(self.code_type_addrs.iter().copied()) + .collect(); - for (code, ty_idx) in self.code.into_iter().zip(self.code_type_addrs) { - let ty = self.func_types.get(ty_idx as usize).expect("No func type for func, this is a bug").clone(); - let params = ValueCounts::from_iter(ty.params()); - let results = ValueCounts::from_iter(ty.results()); - if code.uses_local_memory { - local_memory_allocation = LocalMemoryAllocation::Eager; - } + let funcs = self + .code + .into_iter() + .zip(self.code_type_addrs) + .map(|(code, ty_idx)| { + let ty = self.func_types.get(ty_idx as usize).expect("No func type for func, this is a bug").clone(); + let params = ValueCounts::from_iter(ty.params()); + let results = ValueCounts::from_iter(ty.results()); + if code.uses_local_memory { + local_memory_allocation = LocalMemoryAllocation::Eager; + } - funcs.push( - WasmFunction { + Arc::new(WasmFunction { instructions: code.instructions.into(), data: code.data, locals: code.locals, params, results, ty, - } - .into(), - ); - } + }) + }) + .collect(); Ok(ModuleInner { - funcs: funcs.into(), - func_types: self.func_types.into(), - func_type_idxs: func_type_idxs.into(), - globals: self.globals.into(), - table_types: self.table_types.into(), - imports: self.imports.into(), + funcs, + func_types: self.func_types, + func_type_idxs, + globals: self.globals, + table_types: self.table_types, + imports: self.imports, start_func: self.start_func, - data: self.data.into(), - exports: self.exports.into(), - elements: self.elements.into(), - memory_types: self.memory_types.into(), + data: self.data, + exports: self.exports, + elements: self.elements, + memory_types: self.memory_types, local_memory_allocation, } .into()) diff --git a/crates/parser/src/parallel.rs b/crates/parser/src/parallel.rs index 778e4ad..4400053 100644 --- a/crates/parser/src/parallel.rs +++ b/crates/parser/src/parallel.rs @@ -66,12 +66,12 @@ fn process_function_job( imported_memory_count: u32, ) -> Result<(usize, FunctionCode)> { let validator = job.func_to_validate.into_validator(FuncValidatorAllocations::default()); - let (code, _allocations) = match job.body { - FunctionBodyInput::Borrowed(func) => conversion::convert_module_code(func, validator)?, + let (code, _, _) = match job.body { + FunctionBodyInput::Borrowed(func) => conversion::convert_module_code(func, validator, Default::default())?, FunctionBodyInput::Owned(body) => { let reader = wasmparser::BinaryReader::new(&body.section_bytes[body.body_range], body.body_offset); let func = wasmparser::FunctionBody::new(reader); - conversion::convert_module_code(func, validator)? + conversion::convert_module_code(func, validator, Default::default())? } }; diff --git a/crates/parser/src/visit.rs b/crates/parser/src/visit.rs index d1612ed..5fddad9 100644 --- a/crates/parser/src/visit.rs +++ b/crates/parser/src/visit.rs @@ -5,8 +5,8 @@ use alloc::string::ToString; use alloc::vec::Vec; use tinywasm_types::{Instruction, MemoryArg, WasmFunctionData}; use wasmparser::{ - FrameKind, FuncValidator, FuncValidatorAllocations, FunctionBody, VisitOperator, VisitSimdOperator, - WasmModuleResources, + FrameKind, FuncValidator, FuncValidatorAllocations, FunctionBody, OperatorsReader, OperatorsReaderAllocations, + VisitOperator, VisitSimdOperator, WasmModuleResources, }; #[derive(Debug, Clone, Copy)] @@ -51,7 +51,6 @@ impl FunctionDataBuilder { } } } - struct ValidateThenVisit<'a, R: WasmModuleResources>(&'a mut FunctionBuilder<R>); fn operand_size(ty: wasmparser::ValType) -> OperandSize { @@ -75,12 +74,14 @@ impl<R: WasmModuleResources> VisitSimdOperator<'_> for ValidateThenVisit<'_, R> wasmparser::for_each_visit_simd_operator!(validate_then_visit_simd); } -pub(crate) fn process_operators_and_validate<R: WasmModuleResources>( - validator: FuncValidator<R>, +pub(crate) fn process_operators_and_validate( + validator: FuncValidator<impl WasmModuleResources>, body: FunctionBody<'_>, local_addr_map: Vec<u16>, -) -> Result<(Vec<Instruction>, WasmFunctionData, FuncValidatorAllocations)> { - let mut reader = body.get_operators_reader()?; + allocs: OperatorsReaderAllocations, +) -> Result<(Vec<Instruction>, WasmFunctionData, FuncValidatorAllocations, OperatorsReaderAllocations)> { + let reader = body.get_binary_reader_for_operators()?; + let mut reader = OperatorsReader::new_with_allocs(reader, allocs); let mut builder = FunctionBuilder::new(validator, local_addr_map); while !reader.eof() { @@ -92,11 +93,12 @@ pub(crate) fn process_operators_and_validate<R: WasmModuleResources>( } reader.finish()?; + if let Some(error) = builder.error { return Err(error); } - Ok((builder.instructions, builder.data.finish(), builder.validator.into_allocations())) + Ok((builder.instructions, builder.data.finish(), builder.validator.into_allocations(), reader.into_allocations())) } pub(crate) struct FunctionBuilder<R> { |
