diff options
| author | Henry Gressmann <mail@henrygressmann.de> | 2024-02-25 19:36:13 +0100 |
|---|---|---|
| committer | Henry Gressmann <mail@henrygressmann.de> | 2024-02-25 19:36:13 +0100 |
| commit | 43e6d23ae8806c813dd5fa0663c17c1772ebf5a8 (patch) | |
| tree | 8afa3b6c963685773ba94ac777b1986457fbddc6 | |
| parent | 062515c39154b29bb0406b207e3c67bae399a449 (diff) | |
chore: improve new parser arch
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
| -rw-r--r-- | Cargo.lock | 4 | ||||
| -rw-r--r-- | crates/parser/src/conversion.rs | 6 | ||||
| -rw-r--r-- | crates/parser/src/lib.rs | 2 | ||||
| -rw-r--r-- | crates/parser/src/module.rs | 4 | ||||
| -rw-r--r-- | crates/parser/src/visit.rs | 45 |
5 files changed, 37 insertions, 24 deletions
@@ -293,9 +293,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.0.87" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3286b845d0fccbdd15af433f61c5970e711987036cb468f437ff6badd70f4e24" +checksum = "02f341c093d19155a6e41631ce5971aac4e9a868262212153124c15fa22d1cdc" [[package]] name = "cfg-if" diff --git a/crates/parser/src/conversion.rs b/crates/parser/src/conversion.rs index 03b5f82..53cceb6 100644 --- a/crates/parser/src/conversion.rs +++ b/crates/parser/src/conversion.rs @@ -1,5 +1,5 @@ -use crate::visit::process_operators; use crate::Result; +use crate::{module::Code, visit::process_operators}; use alloc::{boxed::Box, format, string::ToString, vec::Vec}; use tinywasm_types::*; use wasmparser::{FuncValidator, OperatorsReader, ValidatorResources}; @@ -159,7 +159,7 @@ 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<(Box<[Instruction]>, Box<[ValType]>)> { +) -> Result<Code> { let locals_reader = func.get_locals_reader()?; let count = locals_reader.get_count(); let pos = locals_reader.original_position(); @@ -173,7 +173,7 @@ pub(crate) fn convert_module_code( } } - let body = process_operators(&mut validator, &func)?; + let body = process_operators(Some(&mut validator), &func)?; let locals = locals.into_boxed_slice(); Ok((body, locals)) } diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs index dd4b931..5de4b03 100644 --- a/crates/parser/src/lib.rs +++ b/crates/parser/src/lib.rs @@ -52,13 +52,13 @@ impl Parser { let features = WasmFeatures { bulk_memory: true, floats: true, - function_references: true, multi_value: true, mutable_global: true, reference_types: true, sign_extension: true, saturating_float_to_int: true, + function_references: false, component_model: false, component_model_nested_names: false, component_model_values: false, diff --git a/crates/parser/src/module.rs b/crates/parser/src/module.rs index 813a65d..8414c17 100644 --- a/crates/parser/src/module.rs +++ b/crates/parser/src/module.rs @@ -4,6 +4,8 @@ use alloc::{boxed::Box, format, vec::Vec}; use tinywasm_types::{Data, Element, Export, FuncType, Global, Import, Instruction, MemoryType, TableType, ValType}; use wasmparser::{Payload, Validator}; +pub(crate) type Code = (Box<[Instruction]>, Box<[ValType]>); + #[derive(Default)] pub(crate) struct ModuleReader { pub(crate) version: Option<u16>, @@ -11,7 +13,7 @@ pub(crate) struct ModuleReader { pub(crate) func_types: Vec<FuncType>, pub(crate) code_type_addrs: Vec<u32>, pub(crate) exports: Vec<Export>, - pub(crate) code: Vec<(Box<[Instruction]>, Box<[ValType]>)>, + pub(crate) code: Vec<Code>, pub(crate) globals: Vec<Global>, pub(crate) table_types: Vec<TableType>, pub(crate) memory_types: Vec<MemoryType>, diff --git a/crates/parser/src/visit.rs b/crates/parser/src/visit.rs index b42e462..15024f1 100644 --- a/crates/parser/src/visit.rs +++ b/crates/parser/src/visit.rs @@ -10,6 +10,7 @@ struct ValidateThenVisit<'a, T, U>(T, &'a mut U); macro_rules! validate_then_visit { ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident)*) => { $( + #[inline] fn $visit(&mut self $($(,$arg: $argty)*)?) -> Self::Output { self.0.$visit($($($arg.clone()),*)?)?; Ok(self.1.$visit($($($arg),*)?)) @@ -24,23 +25,29 @@ where U: VisitOperator<'a>, { type Output = Result<U::Output>; - wasmparser::for_each_operator!(validate_then_visit); } pub(crate) fn process_operators<R: WasmModuleResources>( - validator: &mut FuncValidator<R>, + validator: Option<&mut FuncValidator<R>>, body: &FunctionBody<'_>, ) -> Result<Box<[Instruction]>> { let mut reader = body.get_operators_reader()?; - let mut builder = FunctionBuilder::new(1024); + let remaining = reader.get_binary_reader().bytes_remaining(); + let mut builder = FunctionBuilder::new(remaining); - while !reader.eof() { - let validate = validator.visitor(reader.original_position()); - reader.visit_operator(&mut ValidateThenVisit(validate, &mut builder))???; + if let Some(validator) = validator { + while !reader.eof() { + let validate = validator.visitor(reader.original_position()); + reader.visit_operator(&mut ValidateThenVisit(validate, &mut builder))???; + } + validator.finish(reader.original_position())?; + } else { + while !reader.eof() { + reader.visit_operator(&mut builder)??; + } } - validator.finish(reader.original_position())?; Ok(builder.instructions.into_boxed_slice()) } @@ -114,7 +121,7 @@ pub(crate) struct FunctionBuilder { impl FunctionBuilder { pub(crate) fn new(instr_capacity: usize) -> Self { - Self { instructions: Vec::with_capacity(instr_capacity), label_ptrs: Vec::with_capacity(64) } + Self { instructions: Vec::with_capacity(instr_capacity), label_ptrs: Vec::with_capacity(128) } } #[cold] @@ -124,7 +131,8 @@ impl FunctionBuilder { #[inline] fn visit(&mut self, op: Instruction) -> Result<()> { - Ok(self.instructions.push(op)) + self.instructions.push(op); + Ok(()) } } @@ -337,6 +345,7 @@ impl<'a> wasmparser::VisitOperator<'a> for FunctionBuilder { self.visit(Instruction::Else(0)) } + #[inline] fn visit_end(&mut self) -> Self::Output { let Some(label_pointer) = self.label_ptrs.pop() else { return self.visit(Instruction::EndFunc); @@ -348,16 +357,19 @@ impl<'a> wasmparser::VisitOperator<'a> for FunctionBuilder { Instruction::Else(ref mut else_instr_end_offset) => { *else_instr_end_offset = current_instr_ptr - label_pointer; + #[cold] + fn error() -> crate::ParseError { + crate::ParseError::UnsupportedOperator( + "Expected to end an if block, but the last label was not an if".to_string(), + ) + } + // since we're ending an else block, we need to end the if block as well - let if_label_pointer = self.label_ptrs.pop().ok_or(crate::ParseError::UnsupportedOperator( - "Expected to end an if block, but the last label was not an if".to_string(), - ))?; + let if_label_pointer = self.label_ptrs.pop().ok_or_else(error)?; let if_instruction = &mut self.instructions[if_label_pointer]; let Instruction::If(_, ref mut else_offset, ref mut end_offset) = if_instruction else { - return Err(crate::ParseError::UnsupportedOperator( - "Expected to end an if block, but the last label was not an if".to_string(), - )); + return Err(error()); }; *else_offset = Some(label_pointer - if_label_pointer); @@ -386,8 +398,7 @@ impl<'a> wasmparser::VisitOperator<'a> for FunctionBuilder { .collect::<Result<Vec<Instruction>, wasmparser::BinaryReaderError>>() .expect("BrTable targets are invalid, this should have been caught by the validator"); - self.instructions - .extend(IntoIterator::into_iter([Instruction::BrTable(def, instrs.len())]).chain(instrs.into_iter())); + self.instructions.extend(IntoIterator::into_iter([Instruction::BrTable(def, instrs.len())]).chain(instrs)); Ok(()) } |
