Class Analyzer

java.lang.Object
javassist.bytecode.analysis.Analyzer
All Implemented Interfaces:
Opcode

public class Analyzer extends Object implements Opcode
A data-flow analyzer that determines the type state of the stack and local variable table at every reachable instruction in a method. During analysis, bytecode verification is performed in a similar manner to that described in the JVM specification.

Example:

 // Method to analyze
 public Object doSomething(int x) {
     Number n;
     if (x < 5) {
        n = new Double(0);
     } else {
        n = new Long(0);
     }

     return n;
 }

 // Which compiles to:
 // 0:   iload_1
 // 1:   iconst_5
 // 2:   if_icmpge   17
 // 5:   new #18; //class java/lang/Double
 // 8:   dup
 // 9:   dconst_0
 // 10:  invokespecial   #44; //Method java/lang/Double."<init>":(D)V
 // 13:  astore_2
 // 14:  goto    26
 // 17:  new #16; //class java/lang/Long
 // 20:  dup
 // 21:  lconst_1
 // 22:  invokespecial   #47; //Method java/lang/Long."<init>":(J)V
 // 25:  astore_2
 // 26:  aload_2
 // 27:  areturn

 public void analyzeIt(CtClass clazz, MethodInfo method) {
     Analyzer analyzer = new Analyzer();
     Frame[] frames = analyzer.analyze(clazz, method);
     frames[0].getLocal(0).getCtClass(); // returns clazz;
     frames[0].getLocal(1).getCtClass(); // returns java.lang.String
     frames[1].peek(); // returns Type.INTEGER
     frames[27].peek().getCtClass(); // returns java.lang.Number
 }
 
See Also:
  • Field Details

  • Constructor Details

    • Analyzer

      public Analyzer()
  • Method Details

    • analyze

      public Frame[] analyze(CtClass clazz, MethodInfo method) throws BadBytecode
      Performs data-flow analysis on a method and returns an array, indexed by instruction position, containing the starting frame state of all reachable instructions. Non-reachable code, and illegal code offsets are represented as a null in the frame state array. This can be used to detect dead code. If the method does not contain code (it is either native or abstract), null is returned.
      Parameters:
      clazz - the declaring class of the method
      method - the method to analyze
      Returns:
      an array, indexed by instruction position, of the starting frame state, or null if this method doesn't have code
      Throws:
      BadBytecode - if the bytecode does not comply with the JVM specification
    • analyze

      public Frame[] analyze(CtMethod method) throws BadBytecode
      Performs data-flow analysis on a method and returns an array, indexed by instruction position, containing the starting frame state of all reachable instructions. Non-reachable code, and illegal code offsets are represented as a null in the frame state array. This can be used to detect dead code. If the method does not contain code (it is either native or abstract), null is returned.
      Parameters:
      method - the method to analyze
      Returns:
      an array, indexed by instruction position, of the starting frame state, or null if this method doesn't have code
      Throws:
      BadBytecode - if the bytecode does not comply with the JVM specification
    • analyzeNextEntry

      private void analyzeNextEntry(MethodInfo method, CodeIterator iter, IntQueue queue, Executor executor) throws BadBytecode
      Throws:
      BadBytecode
    • buildExceptionInfo

      private Analyzer.ExceptionInfo[] buildExceptionInfo(MethodInfo method)
    • firstFrame

      private Frame firstFrame(MethodInfo method, int maxLocals, int maxStack)
    • getNext

      private int getNext(CodeIterator iter, int of, int restore) throws BadBytecode
      Throws:
      BadBytecode
    • lookAhead

      private int lookAhead(CodeIterator iter, int pos) throws BadBytecode
      Throws:
      BadBytecode
    • merge

      private void merge(IntQueue queue, Frame frame, int target)
    • mergeExceptionHandlers

      private void mergeExceptionHandlers(IntQueue queue, MethodInfo method, int pos, Frame frame)
    • mergeJsr

      private void mergeJsr(IntQueue queue, Frame frame, Subroutine sub, int pos, int next) throws BadBytecode
      Throws:
      BadBytecode
    • mergeLookupSwitch

      private void mergeLookupSwitch(IntQueue queue, int pos, CodeIterator iter, Frame frame) throws BadBytecode
      Throws:
      BadBytecode
    • mergeRet

      private void mergeRet(IntQueue queue, CodeIterator iter, int pos, Frame frame, Subroutine subroutine) throws BadBytecode
      Throws:
      BadBytecode
    • mergeTableSwitch

      private void mergeTableSwitch(IntQueue queue, int pos, CodeIterator iter, Frame frame) throws BadBytecode
      Throws:
      BadBytecode
    • zeroExtend

      private Type zeroExtend(Type type)