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 Note
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 StackAwareMethodVisitor#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.
Modifier and Type | Field and Description |
---|---|
private List | current
A list of the current elements on the operand stack. |
private int | freeIndex
The next index of the local variable array that is available. |
private static final int[] | SIZE_CHANGE
An array mapping any opcode to its size impact onto the operand stack. |
private final Map | sizes
A mapping of labels to the operand stack size that is expected at this label. |
public static final boolean | UNADJUSTED
|
public static final String | UNADJUSTED_PROPERTY
A property to disable stack adjustment. |
Access | Constructor and Description |
---|---|
protected | StackAwareMethodVisitor(MethodVisitor
The method visitor to delegate operations to. methodVisitor, MethodDescription The method description for which this method visitor is applied. instrumentedMethod)Creates a new stack aware method visitor. |
Modifier and Type | Method and Description |
---|---|
private void | adjustStack(int
The change of the current operation of the operand stack. Must not be larger than delta)2 .Adjusts the current state of the operand stack. |
private void | adjustStack(int
The change of the current operation of the operand stack. Must not be larger than delta, int 2 .The offset of the value within the operand stack. Must be bigger then offset)0 and smaller than
the current stack size. Only permitted if the supplied delta is positive.Adjusts the current state of the operand stack. |
private void | |
private static < The type of the action's resolved value. T> T | Returns: The action's resolved value.The action to execute from a privileged context. action)A proxy for |
public void | |
public int | Returns: The minimal size of the local variable array that is required to perform the operation.The opcode used for storing the top value. store, int The opcode used for loading the top value. load, StackSize The size of the value on top of the operand stack. size)Drains the stack to only contain the top value. |
public static MethodVisitor | Returns: An appropriateThe method visitor to delegate operations to. methodVisitor, MethodDescription The method description for which this method visitor is applied. instrumentedMethod)Wraps the provided method visitor within a stack aware method visitor. |
public void | |
public void | visitFieldInsn(int
the opcode of the type instruction to be visited. This opcode is either
GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD. opcode, String the internal name of the field's owner class (see owner, String Type#getInternalName() ).the field's name. name, String the field's descriptor (see descriptor)Type ).Overrides net. |
public void | visitFrame(int
the type of this stack map frame. Must be type, int Opcodes#F_NEW for expanded
frames, or Opcodes#F_FULL , Opcodes#F_APPEND , Opcodes#F_CHOP , Opcodes#F_SAME or Opcodes#F_APPEND , Opcodes#F_SAME1 for compressed frames.the number of local variables in the visited frame. Long and double values
count for one variable. localVariableLength, Object[] the local variable types in this frame. This array must not be modified. Primitive
types are represented by localVariable, int Opcodes#TOP , Opcodes#INTEGER , Opcodes#FLOAT , Opcodes#LONG , Opcodes#DOUBLE , Opcodes#NULL or
Opcodes#UNINITIALIZED_THIS (long and double are represented by a single element).
Reference types are represented by String objects (representing internal names, see Type#getInternalName() ), and uninitialized types by Label objects (this label designates
the NEW instruction that created this uninitialized value).the number of operand stack elements in the visited frame. Long and double
values count for one stack element. stackSize, Object[] the operand stack types in this frame. This array must not be modified. Its
content has the same format as the "local" array. stack)
Visits the current state of the local variables and operand stack elements.
|
public void | visitInsn(int
the opcode of the instruction to be visited. This opcode is either NOP,
ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5,
LCONST_0, LCONST_1, FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD, LALOAD,
FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IASTORE, LASTORE, FASTORE, DASTORE,
AASTORE, BASTORE, CASTORE, SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2,
SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, IDIV, LDIV,
FDIV, DDIV, IREM, LREM, FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR, IUSHR,
LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D, L2I, L2F, L2D, F2I, F2L, F2D, D2I,
D2L, D2F, I2B, I2C, I2S, LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN, FRETURN,
DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER, or MONITOREXIT. opcode)
Visits a zero operand instruction.
|
public void | visitIntInsn(int
the opcode of the instruction to be visited. This opcode is either BIPUSH, SIPUSH
or NEWARRAY. opcode, int the operand of the instruction to be visited. operand)
Visits an instruction with a single int operand.
When opcode is BIPUSH, operand value should be between Byte.MIN_VALUE and Byte.MAX_VALUE. When opcode is SIPUSH, operand value should be between Short.MIN_VALUE and Short.MAX_VALUE. When opcode is NEWARRAY, operand value should be one of Opcodes#T_BOOLEAN , Opcodes#T_CHAR , Opcodes#T_FLOAT , Opcodes#T_DOUBLE , Opcodes#T_BYTE ,
Opcodes#T_SHORT , Opcodes#T_INT or Opcodes#T_LONG . |
public void | visitInvokeDynamicInsn(String
the method's name. name, String the method's descriptor (see descriptor, Handle Type ).the bootstrap method. bootstrap, Object... bootstrapArguments)Overrides net. |
public void | visitJumpInsn(int
the opcode of the type instruction to be visited. This opcode is either IFEQ,
IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT,
IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL. opcode, Label the operand of the instruction to be visited. This operand is a label that
designates the instruction to which the jump instruction may jump. label)Overrides net. |
public void | visitLabel(Label
a label)
Visits a label.
Label object. |
public void | visitLdcInsn(Object
the constant to be loaded on the stack. This parameter must be a non null value)
Visits a LDC instruction.
Integer , a Float , a Long , a Double , a String , a Type of OBJECT or ARRAY sort for .class constants, for classes whose version is
49, a Type of METHOD sort for MethodType, a Handle for MethodHandle
constants, for classes whose version is 51 or a ConstantDynamic for a constant
dynamic for classes whose version is 55. |
public void | visitLineNumber(int
a line number. This number refers to the source file from which the class was
compiled. line, Label the first instruction corresponding to this line number. start)Overrides net. |
public void | visitLookupSwitchInsn(Label
beginning of the default handler block. defaultOption, int[] the values of the keys. key, Label[] beginnings of the handler blocks. option)labels[i] is the beginning of the
handler block for the keys[i] key.Overrides net. |
public void | visitMethodInsn(int
the opcode of the type instruction to be visited. This opcode is either
INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE. opcode, String the internal name of the method's owner class (see owner, String Type#getInternalName() ).the method's name. name, String the method's descriptor (see descriptor, boolean Type ).if the method's owner class is an interface. isInterface)Overrides net. |
public void | visitMultiANewArrayInsn(String
an array type descriptor (see descriptor, int Type ).the number of dimensions of the array to allocate. dimension)Overrides net. |
public void | visitTableSwitchInsn(int
the minimum key value. minimum, int the maximum key value. maximum, Label beginning of the default handler block. defaultOption, Label... beginnings of the handler blocks. option)labels[i] is the beginning of the
handler block for the min + i key.Overrides net. |
public void | visitTryCatchBlock(Label
the beginning of the exception handler's scope (inclusive). start, Label the end of the exception handler's scope (exclusive). end, Label the beginning of the exception handler's code. handler, String the internal name of the type of exceptions handled by the handler (see type)Type#getInternalName() ), or null to catch any exceptions (for "finally"
blocks).Overrides net. |
public void | visitTypeInsn(int
the opcode of the type instruction to be visited. This opcode is either NEW,
ANEWARRAY, CHECKCAST or INSTANCEOF. opcode, String the operand of the instruction to be visited. This operand must be the internal
name of an object or array class (see type)Type#getInternalName() ).Overrides net. |
public void | visitVarInsn(int
the opcode of the local variable instruction to be visited. This opcode is either
ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET. opcode, int the operand of the instruction to be visited. This operand is the index of a
local variable. variable)
Visits a local variable instruction.
|
current | back to summary |
---|---|
private List<StackSize> current A list of the current elements on the operand stack. |
freeIndex | back to summary |
---|---|
private int freeIndex The next index of the local variable array that is available. |
SIZE_CHANGE | back to summary |
---|---|
private static final int[] SIZE_CHANGE An array mapping any opcode to its size impact onto the operand stack. This mapping is taken from
|
sizes | back to summary |
---|---|
private final Map<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. |
UNADJUSTED | back to summary |
---|---|
public static final boolean UNADJUSTED
|
UNADJUSTED_PROPERTY | back to summary |
---|---|
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. |
StackAwareMethodVisitor | back to summary |
---|---|
protected StackAwareMethodVisitor(MethodVisitor methodVisitor, MethodDescription instrumentedMethod) Creates a new stack aware method visitor.
|
adjustStack | back to summary |
---|---|
private void adjustStack(int delta) Adjusts the current state of the operand stack.
|
adjustStack | back to summary |
---|---|
private void adjustStack(int delta, int offset) Adjusts the current state of the operand stack.
|
doDrain | back to summary |
---|---|
private void doDrain(List<StackSize> stackSizes) Drains all supplied elements of the operand stack. |
doPrivileged | back to summary |
---|---|
private static <T> T doPrivileged(PrivilegedAction<T> action) A proxy for
|
drainStack | back to summary |
---|---|
public void drainStack() Pops all values currently on the stack. |
drainStack | back to summary |
---|---|
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.
|
of | back to summary |
---|---|
public static MethodVisitor of(MethodVisitor methodVisitor, MethodDescription instrumentedMethod) Wraps the provided method visitor within a stack aware method visitor.
|
register | back to summary |
---|---|
public void register(Label label, List<StackSize> stackSizes) Explicitly registers a label to define a given stack state. |
visitFieldInsn | back to summary |
---|---|
public void visitFieldInsn(int opcode, String owner, String name, String descriptor) Overrides net. Doc from net. Visits a field instruction. A field instruction is an instruction that loads or stores the value of a field of an object.
|
visitFrame | back to summary |
---|---|
public void visitFrame(int type, int localVariableLength, Object[] localVariable, int stackSize, Object[] stack) Overrides net. Doc from net. Visits the current state of the local variables and operand stack elements. This method must(*)
be called just before any instruction i that follows an unconditional branch
instruction such as GOTO or THROW, that is the target of a jump instruction, or that starts an
exception handler block. The visited types must describe the values of the local variables and
of the operand stack elements just before i is executed.
In both cases the first frame, corresponding to the method's parameters and access flags, is implicit and must not be visited. Also, it is illegal to visit two or more frames for the same code location (i.e., at least one instruction must be visited between two calls to visitFrame).
|
visitInsn | back to summary |
---|---|
public void visitInsn(int opcode) Overrides net. Doc from net. Visits a zero operand instruction.
|
visitIntInsn | back to summary |
---|---|
public void visitIntInsn(int opcode, int operand) Overrides net. Doc from net. Visits an instruction with a single int operand.
|
visitInvokeDynamicInsn | back to summary |
---|---|
public void visitInvokeDynamicInsn(String name, String descriptor, Handle bootstrap, Object... bootstrapArguments) Overrides net. Doc from net. Visits an invokedynamic instruction.
|
visitJumpInsn | back to summary |
---|---|
public void visitJumpInsn(int opcode, Label label) Overrides net. Doc from net. Visits a jump instruction. A jump instruction is an instruction that may jump to another instruction.
|
visitLabel | back to summary |
---|---|
public void visitLabel(Label label) Overrides net. Doc from net. Visits a label. A label designates the instruction that will be visited just after it. |
visitLdcInsn | back to summary |
---|---|
public void visitLdcInsn(Object value) Overrides net. Doc from net. Visits a LDC instruction. Note that new constant types may be added in future versions of the Java Virtual Machine. To easily detect new constant types, implementations of this method should check for unexpected constant types, like this: if (cst instanceof Integer) { // ... } else if (cst instanceof Float) { // ... } else if (cst instanceof Long) { // ... } else if (cst instanceof Double) { // ... } else if (cst instanceof String) { // ... } else if (cst instanceof Type) { int sort = ((Type) cst).getSort(); if (sort == Type.OBJECT) { // ... } else if (sort == Type.ARRAY) { // ... } else if (sort == Type.METHOD) { // ... } else { // throw an exception } } else if (cst instanceof Handle) { // ... } else if (cst instanceof ConstantDynamic) { // ... } else { // throw an exception }
|
visitLineNumber | back to summary |
---|---|
public void visitLineNumber(int line, Label start) Overrides net. Doc from net. Visits a line number declaration. |
visitLookupSwitchInsn | back to summary |
---|---|
public void visitLookupSwitchInsn(Label defaultOption, int[] key, Label[] option) Overrides net. Doc from net. Visits a LOOKUPSWITCH instruction. |
visitMethodInsn | back to summary |
---|---|
public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) Overrides net. Doc from net. Visits a method instruction. A method instruction is an instruction that invokes a method.
|
visitMultiANewArrayInsn | back to summary |
---|---|
public void visitMultiANewArrayInsn(String descriptor, int dimension) Overrides net. Doc from net. Visits a MULTIANEWARRAY instruction. |
visitTableSwitchInsn | back to summary |
---|---|
public void visitTableSwitchInsn(int minimum, int maximum, Label defaultOption, Label... option) Overrides net. Doc from net. Visits a TABLESWITCH instruction. |
visitTryCatchBlock | back to summary |
---|---|
public void visitTryCatchBlock(Label start, Label end, Label handler, String type) Overrides net. Doc from net. Visits a try catch block.
|
visitTypeInsn | back to summary |
---|---|
public void visitTypeInsn(int opcode, String type) Overrides net. Doc from net. Visits a type instruction. A type instruction is an instruction that takes the internal name of
a class as parameter (see
|
visitVarInsn | back to summary |
---|---|
public void visitVarInsn(int opcode, int variable) Overrides net. Doc from net. Visits a local variable instruction. A local variable instruction is an instruction that loads or stores the value of a local variable.
|