-
Notifications
You must be signed in to change notification settings - Fork 43
/
Copy pathDemo42Monitor.v3
51 lines (46 loc) · 2.04 KB
/
Demo42Monitor.v3
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
// 1. Register our simple monitor so it is accessible with --monitors=demo42
def monitor_ = MonitorRegistry.add(
"demo42", "Reports occurrences of the number 42 after an integer addition.",
Demo42Monitor.new());
// Our monitor class that is put in the registry. Its {onParse()} method will be called
// after a user module is parsed.
class Demo42Monitor extends Monitor {
// 2. Instrument bytecode of the module using our class below.
def onParse(m: Module, err: ErrorGen) {
System.puts("Instrumenting module...\n");
Demo42Instrumenter.new(m).run(); // run bytecode instrumenter
}
// 4. Report results when finished.
def onFinish(i: Instance, r: Result) {
if (found) System.puts("A 42 was found!\n");
else System.puts("No 42 occurred in any i32.add.\n");
}
}
// Our monitor defines a bytecode instrumenter and overrides the {visit_I32_ADD()} method
// to insert instrumentation on "i32.add" bytecodes.
class Demo42Instrumenter extends BytecodeInstrumenter {
new(module: Module) super(module) { } // constructor must take a module
def visit_I32_ADD() { // instrument all "i32.add" instructions
System.puts("Found an i32.add...\n");
insertProbeHere(AddCheckerProbe.new());
}
}
// A global variable indicating whether 42 was found.
var found = false;
// Our monitor uses a custom probe that checks whether an "i32.add" will produce 42.
class AddCheckerProbe extends Probe {
// 3. Execute probe logic at runtime.
def fire(dynamicLoc: DynamicLoc) -> Resumption {
System.puts("Executing an i32.add...\n");
var accessor = dynamicLoc.frame.getFrameAccessor(); // get accessor to inspect stack frame
var a = accessor.getOperand(-1); // get first operand to add
var b = accessor.getOperand(0); // get second operand to add
var result = Values.unbox_i(a) + Values.unbox_i(b); // compute result of add
if (result == 42) { // check if we should terminate
found = true;
System.puts("42 was the result!\n");
return Resumption.Trap(TrapReason.BREAK, true);
}
return Resumption.Continue; // otherwise, continue unimpeded
}
}