1616use crate :: limits:: { MAX_WASM_CATCHES , MAX_WASM_HANDLERS } ;
1717use crate :: prelude:: * ;
1818use 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
345387struct 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 ) ]
372414pub 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
386428impl < ' a > OperatorsReader < ' a > {
387429 /// Creates a new reader for an expression (instruction sequence).
0 commit comments