类 Frame
- 直接已知子类:
CurrentFrame
Stack map frames are computed in two steps:
- During the visit of each instruction in MethodWriter, the state of the frame at the end of the current basic block is updated by simulating the action of the instruction on the previous state of this so called "output frame".
- After all instructions have been visited, a fix point algorithm is used in MethodWriter to
compute the "input frame" of each basic block (i.e. the stack map frame at the beginning of
the basic block). See
MethodWriter.computeAllFrames().
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| =====================================
- the DIM field, stored in the 6 most significant bits, is a signed number of array
dimensions (from -32 to 31, included). It can be retrieved with
DIM_MASKand a right shift ofDIM_SHIFT. - the KIND field, stored in 4 bits, indicates the kind of VALUE used. These 4 bits can be
retrieved with
KIND_MASKand, without any shift, must be equal toCONSTANT_KIND,REFERENCE_KIND,UNINITIALIZED_KIND,LOCAL_KINDorSTACK_KIND. - the FLAGS field, stored in 2 bits, contains up to 2 boolean flags. Currently only one flag
is defined, namely
TOP_IF_LONG_OR_DOUBLE_FLAG. - the VALUE field, stored in the remaining 20 bits, contains either
- one of the constants
ITEM_TOP,ITEM_ASM_BOOLEAN,ITEM_ASM_BYTE,ITEM_ASM_CHARorITEM_ASM_SHORT,ITEM_INTEGER,ITEM_FLOAT,ITEM_LONG,ITEM_DOUBLE,ITEM_NULLorITEM_UNINITIALIZED_THIS, if KIND is equal toCONSTANT_KIND. - the index of a
Symbol.TYPE_TAGSymbolin the type table of aSymbolTable, if KIND is equal toREFERENCE_KIND. - the index of an
Symbol.UNINITIALIZED_TYPE_TAGSymbolin the type table of a SymbolTable, if KIND is equal toUNINITIALIZED_KIND. - the index of a local variable in the input stack frame, if KIND is equal to
LOCAL_KIND. - a position relatively to the top of the stack of the input stack frame, if KIND is
equal to
STACK_KIND,
- one of the constants
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 or 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).
- 作者:
- Eric Bruneton
-
字段概要
字段修饰符和类型字段说明(专用程序包) static final intprivate static final intThe constant to be added to an abstract type to get one with one more array dimension.private static final intprivate static final intprivate static final int(专用程序包) static final intprivate static final intprivate static final intprivate static final intprivate static final intprivate static final intprivate static final intThe constant to be added to an abstract type to get one with one less array dimension.private static final intprivate static final intprivate static final int(专用程序包) static final intprivate intThe number of types that are initialized in the basic block.private int[]The abstract types that are initialized in the basic block.private int[]The input stack map frame locals.private int[]The input stack map frame stack.private static final intprivate static final intprivate static final intprivate static final intprivate static final int(专用程序包) static final int(专用程序包) static final int(专用程序包) static final int(专用程序包) static final int(专用程序包) static final int(专用程序包) static final int(专用程序包) static final int(专用程序包) static final int(专用程序包) static final intprivate static final intprivate static final intprivate static final intprivate static final intprivate static final intprivate static final intprivate int[]The output stack map frame locals.private int[]The output stack map frame stack.private shortThe start of the output stack, relatively to the input stack.private shortThe index of the top stack element inoutputStack.The basic block to which these input and output stack map frames correspond.private static final int(专用程序包) static final int(专用程序包) static final int(专用程序包) static final int(专用程序包) static final int(专用程序包) static final intprivate static final intprivate static final intprivate static final intprivate static final intA 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 intprivate static final intprivate static final intprivate static final int -
构造器概要
构造器 -
方法概要
修饰符和类型方法说明(专用程序包) final voidaccept(MethodWriter methodWriter) Makes the givenMethodWritervisit the input frame of thisFrame.private voidaddInitializedType(int abstractType) Adds an abstract type to the list of types on which a constructor is invoked in the basic block.(专用程序包) final voidSets this frame to the value of the given frame.(专用程序包) voidexecute(int opcode, int arg, Symbol argSymbol, SymbolTable symbolTable) Simulates the action of the given instruction on the output stack frame.(专用程序包) static intgetAbstractTypeFromApiFormat(SymbolTable symbolTable, Object type) Returns the abstract type corresponding to the given public API frame element type.private static intgetAbstractTypeFromDescriptor(SymbolTable symbolTable, String buffer, int offset) Returns the abstract type corresponding to the given type descriptor.(专用程序包) static intgetAbstractTypeFromInternalName(SymbolTable symbolTable, String internalName) Returns the abstract type corresponding to the internal name of a class.private intgetConcreteOutputType(int abstractOutputType, int numStack) Computes the concrete output type corresponding to a given abstract output type.private intgetInitializedType(SymbolTable symbolTable, int abstractType) Returns the "initialized" abstract type corresponding to the given abstract type.(专用程序包) final intprivate intgetLocal(int localIndex) Returns the abstract type stored at the given local variable index in the output frame.private static booleanmerge(SymbolTable symbolTable, int sourceType, int[] dstTypes, int dstIndex) Merges the type at the given index in the given abstract type array with the given type.(专用程序包) final booleanmerge(SymbolTable symbolTable, Frame dstFrame, int catchTypeIndex) private intpop()Pops an abstract type from the output frame stack and returns its value.private voidpop(int elements) Pops the given number of abstract types from the output frame stack.private voidPops as many abstract types from the output frame stack as described by the given descriptor.private voidpush(int abstractType) Pushes the given abstract type on the output frame stack.private voidpush(SymbolTable symbolTable, String descriptor) Pushes the abstract type corresponding to the given descriptor on the output frame stack.(专用程序包) static voidputAbstractType(SymbolTable symbolTable, int abstractType, ByteVector output) Put the given abstract type in the given ByteVector, using the JVMS verification_type_info format used in StackMapTable attributes.(专用程序包) final voidsetInputFrameFromApiFormat(SymbolTable symbolTable, int numLocal, Object[] local, int numStack, Object[] stack) Sets the input frame from the given public API frame description.(专用程序包) final voidsetInputFrameFromDescriptor(SymbolTable symbolTable, int access, String descriptor, int maxLocals) Sets the input frame from the given method description.private voidsetLocal(int localIndex, int abstractType) Replaces the abstract type stored at the given local variable index in the output frame.
-
字段详细资料
-
SAME_FRAME
static final int SAME_FRAME- 另请参阅:
-
SAME_LOCALS_1_STACK_ITEM_FRAME
static final int SAME_LOCALS_1_STACK_ITEM_FRAME- 另请参阅:
-
RESERVED
static final int RESERVED- 另请参阅:
-
SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED
static final int SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED- 另请参阅:
-
CHOP_FRAME
static final int CHOP_FRAME- 另请参阅:
-
SAME_FRAME_EXTENDED
static final int SAME_FRAME_EXTENDED- 另请参阅:
-
APPEND_FRAME
static final int APPEND_FRAME- 另请参阅:
-
FULL_FRAME
static final int FULL_FRAME- 另请参阅:
-
ITEM_TOP
static final int ITEM_TOP- 另请参阅:
-
ITEM_INTEGER
static final int ITEM_INTEGER- 另请参阅:
-
ITEM_FLOAT
static final int ITEM_FLOAT- 另请参阅:
-
ITEM_DOUBLE
static final int ITEM_DOUBLE- 另请参阅:
-
ITEM_LONG
static final int ITEM_LONG- 另请参阅:
-
ITEM_NULL
static final int ITEM_NULL- 另请参阅:
-
ITEM_UNINITIALIZED_THIS
static final int ITEM_UNINITIALIZED_THIS- 另请参阅:
-
ITEM_OBJECT
static final int ITEM_OBJECT- 另请参阅:
-
ITEM_UNINITIALIZED
static final int ITEM_UNINITIALIZED- 另请参阅:
-
ITEM_ASM_BOOLEAN
private static final int ITEM_ASM_BOOLEAN- 另请参阅:
-
ITEM_ASM_BYTE
private static final int ITEM_ASM_BYTE- 另请参阅:
-
ITEM_ASM_CHAR
private static final int ITEM_ASM_CHAR- 另请参阅:
-
ITEM_ASM_SHORT
private static final int ITEM_ASM_SHORT- 另请参阅:
-
DIM_SIZE
private static final int DIM_SIZE- 另请参阅:
-
KIND_SIZE
private static final int KIND_SIZE- 另请参阅:
-
FLAGS_SIZE
private static final int FLAGS_SIZE- 另请参阅:
-
VALUE_SIZE
private static final int VALUE_SIZE- 另请参阅:
-
DIM_SHIFT
private static final int DIM_SHIFT- 另请参阅:
-
KIND_SHIFT
private static final int KIND_SHIFT- 另请参阅:
-
FLAGS_SHIFT
private static final int FLAGS_SHIFT- 另请参阅:
-
DIM_MASK
private static final int DIM_MASK- 另请参阅:
-
KIND_MASK
private static final int KIND_MASK- 另请参阅:
-
VALUE_MASK
private static final int VALUE_MASK- 另请参阅:
-
ARRAY_OF
private static final int ARRAY_OFThe constant to be added to an abstract type to get one with one more array dimension.- 另请参阅:
-
ELEMENT_OF
private static final int ELEMENT_OFThe constant to be added to an abstract type to get one with one less array dimension.- 另请参阅:
-
CONSTANT_KIND
private static final int CONSTANT_KIND- 另请参阅:
-
REFERENCE_KIND
private static final int REFERENCE_KIND- 另请参阅:
-
UNINITIALIZED_KIND
private static final int UNINITIALIZED_KIND- 另请参阅:
-
LOCAL_KIND
private static final int LOCAL_KIND- 另请参阅:
-
STACK_KIND
private static final int STACK_KIND- 另请参阅:
-
TOP_IF_LONG_OR_DOUBLE_FLAG
private static final int TOP_IF_LONG_OR_DOUBLE_FLAGA 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).- 另请参阅:
-
TOP
private static final int TOP- 另请参阅:
-
BOOLEAN
private static final int BOOLEAN- 另请参阅:
-
BYTE
private static final int BYTE- 另请参阅:
-
CHAR
private static final int CHAR- 另请参阅:
-
SHORT
private static final int SHORT- 另请参阅:
-
INTEGER
private static final int INTEGER- 另请参阅:
-
FLOAT
private static final int FLOAT- 另请参阅:
-
LONG
private static final int LONG- 另请参阅:
-
DOUBLE
private static final int DOUBLE- 另请参阅:
-
NULL
private static final int NULL- 另请参阅:
-
UNINITIALIZED_THIS
private static final int UNINITIALIZED_THIS- 另请参阅:
-
owner
The basic block to which these input and output stack map frames correspond. -
inputLocals
private int[] inputLocalsThe input stack map frame locals. This is an array of abstract types. -
inputStack
private int[] inputStackThe input stack map frame stack. This is an array of abstract types. -
outputLocals
private int[] outputLocalsThe output stack map frame locals. This is an array of abstract types. -
outputStack
private int[] outputStackThe output stack map frame stack. This is an array of abstract types. -
outputStackStart
private short outputStackStartThe 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. -
outputStackTop
private short outputStackTopThe index of the top stack element inoutputStack. -
initializationCount
private int initializationCountThe number of types that are initialized in the basic block. Seeinitializations. -
initializations
private int[] initializationsThe abstract types that are initialized in the basic block. A constructor invocation on an 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.
-
-
构造器详细资料
-
Frame
Frame(Label owner) Constructs a new Frame.- 参数:
owner- the basic block to which these input and output stack map frames correspond.
-
-
方法详细资料
-
copyFrom
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.
- 参数:
frame- The new frame value.
-
getAbstractTypeFromApiFormat
Returns the abstract type corresponding to the given public API frame element type.- 参数:
symbolTable- the type table to use to lookup and store typeSymbol.type- a frame element type described using the same format as inMethodVisitor.visitFrame(int, int, java.lang.Object[], int, java.lang.Object[]), i.e. eitherOpcodes.TOP,Opcodes.INTEGER,Opcodes.FLOAT,Opcodes.LONG,Opcodes.DOUBLE,Opcodes.NULL, orOpcodes.UNINITIALIZED_THIS, or the internal name of a class, or a Label designating a NEW instruction (for uninitialized types).- 返回:
- the abstract type corresponding to the given frame element type.
-
getAbstractTypeFromInternalName
Returns the abstract type corresponding to the internal name of a class.- 参数:
symbolTable- the type table to use to lookup and store typeSymbol.internalName- the internal name of a class. This must not be an array type descriptor.- 返回:
- the abstract type value corresponding to the given internal name.
-
getAbstractTypeFromDescriptor
private static int getAbstractTypeFromDescriptor(SymbolTable symbolTable, String buffer, int offset) Returns the abstract type corresponding to the given type descriptor.- 参数:
symbolTable- the type table to use to lookup and store typeSymbol.buffer- a string ending with a type descriptor.offset- the start offset of the type descriptor in buffer.- 返回:
- the abstract type corresponding to the given type descriptor.
-
setInputFrameFromDescriptor
final void setInputFrameFromDescriptor(SymbolTable symbolTable, int access, String descriptor, 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).- 参数:
symbolTable- the type table to use to lookup and store typeSymbol.access- the method's access flags.descriptor- the method descriptor.maxLocals- the maximum number of local variables of the method.
-
setInputFrameFromApiFormat
final void setInputFrameFromApiFormat(SymbolTable symbolTable, int numLocal, Object[] local, int numStack, Object[] stack) Sets the input frame from the given public API frame description.- 参数:
symbolTable- the type table to use to lookup and store typeSymbol.numLocal- the number of local variables.local- the local variable types, described using the same format as inMethodVisitor.visitFrame(int, int, java.lang.Object[], int, java.lang.Object[]).numStack- the number of operand stack elements.stack- the operand stack types, described using the same format as inMethodVisitor.visitFrame(int, int, java.lang.Object[], int, java.lang.Object[]).
-
getInputStackSize
final int getInputStackSize() -
getLocal
private int getLocal(int localIndex) Returns the abstract type stored at the given local variable index in the output frame.- 参数:
localIndex- the index of the local variable whose value must be returned.- 返回:
- the abstract type stored at the given local variable index in the output frame.
-
setLocal
private void setLocal(int localIndex, int abstractType) Replaces the abstract type stored at the given local variable index in the output frame.- 参数:
localIndex- the index of the output frame local variable that must be set.abstractType- the value that must be set.
-
push
private void push(int abstractType) Pushes the given abstract type on the output frame stack.- 参数:
abstractType- an abstract type.
-
push
Pushes the abstract type corresponding to the given descriptor on the output frame stack.- 参数:
symbolTable- the type table to use to lookup and store typeSymbol.descriptor- a type or method descriptor (in which case its return type is pushed).
-
pop
private int pop()Pops an abstract type from the output frame stack and returns its value.- 返回:
- the abstract type that has been popped from the output frame stack.
-
pop
private void pop(int elements) Pops the given number of abstract types from the output frame stack.- 参数:
elements- the number of abstract types that must be popped.
-
pop
Pops as many abstract types from the output frame stack as described by the given descriptor.- 参数:
descriptor- a type or method descriptor (in which case its argument types are popped).
-
addInitializedType
private void addInitializedType(int abstractType) Adds an abstract type to the list of types on which a constructor is invoked in the basic block.- 参数:
abstractType- an abstract type on a which a constructor is invoked.
-
getInitializedType
Returns the "initialized" abstract type corresponding to the given abstract type.- 参数:
symbolTable- the type table to use to lookup and store typeSymbol.abstractType- an abstract type.- 返回:
- the REFERENCE_KIND abstract type corresponding to abstractType if it is UNINITIALIZED_THIS or an UNINITIALIZED_KIND abstract type for one of the types on which a constructor is invoked in the basic block. Otherwise returns abstractType.
-
execute
Simulates the action of the given instruction on the output stack frame.- 参数:
opcode- the opcode of the instruction.arg- the numeric operand of the instruction, if any.argSymbol- the Symbol operand of the instruction, if any.symbolTable- the type table to use to lookup and store typeSymbol.
-
getConcreteOutputType
private int getConcreteOutputType(int abstractOutputType, int numStack) Computes the concrete output type corresponding to a given abstract output type.- 参数:
abstractOutputType- an abstract output type.numStack- the size of the input stack, used to resolve abstract output types of STACK_KIND kind.- 返回:
- the concrete output type corresponding to 'abstractOutputType'.
-
merge
Merges the input frame of the givenFramewith the input and output frames of thisFrame. Returns true if the given frame has been changed by this operation (the input and output frames of thisFrameare never changed).- 参数:
symbolTable- the type table to use to lookup and store typeSymbol.dstFrame- theFramewhose 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- if 'frame' corresponds to an exception handler basic block, the type table index of the caught exception type, otherwise 0.- 返回:
- true if the input frame of 'frame' has been changed by this operation.
-
merge
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.- 参数:
symbolTable- the type table to use to lookup and store typeSymbol.sourceType- the abstract type with which the abstract type array element must be merged. This type should be ofCONSTANT_KIND,REFERENCE_KINDorUNINITIALIZED_KINDkind, with positive or null array dimensions.dstTypes- an array of abstract types. These types should be ofCONSTANT_KIND,REFERENCE_KINDorUNINITIALIZED_KINDkind, with positive or null array dimensions.dstIndex- the index of the type that must be merged in dstTypes.- 返回:
- true if the type array has been modified by this operation.
-
accept
Makes the givenMethodWritervisit the input frame of thisFrame. The visit is done with theMethodWriter.visitFrameStart(int, int, int),MethodWriter.visitAbstractType(int, int)andMethodWriter.visitFrameEnd()methods.- 参数:
methodWriter- theMethodWriterthat should visit the input frame of thisFrame.
-
putAbstractType
Put the given abstract type in the given ByteVector, using the JVMS verification_type_info format used in StackMapTable attributes.- 参数:
symbolTable- the type table to use to lookup and store typeSymbol.abstractType- an abstract type, restricted toCONSTANT_KIND,REFERENCE_KINDorUNINITIALIZED_KINDtypes.output- where the abstract type must be put.- 另请参阅:
-