Package alt.jiapi.event

Source Code of alt.jiapi.event.FieldEventInstrumentor

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();
        }
    }
}
TOP

Related Classes of alt.jiapi.event.FieldEventInstrumentor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.