public final class EventContext extends Object
EventContext
should be neither stored, cached nor hashed. One exception is
when they are stored in ExecutionEventNode
implementations. The equality and hashing
behavior is undefined.ExecutionEventNodeFactory
,
ExecutionEventListener
Modifier and Type | Method and Description |
---|---|
ThreadDeath |
createUnwind(Object info)
Create an unwind throwable, that when thrown, abruptly breaks execution of a node and unwinds
it off the execution stack.
|
ThreadDeath |
createUnwind(Object info,
EventBinding<?> unwindBinding)
Create an unwind throwable, that when thrown, abruptly breaks execution of a node and unwinds
it off the execution stack.
|
Node |
getInstrumentedNode()
Accessor to the instrumented node at which the event occurred.
|
SourceSection |
getInstrumentedSourceSection()
Returns the
SourceSection that is being instrumented. |
Object |
getNodeObject()
Returns a language provided object that represents the instrumented node properties.
|
boolean |
hasTag(Class<? extends Tag> tag)
Returns
true if the underlying instrumented AST is tagged with a particular tag. |
boolean |
isLanguageContextInitialized()
Test if language context of the source of the event is initialized.
|
ExecutionEventNode |
lookupExecutionEventNode(EventBinding<? extends ExecutionEventNodeFactory> binding)
Returns the execution event node that was inserted at this location given an event binding.
|
Iterator<ExecutionEventNode> |
lookupExecutionEventNodes(Collection<EventBinding<? extends ExecutionEventNodeFactory>> bindings)
Returns all execution event nodes in the insertion order at this location, whose event
bindings are contained in the given collection.
|
String |
toString() |
public boolean hasTag(Class<? extends Tag> tag)
true
if the underlying instrumented AST is tagged with a particular tag.
The return value of EventContext.hasTag(Class)
always returns the same value for a particular tag
and EventContext
. The method may be used on compiled code paths.tag
- the tag to check to check, must not be null
.public Object getNodeObject()
null
and
always returns true
for the HAS_KEYS message. Multiple calls to
EventContext.getNodeObject()
return the same node object instance.InstrumentableNode.getNodeObject()
public SourceSection getInstrumentedSourceSection()
SourceSection
that is being instrumented. The returned source section is
final for each EventContext
instance. The returned source section may be null if the
node does not provide sources section.
Performance note: this is method may be invoked in compiled code and is guaranteed to always return a compilation constant .
public Node getInstrumentedNode()
Performance note: this is method may be invoked in compiled code and is guaranteed to always return a compilation constant .
public boolean isLanguageContextInitialized()
public ExecutionEventNode lookupExecutionEventNode(EventBinding<? extends ExecutionEventNodeFactory> binding)
binding
- the binding to lookuppublic Iterator<ExecutionEventNode> lookupExecutionEventNodes(Collection<EventBinding<? extends ExecutionEventNodeFactory>> bindings)
bindings
- a collection of bindings to find the event nodes for at this context locationpublic ThreadDeath createUnwind(Object info)
EventContext.createUnwind(Object, EventBinding)
with the current binding, only the event listener
instance that threw the unwind throwable gets called onUnwind
.info
- an info that is passed into
ExecutionEventListener.onUnwind(EventContext, VirtualFrame, Object)
or
ExecutionEventNode.onUnwind(VirtualFrame, Object)
. It can be used for
arbitrary client data that help to control the unwind process.EventContext.createUnwind(Object, EventBinding)
public ThreadDeath createUnwind(Object info, EventBinding<?> unwindBinding)
onEnter
,
onReturnValue
or onReturnExceptional
methods of
ExecutionEventListener
or ExecutionEventNode
, to initiate the unwind process.
It acts in connection with
ExecutionEventListener.onUnwind(EventContext, VirtualFrame, Object)
or
ExecutionEventNode.onUnwind(VirtualFrame, Object)
. Only the event listener instance
that is associated with the provided unwindBinding
gets called
onUnwind
, use EventContext.createUnwind(java.lang.Object)
to have the current event
listener called onUnwind
. Other bindings that happen to instrument the unwound
nodes get called onReturnExceptional
.
The returned throwable can be kept and thrown again later to repeat the unwind process. A repeating unwind process is possible without deoptimization. A single throwable instance cannot be used on multiple threads concurrently. It can be thrown on a different thread only after the unwind finishes on the last thread.
Usage example of forced return:
protected void onCreate(TruffleInstrument
.TruffleLanguage.Env
env) { // Register a listener that checks the return value to all call nodes // If the return value is not 42, it forces to return 42. env.getInstrumenter().attachExecutionEventListener(SourceSectionFilter
.newBuilder(). tagIs(StandardTags
.CallTag.class).build(), newExecutionEventListener
() { public void onEnter(EventContext
context,VirtualFrame
f) { } public void onReturnValue(EventContext
context,VirtualFrame
f,Object
result) { if (!Objects
.equals(result, 42)) {CompilerDirectives
.transferToInterpreter(); throw context.createUnwind(42); } } publicObject
onUnwind(EventContext
context,VirtualFrame
f,Object
info) { // return 42 on unwind return info; } public void onReturnExceptional(EventContext
context,VirtualFrame
f,Throwable
ex) { } }); }
Usage example of reenter:
protected void onCreate(TruffleInstrument
.TruffleLanguage.Env
env) { // Two event bindings are created: one for reenter, one for unwind // Listener that reenters on unwind, attached to root nodes.EventBinding
<ExecutionEventListener
> functionReenter = env.getInstrumenter().attachExecutionEventListener(SourceSectionFilter
.newBuilder(). tagIs(StandardTags
.RootTag.class).build(), newExecutionEventListener
() { publicObject
onUnwind(EventContext
context,VirtualFrame
f,Object
info) { // Reenters on unwind. returnProbeNode
.UNWIND_ACTION_REENTER; } public void onEnter(EventContext
context,VirtualFrame
f) { } public void onReturnValue(EventContext
context,VirtualFrame
f,Object
result) { } public void onReturnExceptional(EventContext
context,VirtualFrame
f,Throwable
ex) { } }); // Listener that initiates unwind at line 20, attached to statements. env.getInstrumenter().attachExecutionEventListener(SourceSectionFilter
.newBuilder(). tagIs(StandardTags
.StatementTag.class).build(), newExecutionEventListener
() { public void onEnter(EventContext
context,VirtualFrame
f) {SourceSection
ss = context.getInstrumentedSourceSection(); if (ss.getStartLine() == 20) {CompilerDirectives
.transferToInterpreter(); // Unwind to nodes instrumented by functionReenter throw context.createUnwind(null, functionReenter); } } public void onReturnValue(EventContext
context,VirtualFrame
f,Object
result) { } public void onReturnExceptional(EventContext
context,VirtualFrame
f,Throwable
ex) { } }); }
info
- an info that is passed into
ExecutionEventListener.onUnwind(EventContext, VirtualFrame, Object)
or
ExecutionEventNode.onUnwind(VirtualFrame, Object)
. It can be used for
arbitrary client data that help to control the unwind process.unwindBinding
- the binding whose listener's onUnwind
is to be called, or
null
to call the current listener that throws the returned throwable.