1 19 20 package soot.javaToJimple; 21 22 import java.util.*; 23 24 25 public class AccessFieldJBB extends AbstractJimpleBodyBuilder{ 26 27 public AccessFieldJBB(){ 28 } 31 32 protected boolean needsAccessor(polyglot.ast.Expr expr){ 33 if (expr instanceof soot.javaToJimple.jj.ast.JjAccessField_c){ 34 return true; 35 } 36 else { 37 return ext().needsAccessor(expr); 38 } 39 } 40 41 protected soot.Local handlePrivateFieldUnarySet(polyglot.ast.Unary unary){ 42 if (unary.expr() instanceof soot.javaToJimple.jj.ast.JjAccessField_c){ 43 soot.javaToJimple.jj.ast.JjAccessField_c accessField = (soot.javaToJimple.jj.ast.JjAccessField_c)unary.expr(); 45 46 soot.Local baseLocal = (soot.Local)base().getBaseLocal(accessField.field().target()); 48 soot.Local fieldGetLocal = handleCall(accessField.field(), accessField.getMeth(), null, baseLocal); 50 51 soot.Local tmp = base().generateLocal(accessField.field().type()); 52 soot.jimple.AssignStmt stmt1 = soot.jimple.Jimple.v().newAssignStmt(tmp, fieldGetLocal); 53 ext().body.getUnits().add(stmt1); 54 Util.addLnPosTags(stmt1, unary.position()); 55 soot.Value incVal = base().getConstant(Util.getSootType(accessField.field().type()), 1); 56 soot.jimple.BinopExpr binExpr; 57 if (unary.operator() == polyglot.ast.Unary.PRE_INC || unary.operator() == polyglot.ast.Unary.POST_INC){ 58 binExpr = soot.jimple.Jimple.v().newAddExpr(tmp, incVal); 59 } 60 else { 61 binExpr = soot.jimple.Jimple.v().newSubExpr(tmp, incVal); 62 } 63 soot.Local tmp2 = generateLocal(accessField.field().type()); 64 soot.jimple.AssignStmt assign = soot.jimple.Jimple.v().newAssignStmt(tmp2, binExpr); 65 ext().body.getUnits().add(assign); 66 if (unary.operator() == polyglot.ast.Unary.PRE_INC || unary.operator() == polyglot.ast.Unary.PRE_DEC){ 67 return base().handlePrivateFieldSet(accessField, tmp2, baseLocal); 68 } 69 else { 70 base().handlePrivateFieldSet(accessField, tmp2, baseLocal); 71 return tmp; 72 } 73 } 74 else { 75 return ext().handlePrivateFieldUnarySet(unary); 76 } 77 78 } 79 protected soot.Local handlePrivateFieldAssignSet(polyglot.ast.Assign assign){ 80 if (assign.left() instanceof soot.javaToJimple.jj.ast.JjAccessField_c){ 81 soot.javaToJimple.jj.ast.JjAccessField_c accessField = (soot.javaToJimple.jj.ast.JjAccessField_c)assign.left(); 83 84 soot.Local baseLocal = (soot.Local)base().getBaseLocal(accessField.field().target()); 86 if (assign.operator() == polyglot.ast.Assign.ASSIGN){ 87 soot.Value right = base().getSimpleAssignRightLocal(assign); 88 return base().handlePrivateFieldSet(accessField, right, baseLocal); 89 } 90 else { 91 92 soot.Local leftLocal = handleCall(accessField.field(), accessField.getMeth(), null, baseLocal); 94 soot.Value right = base().getAssignRightLocal(assign, leftLocal); 97 return handleFieldSet(accessField, right, baseLocal); 98 } 99 } 100 else { 101 return ext().handlePrivateFieldAssignSet(assign); 102 } 103 } 104 105 private soot.Local handleCall(polyglot.ast.Field field, polyglot.ast.Call call, soot.Value param, soot.Local base){ 106 107 soot.Type sootRecType = Util.getSootType(call.target().type()); 108 soot.SootClass receiverTypeClass = soot.Scene.v().getSootClass("java.lang.Object"); 109 if (sootRecType instanceof soot.RefType){ 110 receiverTypeClass = ((soot.RefType)sootRecType).getSootClass(); 111 } 112 113 soot.SootMethodRef methToCall = base().getSootMethodRef(call); 114 ArrayList params = new ArrayList(); 115 119 if (param != null){ 120 params.add(param); 121 } 122 soot.jimple.InvokeExpr invoke; 123 124 soot.Local baseLocal = base; 125 if (base == null){ 126 baseLocal = (soot.Local)ext().getBaseLocal((polyglot.ast.Receiver)call.target()); 127 } 128 if (methToCall.isStatic()){ 129 invoke = soot.jimple.Jimple.v().newStaticInvokeExpr(methToCall, params); 130 } 131 else if (soot.Modifier.isInterface(receiverTypeClass.getModifiers()) && 132 call.methodInstance().flags().isAbstract()){ 133 invoke = soot.jimple.Jimple.v().newInterfaceInvokeExpr(baseLocal, methToCall, params); 134 } 135 else { 136 invoke = soot.jimple.Jimple.v().newVirtualInvokeExpr(baseLocal, methToCall, params); 137 } 138 soot.Local retLocal = base().generateLocal(field.type()); 139 soot.jimple.AssignStmt assignStmt = soot.jimple.Jimple.v().newAssignStmt(retLocal, invoke); 140 ext().body.getUnits().add(assignStmt); 141 142 return retLocal; 143 } 144 145 protected soot.Local handlePrivateFieldSet(polyglot.ast.Expr expr, soot.Value right, soot.Value baseLocal){ 146 if (expr instanceof soot.javaToJimple.jj.ast.JjAccessField_c){ 147 soot.javaToJimple.jj.ast.JjAccessField_c accessField = (soot.javaToJimple.jj.ast.JjAccessField_c)expr; 148 return handleCall(accessField.field(), accessField.setMeth(), right, null); 149 } 150 else { 151 return ext().handlePrivateFieldSet(expr, right, baseLocal); 152 } 153 } 154 155 private soot.Local handleFieldSet(soot.javaToJimple.jj.ast.JjAccessField_c accessField, soot.Value right, soot.Local base){ 156 return handleCall(accessField.field(), accessField.setMeth(), right, base); 157 } 158 protected soot.Value createExpr(polyglot.ast.Expr expr){ 159 if (expr instanceof soot.javaToJimple.jj.ast.JjAccessField_c){ 160 soot.javaToJimple.jj.ast.JjAccessField_c accessField = (soot.javaToJimple.jj.ast.JjAccessField_c)expr; 161 162 163 return handleCall(accessField.field(), accessField.getMeth(), null, null); 165 } 167 else { 168 return ext().createExpr(expr); 169 } 170 } 171 172 protected soot.Value createLHS(polyglot.ast.Expr expr){ 173 if (expr instanceof soot.javaToJimple.jj.ast.JjAccessField_c) { 174 soot.javaToJimple.jj.ast.JjAccessField_c accessField = (soot.javaToJimple.jj.ast.JjAccessField_c)expr; 175 176 return handleCall(accessField.field(), accessField.getMeth(), null, null); } 178 else { 179 return ext().createLHS(expr); 180 } 181 } 182 183 } 184 | Popular Tags |