00001 package edu.ksu.cis.bandera.abstraction;
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.util.Vector;
00036 import java.util.Enumeration;
00037 import ca.mcgill.sable.soot.*;
00038 import ca.mcgill.sable.util.*;
00039 import edu.ksu.cis.bandera.jext.*;
00040 import ca.mcgill.sable.soot.jimple.*;
00041 import edu.ksu.cis.bandera.annotation.*;
00042 import edu.ksu.cis.bandera.abstraction.util.*;
00043 import edu.ksu.cis.bandera.abstraction.typeinference.*;
00044 import java.util.Hashtable;
00045 public class SLABS extends IRNodes {
00046 private static final Jimple jimple = Jimple.v();
00047 private static final String prefix = "SLABS$";
00048 private SootClassManager scm;
00049 private Vector messages = new Vector();
00050 private AnnotationManager am;
00051 private TypeTable typeTable;
00052 private Annotation methodAnnotation;
00053 private JimpleBody methodBody;
00054 private StmtList methodStmtList;
00055 private Stmt currentStmt;
00056 private Value currentValue;
00057 private Abstraction coercedAbstraction;
00058 private int tempCounter;
00059 private Hashtable interfaceMethodMethod;
00060
00061
00062
00063
00064
00065
00066 public SLABS(AnnotationManager annotationManager, TypeTable typeTable, Hashtable interfaceMethodMethod) {
00067 am = annotationManager;
00068 this.typeTable = typeTable;
00069 this.interfaceMethodMethod = interfaceMethodMethod;
00070 }
00071
00072
00073
00074
00075
00076 public Vector abstractClasses(java.util.Vector classes) {
00077 for (java.util.Iterator i = classes.iterator(); i.hasNext();) {
00078 SootClass sc = (SootClass) i.next();
00079 if (scm == null)
00080 scm = sc.getManager();
00081 for (Iterator j = sc.getFields().iterator(); j.hasNext();) {
00082 SootField sf = (SootField) j.next();
00083 Abstraction a = typeTable.get(sf);
00084 if (((a instanceof IntegralAbstraction) && !(a instanceof ConcreteIntegralAbstraction))
00085 || ((a instanceof RealAbstraction) && !(a instanceof ConcreteRealAbstraction))) {
00086 sf.setType(IntType.v());
00087 }
00088 }
00089 for (Iterator j = sc.getMethods().iterator(); j.hasNext();) {
00090 SootMethod sm = (SootMethod) j.next();
00091 tempCounter = 0;
00092 methodBody = (JimpleBody) sm.getBody(jimple);
00093 for (Iterator k = methodBody.getLocals().iterator(); k.hasNext();) {
00094 Local lcl = (Local) k.next();
00095 Abstraction a = typeTable.get(lcl);
00096 if (((a instanceof IntegralAbstraction) && !(a instanceof ConcreteIntegralAbstraction))
00097 || ((a instanceof RealAbstraction) && !(a instanceof ConcreteRealAbstraction))) {
00098 lcl.setType(IntType.v());
00099 }
00100 }
00101 methodStmtList = methodBody.getStmtList();
00102 methodAnnotation = am.getAnnotation(sc, sm);
00103 Object[] stmts = methodStmtList.toArray();
00104 for (int k = 0; k < stmts.length; k++) {
00105 currentValue = null;
00106 currentStmt = (Stmt) stmts[k];
00107 currentStmt.apply(this);
00108 }
00109 }
00110 }
00111 for (Enumeration e = interfaceMethodMethod.keys(); e.hasMoreElements();) {
00112 SootMethod key = (SootMethod) e.nextElement();
00113 SootMethod value = (SootMethod) interfaceMethodMethod.get(key);
00114 key.setParameterTypes(new LinkedList(value.getParameterTypes()));
00115 key.setReturnType(value.getReturnType());
00116 }
00117 return messages;
00118 }
00119 public void caseAddExpr(AddExpr v) {
00120 Abstraction a = (Abstraction) typeTable.get(v);
00121 if ((a instanceof IntegralAbstraction) && !(a instanceof ConcreteIntegralAbstraction)) {
00122 coercedAbstraction = a;
00123 doOp("add", v.getOp1(), v.getOp2());
00124 coercedAbstraction = ConcreteIntegralAbstraction.v();
00125 } else if ((a instanceof RealAbstraction) && !(a instanceof ConcreteRealAbstraction)) {
00126 coercedAbstraction = a;
00127 doOp("add", v.getOp1(), v.getOp2());
00128 coercedAbstraction = ConcreteIntegralAbstraction.v();
00129 } else {
00130 currentValue = v;
00131 }
00132 }
00133 public void caseAndExpr(AndExpr v) {
00134 Abstraction a = (Abstraction) typeTable.get(v);
00135 if ((a instanceof IntegralAbstraction) && !(a instanceof ConcreteIntegralAbstraction)) {
00136 coercedAbstraction = a;
00137 doOp("and", v.getOp1(), v.getOp2());
00138 coercedAbstraction = ConcreteIntegralAbstraction.v();
00139 } else if ((a instanceof RealAbstraction) && !(a instanceof ConcreteRealAbstraction)) {
00140 coercedAbstraction = a;
00141 doOp("and", v.getOp1(), v.getOp2());
00142 coercedAbstraction = ConcreteIntegralAbstraction.v();
00143 } else {
00144 currentValue = v;
00145 }
00146 }
00147 public void caseArrayRef(ArrayRef v) {
00148 defaultCase(v);
00149 }
00150 public void caseAssignStmt(AssignStmt stmt) {
00151 coercedAbstraction = (Abstraction) typeTable.get(stmt.getLeftOp());
00152 stmt.getRightOp().apply(this);
00153 if (currentValue != null)
00154 stmt.setRightOp(currentValue);
00155 }
00156 public void caseBreakpointStmt(BreakpointStmt stmt) {
00157 defaultCase(stmt);
00158 }
00159 public void caseCastExpr(CastExpr v) {
00160 v.getOp().apply(this);
00161 }
00162 public void caseCaughtExceptionRef(CaughtExceptionRef v) {
00163 defaultCase(v);
00164 }
00165 public void caseChooseExpr(ChooseExpr v) {
00166 defaultCase(v);
00167 }
00168 public void caseCmpExpr(CmpExpr v) {
00169 defaultCase(v);
00170 }
00171 public void caseCmpgExpr(CmpgExpr v) {
00172 defaultCase(v);
00173 }
00174 public void caseCmplExpr(CmplExpr v) {
00175 defaultCase(v);
00176 }
00177
00178
00179
00180
00181 public void caseComplementExpr(ComplementExpr expr) {
00182 defaultCase(expr);
00183 }
00184 public void caseDivExpr(DivExpr v) {
00185 Abstraction a = (Abstraction) typeTable.get(v);
00186 if ((a instanceof IntegralAbstraction) && !(a instanceof ConcreteIntegralAbstraction)) {
00187 coercedAbstraction = a;
00188 doOp("div", v.getOp1(), v.getOp2());
00189 coercedAbstraction = ConcreteIntegralAbstraction.v();
00190 } else if ((a instanceof RealAbstraction) && !(a instanceof ConcreteRealAbstraction)) {
00191 coercedAbstraction = a;
00192 doOp("div", v.getOp1(), v.getOp2());
00193 coercedAbstraction = ConcreteIntegralAbstraction.v();
00194 } else {
00195 currentValue = v;
00196 }
00197 }
00198 public void caseDoubleConstant(DoubleConstant v) {
00199 coerce(v);
00200 }
00201 public void caseEnterMonitorStmt(EnterMonitorStmt stmt) {
00202 defaultCase(stmt);
00203 }
00204 public void caseEqExpr(EqExpr v) {
00205 Abstraction a = (Abstraction) typeTable.get(v);
00206 if ((a instanceof IntegralAbstraction) && !(a instanceof ConcreteIntegralAbstraction)) {
00207 coercedAbstraction = a;
00208 doOp("eq", v.getOp1(), v.getOp2());
00209 coercedAbstraction = ConcreteIntegralAbstraction.v();
00210 } else if ((a instanceof RealAbstraction) && !(a instanceof ConcreteRealAbstraction)) {
00211 coercedAbstraction = a;
00212 doOp("eq", v.getOp1(), v.getOp2());
00213 coercedAbstraction = ConcreteIntegralAbstraction.v();
00214 } else {
00215 currentValue = v;
00216 }
00217 }
00218 public void caseExitMonitorStmt(ExitMonitorStmt stmt) {
00219 defaultCase(stmt);
00220 }
00221 public void caseFloatConstant(FloatConstant v) {
00222 coerce(v);
00223 }
00224 public void caseGeExpr(GeExpr v) {
00225 Abstraction a = (Abstraction) typeTable.get(v);
00226 if ((a instanceof IntegralAbstraction) && !(a instanceof ConcreteIntegralAbstraction)) {
00227 coercedAbstraction = a;
00228 doOp("ge", v.getOp1(), v.getOp2());
00229 coercedAbstraction = ConcreteIntegralAbstraction.v();
00230 } else if ((a instanceof RealAbstraction) && !(a instanceof ConcreteRealAbstraction)) {
00231 coercedAbstraction = a;
00232 doOp("ge", v.getOp1(), v.getOp2());
00233 coercedAbstraction = ConcreteIntegralAbstraction.v();
00234 } else {
00235 currentValue = v;
00236 }
00237 }
00238 public void caseGotoStmt(GotoStmt stmt) {
00239 defaultCase(stmt);
00240 }
00241 public void caseGtExpr(GtExpr v) {
00242 Abstraction a = (Abstraction) typeTable.get(v);
00243 if ((a instanceof IntegralAbstraction) && !(a instanceof ConcreteIntegralAbstraction)) {
00244 coercedAbstraction = a;
00245 doOp("gt", v.getOp1(), v.getOp2());
00246 coercedAbstraction = ConcreteIntegralAbstraction.v();
00247 } else if ((a instanceof RealAbstraction) && !(a instanceof ConcreteRealAbstraction)) {
00248 coercedAbstraction = a;
00249 doOp("gt", v.getOp1(), v.getOp2());
00250 coercedAbstraction = ConcreteIntegralAbstraction.v();
00251 } else {
00252 currentValue = v;
00253 }
00254 }
00255 public void caseIdentityStmt(IdentityStmt stmt) {
00256 if (stmt.getRightOp() instanceof ParameterRef) {
00257 Abstraction a = typeTable.get(stmt.getLeftOp());
00258 if (((a instanceof IntegralAbstraction) && !(a instanceof ConcreteIntegralAbstraction))
00259 || ((a instanceof RealAbstraction) && !(a instanceof ConcreteRealAbstraction))) {
00260 List l = methodBody.getMethod().getParameterTypes();
00261 int index = ((ParameterRef) stmt.getRightOp()).getIndex();
00262 l.add(index, IntType.v());
00263 l.remove(index + 1);
00264 }
00265 }
00266 }
00267 public void caseIfStmt(IfStmt stmt) {
00268 stmt.getCondition().apply(this);
00269 if (currentValue != null) {
00270 if (!(currentValue instanceof ConditionExpr)) {
00271 currentValue = jimple.newNeExpr(makeLocal(currentValue, IntType.v()), IntConstant.v(0));
00272 typeTable.put(currentValue, ConcreteIntegralAbstraction.v());
00273 }
00274 stmt.setCondition(currentValue);
00275 }
00276 }
00277
00278
00279
00280
00281 public void caseInExpr(InExpr v) {
00282 defaultCase(v);
00283 }
00284 public void caseInstanceFieldRef(InstanceFieldRef v) {
00285 coerce(v);
00286 }
00287 public void caseInstanceOfExpr(InstanceOfExpr v) {
00288 defaultCase(v);
00289 }
00290 public void caseIntConstant(IntConstant v) {
00291 coerce(v);
00292 }
00293 public void caseInterfaceInvokeExpr(InterfaceInvokeExpr v) {
00294 defaultCase(v);
00295 }
00296 public void caseInvokeStmt(InvokeStmt stmt) {
00297 stmt.getInvokeExpr().apply(this);
00298 }
00299 public void caseLeExpr(LeExpr v) {
00300 Abstraction a = (Abstraction) typeTable.get(v);
00301 if ((a instanceof IntegralAbstraction) && !(a instanceof ConcreteIntegralAbstraction)) {
00302 coercedAbstraction = a;
00303 doOp("le", v.getOp1(), v.getOp2());
00304 coercedAbstraction = ConcreteIntegralAbstraction.v();
00305 } else if ((a instanceof RealAbstraction) && !(a instanceof ConcreteRealAbstraction)) {
00306 coercedAbstraction = a;
00307 doOp("le", v.getOp1(), v.getOp2());
00308 coercedAbstraction = ConcreteIntegralAbstraction.v();
00309 } else {
00310 currentValue = v;
00311 }
00312 }
00313 public void caseLengthExpr(LengthExpr v) {
00314 defaultCase(v);
00315 }
00316 public void caseLocal(Local v) {
00317 coerce(v);
00318 }
00319
00320
00321
00322
00323 public void caseLocalExpr(LocalExpr v) {
00324 defaultCase(v);
00325 }
00326
00327
00328
00329
00330 public void caseLocationTestExpr(LocationTestExpr e) {
00331 defaultCase(e);
00332 }
00333
00334
00335
00336
00337 public void caseLogicalAndExpr(LogicalAndExpr expr) {
00338 defaultCase(expr);
00339 }
00340
00341
00342
00343
00344 public void caseLogicalOrExpr(LogicalOrExpr expr) {
00345 defaultCase(expr);
00346 }
00347 public void caseLongConstant(LongConstant v) {
00348 coerce(v);
00349 }
00350 public void caseLookupSwitchStmt(LookupSwitchStmt stmt) {
00351 Abstraction a = typeTable.get(stmt.getKey());
00352 int tokens = ((Integer) AbstractionClassLoader.invokeMethod(a.getClass().getName(), "getNumOfTokens", new Class[0], null, new Object[0])).intValue();
00353 Vector[] cases = new Vector[tokens];
00354 Vector[] caseConstants = new Vector[tokens];
00355 for (int i = 0; i < tokens; i++) {
00356 cases[i] = new Vector();
00357 caseConstants[i] = new Vector();
00358 }
00359 int k = 0;
00360 for (ca.mcgill.sable.util.Iterator i = stmt.getLookupValues().iterator(); i.hasNext(); k++) {
00361 int caseConstant = ((Integer) i.next()).intValue();
00362 int token = ((Integer) AbstractionClassLoader.invokeMethod(a.getClass().getName(), "abs", new Class[] {long.class}, null, new Object[] {new Long(caseConstant)})).intValue();
00363 cases[token].add(stmt.getTarget(k));
00364 caseConstants[token].add(new Integer(caseConstant));
00365 }
00366
00367 Vector newStmts = new Vector();
00368 ca.mcgill.sable.util.LinkedList newLookupValues = new ca.mcgill.sable.util.LinkedList();
00369 Unit[] newTargets = new Unit[tokens];
00370
00371 for (int i = 0; i < tokens; i++) {
00372 int newCaseIdx = newStmts.size();
00373 if ((cases[i].size() == 0) || !((Boolean) AbstractionClassLoader.invokeMethod(a.getClass().getName(), "isOne2One", new Class[] {int.class}, null, new Object[] {new Integer(i)})).booleanValue()) {
00374 cases[i].add(stmt.getDefaultTarget());
00375 }
00376 int size = cases[i].size() - 1;
00377 for (int j = 0; j < size; j++) {
00378 Local lcl = jimple.newLocal(prefix + tempCounter++, IntType.v());
00379 methodBody.addLocal(lcl);
00380 typeTable.put(lcl, ConcreteIntegralAbstraction.v());
00381 newStmts.add(jimple.newAssignStmt(lcl, jimple.newStaticInvokeExpr(scm.getClass("edu.ksu.cis.bandera.abstraction.Abstraction").getMethod("choose", new LinkedList()), new LinkedList())));
00382 newStmts.add(jimple.newIfStmt(jimple.newEqExpr(lcl, IntConstant.v(1)), stmt.getTarget(stmt.getLookupValues().indexOf(caseConstants[i].elementAt(j)))));
00383 }
00384 newStmts.add(jimple.newGotoStmt((Stmt) cases[i].lastElement()));
00385 newLookupValues.add(new Integer(i));
00386 newTargets[i] = (Unit) newStmts.elementAt(newCaseIdx);
00387 }
00388
00389 Annotation ann = null;
00390 try {
00391 ann = am.getContainingAnnotation(methodBody.getMethod().getDeclaringClass(), methodBody.getMethod(), currentStmt);
00392 } catch (Exception e) {
00393 System.out.println("Cannot get annotation for statement: " + currentStmt);
00394 }
00395
00396 int index = methodStmtList.indexOf(currentStmt) + 1;
00397 for (java.util.Iterator i = newStmts.iterator(); i.hasNext(); index++) {
00398 Stmt s = (Stmt) i.next();
00399 methodStmtList.add(index, s);
00400 if (ann != null) ann.add(s);
00401 }
00402
00403 stmt.setLookupValues(newLookupValues);
00404 stmt.setTargets(newTargets);
00405 }
00406 public void caseLtExpr(LtExpr v) {
00407 Abstraction a = (Abstraction) typeTable.get(v);
00408 if ((a instanceof IntegralAbstraction) && !(a instanceof ConcreteIntegralAbstraction)) {
00409 coercedAbstraction = a;
00410 doOp("lt", v.getOp1(), v.getOp2());
00411 coercedAbstraction = ConcreteIntegralAbstraction.v();
00412 } else if ((a instanceof RealAbstraction) && !(a instanceof ConcreteRealAbstraction)) {
00413 coercedAbstraction = a;
00414 doOp("lt", v.getOp1(), v.getOp2());
00415 coercedAbstraction = ConcreteIntegralAbstraction.v();
00416 } else {
00417 currentValue = v;
00418 }
00419 }
00420 public void caseMulExpr(MulExpr v) {
00421 Abstraction a = (Abstraction) typeTable.get(v);
00422 if ((a instanceof IntegralAbstraction) && !(a instanceof ConcreteIntegralAbstraction)) {
00423 coercedAbstraction = a;
00424 doOp("mul", v.getOp1(), v.getOp2());
00425 coercedAbstraction = ConcreteIntegralAbstraction.v();
00426 } else if ((a instanceof RealAbstraction) && !(a instanceof ConcreteRealAbstraction)) {
00427 coercedAbstraction = a;
00428 doOp("mul", v.getOp1(), v.getOp2());
00429 coercedAbstraction = ConcreteIntegralAbstraction.v();
00430 } else {
00431 currentValue = v;
00432 }
00433 }
00434 public void caseNeExpr(NeExpr v) {
00435 Abstraction a = (Abstraction) typeTable.get(v);
00436 if ((a instanceof IntegralAbstraction) && !(a instanceof ConcreteIntegralAbstraction)) {
00437 coercedAbstraction = a;
00438 doOp("ne", v.getOp1(), v.getOp2());
00439 coercedAbstraction = ConcreteIntegralAbstraction.v();
00440 } else if ((a instanceof RealAbstraction) && !(a instanceof ConcreteRealAbstraction)) {
00441 coercedAbstraction = a;
00442 doOp("ne", v.getOp1(), v.getOp2());
00443 coercedAbstraction = ConcreteIntegralAbstraction.v();
00444 } else {
00445 currentValue = v;
00446 }
00447 }
00448 public void caseNegExpr(NegExpr v) {
00449 if (v.getType() instanceof LongType) {
00450 Value c = LongConstant.v(0);
00451 typeTable.put(c, ConcreteIntegralAbstraction.v());
00452 Value v2 = jimple.newSubExpr(c, v.getOp());
00453 typeTable.put(v2, typeTable.get(v));
00454 v2.apply(this);
00455 } else if (v.getType() instanceof FloatType) {
00456 Value c = FloatConstant.v(0);
00457 typeTable.put(c, ConcreteRealAbstraction.v());
00458 Value v2 = jimple.newSubExpr(c, v.getOp());
00459 typeTable.put(v2, typeTable.get(v));
00460 v2.apply(this);
00461 } else if (v.getType() instanceof DoubleType) {
00462 Value c = DoubleConstant.v(0);
00463 typeTable.put(c, ConcreteRealAbstraction.v());
00464 Value v2 = jimple.newSubExpr(c, v.getOp());
00465 typeTable.put(v2, typeTable.get(v));
00466 v2.apply(this);
00467 } else {
00468 Value c = IntConstant.v(0);
00469 typeTable.put(c, ConcreteIntegralAbstraction.v());
00470 Value v2 = jimple.newSubExpr(c, v.getOp());
00471 typeTable.put(v2, typeTable.get(v));
00472 v2.apply(this);
00473 }
00474 }
00475 public void caseNewArrayExpr(NewArrayExpr v) {
00476 defaultCase(v);
00477 }
00478 public void caseNewExpr(NewExpr v) {
00479 defaultCase(v);
00480 }
00481 public void caseNewInvokeExpr(NewInvokeExpr v) {
00482 defaultCase(v);
00483 }
00484 public void caseNewMultiArrayExpr(NewMultiArrayExpr v) {
00485 defaultCase(v);
00486 }
00487 public void caseNopStmt(NopStmt stmt) {
00488 defaultCase(stmt);
00489 }
00490 public void caseNullConstant(NullConstant v) {
00491 defaultCase(v);
00492 }
00493 public void caseOrExpr(OrExpr v) {
00494 Abstraction a = (Abstraction) typeTable.get(v);
00495 if ((a instanceof IntegralAbstraction) && !(a instanceof ConcreteIntegralAbstraction)) {
00496 coercedAbstraction = a;
00497 doOp("or", v.getOp1(), v.getOp2());
00498 coercedAbstraction = ConcreteIntegralAbstraction.v();
00499 } else if ((a instanceof RealAbstraction) && !(a instanceof ConcreteRealAbstraction)) {
00500 coercedAbstraction = a;
00501 doOp("or", v.getOp1(), v.getOp2());
00502 coercedAbstraction = ConcreteIntegralAbstraction.v();
00503 } else {
00504 currentValue = v;
00505 }
00506 }
00507 public void caseParameterRef(ParameterRef v) {
00508 defaultCase(v);
00509 }
00510 public void caseRemExpr(RemExpr v) {
00511 Abstraction a = (Abstraction) typeTable.get(v);
00512 if ((a instanceof IntegralAbstraction) && !(a instanceof ConcreteIntegralAbstraction)) {
00513 coercedAbstraction = a;
00514 doOp("rem", v.getOp1(), v.getOp2());
00515 coercedAbstraction = ConcreteIntegralAbstraction.v();
00516 } else if ((a instanceof RealAbstraction) && !(a instanceof ConcreteRealAbstraction)) {
00517 coercedAbstraction = a;
00518 doOp("rem", v.getOp1(), v.getOp2());
00519 coercedAbstraction = ConcreteIntegralAbstraction.v();
00520 } else {
00521 currentValue = v;
00522 }
00523 }
00524 public void caseRetStmt(RetStmt stmt) {
00525 defaultCase(stmt);
00526 }
00527 public void caseReturnStmt(ReturnStmt stmt) {
00528 Abstraction a = typeTable.get(stmt.getReturnValue());
00529 if (((a instanceof IntegralAbstraction) && !(a instanceof ConcreteIntegralAbstraction))
00530 || ((a instanceof RealAbstraction) && !(a instanceof ConcreteRealAbstraction))) {
00531 methodBody.getMethod().setReturnType(IntType.v());
00532 }
00533 }
00534 public void caseReturnVoidStmt(ReturnVoidStmt stmt) {
00535 defaultCase(stmt);
00536 }
00537 public void caseShlExpr(ShlExpr v) {
00538 Abstraction a = (Abstraction) typeTable.get(v);
00539 if ((a instanceof IntegralAbstraction) && !(a instanceof ConcreteIntegralAbstraction)) {
00540 coercedAbstraction = a;
00541 doOp("shl", v.getOp1(), v.getOp2());
00542 coercedAbstraction = ConcreteIntegralAbstraction.v();
00543 } else if ((a instanceof RealAbstraction) && !(a instanceof ConcreteRealAbstraction)) {
00544 coercedAbstraction = a;
00545 doOp("shl", v.getOp1(), v.getOp2());
00546 coercedAbstraction = ConcreteIntegralAbstraction.v();
00547 } else {
00548 currentValue = v;
00549 }
00550 }
00551 public void caseShrExpr(ShrExpr v) {
00552 Abstraction a = (Abstraction) typeTable.get(v);
00553 if ((a instanceof IntegralAbstraction) && !(a instanceof ConcreteIntegralAbstraction)) {
00554 coercedAbstraction = a;
00555 doOp("shr", v.getOp1(), v.getOp2());
00556 coercedAbstraction = ConcreteIntegralAbstraction.v();
00557 } else if ((a instanceof RealAbstraction) && !(a instanceof ConcreteRealAbstraction)) {
00558 coercedAbstraction = a;
00559 doOp("shr", v.getOp1(), v.getOp2());
00560 coercedAbstraction = ConcreteIntegralAbstraction.v();
00561 } else {
00562 currentValue = v;
00563 }
00564 }
00565 public void caseSpecialInvokeExpr(SpecialInvokeExpr v) {
00566 doInvokeExpr(v);
00567 }
00568 public void caseStaticFieldRef(StaticFieldRef v) {
00569 coerce(v);
00570 }
00571 public void caseStaticInvokeExpr(StaticInvokeExpr v) {
00572 doInvokeExpr(v);
00573 }
00574 public void caseStringConstant(StringConstant v) {
00575 defaultCase(v);
00576 }
00577 public void caseSubExpr(SubExpr v) {
00578 Abstraction a = (Abstraction) typeTable.get(v);
00579 if ((a instanceof IntegralAbstraction) && !(a instanceof ConcreteIntegralAbstraction)) {
00580 coercedAbstraction = a;
00581 doOp("sub", v.getOp1(), v.getOp2());
00582 coercedAbstraction = ConcreteIntegralAbstraction.v();
00583 } else if ((a instanceof RealAbstraction) && !(a instanceof ConcreteRealAbstraction)) {
00584 coercedAbstraction = a;
00585 doOp("sub", v.getOp1(), v.getOp2());
00586 coercedAbstraction = ConcreteIntegralAbstraction.v();
00587 } else {
00588 currentValue = v;
00589 }
00590 }
00591 public void caseTableSwitchStmt(TableSwitchStmt stmt) {
00592 defaultCase(stmt);
00593 }
00594 public void caseThisRef(ThisRef v) {
00595 defaultCase(v);
00596 }
00597 public void caseThrowStmt(ThrowStmt stmt) {
00598 defaultCase(stmt);
00599 }
00600 public void caseUshrExpr(UshrExpr v) {
00601 Abstraction a = (Abstraction) typeTable.get(v);
00602 if ((a instanceof IntegralAbstraction) && !(a instanceof ConcreteIntegralAbstraction)) {
00603 coercedAbstraction = a;
00604 doOp("ushr", v.getOp1(), v.getOp2());
00605 coercedAbstraction = ConcreteIntegralAbstraction.v();
00606 } else if ((a instanceof RealAbstraction) && !(a instanceof ConcreteRealAbstraction)) {
00607 coercedAbstraction = a;
00608 doOp("ushr", v.getOp1(), v.getOp2());
00609 coercedAbstraction = ConcreteIntegralAbstraction.v();
00610 } else {
00611 currentValue = v;
00612 }
00613 }
00614 public void caseVirtualInvokeExpr(VirtualInvokeExpr v) {
00615 doInvokeExpr(v);
00616 }
00617 public void caseXorExpr(XorExpr v) {
00618 Abstraction a = (Abstraction) typeTable.get(v);
00619 if ((a instanceof IntegralAbstraction) && !(a instanceof ConcreteIntegralAbstraction)) {
00620 coercedAbstraction = a;
00621 doOp("xor", v.getOp1(), v.getOp2());
00622 coercedAbstraction = ConcreteIntegralAbstraction.v();
00623 } else if ((a instanceof RealAbstraction) && !(a instanceof ConcreteRealAbstraction)) {
00624 coercedAbstraction = a;
00625 doOp("xor", v.getOp1(), v.getOp2());
00626 coercedAbstraction = ConcreteIntegralAbstraction.v();
00627 } else {
00628 currentValue = v;
00629 }
00630 }
00631
00632
00633
00634
00635
00636 private boolean coerce(Value v) {
00637 if ((coercedAbstraction instanceof ConcreteIntegralAbstraction) || (coercedAbstraction instanceof ConcreteRealAbstraction)){
00638 currentValue = v;
00639 return false;
00640 }
00641 if (typeTable.get(v) instanceof ConcreteIntegralAbstraction) {
00642 if (coercedAbstraction instanceof RealAbstraction) {
00643 if (v instanceof IntConstant) {
00644 currentValue = IntConstant.v(((Integer) AbstractionClassLoader.invokeMethod(coercedAbstraction.getClass().getName(), "abs", new Class[] {double.class}, null, new Object[] {new Double(((IntConstant) v).value)})).intValue());
00645 } else if (v instanceof LongConstant) {
00646 currentValue = IntConstant.v(((Integer) AbstractionClassLoader.invokeMethod(coercedAbstraction.getClass().getName(), "abs", new Class[] {double.class}, null, new Object[] {new Double(((LongConstant) v).value)})).intValue());
00647 } else {
00648 LinkedList params = new LinkedList();
00649 params.add(LongType.v());
00650 LinkedList args = new LinkedList();
00651 args.add(makeLocal(v, LongType.v()));
00652 currentValue = jimple.newStaticInvokeExpr(scm.getClass(coercedAbstraction.getClass().getName()).getMethod("abs", params), args);
00653 }
00654 } else {
00655 if (v instanceof IntConstant) {
00656 currentValue = IntConstant.v(((Integer) AbstractionClassLoader.invokeMethod(coercedAbstraction.getClass().getName(), "abs", new Class[] {long.class}, null, new Object[] {new Long(((IntConstant) v).value)})).intValue());
00657 } else if (v instanceof LongConstant) {
00658 currentValue = IntConstant.v(((Integer) AbstractionClassLoader.invokeMethod(coercedAbstraction.getClass().getName(), "abs", new Class[] {long.class}, null, new Object[] {new Long(((LongConstant) v).value)})).intValue());
00659 } else {
00660 LinkedList params = new LinkedList();
00661 params.add(LongType.v());
00662 LinkedList args = new LinkedList();
00663 args.add(makeLocal(v, LongType.v()));
00664 currentValue = jimple.newStaticInvokeExpr(scm.getClass(coercedAbstraction.getClass().getName()).getMethod("abs", params), args);
00665 }
00666 }
00667 typeTable.put(currentValue, coercedAbstraction);
00668 return true;
00669 } else if (typeTable.get(v) instanceof ConcreteRealAbstraction) {
00670 if (v instanceof FloatConstant) {
00671 currentValue = IntConstant.v(((Integer) AbstractionClassLoader.invokeMethod(coercedAbstraction.getClass().getName(), "abs", new Class[] {double.class}, null, new Object[] {new Double(((FloatConstant) v).value)})).intValue());
00672 } else if (v instanceof DoubleConstant) {
00673 currentValue = IntConstant.v(((Integer) AbstractionClassLoader.invokeMethod(coercedAbstraction.getClass().getName(), "abs", new Class[] {double.class}, null, new Object[] {new Double(((DoubleConstant) v).value)})).intValue());
00674 } else {
00675 LinkedList params = new LinkedList();
00676 params.add(DoubleType.v());
00677 LinkedList args = new LinkedList();
00678 args.add(makeLocal(v, DoubleType.v()));
00679 currentValue = jimple.newStaticInvokeExpr(scm.getClass(coercedAbstraction.getClass().getName()).getMethod("abs", params), args);
00680 }
00681 typeTable.put(currentValue, coercedAbstraction);
00682 return true;
00683 } else {
00684 currentValue = v;
00685 return false;
00686 }
00687 }
00688
00689
00690
00691
00692 public void defaultCase(Object v) {
00693 if (v instanceof Value) {
00694 currentValue = (Value) v;
00695 }
00696 }
00697
00698
00699
00700
00701 private void doInvokeExpr(InvokeExpr v) {
00702 SootMethod sm = v.getMethod();
00703 if (sm.isBodyStored(jimple)) {
00704 Value[] parameterLocals = getParameterLocals(sm);
00705 for (int i = 0; i < v.getArgCount(); i++) {
00706 coercedAbstraction = typeTable.get(parameterLocals[i]);
00707 v.getArg(i).apply(this);
00708 v.setArg(i, makeLocal(currentValue, currentValue.getType()));
00709 }
00710 }
00711 currentValue = v;
00712 }
00713
00714
00715
00716
00717
00718 private void doOp(String methodName, Value op1, Value op2) {
00719 Abstraction coercedAbstraction = this.coercedAbstraction;
00720 Object op1Type = typeTable.get(op1);
00721 if ((op1Type instanceof ConcreteIntegralAbstraction) || (op1Type instanceof ConcreteRealAbstraction)) {
00722 if (coerce(op1)) op1 = makeLocal(currentValue, IntType.v());
00723 }
00724 Object op2Type = typeTable.get(op2);
00725 if ((op2Type instanceof ConcreteIntegralAbstraction) || (op2Type instanceof ConcreteRealAbstraction)) {
00726 if (coerce(op2)) op2 = makeLocal(currentValue, IntType.v());
00727 }
00728 LinkedList params = new LinkedList();
00729 params.add(IntType.v());
00730 params.add(IntType.v());
00731 LinkedList args = new LinkedList();
00732 args.add(op1);
00733 args.add(op2);
00734 currentValue = jimple.newStaticInvokeExpr(scm.getClass(coercedAbstraction.getClass().getName()).getMethod(methodName, params), args);
00735 typeTable.put(currentValue, coercedAbstraction);
00736 }
00737
00738
00739
00740
00741
00742 private Value[] getParameterLocals(SootMethod sm) {
00743 Value[] result = new Value[sm.getParameterCount()];
00744 int k = 0;
00745 for (Iterator i = ((JimpleBody) sm.getBody(jimple)).getStmtList().iterator(); i.hasNext();) {
00746 Stmt s = (Stmt) i.next();
00747 if (s instanceof IdentityStmt) {
00748 IdentityStmt is = (IdentityStmt) s;
00749 if (is.getRightOp() instanceof ParameterRef) {
00750 result[k++] = is.getLeftOp();
00751 }
00752 } else break;
00753 }
00754 return result;
00755 }
00756
00757
00758
00759
00760
00761
00762 private Value makeLocal(Value v, Type t) {
00763 if (v == null)
00764 return v;
00765 if ((v instanceof Local) || (v instanceof Constant))
00766 return v;
00767 Local lcl = jimple.newLocal(prefix + tempCounter++, t);
00768 typeTable.put(lcl, typeTable.get(v));
00769 Stmt newStmt = jimple.newAssignStmt(lcl, v);
00770 methodBody.addLocal(lcl);
00771 int index = methodStmtList.indexOf(currentStmt);
00772 methodStmtList.add(index, newStmt);
00773 methodBody.redirectJumps(currentStmt, newStmt);
00774 try {
00775 am.getContainingAnnotation(methodBody.getMethod().getDeclaringClass(), methodBody.getMethod(), currentStmt).insertStmtBefore(newStmt, currentStmt);
00776 } catch (Exception e) {
00777 System.out.println("Cannot get annotation for statement: " + currentStmt);
00778 }
00779 return lcl;
00780 }
00781 }