KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > umd > cs > findbugs > ba > StackDepthAnalysis


1 /*
2  * Bytecode Analysis Framework
3  * Copyright (C) 2003,2004 University of Maryland
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */

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 /**
29  * A really simple forward dataflow analysis to find the depth of
30  * the Java operand stack. This is more of a proof of concept for
31  * the dataflow analysis framework than anything useful.
32  *
33  * @see Dataflow
34  * @see DataflowAnalysis
35  */

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     /**
43      * Constructor.
44      *
45      * @param cpg the ConstantPoolGen of the method whose CFG we're performing the analysis on
46      * @param dfs DepthFirstSearch of the method's CFG
47      */

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 JavaDoc
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); // stack depth == 0 at entry to CFG
76
}
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 JavaDoc
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 JavaDoc("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     /**
119      * Command line driver, for testing.
120      */

121     public static void main(String JavaDoc[] argv) throws Exception JavaDoc {
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 JavaDoc
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 // vim:ts=4
148
Popular Tags