00001 package edu.ksu.cis.bandera.birc;
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 import java.io.*;
00036 import java.util.Vector;
00037 import java.util.Hashtable;
00038
00039 import edu.ksu.cis.bandera.bir.TransSystem;
00040 import edu.ksu.cis.bandera.bir.StateVar;
00041 import edu.ksu.cis.bandera.bir.LocVector;
00042 import edu.ksu.cis.bandera.bir.ThreadLocTest;
00043 import edu.ksu.cis.bandera.bir.IntLit;
00044 import edu.ksu.cis.bandera.jext.*;
00045
00046 import ca.mcgill.sable.util.*;
00047 import ca.mcgill.sable.soot.*;
00048 import ca.mcgill.sable.soot.jimple.*;
00049
00050
00051
00052
00053
00054
00055 public class ExprExtractor extends AbstractBanderaValueSwitch {
00056
00057 TransSystem system;
00058 Stmt stmt;
00059 LocalDefs localDefs;
00060 SootMethod method;
00061 TypeExtractor typeExtract;
00062 PredicateSet predSet;
00063
00064 boolean observable = false;
00065
00066 public ExprExtractor(TransSystem system, Stmt stmt, LocalDefs localDefs,
00067 SootMethod method, TypeExtractor typeExtract,
00068 PredicateSet predSet) {
00069
00070
00071
00072 this.system = system;
00073 this.stmt = stmt;
00074 this.localDefs = localDefs;
00075 this.method = method;
00076 this.typeExtract = typeExtract;
00077 this.predSet = predSet;
00078 }
00079 public void caseAddExpr(AddExpr expr) {
00080 expr.getOp1().apply(this);
00081 edu.ksu.cis.bandera.bir.Expr expr1 =
00082 (edu.ksu.cis.bandera.bir.Expr) getResult();
00083 expr.getOp2().apply(this);
00084 edu.ksu.cis.bandera.bir.Expr expr2 =
00085 (edu.ksu.cis.bandera.bir.Expr) getResult();
00086 setResult(new edu.ksu.cis.bandera.bir.AddExpr(expr1, expr2));
00087 }
00088 public void caseAndExpr(AndExpr expr) {
00089
00090 defaultCase(expr);
00091 }
00092 public void caseArrayRef(ArrayRef expr) {
00093 expr.getBase().apply(this);
00094 edu.ksu.cis.bandera.bir.Expr arrayRef =
00095 (edu.ksu.cis.bandera.bir.Expr) getResult();
00096
00097 edu.ksu.cis.bandera.bir.Expr array =
00098 new edu.ksu.cis.bandera.bir.DerefExpr(arrayRef);
00099 expr.getIndex().apply(this);
00100 edu.ksu.cis.bandera.bir.Expr index =
00101 (edu.ksu.cis.bandera.bir.Expr) getResult();
00102 setResult(new edu.ksu.cis.bandera.bir.ArrayExpr(array, index));
00103 }
00104 public void caseCastExpr(CastExpr expr) {
00105
00106 expr.getOp().apply(this);
00107 }
00108
00109
00110
00111
00112 public void caseChooseExpr(ChooseExpr expr) {
00113 Object choices [] = expr.getChoices().toArray();
00114 ((Value)choices[0]).apply(this);
00115 edu.ksu.cis.bandera.bir.Expr choice =
00116 (edu.ksu.cis.bandera.bir.Expr) getResult();
00117 edu.ksu.cis.bandera.bir.ChooseExpr choose =
00118 new edu.ksu.cis.bandera.bir.ChooseExpr(choice);
00119 for (int i = 1; i < choices.length; i++) {
00120 ((Value)choices[i]).apply(this);
00121 choose.addChoice((edu.ksu.cis.bandera.bir.Expr) getResult());
00122 }
00123 setResult(choose);
00124 }
00125 public void caseComplementExpr(ComplementExpr expr) {
00126 expr.getOp().apply(this);
00127 edu.ksu.cis.bandera.bir.Expr expr1 =
00128 (edu.ksu.cis.bandera.bir.Expr) getResult();
00129 setResult(new edu.ksu.cis.bandera.bir.NotExpr(expr1));
00130 }
00131 public void caseDivExpr(DivExpr expr) {
00132 expr.getOp1().apply(this);
00133 edu.ksu.cis.bandera.bir.Expr expr1 =
00134 (edu.ksu.cis.bandera.bir.Expr) getResult();
00135 expr.getOp2().apply(this);
00136 edu.ksu.cis.bandera.bir.Expr expr2 =
00137 (edu.ksu.cis.bandera.bir.Expr) getResult();
00138 setResult(new edu.ksu.cis.bandera.bir.DivExpr(expr1, expr2));
00139 }
00140 public void caseEqExpr(EqExpr expr)
00141 {
00142 expr.getOp1().apply(this);
00143 edu.ksu.cis.bandera.bir.Expr expr1 =
00144 (edu.ksu.cis.bandera.bir.Expr) getResult();
00145 expr.getOp2().apply(this);
00146 edu.ksu.cis.bandera.bir.Expr expr2 =
00147 (edu.ksu.cis.bandera.bir.Expr) getResult();
00148 setResult(new edu.ksu.cis.bandera.bir.EqExpr(expr1, expr2));
00149 }
00150 public void caseGeExpr(GeExpr expr) {
00151 expr.getOp1().apply(this);
00152 edu.ksu.cis.bandera.bir.Expr expr1 =
00153 (edu.ksu.cis.bandera.bir.Expr) getResult();
00154 expr.getOp2().apply(this);
00155 edu.ksu.cis.bandera.bir.Expr expr2 =
00156 (edu.ksu.cis.bandera.bir.Expr) getResult();
00157 setResult(new edu.ksu.cis.bandera.bir.LeExpr(expr2, expr1));
00158 }
00159 public void caseGtExpr(GtExpr expr) {
00160 expr.getOp1().apply(this);
00161 edu.ksu.cis.bandera.bir.Expr expr1 =
00162 (edu.ksu.cis.bandera.bir.Expr) getResult();
00163 expr.getOp2().apply(this);
00164 edu.ksu.cis.bandera.bir.Expr expr2 =
00165 (edu.ksu.cis.bandera.bir.Expr) getResult();
00166 setResult(new edu.ksu.cis.bandera.bir.LtExpr(expr2, expr1));
00167 }
00168
00169
00170
00171
00172
00173
00174 public void caseInExpr(InExpr expr) {
00175 edu.ksu.cis.bandera.bir.Expr result = null;
00176 expr.getOp1().apply(this);
00177 edu.ksu.cis.bandera.bir.Expr op1 =
00178 (edu.ksu.cis.bandera.bir.Expr) getResult();
00179 Set values = expr.getSet();
00180 Iterator valIt = values.iterator();
00181 while (valIt.hasNext()) {
00182 Value val = (Value) valIt.next();
00183 val.apply(this);
00184 edu.ksu.cis.bandera.bir.Expr element =
00185 (edu.ksu.cis.bandera.bir.Expr) getResult();
00186 edu.ksu.cis.bandera.bir.Expr compare =
00187 new edu.ksu.cis.bandera.bir.EqExpr(op1,element);
00188 if (result == null)
00189 result = compare;
00190 else
00191 result = new edu.ksu.cis.bandera.bir.OrExpr(result,compare);
00192 }
00193 setResult(result);
00194 }
00195 public void caseInstanceFieldRef(InstanceFieldRef expr) {
00196 if (predSet.isObservable(expr.getField()))
00197 observable = true;
00198 expr.getBase().apply(this);
00199 edu.ksu.cis.bandera.bir.Expr base =
00200 (edu.ksu.cis.bandera.bir.Expr) getResult();
00201
00202 edu.ksu.cis.bandera.bir.Expr rec =
00203 new edu.ksu.cis.bandera.bir.DerefExpr(base);
00204 edu.ksu.cis.bandera.bir.Record recType =
00205 (edu.ksu.cis.bandera.bir.Record)
00206 ((edu.ksu.cis.bandera.bir.Ref)base.getType()).getTargetType();
00207 edu.ksu.cis.bandera.bir.Field field =
00208 recType.getField(system.getNameOf(expr.getField()));
00209 setResult(new edu.ksu.cis.bandera.bir.RecordExpr(rec,field));
00210 }
00211 public void caseInstanceOfExpr(InstanceOfExpr expr) {
00212 expr.getOp().apply(this);
00213 edu.ksu.cis.bandera.bir.Expr refExpr =
00214 (edu.ksu.cis.bandera.bir.Expr) getResult();
00215
00216 expr.getCheckType().apply(typeExtract);
00217 edu.ksu.cis.bandera.bir.Ref refType =
00218 (edu.ksu.cis.bandera.bir.Ref) typeExtract.getResult();
00219 setResult(new edu.ksu.cis.bandera.bir.InstanceOfExpr(refExpr,refType));
00220 }
00221 public void caseIntConstant(IntConstant expr) {
00222 setResult(new IntLit(expr.value));
00223 }
00224 public void caseLeExpr(LeExpr expr) {
00225 expr.getOp1().apply(this);
00226 edu.ksu.cis.bandera.bir.Expr expr1 =
00227 (edu.ksu.cis.bandera.bir.Expr) getResult();
00228 expr.getOp2().apply(this);
00229 edu.ksu.cis.bandera.bir.Expr expr2 =
00230 (edu.ksu.cis.bandera.bir.Expr) getResult();
00231 setResult(new edu.ksu.cis.bandera.bir.LeExpr(expr1, expr2));
00232 }
00233 public void caseLengthExpr(LengthExpr expr) {
00234 expr.getOp().apply(this);
00235 edu.ksu.cis.bandera.bir.Expr arrayRef =
00236 (edu.ksu.cis.bandera.bir.Expr) getResult();
00237
00238 edu.ksu.cis.bandera.bir.Expr array =
00239 new edu.ksu.cis.bandera.bir.DerefExpr(arrayRef);
00240 setResult(new edu.ksu.cis.bandera.bir.LengthExpr(array));
00241 }
00242 public void caseLocal(Local expr) {
00243 if (method == null)
00244 throw new RuntimeException("Local appears in predicate outside of a LocalExpr");
00245 String key = localKey(method,expr);
00246
00247 if (predSet.isObservable(key))
00248 observable = true;
00249 edu.ksu.cis.bandera.bir.StateVar var = system.getVarOfKey(key);
00250 if (var == null)
00251 throw new RuntimeException("Variable not declared: " + expr);
00252 setResult(var);
00253 }
00254
00255
00256
00257
00258
00259
00260 public void caseLocalExpr(LocalExpr expr) {
00261 SootMethod method = expr.getMethod();
00262 Local local = expr.getLocal();
00263 String key = ExprExtractor.localKey(method,local);
00264 edu.ksu.cis.bandera.bir.StateVar var = system.getVarOfKey(key);
00265 if (var == null)
00266 throw new RuntimeException("Variable not declared: " + expr);
00267 setResult(var);
00268 }
00269 public void caseLocationTestExpr(LocationTestExpr expr) {
00270
00271
00272
00273
00274 edu.ksu.cis.bandera.bir.Expr predExpr = null;
00275 Vector stmts = expr.getStmts();
00276 for (int i = 0; i < stmts.size(); i++) {
00277 Stmt stmt = (Stmt) stmts.elementAt(i);
00278 LocVector locs = predSet.getPredicateLocations(stmt);
00279 for (int j = 0; j < locs.size(); j++) {
00280 ThreadLocTest locTest = new ThreadLocTest(locs.elementAt(j));
00281 if (predExpr == null)
00282 predExpr = locTest;
00283 else
00284 predExpr =
00285 new edu.ksu.cis.bandera.bir.OrExpr(predExpr,locTest);
00286 }
00287 }
00288 if (predExpr == null)
00289 predExpr = new edu.ksu.cis.bandera.bir.BoolLit(false);
00290 setResult(predExpr);
00291 }
00292 public void caseLogicalAndExpr(LogicalAndExpr expr) {
00293 expr.getOp1().apply(this);
00294 edu.ksu.cis.bandera.bir.Expr expr1 =
00295 (edu.ksu.cis.bandera.bir.Expr) getResult();
00296 expr.getOp2().apply(this);
00297 edu.ksu.cis.bandera.bir.Expr expr2 =
00298 (edu.ksu.cis.bandera.bir.Expr) getResult();
00299 setResult(new edu.ksu.cis.bandera.bir.AndExpr(expr1,expr2));
00300 }
00301 public void caseLogicalOrExpr(LogicalOrExpr expr) {
00302 expr.getOp1().apply(this);
00303 edu.ksu.cis.bandera.bir.Expr expr1 =
00304 (edu.ksu.cis.bandera.bir.Expr) getResult();
00305 expr.getOp2().apply(this);
00306 edu.ksu.cis.bandera.bir.Expr expr2 =
00307 (edu.ksu.cis.bandera.bir.Expr) getResult();
00308 setResult(new edu.ksu.cis.bandera.bir.OrExpr(expr1,expr2));
00309 }
00310 public void caseLtExpr(LtExpr expr) {
00311 expr.getOp1().apply(this);
00312 edu.ksu.cis.bandera.bir.Expr expr1 =
00313 (edu.ksu.cis.bandera.bir.Expr) getResult();
00314 expr.getOp2().apply(this);
00315 edu.ksu.cis.bandera.bir.Expr expr2 =
00316 (edu.ksu.cis.bandera.bir.Expr) getResult();
00317 setResult(new edu.ksu.cis.bandera.bir.LtExpr(expr1, expr2));
00318 }
00319 public void caseMulExpr(MulExpr expr) {
00320 expr.getOp1().apply(this);
00321 edu.ksu.cis.bandera.bir.Expr expr1 =
00322 (edu.ksu.cis.bandera.bir.Expr) getResult();
00323 expr.getOp2().apply(this);
00324 edu.ksu.cis.bandera.bir.Expr expr2 =
00325 (edu.ksu.cis.bandera.bir.Expr) getResult();
00326 setResult(new edu.ksu.cis.bandera.bir.MulExpr(expr1, expr2));
00327 }
00328 public void caseNeExpr(NeExpr expr)
00329 {
00330 expr.getOp1().apply(this);
00331 edu.ksu.cis.bandera.bir.Expr expr1 =
00332 (edu.ksu.cis.bandera.bir.Expr) getResult();
00333 expr.getOp2().apply(this);
00334 edu.ksu.cis.bandera.bir.Expr expr2 =
00335 (edu.ksu.cis.bandera.bir.Expr) getResult();
00336 setResult(new edu.ksu.cis.bandera.bir.NeExpr(expr1, expr2));
00337 }
00338 public void caseNegExpr(NegExpr expr) {
00339 expr.getOp().apply(this);
00340 edu.ksu.cis.bandera.bir.Expr expr1 =
00341 (edu.ksu.cis.bandera.bir.Expr) getResult();
00342 setResult(new edu.ksu.cis.bandera.bir.SubExpr(IntLit.ZERO,expr1));
00343 }
00344 public void caseNewArrayExpr(NewArrayExpr expr) {
00345 StateVar col = system.getVarOfKey(expr);
00346 expr.getSize().apply(this);
00347 edu.ksu.cis.bandera.bir.Expr size =
00348 (edu.ksu.cis.bandera.bir.Expr) getResult();
00349 setResult(new edu.ksu.cis.bandera.bir.NewArrayExpr(col,size));
00350 }
00351 public void caseNewExpr(NewExpr expr) {
00352 StateVar col = system.getVarOfKey(expr);
00353 if (col != null)
00354 setResult(new edu.ksu.cis.bandera.bir.NewExpr(col));
00355 else
00356
00357
00358 setResult(new edu.ksu.cis.bandera.bir.NullExpr(system));
00359 }
00360 public void caseNullConstant(NullConstant expr) {
00361 setResult(new edu.ksu.cis.bandera.bir.NullExpr(system));
00362 }
00363 public void caseOrExpr(OrExpr expr) {
00364
00365 defaultCase(expr);
00366 }
00367 public void caseRemExpr(RemExpr expr) {
00368 expr.getOp1().apply(this);
00369 edu.ksu.cis.bandera.bir.Expr expr1 =
00370 (edu.ksu.cis.bandera.bir.Expr) getResult();
00371 expr.getOp2().apply(this);
00372 edu.ksu.cis.bandera.bir.Expr expr2 =
00373 (edu.ksu.cis.bandera.bir.Expr) getResult();
00374 setResult(new edu.ksu.cis.bandera.bir.RemExpr(expr1, expr2));
00375 }
00376 public void caseStaticFieldRef(StaticFieldRef expr) {
00377
00378 if (predSet.isObservable(expr.getField()))
00379 observable = true;
00380 edu.ksu.cis.bandera.bir.StateVar var =
00381 system.getVarOfKey(expr.getField());
00382 if (var == null)
00383 throw new RuntimeException("Field not declared: " + expr);
00384 setResult(var);
00385 }
00386 public void caseStaticInvokeExpr(StaticInvokeExpr expr) {
00387 throw new RuntimeException("Unhandled static method call: " + expr);
00388 }
00389 public void caseStringConstant(StringConstant expr) {
00390 String s = expr.toString();
00391 setResult(s.substring(1,s.length() - 1));
00392 }
00393 public void caseSubExpr(SubExpr expr) {
00394 expr.getOp1().apply(this);
00395 edu.ksu.cis.bandera.bir.Expr expr1 =
00396 (edu.ksu.cis.bandera.bir.Expr) getResult();
00397 expr.getOp2().apply(this);
00398 edu.ksu.cis.bandera.bir.Expr expr2 =
00399 (edu.ksu.cis.bandera.bir.Expr) getResult();
00400 setResult(new edu.ksu.cis.bandera.bir.SubExpr(expr1, expr2));
00401 }
00402 public void caseThisRef(ThisRef thisRef) {
00403 String threadName = ((RefType)thisRef.getType()).className;
00404 SootClass sClass =
00405 method.getDeclaringClass().getManager().getClass(threadName);
00406
00407
00408 StateVar var = system.getVarOfKey(sClass);
00409 setResult(var);
00410 }
00411 public void defaultCase(Object o) {
00412 throw new RuntimeException("Unhandled expression type " +
00413 o.getClass().getName() + ": " + o);
00414 }
00415 public boolean isObservable() { return observable; }
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426 public static String localKey(SootMethod method, Local local) {
00427 return method.getDeclaringClass().getName() + "."
00428 + method.getName() + "." + local.getName();
00429 }
00430 }