int this_class_index = cp.getThisClassInfo();
String desc = "(" + finfo.getDescriptor() + ")V";
MethodInfo minfo = new MethodInfo(cp, EACH_WRITE_METHOD_PREFIX
+ finfo.getName(), desc);
/* local variables | target obj | each oldvalue | */
Bytecode code = new Bytecode(cp, 6, 3);
// aload_0
code.addAload(0);
// invokeinterface // enabled.getInterceptFieldCallback()
int enabled_class_index = cp.addClassInfo(FIELD_HANDLED_TYPE_NAME);
code.addInvokeinterface(enabled_class_index,
GETFIELDHANDLER_METHOD_NAME, GETFIELDHANDLER_METHOD_DESCRIPTOR,
1);
// ifnonnull (label1)
code.addOpcode(Opcode.IFNONNULL);
code.addIndex(9);
// aload_0
code.addAload(0);
// *load_1
addTypeDependDataLoad(code, finfo.getDescriptor(), 1);
// putfield
code.addOpcode(Opcode.PUTFIELD);
int base_field_index = cp.addFieldrefInfo(this_class_index, finfo
.getName(), finfo.getDescriptor());
code.addIndex(base_field_index);
code.growStack(-Descriptor.dataSize(finfo.getDescriptor()));
// return ;
code.addOpcode(Opcode.RETURN);
// aload_0
code.addAload(0);
// dup
code.addOpcode(Opcode.DUP);
// invokeinterface // enabled.getInterceptFieldCallback()
code.addInvokeinterface(enabled_class_index,
GETFIELDHANDLER_METHOD_NAME, GETFIELDHANDLER_METHOD_DESCRIPTOR,
1);
// aload_0
code.addAload(0);
// ldc // field name
code.addLdc(finfo.getName());
// aload_0
code.addAload(0);
// getfield // old value of the field
code.addOpcode(Opcode.GETFIELD);
code.addIndex(base_field_index);
code.growStack(Descriptor.dataSize(finfo.getDescriptor()) - 1);
// *load_1
addTypeDependDataLoad(code, finfo.getDescriptor(), 1);
// invokeinterface // callback.write*(..)
addInvokeFieldHandlerMethod(classfile, code, finfo.getDescriptor(),
false);
// putfield // new value of the field
code.addOpcode(Opcode.PUTFIELD);
code.addIndex(base_field_index);
code.growStack(-Descriptor.dataSize(finfo.getDescriptor()));
// return
code.addOpcode(Opcode.RETURN);
minfo.setCodeAttribute(code.toCodeAttribute());
minfo.setAccessFlags(AccessFlag.PUBLIC);
CodeAttribute codeAttribute = minfo.getCodeAttribute();
if (codeAttribute != null) {
StackMapTable smt = MapMaker.make(classPool, minfo);
codeAttribute.setAttribute(smt);