public abstract class TruffleInstrument extends Object
The service provider interface (SPI) for Truffle Instruments: clients of Truffle instrumentation that may observe and inject behavior into interpreters written using the Truffle framework.
Each registered instrument can be
enabled/disabled multiple times during the lifetime of a
PolyglotEngine, but there is never more than one
instance per engine. A new TruffleInstrument instance is created each time the instrument
is enabled, and the currently enabled instance is disposed when the instrument is disabled.
Instrument implementation classes must use the TruffleInstrument.Registration annotation to provide
required metadata and to enable automatic discovery of the implementation.
TruffleInstrument.onCreate(Env).Instrumenter available in the provided environment allows the
instrument instance to bind listeners for execution and
source events, as well as node factories for code injection at guest language code locations.TruffleInstrument.onDispose(Env).Instrumenter instance available in the provided environment may
not be used after disposal.@TruffleInstrument.Registration(id = CoverageExample.ID) public final class CoverageExample extendsTruffleInstrument{ public static finalStringID = "test-coverage"; private finalSet<SourceSection> coverage = newHashSet<>(); @Overrideprotected void onCreate(final Env env) {SourceSectionFilter.Builder builder =SourceSectionFilter.newBuilder();SourceSectionFilterfilter = builder.tagIs(EXPRESSION).build();Instrumenterinstrumenter = env.getInstrumenter(); instrumenter.attachFactory(filter, new CoverageEventFactory(env)); } private class CoverageEventFactory implementsExecutionEventNodeFactory{ private final Env env; CoverageEventFactory(final Env env) { this.env = env; } publicExecutionEventNodecreate(finalEventContextec) { finalPrintStreamout = newPrintStream(env.out()); return newExecutionEventNode() { @CompilerDirectives.CompilationFinalprivate boolean visited; @Overridepublic void onReturnValue(VirtualFramevFrame,Objectresult) { if (!visited) {CompilerDirectives.transferToInterpreterAndInvalidate(); visited = true;SourceSectionsrc = ec.getInstrumentedSourceSection(); out.print(src.getCharIndex() + " "); coverage.add(src); } } }; } } }
| Modifier and Type | Class and Description |
|---|---|
static class |
TruffleInstrument.Env
Access to instrumentation services as well as input, output, and error streams.
|
static interface |
TruffleInstrument.Registration
Annotation that registers an
instrument implementations for
automatic discovery. |
| Modifier | Constructor and Description |
|---|---|
protected |
TruffleInstrument()
Constructor for subclasses.
|
| Modifier and Type | Method and Description |
|---|---|
protected abstract void |
onCreate(TruffleInstrument.Env env)
Invoked once on each newly allocated
TruffleInstrument instance. |
protected void |
onDispose(TruffleInstrument.Env env)
|
protected TruffleInstrument()
protected abstract void onCreate(TruffleInstrument.Env env)
TruffleInstrument instance.
The method may register additional
services - e.g. objects to be exposed via
lookup query. For example
to expose a debugger one could define an abstract debugger controller:
public abstract class DebuggerController {
DebuggerController() {
}
public abstract void installBreakpoint(int i, Callback callback);
public abstract void stepInto(Callback callback);
public abstract void stepOut(Callback callback);
public abstract void stepOver(Callback callback);
public interface Callback {
void halted(DebuggerController debugger, EventContext haltedAt);
}
}
and declare it as a service associated with the instrument,
implement it, instantiate and register in own's
instrument onCreate method:
@TruffleInstrument.Registration(id = DebuggerExample.ID, services = DebuggerController.class) public final class DebuggerExample extendsTruffleInstrument{ private Controller controller; @Overrideprotected void onCreate(Env env) { assert this.controller == null; this.controller = new Controller(env.getInstrumenter()); env.registerService(controller); } private static final class Controller extends DebuggerController { private finalInstrumenterinstrumenter; privateEventBinding<?> stepping; private Callback currentStatementCallback; Controller(Instrumenterinstrumenter) { this.instrumenter = instrumenter; } } }
env - environment information for the instrumentTruffleInstrument.Env.getInstrumenter()protected void onDispose(TruffleInstrument.Env env)
env - environment information for the instrument