Value used for the analysis.
Analyzer subclass which checks that methods provide stack map frames where expected
(i.e. at jump target and after instructions without immediate successor), and that these stack
map frames are valid (for the provided interpreter; they may still be invalid for the JVM, if the
Interpreter uses a simplified type system compared to the JVM verifier). This is done in
two steps:
FrameNodes are expanded, and stored at their
respective instruction offsets. The expansion process uncompresses the APPEND, CHOP and
SAME frames to FULL frames. It also converts the stack map frame verification types to
Values, via the provided Interpreter. The expansion is done in expandFrames, by looking at each FrameNode in sequence (compressed frames are
defined relatively to the previous FrameNode, or the implicit first frame). The
actual decompression is done in expandFrame, and the type conversion in newFrameValue.
Frame#execute method. This gives a new stack map frame f,
representing the stack map frame state after the execution of i. Then:
init, which is called from
the Analyzer#analyze method. Cases where the control flow cannot continue to the
next instruction are handled in endControlFlow. Cases where the control flow can
continue to the next instruction, or jump to another instruction, are handled in checkFrame. This method checks that an existing stack map frame is present when required,
and checks the stack map frames compatibility with checkMerge.
| Modifier and Type | Field and Description |
|---|---|
| private int | currentLocals
The number of locals in the last stack map frame processed by |
| private InsnList | insnList
The instructions of the currently analyzed method.
|
| private final Interpreter | interpreter
The interpreter to use to symbolically interpret the bytecode instructions.
|
| Access | Constructor and Description |
|---|---|
| pack-priv |
| Modifier and Type | Method and Description |
|---|---|
| private void | checkFrame(final int
an instruction index. insnIndex, final Frame<V> a frame. This frame is left unchanged by this method. frame, final boolean whether a frame must already exist or not in requireFrame)frames at
'insnIndex'.Checks that the given frame is compatible with the frame at the given instruction index, if any. |
| private String | Returns: an error message if the frames have incompatible sizes, or if a type in the source frame is not a sub type of the corresponding type in the destination frame. Returns null otherwise.a source frame. This frame is left unchanged by this method. srcFrame, final Frame<V> a destination frame. This frame is left unchanged by this method. dstFrame)Checks that merging the two given frames would not produce any change, i.e. that the types in the source frame are sub types of the corresponding types in the destination frame. |
| private void | endControlFlow(final int
an instruction index. insnIndex)Ends the control flow graph at the given instruction. |
| private Frame | Returns: the expanded version of 'frameNode'.the internal name of the class to which 'frameNode' belongs. owner, final Frame<V> the frame before 'frameNode', in expanded form. previousFrame, final FrameNode a possibly compressed stack map frame. frameNode)Returns the expanded representation of the given |
| private void | expandFrames(final String
the internal name of the class to which 'method' belongs. owner, final MethodNode the method whose frames must be expanded. method, final Frame<V> the implicit initial frame of 'method'. initialFrame)Expands the |
| private boolean | Returns: true if 'insnIndex' is followed by a JVM instruction or a by stack map frame.an instruction index. insnIndex)Returns true if the given instruction is followed by a JVM instruction or a by stack map frame. |
| protected void | init(final String
the internal name of the class to which the method belongs (see owner, final MethodNode Type#getInternalName()).the method to be analyzed. method)
Initializes this analyzer.
|
| private static boolean | Returns: true except for label, line number and stack map frame nodes.an instruction node. insnNode)Returns true if the given instruction node corresponds to a real JVM instruction. |
| private V | Returns: a value that represents the given type.the internal name of the class to which 'frameNode' belongs. owner, final FrameNode the stack map frame to which 'type' belongs. frameNode, final Object an Integer, String or LabelNode object representing a primitive, reference or
uninitialized a stack map frame type, respectively. See type)FrameNode.Creates a new |
| currentLocals | back to summary |
|---|---|
| private int currentLocals The number of locals in the last stack map frame processed by | |
| insnList | back to summary |
|---|---|
| private InsnList insnList Hides org. The instructions of the currently analyzed method. | |
| interpreter | back to summary |
|---|---|
| private final Interpreter<V> interpreter Hides org. The interpreter to use to symbolically interpret the bytecode instructions. | |
| CheckFrameAnalyzer | back to summary |
|---|---|
| pack-priv CheckFrameAnalyzer(final Interpreter<V> interpreter) | |
| checkFrame | back to summary |
|---|---|
| private void checkFrame(final int insnIndex, final Frame<V> frame, final boolean requireFrame) throws AnalyzerException Checks that the given frame is compatible with the frame at the given instruction index, if any. If there is no frame at this instruction index and none is required, the frame at 'insnIndex' is set to the given frame. Otherwise, if the merge of the two frames is not equal to the current frame at 'insnIndex', an exception is thrown.
| |
| checkMerge | back to summary |
|---|---|
| private String checkMerge(final Frame<V> srcFrame, final Frame<V> dstFrame) Checks that merging the two given frames would not produce any change, i.e. that the types in the source frame are sub types of the corresponding types in the destination frame.
| |
| endControlFlow | back to summary |
|---|---|
| private void endControlFlow(final int insnIndex) throws AnalyzerException Ends the control flow graph at the given instruction. This method checks that there is an existing frame for the next instruction, if any.
| |
| expandFrame | back to summary |
|---|---|
| private Frame Returns the expanded representation of the given
| |
| expandFrames | back to summary |
|---|---|
| private void expandFrames(final String owner, final MethodNode method, final Frame<V> initialFrame) throws AnalyzerException Expands the
| |
| hasNextJvmInsnOrFrame | back to summary |
|---|---|
| private boolean hasNextJvmInsnOrFrame(final int insnIndex) Returns true if the given instruction is followed by a JVM instruction or a by stack map frame.
| |
| init | back to summary |
|---|---|
| protected void init(final String owner, final MethodNode method) throws AnalyzerException Overrides org. Doc from org. Initializes this analyzer. This method is called just before the execution of control flow
analysis loop in
| |
| isJvmInsnNode | back to summary |
|---|---|
| private static boolean isJvmInsnNode(final AbstractInsnNode insnNode) Returns true if the given instruction node corresponds to a real JVM instruction.
| |
| newFrameValue | back to summary |
|---|---|
| private V newFrameValue(final String owner, final FrameNode frameNode, final Object type) throws AnalyzerException Creates a new
| |