in openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCDataGenerator.java [1080:1200]
private void addStore(ClassNode classNode, MethodNode meth, InsnList instructions, FieldMetaData fmd, int objectCount) {
int typeCode = replaceType(fmd);
int index = fmd.getIndex();
if (typeCode < JavaTypes.OBJECT) {
Class<?> type = forType(typeCode);
// field<i> = sm.fetch<Type>(index)
instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); // this
instructions.add(new VarInsnNode(Opcodes.ALOAD, 1)); // 1st param
instructions.add(AsmHelper.getLoadConstantInsn(index));
instructions.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE,
Type.getInternalName(OpenJPAStateManager.class),
"fetch" + StringUtil.capitalize(type.getName()),
Type.getMethodDescriptor(Type.getType(type), Type.INT_TYPE)));
instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, classNode.name, getFieldName(index), Type.getDescriptor(type)));
instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); // this
instructions.add(new FieldInsnNode(Opcodes.GETFIELD, classNode.name, "loaded", Type.getDescriptor(BitSet.class)));
instructions.add(AsmHelper.getLoadConstantInsn(index));
instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
Type.getInternalName(BitSet.class),
"set",
Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE)));
}
else {
// Object val = toData(sm.getMetaData().getField(index),
// sm.fetchField(index, false), sm.getContext());
int localVarPos = AsmHelper.getLocalVarPos(meth);
instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); // this
instructions.add(new VarInsnNode(Opcodes.ALOAD, 1)); // 1st param
instructions.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE,
Type.getInternalName(OpenJPAStateManager.class),
"getMetaData",
Type.getMethodDescriptor(Type.getType(ClassMetaData.class))));
instructions.add(AsmHelper.getLoadConstantInsn(fmd.getIndex()));
instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
Type.getInternalName(ClassMetaData.class),
"getField",
Type.getMethodDescriptor(Type.getType(FieldMetaData.class), Type.INT_TYPE)));
instructions.add(new VarInsnNode(Opcodes.ALOAD, 1)); // 1st param
instructions.add(AsmHelper.getLoadConstantInsn(fmd.getIndex()));
instructions.add(AsmHelper.getLoadConstantInsn(false));
instructions.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE,
Type.getInternalName(OpenJPAStateManager.class),
"fetchField",
Type.getMethodDescriptor(AsmHelper.TYPE_OBJECT, Type.INT_TYPE, Type.BOOLEAN_TYPE)));
instructions.add(new VarInsnNode(Opcodes.ALOAD, 1)); // 1st param
instructions.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE,
Type.getInternalName(OpenJPAStateManager.class),
"getContext",
Type.getMethodDescriptor(Type.getType(StoreContext.class))));
instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
classNode.name,
"toData",
Type.getMethodDescriptor(AsmHelper.TYPE_OBJECT,
Type.getType(FieldMetaData.class),
AsmHelper.TYPE_OBJECT,
Type.getType(StoreContext.class))));
instructions.add(new VarInsnNode(Opcodes.ASTORE, localVarPos));
// if (val == NULL) {
// val = null;
// loaded.clear(index);
// } else
// loaded.set(index);
// objects[objectCount] = val;
instructions.add(new VarInsnNode(Opcodes.ALOAD, localVarPos));
instructions.add(new FieldInsnNode(Opcodes.GETSTATIC, Type.getInternalName(AbstractPCData.class),
"NULL", AsmHelper.TYPE_OBJECT.getDescriptor()));
LabelNode lblElse = new LabelNode();
instructions.add(new JumpInsnNode(Opcodes.IF_ACMPNE, lblElse));
instructions.add(new InsnNode(Opcodes.ACONST_NULL));
instructions.add(new VarInsnNode(Opcodes.ASTORE, localVarPos));
instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); // this
instructions.add(new FieldInsnNode(Opcodes.GETFIELD, classNode.name, "loaded", Type.getDescriptor(BitSet.class)));
instructions.add(AsmHelper.getLoadConstantInsn(index));
instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
Type.getInternalName(BitSet.class),
"clear",
Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE)));
LabelNode lblEndIf = new LabelNode();
instructions.add(new JumpInsnNode(Opcodes.GOTO, lblEndIf));
instructions.add(lblElse);
instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); // this
instructions.add(new FieldInsnNode(Opcodes.GETFIELD, classNode.name, "loaded", Type.getDescriptor(BitSet.class)));
instructions.add(AsmHelper.getLoadConstantInsn(index));
instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
Type.getInternalName(BitSet.class),
"set",
Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE)));
instructions.add(lblEndIf);
instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); // this
instructions.add(new FieldInsnNode(Opcodes.GETFIELD, classNode.name, "objects", Type.getDescriptor(Object[].class)));
instructions.add(AsmHelper.getLoadConstantInsn(objectCount));
instructions.add(new VarInsnNode(Opcodes.ALOAD, localVarPos));
instructions.add(new InsnNode(Opcodes.AASTORE));
}
if (!usesImplData(fmd)) {
return;
}
// storeImplData(sm, i, loaded.get(i);
instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); // this
instructions.add(new VarInsnNode(Opcodes.ALOAD, 1)); // 1st param
instructions.add(AsmHelper.getLoadConstantInsn(index));
instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); // this
instructions.add(new FieldInsnNode(Opcodes.GETFIELD, classNode.name, "loaded", Type.getDescriptor(BitSet.class)));
instructions.add(AsmHelper.getLoadConstantInsn(index));
instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
Type.getInternalName(BitSet.class),
"get",
Type.getMethodDescriptor(Type.BOOLEAN_TYPE, Type.INT_TYPE)));
instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
classNode.name,
"storeImplData",
Type.getMethodDescriptor(Type.VOID_TYPE,
Type.getType(OpenJPAStateManager.class), Type.INT_TYPE, Type.BOOLEAN_TYPE)));
}