Main Page   Packages   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

CFG.java

00001 package ca.mcgill.sable.soot.coffi;
00002 
00003 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00004  * Jimple, a 3-address code Java(TM) bytecode representation.        *
00005  * Copyright (C) 1997, 1998 Raja Vallee-Rai (kor@sable.mcgill.ca)    *
00006  * All rights reserved.                                              *
00007  *                                                                   *
00008  * Modifications by Patrick Lam (gagnon@sable.mcgill.ca) are         *
00009  * Copyright (C) 1998 Patrick Lam.  All rights reserved.             *
00010  *                                                                   *
00011  * Modifications by Vijay Sundaresan (vijay@sable.mcgill.ca) are     *
00012  * Copyright (C) 1999 Vijay Sundaresan.  All rights reserved.        *
00013  *                                                                   *
00014  * This work was done as a project of the Sable Research Group,      *
00015  * School of Computer Science, McGill University, Canada             *
00016  * (http://www.sable.mcgill.ca/).  It is understood that any         *
00017  * modification not identified as such is not covered by the         *
00018  * preceding statement.                                              *
00019  *                                                                   *
00020  * This work is free software; you can redistribute it and/or        *
00021  * modify it under the terms of the GNU Library General Public       *
00022  * License as published by the Free Software Foundation; either      *
00023  * version 2 of the License, or (at your option) any later version.  *
00024  *                                                                   *
00025  * This work is distributed in the hope that it will be useful,      *
00026  * but WITHOUT ANY WARRANTY; without even the implied warranty of    *
00027  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *
00028  * Library General Public License for more details.                  *
00029  *                                                                   *
00030  * You should have received a copy of the GNU Library General Public *
00031  * License along with this library; if not, write to the             *
00032  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,      *
00033  * Boston, MA  02111-1307, USA.                                      *
00034  *                                                                   *
00035  * Java is a trademark of Sun Microsystems, Inc.                     *
00036  *                                                                   *
00037  * To submit a bug report, send a comment, or get the latest news on *
00038  * this project and other Sable Research Group projects, please      *
00039  * visit the web site: http://www.sable.mcgill.ca/                   *
00040  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00041 
00042 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00043  * Coffi, a bytecode parser for the Java(TM) language.               *
00044  * Copyright (C) 1996, 1997 Clark Verbrugge (clump@sable.mcgill.ca). *
00045  * All rights reserved.                                              *
00046  *                                                                   *
00047  * This work was done as a project of the Sable Research Group,      *
00048  * School of Computer Science, McGill University, Canada             *
00049  * (http://www.sable.mcgill.ca/).  It is understood that any         *
00050  * modification not identified as such is not covered by the         *
00051  * preceding statement.                                              *
00052  *                                                                   *
00053  * This work is free software; you can redistribute it and/or        *
00054  * modify it under the terms of the GNU Library General Public       *
00055  * License as published by the Free Software Foundation; either      *
00056  * version 2 of the License, or (at your option) any later version.  *
00057  *                                                                   *
00058  * This work is distributed in the hope that it will be useful,      *
00059  * but WITHOUT ANY WARRANTY; without even the implied warranty of    *
00060  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *
00061  * Library General Public License for more details.                  *
00062  *                                                                   *
00063  * You should have received a copy of the GNU Library General Public *
00064  * License along with this library; if not, write to the             *
00065  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,      *
00066  * Boston, MA  02111-1307, USA.                                      *
00067  *                                                                   *
00068  * Java is a trademark of Sun Microsystems, Inc.                     *
00069  *                                                                   *
00070  * To submit a bug report, send a comment, or get the latest news on *
00071  * this project and other Sable Research Group projects, please      *
00072  * visit the web site: http://www.sable.mcgill.ca/                   *
00073  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00074 
00075 /*
00076  Reference Version
00077  -----------------
00078  This is the latest official version on which this file is based.
00079  The reference version is: $CoffiVersion: 1.1 $
00080                            $SootVersion: 1.beta.4 $
00081 
00082  Change History
00083  --------------
00084  A) Notes:
00085 
00086  Please use the following template.  Most recent changes should
00087  appear at the top of the list.
00088 
00089  - Modified on [date (March 1, 1900)] by [name]. [(*) if appropriate]
00090    [description of modification].
00091 
00092  Any Modification flagged with "(*)" was done as a project of the
00093  Sable Research Group, School of Computer Science,
00094  McGill University, Canada (http://www.sable.mcgill.ca/).
00095 
00096  You should add your copyright, using the following template, at
00097  the top of this file, along with other copyrights.
00098 
00099  *                                                                   *
00100  * Modifications by [name] are                                       *
00101  * Copyright (C) [year(s)] [your name (or company)].  All rights     *
00102  * reserved.                                                         *
00103  *                                                                   *
00104 
00105  B) Changes:
00106 
00107  - Modified on March 17, 1999 by Vijay Sundaresan (vijay@sable.mcgill.ca) (*)
00108    Fixed the JSR code duplicator.
00109  
00110  - Modified on March 2, by Patrick Lam (plam@sable.mcgill.ca). (*)
00111    Commented out JSR bytecode code for now.
00112    
00113  - Modified on February 22, by Raja Vallee-Rai (kor@sable.mcgill.ca). (*)
00114    Fixed a bug with the DUP2_x1 bytecode.   
00115  
00116  - Modified on February 19, 1999 by Vijay Sundaresan (vijay@sable.mcgill.ca) (*)
00117    Implemented a JSR eliminator/handler code duplicator.
00118    
00119  - Modified on January 18, 1998 by Patrick Lam (plam@sable.mcgill.ca) (*)
00120    Fixed a bug in interpreting the SWAP bytecode.
00121 
00122  - Modified on November 2, 1998 by Raja Vallee-Rai (kor@sable.mcgill.ca) (*)
00123    Repackaged all source files and performed extensive modifications.
00124    First initial release of Soot.
00125 
00126  - Modified on September 29, 1998 by Raja Vallee-Rai (kor@sable.mcgill.ca). (*)
00127    Fixed the production of (char) casts.
00128 
00129  - Modified on 31-Aug-1998 by Raja Vallee-Rai (kor@sable.mcgill.ca). (*)
00130    Minor changes to the type analysis.
00131    Ret now points back to all Jsr's.
00132    Fixed InstanceOf.
00133    Fixed an AALOAD problem.
00134 
00135  - Modified on 29-Jul-1998 by Raja Vallee-Rai (kor@sable.mcgill.ca). (*)
00136    Fixed a bug concerned local variable naming.
00137 
00138  - Modified on 23-Jul-1998 by Raja Vallee-Rai (kor@sable.mcgill.ca). (*)
00139    Renamed the uses of Hashtable to HashMap.
00140 
00141  - Modified on 15-Jun-1998 by Raja Vallee-Rai (kor@sable.mcgill.ca). (*)
00142    First internal release (Version 0.1).
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 /** A Control Flow Graph.
00156  * @author Clark Verbrugge
00157  * @see BasicBlock
00158  * @see ClassFile#parse
00159  */
00160 public class CFG {
00161 
00162    /** Method for which this is a control flow graph.
00163     * @see method_info
00164     */
00165     method_info method;
00166    /** Ordered list of BasicBlocks comprising the code of this CFG.
00167     * @see BasicBlock
00168     */
00169     BasicBlock cfg;
00170    /** For associating Instruction leaders with basic blocks. */
00171    private java.util.Hashtable h;
00172    private int bbcount;        // statistics, number of BBs processed
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;                 // convert indices when parsing jimple
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    /** Constructs a new control flow graph for the given method.
00237     * @param m the method in question.
00238     * @see method_info
00239     * @see ClassFile@parse
00240     */
00241     public CFG(method_info m) {
00242       Instruction i,head;
00243       BasicBlock bb,blast;
00244       method = m;
00245 
00246       // Copy all the instructions to a list
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          // Vijay's JSR eliminator
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         // Build the instructionToNext table
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    // given the list of instructions head, this pulls off the front
00421    // basic block, terminates it with a null, and returns the next
00422    // instruction after.
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    // Constructs the actual control flow graph. Assumes the hash table
00439    // currently associates leaders with BasicBlocks, this function
00440    // builds the next[] and prev[] pointer arrays.
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       // System.out.println("Building CFG...");
00448       while (b!=null) {
00449          /*for (Enumeration e = h.elem ents();e.hasMoreElements();) {
00450            b = (BasicBlock)(e.nextElement());*/
00451          i = b.tail;
00452          if (i.branches) {
00453             // must look out for athrow, which can call an exception handler
00454 
00455             if(i instanceof Instruction_Ret)
00456             {
00457                 // Must make the ret point back to all the instructions
00458                 // past a Jsr
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                // see how many targets it can reach.  Note that this is a
00483                // subset of the exception_table.
00484                int icount = 1;
00485                // not quite a subset---could also be that control exits this
00486                // method, so start icount at 1
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             // System.out.println(i.label + "(" + i + " has " + numb + " branches)");
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) { // BB ended not with a branch, so just go to next
00542             b.succ.addElement(b.next);
00543             b.next.pred.addElement(b);
00544          }
00545          b = b.next;
00546       }
00547       // One final step, run through exception handlers and mark which
00548       // basic blocks begin their code
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   //      System.out.println ( "RET "+BBtail+" JSR "+i );
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 //          System.out.println ( "Ret with 2 possible Jsr's" );
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           } // FOR
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           } // WHILE
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 //          System.out.println ( "RET "+clonedjsrtargetBB.tail+" JSR "+i );
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  // LAST STMT OF BB WAS NOT A RET 
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     } // WHILE 
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     // NOT YET CLONED EVERYTHING, SO CLONE THIS BB
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     // System.out.println ( "CLONED "+ clonedhead );
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     clonedBB.next = highestBlock.next;
00880 
00881     highestBlock.next = clonedBB;
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       // CLONE ALL THE PRED BBs TILL HIGHEST BB IS REACHED 
00897       // RECURSION
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  // ALREADY BEEN CLONED BEFORE
00911    clonedBB = ( BasicBlock ) clonedHT.get ( lowestBB );
00912 
00913   }
00914 
00915   return clonedBB;
00916 
00917  } 
00918    void confirmRefType(Type actualType)
00919    {
00920     /*
00921         if(!(actualType instanceof RefType) &&
00922             !(actualType instanceof ArrayType))
00923             throw new RuntimeException("confirmRefType failed; actualType: " + actualType);*/
00924    }   
00925    void confirmType(Type actualType, Type requiredType)
00926    {
00927     /*
00928         if(!actualType.equals(requiredType))
00929             throw new RuntimeException("confirmType failed; actualType: " + actualType +
00930                 "  required: " + requiredType);*/
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          // ( ( Instruction_intbranch ) i ) = ( Instruction ) replacedinstructionHT.get ( tgt );
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             // break;
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                 // generation of a free temporary
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          case ByteCode.JSR:
02266          case ByteCode.JSR_W:
02267          {
02268              stmt = Jimple.v().newAssignStmt(Util.getLocalForStackOp(listBody, postTypeStack,
02269                 postTypeStack.topIndex()), Jimple.v().newNextNextStmtRef());
02270 
02271              statements.add(stmt);
02272 
02273              stmt = Jimple.v().newGotoStmt(new FutureStmt());
02274              statements.add(stmt);
02275 
02276              stmt = null;
02277              break;
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             // Generate parameters & returnType & parameterTypes
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             // build array of parameters
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                 // Generate parameters & returnType & parameterTypes
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             // build array of parameters
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                 // Generate parameters & returnType & parameterTypes
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             // build Vector of parameters
02675                    params = new Value[args];
02676                 for (int j=args-1;j>=0;j--)
02677                 {
02678                     /* System.out.println("BeforeTypeStack");
02679                     typeStack.print(System.out);
02680 
02681                     System.out.println("AfterTypeStack");
02682                     postTypeStack.print(System.out);
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                 // Generate parameters & returnType & parameterTypes
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             // build Vector of parameters
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    /** After the initial jimple construction, a second pass is made to fix up
02984     * missing Stmt targets for <tt>goto</tt>s, <tt>if</tt>'s etc.
02985     * @param c code attribute of this method.
02986     * @see CFG#jimplify
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       // Reset all the dones to true
02996       {
02997             BasicBlock bb = cfg;
02998 
02999         while(bb != null)
03000         {
03001             bb.done = true;
03002             bb = bb.next;
03003         }
03004       }
03005 
03006 
03007       // first process the main code
03008       bbq.push(cfg);
03009       processTargetFixup(bbq);
03010 
03011       // then the exceptions
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             // if block hasn't yet been processed...
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    /** Main entry point for converting list of Instructions to Jimple statements;
03075     * performs flow analysis, constructs Jimple statements, and fixes jumps.
03076     * @param constant_pool constant pool of ClassFile.
03077     * @param this_class constant pool index of the CONSTANT_Class_info object for
03078     * this' class.
03079     * @param clearStacks if <i>true</i> semantic stacks will be deleted after
03080     * the process is complete.
03081     * @return <i>true</i> if all ok, <i>false</i> if there was an error.
03082     * @see CFG#jimplify(cp_info[], int)
03083     * @see Stmt
03084     * @see BasicBlock#jhead
03085     * @see BasicBlock#sout
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         // System.out.println("Starting to jimplify: " + jmethod.getName());
03099 
03100         // Build up instructionToSuccessors table
03101         {
03102             // Put in all regular basic block successors
03103             {
03104                 BasicBlock b = cfg;
03105 
03106                 while(b != null)
03107                 {
03108                     Instruction ins = b.head;
03109 
03110                     while(ins != null)
03111                     {
03112 
03113                         //System.out.println("ins:" + ins.toString());
03114                         
03115                         //if(ins instanceof Instruction_Goto)
03116                         //{
03117                         //    System.out.println("targets: ");
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                             // The successors are the ones from the basic block.
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             // Put in successors due to exception handlers
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                     // Determine exception to catch
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         // Perform the flow analysis, and build up instructionToTypeStack and instructionToLocalArray
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             // Build up initial type stack and initial local array (for the first instruction)
03221             {
03222                 initialTypeStack = TypeStack.v();
03223                     // the empty stack with nothing on it.
03224             }
03225 
03226             // Get the loop cranked up.
03227             {
03228                 instructionToTypeStack.put(firstInstruction, initialTypeStack);
03229 
03230                 visitedInstructions.add(firstInstruction);
03231                 changedInstructions.add(firstInstruction);
03232 
03233                 // System.out.println("firstInstruction:" + firstInstruction);
03234             }
03235 
03236             // Do the flow-analysis loop
03237             {
03238                 while(!changedInstructions.isEmpty())
03239                 {
03240                     Instruction ins = (Instruction) changedInstructions.get(0);
03241 
03242                     /*
03243                     // Some debugging info
03244                     {
03245                         System.out.println("Visiting: "  + ins);
03246 
03247                         System.out.println("[BeforeTypeStack]");
03248                         TypeStack typeStack = (TypeStack) instructionToTypeStack.get(ins);
03249                         typeStack.print(System.out);
03250 
03251                         //System.out.println("[BeforeLocalArray]");
03252                         //TypeArray localArray = (TypeArray) instructionToLocalArray.get(ins);
03253 
03254                         //localArray.print(System.out);
03255                     }
03256                     */
03257                     
03258                     changedInstructions.remove(0);
03259 
03260                     // System.out.println(ins);
03261 
03262                     OutFlow ret = processFlow(ins, (TypeStack) instructionToTypeStack.get(ins),
03263                         constant_pool);
03264 
03265                     instructionToPostTypeStack.put(ins, ret.typeStack);
03266 
03267                     /*
03268                     // More debugging info
03269                     {
03270                         System.out.println("[AfterTypeStack]");
03271                         ret.typeStack.print(System.out);
03272 
03273                         System.out.println("[AfterLocalArray]");
03274                         ret.localArray.print(System.out);
03275                     }
03276                       */
03277 
03278                     Object[] successors = ((Set) instructionToSuccessors.get(ins)).toArray();
03279 
03280                     /*
03281                     if(successors.length != 1)
03282                         System.out.println();
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                             // Special case for the first time visiting.
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                             // System.out.println("adding successor: " + s);
03309                         }
03310                         else {
03311                              // System.out.println("considering successor: " + s);
03312                             TypeStack newTypeStack,
03313                                 oldTypeStack = (TypeStack) instructionToTypeStack.get(s);
03314 
03315                             if(handlerInstructions.contains(s))
03316                             {
03317                                 // The type stack for an instruction handler should always be that of
03318                                 // single object on the stack.
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                                 // System.out.println("requires a revisit: " + s);
03332                             }
03333 
03334                             instructionToTypeStack.put(s, newTypeStack);
03335                         }
03336                     }
03337                 }
03338             }
03339         }
03340 
03341         // Print out instructions + their localArray + typeStack
03342         {
03343             Instruction ins = firstInstruction;
03344 
03345      //       System.out.println();
03346 
03347             while(ins != null)
03348             {
03349                 TypeStack typeStack = (TypeStack) instructionToTypeStack.get(ins);
03350                 // TypeArray typeArray = (TypeArray) instructionToLocalArray.get(ins);
03351 /*
03352                 System.out.println("[TypeArray]");
03353                 typeArray.print(System.out);
03354                 System.out.println();
03355 
03356                 System.out.println("[TypeStack]");
03357                 typeStack.print(System.out);
03358                 System.out.println();
03359 
03360                 System.out.println(ins.toString());
03361 */
03362 
03363                 ins = (Instruction) instructionToNext.get(ins);
03364 /*
03365 
03366                 System.out.println();
03367                 System.out.println();
03368 */
03369 
03370             }
03371         }
03372 
03373 
03374         // System.out.println("Producing Jimple code...");
03375 
03376         // Jimplify each statement
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 //                    System.out.println ( ins ); 
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         // Print out basic blocks
03418         {
03419             BasicBlock b = cfg;
03420 
03421             System.out.println("Basic blocks for: " + jmethod.getName());
03422 
03423             while(b != null)
03424             {
03425                 Instruction ins = b.head;
03426 
03427                 System.out.println();
03428 
03429                 while(ins != null)
03430                 {
03431                     System.out.println(ins.toString());
03432                     ins = ins.next;
03433                 }
03434 
03435                 b = b.next;
03436             }
03437         }
03438         */
03439 
03440         jimpleTargetFixup();  // fix up jump targets
03441 
03442         // Insert beginCatch/endCatch statements for exception handling
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                     // Determine the last stmt
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                     // Determine exception to catch
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                     // Insert assignment of exception
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                     // Insert trap
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                     // Insert begincatch
03519                     {
03520                         Stmt beginCatchStmt = new BeginCatchStmt(exception, newTarget);
03521                         int startIndex = stmtList.indexOf(firstStmt);
03522 
03523                         stmtList.add(startIndex, beginCatchStmt);
03524                     }
03525 
03526                     // Insert endcatch
03527                     {
03528                         Stmt endCatchStmt = new EndCatchStmt(exception);
03529                         int endIndex = stmtList.indexOf(lastStmt);
03530 
03531                         stmtList.add(endIndex + 1, endCatchStmt);
03532                     } */
03533               }
03534         }
03535     }
03536    /** Main entry point for converting list of Instructions to Jimple statements;
03537     * performs flow analysis, constructs Jimple statements, and fixes jumps.
03538     * @param constant_pool constant pool of ClassFile.
03539     * @param this_class constant pool index of the CONSTANT_Class_info object for
03540     * this' class.
03541     * @return <i>true</i> if all ok, <i>false</i> if there was an error.
03542     * @see CFG#jimplify(cp_info[], int, boolean)
03543     * @see Stmt
03544     * @see BasicBlock#jhead
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         // Initialize nameToLocal which is an index*Type->Local map, which is used
03569         // to determine local in bytecode references.
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             // Initialize the 'this' variable
03582             {
03583                 if(!isStatic)
03584                 {
03585                     Local local = Jimple.v().newLocal("l0", UnknownType.v());
03586 
03587                     // stmtList.setThisLocal(local);
03588                     listBody.addLocal(local);
03589 
03590                     currentLocalIndex++;
03591 
03592                     stmtList.add(Jimple.v().newIdentityStmt(local, Jimple.v().newThisRef(jmethod.getDeclaringClass())));
03593                 }
03594             }
03595 
03596             // Initialize parameters
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 )  // 1 INSTRUCTION IN BB
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 ( /* method.instructionList.indexOf ( originstruction ), */ 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 ( /* method.instructionList.indexOf ( originstruction ), */ 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 ( /* method.instructionList.indexOf ( originstruction ) , */ 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 ( /* method.instructionList.indexOf ( originstruction ), */ 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         if(!typeStack.top().equals(requiredType))
03901             throw new RuntimeException("popSafe failed; top: " + typeStack.top() +
03902             " required: " + requiredType);
03903       */
03904 
03905         return typeStack.pop();
03906    }   
03907    TypeStack popSafeArrayType(TypeStack typeStack)
03908    {
03909     /*
03910         if(!(typeStack.top() instanceof ArrayType) &&
03911             !(RefType.v("null").equals(typeStack.top())))
03912         {
03913             throw new RuntimeException("popSafe failed; top: " + typeStack.top() +
03914                     " required: ArrayType");
03915         }
03916       */
03917 
03918         return typeStack.pop();
03919    }   
03920    TypeStack popSafeRefType(TypeStack typeStack)
03921    {
03922         /*
03923         if(!(typeStack.top() instanceof RefType) &&
03924             !(typeStack.top() instanceof ArrayType))
03925         {
03926             throw new RuntimeException("popSafe failed; top: " + typeStack.top() +
03927                     " required: RefType");
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    // reconstructInstructions();
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         // System.out.println(ins.toString());
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                 // this is highly imprecise
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                 // this is highly imprecise
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             // break;
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                 // it's a null object
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             // Doesn't check to see if the required types are on the stack, but it should
04465             // if it wanted to be safe.
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             // pop off parameters.
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             // pop off parameters.
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             // pop off parameters.
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             // pop off parameters.
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             // technically athrow leaves the stack in an undefined
04869             // state.  In fact, the top value is the one we actually
04870             // throw, but it should stay on the stack since the exception
04871             // handler expects to start that way, at least in the real JVM.
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    /** Runs through the given bbq contents performing the target fix-up pass;
04920     * Requires all reachable blocks to have their done flags set to true, and
04921     * this resets them all back to false;
04922     * @param bbq queue of BasicBlocks to process.
04923     * @see jimpleTargetFixup
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                    // Regular goto
04941 
04942                     ((GotoStmt)s).setTarget(((BasicBlock) b.succ.firstElement()).getHeadJStmt());
04943                 }
04944                 else
04945                 {
04946                     // Goto derived from a jsr bytecode
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                // Successors of the basic block ending with a switch statement
04974                // are listed in the successor vector in order, with the
04975                // default as the very first (0-th entry)
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                // Successors of the basic block ending with a switch statement
04991                // are listed in the successor vector in order, with the
04992                // default as the very first (0-th entry)
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    /** Reconstructs the instruction stream by appending the Instruction
05013     * lists associated with each basic block.
05014     * <p>
05015     * Note that this joins up the basic block Instruction lists, and so
05016     * they will no longer end with <i>null</i> after this.
05017     * @return the head of the list of instructions.
05018     * @see BasicBlock#head
05019     * @see BasicBlock#tail
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    // CLONE THE HIGHEST BB ( IMMEDIATE SUCC OF JSRBB ) TO BE CLONED FIRST 
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     // System.out.println ( "CLONED "+ clonedcurrent );
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 }

Generated at Thu Feb 7 06:41:58 2002 for Bandera by doxygen1.2.10 written by Dimitri van Heesch, © 1997-2001