Class Analyzer<V extends Value>

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

public class Analyzer<V extends Value> extends Object implements Opcodes
A semantic bytecode analyzer. This class does not fully check that JSR and RET instructions are valid.
  • Constructor Details

    • Analyzer

      public Analyzer(Interpreter<V> interpreter)
      Constructs a new Analyzer.
      Parameters:
      interpreter - the interpreter to use to symbolically interpret the bytecode instructions.
  • Method Details

    • setComputeLimits

      public void setComputeLimits(int maxBytes, long maxOperations)
      Sets the maximum number of bytes which can be allocated, and the maximum number of "operations" which can be performed, to analyze each method. Operations are not formally defined but their total number is deterministic and approximatively proportional to the computation time.

      The default limits should be sufficient for any "normal" class. You only need to set new limits if analyze(java.lang.String, org.objectweb.asm.tree.MethodNode) throws a LimitExceededException on some of your classes.

      Parameters:
      maxBytes - the maximum number of bytes which can be allocated. Not all object instantiations are tracked (and garbage collection is ignored), but the most important ones are. The default value, 400MB, is more than 20 times larger than the memory used for any method in the java.* modules of the JDK (for the BasicInterpreter, BasicVerifier, and SimpleVerifier; for SourceInterpreter, it is only 4 times larger).
      maxOperations - the maximum number of "operations" that can be performed. The default value, 50 billions, is more than ten times larger than the number of operations used for any method in the java.* modules of the JDK.
    • analyze

      public Frame<V>[] analyze(String owner, MethodNode method) throws AnalyzerException
      Analyzes the given method.
      Parameters:
      owner - the internal name of the class to which 'method' belongs (see Type.getInternalName()).
      method - the method to be analyzed. The maxStack and maxLocals fields must have correct values.
      Returns:
      the symbolic state of the execution stack frame at each bytecode instruction of the method. The size of the returned array is equal to the number of instructions (and labels) of the method. A given frame is null if and only if the corresponding instruction cannot be reached (dead code).
      Throws:
      AnalyzerException - if a problem occurs during the analysis.
    • analyzeAndComputeMaxs

      public Frame<V>[] analyzeAndComputeMaxs(String owner, MethodNode method) throws AnalyzerException
      Analyzes the given method and computes and sets its maximum stack size and maximum number of local variables.
      Parameters:
      owner - the internal name of the class to which 'method' belongs (see Type.getInternalName()).
      method - the method to be analyzed.
      Returns:
      the symbolic state of the execution stack frame at each bytecode instruction of the method. The size of the returned array is equal to the number of instructions (and labels) of the method. A given frame is null if and only if the corresponding instruction cannot be reached (dead code).
      Throws:
      AnalyzerException - if a problem occurs during the analysis.
    • getFrames

      public Frame<V>[] getFrames()
      Returns the symbolic execution stack frame for each instruction of the last analyzed method.
      Returns:
      the symbolic state of the execution stack frame at each bytecode instruction of the method. The size of the returned array is equal to the number of instructions (and labels) of the method. A given frame is null if the corresponding instruction cannot be reached, or if an error occurred during the analysis of the method.
    • getHandlers

      public List<TryCatchBlockNode> getHandlers(int insnIndex)
      Returns the exception handlers for the given instruction.
      Parameters:
      insnIndex - the index of an instruction of the last analyzed method.
      Returns:
      a list of TryCatchBlockNode objects.
    • init

      protected void init(String owner, MethodNode method) throws AnalyzerException
      Initializes this analyzer. This method is called just before the execution of control flow analysis loop in analyze(java.lang.String, org.objectweb.asm.tree.MethodNode). The default implementation of this method does nothing.
      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.
    • newFrame

      protected Frame<V> newFrame(int numLocals, int numStack)
      Constructs a new frame with the given size. Subclasses can override this to construct subclasses of Frame. But they should not call this method directly, and use newFrameWithComputeLimits(int, int) instead.
      Parameters:
      numLocals - the maximum number of local variables of the frame.
      numStack - the maximum stack size of the frame.
      Returns:
      the created frame.
    • newFrame

      protected Frame<V> newFrame(Frame<? extends V> frame)
      Constructs a copy of the given frame. Subclasses can override this to construct subclasses of Frame. But they should not call this method directly, and use newFrameWithComputeLimits(Frame) instead.
      Parameters:
      frame - a frame.
      Returns:
      the created frame.
    • newFrameWithComputeLimits

      protected final Frame<V> newFrameWithComputeLimits(int numLocals, int numStack)
      Constructs a new frame with the given size, and subject to the compute limits set in setComputeLimits(int, long).
      Parameters:
      numLocals - the maximum number of local variables of the frame.
      numStack - the maximum stack size of the frame.
      Returns:
      the created frame.
    • newFrameWithComputeLimits

      protected final Frame<V> newFrameWithComputeLimits(Frame<? extends V> frame)
      Constructs a copy of the given frame, and subject to the compute limits set in setComputeLimits(int, long).
      Parameters:
      frame - a frame.
      Returns:
      the created frame.
    • newControlFlowEdge

      protected void newControlFlowEdge(int insnIndex, int successorIndex)
      Creates a control flow graph edge. The default implementation of this method does nothing. It can be overridden in order to construct the control flow graph of a method (this method is called by the analyze(java.lang.String, org.objectweb.asm.tree.MethodNode) method during its visit of the method's code).
      Parameters:
      insnIndex - an instruction index.
      successorIndex - index of a successor instruction.
    • newControlFlowExceptionEdge

      protected boolean newControlFlowExceptionEdge(int insnIndex, int successorIndex)
      Creates a control flow graph edge corresponding to an exception handler. The default implementation of this method does nothing. It can be overridden in order to construct the control flow graph of a method (this method is called by the analyze(java.lang.String, org.objectweb.asm.tree.MethodNode) method during its visit of the method's code).
      Parameters:
      insnIndex - an instruction index.
      successorIndex - index of a successor instruction.
      Returns:
      true if this edge must be considered in the data flow analysis performed by this analyzer, or false otherwise. The default implementation of this method always returns true.
    • newControlFlowExceptionEdge

      protected boolean newControlFlowExceptionEdge(int insnIndex, TryCatchBlockNode tryCatchBlock)
      Creates a control flow graph edge corresponding to an exception handler. The default implementation of this method delegates to newControlFlowExceptionEdge(int, int). It can be overridden in order to construct the control flow graph of a method (this method is called by the analyze(java.lang.String, org.objectweb.asm.tree.MethodNode) method during its visit of the method's code).
      Parameters:
      insnIndex - an instruction index.
      tryCatchBlock - TryCatchBlockNode corresponding to this edge.
      Returns:
      true if this edge must be considered in the data flow analysis performed by this analyzer, or false otherwise. The default implementation of this method delegates to newControlFlowExceptionEdge(int, int).
    • checkLimits

      protected final void checkLimits(int numBytes, long numOperations)
      Checks that the given allocations and operations are within the limits set in setComputeLimits(int, long). This also checks that the allocations and operations done by the interpreter, since the last call to this method, are within the limits. Subclasses should call this when they allocate additional memory or perform additional operations, for instance in init(java.lang.String, org.objectweb.asm.tree.MethodNode), newControlFlowEdge(int, int), etc.
      Parameters:
      numBytes - a number of bytes to allocate.
      numOperations - a number of operations to perform.
      Throws:
      LimitExceededException - if the limits are exceeded.