Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /* Soot - a J*va Optimization Framework
   * Copyright (C) 2004 Jennifer Lhotak
   *
   * This library is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
   * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
 
 package soot.jimple.toolkits.base;
 
 import soot.*;
 import soot.jimple.*;
 import soot.util.*;
 import java.util.*;
 
 public class ThisInliner extends BodyTransformer{
 
     public void internalTransform(Body bString phaseNameMap options){
         
         // assure body is a constructor
         if (!b.getMethod().getName().equals("<init>")) return;
 
         // if the first invoke is a this() and not a super() inline the this()
         InvokeStmt invokeStmt = getFirstSpecialInvoke(b);
         if (invokeStmt == nullreturn
         SpecialInvokeExpr specInvokeExpr = (SpecialInvokeExpr)invokeStmt.getInvokeExpr();
         if (specInvokeExpr.getMethod().getDeclaringClass().equals(b.getMethod().getDeclaringClass())){
             
             // put locals from inlinee into container
             if (!specInvokeExpr.getMethod().hasActiveBody()){
                 specInvokeExpr.getMethod().retrieveActiveBody();
             }
 
             HashMap oldLocalsToNew = new HashMap();
             
             Iterator localsIt = specInvokeExpr.getMethod().getActiveBody().getLocals().iterator();
             while (localsIt.hasNext()){
                 Local l = (Local)localsIt.next();
                 Local newLocal = (Local)l.clone();
                 b.getLocals().add(newLocal);
                 oldLocalsToNew.put(lnewLocal);
             }
            
             //find identity stmt of original method
             IdentityStmt origIdStmt = findIdentityStmt(b);
            
             HashMap<StmtStmtoldStmtsToNew = new HashMap<StmtStmt>();
             
             //System.out.println("locals: "+b.getLocals());
             Chain containerUnits = b.getUnits();
             Iterator inlineeIt = specInvokeExpr.getMethod().getActiveBody().getUnits().iterator();
             while (inlineeIt.hasNext()){
                 Stmt inlineeStmt = (Stmt)inlineeIt.next();
                
                 // handle identity stmts
                 if (inlineeStmt instanceof IdentityStmt){
                     IdentityStmt idStmt = (IdentityStmt)inlineeStmt;
                     
                     if (idStmt.getRightOp() instanceof ThisRef) {
                         Stmt newThis = Jimple.v().newAssignStmt((Local)oldLocalsToNew.get(idStmt.getLeftOp()), origIdStmt.getLeftOp());         
                         containerUnits.insertBefore(newThisinvokeStmt);
                         oldStmtsToNew.put(inlineeStmtnewThis);
                     }
                     
                     else if (idStmt.getRightOp() instanceof CaughtExceptionRef){
                         Stmt newInlinee = (Stmt)inlineeStmt.clone();
                         Iterator localsToPatch = newInlinee.getUseAndDefBoxes().iterator();
                         while (localsToPatch.hasNext()){
                             ValueBox next = (ValueBox)localsToPatch.next();
                             if (next.getValue() instanceof Local){
                                 next.setValue((Local)oldLocalsToNew.get(next.getValue()));
                             }
                         }
                     
                        
                         containerUnits.insertBefore(newInlineeinvokeStmt);
                         oldStmtsToNew.put(inlineeStmtnewInlinee);
                     }
                     else if (idStmt.getRightOp() instanceof ParameterRef) {
                         Stmt newParam = Jimple.v().newAssignStmt((Local)oldLocalsToNew.get(idStmt.getLeftOp()), specInvokeExpr.getArg(((ParameterRef)idStmt.getRightOp()).getIndex()));         
                         containerUnits.insertBefore(newParaminvokeStmt);
                         oldStmtsToNew.put(inlineeStmtnewParam);
                     }
                 }
 
                 // handle return void stmts (cannot return anything else 
                 // from a constructor)
                else if (inlineeStmt instanceof ReturnVoidStmt){
                    Stmt newRet = Jimple.v().newGotoStmt((Stmt)containerUnits.getSuccOf(invokeStmt));
                    containerUnits.insertBefore(newRetinvokeStmt);
                    ..println("adding to stmt map: "+inlineeStmt+" and "+newRet);
                    oldStmtsToNew.put(inlineeStmtnewRet);
                }
                else {
                    Stmt newInlinee = (Stmt)inlineeStmt.clone();
                    Iterator localsToPatch = newInlinee.getUseAndDefBoxes().iterator();
                    while (localsToPatch.hasNext()){
                        ValueBox next = (ValueBox)localsToPatch.next();
                        if (next.getValue() instanceof Local){
                            next.setValue((Local)oldLocalsToNew.get(next.getValue()));
                        }
                    }
                       
                    containerUnits.insertBefore(newInlineeinvokeStmt);
                    oldStmtsToNew.put(inlineeStmtnewInlinee);
                }
                
            }
                
            // handleTraps
            Iterator trapsIt = specInvokeExpr.getMethod().getActiveBody().getTraps().iterator();
            while (trapsIt.hasNext()){
                Trap t = (Trap)trapsIt.next();
                ..println("begin: "+t.getBeginUnit());
                Stmt newBegin = oldStmtsToNew.get(t.getBeginUnit());
                ..println("end: "+t.getEndUnit());
                Stmt newEnd = oldStmtsToNew.get(t.getEndUnit());
                ..println("handler: "+t.getHandlerUnit());
                Stmt newHandler = oldStmtsToNew.get(t.getHandlerUnit());
                if (newBegin == null || newEnd == null || newHandler == null)
                    throw new RuntimeException("couldn't map trap!");
                b.getTraps().add(Jimple.v().newTrap(t.getException(), newBeginnewEndnewHandler));
            }
            // patch gotos
            inlineeIt = specInvokeExpr.getMethod().getActiveBody().getUnits().iterator();
            while (inlineeIt.hasNext()){
                Stmt inlineeStmt = (Stmt)inlineeIt.next();
                if (inlineeStmt instanceof GotoStmt){
                    ..println("inlinee goto target: "+((GotoStmt)inlineeStmt).getTarget());
                    ((GotoStmt)oldStmtsToNew.get(inlineeStmt)).setTarget(oldStmtsToNew.get(((GotoStmt)inlineeStmt).getTarget()));
                }
                       
            }
                
            // remove original invoke
            containerUnits.remove(invokeStmt);
               
            // resolve name collisions
            LocalNameStandardizer.v().transform(b"ji.lns");
            
        }
        //System.out.println("locals: "+b.getLocals());
        //System.out.println("units: "+b.getUnits());
    }
        Iterator it = b.getUnits().iterator();
        while (it.hasNext()){
            Stmt s = (Stmt)it.next();
            if (!(s instanceof InvokeStmt)) continue;
            InvokeExpr invokeExpr = ((InvokeStmt)s).getInvokeExpr();
            if (!(invokeExpr instanceof SpecialInvokeExpr)) continue;
    
            return (InvokeStmt)s;        
        }
        // but there will always be either a call to this() or to super()
        // from the constructor
        return null;
    }
    private IdentityStmt findIdentityStmt(Body b){
        Iterator it = b.getUnits().iterator();
        while (it.hasNext()){
            Stmt s = (Stmt)it.next();
            if ((s instanceof IdentityStmt) && (((IdentityStmt)s).getRightOp() instanceof ThisRef)){
                return (IdentityStmt)s;
            }
        }
        return null;
    }
New to GrepCode? Check out our FAQ X