1 package alt.jiapi.interceptor; 2 3 import java.util.List ; 4 5 import java.lang.reflect.Field ; 6 import java.lang.reflect.Modifier ; 7 8 import alt.jiapi.InstrumentationException; 9 10 import alt.jiapi.event.EventInstrumentor; 11 import alt.jiapi.event.EventRuntime; 12 13 import alt.jiapi.reflect.Instruction; 14 import alt.jiapi.reflect.InstructionFactory; 15 import alt.jiapi.reflect.InstructionList; 16 import alt.jiapi.reflect.JiapiClass; 17 import alt.jiapi.reflect.JiapiField; 18 import alt.jiapi.reflect.JiapiMethod; 19 import alt.jiapi.reflect.Loader; 20 import alt.jiapi.reflect.Signature; 21 import alt.jiapi.reflect.SignatureUtil; 22 23 import alt.jiapi.reflect.FieldExistsException; 24 import alt.jiapi.reflect.MethodExistsException; 25 26 import alt.jiapi.reflect.instruction.FieldAccess; 27 import alt.jiapi.reflect.instruction.Invocation; 28 import alt.jiapi.reflect.instruction.OpcodeGroups; 29 import alt.jiapi.reflect.instruction.Opcodes; 30 31 import alt.jiapi.util.HotSpot; 32 import alt.jiapi.util.HotSpotLocator; 33 34 35 40 class FieldAdvisorInstrumentor extends EventInstrumentor { 41 private AccessAdvisor advisor; 42 private JiapiMethod getMethod; 43 private JiapiMethod setMethod; 44 45 FieldAdvisorInstrumentor(FieldInterceptor fi, AccessAdvisor advisor) { 46 super(fi); 47 this.advisor = advisor; 48 49 JiapiClass jc = getEventProducer(); 50 try { 51 this.getMethod = 52 jc.getDeclaredMethod("getField", 53 new String [] { "java.lang.Object", 54 "java.lang.String", 55 "java.lang.Object"}); 56 57 this.setMethod = 58 jc.getDeclaredMethod("setField", 59 new String [] { "java.lang.Object", 60 "java.lang.String", 61 "java.lang.Object"}); 62 } 63 catch(Exception e) { 64 e.printStackTrace(); 65 } 66 } 67 68 public void instrument(JiapiMethod jm) { 69 JiapiClass clazz = jm.getDeclaringClass(); 70 JiapiField interceptor = getEventProducerField(); 71 InstructionList il = jm.getInstructionList(); 72 InstructionFactory factory = il.getInstructionFactory(); 73 74 HotSpotLocator hsl = 75 new HotSpotLocator(il, new byte[]{Opcodes.GETSTATIC, 76 Opcodes.GETFIELD}); 77 HotSpot[] hotSpots = hsl.getHotSpots(); 78 79 for (int i = 0; i < hotSpots.length; i++) { 80 FieldAccess fa = (FieldAccess)hotSpots[i].getHotSpotInstruction(); 81 short opCode = fa.getOpcode(); 82 83 if (!match(fa.getClassName() + "." + fa.getFieldName())) { 84 continue; 85 } 86 87 InstructionList hsList = hotSpots[i].getInstructionList(); 88 InstructionList nList = il.createEmptyList(); 89 90 boolean primitive = SignatureUtil.isPrimitive(fa.getTypeName()); 91 92 93 if (opCode == Opcodes.GETSTATIC || 94 opCode == Opcodes.GETFIELD) { 95 nList.add(factory.getField(interceptor)); 97 if (opCode == Opcodes.GETSTATIC) { 101 short lvIdx = 102 addClassForNameInstructions(fa.getClassName(), jm); 103 nList.add(factory.aload(lvIdx)); 104 } 107 else { 108 nList.add(hsList.get(0)); } 111 112 nList.add(factory.pushConstant(fa.getFieldName())); 114 115 Instruction pIns = null; 117 if (primitive) { 118 pIns = handlePrimitiveType(fa.getTypeName(), nList); 120 } 121 nList.add(hotSpots[i].getInstructionList()); 124 125 if (pIns != null) { 126 nList.add(pIns); 127 } 128 129 nList.add(factory.invoke(getMethod)); 131 132 handleReturnValue(nList, fa.getTypeName()); 133 135 hotSpots[i].getInstructionList().replace(nList); 136 } 137 } 138 } 139 140 141 149 private short addClassForNameInstructions(String name, JiapiMethod jm) { 150 InstructionList il = jm.getInstructionList(); 151 InstructionFactory f = il.getInstructionFactory(); 152 153 InstructionList nl = il.createEmptyList(); 154 short maxLocals = (short)jm.getMaxLocals(); 155 156 try { 161 nl.add(f.pushConstant(name)); 162 nl.add(f.invoke(Modifier.STATIC, "java.lang.Class", 163 "forName", new Signature("java.lang.Class", 164 new String [] {"java.lang.String"}))); 165 nl.add(f.astore(maxLocals)); 166 } 167 catch(Exception e) { 168 e.printStackTrace(); 169 il.add(f.pushNull()); 170 } 171 172 il.insert(0, nl); 174 175 return maxLocals; 176 } 177 178 179 private boolean isPublicField(FieldAccess fa) { 180 try { 181 JiapiClass jc = new Loader().loadClass(fa.getClassName()); 182 JiapiField jf = jc.getField(fa.getName()); 183 184 return Modifier.isPublic(jf.getModifiers()); 185 } 186 catch(Exception e) { 187 e.printStackTrace(); 188 } 189 190 return false; 191 } 192 193 194 195 private void handleReturnValue(InstructionList il, String rType) { 196 InstructionFactory factory = il.getInstructionFactory(); 198 199 if ("int".equals(rType)) { 200 try { 201 JiapiClass jc = new Loader().loadClass("java.lang.Integer"); 202 JiapiMethod jm = 203 jc.getDeclaredMethod("intValue", new String [0]); 204 205 il.add(factory.cast("java.lang.Integer")); 206 il.add(factory.invoke(jm)); 207 } 208 catch(Exception e) { 209 e.printStackTrace(); 210 } 211 } 212 else if ("long".equals(rType)) { 213 try { 214 JiapiClass jc = new Loader().loadClass("java.lang.Long"); 215 JiapiMethod jm = 216 jc.getDeclaredMethod("longValue", new String [0]); 217 218 il.add(factory.cast("java.lang.Long")); 219 il.add(factory.invoke(jm)); 220 } 221 catch(Exception e) { 222 e.printStackTrace(); 223 } 224 } 225 else if ("char".equals(rType)) { 226 try { 227 JiapiClass jc = new Loader().loadClass("java.lang.Character"); 228 JiapiMethod jm = 229 jc.getDeclaredMethod("charValue", new String [0]); 230 231 il.add(factory.cast("java.lang.Character")); 232 il.add(factory.invoke(jm)); 233 } 234 catch(Exception e) { 235 e.printStackTrace(); 236 } 237 } 238 else if ("boolean".equals(rType)) { 239 try { 240 JiapiClass jc = new Loader().loadClass("java.lang.Boolean"); 241 JiapiMethod jm = 242 jc.getDeclaredMethod("booleanValue", new String [0]); 243 244 il.add(factory.cast("java.lang.Boolean")); 245 il.add(factory.invoke(jm)); 246 } 247 catch(Exception e) { 248 e.printStackTrace(); 249 } 250 } 251 else if ("byte".equals(rType)) { 252 try { 253 JiapiClass jc = new Loader().loadClass("java.lang.Byte"); 254 JiapiMethod jm = 255 jc.getDeclaredMethod("byteValue", new String [0]); 256 257 il.add(factory.cast("java.lang.Byte")); 258 il.add(factory.invoke(jm)); 259 } 260 catch(Exception e) { 261 e.printStackTrace(); 262 } 263 } 264 else if ("float".equals(rType)) { 265 try { 266 JiapiClass jc = new Loader().loadClass("java.lang.Float"); 267 JiapiMethod jm = 268 jc.getDeclaredMethod("floatValue", new String [0]); 269 270 il.add(factory.cast("java.lang.Float")); 271 il.add(factory.invoke(jm)); 272 } 273 catch(Exception e) { 274 e.printStackTrace(); 275 } 276 } 277 else if ("double".equals(rType)) { 278 try { 279 JiapiClass jc = new Loader().loadClass("java.lang.Double"); 280 JiapiMethod jm = 281 jc.getDeclaredMethod("doubleValue", new String [0]); 282 283 il.add(factory.cast("java.lang.Double")); 284 il.add(factory.invoke(jm)); 285 } 286 catch(Exception e) { 287 e.printStackTrace(); 288 } 289 } 290 else if ("void".equals(rType)){ 291 il.add(new Instruction(new byte[]{Opcodes.POP})); 294 } 295 else { il.add(factory.cast(rType)); 297 } 298 } 299 300 301 302 305 private Instruction handlePrimitiveType(String type, InstructionList il) { 306 InstructionFactory f = il.getInstructionFactory(); 307 String cName = null; 308 Signature s = new Signature("void", new String []{ type }); 309 310 if ("int".equals(type)) { 311 cName = "java.lang.Integer"; 312 } 313 else if ("long".equals(type)) { 314 cName = "java.lang.Long"; 315 } 316 else if ("char".equals(type)) { 317 cName = "java.lang.Character"; 318 } 319 else if ("boolean".equals(type)) { 320 cName = "java.lang.Boolean"; 321 } 322 else if ("byte".equals(type)) { 323 cName = "java.lang.Byte"; 324 } 325 else if ("float".equals(type)) { 326 cName = "java.lang.Float"; 327 } 328 else if ("double".equals(type)) { 329 cName = "java.lang.Double"; 330 } 331 332 il.add(f.newClass(cName)); 333 il.add(f.dup()); 334 Instruction ins = f.invoke(Modifier.PUBLIC, cName, "<init>", s); 335 return ins; 336 } 337 } 338 | Popular Tags |