00001 package edu.ksu.cis.bandera.jjjc.codegenerator;
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 edu.ksu.cis.bandera.jjjc.decompiler.*;
00036 import edu.ksu.cis.bandera.jext.*;
00037 import edu.ksu.cis.bandera.specification.datastructure.*;
00038 import java.util.*;
00039 import java.math.*;
00040 import edu.ksu.cis.bandera.annotation.*;
00041 import edu.ksu.cis.bandera.jjjc.analysis.*;
00042 import edu.ksu.cis.bandera.jjjc.node.*;
00043 import edu.ksu.cis.bandera.jjjc.optimizer.*;
00044 import edu.ksu.cis.bandera.jjjc.symboltable.*;
00045 import edu.ksu.cis.bandera.jjjc.symboltable.Package;
00046 import edu.ksu.cis.bandera.jjjc.exception.*;
00047 import edu.ksu.cis.bandera.jjjc.util.*;
00048 import edu.ksu.cis.bandera.jjjc.*;
00049 import edu.ksu.cis.bandera.jjjc.doc.*;
00050 import ca.mcgill.sable.util.*;
00051 import ca.mcgill.sable.soot.*;
00052 import ca.mcgill.sable.soot.jimple.*;
00053 import ca.mcgill.sable.util.List;
00054 import ca.mcgill.sable.util.LinkedList;
00055 import ca.mcgill.sable.util.Iterator;
00056 import edu.ksu.cis.bandera.specification.assertion.*;
00057 import edu.ksu.cis.bandera.specification.predicate.*;
00058
00059 public class JIJCCodeGenerator extends DepthFirstAdapter {
00060 private SootClassManager scm = null;
00061 private AnnotationManager am = null;
00062 private Hashtable docComments = null;
00063 private Vector exceptions = new Vector();
00064 private SymbolTable symbolTable = null;
00065 private Jimple jimple = Jimple.v();
00066 private SootClass currentSootClass = null;
00067 private SootMethod currentSootMethod = null;
00068 private ClassOrInterfaceType currentClassOrInterfaceType = null;
00069 private Vector compiledClasses = new Vector();
00070 private edu.ksu.cis.bandera.jjjc.symboltable.Type integralConstantType = null;
00071 private boolean assignExp = false;
00072 private boolean isInterface = false;
00073
00074
00075 private Vector synchAnnotations = new Vector();
00076 private BlockStmtAnnotation currentAnnotation = null;
00077 private LocalDeclarationStmtAnnotation localAnnotation = null;
00078 private Node fieldNode = null;
00079
00080
00081 public Stmt trueBranch = null;
00082 public Stmt falseBranch = null;
00083
00084
00085 private NameGenerator nameGen = null;
00086 private NameGenerator qtNameGen = null;
00087 private Hashtable currentLocals = null;
00088 private Hashtable currentLocalNames = null;
00089 private Hashtable currentLocalNamesIterator = null;
00090 private Vector currentStmts = null;
00091 private Value currentValue = null;
00092 private ca.mcgill.sable.soot.Type currentType = null;
00093 private Local currentThisLocal = null;
00094 private JimpleBody currentBody = null;
00095 private String currentName = null;
00096 private Vector currentTraps = null;
00097
00098
00099 private Hashtable staticLocals = null;
00100 private Vector staticStmts = null;
00101 private Hashtable instanceLocals = null;
00102 private Vector instanceStmts = null;
00103 private SootMethod clinit = null;
00104 private JimpleBody clinitBody = null;
00105 private SootMethod init = null;
00106 private JimpleBody initBody = null;
00107 private int staticInitializers = 0;
00108 private int instanceInitializers = 0;
00109
00110
00111 private LinkedList currentLookupValues = null;
00112 private LinkedList currentTargets = null;
00113 private Stmt currentDefaultStmt = null;
00114 private boolean defaultSwitch = false;
00115
00116
00117 private TryStmtAnnotation currentTryAnnotation = null;
00118 private Stmt beginTrapStmt = null;
00119 private Stmt endTrapStmt = null;
00120 private Stmt endTryStmt = null;
00121 private boolean catchHasEnd;
00122
00123
00124 private LinkedList labels = null;
00125 private Hashtable currentLabels = null;
00126 private Stmt currentBreakTarget = null;
00127 private Stmt currentContinueTarget = null;
00128
00129
00130 private Hashtable forLocals = null;
00131 private ca.mcgill.sable.soot.Type forInitType = null;
00132 private int forInitModifiers = 0;
00133
00134
00135 private Vector finallyAndSynch = new Vector();
00136 private Object lastFinallySynchBeforeControl = null;
00137
00138 private ca.mcgill.sable.soot.SootMethod assertMethod;
00139 private ca.mcgill.sable.soot.SootMethod chooseMethod;
00140
00141 private int methodLine;
00142
00143
00144
00145
00146
00147
00148 public JIJCCodeGenerator(SymbolTable symbolTable, SootClassManager sootClassManager,
00149 AnnotationManager annotationManager, Hashtable docComments) {
00150 this.symbolTable = symbolTable;
00151 this.scm = sootClassManager;
00152 this.am = annotationManager;
00153 this.docComments = docComments;
00154
00155 symbolTable.setCurrentPackage(null);
00156 symbolTable.setCurrentClassOrInterfaceType(null);
00157 while (symbolTable.getNumScopeLevels() > 0) {
00158 symbolTable.exitScope();
00159 }
00160 if (!scm.managesClass("Bandera")) {
00161 SootClass sc = new SootClass("Bandera", Modifier.PUBLIC);
00162
00163 LinkedList parms = new LinkedList();
00164 chooseMethod = new SootMethod("choose", parms, ca.mcgill.sable.soot.BooleanType.v(),
00165 Modifier.PUBLIC | Modifier.STATIC);
00166
00167 sc.addMethod(chooseMethod);
00168
00169 parms = new LinkedList();
00170 parms.addLast(ca.mcgill.sable.soot.BooleanType.v());
00171 assertMethod = new SootMethod("assert", parms, ca.mcgill.sable.soot.VoidType.v(),
00172 Modifier.PUBLIC | Modifier.STATIC);
00173
00174 sc.addMethod(assertMethod);
00175
00176 scm.addClass(sc);
00177 } else {
00178 SootClass sc = scm.getClass("Bandera");
00179 chooseMethod = sc.getMethod("choose");
00180 assertMethod = sc.getMethod("assert");
00181 }
00182 }
00183
00184
00185
00186
00187
00188 private void addRetIfNecessary(JimpleBody body, ca.mcgill.sable.soot.Type retType) {
00189 if (body.declaresLocal("$ret")) return;
00190
00191 Local ret = jimple.newLocal("$ret", retType);
00192 body.addLocal(ret);
00193
00194 Object[] stmts = body.getStmtList().toArray();
00195 for (int i = 0; i < stmts.length; i++) {
00196 if (stmts[i] instanceof ReturnStmt) {
00197 ReturnStmt rs = (ReturnStmt) stmts[i];
00198 Local lcl = (Local) rs.getReturnValue();
00199 for (int j = i - 1; j >= 0; j--) {
00200 if (stmts[j] instanceof AssignStmt) {
00201 AssignStmt as = (AssignStmt) stmts[j];
00202 if (as.getLeftOp() == lcl) {
00203 as.setLeftOp(ret);
00204 break;
00205 }
00206 }
00207 }
00208 rs.setReturnValue(ret);
00209 }
00210 }
00211 return;
00212 }
00213
00214
00215
00216
00217 public void caseAAbstractMethodDeclarationInterfaceMemberDeclaration(AAbstractMethodDeclarationInterfaceMemberDeclaration node) {
00218 currentSootMethod = null;
00219 currentAnnotation = new MethodDeclarationAnnotation(node);
00220 LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
00221 currentAnnotation.setFirstLine(lc.getFirstLine());
00222 currentAnnotation.setFirstColumn(lc.getFirstColumn());
00223 currentAnnotation.setLastLine(lc.getLastLine());
00224 currentAnnotation.setLastColumn(lc.getLastColumn());
00225
00226 isInterface = true;
00227 node.getMethodHeader().apply(this);
00228 isInterface = false;
00229
00230 am.addAnnotation(currentSootClass, currentSootMethod, currentAnnotation);
00231 currentAnnotation = null;
00232 }
00233
00234
00235
00236
00237 public void caseAArrayInitializer(AArrayInitializer node) {
00238 Object temp[] = node.getVariableInitializer().toArray();
00239
00240 Value leftValue = currentValue;
00241
00242 if (!(leftValue instanceof Local)) {
00243 Local lcl = declareLocal(nameGen.newName(), leftValue.getType(), 0);
00244 currentStmts.addElement(jimple.newAssignStmt(lcl, leftValue));
00245 leftValue = lcl;
00246 }
00247
00248 ca.mcgill.sable.soot.ArrayType type = (ca.mcgill.sable.soot.ArrayType) leftValue.getType();
00249 Value v = jimple.newNewArrayExpr(ca.mcgill.sable.soot.ArrayType.v(type.baseType, type.numDimensions - 1),
00250 IntConstant.v(temp.length));
00251
00252 currentStmts.addElement(jimple.newAssignStmt(leftValue, v));
00253
00254 for (int i = 0; i < temp.length; i++) {
00255 if (temp[i] instanceof AArrayVariableInitializer) {
00256 currentValue = declareLocal(nameGen.newName(), ca.mcgill.sable.soot.ArrayType.v(type.baseType, type.numDimensions - 1), 0);
00257 }
00258 ((PVariableInitializer) temp[i]).apply(this);
00259 currentStmts.addElement(jimple.newAssignStmt(jimple.newArrayRef(leftValue, IntConstant.v(i)), currentValue));
00260 }
00261 currentValue = leftValue;
00262 }
00263
00264
00265
00266
00267 public void caseAAssignedVariableDeclarator(AAssignedVariableDeclarator node) {
00268 node.getVariableDeclaratorId().apply(this);
00269 if (currentType instanceof ca.mcgill.sable.soot.BooleanType) {
00270 if (symbolTable.getNumScopeLevels() > 0) {
00271 Local lcl = declareLocal(currentName, currentType, 0);
00272 if (currentAnnotation == null) {
00273 forLocals.put(currentName, lcl);
00274 } else {
00275 localAnnotation.addDeclaredLocal(currentName, lcl);
00276 }
00277 currentValue = lcl;
00278 Stmt endStmt = jimple.newNopStmt();
00279 Stmt prevTrueBranch = trueBranch;
00280 Stmt prevFalseBranch = falseBranch;
00281 trueBranch = jimple.newAssignStmt(lcl, IntConstant.v(1));
00282 falseBranch = jimple.newAssignStmt(lcl, IntConstant.v(0));
00283 Node n = (Node) node.getVariableInitializer().clone();
00284 PushComplement.push(n);
00285 n.apply(new BooleanExpression(this, trueBranch, falseBranch));
00286 currentStmts.addElement(falseBranch);
00287 currentStmts.addElement(jimple.newGotoStmt(endStmt));
00288 currentStmts.addElement(trueBranch);
00289 currentStmts.addElement(endStmt);
00290 trueBranch = prevTrueBranch;
00291 falseBranch = prevFalseBranch;
00292 } else {
00293 int start = currentStmts.size();
00294 String fieldName = currentName;
00295 nameFieldOrLocalExp(true, currentName);
00296 Value field = currentValue;
00297 Stmt endStmt = jimple.newNopStmt();
00298 Stmt prevTrueBranch = trueBranch;
00299 Stmt prevFalseBranch = falseBranch;
00300 trueBranch = jimple.newAssignStmt(field, IntConstant.v(1));
00301 falseBranch = jimple.newAssignStmt(field, IntConstant.v(0));
00302 Node n = (Node) node.getVariableInitializer().clone();
00303 PushComplement.push(n);
00304 n.apply(new BooleanExpression(this, trueBranch, falseBranch));
00305 currentStmts.addElement(falseBranch);
00306 currentStmts.addElement(jimple.newGotoStmt(endStmt));
00307 currentStmts.addElement(trueBranch);
00308 currentStmts.addElement(endStmt);
00309 trueBranch = prevTrueBranch;
00310 falseBranch = prevFalseBranch;
00311
00312 int end = currentStmts.size();
00313 FieldDeclarationAnnotation ann = new FieldDeclarationAnnotation(fieldNode);
00314 LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
00315 ann.setFirstLine(lc.getFirstLine());
00316 ann.setFirstColumn(lc.getFirstColumn());
00317 ann.setLastLine(lc.getLastLine());
00318 ann.setLastColumn(lc.getLastColumn());
00319
00320 for (int i = start; i < end; i++) {
00321 ann.addStmt((Stmt) currentStmts.elementAt(i));
00322 }
00323
00324 try {
00325 SootField sf = getSootField(currentSootClass.getName(), fieldName);
00326 am.addAnnotation(currentSootClass, sf, ann);
00327 ann.setSootField(sf);
00328 ann.setField(currentClassOrInterfaceType.getField(new Name(fieldName)));
00329 am.putFilenameLinePairAnnotation(
00330 new FilenameLinePair(currentClassOrInterfaceType.getPath(),
00331 LineExtractor.extractLine(node.getVariableDeclaratorId())),
00332 ann);
00333 } catch (CompilerException e) {}
00334 }
00335 } else {
00336 if (symbolTable.getNumScopeLevels() > 0) {
00337 Local lcl = declareLocal(currentName, currentType, 0);
00338 if (currentAnnotation == null) {
00339 forLocals.put(currentName, lcl);
00340 } else {
00341 localAnnotation.addDeclaredLocal(currentName, lcl);
00342 }
00343 currentValue = lcl;
00344 node.getVariableInitializer().apply(this);
00345 currentStmts.addElement(jimple.newAssignStmt(lcl, currentValue));
00346 } else {
00347 int start = currentStmts.size();
00348
00349 String fieldName = currentName;
00350
00351 nameFieldOrLocalExp(true, currentName);
00352 Value field = currentValue;
00353 node.getVariableInitializer().apply(this);
00354 currentStmts.addElement(jimple.newAssignStmt(field, currentValue));
00355
00356 int end = currentStmts.size();
00357 FieldDeclarationAnnotation ann = new FieldDeclarationAnnotation(fieldNode);
00358
00359 for (int i = start; i < end; i++) {
00360 ann.addStmt((Stmt) currentStmts.elementAt(i));
00361 }
00362
00363 try {
00364 SootField sf = getSootField(currentSootClass.getName(), fieldName);
00365 am.addAnnotation(currentSootClass, sf, ann);
00366 ann.setSootField(sf);
00367 ann.setField(currentClassOrInterfaceType.getField(new Name(fieldName)));
00368 am.putFilenameLinePairAnnotation(
00369 new FilenameLinePair(currentClassOrInterfaceType.getPath(),
00370 LineExtractor.extractLine(node.getVariableDeclaratorId())),
00371 ann);
00372 } catch (CompilerException e) {}
00373 }
00374 }
00375 }
00376
00377
00378
00379
00380 public void caseAAssignmentExp(AAssignmentExp node) {
00381 String operator = node.getAssignmentOperator().toString().trim();
00382 node.getLeftHandSide().apply(this);
00383 Value firstValue = currentValue;
00384
00385 if ((firstValue instanceof ca.mcgill.sable.soot.BooleanType) && "=".equals(operator)) {
00386 Stmt endStmt = jimple.newNopStmt();
00387 Stmt prevTrueBranch = trueBranch;
00388 Stmt prevFalseBranch = falseBranch;
00389 trueBranch = jimple.newAssignStmt(firstValue, IntConstant.v(1));
00390 falseBranch = jimple.newAssignStmt(firstValue, IntConstant.v(0));
00391 Node n = (Node) node.getExp().clone();
00392 PushComplement.push(n);
00393 if (node.getExp() instanceof AUnaryExp)
00394 if ("!".equals(((AUnaryExp) node.getExp()).getUnaryOperator().toString().trim()))
00395 n = ((AUnaryExp) n).getExp();
00396 n.apply(new BooleanExpression(this, trueBranch, falseBranch));
00397 currentStmts.addElement(falseBranch);
00398 currentStmts.addElement(jimple.newGotoStmt(endStmt));
00399 currentStmts.addElement(trueBranch);
00400 currentStmts.addElement(endStmt);
00401 currentValue = firstValue;
00402 trueBranch = prevTrueBranch;
00403 falseBranch = prevFalseBranch;
00404 if (!(currentValue instanceof Local) || !(currentValue instanceof Constant)) {
00405 Local lcl = declareLocal(nameGen.newName(), currentValue.getType(), 0);
00406 currentStmts.addElement(jimple.newAssignStmt(lcl, currentValue));
00407 currentValue = lcl;
00408 }
00409 return;
00410 }
00411
00412 node.getExp().apply(this);
00413 Value secondValue = currentValue;
00414 currentValue = null;
00415 if ("=".equals(operator)) {
00416 currentStmts.addElement(jimple.newAssignStmt(firstValue, secondValue));
00417 currentValue = firstValue;
00418 if (!(currentValue instanceof Local) || !(currentValue instanceof Constant)) {
00419 Local lcl = declareLocal(nameGen.newName(), currentValue.getType(), 0);
00420 currentStmts.addElement(jimple.newAssignStmt(lcl, currentValue));
00421 currentValue = lcl;
00422 }
00423 } else {
00424 operator = operator.substring(0, operator.length() - 1);
00425 Value resultValue = firstValue;
00426 if (!(firstValue instanceof Local)) {
00427 Local lcl = declareLocal(nameGen.newName(), firstValue.getType(), 0);
00428 currentStmts.addElement(jimple.newAssignStmt(lcl, firstValue));
00429 firstValue = lcl;
00430 }
00431 try {
00432 numericOperation(operator, firstValue, secondValue);
00433 if (currentValue == null) {
00434 exceptions.addElement(new CompilerException("Cannot resolve " + node.getLeftHandSide().toString()));
00435 return;
00436 }
00437 currentStmts.addElement(jimple.newAssignStmt(resultValue, currentValue));
00438 currentValue = resultValue;
00439 if (!(currentValue instanceof Local) || !(currentValue instanceof Constant)) {
00440 Local lcl = declareLocal(nameGen.newName(), currentValue.getType(), 0);
00441 currentStmts.addElement(jimple.newAssignStmt(lcl, currentValue));
00442 currentValue = lcl;
00443 }
00444 } catch (CompilerException e) {
00445 exceptions.addElement(e);
00446 }
00447 }
00448 }
00449
00450
00451
00452
00453 public void caseABinaryExp(ABinaryExp node) {
00454 node = (ABinaryExp) node.clone();
00455 TrivialExpression.optimize(node);
00456
00457 PBinaryOperator op = node.getBinaryOperator();
00458 Stmt prevTrueBranch = trueBranch;
00459 Stmt prevFalseBranch = falseBranch;
00460
00461 if ((op instanceof AOrBinaryOperator) || (op instanceof AAndBinaryOperator)) {
00462 Local lcl = null;
00463 if (trueBranch == null) {
00464 lcl = declareLocal(nameGen.newName(), ca.mcgill.sable.soot.BooleanType.v(), 0);
00465 trueBranch = jimple.newAssignStmt(lcl, IntConstant.v(1));
00466 falseBranch = jimple.newAssignStmt(lcl, IntConstant.v(0));
00467 }
00468
00469 Node n = (Node) node.clone();
00470 PushComplement.push(n);
00471 n.apply(new BooleanExpression(this, trueBranch, falseBranch));
00472
00473 if (lcl != null) {
00474 Stmt endStmt = jimple.newNopStmt();
00475 currentStmts.addElement(falseBranch);
00476 currentStmts.addElement(jimple.newGotoStmt(endStmt));
00477 currentStmts.addElement(trueBranch);
00478 currentStmts.addElement(endStmt);
00479 trueBranch = prevTrueBranch;
00480 falseBranch = prevFalseBranch;
00481 currentValue = lcl;
00482 }
00483 return;
00484 }
00485
00486 node.getFirst().apply(this);
00487 Value firstValue = currentValue;
00488 if (!(firstValue instanceof Local) && !(firstValue instanceof Constant)) {
00489 Local lcl = declareLocal(nameGen.newName(), firstValue.getType(), 0);
00490 currentStmts.addElement(jimple.newAssignStmt(lcl, firstValue));
00491 firstValue = lcl;
00492 }
00493 node.getSecond().apply(this);
00494 Value secondValue = currentValue;
00495 currentValue = null;
00496 if (!(secondValue instanceof Local) && !(secondValue instanceof Constant)) {
00497 Local lcl = declareLocal(nameGen.newName(), secondValue.getType(), 0);
00498 currentStmts.addElement(jimple.newAssignStmt(lcl, secondValue));
00499 secondValue = lcl;
00500 }
00501
00502 if (op instanceof AGtBinaryOperator || op instanceof ALtBinaryOperator || op instanceof ALteqBinaryOperator || op instanceof AGteqBinaryOperator || op instanceof AEqBinaryOperator || op instanceof ANeqBinaryOperator) {
00503
00504 Local lcl = null;
00505 if (trueBranch == null) {
00506 lcl = declareLocal(nameGen.newName(), ca.mcgill.sable.soot.BooleanType.v(), 0);
00507 trueBranch = jimple.newAssignStmt(lcl, IntConstant.v(1));
00508 falseBranch = jimple.newAssignStmt(lcl, IntConstant.v(0));
00509 }
00510
00511 if ((firstValue.getType() instanceof ca.mcgill.sable.soot.DoubleType)
00512 || (secondValue.getType() instanceof ca.mcgill.sable.soot.DoubleType)
00513 || (firstValue.getType() instanceof ca.mcgill.sable.soot.FloatType)
00514 || (secondValue.getType() instanceof ca.mcgill.sable.soot.FloatType)) {
00515 if (op instanceof AGtBinaryOperator) {
00516 currentValue = jimple.newCmpgExpr(firstValue, secondValue);
00517 } else if (op instanceof ALtBinaryOperator) {
00518 currentValue = jimple.newCmplExpr(firstValue, secondValue);
00519 } else if (op instanceof ALteqBinaryOperator) {
00520 currentValue = jimple.newCmplExpr(firstValue, secondValue);
00521 } else if (op instanceof AGteqBinaryOperator) {
00522 currentValue = jimple.newCmpgExpr(firstValue, secondValue);
00523 } else if (op instanceof AEqBinaryOperator) {
00524 currentValue = jimple.newCmplExpr(firstValue, secondValue);
00525 } else if (op instanceof ANeqBinaryOperator) {
00526 currentValue = jimple.newCmplExpr(firstValue, secondValue);
00527 }
00528 Local local = declareLocal(nameGen.newName(), ca.mcgill.sable.soot.IntType.v(), 0);
00529 currentStmts.addElement(jimple.newAssignStmt(local, currentValue));
00530 firstValue = local;
00531 secondValue = IntConstant.v(0);
00532 }
00533
00534 if (op instanceof AGtBinaryOperator) {
00535 currentValue = jimple.newGtExpr(firstValue, secondValue);
00536 } else if (op instanceof ALtBinaryOperator) {
00537 currentValue = jimple.newLtExpr(firstValue, secondValue);
00538 } else if (op instanceof ALteqBinaryOperator) {
00539 currentValue = jimple.newLeExpr(firstValue, secondValue);
00540 } else if (op instanceof AGteqBinaryOperator) {
00541 currentValue = jimple.newGeExpr(firstValue, secondValue);
00542 } else if (op instanceof AEqBinaryOperator) {
00543 currentValue = jimple.newEqExpr(firstValue, secondValue);
00544 } else if (op instanceof ANeqBinaryOperator) {
00545 currentValue = jimple.newNeExpr(firstValue, secondValue);
00546 }
00547
00548 currentStmts.addElement(jimple.newIfStmt(currentValue, trueBranch));
00549
00550 if (lcl != null) {
00551 Stmt endStmt = jimple.newNopStmt();
00552 currentStmts.addElement(falseBranch);
00553 currentStmts.addElement(jimple.newGotoStmt(endStmt));
00554 currentStmts.addElement(trueBranch);
00555 currentStmts.addElement(endStmt);
00556 trueBranch = prevTrueBranch;
00557 falseBranch = prevFalseBranch;
00558 currentValue = lcl;
00559 }
00560 } else if (op instanceof APlusBinaryOperator || op instanceof AMinusBinaryOperator || op instanceof AModBinaryOperator || op instanceof ADivBinaryOperator || op instanceof AStarBinaryOperator || op instanceof ABitXorBinaryOperator || op instanceof ABitAndBinaryOperator || op instanceof AShiftLeftBinaryOperator || op instanceof ASignedShiftRightBinaryOperator || op instanceof AUnsignedShiftRightBinaryOperator || op instanceof ABitOrBinaryOperator) {
00561
00562 try {
00563 numericOperation(op.toString().trim(), firstValue, secondValue);
00564 } catch (CompilerException e) {
00565 exceptions.addElement(e);
00566 }
00567 } else {
00568 exceptions.addElement(new CompilerException("Unknown binary operator " + op));
00569 currentValue = null;
00570 }
00571 }
00572
00573
00574
00575
00576 public void caseABlock(ABlock node) {
00577 if (!(node.parent() instanceof ABlockMethodBody)) {
00578 symbolTable.enterScope();
00579 }
00580 labelEnterBlock();
00581 for (Iterator i = node.getBlockedStmt().iterator(); i.hasNext();) {
00582 ((PBlockedStmt) i.next()).apply(this);
00583 }
00584 labelExitBlock();
00585 if (!(node.parent() instanceof ABlockMethodBody)) {
00586 symbolTable.exitScope();
00587 }
00588 }
00589
00590
00591
00592
00593 public void caseABlockClassBodyDeclaration(ABlockClassBodyDeclaration node) {
00594 if (init == null) {
00595 try {
00596 init = getSootMethod(currentSootClass.getName(), "<init>", new Vector());
00597 init.setReturnType(ca.mcgill.sable.soot.VoidType.v());
00598 init.setModifiers(Modifier.PUBLIC);
00599 initBody = (JimpleBody) jimple.newBody(init);
00600 } catch (CompilerException e) {
00601 exceptions.addElement(e);
00602 return;
00603 }
00604 }
00605 currentSootMethod = init;
00606 currentBody = initBody;
00607 currentLocalNames = new Hashtable();
00608 currentLocalNamesIterator = new Hashtable();
00609 currentLocals = instanceLocals;
00610 currentStmts = instanceStmts;
00611 currentValue = null;
00612 currentType = null;
00613 currentName = null;
00614 labels = new LinkedList();
00615 currentAnnotation = new InstanceInitializerAnnotation(node);
00616 LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
00617 currentAnnotation.setFirstLine(lc.getFirstLine());
00618 currentAnnotation.setFirstColumn(lc.getFirstColumn());
00619 currentAnnotation.setLastLine(lc.getLastLine());
00620 currentAnnotation.setLastColumn(lc.getLastColumn());
00621 currentTraps = new Vector();
00622
00623 node.getBlock().apply(this);
00624
00625 for (Enumeration e = currentTraps.elements(); e.hasMoreElements();) {
00626 initBody.addTrap((JTrap) e.nextElement());
00627 }
00628
00629 currentLocals = null;
00630 currentLocalNames = null;
00631 currentLocalNamesIterator = null;
00632 currentStmts = null;
00633 currentValue = null;
00634 currentType = null;
00635 currentName = null;
00636 currentBody = null;
00637 labels = null;
00638 currentTraps = null;
00639 currentSootMethod = null;
00640
00641 am.addAnnotation(currentSootClass, "instance initializer " + instanceInitializers++, currentAnnotation);
00642 currentAnnotation = null;
00643 }
00644
00645
00646
00647
00648 public void caseABlockMethodBody(ABlockMethodBody node) {
00649 node.getBlock().apply(this);
00650 }
00651
00652
00653
00654
00655 public void caseABlockStmt(ABlockStmt node) {
00656 if(node.getBlock() != null) {
00657 BlockStmtAnnotation prevAnnotation = currentAnnotation;
00658 currentAnnotation = new BlockStmtAnnotation(node);
00659 LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
00660 currentAnnotation.setFirstLine(lc.getFirstLine());
00661 currentAnnotation.setFirstColumn(lc.getFirstColumn());
00662 currentAnnotation.setLastLine(lc.getLastLine());
00663 currentAnnotation.setLastColumn(lc.getLastColumn());
00664 am.putFilenameLinePairAnnotation(
00665 new FilenameLinePair(currentClassOrInterfaceType.getPath(),
00666 LineExtractor.extractLine(node)),
00667 currentAnnotation);
00668 node.getBlock().apply(this);
00669 if (prevAnnotation != null) {
00670 prevAnnotation.addAnnotation(currentAnnotation);
00671 currentAnnotation = prevAnnotation;
00672 }
00673 }
00674 }
00675
00676
00677
00678
00679 public void caseABooleanPrimitiveType(ABooleanPrimitiveType node) {
00680 currentType = ca.mcgill.sable.soot.BooleanType.v();
00681 }
00682
00683
00684
00685
00686 public void caseABreakStmt(ABreakStmt node) {
00687 int start = currentStmts.size();
00688
00689 if (node.getId() != null) {
00690 Unit target = getLabelUnit(node.getId().toString().trim());
00691 if (target == null) {
00692 exceptions.addElement(new CompilerException("Invalid break statement..."));
00693 return;
00694 }
00695 Object lastFinallySynchBeforeControl = ((Vector) getLabelObject(target)).firstElement();
00696 for (Enumeration e = synchAnnotations.elements(); e.hasMoreElements();) {
00697 Object o = e.nextElement();
00698 if (o == lastFinallySynchBeforeControl) break;
00699 if (o instanceof Node) {
00700 ((Node) o).apply(this);
00701 } else {
00702 SynchronizedStmtAnnotation sann = (SynchronizedStmtAnnotation) o;
00703 Stmt exitMon = jimple.newExitMonitorStmt(sann.getLockValue());
00704 sann.addExitMonitor(exitMon);
00705 currentStmts.addElement(exitMon);
00706 }
00707 }
00708 currentStmts.addElement(jimple.newGotoStmt(target));
00709 } else {
00710 if (currentBreakTarget == null) {
00711 exceptions.addElement(new CompilerException("Invalid break statement..."));
00712 return;
00713 }
00714 for (Enumeration e = synchAnnotations.elements(); e.hasMoreElements();) {
00715 Object o = e.nextElement();
00716 if (o == lastFinallySynchBeforeControl) break;
00717 if (o instanceof Node) {
00718 ((Node) o).apply(this);
00719 } else {
00720 SynchronizedStmtAnnotation sann = (SynchronizedStmtAnnotation) o;
00721 Stmt exitMon = jimple.newExitMonitorStmt(sann.getLockValue());
00722 sann.addExitMonitor(exitMon);
00723 currentStmts.addElement(exitMon);
00724 }
00725 }
00726 currentStmts.addElement(jimple.newGotoStmt(currentBreakTarget));
00727 }
00728
00729 int end = currentStmts.size();
00730 BreakStmtAnnotation ann = new BreakStmtAnnotation(node);
00731 LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
00732 ann.setFirstLine(lc.getFirstLine());
00733 ann.setFirstColumn(lc.getFirstColumn());
00734 ann.setLastLine(lc.getLastLine());
00735 ann.setLastColumn(lc.getLastColumn());
00736 am.putFilenameLinePairAnnotation(
00737 new FilenameLinePair(currentClassOrInterfaceType.getPath(),
00738 LineExtractor.extractLine(node)),
00739 ann);
00740
00741 for (int i = start; i < end; i++) {
00742 ann.addStmt((Stmt) currentStmts.elementAt(i));
00743 }
00744 currentAnnotation.addAnnotation(ann);
00745 }
00746
00747
00748
00749
00750 public void caseABytePrimitiveType(ABytePrimitiveType node) {
00751 currentType = ca.mcgill.sable.soot.ByteType.v();
00752 }
00753
00754
00755
00756
00757 public void caseACaseSwitchLabel(ACaseSwitchLabel node) {
00758 Value tempValue = currentValue;
00759 TrivialExpression.optimize(node.getExp(), true);
00760 node.getExp().apply(this);
00761 if ((currentValue == null) || !isNumberConstant(currentValue)) {
00762 exceptions.addElement(new CompilerException("Cannot have " + node.getExp().toString() + " as a switch case"));
00763 return;
00764 }
00765 if (currentValue instanceof LongConstant) {
00766 currentValue = IntConstant.v((int) ((LongConstant) currentValue).value);
00767 }
00768 currentLookupValues.addLast(new Integer(((IntConstant) currentValue).value));
00769 currentValue = tempValue;
00770 }
00771
00772
00773
00774
00775 public void caseACatchClause(ACatchClause node) {
00776 BlockStmtAnnotation prevAnnotation = currentAnnotation;
00777 try {
00778 symbolTable.enterScope();
00779 labelEnterBlock();
00780 PFormalParameter formalParameter = (PFormalParameter) node.getFormalParameter();
00781 formalParameter.apply(this);
00782 Local tempLocal = declareLocal(((AVariableDeclaratorId)
00783 ((AFormalParameter) formalParameter).getVariableDeclaratorId()).getId().toString().trim(), currentType, 0);
00784
00785 Stmt handlerStmt = jimple.newIdentityStmt(tempLocal, jimple.newCaughtExceptionRef(currentBody));
00786 currentStmts.addElement(handlerStmt);
00787
00788 currentAnnotation = new CatchAnnotation(node);
00789 LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
00790 currentAnnotation.setFirstLine(lc.getFirstLine());
00791 currentAnnotation.setFirstColumn(lc.getFirstColumn());
00792 currentAnnotation.setLastLine(lc.getLastLine());
00793 currentAnnotation.setLastColumn(lc.getLastColumn());
00794 am.putFilenameLinePairAnnotation(
00795 new FilenameLinePair(currentClassOrInterfaceType.getPath(),
00796 LineExtractor.extractLine(node)),
00797 currentAnnotation);
00798 node.getBlock().apply(this);
00799
00800 SequentialAnnotation sann = new SequentialAnnotation(null);
00801 sann.addStmt(handlerStmt);
00802 currentAnnotation.insertAnnotationAt(sann, 0);
00803
00804 Stmt lastStmt = (Stmt) currentStmts.lastElement();
00805
00806
00807 if (!((lastStmt instanceof ReturnStmt) || (lastStmt instanceof ReturnVoidStmt)
00808 || (lastStmt instanceof ThrowStmt) || (lastStmt instanceof GotoStmt))) {
00809 sann = new SequentialAnnotation(null);
00810 Stmt endCatchStmt = jimple.newGotoStmt(endTryStmt);
00811 sann.addStmt(endCatchStmt);
00812 currentStmts.addElement(endCatchStmt);
00813 currentAnnotation.addAnnotation(sann);
00814 } else {
00815 catchHasEnd = false;
00816 }
00817
00818
00819 String className = ((ca.mcgill.sable.soot.RefType) tempLocal.getType()).className;
00820 SootClass sc = getSootClass(className);
00821 ClassOrInterfaceType exceptionType = symbolTable.resolveClassOrInterfaceType(new Name(className));
00822 Name throwableName = new Name("java.lang.Throwable");
00823 if (!(exceptionType.hasSuperClass(throwableName) || throwableName.equals(exceptionType.getName()))) {
00824 throw new NotThrowableException("Cannot have an unthrowable exception type named '" + className + "'");
00825 }
00826 currentTraps.addElement(jimple.newTrap(sc, beginTrapStmt, endTrapStmt, handlerStmt));
00827 symbolTable.exitScope();
00828 labelExitBlock();
00829 currentTryAnnotation.addCatchClauseAnnotation(currentAnnotation);
00830 } catch (CompilerException e) {
00831 exceptions.addElement(e);
00832 }
00833 currentAnnotation = prevAnnotation;
00834 }
00835
00836
00837
00838
00839 public void caseACharacterLiteralLiteral(ACharacterLiteralLiteral node) {
00840 String literal = node.toString().trim();
00841 literal = literal.substring(1, literal.length() - 1);
00842 int value = 0;
00843
00844 if (literal.startsWith("\\")) {
00845 switch (literal.charAt(1)) {
00846 case 'b': value = '\b';
00847 break;
00848 case 't': value = '\t';
00849 break;
00850 case 'n': value = '\n';
00851 break;
00852 case 'f': value = '\f';
00853 break;
00854 case 'r': value = '\r';
00855 break;
00856 case '\"': value = '\"';
00857 break;
00858 case '\'': value = '\'';
00859 break;
00860 case '\\': value = '\\';
00861 break;
00862 default: value = Integer.valueOf(literal.substring(1), 8).intValue();
00863 }
00864 } else if (literal.startsWith("\\u")) {
00865 value = Integer.valueOf(literal.substring(2), 16).intValue();
00866 } else value = literal.charAt(0);
00867
00868 currentValue = IntConstant.v(value);
00869 integralConstantType = edu.ksu.cis.bandera.jjjc.symboltable.CharType.TYPE;
00870 }
00871
00872
00873
00874
00875 public void caseACharPrimitiveType(ACharPrimitiveType node) {
00876 currentType = ca.mcgill.sable.soot.CharType.v();
00877 }
00878
00879
00880
00881
00882 public void caseAClassBody(AClassBody node) {
00883
00884 nameGen = new NameGenerator();
00885 currentLocalNames = new Hashtable();
00886 currentLocalNamesIterator = new Hashtable();
00887 currentLocals = new Hashtable();
00888 currentStmts = new Vector();
00889 currentValue = null;
00890 currentType = null;
00891 currentName = null;
00892 staticLocals = new Hashtable();
00893 staticStmts = new Vector();
00894 instanceLocals = new Hashtable();
00895 instanceStmts = new Vector();
00896 currentThisLocal = jimple.newLocal(nameGen.newName(), ca.mcgill.sable.soot.RefType.v(currentSootClass.getName()));
00897 instanceLocals.put(currentThisLocal.getName(), currentThisLocal);
00898 instanceStmts.addElement(jimple.newIdentityStmt(currentThisLocal, jimple.newThisRef(currentSootClass)));
00899 LinkedList ClassBodyDeclList = node.getClassBodyDeclaration();
00900 PClassBodyDeclaration classBodyDecl;
00901 if (ClassBodyDeclList.size() > 0) {
00902 classBodyDecl = (PClassBodyDeclaration) ClassBodyDeclList.getFirst();
00903 for (Iterator i = ClassBodyDeclList.iterator(); i.hasNext();) {
00904 classBodyDecl = (PClassBodyDeclaration) i.next();
00905 if (classBodyDecl instanceof AFieldClassBodyDeclaration)
00906 classBodyDecl.apply(this);
00907 }
00908 for (Iterator i = ClassBodyDeclList.iterator(); i.hasNext();) {
00909 classBodyDecl = (PClassBodyDeclaration) i.next();
00910 if (classBodyDecl instanceof AStaticInitializerClassBodyDeclaration)
00911 classBodyDecl.apply(this);
00912 }
00913 for (Iterator i = ClassBodyDeclList.iterator(); i.hasNext();) {
00914 classBodyDecl = (PClassBodyDeclaration) i.next();
00915 if (classBodyDecl instanceof ABlockClassBodyDeclaration)
00916 classBodyDecl.apply(this);
00917 }
00918 }
00919 nameGen = null;
00920 boolean generateConstructor = false;
00921 Local thisLocal = currentThisLocal;
00922
00923
00924 if (ClassBodyDeclList.size() > 0) {
00925 classBodyDecl = (PClassBodyDeclaration) ClassBodyDeclList.getFirst();
00926 for (Iterator i = ClassBodyDeclList.iterator(); i.hasNext();) {
00927 classBodyDecl = (PClassBodyDeclaration) i.next();
00928 if (classBodyDecl instanceof AConstructorClassBodyDeclaration)
00929 break;
00930 }
00931
00932
00933 if (!(classBodyDecl instanceof AConstructorClassBodyDeclaration)) {
00934 generateConstructor = true;
00935 }
00936
00937
00938 currentLocals = null;
00939 currentStmts = null;
00940 currentThisLocal = null;
00941 currentLocalNames = null;
00942 currentLocalNamesIterator = null;
00943 for (Iterator i = ClassBodyDeclList.iterator(); i.hasNext();) {
00944 classBodyDecl = (PClassBodyDeclaration) i.next();
00945 if (!(classBodyDecl instanceof AFieldClassBodyDeclaration) && !(classBodyDecl instanceof ABlockClassBodyDeclaration) && !(classBodyDecl instanceof AStaticInitializerClassBodyDeclaration))
00946 classBodyDecl.apply(this);
00947 }
00948 } else
00949 generateConstructor = true;
00950
00951
00952 if (generateConstructor) {
00953 try {
00954 SootMethod sootMethod;
00955 JimpleBody body;
00956 if (init == null) {
00957 sootMethod = getSootMethod(currentSootClass.getName(), "<init>", new Vector());
00958 sootMethod.setReturnType(ca.mcgill.sable.soot.VoidType.v());
00959 sootMethod.setModifiers(Modifier.PUBLIC);
00960 body = (JimpleBody) jimple.newBody(sootMethod);
00961 } else {
00962 sootMethod = init;
00963 body = initBody;
00964 }
00965
00966 SequentialAnnotation sann = new SequentialAnnotation(null);
00967 StmtList stmts = body.getStmtList();
00968 for (Enumeration e = instanceLocals.elements(); e.hasMoreElements();) {
00969 body.addLocal((Local) e.nextElement());
00970 }
00971 for (int i = 0; i < instanceStmts.size(); i++) {
00972 sann.addStmt((Stmt) instanceStmts.elementAt(i));
00973 stmts.add(instanceStmts.elementAt(i));
00974 if ((i == 0) && (!currentSootClass.getName().equals("java.lang.Object"))) {
00975 try {
00976 SootClass sc = currentSootClass.getSuperClass();
00977 SootMethod sm = getSootMethod(sc.getName(), "<init>", new Vector());
00978 Stmt stmt = jimple.newInvokeStmt(jimple.newSpecialInvokeExpr(thisLocal, sm, new LinkedList()));
00979 stmts.add(stmt);
00980 sann.addStmt(stmt);
00981 } catch (NoSuperClassException nsce) {
00982 }
00983 }
00984 }
00985 Stmt stmt = jimple.newReturnVoidStmt();
00986 stmts.add(stmt);
00987 sann.addStmt(stmt);
00988
00989 ConstructorDeclarationAnnotation bann = new ConstructorDeclarationAnnotation(null);
00990 bann.addAnnotation(sann);
00991 bann.setSootMethod(sootMethod);
00992 bann.setConstructor(currentClassOrInterfaceType.getConstructor(new Vector()));
00993 am.addAnnotation(currentSootClass, sootMethod, bann);
00994
00995 TemporaryLocalsReduction.reduce(body, bann);
00996 DeadCodeElimination.eliminate(body);
00997 JumpElimination.eliminate(body);
00998 DeadCodeEliminator.eliminateDeadCode(body);
00999 Transformations.removeUnusedLocals(body);
01000
01001 bann.validate(body);
01002
01003 sootMethod.storeBody(jimple, body);
01004 } catch (CompilerException e) {
01005 exceptions.addElement(e);
01006 }
01007 }
01008
01009
01010 if (staticStmts.size() > 0) {
01011 SootMethod sootMethod;
01012 JimpleBody body;
01013 if (clinit == null) {
01014 sootMethod = new SootMethod("<clinit>", new LinkedList(), ca.mcgill.sable.soot.VoidType.v(),
01015 Modifier.PUBLIC);
01016 body = (JimpleBody) jimple.newBody(sootMethod);
01017 } else {
01018 sootMethod = clinit;
01019 body = clinitBody;
01020 }
01021 SequentialAnnotation sann = new SequentialAnnotation(null);
01022 StmtList stmts = body.getStmtList();
01023 for (Enumeration e = staticLocals.elements(); e.hasMoreElements();) {
01024 body.addLocal((Local) e.nextElement());
01025 }
01026 for (int i = 0; i < staticStmts.size(); i++) {
01027 stmts.add(staticStmts.elementAt(i));
01028 sann.addStmt((Stmt) staticStmts.elementAt(i));
01029 }
01030 Stmt stmt = jimple.newReturnVoidStmt();
01031 stmts.add(stmt);
01032 sann.add(stmt);
01033 ConstructorDeclarationAnnotation bann = new ConstructorDeclarationAnnotation(null);
01034 bann.addAnnotation(sann);
01035 bann.setSootMethod(sootMethod);
01036 am.addAnnotation(currentSootClass, sootMethod, bann);
01037
01038 currentSootClass.addMethod(sootMethod);
01039
01040 TemporaryLocalsReduction.reduce(body, bann);
01041 DeadCodeElimination.eliminate(body);
01042 JumpElimination.eliminate(body);
01043 DeadCodeEliminator.eliminateDeadCode(body);
01044 Transformations.removeUnusedLocals(body);
01045
01046 bann.validate(body);
01047 sootMethod.storeBody(jimple, body);
01048 }
01049 }
01050
01051
01052
01053
01054 public void caseAClassClassBodyDeclaration(AClassClassBodyDeclaration node) {
01055 System.out.println("Unsupported feature of Java: " + node);
01056 exceptions.addElement(new CompilerException("Unsupported feature of Java: " + node));
01057 throw new Error("Unsupported feature of Java: " + node);
01058 }
01059
01060
01061
01062
01063 public void caseAClassDeclaration(AClassDeclaration node) {
01064 try {
01065 currentClassOrInterfaceType = symbolTable.getDeclaredType(new Name(node.getId().toString()));
01066 symbolTable.setCurrentClassOrInterfaceType(currentClassOrInterfaceType);
01067
01068 currentSootClass = getSootClass(currentClassOrInterfaceType.getName().toString());
01069 ClassDeclarationAnnotation cda = new ClassDeclarationAnnotation(node);
01070 LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
01071 cda.setFirstLine(lc.getFirstLine());
01072 cda.setFirstColumn(lc.getFirstColumn());
01073 cda.setLastLine(lc.getLastLine());
01074 cda.setLastColumn(lc.getLastColumn());
01075 cda.setSootClass(currentSootClass);
01076 am.addAnnotation(cda);
01077 am.putFilenameLinePairAnnotation(new FilenameLinePair(currentClassOrInterfaceType.getPath(),
01078 LineExtractor.extractLine(node)), cda);
01079
01080 symbolTable.resetScope();
01081 if (node.getClassBody() != null) {
01082 node.getClassBody().apply(this);
01083 }
01084 compiledClasses.addElement(currentSootClass.getName());
01085 CompilationManager.addDocTriple(new DocTriple(currentSootClass, null, DocProcessor.tags(node, docComments)));
01086 } catch (CompilerException e) {
01087 exceptions.addElement(e);
01088 }
01089
01090 currentClassOrInterfaceType = null;
01091 symbolTable.setCurrentClassOrInterfaceType(null);
01092 currentSootClass = null;
01093 }
01094
01095
01096
01097
01098 public void caseAClassDeclarationBlockedStmt(AClassDeclarationBlockedStmt node) {
01099 System.out.println("Unsupported feature of Java: " + node);
01100 exceptions.addElement(new CompilerException("Unsupported feature of Java: " + node));
01101 throw new Error("Unsupported feature of Java: " + node);
01102 }
01103
01104
01105
01106
01107 public void caseAClassDeclarationInterfaceMemberDeclaration(AClassDeclarationInterfaceMemberDeclaration node) {
01108 System.out.println("Unsupported feature of Java: " + node);
01109 exceptions.addElement(new CompilerException("Unsupported feature of Java: " + node));
01110 throw new Error("Unsupported feature of Java: " + node);
01111 }
01112
01113
01114
01115
01116 public void caseAClassOrInterfaceTypeExp(AClassOrInterfaceTypeExp node) {
01117 try {
01118 RefType refType = RefType.v(getSootClass((new Name(node.getClassOrInterfaceType().toString())).toString()).getName());
01119 currentType = null;
01120 LinkedList arrayExps = new LinkedList();
01121 int dimensions = 0;
01122 currentValue = null;
01123 for (Iterator i = node.getDimExp().iterator(); i.hasNext();) {
01124 ((PDimExp) i.next()).apply(this);
01125 arrayExps.addLast(currentValue);
01126 currentValue = null;
01127 dimensions++;
01128 }
01129 dimensions += node.getDim().size();
01130 if (dimensions == 1) {
01131 currentValue = jimple.newNewArrayExpr(refType, (Value) arrayExps.removeFirst());
01132 } else {
01133 currentType = ca.mcgill.sable.soot.ArrayType.v(refType, dimensions);
01134 currentValue = jimple.newNewMultiArrayExpr((ca.mcgill.sable.soot.ArrayType) currentType, arrayExps);
01135 currentType = null;
01136 }
01137 Value newValue = currentValue;
01138 currentValue = null;
01139 Local lcl = declareLocal(nameGen.newName(), newValue.getType(), 0);
01140 currentStmts.addElement(jimple.newAssignStmt(lcl, newValue));
01141 currentValue = lcl;
01142 currentType = lcl.getType();
01143 } catch (CompilerException e) {
01144 exceptions.addElement(e);
01145 }
01146 }
01147
01148
01149
01150
01151 public void caseACompilationUnit(ACompilationUnit node) {
01152 try {
01153 if (node.getPackageDeclaration() != null) {
01154 symbolTable.setCurrentPackage(Package.getPackage(new Name(node.getPackageDeclaration().toString())));
01155 } else {
01156 symbolTable.setCurrentPackage(Package.getPackage(new Name("")));
01157 }
01158 Object temp[] = node.getTypeDeclaration().toArray();
01159 for (int i = 0; i < temp.length; i++) {
01160 ((PTypeDeclaration) temp[i]).apply(this);
01161 }
01162 } catch (CompilerException e) {
01163 exceptions.addElement(e);
01164 }
01165 }
01166
01167
01168
01169
01170 public void caseAConstructorBody(AConstructorBody node) {
01171 try {
01172 symbolTable.enterScope();
01173 boolean needHelper = false;
01174 PConstructorInvocation constructorInvocation = (PConstructorInvocation) node.getConstructorInvocation();
01175 if (!(constructorInvocation instanceof AThisConstructorInvocation)) {
01176 needHelper = true;
01177 }
01178 if (constructorInvocation != null) {
01179 constructorInvocation.apply(this);
01180 } else {
01181 SootMethod sm = getSootMethod(currentSootClass.getSuperClass().getName(), "<init>", new Vector());
01182 SequentialAnnotation sann = new SequentialAnnotation(null);
01183 Stmt stmt = jimple.newInvokeStmt(jimple.newSpecialInvokeExpr(currentThisLocal, sm, new LinkedList()));
01184 currentStmts.addElement(stmt);
01185 sann.addStmt(stmt);
01186 currentAnnotation.addAnnotation(sann);
01187 needHelper = true;
01188 }
01189
01190 if ((instanceStmts.size() > 1) && needHelper) {
01191 SequentialAnnotation sann = new SequentialAnnotation(null);
01192 JimpleStmtCloner.reset();
01193 JimpleStmtCloner.setBody(currentBody);
01194
01195 for (Enumeration e = instanceStmts.elements(); e.hasMoreElements();) {
01196 Stmt s = (Stmt) e.nextElement();
01197 Stmt stmt = JimpleStmtCloner.clone(s);
01198 sann.addStmt(stmt);
01199 currentStmts.addElement(stmt);
01200 }
01201 if (initBody != null)
01202 JimpleStmtCloner.copyTrap(initBody);
01203 JimpleStmtCloner.reset();
01204 JimpleStmtCloner.setBody(null);
01205 currentAnnotation.addAnnotation(sann);
01206 }
01207 labelEnterBlock();
01208 for (Iterator i = node.getBlockedStmt().iterator(); i.hasNext();) {
01209 ((PBlockedStmt) i.next()).apply(this);
01210 }
01211 labelExitBlock();
01212 symbolTable.exitScope();
01213 } catch (CompilerException e) {
01214 exceptions.addElement(e);
01215 }
01216 }
01217
01218
01219
01220
01221 public void caseAConstructorDeclaration(AConstructorDeclaration node) {
01222 if (CompilationManager.getModifiedMethodTable().get(node) != null) {
01223 ((Node) CompilationManager.getModifiedMethodTable().get(node)).apply(this);
01224 CompilationManager.addDocTriple(new DocTriple(currentSootClass, currentSootMethod, DocProcessor.tags(node, docComments)));
01225 return;
01226 }
01227 currentSootMethod = null;
01228 nameGen = new NameGenerator();
01229 currentLocalNames = new Hashtable();
01230 currentLocalNamesIterator = new Hashtable();
01231 currentLocals = new Hashtable();
01232 currentStmts = new Vector();
01233 currentValue = null;
01234 currentType = null;
01235 currentName = null;
01236 currentThisLocal = null;
01237 labels = new LinkedList();
01238 currentAnnotation = new ConstructorDeclarationAnnotation(node);
01239 LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
01240 currentAnnotation.setFirstLine(lc.getFirstLine());
01241 currentAnnotation.setFirstColumn(lc.getFirstColumn());
01242 currentAnnotation.setLastLine(lc.getLastLine());
01243 currentAnnotation.setLastColumn(lc.getLastColumn());
01244 currentTraps = new Vector();
01245
01246 symbolTable.enterScope();
01247 node.getConstructorDeclarator().apply(this);
01248 node.getConstructorBody().apply(this);
01249 symbolTable.exitScope();
01250
01251
01252 StmtList stmts = currentBody.getStmtList();
01253 for (Enumeration e = currentLocals.elements(); e.hasMoreElements();) {
01254 currentBody.addLocal((Local) e.nextElement());
01255 }
01256 for (int i = 0; i < currentStmts.size(); i++) {
01257 stmts.add((Stmt) currentStmts.elementAt(i));
01258 }
01259
01260 Stmt tempStmt = null;
01261 if (currentStmts.size() > 0) {
01262 int size = currentStmts.size();
01263 Stmt lastStmt = (Stmt) currentStmts.elementAt(--size);
01264 if (!(lastStmt instanceof JReturnStmt) && !(lastStmt instanceof JReturnVoidStmt)
01265 && !(lastStmt instanceof JThrowStmt)) {
01266 tempStmt = jimple.newReturnVoidStmt();
01267 stmts.add(tempStmt);
01268 SequentialAnnotation ann = new SequentialAnnotation(null);
01269 ann.addStmt(tempStmt);
01270 currentAnnotation.addAnnotation(ann);
01271 }
01272 } else {
01273 SequentialAnnotation ann = new SequentialAnnotation(null);
01274 Stmt stmt = jimple.newReturnVoidStmt();
01275 ann.addStmt(stmt);
01276 stmts.add(stmt);
01277 currentAnnotation.addAnnotation(ann);
01278 }
01279
01280 for (Enumeration e = currentTraps.elements(); e.hasMoreElements();) {
01281 currentBody.addTrap((Trap) e.nextElement());
01282 }
01283
01284 am.addAnnotation(currentSootClass, currentSootMethod, currentAnnotation);
01285
01286
01287 convertLocalTypes(currentBody);
01288 TemporaryLocalsReduction.reduce(currentBody, currentAnnotation);
01289 DeadCodeElimination.eliminate(currentBody);
01290 JumpElimination.eliminate(currentBody);
01291 DeadCodeEliminator.eliminateDeadCode(currentBody);
01292 DeadCodeElimination.eliminate(currentBody);
01293
01294 Transformations.cleanupCode(currentBody);
01295
01296 currentAnnotation.validate(currentBody);
01297
01298 currentSootMethod.storeBody(jimple, currentBody);
01299 am.putFilenameLinePairAnnotation(new FilenameLinePair(currentClassOrInterfaceType.getPath(),
01300 LineExtractor.extractLine(node)), currentAnnotation);
01301
01302 CompilationManager.addDocTriple(new DocTriple(currentSootClass, currentSootMethod, DocProcessor.tags(node, docComments)));
01303
01304
01305 nameGen = null;
01306 currentLocals = null;
01307 currentLocalNames = null;
01308 currentLocalNamesIterator = null;
01309 currentStmts = null;
01310 currentValue = null;
01311 currentType = null;
01312 currentName = null;
01313 currentThisLocal = null;
01314 labels = null;
01315 currentTraps = null;
01316 currentAnnotation = null;
01317 }
01318
01319
01320
01321
01322 public void caseAConstructorDeclarator(AConstructorDeclarator node) {
01323
01324 String constructorName = "<init>";
01325
01326 try {
01327
01328 currentType = null;
01329 Vector formalParameters = new Vector();
01330 for (Iterator i = node.getFormalParameter().iterator(); i.hasNext();) {
01331 ((PFormalParameter) i.next()).apply(this);
01332 formalParameters.addElement(Util.convertType(currentType, symbolTable));
01333 currentType = null;
01334 }
01335
01336 currentSootMethod = getSootMethod(currentSootClass.getName(), constructorName, formalParameters);
01337 ((ConstructorDeclarationAnnotation) currentAnnotation).setSootMethod(currentSootMethod);
01338 ((ConstructorDeclarationAnnotation) currentAnnotation).setConstructor(currentClassOrInterfaceType.getConstructor(formalParameters));
01339 currentBody = (JimpleBody) jimple.newBody(currentSootMethod);
01340
01341
01342 {
01343 String thisName = nameGen.newName();
01344 currentThisLocal = declareLocal(thisName, ca.mcgill.sable.soot.RefType.v(currentSootClass.getName()), 0);
01345 SequentialAnnotation ann = new SequentialAnnotation(null);
01346 Stmt s = jimple.newIdentityStmt(currentThisLocal, jimple.newThisRef(currentSootClass));
01347 currentStmts.addElement(s);
01348 ann.addStmt(s);
01349 currentAnnotation.addAnnotation(ann);
01350 }
01351
01352
01353 SequentialAnnotation ann = new SequentialAnnotation(null);
01354 int paramNum = 0;
01355 Method m = currentClassOrInterfaceType.getConstructor(formalParameters);
01356 for (Enumeration e = m.getParameters().elements(); e.hasMoreElements(); paramNum++) {
01357 Variable v = (Variable) e.nextElement();
01358 Local tempLocal = declareLocal(v.getName().toString(), Util.convertType(v.getType()),
01359 Util.convertModifiers(v.getModifiers()));
01360 currentLocals.put(tempLocal.getName(), tempLocal);
01361 Stmt s = jimple.newIdentityStmt(tempLocal, jimple.newParameterRef(currentSootMethod, paramNum));
01362 currentStmts.addElement(s);
01363 ann.addStmt(s);
01364 }
01365 currentAnnotation.addAnnotation(ann);
01366 } catch (CompilerException e) {
01367 exceptions.addElement(e);
01368 }
01369 }
01370
01371
01372
01373
01374 public void caseAContinueStmt(AContinueStmt node) {
01375 int start = currentStmts.size();
01376
01377 if (node.getId() != null) {
01378 Unit target = getLabelUnit(node.getId().toString().trim());
01379 if (target == null) {
01380 exceptions.addElement(new CompilerException("Invalid continue statement..."));
01381 return;
01382 }
01383 Object lastFinallySynchBeforeControl = ((Vector) getLabelObject(target)).firstElement();
01384 for (Enumeration e = synchAnnotations.elements(); e.hasMoreElements();) {
01385 Object o = e.nextElement();
01386 if (o == lastFinallySynchBeforeControl) break;
01387 if (o instanceof Node) {
01388 ((Node) o).apply(this);
01389 } else {
01390 SynchronizedStmtAnnotation sann = (SynchronizedStmtAnnotation) o;
01391 Stmt exitMon = jimple.newExitMonitorStmt(sann.getLockValue());
01392 sann.addExitMonitor(exitMon);
01393 currentStmts.addElement(exitMon);
01394 }
01395 }
01396 currentStmts.addElement(jimple.newGotoStmt(target));
01397 } else {
01398 if (currentContinueTarget == null) {
01399 exceptions.addElement(new CompilerException("Invalid continue statement..."));
01400 return;
01401 }
01402 for (Enumeration e = synchAnnotations.elements(); e.hasMoreElements();) {
01403 Object o = e.nextElement();
01404 if (o == lastFinallySynchBeforeControl) break;
01405 if (o instanceof Node) {
01406 ((Node) o).apply(this);
01407 } else {
01408 SynchronizedStmtAnnotation sann = (SynchronizedStmtAnnotation) o;
01409 Stmt exitMon = jimple.newExitMonitorStmt(sann.getLockValue());
01410 sann.addExitMonitor(exitMon);
01411 currentStmts.addElement(exitMon);
01412 }
01413 }
01414 currentStmts.addElement(jimple.newGotoStmt(currentContinueTarget));
01415 }
01416
01417 int end = currentStmts.size();
01418 ContinueStmtAnnotation ann = new ContinueStmtAnnotation(node);
01419 LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
01420 ann.setFirstLine(lc.getFirstLine());
01421 ann.setFirstColumn(lc.getFirstColumn());
01422 ann.setLastLine(lc.getLastLine());
01423 ann.setLastColumn(lc.getLastColumn());
01424 am.putFilenameLinePairAnnotation(
01425 new FilenameLinePair(currentClassOrInterfaceType.getPath(),
01426 LineExtractor.extractLine(node)),
01427 ann);
01428
01429 for (int i = start; i < end; i++) {
01430 ann.addStmt((Stmt) currentStmts.elementAt(i));
01431 }
01432 currentAnnotation.addAnnotation(ann);
01433 }
01434
01435
01436
01437
01438 public void caseADecimalIntegerLiteral(ADecimalIntegerLiteral node) {
01439 String literal = node.toString().trim();
01440 if (literal.endsWith("L") || literal.endsWith("l")) {
01441 currentValue = LongConstant.v(Long.valueOf(literal.substring(0, literal.length() - 1)).longValue());
01442 integralConstantType = edu.ksu.cis.bandera.jjjc.symboltable.LongType.TYPE;
01443 } else {
01444 currentValue = IntConstant.v(Integer.valueOf(literal).intValue());
01445 integralConstantType = edu.ksu.cis.bandera.jjjc.symboltable.IntType.TYPE;
01446 }
01447 }
01448
01449
01450
01451
01452 public void caseADefaultSwitchLabel(ADefaultSwitchLabel node) {
01453 defaultSwitch = !defaultSwitch;
01454 }
01455
01456
01457
01458
01459 public void caseADoStmt(ADoStmt node) {
01460 Stmt doStmt = jimple.newNopStmt();
01461 Stmt testStmt = jimple.newNopStmt();
01462 Stmt endStmt = jimple.newNopStmt();
01463
01464 DoWhileStmtAnnotation ann = new DoWhileStmtAnnotation(node);
01465 LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
01466 ann.setFirstLine(lc.getFirstLine());
01467 ann.setFirstColumn(lc.getFirstColumn());
01468 ann.setLastLine(lc.getLastLine());
01469 ann.setLastColumn(lc.getLastColumn());
01470 am.putFilenameLinePairAnnotation(
01471 new FilenameLinePair(currentClassOrInterfaceType.getPath(),
01472 LineExtractor.extractLine(node)),
01473 ann);
01474
01475 Object prevLastSynch = lastFinallySynchBeforeControl;
01476 if (synchAnnotations.size() > 0)
01477 lastFinallySynchBeforeControl = (Annotation) synchAnnotations.lastElement();
01478
01479 Stmt prevTrueBranch = trueBranch;
01480 Stmt prevFalseBranch = falseBranch;
01481 trueBranch = doStmt;
01482 falseBranch = endStmt;
01483 Stmt prevBreakTarget = currentBreakTarget;
01484 Stmt prevContinueTarget = currentContinueTarget;
01485 currentBreakTarget = endStmt;
01486 currentContinueTarget = testStmt;
01487
01488 BlockStmtAnnotation prevAnnotation = currentAnnotation;
01489 currentAnnotation = new BlockStmtAnnotation(node.getBlock());
01490
01491 currentStmts.addElement(doStmt);
01492
01493 node.getBlock().apply(this);
01494
01495 ann.setBlockAnnotation(getFirstEnclosedAnnotation(currentAnnotation));
01496
01497 currentStmts.addElement(testStmt);
01498
01499 int start = currentStmts.size();
01500
01501 Node n = (Node) node.getExp().clone();
01502 PushComplement.push(n);
01503 if (node.getExp() instanceof AUnaryExp)
01504 if ("!".equals(((AUnaryExp) node.getExp()).getUnaryOperator().toString().trim()))
01505 n = ((AUnaryExp) n).getExp();
01506 n.apply(new BooleanExpression(this, trueBranch, falseBranch));
01507
01508 ann.setIndefinite(currentStmts.elementAt(currentStmts.size() - 1) instanceof JGotoStmt);
01509
01510 int end = currentStmts.size();
01511
01512 for (int i = start; i < end; i++) {
01513 ann.addStmt((Stmt) currentStmts.elementAt(i));
01514 }
01515
01516 currentStmts.addElement(endStmt);
01517 currentValue = null;
01518
01519
01520 trueBranch = prevTrueBranch;
01521 falseBranch = prevFalseBranch;
01522 currentBreakTarget = prevBreakTarget;
01523 currentContinueTarget = prevContinueTarget;
01524 lastFinallySynchBeforeControl = prevLastSynch;
01525
01526 currentAnnotation = prevAnnotation;
01527 currentAnnotation.addAnnotation(ann);
01528 }
01529
01530
01531
01532
01533 public void caseADoublePrimitiveType(ADoublePrimitiveType node) {
01534 currentType = ca.mcgill.sable.soot.DoubleType.v();
01535 }
01536
01537
01538
01539
01540 public void caseAEmptyStmt(AEmptyStmt node) {
01541 Annotation ea = new EmptyStmtAnnotation(node);
01542 LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
01543 ea.setFirstLine(lc.getFirstLine());
01544 ea.setFirstColumn(lc.getFirstColumn());
01545 ea.setLastLine(lc.getLastLine());
01546 ea.setLastColumn(lc.getLastColumn());
01547 currentAnnotation.addAnnotation(ea);
01548 am.putFilenameLinePairAnnotation(
01549 new FilenameLinePair(currentClassOrInterfaceType.getPath(),
01550 LineExtractor.extractLine(node)),
01551 ea);
01552 }
01553
01554
01555
01556
01557 public void caseAExpCastExp(AExpCastExp node) {
01558 try {
01559 String t = ((ANameExp) node.getFirst()).getName().toString();
01560 ca.mcgill.sable.soot.Type type =
01561 Util.convertType(symbolTable.resolveType(new Name(t)));
01562 int dimensions = Util.countArrayDimensions(t);
01563 if (dimensions > 0)
01564 type = ca.mcgill.sable.soot.ArrayType.v((BaseType) type, dimensions);
01565 node.getSecond().apply(this);
01566 Value castedValue = currentValue;
01567 currentValue = null;
01568 Local lcl = declareLocal(nameGen.newName(), type, 0);
01569 currentStmts.addElement(jimple.newAssignStmt(lcl, jimple.newCastExpr(castedValue, type)));
01570 currentValue = lcl;
01571 } catch (CompilerException e) {
01572 exceptions.addElement(e);
01573 }
01574 }
01575
01576
01577
01578
01579 public void caseAExpStmt(AExpStmt node) {
01580 int start = currentStmts.size();
01581 if(node.getExp() != null) {
01582 node.getExp().apply(this);
01583 }
01584 int end = currentStmts.size();
01585 ExpStmtAnnotation ann = new ExpStmtAnnotation(node);
01586 LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
01587 ann.setFirstLine(lc.getFirstLine());
01588 ann.setFirstColumn(lc.getFirstColumn());
01589 ann.setLastLine(lc.getLastLine());
01590 ann.setLastColumn(lc.getLastColumn());
01591 am.putFilenameLinePairAnnotation(
01592 new FilenameLinePair(currentClassOrInterfaceType.getPath(),
01593 LineExtractor.extractLine(node)),
01594 ann);
01595
01596 for (int i = start; i < end; i++) {
01597 ann.addStmt((Stmt) currentStmts.elementAt(i));
01598 }
01599 currentAnnotation.addAnnotation(ann);
01600 }
01601
01602
01603
01604
01605 public void caseAFalseBooleanLiteral(AFalseBooleanLiteral node) {
01606 currentValue = IntConstant.v(0);
01607 integralConstantType = edu.ksu.cis.bandera.jjjc.symboltable.BooleanType.TYPE;
01608 }
01609
01610
01611
01612
01613 public void caseAFieldDeclaration(AFieldDeclaration node) {
01614 try {
01615 fieldNode = node;
01616
01617 int fieldModifiers = Util.convertModifiers(Util.convertModifiers(node.getModifier().toString()));
01618 if (node.parent() instanceof AConstantDeclarationInterfaceMemberDeclaration) {
01619 fieldModifiers = Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL;
01620 }
01621
01622
01623 if (Modifier.isStatic(fieldModifiers)) {
01624 currentLocals = staticLocals;
01625 currentStmts = staticStmts;
01626 } else {
01627 currentLocals = instanceLocals;
01628 currentStmts = instanceStmts;
01629 }
01630
01631 PVariableDeclarator variableDeclarator;
01632 for (Iterator i = node.getVariableDeclarator().iterator(); i.hasNext();) {
01633 variableDeclarator = (PVariableDeclarator) i.next();
01634 currentType = ca.mcgill.sable.soot.IntType.v();
01635 variableDeclarator.apply(this);
01636 }
01637 } catch (CompilerException e) {
01638 exceptions.addElement(e);
01639 }
01640 currentType = null;
01641 }
01642
01643
01644
01645
01646 public void caseAFloatingPointLiteralLiteral(AFloatingPointLiteralLiteral node) {
01647 String literal = node.toString().trim();
01648 if (literal.equals("Infinity"))
01649 currentValue = DoubleConstant.v(Double.POSITIVE_INFINITY);
01650 else if (literal.equals("NaN"))
01651 currentValue = DoubleConstant.v(Double.NaN);
01652 else if (literal.endsWith("F") || literal.endsWith("f"))
01653 currentValue = FloatConstant.v(Float.valueOf(literal).floatValue());
01654 else
01655 currentValue = DoubleConstant.v(Double.valueOf(literal).doubleValue());
01656 }
01657
01658
01659
01660
01661 public void caseAFloatPrimitiveType(AFloatPrimitiveType node) {
01662 currentType = ca.mcgill.sable.soot.FloatType.v();
01663 }
01664
01665
01666
01667
01668 public void caseAForStmt(AForStmt node) {
01669 PExp exp = null;
01670
01671 if (node.getExp() != null) {
01672 exp = new AUnaryExp(new AComplementUnaryOperator(new TComplement()), (PExp) node.getExp().clone());
01673 PushComplement.push(exp);
01674 exp = ((AUnaryExp) exp).getExp();
01675 }
01676
01677 ForStmtAnnotation ann = new ForStmtAnnotation(node);
01678 LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
01679 ann.setFirstLine(lc.getFirstLine());
01680 ann.setFirstColumn(lc.getFirstColumn());
01681 ann.setLastLine(lc.getLastLine());
01682 ann.setLastColumn(lc.getLastColumn());
01683
01684 am.putFilenameLinePairAnnotation(
01685 new FilenameLinePair(currentClassOrInterfaceType.getPath(),
01686 LineExtractor.extractLine(node)),
01687 ann);
01688 BlockStmtAnnotation prevAnnotation = currentAnnotation;
01689
01690 Object prevLastSynch = lastFinallySynchBeforeControl;
01691 if (synchAnnotations.size() > 0)
01692 lastFinallySynchBeforeControl = (Annotation) synchAnnotations.lastElement();
01693
01694 Stmt initStmt = jimple.newNopStmt();
01695 Stmt testStmt = jimple.newNopStmt();
01696 Stmt blockStmt = jimple.newNopStmt();
01697 Stmt updateStmt = jimple.newNopStmt();
01698 Stmt endStmt = jimple.newNopStmt();
01699
01700 symbolTable.enterScope();
01701 labelEnterBlock();
01702 if (node.getForInit() != null) {
01703 forLocals = new Hashtable();
01704 forInitType = null;
01705 forInitModifiers = 0;
01706 currentStmts.addElement(initStmt);
01707
01708 int start = currentStmts.size();
01709
01710 currentAnnotation = null;
01711
01712 node.getForInit().apply(this);
01713
01714 currentAnnotation = prevAnnotation;
01715
01716 int end = currentStmts.size();
01717
01718 SequentialAnnotation sann = new SequentialAnnotation(null);
01719
01720 for (int i = start; i < end; i++) {
01721 sann.addStmt((Stmt) currentStmts.elementAt(i));
01722 }
01723
01724 ann.setInitAnnotation(sann);
01725
01726 for (Enumeration e = forLocals.keys(); e.hasMoreElements();) {
01727 String key = (String) e.nextElement();
01728 ann.addDeclaredLocal(key, (Local) forLocals.get(key));
01729 }
01730
01731 ann.setType(forInitType);
01732 ann.setModifiers(forInitModifiers);
01733 } else {
01734 initStmt = null;
01735 }
01736
01737 boolean isIndefiniteLoop = false;
01738
01739 if (exp != null) {
01740 currentStmts.addElement(testStmt);
01741 Stmt prevTrueBranch = trueBranch;
01742 Stmt prevFalseBranch = falseBranch;
01743 trueBranch = endStmt;
01744 falseBranch = blockStmt;
01745
01746 int start = currentStmts.size();
01747
01748 exp.apply(new BooleanExpression(this, trueBranch, falseBranch));
01749
01750 if (currentStmts.elementAt(currentStmts.size() - 1) instanceof JGotoStmt) isIndefiniteLoop = true;
01751
01752 int end = currentStmts.size();
01753
01754 for (int i = start; i < end; i++) {
01755 ann.addStmt((Stmt) currentStmts.elementAt(i));
01756 }
01757
01758 trueBranch = prevTrueBranch;
01759 falseBranch = prevFalseBranch;
01760 } else {
01761 testStmt = null;
01762 isIndefiniteLoop = true;
01763 }
01764
01765 currentStmts.addElement(blockStmt);
01766
01767 currentAnnotation = new BlockStmtAnnotation(node.getBlock());
01768
01769 Stmt prevBreakTarget = currentBreakTarget;
01770 Stmt prevContinueTarget = currentContinueTarget;
01771
01772 currentBreakTarget = endStmt;
01773 currentContinueTarget = updateStmt;
01774
01775 node.getBlock().apply(this);
01776
01777 ann.setBlockAnnotation(getFirstEnclosedAnnotation(currentAnnotation));
01778
01779 currentBreakTarget = prevBreakTarget;
01780 currentContinueTarget = prevContinueTarget;
01781
01782 currentStmts.addElement(updateStmt);
01783
01784 int start = currentStmts.size();
01785
01786 for (Iterator i = node.getForUpdate().iterator(); i.hasNext();) {
01787 ((PExp) i.next()).apply(this);
01788 }
01789
01790 if (testStmt == null)
01791 currentStmts.addElement(jimple.newGotoStmt(blockStmt));
01792 else
01793 currentStmts.addElement(jimple.newGotoStmt(testStmt));
01794
01795 int end = currentStmts.size();
01796
01797 SequentialAnnotation sann = new SequentialAnnotation(null);
01798
01799 for (int i = start; i < end; i++) {
01800 sann.addStmt((Stmt) currentStmts.elementAt(i));
01801 }
01802
01803 ann.setUpdateAnnotation(sann);
01804
01805 Stmt backPointStmt = (Stmt) currentStmts.elementAt(currentStmts.size() - 1);
01806 currentStmts.addElement(endStmt);
01807
01808 symbolTable.exitScope();
01809 labelExitBlock();
01810
01811 ann.setIndefinite(isIndefiniteLoop);
01812
01813 currentAnnotation = prevAnnotation;
01814 currentAnnotation.addAnnotation(ann);
01815
01816 lastFinallySynchBeforeControl = prevLastSynch;
01817 }
01818
01819
01820
01821
01822 public void caseAHexIntegerLiteral(AHexIntegerLiteral node) {
01823 String literal = node.toString().substring(2).trim();
01824 if (literal.endsWith("L") || literal.endsWith("l")) {
01825 currentValue = LongConstant.v(new BigInteger(literal.substring(0, literal.length() - 1), 16).longValue());
01826 integralConstantType = edu.ksu.cis.bandera.jjjc.symboltable.LongType.TYPE;
01827 } else {
01828 currentValue = IntConstant.v(Long.valueOf(literal, 16).intValue());
01829 integralConstantType = edu.ksu.cis.bandera.jjjc.symboltable.IntType.TYPE;
01830 }
01831 }
01832
01833
01834
01835
01836 public void caseAIdVariableDeclarator(AIdVariableDeclarator node) {
01837 try {
01838 node.getVariableDeclaratorId().apply(this);
01839 if (symbolTable.getNumScopeLevels() > 0) {
01840 Local lcl = declareLocal(currentName, currentType, 0);
01841 localAnnotation.addDeclaredLocal(currentName, lcl);
01842 } else {
01843 FieldDeclarationAnnotation ann = new FieldDeclarationAnnotation(fieldNode);
01844 SootField sf = getSootField(currentSootClass.getName(), currentName);
01845 ann.setSootField(sf);
01846 ann.setField(currentClassOrInterfaceType.getField(new Name(currentName)));
01847 am.addAnnotation(currentSootClass, sf, ann);
01848 am.putFilenameLinePairAnnotation(
01849 new FilenameLinePair(currentClassOrInterfaceType.getPath(),
01850 LineExtractor.extractLine(node.getVariableDeclaratorId())),
01851 ann);
01852 }
01853 } catch (CompilerException e) {
01854 exceptions.addElement(e);
01855 }
01856 }
01857
01858
01859
01860
01861 public void caseAIfStmt(AIfStmt node) {
01862 PExp exp = new AUnaryExp(new AComplementUnaryOperator(new TComplement()), (PExp) node.getExp().clone());
01863 PushComplement.push(exp);
01864 exp = ((AUnaryExp) exp).getExp();
01865
01866 Stmt thenStmt = jimple.newNopStmt();
01867 Stmt elseStmt = jimple.newNopStmt();
01868 Stmt endStmt = jimple.newNopStmt();
01869
01870 BlockStmtAnnotation prevAnnotation = currentAnnotation;
01871 IfStmtAnnotation ann = new IfStmtAnnotation(node);
01872 LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
01873 ann.setFirstLine(lc.getFirstLine());
01874 ann.setFirstColumn(lc.getFirstColumn());
01875 ann.setLastLine(lc.getLastLine());
01876 ann.setLastColumn(lc.getLastColumn());
01877 am.putFilenameLinePairAnnotation(
01878 new FilenameLinePair(currentClassOrInterfaceType.getPath(),
01879 LineExtractor.extractLine(node)),
01880 ann);
01881
01882 Stmt prevTrueBranch = trueBranch;
01883 Stmt prevFalseBranch = falseBranch;
01884 trueBranch = elseStmt;
01885 falseBranch = thenStmt;
01886
01887 int start = currentStmts.size();
01888
01889 exp.apply(new BooleanExpression(this, trueBranch, falseBranch));
01890
01891 int end = currentStmts.size();
01892
01893 for (int i = start; i < end; i++) {
01894 ann.addStmt((Stmt) currentStmts.elementAt(i));
01895 }
01896
01897 currentStmts.addElement(thenStmt);
01898
01899 currentAnnotation = new BlockStmtAnnotation(node.getBlock());
01900
01901 node.getThenPart().apply(this);
01902
01903 SequentialAnnotation sann = new SequentialAnnotation(null);
01904 Stmt gotoStmt = jimple.newGotoStmt(endStmt);
01905 sann.addStmt(gotoStmt);
01906 ann.setAnnotation(sann);
01907 ann.setThenAnnotation(getFirstEnclosedAnnotation(currentAnnotation));
01908
01909 currentStmts.addElement(gotoStmt);
01910 currentStmts.addElement(elseStmt);
01911
01912 currentAnnotation = new BlockStmtAnnotation(node.getBlock());
01913
01914 node.getBlock().apply(this);
01915
01916 ann.setElseAnnotation(getFirstEnclosedAnnotation(currentAnnotation));
01917
01918 currentStmts.addElement(endStmt);
01919
01920 trueBranch = prevTrueBranch;
01921 falseBranch = prevFalseBranch;
01922
01923 currentAnnotation = prevAnnotation;
01924 currentAnnotation.addAnnotation(ann);
01925 }
01926
01927
01928
01929
01930 public void caseAInitClassInterfaceExp(AInitClassInterfaceExp node) {
01931 try {
01932 String className = (new Name(node.getClassOrInterfaceType().toString())).toString();
01933 SootClass sc = getSootClass(className);
01934 className = sc.getName();
01935 ca.mcgill.sable.soot.Type type = ca.mcgill.sable.soot.RefType.v(className);
01936 int dimensions = node.getDim().size();
01937 Local lcl = declareLocal(nameGen.newName(), ca.mcgill.sable.soot.ArrayType.v((BaseType) type, dimensions), 0);
01938 currentValue = lcl;
01939 node.getArrayInitializer().apply(this);
01940 currentValue = lcl;
01941 } catch (Exception e) {
01942 exceptions.add(e);
01943 }
01944 }
01945
01946
01947
01948
01949 public void caseAInitPrimitiveExp(AInitPrimitiveExp node) {
01950 node.getPrimitiveType().apply(this);
01951 ca.mcgill.sable.soot.Type primitiveType = currentType;
01952 currentType = null;
01953 int dimensions = node.getDim().size();
01954 Local lcl = declareLocal(nameGen.newName(),
01955 ca.mcgill.sable.soot.ArrayType.v((BaseType) primitiveType, dimensions), 0);
01956 currentValue = lcl;
01957 node.getArrayInitializer().apply(this);
01958 currentValue = lcl;
01959 }
01960
01961
01962
01963
01964 public void caseAInstanceofExp(AInstanceofExp node) {
01965 node.getExp().apply(this);
01966 node.getReferenceType().apply(this);
01967
01968 Local lcl = declareLocal(nameGen.newName(), ca.mcgill.sable.soot.BooleanType.v(), 0);
01969 currentStmts.addElement(jimple.newAssignStmt(lcl, jimple.newInstanceOfExpr(currentValue, currentType)));
01970
01971 currentValue = lcl;
01972 }
01973
01974
01975
01976
01977 public void caseAInterfaceBody(AInterfaceBody node) {
01978
01979 currentThisLocal = null;
01980 instanceLocals = null;
01981 currentValue = null;
01982 currentType = null;
01983 currentName = null;
01984 instanceStmts = null;
01985 nameGen = new NameGenerator();
01986 currentLocalNames = new Hashtable();
01987 currentLocalNamesIterator = new Hashtable();
01988 currentLocals = new Hashtable();
01989 currentStmts = new Vector();
01990 staticLocals = currentLocals;
01991 staticStmts = currentStmts;
01992
01993 LinkedList interfaceMemberDeclList = node.getInterfaceMemberDeclaration();
01994 PInterfaceMemberDeclaration interfaceMemberDecl;
01995 if (interfaceMemberDeclList.size() > 0) {
01996
01997 for (Iterator i = interfaceMemberDeclList.iterator(); i.hasNext();) {
01998 interfaceMemberDecl = (PInterfaceMemberDeclaration) i.next();
01999 if (interfaceMemberDecl instanceof AConstantDeclarationInterfaceMemberDeclaration)
02000 interfaceMemberDecl.apply(this);
02001 }
02002
02003
02004 if (staticStmts.size() > 0) {
02005 SootMethod sootMethod = new SootMethod("<clinit>", new LinkedList(), ca.mcgill.sable.soot.VoidType.v(), Modifier.PUBLIC | Modifier.STATIC);
02006 currentSootClass.addMethod(sootMethod);
02007 JimpleBody body = (JimpleBody) jimple.newBody(sootMethod);
02008 StmtList stmts = body.getStmtList();
02009 for (Enumeration e = staticLocals.elements(); e.hasMoreElements();) {
02010 body.addLocal((Local) e.nextElement());
02011 }
02012 for (int i = 0; i < staticStmts.size(); i++) {
02013 stmts.add(staticStmts.elementAt(i));
02014 }
02015 stmts.add(jimple.newReturnVoidStmt());
02016 sootMethod.storeBody(jimple, body);
02017 }
02018 currentLocals = null;
02019 currentStmts = null;
02020 nameGen = null;
02021 staticLocals = currentLocals;
02022 staticStmts = currentStmts;
02023 instanceLocals = currentLocals;
02024 instanceStmts = currentStmts;
02025
02026
02027 for (Iterator i = interfaceMemberDeclList.iterator(); i.hasNext();) {
02028 interfaceMemberDecl = (PInterfaceMemberDeclaration) i.next();
02029 if (!(interfaceMemberDecl instanceof AConstantDeclarationInterfaceMemberDeclaration))
02030 interfaceMemberDecl.apply(this);
02031 }
02032 }
02033 compiledClasses.addElement(currentSootClass.getName());
02034 }
02035
02036
02037
02038
02039 public void caseAInterfaceDeclaration(AInterfaceDeclaration node) {
02040 try {
02041 currentClassOrInterfaceType = symbolTable.getDeclaredType(new Name(node.getId().toString()));
02042 symbolTable.setCurrentClassOrInterfaceType(currentClassOrInterfaceType);
02043
02044 currentSootClass = getSootClass(currentClassOrInterfaceType.getName().toString());
02045
02046 ClassDeclarationAnnotation cda = new ClassDeclarationAnnotation(node);
02047 LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
02048 cda.setFirstLine(lc.getFirstLine());
02049 cda.setFirstColumn(lc.getFirstColumn());
02050 cda.setLastLine(lc.getLastLine());
02051 cda.setLastColumn(lc.getLastColumn());
02052 cda.setSootClass(currentSootClass);
02053 am.addAnnotation(cda);
02054 am.putFilenameLinePairAnnotation(new FilenameLinePair(currentClassOrInterfaceType.getPath(),
02055 LineExtractor.extractLine(node)), cda);
02056
02057 if (node.getInterfaceBody() != null) {
02058 node.getInterfaceBody().apply(this);
02059 }
02060 compiledClasses.addElement(currentSootClass.getName());
02061 } catch (CompilerException e) {
02062 exceptions.addElement(e);
02063 }
02064
02065 currentClassOrInterfaceType = null;
02066 symbolTable.setCurrentClassOrInterfaceType(null);
02067 currentSootClass = null;
02068 }
02069
02070
02071
02072
02073 public void caseAInterfaceDeclarationClassMemberDeclaration(AInterfaceDeclarationClassMemberDeclaration node) {
02074 System.out.println("Unsupported feature of Java: " + node);
02075 exceptions.addElement(new CompilerException("Unsupported feature of Java: " + node));
02076 throw new Error("Unsupported feature of Java: " + node);
02077 }
02078
02079
02080
02081
02082 public void caseAInterfaceDeclarationInterfaceMemberDeclaration(AInterfaceDeclarationInterfaceMemberDeclaration node) {
02083 System.out.println("Unsupported feature of Java: " + node);
02084 exceptions.addElement(new CompilerException("Unsupported feature of Java: " + node));
02085 throw new Error("Unsupported feature of Java: " + node);
02086 }
02087
02088
02089
02090
02091 public void caseAIntPrimitiveType(AIntPrimitiveType node) {
02092 currentType = ca.mcgill.sable.soot.IntType.v();
02093 }
02094
02095
02096
02097
02098 public void caseALabelStmt(ALabelStmt node) {
02099 LabeledStmtAnnotation ann = new LabeledStmtAnnotation(node);
02100 LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
02101 ann.setFirstLine(lc.getFirstLine());
02102 ann.setFirstColumn(lc.getFirstColumn());
02103 ann.setLastLine(lc.getLastLine());
02104 ann.setLastColumn(lc.getLastColumn());
02105 ann.setId(node.getId().toString().trim());
02106 try {
02107 declareLabel(node.getId().toString().trim());
02108 } catch (CompilerException e) {
02109 exceptions.addElement(e);
02110 return;
02111 }
02112 BlockStmtAnnotation prevAnnotation = currentAnnotation;
02113 currentAnnotation = new BlockStmtAnnotation(node.getBlock());
02114 node.getBlock().apply(this);
02115 ann.setAnnotation(getFirstEnclosedAnnotation(currentAnnotation));
02116 currentAnnotation = prevAnnotation;
02117 currentAnnotation.addAnnotation(ann);
02118 }
02119
02120
02121
02122
02123 public void caseALocalVariableDeclaration(ALocalVariableDeclaration node) {
02124
02125 try {
02126 localAnnotation = new LocalDeclarationStmtAnnotation(node);
02127 LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
02128 localAnnotation.setFirstLine(lc.getFirstLine());
02129 localAnnotation.setFirstColumn(lc.getFirstColumn());
02130 localAnnotation.setLastLine(lc.getLastLine());
02131 localAnnotation.setLastColumn(lc.getLastColumn());
02132 am.putFilenameLinePairAnnotation(
02133 new FilenameLinePair(currentClassOrInterfaceType.getPath(),
02134 LineExtractor.extractLine(node)),
02135 localAnnotation);
02136
02137 int start = currentStmts.size();
02138
02139 int modifiers = Util.convertModifiers(Util.convertModifiers(node.getModifier().toString()));
02140 currentType = null;
02141 node.getType().apply(this);
02142 ca.mcgill.sable.soot.Type localType = currentType;
02143 localAnnotation.setType(localType);
02144 localAnnotation.setModifiers(modifiers);
02145 PVariableDeclarator variableDeclarator;
02146 for (Iterator i = node.getVariableDeclarator().iterator(); i.hasNext();) {
02147 variableDeclarator = (PVariableDeclarator) i.next();
02148 currentType = localType;
02149 variableDeclarator.apply(this);
02150 }
02151 currentType = null;
02152
02153 if (currentAnnotation != null) {
02154 int end = currentStmts.size();
02155
02156 for (int i = start; i < end; i++) {
02157 localAnnotation.addStmt((Stmt) currentStmts.elementAt(i));
02158 }
02159 currentAnnotation.addAnnotation(localAnnotation);
02160 } else {
02161 forInitType = localType;
02162 forInitModifiers = modifiers;
02163 }
02164 localAnnotation = null;
02165 } catch (CompilerException e) {
02166 exceptions.addElement(e);
02167 }
02168 }
02169
02170
02171
02172
02173 public void caseALongPrimitiveType(ALongPrimitiveType node) {
02174 currentType = ca.mcgill.sable.soot.LongType.v();
02175 }
02176
02177
02178
02179
02180 public void caseAMethodDeclaration(AMethodDeclaration node) {
02181 if (CompilationManager.getModifiedMethodTable().get(node) != null) {
02182 ((Node) CompilationManager.getModifiedMethodTable().get(node)).apply(this);
02183 CompilationManager.addDocTriple(new DocTriple(currentSootClass, currentSootMethod, DocProcessor.tags(node, docComments)));
02184 return;
02185 }
02186 methodLine = LineExtractor.extractLine(node);
02187
02188 currentSootMethod = null;
02189 nameGen = new NameGenerator();
02190 currentLocalNames = new Hashtable();
02191 currentLocalNamesIterator = new Hashtable();
02192 currentLocals = new Hashtable();
02193 currentStmts = new Vector();
02194 currentValue = null;
02195 currentType = null;
02196 currentName = null;
02197 currentThisLocal = null;
02198 labels = new LinkedList();
02199 currentAnnotation = new MethodDeclarationAnnotation(node);
02200 LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
02201 currentAnnotation.setFirstLine(lc.getFirstLine());
02202 currentAnnotation.setFirstColumn(lc.getFirstColumn());
02203 currentAnnotation.setLastLine(lc.getLastLine());
02204 currentAnnotation.setLastColumn(lc.getLastColumn());
02205
02206 currentTraps = new Vector();
02207
02208
02209 symbolTable.enterScope();
02210 node.getMethodHeader().apply(this);
02211 node.getMethodBody().apply(this);
02212 symbolTable.exitScope();
02213
02214
02215 StmtList stmts = currentBody.getStmtList();
02216 for (Enumeration e = currentLocals.elements(); e.hasMoreElements();) {
02217 currentBody.addLocal((Local) e.nextElement());
02218 }
02219
02220 for (int i = 0; i < currentStmts.size(); i++) {
02221 stmts.add((Stmt) currentStmts.elementAt(i));
02222 }
02223
02224 Stmt tempStmt = null;
02225 if (currentStmts.size() > 0) {
02226 int size = currentStmts.size();
02227 Stmt lastStmt = (Stmt) currentStmts.elementAt(--size);
02228 if (!(lastStmt instanceof JReturnStmt) && !(lastStmt instanceof JReturnVoidStmt)
02229 && !(lastStmt instanceof JThrowStmt)) {
02230 tempStmt = jimple.newReturnVoidStmt();
02231 stmts.add(tempStmt);
02232 SequentialAnnotation ann = new SequentialAnnotation(null);
02233 ann.addStmt(tempStmt);
02234 currentAnnotation.addAnnotation(ann);
02235 }
02236 } else {
02237 SequentialAnnotation ann = new SequentialAnnotation(null);
02238 Stmt stmt = jimple.newReturnVoidStmt();
02239 ann.addStmt(stmt);
02240 stmts.add(stmt);
02241 currentAnnotation.addAnnotation(ann);
02242 }
02243
02244 for (Enumeration e = currentTraps.elements(); e.hasMoreElements();) {
02245 currentBody.addTrap((Trap) e.nextElement());
02246 }
02247
02248 am.addAnnotation(currentSootClass, currentSootMethod, currentAnnotation);
02249
02250
02251 if (!(currentSootMethod.getReturnType() instanceof ca.mcgill.sable.soot.VoidType)) {
02252 addRetIfNecessary(currentBody, currentSootMethod.getReturnType());
02253 }
02254 convertLocalTypes(currentBody);
02255 TemporaryLocalsReduction.reduce(currentBody, currentAnnotation);
02256 DeadCodeElimination.eliminate(currentBody);
02257 JumpElimination.eliminate(currentBody);
02258 DeadCodeEliminator.eliminateDeadCode(currentBody);
02259 DeadCodeElimination.eliminate(currentBody);
02260 Transformations.removeUnusedLocals(currentBody);
02261 patchBody(currentBody);
02262
02263
02264 currentAnnotation.validate(currentBody);
02265
02266 currentSootMethod.storeBody(jimple, currentBody);
02267 am.putFilenameLinePairAnnotation(new FilenameLinePair(currentClassOrInterfaceType.getPath(),
02268 LineExtractor.extractLine(node)), currentAnnotation);
02269
02270 if (!Modifier.isAbstract(currentSootMethod.getModifiers()))
02271 CompilationManager.addDocTriple(new DocTriple(currentSootClass, currentSootMethod, DocProcessor.tags(node, docComments)));
02272
02273
02274 nameGen = null;
02275 currentLocals = null;
02276 currentLocalNames = null;
02277 currentLocalNamesIterator = null;
02278 currentStmts = null;
02279 currentValue = null;
02280 currentType = null;
02281 currentName = null;
02282 currentThisLocal = null;
02283 currentBody = null;
02284 labels = null;
02285 currentTraps = null;
02286 currentAnnotation = null;
02287 }
02288
02289
02290
02291
02292 public void caseAMethodDeclarator(AMethodDeclarator node) {
02293
02294 String methodName = node.getId().toString().trim();
02295
02296 try {
02297
02298 Vector formalParameters = new Vector();
02299 for (Iterator i = node.getFormalParameter().iterator(); i.hasNext();) {
02300 ((PFormalParameter) i.next()).apply(this);
02301 formalParameters.addElement(Util.convertType(currentType, symbolTable));
02302 currentType = null;
02303 }
02304
02305 currentSootMethod = getSootMethod(currentSootClass.getName(), methodName, formalParameters);
02306 ((MethodDeclarationAnnotation) currentAnnotation).setSootMethod(currentSootMethod);
02307 ((MethodDeclarationAnnotation) currentAnnotation).setMethod(currentClassOrInterfaceType.getMethod(new Name(methodName), formalParameters));
02308
02309 if (!isInterface) {
02310 currentBody = (JimpleBody) jimple.newBody(currentSootMethod);
02311
02312 int methodModifiers = currentSootMethod.getModifiers();
02313
02314 if (!Modifier.isStatic(methodModifiers) && !Modifier.isAbstract(methodModifiers) && !Modifier.isNative(methodModifiers)) {
02315 String thisName = nameGen.newName();
02316 currentThisLocal = declareLocal(thisName, ca.mcgill.sable.soot.RefType.v(currentSootClass.getName()), 0);
02317 currentLocals.put(currentThisLocal.getName(), currentThisLocal);
02318
02319 SequentialAnnotation sann = new SequentialAnnotation(null);
02320 Stmt stmt = jimple.newIdentityStmt(currentThisLocal, jimple.newThisRef(currentSootClass));
02321 currentStmts.addElement(stmt);
02322 sann.addStmt(stmt);
02323 currentAnnotation.addAnnotation(sann);
02324 }
02325
02326
02327 if (!Modifier.isAbstract(methodModifiers) && !Modifier.isNative(methodModifiers)) {
02328 Method m = currentClassOrInterfaceType.getMethod(new Name(methodName), formalParameters);
02329
02330 SequentialAnnotation sann = new SequentialAnnotation(null);
02331
02332 int paramNum = 0;
02333 for (Enumeration e = m.getParameters().elements(); e.hasMoreElements(); paramNum++) {
02334 Variable v = (Variable) e.nextElement();
02335 Local tempLocal = declareLocal(v.getName().toString(), Util.convertType(v.getType()),
02336 Util.convertModifiers(v.getModifiers()));
02337 Stmt stmt = jimple.newIdentityStmt(tempLocal, jimple.newParameterRef(currentSootMethod, paramNum));
02338 currentStmts.addElement(stmt);
02339 sann.addStmt(stmt);
02340 }
02341
02342 currentAnnotation.addAnnotation(sann);
02343 }
02344 }
02345 } catch (CompilerException e) {
02346 exceptions.addElement(e);
02347 }
02348 }
02349
02350
02351
02352
02353 public void caseANameArrayAccess(ANameArrayAccess node) {
02354 String arrayName = (new Name(node.getName().toString())).toString();
02355 node.getExp().apply(this);
02356 Value index = currentValue;
02357 currentValue = null;
02358 if ((node.parent() instanceof AArrayAccessLeftHandSide) || assignExp) {
02359 nameExp(false, arrayName);
02360 currentValue = jimple.newArrayRef(currentValue, index);
02361 } else {
02362 nameExp(false, arrayName);
02363 currentValue = jimple.newArrayRef(currentValue, index);
02364 Local lcl = declareLocal(nameGen.newName(), currentValue.getType(), 0);
02365 currentStmts.addElement(jimple.newAssignStmt(lcl, currentValue));
02366 currentValue = lcl;
02367 }
02368 assignExp = false;
02369 }
02370
02371
02372
02373
02374 public void caseANameArrayType(ANameArrayType node) {
02375 try {
02376 ca.mcgill.sable.soot.BaseType temp =
02377 ca.mcgill.sable.soot.RefType.v(getSootClass(node.getName().toString().trim()).getName());
02378 currentType = ca.mcgill.sable.soot.ArrayType.v(temp, node.getDim().size());
02379 } catch (CompilerException e) {
02380 exceptions.addElement(e);
02381 }
02382 }
02383
02384
02385
02386
02387 public void caseANameCastExp(ANameCastExp node) {
02388 try {
02389 String className = (new Name(node.getName().toString())).toString();
02390 SootClass sc = getSootClass(className);
02391 className = sc.getName();
02392 ca.mcgill.sable.soot.Type type = ca.mcgill.sable.soot.RefType.v(className);
02393 int dimensions = node.getDim().size();
02394 if (dimensions != 0) {
02395 type = ca.mcgill.sable.soot.ArrayType.v((ca.mcgill.sable.soot.BaseType) type, dimensions);
02396 }
02397 node.getExp().apply(this);
02398 Value castedValue = currentValue;
02399 currentValue = null;
02400 Local lcl = declareLocal(nameGen.newName(), type, 0);
02401 currentStmts.addElement(jimple.newAssignStmt(lcl, jimple.newCastExpr(castedValue, type)));
02402 currentValue = lcl;
02403 } catch (CompilerException e) {
02404 exceptions.addElement(e);
02405 }
02406 }
02407
02408
02409
02410
02411 public void caseANamedTypeExp(ANamedTypeExp node) {
02412 System.out.println("Unsupported feature of Java: " + node);
02413 exceptions.addElement(new CompilerException("Unsupported feature of Java: " + node));
02414 throw new Error("Unsupported feature of Java: " + node);
02415 }
02416
02417
02418
02419
02420 public void caseANameExp(ANameExp node) {
02421 nameExp(node.parent() instanceof ANameLeftHandSide, (new Name(node.getName().toString())).toString());
02422 }
02423
02424
02425
02426
02427 public void caseANameLeftHandSide(ANameLeftHandSide node) {
02428 nameExp(true, (new Name(node.getName().toString())).toString());
02429 }
02430
02431
02432
02433
02434 public void caseANameMethodInvocationExp(ANameMethodInvocationExp node) {
02435 try {
02436 String methodName = (new Name(node.getName().toString())).toString();
02437 LinkedList args = new LinkedList();
02438 currentValue = null;
02439 Vector types = new Vector();
02440 {
02441 Object temp[] = node.getArgumentList().toArray();
02442 for (int i = 0; i < temp.length; i++) {
02443 ((PExp) temp[i]).apply(this);
02444 args.addLast(currentValue);
02445 if (currentValue instanceof IntConstant) {
02446 types.addElement(integralConstantType);
02447 } else {
02448 types.addElement(Util.convertType(currentValue instanceof ConditionExpr ? ca.mcgill.sable.soot.BooleanType.v() : currentValue.getType(), symbolTable));
02449 }
02450 currentValue = null;
02451 }
02452 }
02453 methodInvocation(methodName, args, types, false);
02454 } catch (CompilerException e) {
02455 exceptions.addElement(e);
02456 }
02457 }
02458
02459
02460
02461
02462 public void caseANameReferenceType(ANameReferenceType node) {
02463 try {
02464 currentType = ca.mcgill.sable.soot.RefType.v(getSootClass(node.getName().toString().trim()).getName());
02465 } catch (CompilerException e) {
02466 exceptions.addElement(e);
02467 }
02468 }
02469
02470
02471
02472
02473 public void caseANullLiteral(ANullLiteral node) {
02474 currentValue = NullConstant.v();
02475 }
02476
02477
02478
02479
02480 public void caseAOctalIntegerLiteral(AOctalIntegerLiteral node) {
02481 String literal = node.toString().substring(1).trim();
02482 if (literal.endsWith("L") || literal.endsWith("l")) {
02483 currentValue = LongConstant.v(new BigInteger(literal.substring(0, literal.length() - 1), 8).longValue());
02484 integralConstantType = edu.ksu.cis.bandera.jjjc.symboltable.LongType.TYPE;
02485 } else {
02486 currentValue = IntConstant.v(Long.valueOf(literal, 8).intValue());
02487 integralConstantType = edu.ksu.cis.bandera.jjjc.symboltable.IntType.TYPE;
02488 }
02489 }
02490
02491
02492
02493
02494 public void caseAPostDecrementExp(APostDecrementExp node) {
02495 postIncDecExp(node, false);
02496 }
02497
02498
02499
02500
02501 public void caseAPostIncrementExp(APostIncrementExp node) {
02502 postIncDecExp(node, true);
02503 }
02504
02505
02506
02507
02508 public void caseAPrimaryFieldAccess(APrimaryFieldAccess node) {
02509 node.getExp().apply(this);
02510 if (currentValue.getType() instanceof RefType) {
02511 try {
02512 boolean isAssign = assignExp;
02513 assignExp = false;
02514 fieldAccess((node.parent() instanceof AFieldAccessLeftHandSide) || isAssign, currentValue,
02515 (currentValue == currentThisLocal) ? currentSootClass.getName() : ((RefType) currentValue.getType()).className,
02516 node.getId().toString().trim());
02517 } catch (CompilerException e) {
02518 exceptions.addElement(e);
02519 }
02520 } else {
02521 if ("length".equals(node.getId().toString().trim())) {
02522 currentValue = jimple.newLengthExpr(currentValue);
02523 Local lcl = declareLocal(nameGen.newName(), currentValue.getType(), 0);
02524 currentStmts.addElement(jimple.newAssignStmt(lcl, currentValue));
02525 currentValue = lcl;
02526 } else {
02527 exceptions.addElement(new CompilerException("Arrays does not have field " + node.getId() + " in expression " + node));
02528 currentValue = IntConstant.v(0);
02529 }
02530 }
02531 }
02532
02533
02534
02535
02536 public void caseAPrimaryMethodInvocationExp(APrimaryMethodInvocationExp node) {
02537 try {
02538 node.getExp().apply(this);
02539 Value caller = currentValue;
02540 currentValue = null;
02541 LinkedList args = new LinkedList();
02542 Vector types = new Vector();
02543 {
02544 Object temp[] = node.getArgumentList().toArray();
02545 for (int i = 0; i < temp.length; i++) {
02546 ((PExp) temp[i]).apply(this);
02547 args.addLast(currentValue);
02548 if (currentValue instanceof IntConstant) {
02549 types.addElement(integralConstantType);
02550 } else {
02551 types.addElement(Util.convertType(currentValue instanceof ConditionExpr ? ca.mcgill.sable.soot.BooleanType.v() : currentValue.getType(), symbolTable));
02552 }
02553 currentValue = null;
02554 }
02555 }
02556 String methodName = node.getId().toString().trim();
02557 methodInvoke(caller, ((RefType) caller.getType()).className, methodName, args, types, false);
02558 } catch (CompilerException e) {
02559 exceptions.addElement(e);
02560 }
02561 }
02562
02563
02564
02565
02566 public void caseAPrimaryNoNewArrayArrayAccess(APrimaryNoNewArrayArrayAccess node) {
02567 node.getFirst().apply(this);
02568 Value first = currentValue;
02569 currentValue = null;
02570 node.getSecond().apply(this);
02571 if (node.parent() instanceof AArrayAccessLeftHandSide){
02572 currentValue = jimple.newArrayRef(first, currentValue);
02573 } else {
02574 currentValue = jimple.newArrayRef(first, currentValue);
02575 Local lcl = declareLocal(nameGen.newName(), currentValue.getType(), 0);
02576 currentStmts.addElement(jimple.newAssignStmt(lcl, currentValue));
02577 currentValue = lcl;
02578 }
02579 }
02580
02581
02582
02583
02584 public void caseAPrimitiveArrayType(APrimitiveArrayType node) {
02585 node.getPrimitiveType().apply(this);
02586
02587 ca.mcgill.sable.soot.BaseType temp = (ca.mcgill.sable.soot.BaseType) currentType;
02588 currentType = ca.mcgill.sable.soot.ArrayType.v(temp, node.getDim().size());
02589 }
02590
02591
02592
02593
02594 public void caseAPrimitiveTypeArrayExp(APrimitiveTypeArrayExp node) {
02595 node.getPrimitiveType().apply(this);
02596 ca.mcgill.sable.soot.Type primitiveType = currentType;
02597 currentType = null;
02598 LinkedList arrayExps = new LinkedList();
02599 int dimensions = 0;
02600 for (Iterator i = node.getDimExp().iterator(); i.hasNext();) {
02601 ((PDimExp) i.next()).apply(this);
02602 arrayExps.addLast(currentValue);
02603 currentValue = null;
02604 dimensions++;
02605 }
02606 dimensions += node.getDim().size();
02607 if (dimensions == 1) {
02608 currentValue = jimple.newNewArrayExpr(primitiveType, (Value) arrayExps.removeFirst());
02609 } else {
02610 currentType = ca.mcgill.sable.soot.ArrayType.v((ca.mcgill.sable.soot.BaseType) primitiveType, dimensions);
02611 currentValue = jimple.newNewMultiArrayExpr((ca.mcgill.sable.soot.ArrayType) currentType, arrayExps);
02612 currentType = null;
02613 }
02614 Value newValue = currentValue;
02615 currentValue = null;
02616 Local lcl = declareLocal(nameGen.newName(), newValue.getType(), 0);
02617 currentStmts.addElement(jimple.newAssignStmt(lcl, newValue));
02618 currentValue = lcl;
02619 currentType = lcl.getType();
02620 }
02621
02622
02623
02624
02625 public void caseAPrimitiveTypeCastExp(APrimitiveTypeCastExp node) {
02626 node.getPrimitiveType().apply(this);
02627 int dimensions = node.getDim().size();
02628 if (dimensions != 0) {
02629 currentType = ca.mcgill.sable.soot.ArrayType.v((ca.mcgill.sable.soot.BaseType) currentType, dimensions);
02630 }
02631 node.getExp().apply(this);
02632 Local lcl = declareLocal(nameGen.newName(), currentType, 0);
02633 currentStmts.addElement(jimple.newAssignStmt(lcl, jimple.newCastExpr(currentValue, currentType)));
02634 currentValue = lcl;
02635 }
02636
02637
02638
02639
02640 public void caseAPrimitiveTypePrimaryExp(APrimitiveTypePrimaryExp node) {
02641 System.out.println("Unsupported feature of Java: " + node);
02642 exceptions.addElement(new CompilerException("Unsupported feature of Java: " + node));
02643 throw new Error("Unsupported feature of Java: " + node);
02644 }
02645
02646
02647
02648
02649 public void caseAQualifiedClassInstanceCreationExp(AQualifiedClassInstanceCreationExp node) {
02650 System.out.println("Unsupported feature of Java: " + node);
02651 exceptions.addElement(new CompilerException("Unsupported feature of Java: " + node));
02652 throw new Error("Unsupported feature of Java: " + node);
02653 }
02654
02655
02656
02657
02658 public void caseAQualifiedConstructorInvocation(AQualifiedConstructorInvocation node) {
02659 System.out.println("Unsupported feature of Java: " + node);
02660 exceptions.addElement(new CompilerException("Unsupported feature of Java: " + node));
02661 throw new Error("Unsupported feature of Java: " + node);
02662 }
02663
02664
02665
02666
02667 public void caseAQualifiedThisExp(AQualifiedThisExp node) {
02668 System.out.println("Unsupported feature of Java: " + node);
02669 exceptions.addElement(new CompilerException("Unsupported feature of Java: " + node));
02670 throw new Error("Unsupported feature of Java: " + node);
02671 }
02672
02673
02674
02675
02676 public void caseAQuestionExp(AQuestionExp node) {
02677 Stmt thenStmt = jimple.newNopStmt();
02678 Stmt elseStmt = jimple.newNopStmt();
02679 Stmt endStmt = jimple.newNopStmt();
02680 Stmt prevTrueBranch = trueBranch;
02681 Stmt prevFalseBranch = falseBranch;
02682 trueBranch = elseStmt;
02683 falseBranch = thenStmt;
02684 Node n = new AUnaryExp(new AComplementUnaryOperator(new TComplement()), (PExp) node.getFirst().clone());
02685 PushComplement.push(n);
02686 n = ((AUnaryExp) n).getExp();
02687 n.apply(new BooleanExpression(this, trueBranch, falseBranch));
02688 currentStmts.addElement(thenStmt);
02689 trueBranch = falseBranch = null;
02690 node.getSecond().apply(this);
02691 boolean nullConstant = currentValue.getType() instanceof ca.mcgill.sable.soot.NullType;
02692 Local lcl = declareLocal(nameGen.newName(), currentValue.getType(), 0);
02693 currentStmts.addElement(jimple.newAssignStmt(lcl, currentValue));
02694 currentStmts.addElement(jimple.newGotoStmt(endStmt));
02695 currentStmts.addElement(elseStmt);
02696 node.getThird().apply(this);
02697 if (!(currentValue.getType() instanceof ca.mcgill.sable.soot.NullType) && nullConstant) {
02698 lcl.setType(currentValue.getType());
02699 }
02700 currentStmts.addElement(jimple.newAssignStmt(lcl, currentValue));
02701 currentStmts.addElement(endStmt);
02702 currentValue = lcl;
02703
02704 trueBranch = prevTrueBranch;
02705 falseBranch = prevFalseBranch;
02706 }
02707
02708
02709
02710
02711 public void caseAReturnStmt(AReturnStmt node) {
02712 int start = currentStmts.size();
02713
02714 if (node.getExp() == null) {
02715 if (!(currentSootMethod.getReturnType() instanceof ca.mcgill.sable.soot.VoidType))
02716 exceptions.addElement(new CompilerException("Method " + currentSootMethod.getName() + " should return a value"));
02717 for (Enumeration e = synchAnnotations.elements(); e.hasMoreElements();) {
02718 SynchronizedStmtAnnotation sann = (SynchronizedStmtAnnotation) e.nextElement();
02719 Stmt exitMon = jimple.newExitMonitorStmt(sann.getLockValue());
02720 sann.addExitMonitor(exitMon);
02721 currentStmts.addElement(exitMon);
02722 }
02723 currentStmts.addElement(jimple.newReturnVoidStmt());
02724 } else {
02725 node.getExp().apply(this);
02726 boolean f = true;
02727 if (currentValue instanceof Local) {
02728 f = !"$ret".equals(((Local) currentValue).getName().trim());
02729 }
02730 if (f) {
02731 Value exp = currentValue;
02732 currentValue = null;
02733 Local lcl = declareLocal("$ret", exp.getType(), 0);
02734 currentStmts.addElement(jimple.newAssignStmt(lcl, exp));
02735 currentValue = lcl;
02736 }
02737 for (Enumeration e = synchAnnotations.elements(); e.hasMoreElements();) {
02738 SynchronizedStmtAnnotation sann = (SynchronizedStmtAnnotation) e.nextElement();
02739 Stmt exitMon = jimple.newExitMonitorStmt(sann.getLockValue());
02740 sann.addExitMonitor(exitMon);
02741 currentStmts.addElement(exitMon);
02742 }
02743 currentStmts.addElement(jimple.newReturnStmt(currentValue));
02744 }
02745
02746 int end = currentStmts.size();
02747 ReturnStmtAnnotation ann = new ReturnStmtAnnotation(node);
02748 LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
02749 ann.setFirstLine(lc.getFirstLine());
02750 ann.setFirstColumn(lc.getFirstColumn());
02751 ann.setLastLine(lc.getLastLine());
02752 ann.setLastColumn(lc.getLastColumn());
02753 am.putFilenameLinePairAnnotation(
02754 new FilenameLinePair(currentClassOrInterfaceType.getPath(),
02755 LineExtractor.extractLine(node)),
02756 ann);
02757
02758 for (int i = start; i < end; i++) {
02759 ann.addStmt((Stmt) currentStmts.elementAt(i));
02760 }
02761 currentAnnotation.addAnnotation(ann);
02762 }
02763
02764
02765
02766
02767 public void caseAShortPrimitiveType(AShortPrimitiveType node) {
02768 currentType = ca.mcgill.sable.soot.ShortType.v();
02769 }
02770
02771
02772
02773
02774 public void caseASimpleClassInstanceCreationExp(ASimpleClassInstanceCreationExp node) {
02775 try {
02776 SootClass sc = getSootClass((new Name(node.getName().toString())).toString());
02777 String className = sc.getName();
02778 Local lcl = declareLocal(nameGen.newName(), ca.mcgill.sable.soot.RefType.v(className), 0);
02779 currentStmts.addElement(jimple.newAssignStmt(lcl, jimple.newNewExpr(ca.mcgill.sable.soot.RefType.v(className))));
02780 currentValue = null;
02781 LinkedList args = new LinkedList();
02782 Vector argTypes = new Vector();
02783 {
02784 Object temp[] = node.getArgumentList().toArray();
02785 for (int i = 0; i < temp.length; i++) {
02786 ((PExp) temp[i]).apply(this);
02787 args.addLast(currentValue);
02788 if (currentValue instanceof IntConstant) {
02789 argTypes.addElement(integralConstantType);
02790 } else {
02791 argTypes.addElement(Util.convertType(currentValue.getType(), symbolTable));
02792 }
02793 currentValue = null;
02794 }
02795 }
02796 SootMethod sm = getSootMethod(className, "<init>", argTypes);
02797 currentStmts.addElement(jimple.newInvokeStmt(jimple.newSpecialInvokeExpr(lcl, sm, args)));
02798
02799 for (java.util.Iterator i = CompilationManager.getQuantifiers().iterator(); i.hasNext();) {
02800
02801 QuantifiedVariable q = (QuantifiedVariable) i.next();
02802 if (q.isExact()) {
02803 if (q.getType().toString().equals(sc.getName())) {
02804 inlineAvailable(q, lcl);
02805 }
02806 } else {
02807 if (isSubtypeOf(className, q.getType().toString())) {
02808 inlineAvailable(q, lcl);
02809 }
02810 }
02811 }
02812
02813 currentValue = lcl;
02814 } catch (CompilerException e) {
02815 exceptions.addElement(e);
02816 }
02817 }
02818
02819
02820
02821
02822 public void caseAStaticInitializerClassBodyDeclaration(AStaticInitializerClassBodyDeclaration node) {
02823 if (clinit == null) {
02824 clinit = new SootMethod("<clinit>", new LinkedList(), ca.mcgill.sable.soot.VoidType.v(),
02825 Modifier.PUBLIC | Modifier.STATIC);
02826 clinitBody = (JimpleBody) jimple.newBody(clinit);
02827 }
02828
02829 currentSootMethod = clinit;
02830 currentBody = clinitBody;
02831 currentLocalNames = new Hashtable();
02832 currentLocalNamesIterator = new Hashtable();
02833 currentLocals = staticLocals;
02834 currentStmts = staticStmts;
02835 currentValue = null;
02836 currentType = null;
02837 currentName = null;
02838 labels = new LinkedList();
02839 currentAnnotation = new StaticInitializerAnnotation(node);
02840 LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
02841 currentAnnotation.setFirstLine(lc.getFirstLine());
02842 currentAnnotation.setFirstColumn(lc.getFirstColumn());
02843 currentAnnotation.setLastLine(lc.getLastLine());
02844 currentAnnotation.setLastColumn(lc.getLastColumn());
02845 currentTraps = new Vector();
02846
02847 node.getBlock().apply(this);
02848
02849 for (Enumeration e = currentTraps.elements(); e.hasMoreElements();) {
02850 clinitBody.addTrap((JTrap) e.nextElement());
02851 }
02852
02853 currentLocals = null;
02854 currentLocalNames = null;
02855 currentLocalNamesIterator = null;
02856 currentStmts = null;
02857 currentValue = null;
02858 currentType = null;
02859 currentName = null;
02860 currentBody = null;
02861 labels = null;
02862 currentTraps = null;
02863 currentSootMethod = null;
02864
02865 am.addAnnotation(currentSootClass, "static initializer " + staticInitializers++, currentAnnotation);
02866 currentAnnotation = null;
02867 }
02868
02869
02870
02871
02872 public void caseAStringLiteralLiteral(AStringLiteralLiteral node) {
02873 currentValue = StringConstant.v(Util.decodeString(node.toString().trim()));
02874 }
02875
02876
02877
02878
02879 public void caseASuperConstructorInvocation(ASuperConstructorInvocation node) {
02880 SuperConstructorInvocationStmtAnnotation ann = new SuperConstructorInvocationStmtAnnotation(node);
02881 LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
02882 ann.setFirstLine(lc.getFirstLine());
02883 ann.setFirstColumn(lc.getFirstColumn());
02884 ann.setLastLine(lc.getLastLine());
02885 ann.setLastColumn(lc.getLastColumn());
02886 try {
02887 LinkedList args = new LinkedList();
02888 Vector types = new Vector();
02889 currentValue = null;
02890 for (Iterator i = node.getArgumentList().iterator(); i.hasNext();) {
02891 ((PExp) i.next()).apply(this);
02892 args.addLast(currentValue);
02893 if (currentValue instanceof IntConstant)
02894 types.addElement(integralConstantType);
02895 else
02896 types.addElement(Util.convertType(currentValue instanceof ConditionExpr ? ca.mcgill.sable.soot.BooleanType.v() : currentValue.getType(), symbolTable));
02897 currentValue = null;
02898 }
02899 SootMethod sm = getSootMethod(currentSootClass.getSuperClass().getName(), "<init>", types);
02900 Stmt stmt = jimple.newInvokeStmt(jimple.newSpecialInvokeExpr(currentThisLocal, sm, args));
02901 currentStmts.addElement(stmt);
02902 ann.addStmt(stmt);
02903 } catch (CompilerException e) {
02904 exceptions.addElement(e);
02905 }
02906 currentAnnotation.addAnnotation(ann);
02907 }
02908
02909
02910
02911
02912 public void caseASuperFieldAccess(ASuperFieldAccess node) {
02913 try {
02914 fieldAccess(node.parent() instanceof AFieldAccessLeftHandSide, currentThisLocal,
02915 currentSootClass.getSuperClass().getName(), node.getId().toString().trim());
02916 } catch (CompilerException e) {
02917 exceptions.addElement(e);
02918 }
02919 }
02920
02921
02922
02923
02924 public void caseASuperMethodInvocationExp(ASuperMethodInvocationExp node) {
02925 try {
02926 String methodName = node.getId().toString().trim();
02927 String className = currentSootClass.getSuperClass().getName();
02928 Value caller = currentThisLocal;
02929 currentValue = null;
02930 LinkedList args = new LinkedList();
02931 Object temp[] = node.getArgumentList().toArray();
02932 Vector types = new Vector();
02933 for (int i = 0; i < temp.length; i++) {
02934 ((PExp) temp[i]).apply(this);
02935 args.addLast(currentValue);
02936 if (currentValue instanceof IntConstant) {
02937 types.addElement(integralConstantType);
02938 } else {
02939 types.addElement(Util.convertType(currentValue instanceof ConditionExpr ? ca.mcgill.sable.soot.BooleanType.v() : currentValue.getType(), symbolTable));
02940 }
02941 }
02942 currentValue = null;
02943 methodInvoke(caller, className, methodName, args, types, true);
02944 } catch (CompilerException e) {
02945 exceptions.addElement(e);
02946 }
02947 }
02948
02949
02950
02951
02952 public void caseASwitchStmt(ASwitchStmt node) {
02953 LinkedList prevLookupValues = currentLookupValues;
02954 LinkedList prevTargets = currentTargets;
02955 Stmt prevDefaultStmt = currentDefaultStmt;
02956 boolean prevDefaultSwitch = defaultSwitch;
02957
02958 SwitchStmtAnnotation ann = new SwitchStmtAnnotation(node);
02959 LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
02960 ann.setFirstLine(lc.getFirstLine());
02961 ann.setFirstColumn(lc.getFirstColumn());
02962 ann.setLastLine(lc.getLastLine());
02963 ann.setLastColumn(lc.getLastColumn());
02964 am.putFilenameLinePairAnnotation(
02965 new FilenameLinePair(currentClassOrInterfaceType.getPath(),
02966 LineExtractor.extractLine(node)),
02967 ann);
02968 BlockStmtAnnotation prevAnnotation = currentAnnotation;
02969
02970 Stmt startStmt = jimple.newNopStmt();
02971 Stmt endStmt = jimple.newNopStmt();
02972 currentTargets = new LinkedList();
02973 currentDefaultStmt = endStmt;
02974 Stmt prevBreakTarget = currentBreakTarget;
02975 Stmt prevContinueTarget = currentContinueTarget;
02976 currentBreakTarget = endStmt;
02977 currentContinueTarget = endStmt;
02978 currentStmts.addElement(startStmt);
02979
02980
02981 int start = currentStmts.size();
02982
02983 node.getExp().apply(this);
02984
02985 int end = currentStmts.size();
02986
02987 for (int i = start; i < end; i++) {
02988 ann.addStmt((Stmt) currentStmts.elementAt(i));
02989 }
02990
02991 Value switchValue = currentValue;
02992 currentValue = null;
02993 Vector tempStmts;
02994 LinkedList casesStmts = new LinkedList();
02995
02996 currentLookupValues = new LinkedList();
02997
02998 for (Iterator i = node.getSwitchBlockStmtGroup().iterator(); i.hasNext();) {
02999 defaultSwitch = false;
03000 ASwitchBlockStmtGroup switchBlockStmtGroup = (ASwitchBlockStmtGroup) i.next();
03001 tempStmts = currentStmts;
03002 currentStmts = new Vector();
03003
03004 currentAnnotation = new BlockStmtAnnotation(switchBlockStmtGroup);
03005
03006 for (Iterator j = switchBlockStmtGroup.getBlockedStmt().iterator(); j.hasNext();) {
03007 ((PBlockedStmt) j.next()).apply(this);
03008 }
03009
03010 Stmt caseStmt = jimple.newNopStmt();
03011 casesStmts.addLast(caseStmt);
03012 for (int k = 0; k < currentStmts.size(); k++) {
03013 casesStmts.addLast(currentStmts.elementAt(k));
03014 }
03015 currentStmts = tempStmts;
03016
03017 for (Iterator j = switchBlockStmtGroup.getSwitchLabel().iterator(); j.hasNext();) {
03018 boolean tempDefault = defaultSwitch;
03019
03020 ((PSwitchLabel) j.next()).apply(this);
03021
03022 if (tempDefault == defaultSwitch) {
03023 currentTargets.addLast(caseStmt);
03024 ann.addSwitchCase((Integer) currentLookupValues.getLast(), currentAnnotation);
03025 } else {
03026 currentDefaultStmt = caseStmt;
03027 ann.setDefaultAnnotation(currentAnnotation);
03028 }
03029 }
03030 }
03031 Stmt caseStmt = endStmt;
03032 for (Iterator i = node.getSwitchLabel().iterator(); i.hasNext();) {
03033 boolean tempDefault = defaultSwitch;
03034 ((PSwitchLabel) i.next()).apply(this);
03035 if (tempDefault == defaultSwitch)
03036 currentTargets.addLast(caseStmt);
03037 else {
03038 currentDefaultStmt = caseStmt;
03039 }
03040 }
03041
03042 Stmt stmt = jimple.newLookupSwitchStmt(switchValue, currentLookupValues, currentTargets, currentDefaultStmt);
03043 currentStmts.addElement(stmt);
03044 ann.addStmt(stmt);
03045
03046 currentLookupValues = null;
03047 currentTargets = null;
03048 currentDefaultStmt = null;
03049 defaultSwitch = false;
03050 for (Iterator i = casesStmts.iterator(); i.hasNext();) {
03051 currentStmts.addElement(i.next());
03052 }
03053 currentStmts.addElement(endStmt);
03054 currentValue = null;
03055 currentBreakTarget = prevBreakTarget;
03056 currentContinueTarget = prevContinueTarget;
03057
03058 currentAnnotation = prevAnnotation;
03059 currentAnnotation.addAnnotation(ann);
03060
03061 currentLookupValues = prevLookupValues;
03062 currentTargets = prevTargets;
03063 currentDefaultStmt = prevDefaultStmt;
03064 defaultSwitch = prevDefaultSwitch;
03065 }
03066
03067
03068
03069
03070 public void caseASynchronizedModifier(ASynchronizedModifier node) {
03071 node.getSynchronized();
03072 }
03073
03074
03075
03076
03077 public void caseASynchronizedStmt(ASynchronizedStmt node) {
03078 try {
03079 SynchronizedStmtAnnotation ann = new SynchronizedStmtAnnotation(node);
03080 LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
03081 ann.setFirstLine(lc.getFirstLine());
03082 ann.setFirstColumn(lc.getFirstColumn());
03083 ann.setLastLine(lc.getLastLine());
03084 ann.setLastColumn(lc.getLastColumn());
03085 int ln = LineExtractor.extractLine(node);
03086 if (ln <= 0) ln = methodLine;
03087 am.putFilenameLinePairAnnotation(
03088 new FilenameLinePair(currentClassOrInterfaceType.getPath(),
03089 ln),
03090 ann);
03091
03092 Stmt beginStmt = jimple.newNopStmt();
03093 Stmt stmt1 = jimple.newNopStmt();
03094 Stmt stmt2 = jimple.newNopStmt();
03095 Stmt endStmt = jimple.newNopStmt();
03096 Stmt gotoStmt = jimple.newGotoStmt(endStmt);
03097 currentStmts.addElement(beginStmt);
03098
03099 int start = currentStmts.size();
03100 if (node.getExp() != null)
03101 node.getExp().apply(this);
03102
03103 Value lockValue = currentValue;
03104
03105 ann.setLockValue(lockValue);
03106
03107 Stmt enterMonitor = jimple.newEnterMonitorStmt(lockValue);
03108 Stmt exitMonitor = jimple.newExitMonitorStmt(lockValue);
03109
03110 ann.setEnterMonitor(enterMonitor);
03111 ann.addExitMonitor(exitMonitor);
03112
03113 synchAnnotations.insertElementAt(ann, 0);
03114 finallyAndSynch.insertElementAt(ann, 0);
03115
03116 currentValue = null;
03117 currentStmts.addElement(enterMonitor);
03118 int end = currentStmts.size();
03119
03120 for (int i = start; i < end; i++) {
03121 ann.addStmt((Stmt) currentStmts.elementAt(i));
03122 }
03123
03124 currentStmts.addElement(stmt1);
03125
03126 if (node.getBlock() != null) {
03127 BlockStmtAnnotation prevAnnotation = currentAnnotation;
03128 currentAnnotation = new BlockStmtAnnotation(node.getBlock());
03129
03130 node.getBlock().apply(this);
03131
03132 ann.setBlockAnnotation(currentAnnotation);
03133 currentAnnotation = prevAnnotation;
03134 } else {
03135 ann.setBlockAnnotation(new BlockStmtAnnotation(null));
03136 }
03137
03138 Stmt lastStmt = (Stmt) currentStmts.lastElement();
03139
03140 boolean f = false;
03141 if ((lastStmt instanceof ReturnStmt) || (lastStmt instanceof ReturnVoidStmt)
03142 || (lastStmt instanceof ThrowStmt) || (lastStmt instanceof GotoStmt)) {
03143 f = true;
03144 stmt2 = lastStmt;
03145 } else {
03146 currentStmts.addElement(stmt2);
03147 SequentialAnnotation seqann = new SequentialAnnotation(null);
03148 seqann.addStmt(exitMonitor);
03149 seqann.addStmt(gotoStmt);
03150 ((BlockStmtAnnotation) ann.getBlockAnnotation()).addAnnotation(seqann);
03151
03152 currentStmts.addElement(exitMonitor);
03153 currentStmts.addElement(gotoStmt);
03154 }
03155
03156
03157 start = currentStmts.size();
03158
03159 SootClass sc = getSootClass("java.lang.Throwable");
03160 Local lcl = declareLocal(nameGen.newName(), ca.mcgill.sable.soot.RefType.v("java.lang.Throwable"), 0);
03161 Stmt stmt3 = jimple.newIdentityStmt(lcl, jimple.newCaughtExceptionRef(currentBody));
03162 currentStmts.addElement(stmt3);
03163
03164 for (Enumeration e = synchAnnotations.elements(); e.hasMoreElements();) {
03165 SynchronizedStmtAnnotation sann = (SynchronizedStmtAnnotation) e.nextElement();
03166 Stmt exitMon = jimple.newExitMonitorStmt(sann.getLockValue());
03167 if (sann != ann) sann.addExitMonitor(exitMon);
03168 currentStmts.addElement(exitMon);
03169 }
03170
03171 Stmt stmt4 = jimple.newThrowStmt(lcl);
03172 currentStmts.addElement(stmt4);
03173
03174 end = currentStmts.size();
03175
03176 SequentialAnnotation sann = new SequentialAnnotation(null);
03177
03178 for (int i = start; i < end; i++) {
03179 sann.addStmt((Stmt) currentStmts.elementAt(i));
03180 }
03181
03182 ann.setCatchAnnotation(sann);
03183
03184 if (!f)
03185 currentStmts.addElement(endStmt);
03186
03187 currentBody.addTrap(jimple.newTrap(sc, stmt1, stmt2, stmt3));
03188
03189 synchAnnotations.removeElementAt(0);
03190 finallyAndSynch.removeElementAt(0);
03191
03192 currentAnnotation.addAnnotation(ann);
03193 } catch (CompilerException e) {
03194 exceptions.addElement(e);
03195 }
03196 }
03197
03198
03199
03200
03201 public void caseAThisConstructorInvocation(AThisConstructorInvocation node) {
03202 ThisConstructorInvocationStmtAnnotation ann = new ThisConstructorInvocationStmtAnnotation(node);
03203 LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
03204 ann.setFirstLine(lc.getFirstLine());
03205 ann.setFirstColumn(lc.getFirstColumn());
03206 ann.setLastLine(lc.getLastLine());
03207 ann.setLastColumn(lc.getLastColumn());
03208 try {
03209 LinkedList args = new LinkedList();
03210 Vector types = new Vector();
03211 currentValue = null;
03212 for (Iterator i = node.getArgumentList().iterator(); i.hasNext();) {
03213 ((PExp) i.next()).apply(this);
03214 args.addLast(currentValue);
03215 if (currentValue instanceof IntConstant)
03216 types.addElement(integralConstantType);
03217 else
03218 types.addElement(Util.convertType(currentValue instanceof ConditionExpr ? ca.mcgill.sable.soot.BooleanType.v() : currentValue.getType(), symbolTable));
03219 currentValue = null;
03220 }
03221 SootMethod sm = getSootMethod(currentSootClass.getName(), "<init>", types);
03222 Stmt stmt = jimple.newInvokeStmt(jimple.newSpecialInvokeExpr(currentThisLocal, sm, args));
03223 currentStmts.addElement(stmt);
03224 ann.addStmt(stmt);
03225 } catch (CompilerException e) {
03226 exceptions.addElement(e);
03227 }
03228 currentAnnotation.addAnnotation(ann);
03229 }
03230
03231
03232
03233
03234 public void caseAThisExp(AThisExp node) {
03235 currentValue = currentThisLocal;
03236 }
03237
03238
03239
03240
03241 public void caseAThrowStmt(AThrowStmt node) {
03242 int start = currentStmts.size();
03243
03244 for (Enumeration e = synchAnnotations.elements(); e.hasMoreElements();) {
03245 SynchronizedStmtAnnotation sann = (SynchronizedStmtAnnotation) e.nextElement();
03246 Stmt exitMon = jimple.newExitMonitorStmt(sann.getLockValue());
03247 sann.addExitMonitor(exitMon);
03248 currentStmts.addElement(exitMon);
03249 }
03250
03251 node.getExp().apply(this);
03252 currentStmts.addElement(jimple.newThrowStmt(currentValue));
03253 currentValue = null;
03254
03255 int end = currentStmts.size();
03256 ThrowStmtAnnotation ann = new ThrowStmtAnnotation(node);
03257 LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
03258 ann.setFirstLine(lc.getFirstLine());
03259 ann.setFirstColumn(lc.getFirstColumn());
03260 ann.setLastLine(lc.getLastLine());
03261 ann.setLastColumn(lc.getLastColumn());
03262 am.putFilenameLinePairAnnotation(
03263 new FilenameLinePair(currentClassOrInterfaceType.getPath(),
03264 LineExtractor.extractLine(node)),
03265 ann);
03266
03267 for (int i = start; i < end; i++) {
03268 ann.addStmt((Stmt) currentStmts.elementAt(i));
03269 }
03270 currentAnnotation.addAnnotation(ann);
03271 }
03272
03273
03274
03275
03276 public void caseATrueBooleanLiteral(ATrueBooleanLiteral node) {
03277 currentValue = IntConstant.v(1);
03278 integralConstantType = edu.ksu.cis.bandera.jjjc.symboltable.BooleanType.TYPE;
03279 }
03280
03281
03282
03283
03284 public void caseATryFinallyStmt(ATryFinallyStmt node) {
03285 System.out.println("Unsupported feature of Java: " + node);
03286 exceptions.addElement(new CompilerException("Unsupported feature of Java: " + node));
03287 throw new Error("Unsupported feature of Java: " + node);
03288
03289
03290
03291
03292
03293
03294
03295
03296
03297
03298
03299
03300
03301
03302
03303
03304
03305
03306
03307
03308
03309
03310
03311
03312
03313
03314
03315
03316
03317
03318
03319
03320
03321
03322
03323
03324
03325
03326
03327
03328
03329
03330
03331
03332
03333
03334
03335
03336
03337
03338
03339
03340
03341
03342
03343
03344
03345
03346
03347
03348
03349
03350
03351
03352
03353
03354
03355
03356
03357
03358
03359
03360
03361
03362
03363
03364
03365
03366
03367
03368
03369
03370
03371
03372
03373
03374
03375
03376
03377
03378
03379
03380
03381
03382
03383
03384
03385 }
03386
03387
03388
03389
03390 public void caseATryStmt(ATryStmt node) {
03391 Stmt prevBeginTrapStmt = beginTrapStmt;
03392 Stmt prevEndTrapStmt = endTrapStmt;
03393 Stmt prevEndTryStmt = endTryStmt;
03394
03395 TryStmtAnnotation ann = new TryStmtAnnotation(node);
03396 LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
03397 ann.setFirstLine(lc.getFirstLine());
03398 ann.setFirstColumn(lc.getFirstColumn());
03399 ann.setLastLine(lc.getLastLine());
03400 ann.setLastColumn(lc.getLastColumn());
03401 am.putFilenameLinePairAnnotation(
03402 new FilenameLinePair(currentClassOrInterfaceType.getPath(),
03403 LineExtractor.extractLine(node)),
03404 ann);
03405
03406 TryStmtAnnotation prevAnn = currentTryAnnotation;
03407 currentTryAnnotation = ann;
03408
03409 BlockStmtAnnotation prevAnnotation = currentAnnotation;
03410
03411 endTryStmt = jimple.newNopStmt();
03412 beginTrapStmt = jimple.newNopStmt();
03413
03414 currentStmts.addElement(beginTrapStmt);
03415
03416 currentAnnotation = new BlockStmtAnnotation(node.getBlock());
03417
03418 node.getBlock().apply(this);
03419
03420 Stmt lastStmt = (Stmt) currentStmts.lastElement();
03421
03422 boolean f = false;
03423
03424 if ((lastStmt instanceof ReturnStmt) || (lastStmt instanceof ReturnVoidStmt)
03425 || (lastStmt instanceof ThrowStmt) || (lastStmt instanceof GotoStmt)) {
03426 f = true;
03427 endTrapStmt = lastStmt;
03428 } else {
03429 SequentialAnnotation sann = new SequentialAnnotation(null);
03430 endTrapStmt = jimple.newGotoStmt(endTryStmt);
03431 sann.addStmt(endTrapStmt);
03432 currentAnnotation.addAnnotation(sann);
03433 currentStmts.addElement(endTrapStmt);
03434 }
03435
03436 ann.setBlockAnnotation(currentAnnotation);
03437
03438 catchHasEnd = true;
03439
03440 for (Iterator i = node.getCatchClause().iterator(); i.hasNext();) {
03441 PCatchClause catchClause = (PCatchClause) i.next();
03442 catchClause.apply(this);
03443 }
03444
03445 if (!f || catchHasEnd)
03446 currentStmts.addElement(endTryStmt);
03447
03448 currentAnnotation = prevAnnotation;
03449 currentAnnotation.addAnnotation(ann);
03450 currentTryAnnotation = prevAnn;
03451
03452 beginTrapStmt = prevBeginTrapStmt;
03453 endTrapStmt = prevEndTrapStmt;
03454 endTryStmt = prevEndTryStmt;
03455 }
03456
03457
03458
03459
03460 public void caseAUnaryExp(AUnaryExp node) {
03461 String operator = node.getUnaryOperator().toString().trim();
03462 if (operator.equals("++")) {
03463 preIncDecExp(node, true);
03464 } else if (operator.equals("--")) {
03465 preIncDecExp(node, false);
03466 } else if (operator.equals("+")) {
03467 node.getExp().apply(this);
03468 } else if (operator.equals("-")) {
03469 node.getExp().apply(this);
03470 if (currentValue instanceof IntConstant) {
03471 currentValue = IntConstant.v(-((IntConstant) currentValue).value);
03472 } else if (currentValue instanceof LongConstant) {
03473 currentValue = LongConstant.v(-((LongConstant) currentValue).value);
03474 } else if (currentValue instanceof FloatConstant) {
03475 currentValue = FloatConstant.v(-((FloatConstant) currentValue).value);
03476 } else if (currentValue instanceof DoubleConstant) {
03477 currentValue = DoubleConstant.v(-((DoubleConstant) currentValue).value);
03478 } else {
03479 currentValue = jimple.newNegExpr(currentValue);
03480 Local lcl = declareLocal(nameGen.newName(), currentValue.getType(), 0);
03481 currentStmts.addElement(jimple.newAssignStmt(lcl, currentValue));
03482 currentValue = lcl;
03483 }
03484 } else if (operator.equals("~")) {
03485 node.getExp().apply(this);
03486 Value operand;
03487 if (currentValue.getType() instanceof ca.mcgill.sable.soot.IntType)
03488 operand = IntConstant.v(-1);
03489 else
03490 operand = LongConstant.v(-1);
03491 currentStmts.addElement(jimple.newAssignStmt(currentValue, jimple.newXorExpr(currentValue, operand)));
03492 } else if (operator.equals("!")) {
03493 Local lcl = null;
03494 if (trueBranch == null) {
03495 lcl = declareLocal(nameGen.newName(), ca.mcgill.sable.soot.BooleanType.v(), 0);
03496 trueBranch = jimple.newAssignStmt(lcl, IntConstant.v(1));
03497 falseBranch = jimple.newAssignStmt(lcl, IntConstant.v(0));
03498 }
03499
03500 Node n = (Node) node.clone();
03501 PushComplement.push(n);
03502 n = ((AUnaryExp) n).getExp();
03503 n.apply(new BooleanExpression(this, trueBranch, falseBranch));
03504 if (!(currentValue instanceof Local)) {
03505 Local l = declareLocal(nameGen.newName(), ca.mcgill.sable.soot.BooleanType.v(), 0);
03506 currentStmts.addElement(jimple.newAssignStmt(l, currentValue));
03507 currentValue = l;
03508 }
03509
03510 if (lcl != null) {
03511 Stmt endStmt = jimple.newNopStmt();
03512 currentStmts.addElement(falseBranch);
03513 currentStmts.addElement(jimple.newGotoStmt(endStmt));
03514 currentStmts.addElement(trueBranch);
03515 currentStmts.addElement(endStmt);
03516 trueBranch = null;
03517 falseBranch = null;
03518 currentValue = lcl;
03519 }
03520 }
03521 }
03522
03523
03524
03525
03526 public void caseAVariableDeclaratorId(AVariableDeclaratorId node) {
03527 currentName = new String(node.getId().toString().trim());
03528
03529 int dimensions = node.getDim().size();
03530
03531 if (dimensions > 0)
03532 if (currentType instanceof ca.mcgill.sable.soot.ArrayType) {
03533 ca.mcgill.sable.soot.ArrayType arrayType = (ca.mcgill.sable.soot.ArrayType) currentType;
03534 currentType = ca.mcgill.sable.soot.ArrayType.v(arrayType.baseType, arrayType.numDimensions + dimensions);
03535 } else
03536 currentType = ca.mcgill.sable.soot.ArrayType.v((ca.mcgill.sable.soot.BaseType) currentType, dimensions);
03537 }
03538
03539
03540
03541
03542 public void caseAVoidExp(AVoidExp node) {
03543 System.out.println("Unsupported feature of Java: " + node);
03544 exceptions.addElement(new CompilerException("Unsupported feature of Java: " + node));
03545 throw new Error("Unsupported feature of Java: " + node);
03546 }
03547
03548
03549
03550
03551 public void caseAWhileStmt(AWhileStmt node) {
03552 Stmt blockStmt = jimple.newNopStmt();
03553 Stmt testStmt = jimple.newNopStmt();
03554 Stmt endStmt = jimple.newNopStmt();
03555 Stmt initStmt = jimple.newGotoStmt(testStmt);
03556
03557 WhileStmtAnnotation ann = new WhileStmtAnnotation(node);
03558 LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
03559 ann.setFirstLine(lc.getFirstLine());
03560 ann.setFirstColumn(lc.getFirstColumn());
03561 ann.setLastLine(lc.getLastLine());
03562 ann.setLastColumn(lc.getLastColumn());
03563 am.putFilenameLinePairAnnotation(
03564 new FilenameLinePair(currentClassOrInterfaceType.getPath(),
03565 LineExtractor.extractLine(node)),
03566 ann);
03567 BlockStmtAnnotation prevAnnotation = currentAnnotation;
03568
03569 Object prevLastSynch = lastFinallySynchBeforeControl;
03570 if (synchAnnotations.size() > 0)
03571 lastFinallySynchBeforeControl = (Annotation) synchAnnotations.lastElement();
03572
03573 Stmt prevTrueBranch = trueBranch;
03574 Stmt prevFalseBranch = falseBranch;
03575 trueBranch = blockStmt;
03576 falseBranch = endStmt;
03577
03578 Stmt prevBreakTarget = currentBreakTarget;
03579 Stmt prevContinueTarget = currentContinueTarget;
03580 currentBreakTarget = endStmt;
03581 currentContinueTarget = testStmt;
03582
03583 currentStmts.addElement(initStmt);
03584
03585 currentStmts.addElement(blockStmt);
03586
03587 currentAnnotation = new BlockStmtAnnotation(node.getBlock());
03588 node.getBlock().apply(this);
03589
03590 SequentialAnnotation sann = new SequentialAnnotation(null);
03591 sann.addStmt(initStmt);
03592 ann.setInitAnnotation(sann);
03593 ann.setBlockAnnotation(getFirstEnclosedAnnotation(currentAnnotation));
03594
03595 currentStmts.addElement(testStmt);
03596
03597 int start = currentStmts.size();
03598
03599 Node n = (Node) node.getExp().clone();
03600 PushComplement.push(n);
03601 if (node.getExp() instanceof AUnaryExp)
03602 if ("!".equals(((AUnaryExp) node.getExp()).getUnaryOperator().toString().trim()))
03603 n = ((AUnaryExp) n).getExp();
03604 n.apply(new BooleanExpression(this, trueBranch, falseBranch));
03605
03606 ann.setIndefinite(currentStmts.elementAt(currentStmts.size() - 1) instanceof JGotoStmt);
03607
03608 int end = currentStmts.size();
03609
03610 for (int i = start; i < end; i++) {
03611 ann.addStmt((Stmt) currentStmts.elementAt(i));
03612 }
03613
03614 currentStmts.addElement(endStmt);
03615
03616 trueBranch = prevTrueBranch;
03617 falseBranch = prevFalseBranch;
03618 currentBreakTarget = prevBreakTarget;
03619 currentContinueTarget = prevContinueTarget;
03620
03621 lastFinallySynchBeforeControl = prevLastSynch;
03622
03623 currentAnnotation = prevAnnotation;
03624 currentAnnotation.addAnnotation(ann);
03625 }
03626
03627
03628
03629
03630 public void caseStart(Start node) {
03631 node.getPCompilationUnit().apply(this);
03632 }
03633
03634
03635
03636
03637
03638 private void checkAnnotation(Annotation annotation, JimpleBody body) {
03639 String line = System.getProperty("line.separator");
03640 boolean failed = false;
03641
03642 String name = currentSootMethod.toString();
03643 System.out.print("Checking annotation for " + name + ", phase 1...");
03644
03645 StmtList stmtList = body.getStmtList();
03646
03647 for (Iterator i = stmtList.iterator(); i.hasNext();) {
03648 Stmt stmt = (Stmt) i.next();
03649 int idx = stmtList.indexOf(stmt);
03650 try {
03651 if (annotation.getContainingAnnotation(stmt) == null) {
03652 System.out.println(line + name + ", statement index: " + idx + ", " + stmt);
03653 failed = true;
03654 }
03655 } catch (Exception e) {
03656 System.out.println(line + e + name + ", statement index: " + idx + ", " + stmt);
03657 failed = true;
03658 }
03659 }
03660
03661 if (failed) System.out.println("Phase 1 failed");
03662 else System.out.println(" passed");
03663
03664 Object[] bodyStmts = stmtList.toArray();
03665 Stmt[] stmts = annotation.getStatements();
03666
03667 System.out.println("Checking annotation for " + name + ", phase 2... "
03668 + ((bodyStmts.length == stmts.length) ? "passed" : "failed"));
03669
03670 System.out.print("Checking annotation for " + name + ", phase 3...");
03671
03672 failed = false;
03673
03674 try {
03675
03676 for (int i = 0; i < stmts.length; i++) {
03677 if (stmts[i] != bodyStmts[i]) {
03678 System.out.println(line + name + ", statement index: " + i + ":" + line
03679 + bodyStmts[i] + " <!=> " + stmts[i]);
03680 Annotation a = annotation.getContainingAnnotation(stmts[i]);
03681 System.out.println(a.getClass().getName());
03682 System.out.println(stmtList.contains(stmts[i]));
03683 failed = true;
03684 }
03685 }
03686 } catch (Exception e) {
03687 failed = true;
03688 }
03689
03690 if (failed) System.out.println(line + "Phase 3 failed");
03691 else System.out.println(" passed");
03692 }
03693
03694
03695
03696
03697 private void convertLocalTypes(JimpleBody body) {
03698 for (Iterator i = body.getLocals().iterator(); i.hasNext();) {
03699 Local l = (Local) i.next();
03700 ca.mcgill.sable.soot.Type type = l.getType();
03701
03702 if ((type instanceof ca.mcgill.sable.soot.BooleanType) || (type instanceof ca.mcgill.sable.soot.ByteType)
03703 || (type instanceof ca.mcgill.sable.soot.CharType) || (type instanceof ca.mcgill.sable.soot.ShortType)) {
03704 l.setType(ca.mcgill.sable.soot.IntType.v());
03705 }
03706 }
03707 }
03708
03709
03710
03711
03712
03713 private Unit declareLabel(String labelName) throws CompilerException {
03714 for (Iterator i = labels.iterator(); i.hasNext();) {
03715 Hashtable labelTable = (Hashtable) i.next();
03716 if (labelTable == null) continue;
03717 if (labelTable.get(labelName) != null)
03718 throw new CompilerException("Labeled statement cannot contain the same label identifier " + labelName);
03719 }
03720 Stmt stmt = jimple.newNopStmt();
03721 currentStmts.addElement(stmt);
03722 currentLabels.put(labelName, stmt);
03723 Vector v = new Vector();
03724 v.addElement(lastFinallySynchBeforeControl);
03725 currentLabels.put(stmt, v);
03726 return stmt;
03727 }
03728
03729
03730
03731
03732
03733
03734
03735 private Local declareLocal(String name, ca.mcgill.sable.soot.Type type, int modifiers) {
03736 if ("$ret".equals(name)) {
03737 if (currentLocalNames.get(name) != null) {
03738 return (Local) currentLocals.get(name);
03739 }
03740 }
03741 if (type instanceof ca.mcgill.sable.soot.NullType) {
03742 type = RefType.v("java.lang.Object");
03743 }
03744
03745 String localName;
03746 if (currentLocalNames.get(name) != null) {
03747 currentLocalNames.remove(name);
03748 localName = getUniqueName(name);
03749 if (symbolTable.getNumScopeLevels() != 0) {
03750 if (symbolTable.hasLocalVariableDeclared(new Name(name)))
03751 exceptions.addElement(new CompilerException("Local variable " + name + " has already been declared"));
03752 }
03753 } else
03754 localName = name;
03755
03756 currentLocalNames.put(name, localName);
03757 if (symbolTable.getNumScopeLevels() != 0) {
03758 try {
03759
03760 symbolTable.declareLocalVariable(new Variable(0, Util.convertType(type, symbolTable),
03761 new Name(name)));
03762 } catch (CompilerException e) {
03763 exceptions.addElement(e);
03764 }
03765 }
03766
03767 Local tempLocal = jimple.newLocal(localName, type);
03768 currentLocals.put(tempLocal.getName(), tempLocal);
03769 return tempLocal;
03770 }
03771
03772
03773
03774
03775
03776
03777
03778 private void fieldAccess(boolean lhs, Value caller, String className, String fieldName) throws CompilerException {
03779 SootField sf = getSootField(className, fieldName);
03780 if (!lhs) {
03781 String tempName = nameGen.newName();
03782 Local lcl = declareLocal(tempName, sf.getType(), 0);
03783 if (Modifier.isStatic(sf.getModifiers())) {
03784 currentStmts.addElement(jimple.newAssignStmt(lcl, jimple.newStaticFieldRef(sf)));
03785 currentValue = lcl;
03786 } else {
03787 if (caller != null) {
03788 currentStmts.addElement(jimple.newAssignStmt(lcl, jimple.newInstanceFieldRef(caller, sf)));
03789 currentValue = lcl;
03790 } else {
03791 exceptions.addElement(new CompilerException("Could not access instance field " + fieldName + " in static method " + currentSootMethod.getName()));
03792 return;
03793 }
03794 }
03795 currentValue = lcl;
03796 } else {
03797 if (Modifier.isStatic(sf.getModifiers())) {
03798 currentValue = jimple.newStaticFieldRef(sf);
03799 } else {
03800 if (caller != null) {
03801 currentValue = jimple.newInstanceFieldRef(caller, sf);
03802 } else {
03803 exceptions.addElement(new CompilerException("Could not access instance field " + fieldName + " in static method " + currentSootMethod.getName()));
03804 currentValue = null;
03805 return;
03806 }
03807 }
03808 }
03809 }
03810
03811
03812
03813
03814 public Vector getCompiledClasses() {
03815 return compiledClasses;
03816 }
03817
03818
03819
03820
03821 public Vector getCurrentStmts() {
03822 return currentStmts;
03823 }
03824
03825
03826
03827
03828 public ca.mcgill.sable.soot.Type getCurrentType() {
03829 return currentType;
03830 }
03831
03832
03833
03834
03835 public Value getCurrentValue() {
03836 return currentValue;
03837 }
03838
03839
03840
03841
03842 public Vector getExceptions() {
03843 return exceptions;
03844 }
03845
03846
03847
03848
03849
03850 private Annotation getFirstEnclosedAnnotation(BlockStmtAnnotation annotation) {
03851 Vector annotations = annotation.getContainedAnnotations();
03852 return (annotations.size() > 0) ? (Annotation) annotations.elementAt(0)
03853 : new EmptyStmtAnnotation(null);
03854 }
03855
03856
03857
03858
03859
03860 private Object getLabelObject(Unit unit) {
03861 for (Iterator i = labels.iterator(); i.hasNext();) {
03862 Hashtable labelTable = (Hashtable) i.next();
03863 if (labelTable.get(unit) != null)
03864 return labelTable.get(unit);
03865 }
03866 return null;
03867 }
03868
03869
03870
03871
03872
03873 private Unit getLabelUnit(String name) {
03874 for (Iterator i = labels.iterator(); i.hasNext();) {
03875 Hashtable labelTable = (Hashtable) i.next();
03876 if (labelTable.get(name) != null)
03877 return (Unit) labelTable.get(name);
03878 }
03879 return null;
03880 }
03881
03882
03883
03884
03885 private Value getPlaceHolder(QuantifiedVariable q) {
03886 String fName = "quantification$" + q.getName();
03887
03888 SootField f;
03889
03890 if (CompilationManager.getFieldForQuantifier(fName) == null) {
03891 f = new SootField(fName, RefType.v(q.getType().toString()), Modifier.PUBLIC | Modifier.STATIC);
03892 CompilationManager.addFieldForQuantifier(f);
03893 } else {
03894 f = CompilationManager.getFieldForQuantifier(fName);
03895 }
03896
03897 return jimple.newStaticFieldRef(f);
03898 }
03899
03900
03901
03902
03903
03904
03905 private ca.mcgill.sable.soot.Type getResultType(ca.mcgill.sable.soot.Type firstType, ca.mcgill.sable.soot.Type secondType) {
03906 if (((firstType instanceof RefType) && ("java.lang.String".equals(((RefType) firstType).className)))
03907 || ((secondType instanceof RefType) && ("java.lang.String".equals(((RefType) secondType).className)))) {
03908 return RefType.v("java.lang.String");
03909 } else if ((firstType instanceof ca.mcgill.sable.soot.DoubleType)
03910 || (secondType instanceof ca.mcgill.sable.soot.DoubleType)) {
03911 return ca.mcgill.sable.soot.DoubleType.v();
03912 } else if ((firstType instanceof ca.mcgill.sable.soot.FloatType)
03913 || (secondType instanceof ca.mcgill.sable.soot.FloatType)) {
03914 return ca.mcgill.sable.soot.FloatType.v();
03915 } else if ((firstType instanceof ca.mcgill.sable.soot.LongType)
03916 || (secondType instanceof ca.mcgill.sable.soot.LongType)) {
03917 return ca.mcgill.sable.soot.LongType.v();
03918 } else if ((firstType instanceof RefType) || (secondType instanceof RefType)) {
03919 return null;
03920 } else {
03921 return ca.mcgill.sable.soot.IntType.v();
03922 }
03923 }
03924
03925
03926
03927
03928
03929 private SootClass getSootClass(String name) throws CompilerException {
03930 ClassOrInterfaceType type = symbolTable.resolveClassOrInterfaceType(new Name(name));
03931 type.loadReferences();
03932 String typeName = type.getName().toString();
03933
03934 if (scm.managesClass(typeName))
03935 return scm.getClass(typeName);
03936
03937 SootClass sc = new SootClass(typeName);
03938 sc.setResolved(true);
03939 scm.addClass(sc);
03940
03941 int modifiers = Util.convertModifiers(type.getModifiers());
03942
03943 if (type.isInterface())
03944 modifiers |= Modifier.INTERFACE;
03945
03946 sc.setModifiers(modifiers);
03947
03948 if (type.getDirectSuperClass() != null)
03949 sc.setSuperClass(getSootClass(type.getDirectSuperClass().getName().toString()));
03950
03951 for (Enumeration e = type.getDirectSuperInterfaces(); e.hasMoreElements();) {
03952 sc.addInterface(getSootClass(((ClassOrInterfaceType) e.nextElement()).getName().toString()));
03953 }
03954
03955 return sc;
03956 }
03957
03958
03959
03960
03961
03962
03963 private SootField getSootField(String typeName, String fieldName) throws CompilerException {
03964 try {
03965 ClassOrInterfaceType classType = symbolTable.resolveClassOrInterfaceType(new Name(typeName));
03966 classType.loadReferences();
03967 Field f = (Field) classType.getField(new Name(fieldName));
03968 String declaringType = f.getDeclaringClassOrInterface().toString();
03969 SootClass sc = getSootClass(declaringType);
03970 if (sc.declaresField(fieldName))
03971 return sc.getField(fieldName);
03972 int modifiers = Util.convertModifiers(f.getModifiers());
03973 if (f.getDeclaringClassOrInterface().isInterface())
03974 modifiers = Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL;
03975 SootField sf = new SootField(fieldName, Util.convertType(f.getType()), modifiers);
03976 sc.addField(sf);
03977 return sf;
03978 } catch (CompilerException e) {
03979 throw e;
03980 }
03981 }
03982
03983
03984
03985
03986
03987
03988
03989 private SootMethod getSootMethod(String typeName, String methodName, Vector parameterTypes) throws CompilerException {
03990 if ("Bandera".equals(typeName)) {
03991 if ("assert".equals(methodName)) {
03992 return assertMethod;
03993 } else if ("choose".equals(methodName)) {
03994 return chooseMethod;
03995 }
03996 }
03997 try {
03998 LinkedList parmTypes = new LinkedList();
03999 Method m;
04000 SootMethod sm;
04001 if ("<init>".equals(methodName)) {
04002 m = symbolTable.resolveConstructor(new Name(typeName), parameterTypes);
04003 for (Enumeration e = m.getParameterTypes().elements(); e.hasMoreElements();) {
04004 parmTypes.addLast(Util.convertType((edu.ksu.cis.bandera.jjjc.symboltable.Type) e.nextElement()));
04005 }
04006 SootClass sc = getSootClass(m.getDeclaringClassOrInterface().getName().toString());
04007 if (sc.declaresMethod(methodName, parmTypes))
04008 return sc.getMethod(methodName, parmTypes);
04009 sm = new SootMethod(methodName, parmTypes, ca.mcgill.sable.soot.VoidType.v());
04010 sc.addMethod(sm);
04011 } else {
04012 m = symbolTable.resolveMethod(new Name(typeName), new Name(methodName), parameterTypes);
04013 for (Enumeration e = m.getParameterTypes().elements(); e.hasMoreElements();) {
04014 parmTypes.addLast(Util.convertType((edu.ksu.cis.bandera.jjjc.symboltable.Type) e.nextElement()));
04015 }
04016 String declaringType = m.getDeclaringClassOrInterface().getName().toString();
04017 SootClass sc = getSootClass(declaringType);
04018 if (sc.declaresMethod(methodName, parmTypes))
04019 return sc.getMethod(methodName, parmTypes);
04020 sm = new SootMethod(methodName, parmTypes, Util.convertType(m.getReturnType()));
04021 sc.addMethod(sm);
04022 }
04023 int modifiers = Util.convertModifiers(m.getModifiers());
04024 if (m.getDeclaringClassOrInterface().isInterface())
04025 modifiers |= Modifier.ABSTRACT;
04026 sm.setModifiers(modifiers);
04027 for (Enumeration e = m.getExceptions(); e.hasMoreElements();) {
04028 ClassOrInterfaceType exceptionType = (ClassOrInterfaceType) e.nextElement();
04029 SootClass exceptionSootClass = getSootClass(exceptionType.getName().toString());
04030 Name throwableName = new Name("java.lang.Throwable");
04031 if (exceptionType.hasSuperClass(throwableName) || throwableName.equals(exceptionType.getName())) {
04032 sm.addException(exceptionSootClass);
04033 } else {
04034 exceptions.addElement(new NotThrowableException("Cannot have an unthrowable exception type named '" + exceptionType.getName() + "'"));
04035 }
04036 }
04037 return sm;
04038 } catch (CompilerException e) {
04039 throw e;
04040 }
04041 }
04042
04043
04044
04045
04046
04047 private String getUniqueName(String varName) {
04048 String result;
04049 Integer iteration;
04050 if (currentLocalNamesIterator.get(varName) == null)
04051 iteration = new Integer(0);
04052 else
04053 iteration = new Integer(((Integer) currentLocalNamesIterator.get(varName)).intValue() + 1);
04054 result = varName + "$" + iteration.toString();
04055 currentLocalNamesIterator.put(varName, iteration);
04056 return result;
04057 }
04058
04059
04060
04061
04062
04063 private void inlineAvailable(QuantifiedVariable q, Local c) {
04064
04065
04066
04067
04068
04069
04070
04071
04072
04073
04074
04075
04076
04077
04078
04079
04080 if (qtNameGen == null) qtNameGen = new NameGenerator("qtvar_");
04081
04082 Stmt s = jimple.newNopStmt();
04083
04084 Local lcl = declareLocal(qtNameGen.newName(), c.getType(), 0);
04085 Value ph = getPlaceHolder(q);
04086 currentStmts.addElement(jimple.newAssignStmt(lcl, ph));
04087 currentStmts.addElement(jimple.newIfStmt(jimple.newNeExpr(lcl, NullConstant.v()), s));
04088 Local temp = declareLocal(qtNameGen.newName(), ca.mcgill.sable.soot.IntType.v(), 0);
04089 LinkedList l = new LinkedList();
04090 l.addLast(IntConstant.v(0));
04091 l.addLast(IntConstant.v(1));
04092 Stmt ts = jimple.newAssignStmt(temp, new ChooseExpr(l));
04093 currentStmts.addElement(ts);
04094 currentStmts.addElement(jimple.newIfStmt(jimple.newEqExpr(temp, IntConstant.v(0)), s));
04095 currentStmts.addElement(jimple.newAssignStmt(ph, c));
04096 currentStmts.addElement(s);
04097 }
04098
04099
04100
04101
04102
04103 private boolean isNumberConstant(Value value) {
04104 return ((value instanceof IntConstant) || (value instanceof LongConstant) || (value instanceof DoubleConstant)
04105 || (value instanceof FloatConstant));
04106 }
04107
04108
04109
04110
04111
04112
04113 private boolean isSubtypeOf(String typeName1, String typeName2) {
04114 try {
04115 Name superName = new Name(typeName1);
04116 ClassOrInterfaceType type = symbolTable.resolveClassOrInterfaceType(superName);
04117 return type.hasSuperClass(superName) || type.hasSuperInterface(superName);
04118 } catch (Exception e) {
04119 exceptions.addElement(e);
04120 }
04121 return false;
04122 }
04123
04124
04125
04126 private void labelEnterBlock() {
04127 if (!labels.contains(currentLabels)) {
04128 labels.add(currentLabels);
04129 }
04130 currentLabels = new Hashtable();
04131 labels.addLast(currentLabels);
04132 }
04133
04134
04135
04136 private void labelExitBlock() {
04137 currentLabels = (Hashtable) labels.removeLast();
04138 }
04139
04140
04141
04142
04143
04144
04145 private void methodInvocation(String name, List args, Vector types, boolean specialInvoke) {
04146 LinkedList newArgs = new LinkedList();
04147 for (Iterator i = args.iterator(); i.hasNext();) {
04148 Value value = (Value) i.next();
04149 if (!(value instanceof Local) && !(value instanceof Constant)) {
04150 Local lcl = declareLocal(nameGen.newName(), value instanceof ConditionExpr ? ca.mcgill.sable.soot.BooleanType.v() : value.getType(), 0);
04151 currentStmts.addElement(jimple.newAssignStmt(lcl, value));
04152 newArgs.addLast(lcl);
04153 } else {
04154 newArgs.addLast(value);
04155 }
04156 }
04157
04158 args = newArgs;
04159
04160 String methodName = name.trim();
04161 Name qName = new Name(methodName);
04162 Value caller;
04163 String className;
04164 if (qName.isSimpleName()) {
04165 caller = currentThisLocal;
04166 className = currentSootClass.getName();
04167 } else {
04168 Name superName = qName.getSuperName();
04169 methodName = qName.getLastIdentifier().toString();
04170 try {
04171 symbolTable.resolveFieldOrLocal(superName);
04172
04173 nameFieldOrLocalExp(false, superName.toString());
04174 caller = currentValue;
04175 currentValue = null;
04176 if (caller.getType() instanceof ca.mcgill.sable.soot.ArrayType)
04177 className = "java.lang.Object";
04178 else
04179 className = ((RefType) caller.getType()).className;
04180 } catch (Exception e) {
04181 className = superName.toString();
04182 caller = null;
04183 }
04184 }
04185 methodInvoke(caller, className, methodName, args, types, specialInvoke);
04186 }
04187
04188
04189
04190
04191
04192
04193
04194
04195 private void methodInvoke(Value caller, String className, String methodName, List args, Vector types, boolean specialInvoke) {
04196 try {
04197 if (caller != null) {
04198 if (!(caller instanceof Local)) {
04199 Local lcl = declareLocal(nameGen.newName(), caller.getType(), 0);
04200 currentStmts.addElement(jimple.newAssignStmt(lcl, caller));
04201 caller = lcl;
04202 }
04203 }
04204 SootMethod sm;
04205 try {
04206 sm = getSootMethod(className, methodName, types);
04207 } catch (CompilerException e) {
04208 if (Modifier.isInterface(scm.getClass(className).getModifiers())) {
04209 sm = getSootMethod("java.lang.Object", methodName, types);
04210 } else {
04211 throw e;
04212 }
04213 }
04214 if (Modifier.isStatic(sm.getModifiers())) {
04215 currentValue = jimple.newStaticInvokeExpr(sm, args);
04216 } else {
04217 if (caller != null) {
04218 if (Modifier.isInterface(sm.getDeclaringClass().getModifiers()))
04219 currentValue = jimple.newInterfaceInvokeExpr((Local) caller, sm, args);
04220 else if (specialInvoke || Modifier.isPrivate(sm.getModifiers()))
04221 currentValue = jimple.newSpecialInvokeExpr((Local) caller, sm, args);
04222 else
04223 currentValue = jimple.newVirtualInvokeExpr((Local) caller, sm, args);
04224 } else {
04225 exceptions.addElement(new CompilerException("Could not invoke instance method " + methodName + " in " + sm.getName()));
04226 return;
04227 }
04228 }
04229 Value methodValue = currentValue;
04230 currentValue = null;
04231 if (sm.getReturnType() instanceof ca.mcgill.sable.soot.VoidType) {
04232 currentStmts.addElement(jimple.newInvokeStmt(methodValue));
04233 } else {
04234 Local lcl = declareLocal(nameGen.newName(), sm.getReturnType(), 0);
04235 currentStmts.addElement(jimple.newAssignStmt(lcl, methodValue));
04236 currentValue = lcl;
04237 }
04238 } catch (CompilerException e) {
04239 exceptions.addElement(e);
04240 }
04241 }
04242
04243
04244
04245
04246
04247 private void nameExp(boolean lhs, String name) {
04248 String expName = name.trim();
04249 if (expName.endsWith(".length")) {
04250 if (lhs) {
04251 currentValue = null;
04252 exceptions.addElement(new CompilerException("Cannot have array length expression in left hand side of assignment"));
04253 return;
04254 }
04255 String arrayName = name.substring(0, name.length() - 7);
04256 nameFieldOrLocalExp(lhs, arrayName);
04257 if (currentValue != null) {
04258 String tempName = nameGen.newName();
04259 Local lcl = declareLocal(tempName, ca.mcgill.sable.soot.IntType.v(), 0);
04260 currentStmts.addElement(jimple.newAssignStmt(lcl, jimple.newLengthExpr(currentValue)));
04261 currentValue = lcl;
04262 } else {
04263 exceptions.addElement(new CompilerException("Could not resolve array name " + arrayName + " in " + expName));
04264 }
04265 } else {
04266 nameFieldOrLocalExp(lhs, expName);
04267 }
04268 }
04269
04270
04271
04272
04273
04274 private void nameFieldOrLocalExp(boolean lhs, String name) {
04275 name = name.trim();
04276
04277 Value caller;
04278 if (currentLocalNames.get(name) != null) {
04279 currentValue = (Local) currentLocals.get(currentLocalNames.get(name));
04280 return;
04281 } else {
04282 Name qName = new Name(name);
04283 String className;
04284 String fieldName;
04285 if (qName.isSimpleName()) {
04286 className = currentSootClass.getName();
04287 fieldName = name;
04288 caller = currentThisLocal;
04289 } else {
04290 fieldName = qName.getLastIdentifier();
04291 Name superName = qName.getSuperName();
04292 boolean isTypeName;
04293 try {
04294 superName = symbolTable.resolveClassOrInterfaceType(superName).getName();
04295 isTypeName = true;
04296 } catch (Exception e) {
04297 isTypeName = false;
04298 }
04299 if (isTypeName) {
04300 className = superName.toString();
04301 caller = null;
04302 } else {
04303 nameFieldOrLocalExp(lhs, superName.toString());
04304 className = ((RefType) currentValue.getType()).className;
04305 caller = currentValue;
04306 currentValue = null;
04307 Local lcl = declareLocal(nameGen.newName(), caller.getType(), 0);
04308 currentStmts.addElement(jimple.newAssignStmt(lcl, caller));
04309 caller = lcl;
04310 }
04311 }
04312 try {
04313 symbolTable.resolveExpression(new Name(name));
04314 fieldAccess(lhs, caller, className, fieldName);
04315 } catch (CompilerException e) {
04316 exceptions.addElement(e);
04317 }
04318 }
04319 }
04320
04321
04322
04323
04324
04325
04326 private void numericOperation(String operator, Value firstValue, Value secondValue) throws CompilerException {
04327 ca.mcgill.sable.soot.Type firstType = firstValue.getType();
04328 ca.mcgill.sable.soot.Type secondType = secondValue.getType();
04329 ca.mcgill.sable.soot.Type resultType = getResultType(firstType, secondType);
04330 Local lcl;
04331 if (resultType == null) {
04332 exceptions.addElement(new CompilerException("Cannot perform operation " + firstType + " " + operator + " " + secondType));
04333 currentValue = null;
04334 return;
04335 } else if (resultType instanceof RefType) {
04336 if ("+".equals(operator)) {
04337 RefType refType = ca.mcgill.sable.soot.RefType.v("java.lang.String");
04338 ClassOrInterfaceType stringType = symbolTable.resolveClassOrInterfaceType(new Name("java.lang.String"));
04339 Vector types = new Vector();
04340 types.addElement(stringType);
04341 LinkedList values = new LinkedList();
04342 if (!(firstType instanceof RefType)) {
04343 values.addLast(firstValue);
04344 SootMethod valueOf1 = getSootMethod("java.lang.String", "valueOf", types);
04345 Local lcl1 = declareLocal(nameGen.newName(), refType, 0);
04346 currentStmts.addElement(jimple.newAssignStmt(lcl1, jimple.newStaticInvokeExpr(valueOf1, values)));
04347 firstValue = lcl1;
04348 } else if (!(secondType instanceof RefType)) {
04349 values.addLast(secondValue);
04350 SootMethod valueOf2 = getSootMethod("java.lang.String", "valueOf", types);
04351 Local lcl2 = declareLocal(nameGen.newName(), refType, 0);
04352 currentStmts.addElement(jimple.newAssignStmt(lcl2, jimple.newStaticInvokeExpr(valueOf2, values)));
04353 secondValue = lcl2;
04354 }
04355 SootMethod concat = getSootMethod("java.lang.String", "concat", types);
04356 lcl = declareLocal(nameGen.newName(), refType, 0);
04357 if (!(firstValue instanceof Local)) {
04358 Local tempLocal = declareLocal(nameGen.newName(), refType, 0);
04359 currentStmts.addElement(jimple.newAssignStmt(tempLocal, firstValue));
04360 firstValue = tempLocal;
04361 }
04362 String secondTypeString = secondValue.getType().toString().trim();
04363 if (!"java.lang.String".equals(secondTypeString)) {
04364 Local tempLocal = declareLocal(nameGen.newName(), refType, 0);
04365 currentStmts.addElement(jimple.newAssignStmt(tempLocal, jimple.newVirtualInvokeExpr((Local) secondValue,
04366 getSootMethod("java.lang.Object", "toString", new Vector()), new LinkedList())));
04367 secondValue = tempLocal;
04368 }
04369 values = new LinkedList();
04370 values.addLast(secondValue);
04371 currentStmts.addElement(jimple.newAssignStmt(lcl, jimple.newVirtualInvokeExpr((Local) firstValue, concat, values)));
04372 currentValue = lcl;
04373 return;
04374 } else {
04375 exceptions.addElement(new CompilerException("Cannot perform operation " + firstType + " + " + secondType));
04376 currentValue = null;
04377 return;
04378 }
04379 } else {
04380 lcl = declareLocal(nameGen.newName(), resultType, 0);
04381 }
04382 if ("+".equals(operator)) {
04383 currentValue = jimple.newAddExpr(firstValue, secondValue);
04384 } else if ("-".equals(operator)) {
04385 currentValue = jimple.newSubExpr(firstValue, secondValue);
04386 } else if ("*".equals(operator)) {
04387 currentValue = jimple.newMulExpr(firstValue, secondValue);
04388 } else if ("%".equals(operator)) {
04389 currentValue = jimple.newRemExpr(firstValue, secondValue);
04390 } else if ("/".equals(operator)) {
04391 currentValue = jimple.newDivExpr(firstValue, secondValue);
04392 } else if ("&".equals(operator)) {
04393 currentValue = jimple.newAndExpr(firstValue, secondValue);
04394 } else if ("|".equals(operator)) {
04395 currentValue = jimple.newOrExpr(firstValue, secondValue);
04396 } else if (">>".equals(operator)) {
04397 currentValue = jimple.newShrExpr(firstValue, secondValue);
04398 } else if (">>>".equals(operator)) {
04399 currentValue = jimple.newUshrExpr(firstValue, secondValue);
04400 } else if ("<<".equals(operator)) {
04401 currentValue = jimple.newShlExpr(firstValue, secondValue);
04402 } else {
04403 currentValue = jimple.newXorExpr(firstValue, secondValue);
04404 }
04405 currentStmts.addElement(jimple.newAssignStmt(lcl, currentValue));
04406 currentValue = lcl;
04407 }
04408
04409
04410
04411 private void patchBody(JimpleBody body) {
04412 StmtList stmts = body.getStmtList();
04413 Local thisLocal = null;
04414 for (ca.mcgill.sable.util.Iterator i = stmts.iterator(); i.hasNext();) {
04415 Stmt s = (Stmt) i.next();
04416 if (s instanceof IdentityStmt) {
04417 IdentityStmt is = (IdentityStmt) s;
04418 if (is.getRightOp() instanceof ThisRef) {
04419 thisLocal = (Local) is.getLeftOp();
04420 thisLocal.setName("JJJCTEMP$0");
04421 return;
04422 }
04423 }
04424 }
04425 }
04426
04427
04428
04429
04430
04431 private void postIncDecExp(PExp node, boolean isPlus) {
04432 String name = null;
04433 if (isPlus) {
04434 if (((APostIncrementExp) node).getExp() instanceof ANameExp) {
04435 name = (new Name((((ANameExp) ((APostIncrementExp) node).getExp()).getName()).toString())).toString();
04436 nameExp(node.parent() instanceof ANameLeftHandSide, name);
04437 } else {
04438 ((APostIncrementExp) node).getExp().apply(this);
04439 }
04440 } else {
04441 if (((APostDecrementExp) node).getExp() instanceof ANameExp) {
04442 name = (new Name((((ANameExp) ((APostDecrementExp) node).getExp()).getName()).toString())).toString();
04443 nameExp(node.parent() instanceof ANameLeftHandSide, name);
04444 } else {
04445 ((APostDecrementExp) node).getExp().apply(this);
04446 }
04447 }
04448 Value postValue = currentValue;
04449 currentValue = null;
04450 Local lcl = declareLocal(nameGen.newName(), postValue.getType(), 0);
04451 currentStmts.addElement(jimple.newAssignStmt(lcl, postValue));
04452 Value operandValue;
04453 if (postValue.getType() instanceof ca.mcgill.sable.soot.IntType)
04454 operandValue = IntConstant.v(1);
04455 else
04456 operandValue = LongConstant.v(1);
04457 if (isPlus)
04458 currentStmts.addElement(jimple.newAssignStmt(postValue, jimple.newAddExpr(postValue, operandValue)));
04459 else
04460 currentStmts.addElement(jimple.newAssignStmt(postValue, jimple.newSubExpr(postValue, operandValue)));
04461 if (name != null) {
04462 nameExp(true, name);
04463 } else {
04464 assignExp = true;
04465 if (isPlus) {
04466 ((APostIncrementExp) node).getExp().apply(this);
04467 } else {
04468 ((APostDecrementExp) node).getExp().apply(this);
04469 }
04470 }
04471 currentStmts.addElement(jimple.newAssignStmt(currentValue, postValue));
04472 currentValue = lcl;
04473 }
04474
04475
04476
04477
04478
04479 private void preIncDecExp(AUnaryExp node, boolean isPlus) {
04480 String name = null;
04481 if (node.getExp() instanceof ANameExp) {
04482 name = (new Name((((ANameExp) node.getExp()).getName()).toString())).toString();
04483 nameExp(node.parent() instanceof ANameLeftHandSide, name);
04484 } else {
04485 node.getExp().apply(this);
04486 }
04487
04488 Value preValue = currentValue;
04489 currentValue = null;
04490 Value operandValue;
04491 if (preValue.getType() instanceof ca.mcgill.sable.soot.IntType)
04492 operandValue = IntConstant.v(1);
04493 else
04494 operandValue = LongConstant.v(1);
04495 if (isPlus)
04496 currentStmts.addElement(jimple.newAssignStmt(preValue, jimple.newAddExpr(preValue, operandValue)));
04497 else
04498 currentStmts.addElement(jimple.newAssignStmt(preValue, jimple.newSubExpr(preValue, operandValue)));
04499
04500 if (name != null) {
04501 nameExp(true, name);
04502 } else {
04503 assignExp = true;
04504 node.getExp().apply(this);
04505 }
04506
04507 currentStmts.addElement(jimple.newAssignStmt(currentValue, preValue));
04508 currentValue = preValue;
04509 }
04510 }