1 19 20 25 26 package soot.jimple.toolkits.invoke; 27 28 import soot.*; 29 import soot.jimple.*; 30 import java.util.*; 31 32 33 public class InlinerSafetyManager 34 { 35 public static boolean checkSpecialInlineRestrictions(SootMethod container, SootMethod target, String options) { 37 39 boolean accessors=options.equals("accessors"); 40 41 Body inlineeBody = (JimpleBody) target.getActiveBody(); 42 43 Iterator unitsIt = inlineeBody.getUnits().iterator(); 44 while (unitsIt.hasNext()) 45 { 46 Stmt st = (Stmt)unitsIt.next(); 47 if (st.containsInvokeExpr()) 48 { 49 InvokeExpr ie1 = (InvokeExpr)st.getInvokeExpr(); 50 51 if (ie1 instanceof SpecialInvokeExpr) 52 { 53 if((InlinerSafetyManager.specialInvokePerformsLookupIn(ie1, container.getDeclaringClass()) || 54 InlinerSafetyManager.specialInvokePerformsLookupIn(ie1, target.getDeclaringClass()))) 55 { 56 return false; 57 58 } 59 60 SootMethod specialTarget = ie1.getMethod(); 61 62 if(specialTarget.isPrivate()) 63 { 64 if(specialTarget.getDeclaringClass() != container.getDeclaringClass()) 65 { 66 70 if (!accessors) 71 return false; 72 } 73 } 74 } 75 } 76 } 77 78 79 return true; 80 } 81 82 public static boolean checkAccessRestrictions(SootMethod container, SootMethod target, String modifierOptions) { 83 { 86 Body inlineeBody = (JimpleBody) target.getActiveBody(); 87 88 Iterator unitsIt = inlineeBody.getUnits().iterator(); 89 while (unitsIt.hasNext()) 90 { 91 Stmt st = (Stmt)unitsIt.next(); 92 if (st.containsInvokeExpr()) 93 { 94 InvokeExpr ie1 = (InvokeExpr)st.getInvokeExpr(); 95 96 if (!AccessManager.ensureAccess(container, ie1.getMethod(), modifierOptions)) 97 return false; 98 } 99 100 if (st instanceof AssignStmt) 101 { 102 Value lhs = ((AssignStmt)st).getLeftOp(); 103 Value rhs = ((AssignStmt)st).getRightOp(); 104 105 if (lhs instanceof FieldRef && 106 !AccessManager.ensureAccess(container, ((FieldRef)lhs).getField(), 107 modifierOptions)) 108 return false; 109 110 111 if (rhs instanceof FieldRef && 112 !AccessManager.ensureAccess(container, ((FieldRef)rhs).getField(), 113 modifierOptions)) 114 return false; 115 116 } 117 } 118 } 119 120 return true; 121 122 } 123 124 131 132 public static boolean ensureInlinability(SootMethod target, 133 Stmt toInline, 134 SootMethod container, 135 String modifierOptions) 136 { 137 if(!InlinerSafetyManager.canSafelyInlineInto(target, toInline, container)) { 138 return false; 140 } 141 142 if(!AccessManager.ensureAccess(container, target, modifierOptions)) { 143 return false; 145 } 146 147 if (!checkSpecialInlineRestrictions(container, target, modifierOptions)) { 148 return false; 150 } 151 152 if (!checkAccessRestrictions(container, target, modifierOptions)) { 153 return false; 155 } 156 157 return true; 158 } 159 160 162 private static boolean canSafelyInlineInto(SootMethod inlinee, 163 Stmt toInline, 164 SootMethod container) 165 166 { 167 168 169 if (inlinee.getName().equals("<init>")) 171 return false; 172 173 if (inlinee.getSignature().equals(container.getSignature())) 175 return false; 176 177 if (inlinee.isNative() || inlinee.isAbstract()) 179 return false; 180 181 184 190 InvokeExpr ie = (InvokeExpr)toInline.getInvokeExpr(); 191 Value base = (ie instanceof InstanceInvokeExpr) ? 192 ((InstanceInvokeExpr)ie).getBase() : null; 193 194 if (base != null && invokeThrowsAccessErrorIn(((RefType)base.getType()).getSootClass(), inlinee, container)) 195 return false; 196 197 200 203 208 if (ie instanceof SpecialInvokeExpr && 211 (specialInvokePerformsLookupIn(ie, inlinee.getDeclaringClass()) || 212 specialInvokePerformsLookupIn(ie, container.getDeclaringClass()))) 213 return false; 214 215 return true; 216 } 217 218 230 private static boolean invokeThrowsAccessErrorIn(SootClass base, 231 SootMethod inlinee, 232 SootMethod container) 233 { 234 SootClass inlineeClass = inlinee.getDeclaringClass(); 235 SootClass containerClass = container.getDeclaringClass(); 236 237 if (inlinee.isPrivate() && 239 !inlineeClass.getName().equals(containerClass.getName())) 240 return true; 241 242 if (!inlinee.isPrivate() && !inlinee.isProtected() 244 && !inlinee.isPublic()) 245 { 246 if (!inlineeClass.getPackageName().equals 247 (containerClass.getPackageName())) 248 return true; 249 } 250 251 if (inlinee.isProtected()) 253 { 254 Hierarchy h = Scene.v().getActiveHierarchy(); 255 boolean saved = false; 256 257 if (h.isClassSuperclassOfIncluding(inlineeClass, containerClass) || 260 ((base != null) && 261 h.isClassSuperclassOfIncluding(base, containerClass))) 262 saved = true; 263 264 if (!saved) 265 return true; 266 } 267 268 return false; 269 } 270 271 static boolean specialInvokePerformsLookupIn 274 (InvokeExpr ie, SootClass containerClass) 275 { 276 SootMethod m = ie.getMethod(); 278 279 280 if (m.getName().equals("<init>")) 281 { 282 return false; 283 } 284 285 if (m.isPrivate()) 286 { 287 return false; 288 } 289 290 Hierarchy h = Scene.v().getActiveHierarchy(); 291 292 if (!h.isClassSuperclassOf(m.getDeclaringClass(), 293 containerClass)) 294 return false; 295 296 298 return true; 299 } 300 } 301 | Popular Tags |