1 package alt.jiapi.event; 2 3 import java.lang.reflect.Modifier ; 4 5 import alt.jiapi.InstrumentationException; 6 import alt.jiapi.Instrumentor; 7 8 import alt.jiapi.reflect.FieldExistsException; 9 import alt.jiapi.reflect.Instruction; 10 import alt.jiapi.reflect.InstructionFactory; 11 import alt.jiapi.reflect.InstructionList; 12 import alt.jiapi.reflect.JiapiClass; 13 import alt.jiapi.reflect.JiapiField; 14 import alt.jiapi.reflect.JiapiMethod; 15 import alt.jiapi.reflect.Loader; 16 import alt.jiapi.reflect.MethodExistsException; 17 import alt.jiapi.reflect.Signature; 18 19 24 public abstract class EventInstrumentor implements Instrumentor { 25 private EventProducer ep; 26 private JiapiField eventProducerField; 27 private JiapiClass currentClass; 28 29 protected EventInstrumentor(EventProducer ep) { 30 this.ep = ep; 31 } 32 33 36 public boolean match(String s) { 37 return ep.match(s); 38 } 39 40 43 public void instrument(JiapiClass jc) { 44 this.currentClass = jc; 45 46 if (jc.isInterface()) { 47 return; 48 } 49 50 51 JiapiMethod[] dMethods = jc.getDeclaredMethods(); 53 for (int i = 0; i < dMethods.length; i++) { 54 if (!dMethods[i].isSynthetic()) { 56 if (dMethods[i].getInstructionList() != null) { 58 int su1 = dMethods[i].getInstructionList().stackUsage(); 59 instrument(dMethods[i]); 60 int su2 = dMethods[i].getInstructionList().stackUsage(); 61 62 if (su1 != su2) { 63 System.out.println("ERROR: " + "Instrumentation of " + jc.getName() + ": " + dMethods[i] + " changes stack usage from " + su1 + " to " + su2); 64 } 66 } 67 } 68 } 69 } 70 71 protected JiapiClass getEventProducer() { 72 JiapiClass jc = null; 73 try { 74 jc = new Loader().loadClass(ep.getClass().getName()); 75 } 76 catch(Exception e) { 77 System.out.println("ERROR: " + e); 78 } 79 80 return jc; 81 } 82 83 protected JiapiField getEventProducerField() { 84 String fieldName = "__jiapi_field_" + 85 EventRuntime.nextFieldNameIndex(); 86 87 EventRuntime.setFieldValue(fieldName, ep); 91 92 eventProducerField = null; 94 try { 95 eventProducerField = 96 currentClass.addField(Modifier.PRIVATE +Modifier.STATIC, 97 ep.getClass().getName(), fieldName); 98 } 99 catch(FieldExistsException fee) { 100 } 102 103 104 JiapiMethod clinit = null; 107 try { 108 clinit = currentClass.getDeclaredMethod("<clinit>",new String []{}); 109 } 110 catch(NoSuchMethodException nsme) { 111 try { 113 clinit = 114 currentClass.addMethod(Modifier.STATIC, "<clinit>", 115 new Signature("void", 116 new String [0])); 117 clinit.getInstructionList().add(clinit.getInstructionList().getInstructionFactory().returnMethod(clinit)); 119 } 120 catch(MethodExistsException mee) { 121 mee.printStackTrace(); 122 } 123 } 124 125 InstructionList il = clinit.getInstructionList(); 126 InstructionFactory factory = il.getInstructionFactory(); 127 InstructionList initializer = il.createEmptyList(); 128 129 try { 130 JiapiClass er = currentClass.getLoader().loadClass("alt.jiapi.event.EventRuntime"); 131 JiapiMethod gfv = 132 er.getDeclaredMethod("getFieldValue", 133 new String [] {"java.lang.String"}); 134 135 initializer.add(factory.pushConstant(fieldName)); 137 initializer.add(factory.invoke(gfv)); 138 139 140 initializer.add(factory.cast(ep.getClass().getName())); 142 initializer.add(factory.setField(eventProducerField)); 143 } 144 catch(NoSuchMethodException nsme) { 145 nsme.printStackTrace(); 146 } 147 catch(ClassNotFoundException cnfe) { 148 cnfe.printStackTrace(); 149 } 150 catch(java.io.IOException ioe) { 151 ioe.printStackTrace(); 152 } 153 154 il.insert(0, initializer); 156 157 158 return eventProducerField; 159 } 160 161 public JiapiClass getCurrentClass() { 162 return currentClass; 163 } 164 165 166 public abstract void instrument(JiapiMethod jm); 167 } 168 | Popular Tags |