Annotation Interface GenerateWrapper
Generates a default wrapper subclass of an annotated
InstrumentableNode
subclass. The
generated subclass has the same class name as the original class name plus the 'Wrapper' suffix.
The generated class has default package visibility. All non-final and non-private methods
starting with execute or resume prefix (when specified)
are
overridden by the generated wrapper. The generated overrides notifies execution events as
required by probes
. Other abstract methods are directly delegated to the
wrapped node. No other methods are overridden by the generated wrapper. At least one method
starting with execute must be non-private and non-final. Every execute method must have
VirtualFrame
as the first declared parameter.
Use methods with execute
prefix for ordinary guest code execution. If the guest
language supports yield, add yieldExceptions()
argument and specify
resume prefix
to mark method(s) that resume the yielded execution.
To successfully match the yielded/resumed execution, override
RootNode.isSameFrame(Frame, Frame)
in case the resumed frame is not an identical instance
to the yielded frame.
Example Usage:
@GenerateWrapper abstract class ExpressionNode extends Node implements InstrumentableNode { abstract Object execute(VirtualFrame frame); @Override public WrapperNode createWrapper(ProbeNode probeNode) { return new ExpressionNodeWrapper(this, probeNode); } }
Example that ignores return values:
@GenerateWrapper abstract class ExpressionNode extends Node implements InstrumentableNode { abstract Object execute(VirtualFrame frame); @Override public WrapperNode createWrapper(ProbeNode probeNode) { return new ExpressionNodeWrapper(this, probeNode); } @GenerateWrapper.OutgoingConverter final Object convertOutgoing(Object outgoingValue) { return null; } }
Example that converts incoming byte values to int:
@GenerateWrapper abstract class ExpressionNode extends Node implements InstrumentableNode { abstract Object execute(VirtualFrame frame); @Override public WrapperNode createWrapper(ProbeNode probeNode) { return new ExpressionNodeWrapper(this, probeNode); } @GenerateWrapper.IncomingConverter final Object convertIncoming(Object incomingValue) { if (incomingValue instanceof Byte) { return (int) ((byte) incomingValue); } return incomingValue; } }
Example that prevents instrumentation from being added to a method:
@GenerateWrapper abstract class ExpressionNode extends Node implements InstrumentableNode { abstract Object execute(VirtualFrame frame); @Override public WrapperNode createWrapper(ProbeNode probeNode) { return new ExpressionNodeWrapper(this, probeNode); } @GenerateWrapper.Ignore abstract Object executeWithoutInstrumentation(VirtualFrame frame); }
- Since:
- 0.33
- See Also:
-
Nested Class Summary
Modifier and TypeClassDescriptionstatic @interface
Annotates a method which should not be instrumented in the generated wrapper subclass.static @interface
Annotates a method to be used as incoming value converter.static @interface
Annotates a method to be used as outgoing value converter.static interface
An interface to be implemented byyield exceptions
. -
Optional Element Summary
-
Element Details
-
yieldExceptions
Class<?>[] yieldExceptionsExceptions that are thrown to yield the execution of a thread. They must implementGenerateWrapper.YieldException
interface. When one of them is thrown,onYield()
is called automatically. To indicate resume of the execution, provideresumeMethodPrefix()
.- Since:
- 24.0
- Default:
{}
-
resumeMethodPrefix
String resumeMethodPrefixPrefix of methods that resume execution afteryield
. The prefix is empty by default, which means no resume methods. When non-empty, the generated wrapper callsProbeNode.onResume(VirtualFrame)
instead ofProbeNode.onEnter(VirtualFrame)
.- Since:
- 24.0
- Default:
""
-