Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/wasmparser/benches/benchmark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ fn read_all_wasm(wasm: &[u8]) -> Result<()> {
let mut ops = OperatorsReader::new_with_allocs(reader, mem::take(&mut allocs));

while !ops.eof() {
ops.visit_operator(&mut NopVisit)?;
ops.visit_operator_owned(NopVisit)?;
}
ops.finish()?;
allocs = ops.into_allocations();
Expand Down
32 changes: 23 additions & 9 deletions crates/wasmparser/src/binary_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -828,6 +828,20 @@ impl<'a> BinaryReader<'a> {
/// See the documentation for [`OperatorsReader::visit_operator`] for a version that
/// does not require the visitor to implement [`FrameStack`].
pub fn visit_operator<T>(&mut self, visitor: &mut T) -> Result<<T as VisitOperator<'a>>::Output>
where
T: VisitOperator<'a> + FrameStack,
{
self.visit_operator_owned(visitor)
}

/// Visit the next available operator with the specified [`VisitOperator`] instance
/// that is also a [`FrameStack`].
///
/// Owned (faster) version of [`BinaryReader::visit_operator`], because this one does not use pointer `&mut T`.
pub fn visit_operator_owned<T>(
&mut self,
mut visitor: T,
) -> Result<<T as VisitOperator<'a>>::Output>
where
T: VisitOperator<'a> + FrameStack,
{
Expand All @@ -846,7 +860,7 @@ impl<'a> BinaryReader<'a> {
0x03 => visitor.visit_loop(self.read_block_type()?),
0x04 => visitor.visit_if(self.read_block_type()?),
0x05 => {
self.expect_frame(visitor, FrameKind::If, "else")?;
self.expect_frame(&visitor, FrameKind::If, "else")?;
visitor.visit_else()
}
0x06 => {
Expand All @@ -865,9 +879,9 @@ impl<'a> BinaryReader<'a> {
"legacy_exceptions feature required for catch instruction",
pos,
)?;
match self.expect_frame(visitor, FrameKind::LegacyCatch, "catch") {
match self.expect_frame(&visitor, FrameKind::LegacyCatch, "catch") {
Ok(()) => (),
Err(_) => self.expect_frame(visitor, FrameKind::LegacyTry, "catch")?,
Err(_) => self.expect_frame(&visitor, FrameKind::LegacyTry, "catch")?,
}
visitor.visit_catch(self.read_var_u32()?)
}
Expand All @@ -890,7 +904,7 @@ impl<'a> BinaryReader<'a> {
0x14 => visitor.visit_call_ref(self.read()?),
0x15 => visitor.visit_return_call_ref(self.read()?),
0x18 => {
self.expect_frame(visitor, FrameKind::LegacyTry, "delegate")?;
self.expect_frame(&visitor, FrameKind::LegacyTry, "delegate")?;
visitor.visit_delegate(self.read_var_u32()?)
}
0x19 => {
Expand All @@ -900,9 +914,9 @@ impl<'a> BinaryReader<'a> {
"legacy_exceptions feature required for catch_all instruction",
pos,
)?;
match self.expect_frame(visitor, FrameKind::LegacyCatch, "catch_all") {
match self.expect_frame(&visitor, FrameKind::LegacyCatch, "catch_all") {
Ok(()) => (),
Err(_) => self.expect_frame(visitor, FrameKind::LegacyTry, "catch_all")?,
Err(_) => self.expect_frame(&visitor, FrameKind::LegacyTry, "catch_all")?,
}
visitor.visit_catch_all()
}
Expand Down Expand Up @@ -1134,7 +1148,7 @@ impl<'a> BinaryReader<'a> {
fn visit_0xfb_operator<T>(
&mut self,
pos: u64,
visitor: &mut T,
mut visitor: T,
) -> Result<<T as VisitOperator<'a>>::Output>
where
T: VisitOperator<'a>,
Expand Down Expand Up @@ -1351,7 +1365,7 @@ impl<'a> BinaryReader<'a> {
fn visit_0xfc_operator<T>(
&mut self,
pos: u64,
visitor: &mut T,
mut visitor: T,
) -> Result<<T as VisitOperator<'a>>::Output>
where
T: VisitOperator<'a>,
Expand Down Expand Up @@ -1748,7 +1762,7 @@ impl<'a> BinaryReader<'a> {
fn visit_0xfe_operator<T>(
&mut self,
pos: u64,
visitor: &mut T,
mut visitor: T,
) -> Result<<T as VisitOperator<'a>>::Output>
where
T: VisitOperator<'a>,
Expand Down
37 changes: 28 additions & 9 deletions crates/wasmparser/src/readers/core/operators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,12 @@ pub trait FrameStack {
fn current_frame(&self) -> Option<FrameKind>;
}

impl<T: FrameStack> FrameStack for &mut T {
fn current_frame(&self) -> Option<FrameKind> {
(**self).current_frame()
}
}

/// The Wasm control stack for the [`OperatorsReader`].
#[derive(Debug, Default, Clone)]
pub struct ControlStack {
Expand Down Expand Up @@ -398,7 +404,7 @@ impl ControlStack {
/// Adapters from VisitOperators to FrameStacks
struct FrameStackAdapter<'a, T> {
stack: &'a mut ControlStack,
visitor: &'a mut T,
visitor: T,
}

impl<T> FrameStack for FrameStackAdapter<'_, T> {
Expand All @@ -407,12 +413,12 @@ impl<T> FrameStack for FrameStackAdapter<'_, T> {
}
}

struct SingleFrameAdapter<'a, T> {
struct SingleFrameAdapter<T> {
current_frame: FrameKind,
visitor: &'a mut T,
visitor: T,
}

impl<T> FrameStack for SingleFrameAdapter<'_, T> {
impl<T> FrameStack for SingleFrameAdapter<T> {
fn current_frame(&self) -> Option<FrameKind> {
Some(self.current_frame)
}
Expand Down Expand Up @@ -502,7 +508,7 @@ impl<'a> OperatorsReader<'a> {
/// If `OperatorsReader` has less bytes remaining than required to parse
/// the `Operator`, or if the input is malformed.
pub fn read(&mut self) -> Result<Operator<'a>> {
self.visit_operator(&mut OperatorFactory)
self.visit_operator_owned(OperatorFactory)
}

/// Visit the next available operator with the specified [`VisitOperator`] instance.
Expand Down Expand Up @@ -555,7 +561,20 @@ impl<'a> OperatorsReader<'a> {
where
T: VisitOperator<'a>,
{
self.reader.visit_operator(&mut FrameStackAdapter {
self.visit_operator_owned(visitor)
}

/// Visit the next available operator with the specified [`VisitOperator`] instance.
///
/// Owned (faster) version of [`OperatorsReader::visit_operator`], because this one does not use pointer `&mut T`.
pub fn visit_operator_owned<T>(
&mut self,
visitor: T,
) -> Result<<T as VisitOperator<'a>>::Output>
where
T: VisitOperator<'a>,
{
self.reader.visit_operator_owned(FrameStackAdapter {
stack: &mut self.stack,
visitor,
})
Expand Down Expand Up @@ -1085,7 +1104,7 @@ macro_rules! define_passthrough_visit_operator {
};
}

impl<'a, T: VisitOperator<'a>> VisitOperator<'a> for SingleFrameAdapter<'_, T> {
impl<'a, T: VisitOperator<'a>> VisitOperator<'a> for SingleFrameAdapter<T> {
type Output = T::Output;

#[cfg(feature = "simd")]
Expand All @@ -1104,14 +1123,14 @@ impl<'a> BinaryReader<'a> {
/// If `BinaryReader` has less bytes remaining than required to parse
/// the `Operator`, or if the input is malformed.
pub fn peek_operator<T: FrameStack>(&self, stack: &T) -> Result<Operator<'a>> {
self.clone().visit_operator(&mut SingleFrameAdapter {
self.clone().visit_operator_owned(SingleFrameAdapter {
current_frame: stack.current_frame().ok_or_else(|| {
format_err!(
self.original_position(),
"operators remaining after end of function body or expression"
)
})?,
visitor: &mut OperatorFactory,
visitor: OperatorFactory,
})
}
}
2 changes: 1 addition & 1 deletion crates/wasmparser/src/validator/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ impl<T: WasmModuleResources> FuncValidator<T> {
(reader.clone(), arity)
};

reader.visit_operator(&mut self.visitor(reader.original_position()))??;
reader.visit_operator_owned(self.visitor(reader.original_position()))??;

#[cfg(debug_assertions)]
{
Expand Down
2 changes: 1 addition & 1 deletion crates/wasmprinter/src/operand_stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ impl FuncValidator {
let pos = reader.original_position();
reader
.clone()
.visit_operator(&mut self.validator.visitor(pos))??;
.visit_operator_owned(self.validator.visitor(pos))??;

if !is_end {
let op = reader.clone().read()?;
Expand Down
5 changes: 2 additions & 3 deletions crates/wasmprinter/src/operator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1531,9 +1531,8 @@ impl OpPrinter for PrintOperatorFolded<'_, '_, '_, '_> {
code_section_hints: Vec::new(),
};

let mut op_printer =
PrintOperator::new(&mut internal_printer, self.state, self.operator_state);
reader.visit_operator(&mut op_printer)??;
let op_printer = PrintOperator::new(&mut internal_printer, self.state, self.operator_state);
reader.visit_operator_owned(op_printer)??;
if let Some(s) = annotation {
internal_printer.result.start_comment()?;
write!(internal_printer.result, " (; {s}")?;
Expand Down
Loading