Search in sources :

Example 31 with Label

use of org.datanucleus.enhancer.asm.Label in project tests by datanucleus.

the class DynamicEnhanceSchemaToolTest method createClass.

private static byte[] createClass(String className) throws Exception {
    ClassWriter cw = new ClassWriter(0);
    MethodVisitor mv;
    FieldVisitor fv;
    String classNameASM = className.replace('.', '/');
    // TODO Use getAsmVersionForJRE instead of V1_6 (requires proper stack map)
    cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, classNameASM, null, "java/lang/Object", new String[] {});
    fv = cw.visitField(Opcodes.ACC_PRIVATE, "name", "Ljava/lang/String;", null, null);
    fv.visitEnd();
    // Default Constructor
    {
        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
        mv.visitInsn(Opcodes.RETURN);
        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitLocalVariable("this", "L" + classNameASM + ";", null, l0, l1, 0);
        mv.visitMaxs(1, 1);
        mv.visitEnd();
    }
    // String getName()
    {
        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getName", "()Ljava/lang/String;", null, null);
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitFieldInsn(Opcodes.GETFIELD, classNameASM, "name", "Ljava/lang/String;");
        mv.visitInsn(Opcodes.ARETURN);
        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitLocalVariable("this", "L" + classNameASM + ";", null, l0, l1, 0);
        mv.visitMaxs(1, 1);
        mv.visitEnd();
    }
    // void setName(String)
    {
        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "setName", "(Ljava/lang/String;)V", null, null);
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitVarInsn(Opcodes.ALOAD, 1);
        mv.visitFieldInsn(Opcodes.PUTFIELD, classNameASM, "name", "Ljava/lang/String;");
        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitInsn(Opcodes.RETURN);
        Label l2 = new Label();
        mv.visitLabel(l2);
        mv.visitLocalVariable("this", "L" + classNameASM + ";", null, l0, l2, 0);
        mv.visitLocalVariable("s", "Ljava/lang/String;", null, l0, l2, 1);
        mv.visitMaxs(2, 2);
        mv.visitEnd();
    }
    // Object getProperty(String)
    {
        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getProperty", "(Ljava/lang/String;)Ljava/lang/Object;", null, null);
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitInsn(Opcodes.ACONST_NULL);
        mv.visitVarInsn(Opcodes.ASTORE, 2);
        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitVarInsn(Opcodes.ALOAD, 1);
        mv.visitLdcInsn("name");
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false);
        Label l2 = new Label();
        mv.visitJumpInsn(Opcodes.IFEQ, l2);
        Label l3 = new Label();
        mv.visitLabel(l3);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitFieldInsn(Opcodes.GETFIELD, classNameASM, "name", "Ljava/lang/String;");
        mv.visitVarInsn(Opcodes.ASTORE, 2);
        mv.visitLabel(l2);
        mv.visitVarInsn(Opcodes.ALOAD, 2);
        mv.visitInsn(Opcodes.ARETURN);
        Label l4 = new Label();
        mv.visitLabel(l4);
        mv.visitLocalVariable("this", "L" + classNameASM + ";", null, l0, l4, 0);
        mv.visitLocalVariable("propertyName", "Ljava/lang/String;", null, l0, l4, 1);
        mv.visitLocalVariable("o", "Ljava/lang/Object;", null, l1, l4, 2);
        mv.visitMaxs(2, 3);
        mv.visitEnd();
    }
    // void setProperty(String, Object)
    {
        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "setProperty", "(Ljava/lang/String;Ljava/lang/Object;)V", null, null);
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitVarInsn(Opcodes.ALOAD, 1);
        mv.visitLdcInsn("name");
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false);
        Label l1 = new Label();
        mv.visitJumpInsn(Opcodes.IFEQ, l1);
        Label l2 = new Label();
        mv.visitLabel(l2);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitVarInsn(Opcodes.ALOAD, 2);
        mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/String");
        mv.visitFieldInsn(Opcodes.PUTFIELD, classNameASM, "name", "Ljava/lang/String;");
        mv.visitLabel(l1);
        mv.visitInsn(Opcodes.RETURN);
        Label l3 = new Label();
        mv.visitLabel(l3);
        mv.visitLocalVariable("this", "L" + classNameASM + ";", null, l0, l3, 0);
        mv.visitLocalVariable("propertyName", "Ljava/lang/String;", null, l0, l3, 1);
        mv.visitLocalVariable("value", "Ljava/lang/Object;", null, l0, l3, 2);
        mv.visitMaxs(2, 3);
        mv.visitEnd();
    }
    return cw.toByteArray();
}
Also used : Label(org.datanucleus.enhancer.asm.Label) FieldVisitor(org.datanucleus.enhancer.asm.FieldVisitor) ClassWriter(org.datanucleus.enhancer.asm.ClassWriter) MethodVisitor(org.datanucleus.enhancer.asm.MethodVisitor)

Example 32 with Label

use of org.datanucleus.enhancer.asm.Label in project datanucleus-core by datanucleus.

the class NewObjectIdInstance1 method execute.

/**
 * Method to add the contents of the class method.
 */
public void execute() {
    visitor.visitCode();
    Label startLabel = new Label();
    visitor.visitLabel(startLabel);
    ClassMetaData cmd = enhancer.getClassMetaData();
    if (cmd.getIdentityType() == IdentityType.APPLICATION) {
        // application identity
        if (!cmd.isInstantiable()) {
            // Application identity but mapped-superclass with no PK defined, so throw exception
            visitor.visitTypeInsn(Opcodes.NEW, getClassEnhancer().getNamer().getFatalInternalExceptionAsmClassName());
            visitor.visitInsn(Opcodes.DUP);
            visitor.visitLdcInsn("This class has no identity");
            visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, getClassEnhancer().getNamer().getFatalInternalExceptionAsmClassName(), "<init>", "(Ljava/lang/String;)V");
            visitor.visitInsn(Opcodes.ATHROW);
            Label endLabel = new Label();
            visitor.visitLabel(endLabel);
            visitor.visitLocalVariable("this", getClassEnhancer().getClassDescriptor(), null, startLabel, endLabel, 0);
            visitor.visitMaxs(3, 1);
        } else {
            String objectIdClass = cmd.getObjectidClass();
            int[] pkFieldNums = cmd.getPKMemberPositions();
            if (IdentityUtils.isSingleFieldIdentityClass(objectIdClass)) {
                // SingleFieldIdentity
                String ACN_objectIdClass = objectIdClass.replace('.', '/');
                AbstractMemberMetaData fmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(pkFieldNums[0]);
                visitor.visitTypeInsn(Opcodes.NEW, ACN_objectIdClass);
                visitor.visitInsn(Opcodes.DUP);
                visitor.visitVarInsn(Opcodes.ALOAD, 0);
                visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;");
                visitor.visitVarInsn(Opcodes.ALOAD, 0);
                if (fmd instanceof PropertyMetaData) {
                    // Persistent property so use dnGetXXX()
                    visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, getClassEnhancer().getASMClassName(), getNamer().getGetMethodPrefixMethodName() + fmd.getName(), "()" + Type.getDescriptor(fmd.getType()));
                } else {
                    // Persistent field so use xxx
                    visitor.visitFieldInsn(Opcodes.GETFIELD, getClassEnhancer().getASMClassName(), fmd.getName(), Type.getDescriptor(fmd.getType()));
                }
                Class primitiveType = ClassUtils.getPrimitiveTypeForType(fmd.getType());
                if (primitiveType != null) {
                    // Using object wrapper of primitive so use wrapper constructor
                    visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, ACN_objectIdClass, "<init>", "(Ljava/lang/Class;" + Type.getDescriptor(fmd.getType()) + ")V");
                } else {
                    visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, ACN_objectIdClass, "<init>", "(Ljava/lang/Class;" + getNamer().getTypeDescriptorForSingleFieldIdentityGetKey(objectIdClass) + ")V");
                }
                visitor.visitInsn(Opcodes.ARETURN);
                Label endLabel = new Label();
                visitor.visitLabel(endLabel);
                visitor.visitLocalVariable("this", getClassEnhancer().getClassDescriptor(), null, startLabel, endLabel, 0);
                visitor.visitMaxs(4, 1);
            } else {
                // User-provided app identity, and compound identity
                String ACN_objectIdClass = objectIdClass.replace('.', '/');
                visitor.visitTypeInsn(Opcodes.NEW, ACN_objectIdClass);
                visitor.visitInsn(Opcodes.DUP);
                visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, ACN_objectIdClass, "<init>", "()V");
                visitor.visitInsn(Opcodes.ARETURN);
                Label endLabel = new Label();
                visitor.visitLabel(endLabel);
                visitor.visitLocalVariable("this", getClassEnhancer().getClassDescriptor(), null, startLabel, endLabel, 0);
                visitor.visitMaxs(2, 1);
            }
        }
    } else {
        // datastore/nondurable identity
        visitor.visitInsn(Opcodes.ACONST_NULL);
        visitor.visitInsn(Opcodes.ARETURN);
        Label endLabel = new Label();
        visitor.visitLabel(endLabel);
        visitor.visitLocalVariable("this", getClassEnhancer().getClassDescriptor(), null, startLabel, endLabel, 0);
        visitor.visitMaxs(1, 1);
    }
    visitor.visitEnd();
}
Also used : Label(org.datanucleus.enhancer.asm.Label) PropertyMetaData(org.datanucleus.metadata.PropertyMetaData) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) ClassMetaData(org.datanucleus.metadata.ClassMetaData)

Example 33 with Label

use of org.datanucleus.enhancer.asm.Label in project datanucleus-core by datanucleus.

the class NewObjectIdInstance2 method execute.

/**
 * Method to add the contents of the class method.
 */
public void execute() {
    visitor.visitCode();
    Label startLabel = new Label();
    visitor.visitLabel(startLabel);
    ClassMetaData cmd = enhancer.getClassMetaData();
    if (cmd.getIdentityType() == IdentityType.APPLICATION) {
        // application identity
        if (!cmd.isInstantiable()) {
            // Application identity but mapped-superclass with no PK defined, so throw exception
            visitor.visitTypeInsn(Opcodes.NEW, getClassEnhancer().getNamer().getFatalInternalExceptionAsmClassName());
            visitor.visitInsn(Opcodes.DUP);
            visitor.visitLdcInsn("This class has no identity");
            visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, getClassEnhancer().getNamer().getFatalInternalExceptionAsmClassName(), "<init>", "(Ljava/lang/String;)V");
            visitor.visitInsn(Opcodes.ATHROW);
            Label endLabel = new Label();
            visitor.visitLabel(endLabel);
            visitor.visitLocalVariable("this", getClassEnhancer().getClassDescriptor(), null, startLabel, endLabel, 0);
            visitor.visitLocalVariable("key", "Ljava/lang/Object;", null, startLabel, endLabel, 1);
            visitor.visitMaxs(3, 2);
        } else {
            String objectIdClass = cmd.getObjectidClass();
            int[] pkFieldNums = cmd.getPKMemberPositions();
            if (IdentityUtils.isSingleFieldIdentityClass(objectIdClass)) {
                // SingleFieldIdentity
                String ACN_objectIdClass = objectIdClass.replace('.', '/');
                AbstractMemberMetaData fmd = enhancer.getClassMetaData().getMetaDataForManagedMemberAtAbsolutePosition(pkFieldNums[0]);
                {
                    // if (key == null) throw new IllegalArgumentException("...");
                    visitor.visitVarInsn(Opcodes.ALOAD, 1);
                    Label l1 = new Label();
                    visitor.visitJumpInsn(Opcodes.IFNONNULL, l1);
                    visitor.visitTypeInsn(Opcodes.NEW, "java/lang/IllegalArgumentException");
                    visitor.visitInsn(Opcodes.DUP);
                    visitor.visitLdcInsn("key is null");
                    visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/IllegalArgumentException", "<init>", "(Ljava/lang/String;)V");
                    visitor.visitInsn(Opcodes.ATHROW);
                    // Object constructor : "if (key instanceof String != true) return new XXXIdentity(this.getClass(), key);"
                    visitor.visitLabel(l1);
                    visitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
                    visitor.visitVarInsn(Opcodes.ALOAD, 1);
                    visitor.visitTypeInsn(Opcodes.INSTANCEOF, "java/lang/String");
                    Label l3 = new Label();
                    visitor.visitJumpInsn(Opcodes.IFNE, l3);
                    visitor.visitTypeInsn(Opcodes.NEW, ACN_objectIdClass);
                    visitor.visitInsn(Opcodes.DUP);
                    visitor.visitVarInsn(Opcodes.ALOAD, 0);
                    visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;");
                    visitor.visitVarInsn(Opcodes.ALOAD, 1);
                    String objectTypeInConstructor = EnhanceUtils.getASMClassNameForSingleFieldIdentityConstructor(fmd.getType());
                    Class primitiveType = ClassUtils.getPrimitiveTypeForType(fmd.getType());
                    if (primitiveType != null) {
                        objectTypeInConstructor = fmd.getTypeName().replace('.', '/');
                    }
                    if (!objectIdClass.equals(getNamer().getObjectIdentityClass().getName()) || primitiveType != null) {
                        // Add cast if using an Object based type or an Object wrapper of a primitive
                        visitor.visitTypeInsn(Opcodes.CHECKCAST, objectTypeInConstructor);
                    }
                    visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, ACN_objectIdClass, "<init>", "(Ljava/lang/Class;" + "L" + objectTypeInConstructor + ";)V");
                    visitor.visitInsn(Opcodes.ARETURN);
                    // String constructor : "return new XXXIdentity(this.getClass(), (String) key);"
                    visitor.visitLabel(l3);
                    visitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
                    visitor.visitTypeInsn(Opcodes.NEW, ACN_objectIdClass);
                    visitor.visitInsn(Opcodes.DUP);
                    visitor.visitVarInsn(Opcodes.ALOAD, 0);
                    visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;");
                    visitor.visitVarInsn(Opcodes.ALOAD, 1);
                    visitor.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/String");
                    visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, ACN_objectIdClass, "<init>", "(Ljava/lang/Class;Ljava/lang/String;" + ")V");
                    visitor.visitInsn(Opcodes.ARETURN);
                    Label endLabel = new Label();
                    visitor.visitLabel(endLabel);
                    visitor.visitLocalVariable("this", getClassEnhancer().getClassDescriptor(), null, startLabel, endLabel, 0);
                    visitor.visitLocalVariable("key", EnhanceUtils.CD_Object, null, startLabel, endLabel, 1);
                    visitor.visitMaxs(4, 2);
                }
            } else {
                // User-provided app identity, and compound identity
                String ACN_objectIdClass = objectIdClass.replace('.', '/');
                visitor.visitTypeInsn(Opcodes.NEW, ACN_objectIdClass);
                visitor.visitInsn(Opcodes.DUP);
                visitor.visitVarInsn(Opcodes.ALOAD, 1);
                visitor.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/String");
                visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, ACN_objectIdClass, "<init>", "(Ljava/lang/String;)V");
                visitor.visitInsn(Opcodes.ARETURN);
                Label endLabel = new Label();
                visitor.visitLabel(endLabel);
                visitor.visitLocalVariable("this", getClassEnhancer().getClassDescriptor(), null, startLabel, endLabel, 0);
                visitor.visitLocalVariable(argNames[0], EnhanceUtils.CD_Object, null, startLabel, endLabel, 1);
                visitor.visitMaxs(3, 2);
                visitor.visitEnd();
            }
        }
    } else {
        // datastore/nondurable identity
        visitor.visitInsn(Opcodes.ACONST_NULL);
        visitor.visitInsn(Opcodes.ARETURN);
        Label endLabel = new Label();
        visitor.visitLabel(endLabel);
        visitor.visitLocalVariable("this", getClassEnhancer().getClassDescriptor(), null, startLabel, endLabel, 0);
        visitor.visitLocalVariable(argNames[0], "Ljava/lang/Object;", null, startLabel, endLabel, 1);
        visitor.visitMaxs(1, 2);
    }
    visitor.visitEnd();
}
Also used : Label(org.datanucleus.enhancer.asm.Label) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) ClassMetaData(org.datanucleus.metadata.ClassMetaData)

Example 34 with Label

use of org.datanucleus.enhancer.asm.Label in project datanucleus-core by datanucleus.

the class PreSerialize method execute.

/**
 * Method to add the contents of the class method.
 */
public void execute() {
    visitor.visitCode();
    Label l0 = new Label();
    visitor.visitLabel(l0);
    visitor.visitVarInsn(Opcodes.ALOAD, 0);
    visitor.visitFieldInsn(Opcodes.GETFIELD, getClassEnhancer().getASMClassName(), getNamer().getStateManagerFieldName(), getNamer().getStateManagerDescriptor());
    Label l1 = new Label();
    visitor.visitJumpInsn(Opcodes.IFNULL, l1);
    visitor.visitVarInsn(Opcodes.ALOAD, 0);
    visitor.visitFieldInsn(Opcodes.GETFIELD, getClassEnhancer().getASMClassName(), getNamer().getStateManagerFieldName(), getNamer().getStateManagerDescriptor());
    visitor.visitVarInsn(Opcodes.ALOAD, 0);
    visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, getNamer().getStateManagerAsmClassName(), "preSerialize", "(" + getNamer().getPersistableDescriptor() + ")V");
    visitor.visitLabel(l1);
    visitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
    visitor.visitInsn(Opcodes.RETURN);
    Label l3 = new Label();
    visitor.visitLabel(l3);
    visitor.visitLocalVariable("this", getClassEnhancer().getClassDescriptor(), null, l0, l3, 0);
    visitor.visitMaxs(2, 1);
    visitor.visitEnd();
}
Also used : Label(org.datanucleus.enhancer.asm.Label)

Example 35 with Label

use of org.datanucleus.enhancer.asm.Label in project datanucleus-core by datanucleus.

the class ProvideField method execute.

/**
 * Method to add the contents of the class method.
 */
public void execute() {
    AbstractMemberMetaData[] fields = enhancer.getClassMetaData().getManagedMembers();
    String pcSuperclassName = enhancer.getClassMetaData().getPersistableSuperclass();
    visitor.visitCode();
    Label startLabel = new Label();
    visitor.visitLabel(startLabel);
    if (pcSuperclassName != null) {
        if (fields.length > 0) {
            visitor.visitVarInsn(Opcodes.ALOAD, 0);
            visitor.visitFieldInsn(Opcodes.GETFIELD, getClassEnhancer().getASMClassName(), getNamer().getStateManagerFieldName(), getNamer().getStateManagerDescriptor());
            Label l1 = new Label();
            visitor.visitJumpInsn(Opcodes.IFNONNULL, l1);
            visitor.visitTypeInsn(Opcodes.NEW, "java/lang/IllegalStateException");
            visitor.visitInsn(Opcodes.DUP);
            visitor.visitLdcInsn("state manager is null");
            visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/IllegalStateException", "<init>", "(Ljava/lang/String;)V");
            visitor.visitInsn(Opcodes.ATHROW);
            visitor.visitLabel(l1);
            visitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
            visitor.visitVarInsn(Opcodes.ILOAD, 1);
            visitor.visitFieldInsn(Opcodes.GETSTATIC, getClassEnhancer().getASMClassName(), getNamer().getInheritedFieldCountFieldName(), "I");
            visitor.visitInsn(Opcodes.ISUB);
            Label[] fieldOptions = new Label[fields.length];
            for (int i = 0; i < fields.length; i++) {
                fieldOptions[i] = new Label();
            }
            Label defaultLabel = new Label();
            Label endSwitchLabel = new Label();
            // switch:
            visitor.visitTableSwitchInsn(0, fields.length - 1, defaultLabel, fieldOptions);
            for (int i = 0; i < fields.length; i++) {
                visitor.visitLabel(fieldOptions[i]);
                visitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
                visitor.visitVarInsn(Opcodes.ALOAD, 0);
                visitor.visitFieldInsn(Opcodes.GETFIELD, getClassEnhancer().getASMClassName(), getNamer().getStateManagerFieldName(), getNamer().getStateManagerDescriptor());
                visitor.visitVarInsn(Opcodes.ALOAD, 0);
                visitor.visitVarInsn(Opcodes.ILOAD, 1);
                visitor.visitVarInsn(Opcodes.ALOAD, 0);
                if (fields[i] instanceof PropertyMetaData) {
                    // Persistent property so use dnGetXXX()
                    visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, getClassEnhancer().getASMClassName(), getNamer().getGetMethodPrefixMethodName() + fields[i].getName(), "()" + Type.getDescriptor(fields[i].getType()));
                } else {
                    // Persistent field so use xxx
                    visitor.visitFieldInsn(Opcodes.GETFIELD, getClassEnhancer().getASMClassName(), fields[i].getName(), Type.getDescriptor(fields[i].getType()));
                }
                visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, getNamer().getStateManagerAsmClassName(), "provided" + EnhanceUtils.getTypeNameForPersistableMethod(fields[i].getType()) + "Field", "(" + getNamer().getPersistableDescriptor() + "I" + EnhanceUtils.getTypeDescriptorForEnhanceMethod(fields[i].getType()) + ")V");
                visitor.visitJumpInsn(Opcodes.GOTO, endSwitchLabel);
            }
            // default:
            visitor.visitLabel(defaultLabel);
            visitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
            visitor.visitVarInsn(Opcodes.ALOAD, 0);
            visitor.visitVarInsn(Opcodes.ILOAD, 1);
            visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, pcSuperclassName.replace('.', '/'), getNamer().getProvideFieldMethodName(), "(I)V");
            // End of switch
            visitor.visitLabel(endSwitchLabel);
            visitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
            visitor.visitInsn(Opcodes.RETURN);
            Label endLabel = new Label();
            visitor.visitLabel(endLabel);
            visitor.visitLocalVariable("this", getClassEnhancer().getClassDescriptor(), null, startLabel, endLabel, 0);
            visitor.visitLocalVariable(argNames[0], "I", null, startLabel, endLabel, 1);
            visitor.visitMaxs(4, 2);
        } else {
            visitor.visitVarInsn(Opcodes.ALOAD, 0);
            visitor.visitVarInsn(Opcodes.ILOAD, 1);
            visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, pcSuperclassName.replace('.', '/'), getNamer().getProvideFieldMethodName(), "(I)V");
            visitor.visitInsn(Opcodes.RETURN);
            Label endLabel = new Label();
            visitor.visitLabel(endLabel);
            visitor.visitLocalVariable("this", getClassEnhancer().getClassDescriptor(), null, startLabel, endLabel, 0);
            visitor.visitLocalVariable(argNames[0], "I", null, startLabel, endLabel, 1);
            visitor.visitMaxs(2, 2);
        }
    } else {
        if (fields.length > 0) {
            visitor.visitVarInsn(Opcodes.ALOAD, 0);
            visitor.visitFieldInsn(Opcodes.GETFIELD, getClassEnhancer().getASMClassName(), getNamer().getStateManagerFieldName(), getNamer().getStateManagerDescriptor());
            Label l1 = new Label();
            visitor.visitJumpInsn(Opcodes.IFNONNULL, l1);
            visitor.visitTypeInsn(Opcodes.NEW, "java/lang/IllegalStateException");
            visitor.visitInsn(Opcodes.DUP);
            visitor.visitLdcInsn("state manager is null");
            visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/IllegalStateException", "<init>", "(" + EnhanceUtils.CD_String + ")V");
            visitor.visitInsn(Opcodes.ATHROW);
            visitor.visitLabel(l1);
            visitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
            visitor.visitVarInsn(Opcodes.ILOAD, 1);
            Label[] fieldOptions = new Label[fields.length];
            for (int i = 0; i < fields.length; i++) {
                fieldOptions[i] = new Label();
            }
            Label defaultLabel = new Label();
            Label endSwitchLabel = new Label();
            // switch:
            visitor.visitTableSwitchInsn(0, fields.length - 1, defaultLabel, fieldOptions);
            for (int i = 0; i < fields.length; i++) {
                visitor.visitLabel(fieldOptions[i]);
                visitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
                visitor.visitVarInsn(Opcodes.ALOAD, 0);
                visitor.visitFieldInsn(Opcodes.GETFIELD, getClassEnhancer().getASMClassName(), getNamer().getStateManagerFieldName(), getNamer().getStateManagerDescriptor());
                visitor.visitVarInsn(Opcodes.ALOAD, 0);
                visitor.visitVarInsn(Opcodes.ILOAD, 1);
                visitor.visitVarInsn(Opcodes.ALOAD, 0);
                if (fields[i] instanceof PropertyMetaData) {
                    // Persistent property so use dnGetXXX()
                    visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, getClassEnhancer().getASMClassName(), getNamer().getGetMethodPrefixMethodName() + fields[i].getName(), "()" + Type.getDescriptor(fields[i].getType()));
                } else {
                    // Persistent field so use xxx
                    visitor.visitFieldInsn(Opcodes.GETFIELD, getClassEnhancer().getASMClassName(), fields[i].getName(), Type.getDescriptor(fields[i].getType()));
                }
                visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, getNamer().getStateManagerAsmClassName(), "provided" + EnhanceUtils.getTypeNameForPersistableMethod(fields[i].getType()) + "Field", "(" + getNamer().getPersistableDescriptor() + "I" + EnhanceUtils.getTypeDescriptorForEnhanceMethod(fields[i].getType()) + ")V");
                visitor.visitJumpInsn(Opcodes.GOTO, endSwitchLabel);
            }
            // default:
            visitor.visitLabel(defaultLabel);
            visitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
            visitor.visitTypeInsn(Opcodes.NEW, "java/lang/IllegalArgumentException");
            visitor.visitInsn(Opcodes.DUP);
            visitor.visitTypeInsn(Opcodes.NEW, "java/lang/StringBuffer");
            visitor.visitInsn(Opcodes.DUP);
            visitor.visitLdcInsn("out of field index :");
            visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/StringBuffer", "<init>", "(Ljava/lang/String;)V");
            visitor.visitVarInsn(Opcodes.ILOAD, 1);
            visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuffer", "append", "(I)Ljava/lang/StringBuffer;");
            visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;");
            visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/IllegalArgumentException", "<init>", "(Ljava/lang/String;)V");
            visitor.visitInsn(Opcodes.ATHROW);
            // End of switch
            visitor.visitLabel(endSwitchLabel);
            visitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
            visitor.visitInsn(Opcodes.RETURN);
            Label l7 = new Label();
            visitor.visitLabel(l7);
            visitor.visitLocalVariable("this", getClassEnhancer().getClassDescriptor(), null, startLabel, l7, 0);
            visitor.visitLocalVariable(argNames[0], "I", null, startLabel, l7, 1);
            visitor.visitMaxs(5, 2);
        } else {
            visitor.visitInsn(Opcodes.RETURN);
            Label endLabel = new Label();
            visitor.visitLabel(endLabel);
            visitor.visitLocalVariable("this", getClassEnhancer().getClassDescriptor(), null, startLabel, endLabel, 0);
            visitor.visitLocalVariable(argNames[0], "I", null, startLabel, endLabel, 1);
            visitor.visitMaxs(0, 2);
        }
    }
    visitor.visitEnd();
}
Also used : Label(org.datanucleus.enhancer.asm.Label) PropertyMetaData(org.datanucleus.metadata.PropertyMetaData) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Aggregations

Label (org.datanucleus.enhancer.asm.Label)48 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)13 MethodVisitor (org.datanucleus.enhancer.asm.MethodVisitor)9 PropertyMetaData (org.datanucleus.metadata.PropertyMetaData)8 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)7 ClassMetaData (org.datanucleus.metadata.ClassMetaData)6 Date (java.util.Date)2 TimeZone (java.util.TimeZone)2 InterfaceMetaData (org.datanucleus.metadata.InterfaceMetaData)2 ClassWriter (org.datanucleus.enhancer.asm.ClassWriter)1 FieldVisitor (org.datanucleus.enhancer.asm.FieldVisitor)1