Annotation Interface GenerateWrapper


@Retention(CLASS) @Target(TYPE) public @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: