Class StackAwareMethodVisitor

java.lang.Object
org.objectweb.asm.MethodVisitor
net.bytebuddy.utility.visitor.StackAwareMethodVisitor

public class StackAwareMethodVisitor extends org.objectweb.asm.MethodVisitor

A method visitor that is aware of the current size of the operand stack at all times. Additionally, this method takes care of maintaining an index for the next currently unused index of the local variable array.

Important: It is not always possible to apply this method visitor if it is applied to a class file compiled for Java 5 or earlier, or if frames are computed by ASM and not passed to this visitor, if a method also contains Opcodes.GOTO instructions. In the latter case, the stack is assumed empty after the instruction. If this is a problem, stack adjustment can be disabled by setting UNADJUSTED_PROPERTY to true. With this setting, Byte Buddy does no longer attempt draining non-empty stacks and skips this visitor in all cases. This might however lead to verification problems if stacks are left non-empty. As the latter happens more common and since this visitor is applied defensively, using this wrapper is considered the more sensible default.

  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    private List<StackSize>
    A list of the current elements on the operand stack.
    private int
    The next index of the local variable array that is available.
    private static final int[]
    An array mapping any opcode to its size impact onto the operand stack.
    private final Map<org.objectweb.asm.Label,List<StackSize>>
    A mapping of labels to the operand stack size that is expected at this label.
    static final boolean
    true if stack adjustment is disabled.
    static final String
    A property to disable stack adjustment.

    Fields inherited from class org.objectweb.asm.MethodVisitor

    api, mv
  • Constructor Summary

    Constructors
    Modifier
    Constructor
    Description
    protected
    StackAwareMethodVisitor(org.objectweb.asm.MethodVisitor methodVisitor, MethodDescription instrumentedMethod)
    Creates a new stack aware method visitor.
  • Method Summary

    Modifier and Type
    Method
    Description
    private void
    adjustStack(int delta)
    Adjusts the current state of the operand stack.
    private void
    adjustStack(int delta, int offset)
    Adjusts the current state of the operand stack.
    private void
    doDrain(List<StackSize> stackSizes)
    Drains all supplied elements of the operand stack.
    private static <T> T
    A proxy for java.security.AccessController#doPrivileged that is activated if available.
    void
    Pops all values currently on the stack.
    int
    drainStack(int store, int load, StackSize size)
    Drains the stack to only contain the top value.
    static org.objectweb.asm.MethodVisitor
    of(org.objectweb.asm.MethodVisitor methodVisitor, MethodDescription instrumentedMethod)
    Wraps the provided method visitor within a stack aware method visitor.
    void
    register(org.objectweb.asm.Label label, List<StackSize> stackSizes)
    Explicitly registers a label to define a given stack state.
    void
    visitFieldInsn(int opcode, String owner, String name, String descriptor)
     
    void
    visitFrame(int type, int localVariableLength, Object[] localVariable, int stackSize, Object[] stack)
     
    void
    visitInsn(int opcode)
     
    void
    visitIntInsn(int opcode, int operand)
     
    void
    visitInvokeDynamicInsn(String name, String descriptor, org.objectweb.asm.Handle bootstrap, Object... bootstrapArguments)
     
    void
    visitJumpInsn(int opcode, org.objectweb.asm.Label label)
     
    void
    visitLabel(org.objectweb.asm.Label label)
     
    void
     
    void
    visitLineNumber(int line, org.objectweb.asm.Label start)
     
    void
    visitLookupSwitchInsn(org.objectweb.asm.Label defaultOption, int[] key, org.objectweb.asm.Label[] option)
     
    void
    visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface)
     
    void
    visitMultiANewArrayInsn(String descriptor, int dimension)
     
    void
    visitTableSwitchInsn(int minimum, int maximum, org.objectweb.asm.Label defaultOption, org.objectweb.asm.Label... option)
     
    void
    visitTryCatchBlock(org.objectweb.asm.Label start, org.objectweb.asm.Label end, org.objectweb.asm.Label handler, String type)
     
    void
    visitTypeInsn(int opcode, String type)
     
    void
    visitVarInsn(int opcode, int variable)
     

    Methods inherited from class org.objectweb.asm.MethodVisitor

    getDelegate, visitAnnotableParameterCount, visitAnnotation, visitAnnotationDefault, visitAttribute, visitCode, visitEnd, visitIincInsn, visitInsnAnnotation, visitLocalVariable, visitLocalVariableAnnotation, visitMaxs, visitMethodInsn, visitParameter, visitParameterAnnotation, visitTryCatchAnnotation, visitTypeAnnotation

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • UNADJUSTED_PROPERTY

      public static final String UNADJUSTED_PROPERTY
      A property to disable stack adjustment. Stack adjustment is typically needed when instrumenting other generated code that leaves excess values on the stack. This is also often the case when byte code obfuscation is used.
      See Also:
    • UNADJUSTED

      public static final boolean UNADJUSTED
      true if stack adjustment is disabled.
    • SIZE_CHANGE

      private static final int[] SIZE_CHANGE
      An array mapping any opcode to its size impact onto the operand stack. This mapping is taken from Frame with the difference that the Opcodes.JSR instruction is mapped to a size of 0 as it does not impact the stack after returning from the instruction.
    • current

      private List<StackSize> current
      A list of the current elements on the operand stack.
    • sizes

      private final Map<org.objectweb.asm.Label,List<StackSize>> sizes
      A mapping of labels to the operand stack size that is expected at this label. Lists stored in this map must not be mutated.
    • freeIndex

      private int freeIndex
      The next index of the local variable array that is available.
  • Constructor Details

    • StackAwareMethodVisitor

      protected StackAwareMethodVisitor(org.objectweb.asm.MethodVisitor methodVisitor, MethodDescription instrumentedMethod)
      Creates a new stack aware method visitor.
      Parameters:
      methodVisitor - The method visitor to delegate operations to.
      instrumentedMethod - The method description for which this method visitor is applied.
  • Method Details

    • of

      public static org.objectweb.asm.MethodVisitor of(org.objectweb.asm.MethodVisitor methodVisitor, MethodDescription instrumentedMethod)
      Wraps the provided method visitor within a stack aware method visitor.
      Parameters:
      methodVisitor - The method visitor to delegate operations to.
      instrumentedMethod - The method description for which this method visitor is applied.
      Returns:
      An appropriate
    • doPrivileged

      @Enhance private static <T> T doPrivileged(PrivilegedAction<T> action)
      A proxy for java.security.AccessController#doPrivileged that is activated if available.
      Type Parameters:
      T - The type of the action's resolved value.
      Parameters:
      action - The action to execute from a privileged context.
      Returns:
      The action's resolved value.
    • adjustStack

      private void adjustStack(int delta)
      Adjusts the current state of the operand stack.
      Parameters:
      delta - The change of the current operation of the operand stack. Must not be larger than 2.
    • adjustStack

      private void adjustStack(int delta, int offset)
      Adjusts the current state of the operand stack.
      Parameters:
      delta - The change of the current operation of the operand stack. Must not be larger than 2.
      offset - The offset of the value within the operand stack. Must be bigger then 0 and smaller than the current stack size. Only permitted if the supplied delta is positive.
    • drainStack

      public void drainStack()
      Pops all values currently on the stack.
    • drainStack

      public int drainStack(int store, int load, StackSize size)
      Drains the stack to only contain the top value. For this, the value on top of the stack is temporarily stored in the local variable array until all values on the stack are popped off. Subsequently, the top value is pushed back onto the operand stack.
      Parameters:
      store - The opcode used for storing the top value.
      load - The opcode used for loading the top value.
      size - The size of the value on top of the operand stack.
      Returns:
      The minimal size of the local variable array that is required to perform the operation.
    • doDrain

      private void doDrain(List<StackSize> stackSizes)
      Drains all supplied elements of the operand stack.
      Parameters:
      stackSizes - The stack sizes of the elements to drain.
    • register

      public void register(org.objectweb.asm.Label label, List<StackSize> stackSizes)
      Explicitly registers a label to define a given stack state.
      Parameters:
      label - The label to register a stack state for.
      stackSizes - The stack sizes to assume when reaching the supplied label.
    • visitInsn

      public void visitInsn(int opcode)
      Overrides:
      visitInsn in class org.objectweb.asm.MethodVisitor
    • visitIntInsn

      public void visitIntInsn(int opcode, int operand)
      Overrides:
      visitIntInsn in class org.objectweb.asm.MethodVisitor
    • visitVarInsn

      public void visitVarInsn(int opcode, int variable)
      Overrides:
      visitVarInsn in class org.objectweb.asm.MethodVisitor
    • visitTypeInsn

      public void visitTypeInsn(int opcode, String type)
      Overrides:
      visitTypeInsn in class org.objectweb.asm.MethodVisitor
    • visitFieldInsn

      public void visitFieldInsn(int opcode, String owner, String name, String descriptor)
      Overrides:
      visitFieldInsn in class org.objectweb.asm.MethodVisitor
    • visitMethodInsn

      public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface)
      Overrides:
      visitMethodInsn in class org.objectweb.asm.MethodVisitor
    • visitInvokeDynamicInsn

      public void visitInvokeDynamicInsn(String name, String descriptor, org.objectweb.asm.Handle bootstrap, Object... bootstrapArguments)
      Overrides:
      visitInvokeDynamicInsn in class org.objectweb.asm.MethodVisitor
    • visitLdcInsn

      public void visitLdcInsn(Object value)
      Overrides:
      visitLdcInsn in class org.objectweb.asm.MethodVisitor
    • visitMultiANewArrayInsn

      public void visitMultiANewArrayInsn(String descriptor, int dimension)
      Overrides:
      visitMultiANewArrayInsn in class org.objectweb.asm.MethodVisitor
    • visitJumpInsn

      public void visitJumpInsn(int opcode, org.objectweb.asm.Label label)
      Overrides:
      visitJumpInsn in class org.objectweb.asm.MethodVisitor
    • visitLabel

      public void visitLabel(org.objectweb.asm.Label label)
      Overrides:
      visitLabel in class org.objectweb.asm.MethodVisitor
    • visitLineNumber

      public void visitLineNumber(int line, org.objectweb.asm.Label start)
      Overrides:
      visitLineNumber in class org.objectweb.asm.MethodVisitor
    • visitTableSwitchInsn

      public void visitTableSwitchInsn(int minimum, int maximum, org.objectweb.asm.Label defaultOption, org.objectweb.asm.Label... option)
      Overrides:
      visitTableSwitchInsn in class org.objectweb.asm.MethodVisitor
    • visitLookupSwitchInsn

      public void visitLookupSwitchInsn(org.objectweb.asm.Label defaultOption, int[] key, org.objectweb.asm.Label[] option)
      Overrides:
      visitLookupSwitchInsn in class org.objectweb.asm.MethodVisitor
    • visitTryCatchBlock

      public void visitTryCatchBlock(org.objectweb.asm.Label start, org.objectweb.asm.Label end, org.objectweb.asm.Label handler, @MaybeNull String type)
      Overrides:
      visitTryCatchBlock in class org.objectweb.asm.MethodVisitor
    • visitFrame

      public void visitFrame(int type, int localVariableLength, @MaybeNull Object[] localVariable, int stackSize, @MaybeNull Object[] stack)
      Overrides:
      visitFrame in class org.objectweb.asm.MethodVisitor