00001 package ca.mcgill.sable.soot.coffi;
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145 import java.util.Hashtable;
00146 import java.util.Enumeration;
00147 import java.util.Vector;
00148 import java.util.NoSuchElementException;
00149
00150 import ca.mcgill.sable.soot.*;
00151 import ca.mcgill.sable.soot.jimple.*;
00152 import ca.mcgill.sable.soot.baf.*;
00153 import ca.mcgill.sable.util.*;
00154
00155
00156
00157
00158
00159
00160 public class CFG {
00161
00162
00163
00164
00165 method_info method;
00166
00167
00168
00169 BasicBlock cfg;
00170
00171 private java.util.Hashtable h;
00172 private int bbcount;
00173
00174 StmtList stmtList;
00175 JimpleBody listBody;
00176
00177 Map instructionToFirstStmt;
00178 Map instructionToLastStmt;
00179 SootMethod jmethod;
00180 SootClassManager cm;
00181
00182 Map instructionToNext;
00183 Instruction firstInstruction;
00184
00185 private short wide;
00186
00187 HashMap JsrToNext = new HashMap();
00188
00189 HashMap RetToJsr = new HashMap();
00190
00191 HashMap RetToJsrBB = new HashMap();
00192
00193 HashMap RetToOrigJsr = new HashMap();
00194
00195 HashMap RetToOrigJsrBB = new HashMap();
00196
00197 HashMap RetToOrigRetBB = new HashMap();
00198
00199 HashMap RetToRetBB = new HashMap();
00200
00201 HashMap RetToJsrSucc = new HashMap();
00202
00203 HashMap RetToOrigJsrSucc = new HashMap();
00204
00205 BasicBlock endofBBList;
00206
00207 BasicBlock highestBlock;
00208
00209
00210
00211
00212
00213 private HashMap clonedstmtsHT = new HashMap();
00214
00215
00216
00217 Map clonedHT = new HashMap();
00218
00219 BasicBlock orighighestBlock;
00220
00221
00222
00223
00224
00225
00226
00227 private HashMap replacedinstructionHT = new HashMap(6, 0.7f);
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241 public CFG(method_info m) {
00242 Instruction i,head;
00243 BasicBlock bb,blast;
00244 method = m;
00245
00246
00247 {
00248 Instruction ins = m.instructions;
00249
00250 m.instructionList = new ArrayList();
00251
00252 while(ins.next != null)
00253 {
00254
00255 m.instructionList.add(ins);
00256
00257
00258 if ( ins instanceof Instruction_Jsr )
00259 JsrToNext.put ( ins, ins.next );
00260
00261 ins = ins.next;
00262
00263 }
00264 }
00265
00266 h = new java.util.Hashtable(100,25);
00267 if (m.instructions!=null) {
00268 i = buildBasicBlock(m.instructions);
00269
00270 cfg = new BasicBlock(m.instructions);
00271 blast = cfg;
00272 h.put(m.instructions,cfg);
00273 while (i != null) {
00274 head = buildBasicBlock(i);
00275
00276 bb = new BasicBlock(i);
00277 blast.next = bb;
00278 blast = bb;
00279 h.put(i,bb);
00280
00281 i = head;
00282 }
00283
00284 buildCFG();
00285
00286 endofBBList = getEndOfBBList();
00287
00288
00289
00290 {
00291
00292 buildJsrRetPairs();
00293
00294 fixupJsrRets();
00295
00296 JsrEliminate();
00297
00298 fixupTargets();
00299
00300 adjustExceptionTable();
00301
00302 prepareForGC();
00303
00304 }
00305
00306
00307
00308 cfg.beginCode = true;
00309 }
00310 m.cfg = this;
00311
00312 if(cfg != null)
00313 firstInstruction = cfg.head;
00314 else
00315 firstInstruction = null;
00316
00317
00318 {
00319 instructionToNext = new HashMap();
00320
00321 BasicBlock b = cfg;
00322 Instruction last = null;
00323
00324 while (b != null)
00325 {
00326 Instruction ins = b.head;
00327
00328 while(ins != null)
00329 {
00330
00331 if(ins.next != null)
00332 instructionToNext.put(ins, ins.next);
00333 else if(b.next != null)
00334 {
00335
00336 instructionToNext.put(ins, b.next.head);
00337
00338 }
00339
00340 ins = ins.next;
00341 }
00342
00343 b = b.next;
00344 }
00345 }
00346
00347 }
00348 private void adjustExceptionTable() {
00349
00350 Code_attribute codeAttribute = method.locate_code_attribute();
00351
00352 for(int i = 0; i < codeAttribute.exception_table_length; i++)
00353 {
00354 Instruction startIns = codeAttribute.exception_table[i].start_inst;
00355
00356 if ( ( ( Instruction ) replacedinstructionHT.get ( startIns ) ) != null )
00357 codeAttribute.exception_table[i].start_inst = ( Instruction ) replacedinstructionHT.get ( startIns );
00358
00359 Instruction endIns = codeAttribute.exception_table[i].end_inst;
00360
00361 if ( ( ( Instruction ) replacedinstructionHT.get ( endIns ) ) != null )
00362 codeAttribute.exception_table[i].end_inst = ( Instruction ) replacedinstructionHT.get ( endIns );
00363
00364 Instruction targetIns = codeAttribute.exception_table[i].handler_inst;
00365
00366 if ( ( ( Instruction ) replacedinstructionHT.get ( targetIns ) ) != null )
00367 codeAttribute.exception_table[i].handler_inst = ( Instruction ) replacedinstructionHT.get ( targetIns );
00368
00369 }
00370
00371 }
00372 private void arrangeclonedBBinorder() {
00373
00374 ArrayList alreadyarranged = new ArrayList();
00375
00376 BasicBlock nextBB = orighighestBlock.next;
00377
00378 BasicBlock nextclonedBB = ( BasicBlock ) clonedHT.get ( nextBB );
00379
00380 BasicBlock currentclonedBB = highestBlock;
00381
00382 alreadyarranged.add ( orighighestBlock );
00383
00384 while ( nextclonedBB != null )
00385 {
00386
00387 alreadyarranged.add ( nextBB );
00388
00389 currentclonedBB.next = nextclonedBB;
00390
00391 currentclonedBB = currentclonedBB.next;
00392
00393 nextBB = nextBB.next;
00394
00395 nextclonedBB = ( BasicBlock ) clonedHT.get ( nextBB );
00396
00397 }
00398
00399 Iterator keysit = clonedHT.entries().iterator();
00400
00401 while ( keysit.hasNext() )
00402 {
00403
00404 BasicBlock bb = ( BasicBlock ) (( Map.Entry ) keysit.next()).getKey();
00405
00406 if ( ! alreadyarranged.contains ( bb ) )
00407 {
00408
00409 nextclonedBB = ( BasicBlock ) clonedHT.get ( bb );
00410
00411 currentclonedBB.next = nextclonedBB;
00412
00413 currentclonedBB = currentclonedBB.next;
00414
00415 }
00416
00417 }
00418
00419 }
00420
00421
00422
00423 private static Instruction buildBasicBlock(Instruction head) {
00424 Instruction newhead,i;
00425 i = head;
00426 while (i!=null) {
00427
00428 if (i.branches || (i.next!=null && i.next.labelled)) {
00429 newhead = i.next;
00430 i.next = null;
00431 return newhead;
00432 }
00433
00434 i = i.next;
00435 }
00436 return null;
00437 }
00438
00439
00440
00441 private void buildCFG() {
00442 BasicBlock b,bb;
00443 Instruction i,branches[],nexti;
00444 int numb,k;
00445 Code_attribute ca = method.locate_code_attribute();
00446 b = cfg;
00447
00448 while (b!=null) {
00449
00450
00451 i = b.tail;
00452 if (i.branches) {
00453
00454
00455 if(i instanceof Instruction_Ret)
00456 {
00457
00458
00459
00460 ListIterator instructionIt = method.instructionList.listIterator();
00461 List branchesList = new ArrayList();
00462
00463 while(instructionIt.hasNext())
00464 {
00465 Instruction ins = (Instruction) instructionIt.next();
00466
00467 if(ins instanceof Instruction_Jsr)
00468 {
00469 ListIterator succIt = method.instructionList.listIterator(
00470 instructionIt.nextIndex());
00471
00472 if(succIt.hasNext())
00473 branchesList.add(succIt.next());
00474 }
00475 }
00476
00477 branches = new Instruction[branchesList.size()];
00478
00479 for(k = 0; k < branches.length; k++)
00480 branches[k] = (Instruction) branchesList.get(k);
00481 } else if (i instanceof Instruction_Athrow) {
00482
00483
00484 int icount = 1;
00485
00486
00487 for (k = 0; k<ca.exception_table_length;k++) {
00488 if (i.label >= ca.exception_table[k].start_inst.label &&
00489 (ca.exception_table[k].end_inst==null ||
00490 i.label < ca.exception_table[k].end_inst.label)) {
00491 icount++;
00492 }
00493 }
00494 branches = new Instruction[icount];
00495 branches[0] = null;
00496 icount = 1;
00497 for (k = 0; k<ca.exception_table_length;k++) {
00498 if (i.label >= ca.exception_table[k].start_inst.label &&
00499 (ca.exception_table[k].end_inst==null ||
00500 i.label < ca.exception_table[k].end_inst.label)) {
00501 branches[icount] = ca.exception_table[k].handler_inst;
00502 }
00503 }
00504 } else {
00505 nexti = (i.next==null) ? ((b.next==null) ? null : b.next.head) : i.next;
00506
00507 branches = i.branchpoints(nexti);
00508
00509 }
00510 if (i.calls) numb = 1;
00511 else numb = 0;
00512 if (branches!=null)
00513 numb += branches.length;
00514 b.succ.ensureCapacity(b.succ.size()+numb);
00515
00516 if (i.calls && b.next!=null) {
00517 b.succ.addElement(b.next);
00518 b.next.pred.addElement(b);
00519 }
00520 if (branches!=null) {
00521 int j;
00522 for (j=0;j<branches.length;j++) {
00523
00524 if (branches[j]!=null) {
00525 bb = (BasicBlock)(h.get(branches[j]));
00526
00527 if (bb==null)
00528 {
00529
00530 System.out.println("Warning: target of a branch is null");
00531 System.out.println ( i );
00532
00533 }
00534 else {
00535 b.succ.addElement(bb);
00536 bb.pred.addElement(b);
00537 }
00538 }
00539 }
00540 }
00541 } else if (b.next!=null) {
00542 b.succ.addElement(b.next);
00543 b.next.pred.addElement(b);
00544 }
00545 b = b.next;
00546 }
00547
00548
00549 for (k=0;k<ca.exception_table_length;k++) {
00550 bb = (BasicBlock)(h.get(ca.exception_table[k].handler_inst));
00551 if (bb==null)
00552 System.out.println("Warning: No basic block found for" +
00553 " start of exception handler code.");
00554 else {
00555 bb.beginException = true;
00556 ca.exception_table[k].b = bb;
00557 }
00558 }
00559 }
00560 private void buildJsrRetPairs() {
00561
00562 BasicBlock b = cfg;
00563
00564 Instruction i = null;
00565
00566 while ( b != null )
00567 {
00568
00569 i = b.tail;
00570
00571 if ( i instanceof Instruction_Jsr)
00572 {
00573
00574 boolean retNotFound = true;
00575
00576 Set successors = new VectorSet();
00577
00578 java.util.Vector succ = b.succ;
00579
00580 for(int k = 0; k < succ.size(); k++)
00581 successors.add((BasicBlock) succ.elementAt(k));
00582
00583 Iterator succIt = successors.iterator();
00584
00585 while ( retNotFound && succIt.hasNext() )
00586 {
00587
00588 BasicBlock succBB = (BasicBlock) succIt.next();
00589
00590 Instruction BBtail = succBB.tail;
00591
00592 if ( BBtail instanceof Instruction_Ret )
00593 {
00594
00595 retNotFound = false;
00596
00597 if ( ( ( Instruction ) RetToJsr.get ( BBtail ) ) == null )
00598 {
00599
00600
00601
00602 RetToJsr.put ( BBtail, i );
00603 RetToJsrBB.put ( BBtail, b );
00604 RetToJsrSucc.put ( BBtail, b.succ.elementAt(0) );
00605 RetToRetBB.put ( BBtail, succBB );
00606 RetToOrigJsrSucc.put ( BBtail, b.succ.elementAt(0) );
00607 RetToOrigJsr.put ( BBtail, i );
00608 RetToOrigJsrBB.put ( BBtail, b );
00609 RetToOrigRetBB.put ( BBtail, succBB );
00610
00611 }
00612 else
00613 {
00614
00615 try {
00616
00617
00618
00619 setHighestBlock ( ( BasicBlock ) b.succ.elementAt(0) );
00620
00621 endofBBList = getEndOfBBList();
00622
00623 highestBlock.next = endofBBList.next;
00624
00625 endofBBList.next = highestBlock;
00626
00627 BasicBlock clonedjsrtargetBB = cloneJsrTargetBB( succBB, ( BasicBlock ) b.succ.elementAt(0) );
00628
00629 arrangeclonedBBinorder();
00630
00631 Code_attribute codeAttribute = method.locate_code_attribute();
00632
00633 int nextind = codeAttribute.exception_table_length;
00634
00635 for(int j = 0; j < codeAttribute.exception_table_length; j++)
00636 {
00637
00638 Instruction startIns = codeAttribute.exception_table[j].start_inst;
00639
00640 Instruction endIns = codeAttribute.exception_table[j].end_inst;
00641
00642 Instruction targetIns = codeAttribute.exception_table[j].handler_inst;
00643
00644 if ( ( ( ( Instruction ) clonedstmtsHT.get ( startIns ) ) != null )
00645 ||( ( ( Instruction ) clonedstmtsHT.get ( endIns ) ) != null )
00646 ||( ( ( Instruction ) clonedstmtsHT.get ( targetIns ) ) != null ) )
00647
00648 {
00649
00650 exception_table_entry[] newexception_table = new exception_table_entry[nextind+1];
00651
00652 for(int k = 0; k < nextind; k++)
00653 newexception_table[k] = codeAttribute.exception_table[k];
00654
00655 newexception_table[nextind] = new exception_table_entry();
00656
00657 codeAttribute.exception_table = newexception_table;
00658
00659 codeAttribute.exception_table_length++;
00660
00661 codeAttribute.exception_table[nextind].catch_type = codeAttribute.exception_table[j].catch_type;
00662
00663 if ( ( ( Instruction ) clonedstmtsHT.get ( startIns ) ) != null )
00664 codeAttribute.exception_table[nextind].start_inst = ( Instruction ) clonedstmtsHT.get ( startIns );
00665 else
00666 codeAttribute.exception_table[nextind].start_inst = startIns;
00667
00668 if ( ( ( Instruction ) clonedstmtsHT.get ( endIns ) ) != null )
00669 codeAttribute.exception_table[nextind].end_inst = ( Instruction ) clonedstmtsHT.get ( endIns );
00670 else
00671 codeAttribute.exception_table[nextind].end_inst = endIns;
00672
00673 if ( ( ( Instruction ) clonedstmtsHT.get ( targetIns ) ) != null )
00674 {
00675 codeAttribute.exception_table[nextind].handler_inst = ( Instruction ) clonedstmtsHT.get ( targetIns );
00676
00677 codeAttribute.exception_table[nextind].b = (BasicBlock) h.get ( ( Instruction ) clonedstmtsHT.get ( targetIns ) );
00678 }
00679 else
00680 {
00681 codeAttribute.exception_table[nextind].handler_inst = targetIns;
00682
00683 codeAttribute.exception_table[nextind].b = (BasicBlock) h.get ( targetIns );
00684 }
00685
00686 nextind++;
00687
00688 }
00689
00690 }
00691
00692
00693 Iterator clonedstmtit = clonedstmtsHT.entries().iterator();
00694
00695 while ( clonedstmtit.hasNext() )
00696 {
00697
00698 Instruction instrn = ( Instruction ) ( ( Map.Entry ) clonedstmtit.next() ).getKey();
00699
00700 Instruction tgt = null;
00701
00702 if ( instrn instanceof Instruction_intbranch )
00703 tgt = (( Instruction_intbranch ) instrn ).target;
00704 else if ( i instanceof Instruction_longbranch )
00705 tgt = (( Instruction_longbranch ) instrn ).target;
00706
00707 if ( tgt != null )
00708 {
00709
00710 Instruction clonedinstrn = ( Instruction ) clonedstmtsHT.get ( instrn );
00711
00712 if ( clonedstmtsHT.get ( tgt ) != null )
00713 {
00714
00715 Instruction clonedtgt = ( Instruction ) clonedstmtsHT.get ( tgt );
00716
00717 if ( instrn instanceof Instruction_intbranch )
00718 (( Instruction_intbranch ) clonedinstrn ).target = clonedtgt;
00719 else if ( i instanceof Instruction_longbranch )
00720 (( Instruction_longbranch ) clonedinstrn ).target = clonedtgt;
00721
00722 }
00723
00724 }
00725
00726 if ( instrn instanceof Instruction_Lookupswitch )
00727 {
00728
00729 Instruction_Lookupswitch ilookup = ( Instruction_Lookupswitch ) instrn;
00730
00731 if ( ( ( Instruction ) clonedstmtsHT.get ( ilookup.default_inst ) ) != null )
00732 ilookup.default_inst = ( Instruction ) clonedstmtsHT.get ( ilookup.default_inst );
00733
00734 for(int cnt=0;cnt<ilookup.npairs;cnt++)
00735 {
00736
00737 if ( ( ( Instruction ) clonedstmtsHT.get ( ilookup.match_insts[cnt]) ) != null )
00738 ilookup.match_insts[cnt] = ( Instruction ) clonedstmtsHT.get ( ilookup.match_insts[cnt] );
00739
00740 }
00741
00742 }
00743
00744 if ( instrn instanceof Instruction_Tableswitch )
00745 {
00746
00747 Instruction_Tableswitch tlookup = ( Instruction_Tableswitch ) instrn;
00748
00749 if ( ( ( Instruction ) clonedstmtsHT.get ( tlookup.default_inst ) ) != null )
00750 tlookup.default_inst = ( Instruction ) clonedstmtsHT.get ( tlookup.default_inst );
00751
00752 for(int cnt=0;cnt<(tlookup.high - tlookup.low + 1);cnt++)
00753 {
00754
00755 if ( ( ( Instruction ) clonedstmtsHT.get ( tlookup.jump_insts[cnt]) ) != null )
00756 tlookup.jump_insts[cnt] = ( Instruction ) clonedstmtsHT.get ( tlookup.jump_insts[cnt] );
00757
00758 }
00759
00760 }
00761
00762 }
00763
00764 RetToOrigJsr.put ( clonedjsrtargetBB.tail, ( Instruction ) RetToJsr.get ( BBtail ) );
00765
00766 RetToOrigJsrBB.put ( clonedjsrtargetBB.tail, ( BasicBlock ) RetToJsrBB.get ( BBtail ) );
00767
00768 RetToOrigRetBB.put ( clonedjsrtargetBB.tail, succBB );
00769
00770 RetToJsr.put ( clonedjsrtargetBB.tail, i );
00771
00772
00773
00774 RetToJsrBB.put ( clonedjsrtargetBB.tail, b );
00775
00776 RetToRetBB.put ( clonedjsrtargetBB.tail, clonedjsrtargetBB );
00777
00778 RetToJsrSucc.put ( clonedjsrtargetBB.tail, highestBlock );
00779
00780 RetToOrigJsrSucc.put ( clonedjsrtargetBB.tail, b.succ.elementAt(0) );
00781
00782 } catch ( java.lang.CloneNotSupportedException e ) {
00783
00784 System.out.println ( "CLONE UNSUCCESSFUL" ); }
00785 }
00786
00787 }
00788 else
00789 {
00790
00791 java.util.Vector succsuccBB = succBB.succ;
00792
00793 for(int n = 0; n < succsuccBB.size(); n++)
00794 {
00795
00796 BasicBlock BBnext = (BasicBlock) succsuccBB.elementAt(n);
00797
00798 successors.add( BBnext );
00799
00800 }
00801
00802 }
00803
00804 }
00805
00806 }
00807
00808 b = b.next;
00809
00810 }
00811
00812 }
00813 private Type byteCodeTypeOf(Type type)
00814 {
00815 if(type.equals(ShortType.v()) ||
00816 type.equals(CharType.v()) ||
00817 type.equals(ByteType.v()) ||
00818 type.equals(BooleanType.v()))
00819 {
00820 return IntType.v();
00821 }
00822 else
00823 return type;
00824 }
00825 private BasicBlock cloneJsrTargetBB( BasicBlock lowestBB, BasicBlock highestBB ) throws java.lang.CloneNotSupportedException {
00826
00827 BasicBlock clonedBB = null;
00828
00829 if ( lowestBB == highestBB )
00830 return highestBlock;
00831 else
00832 {
00833
00834 if ( ( ( BasicBlock ) clonedHT.get ( lowestBB ) == null ) )
00835 {
00836
00837
00838
00839 Instruction prev = lowestBB.head;
00840
00841 Instruction clonedprev = ( Instruction ) prev.clone();
00842
00843 clonedstmtsHT.put ( prev, clonedprev );
00844
00845 Instruction clonedhead = clonedprev;
00846
00847
00848
00849 method.instructionList.add ( clonedhead );
00850
00851 Instruction clonedcurrent = null;
00852
00853 while ( prev != lowestBB.tail )
00854 {
00855
00856 Instruction current = prev.next;
00857
00858 clonedcurrent = ( Instruction ) current.clone();
00859
00860 clonedstmtsHT.put ( current, clonedcurrent );
00861
00862 method.instructionList.add ( clonedcurrent );
00863
00864 clonedprev.next = clonedcurrent;
00865
00866 prev = current;
00867
00868 clonedprev = clonedcurrent;
00869
00870 }
00871
00872 buildBasicBlock( clonedhead );
00873
00874 clonedBB = new BasicBlock(clonedhead);
00875
00876 h.put ( clonedhead, clonedBB );
00877
00878
00879
00880
00881
00882
00883
00884 clonedHT.put ( lowestBB, clonedBB );
00885
00886 java.util.Vector lowestpreds = lowestBB.pred;
00887
00888 for(int n = 0; n < lowestpreds.size(); n++)
00889 {
00890
00891 BasicBlock BBnext = (BasicBlock) lowestpreds.elementAt(n);
00892
00893 if ( lowestBB != BBnext )
00894 {
00895
00896
00897
00898
00899 BasicBlock clonedJsrTargetBB = cloneJsrTargetBB ( BBnext, highestBB );
00900
00901 clonedBB.pred.addElement ( clonedJsrTargetBB );
00902
00903 clonedJsrTargetBB.succ.addElement ( clonedBB );
00904
00905 }
00906
00907 }
00908
00909 }
00910 else
00911 clonedBB = ( BasicBlock ) clonedHT.get ( lowestBB );
00912
00913 }
00914
00915 return clonedBB;
00916
00917 }
00918 void confirmRefType(Type actualType)
00919 {
00920
00921
00922
00923
00924 }
00925 void confirmType(Type actualType, Type requiredType)
00926 {
00927
00928
00929
00930
00931 }
00932 private void fixupJsrRets() {
00933
00934 BasicBlock b = cfg;
00935
00936 Instruction i = null;
00937
00938 while ( b != null )
00939 {
00940
00941 i = b.tail;
00942
00943 if ( i instanceof Instruction_Ret )
00944 {
00945
00946 Instruction_Jsr matchingjsr = ( Instruction_Jsr) RetToJsr.get ( i );
00947
00948 BasicBlock matchingjsrBB = ( BasicBlock ) RetToJsrBB.get ( i );
00949
00950 java.util.Vector succOfmatchingjsr = matchingjsrBB.succ;
00951
00952 BasicBlock WrongsuccBB = null;
00953
00954 BasicBlock OrigsuccBB = (BasicBlock) succOfmatchingjsr.elementAt(0);
00955
00956 BasicBlock NewsuccBB = ( BasicBlock ) RetToJsrSucc.get ( i );
00957
00958 if ( OrigsuccBB != NewsuccBB )
00959 WrongsuccBB = OrigsuccBB;
00960
00961 if ( WrongsuccBB != null )
00962 {
00963
00964 BasicBlock OrigretBB = ( BasicBlock ) RetToOrigRetBB.get ( i );
00965
00966 BasicBlock OrigjsrBB = ( BasicBlock ) RetToOrigJsrBB.get ( i );
00967
00968 BasicBlock OrigjsrnextBB = null;
00969
00970 OrigjsrnextBB = ( BasicBlock) h.get ( (Instruction ) JsrToNext.get ( OrigjsrBB.tail) );
00971
00972 BasicBlock matchingjsrnextBB = null;
00973
00974 matchingjsrnextBB = ( BasicBlock) h.get ( (Instruction ) JsrToNext.get ( matchingjsrBB.tail ) );
00975
00976 OrigsuccBB.pred.removeElement ( matchingjsrBB );
00977
00978 OrigretBB.succ.removeElement ( matchingjsrnextBB );
00979
00980 matchingjsrBB.succ.addElement ( NewsuccBB );
00981
00982 matchingjsrBB.succ.removeElement ( OrigsuccBB );
00983
00984 matchingjsrnextBB.pred.addElement ( b );
00985
00986 matchingjsrnextBB.pred.removeElement ( OrigretBB );
00987
00988 for ( int k=NewsuccBB.pred.size() -1; k > -1;k-- )
00989 {
00990
00991 BasicBlock tempBB = ( BasicBlock ) NewsuccBB.pred.elementAt ( k );
00992
00993 if ( tempBB.tail instanceof Instruction_Jsr )
00994 NewsuccBB.pred.removeElement ( tempBB );
00995
00996 }
00997
00998 NewsuccBB.pred.addElement ( matchingjsrBB );
00999
01000 b.succ.removeAllElements();
01001
01002 b.succ.addElement ( matchingjsrnextBB );
01003
01004 }
01005
01006 }
01007
01008 b = b.next;
01009
01010 }
01011
01012 }
01013 private void fixupTargets() {
01014
01015 BasicBlock b = cfg;
01016
01017 Instruction i = null;
01018
01019 while ( b != null )
01020 {
01021
01022 i = b.head;
01023
01024 while ( i != null )
01025 {
01026
01027 if ( i.branches )
01028 {
01029
01030 Instruction tgt = null;
01031
01032 if ( i instanceof Instruction_intbranch )
01033 tgt = (( Instruction_intbranch ) i ).target;
01034 else if ( i instanceof Instruction_longbranch )
01035 tgt = (( Instruction_longbranch ) i ).target;
01036
01037 if ( tgt != null )
01038 {
01039
01040 if ( ( ( Instruction ) replacedinstructionHT.get ( tgt ) ) != null )
01041 {
01042
01043 if ( i instanceof Instruction_intbranch )
01044 {
01045 ( ( Instruction_intbranch ) i ).target = ( Instruction ) replacedinstructionHT.get ( tgt );
01046
01047
01048 }
01049 else if ( i instanceof Instruction_longbranch )
01050 ( ( Instruction_longbranch ) i ).target = ( Instruction ) replacedinstructionHT.get ( tgt );
01051
01052 }
01053
01054 }
01055
01056 if ( i instanceof Instruction_Lookupswitch )
01057 {
01058
01059 Instruction_Lookupswitch ilookup = ( Instruction_Lookupswitch ) i;
01060
01061 if ( ( ( Instruction ) replacedinstructionHT.get ( ilookup.default_inst ) ) != null )
01062 ilookup.default_inst = ( Instruction ) replacedinstructionHT.get ( ilookup.default_inst );
01063
01064 for(int cnt=0;cnt<ilookup.npairs;cnt++)
01065 {
01066
01067 if ( ( ( Instruction ) replacedinstructionHT.get ( ilookup.match_insts[cnt]) ) != null )
01068 ilookup.match_insts[cnt] = ( Instruction ) replacedinstructionHT.get ( ilookup.match_insts[cnt] );
01069
01070 }
01071
01072 }
01073
01074 if ( i instanceof Instruction_Tableswitch )
01075 {
01076
01077 Instruction_Tableswitch tlookup = ( Instruction_Tableswitch ) i;
01078
01079 if ( ( ( Instruction ) replacedinstructionHT.get ( tlookup.default_inst ) ) != null )
01080 tlookup.default_inst = ( Instruction ) replacedinstructionHT.get ( tlookup.default_inst );
01081
01082 for(int cnt=0;cnt<(tlookup.high - tlookup.low + 1);cnt++)
01083 {
01084
01085 if ( ( ( Instruction ) replacedinstructionHT.get ( tlookup.jump_insts[cnt]) ) != null )
01086 tlookup.jump_insts[cnt] = ( Instruction ) replacedinstructionHT.get ( tlookup.jump_insts[cnt] );
01087
01088 }
01089
01090 }
01091
01092 }
01093
01094 i = i.next;
01095
01096 }
01097
01098 b = b.next;
01099
01100 }
01101
01102 }
01103 void generateJimple(Instruction ins, TypeStack typeStack, TypeStack postTypeStack,
01104 cp_info constant_pool[],
01105 List statements, BasicBlock basicBlock)
01106 {
01107 Value[] params;
01108 Value v1=null,v2=null,v3=null,v4=null;
01109 Local l1 = null, l2 = null, l3 = null, l4 = null;
01110
01111 Expr e=null,rhs=null;
01112 BinopExpr b=null;
01113 ConditionExpr co = null;
01114
01115 ArrayRef a=null;
01116 int args;
01117 Value rvalue;
01118
01119 int localIndex;
01120
01121 Stmt stmt = null;
01122
01123 int x = ((int)(ins.code))&0xff;
01124
01125 switch(x)
01126 {
01127 case ByteCode.BIPUSH:
01128 rvalue = IntConstant.v(((Instruction_Bipush)ins).arg_b);
01129 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01130 postTypeStack.topIndex()), rvalue);
01131 break;
01132
01133 case ByteCode.SIPUSH:
01134 rvalue = IntConstant.v(((Instruction_Sipush)ins).arg_i);
01135 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01136 postTypeStack.topIndex()), rvalue);
01137 break;
01138
01139 case ByteCode.LDC1:
01140 generateJimpleForCPEntry(constant_pool,((Instruction_Ldc1)ins).arg_b, typeStack, postTypeStack,
01141 jmethod, statements);
01142 break;
01143
01144 case ByteCode.LDC2:
01145 case ByteCode.LDC2W:
01146 generateJimpleForCPEntry(constant_pool, ((Instruction_intindex)ins).arg_i,
01147 typeStack, postTypeStack, jmethod, statements);
01148 break;
01149
01150 case ByteCode.ACONST_NULL:
01151 rvalue = NullConstant.v();
01152 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01153 postTypeStack.topIndex()), rvalue);
01154 break;
01155
01156 case ByteCode.ICONST_M1:
01157 case ByteCode.ICONST_0:
01158 case ByteCode.ICONST_1:
01159 case ByteCode.ICONST_2:
01160 case ByteCode.ICONST_3:
01161 case ByteCode.ICONST_4:
01162 case ByteCode.ICONST_5:
01163 rvalue = IntConstant.v(x-ByteCode.ICONST_0);
01164 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01165 postTypeStack.topIndex()), rvalue);
01166 break;
01167
01168 case ByteCode.LCONST_0:
01169 case ByteCode.LCONST_1:
01170 rvalue = LongConstant.v(x-ByteCode.LCONST_0);
01171 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01172 postTypeStack.topIndex()), rvalue);
01173 break;
01174
01175 case ByteCode.FCONST_0:
01176 case ByteCode.FCONST_1:
01177 case ByteCode.FCONST_2:
01178 rvalue = FloatConstant.v((float)(x - ByteCode.FCONST_0));
01179 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01180 postTypeStack.topIndex()), rvalue);
01181 break;
01182
01183 case ByteCode.DCONST_0:
01184 case ByteCode.DCONST_1:
01185 rvalue = DoubleConstant.v((double)(x-ByteCode.DCONST_0));
01186 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01187 postTypeStack.topIndex()), rvalue);
01188 break;
01189
01190 case ByteCode.ILOAD:
01191 {
01192 Local local = (Local)
01193 Util.getLocalForIndex(listBody, ((Instruction_bytevar) ins).arg_b);
01194
01195 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01196 postTypeStack.topIndex()), local);
01197 break;
01198 }
01199
01200 case ByteCode.FLOAD:
01201 {
01202 Local local = (Local)
01203 Util.getLocalForIndex(listBody, ((Instruction_bytevar)ins).arg_b);
01204
01205 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01206 postTypeStack.topIndex()), local);
01207 break;
01208 }
01209
01210 case ByteCode.ALOAD:
01211 {
01212 Local local =
01213 Util.getLocalForIndex(listBody, ((Instruction_bytevar)ins).arg_b);
01214
01215 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01216 postTypeStack.topIndex()), local);
01217 break;
01218 }
01219
01220 case ByteCode.DLOAD:
01221 {
01222 Local local =
01223 Util.getLocalForIndex(listBody, ((Instruction_bytevar)ins).arg_b);
01224
01225 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01226 postTypeStack.topIndex()), local);
01227 break;
01228 }
01229
01230 case ByteCode.LLOAD:
01231 {
01232 Local local =
01233 Util.getLocalForIndex(listBody, ((Instruction_bytevar)ins).arg_b);
01234
01235 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01236 postTypeStack.topIndex()), local);
01237 break;
01238 }
01239
01240 case ByteCode.ILOAD_0:
01241 case ByteCode.ILOAD_1:
01242 case ByteCode.ILOAD_2:
01243 case ByteCode.ILOAD_3:
01244 {
01245 Local local =
01246 Util.getLocalForIndex(listBody, (x - ByteCode.ILOAD_0));
01247
01248 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01249 postTypeStack.topIndex()), local);
01250 break;
01251 }
01252
01253 case ByteCode.FLOAD_0:
01254 case ByteCode.FLOAD_1:
01255 case ByteCode.FLOAD_2:
01256 case ByteCode.FLOAD_3:
01257 {
01258 Local local =
01259 Util.getLocalForIndex(listBody, (x - ByteCode.FLOAD_0));
01260
01261 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01262 postTypeStack.topIndex()), local);
01263 break;
01264 }
01265
01266 case ByteCode.ALOAD_0:
01267 case ByteCode.ALOAD_1:
01268 case ByteCode.ALOAD_2:
01269 case ByteCode.ALOAD_3:
01270 {
01271 Local local =
01272 Util.getLocalForIndex(listBody, (x - ByteCode.ALOAD_0));
01273
01274 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01275 postTypeStack.topIndex()), local);
01276 break;
01277 }
01278
01279 case ByteCode.LLOAD_0:
01280 case ByteCode.LLOAD_1:
01281 case ByteCode.LLOAD_2:
01282 case ByteCode.LLOAD_3:
01283 {
01284 Local local =
01285 Util.getLocalForIndex(listBody, (x - ByteCode.LLOAD_0));
01286
01287 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01288 postTypeStack.topIndex()), local);
01289 break;
01290 }
01291
01292 case ByteCode.DLOAD_0:
01293 case ByteCode.DLOAD_1:
01294 case ByteCode.DLOAD_2:
01295 case ByteCode.DLOAD_3:
01296 {
01297 Local local =
01298 Util.getLocalForIndex(listBody, (x - ByteCode.DLOAD_0));
01299
01300 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01301 postTypeStack.topIndex()), local);
01302 break;
01303 }
01304
01305 case ByteCode.ISTORE:
01306 {
01307 Local local =
01308 Util.getLocalForIndex(listBody,
01309 ((Instruction_bytevar)ins).arg_b);
01310
01311 stmt = Jimple.v().newAssignStmt(local, Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
01312 break;
01313 }
01314
01315 case ByteCode.FSTORE:
01316 {
01317 Local local =
01318 Util.getLocalForIndex(listBody,
01319 ((Instruction_bytevar)ins).arg_b);
01320
01321 stmt = Jimple.v().newAssignStmt(local, Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
01322 break;
01323 }
01324
01325 case ByteCode.ASTORE:
01326 {
01327 Local local =
01328 Util.getLocalForIndex(listBody,
01329 ((Instruction_bytevar)ins).arg_b);
01330
01331 stmt = Jimple.v().newAssignStmt(local, Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
01332 break;
01333 }
01334
01335 case ByteCode.LSTORE:
01336 {
01337 Local local =
01338 Util.getLocalForIndex(listBody,
01339 ((Instruction_bytevar)ins).arg_b);
01340
01341 stmt = Jimple.v().newAssignStmt(local, Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
01342 break;
01343 }
01344
01345 case ByteCode.DSTORE:
01346 {
01347 Local local =
01348 Util.getLocalForIndex(listBody,
01349 ((Instruction_bytevar)ins).arg_b);
01350
01351 stmt = Jimple.v().newAssignStmt(local, Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
01352 break;
01353 }
01354
01355 case ByteCode.ISTORE_0:
01356 case ByteCode.ISTORE_1:
01357 case ByteCode.ISTORE_2:
01358 case ByteCode.ISTORE_3:
01359 {
01360 Local local =
01361 Util.getLocalForIndex(listBody, (x - ByteCode.ISTORE_0));
01362
01363 stmt = Jimple.v().newAssignStmt(local, Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
01364 break;
01365 }
01366
01367 case ByteCode.FSTORE_0:
01368 case ByteCode.FSTORE_1:
01369 case ByteCode.FSTORE_2:
01370 case ByteCode.FSTORE_3:
01371 {
01372 Local local = (Local)
01373 Util.getLocalForIndex(listBody, (x - ByteCode.FSTORE_0));
01374
01375 stmt = Jimple.v().newAssignStmt(local, Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
01376 break;
01377 }
01378
01379 case ByteCode.ASTORE_0:
01380 case ByteCode.ASTORE_1:
01381 case ByteCode.ASTORE_2:
01382 case ByteCode.ASTORE_3:
01383 {
01384 Local local = Util.getLocalForIndex(listBody, (x - ByteCode.ASTORE_0));
01385
01386 stmt = Jimple.v().newAssignStmt(local, Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
01387 break;
01388 }
01389
01390 case ByteCode.LSTORE_0:
01391 case ByteCode.LSTORE_1:
01392 case ByteCode.LSTORE_2:
01393 case ByteCode.LSTORE_3:
01394 {
01395 Local local =
01396 Util.getLocalForIndex(listBody, (x - ByteCode.LSTORE_0));
01397
01398 stmt = Jimple.v().newAssignStmt(local, Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
01399 break;
01400 }
01401
01402 case ByteCode.DSTORE_0:
01403 case ByteCode.DSTORE_1:
01404 case ByteCode.DSTORE_2:
01405 case ByteCode.DSTORE_3:
01406 {
01407 Local local =
01408 Util.getLocalForIndex(listBody, (x - ByteCode.DSTORE_0));
01409
01410 stmt = Jimple.v().newAssignStmt(local, Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
01411 break;
01412 }
01413
01414 case ByteCode.IINC:
01415 {
01416 Local local =
01417 Util.getLocalForIndex(listBody,
01418 ((Instruction_Iinc)ins).arg_b);
01419
01420 int amt = (((Instruction_Iinc)ins).arg_c);
01421 rhs = Jimple.v().newAddExpr(local, IntConstant.v(amt));
01422 stmt = Jimple.v().newAssignStmt(local,rhs);
01423 break;
01424 }
01425
01426 case ByteCode.WIDE:
01427 throw new RuntimeException("WIDE instruction should not be encountered anymore");
01428
01429
01430 case ByteCode.NEWARRAY:
01431 {
01432 BaseType baseType = (BaseType) jimpleTypeOfAtype(((Instruction_Newarray)ins).atype);
01433
01434 rhs = Jimple.v().newNewArrayExpr(baseType,
01435 Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
01436
01437 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody,
01438 postTypeStack, postTypeStack.topIndex()), rhs);
01439
01440 break;
01441 }
01442
01443 case ByteCode.ANEWARRAY:
01444 {
01445 String baseName = getClassName(constant_pool, ((Instruction_Anewarray)ins).arg_i);
01446
01447 Type baseType;
01448
01449 if(baseName.startsWith("["))
01450 baseType = Util.jimpleTypeOfFieldDescriptor(cm,
01451 getClassName(constant_pool, ((Instruction_Anewarray)ins).arg_i));
01452 else
01453 baseType = RefType.v(baseName);
01454
01455 rhs = Jimple.v().newNewArrayExpr(baseType, Util.getLocalForStackOp(listBody,
01456 typeStack, typeStack.topIndex()));
01457
01458 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody,
01459 postTypeStack, postTypeStack.topIndex()),rhs);
01460 break;
01461 }
01462
01463 case ByteCode.MULTIANEWARRAY:
01464 {
01465 int bdims = (int)(((Instruction_Multianewarray)ins).dims);
01466 List dims = new ArrayList();
01467
01468 for (int j=0; j < bdims; j++)
01469 dims.add(Util.getLocalForStackOp(listBody, typeStack,
01470 typeStack.topIndex() - bdims + j + 1));
01471
01472 String mstype = constant_pool[((Instruction_Multianewarray)ins).arg_i].
01473 toString(constant_pool);
01474
01475 ArrayType jimpleType = (ArrayType) Util.jimpleTypeOfFieldDescriptor(cm, mstype);
01476
01477 rhs = Jimple.v().newNewMultiArrayExpr(jimpleType, dims);
01478
01479 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01480 postTypeStack.topIndex()),rhs);
01481 break;
01482 }
01483
01484
01485 case ByteCode.ARRAYLENGTH:
01486 rhs = Jimple.v().newLengthExpr(
01487 Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
01488
01489 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01490 postTypeStack.topIndex()),rhs);
01491 break;
01492
01493 case ByteCode.IALOAD:
01494 case ByteCode.BALOAD:
01495 case ByteCode.CALOAD:
01496 case ByteCode.SALOAD:
01497 case ByteCode.FALOAD:
01498 case ByteCode.LALOAD:
01499 case ByteCode.DALOAD:
01500 case ByteCode.AALOAD:
01501 a = Jimple.v().newArrayRef(Util.getLocalForStackOp(listBody, typeStack,
01502 typeStack.topIndex() - 1),
01503 Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
01504
01505 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody,
01506 postTypeStack, postTypeStack.topIndex()), a);
01507
01508 break;
01509
01510 case ByteCode.IASTORE:
01511 case ByteCode.FASTORE:
01512 case ByteCode.AASTORE:
01513 case ByteCode.BASTORE:
01514 case ByteCode.CASTORE:
01515 case ByteCode.SASTORE:
01516 a = Jimple.v().newArrayRef(Util.getLocalForStackOp(listBody, typeStack,
01517 typeStack.topIndex() - 2), Util.getLocalForStackOp(listBody, typeStack,
01518 typeStack.topIndex() - 1));
01519
01520 stmt = Jimple.v().newAssignStmt(a, Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
01521 break;
01522
01523 case ByteCode.LASTORE:
01524 case ByteCode.DASTORE:
01525 a = Jimple.v().newArrayRef(Util.getLocalForStackOp(listBody, typeStack,
01526 typeStack.topIndex() - 3), Util.getLocalForStackOp(listBody, typeStack,
01527 typeStack.topIndex() - 2));
01528
01529 stmt = Jimple.v().newAssignStmt(a, Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
01530 break;
01531
01532
01533 case ByteCode.NOP:
01534 stmt = Jimple.v().newNopStmt();
01535 break;
01536
01537 case ByteCode.POP:
01538 case ByteCode.POP2:
01539 stmt = Jimple.v().newNopStmt();
01540 break;
01541
01542 case ByteCode.DUP:
01543 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01544 postTypeStack.topIndex()), Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
01545 break;
01546
01547 case ByteCode.DUP2:
01548 if(typeSize(typeStack.top()) == 2)
01549 {
01550 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01551 postTypeStack.topIndex() - 1),
01552 Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1));
01553 }
01554 else {
01555 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01556 postTypeStack.topIndex() - 1),
01557 Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1));
01558
01559 statements.add(stmt);
01560
01561 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01562 postTypeStack.topIndex()), Util.getLocalForStackOp(listBody,
01563 typeStack, typeStack.topIndex()));
01564
01565 statements.add(stmt);
01566
01567 stmt = null;
01568 }
01569 break;
01570
01571 case ByteCode.DUP_X1:
01572 l1 = Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex());
01573 l2 = Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()-1);
01574
01575 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01576 postTypeStack.topIndex()), l1);
01577
01578 statements.add(stmt);
01579
01580 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01581 postTypeStack.topIndex() - 1), l2);
01582
01583 statements.add(stmt);
01584
01585 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01586 postTypeStack.topIndex() - 2), Util.getLocalForStackOp(listBody,
01587 postTypeStack, postTypeStack.topIndex()));
01588
01589 statements.add(stmt);
01590
01591 stmt = null;
01592 break;
01593
01594 case ByteCode.DUP_X2:
01595 if(typeSize(typeStack.get(typeStack.topIndex() - 2)) == 2)
01596 {
01597 l3 = Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 2);
01598 l1 = Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex());
01599
01600 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01601 postTypeStack.topIndex() - 3), l1);
01602
01603 statements.add(stmt);
01604
01605 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01606 postTypeStack.topIndex() - 2), l3);
01607
01608 statements.add(stmt);
01609
01610 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01611 postTypeStack.topIndex()), l1);
01612
01613 statements.add(stmt);
01614
01615 stmt = null;
01616 }
01617 else {
01618 l3 = Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 2);
01619 l2 = Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1);
01620 l1 = Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex());
01621
01622 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01623 postTypeStack.topIndex()), l1);
01624
01625 statements.add(stmt);
01626
01627 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01628 postTypeStack.topIndex() - 1), l2);
01629
01630 statements.add(stmt);
01631
01632 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01633 postTypeStack.topIndex() - 2), l3);
01634
01635 statements.add(stmt);
01636
01637 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01638 postTypeStack.topIndex() - 3), Util.getLocalForStackOp(
01639 listBody, postTypeStack, postTypeStack.topIndex()));
01640
01641 statements.add(stmt);
01642
01643 stmt = null;
01644 }
01645 break;
01646
01647 case ByteCode.DUP2_X1:
01648 if(typeSize(typeStack.get(typeStack.topIndex() - 1)) == 2)
01649 {
01650 l2 = Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1);
01651 l3 = Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 2);
01652
01653 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01654 postTypeStack.topIndex() -1), l2);
01655
01656 statements.add(stmt);
01657
01658 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01659 postTypeStack.topIndex() - 2), l3);
01660
01661 statements.add(stmt);
01662
01663 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01664 postTypeStack.topIndex() - 4),
01665 Util.getLocalForStackOp(listBody, postTypeStack, postTypeStack.topIndex() - 1));
01666
01667 statements.add(stmt);
01668
01669 stmt = null;
01670 }
01671 else {
01672 l3 = Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 2);
01673 l2 = Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1);
01674 l1 = Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex());
01675
01676 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01677 postTypeStack.topIndex()), l1);
01678
01679 statements.add(stmt);
01680
01681 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01682 postTypeStack.topIndex() - 1), l2);
01683
01684 statements.add(stmt);
01685
01686 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01687 postTypeStack.topIndex() - 2), l3);
01688
01689 statements.add(stmt);
01690
01691 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01692 postTypeStack.topIndex() - 3), Util.getLocalForStackOp(
01693 listBody, postTypeStack, postTypeStack.topIndex()));
01694
01695 statements.add(stmt);
01696
01697 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01698 postTypeStack.topIndex() - 4), Util.getLocalForStackOp(
01699 listBody, postTypeStack, postTypeStack.topIndex() - 1));
01700
01701 statements.add(stmt);
01702
01703 stmt = null;
01704 }
01705 break;
01706
01707 case ByteCode.DUP2_X2:
01708 if(typeSize(typeStack.get(typeStack.topIndex() - 1)) == 2)
01709 {
01710 l2 = Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1);
01711
01712 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01713 postTypeStack.topIndex() - 1), l2);
01714
01715 statements.add(stmt);
01716 }
01717 else {
01718 l1 = Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex());
01719 l2 = Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 1);
01720
01721 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01722 postTypeStack.topIndex() - 1), l2);
01723
01724 statements.add(stmt);
01725
01726 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01727 postTypeStack.topIndex()), l1);
01728
01729 statements.add(stmt);
01730
01731 }
01732
01733 if(typeSize(typeStack.get(typeStack.topIndex() - 3)) == 2)
01734 {
01735 l4 = Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 3);
01736
01737 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01738 postTypeStack.topIndex() - 3), l4);
01739
01740 statements.add(stmt);
01741 }
01742 else {
01743 l4 = Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 3);
01744 l3 = Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex() - 2);
01745
01746 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01747 postTypeStack.topIndex() - 3), l4);
01748
01749 statements.add(stmt);
01750
01751 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01752 postTypeStack.topIndex() - 2), l3);
01753
01754 statements.add(stmt);
01755
01756 }
01757
01758 if(typeSize(typeStack.get(typeStack.topIndex() - 1)) == 2)
01759 {
01760 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01761 postTypeStack.topIndex() - 5), Util.getLocalForStackOp(
01762 listBody, postTypeStack, postTypeStack.topIndex() - 1));
01763
01764 statements.add(stmt);
01765 }
01766 else {
01767 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01768 postTypeStack.topIndex() - 5), Util.getLocalForStackOp(
01769 listBody, postTypeStack, postTypeStack.topIndex() - 1));
01770
01771 statements.add(stmt);
01772
01773 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01774 postTypeStack.topIndex() - 4), Util.getLocalForStackOp(
01775 listBody, postTypeStack, postTypeStack.topIndex()));
01776
01777 statements.add(stmt);
01778 }
01779 stmt = null;
01780 break;
01781
01782 case ByteCode.SWAP:
01783 {
01784 Local first;
01785
01786 typeStack = typeStack.push(typeStack.top());
01787 first = Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex());
01788 typeStack = typeStack.pop();
01789
01790
01791 Local second = Util.getLocalForStackOp(listBody, postTypeStack,
01792 postTypeStack.topIndex());
01793
01794 Local third = Util.getLocalForStackOp(listBody, postTypeStack,
01795 postTypeStack.topIndex() - 1);
01796
01797 stmt = Jimple.v().newAssignStmt(first, second);
01798 statements.add(stmt);
01799
01800 stmt = Jimple.v().newAssignStmt(second, third);
01801 statements.add(stmt);
01802
01803 stmt = Jimple.v().newAssignStmt(third, first);
01804 statements.add(stmt);
01805
01806 stmt = null;
01807 break;
01808 }
01809
01810 case ByteCode.FADD:
01811 case ByteCode.IADD:
01812 rhs = Jimple.v().newAddExpr(Util.getLocalForStackOp(listBody, typeStack,
01813 typeStack.topIndex() - 1), Util.getLocalForStackOp(listBody, typeStack,
01814 typeStack.topIndex()));
01815
01816 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01817 postTypeStack.topIndex()), rhs);
01818 break;
01819
01820 case ByteCode.DADD:
01821 case ByteCode.LADD:
01822 rhs = Jimple.v().newAddExpr(Util.getLocalForStackOp(listBody, typeStack,
01823 typeStack.topIndex() - 3), Util.getLocalForStackOp(listBody, typeStack,
01824 typeStack.topIndex() - 1));
01825
01826 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01827 postTypeStack.topIndex()), rhs);
01828 break;
01829
01830 case ByteCode.FSUB:
01831 case ByteCode.ISUB:
01832 rhs = Jimple.v().newSubExpr(Util.getLocalForStackOp(listBody, typeStack,
01833 typeStack.topIndex() - 1), Util.getLocalForStackOp(listBody, typeStack,
01834 typeStack.topIndex()));
01835
01836 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01837 postTypeStack.topIndex()), rhs);
01838 break;
01839
01840 case ByteCode.DSUB:
01841 case ByteCode.LSUB:
01842 rhs = Jimple.v().newSubExpr(Util.getLocalForStackOp(listBody, typeStack,
01843 typeStack.topIndex() - 3), Util.getLocalForStackOp(listBody, typeStack,
01844 typeStack.topIndex() - 1));
01845
01846 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01847 postTypeStack.topIndex()), rhs);
01848 break;
01849
01850 case ByteCode.FMUL:
01851 case ByteCode.IMUL:
01852 rhs = Jimple.v().newMulExpr(Util.getLocalForStackOp(listBody, typeStack,
01853 typeStack.topIndex() - 1), Util.getLocalForStackOp(listBody, typeStack,
01854 typeStack.topIndex()));
01855
01856 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01857 postTypeStack.topIndex()), rhs);
01858 break;
01859
01860 case ByteCode.DMUL:
01861 case ByteCode.LMUL:
01862 rhs = Jimple.v().newMulExpr(Util.getLocalForStackOp(listBody, typeStack,
01863 typeStack.topIndex() - 3), Util.getLocalForStackOp(listBody, typeStack,
01864 typeStack.topIndex() - 1));
01865
01866 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01867 postTypeStack.topIndex()), rhs);
01868 break;
01869
01870 case ByteCode.FDIV:
01871 case ByteCode.IDIV:
01872 rhs = Jimple.v().newDivExpr(Util.getLocalForStackOp(listBody, typeStack,
01873 typeStack.topIndex() - 1), Util.getLocalForStackOp(listBody, typeStack,
01874 typeStack.topIndex()));
01875
01876 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01877 postTypeStack.topIndex()), rhs);
01878 break;
01879
01880 case ByteCode.DDIV:
01881 case ByteCode.LDIV:
01882 rhs = Jimple.v().newDivExpr(Util.getLocalForStackOp(listBody, typeStack,
01883 typeStack.topIndex() - 3), Util.getLocalForStackOp(listBody, typeStack,
01884 typeStack.topIndex() - 1));
01885
01886 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01887 postTypeStack.topIndex()), rhs);
01888 break;
01889
01890 case ByteCode.FREM:
01891 case ByteCode.IREM:
01892 rhs = Jimple.v().newRemExpr(Util.getLocalForStackOp(listBody, typeStack,
01893 typeStack.topIndex() - 1), Util.getLocalForStackOp(listBody, typeStack,
01894 typeStack.topIndex()));
01895
01896 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01897 postTypeStack.topIndex()), rhs);
01898 break;
01899
01900 case ByteCode.DREM:
01901 case ByteCode.LREM:
01902 rhs = Jimple.v().newRemExpr(Util.getLocalForStackOp(listBody, typeStack,
01903 typeStack.topIndex() - 3), Util.getLocalForStackOp(listBody, typeStack,
01904 typeStack.topIndex() - 1));
01905
01906 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01907 postTypeStack.topIndex()), rhs);
01908 break;
01909
01910 case ByteCode.INEG:
01911 case ByteCode.LNEG:
01912 case ByteCode.FNEG:
01913 case ByteCode.DNEG:
01914 rhs = Jimple.v().newNegExpr(Util.getLocalForStackOp(listBody, typeStack,
01915 typeStack.topIndex()));
01916 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01917 postTypeStack.topIndex()),rhs);
01918 break;
01919
01920 case ByteCode.ISHL:
01921 rhs = Jimple.v().newShlExpr(Util.getLocalForStackOp(listBody, typeStack,
01922 typeStack.topIndex() - 1), Util.getLocalForStackOp(listBody, typeStack,
01923 typeStack.topIndex()));
01924
01925 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01926 postTypeStack.topIndex()), rhs);
01927 break;
01928
01929 case ByteCode.ISHR:
01930 rhs = Jimple.v().newShrExpr(Util.getLocalForStackOp(listBody, typeStack,
01931 typeStack.topIndex() - 1), Util.getLocalForStackOp(listBody, typeStack,
01932 typeStack.topIndex()));
01933
01934 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01935 postTypeStack.topIndex()), rhs);
01936 break;
01937
01938 case ByteCode.IUSHR:
01939 rhs = Jimple.v().newUshrExpr(Util.getLocalForStackOp(listBody, typeStack,
01940 typeStack.topIndex() - 1), Util.getLocalForStackOp(listBody, typeStack,
01941 typeStack.topIndex()));
01942
01943 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01944 postTypeStack.topIndex()), rhs);
01945 break;
01946
01947 case ByteCode.LSHL:
01948 rhs = Jimple.v().newShlExpr(Util.getLocalForStackOp(listBody, typeStack,
01949 typeStack.topIndex() - 2), Util.getLocalForStackOp(listBody, typeStack,
01950 typeStack.topIndex()));
01951
01952 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01953 postTypeStack.topIndex()), rhs);
01954 break;
01955
01956 case ByteCode.LSHR:
01957 rhs = Jimple.v().newShrExpr(Util.getLocalForStackOp(listBody, typeStack,
01958 typeStack.topIndex() - 2), Util.getLocalForStackOp(listBody, typeStack,
01959 typeStack.topIndex()));
01960
01961 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01962 postTypeStack.topIndex()), rhs);
01963 break;
01964
01965 case ByteCode.LUSHR:
01966 rhs = Jimple.v().newUshrExpr(Util.getLocalForStackOp(listBody, typeStack,
01967 typeStack.topIndex() - 2), Util.getLocalForStackOp(listBody, typeStack,
01968 typeStack.topIndex()));
01969
01970 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01971 postTypeStack.topIndex()), rhs);
01972 break;
01973
01974 case ByteCode.IAND:
01975 rhs = Jimple.v().newAndExpr(Util.getLocalForStackOp(listBody, typeStack,
01976 typeStack.topIndex() - 1), Util.getLocalForStackOp(listBody, typeStack,
01977 typeStack.topIndex()));
01978
01979 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01980 postTypeStack.topIndex()), rhs);
01981 break;
01982
01983 case ByteCode.LAND:
01984 rhs = Jimple.v().newAndExpr(Util.getLocalForStackOp(listBody, typeStack,
01985 typeStack.topIndex() - 3), Util.getLocalForStackOp(listBody, typeStack,
01986 typeStack.topIndex() - 1));
01987
01988 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01989 postTypeStack.topIndex()), rhs);
01990 break;
01991
01992 case ByteCode.IOR:
01993 rhs = Jimple.v().newOrExpr(Util.getLocalForStackOp(listBody, typeStack,
01994 typeStack.topIndex() - 1), Util.getLocalForStackOp(listBody, typeStack,
01995 typeStack.topIndex()));
01996
01997 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
01998 postTypeStack.topIndex()), rhs);
01999 break;
02000
02001 case ByteCode.LOR:
02002 rhs = Jimple.v().newOrExpr(Util.getLocalForStackOp(listBody, typeStack,
02003 typeStack.topIndex() - 3), Util.getLocalForStackOp(listBody, typeStack,
02004 typeStack.topIndex() - 1));
02005
02006 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
02007 postTypeStack.topIndex()), rhs);
02008 break;
02009
02010 case ByteCode.IXOR:
02011 rhs = Jimple.v().newXorExpr(Util.getLocalForStackOp(listBody, typeStack,
02012 typeStack.topIndex() - 1), Util.getLocalForStackOp(listBody, typeStack,
02013 typeStack.topIndex()));
02014
02015 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
02016 postTypeStack.topIndex()), rhs);
02017 break;
02018
02019 case ByteCode.LXOR:
02020 rhs = Jimple.v().newXorExpr(Util.getLocalForStackOp(listBody, typeStack,
02021 typeStack.topIndex() - 3), Util.getLocalForStackOp(listBody, typeStack,
02022 typeStack.topIndex() - 1));
02023
02024 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
02025 postTypeStack.topIndex()), rhs);
02026 break;
02027
02028 case ByteCode.D2L:
02029 case ByteCode.F2L:
02030 case ByteCode.I2L:
02031 rhs = Jimple.v().newCastExpr(Util.getLocalForStackOp(listBody, typeStack,
02032 typeStack.topIndex()), LongType.v());
02033
02034 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
02035 postTypeStack.topIndex()), rhs);
02036 break;
02037
02038 case ByteCode.D2F:
02039 case ByteCode.L2F:
02040 case ByteCode.I2F:
02041 rhs = Jimple.v().newCastExpr(Util.getLocalForStackOp(listBody, typeStack,
02042 typeStack.topIndex()), FloatType.v());
02043
02044 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
02045 postTypeStack.topIndex()), rhs);
02046 break;
02047
02048 case ByteCode.I2D:
02049 case ByteCode.L2D:
02050 case ByteCode.F2D:
02051 rhs = Jimple.v().newCastExpr(Util.getLocalForStackOp(listBody, typeStack,
02052 typeStack.topIndex()), DoubleType.v());
02053
02054 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
02055 postTypeStack.topIndex()), rhs);
02056 break;
02057
02058 case ByteCode.L2I:
02059 case ByteCode.F2I:
02060 case ByteCode.D2I:
02061 rhs = Jimple.v().newCastExpr(Util.getLocalForStackOp(listBody, typeStack,
02062 typeStack.topIndex()), IntType.v());
02063
02064 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
02065 postTypeStack.topIndex()), rhs);
02066 break;
02067
02068 case ByteCode.INT2BYTE:
02069 rhs = Jimple.v().newCastExpr(Util.getLocalForStackOp(listBody, typeStack,
02070 typeStack.topIndex()), ByteType.v());
02071
02072 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
02073 postTypeStack.topIndex()), rhs);
02074 break;
02075
02076 case ByteCode.INT2CHAR:
02077 rhs = Jimple.v().newCastExpr(Util.getLocalForStackOp(listBody, typeStack,
02078 typeStack.topIndex()), CharType.v());
02079
02080 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
02081 postTypeStack.topIndex()), rhs);
02082 break;
02083
02084 case ByteCode.INT2SHORT:
02085 rhs = Jimple.v().newCastExpr(Util.getLocalForStackOp(listBody, typeStack,
02086 typeStack.topIndex()), ShortType.v());
02087
02088 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
02089 postTypeStack.topIndex()), rhs);
02090 break;
02091
02092 case ByteCode.IFEQ:
02093 co = Jimple.v().newEqExpr(Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()),
02094 IntConstant.v(0));
02095
02096 stmt = Jimple.v().newIfStmt(co, new FutureStmt());
02097 break;
02098
02099 case ByteCode.IFNULL:
02100 co = Jimple.v().newEqExpr(Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()),
02101 NullConstant.v());
02102
02103 stmt = Jimple.v().newIfStmt(co, new FutureStmt());
02104 break;
02105
02106 case ByteCode.IFLT:
02107 co = Jimple.v().newLtExpr(Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()),
02108 IntConstant.v(0));
02109
02110 stmt = Jimple.v().newIfStmt(co, new FutureStmt());
02111 break;
02112
02113 case ByteCode.IFLE:
02114 co = Jimple.v().newLeExpr(Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()),
02115 IntConstant.v(0));
02116
02117 stmt = Jimple.v().newIfStmt(co, new FutureStmt());
02118 break;
02119
02120 case ByteCode.IFNE:
02121 co = Jimple.v().newNeExpr(Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()),
02122 IntConstant.v(0));
02123
02124 stmt = Jimple.v().newIfStmt(co, new FutureStmt());
02125 break;
02126
02127 case ByteCode.IFNONNULL:
02128 co = Jimple.v().newNeExpr(Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()),
02129 NullConstant.v());
02130
02131 stmt = Jimple.v().newIfStmt(co, new FutureStmt());
02132 break;
02133
02134 case ByteCode.IFGT:
02135 co = Jimple.v().newGtExpr(Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()),
02136 IntConstant.v(0));
02137
02138 stmt = Jimple.v().newIfStmt(co, new FutureStmt());
02139 break;
02140
02141 case ByteCode.IFGE:
02142 co = Jimple.v().newGeExpr(Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()),
02143 IntConstant.v(0));
02144
02145 stmt = Jimple.v().newIfStmt(co, new FutureStmt());
02146 break;
02147
02148 case ByteCode.IF_ICMPEQ:
02149 co = Jimple.v().newEqExpr(
02150 Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()-1),
02151 Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
02152
02153 stmt = Jimple.v().newIfStmt(co, new FutureStmt());
02154 break;
02155
02156 case ByteCode.IF_ICMPLT:
02157 co = Jimple.v().newLtExpr(
02158 Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()-1),
02159 Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
02160
02161 stmt = Jimple.v().newIfStmt(co, new FutureStmt());
02162 break;
02163
02164 case ByteCode.IF_ICMPLE:
02165 co = Jimple.v().newLeExpr(
02166 Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()-1),
02167 Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
02168
02169 stmt = Jimple.v().newIfStmt(co, new FutureStmt());
02170 break;
02171
02172 case ByteCode.IF_ICMPNE:
02173 co = Jimple.v().newNeExpr(
02174 Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()-1),
02175 Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
02176
02177 stmt = Jimple.v().newIfStmt(co, new FutureStmt());
02178 break;
02179
02180 case ByteCode.IF_ICMPGT:
02181 co = Jimple.v().newGtExpr(
02182 Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()-1),
02183 Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
02184
02185 stmt = Jimple.v().newIfStmt(co, new FutureStmt());
02186 break;
02187
02188 case ByteCode.IF_ICMPGE:
02189 co = Jimple.v().newGeExpr(
02190 Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()-1),
02191 Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
02192
02193 stmt = Jimple.v().newIfStmt(co, new FutureStmt());
02194 break;
02195
02196 case ByteCode.LCMP:
02197 rhs = Jimple.v().newCmpExpr(
02198 Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()-3),
02199 Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()-1));
02200
02201 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
02202 postTypeStack.topIndex()), rhs);
02203 break;
02204
02205 case ByteCode.FCMPL:
02206 rhs = Jimple.v().newCmplExpr(
02207 Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()-1),
02208 Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
02209
02210 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody,
02211 postTypeStack, postTypeStack.topIndex()),rhs);
02212 break;
02213
02214 case ByteCode.FCMPG:
02215 rhs = Jimple.v().newCmpgExpr(
02216 Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()-1),
02217 Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
02218
02219 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody,
02220 postTypeStack, postTypeStack.topIndex()),rhs);
02221 break;
02222
02223 case ByteCode.DCMPL:
02224 rhs = Jimple.v().newCmplExpr(
02225 Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()-3),
02226 Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()-1));
02227
02228 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody,
02229 postTypeStack, postTypeStack.topIndex()),rhs);
02230 break;
02231
02232 case ByteCode.DCMPG:
02233 rhs = Jimple.v().newCmpgExpr(
02234 Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()-3),
02235 Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()-1));
02236
02237 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody,
02238 postTypeStack, postTypeStack.topIndex()),rhs);
02239 break;
02240
02241 case ByteCode.IF_ACMPEQ:
02242 co = Jimple.v().newEqExpr(
02243 Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()-1),
02244 Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
02245
02246 stmt = Jimple.v().newIfStmt(co, new FutureStmt());
02247 break;
02248
02249 case ByteCode.IF_ACMPNE:
02250 co = Jimple.v().newNeExpr(
02251 Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()-1),
02252 Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()));
02253
02254 stmt = Jimple.v().newIfStmt(co, new FutureStmt());
02255 break;
02256
02257 case ByteCode.GOTO:
02258 stmt = Jimple.v().newGotoStmt(new FutureStmt());
02259 break;
02260
02261 case ByteCode.GOTO_W:
02262 stmt = Jimple.v().newGotoStmt(new FutureStmt());
02263 break;
02264
02265
02266
02267
02268
02269
02270
02271
02272
02273
02274
02275
02276
02277
02278
02279
02280
02281 case ByteCode.RET:
02282 {
02283 Local local =
02284 Util.getLocalForIndex(listBody, ((Instruction_Ret)ins).arg_b);
02285
02286 stmt = Jimple.v().newRetStmt(local);
02287 break;
02288 }
02289
02290 case ByteCode.RET_W:
02291 {
02292 Local local =
02293 Util.getLocalForIndex(listBody, ((Instruction_Ret_w)ins).arg_i);
02294
02295
02296 stmt = Jimple.v().newRetStmt(local);
02297 break;
02298 }
02299
02300 case ByteCode.RETURN:
02301 stmt = Jimple.v().newReturnVoidStmt();
02302 break;
02303
02304 case ByteCode.LRETURN:
02305 case ByteCode.DRETURN:
02306 case ByteCode.IRETURN:
02307 case ByteCode.FRETURN:
02308 case ByteCode.ARETURN:
02309 stmt = Jimple.v().newReturnStmt(Util.getLocalForStackOp(listBody,
02310 typeStack, typeStack.topIndex()));
02311 break;
02312
02313 case ByteCode.BREAKPOINT:
02314 stmt = Jimple.v().newBreakpointStmt();
02315 break;
02316
02317 case ByteCode.TABLESWITCH:
02318 {
02319 int lowIndex = ((Instruction_Tableswitch)ins).low,
02320 highIndex = ((Instruction_Tableswitch)ins).high;
02321
02322 stmt = Jimple.v().newTableSwitchStmt(
02323 Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()),
02324 lowIndex,
02325 highIndex,
02326 Arrays.toList(new FutureStmt[highIndex - lowIndex + 1]),
02327 new FutureStmt());
02328 break;
02329 }
02330
02331 case ByteCode.LOOKUPSWITCH:
02332 {
02333 List matches = new ArrayList();
02334 int npairs = ((Instruction_Lookupswitch)ins).npairs;
02335
02336 for (int j = 0; j < npairs; j++)
02337 matches.add(new Integer( ((Instruction_Lookupswitch)ins).match_offsets[j*2]));
02338
02339 stmt = Jimple.v().newLookupSwitchStmt(
02340 Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex()),
02341 matches,
02342 Arrays.toList(new FutureStmt[npairs]),
02343 new FutureStmt());
02344 break;
02345 }
02346
02347 case ByteCode.PUTFIELD:
02348 {
02349 CONSTANT_Fieldref_info fieldInfo =
02350 (CONSTANT_Fieldref_info) constant_pool[((Instruction_Putfield)ins).arg_i];
02351
02352 CONSTANT_Class_info c =
02353 (CONSTANT_Class_info) constant_pool[fieldInfo.class_index];
02354
02355 String className = ((CONSTANT_Utf8_info) (constant_pool[c.name_index])).convert();
02356 className = className.replace('/', '.');
02357
02358 CONSTANT_NameAndType_info i =
02359 (CONSTANT_NameAndType_info) constant_pool[fieldInfo.name_and_type_index];
02360
02361 String fieldName = ((CONSTANT_Utf8_info) (constant_pool[i.name_index])).convert();
02362 String fieldDescriptor = ((CONSTANT_Utf8_info) (constant_pool[i.descriptor_index])).
02363 convert();
02364
02365 Type fieldType = Util.jimpleTypeOfFieldDescriptor(cm, fieldDescriptor);
02366
02367 SootClass bclass = cm.getClass(className);
02368
02369 SootField field = bclass.getField(fieldName, fieldType);
02370
02371 InstanceFieldRef fr =
02372 Jimple.v().newInstanceFieldRef(Util.getLocalForStackOp(listBody,
02373 typeStack, typeStack.topIndex() - typeSize(typeStack.top())), field);
02374
02375 rvalue = Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex());
02376 stmt = Jimple.v().newAssignStmt(fr,rvalue);
02377 break;
02378 }
02379
02380 case ByteCode.GETFIELD:
02381 {
02382 InstanceFieldRef fr = null;
02383
02384 CONSTANT_Fieldref_info fieldInfo =
02385 (CONSTANT_Fieldref_info) constant_pool[((Instruction_Getfield)ins).arg_i];
02386
02387 CONSTANT_Class_info c =
02388 (CONSTANT_Class_info) constant_pool[fieldInfo.class_index];
02389
02390 String className = ((CONSTANT_Utf8_info) (constant_pool[c.name_index])).convert();
02391 className = className.replace('/', '.');
02392
02393 CONSTANT_NameAndType_info i =
02394 (CONSTANT_NameAndType_info) constant_pool[fieldInfo.name_and_type_index];
02395
02396 String fieldName = ((CONSTANT_Utf8_info) (constant_pool[i.name_index])).convert();
02397 String fieldDescriptor = ((CONSTANT_Utf8_info) (constant_pool[i.descriptor_index])).
02398 convert();
02399
02400 SootClass bclass = cm.getClass(className);
02401
02402
02403 Type fieldType = Util.jimpleTypeOfFieldDescriptor(cm, fieldDescriptor);
02404 SootField field = bclass.getField(fieldName, fieldType);
02405
02406 fr = Jimple.v().newInstanceFieldRef(Util.getLocalForStackOp(listBody, typeStack,
02407 typeStack.topIndex()), field);
02408
02409 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
02410 postTypeStack.topIndex()), fr);
02411 break;
02412 }
02413
02414
02415 case ByteCode.PUTSTATIC:
02416 {
02417 StaticFieldRef fr = null;
02418
02419 CONSTANT_Fieldref_info fieldInfo =
02420 (CONSTANT_Fieldref_info) constant_pool[((Instruction_Putstatic)ins).arg_i];
02421
02422 CONSTANT_Class_info c =
02423 (CONSTANT_Class_info) constant_pool[fieldInfo.class_index];
02424
02425 String className = ((CONSTANT_Utf8_info) (constant_pool[c.name_index])).convert();
02426 className = className.replace('/', '.');
02427
02428 CONSTANT_NameAndType_info i =
02429 (CONSTANT_NameAndType_info) constant_pool[fieldInfo.name_and_type_index];
02430
02431 String fieldName = ((CONSTANT_Utf8_info) (constant_pool[i.name_index])).convert();
02432 String fieldDescriptor = ((CONSTANT_Utf8_info) (constant_pool[i.descriptor_index])).
02433 convert();
02434
02435 Type fieldType = Util.jimpleTypeOfFieldDescriptor(cm, fieldDescriptor);
02436
02437 SootClass bclass = cm.getClass(className);
02438 SootField field = bclass.getField(fieldName, fieldType);
02439
02440 fr = Jimple.v().newStaticFieldRef(field);
02441
02442 stmt = Jimple.v().newAssignStmt(fr, Util.getLocalForStackOp(listBody, typeStack,
02443 typeStack.topIndex()));
02444 break;
02445 }
02446
02447 case ByteCode.GETSTATIC:
02448 {
02449 StaticFieldRef fr = null;
02450
02451 CONSTANT_Fieldref_info fieldInfo =
02452 (CONSTANT_Fieldref_info) constant_pool[((Instruction_Getstatic)ins).arg_i];
02453
02454 CONSTANT_Class_info c =
02455 (CONSTANT_Class_info) constant_pool[fieldInfo.class_index];
02456
02457 String className = ((CONSTANT_Utf8_info) (constant_pool[c.name_index])).convert();
02458 className = className.replace('/', '.');
02459
02460 CONSTANT_NameAndType_info i =
02461 (CONSTANT_NameAndType_info) constant_pool[fieldInfo.name_and_type_index];
02462
02463 String fieldName = ((CONSTANT_Utf8_info) (constant_pool[i.name_index])).convert();
02464 String fieldDescriptor = ((CONSTANT_Utf8_info) (constant_pool[i.descriptor_index])).
02465 convert();
02466
02467 Type fieldType = Util.jimpleTypeOfFieldDescriptor(cm, fieldDescriptor);
02468
02469 SootClass bclass = cm.getClass(className);
02470 SootField field = bclass.getField(fieldName, fieldType);
02471
02472 fr = Jimple.v().newStaticFieldRef(field);
02473
02474 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
02475 postTypeStack.topIndex()), fr);
02476 break;
02477 }
02478
02479
02480 case ByteCode.INVOKEVIRTUAL:
02481 {
02482 Instruction_Invokevirtual iv = (Instruction_Invokevirtual)ins;
02483 args = cp_info.countParams(constant_pool,iv.arg_i);
02484
02485 SootMethod method = null;
02486
02487 CONSTANT_Methodref_info methodInfo =
02488 (CONSTANT_Methodref_info) constant_pool[iv.arg_i];
02489
02490 CONSTANT_Class_info c =
02491 (CONSTANT_Class_info) constant_pool[methodInfo.class_index];
02492
02493 String className = ((CONSTANT_Utf8_info) (constant_pool[c.name_index])).convert();
02494 className = className.replace('/', '.');
02495
02496 CONSTANT_NameAndType_info i =
02497 (CONSTANT_NameAndType_info) constant_pool[methodInfo.name_and_type_index];
02498
02499 String methodName = ((CONSTANT_Utf8_info) (constant_pool[i.name_index])).convert();
02500 String methodDescriptor = ((CONSTANT_Utf8_info) (constant_pool[i.descriptor_index])).
02501 convert();
02502
02503 SootClass bclass = cm.getClass(className);
02504
02505 Local[] parameters;
02506 List parameterTypes;
02507 Type returnType;
02508
02509
02510 {
02511 Type[] types = Util.jimpleTypesOfFieldOrMethodDescriptor(cm,
02512 methodDescriptor);
02513
02514 parameterTypes = new ArrayList();
02515
02516 for(int k = 0; k < types.length - 1; k++)
02517 {
02518 parameterTypes.add(types[k]);
02519 }
02520
02521 returnType = types[types.length - 1];
02522 }
02523
02524 method = bclass.getMethod(methodName, parameterTypes, returnType);
02525
02526
02527 params = new Value[args];
02528 for (int j=args-1;j>=0;j--)
02529 {
02530 params[j] = Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex());
02531
02532 if(typeSize(typeStack.top()) == 2)
02533 {
02534 typeStack = typeStack.pop();
02535 typeStack = typeStack.pop();
02536 }
02537 else
02538 typeStack = typeStack.pop();
02539 }
02540
02541 rvalue = Jimple.v().newVirtualInvokeExpr(Util.getLocalForStackOp(listBody, typeStack,
02542 typeStack.topIndex()), method, Arrays.toList(params));
02543
02544 if(!returnType.equals(VoidType.v()))
02545 {
02546 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
02547 postTypeStack.topIndex()),rvalue);
02548 }
02549 else
02550 stmt = Jimple.v().newInvokeStmt((InvokeExpr) rvalue);
02551 break;
02552 }
02553
02554 case ByteCode.INVOKENONVIRTUAL:
02555 {
02556 Instruction_Invokenonvirtual iv = (Instruction_Invokenonvirtual)ins;
02557 args = cp_info.countParams(constant_pool,iv.arg_i);
02558
02559 SootMethod method = null;
02560
02561 CONSTANT_Methodref_info methodInfo =
02562 (CONSTANT_Methodref_info) constant_pool[iv.arg_i];
02563
02564 CONSTANT_Class_info c =
02565 (CONSTANT_Class_info) constant_pool[methodInfo.class_index];
02566
02567 String className = ((CONSTANT_Utf8_info) (constant_pool[c.name_index])).convert();
02568 className = className.replace('/', '.');
02569
02570 CONSTANT_NameAndType_info i =
02571 (CONSTANT_NameAndType_info) constant_pool[methodInfo.name_and_type_index];
02572
02573 String methodName = ((CONSTANT_Utf8_info) (constant_pool[i.name_index])).convert();
02574 String methodDescriptor = ((CONSTANT_Utf8_info) (constant_pool[i.descriptor_index])).
02575 convert();
02576
02577 SootClass bclass = cm.getClass(className);
02578
02579 Local[] parameters;
02580 List parameterTypes;
02581 Type returnType;
02582
02583
02584 {
02585 Type[] types = Util.jimpleTypesOfFieldOrMethodDescriptor(cm,
02586 methodDescriptor);
02587
02588 parameterTypes = new ArrayList();
02589
02590 for(int k = 0; k < types.length - 1; k++)
02591 {
02592 parameterTypes.add(types[k]);
02593 }
02594
02595 returnType = types[types.length - 1];
02596 }
02597
02598 method = bclass.getMethod(methodName, parameterTypes, returnType);
02599
02600
02601 params = new Value[args];
02602 for (int j=args-1;j>=0;j--)
02603 {
02604 params[j] = Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex());
02605
02606 if(typeSize(typeStack.top()) == 2)
02607 {
02608 typeStack = typeStack.pop();
02609 typeStack = typeStack.pop();
02610 }
02611 else
02612 typeStack = typeStack.pop();
02613 }
02614
02615 rvalue = Jimple.v().newSpecialInvokeExpr(Util.getLocalForStackOp(listBody, typeStack,
02616 typeStack.topIndex()), method, Arrays.toList(params));
02617
02618 if(!returnType.equals(VoidType.v()))
02619 {
02620 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
02621 postTypeStack.topIndex()), rvalue);
02622 }
02623 else
02624 stmt = Jimple.v().newInvokeStmt((InvokeExpr) rvalue);
02625 break;
02626 }
02627
02628 case ByteCode.INVOKESTATIC:
02629 {
02630 Instruction_Invokestatic is = (Instruction_Invokestatic)ins;
02631 args = cp_info.countParams(constant_pool,is.arg_i);
02632
02633 SootMethod method = null;
02634
02635 CONSTANT_Methodref_info methodInfo =
02636 (CONSTANT_Methodref_info) constant_pool[is.arg_i];
02637
02638 CONSTANT_Class_info c =
02639 (CONSTANT_Class_info) constant_pool[methodInfo.class_index];
02640
02641 String className = ((CONSTANT_Utf8_info) (constant_pool[c.name_index])).convert();
02642 className = className.replace('/', '.');
02643
02644 CONSTANT_NameAndType_info i =
02645 (CONSTANT_NameAndType_info) constant_pool[methodInfo.name_and_type_index];
02646
02647 String methodName = ((CONSTANT_Utf8_info) (constant_pool[i.name_index])).convert();
02648 String methodDescriptor = ((CONSTANT_Utf8_info) (constant_pool[i.descriptor_index])).
02649 convert();
02650
02651 SootClass bclass = cm.getClass(className);
02652
02653 Local[] parameters;
02654 List parameterTypes;
02655 Type returnType;
02656
02657
02658 {
02659 Type[] types = Util.jimpleTypesOfFieldOrMethodDescriptor(cm,
02660 methodDescriptor);
02661
02662 parameterTypes = new ArrayList();
02663
02664 for(int k = 0; k < types.length - 1; k++)
02665 {
02666 parameterTypes.add(types[k]);
02667 }
02668
02669 returnType = types[types.length - 1];
02670 }
02671
02672 method = bclass.getMethod(methodName, parameterTypes, returnType);
02673
02674
02675 params = new Value[args];
02676 for (int j=args-1;j>=0;j--)
02677 {
02678
02679
02680
02681
02682
02683
02684
02685 params[j] = Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex());
02686
02687 if(typeSize(typeStack.top()) == 2)
02688 {
02689 typeStack = typeStack.pop();
02690 typeStack = typeStack.pop();
02691 }
02692 else
02693 typeStack = typeStack.pop();
02694 }
02695
02696 rvalue = Jimple.v().newStaticInvokeExpr(method, Arrays.toList(params));
02697
02698 if(!returnType.equals(VoidType.v()))
02699 {
02700 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
02701 postTypeStack.topIndex()),rvalue);
02702 }
02703 else
02704 stmt = Jimple.v().newInvokeStmt((InvokeExpr) rvalue);
02705
02706 break;
02707 }
02708
02709 case ByteCode.INVOKEINTERFACE:
02710 {
02711 Instruction_Invokeinterface ii = (Instruction_Invokeinterface)ins;
02712 args = cp_info.countParams(constant_pool,ii.arg_i);
02713
02714 SootMethod method = null;
02715
02716 CONSTANT_InterfaceMethodref_info methodInfo =
02717 (CONSTANT_InterfaceMethodref_info) constant_pool[ii.arg_i];
02718
02719 CONSTANT_Class_info c =
02720 (CONSTANT_Class_info) constant_pool[methodInfo.class_index];
02721
02722 String className = ((CONSTANT_Utf8_info) (constant_pool[c.name_index])).convert();
02723 className = className.replace('/', '.');
02724
02725 CONSTANT_NameAndType_info i =
02726 (CONSTANT_NameAndType_info) constant_pool[methodInfo.name_and_type_index];
02727
02728 String methodName = ((CONSTANT_Utf8_info) (constant_pool[i.name_index])).convert();
02729 String methodDescriptor = ((CONSTANT_Utf8_info) (constant_pool[i.descriptor_index])).
02730 convert();
02731
02732 SootClass bclass = cm.getClass(className);
02733
02734 Local[] parameters;
02735 List parameterTypes;
02736 Type returnType;
02737
02738
02739 {
02740 Type[] types = Util.jimpleTypesOfFieldOrMethodDescriptor(cm,
02741 methodDescriptor);
02742
02743 parameterTypes = new ArrayList();
02744
02745 for(int k = 0; k < types.length - 1; k++)
02746 {
02747 parameterTypes.add(types[k]);
02748 }
02749
02750 returnType = types[types.length - 1];
02751 }
02752
02753 method = bclass.getMethod(methodName, parameterTypes, returnType);
02754
02755
02756 params = new Value[args];
02757 for (int j=args-1;j>=0;j--)
02758 {
02759 params[j] = Util.getLocalForStackOp(listBody, typeStack, typeStack.topIndex());
02760
02761 if(typeSize(typeStack.top()) == 2)
02762 {
02763 typeStack = typeStack.pop();
02764 typeStack = typeStack.pop();
02765 }
02766 else
02767 typeStack = typeStack.pop();
02768 }
02769
02770 rvalue = Jimple.v().newInterfaceInvokeExpr(Util.getLocalForStackOp(listBody, typeStack,
02771 typeStack.topIndex()), method, Arrays.toList(params));
02772
02773 if(!returnType.equals(VoidType.v()))
02774 {
02775 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
02776 postTypeStack.topIndex()), rvalue);
02777 }
02778 else
02779 stmt = Jimple.v().newInvokeStmt((InvokeExpr) rvalue);
02780 break;
02781 }
02782
02783 case ByteCode.ATHROW:
02784 stmt = Jimple.v().newThrowStmt(Util.getLocalForStackOp(listBody, typeStack,
02785 typeStack.topIndex()));
02786 break;
02787
02788 case ByteCode.NEW:
02789 {
02790 SootClass bclass = cm.getClass(getClassName(constant_pool,
02791 ((Instruction_New)ins).arg_i));
02792
02793 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
02794 postTypeStack.topIndex()), Jimple.v().newNewExpr(RefType.v(bclass.getName())));
02795 break;
02796 }
02797
02798 case ByteCode.CHECKCAST:
02799 {
02800 String className = getClassName(constant_pool, ((Instruction_Checkcast)ins).arg_i);
02801
02802 Type castType;
02803
02804 if(className.startsWith("["))
02805 castType = Util.jimpleTypeOfFieldDescriptor(cm, getClassName(constant_pool,
02806 ((Instruction_Checkcast)ins).arg_i));
02807 else
02808 castType = RefType.v(className);
02809
02810 rhs = Jimple.v().newCastExpr(Util.getLocalForStackOp(listBody, typeStack,
02811 typeStack.topIndex()), castType);
02812
02813 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
02814 postTypeStack.topIndex()),rhs);
02815 break;
02816 }
02817
02818 case ByteCode.INSTANCEOF:
02819 {
02820 Type checkType;
02821
02822 String className = getClassName(constant_pool, ((Instruction_Instanceof)ins).arg_i);
02823
02824 if(className.startsWith("["))
02825 checkType = Util.jimpleTypeOfFieldDescriptor(cm, getClassName(constant_pool,
02826 ((Instruction_Instanceof)ins).arg_i));
02827 else
02828 checkType = RefType.v(className);
02829
02830 rhs = Jimple.v().newInstanceOfExpr(Util.getLocalForStackOp(listBody, typeStack,
02831 typeStack.topIndex()), checkType);
02832
02833 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
02834 postTypeStack.topIndex()),rhs);
02835 break;
02836 }
02837
02838 case ByteCode.MONITORENTER:
02839 stmt = Jimple.v().newEnterMonitorStmt(Util.getLocalForStackOp(listBody, typeStack,
02840 typeStack.topIndex()));
02841 break;
02842 case ByteCode.MONITOREXIT:
02843 stmt = Jimple.v().newExitMonitorStmt(Util.getLocalForStackOp(listBody, typeStack,
02844 typeStack.topIndex()));
02845 break;
02846
02847 default:
02848 throw new RuntimeException("Unrecognized bytecode instruction: " + x);
02849 }
02850
02851 if(stmt != null)
02852 statements.add(stmt);
02853 }
02854 private void generateJimpleForCPEntry(cp_info constant_pool[], int i,
02855 TypeStack typeStack, TypeStack postTypeStack,
02856 SootMethod jmethod, List statements)
02857 {
02858 Expr e;
02859 Stmt stmt;
02860 Value rvalue;
02861
02862 cp_info c = constant_pool[i];
02863
02864 if (c instanceof CONSTANT_Integer_info)
02865 {
02866 CONSTANT_Integer_info ci = (CONSTANT_Integer_info)c;
02867
02868 rvalue = IntConstant.v((int) ci.bytes);
02869 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
02870 postTypeStack.topIndex()), rvalue);
02871 }
02872 else if (c instanceof CONSTANT_Float_info)
02873 {
02874 CONSTANT_Float_info cf = (CONSTANT_Float_info)c;
02875
02876 rvalue = FloatConstant.v(cf.convert());
02877 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
02878 postTypeStack.topIndex()), rvalue);
02879 }
02880 else if (c instanceof CONSTANT_Long_info)
02881 {
02882 CONSTANT_Long_info cl = (CONSTANT_Long_info)c;
02883
02884 rvalue = LongConstant.v(cl.convert());
02885 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
02886 postTypeStack.topIndex()), rvalue);
02887 }
02888 else if (c instanceof CONSTANT_Double_info)
02889 {
02890 CONSTANT_Double_info cd = (CONSTANT_Double_info)c;
02891
02892 rvalue = DoubleConstant.v(cd.convert());
02893
02894 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
02895 postTypeStack.topIndex()), rvalue);
02896 }
02897 else if (c instanceof CONSTANT_String_info)
02898 {
02899 CONSTANT_String_info cs = (CONSTANT_String_info)c;
02900
02901 String constant = cs.toString(constant_pool);
02902
02903 if(constant.startsWith("\"") && constant.endsWith("\""))
02904 constant = constant.substring(1, constant.length() - 1);
02905
02906 rvalue = StringConstant.v(constant);
02907 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
02908 postTypeStack.topIndex()), rvalue);
02909 }
02910 else if (c instanceof CONSTANT_Utf8_info)
02911 {
02912 CONSTANT_Utf8_info cu = (CONSTANT_Utf8_info)c;
02913
02914 String constant = cu.convert();
02915
02916 if(constant.startsWith("\"") && constant.endsWith("\""))
02917 constant = constant.substring(1, constant.length() - 1);
02918
02919 rvalue = StringConstant.v(constant);
02920 stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
02921 postTypeStack.topIndex()), rvalue);
02922 }
02923 else {
02924 throw new RuntimeException("Attempting to push a non-constant cp entry");
02925 }
02926
02927 statements.add(stmt);
02928 }
02929 String getClassName(cp_info[] constant_pool, int index)
02930 {
02931 CONSTANT_Class_info c = (CONSTANT_Class_info) constant_pool[index];
02932
02933 String name = ((CONSTANT_Utf8_info) (constant_pool[c.name_index])).convert();
02934
02935 return name.replace('/', '.');
02936 }
02937 private BasicBlock getEndOfBBList() {
02938
02939 BasicBlock b = cfg;
02940
02941 BasicBlock prev = cfg;
02942
02943 while ( b != null )
02944 {
02945
02946 prev = b;
02947
02948 b = b.next;
02949
02950 }
02951
02952 return prev;
02953
02954 }
02955 private Type jimpleReturnTypeOfInterfaceMethodRef(SootClassManager cm,
02956 cp_info[] constant_pool, int index)
02957 {
02958 CONSTANT_InterfaceMethodref_info mr = (CONSTANT_InterfaceMethodref_info)
02959 (constant_pool[index]);
02960
02961 CONSTANT_NameAndType_info nat = (CONSTANT_NameAndType_info)
02962 (constant_pool[mr.name_and_type_index]);
02963
02964 String methodDescriptor = ((CONSTANT_Utf8_info)
02965 (constant_pool[nat.descriptor_index])).convert();
02966
02967 return Util.jimpleReturnTypeOfMethodDescriptor(cm, methodDescriptor);
02968 }
02969 private Type jimpleReturnTypeOfMethodRef(SootClassManager cm,
02970 cp_info[] constant_pool, int index)
02971 {
02972 CONSTANT_Methodref_info mr = (CONSTANT_Methodref_info)
02973 (constant_pool[index]);
02974
02975 CONSTANT_NameAndType_info nat = (CONSTANT_NameAndType_info)
02976 (constant_pool[mr.name_and_type_index]);
02977
02978 String methodDescriptor = ((CONSTANT_Utf8_info)
02979 (constant_pool[nat.descriptor_index])).convert();
02980
02981 return Util.jimpleReturnTypeOfMethodDescriptor(cm, methodDescriptor);
02982 }
02983
02984
02985
02986
02987
02988 void jimpleTargetFixup() {
02989 BasicBlock b;
02990 BBQ bbq = new BBQ();
02991
02992 Code_attribute c = method.locate_code_attribute();
02993 if (c==null) return;
02994
02995
02996 {
02997 BasicBlock bb = cfg;
02998
02999 while(bb != null)
03000 {
03001 bb.done = true;
03002 bb = bb.next;
03003 }
03004 }
03005
03006
03007
03008 bbq.push(cfg);
03009 processTargetFixup(bbq);
03010
03011
03012 if (bbq.isEmpty()) {
03013 int i;
03014 for (i=0;i<c.exception_table_length;i++) {
03015 b = c.exception_table[i].b;
03016
03017 if (b!=null && b.done) {
03018 bbq.push(b);
03019 processTargetFixup(bbq);
03020 if (!bbq.isEmpty()) {
03021 System.out.println("Error 2nd processing exception block.");
03022 break;
03023 }
03024 }
03025 }
03026 }
03027 }
03028 Type jimpleTypeOfAtype(int atype)
03029 {
03030 switch(atype)
03031 {
03032 case 4:
03033 return BooleanType.v();
03034
03035 case 5:
03036 return CharType.v();
03037
03038 case 6:
03039 return FloatType.v();
03040
03041 case 7:
03042 return DoubleType.v();
03043
03044 case 8:
03045 return ByteType.v();
03046
03047 case 9:
03048 return ShortType.v();
03049
03050 case 10:
03051 return IntType.v();
03052
03053 case 11:
03054 return LongType.v();
03055
03056 default:
03057 throw new RuntimeException("Undefined 'atype' in NEWARRAY byte instruction");
03058 }
03059 }
03060 private Type jimpleTypeOfFieldInFieldRef(SootClassManager cm,
03061 cp_info[] constant_pool, int index)
03062 {
03063 CONSTANT_Fieldref_info fr = (CONSTANT_Fieldref_info)
03064 (constant_pool[index]);
03065
03066 CONSTANT_NameAndType_info nat = (CONSTANT_NameAndType_info)
03067 (constant_pool[fr.name_and_type_index]);
03068
03069 String fieldDescriptor = ((CONSTANT_Utf8_info)
03070 (constant_pool[nat.descriptor_index])).convert();
03071
03072 return Util.jimpleTypeOfFieldDescriptor(cm, fieldDescriptor);
03073 }
03074
03075
03076
03077
03078
03079
03080
03081
03082
03083
03084
03085
03086
03087
03088 void jimplify(cp_info constant_pool[],int this_class)
03089 {
03090 Map instructionToSuccessors = new HashMap();
03091 Code_attribute codeAttribute = method.locate_code_attribute();
03092 Set handlerInstructions = new VectorSet();
03093
03094 Map handlerInstructionToException = new HashMap();
03095 Map instructionToTypeStack;
03096 Map instructionToPostTypeStack;
03097
03098
03099
03100
03101 {
03102
03103 {
03104 BasicBlock b = cfg;
03105
03106 while(b != null)
03107 {
03108 Instruction ins = b.head;
03109
03110 while(ins != null)
03111 {
03112
03113
03114
03115
03116
03117
03118
03119
03120 if(ins.next != null)
03121 {
03122 Set successors = new VectorSet();
03123
03124 successors.add(ins.next);
03125
03126 instructionToSuccessors.put(ins, successors);
03127 }
03128 else
03129 {
03130
03131
03132 Set successors = new VectorSet();
03133 java.util.Vector succ = b.succ;
03134
03135 for(int i = 0; i < succ.size(); i++)
03136 {
03137 successors.add(((BasicBlock) succ.elementAt(i)).head);
03138
03139 }
03140 instructionToSuccessors.put(ins, successors);
03141 }
03142
03143 ins = ins.next;
03144 }
03145
03146 b = b.next;
03147 }
03148 }
03149
03150
03151 {
03152 for(int i = 0; i < codeAttribute.exception_table_length; i++)
03153 {
03154 Instruction startIns = codeAttribute.exception_table[i].start_inst;
03155 Instruction endIns = codeAttribute.exception_table[i].end_inst;
03156 Instruction handlerIns = codeAttribute.exception_table[i].handler_inst;
03157
03158 handlerInstructions.add(handlerIns);
03159
03160
03161 {
03162 int catchType = codeAttribute.exception_table[i].catch_type;
03163
03164 SootClass exception;
03165
03166 if(catchType != 0)
03167 {
03168 CONSTANT_Class_info classinfo = (CONSTANT_Class_info)
03169 constant_pool[catchType];
03170
03171 String name = ((CONSTANT_Utf8_info) (constant_pool[classinfo.name_index])).
03172 convert();
03173 name = name.replace('/', '.');
03174
03175 exception = cm.getClass(name);
03176 }
03177 else
03178 exception = cm.getClass("java.lang.Throwable");
03179
03180 handlerInstructionToException.put(handlerIns, exception);
03181 }
03182
03183
03184 if(startIns == endIns)
03185 throw new RuntimeException("Empty catch range for exception handler");
03186
03187 Instruction ins = startIns;
03188
03189 for(;;)
03190 {
03191
03192
03193 Set successors = (Set) instructionToSuccessors.get(ins);
03194
03195 successors.add(handlerIns);
03196
03197 ins = (Instruction) instructionToNext.get(ins);
03198
03199 if ( (ins == endIns ) )
03200 {
03201
03202 break;
03203 }
03204
03205 }
03206 }
03207 }
03208 }
03209
03210
03211 {
03212 instructionToTypeStack = new HashMap();
03213 instructionToPostTypeStack = new HashMap();
03214
03215 Set visitedInstructions = new HashSet();
03216 List changedInstructions = new VectorList();
03217
03218 TypeStack initialTypeStack;
03219
03220
03221 {
03222 initialTypeStack = TypeStack.v();
03223
03224 }
03225
03226
03227 {
03228 instructionToTypeStack.put(firstInstruction, initialTypeStack);
03229
03230 visitedInstructions.add(firstInstruction);
03231 changedInstructions.add(firstInstruction);
03232
03233
03234 }
03235
03236
03237 {
03238 while(!changedInstructions.isEmpty())
03239 {
03240 Instruction ins = (Instruction) changedInstructions.get(0);
03241
03242
03243
03244
03245
03246
03247
03248
03249
03250
03251
03252
03253
03254
03255
03256
03257
03258 changedInstructions.remove(0);
03259
03260
03261
03262 OutFlow ret = processFlow(ins, (TypeStack) instructionToTypeStack.get(ins),
03263 constant_pool);
03264
03265 instructionToPostTypeStack.put(ins, ret.typeStack);
03266
03267
03268
03269
03270
03271
03272
03273
03274
03275
03276
03277
03278 Object[] successors = ((Set) instructionToSuccessors.get(ins)).toArray();
03279
03280
03281
03282
03283
03284
03285
03286 for(int i = 0; i < successors.length; i++)
03287 {
03288 Instruction s = (Instruction) successors[i];
03289
03290 if(!visitedInstructions.contains(s))
03291 {
03292
03293
03294 if(handlerInstructions.contains(s))
03295 {
03296 TypeStack exceptionTypeStack = (TypeStack.v()).push(RefType.v(
03297 ((SootClass) handlerInstructionToException.get(s)).getName()));
03298
03299 instructionToTypeStack.put(s, exceptionTypeStack);
03300 }
03301 else {
03302 instructionToTypeStack.put(s, ret.typeStack);
03303 }
03304
03305 visitedInstructions.add(s);
03306 changedInstructions.add(s);
03307
03308
03309 }
03310 else {
03311
03312 TypeStack newTypeStack,
03313 oldTypeStack = (TypeStack) instructionToTypeStack.get(s);
03314
03315 if(handlerInstructions.contains(s))
03316 {
03317
03318
03319
03320 TypeStack exceptionTypeStack = (TypeStack.v()).push(RefType.v(
03321 ((SootClass) handlerInstructionToException.get(s)).getName()));
03322
03323 newTypeStack = exceptionTypeStack;
03324 }
03325 else
03326 newTypeStack = ret.typeStack.merge(oldTypeStack);
03327
03328 if(!newTypeStack.equals(oldTypeStack))
03329 {
03330 changedInstructions.add(s);
03331
03332 }
03333
03334 instructionToTypeStack.put(s, newTypeStack);
03335 }
03336 }
03337 }
03338 }
03339 }
03340
03341
03342 {
03343 Instruction ins = firstInstruction;
03344
03345
03346
03347 while(ins != null)
03348 {
03349 TypeStack typeStack = (TypeStack) instructionToTypeStack.get(ins);
03350
03351
03352
03353
03354
03355
03356
03357
03358
03359
03360
03361
03362
03363 ins = (Instruction) instructionToNext.get(ins);
03364
03365
03366
03367
03368
03369
03370 }
03371 }
03372
03373
03374
03375
03376
03377 {
03378 BasicBlock b = cfg;
03379
03380 while(b != null)
03381 {
03382 Instruction ins = b.head;
03383 b.statements = new VectorList();
03384
03385 List blockStatements = b.statements;
03386
03387 while(ins != null)
03388 {
03389 List statementsForIns = new VectorList();
03390
03391
03392
03393 generateJimple(ins, (TypeStack) instructionToTypeStack.get(ins),
03394 (TypeStack) instructionToPostTypeStack.get(ins), constant_pool,
03395 statementsForIns, b);
03396
03397 if(!statementsForIns.isEmpty())
03398 {
03399 for(int i = 0; i < statementsForIns.size(); i++)
03400 {
03401 stmtList.add(statementsForIns.get(i));
03402 blockStatements.add(statementsForIns.get(i));
03403 }
03404
03405 instructionToFirstStmt.put(ins, statementsForIns.get(0));
03406 instructionToLastStmt.put(ins, statementsForIns.get(statementsForIns.size() - 1));
03407 }
03408
03409 ins = ins.next;
03410 }
03411
03412 b = b.next;
03413 }
03414 }
03415
03416
03417
03418
03419
03420
03421
03422
03423
03424
03425
03426
03427
03428
03429
03430
03431
03432
03433
03434
03435
03436
03437
03438
03439
03440 jimpleTargetFixup();
03441
03442
03443 {
03444 for(int i = 0; i < codeAttribute.exception_table_length; i++)
03445 {
03446 Instruction startIns = codeAttribute.exception_table[i].start_inst;
03447 Instruction endIns = codeAttribute.exception_table[i].end_inst;
03448 Instruction targetIns = codeAttribute.exception_table[i].handler_inst;
03449
03450 if(!instructionToFirstStmt.containsKey(startIns) ||
03451 !instructionToLastStmt.containsKey(endIns))
03452 {
03453 throw new RuntimeException("Exception range does not coincide with jimple instructions");
03454 }
03455
03456 Stmt firstStmt = (Stmt) instructionToFirstStmt.get(startIns);
03457 Stmt lastStmt;
03458
03459
03460 {
03461 int afterLastIndex = stmtList.indexOf(instructionToLastStmt.get(endIns));
03462
03463 lastStmt = (Stmt) stmtList.get(afterLastIndex - 1);
03464 }
03465
03466 if(!instructionToFirstStmt.containsKey(targetIns))
03467 {
03468 throw new RuntimeException
03469 ("Exception handler does not coincide with jimple instruction");
03470 }
03471
03472 SootClass exception;
03473
03474
03475 {
03476 int catchType = codeAttribute.exception_table[i].catch_type;
03477
03478 if(catchType != 0)
03479 {
03480 CONSTANT_Class_info classinfo = (CONSTANT_Class_info)
03481 constant_pool[catchType];
03482
03483 String name = ((CONSTANT_Utf8_info) (constant_pool[classinfo.name_index])).
03484 convert();
03485 name = name.replace('/', '.');
03486
03487 exception = cm.getClass(name);
03488 }
03489 else
03490 exception = cm.getClass("java.lang.Throwable");
03491
03492 }
03493
03494 Stmt newTarget;
03495
03496
03497 {
03498 int targetIndex = stmtList.indexOf(instructionToFirstStmt.get(targetIns));
03499
03500 Local local = Util.getLocalCreatingIfNecessary(listBody, "op0",
03501 UnknownType.v());
03502
03503 newTarget = Jimple.v().newIdentityStmt(local, Jimple.v().newCaughtExceptionRef(listBody));
03504
03505 stmtList.add(targetIndex, newTarget);
03506 }
03507
03508
03509 {
03510 int endIndex = stmtList.indexOf(lastStmt);
03511 Stmt afterEndStmt = (Stmt) stmtList.get(endIndex + 1);
03512
03513 Trap trap = Jimple.v().newTrap(exception, firstStmt, afterEndStmt, newTarget);
03514 listBody.addTrap(trap);
03515 }
03516
03517
03518
03519
03520
03521
03522
03523
03524
03525
03526
03527
03528
03529
03530
03531
03532
03533 }
03534 }
03535 }
03536
03537
03538
03539
03540
03541
03542
03543
03544
03545
03546 public boolean jimplify(cp_info constant_pool[],int this_class, JimpleBody listBody)
03547 {
03548 Util.setClassNameToAbbreviation(new HashMap());
03549
03550 StmtList stmtList = listBody.getStmtList();
03551
03552 this.listBody = listBody;
03553 this.stmtList = stmtList;
03554 instructionToFirstStmt = new HashMap();
03555 instructionToLastStmt = new HashMap();
03556
03557 jmethod = listBody.getMethod();
03558 cm = jmethod.getDeclaringClass().getManager();
03559
03560 Util.setActiveClassManager(cm);
03561 TypeArray.setClassManager(cm);
03562 TypeStack.setClassManager(cm);
03563
03564 Set initialLocals = new VectorSet();
03565
03566 List parameterTypes = jmethod.getParameterTypes();
03567
03568
03569
03570 {
03571 Code_attribute ca = method.locate_code_attribute();
03572 LocalVariableTable_attribute la = ca.findLocalVariableTable();
03573
03574 boolean useFakeNames = false;
03575
03576 Type thisType = RefType.v(jmethod.getDeclaringClass().getName());
03577 boolean isStatic = Modifier.isStatic(jmethod.getModifiers());
03578
03579 int currentLocalIndex = 0;
03580
03581
03582 {
03583 if(!isStatic)
03584 {
03585 Local local = Jimple.v().newLocal("l0", UnknownType.v());
03586
03587
03588 listBody.addLocal(local);
03589
03590 currentLocalIndex++;
03591
03592 stmtList.add(Jimple.v().newIdentityStmt(local, Jimple.v().newThisRef(jmethod.getDeclaringClass())));
03593 }
03594 }
03595
03596
03597 {
03598 Iterator typeIt = parameterTypes.iterator();
03599 int argCount = 0;
03600
03601 while(typeIt.hasNext())
03602 {
03603 String name;
03604 Type type = (Type) typeIt.next();
03605
03606 if(useFakeNames || la == null)
03607 name = "arg" + argCount;
03608 else
03609 name = la.getLocalVariableName(constant_pool, currentLocalIndex);
03610
03611 Local local = Jimple.v().newLocal("l" + currentLocalIndex, UnknownType.v());
03612 initialLocals.add(local);
03613 listBody.addLocal(local);
03614
03615 stmtList.add(Jimple.v().newIdentityStmt(local, Jimple.v().newParameterRef(jmethod, argCount)));
03616
03617 if(type.equals(DoubleType.v()) ||
03618 type.equals(LongType.v()))
03619 {
03620 currentLocalIndex += 2;
03621 }
03622 else {
03623 currentLocalIndex += 1;
03624 }
03625
03626 argCount++;
03627 }
03628 }
03629
03630 Util.resetEasyNames();
03631 }
03632
03633 jimplify(constant_pool,this_class);
03634
03635 return true;
03636 }
03637 private void JsrEliminate() {
03638
03639 BasicBlock b = cfg;
03640
03641 Instruction i = null;
03642
03643 while ( b != null )
03644 {
03645
03646 i = b.tail;
03647
03648 if ( i instanceof Instruction_Ret )
03649 {
03650
03651 Instruction originstruction = null;
03652
03653 BasicBlock matchingjsrBB = ( BasicBlock ) RetToJsrBB.get ( i );
03654
03655 BasicBlock matchingjsrnextBB = null;
03656
03657 matchingjsrnextBB = ( BasicBlock) h.get ( (Instruction ) JsrToNext.get ( matchingjsrBB.tail ) );
03658
03659 b.succ.removeAllElements();
03660
03661 b.succ.addElement ( matchingjsrnextBB );
03662
03663 for ( int k= matchingjsrnextBB.pred.size() - 1; k > -1;k-- )
03664 {
03665
03666 BasicBlock tempBB = ( BasicBlock ) matchingjsrnextBB.pred.elementAt ( k );
03667
03668 if ( tempBB.tail instanceof Instruction_Ret )
03669 matchingjsrnextBB.pred.removeElement ( tempBB );
03670
03671 }
03672
03673
03674 matchingjsrnextBB.pred.addElement ( b );
03675
03676 BasicBlock matchingjsrsuccBB = ( BasicBlock ) RetToJsrSucc.get( i );
03677
03678 Instruction temp = b.head;
03679
03680 if ( b.head == b.tail )
03681 {
03682
03683 originstruction = b.tail;
03684
03685 b.head = new Instruction_Goto();
03686
03687 b.head.branchpoints ( matchingjsrnextBB.head );
03688
03689 ( ( Instruction_Goto ) b.head).target = matchingjsrnextBB.head;
03690
03691 if ( originstruction.labelled )
03692 b.head.labelled = true;
03693
03694 Iterator entriesIt = JsrToNext.entries().iterator();
03695
03696 while ( entriesIt.hasNext() )
03697 {
03698
03699 Instruction entryins = ( Instruction ) ( ( Map.Entry ) entriesIt.next() ).getKey();
03700
03701 if ( ( ( Instruction ) JsrToNext.get ( entryins ) ) == originstruction )
03702 {
03703
03704 JsrToNext.put ( entryins, b.head );
03705
03706 }
03707
03708 }
03709
03710 replacedinstructionHT.put ( originstruction, b.head );
03711
03712 method.instructionList.add ( b.head );
03713
03714 h.put ( b.head, b );
03715
03716 b.tail = b.head;
03717
03718 }
03719 else
03720 {
03721
03722 originstruction = b.tail;
03723
03724 while ( temp.next != b.tail )
03725 {
03726
03727 temp = temp.next;
03728
03729 }
03730
03731 temp.next = new Instruction_Goto();
03732
03733 temp.next.branchpoints ( matchingjsrnextBB.head );
03734
03735 ((Instruction_Goto) temp.next).target = matchingjsrnextBB.head;
03736
03737 if ( originstruction.labelled )
03738 temp.next.labelled = true;
03739
03740
03741 Iterator entriesIt = JsrToNext.entries().iterator();
03742
03743 while ( entriesIt.hasNext() )
03744 {
03745
03746 Instruction entryins = ( Instruction ) ( ( Map.Entry ) entriesIt.next() ).getKey();
03747
03748 if ( ( ( Instruction ) JsrToNext.get ( entryins ) ) == originstruction )
03749 {
03750
03751 JsrToNext.put ( entryins, temp.next );
03752
03753 }
03754
03755 }
03756
03757 replacedinstructionHT.put ( originstruction, temp.next );
03758
03759 method.instructionList.add ( temp.next );
03760
03761 b.tail = temp.next;
03762
03763 }
03764
03765 b.tail.next = null;
03766
03767 method.instructionList.remove ( originstruction );
03768
03769 temp = matchingjsrBB.head;
03770
03771 if ( matchingjsrBB.head == matchingjsrBB.tail )
03772 {
03773
03774 originstruction = matchingjsrBB.tail;
03775
03776 matchingjsrBB.head = new Instruction_Goto();
03777
03778 matchingjsrBB.head.branchpoints ( matchingjsrsuccBB.head.next );
03779
03780 ((Instruction_Goto)matchingjsrBB.head).target = matchingjsrsuccBB.head.next;
03781
03782 if ( originstruction.labelled )
03783 matchingjsrBB.head.labelled = true;
03784
03785
03786
03787 Iterator entriesIt = JsrToNext.entries().iterator();
03788
03789 while ( entriesIt.hasNext() )
03790 {
03791
03792 Instruction entryins = ( Instruction ) ( ( Map.Entry ) entriesIt.next() ).getKey();
03793
03794 if ( ( ( Instruction ) JsrToNext.get ( entryins ) ) == originstruction )
03795 {
03796
03797 JsrToNext.put ( entryins, matchingjsrBB.head );
03798
03799 }
03800
03801 }
03802
03803 replacedinstructionHT.put ( originstruction, matchingjsrBB.head );
03804
03805 method.instructionList.add ( matchingjsrBB.head );
03806
03807 h.put ( matchingjsrBB.head, matchingjsrBB );
03808
03809 matchingjsrBB.tail = matchingjsrBB.head;
03810
03811 }
03812 else
03813 {
03814
03815 originstruction = matchingjsrBB.tail;
03816
03817 while ( temp.next != matchingjsrBB.tail )
03818 {
03819
03820 temp = temp.next;
03821
03822 }
03823
03824 temp.next = new Instruction_Goto();
03825
03826 temp.next.branchpoints ( matchingjsrsuccBB.head.next );
03827
03828
03829 ((Instruction_Goto)temp.next).target = matchingjsrsuccBB.head.next;
03830
03831 if ( originstruction.labelled )
03832 temp.next.labelled = true;
03833
03834
03835 Iterator entriesIt = JsrToNext.entries().iterator();
03836
03837 while ( entriesIt.hasNext() )
03838 {
03839
03840 Instruction entryins = ( Instruction ) ( ( Map.Entry ) entriesIt.next() ).getKey();
03841
03842 if ( ( ( Instruction ) JsrToNext.get ( entryins ) ) == originstruction )
03843 {
03844
03845 JsrToNext.put ( entryins, temp.next );
03846
03847 }
03848
03849 }
03850
03851
03852 replacedinstructionHT.put ( originstruction, temp.next );
03853
03854 method.instructionList.add ( temp.next );
03855
03856 matchingjsrBB.tail = temp.next;
03857
03858 }
03859
03860 matchingjsrBB.tail.next = null;
03861
03862 method.instructionList.remove ( originstruction );
03863
03864 temp = matchingjsrsuccBB.head;
03865
03866 Iterator entriesIt = JsrToNext.entries().iterator();
03867
03868 while ( entriesIt.hasNext() )
03869 {
03870
03871 Instruction entryins = ( Instruction ) ( ( Map.Entry ) entriesIt.next() ).getKey();
03872
03873 if ( ( ( Instruction ) JsrToNext.get ( entryins ) ) == originstruction )
03874 {
03875
03876 JsrToNext.put ( entryins, temp.next );
03877
03878 }
03879
03880 }
03881
03882 replacedinstructionHT.put ( temp, temp.next );
03883
03884 matchingjsrsuccBB.head = temp.next;
03885
03886 h.put ( temp.next, matchingjsrsuccBB );
03887
03888 method.instructionList.remove ( temp );
03889
03890 }
03891
03892 b = b.next;
03893
03894 }
03895
03896 }
03897 TypeStack popSafe(TypeStack typeStack, Type requiredType)
03898 {
03899
03900
03901
03902
03903
03904
03905 return typeStack.pop();
03906 }
03907 TypeStack popSafeArrayType(TypeStack typeStack)
03908 {
03909
03910
03911
03912
03913
03914
03915
03916
03917
03918 return typeStack.pop();
03919 }
03920 TypeStack popSafeRefType(TypeStack typeStack)
03921 {
03922
03923
03924
03925
03926
03927
03928
03929
03930
03931 return typeStack.pop();
03932 }
03933 private void prepareForGC () {
03934
03935 RetToJsr = null;
03936 RetToJsrBB = null;
03937 RetToJsrSucc = null;
03938 RetToRetBB = null;
03939 RetToOrigJsrSucc = null;
03940 RetToOrigJsr = null;
03941 RetToOrigJsrBB = null;
03942 RetToOrigRetBB = null;
03943 JsrToNext = null;
03944 replacedinstructionHT = null;
03945 clonedHT = null;
03946 endofBBList = null;
03947 highestBlock = null;
03948
03949
03950
03951 }
03952 private OutFlow processCPEntry(cp_info constant_pool[],int i,
03953 TypeStack typeStack,
03954 SootMethod jmethod)
03955 {
03956 cp_info c = constant_pool[i];
03957
03958 if (c instanceof CONSTANT_Integer_info)
03959 typeStack = typeStack.push(IntType.v());
03960 else if (c instanceof CONSTANT_Float_info)
03961 typeStack = typeStack.push(FloatType.v());
03962 else if (c instanceof CONSTANT_Long_info)
03963 {
03964 typeStack = typeStack.push(LongType.v());
03965 typeStack = typeStack.push(Long2ndHalfType.v());
03966 }
03967 else if (c instanceof CONSTANT_Double_info)
03968 {
03969 typeStack = typeStack.push(DoubleType.v());
03970 typeStack = typeStack.push(Double2ndHalfType.v());
03971 }
03972 else if (c instanceof CONSTANT_String_info)
03973 typeStack = typeStack.push(RefType.v("java.lang.String"));
03974 else if (c instanceof CONSTANT_Utf8_info)
03975 typeStack = typeStack.push(RefType.v("java.lang.String"));
03976 else
03977 throw new RuntimeException("Attempting to push a non-constant cp entry");
03978
03979 return new OutFlow(typeStack);
03980 }
03981 OutFlow processFlow(Instruction ins, TypeStack typeStack,
03982 cp_info[] constant_pool)
03983 {
03984 int x;
03985 x = ((int)(ins.code))&0xff;
03986
03987
03988 switch(x)
03989 {
03990 case ByteCode.BIPUSH:
03991 typeStack = typeStack.push(IntType.v());
03992 break;
03993
03994 case ByteCode.SIPUSH:
03995 typeStack = typeStack.push(IntType.v());
03996 break;
03997
03998 case ByteCode.LDC1:
03999 return processCPEntry(constant_pool,
04000 ((Instruction_Ldc1)ins).arg_b, typeStack, jmethod);
04001
04002 case ByteCode.LDC2:
04003 case ByteCode.LDC2W:
04004 return processCPEntry(constant_pool,
04005 ((Instruction_intindex)ins).arg_i, typeStack, jmethod);
04006
04007 case ByteCode.ACONST_NULL:
04008 typeStack = typeStack.push(RefType.v("java.lang.Object"));
04009 break;
04010
04011 case ByteCode.ICONST_M1:
04012 case ByteCode.ICONST_0:
04013 case ByteCode.ICONST_1:
04014 case ByteCode.ICONST_2:
04015 case ByteCode.ICONST_3:
04016 case ByteCode.ICONST_4:
04017 case ByteCode.ICONST_5:
04018 typeStack = typeStack.push(IntType.v());
04019 break;
04020 case ByteCode.LCONST_0:
04021 case ByteCode.LCONST_1:
04022 typeStack = typeStack.push(LongType.v());
04023 typeStack = typeStack.push(Long2ndHalfType.v());
04024 break;
04025 case ByteCode.FCONST_0:
04026 case ByteCode.FCONST_1:
04027 case ByteCode.FCONST_2:
04028 typeStack = typeStack.push(FloatType.v());
04029 break;
04030 case ByteCode.DCONST_0:
04031 case ByteCode.DCONST_1:
04032 typeStack = typeStack.push(DoubleType.v());
04033 typeStack = typeStack.push(Double2ndHalfType.v());
04034 break;
04035 case ByteCode.ILOAD:
04036 typeStack = typeStack.push(IntType.v());
04037 break;
04038
04039 case ByteCode.FLOAD:
04040 typeStack = typeStack.push(FloatType.v());
04041 break;
04042
04043 case ByteCode.ALOAD:
04044 typeStack = typeStack.push(RefType.v("java.lang.Object"));
04045
04046 break;
04047
04048 case ByteCode.DLOAD:
04049 typeStack = typeStack.push(DoubleType.v());
04050 typeStack = typeStack.push(Double2ndHalfType.v());
04051 break;
04052
04053 case ByteCode.LLOAD:
04054 typeStack = typeStack.push(LongType.v());
04055 typeStack = typeStack.push(Long2ndHalfType.v());
04056 break;
04057
04058 case ByteCode.ILOAD_0:
04059 case ByteCode.ILOAD_1:
04060 case ByteCode.ILOAD_2:
04061 case ByteCode.ILOAD_3:
04062 typeStack = typeStack.push(IntType.v());
04063 break;
04064
04065 case ByteCode.FLOAD_0:
04066 case ByteCode.FLOAD_1:
04067 case ByteCode.FLOAD_2:
04068 case ByteCode.FLOAD_3:
04069 typeStack = typeStack.push(FloatType.v());
04070 break;
04071
04072 case ByteCode.ALOAD_0:
04073 case ByteCode.ALOAD_1:
04074 case ByteCode.ALOAD_2:
04075 case ByteCode.ALOAD_3:
04076 typeStack = typeStack.push(RefType.v("java.lang.Object"));
04077
04078 break;
04079
04080 case ByteCode.LLOAD_0:
04081 case ByteCode.LLOAD_1:
04082 case ByteCode.LLOAD_2:
04083 case ByteCode.LLOAD_3:
04084 typeStack = typeStack.push(LongType.v());
04085 typeStack = typeStack.push(Long2ndHalfType.v());
04086 break;
04087
04088 case ByteCode.DLOAD_0:
04089 case ByteCode.DLOAD_1:
04090 case ByteCode.DLOAD_2:
04091 case ByteCode.DLOAD_3:
04092 typeStack = typeStack.push(DoubleType.v());
04093 typeStack = typeStack.push(Double2ndHalfType.v());
04094 break;
04095
04096 case ByteCode.ISTORE:
04097 typeStack = popSafe(typeStack, IntType.v());
04098 break;
04099
04100 case ByteCode.FSTORE:
04101 typeStack = popSafe(typeStack, FloatType.v());
04102 break;
04103
04104 case ByteCode.ASTORE:
04105 typeStack = typeStack.pop();
04106 break;
04107
04108 case ByteCode.LSTORE:
04109 typeStack = popSafe(typeStack, Long2ndHalfType.v());
04110 typeStack = popSafe(typeStack, LongType.v());
04111 break;
04112
04113 case ByteCode.DSTORE:
04114 typeStack = popSafe(typeStack, Double2ndHalfType.v());
04115 typeStack = popSafe(typeStack, DoubleType.v());
04116 break;
04117
04118 case ByteCode.ISTORE_0:
04119 case ByteCode.ISTORE_1:
04120 case ByteCode.ISTORE_2:
04121 case ByteCode.ISTORE_3:
04122 typeStack = popSafe(typeStack, IntType.v());
04123 break;
04124
04125 case ByteCode.FSTORE_0:
04126 case ByteCode.FSTORE_1:
04127 case ByteCode.FSTORE_2:
04128 case ByteCode.FSTORE_3:
04129 typeStack = popSafe(typeStack, FloatType.v());
04130 break;
04131
04132 case ByteCode.ASTORE_0:
04133 case ByteCode.ASTORE_1:
04134 case ByteCode.ASTORE_2:
04135 case ByteCode.ASTORE_3:
04136 if(!(typeStack.top() instanceof StmtAddressType) &&
04137 !(typeStack.top() instanceof RefType) &&
04138 !(typeStack.top() instanceof ArrayType))
04139 {
04140 throw new RuntimeException("Astore failed, invalid stack type: " + typeStack.top());
04141 }
04142
04143 typeStack = typeStack.pop();
04144 break;
04145
04146 case ByteCode.LSTORE_0:
04147 case ByteCode.LSTORE_1:
04148 case ByteCode.LSTORE_2:
04149 case ByteCode.LSTORE_3:
04150 typeStack = popSafe(typeStack, Long2ndHalfType.v());
04151 typeStack = popSafe(typeStack, LongType.v());
04152 break;
04153
04154 case ByteCode.DSTORE_0:
04155 case ByteCode.DSTORE_1:
04156 case ByteCode.DSTORE_2:
04157 case ByteCode.DSTORE_3:
04158 typeStack = popSafe(typeStack, Double2ndHalfType.v());
04159 typeStack = popSafe(typeStack, DoubleType.v());
04160 break;
04161
04162 case ByteCode.IINC:
04163 break;
04164
04165 case ByteCode.WIDE:
04166 throw new RuntimeException("Wide instruction should not be encountered");
04167
04168
04169 case ByteCode.NEWARRAY:
04170 {
04171 typeStack = popSafe(typeStack, IntType.v());
04172 BaseType baseType = (BaseType) jimpleTypeOfAtype(((Instruction_Newarray)ins).atype);
04173
04174 typeStack = typeStack.push(ArrayType.v(baseType, 1));
04175 break;
04176 }
04177
04178 case ByteCode.ANEWARRAY:
04179 {
04180 CONSTANT_Class_info c = (CONSTANT_Class_info) constant_pool[
04181 ((Instruction_Anewarray)ins).arg_i];
04182
04183 String name = ((CONSTANT_Utf8_info) (constant_pool[c.name_index])).convert();
04184 name = name.replace('/', '.');
04185
04186 typeStack = popSafe(typeStack, IntType.v());
04187 typeStack = typeStack.push(ArrayType.v(
04188 RefType.v(name), 1));
04189 break;
04190 }
04191
04192 case ByteCode.MULTIANEWARRAY:
04193 {
04194 int bdims = (int)(((Instruction_Multianewarray)ins).dims);
04195
04196
04197 CONSTANT_Class_info c = (CONSTANT_Class_info) constant_pool[
04198 ((Instruction_Multianewarray)ins).arg_i];
04199
04200 String arrayDescriptor = ((CONSTANT_Utf8_info) (constant_pool[c.name_index])).convert();
04201
04202 ArrayType arrayType = (ArrayType)
04203 Util.jimpleTypeOfFieldDescriptor(cm, arrayDescriptor);
04204
04205 for (int j=0;j<bdims;j++)
04206 typeStack = popSafe(typeStack, IntType.v());
04207
04208 typeStack = typeStack.push(arrayType);
04209 break;
04210 }
04211
04212 case ByteCode.ARRAYLENGTH:
04213 typeStack = popSafeRefType(typeStack);
04214 typeStack = typeStack.push(IntType.v());
04215 break;
04216
04217 case ByteCode.IALOAD:
04218 case ByteCode.BALOAD:
04219 case ByteCode.CALOAD:
04220 case ByteCode.SALOAD:
04221 typeStack = popSafe(typeStack, IntType.v());
04222 typeStack = popSafeRefType(typeStack);
04223 typeStack = typeStack.push(IntType.v());
04224 break;
04225 case ByteCode.FALOAD:
04226 typeStack = popSafe(typeStack, FloatType.v());
04227 typeStack = popSafeRefType(typeStack);
04228 typeStack = typeStack.push(FloatType.v());
04229 break;
04230
04231 case ByteCode.AALOAD:
04232 {
04233
04234 typeStack = popSafe(typeStack, IntType.v());
04235
04236 if(typeStack.top() instanceof ArrayType)
04237 {
04238 ArrayType arrayType = (ArrayType) typeStack.top();
04239 typeStack = popSafeRefType(typeStack);
04240
04241 if(arrayType.numDimensions == 1)
04242 typeStack = typeStack.push(arrayType.baseType);
04243 else
04244 typeStack = typeStack.push(ArrayType.v(arrayType.baseType, arrayType.numDimensions - 1));
04245 }
04246 else {
04247
04248
04249 typeStack = popSafeRefType(typeStack);
04250
04251 typeStack = typeStack.push(RefType.v("java.lang.Object"));
04252 }
04253
04254 break;
04255 }
04256 case ByteCode.LALOAD:
04257 typeStack = popSafe(typeStack, IntType.v());
04258 typeStack = popSafeRefType(typeStack);
04259 typeStack = typeStack.push(LongType.v());
04260 typeStack = typeStack.push(Long2ndHalfType.v());
04261 break;
04262
04263 case ByteCode.DALOAD:
04264 typeStack = popSafe(typeStack, IntType.v());
04265 typeStack = popSafeRefType(typeStack);
04266 typeStack = typeStack.push(DoubleType.v());
04267 typeStack = typeStack.push(Double2ndHalfType.v());
04268 break;
04269
04270 case ByteCode.IASTORE:
04271 case ByteCode.BASTORE:
04272 case ByteCode.CASTORE:
04273 case ByteCode.SASTORE:
04274 typeStack = popSafe(typeStack, IntType.v());
04275 typeStack = popSafe(typeStack, IntType.v());
04276 typeStack = popSafeRefType(typeStack);
04277 break;
04278
04279 case ByteCode.AASTORE:
04280 typeStack = popSafeRefType(typeStack);
04281 typeStack = popSafe(typeStack, IntType.v());
04282 typeStack = popSafeRefType(typeStack);
04283 break;
04284
04285 case ByteCode.FASTORE:
04286 typeStack = popSafe(typeStack, FloatType.v());
04287 typeStack = popSafe(typeStack, IntType.v());
04288 typeStack = popSafeRefType(typeStack);
04289 break;
04290
04291 case ByteCode.LASTORE:
04292 typeStack = popSafe(typeStack, Long2ndHalfType.v());
04293 typeStack = popSafe(typeStack, LongType.v());
04294 typeStack = popSafe(typeStack, IntType.v());
04295 typeStack = popSafeRefType(typeStack);
04296 break;
04297
04298 case ByteCode.DASTORE:
04299 typeStack = popSafe(typeStack, Double2ndHalfType.v());
04300 typeStack = popSafe(typeStack, DoubleType.v());
04301 typeStack = popSafe(typeStack, IntType.v());
04302 typeStack = popSafeRefType(typeStack);
04303 break;
04304
04305 case ByteCode.NOP:
04306 break;
04307
04308 case ByteCode.POP:
04309 typeStack = typeStack.pop();
04310 break;
04311
04312 case ByteCode.POP2:
04313 typeStack = typeStack.pop();
04314 typeStack = typeStack.pop();
04315 break;
04316
04317 case ByteCode.DUP:
04318 typeStack = typeStack.push(typeStack.top());
04319 break;
04320
04321 case ByteCode.DUP2:
04322 {
04323 Type topType = typeStack.get(typeStack.topIndex()),
04324 secondType = typeStack.get(typeStack.topIndex()-1);
04325 typeStack = (typeStack.push(secondType)).push(topType);
04326 break;
04327 }
04328
04329 case ByteCode.DUP_X1:
04330 {
04331 Type topType = typeStack.get(typeStack.topIndex()),
04332 secondType = typeStack.get(typeStack.topIndex()-1);
04333
04334 typeStack = typeStack.pop().pop();
04335
04336 typeStack = typeStack.push(topType).push(secondType).push(topType);
04337 break;
04338 }
04339
04340 case ByteCode.DUP_X2:
04341 {
04342 Type topType = typeStack.get(typeStack.topIndex()),
04343 secondType = typeStack.get(typeStack.topIndex()-1),
04344 thirdType = typeStack.get(typeStack.topIndex()-2);
04345
04346 typeStack = typeStack.pop().pop().pop();
04347
04348 typeStack = typeStack.push(topType).push(thirdType).push(secondType).push(topType);
04349 break;
04350 }
04351
04352 case ByteCode.DUP2_X1:
04353 {
04354 Type topType = typeStack.get(typeStack.topIndex()),
04355 secondType = typeStack.get(typeStack.topIndex()-1),
04356 thirdType = typeStack.get(typeStack.topIndex()-2);
04357
04358 typeStack = typeStack.pop().pop().pop();
04359
04360 typeStack = typeStack.push(secondType).push(topType).
04361 push(thirdType).push(secondType).push(topType);
04362 break;
04363 }
04364
04365 case ByteCode.DUP2_X2:
04366 {
04367 Type topType = typeStack.get(typeStack.topIndex()),
04368 secondType = typeStack.get(typeStack.topIndex()-1),
04369 thirdType = typeStack.get(typeStack.topIndex()-2),
04370 fourthType = typeStack.get(typeStack.topIndex()-3);
04371
04372 typeStack = typeStack.pop().pop().pop().pop();
04373
04374 typeStack = typeStack.push(secondType).push(topType).
04375 push(fourthType).push(thirdType).push(secondType).push(topType);
04376 break;
04377 }
04378
04379 case ByteCode.SWAP:
04380 {
04381 Type topType = typeStack.top();
04382
04383 typeStack = typeStack.pop();
04384
04385 Type secondType = typeStack.top();
04386
04387 typeStack = typeStack.pop();
04388
04389 typeStack = typeStack.push(topType);
04390 typeStack = typeStack.push(secondType);
04391 break;
04392 }
04393
04394
04395 case ByteCode.IADD:
04396 case ByteCode.ISUB:
04397 case ByteCode.IMUL:
04398 case ByteCode.IDIV:
04399 case ByteCode.IREM:
04400 case ByteCode.ISHL:
04401 case ByteCode.ISHR:
04402 case ByteCode.IUSHR:
04403 case ByteCode.IAND:
04404 case ByteCode.IOR:
04405 case ByteCode.IXOR:
04406 typeStack = popSafe(typeStack, IntType.v());
04407 typeStack = popSafe(typeStack, IntType.v());
04408 typeStack = typeStack.push(IntType.v());
04409 break;
04410
04411 case ByteCode.LUSHR:
04412 case ByteCode.LSHR:
04413 case ByteCode.LSHL:
04414 typeStack = popSafe(typeStack, IntType.v());
04415 typeStack = popSafe(typeStack, Long2ndHalfType.v());
04416 typeStack = popSafe(typeStack, LongType.v());
04417 typeStack = typeStack.push(LongType.v());
04418 typeStack = typeStack.push(Long2ndHalfType.v());
04419 break;
04420
04421 case ByteCode.LREM:
04422 case ByteCode.LDIV:
04423 case ByteCode.LMUL:
04424 case ByteCode.LSUB:
04425 case ByteCode.LADD:
04426 case ByteCode.LAND:
04427 case ByteCode.LOR:
04428 case ByteCode.LXOR:
04429 typeStack = popSafe(typeStack, Long2ndHalfType.v());
04430 typeStack = popSafe(typeStack, LongType.v());
04431 typeStack = popSafe(typeStack, Long2ndHalfType.v());
04432 typeStack = popSafe(typeStack, LongType.v());
04433 typeStack = typeStack.push(LongType.v());
04434 typeStack = typeStack.push(Long2ndHalfType.v());
04435 break;
04436
04437 case ByteCode.FREM:
04438 case ByteCode.FDIV:
04439 case ByteCode.FMUL:
04440 case ByteCode.FSUB:
04441 case ByteCode.FADD:
04442 typeStack = popSafe(typeStack, FloatType.v());
04443 typeStack = popSafe(typeStack, FloatType.v());
04444 typeStack = typeStack.push(FloatType.v());
04445 break;
04446
04447 case ByteCode.DREM:
04448 case ByteCode.DDIV:
04449 case ByteCode.DMUL:
04450 case ByteCode.DSUB:
04451 case ByteCode.DADD:
04452 typeStack = popSafe(typeStack, Double2ndHalfType.v());
04453 typeStack = popSafe(typeStack, DoubleType.v());
04454 typeStack = popSafe(typeStack, Double2ndHalfType.v());
04455 typeStack = popSafe(typeStack, DoubleType.v());
04456 typeStack = typeStack.push(DoubleType.v());
04457 typeStack = typeStack.push(Double2ndHalfType.v());
04458 break;
04459
04460 case ByteCode.INEG:
04461 case ByteCode.LNEG:
04462 case ByteCode.FNEG:
04463 case ByteCode.DNEG:
04464
04465
04466 break;
04467
04468 case ByteCode.I2L:
04469 typeStack = popSafe(typeStack, IntType.v());
04470 typeStack = typeStack.push(LongType.v());
04471 typeStack = typeStack.push(Long2ndHalfType.v());
04472 break;
04473
04474 case ByteCode.I2F:
04475 typeStack = popSafe(typeStack, IntType.v());
04476 typeStack = typeStack.push(FloatType.v());
04477 break;
04478
04479 case ByteCode.I2D:
04480 typeStack = popSafe(typeStack, IntType.v());
04481 typeStack = typeStack.push(DoubleType.v());
04482 typeStack = typeStack.push(Double2ndHalfType.v());
04483 break;
04484
04485 case ByteCode.L2I:
04486 typeStack = popSafe(typeStack, Long2ndHalfType.v());
04487 typeStack = popSafe(typeStack, LongType.v());
04488 typeStack = typeStack.push(IntType.v());
04489 break;
04490
04491 case ByteCode.L2F:
04492 typeStack = popSafe(typeStack, Long2ndHalfType.v());
04493 typeStack = popSafe(typeStack, LongType.v());
04494 typeStack = typeStack.push(FloatType.v());
04495 break;
04496
04497 case ByteCode.L2D:
04498 typeStack = popSafe(typeStack, Long2ndHalfType.v());
04499 typeStack = popSafe(typeStack, LongType.v());
04500 typeStack = typeStack.push(DoubleType.v());
04501 typeStack = typeStack.push(Double2ndHalfType.v());
04502 break;
04503
04504 case ByteCode.F2I:
04505 typeStack = popSafe(typeStack, FloatType.v());
04506 typeStack = typeStack.push(IntType.v());
04507 break;
04508
04509 case ByteCode.F2L:
04510 typeStack = popSafe(typeStack, FloatType.v());
04511 typeStack = typeStack.push(LongType.v());
04512 typeStack = typeStack.push(Long2ndHalfType.v());
04513 break;
04514
04515 case ByteCode.F2D:
04516 typeStack = popSafe(typeStack, FloatType.v());
04517 typeStack = typeStack.push(DoubleType.v());
04518 typeStack = typeStack.push(Double2ndHalfType.v());
04519 break;
04520
04521 case ByteCode.D2I:
04522 typeStack = popSafe(typeStack, Double2ndHalfType.v());
04523 typeStack = popSafe(typeStack, DoubleType.v());
04524 typeStack = typeStack.push(IntType.v());
04525 break;
04526
04527 case ByteCode.D2L:
04528 typeStack = popSafe(typeStack, Double2ndHalfType.v());
04529 typeStack = popSafe(typeStack, DoubleType.v());
04530 typeStack = typeStack.push(LongType.v());
04531 typeStack = typeStack.push(Long2ndHalfType.v());
04532 break;
04533
04534 case ByteCode.D2F:
04535 typeStack = popSafe(typeStack, Double2ndHalfType.v());
04536 typeStack = popSafe(typeStack, DoubleType.v());
04537 typeStack = typeStack.push(FloatType.v());
04538 break;
04539
04540 case ByteCode.INT2BYTE:
04541 break;
04542 case ByteCode.INT2CHAR:
04543 break;
04544 case ByteCode.INT2SHORT:
04545 break;
04546
04547 case ByteCode.IFEQ:
04548 case ByteCode.IFGT:
04549 case ByteCode.IFLT:
04550 case ByteCode.IFLE:
04551 case ByteCode.IFNE:
04552 case ByteCode.IFGE:
04553 typeStack = popSafe(typeStack, IntType.v());
04554 break;
04555
04556 case ByteCode.IFNULL:
04557 case ByteCode.IFNONNULL:
04558 typeStack = popSafeRefType(typeStack);
04559 break;
04560
04561 case ByteCode.IF_ICMPEQ:
04562 case ByteCode.IF_ICMPLT:
04563 case ByteCode.IF_ICMPLE:
04564 case ByteCode.IF_ICMPNE:
04565 case ByteCode.IF_ICMPGT:
04566 case ByteCode.IF_ICMPGE:
04567 typeStack = popSafe(typeStack, IntType.v());
04568 typeStack = popSafe(typeStack, IntType.v());
04569 break;
04570
04571 case ByteCode.LCMP:
04572 typeStack = popSafe(typeStack, Long2ndHalfType.v());
04573 typeStack = popSafe(typeStack, LongType.v());
04574 typeStack = popSafe(typeStack, Long2ndHalfType.v());
04575 typeStack = popSafe(typeStack, LongType.v());
04576 typeStack = typeStack.push(IntType.v());
04577 break;
04578
04579 case ByteCode.FCMPL:
04580 case ByteCode.FCMPG:
04581 typeStack = popSafe(typeStack, FloatType.v());
04582 typeStack = popSafe(typeStack, FloatType.v());
04583 typeStack = typeStack.push(IntType.v());
04584 break;
04585
04586 case ByteCode.DCMPL:
04587 case ByteCode.DCMPG:
04588 typeStack = popSafe(typeStack, Double2ndHalfType.v());
04589 typeStack = popSafe(typeStack, DoubleType.v());
04590 typeStack = popSafe(typeStack, Double2ndHalfType.v());
04591 typeStack = popSafe(typeStack, DoubleType.v());
04592 typeStack = typeStack.push(IntType.v());
04593 break;
04594
04595 case ByteCode.IF_ACMPEQ:
04596 case ByteCode.IF_ACMPNE:
04597 typeStack = popSafeRefType(typeStack);
04598 typeStack = popSafeRefType(typeStack);
04599 break;
04600
04601 case ByteCode.GOTO:
04602 case ByteCode.GOTO_W:
04603 break;
04604
04605 case ByteCode.JSR:
04606 case ByteCode.JSR_W:
04607 typeStack = typeStack.push(StmtAddressType.v());
04608 break;
04609
04610 case ByteCode.RET:
04611 break;
04612
04613 case ByteCode.RET_W:
04614 break;
04615
04616 case ByteCode.RETURN:
04617 break;
04618
04619 case ByteCode.IRETURN:
04620 typeStack = popSafe(typeStack, IntType.v());
04621 break;
04622
04623 case ByteCode.FRETURN:
04624 typeStack = popSafe(typeStack, FloatType.v());
04625 break;
04626
04627 case ByteCode.ARETURN:
04628 typeStack = popSafeRefType(typeStack);
04629 break;
04630
04631 case ByteCode.DRETURN:
04632 typeStack = popSafe(typeStack, Double2ndHalfType.v());
04633 typeStack = popSafe(typeStack, DoubleType.v());
04634 break;
04635
04636 case ByteCode.LRETURN:
04637 typeStack = popSafe(typeStack, Long2ndHalfType.v());
04638 typeStack = popSafe(typeStack, LongType.v());
04639 break;
04640
04641 case ByteCode.BREAKPOINT:
04642 break;
04643
04644 case ByteCode.TABLESWITCH:
04645 typeStack = popSafe(typeStack, IntType.v());
04646 break;
04647
04648 case ByteCode.LOOKUPSWITCH:
04649 typeStack = popSafe(typeStack, IntType.v());
04650 break;
04651
04652 case ByteCode.PUTFIELD:
04653 {
04654 Type type = byteCodeTypeOf(jimpleTypeOfFieldInFieldRef(cm, constant_pool,
04655 ((Instruction_Putfield)ins).arg_i));
04656
04657 if(type.equals(DoubleType.v()))
04658 {
04659 typeStack = popSafe(typeStack, Double2ndHalfType.v());
04660 typeStack = popSafe(typeStack, DoubleType.v());
04661 }
04662 else if(type.equals(LongType.v()))
04663 {
04664 typeStack = popSafe(typeStack, Long2ndHalfType.v());
04665 typeStack = popSafe(typeStack, LongType.v());
04666 }
04667 else if(type instanceof RefType)
04668 typeStack = popSafeRefType(typeStack);
04669 else
04670 typeStack = popSafe(typeStack, type);
04671
04672 typeStack = popSafeRefType(typeStack);
04673 break;
04674 }
04675
04676 case ByteCode.GETFIELD:
04677 {
04678 Type type = byteCodeTypeOf(jimpleTypeOfFieldInFieldRef(cm, constant_pool,
04679 ((Instruction_Getfield)ins).arg_i));
04680
04681 typeStack = popSafeRefType(typeStack);
04682
04683 if (type.equals(DoubleType.v()))
04684 {
04685 typeStack = typeStack.push(DoubleType.v());
04686 typeStack = typeStack.push(Double2ndHalfType.v());
04687 }
04688 else if(type.equals(LongType.v()))
04689 {
04690 typeStack = typeStack.push(LongType.v());
04691 typeStack = typeStack.push(Long2ndHalfType.v());
04692 }
04693 else
04694 typeStack = typeStack.push(type);
04695 break;
04696 }
04697
04698 case ByteCode.PUTSTATIC:
04699 {
04700 Type type = byteCodeTypeOf(jimpleTypeOfFieldInFieldRef(cm, constant_pool,
04701 ((Instruction_Putstatic)ins).arg_i));
04702
04703 if(type.equals(DoubleType.v()))
04704 {
04705 typeStack = popSafe(typeStack, Double2ndHalfType.v());
04706 typeStack = popSafe(typeStack, DoubleType.v());
04707 }
04708 else if(type.equals(LongType.v()))
04709 {
04710 typeStack = popSafe(typeStack, Long2ndHalfType.v());
04711 typeStack = popSafe(typeStack, LongType.v());
04712 }
04713 else if(type instanceof RefType)
04714 typeStack = popSafeRefType(typeStack);
04715 else
04716 typeStack = popSafe(typeStack, type);
04717
04718 break;
04719 }
04720
04721 case ByteCode.GETSTATIC:
04722 {
04723 Type type = byteCodeTypeOf(jimpleTypeOfFieldInFieldRef(cm, constant_pool,
04724 ((Instruction_Getstatic)ins).arg_i));
04725
04726 if (type.equals(DoubleType.v()))
04727 {
04728 typeStack = typeStack.push(DoubleType.v());
04729 typeStack = typeStack.push(Double2ndHalfType.v());
04730 }
04731 else if(type.equals(LongType.v()))
04732 {
04733 typeStack = typeStack.push(LongType.v());
04734 typeStack = typeStack.push(Long2ndHalfType.v());
04735 }
04736 else
04737 typeStack = typeStack.push(type);
04738 break;
04739 }
04740
04741 case ByteCode.INVOKEVIRTUAL:
04742 {
04743 Instruction_Invokevirtual iv = (Instruction_Invokevirtual)ins;
04744 int args = cp_info.countParams(constant_pool,iv.arg_i);
04745 Type returnType = byteCodeTypeOf(jimpleReturnTypeOfMethodRef(cm,
04746 constant_pool, iv.arg_i));
04747
04748
04749 for (int j=args-1;j>=0;j--)
04750 {
04751 if(typeStack.top().equals(Long2ndHalfType.v()))
04752 {
04753 typeStack = popSafe(typeStack, Long2ndHalfType.v());
04754 typeStack = popSafe(typeStack, LongType.v());
04755
04756 }
04757 else if(typeStack.top().equals(Double2ndHalfType.v()))
04758 {
04759 typeStack = popSafe(typeStack, Double2ndHalfType.v());
04760 typeStack = popSafe(typeStack, DoubleType.v());
04761 }
04762 else
04763 typeStack = popSafe(typeStack, typeStack.top());
04764 }
04765
04766 typeStack = popSafeRefType(typeStack);
04767
04768 if(!returnType.equals(VoidType.v()))
04769 typeStack = smartPush(typeStack, returnType);
04770 break;
04771 }
04772
04773 case ByteCode.INVOKENONVIRTUAL:
04774 {
04775 Instruction_Invokenonvirtual iv = (Instruction_Invokenonvirtual)ins;
04776 int args = cp_info.countParams(constant_pool,iv.arg_i);
04777 Type returnType = byteCodeTypeOf(jimpleReturnTypeOfMethodRef(cm,
04778 constant_pool, iv.arg_i));
04779
04780
04781 for (int j=args-1;j>=0;j--)
04782 {
04783 if(typeStack.top().equals(Long2ndHalfType.v()))
04784 {
04785 typeStack = popSafe(typeStack, Long2ndHalfType.v());
04786 typeStack = popSafe(typeStack, LongType.v());
04787
04788 }
04789 else if(typeStack.top().equals(Double2ndHalfType.v()))
04790 {
04791 typeStack = popSafe(typeStack, Double2ndHalfType.v());
04792 typeStack = popSafe(typeStack, DoubleType.v());
04793 }
04794 else
04795 typeStack = popSafe(typeStack, typeStack.top());
04796 }
04797
04798 typeStack = popSafeRefType(typeStack);
04799
04800 if(!returnType.equals(VoidType.v()))
04801 typeStack = smartPush(typeStack, returnType);
04802 break;
04803 }
04804
04805 case ByteCode.INVOKESTATIC:
04806 {
04807 Instruction_Invokestatic iv = (Instruction_Invokestatic)ins;
04808 int args = cp_info.countParams(constant_pool,iv.arg_i);
04809 Type returnType = byteCodeTypeOf(jimpleReturnTypeOfMethodRef(cm,
04810 constant_pool, iv.arg_i));
04811
04812
04813 for (int j=args-1;j>=0;j--)
04814 {
04815 if(typeStack.top().equals(Long2ndHalfType.v()))
04816 {
04817 typeStack = popSafe(typeStack, Long2ndHalfType.v());
04818 typeStack = popSafe(typeStack, LongType.v());
04819
04820 }
04821 else if(typeStack.top().equals(Double2ndHalfType.v()))
04822 {
04823 typeStack = popSafe(typeStack, Double2ndHalfType.v());
04824 typeStack = popSafe(typeStack, DoubleType.v());
04825 }
04826 else
04827 typeStack = popSafe(typeStack, typeStack.top());
04828 }
04829
04830 if(!returnType.equals(VoidType.v()))
04831 typeStack = smartPush(typeStack, returnType);
04832 break;
04833 }
04834
04835 case ByteCode.INVOKEINTERFACE:
04836 {
04837 Instruction_Invokeinterface iv = (Instruction_Invokeinterface) ins;
04838 int args = cp_info.countParams(constant_pool,iv.arg_i);
04839 Type returnType = byteCodeTypeOf(jimpleReturnTypeOfInterfaceMethodRef(cm,
04840 constant_pool, iv.arg_i));
04841
04842
04843 for (int j=args-1;j>=0;j--)
04844 {
04845 if(typeStack.top().equals(Long2ndHalfType.v()))
04846 {
04847 typeStack = popSafe(typeStack, Long2ndHalfType.v());
04848 typeStack = popSafe(typeStack, LongType.v());
04849
04850 }
04851 else if(typeStack.top().equals(Double2ndHalfType.v()))
04852 {
04853 typeStack = popSafe(typeStack, Double2ndHalfType.v());
04854 typeStack = popSafe(typeStack, DoubleType.v());
04855 }
04856 else
04857 typeStack = popSafe(typeStack, typeStack.top());
04858 }
04859
04860 typeStack = popSafeRefType(typeStack);
04861
04862 if(!returnType.equals(VoidType.v()))
04863 typeStack = smartPush(typeStack, returnType);
04864 break;
04865 }
04866
04867 case ByteCode.ATHROW:
04868
04869
04870
04871
04872 break;
04873
04874 case ByteCode.NEW:
04875 {
04876 Type type = RefType.v(getClassName(constant_pool, ((Instruction_New)ins).arg_i));
04877
04878 typeStack = typeStack.push(type);
04879 break;
04880 }
04881
04882 case ByteCode.CHECKCAST:
04883 {
04884 String className = getClassName(constant_pool, ((Instruction_Checkcast)ins).arg_i);
04885
04886 Type castType;
04887
04888 if(className.startsWith("["))
04889 castType = Util.jimpleTypeOfFieldDescriptor(cm, getClassName(constant_pool,
04890 ((Instruction_Checkcast)ins).arg_i));
04891 else
04892 castType = RefType.v(className);
04893
04894 typeStack = popSafeRefType(typeStack);
04895 typeStack = typeStack.push(castType);
04896 break;
04897 }
04898
04899 case ByteCode.INSTANCEOF:
04900 {
04901 typeStack = popSafeRefType(typeStack);
04902 typeStack = typeStack.push(IntType.v());
04903 break;
04904 }
04905
04906 case ByteCode.MONITORENTER:
04907 typeStack = popSafeRefType(typeStack);
04908 break;
04909 case ByteCode.MONITOREXIT:
04910 typeStack = popSafeRefType(typeStack);
04911 break;
04912
04913 default:
04914 throw new RuntimeException("processFlow failed: Unknown bytecode instruction: " + x);
04915 }
04916
04917 return new OutFlow(typeStack);
04918 }
04919
04920
04921
04922
04923
04924
04925 private void processTargetFixup(BBQ bbq)
04926 {
04927 BasicBlock b,p;
04928 Stmt s;
04929 while (!bbq.isEmpty()) {
04930 try {
04931 b = bbq.pull();
04932 } catch(NoSuchElementException e) { break; }
04933
04934 s = b.getTailJStmt();
04935
04936 if (s instanceof GotoStmt)
04937 {
04938 if (b.succ.size() == 1)
04939 {
04940
04941
04942 ((GotoStmt)s).setTarget(((BasicBlock) b.succ.firstElement()).getHeadJStmt());
04943 }
04944 else
04945 {
04946
04947
04948 if((BasicBlock)(b.succ.firstElement())==b.next)
04949 ((GotoStmt)s).setTarget(((BasicBlock) b.succ.elementAt(1)).getHeadJStmt());
04950 else
04951 ((GotoStmt)s).setTarget(((BasicBlock) b.succ.firstElement()).getHeadJStmt());
04952 }
04953 }
04954 else if (s instanceof IfStmt)
04955 {
04956 if (b.succ.size()!=2)
04957 System.out.println("How can an if not have 2 successors?");
04958
04959 if((BasicBlock)(b.succ.firstElement())==b.next)
04960 {
04961 ((IfStmt)s).setTarget(((BasicBlock) b.succ.elementAt(1)).getHeadJStmt());
04962 }
04963 else
04964 {
04965 ((IfStmt)s).setTarget(((BasicBlock) b.succ.firstElement()).getHeadJStmt());
04966 }
04967
04968 }
04969 else if (s instanceof TableSwitchStmt)
04970 {
04971 int count=0;
04972 TableSwitchStmt sts = (TableSwitchStmt)s;
04973
04974
04975
04976
04977 for (Enumeration e = b.succ.elements();e.hasMoreElements();) {
04978 p = (BasicBlock)(e.nextElement());
04979 if (count==0) {
04980 sts.setDefaultTarget(p.getHeadJStmt());
04981 } else {
04982 sts.setTarget(count-1, p.getHeadJStmt());
04983 }
04984 count++;
04985 }
04986 } else if (s instanceof LookupSwitchStmt)
04987 {
04988 int count=0;
04989 LookupSwitchStmt sls = (LookupSwitchStmt)s;
04990
04991
04992
04993
04994 for (Enumeration e = b.succ.elements();e.hasMoreElements();) {
04995 p = (BasicBlock)(e.nextElement());
04996 if (count==0) {
04997 sls.setDefaultTarget(p.getHeadJStmt());
04998 } else {
04999 sls.setTarget(count-1, p.getHeadJStmt());
05000 }
05001 count++;
05002 }
05003 }
05004
05005 b.done = false;
05006 for (Enumeration e = b.succ.elements();e.hasMoreElements();) {
05007 p = (BasicBlock)(e.nextElement());
05008 if (p.done) bbq.push(p);
05009 }
05010 }
05011 }
05012
05013
05014
05015
05016
05017
05018
05019
05020
05021 public Instruction reconstructInstructions() {
05022 BasicBlock b;
05023 Instruction last = null;
05024
05025 b = cfg;
05026 while (b!=null) {
05027 if (b.tail!=null) {
05028 if (last!=null) last.next = b.head;
05029 last = b.tail;
05030 }
05031 b = b.next;
05032 }
05033 return cfg.head;
05034 }
05035 private void setHighestBlock ( BasicBlock highestBB ) throws java.lang.CloneNotSupportedException {
05036
05037
05038
05039 clonedHT = new HashMap();
05040
05041 clonedstmtsHT = new HashMap();
05042
05043 Instruction prev = highestBB.head;
05044
05045 Instruction clonedprev = ( Instruction ) prev.clone();
05046
05047 clonedstmtsHT.put ( prev, clonedprev );
05048
05049 Instruction clonedhead = clonedprev;
05050
05051 method.instructionList.add ( clonedhead );
05052
05053 Instruction clonedcurrent = null;
05054
05055 while ( prev != highestBB.tail )
05056 {
05057
05058 Instruction current = prev.next;
05059
05060 clonedcurrent = ( Instruction ) current.clone();
05061
05062 clonedstmtsHT.put ( current, clonedcurrent );
05063
05064
05065
05066 method.instructionList.add ( clonedcurrent );
05067
05068 clonedprev.next = clonedcurrent;
05069
05070 prev = current;
05071
05072 clonedprev = clonedcurrent;
05073
05074 }
05075
05076 buildBasicBlock( clonedhead );
05077
05078 highestBlock = new BasicBlock(clonedhead);
05079
05080 h.put ( clonedhead, highestBlock );
05081
05082 clonedHT.put ( highestBB, highestBlock );
05083
05084 orighighestBlock = highestBB;
05085
05086 }
05087 TypeStack smartPush(TypeStack typeStack, Type type)
05088 {
05089 if(type.equals(LongType.v()))
05090 {
05091 typeStack = typeStack.push(LongType.v());
05092 typeStack = typeStack.push(Long2ndHalfType.v());
05093 }
05094 else if(type.equals(DoubleType.v()))
05095 {
05096 typeStack = typeStack.push(DoubleType.v());
05097 typeStack = typeStack.push(Double2ndHalfType.v());
05098 }
05099 else
05100 typeStack = typeStack.push(type);
05101
05102 return typeStack;
05103 }
05104 int typeSize(Type type)
05105 {
05106 if(type.equals(LongType.v()) || type.equals(DoubleType.v()) ||
05107 type.equals(Long2ndHalfType.v()) || type.equals(Double2ndHalfType.v()))
05108 {
05109 return 2;
05110 }
05111 else
05112 return 1;
05113 }
05114 }