1 19 20 25 26 27 28 29 30 31 package soot.grimp.toolkits.base; 32 import soot.options.*; 33 34 import soot.*; 35 import soot.toolkits.scalar.*; 36 import soot.jimple.*; 37 import soot.toolkits.graph.*; 38 import soot.grimp.*; 39 import soot.util.*; 40 import java.util.*; 41 42 public class ConstructorFolder extends BodyTransformer 43 { 44 public ConstructorFolder( Singletons.Global g ) {} 45 public static ConstructorFolder v() { return G.v().soot_grimp_toolkits_base_ConstructorFolder(); } 46 47 48 protected void internalTransform(Body b, String phaseName, Map options) 49 { 50 GrimpBody body = (GrimpBody)b; 51 52 if(Options.v().verbose()) 53 G.v().out.println("[" + body.getMethod().getName() + 54 "] Folding constructors..."); 55 56 Chain units = body.getUnits(); 57 List stmtList = new ArrayList(); 58 stmtList.addAll(units); 59 60 Iterator it = stmtList.iterator(); 61 62 ExceptionalUnitGraph graph = new ExceptionalUnitGraph(body); 63 64 65 LocalDefs localDefs = new SmartLocalDefs(graph, new SimpleLiveLocals(graph)); 66 LocalUses localUses = new SimpleLocalUses(graph, localDefs); 67 68 69 while (it.hasNext()) 70 { 71 Stmt s = (Stmt)it.next(); 72 73 if (!(s instanceof AssignStmt)) 74 continue; 75 76 77 Value lhs = ((AssignStmt)s).getLeftOp(); 78 if (!(lhs instanceof Local)) 79 continue; 80 81 Value rhs = ((AssignStmt)s).getRightOp(); 82 if (!(rhs instanceof NewExpr)) 83 continue; 84 85 92 93 List lu = localUses.getUsesOf((DefinitionStmt)s); 94 Iterator luIter = lu.iterator(); 95 boolean MadeNewInvokeExpr = false; 96 97 while (luIter.hasNext()) 98 { 99 Unit use = ((UnitValueBoxPair)(luIter.next())).unit; 100 if (!(use instanceof InvokeStmt)) 101 continue; 102 InvokeStmt is = (InvokeStmt)use; 103 if (!(is.getInvokeExpr() instanceof SpecialInvokeExpr) || 104 lhs != ((SpecialInvokeExpr)is.getInvokeExpr()).getBase()) 105 continue; 106 107 SpecialInvokeExpr oldInvoke = 108 ((SpecialInvokeExpr)is.getInvokeExpr()); 109 LinkedList invokeArgs = new LinkedList(); 110 for (int i = 0; i < oldInvoke.getArgCount(); i++) 111 invokeArgs.add(oldInvoke.getArg(i)); 112 113 AssignStmt constructStmt = Grimp.v().newAssignStmt 114 ((AssignStmt)s); 115 constructStmt.setRightOp 116 (Grimp.v().newNewInvokeExpr 117 (((NewExpr)rhs).getBaseType(), oldInvoke.getMethodRef(), invokeArgs)); 118 MadeNewInvokeExpr = true; 119 120 use.redirectJumpsToThisTo(constructStmt); 121 units.insertBefore(constructStmt, use); 122 units.remove(use); 123 } 124 if (MadeNewInvokeExpr) 125 { 126 units.remove(s); 127 } 128 } 129 } 130 } 131 | Popular Tags |