[][src]Function walrus::ir::dfs_pre_order_mut

pub fn dfs_pre_order_mut(
    visitor: &mut impl VisitorMut,
    func: &mut LocalFunction,
    start: InstrSeqId
)

Perform an intra-procedural, depth-first, pre-order, mutable traversal of the IR.

  • Intra-procedural: Only traverses IR within a function. Does not cross function boundaries (although it will report edges to other functions via visit_function_id calls on the visitor, so you can use this as a building block for making global, inter-procedural analyses).

  • Depth-first, pre-order: Visits instructions and instruction sequences in a top-down manner, where all instructions in a parent sequences are visited before child sequences. See Wikipedia for details.

Calls visitor methods for every instruction, instruction sequence, and resource that the traversal visits.

The traversals begins at the start instruction sequence and goes from there. To traverse everything in a function, pass func.entry_block() as start.

This implementation is iterative — not recursive — and so it will not blow the call stack on deeply nested Wasm (although it may still OOM).

Example

This example walks the IR and adds one to all i32.const's values.

use walrus::LocalFunction;
use walrus::ir::*;

#[derive(Default)]
struct AddOneToI32Consts;

impl VisitorMut for AddOneToI32Consts {
    fn visit_const_mut(&mut self, c: &mut Const) {
        match &mut c.value {
            Value::I32(x) => {
                *x += 1;
            }
            _ => {},
        }
    }
}

// Get a function from somewhere.
let my_func: &mut LocalFunction = get_my_function();

// Create our visitor.
let mut visitor = AddOneToI32Consts::default();

// Traverse and mutate everything in the function with our visitor.
dfs_pre_order_mut(&mut visitor, my_func, my_func.entry_block());