1 19 20 package edu.umd.cs.findbugs.ba; 21 22 import org.apache.bcel.Constants; 23 import org.apache.bcel.classfile.Method; 24 import org.apache.bcel.generic.ConstantPoolGen; 25 import org.apache.bcel.generic.Instruction; 26 import org.apache.bcel.generic.InstructionHandle; 27 28 36 public class StackDepthAnalysis extends ForwardDataflowAnalysis<StackDepth> { 37 public static final int TOP = -1; 38 public static final int BOTTOM = -2; 39 40 private ConstantPoolGen cpg; 41 42 48 public StackDepthAnalysis(ConstantPoolGen cpg, DepthFirstSearch dfs) { 49 super(dfs); 50 this.cpg = cpg; 51 } 52 53 public StackDepth createFact() { 54 return new StackDepth(TOP); 55 } 56 57 public void makeFactTop(StackDepth fact) { 58 fact.setDepth(TOP); 59 } 60 public boolean isTop(StackDepth fact) { 61 return fact.getDepth() == TOP; 62 } 63 64 @Override 65 public boolean isFactValid(StackDepth fact) { 66 int depth = fact.getDepth(); 67 return depth != TOP && depth != BOTTOM; 68 } 69 70 public void copy(StackDepth source, StackDepth dest) { 71 dest.setDepth(source.getDepth()); 72 } 73 74 public void initEntryFact(StackDepth entryFact) { 75 entryFact.setDepth(0); } 77 78 public void initResultFact(StackDepth result) { 79 makeFactTop(result); 80 } 81 82 public boolean same(StackDepth fact1, StackDepth fact2) { 83 return fact1.getDepth() == fact2.getDepth(); 84 } 85 86 @Override 87 public void transferInstruction(InstructionHandle handle, BasicBlock basicBlock, StackDepth fact) throws DataflowAnalysisException { 88 Instruction ins = handle.getInstruction(); 89 int produced = ins.produceStack(cpg); 90 int consumed = ins.consumeStack(cpg); 91 if (produced == Constants.UNPREDICTABLE || consumed == Constants.UNPREDICTABLE) 92 throw new IllegalStateException ("Unpredictable stack delta for instruction: " + handle); 93 int depth = fact.getDepth(); 94 depth += (produced - consumed); 95 if (depth < 0) 96 fact.setDepth(BOTTOM); 97 else 98 fact.setDepth(depth); 99 } 100 101 public void meetInto(StackDepth fact, Edge edge, StackDepth result) { 102 int a = fact.getDepth(); 103 int b = result.getDepth(); 104 int combined; 105 106 if (a == TOP) 107 combined = b; 108 else if (b == TOP) 109 combined = a; 110 else if (a == BOTTOM || b == BOTTOM || a != b) 111 combined = BOTTOM; 112 else 113 combined = a; 114 115 result.setDepth(combined); 116 } 117 118 121 public static void main(String [] argv) throws Exception { 122 if (argv.length != 1) { 123 System.out.println("Usage: " + StackDepthAnalysis.class.getName() + " <class file>"); 124 System.exit(1); 125 } 126 127 DataflowTestDriver<StackDepth, StackDepthAnalysis> driver = new DataflowTestDriver<StackDepth, StackDepthAnalysis>() { 128 @Override 129 public Dataflow<StackDepth, StackDepthAnalysis> createDataflow(ClassContext classContext, Method method) 130 throws CFGBuilderException, DataflowAnalysisException { 131 132 DepthFirstSearch dfs = classContext.getDepthFirstSearch(method); 133 CFG cfg = classContext.getCFG(method); 134 135 StackDepthAnalysis analysis = new StackDepthAnalysis(classContext.getConstantPoolGen(), dfs); 136 Dataflow<StackDepth, StackDepthAnalysis> dataflow = new Dataflow<StackDepth, StackDepthAnalysis>(cfg, analysis); 137 dataflow.execute(); 138 139 return dataflow; 140 } 141 }; 142 143 driver.execute(argv[0]); 144 } 145 } 146 147 | Popular Tags |