Skip to content

Commit cd6b84b

Browse files
committed
use ControlStack that does not allocate by default
1 parent f88440c commit cd6b84b

File tree

1 file changed

+46
-4
lines changed

1 file changed

+46
-4
lines changed

crates/wasmparser/src/readers/core/operators.rs

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
use crate::limits::{MAX_WASM_CATCHES, MAX_WASM_HANDLERS};
1717
use crate::prelude::*;
1818
use crate::{BinaryReader, BinaryReaderError, FromReader, Result, ValType};
19-
use core::fmt;
19+
use core::{fmt, mem};
2020

2121
/// Represents a block type.
2222
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
@@ -341,9 +341,51 @@ pub trait FrameStack {
341341
fn current_frame(&self) -> Option<FrameKind>;
342342
}
343343

344+
/// The Wasm control stack for the [`OperatorsReader`].
345+
#[derive(Debug, Default, Clone)]
346+
pub struct ControlStack {
347+
/// All frames on the control stack exclusing the top-most frame.
348+
frames: Vec<FrameKind>,
349+
/// The top-most frame on the control stack if any.
350+
top: Option<FrameKind>,
351+
}
352+
353+
impl ControlStack {
354+
/// Resets `self` but keeps heap allocations.
355+
pub fn clear(&mut self) {
356+
self.frames.clear();
357+
self.top = None;
358+
}
359+
360+
/// Returns `true` if `self` is empty.
361+
#[inline]
362+
pub fn is_empty(&self) -> bool {
363+
self.top.is_none()
364+
}
365+
366+
/// Pushes the `frame` to `self`.
367+
#[inline]
368+
pub fn push(&mut self, frame: FrameKind) {
369+
if let Some(old_top) = self.top.replace(frame) {
370+
self.frames.push(old_top);
371+
}
372+
}
373+
374+
/// Pops the top-most [`FrameKind`] from `self`.
375+
pub fn pop(&mut self) -> Option<FrameKind> {
376+
mem::replace(&mut self.top, self.frames.pop())
377+
}
378+
379+
/// Returns the top-mot [`FrameKind`].
380+
#[inline]
381+
pub fn last(&self) -> Option<FrameKind> {
382+
self.top
383+
}
384+
}
385+
344386
/// Adapters from VisitOperators to FrameStacks
345387
struct FrameStackAdapter<'a, T> {
346-
stack: &'a mut Vec<FrameKind>,
388+
stack: &'a mut ControlStack,
347389
visitor: &'a mut T,
348390
}
349391

@@ -371,7 +413,7 @@ impl<T> FrameStack for SingleFrameAdapter<'_, T> {
371413
#[derive(Clone)]
372414
pub struct OperatorsReader<'a> {
373415
reader: BinaryReader<'a>,
374-
stack: Vec<FrameKind>,
416+
stack: ControlStack,
375417
}
376418

377419
/// External handle to the internal allocations used by the OperatorsReader
@@ -381,7 +423,7 @@ pub struct OperatorsReader<'a> {
381423
/// [`OperatorsReader::new`] to provide a means of reusing allocations
382424
/// between each expression or function body.
383425
#[derive(Default)]
384-
pub struct OperatorsReaderAllocations(Vec<FrameKind>);
426+
pub struct OperatorsReaderAllocations(ControlStack);
385427

386428
impl<'a> OperatorsReader<'a> {
387429
/// Creates a new reader for an expression (instruction sequence).

0 commit comments

Comments
 (0)