summaryrefslogtreecommitdiff
path: root/crates/parser/src
diff options
context:
space:
mode:
authorHenry Gressmann <mail@henrygressmann.de>2024-02-25 19:36:13 +0100
committerHenry Gressmann <mail@henrygressmann.de>2024-02-25 19:36:13 +0100
commit43e6d23ae8806c813dd5fa0663c17c1772ebf5a8 (patch)
tree8afa3b6c963685773ba94ac777b1986457fbddc6 /crates/parser/src
parent062515c39154b29bb0406b207e3c67bae399a449 (diff)
chore: improve new parser arch
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
Diffstat (limited to 'crates/parser/src')
-rw-r--r--crates/parser/src/conversion.rs6
-rw-r--r--crates/parser/src/lib.rs2
-rw-r--r--crates/parser/src/module.rs4
-rw-r--r--crates/parser/src/visit.rs45
4 files changed, 35 insertions, 22 deletions
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(())
}