1 19 20 25 26 27 package soot.jimple.parser; 28 29 import soot.baf.*; 30 import soot.*; 31 import soot.jimple.*; 32 import soot.util.*; 33 34 import soot.jimple.parser.parser.*; 35 import soot.jimple.parser.lexer.*; 36 import soot.jimple.parser.node.*; 37 import soot.jimple.parser.analysis.*; 38 39 import java.io.*; 40 import java.util.*; 41 42 43 44 public class Walker extends DepthFirstAdapter 45 { 46 boolean debug = false; 47 LinkedList mProductions = new LinkedList(); 48 SootClass mSootClass = null; 49 Map mLocals = null; 50 Value mValue = IntConstant.v(1); 51 52 Map mLabelToStmtMap; Map mLabelToPatchList; 55 56 57 protected SootResolver mResolver; 58 59 60 public Walker(SootResolver resolver) 61 { 62 mResolver = resolver; 63 if(debug) { 64 mProductions = new LinkedList(){ 65 public Object removeLast(){ 66 Object o = super.removeLast(); 67 if(debug) 68 G.v().out.println("popped: " + o ); 69 return o; 70 } 71 }; 72 } 73 } 74 75 76 public Walker(SootClass sc, SootResolver resolver) 77 { 78 mSootClass = sc; 79 mResolver = resolver; 80 } 81 82 83 public void outStart(Start node) 84 { 85 SootClass c = (SootClass) mProductions.removeLast(); 86 } 87 88 89 public SootClass getSootClass() 90 { 91 if(mSootClass == null) 92 throw new RuntimeException ("did not parse class yet...."); 93 94 return mSootClass; 95 } 96 97 98 102 public void inAFile(AFile node) 103 { 104 if(debug) 105 G.v().out.println("reading class " + node.getClassName()); 106 } 107 108 109 public void caseAFile(AFile node) 110 { 111 inAFile(node); 112 { 113 Object temp[] = node.getModifier().toArray(); 114 for(int i = 0; i < temp.length; i++) 115 { 116 ((PModifier) temp[i]).apply(this); 117 } 118 } 119 if(node.getFileType() != null) 120 { 121 node.getFileType().apply(this); 122 } 123 if(node.getClassName() != null) 124 { 125 node.getClassName().apply(this); 126 } 127 128 String className = (String ) mProductions.removeLast(); 129 130 131 if(mSootClass == null) { 132 mSootClass = new SootClass(className); 133 mSootClass.setResolvingLevel(SootClass.BODIES); 134 } else { 135 if(!mSootClass.getName().equals(className)) 136 throw new RuntimeException ("Invalid SootClass for this JimpleAST. The SootClass provided is of type: >" + mSootClass.getName() + "< whereas this parse tree is for type: >" + className + "<"); 137 } 138 139 if(node.getExtendsClause() != null) 140 { 141 node.getExtendsClause().apply(this); 142 } 143 if(node.getImplementsClause() != null) 144 { 145 node.getImplementsClause().apply(this); 146 } 147 if(node.getFileBody() != null) 148 { 149 node.getFileBody().apply(this); 150 } 151 outAFile(node); 152 } 153 154 155 public void outAFile(AFile node) 156 { 157 List implementsList = null; 159 String superClass = null; 160 161 String classType = null; 162 163 if(node.getImplementsClause() != null) { 164 implementsList = (List) mProductions.removeLast(); 165 } 166 if(node.getExtendsClause() != null) { 167 superClass = (String ) mProductions.removeLast(); 168 } 169 170 classType = (String ) mProductions.removeLast(); 171 172 173 int modifierCount = node.getModifier().size(); 174 175 176 177 int modifierFlags = processModifiers(node.getModifier()); 178 179 180 if(classType.equals("interface")) 181 modifierFlags |= Modifier.INTERFACE; 182 183 mSootClass.setModifiers(modifierFlags); 184 185 if(superClass != null) { 186 mSootClass.setSuperclass(mResolver.makeClassRef(superClass)); 187 } 188 189 if(implementsList != null) { 190 Iterator implIt = implementsList.iterator(); 191 while(implIt.hasNext()) { 192 SootClass interfaceClass = mResolver.makeClassRef((String ) implIt.next()); 193 mSootClass.addInterface(interfaceClass); 194 } 195 } 196 197 mProductions.addLast(mSootClass); 198 } 199 200 205 public void outAFieldMember(AFieldMember node) 206 { 207 int modifier = 0; 208 Type type = null; 209 String name = null; 210 211 name = (String ) mProductions.removeLast(); 212 type = (Type) mProductions.removeLast(); 213 214 modifier = processModifiers(node.getModifier()); 215 216 SootField f = new SootField(name, type, modifier); 217 mSootClass.addField(f); 218 } 219 220 public void outAMethodMember(AMethodMember node) 221 { 222 int modifier = 0; 223 Type type; 224 String name; 225 List parameterList = null; 226 List throwsClause = null; 227 JimpleBody methodBody = null; 228 229 if(node.getMethodBody() instanceof AFullMethodBody) 230 methodBody = (JimpleBody) mProductions.removeLast(); 231 232 if(node.getThrowsClause() != null) 233 throwsClause = (List) mProductions.removeLast(); 234 235 if(node.getParameterList() != null) { 236 parameterList = (List) mProductions.removeLast(); 237 } 238 else { 239 parameterList = new ArrayList(); 240 } 241 242 Object o = mProductions.removeLast(); 243 244 name = (String ) o; 245 type = (Type) mProductions.removeLast(); 246 modifier = processModifiers(node.getModifier()); 247 248 SootMethod method; 249 250 if(throwsClause != null) 251 method = new SootMethod(name, parameterList, type, modifier, throwsClause); 252 else 253 method = new SootMethod(name, parameterList, type, modifier); 254 255 mSootClass.addMethod(method); 256 257 if(method.isConcrete()) { 258 methodBody.setMethod(method); 259 method.setActiveBody(methodBody); 260 261 } else if(node.getMethodBody() instanceof AFullMethodBody) 262 throw new RuntimeException ("Impossible: !concrete => ! instanceof"); 263 264 } 265 266 267 272 273 public void outAVoidType(AVoidType node) 274 { 275 mProductions.addLast(VoidType.v()); 276 } 277 278 279 286 public void outABaseNonvoidType(ABaseNonvoidType node) 287 { 288 Type t = (Type) mProductions.removeLast(); 289 int dim = node.getArrayBrackets().size(); 290 if(dim > 0) 291 t = ArrayType.v(t, dim); 292 mProductions.addLast(t); 293 } 294 295 296 public void outAQuotedNonvoidType(AQuotedNonvoidType node) 297 { 298 String typeName = (String ) mProductions.removeLast(); 299 Type t = RefType.v(typeName); 300 301 int dim = node.getArrayBrackets().size(); 302 if(dim > 0) 303 t = ArrayType.v(t, dim); 304 mProductions.addLast(t); 305 } 306 307 public void outAIdentNonvoidType(AIdentNonvoidType node) 308 { 309 String typeName = (String ) mProductions.removeLast(); 310 Type t = RefType.v(typeName); 311 int dim = node.getArrayBrackets().size(); 312 if(dim > 0) 313 t = ArrayType.v( t, dim); 314 mProductions.addLast(t); 315 } 316 317 318 public void outAFullIdentNonvoidType(AFullIdentNonvoidType node) 319 { 320 String typeName = (String ) mProductions.removeLast(); 321 Type t = RefType.v(typeName); 322 int dim = node.getArrayBrackets().size(); 323 if(dim > 0) 324 t = ArrayType.v(t, dim); 325 mProductions.addLast(t); 326 } 327 328 329 330 331 332 344 345 public void outABooleanBaseTypeNoName(ABooleanBaseTypeNoName node) 346 { 347 mProductions.addLast(BooleanType.v()); 348 } 349 350 public void outAByteBaseTypeNoName(AByteBaseTypeNoName node) 351 { 352 mProductions.addLast(ByteType.v()); 353 } 354 355 356 public void outACharBaseTypeNoName(ACharBaseTypeNoName node) 357 { 358 mProductions.addLast(CharType.v()); 359 } 360 361 public void outAShortBaseTypeNoName(AShortBaseTypeNoName node) 362 { 363 mProductions.addLast(ShortType.v()); 364 } 365 366 367 368 public void outAIntBaseTypeNoName(AIntBaseTypeNoName node) 369 { 370 mProductions.addLast(IntType.v()); 371 } 372 373 public void outALongBaseTypeNoName(ALongBaseTypeNoName node) 374 { 375 mProductions.addLast(LongType.v()); 376 } 377 378 379 public void outAFloatBaseTypeNoName(AFloatBaseTypeNoName node) 380 { 381 mProductions.addLast(FloatType.v()); 382 } 383 384 public void outADoubleBaseTypeNoName(ADoubleBaseTypeNoName node) 385 { 386 mProductions.addLast(DoubleType.v()); 387 } 388 public void outANullBaseTypeNoName(ANullBaseTypeNoName node) 389 { 390 mProductions.addLast(NullType.v()); 391 } 392 393 394 407 408 409 public void outABooleanBaseType(ABooleanBaseType node) 410 { 411 mProductions.addLast(BooleanType.v()); 412 } 413 414 public void outAByteBaseType(AByteBaseType node) 415 { 416 mProductions.addLast(ByteType.v()); 417 } 418 419 420 public void outACharBaseType(ACharBaseType node) 421 { 422 mProductions.addLast(CharType.v()); 423 } 424 425 public void outAShortBaseType(AShortBaseType node) 426 { 427 mProductions.addLast(ShortType.v()); 428 } 429 430 431 432 public void outAIntBaseType(AIntBaseType node) 433 { 434 mProductions.addLast(IntType.v()); 435 } 436 437 public void outALongBaseType(ALongBaseType node) 438 { 439 mProductions.addLast(LongType.v()); 440 } 441 442 443 public void outAFloatBaseType(AFloatBaseType node) 444 { 445 mProductions.addLast(FloatType.v()); 446 } 447 448 public void outADoubleBaseType(ADoubleBaseType node) 449 { 450 mProductions.addLast(DoubleType.v()); 451 } 452 453 public void outANullBaseType(ANullBaseType node) 454 { 455 mProductions.addLast(NullType.v()); 456 } 457 458 public void outAClassNameBaseType(AClassNameBaseType node) 459 { 460 String type = (String ) mProductions.removeLast(); 461 if(type.equals("int")) throw new RuntimeException (); 462 mProductions.addLast(RefType.v(type)); 463 } 464 465 466 471 472 473 public void inAFullMethodBody(AFullMethodBody node) 474 { 475 mLocals = new HashMap(); 476 mLabelToStmtMap = new HashMap(); 477 mLabelToPatchList = new HashMap(); 478 } 479 480 public void outAFullMethodBody(AFullMethodBody node) 481 { 482 Object catchClause = null; 483 JimpleBody jBody = Jimple.v().newBody(); 484 485 if(node.getCatchClause() != null) { 486 int size = node.getCatchClause().size(); 487 for(int i =0; i < size; i++) 488 jBody.getTraps().addFirst((Trap) mProductions.removeLast()); 489 } 490 491 if(node.getStatement() != null) { 492 int size = node.getStatement().size(); 493 Unit lastStmt = null; 494 for(int i = 0; i < size; i++) { 495 Object o = mProductions.removeLast(); 496 if(o instanceof Unit) { 497 jBody.getUnits().addFirst(o); 498 lastStmt = (Unit) o; 499 } 500 else if(o instanceof String ) { 501 if(lastStmt == null) 502 throw new RuntimeException ("impossible"); 503 mLabelToStmtMap.put(o, lastStmt); 504 } 505 else 506 throw new RuntimeException ("impossible"); 507 } 508 } 509 510 if(node.getDeclaration() != null) { 511 int size = node.getDeclaration().size(); 512 for(int i = 0; i < size; i++) { 513 List localList = (List) mProductions.removeLast(); 514 515 int listSize = localList.size(); 516 for(int j = listSize-1; j>=0; j--) 517 jBody.getLocals().addFirst(localList.get(j)); 518 } 519 } 520 521 522 523 Iterator it = mLabelToPatchList.keySet().iterator(); 524 while(it.hasNext()) { 525 String label = (String ) it.next(); 526 Unit target = (Unit) mLabelToStmtMap.get(label); 527 528 Iterator patchIt = ((List) mLabelToPatchList.get(label)).iterator(); 529 while(patchIt.hasNext()) { 530 UnitBox box = (UnitBox) patchIt.next(); 531 box.setUnit(target); 532 } 533 } 534 535 536 552 553 mProductions.addLast(jBody); 554 } 555 556 public void outANovoidType(ANovoidType node) 557 { 558 } 559 560 565 566 public void outASingleParameterList(ASingleParameterList node) 567 { 568 List l = new ArrayList(); 569 l.add((Type) mProductions.removeLast()); 570 mProductions.addLast(l); 571 } 572 573 public void outAMultiParameterList(AMultiParameterList node) 574 { 575 List l = (List) mProductions.removeLast(); 576 l.add(0,(Type) mProductions.removeLast()); 577 mProductions.addLast(l); 578 } 579 580 585 public void outASingleArgList(ASingleArgList node) 586 { 587 List l = new ArrayList(); 588 589 l.add((Value) mProductions.removeLast()); 590 mProductions.addLast(l); 591 } 592 593 public void outAMultiArgList(AMultiArgList node) 594 { 595 List l = (List) mProductions.removeLast(); 596 l.add(0,(Value) mProductions.removeLast()); 597 mProductions.addLast(l); 598 } 599 600 605 606 public void outAClassNameSingleClassNameList(AClassNameSingleClassNameList node) 607 { 608 List l = new ArrayList(); 609 l.add((String ) mProductions.removeLast()); 610 mProductions.addLast(l); 611 } 612 613 public void outAClassNameMultiClassNameList(AClassNameMultiClassNameList node) 614 { 615 List l = (List) mProductions.removeLast(); 616 l.add(0,(String ) mProductions.removeLast()); 617 mProductions.addLast(l); 618 } 619 620 625 626 public void outAClassFileType(AClassFileType node) 627 { 628 mProductions.addLast("class"); 629 } 630 631 public void outAInterfaceFileType(AInterfaceFileType node) 632 { 633 mProductions.addLast("interface"); 634 } 635 636 637 641 642 643 645 public void outACatchClause(ACatchClause node) 646 { 647 String exceptionName; 648 UnitBox withUnit, fromUnit, toUnit; 649 650 withUnit = Jimple.v().newStmtBox(null); 651 addBoxToPatch((String ) mProductions.removeLast(), withUnit); 652 653 toUnit = Jimple.v().newStmtBox(null); 654 addBoxToPatch((String ) mProductions.removeLast(), toUnit); 655 656 fromUnit = Jimple.v().newStmtBox(null); 657 addBoxToPatch((String ) mProductions.removeLast(), fromUnit); 658 659 exceptionName = (String ) mProductions.removeLast(); 660 661 Trap trap = Jimple.v().newTrap(mResolver.makeClassRef(exceptionName), fromUnit, toUnit, withUnit); 662 mProductions.addLast(trap); 663 } 664 665 669 670 671 public void outADeclaration(ADeclaration node) 672 { 673 List localNameList = (List) mProductions.removeLast(); 674 Type type = (Type) mProductions.removeLast(); 675 Iterator it = localNameList.iterator(); 676 List localList = new ArrayList(); 677 678 while(it.hasNext()) { 679 Local l = Jimple.v().newLocal((String ) it.next(),type); 680 mLocals.put(l.getName(), l); 681 localList.add(l); 682 } 683 mProductions.addLast(localList); 684 } 685 686 687 688 689 690 695 public void outAUnknownJimpleType(AUnknownJimpleType node) 696 { 697 mProductions.addLast(UnknownType.v()); 698 } 699 700 701 706 707 public void outASingleLocalNameList(ASingleLocalNameList node) 708 { 709 List l = new ArrayList(); 710 l.add((String ) mProductions.removeLast()); 711 mProductions.addLast(l); 712 } 713 714 public void outAMultiLocalNameList(AMultiLocalNameList node) 715 { 716 List l = (List) mProductions.removeLast(); 717 l.add(0,(String ) mProductions.removeLast()); 718 mProductions.addLast(l); 719 } 720 721 722 740 741 public void outALabelStatement(ALabelStatement node) 742 { 743 } 744 745 public void outABreakpointStatement(ABreakpointStatement node) 746 { 747 Unit u = Jimple.v().newBreakpointStmt(); 748 mProductions.addLast(u); 749 } 750 751 752 public void outAEntermonitorStatement(AEntermonitorStatement node) 753 { 754 Value op = (Value) mProductions.removeLast(); 755 756 Unit u = Jimple.v().newEnterMonitorStmt(op); 757 mProductions.addLast(u); 758 } 759 760 public void outAExitmonitorStatement(AExitmonitorStatement node) 761 { 762 Value op = (Value) mProductions.removeLast(); 763 764 Unit u = Jimple.v().newExitMonitorStmt(op); 765 mProductions.addLast(u); 766 } 767 768 769 774 778 public void outACaseStmt(ACaseStmt node) 779 { 780 String labelName = (String ) mProductions.removeLast(); 781 UnitBox box = Jimple.v().newStmtBox(null); 782 783 addBoxToPatch(labelName, box); 784 785 Value labelValue = null; 786 if(node.getCaseLabel() instanceof AConstantCaseLabel) 787 labelValue = (Value) mProductions.removeLast(); 788 789 if(labelValue == null) 791 mProductions.addLast(box); 792 else { 793 Object [] valueTargetPair = new Object [2]; 794 valueTargetPair[0] = labelValue; 795 valueTargetPair[1] = box; 796 mProductions.addLast(valueTargetPair); 797 } 798 } 799 800 801 802 public void outATableswitchStatement(ATableswitchStatement node) 803 { 804 List targets = new ArrayList(); 805 UnitBox defaultTarget = null; 806 807 int lowIndex = 0, highIndex = 0; 808 809 if(node.getCaseStmt() != null) { 810 int size = node.getCaseStmt().size(); 811 812 for(int i = 0; i < size; i++) { 813 Object valueTargetPair = mProductions.removeLast(); 814 if(valueTargetPair instanceof UnitBox) { 815 if(defaultTarget != null) 816 throw new RuntimeException ("error: can't ;have more than 1 default stmt"); 817 818 defaultTarget = (UnitBox) valueTargetPair; 819 } else { 820 Object [] pair = (Object []) valueTargetPair; 821 822 if((i == 0 && defaultTarget == null) || (i==1 && defaultTarget != null)) 823 highIndex = ((IntConstant) pair[0]).value; 824 if(i == (size -1)) 825 lowIndex = ((IntConstant) pair[0]).value; 826 827 targets.add(0, pair[1]); 828 } 829 } 830 } else { 831 throw new RuntimeException ("error: switch stmt has no case stmts"); 832 } 833 834 835 Value key = (Value) mProductions.removeLast(); 836 Unit switchStmt = Jimple.v().newTableSwitchStmt(key, lowIndex, highIndex, targets, defaultTarget); 837 838 839 mProductions.addLast(switchStmt); 840 } 841 842 843 public void outALookupswitchStatement(ALookupswitchStatement node) 844 { 845 List lookupValues = new ArrayList(); 846 List targets = new ArrayList(); 847 UnitBox defaultTarget = null; 848 849 850 if(node.getCaseStmt() != null) { 851 int size = node.getCaseStmt().size(); 852 853 for(int i = 0; i < size; i++) { 854 Object valueTargetPair = mProductions.removeLast(); 855 if(valueTargetPair instanceof UnitBox) { 856 if(defaultTarget != null) 857 throw new RuntimeException ("error: can't ;have more than 1 default stmt"); 858 859 defaultTarget = (UnitBox) valueTargetPair; 860 } else { 861 Object [] pair = (Object []) valueTargetPair; 862 863 lookupValues.add(0, pair[0]); 864 targets.add(0, pair[1]); 865 } 866 } 867 } else { 868 throw new RuntimeException ("error: switch stmt has no case stmts"); 869 } 870 871 872 Value key = (Value) mProductions.removeLast(); 873 Unit switchStmt = Jimple.v().newLookupSwitchStmt(key, lookupValues, targets, defaultTarget); 874 875 mProductions.addLast(switchStmt); 876 } 877 878 879 880 881 public void outAIdentityStatement(AIdentityStatement node) 882 { 883 Type identityRefType = (Type) mProductions.removeLast(); 884 String atClause = (String ) mProductions.removeLast(); 885 Value local = (Value) mLocals.get(mProductions.removeLast()); 887 Value ref = null; 888 if(atClause.startsWith("@this")) { 889 ref = Jimple.v().newThisRef((RefType) identityRefType); 890 } else if(atClause.startsWith("@parameter")) { 891 int index = Integer.parseInt(atClause.substring(10, atClause.length() - 1)); 892 893 ref = Jimple.v().newParameterRef(identityRefType, index); 894 } else 895 throw new RuntimeException ("shouldn't @caughtexception be handled by outAIdentityNoTypeStatement: got" + atClause); 896 897 Unit u = Jimple.v().newIdentityStmt(local, ref); 898 mProductions.addLast(u); 899 } 900 901 902 public void outAIdentityNoTypeStatement(AIdentityNoTypeStatement node) 903 { 904 mProductions.removeLast(); Value local = (Value) mLocals.get(mProductions.removeLast()); 907 908 Unit u = Jimple.v().newIdentityStmt(local, Jimple.v().newCaughtExceptionRef()); 909 mProductions.addLast(u); 910 } 911 912 913 public void outAAssignStatement(AAssignStatement node) 914 { 915 Value rvalue = (Value) mProductions.removeLast(); 916 Value variable =(Value)mProductions.removeLast(); 917 918 919 Unit u = Jimple.v().newAssignStmt(variable, rvalue); 920 mProductions.addLast(u); 921 } 922 923 public void outAIfStatement(AIfStatement node) 924 { 925 String targetLabel = (String ) mProductions.removeLast(); 926 Value condition =(Value) mProductions.removeLast(); 927 928 UnitBox box = Jimple.v().newStmtBox(null); 929 Unit u = Jimple.v().newIfStmt(condition, box); 930 931 addBoxToPatch(targetLabel, box); 932 933 mProductions.addLast(u); 934 } 935 936 public void outAReturnStatement(AReturnStatement node) 937 { 938 Value v; 939 Stmt s = null; 940 if(node.getImmediate() != null) { 941 v = (Value) mProductions.removeLast(); 942 s = Jimple.v().newReturnStmt(v); 943 } else { 944 s = Jimple.v().newReturnVoidStmt(); 945 } 946 947 mProductions.addLast(s); 948 } 949 950 public void outAGotoStatement(AGotoStatement node) 951 { 952 String targetLabel = (String ) mProductions.removeLast(); 953 954 UnitBox box = Jimple.v().newStmtBox(null); 955 Unit branch = Jimple.v().newGotoStmt(box); 956 957 addBoxToPatch(targetLabel, box); 958 959 mProductions.addLast(branch); 960 } 961 962 963 public void outANopStatement(ANopStatement node) 964 { 965 Unit u = Jimple.v().newNopStmt(); 966 mProductions.addLast(u); 967 } 968 969 public void outARetStatement(ARetStatement node) 970 { 971 throw new RuntimeException ("ret not yet implemented."); 972 } 973 974 975 public void outAThrowStatement(AThrowStatement node) 976 { 977 Value op = (Value) mProductions.removeLast(); 978 979 Unit u = Jimple.v().newThrowStmt(op); 980 mProductions.addLast(u); 981 } 982 983 public void outAInvokeStatement(AInvokeStatement node) 984 { 985 Value op = (Value) mProductions.removeLast(); 986 987 Unit u = Jimple.v().newInvokeStmt(op); 988 989 mProductions.addLast(u); 990 } 991 992 993 994 999 public void outAConstantCaseLabel(AConstantCaseLabel node) 1000 { 1001 String s = (String ) mProductions.removeLast(); 1002 int sign = 1; 1003 if(node.getMinus() != null) 1004 sign = -1; 1005 1006 if(s.endsWith("L")) { 1007 mProductions.addLast(LongConstant.v(sign * Long.parseLong(s.substring(0, s.length()-1)))); 1008 } 1009 else if (s.equals("2147483648")) 1010 mProductions.addLast(IntConstant.v(sign * Integer.MIN_VALUE)); 1011 else 1012 mProductions.addLast(IntConstant.v(sign * Integer.parseInt(s))); 1013 } 1014 1015 1020 1021 public void outALocalImmediate(ALocalImmediate node) 1022 { 1023 String local = (String ) mProductions.removeLast(); 1024 1025 Local l = (Local) mLocals.get(local); 1026 if(l == null) throw new RuntimeException ("did not find local: " + local); 1027 mProductions.addLast(l); 1028 } 1029 1030 1031 1032 1039 1040 1041 public void outANullConstant(ANullConstant node) 1042 { 1043 mProductions.addLast(NullConstant.v()); 1044 } 1045 1046 1047 public void outAIntegerConstant(AIntegerConstant node) 1048 { 1049 String s = (String ) mProductions.removeLast(); 1050 1051 StringBuffer buf = new StringBuffer (); 1052 if(node.getMinus() != null) 1053 buf.append('-'); 1054 buf.append(s); 1055 1056 s = buf.toString(); 1057 if(s.endsWith("L")) { 1058 mProductions.addLast(LongConstant.v(Long.parseLong(s.substring(0, s.length()-1)))); 1059 } 1060 else if (s.equals("2147483648")) 1061 mProductions.addLast(IntConstant.v(Integer.MIN_VALUE)); 1062 else 1063 mProductions.addLast(IntConstant.v(Integer.parseInt(s))); 1064 } 1065 1066 public void outAStringConstant(AStringConstant node) 1067 { 1068 String s = (String ) mProductions.removeLast(); 1069 mProductions.addLast(StringConstant.v(s)); 1070 1080 } 1081 1082 public void outAClzzConstant(AClzzConstant node) 1083 { 1084 String s = (String )mProductions.removeLast(); 1085 mProductions.addLast(ClassConstant.v(s)); 1086 } 1087 1088 1089 1090 1091 public void outAFloatConstant(AFloatConstant node) 1092 { 1093 String s = (String ) mProductions.removeLast(); 1094 1095 boolean isDouble = true; 1096 float value = 0; 1097 double dvalue = 0; 1098 1099 if(s.endsWith("f") || s.endsWith("F")) 1100 isDouble = false; 1101 1102 if(s.charAt(0) == '#') { 1103 if(s.charAt(1) == '-') { 1104 if(isDouble) 1105 dvalue = Double.NEGATIVE_INFINITY; 1106 else 1107 value = Float.NEGATIVE_INFINITY; 1108 } 1109 else if(s.charAt(1) == 'I') { 1110 if(isDouble) 1111 dvalue = Double.POSITIVE_INFINITY; 1112 else 1113 value = Float.POSITIVE_INFINITY; 1114 } 1115 else { 1116 if(isDouble) 1117 dvalue = Double.NaN; 1118 else 1119 value = Float.NaN; 1120 } 1121 } 1122 else { 1123 StringBuffer buf = new StringBuffer (); 1124 if(node.getMinus() != null) 1125 buf.append('-'); 1126 buf.append(s); 1127 s = buf.toString(); 1128 1129 if(isDouble) 1130 dvalue = Double.parseDouble(s); 1131 else 1132 value =Float.parseFloat(s); 1133 } 1134 1135 Object res; 1136 if(isDouble) 1137 res = DoubleConstant.v(dvalue); 1138 else 1139 res = FloatConstant.v(value); 1140 1141 mProductions.addLast(res); 1142 } 1143 1144 1145 1149 1150 1151 public void outABinopExpr(ABinopExpr node) 1152 { 1153 Value right = (Value) mProductions.removeLast(); 1154 BinopExpr expr = (BinopExpr) mProductions.removeLast(); 1155 Value left = (Value) mProductions.removeLast(); 1156 1157 1158 expr.setOp1(left); 1159 expr.setOp2(right); 1160 mProductions.addLast(expr); 1161 } 1162 1163 public void outABinopBoolExpr(ABinopBoolExpr node){ 1164 } 1165 1166 1167 public void outAUnopExpression(AUnopExpression node) 1168 { 1169 } 1170 1171 1172 1173 1174 1201 1202 1203 public void outAAndBinop(AAndBinop node) 1204 { 1205 mProductions.addLast(Jimple.v().newAndExpr(mValue, mValue)); 1206 } 1207 public void outAOrBinop(AOrBinop node) 1208 { 1209 mProductions.addLast(Jimple.v().newOrExpr(mValue, mValue)); 1210 } 1211 1212 public void outAXorBinop(AXorBinop node) 1213 { 1214 mProductions.addLast(Jimple.v().newXorExpr(mValue, mValue)); 1215 } 1216 public void outAModBinop(AModBinop node) 1217 { 1218 mProductions.addLast(Jimple.v().newRemExpr(mValue, mValue)); 1219 } 1220 1221 public void outACmpBinop(ACmpBinop node) 1222 { 1223 mProductions.addLast(Jimple.v().newCmpExpr(mValue, mValue)); 1224 } 1225 1226 public void outACmpgBinop(ACmpgBinop node) 1227 { 1228 mProductions.addLast(Jimple.v().newCmpgExpr(mValue, mValue)); 1229 } 1230 1231 public void outACmplBinop(ACmplBinop node) 1232 { 1233 mProductions.addLast(Jimple.v().newCmplExpr(mValue, mValue)); 1234 } 1235 1236 public void outACmpeqBinop(ACmpeqBinop node) 1237 { 1238 mProductions.addLast(Jimple.v().newEqExpr(mValue, mValue)); 1239 } 1240 1241 1242 public void outACmpneBinop(ACmpneBinop node) 1243 { 1244 mProductions.addLast(Jimple.v().newNeExpr(mValue, mValue)); 1245 } 1246 1247 public void outACmpgtBinop(ACmpgtBinop node) 1248 { 1249 mProductions.addLast(Jimple.v().newGtExpr(mValue, mValue)); 1250 } 1251 1252 public void outACmpgeBinop(ACmpgeBinop node) 1253 { 1254 mProductions.addLast(Jimple.v().newGeExpr(mValue, mValue)); 1255 } 1256 1257 public void outACmpltBinop(ACmpltBinop node) 1258 { 1259 mProductions.addLast(Jimple.v().newLtExpr(mValue, mValue)); 1260 } 1261 1262 public void outACmpleBinop(ACmpleBinop node) 1263 { 1264 mProductions.addLast(Jimple.v().newLeExpr(mValue, mValue)); 1265 } 1266 1267 public void outAShlBinop(AShlBinop node) 1268 { 1269 mProductions.addLast(Jimple.v().newShlExpr(mValue, mValue)); 1270 } 1271 1272 public void outAShrBinop(AShrBinop node) 1273 { 1274 mProductions.addLast(Jimple.v().newShrExpr(mValue, mValue)); 1275 } 1276 1277 public void outAUshrBinop(AUshrBinop node) 1278 { 1279 mProductions.addLast(Jimple.v().newUshrExpr(mValue, mValue)); 1280 } 1281 1282 public void outAPlusBinop(APlusBinop node) 1283 { 1284 mProductions.addLast(Jimple.v().newAddExpr(mValue, mValue)); 1285 } 1286 1287 public void outAMinusBinop(AMinusBinop node) 1288 { 1289 mProductions.addLast(Jimple.v().newSubExpr(mValue, mValue)); 1290 } 1291 1292 public void outAMultBinop(AMultBinop node) 1293 { 1294 mProductions.addLast(Jimple.v().newMulExpr(mValue, mValue)); 1295 } 1296 public void outADivBinop(ADivBinop node) 1297 { 1298 mProductions.addLast(Jimple.v().newDivExpr(mValue, mValue)); 1299 } 1300 1301 1305 public void outAThrowsClause(AThrowsClause node) 1306 { 1307 List l = (List) mProductions.removeLast(); 1308 1309 Iterator it = l.iterator(); 1310 List exceptionClasses = new ArrayList(l.size()); 1311 1312 while(it.hasNext()) { 1313 String className = (String ) it.next(); 1314 1315 exceptionClasses.add(mResolver.makeClassRef(className)); 1316 } 1317 1318 mProductions.addLast(exceptionClasses); 1319 } 1320 1321 1322 1323 1324 1329 1330 public void outALocalVariable(ALocalVariable node) 1331 { 1332 String local = (String ) mProductions.removeLast(); 1333 1334 Local l = (Local) mLocals.get(local); 1335 if(l == null) throw new RuntimeException ("did not find local: " + local); 1336 mProductions.addLast(l); 1337 } 1338 1339 1344 1345 1346 1350 1351 public void outAArrayRef(AArrayRef node) 1352 { 1353 Value immediate = (Value) mProductions.removeLast(); 1354 String identifier = (String ) mProductions.removeLast(); 1355 1356 Local l = (Local) mLocals.get(identifier); 1357 if(l == null) throw new RuntimeException ("did not find local: " + identifier); 1358 1359 mProductions.addLast(Jimple.v().newArrayRef(l, immediate)); 1360 1361 } 1362 1363 1368 1369 public void outALocalFieldRef(ALocalFieldRef node) 1370 { 1371 SootFieldRef field = (SootFieldRef) mProductions.removeLast(); 1372 1373 String local = (String ) mProductions.removeLast(); 1374 1375 Local l = (Local) mLocals.get(local); 1376 if(l == null) throw new RuntimeException ("did not find local: " + local); 1377 1378 mProductions.addLast(Jimple.v().newInstanceFieldRef(l, field)); 1379 } 1380 1381 1382 public void outASigFieldRef(ASigFieldRef node) 1383 { 1384 SootFieldRef field = (SootFieldRef) mProductions.removeLast(); 1385 field = Scene.v().makeFieldRef(field.declaringClass(), field.name(), 1386 field.type(), true); 1387 mProductions.addLast(Jimple.v().newStaticFieldRef(field)); 1388 } 1389 1390 1391 1395 1396 public void outAFieldSignature(AFieldSignature node) 1397 { 1398 String className, fieldName; 1399 Type t; 1400 1401 fieldName = (String ) mProductions.removeLast(); 1402 t = (Type) mProductions.removeLast(); 1403 className = (String ) mProductions.removeLast(); 1404 1405 SootClass cl = mResolver.makeClassRef(className); 1406 SootFieldRef field = Scene.v().makeFieldRef(cl, fieldName, t, false); 1407 1408 mProductions.addLast(field); 1409 } 1410 1411 1423 public void outACastExpression(ACastExpression node) 1424 { 1425 Value val = (Value) mProductions.removeLast(); 1426 1427 Type type = (Type) mProductions.removeLast(); 1428 mProductions.addLast(Jimple.v().newCastExpr(val, type)); 1429 } 1430 1431 1432 1433 public void outAInstanceofExpression(AInstanceofExpression node) 1434 { 1435 Type nonvoidType = (Type) mProductions.removeLast(); 1436 Value immediate = (Value) mProductions.removeLast(); 1437 mProductions.addLast(Jimple.v().newInstanceOfExpr(immediate, nonvoidType)); 1438 1439 } 1440 1441 1442 1446 public void outAUnopExpr(AUnopExpr node) 1447 { 1448 Value v = (Value) mProductions.removeLast(); 1449 UnopExpr expr = (UnopExpr) mProductions.removeLast(); 1450 expr.setOp(v); 1451 mProductions.addLast(expr); 1452 } 1453 1454 1455 1460 public void outALengthofUnop(ALengthofUnop node) 1461 { 1462 mProductions.addLast(Jimple.v().newLengthExpr(mValue)); 1463 } 1464 1465 public void outANegUnop(ANegUnop node) 1466 { 1467 mProductions.addLast(Jimple.v().newNegExpr(mValue)); 1468 } 1469 1470 1471 1476 1477 public void outANonstaticInvokeExpr(ANonstaticInvokeExpr node) 1478 { 1479 List args; 1480 1481 if(node.getArgList() != null) 1482 args = (List) mProductions.removeLast(); 1483 else 1484 args = new ArrayList(); 1485 1486 SootMethodRef method = (SootMethodRef) mProductions.removeLast(); 1487 1488 String local = (String ) mProductions.removeLast(); 1489 1490 1491 Local l = (Local) mLocals.get(local); 1492 if(l == null) throw new RuntimeException ("did not find local: " + local); 1493 1494 1495 Node invokeType = (Node) node.getNonstaticInvoke(); 1496 Expr invokeExpr; 1497 1498 if(invokeType instanceof ASpecialNonstaticInvoke){ 1499 invokeExpr = Jimple.v().newSpecialInvokeExpr(l, method, args); 1500 } else if(invokeType instanceof AVirtualNonstaticInvoke){ 1501 invokeExpr = Jimple.v().newVirtualInvokeExpr(l, method, args); 1502 } else { 1503 if(debug)if(!(invokeType instanceof AInterfaceNonstaticInvoke)) throw new RuntimeException ("expected interface invoke."); 1504 invokeExpr = Jimple.v().newInterfaceInvokeExpr(l, method, args); 1505 } 1506 1507 mProductions.addLast(invokeExpr); 1508 1509 } 1510 1511 1512 1513 public void outAStaticInvokeExpr(AStaticInvokeExpr node) 1514 { 1515 List args; 1516 1517 if(node.getArgList() != null) 1518 args = (List) mProductions.removeLast(); 1519 else 1520 args = new ArrayList(); 1521 1522 SootMethodRef method = (SootMethodRef) mProductions.removeLast(); 1523 method = Scene.v().makeMethodRef(method.declaringClass(), 1524 method.name(), method.parameterTypes(), method.returnType(), 1525 true); 1526 1527 mProductions.addLast(Jimple.v().newStaticInvokeExpr(method, args)); 1528 } 1529 1530 1534 public void outAMethodSignature(AMethodSignature node) 1535 { 1536 String className, methodName; 1537 List parameterList = new ArrayList(); 1538 Type returnType; 1539 1540 if(node.getParameterList() != null) 1541 parameterList = (List) mProductions.removeLast(); 1542 1543 methodName = (String ) mProductions.removeLast(); 1544 Type type = (Type) mProductions.removeLast(); 1545 className = (String ) mProductions.removeLast(); 1546 1547 SootClass sootClass = mResolver.makeClassRef(className); 1548 SootMethodRef sootMethod = Scene.v().makeMethodRef(sootClass, methodName, parameterList, type, false); 1549 1550 mProductions.addLast(sootMethod); 1551 } 1552 1553 1559 public void outASimpleNewExpr(ASimpleNewExpr node) 1560 { 1561 mProductions.addLast(Jimple.v().newNewExpr((RefType)mProductions.removeLast())); 1562 } 1563 1564 public void outAArrayNewExpr(AArrayNewExpr node) 1565 { 1566 Value size = (Value) mProductions.removeLast(); 1567 Type type = (Type) mProductions.removeLast(); 1568 mProductions.addLast(Jimple.v().newNewArrayExpr(type, size)); 1569 } 1570 1571 public void outAMultiNewExpr(AMultiNewExpr node) 1572 { 1573 1574 LinkedList arrayDesc = node.getArrayDescriptor(); 1575 1576 int descCnt = arrayDesc.size(); 1577 List sizes = new LinkedList(); 1578 1579 Iterator it = arrayDesc.iterator(); 1580 while(it.hasNext()) { 1581 AArrayDescriptor o = (AArrayDescriptor) it.next(); 1582 if(o.getImmediate() != null) 1583 sizes.add(0,(Value) mProductions.removeLast()); 1584 else 1585 break; 1586 } 1587 1588 Type type = (Type) mProductions.removeLast(); 1589 ArrayType arrayType = ArrayType.v(type, descCnt); 1590 1591 mProductions.addLast(Jimple.v().newNewMultiArrayExpr(arrayType, sizes)); 1592 } 1593 1594 public void defaultCase(Node node) 1595 { 1596 if(node instanceof TQuotedName || 1597 node instanceof TFullIdentifier || 1598 node instanceof TIdentifier || 1599 node instanceof TStringConstant || 1600 1601 node instanceof TIntegerConstant || 1602 node instanceof TFloatConstant || 1603 node instanceof TAtIdentifier 1604 1605 ) { 1606 if(debug) 1607 G.v().out.println("Default case -pushing token:" + ((Token) node).getText()); 1608 String tokenString = ((Token) node).getText(); 1609 if(node instanceof TStringConstant || node instanceof TQuotedName) { 1610 tokenString = tokenString.substring(1, tokenString.length() -1 ); 1611 } 1612 1613 if(node instanceof TIdentifier || node instanceof TFullIdentifier || node instanceof TQuotedName || node instanceof TStringConstant) { 1614 try { 1615 tokenString = StringTools.getUnEscapedStringOf(tokenString); 1616 1617 } catch(RuntimeException e) { 1618 G.v().out.println(tokenString); 1619 throw e; 1620 } 1621 } 1622 1623 mProductions.addLast(tokenString); 1624 } 1625 } 1626 1627 1628 1629 1630 protected int processModifiers(List l) 1631 { 1632 int modifier = 0; 1633 Iterator it = l.iterator(); 1634 1635 while(it.hasNext()) { 1636 Object t = it.next(); 1637 if(t instanceof AAbstractModifier) 1638 modifier |= Modifier.ABSTRACT; 1639 else if(t instanceof AFinalModifier) 1640 modifier |= Modifier.FINAL; 1641 else if(t instanceof ANativeModifier) 1642 modifier |= Modifier.NATIVE; 1643 else if(t instanceof APublicModifier) 1644 modifier |= Modifier.PUBLIC; 1645 else if(t instanceof AProtectedModifier) 1646 modifier |= Modifier.PROTECTED; 1647 else if(t instanceof APrivateModifier) 1648 modifier |= Modifier.PRIVATE; 1649 else if(t instanceof AStaticModifier) 1650 modifier |= Modifier.STATIC; 1651 else if(t instanceof ASynchronizedModifier) 1652 modifier |= Modifier.SYNCHRONIZED; 1653 else if(t instanceof ATransientModifier) 1654 modifier |= Modifier.TRANSIENT; 1655 else if(t instanceof AVolatileModifier) 1656 modifier |= Modifier.VOLATILE; 1657 else if(t instanceof AStrictfpModifier) 1658 modifier |= Modifier.STRICTFP; 1659 else if(t instanceof AEnumModifier) 1660 modifier |= Modifier.ENUM; 1661 else if(t instanceof AAnnotationModifier) 1662 modifier |= Modifier.ANNOTATION; 1663 else 1664 throw new RuntimeException ("Impossible: modifier unknown - Have you added a new modifier and not updated this file?"); 1665 } 1666 1667 return modifier; 1668 } 1669 1670 1671 private void addBoxToPatch(String aLabelName, UnitBox aUnitBox) 1672 { 1673 List patchList = (List) mLabelToPatchList.get(aLabelName); 1674 if(patchList == null) { 1675 patchList = new ArrayList(); 1676 mLabelToPatchList.put(aLabelName, patchList); 1677 } 1678 1679 patchList.add(aUnitBox); 1680 } 1681 1682 1683} 1684 1685 1686 | Popular Tags |