KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > jimple > toolkits > annotation > nullcheck > NullPointerChecker


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

19
20 /*
21  * Modified by the Sable Research Group and others 1997-1999.
22  * See the 'credits' file distributed with Soot for the complete list of
23  * contributors. (Soot is distributed at http://www.sable.mcgill.ca/soot)
24  */

25
26
27 /* Added by Feng, to annotate the object references in the bytecode.
28  */

29
30 package soot.jimple.toolkits.annotation.nullcheck;
31 import soot.options.*;
32
33 import soot.*;
34 import soot.jimple.*;
35 import soot.util.*;
36 import java.io.*;
37 import java.util.*;
38 import soot.tagkit.*;
39 import soot.jimple.toolkits.annotation.tags.*;
40 import soot.toolkits.graph.*;
41 import soot.toolkits.scalar.*;
42
43  /*
44     ArrayRef
45     GetField
46     PutField
47     InvokeVirtual
48     InvokeSpecial
49     InvokeInterface
50     ArrayLength
51 - AThrow
52 - MonitorEnter
53 - MonitorExit
54  */

55
56 public class NullPointerChecker extends BodyTransformer
57 {
58     public NullPointerChecker( Singletons.Global g ) {}
59     public static NullPointerChecker v() { return G.v().soot_jimple_toolkits_annotation_nullcheck_NullPointerChecker(); }
60
61     private boolean isProfiling = false;
62  
63     private boolean enableOther = true;
64     
65     protected void internalTransform(Body body, String JavaDoc phaseName, Map options)
66     {
67     isProfiling = PhaseOptions.getBoolean(options, "profiling");
68     enableOther = !PhaseOptions.getBoolean(options, "onlyarrayref");
69
70     {
71         Date start = new Date();
72
73         if (Options.v().verbose())
74         G.v().out.println("[npc] Null pointer check for "+body.getMethod().getName()
75                    +" started on "+start);
76         
77         BranchedRefVarsAnalysis analysis = new BranchedRefVarsAnalysis(
78                             new ExceptionalUnitGraph(body));
79
80         SootClass counterClass = null;
81         SootMethod increase = null;
82         
83         if (isProfiling)
84         {
85         counterClass = Scene.v().loadClassAndSupport("MultiCounter");
86         increase = counterClass.getMethod("void increase(int)") ;
87         }
88
89         Chain units = body.getUnits();
90
91         Iterator stmtIt = units.snapshotIterator() ;
92
93         while (stmtIt.hasNext())
94         {
95             Stmt s = (Stmt)stmtIt.next() ;
96         
97         Value obj = null;
98
99         if (s.containsArrayRef())
100         {
101             ArrayRef aref = (ArrayRef)s.getArrayRef();
102             obj = aref.getBase();
103         }
104         else
105             {
106             if (enableOther)
107             {
108             // Throw
109
if (s instanceof ThrowStmt)
110             {
111                 obj = ((ThrowStmt)s).getOp();
112             }
113             else
114             // Monitor enter and exit
115
if (s instanceof MonitorStmt)
116             {
117                 obj = ((MonitorStmt)s).getOp();
118             }
119             else
120             {
121                 Iterator boxIt;
122                             boxIt = s.getDefBoxes().iterator();
123                 while (boxIt.hasNext())
124                 {
125                 ValueBox vBox = (ValueBox)boxIt.next();
126                 Value v = vBox.getValue();
127
128                 // putfield, and getfield
129
if (v instanceof InstanceFieldRef)
130                 {
131                     obj = ((InstanceFieldRef)v).getBase();
132                     break;
133                 }
134                 else
135                 // invokevirtual, invokespecial, invokeinterface
136
if (v instanceof InstanceInvokeExpr)
137                 {
138                     obj = ((InstanceInvokeExpr)v).getBase();
139                     break;
140                 }
141                 else
142                 // arraylength
143
if (v instanceof LengthExpr)
144                 {
145                     obj = ((LengthExpr)v).getOp();
146                     break;
147                 }
148                 }
149                             boxIt = s.getUseBoxes().iterator();
150                 while (boxIt.hasNext())
151                 {
152                 ValueBox vBox = (ValueBox)boxIt.next();
153                 Value v = vBox.getValue();
154
155                 // putfield, and getfield
156
if (v instanceof InstanceFieldRef)
157                 {
158                     obj = ((InstanceFieldRef)v).getBase();
159                     break;
160                 }
161                 else
162                 // invokevirtual, invokespecial, invokeinterface
163
if (v instanceof InstanceInvokeExpr)
164                 {
165                     obj = ((InstanceInvokeExpr)v).getBase();
166                     break;
167                 }
168                 else
169                 // arraylength
170
if (v instanceof LengthExpr)
171                 {
172                     obj = ((LengthExpr)v).getOp();
173                     break;
174                 }
175                 }
176             }
177             }
178         }
179
180         // annotate it or now
181
if (obj != null)
182         {
183             FlowSet beforeSet = (FlowSet)analysis.getFlowBefore(s);
184             
185             int vInfo = analysis.anyRefInfo(obj, beforeSet);
186             
187             boolean needCheck =
188             (vInfo != analysis.kNonNull);
189
190             if (isProfiling)
191             {
192             int whichCounter = 5;
193             if (!needCheck)
194                 whichCounter = 6;
195   
196             units.insertBefore(Jimple.v().newInvokeStmt(
197                           Jimple.v().newStaticInvokeExpr(increase.makeRef(),
198                           IntConstant.v(whichCounter))), s);
199             }
200             
201             {
202             Tag nullTag = new NullCheckTag(needCheck);
203             s.addTag(nullTag);
204             }
205         }
206         }
207
208         Date finish = new Date();
209         if (Options.v().verbose())
210         {
211         long runtime = finish.getTime()-start.getTime();
212         long mins = runtime/60000;
213         long secs = (runtime%60000)/1000;
214         G.v().out.println("[npc] Null pointer checker finished. It took "
215                    +mins+" mins and "+secs+" secs.");
216         }
217     }
218     }
219 }
220
Popular Tags