1 19 20 21 22 package soot.javaToJimple; 23 24 import java.util.*; 25 26 import soot.SootFieldRef; 27 28 public class JimpleBodyBuilder extends AbstractJimpleBodyBuilder { 29 30 31 public JimpleBodyBuilder(){ 32 } 35 36 37 ArrayList exceptionTable; Stack endControlNoop = new Stack(); Stack condControlNoop = new Stack(); Stack monitorStack; Stack tryStack; Stack catchStack; 44 Stack trueNoop = new Stack(); 45 Stack falseNoop = new Stack(); 46 47 HashMap labelBreakMap; HashMap labelContinueMap; HashMap labelMap; 52 HashMap localsMap = new HashMap(); 54 HashMap getThisMap = new HashMap(); soot.Local specialThisLocal; soot.Local outerClassParamLocal; 58 private int paramRefCount = 0; 60 LocalGenerator lg; 62 65 public soot.jimple.JimpleBody createJimpleBody(polyglot.ast.Block block, List formals, soot.SootMethod sootMethod){ 66 67 createBody(sootMethod); 68 69 lg = new LocalGenerator(body); 70 if (!soot.Modifier.isStatic(sootMethod.getModifiers())) { 72 73 soot.RefType type = sootMethod.getDeclaringClass().getType(); 74 specialThisLocal = soot.jimple.Jimple.v().newLocal("this", type); 75 body.getLocals().add(specialThisLocal); 76 77 soot.jimple.ThisRef thisRef = soot.jimple.Jimple.v().newThisRef(type); 78 79 soot.jimple.Stmt thisStmt = soot.jimple.Jimple.v().newIdentityStmt(specialThisLocal, thisRef); 80 body.getUnits().add(thisStmt); 81 82 } 85 86 int formalsCounter = 0; 87 88 int outerIndex = sootMethod.getDeclaringClass().getName().lastIndexOf("$"); 90 int classMod = sootMethod.getDeclaringClass().getModifiers(); 91 92 if ((outerIndex != -1) && (sootMethod.getName().equals("<init>")) && sootMethod.getDeclaringClass().declaresFieldByName("this$0")){ 93 94 soot.SootClass outerClass = ((soot.RefType)sootMethod.getDeclaringClass().getFieldByName("this$0").getType()).getSootClass(); 97 soot.Local outerLocal = lg.generateLocal(outerClass.getType()); 98 99 soot.jimple.ParameterRef paramRef = soot.jimple.Jimple.v().newParameterRef(outerClass.getType(), formalsCounter); 100 paramRefCount++; 101 soot.jimple.Stmt stmt = soot.jimple.Jimple.v().newIdentityStmt(outerLocal, paramRef); 102 stmt.addTag(new soot.tagkit.EnclosingTag()); 103 body.getUnits().add(stmt); 104 105 ((soot.javaToJimple.PolyglotMethodSource)sootMethod.getSource()).setOuterClassThisInit(outerLocal); 106 outerClassParamLocal = outerLocal; 107 formalsCounter++; 108 } 109 110 if (formals != null) { 112 ArrayList formalNames = new ArrayList(); 113 Iterator formalsIt = formals.iterator(); 114 while (formalsIt.hasNext()) { 115 polyglot.ast.Formal formal = (polyglot.ast.Formal)formalsIt.next(); 116 createFormal(formal, formalsCounter); 117 formalNames.add(formal.name()); 118 formalsCounter++; 119 } 120 body.getMethod().addTag(new soot.tagkit.ParamNamesTag(formalNames)); 121 } 122 123 ArrayList finalsList = ((PolyglotMethodSource)body.getMethod().getSource()).getFinalsList(); 125 if (finalsList != null){ 126 Iterator finalsIt = finalsList.iterator(); 127 while (finalsIt.hasNext()){ 128 soot.SootField sf = (soot.SootField)finalsIt.next(); 129 soot.jimple.ParameterRef paramRef = soot.jimple.Jimple.v().newParameterRef(sf.getType(), formalsCounter); 130 paramRefCount++; 131 soot.jimple.Stmt stmt = soot.jimple.Jimple.v().newIdentityStmt(lg.generateLocal(sf.getType()), paramRef); 132 body.getUnits().add(stmt); 133 formalsCounter++; 134 } 135 } 136 137 createBlock(block); 138 139 140 if (sootMethod.getName().equals("<clinit>")){ 142 143 handleAssert(sootMethod); 144 handleStaticFieldInits(sootMethod); 145 handleStaticInitializerBlocks(sootMethod); 146 } 147 148 boolean hasReturn = false; 150 if (block != null) { 151 Iterator it = block.statements().iterator(); 152 while (it.hasNext()){ 153 Object next = it.next(); 154 if (next instanceof polyglot.ast.Return){ 155 hasReturn = true; 156 } 157 } 158 } 159 160 soot.Type retType = body.getMethod().getReturnType(); 161 if ((!hasReturn) && (retType instanceof soot.VoidType)) { 163 soot.jimple.Stmt retStmt = soot.jimple.Jimple.v().newReturnVoidStmt(); 164 body.getUnits().add(retStmt); 165 } 166 167 if (exceptionTable != null) { 169 Iterator trapsIt = exceptionTable.iterator(); 170 while (trapsIt.hasNext()){ 171 body.getTraps().add((soot.Trap)trapsIt.next()); 172 } 173 } 174 return body; 175 176 } 177 178 private void handleAssert(soot.SootMethod sootMethod){ 179 if (!((soot.javaToJimple.PolyglotMethodSource)sootMethod.getSource()).hasAssert()) return; 180 ((soot.javaToJimple.PolyglotMethodSource)sootMethod.getSource()).addAssertInits(body); 181 } 182 183 186 private void handleFieldInits(soot.SootMethod sootMethod) { 187 188 ArrayList fieldInits = ((soot.javaToJimple.PolyglotMethodSource)sootMethod.getSource()).getFieldInits(); 189 if (fieldInits != null) { 190 handleFieldInits(fieldInits); 191 } 192 } 193 194 protected void handleFieldInits(ArrayList fieldInits){ 195 Iterator fieldInitsIt = fieldInits.iterator(); 196 while (fieldInitsIt.hasNext()) { 197 polyglot.ast.FieldDecl field = (polyglot.ast.FieldDecl)fieldInitsIt.next(); 198 String fieldName = field.name(); 199 polyglot.ast.Expr initExpr = field.init(); 200 soot.SootClass currentClass = body.getMethod().getDeclaringClass(); 201 soot.SootFieldRef sootField = soot.Scene.v().makeFieldRef(currentClass, fieldName, Util.getSootType(field.type().type()), field.flags().isStatic()); 202 203 soot.Local base = specialThisLocal; 204 205 soot.jimple.FieldRef fieldRef = soot.jimple.Jimple.v().newInstanceFieldRef(base, sootField); 206 207 soot.Value sootExpr; 208 if (initExpr instanceof polyglot.ast.ArrayInit) { 209 sootExpr = getArrayInitLocal((polyglot.ast.ArrayInit)initExpr, field.type().type()); 210 } 211 else { 212 sootExpr = base().createExpr(initExpr); 214 } 216 if (sootExpr instanceof soot.jimple.ConditionExpr) { 217 sootExpr = handleCondBinExpr((soot.jimple.ConditionExpr)sootExpr); 218 } 219 220 soot.jimple.AssignStmt assign; 221 if (sootExpr instanceof soot.Local){ 222 assign = soot.jimple.Jimple.v().newAssignStmt(fieldRef, (soot.Local)sootExpr); 223 } 224 else if (sootExpr instanceof soot.jimple.Constant){ 225 assign = soot.jimple.Jimple.v().newAssignStmt(fieldRef, (soot.jimple.Constant)sootExpr); 226 } 227 else { 228 throw new RuntimeException ("fields must assign to local or constant only"); 229 } 230 body.getUnits().add(assign); 231 Util.addLnPosTags(assign, initExpr.position()); 232 Util.addLnPosTags(assign.getRightOpBox(), initExpr.position()); 233 } 234 } 235 236 237 240 private void handleOuterClassThisInit(soot.SootMethod sootMethod) { 241 if (body.getMethod().getDeclaringClass().declaresFieldByName("this$0")){ 243 soot.jimple.FieldRef fieldRef = soot.jimple.Jimple.v().newInstanceFieldRef(specialThisLocal, body.getMethod().getDeclaringClass().getFieldByName("this$0").makeRef()); 244 soot.jimple.AssignStmt stmt = soot.jimple.Jimple.v().newAssignStmt(fieldRef, outerClassParamLocal); 245 body.getUnits().add(stmt); 246 } 247 } 248 249 250 251 254 private void handleStaticFieldInits(soot.SootMethod sootMethod) { 255 256 ArrayList staticFieldInits = ((soot.javaToJimple.PolyglotMethodSource)sootMethod.getSource()).getStaticFieldInits(); 257 if (staticFieldInits != null) { 258 Iterator staticFieldInitsIt = staticFieldInits.iterator(); 259 while (staticFieldInitsIt.hasNext()) { 260 polyglot.ast.FieldDecl field = (polyglot.ast.FieldDecl)staticFieldInitsIt.next(); 261 String fieldName = field.name(); 262 polyglot.ast.Expr initExpr = field.init(); 263 soot.SootClass currentClass = body.getMethod().getDeclaringClass(); 264 soot.SootFieldRef sootField = soot.Scene.v().makeFieldRef(currentClass, fieldName, Util.getSootType(field.type().type()), field.flags().isStatic()); 265 soot.jimple.FieldRef fieldRef = soot.jimple.Jimple.v().newStaticFieldRef(sootField); 266 267 soot.Value sootExpr; 269 if (initExpr instanceof polyglot.ast.ArrayInit) { 270 sootExpr = getArrayInitLocal((polyglot.ast.ArrayInit)initExpr, field.type().type()); 271 } 272 else { 273 sootExpr = base().createExpr(initExpr); 275 277 if (sootExpr instanceof soot.jimple.ConditionExpr) { 278 sootExpr = handleCondBinExpr((soot.jimple.ConditionExpr)sootExpr); 279 } 280 } 281 282 soot.jimple.Stmt assign = soot.jimple.Jimple.v().newAssignStmt(fieldRef, sootExpr); 283 284 body.getUnits().add(assign); 285 Util.addLnPosTags(assign, initExpr.position()); 286 287 } 288 } 289 } 290 291 294 private void handleInitializerBlocks(soot.SootMethod sootMethod) { 295 ArrayList initializerBlocks = ((soot.javaToJimple.PolyglotMethodSource)sootMethod.getSource()).getInitializerBlocks(); 296 297 if (initializerBlocks != null) { 298 299 handleStaticBlocks(initializerBlocks); 300 } 301 } 302 303 protected void handleStaticBlocks(ArrayList initializerBlocks){ 304 Iterator initBlocksIt = initializerBlocks.iterator(); 305 while (initBlocksIt.hasNext()) { 306 createBlock((polyglot.ast.Block)initBlocksIt.next()); 307 } 308 } 309 310 313 private void handleStaticInitializerBlocks(soot.SootMethod sootMethod) { 314 ArrayList staticInitializerBlocks = ((soot.javaToJimple.PolyglotMethodSource)sootMethod.getSource()).getStaticInitializerBlocks(); 315 316 if (staticInitializerBlocks != null) { 317 318 Iterator staticInitBlocksIt = staticInitializerBlocks.iterator(); 319 while (staticInitBlocksIt.hasNext()) { 320 createBlock((polyglot.ast.Block)staticInitBlocksIt.next()); 321 } 322 } 323 } 324 325 328 private void createBody(soot.SootMethod sootMethod) { 329 body = soot.jimple.Jimple.v().newBody(sootMethod); 330 sootMethod.setActiveBody(body); 331 332 } 333 334 335 338 private void createBlock(polyglot.ast.Block block){ 339 340 if (block == null) return; 341 342 Iterator it = block.statements().iterator(); 344 while (it.hasNext()){ 345 Object next = it.next(); 346 if (next instanceof polyglot.ast.Stmt){ 347 createStmt((polyglot.ast.Stmt)next); 348 } 349 else { 350 throw new RuntimeException ("Unexpected - Unhandled Node"); 351 } 352 } 353 } 354 355 358 private soot.Local createCatchFormal(polyglot.ast.Formal formal){ 359 360 soot.Type sootType = Util.getSootType(formal.type().type()); 361 soot.Local formalLocal = createLocal(formal.localInstance()); 362 soot.jimple.CaughtExceptionRef exceptRef = soot.jimple.Jimple.v().newCaughtExceptionRef(); 363 soot.jimple.Stmt stmt = soot.jimple.Jimple.v().newIdentityStmt(formalLocal, exceptRef); 364 body.getUnits().add(stmt); 365 366 Util.addLnPosTags(stmt, formal.position()); 367 Util.addLnPosTags(((soot.jimple.IdentityStmt) stmt).getRightOpBox(), formal.position()); 368 369 ArrayList names = new ArrayList(); 370 names.add(formal.name()); 371 stmt.addTag(new soot.tagkit.ParamNamesTag(names)); 372 return formalLocal; 373 } 374 375 378 private void createFormal(polyglot.ast.Formal formal, int counter){ 379 380 soot.Type sootType = Util.getSootType(formal.type().type()); 381 soot.Local formalLocal = createLocal(formal.localInstance()); 382 soot.jimple.ParameterRef paramRef = soot.jimple.Jimple.v().newParameterRef(sootType, counter); 383 paramRefCount++; 384 soot.jimple.Stmt stmt = soot.jimple.Jimple.v().newIdentityStmt(formalLocal, paramRef); 385 386 body.getUnits().add(stmt); 387 388 Util.addLnPosTags(((soot.jimple.IdentityStmt) stmt).getRightOpBox(), formal.position()); 389 Util.addLnPosTags(stmt, formal.position()); 390 391 } 392 393 396 private soot.Value createLiteral(polyglot.ast.Lit lit) { 397 if (lit instanceof polyglot.ast.IntLit) { 398 polyglot.ast.IntLit intLit = (polyglot.ast.IntLit)lit; 399 long litValue = intLit.value(); 400 if (intLit.kind() == polyglot.ast.IntLit.INT) { 401 return soot.jimple.IntConstant.v((int)litValue); 402 } 403 else { 404 return soot.jimple.LongConstant.v(litValue); 406 } 407 } 408 else if (lit instanceof polyglot.ast.StringLit) { 409 String litValue = ((polyglot.ast.StringLit)lit).value(); 410 return soot.jimple.StringConstant.v(litValue); 411 } 412 else if (lit instanceof polyglot.ast.NullLit) { 413 return soot.jimple.NullConstant.v(); 414 } 415 else if (lit instanceof polyglot.ast.FloatLit) { 416 polyglot.ast.FloatLit floatLit = (polyglot.ast.FloatLit)lit; 417 double litValue = floatLit.value(); 418 if (floatLit.kind() == polyglot.ast.FloatLit.DOUBLE) { 419 return soot.jimple.DoubleConstant.v(floatLit.value()); 420 } 421 else { 422 return soot.jimple.FloatConstant.v((float)(floatLit.value())); 423 } 424 } 425 else if (lit instanceof polyglot.ast.CharLit) { 426 char litValue = ((polyglot.ast.CharLit)lit).value(); 427 return soot.jimple.IntConstant.v(litValue); 428 } 429 else if (lit instanceof polyglot.ast.BooleanLit) { 430 boolean litValue = ((polyglot.ast.BooleanLit)lit).value(); 431 if (litValue) return soot.jimple.IntConstant.v(1); 432 else return soot.jimple.IntConstant.v(0); 433 } 434 else if (lit instanceof polyglot.ast.ClassLit){ 435 return getSpecialClassLitLocal((polyglot.ast.ClassLit)lit); 436 } 437 else { 438 throw new RuntimeException ("Unknown Literal - Unhandled: "+lit.getClass()); 439 } 440 } 441 442 445 446 private soot.Local createLocal(polyglot.types.LocalInstance localInst) { 448 449 soot.Type sootType = Util.getSootType(localInst.type()); 450 String name = localInst.name(); 451 soot.Local sootLocal = createLocal(name, sootType); 452 453 localsMap.put(new polyglot.util.IdentityKey(localInst), sootLocal); 454 return sootLocal; 455 } 456 457 private soot.Local createLocal(String name, soot.Type sootType) { 459 soot.Local sootLocal = soot.jimple.Jimple.v().newLocal(name, sootType); 460 body.getLocals().add(sootLocal); 461 return sootLocal; 462 } 463 464 467 private soot.Local getLocal(polyglot.ast.Local local) { 468 469 return getLocal(local.localInstance()); 470 } 471 472 475 private soot.Local getLocal(polyglot.types.LocalInstance li) { 476 477 if (localsMap.containsKey(new polyglot.util.IdentityKey(li))){ 478 soot.Local sootLocal = (soot.Local)localsMap.get(new polyglot.util.IdentityKey(li)); 479 return sootLocal; 480 } 481 else if (body.getMethod().getDeclaringClass().declaresField("val$"+li.name(), Util.getSootType(li.type()))){ 482 soot.Local fieldLocal = generateLocal(li.type()); 483 soot.SootFieldRef field = soot.Scene.v().makeFieldRef(body.getMethod().getDeclaringClass(), "val$"+li.name(), Util.getSootType(li.type()), false); 484 soot.jimple.FieldRef fieldRef = soot.jimple.Jimple.v().newInstanceFieldRef(specialThisLocal, field); 485 soot.jimple.AssignStmt assign = soot.jimple.Jimple.v().newAssignStmt(fieldLocal, fieldRef); 486 body.getUnits().add(assign); 487 return fieldLocal; 488 } 489 492 else { 493 499 soot.SootClass currentClass = body.getMethod().getDeclaringClass(); 500 boolean fieldFound = false; 501 502 while (!fieldFound){ 503 if (!currentClass.declaresFieldByName("this$0")){ 504 throw new RuntimeException ("Trying to get field val$"+li.name()+" from some outer class but can't access the outer class of: "+currentClass.getName()+"!"+" current class contains fields: "+currentClass.getFields()); 505 } 506 soot.SootClass outerClass = ((soot.RefType)currentClass.getFieldByName("this$0").getType()).getSootClass(); 507 if (outerClass.declaresField("val$"+li.name(), Util.getSootType(li.type()))){ 510 fieldFound = true; 511 } 512 currentClass = outerClass; 513 } 515 soot.SootMethod methToInvoke = makeLiFieldAccessMethod(currentClass, li); 517 518 ArrayList methParams = new ArrayList(); 521 methParams.add(getThis(currentClass.getType())); 522 523 soot.Local res = Util.getPrivateAccessFieldInvoke(methToInvoke.makeRef(), methParams, body, lg); 524 return res; 525 } 526 } 527 528 private soot.SootMethod makeLiFieldAccessMethod(soot.SootClass classToInvoke, polyglot.types.LocalInstance li){ 529 String name = "access$"+soot.javaToJimple.InitialResolver.v().getNextPrivateAccessCounter()+"00"; 530 ArrayList paramTypes = new ArrayList(); 531 paramTypes.add(classToInvoke.getType()); 532 533 soot.SootMethod meth = new soot.SootMethod(name, paramTypes, Util.getSootType(li.type()), soot.Modifier.STATIC); 534 535 classToInvoke.addMethod(meth); 536 PrivateFieldAccMethodSource src = new PrivateFieldAccMethodSource( 537 Util.getSootType(li.type()), 538 "val$"+li.name(), 539 false, 540 classToInvoke 541 ); 542 meth.setActiveBody(src.getBody(meth, null)); 543 meth.addTag(new soot.tagkit.SyntheticTag()); 544 return meth; 545 } 546 547 550 protected void createStmt(polyglot.ast.Stmt stmt) { 551 if (stmt instanceof polyglot.ast.Eval) { 553 base().createExpr(((polyglot.ast.Eval)stmt).expr()); 554 } 555 else if (stmt instanceof polyglot.ast.If) { 556 createIf2((polyglot.ast.If)stmt); 557 } 558 else if (stmt instanceof polyglot.ast.LocalDecl) { 559 createLocalDecl((polyglot.ast.LocalDecl)stmt); 560 } 561 else if (stmt instanceof polyglot.ast.Block) { 562 createBlock((polyglot.ast.Block)stmt); 563 } 564 else if (stmt instanceof polyglot.ast.While) { 565 createWhile2((polyglot.ast.While)stmt); 566 } 567 else if (stmt instanceof polyglot.ast.Do) { 568 createDo2((polyglot.ast.Do)stmt); 569 } 570 else if (stmt instanceof polyglot.ast.For) { 571 createForLoop2((polyglot.ast.For)stmt); 572 } 573 else if (stmt instanceof polyglot.ast.Switch) { 574 createSwitch((polyglot.ast.Switch)stmt); 575 } 576 else if (stmt instanceof polyglot.ast.Return) { 577 createReturn((polyglot.ast.Return)stmt); 578 } 579 else if (stmt instanceof polyglot.ast.Branch) { 580 createBranch((polyglot.ast.Branch)stmt); 581 } 582 else if (stmt instanceof polyglot.ast.ConstructorCall) { 583 createConstructorCall((polyglot.ast.ConstructorCall)stmt); 584 } 585 else if (stmt instanceof polyglot.ast.Empty) { 586 } 588 else if (stmt instanceof polyglot.ast.Throw) { 589 createThrow((polyglot.ast.Throw)stmt); 590 } 591 else if (stmt instanceof polyglot.ast.Try) { 592 createTry((polyglot.ast.Try)stmt); 593 } 594 else if (stmt instanceof polyglot.ast.Labeled) { 595 createLabeled((polyglot.ast.Labeled)stmt); 596 } 597 else if (stmt instanceof polyglot.ast.Synchronized) { 598 createSynchronized((polyglot.ast.Synchronized)stmt); 599 } 600 else if (stmt instanceof polyglot.ast.Assert) { 601 createAssert((polyglot.ast.Assert)stmt); 602 } 603 else if (stmt instanceof polyglot.ast.LocalClassDecl) { 604 createLocalClassDecl((polyglot.ast.LocalClassDecl)stmt); 605 } 606 else { 607 throw new RuntimeException ("Unhandled Stmt: "+stmt.getClass()); 608 } 609 } 610 611 private boolean needSootIf(soot.Value sootCond){ 612 if (sootCond instanceof soot.jimple.IntConstant){ 613 if (((soot.jimple.IntConstant)sootCond).value == 1){ 614 return false; 615 } 616 } 617 return true; 618 } 619 620 624 687 688 692 private void createIf2(polyglot.ast.If ifExpr){ 693 694 soot.jimple.NopStmt endTgt = soot.jimple.Jimple.v().newNopStmt(); 695 soot.jimple.NopStmt brchTgt = soot.jimple.Jimple.v().newNopStmt(); 696 697 polyglot.ast.Expr condition = ifExpr.cond(); 699 createBranchingExpr(condition, brchTgt, false); 700 701 polyglot.ast.Stmt consequence = ifExpr.consequent(); 703 createStmt(consequence); 704 705 soot.jimple.Stmt goto1 = soot.jimple.Jimple.v().newGotoStmt(endTgt); 706 body.getUnits().add(goto1); 707 708 709 body.getUnits().add(brchTgt); 710 711 polyglot.ast.Stmt alternative = ifExpr.alternative(); 713 if (alternative != null){ 714 createStmt(alternative); 715 } 716 body.getUnits().add(endTgt); 717 718 719 } 720 721 private void createBranchingExpr(polyglot.ast.Expr expr, soot.jimple.Stmt tgt, boolean boto){ 722 if (expr instanceof polyglot.ast.Binary && ((polyglot.ast.Binary)expr).operator() == polyglot.ast.Binary.COND_AND){ 723 polyglot.ast.Binary cond_and = (polyglot.ast.Binary)expr; 724 if (boto){ 725 soot.jimple.Stmt t1 = soot.jimple.Jimple.v().newNopStmt(); 726 createBranchingExpr(cond_and.left(), t1, false); 727 createBranchingExpr(cond_and.right(), tgt, true); 728 body.getUnits().add(t1); 729 } 730 else { 731 createBranchingExpr(cond_and.left(), tgt, false); 732 createBranchingExpr(cond_and.right(), tgt, false); 733 } 734 } 735 else if (expr instanceof polyglot.ast.Binary && ((polyglot.ast.Binary)expr).operator() == polyglot.ast.Binary.COND_OR){ 736 polyglot.ast.Binary cond_or = (polyglot.ast.Binary)expr; 737 if (boto){ 738 createBranchingExpr(cond_or.left(), tgt, true); 739 createBranchingExpr(cond_or.right(), tgt, true); 740 } 741 else { 742 soot.jimple.Stmt t1 = soot.jimple.Jimple.v().newNopStmt(); 743 createBranchingExpr(cond_or.left(), t1, true); 744 createBranchingExpr(cond_or.right(), tgt, false); 745 body.getUnits().add(t1); 746 } 747 748 } 749 else if (expr instanceof polyglot.ast.Unary && ((polyglot.ast.Unary)expr).operator() == polyglot.ast.Unary.NOT){ 750 polyglot.ast.Unary not = (polyglot.ast.Unary)expr; 751 createBranchingExpr(not.expr(), tgt, !boto); 752 } 753 else { 754 soot.Value sootCond = base().createExpr(expr); 755 756 boolean needIf = needSootIf(sootCond); 757 if (!(sootCond instanceof soot.jimple.ConditionExpr)) { 758 if (!boto){ 759 sootCond = soot.jimple.Jimple.v().newEqExpr(sootCond, soot.jimple.IntConstant.v(0)); 760 } 761 else { 762 sootCond = soot.jimple.Jimple.v().newNeExpr(sootCond, soot.jimple.IntConstant.v(0)); 763 } 764 } 765 766 else { 767 sootCond = handleDFLCond((soot.jimple.ConditionExpr)sootCond); 768 if (!boto){ 769 sootCond = reverseCondition((soot.jimple.ConditionExpr)sootCond); 770 } 771 } 772 773 if (needIf) { 774 soot.jimple.IfStmt ifStmt = soot.jimple.Jimple.v().newIfStmt(sootCond, tgt); 775 body.getUnits().add(ifStmt); 776 Util.addLnPosTags(ifStmt.getConditionBox(), expr.position()); 778 Util.addLnPosTags(ifStmt, expr.position()); 779 } 780 786 } 787 } 788 789 792 843 844 847 private void createWhile2(polyglot.ast.While whileStmt){ 848 849 850 soot.jimple.Stmt brchTgt = soot.jimple.Jimple.v().newNopStmt(); 851 soot.jimple.Stmt beginTgt = soot.jimple.Jimple.v().newNopStmt(); 852 853 body.getUnits().add(beginTgt); 854 855 endControlNoop.push(soot.jimple.Jimple.v().newNopStmt()); 857 condControlNoop.push(soot.jimple.Jimple.v().newNopStmt()); 858 859 soot.jimple.Stmt continueStmt = (soot.jimple.Stmt)condControlNoop.pop(); 861 body.getUnits().add(continueStmt); 862 condControlNoop.push(continueStmt); 863 864 polyglot.ast.Expr condition = whileStmt.cond(); 865 createBranchingExpr(condition, brchTgt, false); 866 createStmt(whileStmt.body()); 867 soot.jimple.GotoStmt gotoLoop = soot.jimple.Jimple.v().newGotoStmt(beginTgt); 868 body.getUnits().add(gotoLoop); 869 870 871 body.getUnits().add((soot.jimple.Stmt)(endControlNoop.pop())); 872 body.getUnits().add(brchTgt); 873 condControlNoop.pop(); 874 } 875 876 879 911 912 941 942 945 private void createDo2(polyglot.ast.Do doStmt){ 946 947 948 soot.jimple.Stmt noop1 = soot.jimple.Jimple.v().newNopStmt(); 949 body.getUnits().add(noop1); 950 951 endControlNoop.push(soot.jimple.Jimple.v().newNopStmt()); 953 condControlNoop.push(soot.jimple.Jimple.v().newNopStmt()); 954 955 createStmt(doStmt.body()); 957 958 soot.jimple.Stmt continueStmt = (soot.jimple.Stmt)condControlNoop.pop(); 960 body.getUnits().add(continueStmt); 961 condControlNoop.push(continueStmt); 962 963 if (labelMap != null && labelMap.containsKey(doStmt)){ 964 body.getUnits().add((soot.jimple.Stmt)labelMap.get(doStmt)); 965 } 966 967 polyglot.ast.Expr condition = doStmt.cond(); 968 969 createBranchingExpr(condition, noop1, true); 970 971 body.getUnits().add((soot.jimple.Stmt)(endControlNoop.pop())); 972 condControlNoop.pop(); 973 } 974 975 978 1063 1064 1107 1112 1113 1116 private void createForLoop2(polyglot.ast.For forStmt){ 1117 1118 endControlNoop.push(soot.jimple.Jimple.v().newNopStmt()); 1120 condControlNoop.push(soot.jimple.Jimple.v().newNopStmt()); 1121 1122 Iterator initsIt = forStmt.inits().iterator(); 1124 while (initsIt.hasNext()){ 1125 createStmt((polyglot.ast.Stmt)initsIt.next()); 1126 } 1127 soot.jimple.Stmt noop1 = soot.jimple.Jimple.v().newNopStmt(); 1128 soot.jimple.Stmt noop2 = soot.jimple.Jimple.v().newNopStmt(); 1129 1130 body.getUnits().add(noop2); 1131 1132 1134 polyglot.ast.Expr condition = forStmt.cond(); 1135 if (condition != null) { 1136 createBranchingExpr(condition, noop1, false); 1137 } 1138 createStmt(forStmt.body()); 1139 1140 body.getUnits().add((soot.jimple.Stmt)(condControlNoop.pop())); 1142 1143 if (labelMap != null && labelMap.containsKey(forStmt)){ 1144 body.getUnits().add((soot.jimple.Stmt)labelMap.get(forStmt)); 1145 } 1146 1147 Iterator itersIt = forStmt.iters().iterator(); 1149 while (itersIt.hasNext()){ 1150 createStmt((polyglot.ast.Stmt)itersIt.next()); 1151 } 1152 soot.jimple.Stmt goto1 = soot.jimple.Jimple.v().newGotoStmt(noop2); 1153 body.getUnits().add(goto1); 1154 body.getUnits().add(noop1); 1155 body.getUnits().add((soot.jimple.Stmt)(endControlNoop.pop())); 1156 1157 } 1158 1159 1162 private void createLocalDecl(polyglot.ast.LocalDecl localDecl) { 1163 1164 String name = localDecl.name(); 1166 polyglot.types.LocalInstance localInst = localDecl.localInstance(); 1167 soot.Value lhs = createLocal(localInst); 1168 polyglot.ast.Expr expr = localDecl.init(); 1169 if (expr != null) { 1170 soot.Value rhs; 1172 if (expr instanceof polyglot.ast.ArrayInit){ 1173 rhs = getArrayInitLocal((polyglot.ast.ArrayInit)expr, localInst.type()); 1175 } 1176 else { 1177 rhs = base().createExpr(expr); 1179 } 1181 if (rhs instanceof soot.jimple.ConditionExpr) { 1182 rhs = handleCondBinExpr((soot.jimple.ConditionExpr)rhs); 1183 } 1184 soot.jimple.AssignStmt stmt = soot.jimple.Jimple.v().newAssignStmt(lhs, rhs); 1186 body.getUnits().add(stmt); 1187 Util.addLnPosTags(stmt, localDecl.position()); 1189 if ( localDecl.position() != null){ 1191 Util.addLnPosTags(stmt.getLeftOpBox(), localDecl.position().line(), localDecl.position().endLine(), localDecl.position().endColumn()-name.length(), localDecl.position().endColumn()); 1192 if (expr != null){ 1193 Util.addLnPosTags(stmt, localDecl.position().line(), expr.position().endLine(), localDecl.position().column(), expr.position().endColumn()); 1194 } 1195 else { 1196 Util.addLnPosTags(stmt, localDecl.position().line(), localDecl.position().endLine(), localDecl.position().column(), localDecl.position().endColumn()); 1197 } 1198 } 1199 else { 1200 } 1201 if (expr != null){ 1202 Util.addLnPosTags(stmt.getRightOpBox(), expr.position()); 1203 } 1204 } 1205 } 1206 1207 1210 private void createSwitch(polyglot.ast.Switch switchStmt) { 1211 1212 1213 polyglot.ast.Expr value = switchStmt.expr(); 1214 soot.Value sootValue = base().createExpr(value); 1215 1216 if (switchStmt.elements().size() == 0) return; 1217 1218 soot.jimple.Stmt defaultTarget = null; 1219 1220 polyglot.ast.Case [] caseArray = new polyglot.ast.Case[switchStmt.elements().size()]; 1221 soot.jimple.Stmt [] targetsArray = new soot.jimple.Stmt[switchStmt.elements().size()]; 1222 1223 ArrayList targets = new ArrayList(); 1224 HashMap targetsMap = new HashMap(); 1225 int counter = 0; 1226 Iterator it = switchStmt.elements().iterator(); 1227 while (it.hasNext()) { 1228 Object next = it.next(); 1229 if (next instanceof polyglot.ast.Case) { 1230 soot.jimple.Stmt noop = soot.jimple.Jimple.v().newNopStmt(); 1231 if (!((polyglot.ast.Case)next).isDefault()){ 1232 targets.add(noop); 1233 caseArray[counter] = (polyglot.ast.Case)next; 1234 targetsArray[counter] = noop; 1235 counter++; 1236 targetsMap.put(next, noop); 1237 } 1238 else { 1239 defaultTarget = noop; 1240 } 1241 } 1242 } 1243 1244 int lowIndex = 0; 1246 int highIndex = 0; 1247 1248 1249 for (int i = 0; i < counter; i++) { 1250 for (int j = i+1; j < counter; j++) { 1251 if (caseArray[j].value() < caseArray[i].value()) { 1252 polyglot.ast.Case tempCase = caseArray[i]; 1253 soot.jimple.Stmt tempTarget = targetsArray[i]; 1254 caseArray[i] = caseArray[j]; 1255 targetsArray[i] = targetsArray[j]; 1256 caseArray[j] = tempCase; 1257 targetsArray[j] = tempTarget; 1258 } 1259 } 1260 } 1261 1262 ArrayList sortedTargets = new ArrayList(); 1263 1264 for (int i = 0; i < counter; i++) { 1265 sortedTargets.add(targetsArray[i]); 1266 } 1267 1268 boolean hasDefaultTarget = true; 1270 if (defaultTarget == null) { 1271 soot.jimple.Stmt noop = soot.jimple.Jimple.v().newNopStmt(); 1272 defaultTarget = noop; 1273 hasDefaultTarget = false; 1274 1275 } 1276 1277 soot.jimple.Stmt sootSwitchStmt; 1279 if (isLookupSwitch(switchStmt)) { 1280 1281 ArrayList values = new ArrayList(); 1282 for (int i = 0; i < counter; i++) { 1283 if (!caseArray[i].isDefault()) { 1284 values.add(soot.jimple.IntConstant.v((int)caseArray[i].value())); 1285 } 1286 } 1287 1288 1289 soot.jimple.LookupSwitchStmt lookupStmt = soot.jimple.Jimple.v().newLookupSwitchStmt(sootValue, values, sortedTargets, defaultTarget); 1290 1291 Util.addLnPosTags(lookupStmt.getKeyBox(), value.position()); 1292 sootSwitchStmt = lookupStmt; 1293 1294 } 1295 else { 1296 long lowVal = 0; 1297 long highVal = 0; 1298 boolean unknown = true; 1299 1300 it = switchStmt.elements().iterator(); 1301 while (it.hasNext()){ 1302 Object next = it.next(); 1303 if (next instanceof polyglot.ast.Case) { 1304 if (!((polyglot.ast.Case)next).isDefault()){ 1305 long temp = ((polyglot.ast.Case)next).value(); 1306 if (unknown){ 1307 highVal = temp; 1308 lowVal = temp; 1309 unknown = false; 1310 } 1311 if (temp > highVal) { 1312 highVal = temp; 1313 } 1314 if (temp < lowVal) { 1315 lowVal = temp; 1316 } 1317 } 1318 } 1319 1320 } 1321 1322 soot.jimple.TableSwitchStmt tableStmt = soot.jimple.Jimple.v().newTableSwitchStmt(sootValue, (int)lowVal, (int)highVal, sortedTargets, defaultTarget); 1323 1324 Util.addLnPosTags(tableStmt.getKeyBox(), value.position()); 1325 sootSwitchStmt = tableStmt; 1326 1327 } 1328 1329 body.getUnits().add(sootSwitchStmt); 1330 1331 Util.addLnPosTags(sootSwitchStmt, switchStmt.position()); 1332 endControlNoop.push(soot.jimple.Jimple.v().newNopStmt()); 1333 1334 it = switchStmt.elements().iterator(); 1335 Iterator targetsIt = targets.iterator(); 1336 1337 while (it.hasNext()){ 1338 Object next = it.next(); 1339 if (next instanceof polyglot.ast.Case) { 1340 if (!((polyglot.ast.Case)next).isDefault()){ 1341 body.getUnits().add((soot.jimple.Stmt)targetsMap.get(next)); 1342 } 1343 else { 1344 body.getUnits().add(defaultTarget); 1345 } 1346 } 1347 else { 1348 polyglot.ast.SwitchBlock blockStmt = (polyglot.ast.SwitchBlock)next; 1349 createBlock(blockStmt); 1350 1351 } 1352 } 1353 1354 if (!hasDefaultTarget) { 1355 body.getUnits().add(defaultTarget); 1356 } 1357 body.getUnits().add((soot.jimple.Stmt)(endControlNoop.pop())); 1358 } 1359 1360 1366 private boolean isLookupSwitch(polyglot.ast.Switch switchStmt){ 1367 1368 int lowest = 0; 1369 int highest = 0; 1370 int counter = 0; 1371 Iterator it = switchStmt.elements().iterator(); 1372 while (it.hasNext()){ 1373 Object next = it.next(); 1374 if (next instanceof polyglot.ast.Case) { 1375 polyglot.ast.Case caseStmt = (polyglot.ast.Case)next; 1376 if (caseStmt.isDefault()) continue; 1377 int caseValue = (int)caseStmt.value(); 1378 if (caseValue <= lowest || counter == 0 ) { 1379 lowest = caseValue; 1380 } 1381 if (caseValue >= highest || counter == 0) { 1382 highest = caseValue; 1383 } 1384 counter++; 1385 } 1386 } 1387 1388 if ((counter-1) == (highest - lowest)) return false; 1389 return true; 1390 } 1391 1392 1395 private void createBranch(polyglot.ast.Branch branchStmt){ 1396 1397 if (tryStack != null && !tryStack.isEmpty()){ 1399 polyglot.ast.Try currentTry = (polyglot.ast.Try)tryStack.pop(); 1400 if (currentTry.finallyBlock() != null){ 1401 createBlock(currentTry.finallyBlock()); 1402 tryStack.push(currentTry); 1403 } 1404 else { 1405 tryStack.push(currentTry); 1406 } 1407 } 1408 1409 if (catchStack != null && !catchStack.isEmpty()){ 1411 polyglot.ast.Try currentTry = (polyglot.ast.Try)catchStack.pop(); 1412 if (currentTry.finallyBlock() != null){ 1413 createBlock(currentTry.finallyBlock()); 1414 catchStack.push(currentTry); 1415 } 1416 else { 1417 catchStack.push(currentTry); 1418 } 1419 } 1420 1421 body.getUnits().add(soot.jimple.Jimple.v().newNopStmt()); 1422 if (branchStmt.kind() == polyglot.ast.Branch.BREAK){ 1423 if (branchStmt.label() == null) { 1424 soot.jimple.Stmt gotoEndNoop = (soot.jimple.Stmt)endControlNoop.pop(); 1425 soot.jimple.Stmt gotoEnd = soot.jimple.Jimple.v().newGotoStmt(gotoEndNoop); 1426 endControlNoop.push(gotoEndNoop); 1427 body.getUnits().add(gotoEnd); 1428 Util.addLnPosTags(gotoEnd, branchStmt.position()); 1429 } 1430 else { 1431 soot.jimple.Stmt gotoLabel = soot.jimple.Jimple.v().newGotoStmt((soot.jimple.Stmt)labelBreakMap.get(branchStmt.label())); 1432 body.getUnits().add(gotoLabel); 1433 Util.addLnPosTags(gotoLabel, branchStmt.position()); 1434 } 1435 } 1436 else if (branchStmt.kind() == polyglot.ast.Branch.CONTINUE){ 1437 if (branchStmt.label() == null) { 1438 soot.jimple.Stmt gotoCondNoop = (soot.jimple.Stmt)condControlNoop.pop(); 1439 soot.jimple.Stmt gotoCond = soot.jimple.Jimple.v().newGotoStmt(gotoCondNoop); 1440 condControlNoop.push(gotoCondNoop); 1441 body.getUnits().add(gotoCond); 1442 Util.addLnPosTags(gotoCond, branchStmt.position()); 1443 } 1444 else { 1445 soot.jimple.Stmt gotoLabel = soot.jimple.Jimple.v().newGotoStmt((soot.jimple.Stmt)labelContinueMap.get(branchStmt.label())); 1446 body.getUnits().add(gotoLabel); 1447 Util.addLnPosTags(gotoLabel, branchStmt.position()); 1448 } 1449 1450 } 1451 1452 } 1453 1454 1457 private void createLabeled(polyglot.ast.Labeled labeledStmt){ 1458 String label = labeledStmt.label(); 1459 polyglot.ast.Stmt stmt = labeledStmt.statement(); 1461 1462 soot.jimple.Stmt noop = soot.jimple.Jimple.v().newNopStmt(); 1463 if (!(stmt instanceof polyglot.ast.For) && !(stmt instanceof polyglot.ast.Do)){ 1465 body.getUnits().add(noop); 1466 } 1467 1473 1474 if (labelMap == null){ 1475 labelMap = new HashMap(); 1476 } 1477 1478 labelMap.put(stmt, noop); 1479 1480 1481 if (labelBreakMap == null) { 1482 labelBreakMap = new HashMap(); 1483 } 1484 1485 if (labelContinueMap == null) { 1486 labelContinueMap = new HashMap(); 1487 } 1488 1489 labelContinueMap.put(label, noop); 1490 soot.jimple.Stmt noop2 = soot.jimple.Jimple.v().newNopStmt(); 1491 labelBreakMap.put(label, noop2); 1492 1493 createStmt(stmt); 1494 1495 1498 1499 body.getUnits().add(noop2); 1500 1501 } 1506 1507 1522 1523 1526 private void createAssert(polyglot.ast.Assert assertStmt) { 1527 1528 soot.Local testLocal = lg.generateLocal(soot.BooleanType.v()); 1530 soot.SootFieldRef assertField = soot.Scene.v().makeFieldRef(body.getMethod().getDeclaringClass(), "$assertionsDisabled", soot.BooleanType.v(), true); 1531 soot.jimple.FieldRef assertFieldRef = soot.jimple.Jimple.v().newStaticFieldRef(assertField); 1532 soot.jimple.AssignStmt fieldAssign = soot.jimple.Jimple.v().newAssignStmt(testLocal, assertFieldRef); 1533 body.getUnits().add(fieldAssign); 1534 1535 soot.jimple.NopStmt nop1 = soot.jimple.Jimple.v().newNopStmt(); 1536 soot.jimple.ConditionExpr cond1 = soot.jimple.Jimple.v().newNeExpr(testLocal, soot.jimple.IntConstant.v(0)); 1537 soot.jimple.IfStmt testIf = soot.jimple.Jimple.v().newIfStmt(cond1, nop1); 1538 body.getUnits().add(testIf); 1539 1540 if ((assertStmt.cond() instanceof polyglot.ast.BooleanLit) && (!((polyglot.ast.BooleanLit)assertStmt.cond()).value())){ 1542 } 1544 else { 1545 soot.Value sootCond = base().createExpr(assertStmt.cond()); 1546 boolean needIf = needSootIf(sootCond); 1547 if (!(sootCond instanceof soot.jimple.ConditionExpr)) { 1548 sootCond = soot.jimple.Jimple.v().newEqExpr(sootCond, soot.jimple.IntConstant.v(1)); 1549 } 1550 else { 1551 sootCond = handleDFLCond((soot.jimple.ConditionExpr)sootCond); 1552 } 1553 1554 if (needIf){ 1555 soot.jimple.IfStmt ifStmt = soot.jimple.Jimple.v().newIfStmt(sootCond, nop1); 1557 body.getUnits().add(ifStmt); 1558 1559 Util.addLnPosTags(ifStmt.getConditionBox(), assertStmt.cond().position()); 1560 Util.addLnPosTags(ifStmt, assertStmt.position()); 1561 } 1562 } 1563 1564 soot.Local failureLocal = lg.generateLocal(soot.RefType.v("java.lang.AssertionError")); 1566 soot.jimple.NewExpr newExpr = soot.jimple.Jimple.v().newNewExpr(soot.RefType.v("java.lang.AssertionError")); 1567 soot.jimple.AssignStmt newAssign = soot.jimple.Jimple.v().newAssignStmt(failureLocal, newExpr); 1568 body.getUnits().add(newAssign); 1569 1570 soot.SootMethodRef methToInvoke; 1571 ArrayList paramTypes = new ArrayList(); 1572 ArrayList params = new ArrayList(); 1573 if (assertStmt.errorMessage() != null){ 1574 soot.Value errorExpr = base().createExpr(assertStmt.errorMessage()); 1575 if (errorExpr instanceof soot.jimple.ConditionExpr) { 1576 errorExpr = handleCondBinExpr((soot.jimple.ConditionExpr)errorExpr); 1577 } 1578 soot.Type errorType = errorExpr.getType(); 1579 1580 if (assertStmt.errorMessage().type().isChar()){ 1581 errorType = soot.CharType.v(); 1582 } 1583 if (errorType instanceof soot.IntType) { 1584 paramTypes.add(soot.IntType.v()); 1585 } 1586 else if (errorType instanceof soot.LongType){ 1587 paramTypes.add(soot.LongType.v()); 1588 } 1589 else if (errorType instanceof soot.FloatType){ 1590 paramTypes.add(soot.FloatType.v()); 1591 } 1592 else if (errorType instanceof soot.DoubleType){ 1593 paramTypes.add(soot.DoubleType.v()); 1594 } 1595 else if (errorType instanceof soot.CharType){ 1596 paramTypes.add(soot.CharType.v()); 1597 } 1598 else if (errorType instanceof soot.BooleanType){ 1599 paramTypes.add(soot.BooleanType.v()); 1600 } 1601 else if (errorType instanceof soot.ShortType){ 1602 paramTypes.add(soot.IntType.v()); 1603 } 1604 else if (errorType instanceof soot.ByteType){ 1605 paramTypes.add(soot.IntType.v()); 1606 } 1607 else { 1608 paramTypes.add(soot.Scene.v().getSootClass("java.lang.Object").getType()); 1609 } 1610 1611 params.add(errorExpr); 1612 } 1613 methToInvoke = soot.Scene.v().makeMethodRef( soot.Scene.v().getSootClass("java.lang.AssertionError"), "<init>", paramTypes, soot.VoidType.v(), false); 1614 1615 soot.jimple.SpecialInvokeExpr invokeExpr = soot.jimple.Jimple.v().newSpecialInvokeExpr(failureLocal, methToInvoke, params); 1616 soot.jimple.InvokeStmt invokeStmt = soot.jimple.Jimple.v().newInvokeStmt(invokeExpr); 1617 body.getUnits().add(invokeStmt); 1618 1619 1620 if (assertStmt.errorMessage() != null){ 1621 Util.addLnPosTags(invokeExpr.getArgBox(0), assertStmt.errorMessage().position()); 1622 } 1623 1624 soot.jimple.ThrowStmt throwStmt = soot.jimple.Jimple.v().newThrowStmt(failureLocal); 1625 body.getUnits().add(throwStmt); 1626 1627 body.getUnits().add(nop1); 1629 1630 } 1631 1632 1635 private void createSynchronized(polyglot.ast.Synchronized synchStmt) { 1636 soot.Value sootExpr = base().createExpr(synchStmt.expr()); 1637 1638 soot.jimple.EnterMonitorStmt enterMon = soot.jimple.Jimple.v().newEnterMonitorStmt(sootExpr); 1639 body.getUnits().add(enterMon); 1640 1641 if (monitorStack == null){ 1642 monitorStack = new Stack(); 1643 } 1644 monitorStack.push(sootExpr); 1645 1646 Util.addLnPosTags(enterMon.getOpBox(), synchStmt.expr().position()); 1647 Util.addLnPosTags(enterMon, synchStmt.expr().position()); 1648 1649 soot.jimple.Stmt startNoop = soot.jimple.Jimple.v().newNopStmt(); 1650 body.getUnits().add(startNoop); 1651 1652 createBlock(synchStmt.body()); 1653 1654 soot.jimple.ExitMonitorStmt exitMon = soot.jimple.Jimple.v().newExitMonitorStmt(sootExpr); 1655 body.getUnits().add(exitMon); 1656 1657 monitorStack.pop(); 1658 Util.addLnPosTags(exitMon.getOpBox(), synchStmt.expr().position()); 1659 Util.addLnPosTags(exitMon, synchStmt.expr().position()); 1660 1661 soot.jimple.Stmt endSynchNoop = soot.jimple.Jimple.v().newNopStmt(); 1662 soot.jimple.Stmt gotoEnd = soot.jimple.Jimple.v().newGotoStmt(endSynchNoop); 1663 1664 soot.jimple.Stmt endNoop = soot.jimple.Jimple.v().newNopStmt(); 1665 body.getUnits().add(endNoop); 1666 1667 body.getUnits().add(gotoEnd); 1668 1669 soot.jimple.Stmt catchAllBeforeNoop = soot.jimple.Jimple.v().newNopStmt(); 1670 body.getUnits().add(catchAllBeforeNoop); 1671 1672 soot.Local formalLocal = lg.generateLocal(soot.RefType.v("java.lang.Throwable")); 1674 1675 soot.jimple.CaughtExceptionRef exceptRef = soot.jimple.Jimple.v().newCaughtExceptionRef(); 1676 soot.jimple.Stmt stmt = soot.jimple.Jimple.v().newIdentityStmt(formalLocal, exceptRef); 1677 body.getUnits().add(stmt); 1678 1679 soot.jimple.Stmt catchBeforeNoop = soot.jimple.Jimple.v().newNopStmt(); 1681 body.getUnits().add(catchBeforeNoop); 1682 1683 soot.Local local = lg.generateLocal(soot.RefType.v("java.lang.Throwable")); 1684 1685 soot.jimple.Stmt assign = soot.jimple.Jimple.v().newAssignStmt(local, formalLocal); 1686 1687 body.getUnits().add(assign); 1688 soot.jimple.ExitMonitorStmt catchExitMon = soot.jimple.Jimple.v().newExitMonitorStmt(sootExpr); 1689 1690 body.getUnits().add(catchExitMon); 1691 Util.addLnPosTags(catchExitMon.getOpBox(), synchStmt.expr().position()); 1692 1693 soot.jimple.Stmt catchAfterNoop = soot.jimple.Jimple.v().newNopStmt(); 1694 body.getUnits().add(catchAfterNoop); 1695 1696 soot.jimple.Stmt throwStmt = soot.jimple.Jimple.v().newThrowStmt(local); 1698 body.getUnits().add(throwStmt); 1699 1700 1701 body.getUnits().add(endSynchNoop); 1702 1703 addToExceptionList(startNoop, endNoop, catchAllBeforeNoop, soot.Scene.v().getSootClass("java.lang.Throwable")); 1704 addToExceptionList(catchBeforeNoop, catchAfterNoop, catchAllBeforeNoop, soot.Scene.v().getSootClass("java.lang.Throwable")); 1705 1706 } 1707 1708 1711 private void createReturn(polyglot.ast.Return retStmt) { 1712 polyglot.ast.Expr expr = retStmt.expr(); 1713 soot.Value sootLocal = null; 1714 if (expr != null){ 1715 sootLocal = base().createExpr(expr); 1716 } 1717 1718 if (monitorStack != null){ 1720 Stack putBack = new Stack(); 1721 while (!monitorStack.isEmpty()){ 1722 soot.Local exitVal = (soot.Local)monitorStack.pop(); 1723 putBack.push(exitVal); 1724 soot.jimple.ExitMonitorStmt emStmt = soot.jimple.Jimple.v().newExitMonitorStmt(exitVal); 1725 body.getUnits().add(emStmt); 1726 } 1727 while(!putBack.isEmpty()){ 1728 monitorStack.push(putBack.pop()); 1729 } 1730 } 1731 1732 if (tryStack != null && !tryStack.isEmpty()){ 1734 polyglot.ast.Try currentTry = (polyglot.ast.Try)tryStack.pop(); 1735 if (currentTry.finallyBlock() != null){ 1736 createBlock(currentTry.finallyBlock()); 1737 tryStack.push(currentTry); 1738 } 1745 else { 1746 tryStack.push(currentTry); 1747 } 1748 } 1749 1750 if (catchStack != null && !catchStack.isEmpty()){ 1752 polyglot.ast.Try currentTry = (polyglot.ast.Try)catchStack.pop(); 1753 if (currentTry.finallyBlock() != null){ 1754 createBlock(currentTry.finallyBlock()); 1755 catchStack.push(currentTry); 1756 } 1764 else { 1765 catchStack.push(currentTry); 1766 } 1767 } 1768 1769 if (expr == null) { 1771 soot.jimple.Stmt retStmtVoid = soot.jimple.Jimple.v().newReturnVoidStmt(); 1772 body.getUnits().add(retStmtVoid); 1773 Util.addLnPosTags(retStmtVoid, retStmt.position()); 1774 } 1775 else { 1776 if (sootLocal instanceof soot.jimple.ConditionExpr) { 1778 sootLocal = handleCondBinExpr((soot.jimple.ConditionExpr)sootLocal); 1779 } 1780 soot.jimple.ReturnStmt retStmtLocal = soot.jimple.Jimple.v().newReturnStmt(sootLocal); 1781 body.getUnits().add(retStmtLocal); 1782 Util.addLnPosTags(retStmtLocal.getOpBox(), expr.position()); 1783 Util.addLnPosTags(retStmtLocal, retStmt.position()); 1784 } 1785 } 1786 1787 1790 private void createThrow(polyglot.ast.Throw throwStmt){ 1791 soot.Value toThrow = base().createExpr(throwStmt.expr()); 1792 soot.jimple.ThrowStmt throwSt = soot.jimple.Jimple.v().newThrowStmt(toThrow); 1793 body.getUnits().add(throwSt); 1794 Util.addLnPosTags(throwSt, throwStmt.position()); 1795 Util.addLnPosTags(throwSt.getOpBox(), throwStmt.expr().position()); 1796 } 1797 1798 1801 private void createTry(polyglot.ast.Try tryStmt) { 1802 1803 polyglot.ast.Block finallyBlock = tryStmt.finallyBlock(); 1804 1805 if (finallyBlock == null) { 1806 createTryCatch(tryStmt); 1807 } 1808 else { 1809 createTryCatchFinally(tryStmt); 1810 } 1811 } 1812 1813 1816 private void createTryCatch(polyglot.ast.Try tryStmt){ 1817 1818 polyglot.ast.Block tryBlock = tryStmt.tryBlock(); 1820 1821 soot.jimple.Stmt noop1 = soot.jimple.Jimple.v().newNopStmt(); 1823 body.getUnits().add(noop1); 1824 1825 if (tryStack == null){ 1826 tryStack = new Stack(); 1827 } 1828 tryStack.push(tryStmt); 1829 createBlock(tryBlock); 1830 tryStack.pop(); 1831 1832 soot.jimple.Stmt noop2 = soot.jimple.Jimple.v().newNopStmt(); 1834 body.getUnits().add(noop2); 1835 1836 soot.jimple.Stmt endNoop = soot.jimple.Jimple.v().newNopStmt(); 1838 1839 soot.jimple.Stmt tryEndGoto = soot.jimple.Jimple.v().newGotoStmt(endNoop); 1840 body.getUnits().add(tryEndGoto); 1841 1842 Iterator it = tryStmt.catchBlocks().iterator(); 1843 while (it.hasNext()) { 1844 1845 soot.jimple.Stmt noop3 = soot.jimple.Jimple.v().newNopStmt(); 1846 body.getUnits().add(noop3); 1847 1848 polyglot.ast.Catch catchBlock = (polyglot.ast.Catch)it.next(); 1850 1851 createCatchFormal(catchBlock.formal()); 1853 1854 if (catchStack == null){ 1855 catchStack = new Stack(); 1856 } 1857 catchStack.push(tryStmt); 1858 createBlock(catchBlock.body()); 1859 catchStack.pop(); 1860 1861 soot.jimple.Stmt catchEndGoto = soot.jimple.Jimple.v().newGotoStmt(endNoop); 1862 body.getUnits().add(catchEndGoto); 1863 1864 1865 soot.Type sootType = Util.getSootType(catchBlock.catchType()); 1866 1867 addToExceptionList(noop1, noop2, noop3, soot.Scene.v().getSootClass(sootType.toString())); 1868 1869 } 1870 1871 body.getUnits().add(endNoop); 1872 } 1873 1874 1877 private void createTryCatchFinally(polyglot.ast.Try tryStmt){ 1878 1879 HashMap gotoMap = new HashMap(); 1880 1881 polyglot.ast.Block tryBlock = tryStmt.tryBlock(); 1883 1884 soot.jimple.Stmt noop1 = soot.jimple.Jimple.v().newNopStmt(); 1886 body.getUnits().add(noop1); 1887 1888 if (tryStack == null){ 1889 tryStack = new Stack(); 1890 } 1891 tryStack.push(tryStmt); 1892 createBlock(tryBlock); 1893 tryStack.pop(); 1894 1895 soot.jimple.Stmt noop2 = soot.jimple.Jimple.v().newNopStmt(); 1897 body.getUnits().add(noop2); 1898 1899 soot.jimple.Stmt endNoop = soot.jimple.Jimple.v().newNopStmt(); 1901 1902 soot.jimple.Stmt tryGotoFinallyNoop = soot.jimple.Jimple.v().newNopStmt(); 1904 1905 body.getUnits().add(tryGotoFinallyNoop); 1906 soot.jimple.Stmt tryFinallyNoop = soot.jimple.Jimple.v().newNopStmt(); 1907 1908 soot.jimple.Stmt tryGotoFinally = soot.jimple.Jimple.v().newGotoStmt(tryFinallyNoop); 1909 body.getUnits().add(tryGotoFinally); 1910 1911 soot.jimple.Stmt beforeEndGotoNoop = soot.jimple.Jimple.v().newNopStmt(); 1913 body.getUnits().add(beforeEndGotoNoop); 1914 soot.jimple.Stmt tryEndGoto = soot.jimple.Jimple.v().newGotoStmt(endNoop); 1915 body.getUnits().add(tryEndGoto); 1916 1917 gotoMap.put(tryFinallyNoop, beforeEndGotoNoop); 1918 1919 1920 1921 soot.jimple.Stmt catchAllBeforeNoop = soot.jimple.Jimple.v().newNopStmt(); 1923 Iterator it = tryStmt.catchBlocks().iterator(); 1924 while (it.hasNext()) { 1925 1926 soot.jimple.Stmt noop3 = soot.jimple.Jimple.v().newNopStmt(); 1927 body.getUnits().add(noop3); 1928 1929 polyglot.ast.Catch catchBlock = (polyglot.ast.Catch)it.next(); 1931 1932 soot.jimple.Stmt catchRefNoop = soot.jimple.Jimple.v().newNopStmt(); 1934 body.getUnits().add(catchRefNoop); 1935 1936 createCatchFormal(catchBlock.formal()); 1937 1938 soot.jimple.Stmt catchStmtsNoop = soot.jimple.Jimple.v().newNopStmt(); 1939 body.getUnits().add(catchStmtsNoop); 1940 1941 if (catchStack == null){ 1942 catchStack = new Stack(); 1943 } 1944 catchStack.push(tryStmt); 1945 createBlock(catchBlock.body()); 1946 catchStack.pop(); 1947 1948 soot.jimple.Stmt catchGotoFinallyNoop = soot.jimple.Jimple.v().newNopStmt(); 1950 body.getUnits().add(catchGotoFinallyNoop); 1951 soot.jimple.Stmt catchFinallyNoop = soot.jimple.Jimple.v().newNopStmt(); 1952 1953 soot.jimple.Stmt catchGotoFinally = soot.jimple.Jimple.v().newGotoStmt(catchFinallyNoop); 1954 body.getUnits().add(catchGotoFinally); 1955 1956 soot.jimple.Stmt beforeCatchEndGotoNoop = soot.jimple.Jimple.v().newNopStmt(); 1958 body.getUnits().add(beforeCatchEndGotoNoop); 1959 soot.jimple.Stmt catchEndGoto = soot.jimple.Jimple.v().newGotoStmt(endNoop); 1960 body.getUnits().add(catchEndGoto); 1961 1962 1963 gotoMap.put(catchFinallyNoop, beforeCatchEndGotoNoop); 1964 1965 soot.Type sootType = Util.getSootType(catchBlock.catchType()); 1966 1967 addToExceptionList(noop1, noop2, noop3, soot.Scene.v().getSootClass(sootType.toString())); 1968 addToExceptionList(catchStmtsNoop, beforeCatchEndGotoNoop, catchAllBeforeNoop, soot.Scene.v().getSootClass("java.lang.Throwable")); 1969 } 1970 1971 soot.Local formalLocal = lg.generateLocal(soot.RefType.v("java.lang.Throwable")); 1973 1974 body.getUnits().add(catchAllBeforeNoop); 1975 soot.jimple.CaughtExceptionRef exceptRef = soot.jimple.Jimple.v().newCaughtExceptionRef(); 1976 soot.jimple.Stmt stmt = soot.jimple.Jimple.v().newIdentityStmt(formalLocal, exceptRef); 1977 body.getUnits().add(stmt); 1978 1979 soot.jimple.Stmt beforeCatchAllAssignNoop = soot.jimple.Jimple.v().newNopStmt(); 1981 body.getUnits().add(beforeCatchAllAssignNoop); 1982 soot.Local catchAllAssignLocal = lg.generateLocal(soot.RefType.v("java.lang.Throwable")); 1983 soot.jimple.Stmt catchAllAssign = soot.jimple.Jimple.v().newAssignStmt(catchAllAssignLocal, formalLocal); 1984 1985 body.getUnits().add(catchAllAssign); 1986 1987 soot.jimple.Stmt catchAllFinallyNoop = soot.jimple.Jimple.v().newNopStmt(); 1989 soot.jimple.Stmt catchAllGotoFinally = soot.jimple.Jimple.v().newGotoStmt(catchAllFinallyNoop); 1990 body.getUnits().add(catchAllGotoFinally); 1991 1992 soot.jimple.Stmt catchAllBeforeThrowNoop = soot.jimple.Jimple.v().newNopStmt(); 1994 body.getUnits().add(catchAllBeforeThrowNoop); 1995 soot.jimple.Stmt throwStmt = soot.jimple.Jimple.v().newThrowStmt(catchAllAssignLocal); 1996 throwStmt.addTag(new soot.tagkit.ThrowCreatedByCompilerTag()); 1997 body.getUnits().add(throwStmt); 1998 1999 gotoMap.put(catchAllFinallyNoop, catchAllBeforeThrowNoop); 2000 2001 soot.jimple.Stmt catchAllGotoEnd = soot.jimple.Jimple.v().newGotoStmt(endNoop); 2003 body.getUnits().add(catchAllGotoEnd); 2004 2005 addToExceptionList(beforeCatchAllAssignNoop, catchAllBeforeThrowNoop ,catchAllBeforeNoop, soot.Scene.v().getSootClass("java.lang.Throwable")); 2006 2007 Iterator finallyIt = gotoMap.keySet().iterator(); 2009 while (finallyIt.hasNext()) { 2010 2011 soot.jimple.Stmt noopStmt = (soot.jimple.Stmt)finallyIt.next(); 2012 body.getUnits().add(noopStmt); 2013 2014 createBlock(tryStmt.finallyBlock()); 2015 soot.jimple.Stmt backToStmt = (soot.jimple.Stmt)gotoMap.get(noopStmt); 2016 soot.jimple.Stmt backToGoto = soot.jimple.Jimple.v().newGotoStmt(backToStmt); 2017 body.getUnits().add(backToGoto); 2018 } 2019 body.getUnits().add(endNoop); 2020 2021 addToExceptionList(noop1, beforeEndGotoNoop, catchAllBeforeNoop, soot.Scene.v().getSootClass("java.lang.Throwable")); 2022 } 2023 2024 2027 private void addToExceptionList(soot.jimple.Stmt from, soot.jimple.Stmt to, soot.jimple.Stmt with, soot.SootClass exceptionClass) { 2028 if (exceptionTable == null) { 2029 exceptionTable = new ArrayList(); 2030 } 2031 soot.Trap trap = soot.jimple.Jimple.v().newTrap(exceptionClass, from, to, with); 2032 exceptionTable.add(trap); 2033 } 2034 2035 public soot.jimple.Constant createConstant(polyglot.ast.Expr expr){ 2036 Object constantVal = expr.constantValue(); 2037 2039 return getConstant(constantVal, expr.type()); 2040 } 2041 2042 2045 protected soot.Value createExpr(polyglot.ast.Expr expr){ 2046 if (expr.isConstant() && expr.constantValue() != null && expr.type() != null && !(expr instanceof polyglot.ast.Binary && expr.type().toString().equals("java.lang.String")) ){ 2050 return createConstant(expr); 2051 } 2052 if (expr instanceof polyglot.ast.Assign) { 2053 return getAssignLocal((polyglot.ast.Assign)expr); 2054 } 2055 else if (expr instanceof polyglot.ast.Lit) { 2056 return createLiteral((polyglot.ast.Lit)expr); 2057 } 2058 else if (expr instanceof polyglot.ast.Local) { 2059 return getLocal((polyglot.ast.Local)expr); 2060 } 2061 else if (expr instanceof polyglot.ast.Binary) { 2062 return getBinaryLocal((polyglot.ast.Binary)expr); 2063 } 2064 else if (expr instanceof polyglot.ast.Unary) { 2065 return getUnaryLocal((polyglot.ast.Unary)expr); 2066 } 2067 else if (expr instanceof polyglot.ast.Cast) { 2068 return getCastLocal((polyglot.ast.Cast)expr); 2069 } 2070 else if (expr instanceof polyglot.ast.ArrayAccess) { 2074 return getArrayRefLocal((polyglot.ast.ArrayAccess)expr); 2075 } 2076 else if (expr instanceof polyglot.ast.NewArray) { 2077 return getNewArrayLocal((polyglot.ast.NewArray)expr); 2078 } 2079 else if (expr instanceof polyglot.ast.Call) { 2080 return getCallLocal((polyglot.ast.Call)expr); 2081 } 2082 else if (expr instanceof polyglot.ast.New) { 2083 return getNewLocal((polyglot.ast.New)expr); 2084 } 2085 else if (expr instanceof polyglot.ast.Special) { 2086 return getSpecialLocal((polyglot.ast.Special)expr); 2087 } 2088 else if (expr instanceof polyglot.ast.Instanceof) { 2089 return getInstanceOfLocal((polyglot.ast.Instanceof)expr); 2090 } 2091 else if (expr instanceof polyglot.ast.Conditional) { 2092 return getConditionalLocal((polyglot.ast.Conditional)expr); 2093 } 2094 else if (expr instanceof polyglot.ast.Field) { 2095 return getFieldLocal((polyglot.ast.Field)expr); 2096 } 2097 else { 2098 throw new RuntimeException ("Unhandled Expression: "+expr); 2099 } 2100 2101 } 2102 2103 protected soot.Local handlePrivateFieldUnarySet(polyglot.ast.Unary unary){ 2104 polyglot.ast.Field fLeft = (polyglot.ast.Field)unary.expr(); 2105 2106 soot.Value base = base().getBaseLocal(fLeft.target()); 2107 soot.Value fieldGetLocal = getPrivateAccessFieldLocal(fLeft, base); 2108 2109 soot.Local tmp = generateLocal(fLeft.type()); 2110 soot.jimple.AssignStmt stmt1 = soot.jimple.Jimple.v().newAssignStmt(tmp, fieldGetLocal); 2111 body.getUnits().add(stmt1); 2112 Util.addLnPosTags(stmt1, unary.position()); 2113 2114 soot.Value incVal = base().getConstant(Util.getSootType(fLeft.type()), 1); 2115 2116 soot.jimple.BinopExpr binExpr; 2117 if (unary.operator() == polyglot.ast.Unary.PRE_INC || unary.operator() == polyglot.ast.Unary.POST_INC){ 2118 binExpr = soot.jimple.Jimple.v().newAddExpr(tmp, incVal); 2119 } 2120 else { 2121 binExpr = soot.jimple.Jimple.v().newSubExpr(tmp, incVal); 2122 } 2123 2124 soot.Local tmp2 = generateLocal(fLeft.type()); 2125 soot.jimple.AssignStmt assign = soot.jimple.Jimple.v().newAssignStmt(tmp2, binExpr); 2126 body.getUnits().add(assign); 2127 2128 if (unary.operator() == polyglot.ast.Unary.PRE_INC || unary.operator() == polyglot.ast.Unary.PRE_DEC){ 2129 return base().handlePrivateFieldSet(fLeft, tmp2, base); 2130 } 2131 else { 2132 base().handlePrivateFieldSet(fLeft, tmp2, base); 2133 return tmp; 2134 } 2135 } 2136 2137 protected soot.Local handlePrivateFieldAssignSet(polyglot.ast.Assign assign){ 2138 polyglot.ast.Field fLeft = (polyglot.ast.Field)assign.left(); 2139 2141 soot.Value right; 2147 soot.Value fieldBase = base().getBaseLocal(fLeft.target()); 2148 if (assign.operator() == polyglot.ast.Assign.ASSIGN){ 2149 right = base().getSimpleAssignRightLocal(assign); 2150 } 2151 else if ((assign.operator() == polyglot.ast.Assign.ADD_ASSIGN) && assign.type().toString().equals("java.lang.String")){ 2152 right = getStringConcatAssignRightLocal(assign); 2153 } 2154 else { 2155 soot.Local leftLocal = getPrivateAccessFieldLocal(fLeft, fieldBase); 2157 right = base().getAssignRightLocal(assign, leftLocal); 2159 } 2160 2161 return handlePrivateFieldSet(fLeft, right, fieldBase); 2162 } 2163 2164 protected soot.Local handlePrivateFieldSet(polyglot.ast.Expr expr, soot.Value right, soot.Value base){ 2165 polyglot.ast.Field fLeft = (polyglot.ast.Field)expr; 2168 soot.SootClass containClass = ((soot.RefType)Util.getSootType(fLeft.target().type())).getSootClass(); 2169 soot.SootMethod methToUse = addSetAccessMeth(containClass, fLeft, right); 2170 ArrayList params = new ArrayList(); 2171 if (!fLeft.flags().isStatic()){ 2172 params.add(base); 2175 } 2176 params.add(right); 2177 soot.jimple.InvokeExpr invoke = soot.jimple.Jimple.v().newStaticInvokeExpr(methToUse.makeRef(), params); 2178 soot.Local retLocal = lg.generateLocal(right.getType()); 2179 soot.jimple.AssignStmt assignStmt = soot.jimple.Jimple.v().newAssignStmt(retLocal, invoke); 2180 body.getUnits().add(assignStmt); 2181 2182 return retLocal; 2183 } 2184 2185 private soot.SootMethod addSetAccessMeth(soot.SootClass conClass, polyglot.ast.Field field, soot.Value param){ 2186 if ((InitialResolver.v().getPrivateFieldSetAccessMap() != null) && (InitialResolver.v().getPrivateFieldSetAccessMap().containsKey(new polyglot.util.IdentityKey(field.fieldInstance())))){ 2187 return (soot.SootMethod)InitialResolver.v().getPrivateFieldSetAccessMap().get(new polyglot.util.IdentityKey(field.fieldInstance())); 2188 } 2189 String name = "access$"+soot.javaToJimple.InitialResolver.v().getNextPrivateAccessCounter()+"00"; 2190 ArrayList paramTypes = new ArrayList(); 2191 if (!field.flags().isStatic()){ 2192 paramTypes.add(conClass.getType()); 2194 } 2196 soot.Type retType; 2197 paramTypes.add(Util.getSootType(field.type())); 2198 retType = Util.getSootType(field.type()); 2199 2207 soot.SootMethod meth = new soot.SootMethod(name, paramTypes, retType, soot.Modifier.STATIC); 2208 PrivateFieldSetMethodSource pfsms = new PrivateFieldSetMethodSource( 2209 Util.getSootType(field.type()), 2210 field.name(), 2211 field.flags().isStatic() 2212 ); 2213 2214 2215 conClass.addMethod(meth); 2216 meth.setActiveBody(pfsms.getBody(meth, null)); 2217 2218 InitialResolver.v().addToPrivateFieldSetAccessMap(field, meth); 2219 meth.addTag(new soot.tagkit.SyntheticTag()); 2220 return meth; 2221 } 2222 2223 private soot.SootMethod addGetFieldAccessMeth(soot.SootClass conClass, polyglot.ast.Field field){ 2224 if ((InitialResolver.v().getPrivateFieldGetAccessMap() != null) && (InitialResolver.v().getPrivateFieldGetAccessMap().containsKey(new polyglot.util.IdentityKey(field.fieldInstance())))){ 2225 return (soot.SootMethod)InitialResolver.v().getPrivateFieldGetAccessMap().get(new polyglot.util.IdentityKey(field.fieldInstance())); 2226 } 2227 String name = "access$"+soot.javaToJimple.InitialResolver.v().getNextPrivateAccessCounter()+"00"; 2228 ArrayList paramTypes = new ArrayList(); 2229 if (!field.flags().isStatic()){ 2230 paramTypes.add(conClass.getType()); } 2234 soot.SootMethod meth = new soot.SootMethod(name, paramTypes, Util.getSootType(field.type()), soot.Modifier.STATIC); 2235 PrivateFieldAccMethodSource pfams = new PrivateFieldAccMethodSource( 2236 Util.getSootType(field.type()), 2237 field.name(), 2238 field.flags().isStatic(), 2239 conClass 2240 ); 2241 2242 2243 conClass.addMethod(meth); 2244 meth.setActiveBody(pfams.getBody(meth, null)); 2245 2246 InitialResolver.v().addToPrivateFieldGetAccessMap(field, meth); 2247 meth.addTag(new soot.tagkit.SyntheticTag()); 2248 return meth; 2249 } 2250 2251 private soot.SootMethod addGetMethodAccessMeth(soot.SootClass conClass, polyglot.ast.Call call){ 2252 if ((InitialResolver.v().getPrivateMethodGetAccessMap() != null) && (InitialResolver.v().getPrivateMethodGetAccessMap().containsKey(new polyglot.util.IdentityKey(call.methodInstance())))){ 2253 return (soot.SootMethod)InitialResolver.v().getPrivateMethodGetAccessMap().get(new polyglot.util.IdentityKey(call.methodInstance())); 2254 } 2255 String name = "access$"+soot.javaToJimple.InitialResolver.v().getNextPrivateAccessCounter()+"00"; 2256 ArrayList paramTypes = new ArrayList(); 2257 if (!call.methodInstance().flags().isStatic()){ 2258 paramTypes.add(conClass.getType()); 2261 } 2262 ArrayList sootParamsTypes = getSootParamsTypes(call); 2263 paramTypes.addAll(sootParamsTypes); 2264 soot.SootMethod meth = new soot.SootMethod(name, paramTypes, Util.getSootType(call.methodInstance().returnType()), soot.Modifier.STATIC); 2265 PrivateMethodAccMethodSource pmams = new PrivateMethodAccMethodSource( 2266 call.methodInstance() 2267 ); 2268 2269 2270 conClass.addMethod(meth); 2271 meth.setActiveBody(pmams.getBody(meth, null)); 2272 2273 InitialResolver.v().addToPrivateMethodGetAccessMap(call, meth); 2274 meth.addTag(new soot.tagkit.SyntheticTag()); 2275 return meth; 2276 } 2277 2278 2279 2280 protected soot.Value getAssignRightLocal(polyglot.ast.Assign assign, soot.Local leftLocal){ 2281 2282 if (assign.operator() == polyglot.ast.Assign.ASSIGN){ 2283 return base().getSimpleAssignRightLocal(assign); 2284 } 2285 else if (assign.operator() == polyglot.ast.Assign.ADD_ASSIGN && assign.type().toString().equals("java.lang.String")){ 2286 return getStringConcatAssignRightLocal(assign); 2287 } 2288 else { 2289 return getComplexAssignRightLocal(assign, leftLocal); 2290 } 2291 } 2292 2293 protected soot.Value getSimpleAssignRightLocal(polyglot.ast.Assign assign){ 2294 boolean repush = false; 2295 soot.jimple.Stmt tNoop = null; 2296 soot.jimple.Stmt fNoop = null; 2297 if (!trueNoop.empty() && !falseNoop.empty()){ 2298 tNoop = (soot.jimple.Stmt)trueNoop.pop(); 2299 fNoop = (soot.jimple.Stmt)falseNoop.pop(); 2300 repush = true; 2301 } 2302 2303 soot.Value right = base().createExpr(assign.right()); 2304 2305 if (repush){ 2306 trueNoop.push(tNoop); 2307 falseNoop.push(fNoop); 2308 } 2309 2310 if (right instanceof soot.jimple.ConditionExpr) { 2311 right = handleCondBinExpr((soot.jimple.ConditionExpr)right); 2312 } 2313 return right; 2314 } 2315 2316 private soot.Local getStringConcatAssignRightLocal(polyglot.ast.Assign assign){ 2317 soot.Local sb = (soot.Local)createStringBuffer(assign); 2318 sb = generateAppends(assign.left(), sb); 2319 sb = generateAppends(assign.right(), sb); 2320 soot.Local rLocal = createToString(sb, assign); 2321 return rLocal; 2322 } 2323 2324 private soot.Local getComplexAssignRightLocal(polyglot.ast.Assign assign, soot.Local leftLocal){ 2325 soot.Value right = base().createExpr(assign.right()); 2326 if (right instanceof soot.jimple.ConditionExpr) { 2327 right = handleCondBinExpr((soot.jimple.ConditionExpr)right); 2328 } 2329 2330 soot.jimple.BinopExpr binop = null; 2331 if (assign.operator() == polyglot.ast.Assign.ADD_ASSIGN) { 2332 binop = soot.jimple.Jimple.v().newAddExpr(leftLocal, right); 2333 } 2334 else if (assign.operator() == polyglot.ast.Assign.SUB_ASSIGN){ 2335 binop = soot.jimple.Jimple.v().newSubExpr(leftLocal, right); 2336 } 2337 else if (assign.operator() == polyglot.ast.Assign.MUL_ASSIGN) { 2338 binop = soot.jimple.Jimple.v().newMulExpr(leftLocal, right); 2339 } 2340 else if (assign.operator() == polyglot.ast.Assign.DIV_ASSIGN) { 2341 binop = soot.jimple.Jimple.v().newDivExpr(leftLocal, right); 2342 } 2343 else if (assign.operator() == polyglot.ast.Assign.MOD_ASSIGN) { 2344 binop = soot.jimple.Jimple.v().newRemExpr(leftLocal, right); 2345 } 2346 else if (assign.operator() == polyglot.ast.Assign.SHL_ASSIGN) { 2347 binop = soot.jimple.Jimple.v().newShlExpr(leftLocal, right); 2348 } 2349 else if (assign.operator() == polyglot.ast.Assign.SHR_ASSIGN) { 2350 binop = soot.jimple.Jimple.v().newShrExpr(leftLocal, right); 2351 } 2352 else if (assign.operator() == polyglot.ast.Assign.USHR_ASSIGN) { 2353 binop = soot.jimple.Jimple.v().newUshrExpr(leftLocal, right); 2354 } 2355 else if (assign.operator() == polyglot.ast.Assign.BIT_AND_ASSIGN) { 2356 binop = soot.jimple.Jimple.v().newAndExpr(leftLocal, right); 2357 } 2358 else if (assign.operator() == polyglot.ast.Assign.BIT_OR_ASSIGN) { 2359 binop = soot.jimple.Jimple.v().newOrExpr(leftLocal, right); 2360 } 2361 else if (assign.operator() == polyglot.ast.Assign.BIT_XOR_ASSIGN) { 2362 binop = soot.jimple.Jimple.v().newXorExpr(leftLocal, right); 2363 } 2364 2365 soot.Local retLocal = lg.generateLocal(leftLocal.getType()); 2366 soot.jimple.AssignStmt assignStmt = soot.jimple.Jimple.v().newAssignStmt(retLocal, binop); 2367 body.getUnits().add(assignStmt); 2368 2369 Util.addLnPosTags(binop.getOp1Box(), assign.left().position()); 2370 Util.addLnPosTags(binop.getOp2Box(), assign.right().position()); 2371 2372 return retLocal; 2373 } 2374 2375 private soot.Value getSimpleAssignLocal(polyglot.ast.Assign assign){ 2376 soot.jimple.AssignStmt stmt; 2377 soot.Value left = base().createLHS(assign.left()); 2378 2379 soot.Value right = base().getSimpleAssignRightLocal(assign); 2380 stmt = soot.jimple.Jimple.v().newAssignStmt(left, right); 2381 body.getUnits().add(stmt); 2382 Util.addLnPosTags(stmt, assign.position()); 2383 Util.addLnPosTags(stmt.getRightOpBox(), assign.right().position()); 2384 Util.addLnPosTags(stmt.getLeftOpBox(), assign.left().position()); 2385 if (left instanceof soot.Local){ 2386 return left; 2387 } 2388 else { 2389 return right; 2390 } 2391 2392 } 2393 2394 private soot.Value getStrConAssignLocal(polyglot.ast.Assign assign){ 2395 soot.jimple.AssignStmt stmt; 2396 soot.Value left = base().createLHS(assign.left()); 2397 2398 soot.Value right = getStringConcatAssignRightLocal(assign); 2399 stmt = soot.jimple.Jimple.v().newAssignStmt(left, right); 2400 body.getUnits().add(stmt); 2401 Util.addLnPosTags(stmt, assign.position()); 2402 Util.addLnPosTags(stmt.getRightOpBox(), assign.right().position()); 2403 Util.addLnPosTags(stmt.getLeftOpBox(), assign.left().position()); 2404 if (left instanceof soot.Local){ 2405 return left; 2406 } 2407 else { 2408 return right; 2409 } 2410 2411 } 2412 2413 2416 protected soot.Value getAssignLocal(polyglot.ast.Assign assign) { 2417 2418 if (base().needsAccessor(assign.left())){ 2424 return base().handlePrivateFieldAssignSet(assign); 2427 } 2428 2429 if (assign.operator() == polyglot.ast.Assign.ASSIGN){ 2430 return getSimpleAssignLocal(assign); 2431 } 2432 2433 if ((assign.operator() == polyglot.ast.Assign.ADD_ASSIGN) && assign.type().toString().equals("java.lang.String")){ 2434 return getStrConAssignLocal(assign); 2435 } 2436 2437 soot.jimple.AssignStmt stmt; 2438 soot.Value left = base().createLHS(assign.left()); 2439 soot.Value left2 = (soot.Value)left.clone(); 2440 2441 soot.Local leftLocal; 2442 if (left instanceof soot.Local){ 2443 leftLocal = (soot.Local)left; 2444 2445 } 2446 else { 2447 leftLocal = lg.generateLocal(left.getType()); 2448 soot.jimple.AssignStmt stmt1 = soot.jimple.Jimple.v().newAssignStmt(leftLocal, left); 2449 body.getUnits().add(stmt1); 2450 Util.addLnPosTags(stmt1, assign.position()); 2451 } 2452 2453 2454 soot.Value right = base().getAssignRightLocal(assign, leftLocal); 2455 soot.jimple.AssignStmt stmt2 = soot.jimple.Jimple.v().newAssignStmt(leftLocal, right); 2456 body.getUnits().add(stmt2); 2457 Util.addLnPosTags(stmt2, assign.position()); 2458 Util.addLnPosTags(stmt2.getRightOpBox(), assign.right().position()); 2459 Util.addLnPosTags(stmt2.getLeftOpBox(), assign.left().position()); 2460 2461 if (!(left instanceof soot.Local)) { 2462 soot.jimple.AssignStmt stmt3 = soot.jimple.Jimple.v().newAssignStmt(left2, leftLocal); 2463 body.getUnits().add(stmt3); 2464 Util.addLnPosTags(stmt3, assign.position()); 2465 Util.addLnPosTags(stmt3.getRightOpBox(), assign.right().position()); 2466 Util.addLnPosTags(stmt3.getLeftOpBox(), assign.left().position()); 2467 } 2468 2469 return leftLocal; 2470 2471 } 2472 2473 2474 2477 private soot.Value getFieldLocalLeft(polyglot.ast.Field field){ 2478 polyglot.ast.Receiver receiver = field.target(); 2479 if ((field.name().equals("length")) && (receiver.type() instanceof polyglot.types.ArrayType)){ 2480 return getSpecialArrayLengthLocal(field); 2481 } 2482 else { 2483 return getFieldRef(field); 2484 } 2485 } 2486 2487 2490 private soot.Value getFieldLocal(polyglot.ast.Field field){ 2491 2492 2493 polyglot.ast.Receiver receiver = field.target(); 2494 soot.javaToJimple.PolyglotMethodSource ms = (soot.javaToJimple.PolyglotMethodSource)body.getMethod().getSource(); 2495 2496 if ((field.name().equals("length")) && (receiver.type() instanceof polyglot.types.ArrayType)){ 2497 return getSpecialArrayLengthLocal(field); 2498 } 2499 else if (field.name().equals("class")){ 2500 throw new RuntimeException ("Should go through ClassLit"); 2501 } 2502 else if (base().needsAccessor(field)){ 2503 2506 soot.Value base = base().getBaseLocal(field.target()); 2507 return getPrivateAccessFieldLocal(field, base); 2508 } 2509 if ((field.target() instanceof polyglot.ast.Special) && (((polyglot.ast.Special)field.target()).kind() == polyglot.ast.Special.SUPER) && (((polyglot.ast.Special)field.target()).qualifier() != null)){ 2510 return getSpecialSuperQualifierLocal(field); 2511 } 2512 else if (shouldReturnConstant(field)){ 2513 2514 return getReturnConstant(field); 2515 } 2517 else { 2518 2519 soot.jimple.FieldRef fieldRef = getFieldRef(field); 2520 soot.Local baseLocal = generateLocal(field.type()); 2521 soot.jimple.AssignStmt fieldAssignStmt = soot.jimple.Jimple.v().newAssignStmt(baseLocal, fieldRef); 2522 2523 body.getUnits().add(fieldAssignStmt); 2524 Util.addLnPosTags(fieldAssignStmt, field.position()); 2525 Util.addLnPosTags(fieldAssignStmt.getRightOpBox(), field.position()); 2526 return baseLocal; 2527 } 2528 } 2529 2530 protected boolean needsAccessor(polyglot.ast.Expr expr){ 2531 if (!(expr instanceof polyglot.ast.Field) && !(expr instanceof polyglot.ast.Call)) return false; 2532 else { 2533 if (expr instanceof polyglot.ast.Field){ 2534 return needsAccessor(((polyglot.ast.Field)expr).fieldInstance()); 2535 } 2536 else { 2537 return needsAccessor(((polyglot.ast.Call)expr).methodInstance()); 2538 } 2539 } 2540 } 2541 2542 2547 protected boolean needsAccessor(polyglot.types.MemberInstance inst){ 2548 if (inst.flags().isPrivate()){ 2549 if (!Util.getSootType(inst.container()).equals(body.getMethod().getDeclaringClass().getType())){ 2550 return true; 2551 } 2552 } 2553 else if (inst.flags().isProtected()){ 2554 if (Util.getSootType(inst.container()).equals(body.getMethod().getDeclaringClass().getType())){ 2555 return false; 2556 } 2557 soot.SootClass currentClass = body.getMethod().getDeclaringClass(); 2558 if (currentClass.getSuperclass().getType().equals(Util.getSootType(inst.container()))){ 2559 return false; 2560 } 2561 while (currentClass.hasOuterClass()){ 2562 currentClass = currentClass.getOuterClass(); 2563 if (Util.getSootType(inst.container()).equals(currentClass.getType())){ 2564 return false; 2565 } 2566 else if (Util.getSootType(inst.container()).equals(currentClass.getSuperclass().getType())){ 2567 return true; 2568 } 2569 } 2570 return false; 2571 } 2572 2573 return false; 2574 } 2575 2576 2580 2588 2589 2594 2628 2630 2631 private soot.jimple.Constant getReturnConstant(polyglot.ast.Field field){ 2632 return getConstant(field.constantValue(), field.type()); 2633 } 2634 2635 private soot.jimple.Constant getConstant(Object constVal, polyglot.types.Type type){ 2636 if (constVal instanceof String ){ 2638 return soot.jimple.StringConstant.v((String )constVal); 2639 } 2640 else if (constVal instanceof Boolean ){ 2641 boolean val = ((Boolean )constVal).booleanValue(); 2642 return soot.jimple.IntConstant.v(val ? 1 : 0); 2643 } 2644 else if (type.isChar()){ 2645 char val; 2646 2647 if (constVal instanceof Integer ){ 2648 val = (char)((Integer )constVal).intValue(); 2649 } 2650 else { 2651 val = ((Character )constVal).charValue(); 2652 } 2653 return soot.jimple.IntConstant.v(val); 2655 } 2656 else { 2657 Number num = (Number )constVal; 2658 num = createConstantCast(type, num); 2660 if (num instanceof Long ) { 2662 return soot.jimple.LongConstant.v(((Long )num).longValue()); 2664 } 2665 else if (num instanceof Double ) { 2666 return soot.jimple.DoubleConstant.v(((Double )num).doubleValue()); 2667 } 2668 else if (num instanceof Float ) { 2669 return soot.jimple.FloatConstant.v(((Float )num).floatValue()); 2670 } 2671 else if (num instanceof Byte ) { 2672 return soot.jimple.IntConstant.v(((Byte )num).byteValue()); 2673 } 2674 else if (num instanceof Short ) { 2675 return soot.jimple.IntConstant.v(((Short )num).shortValue()); 2676 } 2677 else { 2678 return soot.jimple.IntConstant.v(((Integer )num).intValue()); 2679 } 2680 } 2681 } 2682 2683 private Number createConstantCast(polyglot.types.Type fieldType, Number constant) { 2684 if (constant instanceof Integer ){ 2685 if (fieldType.isDouble()){ 2686 return new Double ((double)((Integer )constant).intValue()); 2687 } 2688 else if (fieldType.isFloat()){ 2689 return new Float ((float)((Integer )constant).intValue()); 2690 } 2691 else if (fieldType.isLong()){ 2692 return new Long ((long)((Integer )constant).intValue()); 2693 } 2694 } 2695 return constant; 2696 } 2697 2698 private boolean shouldReturnConstant(polyglot.ast.Field field){ 2699 if (field.isConstant() && field.constantValue() != null) { 2700 return true; 2701 } 2702 return false; 2703 } 2704 2705 2708 protected soot.jimple.FieldRef getFieldRef(polyglot.ast.Field field) { 2709 2710 soot.SootClass receiverClass = ((soot.RefType)Util.getSootType(field.target().type())).getSootClass(); 2711 soot.SootFieldRef receiverField = soot.Scene.v().makeFieldRef(receiverClass, field.name(), Util.getSootType(field.type()), field.flags().isStatic()); 2712 2713 soot.jimple.FieldRef fieldRef; 2714 if (field.fieldInstance().flags().isStatic()) { 2715 fieldRef = soot.jimple.Jimple.v().newStaticFieldRef(receiverField); 2716 } 2717 else { 2718 soot.Local base; 2719 base = (soot.Local)base().getBaseLocal(field.target()); 2720 fieldRef = soot.jimple.Jimple.v().newInstanceFieldRef(base, receiverField); 2721 } 2722 2723 if (field.target() instanceof polyglot.ast.Local && fieldRef instanceof soot.jimple.InstanceFieldRef){ 2724 Util.addLnPosTags(((soot.jimple.InstanceFieldRef)fieldRef).getBaseBox(), field.target().position()); 2725 } 2726 return fieldRef; 2727 } 2728 2729 2732 private soot.Local getPrivateAccessFieldLocal(polyglot.ast.Field field, soot.Value base) { 2733 2734 2739 soot.SootMethod toInvoke; 2740 soot.SootClass invokeClass; 2741 if (field.fieldInstance().flags().isPrivate()){ 2742 toInvoke = addGetFieldAccessMeth(((soot.RefType)Util.getSootType(field.fieldInstance().container())).getSootClass(), field); 2743 invokeClass = ((soot.RefType)Util.getSootType(field.fieldInstance().container())).getSootClass(); 2744 } 2745 else { 2746 if (InitialResolver.v().hierarchy() == null){ 2747 InitialResolver.v().hierarchy(new soot.FastHierarchy()); 2748 } 2749 soot.SootClass containingClass = ((soot.RefType)Util.getSootType(field.fieldInstance().container())).getSootClass(); 2750 soot.SootClass addToClass; 2751 if (body.getMethod().getDeclaringClass().hasOuterClass()){ 2752 addToClass = body.getMethod().getDeclaringClass().getOuterClass(); 2753 2754 while (!InitialResolver.v().hierarchy().canStoreType(containingClass.getType(), addToClass.getType())){ 2755 if (addToClass.hasOuterClass()){ 2756 addToClass = addToClass.getOuterClass(); 2757 } 2758 else { 2759 break; 2760 } 2761 } 2762 } 2763 else{ 2764 addToClass = containingClass; 2765 } 2766 invokeClass = addToClass; 2767 toInvoke = addGetFieldAccessMeth(addToClass, field); 2768 } 2769 2770 ArrayList params = new ArrayList(); 2771 if (!field.fieldInstance().flags().isStatic()) { 2772 params.add(base); 2773 2783 2784 2787 2790 2791 2793 } 2798 2799 return Util.getPrivateAccessFieldInvoke(toInvoke.makeRef(), params, body, lg); 2800 } 2801 2802 2803 2806 private soot.Local getSpecialClassLitLocal(polyglot.ast.ClassLit lit) { 2807 2808 if (lit.typeNode().type().isPrimitive()){ 2809 polyglot.types.PrimitiveType primType = (polyglot.types.PrimitiveType)lit.typeNode().type(); 2810 soot.Local retLocal = lg.generateLocal(soot.RefType.v("java.lang.Class")); 2811 soot.SootFieldRef primField = null; 2812 if (primType.isBoolean()){ 2813 primField = soot.Scene.v().makeFieldRef(soot.Scene.v().getSootClass("java.lang.Boolean"), "TYPE", soot.RefType.v("java.lang.Class"), true); 2814 } 2815 else if (primType.isByte()){ 2816 primField = soot.Scene.v().makeFieldRef(soot.Scene.v().getSootClass("java.lang.Byte"), "TYPE", soot.RefType.v("java.lang.Class"), true); 2817 } 2818 else if (primType.isChar()){ 2819 primField = soot.Scene.v().makeFieldRef(soot.Scene.v().getSootClass("java.lang.Character"), "TYPE", soot.RefType.v("java.lang.Class"), true); 2820 } 2821 else if (primType.isDouble()){ 2822 primField = soot.Scene.v().makeFieldRef(soot.Scene.v().getSootClass("java.lang.Double"), "TYPE", soot.RefType.v("java.lang.Class"), true); 2823 } 2824 else if (primType.isFloat()){ 2825 primField = soot.Scene.v().makeFieldRef(soot.Scene.v().getSootClass("java.lang.Float"), "TYPE", soot.RefType.v("java.lang.Class"), true); 2826 } 2827 else if (primType.isInt()){ 2828 primField = soot.Scene.v().makeFieldRef(soot.Scene.v().getSootClass("java.lang.Integer"), "TYPE", soot.RefType.v("java.lang.Class"), true); 2829 } 2830 else if (primType.isLong()){ 2831 primField = soot.Scene.v().makeFieldRef(soot.Scene.v().getSootClass("java.lang.Long"), "TYPE", soot.RefType.v("java.lang.Class"), true); 2832 } 2833 else if (primType.isShort()){ 2834 primField = soot.Scene.v().makeFieldRef(soot.Scene.v().getSootClass("java.lang.Short"), "TYPE", soot.RefType.v("java.lang.Class"), true); 2835 } 2836 else if (primType.isVoid()){ 2837 primField = soot.Scene.v().makeFieldRef(soot.Scene.v().getSootClass("java.lang.Void"), "TYPE", soot.RefType.v("java.lang.Class"), true); 2838 } 2839 soot.jimple.StaticFieldRef fieldRef = soot.jimple.Jimple.v().newStaticFieldRef(primField); 2840 soot.jimple.AssignStmt assignStmt = soot.jimple.Jimple.v().newAssignStmt(retLocal, fieldRef); 2841 body.getUnits().add(assignStmt); 2842 return retLocal; 2843 } 2844 else { 2845 soot.SootClass thisClass = body.getMethod().getDeclaringClass(); 2847 String fieldName = Util.getFieldNameForClassLit(lit.typeNode().type()); 2848 soot.Type fieldType = soot.RefType.v("java.lang.Class"); 2849 soot.Local fieldLocal = lg.generateLocal(soot.RefType.v("java.lang.Class")); 2850 soot.SootFieldRef sootField = null; 2851 if (thisClass.isInterface()){ 2852 HashMap specialAnonMap = InitialResolver.v().specialAnonMap(); 2853 if ((specialAnonMap != null) && (specialAnonMap.containsKey(thisClass))){ 2854 soot.SootClass specialClass = (soot.SootClass)specialAnonMap.get(thisClass); 2855 sootField = soot.Scene.v().makeFieldRef(specialClass, fieldName, fieldType, true); 2856 } 2857 else { 2858 throw new RuntimeException ("Class is interface so it must have an anon class to handle class lits but its anon class cannot be found."); 2859 } 2860 } 2861 else { 2862 sootField = soot.Scene.v().makeFieldRef(thisClass, fieldName, fieldType, true); 2863 } 2864 soot.jimple.StaticFieldRef fieldRef = soot.jimple.Jimple.v().newStaticFieldRef(sootField); 2865 soot.jimple.Stmt fieldAssign = soot.jimple.Jimple.v().newAssignStmt(fieldLocal, fieldRef); 2866 body.getUnits().add(fieldAssign); 2867 2868 soot.jimple.Stmt noop1 = soot.jimple.Jimple.v().newNopStmt(); 2869 soot.jimple.Expr neExpr = soot.jimple.Jimple.v().newNeExpr(fieldLocal, soot.jimple.NullConstant.v()); 2870 soot.jimple.Stmt ifStmt = soot.jimple.Jimple.v().newIfStmt(neExpr, noop1); 2871 body.getUnits().add(ifStmt); 2872 2873 ArrayList paramTypes = new ArrayList(); 2874 paramTypes.add(soot.RefType.v("java.lang.String")); 2875 soot.SootMethodRef invokeMeth = null; 2876 if (thisClass.isInterface()){ 2877 HashMap specialAnonMap = InitialResolver.v().specialAnonMap(); 2878 if ((specialAnonMap != null) && (specialAnonMap.containsKey(thisClass))){ 2879 soot.SootClass specialClass = (soot.SootClass)specialAnonMap.get(thisClass); 2880 invokeMeth = soot.Scene.v().makeMethodRef(specialClass, "class$", paramTypes, soot.RefType.v("java.lang.Class"), true); 2881 } 2882 else { 2883 throw new RuntimeException ("Class is interface so it must have an anon class to handle class lits but its anon class cannot be found."); 2884 } 2885 } 2886 else { 2887 invokeMeth = soot.Scene.v().makeMethodRef(thisClass, "class$", paramTypes, soot.RefType.v("java.lang.Class"), true); 2888 } 2889 ArrayList params = new ArrayList(); 2890 params.add(soot.jimple.StringConstant.v(Util.getParamNameForClassLit(lit.typeNode().type()))); 2891 soot.jimple.Expr classInvoke = soot.jimple.Jimple.v().newStaticInvokeExpr(invokeMeth, params); 2892 soot.Local methLocal = lg.generateLocal(soot.RefType.v("java.lang.Class")); 2893 soot.jimple.Stmt invokeAssign = soot.jimple.Jimple.v().newAssignStmt(methLocal, classInvoke); 2894 body.getUnits().add(invokeAssign); 2895 2896 soot.jimple.Stmt assignField = soot.jimple.Jimple.v().newAssignStmt(fieldRef, methLocal); 2897 body.getUnits().add(assignField); 2898 2899 soot.jimple.Stmt noop2 = soot.jimple.Jimple.v().newNopStmt(); 2900 soot.jimple.Stmt goto1 = soot.jimple.Jimple.v().newGotoStmt(noop2); 2901 body.getUnits().add(goto1); 2902 2903 body.getUnits().add(noop1); 2904 fieldAssign = soot.jimple.Jimple.v().newAssignStmt(methLocal, fieldRef); 2905 body.getUnits().add(fieldAssign); 2906 body.getUnits().add(noop2); 2907 2908 return methLocal; 2909 } 2910 } 2911 2912 2916 private soot.Local getSpecialArrayLengthLocal(polyglot.ast.Field field) { 2917 2918 soot.Local localField; 2919 polyglot.ast.Receiver receiver = field.target(); 2920 if (receiver instanceof polyglot.ast.Local) { 2921 localField = getLocal((polyglot.ast.Local)receiver); 2922 } 2923 else if (receiver instanceof polyglot.ast.Expr){ 2924 localField = (soot.Local)base().createExpr((polyglot.ast.Expr)receiver); 2925 } 2926 else { 2927 localField = generateLocal(receiver.type()); 2928 } 2929 soot.jimple.LengthExpr lengthExpr = soot.jimple.Jimple.v().newLengthExpr(localField); 2930 soot.Local retLocal = lg.generateLocal(soot.IntType.v()); 2931 soot.jimple.Stmt assign = soot.jimple.Jimple.v().newAssignStmt(retLocal, lengthExpr); 2932 body.getUnits().add(assign); 2933 Util.addLnPosTags(assign, field.position()); 2934 Util.addLnPosTags(lengthExpr.getOpBox(), field.target().position()); 2935 return retLocal; 2936 } 2937 2938 2941 private soot.Value getBinaryLocal(polyglot.ast.Binary binary) { 2942 2944 soot.Value rhs; 2945 2946 if (binary.operator() == polyglot.ast.Binary.COND_AND) { 2947 return createCondAnd(binary); 2948 } 2949 if (binary.operator() == polyglot.ast.Binary.COND_OR) { 2950 return createCondOr(binary); 2951 } 2952 2953 if (binary.type().toString().equals("java.lang.String")){ 2954 if (areAllStringLits(binary)){ 2956 String result = createStringConstant(binary); 2957 return soot.jimple.StringConstant.v(result); 2959 } 2960 else { 2961 soot.Local sb = (soot.Local)createStringBuffer(binary); 2962 sb = generateAppends(binary.left(), sb); 2963 sb = generateAppends(binary.right(), sb); 2964 return createToString(sb, binary); 2965 } 2966 } 2967 2968 soot.Value lVal = base().createExpr(binary.left()); 2969 soot.Value rVal = base().createExpr(binary.right()); 2970 2971 if (isComparisonBinary(binary.operator())) { 2972 rhs = getBinaryComparisonExpr(lVal, rVal, binary.operator()); 2973 } 2974 else { 2975 rhs = getBinaryExpr(lVal, rVal, binary.operator()); 2976 } 2977 2978 if (rhs instanceof soot.jimple.BinopExpr) { 2979 Util.addLnPosTags(((soot.jimple.BinopExpr)rhs).getOp1Box(), binary.left().position()); 2980 Util.addLnPosTags(((soot.jimple.BinopExpr)rhs).getOp2Box(), binary.right().position()); 2981 } 2982 2983 if (rhs instanceof soot.jimple.ConditionExpr) { 2984 return rhs; 2985 } 2986 2987 soot.Local lhs = generateLocal(binary.type()); 2988 2989 2990 soot.jimple.AssignStmt assignStmt = soot.jimple.Jimple.v().newAssignStmt(lhs, rhs); 2991 body.getUnits().add(assignStmt); 2992 2994 2995 Util.addLnPosTags(assignStmt.getRightOpBox(), binary.position()); 2996 Util.addLnPosTags(assignStmt, binary.position()); 2997 return lhs; 2998 } 2999 3000 private boolean areAllStringLits(polyglot.ast.Node node){ 3001 3002 if (node instanceof polyglot.ast.StringLit) return true; 3004 else if ( node instanceof polyglot.ast.Field) { 3005 if (shouldReturnConstant((polyglot.ast.Field)node)) return true; 3006 else return false; 3007 } 3008 else if (node instanceof polyglot.ast.Binary){ 3009 if (areAllStringLitsBinary((polyglot.ast.Binary)node)) return true; 3010 return false; 3011 } 3012 else if (node instanceof polyglot.ast.Unary){ 3013 polyglot.ast.Unary unary = (polyglot.ast.Unary)node; 3014 if (unary.isConstant()){ 3015 return true; 3016 } 3017 return false; 3018 } 3019 else if (node instanceof polyglot.ast.Cast){ 3020 polyglot.ast.Cast cast = (polyglot.ast.Cast)node; 3021 if (cast.isConstant()){ 3022 return true; 3023 } 3024 return false; 3025 } 3026 else if (node instanceof polyglot.ast.Lit){ 3027 polyglot.ast.Lit lit = (polyglot.ast.Lit)node; 3028 if (lit.isConstant()){ 3030 return true; 3031 } 3032 return false; 3033 } 3034 return false; 3035 } 3036 3037 private boolean areAllStringLitsBinary(polyglot.ast.Binary binary){ 3038 if (areAllStringLits(binary.left()) && areAllStringLits(binary.right())) return true; 3039 else return false; 3040 } 3041 3042 private String createStringConstant(polyglot.ast.Node node){ 3043 String s = null; 3045 if (node instanceof polyglot.ast.StringLit){ 3046 s = ((polyglot.ast.StringLit)node).value(); 3047 } 3048 else if (node instanceof polyglot.ast.Cast){ 3049 polyglot.ast.Cast cast = (polyglot.ast.Cast)node; 3050 if (cast.type().isChar()){ 3051 s = "" + (char)((Character )cast.constantValue()).charValue(); 3052 } 3053 else { 3054 s = "" + cast.constantValue(); 3055 } 3056 } 3057 else if (node instanceof polyglot.ast.Unary){ 3058 polyglot.ast.Unary unary = (polyglot.ast.Unary)node; 3059 s = "" + unary.constantValue(); 3060 } 3061 else if (node instanceof polyglot.ast.CharLit){ 3062 s = "" + ((polyglot.ast.CharLit)node).value(); 3063 } 3064 else if (node instanceof polyglot.ast.BooleanLit){ 3065 s = "" + ((polyglot.ast.BooleanLit)node).value(); 3066 } 3067 else if (node instanceof polyglot.ast.IntLit){ 3068 s = "" + ((polyglot.ast.IntLit)node).value(); 3069 } 3070 else if (node instanceof polyglot.ast.FloatLit){ 3071 s = "" + ((polyglot.ast.FloatLit)node).value(); 3072 } 3073 else if (node instanceof polyglot.ast.NullLit){ 3074 s = "null"; 3075 } 3076 else if (node instanceof polyglot.ast.Field){ 3077 polyglot.ast.Field field = (polyglot.ast.Field)node; 3078 if (field.fieldInstance().constantValue() instanceof String ){ 3079 s = (String )field.constantValue(); 3080 } 3081 else if (field.fieldInstance().constantValue() instanceof Boolean ){ 3082 boolean val = ((Boolean )field.constantValue()).booleanValue(); 3083 int temp = val ? 1 : 0; 3084 s = "" + temp; 3085 } 3086 else if (field.type().isChar()){ 3087 3088 char val = (char)((Integer )field.constantValue()).intValue(); 3089 s = "" + val; 3090 } 3091 else { 3092 Number num = (Number )field.fieldInstance().constantValue(); 3093 num = createConstantCast(field.type(), num); 3094 if (num instanceof Long ) { 3095 s = "" + ((Long )num).longValue(); 3096 } 3097 else if (num instanceof Double ) { 3098 s = "" + ((Double )num).doubleValue(); 3099 } 3100 else if (num instanceof Float ) { 3101 s = "" + ((Float )num).floatValue(); 3102 } 3103 else if (num instanceof Byte ) { 3104 s = "" + ((Byte )num).byteValue(); 3105 } 3106 else if (num instanceof Short ) { 3107 s = "" + ((Short )num).shortValue(); 3108 } 3109 else { 3110 s = "" + ((Integer )num).intValue(); 3111 } 3112 } 3113 3114 } 3115 else if (node instanceof polyglot.ast.Binary){ 3116 s = createStringConstantBinary((polyglot.ast.Binary)node); 3117 } 3118 else { 3119 throw new RuntimeException ("No other string constant folding done"); 3120 } 3121 return s; 3122 } 3123 3124 private String createStringConstantBinary(polyglot.ast.Binary binary){ 3125 String s = null; 3127 if (Util.getSootType(binary.type()).toString().equals("java.lang.String")){ 3128 s = createStringConstant(binary.left()) + createStringConstant(binary.right()); 3130 } 3131 else { 3132 s = binary.constantValue().toString(); 3134 } 3135 return s; 3136 3137 } 3138 3139 private boolean isComparisonBinary(polyglot.ast.Binary.Operator op) { 3140 if ((op == polyglot.ast.Binary.EQ) || (op == polyglot.ast.Binary.NE) || 3141 (op == polyglot.ast.Binary.GE) || (op == polyglot.ast.Binary.GT) || 3142 (op == polyglot.ast.Binary.LE) || (op == polyglot.ast.Binary.LT)) { 3143 3144 return true; 3145 } 3146 else { 3147 return false; 3148 } 3149 3150 3151 } 3152 3153 3156 private soot.Value getBinaryExpr(soot.Value lVal, soot.Value rVal, polyglot.ast.Binary.Operator operator){ 3157 3158 soot.Value rValue = null; 3159 3160 if (lVal instanceof soot.jimple.ConditionExpr) { 3161 lVal = handleCondBinExpr((soot.jimple.ConditionExpr)lVal); 3162 } 3163 if (rVal instanceof soot.jimple.ConditionExpr) { 3164 rVal = handleCondBinExpr((soot.jimple.ConditionExpr)rVal); 3165 } 3166 if (operator == polyglot.ast.Binary.ADD){ 3167 3168 rValue = soot.jimple.Jimple.v().newAddExpr(lVal, rVal); 3169 } 3170 else if (operator == polyglot.ast.Binary.SUB){ 3171 rValue = soot.jimple.Jimple.v().newSubExpr(lVal, rVal); 3172 } 3173 else if (operator == polyglot.ast.Binary.MUL){ 3174 rValue = soot.jimple.Jimple.v().newMulExpr(lVal, rVal); 3175 } 3176 else if (operator == polyglot.ast.Binary.DIV){ 3177 rValue = soot.jimple.Jimple.v().newDivExpr(lVal, rVal); 3178 } 3179 else if (operator == polyglot.ast.Binary.SHR){ 3180 if (rVal.getType().equals(soot.LongType.v())){ 3181 soot.Local intVal = lg.generateLocal(soot.IntType.v()); 3182 soot.jimple.CastExpr castExpr = soot.jimple.Jimple.v().newCastExpr(rVal, soot.IntType.v()); 3183 soot.jimple.AssignStmt assignStmt = soot.jimple.Jimple.v().newAssignStmt(intVal, castExpr); 3184 body.getUnits().add(assignStmt); 3185 rValue = soot.jimple.Jimple.v().newShrExpr(lVal, intVal); 3186 } 3187 else { 3188 rValue = soot.jimple.Jimple.v().newShrExpr(lVal, rVal); 3189 } 3190 } 3191 else if (operator == polyglot.ast.Binary.USHR){ 3192 if (rVal.getType().equals(soot.LongType.v())){ 3193 soot.Local intVal = lg.generateLocal(soot.IntType.v()); 3194 soot.jimple.CastExpr castExpr = soot.jimple.Jimple.v().newCastExpr(rVal, soot.IntType.v()); 3195 soot.jimple.AssignStmt assignStmt = soot.jimple.Jimple.v().newAssignStmt(intVal, castExpr); 3196 body.getUnits().add(assignStmt); 3197 rValue = soot.jimple.Jimple.v().newUshrExpr(lVal, intVal); 3198 } 3199 else { 3200 rValue = soot.jimple.Jimple.v().newUshrExpr(lVal, rVal); 3201 } 3202 } 3203 else if (operator == polyglot.ast.Binary.SHL){ 3204 if (rVal.getType().equals(soot.LongType.v())){ 3205 soot.Local intVal = lg.generateLocal(soot.IntType.v()); 3206 soot.jimple.CastExpr castExpr = soot.jimple.Jimple.v().newCastExpr(rVal, soot.IntType.v()); 3207 soot.jimple.AssignStmt assignStmt = soot.jimple.Jimple.v().newAssignStmt(intVal, castExpr); 3208 body.getUnits().add(assignStmt); 3209 rValue = soot.jimple.Jimple.v().newShlExpr(lVal, intVal); 3210 } 3211 else { 3212 rValue = soot.jimple.Jimple.v().newShlExpr(lVal, rVal); 3213 } 3214 } 3215 else if (operator == polyglot.ast.Binary.BIT_AND){ 3216 rValue = soot.jimple.Jimple.v().newAndExpr(lVal, rVal); 3217 } 3218 else if (operator == polyglot.ast.Binary.BIT_OR){ 3219 rValue = soot.jimple.Jimple.v().newOrExpr(lVal, rVal); 3220 } 3221 else if (operator == polyglot.ast.Binary.BIT_XOR){ 3222 rValue = soot.jimple.Jimple.v().newXorExpr(lVal, rVal); 3223 } 3224 else if (operator == polyglot.ast.Binary.MOD){ 3225 rValue = soot.jimple.Jimple.v().newRemExpr(lVal, rVal); 3226 } 3227 else { 3228 throw new RuntimeException ("Binary not yet handled!"); 3229 } 3230 3231 return rValue; 3232 } 3233 3234 3237 private soot.Value getBinaryComparisonExpr(soot.Value lVal, soot.Value rVal, polyglot.ast.Binary.Operator operator) { 3238 3239 soot.Value rValue; 3240 3241 if (operator == polyglot.ast.Binary.EQ){ 3242 rValue = soot.jimple.Jimple.v().newEqExpr(lVal, rVal); 3243 } 3244 else if (operator == polyglot.ast.Binary.GE){ 3245 rValue = soot.jimple.Jimple.v().newGeExpr(lVal, rVal); 3246 } 3247 else if (operator == polyglot.ast.Binary.GT){ 3248 rValue = soot.jimple.Jimple.v().newGtExpr(lVal, rVal); 3249 } 3250 else if (operator == polyglot.ast.Binary.LE){ 3251 rValue = soot.jimple.Jimple.v().newLeExpr(lVal, rVal); 3252 } 3253 else if (operator == polyglot.ast.Binary.LT){ 3254 rValue = soot.jimple.Jimple.v().newLtExpr(lVal, rVal); 3255 } 3256 else if (operator == polyglot.ast.Binary.NE){ 3257 rValue = soot.jimple.Jimple.v().newNeExpr(lVal, rVal); 3258 } 3259 else { 3260 throw new RuntimeException ("Unknown Comparison Expr"); 3261 } 3262 3263 return rValue; 3264 } 3265 3266 3270 private soot.Value reverseCondition(soot.jimple.ConditionExpr cond) { 3271 3272 soot.jimple.ConditionExpr newExpr; 3273 if (cond instanceof soot.jimple.EqExpr) { 3274 newExpr = soot.jimple.Jimple.v().newNeExpr(cond.getOp1(), cond.getOp2()); 3275 } 3276 else if (cond instanceof soot.jimple.NeExpr) { 3277 newExpr = soot.jimple.Jimple.v().newEqExpr(cond.getOp1(), cond.getOp2()); 3278 } 3279 else if (cond instanceof soot.jimple.GtExpr) { 3280 newExpr = soot.jimple.Jimple.v().newLeExpr(cond.getOp1(), cond.getOp2()); 3281 } 3282 else if (cond instanceof soot.jimple.GeExpr) { 3283 newExpr = soot.jimple.Jimple.v().newLtExpr(cond.getOp1(), cond.getOp2()); 3284 } 3285 else if (cond instanceof soot.jimple.LtExpr) { 3286 newExpr = soot.jimple.Jimple.v().newGeExpr(cond.getOp1(), cond.getOp2()); 3287 } 3288 else if (cond instanceof soot.jimple.LeExpr) { 3289 newExpr = soot.jimple.Jimple.v().newGtExpr(cond.getOp1(), cond.getOp2()); 3290 } 3291 else { 3292 throw new RuntimeException ("Unknown Condition Expr"); 3293 } 3294 3295 3296 newExpr.getOp1Box().addAllTagsOf(cond.getOp1Box()); 3297 newExpr.getOp2Box().addAllTagsOf(cond.getOp2Box()); 3298 return newExpr; 3299 } 3300 3301 3302 3305 private soot.Value handleDFLCond(soot.jimple.ConditionExpr cond){ 3306 soot.Local result = lg.generateLocal(soot.ByteType.v()); 3307 soot.jimple.Expr cmExpr = null; 3308 if (isDouble(cond.getOp1()) || isDouble(cond.getOp2()) || isFloat(cond.getOp1()) || isFloat(cond.getOp2())) { 3309 if ((cond instanceof soot.jimple.GeExpr) || (cond instanceof soot.jimple.GtExpr)) { 3311 cmExpr = soot.jimple.Jimple.v().newCmpgExpr(cond.getOp1(), cond.getOp2()); 3313 } 3314 else { 3315 cmExpr = soot.jimple.Jimple.v().newCmplExpr(cond.getOp1(), cond.getOp2()); 3317 } 3318 } 3319 else if (isLong(cond.getOp1()) || isLong(cond.getOp2())) { 3320 cmExpr = soot.jimple.Jimple.v().newCmpExpr(cond.getOp1(), cond.getOp2()); 3322 } 3323 else { 3324 return cond; 3325 } 3326 soot.jimple.Stmt assign = soot.jimple.Jimple.v().newAssignStmt(result, cmExpr); 3327 body.getUnits().add(assign); 3328 3329 if (cond instanceof soot.jimple.EqExpr){ 3330 cond = soot.jimple.Jimple.v().newEqExpr(result, soot.jimple.IntConstant.v(0)); 3331 } 3332 else if (cond instanceof soot.jimple.GeExpr){ 3333 cond = soot.jimple.Jimple.v().newGeExpr(result, soot.jimple.IntConstant.v(0)); 3334 } 3335 else if (cond instanceof soot.jimple.GtExpr){ 3336 cond = soot.jimple.Jimple.v().newGtExpr(result, soot.jimple.IntConstant.v(0)); 3337 } 3338 else if (cond instanceof soot.jimple.LeExpr){ 3339 cond = soot.jimple.Jimple.v().newLeExpr(result, soot.jimple.IntConstant.v(0)); 3340 } 3341 else if (cond instanceof soot.jimple.LtExpr){ 3342 cond = soot.jimple.Jimple.v().newLtExpr(result, soot.jimple.IntConstant.v(0)); 3343 } 3344 else if (cond instanceof soot.jimple.NeExpr){ 3345 cond = soot.jimple.Jimple.v().newNeExpr(result, soot.jimple.IntConstant.v(0)); 3346 } 3347 else { 3348 throw new RuntimeException ("Unknown Comparison Expr"); 3349 } 3350 3351 return cond; 3352 } 3353 3354 private boolean isDouble(soot.Value val) { 3355 if (val.getType() instanceof soot.DoubleType) return true; 3356 return false; 3357 } 3358 3359 private boolean isFloat(soot.Value val) { 3360 if (val.getType() instanceof soot.FloatType) return true; 3361 return false; 3362 } 3363 3364 private boolean isLong(soot.Value val) { 3365 if (val.getType() instanceof soot.LongType) return true; 3366 return false; 3367 } 3368 3369 3372 private soot.Value createCondAnd(polyglot.ast.Binary binary) { 3373 3374 soot.Local retLocal = lg.generateLocal(soot.BooleanType.v()); 3375 3376 soot.jimple.Stmt noop1 = soot.jimple.Jimple.v().newNopStmt(); 3377 3378 soot.Value lVal = base().createExpr(binary.left()); 3379 boolean leftNeedIf = needSootIf(lVal); 3380 if (!(lVal instanceof soot.jimple.ConditionExpr)) { 3381 lVal = soot.jimple.Jimple.v().newEqExpr(lVal, soot.jimple.IntConstant.v(0)); 3382 } 3383 else { 3384 lVal = reverseCondition((soot.jimple.ConditionExpr)lVal); 3385 lVal = handleDFLCond((soot.jimple.ConditionExpr)lVal); 3386 } 3387 3388 if (leftNeedIf){ 3389 soot.jimple.IfStmt ifLeft; 3390 3395 ifLeft = soot.jimple.Jimple.v().newIfStmt(lVal, noop1); 3396 body.getUnits().add(ifLeft); 3398 Util.addLnPosTags(ifLeft.getConditionBox(), binary.left().position()); 3399 Util.addLnPosTags(ifLeft, binary.left().position()); 3400 } 3401 3402 soot.jimple.Stmt endNoop = soot.jimple.Jimple.v().newNopStmt(); 3403 soot.Value rVal = base().createExpr(binary.right()); 3404 boolean rightNeedIf = needSootIf(rVal); 3405 if (!(rVal instanceof soot.jimple.ConditionExpr)) { 3406 rVal = soot.jimple.Jimple.v().newEqExpr(rVal, soot.jimple.IntConstant.v(0)); 3407 } 3408 else { 3409 rVal = reverseCondition((soot.jimple.ConditionExpr)rVal); 3410 rVal = handleDFLCond((soot.jimple.ConditionExpr)rVal); 3411 } 3412 if (rightNeedIf){ 3413 soot.jimple.IfStmt ifRight; 3414 3419 ifRight = soot.jimple.Jimple.v().newIfStmt(rVal, noop1); 3420 body.getUnits().add(ifRight); 3422 Util.addLnPosTags(ifRight.getConditionBox(), binary.right().position()); 3423 Util.addLnPosTags(ifRight, binary.right().position()); 3424 } 3425 3426 3430 3431 soot.jimple.Stmt assign1 = soot.jimple.Jimple.v().newAssignStmt(retLocal, soot.jimple.IntConstant.v(1)); 3432 body.getUnits().add(assign1); 3433 soot.jimple.Stmt gotoEnd1 = soot.jimple.Jimple.v().newGotoStmt(endNoop); 3434 body.getUnits().add(gotoEnd1); 3435 3436 body.getUnits().add(noop1); 3437 3438 soot.jimple.Stmt assign2 = soot.jimple.Jimple.v().newAssignStmt(retLocal, soot.jimple.IntConstant.v(0)); 3439 body.getUnits().add(assign2); 3440 3441 body.getUnits().add(endNoop); 3442 3443 Util.addLnPosTags(assign1, binary.position()); 3444 Util.addLnPosTags(assign2, binary.position()); 3445 3446 return retLocal; 3447 } 3448 3449 int inLeftOr = 0; 3450 3451 3454 private soot.Value createCondOr(polyglot.ast.Binary binary) { 3455 soot.Local retLocal = lg.generateLocal(soot.BooleanType.v()); 3457 3458 soot.jimple.Stmt endNoop = soot.jimple.Jimple.v().newNopStmt(); 3460 3461 soot.jimple.Stmt noop1 = soot.jimple.Jimple.v().newNopStmt(); 3462 soot.jimple.Stmt noop2 = soot.jimple.Jimple.v().newNopStmt(); 3463 soot.Value lVal = base().createExpr(binary.left()); 3465 3467 boolean leftNeedIf = needSootIf(lVal); 3469 if (!(lVal instanceof soot.jimple.ConditionExpr)) { 3470 lVal = soot.jimple.Jimple.v().newNeExpr(lVal, soot.jimple.IntConstant.v(0)); 3471 } 3472 else { 3473 lVal = handleDFLCond((soot.jimple.ConditionExpr)lVal); 3476 } 3477 3478 if (leftNeedIf){ 3479 soot.jimple.IfStmt ifLeft; 3480 3484 ifLeft = soot.jimple.Jimple.v().newIfStmt(lVal, noop1); 3485 body.getUnits().add(ifLeft); 3487 Util.addLnPosTags(ifLeft, binary.left().position()); 3488 Util.addLnPosTags(ifLeft.getConditionBox(), binary.left().position()); 3489 } 3490 3491 soot.Value rVal = base().createExpr(binary.right()); 3492 boolean rightNeedIf = needSootIf(rVal); 3493 if (!(rVal instanceof soot.jimple.ConditionExpr)) { 3494 rVal = soot.jimple.Jimple.v().newEqExpr(rVal, soot.jimple.IntConstant.v(0)); 3495 } 3496 else { 3497 if ( inLeftOr == 0){ 3499 rVal = reverseCondition((soot.jimple.ConditionExpr)rVal); 3500 } 3501 rVal = handleDFLCond((soot.jimple.ConditionExpr)rVal); 3502 } 3503 if (rightNeedIf){ 3504 3505 soot.jimple.IfStmt ifRight; 3506 3515 ifRight = soot.jimple.Jimple.v().newIfStmt(rVal, noop2); 3516 body.getUnits().add(ifRight); 3518 Util.addLnPosTags(ifRight, binary.right().position()); 3519 Util.addLnPosTags(ifRight.getConditionBox(), binary.right().position()); 3520 } 3521 3522 3526 3527 body.getUnits().add(noop1); 3528 3529 soot.jimple.Stmt assign2 = soot.jimple.Jimple.v().newAssignStmt(retLocal, soot.jimple.IntConstant.v(1)); 3530 body.getUnits().add(assign2); 3531 Util.addLnPosTags(assign2, binary.position()); 3532 soot.jimple.Stmt gotoEnd2 = soot.jimple.Jimple.v().newGotoStmt(endNoop); 3533 body.getUnits().add(gotoEnd2); 3534 3535 body.getUnits().add(noop2); 3536 3537 soot.jimple.Stmt assign3 = soot.jimple.Jimple.v().newAssignStmt(retLocal, soot.jimple.IntConstant.v(0)); 3538 body.getUnits().add(assign3); 3539 Util.addLnPosTags(assign3, binary.position()); 3540 3541 body.getUnits().add(endNoop); 3542 Util.addLnPosTags(assign2, binary.position()); 3543 Util.addLnPosTags(assign3, binary.position()); 3544 3545 return retLocal; 3546 } 3547 3548 private soot.Local handleCondBinExpr(soot.jimple.ConditionExpr condExpr) { 3549 3550 soot.Local boolLocal = lg.generateLocal(soot.BooleanType.v()); 3551 3552 soot.jimple.Stmt noop1 = soot.jimple.Jimple.v().newNopStmt(); 3553 3554 soot.Value newVal; 3555 3556 newVal = reverseCondition(condExpr); 3557 newVal = handleDFLCond((soot.jimple.ConditionExpr)newVal); 3558 3559 soot.jimple.Stmt ifStmt = soot.jimple.Jimple.v().newIfStmt(newVal, noop1); 3560 body.getUnits().add(ifStmt); 3561 3562 body.getUnits().add(soot.jimple.Jimple.v().newAssignStmt(boolLocal, soot.jimple.IntConstant.v(1))); 3563 3564 soot.jimple.Stmt noop2 = soot.jimple.Jimple.v().newNopStmt(); 3565 3566 soot.jimple.Stmt goto1 = soot.jimple.Jimple.v().newGotoStmt(noop2); 3567 3568 body.getUnits().add(goto1); 3569 3570 body.getUnits().add(noop1); 3571 3572 body.getUnits().add(soot.jimple.Jimple.v().newAssignStmt(boolLocal, soot.jimple.IntConstant.v(0))); 3573 3574 body.getUnits().add(noop2); 3575 3576 return boolLocal; 3577 3578 3579 } 3580 3581 private soot.Local createStringBuffer(polyglot.ast.Expr expr){ 3582 soot.Local local = lg.generateLocal(soot.RefType.v("java.lang.StringBuffer")); 3584 soot.jimple.NewExpr newExpr = soot.jimple.Jimple.v().newNewExpr(soot.RefType.v("java.lang.StringBuffer")); 3585 soot.jimple.Stmt assign = soot.jimple.Jimple.v().newAssignStmt(local, newExpr); 3586 3587 body.getUnits().add(assign); 3588 Util.addLnPosTags(assign, expr.position()); 3589 3590 soot.SootClass classToInvoke1 = soot.Scene.v().getSootClass("java.lang.StringBuffer"); 3591 soot.SootMethodRef methodToInvoke1 = soot.Scene.v().makeMethodRef(classToInvoke1, "<init>", new ArrayList(), soot.VoidType.v(), false); 3592 3593 soot.jimple.SpecialInvokeExpr invoke = soot.jimple.Jimple.v().newSpecialInvokeExpr(local, methodToInvoke1); 3594 3595 soot.jimple.Stmt invokeStmt = soot.jimple.Jimple.v().newInvokeStmt(invoke); 3596 body.getUnits().add(invokeStmt); 3597 Util.addLnPosTags(invokeStmt, expr.position()); 3598 3599 return local; 3600 } 3601 3602 3603 private soot.Local createToString(soot.Local sb, polyglot.ast.Expr expr){ 3604 soot.Local newString = lg.generateLocal(soot.RefType.v("java.lang.String")); 3606 soot.SootClass classToInvoke2 = soot.Scene.v().getSootClass("java.lang.StringBuffer"); 3607 soot.SootMethodRef methodToInvoke2 = soot.Scene.v().makeMethodRef(classToInvoke2, "toString", new ArrayList(), soot.RefType.v("java.lang.String"), false); 3608 3609 soot.jimple.VirtualInvokeExpr toStringInvoke = soot.jimple.Jimple.v().newVirtualInvokeExpr(sb, methodToInvoke2); 3610 3611 soot.jimple.Stmt lastAssign = soot.jimple.Jimple.v().newAssignStmt(newString, toStringInvoke); 3612 3613 body.getUnits().add(lastAssign); 3614 Util.addLnPosTags(lastAssign, expr.position()); 3615 3616 return newString; 3617 } 3618 3619 3620 3621 private boolean isStringConcat(polyglot.ast.Expr expr){ 3622 if (expr instanceof polyglot.ast.Binary) { 3623 polyglot.ast.Binary bin = (polyglot.ast.Binary)expr; 3624 if (bin.operator() == polyglot.ast.Binary.ADD){ 3625 if (bin.type().toString().equals("java.lang.String")) return true; 3626 return false; 3627 } 3628 return false; 3629 } 3630 else if (expr instanceof polyglot.ast.Assign) { 3631 polyglot.ast.Assign assign = (polyglot.ast.Assign)expr; 3632 if (assign.operator() == polyglot.ast.Assign.ADD_ASSIGN){ 3633 if (assign.type().toString().equals("java.lang.String")) return true; 3634 return false; 3635 } 3636 return false; 3637 } 3638 return false; 3639 } 3640 3641 3644 private soot.Local generateAppends(polyglot.ast.Expr expr, soot.Local sb) { 3645 3646 if (isStringConcat(expr)){ 3648 if (expr instanceof polyglot.ast.Binary){ 3649 sb = generateAppends(((polyglot.ast.Binary)expr).left(), sb); 3650 sb = generateAppends(((polyglot.ast.Binary)expr).right(), sb); 3651 } 3652 else { 3653 sb = generateAppends(((polyglot.ast.Assign)expr).left(), sb); 3654 sb = generateAppends(((polyglot.ast.Assign)expr).right(), sb); 3655 } 3656 } 3657 else { 3658 soot.Value toApp = base().createExpr(expr); 3659 soot.Type appendType = null; 3661 if (toApp instanceof soot.jimple.StringConstant) { 3662 appendType = soot.RefType.v("java.lang.String"); 3663 } 3664 else if (toApp instanceof soot.jimple.NullConstant){ 3665 appendType = soot.RefType.v("java.lang.Object"); 3666 } 3667 else if (toApp instanceof soot.jimple.Constant) { 3668 appendType = toApp.getType(); 3669 } 3670 else if (toApp instanceof soot.Local) { 3671 if (((soot.Local)toApp).getType() instanceof soot.PrimType) { 3672 appendType = ((soot.Local)toApp).getType(); 3673 } 3674 else if (((soot.Local)toApp).getType() instanceof soot.RefType) { 3675 if (((soot.Local)toApp).getType().toString().equals("java.lang.String")){ 3676 appendType = soot.RefType.v("java.lang.String"); 3677 } 3678 else if (((soot.Local)toApp).getType().toString().equals("java.lang.StringBuffer")){ 3679 appendType = soot.RefType.v("java.lang.StringBuffer"); 3680 } 3681 else{ 3682 appendType = soot.RefType.v("java.lang.Object"); 3683 } 3684 } 3685 else { 3686 appendType = soot.RefType.v("java.lang.Object"); 3688 } 3689 } 3690 else if (toApp instanceof soot.jimple.ConditionExpr) { 3691 toApp = handleCondBinExpr((soot.jimple.ConditionExpr)toApp); 3692 appendType = soot.BooleanType.v(); 3693 } 3694 3695 if (appendType instanceof soot.ShortType || appendType instanceof soot.ByteType) { 3697 soot.Local intLocal = lg.generateLocal(soot.IntType.v()); 3698 soot.jimple.Expr cast = soot.jimple.Jimple.v().newCastExpr(toApp, soot.IntType.v()); 3699 soot.jimple.Stmt castAssign = soot.jimple.Jimple.v().newAssignStmt(intLocal, cast); 3700 body.getUnits().add(castAssign); 3701 toApp = intLocal; 3702 appendType = soot.IntType.v(); 3703 } 3704 3705 ArrayList paramsTypes = new ArrayList(); 3706 paramsTypes.add(appendType); 3707 ArrayList params = new ArrayList(); 3708 params.add(toApp); 3709 3710 soot.SootClass classToInvoke = soot.Scene.v().getSootClass("java.lang.StringBuffer"); 3711 soot.SootMethodRef methodToInvoke = soot.Scene.v().makeMethodRef(classToInvoke, "append", paramsTypes, soot.RefType.v("java.lang.StringBuffer"), false); 3712 3713 soot.jimple.VirtualInvokeExpr appendInvoke = soot.jimple.Jimple.v().newVirtualInvokeExpr(sb, methodToInvoke, params); 3714 3715 Util.addLnPosTags(appendInvoke.getArgBox(0), expr.position()); 3716 3717 soot.Local tmp = lg.generateLocal(soot.RefType.v("java.lang.StringBuffer")); 3718 soot.jimple.Stmt appendStmt = soot.jimple.Jimple.v().newAssignStmt(tmp, appendInvoke); 3719 3720 sb = tmp; 3721 3722 body.getUnits().add(appendStmt); 3723 3724 Util.addLnPosTags(appendStmt, expr.position()); 3725 } 3726 return sb; 3727 } 3728 3729 3732 private soot.Value getUnaryLocal(polyglot.ast.Unary unary) { 3733 3734 polyglot.ast.Expr expr = unary.expr(); 3735 polyglot.ast.Unary.Operator op = unary.operator(); 3736 3737 if (op == polyglot.ast.Unary.POST_INC || op == polyglot.ast.Unary.PRE_INC || op == polyglot.ast.Unary.POST_DEC || op == polyglot.ast.Unary.PRE_DEC) { 3738 if (base().needsAccessor(unary.expr())){ 3739 return base().handlePrivateFieldUnarySet(unary); 3740 } 3741 3742 soot.Value left = base().createLHS(unary.expr()); 3743 3744 soot.Value leftClone = soot.jimple.Jimple.v().cloneIfNecessary(left); 3746 3747 3748 soot.Local tmp = lg.generateLocal(left.getType()); 3749 soot.jimple.AssignStmt stmt1 = soot.jimple.Jimple.v().newAssignStmt(tmp, left); 3750 body.getUnits().add(stmt1); 3751 Util.addLnPosTags(stmt1, unary.position()); 3752 3753 soot.Value incVal = base().getConstant(left.getType(), 1); 3754 3755 soot.jimple.BinopExpr binExpr; 3756 if (unary.operator() == polyglot.ast.Unary.PRE_INC || unary.operator() == polyglot.ast.Unary.POST_INC){ 3757 binExpr = soot.jimple.Jimple.v().newAddExpr(tmp, incVal); 3758 } 3759 else { 3760 binExpr = soot.jimple.Jimple.v().newSubExpr(tmp, incVal); 3761 } 3762 3763 soot.Local tmp2 = lg.generateLocal(left.getType()); 3764 soot.jimple.AssignStmt assign = soot.jimple.Jimple.v().newAssignStmt(tmp2, binExpr); 3765 body.getUnits().add(assign); 3766 3767 soot.jimple.AssignStmt stmt3 = soot.jimple.Jimple.v().newAssignStmt(leftClone, tmp2); 3772 body.getUnits().add(stmt3); 3773 3775 if (unary.operator() == polyglot.ast.Unary.POST_DEC || unary.operator() == polyglot.ast.Unary.POST_INC){ 3776 return tmp; 3777 } 3778 else { 3779 return tmp2; 3780 } 3781 } 3782 3917 else if (op == polyglot.ast.Unary.BIT_NOT) { 3918 soot.jimple.IntConstant int1 = soot.jimple.IntConstant.v(-1); 3919 3920 soot.Local retLocal = generateLocal(expr.type()); 3921 3922 soot.Value sootExpr = base().createExpr(expr); 3923 3924 soot.jimple.XorExpr xor = soot.jimple.Jimple.v().newXorExpr(sootExpr, base().getConstant(sootExpr.getType(), -1)); 3925 3926 Util.addLnPosTags(xor.getOp1Box(), expr.position()); 3927 soot.jimple.Stmt assign1 = soot.jimple.Jimple.v().newAssignStmt(retLocal, xor); 3928 3929 body.getUnits().add(assign1); 3930 3931 Util.addLnPosTags(assign1, unary.position()); 3932 3933 return retLocal; 3934 } 3935 else if (op == polyglot.ast.Unary.NEG) { 3936 soot.Value sootExpr; 3937 if (expr instanceof polyglot.ast.IntLit) { 3938 3939 long longVal = ((polyglot.ast.IntLit)expr).value(); 3940 if (((polyglot.ast.IntLit)expr).kind() == polyglot.ast.IntLit.LONG){ 3941 sootExpr = soot.jimple.LongConstant.v(-longVal); 3942 } 3943 else { 3944 sootExpr = soot.jimple.IntConstant.v(-(int)longVal); 3945 } 3946 } 3947 else if (expr instanceof polyglot.ast.FloatLit){ 3948 double doubleVal = ((polyglot.ast.FloatLit)expr).value(); 3949 if (((polyglot.ast.FloatLit)expr).kind() == polyglot.ast.FloatLit.DOUBLE){ 3950 sootExpr = soot.jimple.DoubleConstant.v(-doubleVal); 3951 } 3952 else { 3953 sootExpr = soot.jimple.FloatConstant.v(-(float)doubleVal); 3954 } 3955 } 3956 else { 3957 soot.Value local = base().createExpr(expr); 3958 3959 soot.jimple.NegExpr negExpr = soot.jimple.Jimple.v().newNegExpr(local); 3960 sootExpr = negExpr; 3961 Util.addLnPosTags(negExpr.getOpBox(), expr.position()); 3962 } 3963 3964 soot.Local retLocal = generateLocal(expr.type()); 3965 3966 soot.jimple.Stmt assign = soot.jimple.Jimple.v().newAssignStmt(retLocal, sootExpr); 3967 3968 body.getUnits().add(assign); 3969 3970 Util.addLnPosTags(assign, expr.position()); 3971 3972 return retLocal; 3973 3974 } 3975 else if (op == polyglot.ast.Unary.POS) { 3976 soot.Local retLocal = generateLocal(expr.type()); 3977 soot.Value sootExpr = base().createExpr(expr); 3978 soot.jimple.Stmt assign = soot.jimple.Jimple.v().newAssignStmt(retLocal, sootExpr); 3979 body.getUnits().add(assign); 3980 3981 Util.addLnPosTags(assign, expr.position()); 3982 3983 return retLocal; 3984 } 3985 else if (op == polyglot.ast.Unary.NOT) { 3986 3987 boolean repush = false; 3990 soot.jimple.Stmt tNoop = null; 3991 soot.jimple.Stmt fNoop = null; 3992 if (!trueNoop.empty() && !falseNoop.empty()){ 3993 tNoop = (soot.jimple.Stmt)trueNoop.pop(); 3994 fNoop = (soot.jimple.Stmt)falseNoop.pop(); 3995 repush = true; 3996 } 3997 3998 soot.Value local = base().createExpr(expr); 3999 4000 if (repush){ 4002 trueNoop.push(tNoop); 4003 falseNoop.push(fNoop); 4004 } 4005 4006 if (local instanceof soot.jimple.ConditionExpr){ 4007 local = handleCondBinExpr((soot.jimple.ConditionExpr)local); 4008 } 4009 soot.jimple.NeExpr neExpr = soot.jimple.Jimple.v().newNeExpr(local, base().getConstant(local.getType(), 0)); 4010 4011 soot.jimple.Stmt noop1 = soot.jimple.Jimple.v().newNopStmt(); 4012 4013 soot.jimple.IfStmt ifStmt; 4014 if (!falseNoop.empty()){ 4015 ifStmt = soot.jimple.Jimple.v().newIfStmt(neExpr, (soot.jimple.Stmt)falseNoop.peek()); 4016 } 4017 else { 4018 ifStmt = soot.jimple.Jimple.v().newIfStmt(neExpr, noop1); 4019 } 4020 body.getUnits().add(ifStmt); 4021 Util.addLnPosTags(ifStmt, expr.position()); 4022 Util.addLnPosTags(ifStmt.getConditionBox(), expr.position()); 4023 4024 if (!falseNoop.empty()){ 4025 return soot.jimple.IntConstant.v(1); 4026 } 4027 soot.Local retLocal = lg.generateLocal(local.getType()); 4028 4029 soot.jimple.Stmt assign1 = soot.jimple.Jimple.v().newAssignStmt(retLocal, base().getConstant(retLocal.getType(), 1)); 4030 4031 body.getUnits().add(assign1); 4032 Util.addLnPosTags(assign1, expr.position()); 4033 4034 soot.jimple.Stmt noop2 = soot.jimple.Jimple.v().newNopStmt(); 4035 4036 soot.jimple.Stmt goto1 = soot.jimple.Jimple.v().newGotoStmt(noop2); 4037 4038 body.getUnits().add(goto1); 4039 4040 body.getUnits().add(noop1); 4041 4042 soot.jimple.Stmt assign2 = soot.jimple.Jimple.v().newAssignStmt(retLocal, base().getConstant(retLocal.getType(), 0)); 4043 4044 body.getUnits().add(assign2); 4045 Util.addLnPosTags(assign2, expr.position()); 4046 4047 body.getUnits().add(noop2); 4048 4049 return retLocal; 4050 } 4051 else { 4052 throw new RuntimeException ("Unhandled Unary Expr"); 4053 } 4054 4055 4056 } 4057 4058 4061 protected soot.jimple.Constant getConstant(soot.Type type, int val) { 4062 4063 if (type instanceof soot.DoubleType) { 4064 return soot.jimple.DoubleConstant.v(val); 4065 } 4066 else if (type instanceof soot.FloatType) { 4067 return soot.jimple.FloatConstant.v(val); 4068 } 4069 else if (type instanceof soot.LongType) { 4070 return soot.jimple.LongConstant.v(val); 4071 } 4072 else { 4073 return soot.jimple.IntConstant.v(val); 4074 } 4075 } 4076 4079 private soot.Value getCastLocal(polyglot.ast.Cast castExpr){ 4080 4081 4082 if (castExpr.expr().type().equals(castExpr.type()) || (castExpr.type().isClass() && Util.getSootType(castExpr.type()).toString().equals("java.lang.Object"))) { 4084 return base().createExpr(castExpr.expr()); 4085 } 4086 4087 soot.Value val; 4088 val = base().createExpr(castExpr.expr()); 4089 soot.Type type = Util.getSootType(castExpr.type()); 4090 4091 soot.jimple.CastExpr cast = soot.jimple.Jimple.v().newCastExpr(val, type); 4092 Util.addLnPosTags(cast.getOpBox(), castExpr.expr().position()); 4093 soot.Local retLocal = lg.generateLocal(cast.getCastType()); 4094 soot.jimple.Stmt castAssign = soot.jimple.Jimple.v().newAssignStmt(retLocal, cast); 4095 body.getUnits().add(castAssign); 4096 Util.addLnPosTags(castAssign, castExpr.position()); 4097 4098 return retLocal; 4099 } 4100 4101 4105 private ArrayList getSootParams(polyglot.ast.ProcedureCall call) { 4106 4107 ArrayList sootParams = new ArrayList(); 4108 Iterator it = call.arguments().iterator(); 4109 while (it.hasNext()) { 4110 polyglot.ast.Expr next = (polyglot.ast.Expr)it.next(); 4111 soot.Value nextExpr = base().createExpr(next); 4112 if (nextExpr instanceof soot.jimple.ConditionExpr){ 4113 nextExpr = handleCondBinExpr((soot.jimple.ConditionExpr)nextExpr); 4114 } 4115 sootParams.add(nextExpr); 4116 } 4117 return sootParams; 4118 } 4119 4120 4123 private ArrayList getSootParamsTypes(polyglot.ast.ProcedureCall call) { 4124 4125 ArrayList sootParamsTypes = new ArrayList(); 4126 Iterator it = call.procedureInstance().formalTypes().iterator(); 4127 while (it.hasNext()) { 4128 Object next = it.next(); 4129 sootParamsTypes.add(Util.getSootType((polyglot.types.Type)next)); 4130 } 4131 return sootParamsTypes; 4132 } 4133 4134 4137 private soot.SootMethodRef getMethodFromClass(soot.SootClass sootClass, String name, ArrayList paramTypes, soot.Type returnType, boolean isStatic) { 4138 soot.SootMethodRef ref = soot.Scene.v().makeMethodRef(sootClass, name, paramTypes, returnType, isStatic); 4139 return ref; 4140 } 4141 4142 4145 private void handleFinalLocalParams(ArrayList sootParams, ArrayList sootParamTypes, polyglot.types.ClassType keyType){ 4146 4147 HashMap finalLocalInfo = soot.javaToJimple.InitialResolver.v().finalLocalInfo(); 4148 if (finalLocalInfo != null){ 4149 if (finalLocalInfo.containsKey(new polyglot.util.IdentityKey(keyType))){ 4150 AnonLocalClassInfo alci = (AnonLocalClassInfo)finalLocalInfo.get(new polyglot.util.IdentityKey(keyType)); 4151 4152 ArrayList finalLocals = alci.finalLocalsUsed(); 4153 if (finalLocals != null){ 4154 Iterator it = finalLocals.iterator(); 4155 while (it.hasNext()){ 4156 Object next = it.next(); 4157 polyglot.types.LocalInstance li = (polyglot.types.LocalInstance)((polyglot.util.IdentityKey)next).object(); 4158 sootParamTypes.add(Util.getSootType(li.type())); 4159 sootParams.add(getLocal(li)); 4160 } 4161 } 4162 } 4163 } 4164 } 4165 4166 protected soot.Local getThis(soot.Type sootType){ 4167 4168 return Util.getThis(sootType, body, getThisMap, lg); 4169 } 4170 4171 protected boolean needsOuterClassRef(polyglot.types.ClassType typeToInvoke){ 4172 AnonLocalClassInfo info = (AnonLocalClassInfo)InitialResolver.v().finalLocalInfo().get(new polyglot.util.IdentityKey(typeToInvoke)); 4174 4175 if (InitialResolver.v().isAnonInCCall(typeToInvoke)) return false; 4176 4177 if ((info != null) && (!info.inStaticMethod())){ 4178 return true; 4179 } 4180 4181 else if (typeToInvoke.isNested() && !typeToInvoke.flags().isStatic() && !typeToInvoke.isAnonymous() && !typeToInvoke.isLocal()){ 4183 return true; 4184 } 4185 4186 return false; 4187 } 4188 4189 4192 private void handleOuterClassParams(ArrayList sootParams, soot.Value qVal, ArrayList sootParamsTypes, polyglot.types.ClassType typeToInvoke){ 4193 4194 4195 ArrayList needsRef = soot.javaToJimple.InitialResolver.v().getHasOuterRefInInit(); 4196 4197 boolean addRef = needsOuterClassRef(typeToInvoke); if (addRef){ 4199 soot.SootClass outerClass = ((soot.RefType)Util.getSootType(typeToInvoke.outer())).getSootClass(); 4201 sootParamsTypes.add(outerClass.getType()); 4202 } 4203 4204 if (addRef && !typeToInvoke.isAnonymous() && (qVal != null)){ 4205 sootParams.add(qVal); 4207 } 4208 else if (addRef && !typeToInvoke.isAnonymous()){ 4209 soot.SootClass outerClass = ((soot.RefType)Util.getSootType(typeToInvoke.outer())).getSootClass(); 4210 sootParams.add(getThis(outerClass.getType())); 4211 } 4212 else if (addRef && typeToInvoke.isAnonymous()){ 4213 soot.SootClass outerClass = ((soot.RefType)Util.getSootType(typeToInvoke.outer())).getSootClass(); 4214 sootParams.add(getThis(outerClass.getType())); 4215 } 4216 4217 if (typeToInvoke.isAnonymous() && (qVal != null)){ 4219 sootParamsTypes.add(qVal.getType()); 4220 sootParams.add(qVal); 4221 } 4222 } 4223 4224 4227 private void createConstructorCall(polyglot.ast.ConstructorCall cCall) { 4228 4229 ArrayList sootParams = new ArrayList(); 4230 ArrayList sootParamsTypes = new ArrayList(); 4231 4232 polyglot.types.ConstructorInstance cInst = cCall.constructorInstance(); 4233 String containerName = null; 4234 4235 if (cInst.container() instanceof polyglot.types.ClassType) { 4236 containerName = ((polyglot.types.ClassType)cInst.container()).fullName(); 4237 } 4238 4239 soot.SootClass classToInvoke; 4240 4241 if (cCall.kind() == polyglot.ast.ConstructorCall.SUPER) { 4242 4243 classToInvoke = ((soot.RefType)Util.getSootType(cInst.container())).getSootClass(); 4244 } 4245 else if (cCall.kind() == polyglot.ast.ConstructorCall.THIS) { 4246 classToInvoke = body.getMethod().getDeclaringClass(); 4247 } 4248 else { 4249 throw new RuntimeException ("Unknown kind of Constructor Call"); 4250 } 4251 soot.Local base = specialThisLocal; 4252 4253 polyglot.types.ClassType objType = (polyglot.types.ClassType)cInst.container(); 4254 soot.Local qVal = null; 4255 if (cCall.qualifier() != null){ qVal = (soot.Local)base().createExpr(cCall.qualifier()); 4257 } 4258 handleOuterClassParams(sootParams, qVal, sootParamsTypes, objType); 4259 sootParams.addAll(getSootParams(cCall)); 4260 sootParamsTypes.addAll(getSootParamsTypes(cCall)); 4261 handleFinalLocalParams(sootParams, sootParamsTypes, (polyglot.types.ClassType)cCall.constructorInstance().container()); 4262 4263 soot.SootMethodRef methodToInvoke = getMethodFromClass(classToInvoke, "<init>", sootParamsTypes, soot.VoidType.v(), false); 4264 4265 soot.jimple.SpecialInvokeExpr specialInvokeExpr = soot.jimple.Jimple.v().newSpecialInvokeExpr(base, methodToInvoke, sootParams); 4266 4267 soot.jimple.Stmt invokeStmt = soot.jimple.Jimple.v().newInvokeStmt(specialInvokeExpr); 4268 4269 body.getUnits().add(invokeStmt); 4270 Util.addLnPosTags(invokeStmt, cCall.position()); 4271 4272 int numParams = 0; 4275 Iterator invokeParamsIt = cCall.arguments().iterator(); 4276 while (invokeParamsIt.hasNext()) { 4277 Util.addLnPosTags(specialInvokeExpr.getArgBox(numParams), ((polyglot.ast.Expr)invokeParamsIt.next()).position()); 4278 numParams++; 4279 } 4280 4281 if (body.getMethod().getName().equals("<init>") && (cCall.kind() == polyglot.ast.ConstructorCall.SUPER)){ 4283 4284 handleOuterClassThisInit(body.getMethod()); 4285 handleFinalLocalInits(); 4286 handleFieldInits(body.getMethod()); 4287 handleInitializerBlocks(body.getMethod()); 4288 } 4289 4290 } 4291 4292 private void handleFinalLocalInits(){ 4293 ArrayList finalsList = ((PolyglotMethodSource)body.getMethod().getSource()).getFinalsList(); 4294 if (finalsList == null) return; 4295 int paramCount = paramRefCount - finalsList.size(); 4296 Iterator it = finalsList.iterator(); 4297 while (it.hasNext()){ 4298 soot.SootField sf = (soot.SootField)it.next(); 4299 4300 soot.jimple.FieldRef fieldRef = soot.jimple.Jimple.v().newInstanceFieldRef(specialThisLocal, sf.makeRef()); 4301 soot.jimple.AssignStmt stmt = soot.jimple.Jimple.v().newAssignStmt(fieldRef, body.getParameterLocal(paramCount)); 4302 body.getUnits().add(stmt); 4303 paramCount++; 4304 } 4305 } 4306 4307 4310 private void createLocalClassDecl(polyglot.ast.LocalClassDecl cDecl) { 4311 BiMap lcMap = InitialResolver.v().getLocalClassMap(); 4312 String name = Util.getSootType(cDecl.decl().type()).toString(); 4313 if (!InitialResolver.v().hasClassInnerTag(body.getMethod().getDeclaringClass(), name)){ 4314 Util.addInnerClassTag(body.getMethod().getDeclaringClass(), name, null, cDecl.decl().name(), Util.getModifier(cDecl.decl().flags())); 4315 } 4316 } 4317 4318 4321 private soot.Local getNewLocal(polyglot.ast.New newExpr) { 4322 4323 ArrayList sootParams = new ArrayList(); 4325 ArrayList sootParamsTypes = new ArrayList(); 4326 4327 polyglot.types.ClassType objType = (polyglot.types.ClassType)newExpr.objectType().type(); 4328 4329 if (newExpr.anonType() != null){ 4330 objType = newExpr.anonType(); 4331 String name = Util.getSootType(objType).toString(); 4333 polyglot.types.ClassType outerType = objType.outer(); 4334 if (!InitialResolver.v().hasClassInnerTag(body.getMethod().getDeclaringClass(), name)){ 4335 Util.addInnerClassTag(body.getMethod().getDeclaringClass(), name, null, null, outerType.flags().isInterface() ? soot.Modifier.PUBLIC | soot.Modifier.STATIC : Util.getModifier(objType.flags())); 4336 } 4337 } 4338 else { 4339 if (!objType.isTopLevel()){ 4341 String name = Util.getSootType(objType).toString(); 4342 polyglot.types.ClassType outerType = objType.outer(); 4343 if (!InitialResolver.v().hasClassInnerTag(body.getMethod().getDeclaringClass(), name)){ 4344 Util.addInnerClassTag(body.getMethod().getDeclaringClass(), name, Util.getSootType(outerType).toString(), objType.name(), outerType.flags().isInterface() ? soot.Modifier.PUBLIC | soot.Modifier.STATIC : Util.getModifier(objType.flags())); 4345 } 4346 4347 } 4348 } 4349 soot.RefType sootType = (soot.RefType)Util.getSootType(objType); 4350 soot.Local retLocal = lg.generateLocal(sootType); 4351 soot.jimple.NewExpr sootNew = soot.jimple.Jimple.v().newNewExpr(sootType); 4352 4353 soot.jimple.AssignStmt stmt = soot.jimple.Jimple.v().newAssignStmt(retLocal, sootNew); 4354 body.getUnits().add(stmt); 4355 Util.addLnPosTags(stmt, newExpr.position()); 4356 Util.addLnPosTags(stmt.getRightOpBox(), newExpr.position()); 4357 4358 4359 soot.SootClass classToInvoke = sootType.getSootClass(); 4360 soot.Value qVal = null; 4362 if (newExpr.qualifier() != null){ qVal = base().createExpr(newExpr.qualifier()); 4366 } 4367 handleOuterClassParams(sootParams, qVal, sootParamsTypes, objType); 4368 4369 boolean repush = false; 4370 soot.jimple.Stmt tNoop = null; 4371 soot.jimple.Stmt fNoop = null; 4372 4373 if (!trueNoop.empty() && !falseNoop.empty()){ 4374 tNoop = (soot.jimple.Stmt)trueNoop.pop(); 4375 fNoop = (soot.jimple.Stmt)falseNoop.pop(); 4376 repush = true; 4377 } 4378 4379 sootParams.addAll(getSootParams(newExpr)); 4380 4381 if (repush){ 4382 trueNoop.push(tNoop); 4383 falseNoop.push(fNoop); 4384 } 4385 4386 sootParamsTypes.addAll(getSootParamsTypes(newExpr)); 4387 4388 handleFinalLocalParams(sootParams, sootParamsTypes, (polyglot.types.ClassType)objType); 4389 4390 soot.SootMethodRef methodToInvoke = getMethodFromClass(classToInvoke, "<init>", sootParamsTypes, soot.VoidType.v(), false); 4391 soot.jimple.SpecialInvokeExpr specialInvokeExpr = soot.jimple.Jimple.v().newSpecialInvokeExpr(retLocal, methodToInvoke, sootParams); 4392 4393 soot.jimple.Stmt invokeStmt = soot.jimple.Jimple.v().newInvokeStmt(specialInvokeExpr); 4394 4395 body.getUnits().add(invokeStmt); 4396 Util.addLnPosTags(invokeStmt, newExpr.position()); 4397 4398 int numParams = 0; 4399 Iterator invokeParamsIt = newExpr.arguments().iterator(); 4400 while (invokeParamsIt.hasNext()) { 4401 Util.addLnPosTags(specialInvokeExpr.getArgBox(numParams), ((polyglot.ast.Expr)invokeParamsIt.next()).position()); 4402 numParams++; 4403 } 4404 4405 4406 return retLocal; 4407 } 4408 4409 protected soot.SootMethodRef getSootMethodRef(polyglot.ast.Call call){ 4410 soot.Type sootRecType; 4411 soot.SootClass receiverTypeClass; 4412 if (Util.getSootType(call.methodInstance().container()).equals(soot.RefType.v("java.lang.Object"))){ 4413 sootRecType = soot.RefType.v("java.lang.Object"); 4414 receiverTypeClass = soot.Scene.v().getSootClass("java.lang.Object"); 4415 } 4416 else { 4417 if (call.target().type() == null){ 4418 sootRecType = Util.getSootType(call.methodInstance().container()); 4419 } 4420 else { 4421 sootRecType = Util.getSootType(call.target().type()); 4422 } 4423 if (sootRecType instanceof soot.RefType){ 4424 receiverTypeClass = ((soot.RefType)sootRecType).getSootClass(); 4425 } 4426 else if (sootRecType instanceof soot.ArrayType){ 4427 receiverTypeClass = soot.Scene.v().getSootClass("java.lang.Object"); 4428 } 4429 else { 4430 throw new RuntimeException ("call target problem: "+call); 4431 } 4432 } 4433 4434 polyglot.types.MethodInstance methodInstance = call.methodInstance(); 4435 soot.Type sootRetType = Util.getSootType(methodInstance.returnType()); 4436 ArrayList sootParamsTypes = getSootParamsTypes(call); 4437 4438 soot.SootMethodRef callMethod = soot.Scene.v().makeMethodRef(receiverTypeClass, methodInstance.name(), sootParamsTypes, sootRetType, methodInstance.flags().isStatic()); 4439 return callMethod; 4440 } 4441 4442 4445 private soot.Local getCallLocal(polyglot.ast.Call call){ 4446 4447 String name = call.name(); 4449 polyglot.ast.Receiver receiver = call.target(); 4451 soot.Local baseLocal; 4453 if ((receiver instanceof polyglot.ast.Special) && (((polyglot.ast.Special)receiver).kind() == polyglot.ast.Special.SUPER) && (((polyglot.ast.Special)receiver).qualifier() != null)){ 4454 baseLocal = getSpecialSuperQualifierLocal(call); 4455 return baseLocal; 4456 4457 } 4458 baseLocal = (soot.Local)base().getBaseLocal(receiver); 4459 4460 4462 boolean repush = false; 4463 soot.jimple.Stmt tNoop = null; 4464 soot.jimple.Stmt fNoop = null; 4465 if (!trueNoop.empty() && !falseNoop.empty()){ 4466 tNoop = (soot.jimple.Stmt)trueNoop.pop(); 4467 fNoop = (soot.jimple.Stmt)falseNoop.pop(); 4468 repush = true; 4469 } 4470 ArrayList sootParams = getSootParams(call); 4471 4472 if (repush){ 4473 trueNoop.push(tNoop); 4474 falseNoop.push(fNoop); 4475 } 4476 4477 soot.SootMethodRef callMethod = base().getSootMethodRef(call); 4478 4479 soot.Type sootRecType; 4480 soot.SootClass receiverTypeClass; 4481 if (Util.getSootType(call.methodInstance().container()).equals(soot.RefType.v("java.lang.Object"))){ 4482 sootRecType = soot.RefType.v("java.lang.Object"); 4483 receiverTypeClass = soot.Scene.v().getSootClass("java.lang.Object"); 4484 } 4485 else { 4486 if (call.target().type() == null){ 4487 sootRecType = Util.getSootType(call.methodInstance().container()); 4488 } 4489 else { 4490 sootRecType = Util.getSootType(call.target().type()); 4491 } 4492 if (sootRecType instanceof soot.RefType){ 4493 receiverTypeClass = ((soot.RefType)sootRecType).getSootClass(); 4494 } 4495 else if (sootRecType instanceof soot.ArrayType){ 4496 receiverTypeClass = soot.Scene.v().getSootClass("java.lang.Object"); 4497 } 4498 else { 4499 throw new RuntimeException ("call target problem: "+call); 4500 } 4501 } 4502 4503 polyglot.types.MethodInstance methodInstance = call.methodInstance(); 4504 4509 4510 boolean isPrivateAccess = false; 4511 if (needsAccessor(call)){ 4513 4514 soot.SootClass containingClass = ((soot.RefType)Util.getSootType(call.methodInstance().container())).getSootClass(); 4515 soot.SootClass classToAddMethTo = containingClass; 4516 4517 if (call.methodInstance().flags().isProtected()){ 4518 4519 if (InitialResolver.v().hierarchy() == null){ 4520 InitialResolver.v().hierarchy(new soot.FastHierarchy()); 4521 } 4522 soot.SootClass addToClass; 4523 if (body.getMethod().getDeclaringClass().hasOuterClass()){ 4524 addToClass = body.getMethod().getDeclaringClass().getOuterClass(); 4525 4526 while (!InitialResolver.v().hierarchy().canStoreType(containingClass.getType(), addToClass.getType())){ 4527 if (addToClass.hasOuterClass()){ 4528 addToClass = addToClass.getOuterClass(); 4529 } 4530 else { 4531 break; 4532 } 4533 } 4534 } 4535 else{ 4536 addToClass = containingClass; 4537 } 4538 classToAddMethTo = addToClass; 4539 } 4540 4541 callMethod = addGetMethodAccessMeth(classToAddMethTo, call).makeRef(); 4542 if (!call.methodInstance().flags().isStatic()){ 4543 4544 if (call.target() instanceof polyglot.ast.Expr){ 4545 sootParams.add(0, baseLocal); 4546 } 4547 4548 else if (body.getMethod().getDeclaringClass().declaresFieldByName("this$0")){ 4549 sootParams.add(0, getThis(Util.getSootType(call.methodInstance().container()))); } 4551 else { 4552 sootParams.add(0, baseLocal); 4553 } 4554 } 4555 isPrivateAccess = true; 4556 } 4557 4558 soot.jimple.InvokeExpr invokeExpr; 4559 if (isPrivateAccess){ 4560 invokeExpr = soot.jimple.Jimple.v().newStaticInvokeExpr(callMethod, sootParams); 4562 } 4563 else if (soot.Modifier.isInterface(receiverTypeClass.getModifiers()) && methodInstance.flags().isAbstract()) { 4564 invokeExpr = soot.jimple.Jimple.v().newInterfaceInvokeExpr(baseLocal, callMethod, sootParams); 4566 } 4567 else if (methodInstance.flags().isStatic()){ 4568 invokeExpr = soot.jimple.Jimple.v().newStaticInvokeExpr(callMethod, sootParams); 4570 } 4571 else if (methodInstance.flags().isPrivate()){ 4572 invokeExpr = soot.jimple.Jimple.v().newSpecialInvokeExpr(baseLocal, callMethod, sootParams); 4574 } 4575 else if ((receiver instanceof polyglot.ast.Special) && 4576 (((polyglot.ast.Special)receiver).kind() == polyglot.ast.Special.SUPER)){ 4577 invokeExpr = soot.jimple.Jimple.v().newSpecialInvokeExpr(baseLocal, callMethod, sootParams); 4579 } 4580 else { 4581 invokeExpr = soot.jimple.Jimple.v().newVirtualInvokeExpr(baseLocal, callMethod, sootParams); 4583 4584 } 4585 4586 int numParams = 0; 4587 Iterator callParamsIt = call.arguments().iterator(); 4588 while (callParamsIt.hasNext()) { 4589 Util.addLnPosTags(invokeExpr.getArgBox(numParams), ((polyglot.ast.Expr)callParamsIt.next()).position()); 4590 numParams++; 4591 } 4592 4593 if (invokeExpr instanceof soot.jimple.InstanceInvokeExpr) { 4594 Util.addLnPosTags(((soot.jimple.InstanceInvokeExpr)invokeExpr).getBaseBox(), call.target().position()); 4595 } 4596 4597 4599 if (invokeExpr.getMethodRef().returnType().equals(soot.VoidType.v())) { 4600 soot.jimple.Stmt invoke = soot.jimple.Jimple.v().newInvokeStmt(invokeExpr); 4601 body.getUnits().add(invoke); 4602 Util.addLnPosTags(invoke, call.position()); 4603 return null; 4604 } 4605 else { 4606 soot.Local retLocal = lg.generateLocal(invokeExpr.getMethodRef().returnType()); 4607 4608 soot.jimple.Stmt assignStmt = soot.jimple.Jimple.v().newAssignStmt(retLocal, invokeExpr); 4609 4610 body.getUnits().add(assignStmt); 4612 4613 Util.addLnPosTags(assignStmt, call.position()); 4614 return retLocal; 4615 } 4616 } 4617 4618 4619 protected soot.Value getBaseLocal(polyglot.ast.Receiver receiver) { 4620 4621 if (receiver instanceof polyglot.ast.TypeNode) { 4622 return generateLocal(((polyglot.ast.TypeNode)receiver).type()); 4623 } 4624 else { 4625 soot.Value val = base().createExpr((polyglot.ast.Expr)receiver); 4626 if (val instanceof soot.jimple.Constant) { 4627 soot.Local retLocal = lg.generateLocal(val.getType()); 4628 soot.jimple.AssignStmt stmt = soot.jimple.Jimple.v().newAssignStmt(retLocal, val); 4629 body.getUnits().add(stmt); 4630 return retLocal; 4631 } 4632 return val; 4633 } 4634 } 4635 4636 4639 private soot.Local getNewArrayLocal(polyglot.ast.NewArray newArrExpr) { 4640 4641 soot.Type sootType = Util.getSootType(newArrExpr.type()); 4642 4643 soot.jimple.Expr expr; 4645 if (newArrExpr.numDims() == 1) { 4646 4647 soot.Value dimLocal; 4648 if (newArrExpr.additionalDims() == 1) { 4649 dimLocal = soot.jimple.IntConstant.v(1); 4650 } 4651 else { 4652 dimLocal = base().createExpr((polyglot.ast.Expr)newArrExpr.dims().get(0)); 4653 } 4654 soot.jimple.NewArrayExpr newArrayExpr = soot.jimple.Jimple.v().newNewArrayExpr(((soot.ArrayType)sootType).getElementType(), dimLocal); 4656 expr = newArrayExpr; 4657 if (newArrExpr.additionalDims() != 1){ 4658 Util.addLnPosTags(newArrayExpr.getSizeBox(), ((polyglot.ast.Expr)newArrExpr.dims().get(0)).position()); 4659 } 4660 } 4661 else { 4662 4663 ArrayList valuesList = new ArrayList(); 4664 Iterator it = newArrExpr.dims().iterator(); 4665 while (it.hasNext()){ 4666 valuesList.add(base().createExpr((polyglot.ast.Expr)it.next())); 4667 } 4668 4669 if (newArrExpr.additionalDims() != 0) { 4670 valuesList.add(soot.jimple.IntConstant.v(newArrExpr.additionalDims())); 4671 } 4672 soot.jimple.NewMultiArrayExpr newMultiArrayExpr = soot.jimple.Jimple.v().newNewMultiArrayExpr((soot.ArrayType)sootType, valuesList); 4673 4674 4675 expr = newMultiArrayExpr; 4676 Iterator sizeBoxIt = newArrExpr.dims().iterator(); 4677 int counter = 0; 4678 while (sizeBoxIt.hasNext()){ 4679 Util.addLnPosTags(newMultiArrayExpr.getSizeBox(counter), ((polyglot.ast.Expr)sizeBoxIt.next()).position()); 4680 counter++; 4681 } 4682 } 4683 4684 soot.Local retLocal = lg.generateLocal(sootType); 4685 4686 soot.jimple.AssignStmt stmt = soot.jimple.Jimple.v().newAssignStmt(retLocal, expr); 4687 4688 body.getUnits().add(stmt); 4689 4690 Util.addLnPosTags(stmt, newArrExpr.position()); 4691 Util.addLnPosTags(stmt.getRightOpBox(), newArrExpr.position()); 4692 4693 if (newArrExpr.init() != null) { 4695 soot.Value initVal = getArrayInitLocal(newArrExpr.init(), newArrExpr.type()); 4696 soot.jimple.AssignStmt initStmt = soot.jimple.Jimple.v().newAssignStmt(retLocal, initVal); 4697 4698 body.getUnits().add(initStmt); 4699 4700 } 4701 4702 return retLocal; 4703 4704 } 4705 4706 4709 private soot.Local getArrayInitLocal(polyglot.ast.ArrayInit arrInit, polyglot.types.Type lhsType) { 4710 4711 4713 soot.Local local = generateLocal(lhsType); 4714 4715 soot.jimple.NewArrayExpr arrExpr = soot.jimple.Jimple.v().newNewArrayExpr(((soot.ArrayType)local.getType()).getElementType(), soot.jimple.IntConstant.v(arrInit.elements().size())); 4717 4718 soot.jimple.Stmt assign = soot.jimple.Jimple.v().newAssignStmt(local, arrExpr); 4719 4720 body.getUnits().add(assign); 4721 Util.addLnPosTags(assign, arrInit.position()); 4722 4723 4724 Iterator it = arrInit.elements().iterator(); 4725 int index = 0; 4726 4727 while (it.hasNext()){ 4728 4729 polyglot.ast.Expr elemExpr = (polyglot.ast.Expr)it.next(); 4730 soot.Value elem; 4731 if (elemExpr instanceof polyglot.ast.ArrayInit){ 4732 4733 if (((polyglot.ast.ArrayInit)elemExpr).type() instanceof polyglot.types.NullType) { 4734 if (lhsType instanceof polyglot.types.ArrayType){ 4735 elem = getArrayInitLocal((polyglot.ast.ArrayInit)elemExpr, ((polyglot.types.ArrayType)lhsType).base()); 4737 } 4738 else { 4739 elem = getArrayInitLocal((polyglot.ast.ArrayInit)elemExpr, lhsType); 4741 4742 } 4743 } 4744 else { 4745 elem = getArrayInitLocal((polyglot.ast.ArrayInit)elemExpr, ((polyglot.types.ArrayType)lhsType).base()); 4748 } 4749 } 4750 else { 4751 elem = base().createExpr(elemExpr); 4752 } 4753 soot.jimple.ArrayRef arrRef = soot.jimple.Jimple.v().newArrayRef(local, soot.jimple.IntConstant.v(index)); 4754 4755 soot.jimple.AssignStmt elemAssign = soot.jimple.Jimple.v().newAssignStmt(arrRef, elem); 4756 body.getUnits().add(elemAssign); 4757 Util.addLnPosTags(elemAssign, elemExpr.position()); 4758 Util.addLnPosTags(elemAssign.getRightOpBox(), elemExpr.position()); 4759 4760 index++; 4761 } 4762 4763 return local; 4764 } 4765 4766 4767 4770 protected soot.Value createLHS(polyglot.ast.Expr expr) { 4771 if (expr instanceof polyglot.ast.Local) { 4772 return getLocal((polyglot.ast.Local)expr); 4773 } 4774 else if (expr instanceof polyglot.ast.ArrayAccess) { 4775 return getArrayRefLocalLeft((polyglot.ast.ArrayAccess)expr); 4776 } 4777 else if (expr instanceof polyglot.ast.Field) { 4778 return getFieldLocalLeft((polyglot.ast.Field)expr); 4779 } 4780 else { 4781 throw new RuntimeException ("Unhandled LHS"); 4782 } 4783 } 4784 4785 4788 private soot.Value getArrayRefLocalLeft(polyglot.ast.ArrayAccess arrayRefExpr) { 4789 polyglot.ast.Expr array = arrayRefExpr.array(); 4790 polyglot.ast.Expr access = arrayRefExpr.index(); 4791 4792 soot.Local arrLocal = (soot.Local)base().createExpr(array); 4793 soot.Value arrAccess = base().createExpr(access); 4794 4795 soot.Local retLocal = generateLocal(arrayRefExpr.type()); 4796 4797 soot.jimple.ArrayRef ref = soot.jimple.Jimple.v().newArrayRef(arrLocal, arrAccess); 4798 4799 Util.addLnPosTags(ref.getBaseBox(), arrayRefExpr.array().position()); 4800 Util.addLnPosTags(ref.getIndexBox(), arrayRefExpr.index().position()); 4801 return ref; 4802 } 4803 4804 4807 private soot.Value getArrayRefLocal(polyglot.ast.ArrayAccess arrayRefExpr) { 4808 4809 polyglot.ast.Expr array = arrayRefExpr.array(); 4810 polyglot.ast.Expr access = arrayRefExpr.index(); 4811 4812 soot.Local arrLocal = (soot.Local)base().createExpr(array); 4813 soot.Value arrAccess = base().createExpr(access); 4814 4815 soot.Local retLocal = generateLocal(arrayRefExpr.type()); 4816 4817 soot.jimple.ArrayRef ref = soot.jimple.Jimple.v().newArrayRef(arrLocal, arrAccess); 4818 4819 Util.addLnPosTags(ref.getBaseBox(), arrayRefExpr.array().position()); 4820 Util.addLnPosTags(ref.getIndexBox(), arrayRefExpr.index().position()); 4821 4822 soot.jimple.Stmt stmt = soot.jimple.Jimple.v().newAssignStmt(retLocal, ref); 4823 body.getUnits().add(stmt); 4824 Util.addLnPosTags(stmt, arrayRefExpr.position()); 4825 4826 4827 return retLocal; 4828 } 4829 4830 4831 private soot.Local getSpecialSuperQualifierLocal(polyglot.ast.Expr expr){ 4832 soot.SootClass classToInvoke; 4833 ArrayList methodParams = new ArrayList(); 4834 if (expr instanceof polyglot.ast.Call){ 4835 polyglot.ast.Special target = (polyglot.ast.Special)((polyglot.ast.Call)expr).target(); 4836 classToInvoke = ((soot.RefType)Util.getSootType(target.qualifier().type())).getSootClass(); 4837 methodParams = getSootParams((polyglot.ast.Call)expr); 4838 } 4839 else if (expr instanceof polyglot.ast.Field){ 4840 polyglot.ast.Special target = (polyglot.ast.Special)((polyglot.ast.Field)expr).target(); 4841 classToInvoke = ((soot.RefType)Util.getSootType(target.qualifier().type())).getSootClass(); 4842 } 4843 else { 4844 throw new RuntimeException ("Trying to create special super qualifier for: "+expr+" which is not a field or call"); 4845 } 4846 soot.SootMethod methToInvoke = makeSuperAccessMethod(classToInvoke, expr); 4848 soot.Local classToInvokeLocal = Util.getThis(classToInvoke.getType(), body, getThisMap, lg); 4850 methodParams.add(0, classToInvokeLocal); 4851 4852 soot.jimple.InvokeExpr invokeExpr = soot.jimple.Jimple.v().newStaticInvokeExpr(methToInvoke.makeRef(), methodParams); 4853 4854 if (!methToInvoke.getReturnType().equals(soot.VoidType.v())){ 4856 soot.Local retLocal = lg.generateLocal(methToInvoke.getReturnType()); 4857 soot.jimple.AssignStmt stmt = soot.jimple.Jimple.v().newAssignStmt(retLocal, invokeExpr); 4858 body.getUnits().add(stmt); 4859 4860 return retLocal; 4861 } 4862 else { 4863 body.getUnits().add(soot.jimple.Jimple.v().newInvokeStmt(invokeExpr)); 4864 return null; 4865 } 4866 } 4867 4868 4871 private soot.Local getSpecialLocal(polyglot.ast.Special specialExpr) { 4872 4873 if (specialExpr.kind() == polyglot.ast.Special.SUPER) { 4875 if (specialExpr.qualifier() == null){ 4876 return specialThisLocal; 4877 } 4878 else { 4879 return getThis(Util.getSootType(specialExpr.qualifier().type())); 4889 } 4890 } 4891 else if (specialExpr.kind() == polyglot.ast.Special.THIS) { 4892 if (specialExpr.qualifier() == null) { 4894 return specialThisLocal; 4895 } 4896 else { 4897 return getThis(Util.getSootType(specialExpr.qualifier().type())); 4898 } 4899 } 4900 else { 4901 throw new RuntimeException ("Unknown Special"); 4902 } 4903 } 4904 4905 4906 private soot.SootMethod makeSuperAccessMethod(soot.SootClass classToInvoke, Object memberToAccess){ 4907 String name = "access$"+soot.javaToJimple.InitialResolver.v().getNextPrivateAccessCounter()+"00"; 4908 ArrayList paramTypes = new ArrayList(); 4909 paramTypes.add(classToInvoke.getType()); 4910 4911 soot.SootMethod meth; 4912 soot.MethodSource src; 4913 if (memberToAccess instanceof polyglot.ast.Field){ 4914 polyglot.ast.Field fieldToAccess = (polyglot.ast.Field)memberToAccess; 4915 meth = new soot.SootMethod(name, paramTypes, Util.getSootType(fieldToAccess.type()), soot.Modifier.STATIC); 4916 PrivateFieldAccMethodSource fSrc = new PrivateFieldAccMethodSource( 4917 Util.getSootType(fieldToAccess.type()), 4918 fieldToAccess.name(), 4919 fieldToAccess.flags().isStatic(), 4920 ((soot.RefType)Util.getSootType(fieldToAccess.target().type())).getSootClass() 4921 ); 4922 src = fSrc; 4923 } 4924 else if (memberToAccess instanceof polyglot.ast.Call){ 4925 polyglot.ast.Call methToAccess = (polyglot.ast.Call)memberToAccess; 4926 paramTypes.addAll(getSootParamsTypes(methToAccess)); 4927 meth = new soot.SootMethod(name, paramTypes, Util.getSootType(methToAccess.methodInstance().returnType()), soot.Modifier.STATIC); 4928 PrivateMethodAccMethodSource mSrc = new PrivateMethodAccMethodSource( methToAccess.methodInstance()); 4929 src = mSrc; 4930 } 4931 else { 4932 throw new RuntimeException ("trying to access unhandled member type: "+memberToAccess); 4933 } 4934 classToInvoke.addMethod(meth); 4935 meth.setActiveBody(src.getBody(meth, null)); 4936 meth.addTag(new soot.tagkit.SyntheticTag()); 4937 return meth; 4938 } 4939 4940 4943 private soot.Local getInstanceOfLocal(polyglot.ast.Instanceof instExpr) { 4944 4945 soot.Type sootType = Util.getSootType(instExpr.compareType().type()); 4946 4947 soot.Value local = base().createExpr(instExpr.expr()); 4948 4949 soot.jimple.InstanceOfExpr instOfExpr = soot.jimple.Jimple.v().newInstanceOfExpr(local, sootType); 4950 4951 soot.Local lhs = lg.generateLocal(soot.BooleanType.v()); 4952 4953 soot.jimple.AssignStmt instAssign = soot.jimple.Jimple.v().newAssignStmt(lhs, instOfExpr); 4954 body.getUnits().add(instAssign); 4955 Util.addLnPosTags(instAssign, instExpr.position()); 4956 Util.addLnPosTags(instAssign.getRightOpBox(), instExpr.position()); 4957 4958 Util.addLnPosTags(instOfExpr.getOpBox(), instExpr.expr().position()); 4959 return lhs; 4960 } 4961 4962 4965 private soot.Local getConditionalLocal(polyglot.ast.Conditional condExpr){ 4966 4967 4968 soot.jimple.Stmt noop1 = soot.jimple.Jimple.v().newNopStmt(); 4970 polyglot.ast.Expr condition = condExpr.cond(); 4971 createBranchingExpr(condition, noop1, false); 4972 4973 soot.Local retLocal = generateLocal(condExpr.type()); 4974 4975 polyglot.ast.Expr consequence = condExpr.consequent(); 4977 4978 soot.Value conseqVal = base().createExpr(consequence); 4979 if (conseqVal instanceof soot.jimple.ConditionExpr) { 4980 conseqVal = handleCondBinExpr((soot.jimple.ConditionExpr)conseqVal); 4981 } 4982 soot.jimple.AssignStmt conseqAssignStmt = soot.jimple.Jimple.v().newAssignStmt(retLocal, conseqVal); 4983 body.getUnits().add(conseqAssignStmt); 4984 Util.addLnPosTags(conseqAssignStmt, condExpr.position()); 4985 Util.addLnPosTags(conseqAssignStmt.getRightOpBox(), consequence.position()); 4986 4987 soot.jimple.Stmt noop2 = soot.jimple.Jimple.v().newNopStmt(); 4988 soot.jimple.Stmt goto1 = soot.jimple.Jimple.v().newGotoStmt(noop2); 4989 body.getUnits().add(goto1); 4990 4991 4993 body.getUnits().add(noop1); 4994 polyglot.ast.Expr alternative = condExpr.alternative(); 4995 if (alternative != null){ 4996 soot.Value altVal = base().createExpr(alternative); 4997 if (altVal instanceof soot.jimple.ConditionExpr) { 4998 altVal = handleCondBinExpr((soot.jimple.ConditionExpr)altVal); 4999 } 5000 soot.jimple.AssignStmt altAssignStmt = soot.jimple.Jimple.v().newAssignStmt(retLocal, altVal); 5001 body.getUnits().add(altAssignStmt); 5002 Util.addLnPosTags(altAssignStmt, condExpr.position()); 5003 Util.addLnPosTags(altAssignStmt, alternative.position()); 5004 Util.addLnPosTags(altAssignStmt.getRightOpBox(), alternative.position()); 5005 } 5006 body.getUnits().add(noop2); 5007 5008 5009 return retLocal; 5010 } 5011 5012 5015 5020 5021 5024 protected soot.Local generateLocal(polyglot.types.Type polyglotType) { 5025 soot.Type type = Util.getSootType(polyglotType); 5026 return lg.generateLocal(type); 5027 } 5028 5029 protected soot.Local generateLocal(soot.Type sootType){ 5030 return lg.generateLocal(sootType); 5031 } 5032} 5033
| Popular Tags
|