orca_wasm/iterator/
iterator_trait.rs

1//! Trait that needs to be satisfied by all iterators
2
3use crate::ir::id::GlobalID;
4use crate::ir::module::module_globals::Global;
5use crate::ir::types::{InstrumentationMode, Location};
6use crate::opcode::Instrumenter;
7use wasmparser::Operator;
8
9#[allow(dead_code)]
10/// Iterator trait that must be satisfied by all Iterators to enable code traversal.
11pub trait Iterator {
12    /// Reset the Iterator and all Child Iterators and SubIterators
13    fn reset(&mut self);
14
15    /// Go to the next Instruction
16    fn next(&mut self) -> Option<&Operator>;
17
18    /// Returns the Current Location as a Location and a bool value that
19    /// says whether the location is at the end of the function.
20    fn curr_loc(&self) -> (Location, bool);
21
22    /// Get the current instruction
23    fn curr_op(&self) -> Option<&Operator>;
24}
25
26/// This trait coincides with the Iterator as instrumentation occurs during Wasm visitation.
27/// This trait enables code injection during traversal, thus the Iterator trait is required
28/// to be implemented on the structure to inject on.
29/// Instructions as defined [here].
30///
31/// [here]: https://webassembly.github.io/spec/core/binary/instructions.html
32pub trait IteratingInstrumenter<'a>: Instrumenter<'a> + Iterator {
33    // ==== MODES ====
34
35    /// Sets the type of Instrumentation Type of the current location
36    fn set_instrument_mode(&mut self, mode: InstrumentationMode);
37
38    /// Mark the current location to InstrumentAlternate
39    fn alternate(&mut self) -> &mut Self {
40        self.set_instrument_mode(InstrumentationMode::Alternate);
41        self
42    }
43
44    /// Insert an empty alt at the current location
45    /// Effectively removes the instruction
46    fn empty_alternate(&mut self) -> &mut Self {
47        self.empty_alternate_at(self.curr_loc().0);
48        self
49    }
50
51    /// Mark the current location to InstrumentBefore
52    fn before(&mut self) -> &mut Self {
53        self.set_instrument_mode(InstrumentationMode::Before);
54        self
55    }
56
57    /// Mark the current location to InstrumentAfter
58    fn after(&mut self) -> &mut Self {
59        self.set_instrument_mode(InstrumentationMode::After);
60        self
61    }
62
63    /// Mark the current location to InstrumentSemanticAfter
64    fn semantic_after(&mut self) -> &mut Self {
65        self.set_instrument_mode(InstrumentationMode::SemanticAfter);
66        self
67    }
68
69    /// Mark the current location to InstrumentBlockEntry
70    fn block_entry(&mut self) -> &mut Self {
71        self.set_instrument_mode(InstrumentationMode::BlockEntry);
72        self
73    }
74
75    /// Mark the current location to InstrumentBlockExit
76    fn block_exit(&mut self) -> &mut Self {
77        self.set_instrument_mode(InstrumentationMode::BlockExit);
78        self
79    }
80
81    /// Mark the current location to InstrumentBlockAlt
82    fn block_alt(&mut self) -> &mut Self {
83        self.set_instrument_mode(InstrumentationMode::BlockAlt);
84        self
85    }
86
87    /// Insert an empty alt block at the current location
88    /// Effectively removes the block
89    fn empty_block_alt(&mut self) -> &mut Self {
90        self.empty_block_alt_at(self.curr_loc().0);
91        self
92    }
93
94    // ==== VAR INJECTION ====
95
96    /// Adds a global to the current module and returns the Global ID
97    fn add_global(&mut self, global: Global) -> GlobalID;
98}