Package javassist.bytecode.analysis
Class Analyzer
- java.lang.Object
-
- javassist.bytecode.analysis.Analyzer
-
- All Implemented Interfaces:
Opcode
public class Analyzer extends java.lang.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:
FramePrinter
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description private static class
Analyzer.ExceptionInfo
-
Field Summary
Fields Modifier and Type Field Description private CtClass
clazz
private Analyzer.ExceptionInfo[]
exceptions
private Frame[]
frames
private SubroutineScanner
scanner
private Subroutine[]
subroutines
-
Fields inherited from interface javassist.bytecode.Opcode
AALOAD, AASTORE, ACONST_NULL, ALOAD, ALOAD_0, ALOAD_1, ALOAD_2, ALOAD_3, ANEWARRAY, ARETURN, ARRAYLENGTH, ASTORE, ASTORE_0, ASTORE_1, ASTORE_2, ASTORE_3, ATHROW, BALOAD, BASTORE, BIPUSH, CALOAD, CASTORE, CHECKCAST, D2F, D2I, D2L, DADD, DALOAD, DASTORE, DCMPG, DCMPL, DCONST_0, DCONST_1, DDIV, DLOAD, DLOAD_0, DLOAD_1, DLOAD_2, DLOAD_3, DMUL, DNEG, DREM, DRETURN, DSTORE, DSTORE_0, DSTORE_1, DSTORE_2, DSTORE_3, DSUB, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, F2D, F2I, F2L, FADD, FALOAD, FASTORE, FCMPG, FCMPL, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAD_0, FLOAD_1, FLOAD_2, FLOAD_3, FMUL, FNEG, FREM, FRETURN, FSTORE, FSTORE_0, FSTORE_1, FSTORE_2, FSTORE_3, FSUB, GETFIELD, GETSTATIC, GOTO, GOTO_W, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IALOAD, IAND, IASTORE, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, IF_ACMPEQ, IF_ACMPNE, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, IFEQ, IFGE, IFGT, IFLE, IFLT, IFNE, IFNONNULL, IFNULL, IINC, ILOAD, ILOAD_0, ILOAD_1, ILOAD_2, ILOAD_3, IMUL, INEG, INSTANCEOF, INVOKEDYNAMIC, INVOKEINTERFACE, INVOKESPECIAL, INVOKESTATIC, INVOKEVIRTUAL, IOR, IREM, IRETURN, ISHL, ISHR, ISTORE, ISTORE_0, ISTORE_1, ISTORE_2, ISTORE_3, ISUB, IUSHR, IXOR, JSR, JSR_W, L2D, L2F, L2I, LADD, LALOAD, LAND, LASTORE, LCMP, LCONST_0, LCONST_1, LDC, LDC_W, LDC2_W, LDIV, LLOAD, LLOAD_0, LLOAD_1, LLOAD_2, LLOAD_3, LMUL, LNEG, LOOKUPSWITCH, LOR, LREM, LRETURN, LSHL, LSHR, LSTORE, LSTORE_0, LSTORE_1, LSTORE_2, LSTORE_3, LSUB, LUSHR, LXOR, MONITORENTER, MONITOREXIT, MULTIANEWARRAY, NEW, NEWARRAY, NOP, POP, POP2, PUTFIELD, PUTSTATIC, RET, RETURN, SALOAD, SASTORE, SIPUSH, STACK_GROW, SWAP, T_BOOLEAN, T_BYTE, T_CHAR, T_DOUBLE, T_FLOAT, T_INT, T_LONG, T_SHORT, TABLESWITCH, WIDE
-
-
Constructor Summary
Constructors Constructor Description Analyzer()
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description Frame[]
analyze(CtClass clazz, MethodInfo method)
Performs data-flow analysis on a method and returns an array, indexed by instruction position, containing the starting frame state of all reachable instructions.Frame[]
analyze(CtMethod method)
Performs data-flow analysis on a method and returns an array, indexed by instruction position, containing the starting frame state of all reachable instructions.private void
analyzeNextEntry(MethodInfo method, CodeIterator iter, IntQueue queue, Executor executor)
private Analyzer.ExceptionInfo[]
buildExceptionInfo(MethodInfo method)
private Frame
firstFrame(MethodInfo method, int maxLocals, int maxStack)
private int
getNext(CodeIterator iter, int of, int restore)
private int
lookAhead(CodeIterator iter, int pos)
private void
merge(IntQueue queue, Frame frame, int target)
private void
mergeExceptionHandlers(IntQueue queue, MethodInfo method, int pos, Frame frame)
private void
mergeJsr(IntQueue queue, Frame frame, Subroutine sub, int pos, int next)
private void
mergeLookupSwitch(IntQueue queue, int pos, CodeIterator iter, Frame frame)
private void
mergeRet(IntQueue queue, CodeIterator iter, int pos, Frame frame, Subroutine subroutine)
private void
mergeTableSwitch(IntQueue queue, int pos, CodeIterator iter, Frame frame)
private Type
zeroExtend(Type type)
-
-
-
Field Detail
-
scanner
private final SubroutineScanner scanner
-
clazz
private CtClass clazz
-
exceptions
private Analyzer.ExceptionInfo[] exceptions
-
frames
private Frame[] frames
-
subroutines
private Subroutine[] subroutines
-
-
Method Detail
-
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 methodmethod
- 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
-
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
-
-