1 19 20 25 26 27 28 29 30 31 32 package soot.coffi; 33 import soot.options.*; 34 35 import java.lang.*; 36 import java.util.*; 37 38 import soot.*; 39 import soot.jimple.*; 40 import soot.baf.*; 41 import soot.util.*; 42 import soot.tagkit.*; 43 44 47 public class CFG { 48 49 52 private method_info method; 53 55 BasicBlock cfg; 56 57 Chain units; 58 JimpleBody listBody; 59 60 Map instructionToFirstStmt; 61 Map instructionToLastStmt; 62 SootMethod jmethod; 63 Scene cm; 64 65 Instruction firstInstruction; 66 Instruction lastInstruction; 67 68 private short wide; 70 private Instruction sentinel; 71 private Hashtable h2bb, t2bb; 72 private int bbcount; 74 78 public CFG(method_info m) 79 { 80 this.method = m; 81 82 this.sentinel = new Instruction_Nop(); 83 this.sentinel.next = m.instructions; 84 m.instructions.prev = this.sentinel; 85 86 89 eliminateJsrRets(); 90 91 94 buildBBCFG(); 95 96 99 cfg.beginCode = true; 100 101 m.cfg = this; 102 103 if(cfg != null) 104 firstInstruction = cfg.head; 105 else 106 firstInstruction = null; 107 108 121 } 122 123 private void printBBCFGSucc() 124 { 125 BasicBlock b = this.cfg; 126 while ( b!= null ) 127 { 128 G.v().out.print(b.id +" -> "); 129 for (int i=0; i<b.succ.size(); i++) 130 { 131 BasicBlock bs = (BasicBlock)b.succ.elementAt(i); 132 G.v().out.print(bs.id+" "); 133 } 134 G.v().out.println(); 135 b = b.next; 136 } 137 } 138 139 private void printBBCFGPred() 140 { 141 BasicBlock b = this.cfg; 142 while ( b!= null ) 143 { 144 G.v().out.print(b.id +" <- "); 145 for (int i=0; i<b.pred.size(); i++) 146 { 147 BasicBlock bs = (BasicBlock)b.pred.elementAt(i); 148 G.v().out.print(bs.id+" "); 149 } 150 G.v().out.println(); 151 b = b.next; 152 } 153 } 154 155 private void printOneBasicBlock(BasicBlock b) 156 { 157 G.v().out.println("Block "+b.id); 158 159 Instruction insn = b.head; 160 G.v().out.println(insn); 161 while (insn != b.tail && insn != null) 162 { 163 insn = insn.next; 164 G.v().out.println(insn); 165 } 166 167 G.v().out.println(); 168 } 169 170 private void printBBHeadTail(BasicBlock fb) 171 { 172 BasicBlock b = fb; 173 while (b != null) 174 { 175 G.v().out.println(b.head); 176 G.v().out.println(b.tail+"\n"); 177 b = b.next; 178 } 179 } 180 181 private void printBBs() 182 { 183 BasicBlock bb = this.cfg; 184 while (bb != null) 185 { 186 printOneBasicBlock(bb); 187 bb = bb.next; 188 } 189 } 190 191 private void printInstructions() 192 { 193 Instruction insn = method.instructions; 194 while (insn != null) 195 { 196 G.v().out.println(insn); 197 insn = insn.next; 198 } 199 } 200 201 private void printExceptionTable() 202 { 203 Code_attribute ca = this.method.locate_code_attribute(); 204 205 G.v().out.println("\nException table :"); 206 G.v().out.println("start\tend\thandler"); 207 for (int i=0; i<ca.exception_table.length; i++) 208 { 209 exception_table_entry ete = ca.exception_table[i]; 210 G.v().out.println((ete.start_inst == null ? "null" : 211 Integer.toString(ete.start_inst.label)) + " \t " + 212 (ete.end_inst == null ? "null" : 213 Integer.toString(ete.end_inst.label)) + " \t " + 214 ete.handler_inst.label); 215 } 216 } 217 private void buildBBCFG() 221 { 222 Object branches[], nextinsn; 223 Code_attribute ca = method.locate_code_attribute(); 224 225 { 226 h2bb = new Hashtable(100,25); 227 t2bb = new Hashtable(100,25); 228 229 Instruction insn = this.sentinel.next; 230 BasicBlock blast = null; 231 if (insn != null) 232 { 233 Instruction tail = buildBasicBlock(insn); 234 cfg = new BasicBlock(insn, tail); 235 h2bb.put(insn, cfg); 236 t2bb.put(tail, cfg); 237 insn = tail.next; 238 blast = cfg; 239 } 240 241 while (insn != null) 242 { 243 Instruction tail = buildBasicBlock(insn); 244 BasicBlock block = new BasicBlock(insn, tail); 245 blast.next = block; 246 blast = block; 247 h2bb.put(insn, block); 248 t2bb.put(tail, block); 249 insn = tail.next; 250 } 251 } 252 253 BasicBlock block = cfg; 254 255 while (block != null) 256 { 257 Instruction insn = block.tail; 258 259 if (insn.branches) 260 { 261 if (insn instanceof Instruction_Athrow) 262 { 263 HashSet ethandlers = new HashSet(); 266 267 for (int i=0; i<ca.exception_table_length; i++) 270 { 271 exception_table_entry etentry = 272 ca.exception_table[i]; 273 274 if (insn.label >= etentry.start_inst.label 275 && (etentry.end_inst==null 276 || insn.label < etentry.end_inst.label)) 277 { 278 ethandlers.add(etentry.handler_inst); 279 } 280 } 281 282 branches = ethandlers.toArray(); 283 } 284 else 285 { 286 branches = insn.branchpoints(insn.next); 287 } 288 289 if (branches != null) 290 { 291 block.succ.ensureCapacity(block.succ.size()+branches.length); 292 293 for (int i=0; i<branches.length; i++) 294 { 295 if ( branches[i]!=null ) { 296 BasicBlock bb = (BasicBlock)h2bb.get(branches[i]); 297 298 if (bb == null) 299 { 300 G.v().out.println("Warning: " 301 +"target of a branch is null"); 302 G.v().out.println ( insn ); 303 } 304 else 305 { 306 block.succ.addElement(bb); 307 bb.pred.addElement(block); 308 } 309 } 310 } 311 } 312 } 313 else 314 if (block.next!=null) 315 { block.succ.addElement(block.next); 317 block.next.pred.addElement(block); 318 } 319 block = block.next; 320 } 321 322 for (int i=0; i<ca.exception_table_length; i++) 325 { 326 BasicBlock bb = (BasicBlock)h2bb.get( 327 ca.exception_table[i].handler_inst); 328 if ( bb == null ) 329 { 330 G.v().out.println("Warning: No basic block found for" + 331 " start of exception handler code."); 332 } 333 else 334 { 335 bb.beginException = true; 336 ca.exception_table[i].b = bb; 337 } 338 } 339 } 340 341 345 private static Instruction buildBasicBlock(Instruction head) 346 { 347 Instruction insn, next; 348 insn = head; 349 next = insn.next; 350 351 if (next == null) 352 return insn; 353 354 do 355 { 356 if (insn.branches || next.labelled) 357 break; 358 else 359 { 360 insn = next; 361 next = insn.next; 362 } 363 } while (next != null); 364 365 return insn; 366 } 367 368 371 private Set getReachableInsns(Instruction from, Instruction to) 372 { 373 Code_attribute codeAttribute = method.locate_code_attribute(); 374 375 376 Set reachableinsns = new HashSet(); 377 LinkedList tovisit = new LinkedList(); 378 379 reachableinsns.add(from); 380 tovisit.add(from); 381 382 while (!tovisit.isEmpty()) 383 { 384 Instruction insn = (Instruction)tovisit.removeFirst(); 385 386 if (insn == to) 387 continue; 388 389 Instruction[] bps = null; 390 if (insn.branches) 391 { 392 bps = insn.branchpoints(insn.next); 393 } 394 else 395 { 396 bps = new Instruction[1]; 397 bps[0] = insn.next; 398 } 399 400 if (bps != null) 401 { 402 for (int i=0; i<bps.length; i++) 403 { 404 Instruction bp = bps[i]; 405 406 if (bp != null 407 && !reachableinsns.contains(bp)) 408 { 409 reachableinsns.add(bp); 410 tovisit.add(bp); 411 } 412 } 413 } 414 } 415 416 return reachableinsns; 417 } 418 419 420 Map jsr2astore = new HashMap(); 421 Map astore2ret = new HashMap(); 422 423 LinkedList jsrorder = new LinkedList(); 424 425 427 private boolean eliminateJsrRets() 428 { 429 Instruction insn = this.sentinel; 430 431 while (insn.next != null) { 433 insn = insn.next; 434 } 435 this.lastInstruction = insn; 436 437 HashMap todoBlocks = new HashMap(); 438 todoBlocks.put(this.sentinel.next, this.lastInstruction); 439 LinkedList todoList = new LinkedList(); 440 todoList.add(this.sentinel.next); 441 442 while (!todoList.isEmpty()) { 443 Instruction firstInsn = (Instruction)todoList.removeFirst(); 444 Instruction lastInsn = (Instruction)todoBlocks.get(firstInsn); 445 446 jsrorder.clear(); 447 jsr2astore.clear(); 448 astore2ret.clear(); 449 450 if (findOutmostJsrs(firstInsn, lastInsn)) { 451 HashMap newblocks = inliningJsrTargets(); 452 todoBlocks.putAll(newblocks); 453 todoList.addAll(newblocks.keySet()); 454 } 455 } 456 457 458 { 459 method.instructions = this.sentinel.next; 460 461 adjustExceptionTable(); 462 adjustLineNumberTable(); 463 adjustBranchTargets(); 464 } 465 466 470 return true; 471 } 472 473 private boolean findOutmostJsrs(Instruction start, Instruction end) { 480 HashSet innerJsrs = new HashSet(); 482 boolean unusual = false; 483 484 Instruction insn = start; 485 do { 486 if (insn instanceof Instruction_Jsr 487 || insn instanceof Instruction_Jsr_w) 488 { 489 if (innerJsrs.contains(insn)) { 490 insn = insn.next; 492 continue; 493 } 494 495 Instruction astore = ((Instruction_branch)insn).target; 496 if (! (astore instanceof Interface_Astore)) 497 { 498 unusual = true; 499 break; 500 } 501 502 Instruction ret = findMatchingRet(astore, insn, innerJsrs); 503 504 511 512 jsrorder.addLast(insn); 513 jsr2astore.put(insn, astore); 514 astore2ret.put(astore, ret); 515 } 516 517 insn = insn.next; 518 519 } while (insn != end.next); 520 521 if (unusual) 522 { 523 G.v().out.println("Sorry, I cannot handle this method."); 524 return false; 525 } 526 527 return true; 528 } 529 530 private Instruction findMatchingRet(Instruction astore, 531 Instruction jsr, 532 HashSet innerJsrs) 533 { 534 int astorenum = ((Interface_Astore)astore).getLocalNumber(); 535 536 Instruction insn = astore.next; 537 while (insn != null) 538 { 539 if (insn instanceof Instruction_Ret 540 || insn instanceof Instruction_Ret_w) 541 { 542 int retnum = ((Interface_OneIntArg)insn).getIntArg(); 543 if (astorenum == retnum) 544 return insn; 545 } 546 else 547 548 if (insn instanceof Instruction_Jsr 549 || insn instanceof Instruction_Jsr_w) 550 { 551 innerJsrs.add(insn); 552 } 553 554 insn = insn.next; 555 } 556 557 return null; 558 } 559 560 private HashMap inliningJsrTargets() 563 { 564 574 HashMap newblocks = new HashMap(); 575 576 while (!jsrorder.isEmpty()) 577 { 578 Instruction jsr = (Instruction)jsrorder.removeFirst(); 579 Instruction astore = (Instruction)jsr2astore.get(jsr); 580 581 Instruction ret = (Instruction)astore2ret.get(astore); 582 583 Instruction newhead = makeCopyOf(astore, ret, jsr.next); 585 586 Instruction_Goto togo = new Instruction_Goto(); 590 togo.target = newhead; 591 newhead.labelled = true; 592 togo.label = jsr.label; 593 togo.labelled = jsr.labelled; 594 togo.prev = jsr.prev; 595 togo.next = jsr.next; 596 togo.prev.next = togo; 597 togo.next.prev = togo; 598 599 replacedInsns.put(jsr, togo); 600 601 if (ret != null) { 603 newblocks.put(newhead, this.lastInstruction); 604 } 605 } 606 607 return newblocks; 608 } 609 610 613 private Instruction makeCopyOf(Instruction astore, 614 Instruction ret, 615 Instruction target) 616 { 617 if (ret == null) { 619 return astore.next; 620 } 621 622 Instruction last = this.lastInstruction; 623 Instruction headbefore = last; 624 625 int curlabel = this.lastInstruction.label; 626 627 HashMap insnmap = new HashMap(); 629 Instruction insn = astore.next; 630 631 while (insn != ret && insn != null) 632 { 633 try { 634 Instruction newone = (Instruction)insn.clone(); 635 636 newone.label = ++curlabel; 637 newone.prev = last; 638 last.next = newone; 639 last = newone; 640 641 insnmap.put(insn, newone); 642 } catch (CloneNotSupportedException e) 643 { 644 G.v().out.println("Error !"); 645 } 646 insn = insn.next; 647 } 648 649 Instruction_Goto togo = new Instruction_Goto(); 651 togo.target = target; 652 target.labelled = true; 653 togo.label = ++curlabel; 654 last.next = togo; 655 togo.prev = last; 656 last = togo; 657 658 this.lastInstruction = last; 659 660 insnmap.put(astore, headbefore.next); 662 insnmap.put(ret, togo); 663 664 insn = headbefore.next; 668 while (insn != last) 669 { 670 if (insn instanceof Instruction_branch) 671 { 672 Instruction oldtgt = ((Instruction_branch)insn).target; 673 Instruction newtgt = (Instruction)insnmap.get(oldtgt); 674 if (newtgt != null) 675 { 676 ((Instruction_branch)insn).target = newtgt; 677 newtgt.labelled = true; 678 } 679 } 680 else 681 if (insn instanceof Instruction_Lookupswitch) 682 { 683 Instruction_Lookupswitch switchinsn = 684 (Instruction_Lookupswitch)insn; 685 686 Instruction newdefault = (Instruction)insnmap.get(switchinsn.default_inst); 687 if (newdefault != null) 688 { 689 switchinsn.default_inst = newdefault; 690 newdefault.labelled = true; 691 } 692 693 for (int i=0; i<switchinsn.match_insts.length; i++) 694 { 695 Instruction newtgt = (Instruction)insnmap.get(switchinsn.match_insts[i]); 696 if (newtgt != null) 697 { 698 switchinsn.match_insts[i] = newtgt; 699 newtgt.labelled = true; 700 } 701 } 702 } 703 else 704 if (insn instanceof Instruction_Tableswitch) 705 { 706 Instruction_Tableswitch switchinsn = 707 (Instruction_Tableswitch)insn; 708 709 Instruction newdefault = (Instruction)insnmap.get(switchinsn.default_inst); 710 if (newdefault != null) 711 { 712 switchinsn.default_inst = newdefault; 713 newdefault.labelled = true; 714 } 715 716 for (int i=0; i<switchinsn.jump_insts.length; i++) 717 { 718 Instruction newtgt = (Instruction)insnmap.get(switchinsn.jump_insts[i]); 719 if (newtgt != null) 720 { 721 switchinsn.jump_insts[i] = newtgt; 722 newtgt.labelled = true; 723 } 724 } 725 } 726 727 insn = insn.next; 728 } 729 730 { 734 Code_attribute ca = method.locate_code_attribute(); 735 736 LinkedList newentries = new LinkedList(); 737 738 int orig_start_of_subr = astore.next.originalIndex; int orig_end_of_subr = ret.originalIndex; 741 for (int i=0; i<ca.exception_table_length; i++) 742 { 743 exception_table_entry etentry = 744 ca.exception_table[i]; 745 746 int orig_start_of_trap = etentry.start_pc; int orig_end_of_trap = etentry.end_pc; if ( orig_start_of_trap < orig_end_of_subr && 749 orig_end_of_trap > orig_start_of_subr) { 750 exception_table_entry newone = 752 new exception_table_entry(); 753 if (orig_start_of_trap <= orig_start_of_subr) { 754 newone.start_inst = headbefore.next; 755 } else { 756 newone.start_inst = (Instruction)insnmap.get(etentry.start_inst); 757 } 758 if (orig_end_of_trap > orig_end_of_subr) { 759 newone.end_inst = null; } else { 764 newone.end_inst = (Instruction)insnmap.get(etentry.end_inst); 765 } 766 767 newone.handler_inst = (Instruction)insnmap.get(etentry.handler_inst); 768 if (newone.handler_inst == null) 769 newone.handler_inst = etentry.handler_inst; 770 771 775 newentries.add(newone); 776 } 777 if (etentry.end_inst == null) { 782 etentry.end_inst = headbefore.next; 783 } 784 } 785 786 if (newentries.size() > 0) 787 { 788 ca.exception_table_length += newentries.size(); 789 exception_table_entry[] newtable = new exception_table_entry[ca.exception_table_length]; 790 System.arraycopy(ca.exception_table, 0, newtable, 0, ca.exception_table.length); 791 for (int i=0, j=ca.exception_table.length; i<newentries.size(); i++, j++) 792 { 793 newtable[j] = (exception_table_entry)newentries.get(i); 794 } 795 796 ca.exception_table = newtable; 797 } 798 } 799 800 return headbefore.next; 801 } 802 803 private void pruneExceptionTable() { 804 HashSet invalidInsns = new HashSet(); 805 Instruction insn = this.sentinel.next; 806 do { 807 if (insn instanceof Instruction_Jsr 808 || insn instanceof Instruction_Jsr_w) { 809 Instruction astore = ((Instruction_branch)insn).target; 810 int astorenum = ((Interface_Astore)astore).getLocalNumber(); 811 Instruction ret = astore.next; 812 do { 813 invalidInsns.add(ret); 814 if (ret instanceof Instruction_Ret 815 || ret instanceof Instruction_Ret_w) { 816 int retnum = ((Interface_OneIntArg)ret).getIntArg(); 817 if (astorenum == retnum) { 818 insn = ret; 819 break; 820 } 821 } 822 ret = ret.next; 823 } while (true); 824 } 825 insn = insn.next; 826 } while (insn != null); 827 828 Iterator it = invalidInsns.iterator(); 829 while (it.hasNext()) { 830 G.v().out.println(it.next()); 831 } 832 833 LinkedList validEntries = new LinkedList(); 835 836 Code_attribute codeAttribute = method.locate_code_attribute(); 837 for(int i = 0; i < codeAttribute.exception_table_length; i++) 838 { 839 exception_table_entry entry = codeAttribute.exception_table[i]; 840 841 if (!invalidInsns.contains(entry.start_inst)) { 842 validEntries.add(entry); 843 } 844 } 845 846 if (validEntries.size() != codeAttribute.exception_table_length) { 847 exception_table_entry newtable[] = 848 new exception_table_entry[validEntries.size()]; 849 for (int i=0; i<newtable.length; i++) { 850 newtable[i] = 851 (exception_table_entry)validEntries.get(i); 852 } 853 codeAttribute.exception_table = newtable; 854 codeAttribute.exception_table_length = newtable.length; 855 } 856 } 857 858 859 private Hashtable replacedInsns = new Hashtable(); 860 private void dumpReplacedInsns() 861 { 862 G.v().out.println("replaced table:"); 863 Set keys = replacedInsns.keySet(); 864 Iterator keyIt = keys.iterator(); 865 while (keyIt.hasNext()) 866 { 867 Object key = keyIt.next(); 868 Object value = replacedInsns.get(key); 869 G.v().out.println(key + " ==> "+ value); 870 } 871 } 872 873 874 private void adjustBranchTargets() 875 { 876 Instruction insn = this.sentinel.next; 877 while (insn != null) 878 { 879 if (insn instanceof Instruction_branch) 880 { 881 Instruction_branch binsn = (Instruction_branch)insn; 882 Instruction newtgt = (Instruction)replacedInsns.get(binsn.target); 883 if (newtgt != null) 884 { 885 binsn.target = newtgt; 886 newtgt.labelled = true; 887 } 888 } 889 else 890 if (insn instanceof Instruction_Lookupswitch) 891 { 892 Instruction_Lookupswitch switchinsn = 893 (Instruction_Lookupswitch)insn; 894 895 Instruction newdefault = 896 (Instruction)replacedInsns.get(switchinsn.default_inst); 897 if (newdefault != null) 898 { 899 switchinsn.default_inst = newdefault; 900 newdefault.labelled = true; 901 } 902 903 for (int i=0; i<switchinsn.npairs; i++) 904 { 905 Instruction newtgt = 906 (Instruction)replacedInsns.get(switchinsn.match_insts[i]); 907 if (newtgt != null) 908 { 909 switchinsn.match_insts[i] = newtgt; 910 newtgt.labelled = true; 911 } 912 } 913 } 914 else 915 if (insn instanceof Instruction_Tableswitch) 916 { 917 Instruction_Tableswitch switchinsn = 918 (Instruction_Tableswitch)insn; 919 920 Instruction newdefault = (Instruction)replacedInsns.get(switchinsn.default_inst); 921 if (newdefault != null) 922 { 923 switchinsn.default_inst = newdefault; 924 newdefault.labelled = true; 925 } 926 927 for (int i=0; i<=switchinsn.high-switchinsn.low; i++) 928 { 929 Instruction newtgt = 930 (Instruction)replacedInsns.get(switchinsn.jump_insts[i]); 931 if (newtgt != null) 932 { 933 switchinsn.jump_insts[i] = newtgt; 934 newtgt.labelled = true; 935 } 936 } 937 } 938 939 insn = insn.next; 940 } 941 } 942 943 944 private void adjustExceptionTable() 945 { 946 Code_attribute codeAttribute = method.locate_code_attribute(); 947 948 for(int i = 0; i < codeAttribute.exception_table_length; i++) 949 { 950 exception_table_entry entry = codeAttribute.exception_table[i]; 951 952 Instruction oldinsn = entry.start_inst; 953 Instruction newinsn = (Instruction)replacedInsns.get(oldinsn); 954 if (newinsn != null) 955 entry.start_inst = newinsn; 956 957 oldinsn = entry.end_inst; 958 if (entry.end_inst != null) 959 { 960 newinsn = (Instruction)replacedInsns.get(oldinsn); 961 if (newinsn != null) 962 entry.end_inst = newinsn; 963 } 964 965 oldinsn = entry.handler_inst; 966 newinsn = (Instruction)replacedInsns.get(oldinsn); 967 if (newinsn != null) 968 entry.handler_inst = newinsn; 969 } 970 } 971 972 private void adjustLineNumberTable() 973 { 974 if (!Options.v().keep_line_number()) 975 return; 976 if (method.code_attr == null) 977 return; 978 979 attribute_info[] attributes = method.code_attr.attributes; 980 981 for (int i=0; i<attributes.length; i++) 982 { 983 if (attributes[i] instanceof LineNumberTable_attribute) 984 { 985 LineNumberTable_attribute lntattr = 986 (LineNumberTable_attribute)attributes[i]; 987 for (int j=0; j<lntattr.line_number_table.length; j++) 988 { 989 Instruction oldinst = 990 lntattr.line_number_table[j].start_inst; 991 Instruction newinst = 992 (Instruction)replacedInsns.get(oldinst); 993 if (newinst != null) 994 lntattr.line_number_table[j].start_inst = newinst; 995 } 996 } 997 } 998 } 999 1000 1007 public Instruction reconstructInstructions() 1008 { 1009 if (cfg != null) 1010 return cfg.head; 1011 else 1012 return null; 1013 } 1014 1015 1023 public boolean jimplify(cp_info constant_pool[],int this_class, JimpleBody listBody) 1024 { 1025 Util.v().setClassNameToAbbreviation(new HashMap()); 1026 1027 Chain units = listBody.getUnits(); 1028 1029 this.listBody = listBody; 1030 this.units = units; 1031 instructionToFirstStmt = new HashMap(); 1032 instructionToLastStmt = new HashMap(); 1033 1034 jmethod = listBody.getMethod(); 1035 cm = Scene.v(); 1036 1037 1040 Set initialLocals = new ArraySet(); 1041 1042 List parameterTypes = jmethod.getParameterTypes(); 1043 1044 { 1047 Code_attribute ca = method.locate_code_attribute(); 1048 LocalVariableTable_attribute la = ca.findLocalVariableTable(); 1049 LocalVariableTypeTable_attribute lt = ca.findLocalVariableTypeTable(); 1050 1051 Util.v().activeVariableTable = la; 1052 Util.v().activeVariableTypeTable = lt; 1053 1054 Util.v().activeConstantPool = constant_pool; 1055 1056 Type thisType = RefType.v(jmethod.getDeclaringClass().getName()); 1057 boolean isStatic = Modifier.isStatic(jmethod.getModifiers()); 1058 1059 int currentLocalIndex = 0; 1060 1061 { 1063 if(!isStatic) 1064 { 1065 String name; 1066 1067 if(!Util.v().useFaithfulNaming || la == null) 1068 name = "l0"; 1069 else 1070 { 1071 name = la.getLocalVariableName(constant_pool, currentLocalIndex); 1072 if (!Util.v().isValidJimpleName(name)) 1073 name = "l0"; 1074 } 1075 1076 Local local = Jimple.v().newLocal(name, UnknownType.v()); 1077 1078 listBody.getLocals().add(local); 1079 1080 currentLocalIndex++; 1081 1082 units.add(Jimple.v().newIdentityStmt(local, Jimple.v().newThisRef(jmethod.getDeclaringClass().getType()))); 1083 } 1084 } 1085 1086 { 1088 Iterator typeIt = parameterTypes.iterator(); 1089 int argCount = 0; 1090 1091 while(typeIt.hasNext()) 1092 { 1093 String name; 1094 Type type = (Type) typeIt.next(); 1095 1096 if(!Util.v().useFaithfulNaming || la == null) 1097 name = "l" + currentLocalIndex; 1098 else 1099 { 1100 name = la.getLocalVariableName(constant_pool, currentLocalIndex); 1101 if (!Util.v().isValidJimpleName(name)) 1102 name = "l" + currentLocalIndex; 1103 } 1104 1105 Local local = Jimple.v().newLocal(name, UnknownType.v()); 1106 initialLocals.add(local); 1107 listBody.getLocals().add(local); 1108 1109 units.add(Jimple.v().newIdentityStmt(local, Jimple.v().newParameterRef(type, argCount))); 1110 1111 if(type.equals(DoubleType.v()) || 1112 type.equals(LongType.v())) 1113 { 1114 currentLocalIndex += 2; 1115 } 1116 else { 1117 currentLocalIndex += 1; 1118 } 1119 1120 argCount++; 1121 } 1122 } 1123 1124 Util.v().resetEasyNames(); 1125 } 1126 1127 jimplify(constant_pool,this_class); 1128 1129 return true; 1130 } 1131 1132 private void buildInsnCFGfromBBCFG() 1133 { 1134 BasicBlock block = cfg; 1135 1136 while(block != null) 1137 { 1138 Instruction insn = block.head; 1139 while (insn != block.tail) 1140 { 1141 Instruction[] succs = new Instruction[1]; 1142 succs[0] = insn.next; 1143 insn.succs = succs; 1144 insn = insn.next; 1145 } 1146 1147 { 1148 Vector bsucc = block.succ; 1150 int size = bsucc.size(); 1151 Instruction[] succs = new Instruction[size]; 1152 1153 for(int i = 0; i<size; i++) 1154 succs[i] = ((BasicBlock)bsucc.elementAt(i)).head; 1155 insn.succs = succs; 1156 } 1157 1158 block = block.next; 1159 } 1160 } 1161 1162 private void printInsnCFG() 1163 { 1164 Instruction insn = cfg.head; 1165 while (insn != null) 1166 { 1167 G.v().out.println(insn + " --> " + makeString(insn.succs)); 1168 insn = insn.next; 1169 } 1170 } 1171 1172 private String makeString(Object [] objs) 1173 { 1174 String buf = ""; 1175 for (int i=0; i<objs.length; i++) 1176 buf += " , "+objs[i]; 1177 1178 return buf; 1179 } 1180 1181 1192 void jimplify(cp_info constant_pool[],int this_class) 1193 { 1194 Code_attribute codeAttribute = method.locate_code_attribute(); 1195 Set handlerInstructions = new ArraySet(); 1196 1197 Map handlerInstructionToException = new HashMap(); 1198 Map instructionToTypeStack; 1199 Map instructionToPostTypeStack; 1200 1201 { 1202 buildInsnCFGfromBBCFG(); 1204 1205 { 1207 for(int i = 0; i < codeAttribute.exception_table_length; i++) 1208 { 1209 Instruction startIns = codeAttribute.exception_table[i].start_inst; 1210 Instruction endIns = codeAttribute.exception_table[i].end_inst; 1211 Instruction handlerIns = codeAttribute.exception_table[i].handler_inst; 1212 1213 handlerInstructions.add(handlerIns); 1214 1215 { 1217 int catchType = codeAttribute.exception_table[i].catch_type; 1218 1219 SootClass exception; 1220 1221 if(catchType != 0) 1222 { 1223 CONSTANT_Class_info classinfo = (CONSTANT_Class_info) 1224 constant_pool[catchType]; 1225 1226 String name = ((CONSTANT_Utf8_info) (constant_pool[classinfo.name_index])). 1227 convert(); 1228 name = name.replace('/', '.'); 1229 1230 exception = cm.getSootClass(name); 1231 } 1232 else 1233 exception = cm.getSootClass("java.lang.Throwable"); 1234 1235 handlerInstructionToException.put(handlerIns, exception); 1236 } 1237 1238 1239 if(startIns == endIns) 1240 throw new RuntimeException ("Empty catch range for exception handler"); 1241 1242 Instruction ins = startIns; 1243 1244 for(;;) 1245 { 1246 Instruction[] succs = ins.succs; 1247 Instruction[] newsuccs = new Instruction[succs.length+1]; 1248 1249 System.arraycopy(succs, 0, newsuccs, 0, succs.length); 1250 1251 newsuccs[succs.length] = handlerIns; 1252 ins.succs = newsuccs; 1253 1254 ins = ins.next; 1255 if (ins == endIns || ins == null) 1256 break; 1257 } 1258 } 1259 } 1260 } 1261 1262 Set reachableInstructions = new HashSet(); 1263 1264 { 1266 LinkedList instructionsToVisit = new LinkedList(); 1267 1268 reachableInstructions.add(firstInstruction); 1269 instructionsToVisit.addLast(firstInstruction); 1270 1271 while( !instructionsToVisit.isEmpty()) 1272 { 1273 Instruction ins = (Instruction) instructionsToVisit.removeFirst(); 1274 1275 Instruction[] succs = ins.succs; 1276 1277 for (int i=0; i<succs.length; i++) 1278 { 1279 Instruction succ = succs[i]; 1280 1281 if(!reachableInstructions.contains(succ)) 1282 { 1283 reachableInstructions.add(succ); 1284 instructionsToVisit.addLast(succ); 1285 } 1286 } 1287 } 1288 } 1289 1290 1311 1312 { 1314 instructionToTypeStack = new HashMap(); 1315 instructionToPostTypeStack = new HashMap(); 1316 1317 Set visitedInstructions = new HashSet(); 1318 List changedInstructions = new ArrayList(); 1319 1320 TypeStack initialTypeStack; 1321 1322 { 1324 initialTypeStack = TypeStack.v(); 1325 } 1327 1328 { 1330 instructionToTypeStack.put(firstInstruction, initialTypeStack); 1331 1332 visitedInstructions.add(firstInstruction); 1333 changedInstructions.add(firstInstruction); 1334 } 1335 1336 { 1337 while(!changedInstructions.isEmpty()) 1338 { 1339 Instruction ins = (Instruction) changedInstructions.get(0); 1340 1341 changedInstructions.remove(0); 1342 1343 OutFlow ret = processFlow(ins, (TypeStack) instructionToTypeStack.get(ins), 1344 constant_pool); 1345 1346 instructionToPostTypeStack.put(ins, ret.typeStack); 1347 1348 Instruction[] successors = ins.succs; 1349 1350 for(int i = 0; i < successors.length; i++) 1351 { 1352 Instruction s = successors[i]; 1353 1354 if(!visitedInstructions.contains(s)) 1355 { 1356 1358 if(handlerInstructions.contains(s)) 1359 { 1360 TypeStack exceptionTypeStack = (TypeStack.v()).push(RefType.v( 1361 ((SootClass) handlerInstructionToException.get(s)).getName())); 1362 1363 instructionToTypeStack.put(s, exceptionTypeStack); 1364 } 1365 else { 1366 instructionToTypeStack.put(s, ret.typeStack); 1367 } 1368 1369 visitedInstructions.add(s); 1370 changedInstructions.add(s); 1371 1372 } 1374 else { 1375 1377 TypeStack newTypeStack, 1378 oldTypeStack = (TypeStack) instructionToTypeStack.get(s); 1379 1380 if(handlerInstructions.contains(s)) 1381 { 1382 1385 TypeStack exceptionTypeStack = (TypeStack.v()).push(RefType.v( 1386 ((SootClass) handlerInstructionToException.get(s)).getName())); 1387 1388 newTypeStack = exceptionTypeStack; 1389 } 1390 else 1391 { 1392 try { 1393 newTypeStack = ret.typeStack.merge(oldTypeStack); 1394 } catch (RuntimeException re) 1395 { 1396 G.v().out.println("Considering "+s); 1397 throw re; 1398 } 1399 } 1400 if(!newTypeStack.equals(oldTypeStack)) 1401 { 1402 changedInstructions.add(s); 1403 } 1405 1406 instructionToTypeStack.put(s, newTypeStack); 1407 } 1408 } 1409 } 1410 } 1411 } 1412 1413 { 1415 Instruction ins = firstInstruction; 1416 1417 1419 while(ins != null) 1420 { 1421 TypeStack typeStack = (TypeStack) instructionToTypeStack.get(ins); 1422 1434 1435 ins = ins.next; 1436 1441 1442 } 1443 } 1444 1445 1446 1448 { 1450 BasicBlock b = cfg; 1451 1452 while(b != null) 1453 { 1454 Instruction ins = b.head; 1455 b.statements = new ArrayList(); 1456 1457 List blockStatements = b.statements; 1458 1459 for (;;) 1460 { 1461 List statementsForIns = new ArrayList(); 1462 1463 if(reachableInstructions.contains(ins)) 1464 generateJimple(ins, (TypeStack) instructionToTypeStack.get(ins), 1465 (TypeStack) instructionToPostTypeStack.get(ins), constant_pool, 1466 statementsForIns, b); 1467 else 1468 statementsForIns.add(Jimple.v().newNopStmt()); 1469 1470 if(!statementsForIns.isEmpty()) 1471 { 1472 for(int i = 0; i < statementsForIns.size(); i++) 1473 { 1474 units.add(statementsForIns.get(i)); 1475 blockStatements.add(statementsForIns.get(i)); 1476 } 1477 1478 instructionToFirstStmt.put(ins, statementsForIns.get(0)); 1479 instructionToLastStmt.put(ins, statementsForIns.get(statementsForIns.size() - 1)); 1480 } 1481 1482 if (ins == b.tail) 1483 break; 1484 1485 ins = ins.next; 1486 } 1487 1488 b = b.next; 1489 } 1490 } 1491 1492 jimpleTargetFixup(); 1494 1517 1518 { 1520 Map targetToHandler = new HashMap(); 1521 1522 for(int i = 0; i < codeAttribute.exception_table_length; i++) 1523 { 1524 Instruction startIns = 1525 codeAttribute.exception_table[i].start_inst; 1526 Instruction endIns = 1527 codeAttribute.exception_table[i].end_inst; 1528 Instruction targetIns = 1529 codeAttribute.exception_table[i].handler_inst; 1530 1531 if(!instructionToFirstStmt.containsKey(startIns) || 1532 (endIns != null && (!instructionToLastStmt.containsKey(endIns)))) 1533 { 1534 throw new RuntimeException ("Exception range does not coincide with jimple instructions"); 1535 } 1536 1537 if(!instructionToFirstStmt.containsKey(targetIns)) 1538 { 1539 throw new RuntimeException 1540 ("Exception handler does not coincide with jimple instruction"); 1541 } 1542 1543 SootClass exception; 1544 1545 { 1547 int catchType = 1548 codeAttribute.exception_table[i].catch_type; 1549 if(catchType != 0) 1550 { 1551 CONSTANT_Class_info classinfo = (CONSTANT_Class_info) 1552 constant_pool[catchType]; 1553 1554 String name = ((CONSTANT_Utf8_info) 1555 (constant_pool[classinfo.name_index])).convert(); 1556 name = name.replace('/', '.'); 1557 exception = cm.getSootClass(name); 1558 } 1559 else 1560 exception = cm.getSootClass("java.lang.Throwable"); 1561 } 1562 1563 Stmt newTarget; 1564 1565 { 1567 Stmt firstTargetStmt = 1568 (Stmt) instructionToFirstStmt.get(targetIns); 1569 1570 if(targetToHandler.containsKey(firstTargetStmt)) 1571 newTarget = 1572 (Stmt) targetToHandler.get(firstTargetStmt); 1573 else 1574 { 1575 Local local = 1576 Util.v().getLocalCreatingIfNecessary(listBody, "$stack0",UnknownType.v()); 1577 1578 newTarget = Jimple.v().newIdentityStmt(local, Jimple.v().newCaughtExceptionRef()); 1579 1580 units.insertBefore(newTarget, firstTargetStmt); 1581 targetToHandler.put(firstTargetStmt, newTarget); 1582 } 1583 } 1584 1585 { 1587 Stmt firstStmt = (Stmt)instructionToFirstStmt.get(startIns); 1588 Stmt afterEndStmt; 1589 if (endIns == null) { 1590 afterEndStmt = (Stmt) units.getLast(); 1600 } else { 1601 afterEndStmt = (Stmt) instructionToLastStmt.get(endIns); 1602 IdentityStmt catchStart = 1603 (IdentityStmt) targetToHandler.get(afterEndStmt); 1604 if (catchStart != null) { 1606 if (catchStart != units.getPredOf(afterEndStmt)) { 1611 throw new IllegalStateException ("Assertion failure: catchStart != pred of afterEndStmt"); 1612 } 1613 afterEndStmt = catchStart; 1614 } 1615 } 1616 1617 Trap trap = Jimple.v().newTrap(exception, 1618 firstStmt, 1619 afterEndStmt, 1620 newTarget); 1621 listBody.getTraps().add(trap); 1622 } 1623 } 1624 } 1625 1626 1627 if (Options.v().keep_line_number()) 1628 { 1629 HashMap stmtstags = new HashMap(); 1630 LinkedList startstmts = new LinkedList(); 1631 1632 attribute_info[] attrs = codeAttribute.attributes; 1633 for (int i=0; i<attrs.length; i++) 1634 { 1635 if (attrs[i] instanceof LineNumberTable_attribute) 1636 { 1637 LineNumberTable_attribute lntattr = 1638 (LineNumberTable_attribute)attrs[i]; 1639 for (int j=0; j<lntattr.line_number_table.length; j++) 1640 { 1641 Stmt start_stmt = (Stmt)instructionToFirstStmt.get( 1642 lntattr.line_number_table[j].start_inst); 1643 1644 if (start_stmt != null) 1645 { 1646 LineNumberTag lntag= new LineNumberTag( 1647 lntattr.line_number_table[j].line_number); 1648 stmtstags.put(start_stmt, lntag); 1649 startstmts.add(start_stmt); 1650 } 1651 } 1652 } 1653 } 1654 1655 1657 for( Iterator stmtIt = new ArrayList(stmtstags.keySet()).iterator(); stmtIt.hasNext(); ) { 1658 final Stmt stmt = (Stmt) stmtIt.next(); 1659 Stmt pred = stmt; 1660 Tag tag = (Tag) stmtstags.get(stmt); 1661 while(true) { 1662 pred = (Stmt)units.getPredOf(pred); 1663 if( pred == null ) break; 1664 if(!(pred instanceof IdentityStmt)) break; 1665 stmtstags.put(pred, tag); 1666 pred.addTag(tag); 1667 } 1668 } 1669 1670 1671 for (int i=0; i<startstmts.size(); i++) 1672 { 1673 Stmt stmt = (Stmt)startstmts.get(i); 1674 Tag tag = (Tag)stmtstags.get(stmt); 1675 1676 stmt.addTag(tag); 1677 1678 stmt = (Stmt)units.getSuccOf(stmt); 1679 while (stmt != null 1680 && !stmtstags.containsKey(stmt)) 1681 { 1682 stmt.addTag(tag); 1683 stmt = (Stmt)units.getSuccOf(stmt); 1684 } 1685 } 1686 } 1687 } 1688 1689 private Type byteCodeTypeOf(Type type) 1690 { 1691 if(type.equals(ShortType.v()) || 1692 type.equals(CharType.v()) || 1693 type.equals(ByteType.v()) || 1694 type.equals(BooleanType.v())) 1695 { 1696 return IntType.v(); 1697 } 1698 else 1699 return type; 1700 } 1701 1702 OutFlow processFlow(Instruction ins, TypeStack typeStack, 1703 cp_info[] constant_pool) 1704 { 1705 int x; 1706 x = ((int)(ins.code))&0xff; 1707 1708 switch(x) 1709 { 1710 case ByteCode.BIPUSH: 1711 typeStack = typeStack.push(IntType.v()); 1712 break; 1713 1714 case ByteCode.SIPUSH: 1715 typeStack = typeStack.push(IntType.v()); 1716 break; 1717 1718 case ByteCode.LDC1: 1719 return processCPEntry(constant_pool, 1720 ((Instruction_Ldc1)ins).arg_b, typeStack, jmethod); 1721 1722 case ByteCode.LDC2: 1723 case ByteCode.LDC2W: 1724 return processCPEntry(constant_pool, 1725 ((Instruction_intindex)ins).arg_i, typeStack, jmethod); 1726 1727 case ByteCode.ACONST_NULL: 1728 typeStack = typeStack.push(RefType.v("java.lang.Object")); 1729 break; 1730 1731 case ByteCode.ICONST_M1: 1732 case ByteCode.ICONST_0: 1733 case ByteCode.ICONST_1: 1734 case ByteCode.ICONST_2: 1735 case ByteCode.ICONST_3: 1736 case ByteCode.ICONST_4: 1737 case ByteCode.ICONST_5: 1738 typeStack = typeStack.push(IntType.v()); 1739 break; 1740 case ByteCode.LCONST_0: 1741 case ByteCode.LCONST_1: 1742 typeStack = typeStack.push(LongType.v()); 1743 typeStack = typeStack.push(Long2ndHalfType.v()); 1744 break; 1745 case ByteCode.FCONST_0: 1746 case ByteCode.FCONST_1: 1747 case ByteCode.FCONST_2: 1748 typeStack = typeStack.push(FloatType.v()); 1749 break; 1750 case ByteCode.DCONST_0: 1751 case ByteCode.DCONST_1: 1752 typeStack = typeStack.push(DoubleType.v()); 1753 typeStack = typeStack.push(Double2ndHalfType.v()); 1754 break; 1755 case ByteCode.ILOAD: 1756 typeStack = typeStack.push(IntType.v()); 1757 break; 1758 1759 case ByteCode.FLOAD: 1760 typeStack = typeStack.push(FloatType.v()); 1761 break; 1762 1763 case ByteCode.ALOAD: 1764 typeStack = typeStack.push(RefType.v("java.lang.Object")); 1765 break; 1767 1768 case ByteCode.DLOAD: 1769 typeStack = typeStack.push(DoubleType.v()); 1770 typeStack = typeStack.push(Double2ndHalfType.v()); 1771 break; 1772 1773 case ByteCode.LLOAD: 1774 typeStack = typeStack.push(LongType.v()); 1775 typeStack = typeStack.push(Long2ndHalfType.v()); 1776 break; 1777 1778 case ByteCode.ILOAD_0: 1779 case ByteCode.ILOAD_1: 1780 case ByteCode.ILOAD_2: 1781 case ByteCode.ILOAD_3: 1782 typeStack = typeStack.push(IntType.v()); 1783 break; 1784 1785 case ByteCode.FLOAD_0: 1786 case ByteCode.FLOAD_1: 1787 case ByteCode.FLOAD_2: 1788 case ByteCode.FLOAD_3: 1789 typeStack = typeStack.push(FloatType.v()); 1790 break; 1791 1792 case ByteCode.ALOAD_0: 1793 case ByteCode.ALOAD_1: 1794 case ByteCode.ALOAD_2: 1795 case ByteCode.ALOAD_3: 1796 typeStack = typeStack.push(RefType.v("java.lang.Object")); 1797 break; 1799 1800 case ByteCode.LLOAD_0: 1801 case ByteCode.LLOAD_1: 1802 case ByteCode.LLOAD_2: 1803 case ByteCode.LLOAD_3: 1804 typeStack = typeStack.push(LongType.v()); 1805 typeStack = typeStack.push(Long2ndHalfType.v()); 1806 break; 1807 1808 case ByteCode.DLOAD_0: 1809 case ByteCode.DLOAD_1: 1810 case ByteCode.DLOAD_2: 1811 case ByteCode.DLOAD_3: 1812 typeStack = typeStack.push(DoubleType.v()); 1813 typeStack = typeStack.push(Double2ndHalfType.v()); 1814 break; 1815 1816 case ByteCode.ISTORE: 1817 typeStack = popSafe(typeStack, IntType.v()); 1818 break; 1819 1820 case ByteCode.FSTORE: 1821 typeStack = popSafe(typeStack, FloatType.v()); 1822 break; 1823 1824 case ByteCode.ASTORE: 1825 typeStack = typeStack.pop(); 1826 break; 1827 1828 case ByteCode.LSTORE: 1829 typeStack = popSafe(typeStack, Long2ndHalfType.v()); 1830 typeStack = popSafe(typeStack, LongType.v()); 1831 break; 1832 1833 case ByteCode.DSTORE: 1834 typeStack = popSafe(typeStack, Double2ndHalfType.v()); 1835 typeStack = popSafe(typeStack, DoubleType.v()); 1836 break; 1837 1838 case ByteCode.ISTORE_0: 1839 case ByteCode.ISTORE_1: 1840 case ByteCode.ISTORE_2: 1841 case ByteCode.ISTORE_3: 1842 typeStack = popSafe(typeStack, IntType.v()); 1843 break; 1844 1845 case ByteCode.FSTORE_0: 1846 case ByteCode.FSTORE_1: 1847 case ByteCode.FSTORE_2: 1848 case ByteCode.FSTORE_3: 1849 typeStack = popSafe(typeStack, FloatType.v()); 1850 break; 1851 1852 case ByteCode.ASTORE_0: 1853 case ByteCode.ASTORE_1: 1854 case ByteCode.ASTORE_2: 1855 case ByteCode.ASTORE_3: 1856 if(!(typeStack.top() instanceof StmtAddressType) && 1857 !(typeStack.top() instanceof RefType) && 1858 !(typeStack.top() instanceof ArrayType)) 1859 { 1860 throw new RuntimeException ("Astore failed, invalid stack type: " + typeStack.top()); 1861 } 1862 1863 typeStack = typeStack.pop(); 1864 break; 1865 1866 case ByteCode.LSTORE_0: 1867 case ByteCode.LSTORE_1: 1868 case ByteCode.LSTORE_2: 1869 case ByteCode.LSTORE_3: 1870 typeStack = popSafe(typeStack, Long2ndHalfType.v()); 1871 typeStack = popSafe(typeStack, LongType.v()); 1872 break; 1873 1874 case ByteCode.DSTORE_0: 1875 case ByteCode.DSTORE_1: 1876 case ByteCode.DSTORE_2: 1877 case ByteCode.DSTORE_3: 1878 typeStack = popSafe(typeStack, Double2ndHalfType.v()); 1879 typeStack = popSafe(typeStack, DoubleType.v()); 1880 break; 1881 1882 case ByteCode.IINC: 1883 break; 1884 1885 case ByteCode.WIDE: 1886 throw new RuntimeException ("Wide instruction should not be encountered"); 1887 1889 case ByteCode.NEWARRAY: 1890 { 1891 typeStack = popSafe(typeStack, IntType.v()); 1892 Type baseType = (Type) jimpleTypeOfAtype(((Instruction_Newarray)ins).atype); 1893 1894 typeStack = typeStack.push(ArrayType.v(baseType, 1)); 1895 break; 1896 } 1897 1898 case ByteCode.ANEWARRAY: 1899 { 1900 CONSTANT_Class_info c = (CONSTANT_Class_info) constant_pool[ 1901 ((Instruction_Anewarray)ins).arg_i]; 1902 1903 String name = ((CONSTANT_Utf8_info) (constant_pool[c.name_index])).convert(); 1904 name = name.replace('/', '.'); 1905 1906 Type baseType; 1907 1908 if(name.startsWith("[")) { 1909 String baseName = getClassName(constant_pool, ((Instruction_Anewarray)ins).arg_i); 1910 baseType = Util.v().jimpleTypeOfFieldDescriptor(baseName); 1911 } else { 1912 baseType = RefType.v(name); 1913 } 1914 1915 typeStack = popSafe(typeStack, IntType.v()); 1916 typeStack = typeStack.push(baseType.makeArrayType()); 1917 break; 1918 } 1919 1920 case ByteCode.MULTIANEWARRAY: 1921 { 1922 int bdims = (int)(((Instruction_Multianewarray)ins).dims); 1923 1924 1925 CONSTANT_Class_info c = (CONSTANT_Class_info) constant_pool[ 1926 ((Instruction_Multianewarray)ins).arg_i]; 1927 1928 String arrayDescriptor = ((CONSTANT_Utf8_info) (constant_pool[c.name_index])).convert(); 1929 1930 ArrayType arrayType = (ArrayType) 1931 Util.v().jimpleTypeOfFieldDescriptor(arrayDescriptor); 1932 1933 for (int j=0;j<bdims;j++) 1934 typeStack = popSafe(typeStack, IntType.v()); 1935 1936 typeStack = typeStack.push(arrayType); 1937 break; 1938 } 1939 1940 case ByteCode.ARRAYLENGTH: 1941 typeStack = popSafeRefType(typeStack); 1942 typeStack = typeStack.push(IntType.v()); 1943 break; 1944 1945 case ByteCode.IALOAD: 1946 case ByteCode.BALOAD: 1947 case ByteCode.CALOAD: 1948 case ByteCode.SALOAD: 1949 typeStack = popSafe(typeStack, IntType.v()); 1950 typeStack = popSafeRefType(typeStack); 1951 typeStack = typeStack.push(IntType.v()); 1952 break; 1953 case ByteCode.FALOAD: 1954 typeStack = popSafe(typeStack, FloatType.v()); 1955 typeStack = popSafeRefType(typeStack); 1956 typeStack = typeStack.push(FloatType.v()); 1957 break; 1958 1959 case ByteCode.AALOAD: 1960 { 1961 1962 typeStack = popSafe(typeStack, IntType.v()); 1963 1964 if(typeStack.top() instanceof ArrayType) 1965 { 1966 ArrayType arrayType = (ArrayType) typeStack.top(); 1967 typeStack = popSafeRefType(typeStack); 1968 1969 if(arrayType.numDimensions == 1) 1970 typeStack = typeStack.push(arrayType.baseType); 1971 else 1972 typeStack = typeStack.push(ArrayType.v(arrayType.baseType, arrayType.numDimensions - 1)); 1973 } 1974 else { 1975 1977 typeStack = popSafeRefType(typeStack); 1978 1979 typeStack = typeStack.push(RefType.v("java.lang.Object")); 1980 } 1981 1982 break; 1983 } 1984 case ByteCode.LALOAD: 1985 typeStack = popSafe(typeStack, IntType.v()); 1986 typeStack = popSafeRefType(typeStack); 1987 typeStack = typeStack.push(LongType.v()); 1988 typeStack = typeStack.push(Long2ndHalfType.v()); 1989 break; 1990 1991 case ByteCode.DALOAD: 1992 typeStack = popSafe(typeStack, IntType.v()); 1993 typeStack = popSafeRefType(typeStack); 1994 typeStack = typeStack.push(DoubleType.v()); 1995 typeStack = typeStack.push(Double2ndHalfType.v()); 1996 break; 1997 1998 case ByteCode.IASTORE: 1999 case ByteCode.BASTORE: 2000 case ByteCode.CASTORE: 2001 case ByteCode.SASTORE: 2002 typeStack = popSafe(typeStack, IntType.v()); 2003 typeStack = popSafe(typeStack, IntType.v()); 2004 typeStack = popSafeRefType(typeStack); 2005 break; 2006 2007 case ByteCode.AASTORE: 2008 typeStack = popSafeRefType(typeStack); 2009 typeStack = popSafe(typeStack, IntType.v()); 2010 typeStack = popSafeRefType(typeStack); 2011 break; 2012 2013 case ByteCode.FASTORE: 2014 typeStack = popSafe(typeStack, FloatType.v()); 2015 typeStack = popSafe(typeStack, IntType.v()); 2016 typeStack = popSafeRefType(typeStack); 2017 break; 2018 2019 case ByteCode.LASTORE: 2020 typeStack = popSafe(typeStack, Long2ndHalfType.v()); 2021 typeStack = popSafe(typeStack, LongType.v()); 2022 typeStack = popSafe(typeStack, IntType.v()); 2023 typeStack = popSafeRefType(typeStack); 2024 break; 2025 2026 case ByteCode.DASTORE: 2027 typeStack = popSafe(typeStack, Double2ndHalfType.v()); 2028 typeStack = popSafe(typeStack, DoubleType.v()); 2029 typeStack = popSafe(typeStack, IntType.v()); 2030 typeStack = popSafeRefType(typeStack); 2031 break; 2032 2033 case ByteCode.NOP: 2034 break; 2035 2036 case ByteCode.POP: 2037 typeStack = typeStack.pop(); 2038 break; 2039 2040 case ByteCode.POP2: 2041 typeStack = typeStack.pop(); 2042 typeStack = typeStack.pop(); 2043 break; 2044 2045 case ByteCode.DUP: 2046 typeStack = typeStack.push(typeStack.top()); 2047 break; 2048 2049 case ByteCode.DUP2: 2050 { 2051 Type topType = typeStack.get(typeStack.topIndex()), 2052 secondType = typeStack.get(typeStack.topIndex()-1); 2053 typeStack = (typeStack.push(secondType)).push(topType); 2054 break; 2055 } 2056 2057 case ByteCode.DUP_X1: 2058 { 2059 Type topType = typeStack.get(typeStack.topIndex()), 2060 secondType = typeStack.get(typeStack.topIndex()-1); 2061 2062 typeStack = typeStack.pop().pop(); 2063 2064 typeStack = typeStack.push(topType).push(secondType).push(topType); 2065 break; 2066 } 2067 2068 case ByteCode.DUP_X2: 2069 { 2070 Type topType = typeStack.get(typeStack.topIndex()), 2071 secondType = typeStack.get(typeStack.topIndex()-1), 2072 thirdType = typeStack.get(typeStack.topIndex()-2); 2073 2074 typeStack = typeStack.pop().pop().pop(); 2075 2076 typeStack = typeStack.push(topType).push(thirdType).push(secondType).push(topType); 2077 break; 2078 } 2079 2080 case ByteCode.DUP2_X1: 2081 { 2082 Type topType = typeStack.get(typeStack.topIndex()), 2083 secondType = typeStack.get(typeStack.topIndex()-1), 2084 thirdType = typeStack.get(typeStack.topIndex()-2); 2085 2086 typeStack = typeStack.pop().pop().pop(); 2087 2088 typeStack = typeStack.push(secondType).push(topType). 2089 push(thirdType).push(secondType).push(topType); 2090 break; 2091 } 2092 2093 case ByteCode.DUP2_X2: 2094 { 2095 Type topType = typeStack.get(typeStack.topIndex()), 2096 secondType = typeStack.get(typeStack.topIndex()-1), 2097 thirdType = typeStack.get(typeStack.topIndex()-2), 2098 fourthType = typeStack.get(typeStack.topIndex()-3); 2099 2100 typeStack = typeStack.pop().pop().pop().pop(); 2101 2102 typeStack = typeStack.push(secondType).push(topType). 2103 push(fourthType).push(thirdType).push(secondType).push(topType); 2104 break; 2105 } 2106 2107 case ByteCode.SWAP: 2108 { 2109 Type topType = typeStack.top(); 2110 2111 typeStack = typeStack.pop(); 2112 2113 Type secondType = typeStack.top(); 2114 2115 typeStack = typeStack.pop(); 2116 2117 typeStack = typeStack.push(topType); 2118 typeStack = typeStack.push(secondType); 2119 break; 2120 } 2121 2122 2123 case ByteCode.IADD: 2124 case ByteCode.ISUB: 2125 case ByteCode.IMUL: 2126 case ByteCode.IDIV: 2127 case ByteCode.IREM: 2128 case ByteCode.ISHL: 2129 case ByteCode.ISHR: 2130 case ByteCode.IUSHR: 2131 case ByteCode.IAND: 2132 case ByteCode.IOR: 2133 case ByteCode.IXOR: 2134 typeStack = popSafe(typeStack, IntType.v()); 2135 typeStack = popSafe(typeStack, IntType.v()); 2136 typeStack = typeStack.push(IntType.v()); 2137 break; 2138 2139 case ByteCode.LUSHR: 2140 case ByteCode.LSHR: 2141 case ByteCode.LSHL: 2142 typeStack = popSafe(typeStack, IntType.v()); 2143 typeStack = popSafe(typeStack, Long2ndHalfType.v()); 2144 typeStack = popSafe(typeStack, LongType.v()); 2145 typeStack = typeStack.push(LongType.v()); 2146 typeStack = typeStack.push(Long2ndHalfType.v()); 2147 break; 2148 2149 case ByteCode.LREM: 2150 case ByteCode.LDIV: 2151 case ByteCode.LMUL: 2152 case ByteCode.LSUB: 2153 case ByteCode.LADD: 2154 case ByteCode.LAND: 2155 case ByteCode.LOR: 2156 case ByteCode.LXOR: 2157 typeStack = popSafe(typeStack, Long2ndHalfType.v()); 2158 typeStack = popSafe(typeStack, LongType.v()); 2159 typeStack = popSafe(typeStack, Long2ndHalfType.v()); 2160 typeStack = popSafe(typeStack, LongType.v()); 2161 typeStack = typeStack.push(LongType.v()); 2162 typeStack = typeStack.push(Long2ndHalfType.v()); 2163 break; 2164 2165 case ByteCode.FREM: 2166 case ByteCode.FDIV: 2167 case ByteCode.FMUL: 2168 case ByteCode.FSUB: 2169 case ByteCode.FADD: 2170 typeStack = popSafe(typeStack, FloatType.v()); 2171 typeStack = popSafe(typeStack, FloatType.v()); 2172 typeStack = typeStack.push(FloatType.v()); 2173 break; 2174 2175 case ByteCode.DREM: 2176 case ByteCode.DDIV: 2177 case ByteCode.DMUL: 2178 case ByteCode.DSUB: 2179 case ByteCode.DADD: 2180 typeStack = popSafe(typeStack, Double2ndHalfType.v()); 2181 typeStack = popSafe(typeStack, DoubleType.v()); 2182 typeStack = popSafe(typeStack, Double2ndHalfType.v()); 2183 typeStack = popSafe(typeStack, DoubleType.v()); 2184 typeStack = typeStack.push(DoubleType.v()); 2185 typeStack = typeStack.push(Double2ndHalfType.v()); 2186 break; 2187 2188 case ByteCode.INEG: 2189 case ByteCode.LNEG: 2190 case ByteCode.FNEG: 2191 case ByteCode.DNEG: 2192 break; 2195 2196 case ByteCode.I2L: 2197 typeStack = popSafe(typeStack, IntType.v()); 2198 typeStack = typeStack.push(LongType.v()); 2199 typeStack = typeStack.push(Long2ndHalfType.v()); 2200 break; 2201 2202 case ByteCode.I2F: 2203 typeStack = popSafe(typeStack, IntType.v()); 2204 typeStack = typeStack.push(FloatType.v()); 2205 break; 2206 2207 case ByteCode.I2D: 2208 typeStack = popSafe(typeStack, IntType.v()); 2209 typeStack = typeStack.push(DoubleType.v()); 2210 typeStack = typeStack.push(Double2ndHalfType.v()); 2211 break; 2212 2213 case ByteCode.L2I: 2214 typeStack = popSafe(typeStack, Long2ndHalfType.v()); 2215 typeStack = popSafe(typeStack, LongType.v()); 2216 typeStack = typeStack.push(IntType.v()); 2217 break; 2218 2219 case ByteCode.L2F: 2220 typeStack = popSafe(typeStack, Long2ndHalfType.v()); 2221 typeStack = popSafe(typeStack, LongType.v()); 2222 typeStack = typeStack.push(FloatType.v()); 2223 break; 2224 2225 case ByteCode.L2D: 2226 typeStack = popSafe(typeStack, Long2ndHalfType.v()); 2227 typeStack = popSafe(typeStack, LongType.v()); 2228 typeStack = typeStack.push(DoubleType.v()); 2229 typeStack = typeStack.push(Double2ndHalfType.v()); 2230 break; 2231 2232 case ByteCode.F2I: 2233 typeStack = popSafe(typeStack, FloatType.v()); 2234 typeStack = typeStack.push(IntType.v()); 2235 break; 2236 2237 case ByteCode.F2L: 2238 typeStack = popSafe(typeStack, FloatType.v()); 2239 typeStack = typeStack.push(LongType.v()); 2240 typeStack = typeStack.push(Long2ndHalfType.v()); 2241 break; 2242 2243 case ByteCode.F2D: 2244 typeStack = popSafe(typeStack, FloatType.v()); 2245 typeStack = typeStack.push(DoubleType.v()); 2246 typeStack = typeStack.push(Double2ndHalfType.v()); 2247 break; 2248 2249 case ByteCode.D2I: 2250 typeStack = popSafe(typeStack, Double2ndHalfType.v()); 2251 typeStack = popSafe(typeStack, DoubleType.v()); 2252 typeStack = typeStack.push(IntType.v()); 2253 break; 2254 2255 case ByteCode.D2L: 2256 typeStack = popSafe(typeStack, Double2ndHalfType.v()); 2257 typeStack = popSafe(typeStack, DoubleType.v()); 2258 typeStack = typeStack.push(LongType.v()); 2259 typeStack = typeStack.push(Long2ndHalfType.v()); 2260 break; 2261 2262 case ByteCode.D2F: 2263 typeStack = popSafe(typeStack, Double2ndHalfType.v()); 2264 typeStack = popSafe(typeStack, DoubleType.v()); 2265 typeStack = typeStack.push(FloatType.v()); 2266 break; 2267 2268 case ByteCode.INT2BYTE: 2269 break; 2270 case ByteCode.INT2CHAR: 2271 break; 2272 case ByteCode.INT2SHORT: 2273 break; 2274 2275 case ByteCode.IFEQ: 2276 case ByteCode.IFGT: 2277 case ByteCode.IFLT: 2278 case ByteCode.IFLE: 2279 case ByteCode.IFNE: 2280 case ByteCode.IFGE: 2281 typeStack = popSafe(typeStack, IntType.v()); 2282 break; 2283 2284 case ByteCode.IFNULL: 2285 case ByteCode.IFNONNULL: 2286 typeStack = popSafeRefType(typeStack); 2287 break; 2288 2289 case ByteCode.IF_ICMPEQ: 2290 case ByteCode.IF_ICMPLT: 2291 case ByteCode.IF_ICMPLE: 2292 case ByteCode.IF_ICMPNE: 2293 case ByteCode.IF_ICMPGT: 2294 case ByteCode.IF_ICMPGE: 2295 typeStack = popSafe(typeStack, IntType.v()); 2296 typeStack = popSafe(typeStack, IntType.v()); 2297 break; 2298 2299 case ByteCode.LCMP: 2300 typeStack = popSafe(typeStack, Long2ndHalfType.v()); 2301 typeStack = popSafe(typeStack, LongType.v()); 2302 typeStack = popSafe(typeStack, Long2ndHalfType.v()); 2303 typeStack = popSafe(typeStack, LongType.v()); 2304 typeStack = typeStack.push(IntType.v()); 2305 break; 2306 2307 case ByteCode.FCMPL: 2308 case ByteCode.FCMPG: 2309 typeStack = popSafe(typeStack, FloatType.v()); 2310 typeStack = popSafe(typeStack, FloatType.v()); 2311 typeStack = typeStack.push(IntType.v()); 2312 break; 2313 2314 case ByteCode.DCMPL: 2315 case ByteCode.DCMPG: 2316 typeStack = popSafe(typeStack, Double2ndHalfType.v()); 2317 typeStack = popSafe(typeStack, DoubleType.v()); 2318 typeStack = popSafe(typeStack, Double2ndHalfType.v()); 2319 typeStack = popSafe(typeStack, DoubleType.v()); 2320 typeStack = typeStack.push(IntType.v()); 2321 break; 2322 2323 case ByteCode.IF_ACMPEQ: 2324 case ByteCode.IF_ACMPNE: 2325 typeStack = popSafeRefType(typeStack); 2326 typeStack = popSafeRefType(typeStack); 2327 break; 2328 2329 case ByteCode.GOTO: 2330 case ByteCode.GOTO_W: 2331 break; 2332 2333 case ByteCode.JSR: 2334 case ByteCode.JSR_W: 2335 typeStack = typeStack.push(StmtAddressType.v()); 2336 break; 2337 2338 case ByteCode.RET: 2339 break; 2340 2341 case ByteCode.RET_W: 2342 break; 2343 2344 case ByteCode.RETURN: 2345 break; 2346 2347 case ByteCode.IRETURN: 2348 typeStack = popSafe(typeStack, IntType.v()); 2349 break; 2350 2351 case ByteCode.FRETURN: 2352 typeStack = popSafe(typeStack, FloatType.v()); 2353 break; 2354 2355 case ByteCode.ARETURN: 2356 typeStack = popSafeRefType(typeStack); 2357 break; 2358 2359 case ByteCode.DRETURN: 2360 typeStack = popSafe(typeStack, Double2ndHalfType.v()); 2361 typeStack = popSafe(typeStack, DoubleType.v()); 2362 break; 2363 2364 case ByteCode.LRETURN: 2365 typeStack = popSafe(typeStack, Long2ndHalfType.v()); 2366 typeStack = popSafe(typeStack, LongType.v()); 2367 break; 2368 2369 case ByteCode.BREAKPOINT: 2370 break; 2371 2372 case ByteCode.TABLESWITCH: 2373 typeStack = popSafe(typeStack, IntType.v()); 2374 break; 2375 2376 case ByteCode.LOOKUPSWITCH: 2377 typeStack = popSafe(typeStack, IntType.v()); 2378 break; 2379 2380 case ByteCode.PUTFIELD: 2381 { 2382 Type type = byteCodeTypeOf(jimpleTypeOfFieldInFieldRef(cm, constant_pool, 2383 ((Instruction_Putfield)ins).arg_i)); 2384 2385 if(type.equals(DoubleType.v())) 2386 { 2387 typeStack = popSafe(typeStack, Double2ndHalfType.v()); 2388 typeStack = popSafe(typeStack, DoubleType.v()); 2389 } 2390 else if(type.equals(LongType.v())) 2391 { 2392 typeStack = popSafe(typeStack, Long2ndHalfType.v()); 2393 typeStack = popSafe(typeStack, LongType.v()); 2394 } 2395 else if(type instanceof RefType) 2396 typeStack = popSafeRefType(typeStack); 2397 else 2398 typeStack = popSafe(typeStack, type); 2399 2400 typeStack = popSafeRefType(typeStack); 2401 break; 2402 } 2403 2404 case ByteCode.GETFIELD: 2405 { 2406 Type type = byteCodeTypeOf(jimpleTypeOfFieldInFieldRef(cm, constant_pool, 2407 ((Instruction_Getfield)ins).arg_i)); 2408 2409 typeStack = popSafeRefType(typeStack); 2410 2411 if (type.equals(DoubleType.v())) 2412 { 2413 typeStack = typeStack.push(DoubleType.v()); 2414 typeStack = typeStack.push(Double2ndHalfType.v()); 2415 } 2416 else if(type.equals(LongType.v())) 2417 { 2418 typeStack = typeStack.push(LongType.v()); 2419 typeStack = typeStack.push(Long2ndHalfType.v()); 2420 } 2421 else 2422 typeStack = typeStack.push(type); 2423 break; 2424 } 2425 2426 case ByteCode.PUTSTATIC: 2427 { 2428 Type type = byteCodeTypeOf(jimpleTypeOfFieldInFieldRef(cm, constant_pool, 2429 ((Instruction_Putstatic)ins).arg_i)); 2430 2431 if(type.equals(DoubleType.v())) 2432 { 2433 typeStack = popSafe(typeStack, Double2ndHalfType.v()); 2434 typeStack = popSafe(typeStack, DoubleType.v()); 2435 } 2436 else if(type.equals(LongType.v())) 2437 { 2438 typeStack = popSafe(typeStack, Long2ndHalfType.v()); 2439 typeStack = popSafe(typeStack, LongType.v()); 2440 } 2441 else if(type instanceof RefType) 2442 typeStack = popSafeRefType(typeStack); 2443 else 2444 typeStack = popSafe(typeStack, type); 2445 2446 break; 2447 } 2448 2449 case ByteCode.GETSTATIC: 2450 { 2451 Type type = byteCodeTypeOf(jimpleTypeOfFieldInFieldRef(cm, constant_pool, 2452 ((Instruction_Getstatic)ins).arg_i)); 2453 2454 if (type.equals(DoubleType.v())) 2455 { 2456 typeStack = typeStack.push(DoubleType.v()); 2457 typeStack = typeStack.push(Double2ndHalfType.v()); 2458 } 2459 else if(type.equals(LongType.v())) 2460 { 2461 typeStack = typeStack.push(LongType.v()); 2462 typeStack = typeStack.push(Long2ndHalfType.v()); 2463 } 2464 else 2465 typeStack = typeStack.push(type); 2466 break; 2467 } 2468 2469 case ByteCode.INVOKEVIRTUAL: 2470 { 2471 Instruction_Invokevirtual iv = (Instruction_Invokevirtual)ins; 2472 int args = cp_info.countParams(constant_pool,iv.arg_i); 2473 Type returnType = byteCodeTypeOf(jimpleReturnTypeOfMethodRef(cm, 2474 constant_pool, iv.arg_i)); 2475 2476 for (int j=args-1;j>=0;j--) 2478 { 2479 if(typeStack.top().equals(Long2ndHalfType.v())) 2480 { 2481 typeStack = popSafe(typeStack, Long2ndHalfType.v()); 2482 typeStack = popSafe(typeStack, LongType.v()); 2483 2484 } 2485 else if(typeStack.top().equals(Double2ndHalfType.v())) 2486 { 2487 typeStack = popSafe(typeStack, Double2ndHalfType.v()); 2488 typeStack = popSafe(typeStack, DoubleType.v()); 2489 } 2490 else 2491 typeStack = popSafe(typeStack, typeStack.top()); 2492 } 2493 2494 typeStack = popSafeRefType(typeStack); 2495 2496 if(!returnType.equals(VoidType.v())) 2497 typeStack = smartPush(typeStack, returnType); 2498 break; 2499 } 2500 2501 case ByteCode.INVOKENONVIRTUAL: 2502 { 2503 Instruction_Invokenonvirtual iv = (Instruction_Invokenonvirtual)ins; 2504 int args = cp_info.countParams(constant_pool,iv.arg_i); 2505 Type returnType = byteCodeTypeOf(jimpleReturnTypeOfMethodRef(cm, 2506 constant_pool, iv.arg_i)); 2507 2508 for (int j=args-1;j>=0;j--) 2510 { 2511 if(typeStack.top().equals(Long2ndHalfType.v())) 2512 { 2513 typeStack = popSafe(typeStack, Long2ndHalfType.v()); 2514 typeStack = popSafe(typeStack, LongType.v()); 2515 2516 } 2517 else if(typeStack.top().equals(Double2ndHalfType.v())) 2518 { 2519 typeStack = popSafe(typeStack, Double2ndHalfType.v()); 2520 typeStack = popSafe(typeStack, DoubleType.v()); 2521 } 2522 else 2523 typeStack = popSafe(typeStack, typeStack.top()); 2524 } 2525 2526 typeStack = popSafeRefType(typeStack); 2527 2528 if(!returnType.equals(VoidType.v())) 2529 typeStack = smartPush(typeStack, returnType); 2530 break; 2531 } 2532 2533 case ByteCode.INVOKESTATIC: 2534 { 2535 Instruction_Invokestatic iv = (Instruction_Invokestatic)ins; 2536 int args = cp_info.countParams(constant_pool,iv.arg_i); 2537 Type returnType = byteCodeTypeOf(jimpleReturnTypeOfMethodRef(cm, 2538 constant_pool, iv.arg_i)); 2539 2540 for (int j=args-1;j>=0;j--) 2542 { 2543 if(typeStack.top().equals(Long2ndHalfType.v())) 2544 { 2545 typeStack = popSafe(typeStack, Long2ndHalfType.v()); 2546 typeStack = popSafe(typeStack, LongType.v()); 2547 2548 } 2549 else if(typeStack.top().equals(Double2ndHalfType.v())) 2550 { 2551 typeStack = popSafe(typeStack, Double2ndHalfType.v()); 2552 typeStack = popSafe(typeStack, DoubleType.v()); 2553 } 2554 else 2555 typeStack = popSafe(typeStack, typeStack.top()); 2556 } 2557 2558 if(!returnType.equals(VoidType.v())) 2559 typeStack = smartPush(typeStack, returnType); 2560 break; 2561 } 2562 2563 case ByteCode.INVOKEINTERFACE: 2564 { 2565 Instruction_Invokeinterface iv = (Instruction_Invokeinterface) ins; 2566 int args = cp_info.countParams(constant_pool,iv.arg_i); 2567 Type returnType = byteCodeTypeOf(jimpleReturnTypeOfInterfaceMethodRef(cm, 2568 constant_pool, iv.arg_i)); 2569 2570 for (int j=args-1;j>=0;j--) 2572 { 2573 if(typeStack.top().equals(Long2ndHalfType.v())) 2574 { 2575 typeStack = popSafe(typeStack, Long2ndHalfType.v()); 2576 typeStack = popSafe(typeStack, LongType.v()); 2577 2578 } 2579 else if(typeStack.top().equals(Double2ndHalfType.v())) 2580 { 2581 typeStack = popSafe(typeStack, Double2ndHalfType.v()); 2582 typeStack = popSafe(typeStack, DoubleType.v()); 2583 } 2584 else 2585 typeStack = popSafe(typeStack, typeStack.top()); 2586 } 2587 2588 typeStack = popSafeRefType(typeStack); 2589 2590 if(!returnType.equals(VoidType.v())) 2591 typeStack = smartPush(typeStack, returnType); 2592 break; 2593 } 2594 2595 case ByteCode.ATHROW: 2596 break; 2601 2602 case ByteCode.NEW: 2603 { 2604 Type type = RefType.v(getClassName(constant_pool, ((Instruction_New)ins).arg_i)); 2605 2606 typeStack = typeStack.push(type); 2607 break; 2608 } 2609 2610 case ByteCode.CHECKCAST: 2611 { 2612 String className = getClassName(constant_pool, ((Instruction_Checkcast)ins).arg_i); 2613 2614 Type castType; 2615 2616 if(className.startsWith("[")) 2617 castType = Util.v().jimpleTypeOfFieldDescriptor(getClassName(constant_pool, 2618 ((Instruction_Checkcast)ins).arg_i)); 2619 else 2620 castType = RefType.v(className); 2621 2622 typeStack = popSafeRefType(typeStack); 2623 typeStack = typeStack.push(castType); 2624 break; 2625 } 2626 2627 case ByteCode.INSTANCEOF: 2628 { 2629 typeStack = popSafeRefType(typeStack); 2630 typeStack = typeStack.push(IntType.v()); 2631 break; 2632 } 2633 2634 case ByteCode.MONITORENTER: 2635 typeStack = popSafeRefType(typeStack); 2636 break; 2637 case ByteCode.MONITOREXIT: 2638 typeStack = popSafeRefType(typeStack); 2639 break; 2640 2641 default: 2642 throw new RuntimeException ("processFlow failed: Unknown bytecode instruction: " + x); 2643 } 2644 2645 return new OutFlow(typeStack); 2646 } 2647 2648 private Type jimpleTypeOfFieldInFieldRef(Scene cm, 2649 cp_info[] constant_pool, int index) 2650 { 2651 CONSTANT_Fieldref_info fr = (CONSTANT_Fieldref_info) 2652 (constant_pool[index]); 2653 2654 CONSTANT_NameAndType_info nat = (CONSTANT_NameAndType_info) 2655 (constant_pool[fr.name_and_type_index]); 2656 2657 String fieldDescriptor = ((CONSTANT_Utf8_info) 2658 (constant_pool[nat.descriptor_index])).convert(); 2659 2660 return Util.v().jimpleTypeOfFieldDescriptor(fieldDescriptor); 2661 } 2662 2663 private Type jimpleReturnTypeOfMethodRef(Scene cm, 2664 cp_info[] constant_pool, int index) 2665 { 2666 CONSTANT_Methodref_info mr = (CONSTANT_Methodref_info) 2667 (constant_pool[index]); 2668 2669 CONSTANT_NameAndType_info nat = (CONSTANT_NameAndType_info) 2670 (constant_pool[mr.name_and_type_index]); 2671 2672 String methodDescriptor = ((CONSTANT_Utf8_info) 2673 (constant_pool[nat.descriptor_index])).convert(); 2674 2675 return Util.v().jimpleReturnTypeOfMethodDescriptor(methodDescriptor); 2676 } 2677 2678 private Type jimpleReturnTypeOfInterfaceMethodRef(Scene cm, 2679 cp_info[] constant_pool, int index) 2680 { 2681 CONSTANT_InterfaceMethodref_info mr = (CONSTANT_InterfaceMethodref_info) 2682 (constant_pool[index]); 2683 2684 CONSTANT_NameAndType_info nat = (CONSTANT_NameAndType_info) 2685 (constant_pool[mr.name_and_type_index]); 2686 2687 String methodDescriptor = ((CONSTANT_Utf8_info) 2688 (constant_pool[nat.descriptor_index])).convert(); 2689 2690 return Util.v().jimpleReturnTypeOfMethodDescriptor(methodDescriptor); 2691 } 2692 2693 private OutFlow processCPEntry(cp_info constant_pool[],int i, 2694 TypeStack typeStack, 2695 SootMethod jmethod) 2696 { 2697 cp_info c = constant_pool[i]; 2698 2699 if (c instanceof CONSTANT_Integer_info) 2700 typeStack = typeStack.push(IntType.v()); 2701 else if (c instanceof CONSTANT_Float_info) 2702 typeStack = typeStack.push(FloatType.v()); 2703 else if (c instanceof CONSTANT_Long_info) 2704 { 2705 typeStack = typeStack.push(LongType.v()); 2706 typeStack = typeStack.push(Long2ndHalfType.v()); 2707 } 2708 else if (c instanceof CONSTANT_Double_info) 2709 { 2710 typeStack = typeStack.push(DoubleType.v()); 2711 typeStack = typeStack.push(Double2ndHalfType.v()); 2712 } 2713 else if (c instanceof CONSTANT_String_info) 2714 typeStack = typeStack.push(RefType.v("java.lang.String")); 2715 else if (c instanceof CONSTANT_Utf8_info) 2716 typeStack = typeStack.push(RefType.v("java.lang.String")); 2717 else if (c instanceof CONSTANT_Class_info){ 2718 CONSTANT_Class_info info = (CONSTANT_Class_info)c; 2719 String name = ((CONSTANT_Utf8_info) (constant_pool[info.name_index])).convert(); 2720 if (name.charAt(0) == '['){ 2721 int dim = 0; 2722 while (name.charAt(dim) == '['){ 2723 dim++; 2724 } 2725 Type baseType = null; 2727 char typeIndicator = name.charAt(dim); 2728 switch (typeIndicator){ 2729 case 'I': baseType = IntType.v(); break; 2730 case 'C': baseType = CharType.v(); break; 2731 case 'F': baseType = FloatType.v(); break; 2732 case 'D': baseType = DoubleType.v(); break; 2733 case 'B': baseType = ByteType.v(); break; 2734 case 'S': baseType = ShortType.v(); break; 2735 case 'Z': baseType = BooleanType.v(); break; 2736 case 'J': baseType = LongType.v(); break; 2737 case 'L': baseType = RefType.v(name.substring(dim+1)); break; default : throw new RuntimeException ("Unknown Array Base Type in Class Constant"); 2738 } 2739 typeStack = typeStack.push(ArrayType.v(baseType, dim)); 2740 } 2741 else { 2742 typeStack = typeStack.push(RefType.v(name)); 2743 } 2744 } 2745 else 2746 throw new RuntimeException ("Attempting to push a non-constant cp entry"+c.getClass()); 2747 2748 return new OutFlow(typeStack); 2749 } 2750 2751 TypeStack smartPush(TypeStack typeStack, Type type) 2752 { 2753 if(type.equals(LongType.v())) 2754 { 2755 typeStack = typeStack.push(LongType.v()); 2756 typeStack = typeStack.push(Long2ndHalfType.v()); 2757 } 2758 else if(type.equals(DoubleType.v())) 2759 { 2760 typeStack = typeStack.push(DoubleType.v()); 2761 typeStack = typeStack.push(Double2ndHalfType.v()); 2762 } 2763 else 2764 typeStack = typeStack.push(type); 2765 2766 return typeStack; 2767 } 2768 2769 TypeStack popSafeRefType(TypeStack typeStack) 2770 { 2771 2779 2780 return typeStack.pop(); 2781 } 2782 2783 TypeStack popSafeArrayType(TypeStack typeStack) 2784 { 2785 2793 2794 return typeStack.pop(); 2795 } 2796 2797 TypeStack popSafe(TypeStack typeStack, Type requiredType) 2798 { 2799 2804 2805 return typeStack.pop(); 2806 } 2807 2808 void confirmType(Type actualType, Type requiredType) 2809 { 2810 2814 } 2815 2816 String getClassName(cp_info[] constant_pool, int index) 2817 { 2818 CONSTANT_Class_info c = (CONSTANT_Class_info) constant_pool[index]; 2819 2820 String name = ((CONSTANT_Utf8_info) (constant_pool[c.name_index])).convert(); 2821 2822 return name.replace('/', '.'); 2823 } 2824 2825 void confirmRefType(Type actualType) 2826 { 2827 2831 } 2832 2833 2839 private void processTargetFixup(BBQ bbq) 2840 { 2841 BasicBlock b,p; 2842 Stmt s; 2843 while (!bbq.isEmpty()) { 2844 try { 2845 b = bbq.pull(); 2846 } catch(NoSuchElementException e) 2847 { break; } 2848 2849 s = b.getTailJStmt(); 2850 2851 if (s instanceof GotoStmt) 2852 { 2853 if (b.succ.size() == 1) 2854 { 2855 2857 ((GotoStmt)s).setTarget(((BasicBlock) b.succ.firstElement()).getHeadJStmt()); 2858 } 2859 else 2860 { 2861 2868 G.v().out.println("Error :"); 2869 for (int i=0; i<b.statements.size(); i++) 2870 G.v().out.println(b.statements.get(i)); 2871 2872 throw new RuntimeException (b +" has "+b.succ.size()+" successors."); 2873 } 2874 } 2875 else if (s instanceof IfStmt) 2876 { 2877 if (b.succ.size()!=2) 2878 G.v().out.println("How can an if not have 2 successors?"); 2879 2880 if((BasicBlock)(b.succ.firstElement())==b.next) 2881 { 2882 ((IfStmt)s).setTarget(((BasicBlock) b.succ.elementAt(1)).getHeadJStmt()); 2883 } 2884 else 2885 { 2886 ((IfStmt)s).setTarget(((BasicBlock) b.succ.firstElement()).getHeadJStmt()); 2887 } 2888 2889 } 2890 else if (s instanceof TableSwitchStmt) 2891 { 2892 int count=0; 2893 TableSwitchStmt sts = (TableSwitchStmt)s; 2894 2898 for (Enumeration e = b.succ.elements();e.hasMoreElements();) { 2899 p = (BasicBlock)(e.nextElement()); 2900 if (count==0) { 2901 sts.setDefaultTarget(p.getHeadJStmt()); 2902 } else { 2903 sts.setTarget(count-1, p.getHeadJStmt()); 2904 } 2905 count++; 2906 } 2907 } else if (s instanceof LookupSwitchStmt) 2908 { 2909 int count=0; 2910 LookupSwitchStmt sls = (LookupSwitchStmt)s; 2911 2915 for (Enumeration e = b.succ.elements();e.hasMoreElements();) { 2916 p = (BasicBlock)(e.nextElement()); 2917 if (count==0) { 2918 sls.setDefaultTarget(p.getHeadJStmt()); 2919 } else { 2920 sls.setTarget(count-1, p.getHeadJStmt()); 2921 } 2922 count++; 2923 } 2924 } 2925 2926 b.done = false; 2927 for (Enumeration e = b.succ.elements();e.hasMoreElements();) { 2928 p = (BasicBlock)(e.nextElement()); 2929 if (p.done) bbq.push(p); 2930 } 2931 } 2932 } 2933 2934 2939 void jimpleTargetFixup() 2940 { 2941 BasicBlock b; 2942 BBQ bbq = new BBQ(); 2943 2944 Code_attribute c = method.locate_code_attribute(); 2945 if (c==null) 2946 return; 2947 2948 { 2950 BasicBlock bb = cfg; 2951 2952 while(bb != null) 2953 { 2954 bb.done = true; 2955 bb = bb.next; 2956 } 2957 } 2958 2959 2960 bbq.push(cfg); 2962 processTargetFixup(bbq); 2963 2964 if (bbq.isEmpty()) 2966 { 2967 int i; 2968 for (i=0;i<c.exception_table_length;i++) 2969 { 2970 b = c.exception_table[i].b; 2971 if (b!=null && b.done) 2973 { 2974 bbq.push(b); 2975 processTargetFixup(bbq); 2976 if (!bbq.isEmpty()) { 2977 G.v().out.println("Error 2nd processing exception block."); 2978 break; 2979 } 2980 } 2981 } 2982 } 2983 } 2984 2985 private void generateJimpleForCPEntry(cp_info constant_pool[], int i, 2986 TypeStack typeStack, TypeStack postTypeStack, 2987 SootMethod jmethod, List statements) 2988 { 2989 Expr e; 2990 Stmt stmt; 2991 Value rvalue; 2992 2993 cp_info c = constant_pool[i]; 2994 2995 if (c instanceof CONSTANT_Integer_info) 2996 { 2997 CONSTANT_Integer_info ci = (CONSTANT_Integer_info)c; 2998 2999 rvalue = IntConstant.v((int) ci.bytes); 3000 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3001 postTypeStack.topIndex()), rvalue); 3002 } 3003 else if (c instanceof CONSTANT_Float_info) 3004 { 3005 CONSTANT_Float_info cf = (CONSTANT_Float_info)c; 3006 3007 rvalue = FloatConstant.v(cf.convert()); 3008 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3009 postTypeStack.topIndex()), rvalue); 3010 } 3011 else if (c instanceof CONSTANT_Long_info) 3012 { 3013 CONSTANT_Long_info cl = (CONSTANT_Long_info)c; 3014 3015 rvalue = LongConstant.v(cl.convert()); 3016 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3017 postTypeStack.topIndex()), rvalue); 3018 } 3019 else if (c instanceof CONSTANT_Double_info) 3020 { 3021 CONSTANT_Double_info cd = (CONSTANT_Double_info)c; 3022 3023 rvalue = DoubleConstant.v(cd.convert()); 3024 3025 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3026 postTypeStack.topIndex()), rvalue); 3027 } 3028 else if (c instanceof CONSTANT_String_info) 3029 { 3030 CONSTANT_String_info cs = (CONSTANT_String_info)c; 3031 3032 String constant = cs.toString(constant_pool); 3033 3034 if(constant.startsWith("\"") && constant.endsWith("\"")) 3035 constant = constant.substring(1, constant.length() - 1); 3036 3037 rvalue = StringConstant.v(constant); 3038 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3039 postTypeStack.topIndex()), rvalue); 3040 } 3041 else if (c instanceof CONSTANT_Utf8_info) 3042 { 3043 CONSTANT_Utf8_info cu = (CONSTANT_Utf8_info)c; 3044 3045 String constant = cu.convert(); 3046 3047 if(constant.startsWith("\"") && constant.endsWith("\"")) 3048 constant = constant.substring(1, constant.length() - 1); 3049 3050 rvalue = StringConstant.v(constant); 3051 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3052 postTypeStack.topIndex()), rvalue); 3053 } 3054 else if (c instanceof CONSTANT_Class_info){ 3055 3056 String className = ((CONSTANT_Utf8_info) (constant_pool[((CONSTANT_Class_info)c).name_index])).convert(); 3057 3058 3059 rvalue = ClassConstant.v(className); 3060 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex()), rvalue); 3061 } 3062 else { 3063 throw new RuntimeException ("Attempting to push a non-constant cp entry"+c); 3064 } 3065 3066 statements.add(stmt); 3067 } 3068 3069 void generateJimple(Instruction ins, TypeStack typeStack, TypeStack postTypeStack, 3070 cp_info constant_pool[], 3071 List statements, BasicBlock basicBlock) 3072 { 3073 Value[] params; 3074 Value v1=null,v2=null,v3=null,v4=null; 3075 Local l1 = null, l2 = null, l3 = null, l4 = null; 3076 3077 Expr e=null,rhs=null; 3078 BinopExpr b=null; 3079 ConditionExpr co = null; 3080 3081 ArrayRef a=null; 3082 int args; 3083 Value rvalue; 3084 3085 3087 Stmt stmt = null; 3088 3089 int x = ((int)(ins.code))&0xff; 3090 3091 Util.v().activeOriginalIndex = ins.originalIndex; 3092 Util.v().isLocalStore = false; 3093 Util.v().isWideLocalStore = false; 3094 3095 switch(x) 3096 { 3097 case ByteCode.BIPUSH: 3098 rvalue = IntConstant.v(((Instruction_Bipush)ins).arg_b); 3099 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3100 postTypeStack.topIndex()), rvalue); 3101 break; 3102 3103 case ByteCode.SIPUSH: 3104 rvalue = IntConstant.v(((Instruction_Sipush)ins).arg_i); 3105 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3106 postTypeStack.topIndex()), rvalue); 3107 break; 3108 3109 case ByteCode.LDC1: 3110 generateJimpleForCPEntry(constant_pool,((Instruction_Ldc1)ins).arg_b, typeStack, postTypeStack, 3111 jmethod, statements); 3112 break; 3113 3114 case ByteCode.LDC2: 3115 case ByteCode.LDC2W: 3116 generateJimpleForCPEntry(constant_pool, ((Instruction_intindex)ins).arg_i, 3117 typeStack, postTypeStack, jmethod, statements); 3118 break; 3119 3120 case ByteCode.ACONST_NULL: 3121 rvalue = NullConstant.v(); 3122 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3123 postTypeStack.topIndex()), rvalue); 3124 break; 3125 3126 case ByteCode.ICONST_M1: 3127 case ByteCode.ICONST_0: 3128 case ByteCode.ICONST_1: 3129 case ByteCode.ICONST_2: 3130 case ByteCode.ICONST_3: 3131 case ByteCode.ICONST_4: 3132 case ByteCode.ICONST_5: 3133 rvalue = IntConstant.v(x-ByteCode.ICONST_0); 3134 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3135 postTypeStack.topIndex()), rvalue); 3136 break; 3137 3138 case ByteCode.LCONST_0: 3139 case ByteCode.LCONST_1: 3140 rvalue = LongConstant.v(x-ByteCode.LCONST_0); 3141 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3142 postTypeStack.topIndex()), rvalue); 3143 break; 3144 3145 case ByteCode.FCONST_0: 3146 case ByteCode.FCONST_1: 3147 case ByteCode.FCONST_2: 3148 rvalue = FloatConstant.v((float)(x - ByteCode.FCONST_0)); 3149 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3150 postTypeStack.topIndex()), rvalue); 3151 break; 3152 3153 case ByteCode.DCONST_0: 3154 case ByteCode.DCONST_1: 3155 rvalue = DoubleConstant.v((double)(x-ByteCode.DCONST_0)); 3156 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3157 postTypeStack.topIndex()), rvalue); 3158 break; 3159 3160 case ByteCode.ILOAD: 3161 { 3162 Local local = (Local) 3163 Util.v().getLocalForIndex(listBody, ((Instruction_bytevar) ins).arg_b); 3164 3165 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3166 postTypeStack.topIndex()), local); 3167 break; 3168 } 3169 3170 case ByteCode.FLOAD: 3171 { 3172 Local local = (Local) 3173 Util.v().getLocalForIndex(listBody, ((Instruction_bytevar)ins).arg_b); 3174 3175 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3176 postTypeStack.topIndex()), local); 3177 break; 3178 } 3179 3180 case ByteCode.ALOAD: 3181 { 3182 Local local = 3183 Util.v().getLocalForIndex(listBody, ((Instruction_bytevar)ins).arg_b); 3184 3185 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3186 postTypeStack.topIndex()), local); 3187 break; 3188 } 3189 3190 case ByteCode.DLOAD: 3191 { 3192 Local local = 3193 Util.v().getLocalForIndex(listBody, ((Instruction_bytevar)ins).arg_b); 3194 3195 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3196 postTypeStack.topIndex()), local); 3197 break; 3198 } 3199 3200 case ByteCode.LLOAD: 3201 { 3202 Local local = 3203 Util.v().getLocalForIndex(listBody, ((Instruction_bytevar)ins).arg_b); 3204 3205 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3206 postTypeStack.topIndex()), local); 3207 break; 3208 } 3209 3210 case ByteCode.ILOAD_0: 3211 case ByteCode.ILOAD_1: 3212 case ByteCode.ILOAD_2: 3213 case ByteCode.ILOAD_3: 3214 { 3215 Local local = 3216 Util.v().getLocalForIndex(listBody, (x - ByteCode.ILOAD_0)); 3217 3218 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3219 postTypeStack.topIndex()), local); 3220 break; 3221 } 3222 3223 case ByteCode.FLOAD_0: 3224 case ByteCode.FLOAD_1: 3225 case ByteCode.FLOAD_2: 3226 case ByteCode.FLOAD_3: 3227 { 3228 Local local = 3229 Util.v().getLocalForIndex(listBody, (x - ByteCode.FLOAD_0)); 3230 3231 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3232 postTypeStack.topIndex()), local); 3233 break; 3234 } 3235 3236 case ByteCode.ALOAD_0: 3237 case ByteCode.ALOAD_1: 3238 case ByteCode.ALOAD_2: 3239 case ByteCode.ALOAD_3: 3240 { 3241 Local local = 3242 Util.v().getLocalForIndex(listBody, (x - ByteCode.ALOAD_0)); 3243 3244 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3245 postTypeStack.topIndex()), local); 3246 break; 3247 } 3248 3249 case ByteCode.LLOAD_0: 3250 case ByteCode.LLOAD_1: 3251 case ByteCode.LLOAD_2: 3252 case ByteCode.LLOAD_3: 3253 { 3254 Local local = 3255 Util.v().getLocalForIndex(listBody, (x - ByteCode.LLOAD_0)); 3256 3257 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3258 postTypeStack.topIndex()), local); 3259 break; 3260 } 3261 3262 case ByteCode.DLOAD_0: 3263 case ByteCode.DLOAD_1: 3264 case ByteCode.DLOAD_2: 3265 case ByteCode.DLOAD_3: 3266 { 3267 Local local = 3268 Util.v().getLocalForIndex(listBody, (x - ByteCode.DLOAD_0)); 3269 3270 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3271 postTypeStack.topIndex()), local); 3272 break; 3273 } 3274 3275 case ByteCode.ISTORE: 3276 { 3277 Util.v().isLocalStore = true; 3278 Util.v().isWideLocalStore = true; 3279 3280 Local local = 3281 Util.v().getLocalForIndex(listBody, 3282 ((Instruction_bytevar)ins).arg_b); 3283 3284 stmt = Jimple.v().newAssignStmt(local, Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex())); 3285 break; 3286 } 3287 3288 case ByteCode.FSTORE: 3289 { 3290 Util.v().isLocalStore = true; 3291 Util.v().isWideLocalStore = true; 3292 3293 Local local = 3294 Util.v().getLocalForIndex(listBody, 3295 ((Instruction_bytevar)ins).arg_b); 3296 3297 stmt = Jimple.v().newAssignStmt(local, Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex())); 3298 break; 3299 } 3300 3301 case ByteCode.ASTORE: 3302 { 3303 Util.v().isLocalStore = true; 3304 Util.v().isWideLocalStore = true; 3305 3306 Local local = 3307 Util.v().getLocalForIndex(listBody, 3308 ((Instruction_bytevar)ins).arg_b); 3309 3310 stmt = Jimple.v().newAssignStmt(local, Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex())); 3311 break; 3312 } 3313 3314 case ByteCode.LSTORE: 3315 { 3316 Util.v().isLocalStore = true; 3317 Util.v().isWideLocalStore = true; 3318 3319 Local local = 3320 Util.v().getLocalForIndex(listBody, 3321 ((Instruction_bytevar)ins).arg_b); 3322 3323 stmt = Jimple.v().newAssignStmt(local, Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex())); 3324 break; 3325 } 3326 3327 case ByteCode.DSTORE: 3328 { 3329 Util.v().isLocalStore = true; 3330 Util.v().isWideLocalStore = true; 3331 3332 Local local = 3333 Util.v().getLocalForIndex(listBody, 3334 ((Instruction_bytevar)ins).arg_b); 3335 3336 stmt = Jimple.v().newAssignStmt(local, Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex())); 3337 break; 3338 } 3339 3340 case ByteCode.ISTORE_0: 3341 case ByteCode.ISTORE_1: 3342 case ByteCode.ISTORE_2: 3343 case ByteCode.ISTORE_3: 3344 { 3345 Util.v().isLocalStore = true; 3346 Local local = 3347 Util.v().getLocalForIndex(listBody, (x - ByteCode.ISTORE_0)); 3348 3349 stmt = Jimple.v().newAssignStmt(local, Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex())); 3350 break; 3351 } 3352 3353 case ByteCode.FSTORE_0: 3354 case ByteCode.FSTORE_1: 3355 case ByteCode.FSTORE_2: 3356 case ByteCode.FSTORE_3: 3357 { 3358 Util.v().isLocalStore = true; 3359 Local local = (Local) 3360 Util.v().getLocalForIndex(listBody, (x - ByteCode.FSTORE_0)); 3361 3362 stmt = Jimple.v().newAssignStmt(local, Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex())); 3363 break; 3364 } 3365 3366 case ByteCode.ASTORE_0: 3367 case ByteCode.ASTORE_1: 3368 case ByteCode.ASTORE_2: 3369 case ByteCode.ASTORE_3: 3370 { 3371 Util.v().isLocalStore = true; 3372 Local local = Util.v().getLocalForIndex(listBody, (x - ByteCode.ASTORE_0)); 3373 3374 stmt = Jimple.v().newAssignStmt(local, Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex())); 3375 break; 3376 } 3377 3378 case ByteCode.LSTORE_0: 3379 case ByteCode.LSTORE_1: 3380 case ByteCode.LSTORE_2: 3381 case ByteCode.LSTORE_3: 3382 { 3383 Util.v().isLocalStore = true; 3384 Local local = 3385 Util.v().getLocalForIndex(listBody, (x - ByteCode.LSTORE_0)); 3386 3387 stmt = Jimple.v().newAssignStmt(local, Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex())); 3388 break; 3389 } 3390 3391 case ByteCode.DSTORE_0: 3392 case ByteCode.DSTORE_1: 3393 case ByteCode.DSTORE_2: 3394 case ByteCode.DSTORE_3: 3395 { 3396 Util.v().isLocalStore = true; 3397 Local local = 3398 Util.v().getLocalForIndex(listBody, (x - ByteCode.DSTORE_0)); 3399 3400 stmt = Jimple.v().newAssignStmt(local, Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex())); 3401 break; 3402 } 3403 3404 case ByteCode.IINC: 3405 { 3406 Local local = 3407 Util.v().getLocalForIndex(listBody, 3408 ((Instruction_Iinc)ins).arg_b); 3409 3410 int amt = (((Instruction_Iinc)ins).arg_c); 3411 rhs = Jimple.v().newAddExpr(local, IntConstant.v(amt)); 3412 stmt = Jimple.v().newAssignStmt(local,rhs); 3413 break; 3414 } 3415 3416 case ByteCode.WIDE: 3417 throw new RuntimeException ("WIDE instruction should not be encountered anymore"); 3418 3420 case ByteCode.NEWARRAY: 3421 { 3422 Type baseType = (Type) jimpleTypeOfAtype(((Instruction_Newarray)ins).atype); 3423 3424 rhs = Jimple.v().newNewArrayExpr(baseType, 3425 Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex())); 3426 3427 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, 3428 postTypeStack, postTypeStack.topIndex()), rhs); 3429 3430 break; 3431 } 3432 3433 case ByteCode.ANEWARRAY: 3434 { 3435 String baseName = getClassName(constant_pool, ((Instruction_Anewarray)ins).arg_i); 3436 3437 Type baseType; 3438 3439 if(baseName.startsWith("[")) 3440 baseType = Util.v().jimpleTypeOfFieldDescriptor(getClassName(constant_pool, ((Instruction_Anewarray)ins).arg_i)); 3441 else 3442 baseType = RefType.v(baseName); 3443 3444 rhs = Jimple.v().newNewArrayExpr(baseType, Util.v().getLocalForStackOp(listBody, 3445 typeStack, typeStack.topIndex())); 3446 3447 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, 3448 postTypeStack, postTypeStack.topIndex()),rhs); 3449 break; 3450 } 3451 3452 case ByteCode.MULTIANEWARRAY: 3453 { 3454 int bdims = (int)(((Instruction_Multianewarray)ins).dims); 3455 List dims = new ArrayList(); 3456 3457 for (int j=0; j < bdims; j++) 3458 dims.add(Util.v().getLocalForStackOp(listBody, typeStack, 3459 typeStack.topIndex() - bdims + j + 1)); 3460 3461 String mstype = constant_pool[((Instruction_Multianewarray)ins).arg_i]. 3462 toString(constant_pool); 3463 3464 ArrayType jimpleType = (ArrayType) Util.v().jimpleTypeOfFieldDescriptor(mstype); 3465 3466 rhs = Jimple.v().newNewMultiArrayExpr(jimpleType, dims); 3467 3468 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3469 postTypeStack.topIndex()),rhs); 3470 break; 3471 } 3472 3473 3474 case ByteCode.ARRAYLENGTH: 3475 rhs = Jimple.v().newLengthExpr( 3476 Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex())); 3477 3478 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3479 postTypeStack.topIndex()),rhs); 3480 break; 3481 3482 case ByteCode.IALOAD: 3483 case ByteCode.BALOAD: 3484 case ByteCode.CALOAD: 3485 case ByteCode.SALOAD: 3486 case ByteCode.FALOAD: 3487 case ByteCode.LALOAD: 3488 case ByteCode.DALOAD: 3489 case ByteCode.AALOAD: 3490 a = Jimple.v().newArrayRef(Util.v().getLocalForStackOp(listBody, typeStack, 3491 typeStack.topIndex() - 1), 3492 Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex())); 3493 3494 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, 3495 postTypeStack, postTypeStack.topIndex()), a); 3496 3497 break; 3498 3499 case ByteCode.IASTORE: 3500 case ByteCode.FASTORE: 3501 case ByteCode.AASTORE: 3502 case ByteCode.BASTORE: 3503 case ByteCode.CASTORE: 3504 case ByteCode.SASTORE: 3505 a = Jimple.v().newArrayRef(Util.v().getLocalForStackOp(listBody, typeStack, 3506 typeStack.topIndex() - 2), Util.v().getLocalForStackOp(listBody, typeStack, 3507 typeStack.topIndex() - 1)); 3508 3509 stmt = Jimple.v().newAssignStmt(a, Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex())); 3510 break; 3511 3512 case ByteCode.LASTORE: 3513 case ByteCode.DASTORE: 3514 a = Jimple.v().newArrayRef(Util.v().getLocalForStackOp(listBody, typeStack, 3515 typeStack.topIndex() - 3), Util.v().getLocalForStackOp(listBody, typeStack, 3516 typeStack.topIndex() - 2)); 3517 3518 stmt = Jimple.v().newAssignStmt(a, Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex())); 3519 break; 3520 3521 3522 case ByteCode.NOP: 3523 stmt = Jimple.v().newNopStmt(); 3524 break; 3525 3526 case ByteCode.POP: 3527 case ByteCode.POP2: 3528 stmt = Jimple.v().newNopStmt(); 3529 break; 3530 3531 case ByteCode.DUP: 3532 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3533 postTypeStack.topIndex()), Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex())); 3534 break; 3535 3536 case ByteCode.DUP2: 3537 if(typeSize(typeStack.top()) == 2) 3538 { 3539 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3540 postTypeStack.topIndex() - 1), 3541 Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1)); 3542 } 3543 else { 3544 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3545 postTypeStack.topIndex() - 1), 3546 Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1)); 3547 3548 statements.add(stmt); 3549 3550 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3551 postTypeStack.topIndex()), Util.v().getLocalForStackOp(listBody, 3552 typeStack, typeStack.topIndex())); 3553 3554 statements.add(stmt); 3555 3556 stmt = null; 3557 } 3558 break; 3559 3560 case ByteCode.DUP_X1: 3561 l1 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()); 3562 l2 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()-1); 3563 3564 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3565 postTypeStack.topIndex()), l1); 3566 3567 statements.add(stmt); 3568 3569 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3570 postTypeStack.topIndex() - 1), l2); 3571 3572 statements.add(stmt); 3573 3574 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3575 postTypeStack.topIndex() - 2), Util.v().getLocalForStackOp(listBody, 3576 postTypeStack, postTypeStack.topIndex())); 3577 3578 statements.add(stmt); 3579 3580 stmt = null; 3581 break; 3582 3583 case ByteCode.DUP_X2: 3584 if(typeSize(typeStack.get(typeStack.topIndex() - 2)) == 2) 3585 { 3586 l3 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 2); 3587 l1 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()); 3588 3589 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3590 postTypeStack.topIndex() - 2), l3); 3591 3592 statements.add(stmt); 3593 3594 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3595 postTypeStack.topIndex() - 3), l1); 3596 3597 statements.add(stmt); 3598 3599 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3600 postTypeStack.topIndex()), l1); 3601 3602 statements.add(stmt); 3603 3604 stmt = null; 3605 } 3606 else { 3607 l3 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 2); 3608 l2 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1); 3609 l1 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()); 3610 3611 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3612 postTypeStack.topIndex()), l1); 3613 3614 statements.add(stmt); 3615 3616 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3617 postTypeStack.topIndex() - 1), l2); 3618 3619 statements.add(stmt); 3620 3621 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3622 postTypeStack.topIndex() - 2), l3); 3623 3624 statements.add(stmt); 3625 3626 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3627 postTypeStack.topIndex() - 3), Util.v().getLocalForStackOp( 3628 listBody, postTypeStack, postTypeStack.topIndex())); 3629 3630 statements.add(stmt); 3631 3632 stmt = null; 3633 } 3634 break; 3635 3636 case ByteCode.DUP2_X1: 3637 if(typeSize(typeStack.get(typeStack.topIndex() - 1)) == 2) 3638 { 3639 l2 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1); 3640 l3 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 2); 3641 3642 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3643 postTypeStack.topIndex() -1), l2); 3644 3645 statements.add(stmt); 3646 3647 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3648 postTypeStack.topIndex() - 2), l3); 3649 3650 statements.add(stmt); 3651 3652 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3653 postTypeStack.topIndex() - 4), 3654 Util.v().getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex() - 1)); 3655 3656 statements.add(stmt); 3657 3658 stmt = null; 3659 } 3660 else { 3661 l3 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 2); 3662 l2 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1); 3663 l1 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()); 3664 3665 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3666 postTypeStack.topIndex()), l1); 3667 3668 statements.add(stmt); 3669 3670 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3671 postTypeStack.topIndex() - 1), l2); 3672 3673 statements.add(stmt); 3674 3675 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3676 postTypeStack.topIndex() - 2), l3); 3677 3678 statements.add(stmt); 3679 3680 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3681 postTypeStack.topIndex() - 3), Util.v().getLocalForStackOp( 3682 listBody, postTypeStack, postTypeStack.topIndex())); 3683 3684 statements.add(stmt); 3685 3686 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3687 postTypeStack.topIndex() - 4), Util.v().getLocalForStackOp( 3688 listBody, postTypeStack, postTypeStack.topIndex() - 1)); 3689 3690 statements.add(stmt); 3691 3692 stmt = null; 3693 } 3694 break; 3695 3696 case ByteCode.DUP2_X2: 3697 if(typeSize(typeStack.get(typeStack.topIndex() - 1)) == 2) 3698 { 3699 l2 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1); 3700 3701 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3702 postTypeStack.topIndex() - 1), l2); 3703 3704 statements.add(stmt); 3705 } 3706 else { 3707 l1 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()); 3708 l2 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1); 3709 3710 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3711 postTypeStack.topIndex() - 1), l2); 3712 3713 statements.add(stmt); 3714 3715 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3716 postTypeStack.topIndex()), l1); 3717 3718 statements.add(stmt); 3719 3720 } 3721 3722 if(typeSize(typeStack.get(typeStack.topIndex() - 3)) == 2) 3723 { 3724 l4 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 3); 3725 3726 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3727 postTypeStack.topIndex() - 3), l4); 3728 3729 statements.add(stmt); 3730 } 3731 else { 3732 l4 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 3); 3733 l3 = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 2); 3734 3735 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3736 postTypeStack.topIndex() - 3), l4); 3737 3738 statements.add(stmt); 3739 3740 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3741 postTypeStack.topIndex() - 2), l3); 3742 3743 statements.add(stmt); 3744 3745 } 3746 3747 if(typeSize(typeStack.get(typeStack.topIndex() - 1)) == 2) 3748 { 3749 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3750 postTypeStack.topIndex() - 5), Util.v().getLocalForStackOp( 3751 listBody, postTypeStack, postTypeStack.topIndex() - 1)); 3752 3753 statements.add(stmt); 3754 } 3755 else { 3756 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3757 postTypeStack.topIndex() - 5), Util.v().getLocalForStackOp( 3758 listBody, postTypeStack, postTypeStack.topIndex() - 1)); 3759 3760 statements.add(stmt); 3761 3762 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3763 postTypeStack.topIndex() - 4), Util.v().getLocalForStackOp( 3764 listBody, postTypeStack, postTypeStack.topIndex())); 3765 3766 statements.add(stmt); 3767 } 3768 stmt = null; 3769 break; 3770 3771 case ByteCode.SWAP: 3772 { 3773 Local first; 3774 3775 typeStack = typeStack.push(typeStack.top()); 3776 first = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()); 3777 typeStack = typeStack.pop(); 3778 3780 Local second = Util.v().getLocalForStackOp(listBody, postTypeStack, 3781 postTypeStack.topIndex()); 3782 3783 Local third = Util.v().getLocalForStackOp(listBody, postTypeStack, 3784 postTypeStack.topIndex() - 1); 3785 3786 stmt = Jimple.v().newAssignStmt(first, second); 3787 statements.add(stmt); 3788 3789 stmt = Jimple.v().newAssignStmt(second, third); 3790 statements.add(stmt); 3791 3792 stmt = Jimple.v().newAssignStmt(third, first); 3793 statements.add(stmt); 3794 3795 stmt = null; 3796 break; 3797 } 3798 3799 case ByteCode.FADD: 3800 case ByteCode.IADD: 3801 rhs = Jimple.v().newAddExpr(Util.v().getLocalForStackOp(listBody, typeStack, 3802 typeStack.topIndex() - 1), Util.v().getLocalForStackOp(listBody, typeStack, 3803 typeStack.topIndex())); 3804 3805 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3806 postTypeStack.topIndex()), rhs); 3807 break; 3808 3809 case ByteCode.DADD: 3810 case ByteCode.LADD: 3811 rhs = Jimple.v().newAddExpr(Util.v().getLocalForStackOp(listBody, typeStack, 3812 typeStack.topIndex() - 3), Util.v().getLocalForStackOp(listBody, typeStack, 3813 typeStack.topIndex() - 1)); 3814 3815 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3816 postTypeStack.topIndex()), rhs); 3817 break; 3818 3819 case ByteCode.FSUB: 3820 case ByteCode.ISUB: 3821 rhs = Jimple.v().newSubExpr(Util.v().getLocalForStackOp(listBody, typeStack, 3822 typeStack.topIndex() - 1), Util.v().getLocalForStackOp(listBody, typeStack, 3823 typeStack.topIndex())); 3824 3825 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3826 postTypeStack.topIndex()), rhs); 3827 break; 3828 3829 case ByteCode.DSUB: 3830 case ByteCode.LSUB: 3831 rhs = Jimple.v().newSubExpr(Util.v().getLocalForStackOp(listBody, typeStack, 3832 typeStack.topIndex() - 3), Util.v().getLocalForStackOp(listBody, typeStack, 3833 typeStack.topIndex() - 1)); 3834 3835 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3836 postTypeStack.topIndex()), rhs); 3837 break; 3838 3839 case ByteCode.FMUL: 3840 case ByteCode.IMUL: 3841 rhs = Jimple.v().newMulExpr(Util.v().getLocalForStackOp(listBody, typeStack, 3842 typeStack.topIndex() - 1), Util.v().getLocalForStackOp(listBody, typeStack, 3843 typeStack.topIndex())); 3844 3845 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3846 postTypeStack.topIndex()), rhs); 3847 break; 3848 3849 case ByteCode.DMUL: 3850 case ByteCode.LMUL: 3851 rhs = Jimple.v().newMulExpr(Util.v().getLocalForStackOp(listBody, typeStack, 3852 typeStack.topIndex() - 3), Util.v().getLocalForStackOp(listBody, typeStack, 3853 typeStack.topIndex() - 1)); 3854 3855 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3856 postTypeStack.topIndex()), rhs); 3857 break; 3858 3859 case ByteCode.FDIV: 3860 case ByteCode.IDIV: 3861 rhs = Jimple.v().newDivExpr(Util.v().getLocalForStackOp(listBody, typeStack, 3862 typeStack.topIndex() - 1), Util.v().getLocalForStackOp(listBody, typeStack, 3863 typeStack.topIndex())); 3864 3865 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3866 postTypeStack.topIndex()), rhs); 3867 break; 3868 3869 case ByteCode.DDIV: 3870 case ByteCode.LDIV: 3871 rhs = Jimple.v().newDivExpr(Util.v().getLocalForStackOp(listBody, typeStack, 3872 typeStack.topIndex() - 3), Util.v().getLocalForStackOp(listBody, typeStack, 3873 typeStack.topIndex() - 1)); 3874 3875 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3876 postTypeStack.topIndex()), rhs); 3877 break; 3878 3879 case ByteCode.FREM: 3880 case ByteCode.IREM: 3881 rhs = Jimple.v().newRemExpr(Util.v().getLocalForStackOp(listBody, typeStack, 3882 typeStack.topIndex() - 1), Util.v().getLocalForStackOp(listBody, typeStack, 3883 typeStack.topIndex())); 3884 3885 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3886 postTypeStack.topIndex()), rhs); 3887 break; 3888 3889 case ByteCode.DREM: 3890 case ByteCode.LREM: 3891 rhs = Jimple.v().newRemExpr(Util.v().getLocalForStackOp(listBody, typeStack, 3892 typeStack.topIndex() - 3), Util.v().getLocalForStackOp(listBody, typeStack, 3893 typeStack.topIndex() - 1)); 3894 3895 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3896 postTypeStack.topIndex()), rhs); 3897 break; 3898 3899 case ByteCode.INEG: 3900 case ByteCode.LNEG: 3901 case ByteCode.FNEG: 3902 case ByteCode.DNEG: 3903 rhs = Jimple.v().newNegExpr(Util.v().getLocalForStackOp(listBody, typeStack, 3904 typeStack.topIndex())); 3905 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3906 postTypeStack.topIndex()),rhs); 3907 break; 3908 3909 case ByteCode.ISHL: 3910 rhs = Jimple.v().newShlExpr(Util.v().getLocalForStackOp(listBody, typeStack, 3911 typeStack.topIndex() - 1), Util.v().getLocalForStackOp(listBody, typeStack, 3912 typeStack.topIndex())); 3913 3914 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3915 postTypeStack.topIndex()), rhs); 3916 break; 3917 3918 case ByteCode.ISHR: 3919 rhs = Jimple.v().newShrExpr(Util.v().getLocalForStackOp(listBody, typeStack, 3920 typeStack.topIndex() - 1), Util.v().getLocalForStackOp(listBody, typeStack, 3921 typeStack.topIndex())); 3922 3923 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3924 postTypeStack.topIndex()), rhs); 3925 break; 3926 3927 case ByteCode.IUSHR: 3928 rhs = Jimple.v().newUshrExpr(Util.v().getLocalForStackOp(listBody, typeStack, 3929 typeStack.topIndex() - 1), Util.v().getLocalForStackOp(listBody, typeStack, 3930 typeStack.topIndex())); 3931 3932 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3933 postTypeStack.topIndex()), rhs); 3934 break; 3935 3936 case ByteCode.LSHL: 3937 rhs = Jimple.v().newShlExpr(Util.v().getLocalForStackOp(listBody, typeStack, 3938 typeStack.topIndex() - 2), Util.v().getLocalForStackOp(listBody, typeStack, 3939 typeStack.topIndex())); 3940 3941 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3942 postTypeStack.topIndex()), rhs); 3943 break; 3944 3945 case ByteCode.LSHR: 3946 rhs = Jimple.v().newShrExpr(Util.v().getLocalForStackOp(listBody, typeStack, 3947 typeStack.topIndex() - 2), Util.v().getLocalForStackOp(listBody, typeStack, 3948 typeStack.topIndex())); 3949 3950 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3951 postTypeStack.topIndex()), rhs); 3952 break; 3953 3954 case ByteCode.LUSHR: 3955 rhs = Jimple.v().newUshrExpr(Util.v().getLocalForStackOp(listBody, typeStack, 3956 typeStack.topIndex() - 2), Util.v().getLocalForStackOp(listBody, typeStack, 3957 typeStack.topIndex())); 3958 3959 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3960 postTypeStack.topIndex()), rhs); 3961 break; 3962 3963 case ByteCode.IAND: 3964 rhs = Jimple.v().newAndExpr(Util.v().getLocalForStackOp(listBody, typeStack, 3965 typeStack.topIndex() - 1), Util.v().getLocalForStackOp(listBody, typeStack, 3966 typeStack.topIndex())); 3967 3968 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3969 postTypeStack.topIndex()), rhs); 3970 break; 3971 3972 case ByteCode.LAND: 3973 rhs = Jimple.v().newAndExpr(Util.v().getLocalForStackOp(listBody, typeStack, 3974 typeStack.topIndex() - 3), Util.v().getLocalForStackOp(listBody, typeStack, 3975 typeStack.topIndex() - 1)); 3976 3977 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3978 postTypeStack.topIndex()), rhs); 3979 break; 3980 3981 case ByteCode.IOR: 3982 rhs = Jimple.v().newOrExpr(Util.v().getLocalForStackOp(listBody, typeStack, 3983 typeStack.topIndex() - 1), Util.v().getLocalForStackOp(listBody, typeStack, 3984 typeStack.topIndex())); 3985 3986 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3987 postTypeStack.topIndex()), rhs); 3988 break; 3989 3990 case ByteCode.LOR: 3991 rhs = Jimple.v().newOrExpr(Util.v().getLocalForStackOp(listBody, typeStack, 3992 typeStack.topIndex() - 3), Util.v().getLocalForStackOp(listBody, typeStack, 3993 typeStack.topIndex() - 1)); 3994 3995 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 3996 postTypeStack.topIndex()), rhs); 3997 break; 3998 3999 case ByteCode.IXOR: 4000 rhs = Jimple.v().newXorExpr(Util.v().getLocalForStackOp(listBody, typeStack, 4001 typeStack.topIndex() - 1), Util.v().getLocalForStackOp(listBody, typeStack, 4002 typeStack.topIndex())); 4003 4004 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 4005 postTypeStack.topIndex()), rhs); 4006 break; 4007 4008 case ByteCode.LXOR: 4009 rhs = Jimple.v().newXorExpr(Util.v().getLocalForStackOp(listBody, typeStack, 4010 typeStack.topIndex() - 3), Util.v().getLocalForStackOp(listBody, typeStack, 4011 typeStack.topIndex() - 1)); 4012 4013 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 4014 postTypeStack.topIndex()), rhs); 4015 break; 4016 4017 case ByteCode.D2L: 4018 case ByteCode.F2L: 4019 case ByteCode.I2L: 4020 rhs = Jimple.v().newCastExpr(Util.v().getLocalForStackOp(listBody, typeStack, 4021 typeStack.topIndex()), LongType.v()); 4022 4023 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 4024 postTypeStack.topIndex()), rhs); 4025 break; 4026 4027 case ByteCode.D2F: 4028 case ByteCode.L2F: 4029 case ByteCode.I2F: 4030 rhs = Jimple.v().newCastExpr(Util.v().getLocalForStackOp(listBody, typeStack, 4031 typeStack.topIndex()), FloatType.v()); 4032 4033 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 4034 postTypeStack.topIndex()), rhs); 4035 break; 4036 4037 case ByteCode.I2D: 4038 case ByteCode.L2D: 4039 case ByteCode.F2D: 4040 rhs = Jimple.v().newCastExpr(Util.v().getLocalForStackOp(listBody, typeStack, 4041 typeStack.topIndex()), DoubleType.v()); 4042 4043 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 4044 postTypeStack.topIndex()), rhs); 4045 break; 4046 4047 case ByteCode.L2I: 4048 case ByteCode.F2I: 4049 case ByteCode.D2I: 4050 rhs = Jimple.v().newCastExpr(Util.v().getLocalForStackOp(listBody, typeStack, 4051 typeStack.topIndex()), IntType.v()); 4052 4053 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 4054 postTypeStack.topIndex()), rhs); 4055 break; 4056 4057 case ByteCode.INT2BYTE: 4058 rhs = Jimple.v().newCastExpr(Util.v().getLocalForStackOp(listBody, typeStack, 4059 typeStack.topIndex()), ByteType.v()); 4060 4061 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 4062 postTypeStack.topIndex()), rhs); 4063 break; 4064 4065 case ByteCode.INT2CHAR: 4066 rhs = Jimple.v().newCastExpr(Util.v().getLocalForStackOp(listBody, typeStack, 4067 typeStack.topIndex()), CharType.v()); 4068 4069 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 4070 postTypeStack.topIndex()), rhs); 4071 break; 4072 4073 case ByteCode.INT2SHORT: 4074 rhs = Jimple.v().newCastExpr(Util.v().getLocalForStackOp(listBody, typeStack, 4075 typeStack.topIndex()), ShortType.v()); 4076 4077 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 4078 postTypeStack.topIndex()), rhs); 4079 break; 4080 4081 case ByteCode.IFEQ: 4082 co = Jimple.v().newEqExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()), 4083 IntConstant.v(0)); 4084 4085 stmt = Jimple.v().newIfStmt(co, new FutureStmt()); 4086 break; 4087 4088 case ByteCode.IFNULL: 4089 co = Jimple.v().newEqExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()), 4090 NullConstant.v()); 4091 4092 stmt = Jimple.v().newIfStmt(co, new FutureStmt()); 4093 break; 4094 4095 case ByteCode.IFLT: 4096 co = Jimple.v().newLtExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()), 4097 IntConstant.v(0)); 4098 4099 stmt = Jimple.v().newIfStmt(co, new FutureStmt()); 4100 break; 4101 4102 case ByteCode.IFLE: 4103 co = Jimple.v().newLeExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()), 4104 IntConstant.v(0)); 4105 4106 stmt = Jimple.v().newIfStmt(co, new FutureStmt()); 4107 break; 4108 4109 case ByteCode.IFNE: 4110 co = Jimple.v().newNeExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()), 4111 IntConstant.v(0)); 4112 4113 stmt = Jimple.v().newIfStmt(co, new FutureStmt()); 4114 break; 4115 4116 case ByteCode.IFNONNULL: 4117 co = Jimple.v().newNeExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()), 4118 NullConstant.v()); 4119 4120 stmt = Jimple.v().newIfStmt(co, new FutureStmt()); 4121 break; 4122 4123 case ByteCode.IFGT: 4124 co = Jimple.v().newGtExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()), 4125 IntConstant.v(0)); 4126 4127 stmt = Jimple.v().newIfStmt(co, new FutureStmt()); 4128 break; 4129 4130 case ByteCode.IFGE: 4131 co = Jimple.v().newGeExpr(Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()), 4132 IntConstant.v(0)); 4133 4134 stmt = Jimple.v().newIfStmt(co, new FutureStmt()); 4135 break; 4136 4137 case ByteCode.IF_ICMPEQ: 4138 co = Jimple.v().newEqExpr( 4139 Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()-1), 4140 Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex())); 4141 4142 stmt = Jimple.v().newIfStmt(co, new FutureStmt()); 4143 break; 4144 4145 case ByteCode.IF_ICMPLT: 4146 co = Jimple.v().newLtExpr( 4147 Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()-1), 4148 Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex())); 4149 4150 stmt = Jimple.v().newIfStmt(co, new FutureStmt()); 4151 break; 4152 4153 case ByteCode.IF_ICMPLE: 4154 co = Jimple.v().newLeExpr( 4155 Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()-1), 4156 Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex())); 4157 4158 stmt = Jimple.v().newIfStmt(co, new FutureStmt()); 4159 break; 4160 4161 case ByteCode.IF_ICMPNE: 4162 co = Jimple.v().newNeExpr( 4163 Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()-1), 4164 Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex())); 4165 4166 stmt = Jimple.v().newIfStmt(co, new FutureStmt()); 4167 break; 4168 4169 case ByteCode.IF_ICMPGT: 4170 co = Jimple.v().newGtExpr( 4171 Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()-1), 4172 Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex())); 4173 4174 stmt = Jimple.v().newIfStmt(co, new FutureStmt()); 4175 break; 4176 4177 case ByteCode.IF_ICMPGE: 4178 co = Jimple.v().newGeExpr( 4179 Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()-1), 4180 Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex())); 4181 4182 stmt = Jimple.v().newIfStmt(co, new FutureStmt()); 4183 break; 4184 4185 case ByteCode.LCMP: 4186 rhs = Jimple.v().newCmpExpr( 4187 Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()-3), 4188 Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()-1)); 4189 4190 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 4191 postTypeStack.topIndex()), rhs); 4192 break; 4193 4194 case ByteCode.FCMPL: 4195 rhs = Jimple.v().newCmplExpr( 4196 Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()-1), 4197 Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex())); 4198 4199 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, 4200 postTypeStack, postTypeStack.topIndex()),rhs); 4201 break; 4202 4203 case ByteCode.FCMPG: 4204 rhs = Jimple.v().newCmpgExpr( 4205 Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()-1), 4206 Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex())); 4207 4208 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, 4209 postTypeStack, postTypeStack.topIndex()),rhs); 4210 break; 4211 4212 case ByteCode.DCMPL: 4213 rhs = Jimple.v().newCmplExpr( 4214 Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()-3), 4215 Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()-1)); 4216 4217 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, 4218 postTypeStack, postTypeStack.topIndex()),rhs); 4219 break; 4220 4221 case ByteCode.DCMPG: 4222 rhs = Jimple.v().newCmpgExpr( 4223 Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()-3), 4224 Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()-1)); 4225 4226 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, 4227 postTypeStack, postTypeStack.topIndex()),rhs); 4228 break; 4229 4230 case ByteCode.IF_ACMPEQ: 4231 co = Jimple.v().newEqExpr( 4232 Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()-1), 4233 Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex())); 4234 4235 stmt = Jimple.v().newIfStmt(co, new FutureStmt()); 4236 break; 4237 4238 case ByteCode.IF_ACMPNE: 4239 co = Jimple.v().newNeExpr( 4240 Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()-1), 4241 Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex())); 4242 4243 stmt = Jimple.v().newIfStmt(co, new FutureStmt()); 4244 break; 4245 4246 case ByteCode.GOTO: 4247 stmt = Jimple.v().newGotoStmt(new FutureStmt()); 4248 break; 4249 4250 case ByteCode.GOTO_W: 4251 stmt = Jimple.v().newGotoStmt(new FutureStmt()); 4252 break; 4253 4269 4270 case ByteCode.RET: 4271 { 4272 Local local = 4273 Util.v().getLocalForIndex(listBody, ((Instruction_Ret)ins).arg_b); 4274 4275 stmt = Jimple.v().newRetStmt(local); 4276 break; 4277 } 4278 4279 case ByteCode.RET_W: 4280 { 4281 Local local = 4282 Util.v().getLocalForIndex(listBody, ((Instruction_Ret_w)ins).arg_i); 4283 4284 4285 stmt = Jimple.v().newRetStmt(local); 4286 break; 4287 } 4288 4289 case ByteCode.RETURN: 4290 stmt = Jimple.v().newReturnVoidStmt(); 4291 break; 4292 4293 case ByteCode.LRETURN: 4294 case ByteCode.DRETURN: 4295 case ByteCode.IRETURN: 4296 case ByteCode.FRETURN: 4297 case ByteCode.ARETURN: 4298 stmt = Jimple.v().newReturnStmt(Util.v().getLocalForStackOp(listBody, 4299 typeStack, typeStack.topIndex())); 4300 break; 4301 4302 case ByteCode.BREAKPOINT: 4303 stmt = Jimple.v().newBreakpointStmt(); 4304 break; 4305 4306 case ByteCode.TABLESWITCH: 4307 { 4308 int lowIndex = ((Instruction_Tableswitch)ins).low, 4309 highIndex = ((Instruction_Tableswitch)ins).high; 4310 4311 stmt = Jimple.v().newTableSwitchStmt( 4312 Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()), 4313 lowIndex, 4314 highIndex, 4315 Arrays.asList(new FutureStmt[highIndex - lowIndex + 1]), 4316 new FutureStmt()); 4317 break; 4318 } 4319 4320 case ByteCode.LOOKUPSWITCH: 4321 { 4322 List matches = new ArrayList(); 4323 int npairs = ((Instruction_Lookupswitch)ins).npairs; 4324 4325 for (int j = 0; j < npairs; j++) 4326 matches.add(IntConstant.v( ((Instruction_Lookupswitch)ins).match_offsets[j*2])); 4327 4328 stmt = Jimple.v().newLookupSwitchStmt( 4329 Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()), 4330 matches, 4331 Arrays.asList(new FutureStmt[npairs]), 4332 new FutureStmt()); 4333 break; 4334 } 4335 4336 case ByteCode.PUTFIELD: 4337 { 4338 CONSTANT_Fieldref_info fieldInfo = 4339 (CONSTANT_Fieldref_info) constant_pool[((Instruction_Putfield)ins).arg_i]; 4340 4341 CONSTANT_Class_info c = 4342 (CONSTANT_Class_info) constant_pool[fieldInfo.class_index]; 4343 4344 String className = ((CONSTANT_Utf8_info) (constant_pool[c.name_index])).convert(); 4345 className = className.replace('/', '.'); 4346 4347 CONSTANT_NameAndType_info i = 4348 (CONSTANT_NameAndType_info) constant_pool[fieldInfo.name_and_type_index]; 4349 4350 String fieldName = ((CONSTANT_Utf8_info) (constant_pool[i.name_index])).convert(); 4351 String fieldDescriptor = ((CONSTANT_Utf8_info) (constant_pool[i.descriptor_index])). 4352 convert(); 4353 4354 Type fieldType = Util.v().jimpleTypeOfFieldDescriptor(fieldDescriptor); 4355 4356 SootClass bclass = cm.getSootClass(className); 4357 4358 SootFieldRef fieldRef = Scene.v().makeFieldRef(bclass, fieldName, fieldType, false); 4359 4360 InstanceFieldRef fr = 4361 Jimple.v().newInstanceFieldRef(Util.v().getLocalForStackOp(listBody, 4362 typeStack, typeStack.topIndex() - typeSize(typeStack.top())), fieldRef); 4363 4364 rvalue = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()); 4365 stmt = Jimple.v().newAssignStmt(fr,rvalue); 4366 break; 4367 } 4368 4369 case ByteCode.GETFIELD: 4370 { 4371 InstanceFieldRef fr = null; 4372 4373 CONSTANT_Fieldref_info fieldInfo = 4374 (CONSTANT_Fieldref_info) constant_pool[((Instruction_Getfield)ins).arg_i]; 4375 4376 CONSTANT_Class_info c = 4377 (CONSTANT_Class_info) constant_pool[fieldInfo.class_index]; 4378 4379 String className = ((CONSTANT_Utf8_info) (constant_pool[c.name_index])).convert(); 4380 className = className.replace('/', '.'); 4381 4382 CONSTANT_NameAndType_info i = 4383 (CONSTANT_NameAndType_info) constant_pool[fieldInfo.name_and_type_index]; 4384 4385 String fieldName = ((CONSTANT_Utf8_info) (constant_pool[i.name_index])).convert(); 4386 String fieldDescriptor = ((CONSTANT_Utf8_info) (constant_pool[i.descriptor_index])). 4387 convert(); 4388 4389 if (className.charAt(0) == '[') 4390 className = "java.lang.Object"; 4391 4392 SootClass bclass = cm.getSootClass(className); 4393 4394 4395 Type fieldType = Util.v().jimpleTypeOfFieldDescriptor(fieldDescriptor); 4396 SootFieldRef fieldRef = Scene.v().makeFieldRef(bclass, fieldName, fieldType, false); 4397 4398 fr = Jimple.v().newInstanceFieldRef(Util.v().getLocalForStackOp(listBody, typeStack, 4399 typeStack.topIndex()), fieldRef); 4400 4401 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 4402 postTypeStack.topIndex()), fr); 4403 break; 4404 } 4405 4406 4407 case ByteCode.PUTSTATIC: 4408 { 4409 StaticFieldRef fr = null; 4410 4411 CONSTANT_Fieldref_info fieldInfo = 4412 (CONSTANT_Fieldref_info) constant_pool[((Instruction_Putstatic)ins).arg_i]; 4413 4414 CONSTANT_Class_info c = 4415 (CONSTANT_Class_info) constant_pool[fieldInfo.class_index]; 4416 4417 String className = ((CONSTANT_Utf8_info) (constant_pool[c.name_index])).convert(); 4418 className = className.replace('/', '.'); 4419 4420 CONSTANT_NameAndType_info i = 4421 (CONSTANT_NameAndType_info) constant_pool[fieldInfo.name_and_type_index]; 4422 4423 String fieldName = ((CONSTANT_Utf8_info) (constant_pool[i.name_index])).convert(); 4424 String fieldDescriptor = ((CONSTANT_Utf8_info) (constant_pool[i.descriptor_index])). 4425 convert(); 4426 4427 Type fieldType = Util.v().jimpleTypeOfFieldDescriptor(fieldDescriptor); 4428 4429 SootClass bclass = cm.getSootClass(className); 4430 SootFieldRef fieldRef = Scene.v().makeFieldRef(bclass, fieldName, fieldType, true); 4431 4432 fr = Jimple.v().newStaticFieldRef(fieldRef); 4433 4434 stmt = Jimple.v().newAssignStmt(fr, Util.v().getLocalForStackOp(listBody, typeStack, 4435 typeStack.topIndex())); 4436 break; 4437 } 4438 4439 case ByteCode.GETSTATIC: 4440 { 4441 StaticFieldRef fr = null; 4442 4443 CONSTANT_Fieldref_info fieldInfo = 4444 (CONSTANT_Fieldref_info) constant_pool[((Instruction_Getstatic)ins).arg_i]; 4445 4446 CONSTANT_Class_info c = 4447 (CONSTANT_Class_info) constant_pool[fieldInfo.class_index]; 4448 4449 String className = ((CONSTANT_Utf8_info) (constant_pool[c.name_index])).convert(); 4450 className = className.replace('/', '.'); 4451 4452 CONSTANT_NameAndType_info i = 4453 (CONSTANT_NameAndType_info) constant_pool[fieldInfo.name_and_type_index]; 4454 4455 String fieldName = ((CONSTANT_Utf8_info) (constant_pool[i.name_index])).convert(); 4456 String fieldDescriptor = ((CONSTANT_Utf8_info) (constant_pool[i.descriptor_index])). 4457 convert(); 4458 4459 Type fieldType = Util.v().jimpleTypeOfFieldDescriptor(fieldDescriptor); 4460 4461 SootClass bclass = cm.getSootClass(className); 4462 SootFieldRef fieldRef = Scene.v().makeFieldRef(bclass, fieldName, fieldType, true); 4463 4464 fr = Jimple.v().newStaticFieldRef(fieldRef); 4465 4466 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 4467 postTypeStack.topIndex()), fr); 4468 break; 4469 } 4470 4471 4472 case ByteCode.INVOKEVIRTUAL: 4473 { 4474 Instruction_Invokevirtual iv = (Instruction_Invokevirtual)ins; 4475 args = cp_info.countParams(constant_pool,iv.arg_i); 4476 4477 SootMethodRef methodRef = null; 4478 4479 CONSTANT_Methodref_info methodInfo = 4480 (CONSTANT_Methodref_info) constant_pool[iv.arg_i]; 4481 4482 CONSTANT_Class_info c = 4483 (CONSTANT_Class_info) constant_pool[methodInfo.class_index]; 4484 4485 String className = ((CONSTANT_Utf8_info) (constant_pool[c.name_index])).convert(); 4486 className = className.replace('/', '.'); 4487 4488 CONSTANT_NameAndType_info i = 4489 (CONSTANT_NameAndType_info) constant_pool[methodInfo.name_and_type_index]; 4490 4491 String methodName = ((CONSTANT_Utf8_info) (constant_pool[i.name_index])).convert(); 4492 String methodDescriptor = ((CONSTANT_Utf8_info) (constant_pool[i.descriptor_index])). 4493 convert(); 4494 4495 if (className.charAt(0) == '[') 4496 className = "java.lang.Object"; 4497 4498 SootClass bclass = cm.getSootClass(className); 4499 4500 Local[] parameters; 4501 List parameterTypes; 4502 Type returnType; 4503 4504 { 4506 Type[] types = Util.v().jimpleTypesOfFieldOrMethodDescriptor(methodDescriptor); 4507 4508 parameterTypes = new ArrayList(); 4509 4510 for(int k = 0; k < types.length - 1; k++) 4511 { 4512 parameterTypes.add(types[k]); 4513 } 4514 4515 returnType = types[types.length - 1]; 4516 } 4517 4518 methodRef = Scene.v().makeMethodRef(bclass, methodName, parameterTypes, returnType, false); 4519 4520 params = new Value[args]; 4522 for (int j=args-1;j>=0;j--) 4523 { 4524 params[j] = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()); 4525 4526 if(typeSize(typeStack.top()) == 2) 4527 { 4528 typeStack = typeStack.pop(); 4529 typeStack = typeStack.pop(); 4530 } 4531 else 4532 typeStack = typeStack.pop(); 4533 } 4534 4535 rvalue = Jimple.v().newVirtualInvokeExpr(Util.v().getLocalForStackOp(listBody, typeStack, 4536 typeStack.topIndex()), methodRef, Arrays.asList(params)); 4537 4538 if(!returnType.equals(VoidType.v())) 4539 { 4540 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 4541 postTypeStack.topIndex()),rvalue); 4542 } 4543 else 4544 stmt = Jimple.v().newInvokeStmt((InvokeExpr) rvalue); 4545 break; 4546 } 4547 4548 case ByteCode.INVOKENONVIRTUAL: 4549 { 4550 Instruction_Invokenonvirtual iv = (Instruction_Invokenonvirtual)ins; 4551 args = cp_info.countParams(constant_pool,iv.arg_i); 4552 4553 SootMethodRef methodRef = null; 4554 4555 CONSTANT_Methodref_info methodInfo = 4556 (CONSTANT_Methodref_info) constant_pool[iv.arg_i]; 4557 4558 CONSTANT_Class_info c = 4559 (CONSTANT_Class_info) constant_pool[methodInfo.class_index]; 4560 4561 String className = ((CONSTANT_Utf8_info) (constant_pool[c.name_index])).convert(); 4562 className = className.replace('/', '.'); 4563 4564 CONSTANT_NameAndType_info i = 4565 (CONSTANT_NameAndType_info) constant_pool[methodInfo.name_and_type_index]; 4566 4567 String methodName = ((CONSTANT_Utf8_info) (constant_pool[i.name_index])).convert(); 4568 String methodDescriptor = ((CONSTANT_Utf8_info) (constant_pool[i.descriptor_index])). 4569 convert(); 4570 4571 SootClass bclass = cm.getSootClass(className); 4572 4573 Local[] parameters; 4574 List parameterTypes; 4575 Type returnType; 4576 4577 { 4579 Type[] types = Util.v().jimpleTypesOfFieldOrMethodDescriptor(methodDescriptor); 4580 4581 parameterTypes = new ArrayList(); 4582 4583 for(int k = 0; k < types.length - 1; k++) 4584 { 4585 parameterTypes.add(types[k]); 4586 } 4587 4588 returnType = types[types.length - 1]; 4589 } 4590 4591 methodRef = Scene.v().makeMethodRef( bclass, methodName, parameterTypes, returnType, false); 4592 4593 params = new Value[args]; 4595 for (int j=args-1;j>=0;j--) 4596 { 4597 params[j] = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()); 4598 4599 if(typeSize(typeStack.top()) == 2) 4600 { 4601 typeStack = typeStack.pop(); 4602 typeStack = typeStack.pop(); 4603 } 4604 else 4605 typeStack = typeStack.pop(); 4606 } 4607 4608 rvalue = Jimple.v().newSpecialInvokeExpr(Util.v().getLocalForStackOp(listBody, typeStack, 4609 typeStack.topIndex()), methodRef, Arrays.asList(params)); 4610 4611 if(!returnType.equals(VoidType.v())) 4612 { 4613 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 4614 postTypeStack.topIndex()), rvalue); 4615 } 4616 else 4617 stmt = Jimple.v().newInvokeStmt((InvokeExpr) rvalue); 4618 break; 4619 } 4620 4621 case ByteCode.INVOKESTATIC: 4622 { 4623 Instruction_Invokestatic is = (Instruction_Invokestatic)ins; 4624 args = cp_info.countParams(constant_pool,is.arg_i); 4625 4626 SootMethodRef methodRef = null; 4627 4628 CONSTANT_Methodref_info methodInfo = 4629 (CONSTANT_Methodref_info) constant_pool[is.arg_i]; 4630 4631 CONSTANT_Class_info c = 4632 (CONSTANT_Class_info) constant_pool[methodInfo.class_index]; 4633 4634 String className = ((CONSTANT_Utf8_info) (constant_pool[c.name_index])).convert(); 4635 className = className.replace('/', '.'); 4636 4637 CONSTANT_NameAndType_info i = 4638 (CONSTANT_NameAndType_info) constant_pool[methodInfo.name_and_type_index]; 4639 4640 String methodName = ((CONSTANT_Utf8_info) (constant_pool[i.name_index])).convert(); 4641 String methodDescriptor = ((CONSTANT_Utf8_info) (constant_pool[i.descriptor_index])). 4642 convert(); 4643 4644 if (className.charAt(0) == '[') 4645 className = "java.lang.Object"; 4646 4647 SootClass bclass = cm.getSootClass(className); 4648 4649 Local[] parameters; 4650 List parameterTypes; 4651 Type returnType; 4652 4653 { 4655 Type[] types = Util.v().jimpleTypesOfFieldOrMethodDescriptor(methodDescriptor); 4656 4657 parameterTypes = new ArrayList(); 4658 4659 for(int k = 0; k < types.length - 1; k++) 4660 { 4661 parameterTypes.add(types[k]); 4662 } 4663 4664 returnType = types[types.length - 1]; 4665 } 4666 4667 methodRef = Scene.v().makeMethodRef(bclass, methodName, parameterTypes, returnType, true); 4668 4669 params = new Value[args]; 4671 for (int j=args-1;j>=0;j--) 4672 { 4673 4679 4680 params[j] = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()); 4681 4682 if(typeSize(typeStack.top()) == 2) 4683 { 4684 typeStack = typeStack.pop(); 4685 typeStack = typeStack.pop(); 4686 } 4687 else 4688 typeStack = typeStack.pop(); 4689 } 4690 4691 rvalue = Jimple.v().newStaticInvokeExpr(methodRef, Arrays.asList(params)); 4692 4693 if(!returnType.equals(VoidType.v())) 4694 { 4695 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 4696 postTypeStack.topIndex()),rvalue); 4697 } 4698 else 4699 stmt = Jimple.v().newInvokeStmt((InvokeExpr) rvalue); 4700 4701 break; 4702 } 4703 4704 case ByteCode.INVOKEINTERFACE: 4705 { 4706 Instruction_Invokeinterface ii = (Instruction_Invokeinterface)ins; 4707 args = cp_info.countParams(constant_pool,ii.arg_i); 4708 4709 SootMethodRef methodRef = null; 4710 4711 CONSTANT_InterfaceMethodref_info methodInfo = 4712 (CONSTANT_InterfaceMethodref_info) constant_pool[ii.arg_i]; 4713 4714 CONSTANT_Class_info c = 4715 (CONSTANT_Class_info) constant_pool[methodInfo.class_index]; 4716 4717 String className = ((CONSTANT_Utf8_info) (constant_pool[c.name_index])).convert(); 4718 className = className.replace('/', '.'); 4719 4720 CONSTANT_NameAndType_info i = 4721 (CONSTANT_NameAndType_info) constant_pool[methodInfo.name_and_type_index]; 4722 4723 String methodName = ((CONSTANT_Utf8_info) (constant_pool[i.name_index])).convert(); 4724 String methodDescriptor = ((CONSTANT_Utf8_info) (constant_pool[i.descriptor_index])). 4725 convert(); 4726 4727 if (className.charAt(0) == '[') 4728 className = "java.lang.Object"; 4729 4730 SootClass bclass = cm.getSootClass(className); 4731 4732 Local[] parameters; 4733 List parameterTypes; 4734 Type returnType; 4735 4736 { 4738 Type[] types = Util.v().jimpleTypesOfFieldOrMethodDescriptor(methodDescriptor); 4739 4740 parameterTypes = new ArrayList(); 4741 4742 for(int k = 0; k < types.length - 1; k++) 4743 { 4744 parameterTypes.add(types[k]); 4745 } 4746 4747 returnType = types[types.length - 1]; 4748 } 4749 4750 methodRef = Scene.v().makeMethodRef(bclass, methodName, parameterTypes, returnType, false); 4751 4752 params = new Value[args]; 4754 for (int j=args-1;j>=0;j--) 4755 { 4756 params[j] = Util.v().getLocalForStackOp(listBody, typeStack, typeStack.topIndex()); 4757 4758 if(typeSize(typeStack.top()) == 2) 4759 { 4760 typeStack = typeStack.pop(); 4761 typeStack = typeStack.pop(); 4762 } 4763 else 4764 typeStack = typeStack.pop(); 4765 } 4766 4767 rvalue = Jimple.v().newInterfaceInvokeExpr(Util.v().getLocalForStackOp(listBody, typeStack, 4768 typeStack.topIndex()), methodRef, Arrays.asList(params)); 4769 4770 if(!returnType.equals(VoidType.v())) 4771 { 4772 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 4773 postTypeStack.topIndex()), rvalue); 4774 } 4775 else 4776 stmt = Jimple.v().newInvokeStmt((InvokeExpr) rvalue); 4777 break; 4778 } 4779 4780 case ByteCode.ATHROW: 4781 stmt = Jimple.v().newThrowStmt(Util.v().getLocalForStackOp(listBody, typeStack, 4782 typeStack.topIndex())); 4783 break; 4784 4785 case ByteCode.NEW: 4786 { 4787 SootClass bclass = cm.getSootClass(getClassName(constant_pool, 4788 ((Instruction_New)ins).arg_i)); 4789 4790 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 4791 postTypeStack.topIndex()), Jimple.v().newNewExpr(RefType.v(bclass.getName()))); 4792 break; 4793 } 4794 4795 case ByteCode.CHECKCAST: 4796 { 4797 String className = getClassName(constant_pool, ((Instruction_Checkcast)ins).arg_i); 4798 4799 Type castType; 4800 4801 if(className.startsWith("[")) 4802 castType = Util.v().jimpleTypeOfFieldDescriptor(getClassName(constant_pool, 4803 ((Instruction_Checkcast)ins).arg_i)); 4804 else 4805 castType = RefType.v(className); 4806 4807 rhs = Jimple.v().newCastExpr(Util.v().getLocalForStackOp(listBody, typeStack, 4808 typeStack.topIndex()), castType); 4809 4810 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 4811 postTypeStack.topIndex()),rhs); 4812 break; 4813 } 4814 4815 case ByteCode.INSTANCEOF: 4816 { 4817 Type checkType; 4818 4819 String className = getClassName(constant_pool, ((Instruction_Instanceof)ins).arg_i); 4820 4821 if(className.startsWith("[")) 4822 checkType = Util.v().jimpleTypeOfFieldDescriptor(getClassName(constant_pool, 4823 ((Instruction_Instanceof)ins).arg_i)); 4824 else 4825 checkType = RefType.v(className); 4826 4827 rhs = Jimple.v().newInstanceOfExpr(Util.v().getLocalForStackOp(listBody, typeStack, 4828 typeStack.topIndex()), checkType); 4829 4830 stmt = Jimple.v().newAssignStmt(Util.v().getLocalForStackOp(listBody, postTypeStack, 4831 postTypeStack.topIndex()),rhs); 4832 break; 4833 } 4834 4835 case ByteCode.MONITORENTER: 4836 stmt = Jimple.v().newEnterMonitorStmt(Util.v().getLocalForStackOp(listBody, typeStack, 4837 typeStack.topIndex())); 4838 break; 4839 case ByteCode.MONITOREXIT: 4840 stmt = Jimple.v().newExitMonitorStmt(Util.v().getLocalForStackOp(listBody, typeStack, 4841 typeStack.topIndex())); 4842 break; 4843 4844 default: 4845 throw new RuntimeException ("Unrecognized bytecode instruction: " + x); 4846 } 4847 4848 if(stmt != null) { 4849 if (Options.v().keep_offset()) { 4850 stmt.addTag(new BytecodeOffsetTag(ins.label)); 4851 } 4852 statements.add(stmt); 4853 } 4854 } 4855 4856 Type jimpleTypeOfAtype(int atype) 4857 { 4858 switch(atype) 4859 { 4860 case 4: 4861 return BooleanType.v(); 4862 4863 case 5: 4864 return CharType.v(); 4865 4866 case 6: 4867 return FloatType.v(); 4868 4869 case 7: 4870 return DoubleType.v(); 4871 4872 case 8: 4873 return ByteType.v(); 4874 4875 case 9: 4876 return ShortType.v(); 4877 4878 case 10: 4879 return IntType.v(); 4880 4881 case 11: 4882 return LongType.v(); 4883 4884 default: 4885 throw new RuntimeException ("Undefined 'atype' in NEWARRAY byte instruction"); 4886 } 4887 } 4888 4889 int typeSize(Type type) 4890 { 4891 if (type.equals(LongType.v()) || type.equals(DoubleType.v()) || 4892 type.equals(Long2ndHalfType.v()) || type.equals(Double2ndHalfType.v())) 4893 { 4894 return 2; 4895 } 4896 else 4897 return 1; 4898 } 4899} 4900 4901class OutFlow 4902{ 4903 TypeStack typeStack; 4904 4905 OutFlow(TypeStack typeStack) 4906 { 4907 this.typeStack = typeStack; 4908 } 4909} 4910 | Popular Tags |