Class CheckFrameAnalyzer<V extends Value>

java.lang.Object
org.objectweb.asm.tree.analysis.Analyzer<V>
org.objectweb.asm.util.CheckFrameAnalyzer<V>
Type Parameters:
V - type of the Value used for the analysis.
All Implemented Interfaces:
Opcodes

class CheckFrameAnalyzer<V extends Value> extends Analyzer<V>
An 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:
  • Field Details

  • Constructor Details

    • CheckFrameAnalyzer

      CheckFrameAnalyzer(Interpreter<V> interpreter)
  • Method Details

    • init

      protected void init(String owner, MethodNode method) throws AnalyzerException
      Description copied from class: Analyzer
      Initializes this analyzer. This method is called just before the execution of control flow analysis loop in Analyzer.analyze(java.lang.String, org.objectweb.asm.tree.MethodNode). The default implementation of this method does nothing.
      Overrides:
      init in class Analyzer<V extends Value>
      Parameters:
      owner - the internal name of the class to which the method belongs (see Type.getInternalName()).
      method - the method to be analyzed.
      Throws:
      AnalyzerException - if a problem occurs.
    • expandFrames

      private void expandFrames(String owner, MethodNode method, Frame<V> initialFrame) throws AnalyzerException
      Expands the FrameNode "instructions" of the given method into Frame objects and stores them at the corresponding indices of the Analyzer.frames array. The expanded frames are also associated with the label and line number nodes immediately preceding each frame node.
      Parameters:
      owner - the internal name of the class to which 'method' belongs.
      method - the method whose frames must be expanded.
      initialFrame - the implicit initial frame of 'method'.
      Throws:
      AnalyzerException - if the stack map frames of 'method', i.e. its FrameNode "instructions", are invalid.
    • expandFrame

      private Frame<V> expandFrame(String owner, Frame<V> previousFrame, FrameNode frameNode) throws AnalyzerException
      Returns the expanded representation of the given FrameNode.
      Parameters:
      owner - the internal name of the class to which 'frameNode' belongs.
      previousFrame - the frame before 'frameNode', in expanded form.
      frameNode - a possibly compressed stack map frame.
      Returns:
      the expanded version of 'frameNode'.
      Throws:
      AnalyzerException - if 'frameNode' is invalid.
    • newFrameValue

      private V newFrameValue(String owner, FrameNode frameNode, Object type) throws AnalyzerException
      Creates a new Value that represents the given stack map frame type.
      Parameters:
      owner - the internal name of the class to which 'frameNode' belongs.
      frameNode - the stack map frame to which 'type' belongs.
      type - an Integer, String or LabelNode object representing a primitive, reference or uninitialized a stack map frame type, respectively. See FrameNode.
      Returns:
      a value that represents the given type.
      Throws:
      AnalyzerException - if 'type' is an invalid stack map frame type.
    • checkFrame

      private void checkFrame(int insnIndex, Frame<V> frame, 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.
      Parameters:
      insnIndex - an instruction index.
      frame - a frame. This frame is left unchanged by this method.
      requireFrame - whether a frame must already exist or not in Analyzer.frames at 'insnIndex'.
      Throws:
      AnalyzerException - if the frames have incompatible sizes or if the frame at 'insnIndex' is missing (if required) or not compatible with 'frame'.
    • checkMerge

      private String checkMerge(Frame<V> srcFrame, 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.
      Parameters:
      srcFrame - a source frame. This frame is left unchanged by this method.
      dstFrame - a destination frame. This frame is left unchanged by this method.
      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.
    • endControlFlow

      private void endControlFlow(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.
      Parameters:
      insnIndex - an instruction index.
      Throws:
      AnalyzerException - if 'insnIndex' is not the last instruction and there is no frame at 'insnIndex' + 1 in Analyzer.getFrames().
    • hasNextJvmInsnOrFrame

      private boolean hasNextJvmInsnOrFrame(int insnIndex)
      Returns true if the given instruction is followed by a JVM instruction or a by stack map frame.
      Parameters:
      insnIndex - an instruction index.
      Returns:
      true if 'insnIndex' is followed by a JVM instruction or a by stack map frame.
    • isJvmInsnNode

      private static boolean isJvmInsnNode(AbstractInsnNode insnNode)
      Returns true if the given instruction node corresponds to a real JVM instruction.
      Parameters:
      insnNode - an instruction node.
      Returns:
      true except for label, line number and stack map frame nodes.