private void addStore()

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