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 22 import alt.jiapi.reflect.FieldExistsException; 23 import alt.jiapi.reflect.MethodExistsException; 24 25 import alt.jiapi.reflect.instruction.FieldAccess; 26 import alt.jiapi.reflect.instruction.OpcodeGroups; 27 import alt.jiapi.reflect.instruction.Opcodes; 28 29 import alt.jiapi.util.HotSpot; 30 import alt.jiapi.util.HotSpotLocator; 31 32 33 38 class FieldInstrumentor extends EventInstrumentor { 39 private FieldHandler handler; 40 private JiapiMethod getMethod; 41 private JiapiMethod setMethod; 42 43 FieldInstrumentor(FieldInterceptor2 ii, FieldHandler handler) { 44 super(ii); 45 this.handler = handler; 46 47 JiapiClass jc = getEventProducer(); 48 try { 49 this.getMethod = 50 jc.getDeclaredMethod("getField", 51 new String [] { "java.lang.Object", 52 "java.lang.String"}); 53 54 this.setMethod = 55 jc.getDeclaredMethod("setField", 56 new String [] { "java.lang.Object", 57 "java.lang.String", 58 "java.lang.Object"}); 59 } 60 catch(Exception e) { 61 e.printStackTrace(); 62 } 63 } 64 65 public void instrument(JiapiMethod jm) { 66 JiapiField interceptor = getEventProducerField(); 67 InstructionList il = jm.getInstructionList(); 68 InstructionFactory factory = il.getInstructionFactory(); 69 70 HotSpotLocator hsl = 71 new HotSpotLocator(il, 72 new byte[]{Opcodes.GETSTATIC}); 73 HotSpot[] hotSpots = hsl.getHotSpots(); 74 75 for (int i = 0; i < hotSpots.length; i++) { 76 FieldAccess fa = (FieldAccess)hotSpots[i].getHotSpotInstruction(); 77 78 if (fa.getName().startsWith("__jiapi")) { 79 continue; 80 } 81 82 if (!match(fa.getClassName() + "." + fa.getFieldName())) { 83 continue; 84 } 85 86 if (!isPublicField(fa)) { 89 continue; 90 } 91 92 InstructionList hsList = hotSpots[i].getInstructionList(); 93 InstructionList nList = il.createEmptyList(); 94 95 nList.add(factory.getField(interceptor)); 97 if ((fa.getOpcode() == Opcodes.GETSTATIC) || 99 (fa.getOpcode() == Opcodes.PUTSTATIC)) { 100 addClassForNameInstructions(fa.getClassName(), nList); 101 } 102 else { 103 nList.add(il.get(0)); } 105 106 nList.add(factory.pushConstant(fa.getClassName() + "." + 108 fa.getFieldName())); 109 110 if ((fa.getOpcode() == Opcodes.GETSTATIC) || 112 (fa.getOpcode() == Opcodes.GETFIELD)) { 113 nList.add(factory.invoke(getMethod)); 114 } 115 else { 116 nList.add(il.get(1)); nList.add(factory.invoke(setMethod)); 118 } 119 120 handleReturnValue(nList, fa.getTypeName()); 121 122 124 hsList.replace(nList); 125 } 126 } 127 128 129 private void addClassForNameInstructions(String name, InstructionList il) { 130 InstructionFactory f = il.getInstructionFactory(); 131 132 InstructionList nl = il.createEmptyList(); 133 134 try { 139 nl.add(f.pushConstant(name)); 140 nl.add(f.invoke(Modifier.STATIC, "java.lang.Class", 141 "forName", new Signature("java.lang.Class", 142 new String [] {"java.lang.String"}))); 143 } 144 catch(Exception e) { 145 e.printStackTrace(); 146 il.add(f.pushNull()); 147 } 148 149 il.add(nl); 150 } 151 152 153 private boolean isPublicField(FieldAccess fa) { 154 try { 155 JiapiClass jc = new Loader().loadClass(fa.getClassName()); 156 JiapiField jf = jc.getField(fa.getName()); 157 158 return Modifier.isPublic(jf.getModifiers()); 159 } 160 catch(Exception e) { 161 e.printStackTrace(); 162 } 163 164 return false; 165 } 166 167 168 private void handleReturnValue(InstructionList il, String rType) { 169 InstructionFactory factory = il.getInstructionFactory(); 171 172 if ("int".equals(rType)) { 173 try { 174 JiapiClass jc = new Loader().loadClass("java.lang.Integer"); 175 JiapiMethod jm = 176 jc.getDeclaredMethod("intValue", new String [0]); 177 178 il.add(factory.cast("java.lang.Integer")); 179 il.add(factory.invoke(jm)); 180 } 181 catch(Exception e) { 182 e.printStackTrace(); 183 } 184 } 185 else if ("long".equals(rType)) { 186 try { 187 JiapiClass jc = new Loader().loadClass("java.lang.Long"); 188 JiapiMethod jm = 189 jc.getDeclaredMethod("longValue", new String [0]); 190 191 il.add(factory.cast("java.lang.Long")); 192 il.add(factory.invoke(jm)); 193 } 194 catch(Exception e) { 195 e.printStackTrace(); 196 } 197 } 198 else if ("char".equals(rType)) { 199 try { 200 JiapiClass jc = new Loader().loadClass("java.lang.Character"); 201 JiapiMethod jm = 202 jc.getDeclaredMethod("charValue", new String [0]); 203 204 il.add(factory.cast("java.lang.Character")); 205 il.add(factory.invoke(jm)); 206 } 207 catch(Exception e) { 208 e.printStackTrace(); 209 } 210 } 211 else if ("boolean".equals(rType)) { 212 try { 213 JiapiClass jc = new Loader().loadClass("java.lang.Boolean"); 214 JiapiMethod jm = 215 jc.getDeclaredMethod("booleanValue", new String [0]); 216 217 il.add(factory.cast("java.lang.Boolean")); 218 il.add(factory.invoke(jm)); 219 } 220 catch(Exception e) { 221 e.printStackTrace(); 222 } 223 } 224 else if ("byte".equals(rType)) { 225 try { 226 JiapiClass jc = new Loader().loadClass("java.lang.Byte"); 227 JiapiMethod jm = 228 jc.getDeclaredMethod("byteValue", new String [0]); 229 230 il.add(factory.cast("java.lang.Byte")); 231 il.add(factory.invoke(jm)); 232 } 233 catch(Exception e) { 234 e.printStackTrace(); 235 } 236 } 237 else if ("float".equals(rType)) { 238 try { 239 JiapiClass jc = new Loader().loadClass("java.lang.Float"); 240 JiapiMethod jm = 241 jc.getDeclaredMethod("floatValue", new String [0]); 242 243 il.add(factory.cast("java.lang.Float")); 244 il.add(factory.invoke(jm)); 245 } 246 catch(Exception e) { 247 e.printStackTrace(); 248 } 249 } 250 else if ("double".equals(rType)) { 251 try { 252 JiapiClass jc = new Loader().loadClass("java.lang.Double"); 253 JiapiMethod jm = 254 jc.getDeclaredMethod("doubleValue", new String [0]); 255 256 il.add(factory.cast("java.lang.Double")); 257 il.add(factory.invoke(jm)); 258 } 259 catch(Exception e) { 260 e.printStackTrace(); 261 } 262 } 263 else if ("void".equals(rType)){ 264 il.add(new Instruction(new byte[]{Opcodes.POP})); 267 } 268 else { il.add(factory.cast(rType)); 270 } 271 } 272 } 273 | Popular Tags |