summaryrefslogtreecommitdiff
path: root/crates/parser/src/visit.rs
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/visit.rs
parent062515c39154b29bb0406b207e3c67bae399a449 (diff)
chore: improve new parser arch
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
Diffstat (limited to 'crates/parser/src/visit.rs')
-rw-r--r--crates/parser/src/visit.rs45
1 files changed, 28 insertions, 17 deletions
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(())
}