Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /* Soot - a J*va Optimization Framework
   * Copyright (C) 2006 Ondrej 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.
  */
 
 /*
  * Modified by the Sable Research Group and others 1997-1999.  
  * See the 'credits' file distributed with Soot for the complete list of
  * contributors.  (Soot is distributed at http://www.sable.mcgill.ca/soot)
  */
 
 
  
 
 
 
 package soot.jimple.toolkits.base;
 import soot.options.*;
 
 import soot.*;
 import soot.jimple.*;
 import soot.util.*;
 import java.util.*;
 
 public class JimpleConstructorFolder extends BodyTransformer
 {
     static boolean isNew(Stmt s) {
         if(!(s instanceof AssignStmt)) return false;
         if(!(rhs(sinstanceof NewExpr)) return false;
         return true;
     }
     static boolean isConstructor(Stmt s) {
         if(!(s instanceof InvokeStmt)) return false;
         InvokeStmt is = (InvokeStmts;
         InvokeExpr expr = is.getInvokeExpr();
         if(!(expr instanceof SpecialInvokeExpr)) return false;
         SpecialInvokeExpr sie = (SpecialInvokeExprexpr;
         if(!sie.getMethodRef().name().equals(.))
                 return false;
         return true;
     }
     static Local base(Stmt s) {
         InvokeStmt is = (InvokeStmts;
         InstanceInvokeExpr expr = (InstanceInvokeExpris.getInvokeExpr();
         return (Localexpr.getBase();
     }
     static void setBase(Stmt sLocal l) {
         InvokeStmt is = (InvokeStmts;
         InstanceInvokeExpr expr = (InstanceInvokeExpris.getInvokeExpr();
         expr.getBaseBox().setValue(l);
     }
     static boolean isCopy(Stmt s) {
         if(!(s instanceof AssignStmt)) return false;
         if(!(rhs(sinstanceof Local)) return false;
         if(!(lhs(sinstanceof Local)) return false;
         return true;
     }
     static Value rhs(Stmt s) {
         AssignStmt as = (AssignStmts;
         return as.getRightOp();
     }
     static Value lhs(Stmt s) {
         AssignStmt as = (AssignStmts;
         return as.getLeftOp();
     }
     static Local rhsLocal(Stmt s) { return (Localrhs(s); }
     static Local lhsLocal(Stmt s) { return (Locallhs(s); }
     private class Fact {
         private Map<LocalStmtvarToStmt = new HashMap<LocalStmt>();
         private MultiMap stmtToVar = new HashMultiMap();
         private Stmt alloc = null;
         public void add(Local lStmt s) {
             .put(ls);
             .put(sl);
         }
         public Stmt get(Local l) {
             return .get(l);
         }
         public Set get(Stmt s) {
             return .get(s);
         }
         public void removeAll(Stmt s) {
             for(Iterator it = .get(s).iterator(); it.hasNext();) {
                final Local var = (Localit.next();
                .remove(var);
            }
            .remove(s);
        }
        public void copyFrom(Fact in) {
             = new HashMap<LocalStmt>(in.varToStmt);
             = new HashMultiMap(in.stmtToVar);
             = in.alloc;
        }
        public void mergeFrom(Fact in1Fact in2) {
             = new HashMap<LocalStmt>();
            Iterator<Localit = in1.varToStmt.keySet().iterator();
            while(it.hasNext()) {
                Local l = it.next();
                Stmt newStmt = in1.varToStmt.get(l);
                if(in2.varToStmt.containsKey(l)) {
                    Stmt newStmt2 = in2.varToStmt.get(l);
                    if(!newStmt.equals(newStmt2)) {
                        throw new RuntimeException("Merge of different uninitialized values; are you sure this bytecode is verifiable?");
                    }
                }
                add(lnewStmt);
            }
            it = in2.varToStmt.keySet().iterator();
            while(it.hasNext()) {
                Local l = it.next();
                Stmt newStmt = in2.varToStmt.get(l);
                add(lnewStmt);
            }
            if(in1.alloc != null && in1.alloc.equals(in2.alloc)) {
                 = in1.alloc;
            } else {
                 = null;
            }
        }
        public boolean equals(Object other) {
            if(!(other instanceof Fact)) return false;
            Fact o = (Factother;
            if(!.equals(o.stmtToVar)) return false;
            if( == null && o.alloc != nullreturn false;
            if( != null && o.alloc == nullreturn false;
            if( != null && !.equals(o.alloc)) return false;
            return true;
        }
        public Stmt alloc() { return ; }
        public void setAlloc(Stmt newAlloc) {  = newAlloc; }
    }
    private class Analysis extends ForwardFlowAnalysis {
        public Analysis(DirectedGraph graph) {
            super(graph);
            doAnalysis();
        }
        protected Object entryInitialFlow() {
            return new Fact();
        }
        protected Object newInitialFlow() {
            return new Fact();
        }
        public void flowThrough(Object inFactObject unitObject outFact) {
            Stmt s = (Stmtunit;
            Fact in = (FactinFact;
            Fact out = (FactoutFact;
            copy(inout);
            out.setAlloc(null);
            if(isNew(s)) {
                out.add(lhsLocal(s), s);
            } else if(isCopy(s)) {
                Stmt newStmt = out.get(rhsLocal(s));
                if(newStmt != nullout.add(lhsLocal(s), newStmt);
            } else if(isConstructor(s)) {
                Stmt newStmt = out.get(base(s));
                if(newStmt != null) {
                    out.removeAll(newStmt);
                    out.setAlloc(newStmt);
                }
            }
        }
        public void copy(Object sourceObject dest) {
            ((Factdest).copyFrom((Factsource);
        }
        public void merge(Object in1Object in2Object out) {
            ((Factout).mergeFrom((Factin1, (Factin2);
        }
    }
    
This method pushes all newExpr down to be the stmt directly before every invoke of the init
    public void internalTransform(Body bString phaseNameMap options)
    {
        JimpleBody body = (JimpleBody)b;
        //PhaseDumper.v().dumpBody(body, "constructorfolder.in");
        if(Options.v().verbose())
            G.v()..println("[" + body.getMethod().getName() +
                "] Folding Jimple constructors...");
        Analysis analysis = new Analysis(new BriefUnitGraph(body));
        Chain units = body.getUnits();
        List<UnitstmtList = new ArrayList<Unit>();
        stmtList.addAll(units);
        Iterator<Unitit;
        it = stmtList.iterator();
        while(it.hasNext()) {
            Stmt s = (Stmtit.next();
            if(isCopy(s)) continue;
            if(isConstructor(s)) continue;
            Fact before = (Factanalysis.getFlowBefore(s);
            Iterator usesIt = s.getUseBoxes().iterator();
            while(usesIt.hasNext()) {
                ValueBox usebox = (ValueBoxusesIt.next();
                Value value = usebox.getValue();
                if(!(value instanceof Local)) continue;
                Local local = (Localvalue;
                if(before.get(local) != null)
                    throw new RuntimeException("Use of an unitialized value "
                            +"before constructor call; are you sure this "
                            +"bytecode is verifiable?\n"+s);
            }
        }
        // throw out all new statements
        it = stmtList.iterator();
        while(it.hasNext()) {
            Stmt s = (Stmtit.next();
            if(isNew(s)) {
                units.remove(s);
            }
        }
        it = stmtList.iterator();
        while(it.hasNext()) {
            Stmt s = (Stmtit.next();
            Fact before = (Factanalysis.getFlowBefore(s);
            Fact after = (Factanalysis.getFlowAfter(s);
            // throw out copies of uninitialized variables
            if(isCopy(s)) {
                Stmt newStmt = before.get(rhsLocal(s));
                if(newStmt != nullunits.remove(s);
            } else if(after.alloc() != null) {
                // insert the new just before the constructor
                Stmt newStmt = before.get(base(s));
                setBase(slhsLocal(newStmt));
                units.insertBefore(newStmts);
                // add necessary copies
                Iterator copyIt = before.get(newStmt).iterator();
                while(copyIt.hasNext()) {
                    Local l = (LocalcopyIt.next();
                    if(l.equals(base(s))) continue;
                    units.insertAfter(Jimple.v().newAssignStmt(lbase(s)), s);
                }
            }
        }
        //PhaseDumper.v().dumpBody(body, "constructorfolder.out");
    }  
New to GrepCode? Check out our FAQ X