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