int this_class_index = cp.getThisClassInfo();
String desc = "()" + finfo.getDescriptor();
MethodInfo minfo = new MethodInfo(cp, EACH_READ_METHOD_PREFIX
+ finfo.getName(), desc);
/* local variables | target obj | each oldvalue | */
Bytecode code = new Bytecode(cp, 5, 3);
// aload_0
code.addAload(0);
// getfield // get each field
code.addOpcode(Opcode.GETFIELD);
int base_field_index = cp.addFieldrefInfo(this_class_index, finfo
.getName(), finfo.getDescriptor());
code.addIndex(base_field_index);
// aload_0
code.addAload(0);
// invokeinterface // invoke 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
code.addOpcode(Opcode.IFNONNULL);
code.addIndex(4);
// *return // each type
addTypeDependDataReturn(code, finfo.getDescriptor());
// *store_1 // each type
addTypeDependDataStore(code, finfo.getDescriptor(), 1);
// aload_0
code.addAload(0);
// invokeinterface // invoke Enabled.getInterceptFieldCallback()
code.addInvokeinterface(enabled_class_index,
GETFIELDHANDLER_METHOD_NAME, GETFIELDHANDLER_METHOD_DESCRIPTOR,
1);
// aload_0
code.addAload(0);
// ldc // name of the field
code.addLdc(finfo.getName());
// *load_1 // each type
addTypeDependDataLoad(code, finfo.getDescriptor(), 1);
// invokeinterface // invoke Callback.read*() // each type
addInvokeFieldHandlerMethod(classfile, code, finfo.getDescriptor(),
true);
// *return // each type
addTypeDependDataReturn(code, finfo.getDescriptor());
minfo.setCodeAttribute(code.toCodeAttribute());
minfo.setAccessFlags(AccessFlag.PUBLIC);
classfile.addMethod(minfo);
}