1 19 20 package soot.jimple.toolkits.base; 21 22 import soot.*; 23 import soot.jimple.*; 24 import soot.util.*; 25 import java.util.*; 26 import soot.jimple.toolkits.scalar.*; 27 28 public class ThisInliner extends BodyTransformer{ 29 30 public void internalTransform(Body b, String phaseName, Map options){ 31 32 if (!b.getMethod().getName().equals("<init>")) return; 34 35 InvokeStmt invokeStmt = getFirstSpecialInvoke(b); 37 if (invokeStmt == null) return; 38 SpecialInvokeExpr specInvokeExpr = (SpecialInvokeExpr)invokeStmt.getInvokeExpr(); 39 if (specInvokeExpr.getMethod().getDeclaringClass().equals(b.getMethod().getDeclaringClass())){ 40 41 if (!specInvokeExpr.getMethod().hasActiveBody()){ 43 specInvokeExpr.getMethod().retrieveActiveBody(); 44 } 45 46 HashMap oldLocalsToNew = new HashMap(); 47 48 Iterator localsIt = specInvokeExpr.getMethod().getActiveBody().getLocals().iterator(); 49 while (localsIt.hasNext()){ 50 Local l = (Local)localsIt.next(); 51 Local newLocal = (Local)l.clone(); 52 b.getLocals().add(newLocal); 53 oldLocalsToNew.put(l, newLocal); 54 } 55 56 IdentityStmt origIdStmt = findIdentityStmt(b); 58 59 HashMap oldStmtsToNew = new HashMap(); 60 61 Chain containerUnits = b.getUnits(); 63 Iterator inlineeIt = specInvokeExpr.getMethod().getActiveBody().getUnits().iterator(); 64 while (inlineeIt.hasNext()){ 65 Stmt inlineeStmt = (Stmt)inlineeIt.next(); 66 67 if (inlineeStmt instanceof IdentityStmt){ 69 IdentityStmt idStmt = (IdentityStmt)inlineeStmt; 70 71 if (idStmt.getRightOp() instanceof ThisRef) { 72 Stmt newThis = Jimple.v().newAssignStmt((Local)oldLocalsToNew.get(idStmt.getLeftOp()), origIdStmt.getLeftOp()); 73 containerUnits.insertBefore(newThis, invokeStmt); 74 oldStmtsToNew.put(inlineeStmt, newThis); 75 } 76 77 else if (idStmt.getRightOp() instanceof CaughtExceptionRef){ 78 Stmt newInlinee = (Stmt)inlineeStmt.clone(); 79 Iterator localsToPatch = newInlinee.getUseAndDefBoxes().iterator(); 80 while (localsToPatch.hasNext()){ 81 ValueBox next = (ValueBox)localsToPatch.next(); 82 if (next.getValue() instanceof Local){ 83 next.setValue((Local)oldLocalsToNew.get(next.getValue())); 84 } 85 } 86 87 88 containerUnits.insertBefore(newInlinee, invokeStmt); 89 oldStmtsToNew.put(inlineeStmt, newInlinee); 90 } 91 else if (idStmt.getRightOp() instanceof ParameterRef) { 92 Stmt newParam = Jimple.v().newAssignStmt((Local)oldLocalsToNew.get(idStmt.getLeftOp()), specInvokeExpr.getArg(((ParameterRef)idStmt.getRightOp()).getIndex())); 93 containerUnits.insertBefore(newParam, invokeStmt); 94 oldStmtsToNew.put(inlineeStmt, newParam); 95 } 96 } 97 98 else if (inlineeStmt instanceof ReturnVoidStmt){ 101 Stmt newRet = Jimple.v().newGotoStmt((Stmt)containerUnits.getSuccOf(invokeStmt)); 102 containerUnits.insertBefore(newRet, invokeStmt); 103 System.out.println("adding to stmt map: "+inlineeStmt+" and "+newRet); 104 oldStmtsToNew.put(inlineeStmt, newRet); 105 } 106 107 else { 108 Stmt newInlinee = (Stmt)inlineeStmt.clone(); 109 Iterator localsToPatch = newInlinee.getUseAndDefBoxes().iterator(); 110 while (localsToPatch.hasNext()){ 111 ValueBox next = (ValueBox)localsToPatch.next(); 112 if (next.getValue() instanceof Local){ 113 next.setValue((Local)oldLocalsToNew.get(next.getValue())); 114 } 115 } 116 117 118 containerUnits.insertBefore(newInlinee, invokeStmt); 119 oldStmtsToNew.put(inlineeStmt, newInlinee); 120 } 121 122 } 123 124 Iterator trapsIt = specInvokeExpr.getMethod().getActiveBody().getTraps().iterator(); 126 while (trapsIt.hasNext()){ 127 Trap t = (Trap)trapsIt.next(); 128 System.out.println("begin: "+t.getBeginUnit()); 129 Stmt newBegin = (Stmt)oldStmtsToNew.get(t.getBeginUnit()); 130 System.out.println("end: "+t.getEndUnit()); 131 Stmt newEnd = (Stmt)oldStmtsToNew.get(t.getEndUnit()); 132 System.out.println("handler: "+t.getHandlerUnit()); 133 Stmt newHandler = (Stmt)oldStmtsToNew.get(t.getHandlerUnit()); 134 135 if (newBegin == null || newEnd == null || newHandler == null) 136 throw new RuntimeException ("couldn't map trap!"); 137 138 b.getTraps().add(Jimple.v().newTrap(t.getException(), newBegin, newEnd, newHandler)); 139 } 140 141 inlineeIt = specInvokeExpr.getMethod().getActiveBody().getUnits().iterator(); 143 while (inlineeIt.hasNext()){ 144 Stmt inlineeStmt = (Stmt)inlineeIt.next(); 145 if (inlineeStmt instanceof GotoStmt){ 146 System.out.println("inlinee goto target: "+((GotoStmt)inlineeStmt).getTarget()); 147 ((GotoStmt)oldStmtsToNew.get(inlineeStmt)).setTarget((Stmt)oldStmtsToNew.get(((GotoStmt)inlineeStmt).getTarget())); 148 } 149 150 } 151 152 containerUnits.remove(invokeStmt); 154 155 LocalNameStandardizer.v().transform(b, "ji.lns"); 157 158 159 } 160 } 163 164 private InvokeStmt getFirstSpecialInvoke(Body b){ 165 Iterator it = b.getUnits().iterator(); 166 while (it.hasNext()){ 167 Stmt s = (Stmt)it.next(); 168 if (!(s instanceof InvokeStmt)) continue; 169 170 InvokeExpr invokeExpr = ((InvokeStmt)s).getInvokeExpr(); 171 if (!(invokeExpr instanceof SpecialInvokeExpr)) continue; 172 173 return (InvokeStmt)s; 174 } 175 return null; 178 } 179 180 private IdentityStmt findIdentityStmt(Body b){ 181 Iterator it = b.getUnits().iterator(); 182 while (it.hasNext()){ 183 Stmt s = (Stmt)it.next(); 184 if ((s instanceof IdentityStmt) && (((IdentityStmt)s).getRightOp() instanceof ThisRef)){ 185 return (IdentityStmt)s; 186 } 187 } 188 return null; 189 } 190 } 191 | Popular Tags |