1 19 20 package soot.javaToJimple; 21 22 import soot.*; 23 import java.util.*; 24 25 public class AnonInitBodyBuilder extends JimpleBodyBuilder { 26 27 public soot.jimple.JimpleBody createBody(soot.SootMethod sootMethod){ 28 29 body = soot.jimple.Jimple.v().newBody(sootMethod); 30 31 lg = new LocalGenerator(body); 32 33 AnonClassInitMethodSource acims = (AnonClassInitMethodSource) body.getMethod().getSource(); 34 ArrayList fields = acims.getFinalsList(); 35 boolean inStaticMethod = acims.inStaticMethod(); 36 boolean isSubType = acims.isSubType(); 37 soot.Type superOuterType = acims.superOuterType(); 38 soot.Type thisOuterType = acims.thisOuterType(); 39 ArrayList fieldInits = acims.getFieldInits(); 40 soot.Type outerClassType = acims.outerClassType(); 41 polyglot.types.ClassType polyglotType = acims.polyglotType(); 42 polyglot.types.ClassType anonType = acims.anonType(); 43 44 boolean hasOuterRef = ((AnonClassInitMethodSource)body.getMethod().getSource()).hasOuterRef(); 45 boolean hasQualifier = ((AnonClassInitMethodSource)body.getMethod().getSource()).hasQualifier(); 46 47 soot.RefType type = sootMethod.getDeclaringClass().getType(); 49 specialThisLocal = soot.jimple.Jimple.v().newLocal("this", type); 50 body.getLocals().add(specialThisLocal); 51 52 soot.jimple.ThisRef thisRef = soot.jimple.Jimple.v().newThisRef(type); 53 54 soot.jimple.Stmt thisStmt = soot.jimple.Jimple.v().newIdentityStmt(specialThisLocal, thisRef); 55 body.getUnits().add(thisStmt); 56 57 ArrayList invokeList = new ArrayList(); 58 ArrayList invokeTypeList = new ArrayList(); 59 60 int numParams = sootMethod.getParameterCount(); 61 int numFinals = 0; 62 63 if (fields != null){ 64 numFinals = fields.size(); 65 } 66 67 int startFinals = numParams - numFinals; 68 ArrayList paramsForFinals = new ArrayList(); 69 70 soot.Local outerLocal = null; 71 soot.Local qualifierLocal = null; 72 73 Iterator fIt = sootMethod.getParameterTypes().iterator(); 75 int counter = 0; 76 while (fIt.hasNext()){ 77 soot.Type fType = (soot.Type)fIt.next(); 78 soot.Local local = soot.jimple.Jimple.v().newLocal("r"+counter, fType); 79 body.getLocals().add(local); 80 soot.jimple.ParameterRef paramRef = soot.jimple.Jimple.v().newParameterRef(fType, counter); 81 82 soot.jimple.Stmt stmt = soot.jimple.Jimple.v().newIdentityStmt(local, paramRef); 83 84 85 int realArgs = 0; 86 if ((hasOuterRef) && (counter == 0)){ 87 outerLocal = local; 89 realArgs = 1; 90 stmt.addTag(new soot.tagkit.EnclosingTag()); 91 } 92 if ((hasOuterRef) && (hasQualifier) && (counter == 1)){ 93 qualifierLocal = local; 95 realArgs = 2; 96 invokeList.add(qualifierLocal); 97 stmt.addTag(new soot.tagkit.QualifyingTag()); 98 } 99 else if ((!hasOuterRef) && (hasQualifier) && (counter == 0)){ 100 qualifierLocal = local; 101 realArgs = 1; 102 invokeList.add(qualifierLocal); 103 stmt.addTag(new soot.tagkit.QualifyingTag()); 104 } 105 106 if ((counter >= realArgs) && (counter < startFinals)){ 107 invokeTypeList.add(fType); 108 invokeList.add(local); 109 } 110 else if (counter >= startFinals) { 111 paramsForFinals.add(local); 112 } 113 body.getUnits().add(stmt); 114 counter++; 115 } 116 SootClass superClass = sootMethod.getDeclaringClass().getSuperclass(); 117 118 if (needsOuterClassRef(polyglotType)){ 120 invokeTypeList.add(0, superOuterType); 122 } 123 SootMethodRef callMethod = Scene.v().makeMethodRef( sootMethod.getDeclaringClass().getSuperclass(), "<init>", invokeTypeList, VoidType.v(), false); 124 if ((!hasQualifier) && (needsOuterClassRef(polyglotType))){ if (isSubType){ 126 invokeList.add(0, outerLocal); 127 } 128 else { 129 invokeList.add(0, Util.getThisGivenOuter(superOuterType, new HashMap(), body, new LocalGenerator(body), outerLocal)); 130 } 131 } 132 soot.jimple.InvokeExpr invoke = soot.jimple.Jimple.v().newSpecialInvokeExpr(specialThisLocal, callMethod, invokeList); 133 134 soot.jimple.Stmt invokeStmt = soot.jimple.Jimple.v().newInvokeStmt(invoke); 135 body.getUnits().add(invokeStmt); 136 137 139 if (!inStaticMethod && needsOuterClassRef(anonType)){ 141 soot.SootFieldRef field = Scene.v().makeFieldRef( sootMethod.getDeclaringClass(), "this$0", outerClassType, false); 142 soot.jimple.InstanceFieldRef ref = soot.jimple.Jimple.v().newInstanceFieldRef(specialThisLocal, field); 143 soot.jimple.AssignStmt assign = soot.jimple.Jimple.v().newAssignStmt(ref, outerLocal); 144 body.getUnits().add(assign); 145 } 146 if (fields != null){ 147 Iterator finalsIt = paramsForFinals.iterator(); 148 Iterator fieldsIt = fields.iterator(); 149 while (finalsIt.hasNext() && fieldsIt.hasNext()){ 150 151 soot.Local pLocal = (soot.Local)finalsIt.next(); 152 soot.SootField pField = (soot.SootField)fieldsIt.next(); 153 154 soot.jimple.FieldRef pRef = soot.jimple.Jimple.v().newInstanceFieldRef(specialThisLocal, pField.makeRef()); 155 156 soot.jimple.AssignStmt pAssign = soot.jimple.Jimple.v().newAssignStmt(pRef, pLocal); 157 body.getUnits().add(pAssign); 158 159 } 160 } 161 162 165 if (fieldInits != null) { 166 handleFieldInits(fieldInits); 167 } 168 169 ArrayList staticBlocks = ((AnonClassInitMethodSource)body.getMethod().getSource()).getInitializerBlocks(); 170 if (staticBlocks != null){ 171 handleStaticBlocks(staticBlocks); 172 } 173 174 soot.jimple.ReturnVoidStmt retStmt = soot.jimple.Jimple.v().newReturnVoidStmt(); 176 body.getUnits().add(retStmt); 177 178 179 return body; 180 } 181 } 182 | Popular Tags |