Top Description Fields Constructors Methods
net.bytebuddy.jar.asm

pack-priv Class Frame

extends Object
Class Inheritance
Known Direct Subclasses
net.bytebuddy.jar.asm.CurrentFrame

The input and output stack map frames of a basic block.

Stack map frames are computed in two steps:

Output stack map frames are computed relatively to the input frame of the basic block, which is not yet known when output frames are computed. It is therefore necessary to be able to represent abstract types such as "the type at position x in the input frame locals" or "the type at position x from the top of the input frame stack" or even "the type at position x in the input frame, with y more (or less) array dimensions". This explains the rather complicated type format used in this class, explained below.

The local variables and the operand stack of input and output frames contain values called "abstract types" hereafter. An abstract type is represented with 4 fields named DIM, KIND, FLAGS and VALUE, packed in a single int value for better performance and memory efficiency:

  =====================================
  |...DIM|KIND|.F|...............VALUE|
  =====================================

Output frames can contain abstract types of any kind and with a positive or negative array dimension (and even unassigned types, represented by 0 - which does not correspond to any valid abstract type value). Input frames can only contain CONSTANT_KIND, REFERENCE_KIND, UNINITIALIZED_KIND or FORWARD_UNINITIALIZED_KIND abstract types of positive or null array dimension. In all cases the type table contains only internal type names (array type descriptors are forbidden - array dimensions must be represented through the DIM field).

The LONG and DOUBLE types are always represented by using two slots (LONG + TOP or DOUBLE + TOP), for local variables as well as in the operand stack. This is necessary to be able to simulate DUPx_y instructions, whose effect would be dependent on the concrete types represented by the abstract types in the stack (which are not always known).

Author
Eric Bruneton

Field Summary

Modifier and TypeField and Description
pack-priv static final int
private static final int
ARRAY_OF

The constant to be added to an abstract type to get one with one more array dimension.

private static final int
private static final int
private static final int
pack-priv static final int
private static final int
private static final int
private static final int
private static final int
private static final int
private static final int
ELEMENT_OF

The constant to be added to an abstract type to get one with one less array dimension.

private static final int
private static final int
private static final int
private static final int
pack-priv static final int
private int
initializationCount

The number of types that are initialized in the basic block.

private int[]
initializations

The abstract types that are initialized in the basic block.

private int[]
inputLocals

The input stack map frame locals.

private int[]
inputStack

The input stack map frame stack.

private static final int
private static final int
private static final int
private static final int
private static final int
pack-priv static final int
pack-priv static final int
pack-priv static final int
pack-priv static final int
pack-priv static final int
pack-priv static final int
pack-priv static final int
pack-priv static final int
pack-priv static final int
private static final int
private static final int
private static final int
private static final int
private static final int
private static final int
private int[]
outputLocals

The output stack map frame locals.

private int[]
outputStack

The output stack map frame stack.

private short
outputStackStart

The start of the output stack, relatively to the input stack.

private short
outputStackTop

The index of the top stack element in outputStack.

pack-priv Label
owner

The basic block to which these input and output stack map frames correspond.

private static final int
pack-priv static final int
pack-priv static final int
pack-priv static final int
pack-priv static final int
pack-priv static final int
private static final int
private static final int
private static final int
private static final int
TOP_IF_LONG_OR_DOUBLE_FLAG

A flag used for LOCAL_KIND and STACK_KIND abstract types, indicating that if the resolved, concrete type is LONG or DOUBLE, TOP should be used instead (because the value has been partially overridden with an xSTORE instruction).

private static final int
private static final int
private static final int
private static final int

Constructor Summary

AccessConstructor and Description
pack-priv
Frame(final Label
the basic block to which these input and output stack map frames correspond.
owner
)

Constructs a new Frame.

Method Summary

Modifier and TypeMethod and Description
pack-priv final void
accept(final MethodWriter
the MethodWriter that should visit the input frame of this Frame.
methodWriter
)

Makes the given MethodWriter visit the input frame of this Frame.

private void
addInitializedType(final int
an abstract type on a which a constructor is invoked.
abstractType
)

Adds an abstract type to the list of types on which a constructor is invoked in the basic block.

pack-priv final void
copyFrom(final Frame
The new frame value.
frame
)

Sets this frame to the value of the given frame.

pack-priv void
execute(final int
the opcode of the instruction.
opcode
,
final int
the numeric operand of the instruction, if any.
arg
,
final Symbol
the Symbol operand of the instruction, if any.
argSymbol
,
final SymbolTable
the type table to use to lookup and store type Symbol.
symbolTable
)

Simulates the action of the given instruction on the output stack frame.

pack-priv static int

Returns:

the abstract type corresponding to the given frame element type.
getAbstractTypeFromApiFormat
(final SymbolTable
the type table to use to lookup and store type Symbol.
symbolTable
,
final Object
a frame element type described using the same format as in MethodVisitor#visitFrame, i.e. either Opcodes#TOP, Opcodes#INTEGER, Opcodes#FLOAT, Opcodes#LONG, Opcodes#DOUBLE, Opcodes#NULL, or Opcodes#UNINITIALIZED_THIS, or the internal name of a class, or a Label designating a NEW instruction (for uninitialized types).
type
)

Returns the abstract type corresponding to the given public API frame element type.

private static int

Returns:

the abstract type corresponding to the given type descriptor.
getAbstractTypeFromDescriptor
(final SymbolTable
the type table to use to lookup and store type Symbol.
symbolTable
,
final String
a string ending with a type descriptor.
buffer
,
final int
the start offset of the type descriptor in buffer.
offset
)

Returns the abstract type corresponding to the given type descriptor.

pack-priv static int

Returns:

the abstract type value corresponding to the given internal name.
getAbstractTypeFromInternalName
(final SymbolTable
the type table to use to lookup and store type Symbol.
symbolTable
,
final String
the internal name of a class. This must not be an array type descriptor.
internalName
)

Returns the abstract type corresponding to the internal name of a class.

private int

Returns:

the concrete output type corresponding to 'abstractOutputType'.
getConcreteOutputType
(final int
an abstract output type.
abstractOutputType
,
final int
the size of the input stack, used to resolve abstract output types of STACK_KIND kind.
numStack
)

Computes the concrete output type corresponding to a given abstract output type.

private int

Returns:

the REFERENCE_KIND abstract type corresponding to abstractType if it is UNINITIALIZED_THIS or an UNINITIALIZED_KIND or FORWARD_UNINITIALIZED_KIND abstract type for one of the types on which a constructor is invoked in the basic block. Otherwise returns abstractType.
getInitializedType
(final SymbolTable
the type table to use to lookup and store type Symbol.
symbolTable
,
final int
an abstract type.
abstractType
)

Returns the "initialized" abstract type corresponding to the given abstract type.

pack-priv final int
private int

Returns:

the abstract type stored at the given local variable index in the output frame.
getLocal
(final int
the index of the local variable whose value must be returned.
localIndex
)

Returns the abstract type stored at the given local variable index in the output frame.

pack-priv final boolean

Returns:

true if the input frame of 'frame' has been changed by this operation.
merge
(final SymbolTable
the type table to use to lookup and store type Symbol.
symbolTable
,
final Frame
the Frame whose input frame must be updated. This should be the frame of a successor, in the control flow graph, of the basic block corresponding to this frame.
dstFrame
,
final int
if 'frame' corresponds to an exception handler basic block, the type table index of the caught exception type, otherwise 0.
catchTypeIndex
)

Merges the input frame of the given Frame with the input and output frames of this Frame.

private static boolean

Returns:

true if the type array has been modified by this operation.
merge
(final SymbolTable
the type table to use to lookup and store type Symbol.
symbolTable
,
final int
the abstract type with which the abstract type array element must be merged. This type should be of CONSTANT_KIND, REFERENCE_KIND, UNINITIALIZED_KIND or FORWARD_UNINITIALIZED_KIND kind, with positive or null array dimensions.
sourceType
,
final int[]
an array of abstract types. These types should be of CONSTANT_KIND, REFERENCE_KIND, UNINITIALIZED_KIND or FORWARD_UNINITIALIZED_KIND kind, with positive or null array dimensions.
dstTypes
,
final int
the index of the type that must be merged in dstTypes.
dstIndex
)

Merges the type at the given index in the given abstract type array with the given type.

private int

Returns:

the abstract type that has been popped from the output frame stack.
pop
()

Pops an abstract type from the output frame stack and returns its value.

private void
pop(final int
the number of abstract types that must be popped.
elements
)

Pops the given number of abstract types from the output frame stack.

private void
pop(final String
a type or method descriptor (in which case its argument types are popped).
descriptor
)

Pops as many abstract types from the output frame stack as described by the given descriptor.

private void
push(final int
an abstract type.
abstractType
)

Pushes the given abstract type on the output frame stack.

private void
push(final SymbolTable
the type table to use to lookup and store type Symbol.
symbolTable
,
final String
a type or method descriptor (in which case its return type is pushed).
descriptor
)

Pushes the abstract type corresponding to the given descriptor on the output frame stack.

pack-priv static void
putAbstractType(final SymbolTable
the type table to use to lookup and store type Symbol.
symbolTable
,
final int abstractType, final ByteVector
where the abstract type must be put.
output
)

Put the given abstract type in the given ByteVector, using the JVMS verification_type_info format used in StackMapTable attributes.

pack-priv final void
setInputFrameFromApiFormat(final SymbolTable
the type table to use to lookup and store type Symbol.
symbolTable
,
final int
the number of local variables.
numLocal
,
final Object[]
the local variable types, described using the same format as in MethodVisitor#visitFrame.
local
,
final int
the number of operand stack elements.
numStack
,
final Object[]
the operand stack types, described using the same format as in MethodVisitor#visitFrame.
stack
)

Sets the input frame from the given public API frame description.

pack-priv final void
setInputFrameFromDescriptor(final SymbolTable
the type table to use to lookup and store type Symbol.
symbolTable
,
final int
the method's access flags.
access
,
final String
the method descriptor.
descriptor
,
final int
the maximum number of local variables of the method.
maxLocals
)

Sets the input frame from the given method description.

private void
setLocal(final int
the index of the output frame local variable that must be set.
localIndex
,
final int
the value that must be set.
abstractType
)

Replaces the abstract type stored at the given local variable index in the output frame.

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

APPEND_FRAMEback to summary
pack-priv static final int APPEND_FRAME
ARRAY_OFback to summary
private static final int ARRAY_OF

The constant to be added to an abstract type to get one with one more array dimension.

BOOLEANback to summary
private static final int BOOLEAN
BYTEback to summary
private static final int BYTE
CHARback to summary
private static final int CHAR
CHOP_FRAMEback to summary
pack-priv static final int CHOP_FRAME
CONSTANT_KINDback to summary
private static final int CONSTANT_KIND
DIM_MASKback to summary
private static final int DIM_MASK
DIM_SHIFTback to summary
private static final int DIM_SHIFT
DIM_SIZEback to summary
private static final int DIM_SIZE
DOUBLEback to summary
private static final int DOUBLE
ELEMENT_OFback to summary
private static final int ELEMENT_OF

The constant to be added to an abstract type to get one with one less array dimension.

FLAGS_SHIFTback to summary
private static final int FLAGS_SHIFT
FLAGS_SIZEback to summary
private static final int FLAGS_SIZE
FLOATback to summary
private static final int FLOAT
FORWARD_UNINITIALIZED_KINDback to summary
private static final int FORWARD_UNINITIALIZED_KIND
FULL_FRAMEback to summary
pack-priv static final int FULL_FRAME
initializationCountback to summary
private int initializationCount

The number of types that are initialized in the basic block. See initializations.

initializationsback to summary
private int[] initializations

The abstract types that are initialized in the basic block. A constructor invocation on an UNINITIALIZED, FORWARD_UNINITIALIZED or UNINITIALIZED_THIS abstract type must replace every occurrence of this type in the local variables and in the operand stack. This cannot be done during the first step of the algorithm since, during this step, the local variables and the operand stack types are still abstract. It is therefore necessary to store the abstract types of the constructors which are invoked in the basic block, in order to do this replacement during the second step of the algorithm, where the frames are fully computed. Note that this array can contain abstract types that are relative to the input locals or to the input stack.

inputLocalsback to summary
private int[] inputLocals

The input stack map frame locals. This is an array of abstract types.

inputStackback to summary
private int[] inputStack

The input stack map frame stack. This is an array of abstract types.

INTEGERback to summary
private static final int INTEGER
ITEM_ASM_BOOLEANback to summary
private static final int ITEM_ASM_BOOLEAN
ITEM_ASM_BYTEback to summary
private static final int ITEM_ASM_BYTE
ITEM_ASM_CHARback to summary
private static final int ITEM_ASM_CHAR
ITEM_ASM_SHORTback to summary
private static final int ITEM_ASM_SHORT
ITEM_DOUBLEback to summary
pack-priv static final int ITEM_DOUBLE
ITEM_FLOATback to summary
pack-priv static final int ITEM_FLOAT
ITEM_INTEGERback to summary
pack-priv static final int ITEM_INTEGER
ITEM_LONGback to summary
pack-priv static final int ITEM_LONG
ITEM_NULLback to summary
pack-priv static final int ITEM_NULL
ITEM_OBJECTback to summary
pack-priv static final int ITEM_OBJECT
ITEM_TOPback to summary
pack-priv static final int ITEM_TOP
ITEM_UNINITIALIZEDback to summary
pack-priv static final int ITEM_UNINITIALIZED
ITEM_UNINITIALIZED_THISback to summary
pack-priv static final int ITEM_UNINITIALIZED_THIS
KIND_MASKback to summary
private static final int KIND_MASK
KIND_SHIFTback to summary
private static final int KIND_SHIFT
KIND_SIZEback to summary
private static final int KIND_SIZE
LOCAL_KINDback to summary
private static final int LOCAL_KIND
LONGback to summary
private static final int LONG
NULLback to summary
private static final int NULL
outputLocalsback to summary
private int[] outputLocals

The output stack map frame locals. This is an array of abstract types.

outputStackback to summary
private int[] outputStack

The output stack map frame stack. This is an array of abstract types.

outputStackStartback to summary
private short outputStackStart

The start of the output stack, relatively to the input stack. This offset is always negative or null. A null offset means that the output stack must be appended to the input stack. A -n offset means that the first n output stack elements must replace the top n input stack elements, and that the other elements must be appended to the input stack.

outputStackTopback to summary
private short outputStackTop

The index of the top stack element in outputStack.

ownerback to summary
pack-priv Label owner

The basic block to which these input and output stack map frames correspond.

REFERENCE_KINDback to summary
private static final int REFERENCE_KIND
RESERVEDback to summary
pack-priv static final int RESERVED
SAME_FRAMEback to summary
pack-priv static final int SAME_FRAME
SAME_FRAME_EXTENDEDback to summary
pack-priv static final int SAME_FRAME_EXTENDED
SAME_LOCALS_1_STACK_ITEM_FRAMEback to summary
pack-priv static final int SAME_LOCALS_1_STACK_ITEM_FRAME
SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDEDback to summary
pack-priv static final int SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED
SHORTback to summary
private static final int SHORT
STACK_KINDback to summary
private static final int STACK_KIND
TOPback to summary
private static final int TOP
TOP_IF_LONG_OR_DOUBLE_FLAGback to summary
private static final int TOP_IF_LONG_OR_DOUBLE_FLAG

A flag used for LOCAL_KIND and STACK_KIND abstract types, indicating that if the resolved, concrete type is LONG or DOUBLE, TOP should be used instead (because the value has been partially overridden with an xSTORE instruction).

UNINITIALIZED_KINDback to summary
private static final int UNINITIALIZED_KIND
UNINITIALIZED_THISback to summary
private static final int UNINITIALIZED_THIS
VALUE_MASKback to summary
private static final int VALUE_MASK
VALUE_SIZEback to summary
private static final int VALUE_SIZE

Constructor Detail

Frameback to summary
pack-priv Frame(final Label owner)

Constructs a new Frame.

Parameters
owner:Label

the basic block to which these input and output stack map frames correspond.

Method Detail

acceptback to summary
pack-priv final void accept(final MethodWriter methodWriter)

Makes the given MethodWriter visit the input frame of this Frame. The visit is done with the MethodWriter#visitFrameStart, MethodWriter#visitAbstractType and MethodWriter#visitFrameEnd methods.

Parameters
methodWriter:MethodWriter

the MethodWriter that should visit the input frame of this Frame.

addInitializedTypeback to summary
private void addInitializedType(final int abstractType)

Adds an abstract type to the list of types on which a constructor is invoked in the basic block.

Parameters
abstractType:int

an abstract type on a which a constructor is invoked.

copyFromback to summary
pack-priv final void copyFrom(final Frame frame)

Sets this frame to the value of the given frame.

Warning

after this method is called the two frames share the same data structures. It is recommended to discard the given frame to avoid unexpected side effects.

Parameters
frame:Frame

The new frame value.

executeback to summary
pack-priv void execute(final int opcode, final int arg, final Symbol argSymbol, final SymbolTable symbolTable)

Simulates the action of the given instruction on the output stack frame.

Parameters
opcode:int

the opcode of the instruction.

arg:int

the numeric operand of the instruction, if any.

argSymbol:Symbol

the Symbol operand of the instruction, if any.

symbolTable:SymbolTable

the type table to use to lookup and store type Symbol.

getAbstractTypeFromApiFormatback to summary
pack-priv static int getAbstractTypeFromApiFormat(final SymbolTable symbolTable, final Object type)

Returns the abstract type corresponding to the given public API frame element type.

Parameters
symbolTable:SymbolTable

the type table to use to lookup and store type Symbol.

type:Object

a frame element type described using the same format as in MethodVisitor#visitFrame, i.e. either Opcodes#TOP, Opcodes#INTEGER, Opcodes#FLOAT, Opcodes#LONG, Opcodes#DOUBLE, Opcodes#NULL, or Opcodes#UNINITIALIZED_THIS, or the internal name of a class, or a Label designating a NEW instruction (for uninitialized types).

Returns:int

the abstract type corresponding to the given frame element type.

getAbstractTypeFromDescriptorback to summary
private static int getAbstractTypeFromDescriptor(final SymbolTable symbolTable, final String buffer, final int offset)

Returns the abstract type corresponding to the given type descriptor.

Parameters
symbolTable:SymbolTable

the type table to use to lookup and store type Symbol.

buffer:String

a string ending with a type descriptor.

offset:int

the start offset of the type descriptor in buffer.

Returns:int

the abstract type corresponding to the given type descriptor.

getAbstractTypeFromInternalNameback to summary
pack-priv static int getAbstractTypeFromInternalName(final SymbolTable symbolTable, final String internalName)

Returns the abstract type corresponding to the internal name of a class.

Parameters
symbolTable:SymbolTable

the type table to use to lookup and store type Symbol.

internalName:String

the internal name of a class. This must not be an array type descriptor.

Returns:int

the abstract type value corresponding to the given internal name.

getConcreteOutputTypeback to summary
private int getConcreteOutputType(final int abstractOutputType, final int numStack)

Computes the concrete output type corresponding to a given abstract output type.

Parameters
abstractOutputType:int

an abstract output type.

numStack:int

the size of the input stack, used to resolve abstract output types of STACK_KIND kind.

Returns:int

the concrete output type corresponding to 'abstractOutputType'.

getInitializedTypeback to summary
private int getInitializedType(final SymbolTable symbolTable, final int abstractType)

Returns the "initialized" abstract type corresponding to the given abstract type.

Parameters
symbolTable:SymbolTable

the type table to use to lookup and store type Symbol.

abstractType:int

an abstract type.

Returns:int

the REFERENCE_KIND abstract type corresponding to abstractType if it is UNINITIALIZED_THIS or an UNINITIALIZED_KIND or FORWARD_UNINITIALIZED_KIND abstract type for one of the types on which a constructor is invoked in the basic block. Otherwise returns abstractType.

getInputStackSizeback to summary
pack-priv final int getInputStackSize()
getLocalback to summary
private int getLocal(final int localIndex)

Returns the abstract type stored at the given local variable index in the output frame.

Parameters
localIndex:int

the index of the local variable whose value must be returned.

Returns:int

the abstract type stored at the given local variable index in the output frame.

mergeback to summary
pack-priv final boolean merge(final SymbolTable symbolTable, final Frame dstFrame, final int catchTypeIndex)

Merges the input frame of the given Frame with the input and output frames of this Frame. Returns true if the given frame has been changed by this operation (the input and output frames of this Frame are never changed).

Parameters
symbolTable:SymbolTable

the type table to use to lookup and store type Symbol.

dstFrame:Frame

the Frame whose input frame must be updated. This should be the frame of a successor, in the control flow graph, of the basic block corresponding to this frame.

catchTypeIndex:int

if 'frame' corresponds to an exception handler basic block, the type table index of the caught exception type, otherwise 0.

Returns:boolean

true if the input frame of 'frame' has been changed by this operation.

mergeback to summary
private static boolean merge(final SymbolTable symbolTable, final int sourceType, final int[] dstTypes, final int dstIndex)

Merges the type at the given index in the given abstract type array with the given type. Returns true if the type array has been modified by this operation.

Parameters
symbolTable:SymbolTable

the type table to use to lookup and store type Symbol.

sourceType:int

the abstract type with which the abstract type array element must be merged. This type should be of CONSTANT_KIND, REFERENCE_KIND, UNINITIALIZED_KIND or FORWARD_UNINITIALIZED_KIND kind, with positive or null array dimensions.

dstTypes:int[]

an array of abstract types. These types should be of CONSTANT_KIND, REFERENCE_KIND, UNINITIALIZED_KIND or FORWARD_UNINITIALIZED_KIND kind, with positive or null array dimensions.

dstIndex:int

the index of the type that must be merged in dstTypes.

Returns:boolean

true if the type array has been modified by this operation.

popback to summary
private int pop()

Pops an abstract type from the output frame stack and returns its value.

Returns:int

the abstract type that has been popped from the output frame stack.

popback to summary
private void pop(final int elements)

Pops the given number of abstract types from the output frame stack.

Parameters
elements:int

the number of abstract types that must be popped.

popback to summary
private void pop(final String descriptor)

Pops as many abstract types from the output frame stack as described by the given descriptor.

Parameters
descriptor:String

a type or method descriptor (in which case its argument types are popped).

pushback to summary
private void push(final int abstractType)

Pushes the given abstract type on the output frame stack.

Parameters
abstractType:int

an abstract type.

pushback to summary
private void push(final SymbolTable symbolTable, final String descriptor)

Pushes the abstract type corresponding to the given descriptor on the output frame stack.

Parameters
symbolTable:SymbolTable

the type table to use to lookup and store type Symbol.

descriptor:String

a type or method descriptor (in which case its return type is pushed).

putAbstractTypeback to summary
pack-priv static void putAbstractType(final SymbolTable symbolTable, final int abstractType, final ByteVector output)

Put the given abstract type in the given ByteVector, using the JVMS verification_type_info format used in StackMapTable attributes.

Parameters
symbolTable:SymbolTable

the type table to use to lookup and store type Symbol.

abstractType:int

an abstract type, restricted to Frame#CONSTANT_KIND, Frame#REFERENCE_KIND, Frame#UNINITIALIZED_KIND or Frame#FORWARD_UNINITIALIZED_KIND types.

output:ByteVector

where the abstract type must be put.

See Also
JVMS 4.7.4
setInputFrameFromApiFormatback to summary
pack-priv final void setInputFrameFromApiFormat(final SymbolTable symbolTable, final int numLocal, final Object[] local, final int numStack, final Object[] stack)

Sets the input frame from the given public API frame description.

Parameters
symbolTable:SymbolTable

the type table to use to lookup and store type Symbol.

numLocal:int

the number of local variables.

local:Object[]

the local variable types, described using the same format as in MethodVisitor#visitFrame.

numStack:int

the number of operand stack elements.

stack:Object[]

the operand stack types, described using the same format as in MethodVisitor#visitFrame.

setInputFrameFromDescriptorback to summary
pack-priv final void setInputFrameFromDescriptor(final SymbolTable symbolTable, final int access, final String descriptor, final int maxLocals)

Sets the input frame from the given method description. This method is used to initialize the first frame of a method, which is implicit (i.e. not stored explicitly in the StackMapTable attribute).

Parameters
symbolTable:SymbolTable

the type table to use to lookup and store type Symbol.

access:int

the method's access flags.

descriptor:String

the method descriptor.

maxLocals:int

the maximum number of local variables of the method.

setLocalback to summary
private void setLocal(final int localIndex, final int abstractType)

Replaces the abstract type stored at the given local variable index in the output frame.

Parameters
localIndex:int

the index of the output frame local variable that must be set.

abstractType:int

the value that must be set.