package alt.jiapi.event;
import alt.jiapi.reflect.Instruction;
import alt.jiapi.reflect.InstructionFactory;
import alt.jiapi.reflect.InstructionList;
import alt.jiapi.reflect.JiapiClass;
import alt.jiapi.reflect.JiapiField;
import alt.jiapi.reflect.JiapiMethod;
import alt.jiapi.reflect.Signature;
import alt.jiapi.reflect.instruction.FieldAccess;
import alt.jiapi.reflect.instruction.OpcodeGroups;
import alt.jiapi.reflect.instruction.Opcodes;
/**
* Class MethodEventInstrumentor.
*
* @author Mika Riekkinen
*/
class FieldEventInstrumentor extends EventInstrumentor {
FieldEventInstrumentor(FieldEventProducer fep) {
super(fep);
}
public void instrument(JiapiMethod jm) {
InstructionList il = jm.getInstructionList();
InstructionFactory factory = il.getInstructionFactory();
JiapiClass fep = getEventProducer();
JiapiMethod fieldGet = null;
JiapiMethod fieldSet = null;
JiapiField jiapiField = getEventProducerField();
try {
fieldGet =
fep.getDeclaredMethod("fieldGet",
new String[] { "java.lang.Object",
"java.lang.String" });
fieldSet =
fep.getDeclaredMethod("fieldSet",
new String[] { "java.lang.Object",
"java.lang.String" });
}
catch(Exception e) {
System.out.println("ERROR: " + e);
}
//System.out.println("Instrumenting " + il.getDeclaringMethod());
int idx = -1;
while ((idx = il.indexOf(OpcodeGroups.FIELD_ACCESS_INSTRUCTIONS, idx+1)) != -1) {
FieldAccess ins = (FieldAccess)il.get(idx);
// Do not instrument on __jiapi_fields
if (ins.getName().startsWith("__jiapi_field")) {
continue;
}
//System.out.println(" found " + ins);
InstructionList invokeList = il.createEmptyList();
switch(ins.getOpcode()) {
case Opcodes.PUTFIELD:
case Opcodes.GETFIELD:
invokeList.add(factory.getField(jiapiField));
invokeList.add(factory.pushThis());
invokeList.add(factory.pushConstant(ins.getFieldName()));
if (ins.getOpcode() == Opcodes.GETFIELD) {
invokeList.add(factory.invoke(fieldGet));
}
else {
invokeList.add(factory.invoke(fieldSet));
}
break;
case Opcodes.PUTSTATIC:
case Opcodes.GETSTATIC:
invokeList.add(factory.getField(jiapiField));
invokeList.add(factory.getField(jiapiField)); // BUG: Class
invokeList.add(factory.pushConstant(ins.getFieldName()));
if (ins.getOpcode() == Opcodes.GETSTATIC) {
invokeList.add(factory.invoke(fieldGet));
}
else {
invokeList.add(factory.invoke(fieldSet));
}
break;
}
// Insert list after field access operation
il.insert(idx + 1, invokeList);
// Next index. Skip Instructions created above.
idx += invokeList.size();
}
}
}