/**
* Add methods for loading and storing class-level impl data.
*/
private void addFieldImplDataMethods(BCClass bc, ClassMetaData meta) {
// public void loadImplData(OpenJPAStateManager sm, int i)
BCMethod meth = bc.declareMethod("loadImplData", void.class,
new Class[]{ OpenJPAStateManager.class, int.class });
meth.makePrivate();
Code code = meth.getCode(true);
int count = countImplDataFields(meta);
BCField impl = null;
if (count == 0)
code.vreturn();
else {
// Object[] fieldImpl
impl = bc.declareField("fieldImpl", Object[].class);
impl.makePrivate();
// if (fieldImpl != null)
code.aload().setThis();
code.getfield().setField(impl);
JumpInstruction ifins = code.ifnonnull();
code.vreturn();
// Object obj = null;
int obj = code.getNextLocalsIndex();
ifins.setTarget(code.constant().setNull());
code.astore().setLocal(obj);
// establish switch target, then move before it
Instruction target = code.aload().setLocal(obj);
code.previous();
// switch(i)
code.iload().setParam(1);
LookupSwitchInstruction lswitch = code.lookupswitch();
FieldMetaData[] fields = meta.getFields();
int cacheable = 0;
for (int i = 0; i < fields.length; i++) {
if (!usesImplData(fields[i]))
continue;
// case x: obj = fieldImpl[y]; break;
lswitch.addCase(i, code.aload().setThis());
code.getfield().setField(impl);
code.constant().setValue(cacheable++);
code.aaload();
code.astore().setLocal(obj);
code.go2().setTarget(target);
}
lswitch.setDefaultTarget(target);
// if (obj != null)
code.next(); // jump back over target
ifins = code.ifnonnull();
code.vreturn();
// sm.setImplData(index, impl);
ifins.setTarget(code.aload().setParam(0));
code.iload().setParam(1);
code.aload().setLocal(obj);
code.invokeinterface().setMethod(OpenJPAStateManager.class,
"setImplData", void.class,
new Class[]{ int.class, Object.class });
code.vreturn();
}
code.calculateMaxLocals();
code.calculateMaxStack();
// void storeImplData(OpenJPAStateManager sm, int index, boolean loaded)
meth = bc.declareMethod("storeImplData", void.class,
new Class[]{ OpenJPAStateManager.class, int.class, boolean.class });
code = meth.getCode(true);
if (count == 0)
code.vreturn();
else {
// int arrIdx = -1;
// switch(index)