use of org.datanucleus.enhancer.asm.Label in project datanucleus-core by datanucleus.
the class CopyKeyFieldsToObjectId method execute.
/**
* Method to add the contents of the class method.
*/
public void execute() {
visitor.visitCode();
ClassMetaData cmd = enhancer.getClassMetaData();
if (cmd.getIdentityType() == IdentityType.APPLICATION) {
// application identity
if (!cmd.isInstantiable()) {
// Application identity but mapped-superclass with no PK defined, so just "return"
Label startLabel = new Label();
visitor.visitLabel(startLabel);
visitor.visitInsn(Opcodes.RETURN);
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(0, 2);
} else {
String objectIdClass = cmd.getObjectidClass();
String ACN_objectIdClass = objectIdClass.replace('.', '/');
if (IdentityUtils.isSingleFieldIdentityClass(objectIdClass)) {
// SingleFieldIdentity
Label startLabel = new Label();
visitor.visitLabel(startLabel);
visitor.visitTypeInsn(Opcodes.NEW, getNamer().getFatalInternalExceptionAsmClassName());
visitor.visitInsn(Opcodes.DUP);
visitor.visitLdcInsn("It's illegal to call dnCopyKeyFieldsToObjectId for a class with single-field identity.");
visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, 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(argNames[0], EnhanceUtils.CD_Object, null, startLabel, endLabel, 1);
visitor.visitMaxs(3, 2);
} else {
// User-provided app identity, and compound identity
// Put try-catch around the field setting (for reflection cases)
Label l0 = new Label();
Label l1 = new Label();
Label l2 = new Label();
visitor.visitTryCatchBlock(l0, l1, l2, "java/lang/Exception");
Label startLabel = new Label();
visitor.visitLabel(startLabel);
visitor.visitVarInsn(Opcodes.ALOAD, 1);
visitor.visitTypeInsn(Opcodes.INSTANCEOF, ACN_objectIdClass);
Label l4 = new Label();
visitor.visitJumpInsn(Opcodes.IFNE, l4);
visitor.visitTypeInsn(Opcodes.NEW, "java/lang/ClassCastException");
visitor.visitInsn(Opcodes.DUP);
visitor.visitLdcInsn("key class is not " + objectIdClass + " or null");
visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/ClassCastException", "<init>", "(Ljava/lang/String;)V");
visitor.visitInsn(Opcodes.ATHROW);
visitor.visitLabel(l4);
visitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
visitor.visitVarInsn(Opcodes.ALOAD, 1);
visitor.visitTypeInsn(Opcodes.CHECKCAST, ACN_objectIdClass);
visitor.visitVarInsn(Opcodes.ASTORE, 2);
visitor.visitLabel(l0);
int[] pkFieldNums = enhancer.getClassMetaData().getPKMemberPositions();
Label reflectionFieldStart = null;
for (int i = 0; i < pkFieldNums.length; i++) {
AbstractMemberMetaData fmd = enhancer.getClassMetaData().getMetaDataForManagedMemberAtAbsolutePosition(pkFieldNums[i]);
String fieldTypeDesc = Type.getDescriptor(fmd.getType());
AbstractClassMetaData acmd = enhancer.getMetaDataManager().getMetaDataForClass(fmd.getType(), enhancer.getClassLoaderResolver());
int pkFieldModifiers = ClassUtils.getModifiersForFieldOfClass(enhancer.getClassLoaderResolver(), objectIdClass, fmd.getName());
// Check if the PK field type is a PC (CompoundIdentity)
if (acmd != null && acmd.getIdentityType() != IdentityType.NONDURABLE) {
// CompoundIdentity, this field of the PK is a PC
if (fmd instanceof PropertyMetaData) {
// Persistent Property so use o.setXXX((XXX.Key)JDOHelper.getObjectId(dnGetXXX()))
visitor.visitVarInsn(Opcodes.ALOAD, 2);
visitor.visitVarInsn(Opcodes.ALOAD, 0);
visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, getClassEnhancer().getASMClassName(), getNamer().getGetMethodPrefixMethodName() + fmd.getName(), "()" + Type.getDescriptor(fmd.getType()));
// Note that we swap JDOHelper.getObjectId(obj) for ((Persistable)obj).dnGetObjectId())
visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, getNamer().getPersistableAsmClassName(), getNamer().getGetObjectIdMethodName(), "()Ljava/lang/Object;", true);
// visitor.visitMethodInsn(Opcodes.INVOKESTATIC, getNamer().getHelperAsmClassName(), "getObjectId", "(Ljava/lang/Object;)Ljava/lang/Object;");
visitor.visitTypeInsn(Opcodes.CHECKCAST, acmd.getObjectidClass().replace('.', '/'));
// TODO Use properties here
visitor.visitFieldInsn(Opcodes.PUTFIELD, ACN_objectIdClass, fmd.getName(), "L" + acmd.getObjectidClass().replace('.', '/') + ";");
} else if (Modifier.isPublic(pkFieldModifiers)) {
// Persistent Field public, so use o.xxx = (XXX.Key)JDOHelper.getObjectId(xxx);
visitor.visitVarInsn(Opcodes.ALOAD, 2);
visitor.visitVarInsn(Opcodes.ALOAD, 0);
visitor.visitFieldInsn(Opcodes.GETFIELD, getClassEnhancer().getASMClassName(), fmd.getName(), fieldTypeDesc);
// Note that we swap JDOHelper.getObjectId(obj) for ((Persistable)obj).dnGetObjectId())
visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, getNamer().getPersistableAsmClassName(), getNamer().getGetObjectIdMethodName(), "()Ljava/lang/Object;", true);
// visitor.visitMethodInsn(Opcodes.INVOKESTATIC, getNamer().getHelperAsmClassName(), "getObjectId", "(Ljava/lang/Object;)Ljava/lang/Object;");
visitor.visitTypeInsn(Opcodes.CHECKCAST, acmd.getObjectidClass().replace('.', '/'));
visitor.visitFieldInsn(Opcodes.PUTFIELD, ACN_objectIdClass, fmd.getName(), "L" + acmd.getObjectidClass().replace('.', '/') + ";");
} else {
// Persistent Field private/protected so use reflection
// TODO Use reflection here
visitor.visitVarInsn(Opcodes.ALOAD, 2);
visitor.visitVarInsn(Opcodes.ALOAD, 0);
visitor.visitFieldInsn(Opcodes.GETFIELD, getClassEnhancer().getASMClassName(), fmd.getName(), fieldTypeDesc);
// Note that we swap JDOHelper.getObjectId(obj) for ((Persistable)obj).dnGetObjectId())
visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, getNamer().getPersistableAsmClassName(), getNamer().getGetObjectIdMethodName(), "()Ljava/lang/Object;", true);
// visitor.visitMethodInsn(Opcodes.INVOKESTATIC, getNamer().getHelperAsmClassName(), "getObjectId", "(Ljava/lang/Object;)Ljava/lang/Object;");
visitor.visitTypeInsn(Opcodes.CHECKCAST, acmd.getObjectidClass().replace('.', '/'));
// TODO Use reflection here
visitor.visitFieldInsn(Opcodes.PUTFIELD, ACN_objectIdClass, fmd.getName(), "L" + acmd.getObjectidClass().replace('.', '/') + ";");
}
} else {
// Standard application-identity field
if (fmd instanceof PropertyMetaData) {
// Persistent Property so use o.setXXX(dnGetXXX())
visitor.visitVarInsn(Opcodes.ALOAD, 2);
visitor.visitVarInsn(Opcodes.ALOAD, 0);
visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, getClassEnhancer().getASMClassName(), getNamer().getGetMethodPrefixMethodName() + fmd.getName(), "()" + Type.getDescriptor(fmd.getType()));
visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, ACN_objectIdClass, ClassUtils.getJavaBeanSetterName(fmd.getName()), "(" + fieldTypeDesc + ")V");
} else if (Modifier.isPublic(pkFieldModifiers)) {
// Persistent Field public, so use o.xxx = xxx
visitor.visitVarInsn(Opcodes.ALOAD, 2);
visitor.visitVarInsn(Opcodes.ALOAD, 0);
visitor.visitFieldInsn(Opcodes.GETFIELD, getClassEnhancer().getASMClassName(), fmd.getName(), fieldTypeDesc);
visitor.visitFieldInsn(Opcodes.PUTFIELD, ACN_objectIdClass, fmd.getName(), fieldTypeDesc);
} else {
// Persistent Field private/protected so use reflection, generating
// "Field field = o.getClass().getDeclaredField("pmIDFloat");"
// "field.setAccessible(true);"
// "field.set(o, pmIDFloat);"
visitor.visitVarInsn(Opcodes.ALOAD, 2);
visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;");
visitor.visitLdcInsn(fmd.getName());
visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Class", "getDeclaredField", "(Ljava/lang/String;)Ljava/lang/reflect/Field;");
visitor.visitVarInsn(Opcodes.ASTORE, 3);
if (reflectionFieldStart == null) {
reflectionFieldStart = new Label();
visitor.visitLabel(reflectionFieldStart);
}
visitor.visitVarInsn(Opcodes.ALOAD, 3);
visitor.visitInsn(Opcodes.ICONST_1);
visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/reflect/Field", "setAccessible", "(Z)V");
visitor.visitVarInsn(Opcodes.ALOAD, 3);
visitor.visitVarInsn(Opcodes.ALOAD, 2);
visitor.visitVarInsn(Opcodes.ALOAD, 0);
visitor.visitFieldInsn(Opcodes.GETFIELD, getClassEnhancer().getASMClassName(), fmd.getName(), fieldTypeDesc);
if (fmd.getTypeName().equals("boolean")) {
visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/reflect/Field", "setBoolean", "(Ljava/lang/Object;Z)V");
} else if (fmd.getTypeName().equals("byte")) {
visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/reflect/Field", "setByte", "(Ljava/lang/Object;B)V");
} else if (fmd.getTypeName().equals("char")) {
visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/reflect/Field", "setChar", "(Ljava/lang/Object;C)V");
} else if (fmd.getTypeName().equals("double")) {
visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/reflect/Field", "setDouble", "(Ljava/lang/Object;D)V");
} else if (fmd.getTypeName().equals("float")) {
visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/reflect/Field", "setFloat", "(Ljava/lang/Object;F)V");
} else if (fmd.getTypeName().equals("int")) {
visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/reflect/Field", "setInt", "(Ljava/lang/Object;I)V");
} else if (fmd.getTypeName().equals("long")) {
visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/reflect/Field", "setLong", "(Ljava/lang/Object;J)V");
} else if (fmd.getTypeName().equals("short")) {
visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/reflect/Field", "setShort", "(Ljava/lang/Object;S)V");
} else {
visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/reflect/Field", "set", "(Ljava/lang/Object;Ljava/lang/Object;)V");
}
}
}
}
// catch of the try-catch
visitor.visitLabel(l1);
Label l16 = new Label();
visitor.visitJumpInsn(Opcodes.GOTO, l16);
visitor.visitLabel(l2);
visitor.visitFrame(Opcodes.F_FULL, 3, new Object[] { getClassEnhancer().getASMClassName(), "java/lang/Object", ACN_objectIdClass }, 1, new Object[] { "java/lang/Exception" });
visitor.visitVarInsn(Opcodes.ASTORE, 3);
visitor.visitLabel(l16);
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], EnhanceUtils.CD_Object, null, startLabel, endLabel, 1);
visitor.visitLocalVariable("o", "L" + ACN_objectIdClass + ";", null, l0, endLabel, 2);
if (reflectionFieldStart != null) {
visitor.visitLocalVariable("field", "Ljava/lang/reflect/Field;", null, reflectionFieldStart, l2, 3);
visitor.visitMaxs(3, 4);
} else {
visitor.visitMaxs(3, 3);
}
}
}
} else {
// datastore/nondurable identity
Label startLabel = new Label();
visitor.visitLabel(startLabel);
visitor.visitInsn(Opcodes.RETURN);
Label l1 = new Label();
visitor.visitLabel(l1);
visitor.visitLocalVariable("this", getClassEnhancer().getClassDescriptor(), null, startLabel, l1, 0);
visitor.visitLocalVariable(argNames[0], EnhanceUtils.CD_Object, null, startLabel, l1, 1);
visitor.visitMaxs(0, 2);
}
visitor.visitEnd();
}
use of org.datanucleus.enhancer.asm.Label in project datanucleus-core by datanucleus.
the class CopyKeyFieldsToObjectId2 method execute.
/**
* Method to add the contents of the class method.
*/
public void execute() {
visitor.visitCode();
ClassMetaData cmd = enhancer.getClassMetaData();
if (cmd.getIdentityType() == IdentityType.APPLICATION) {
// application identity
if (!cmd.isInstantiable()) {
// Application identity but mapped-superclass with no PK defined, so just "return"
Label startLabel = new Label();
visitor.visitLabel(startLabel);
visitor.visitInsn(Opcodes.RETURN);
Label endLabel = new Label();
visitor.visitLabel(endLabel);
visitor.visitLocalVariable("this", getClassEnhancer().getClassDescriptor(), null, startLabel, endLabel, 0);
visitor.visitLocalVariable(argNames[0], getNamer().getObjectIdFieldSupplierDescriptor(), null, startLabel, endLabel, 1);
visitor.visitLocalVariable(argNames[1], EnhanceUtils.CD_Object, null, startLabel, endLabel, 2);
visitor.visitMaxs(0, 3);
} else {
String objectIdClass = cmd.getObjectidClass();
String ACN_objectIdClass = objectIdClass.replace('.', '/');
if (IdentityUtils.isSingleFieldIdentityClass(objectIdClass)) {
// SingleFieldIdentity
Label startLabel = new Label();
visitor.visitLabel(startLabel);
visitor.visitTypeInsn(Opcodes.NEW, getNamer().getFatalInternalExceptionAsmClassName());
visitor.visitInsn(Opcodes.DUP);
visitor.visitLdcInsn("It's illegal to call dnCopyKeyFieldsToObjectId for a class with single-field identity.");
visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, 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(argNames[0], EnhanceUtils.CD_Object, null, startLabel, endLabel, 1);
visitor.visitLocalVariable("paramObject", "Ljava/lang/Object;", null, startLabel, endLabel, 2);
visitor.visitMaxs(3, 3);
} else {
// User-provided app identity, and compound identity
Label l0 = new Label();
Label l1 = new Label();
Label l2 = new Label();
visitor.visitTryCatchBlock(l0, l1, l2, "java/lang/Exception");
Label startLabel = new Label();
visitor.visitLabel(startLabel);
visitor.visitVarInsn(Opcodes.ALOAD, 1);
Label l4 = new Label();
visitor.visitJumpInsn(Opcodes.IFNONNULL, l4);
visitor.visitTypeInsn(Opcodes.NEW, "java/lang/IllegalArgumentException");
visitor.visitInsn(Opcodes.DUP);
visitor.visitLdcInsn("ObjectIdFieldSupplier is null");
visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/IllegalArgumentException", "<init>", "(Ljava/lang/String;)V");
visitor.visitInsn(Opcodes.ATHROW);
visitor.visitLabel(l4);
visitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
visitor.visitVarInsn(Opcodes.ALOAD, 2);
visitor.visitTypeInsn(Opcodes.INSTANCEOF, ACN_objectIdClass);
Label l5 = new Label();
visitor.visitJumpInsn(Opcodes.IFNE, l5);
visitor.visitTypeInsn(Opcodes.NEW, "java/lang/ClassCastException");
visitor.visitInsn(Opcodes.DUP);
visitor.visitLdcInsn("oid is not instanceof " + objectIdClass);
visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/ClassCastException", "<init>", "(Ljava/lang/String;)V");
visitor.visitInsn(Opcodes.ATHROW);
visitor.visitLabel(l5);
visitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
visitor.visitVarInsn(Opcodes.ALOAD, 2);
visitor.visitTypeInsn(Opcodes.CHECKCAST, ACN_objectIdClass);
visitor.visitVarInsn(Opcodes.ASTORE, 3);
visitor.visitLabel(l0);
// Copy the PK members using the appropriate method for each field/property
int[] pkFieldNums = enhancer.getClassMetaData().getPKMemberPositions();
Label reflectionFieldStart = null;
for (int i = 0; i < pkFieldNums.length; i++) {
AbstractMemberMetaData fmd = enhancer.getClassMetaData().getMetaDataForManagedMemberAtAbsolutePosition(pkFieldNums[i]);
String fieldTypeDesc = Type.getDescriptor(fmd.getType());
String typeMethodName = EnhanceUtils.getTypeNameForPersistableMethod(fmd.getType());
int pkFieldModifiers = ClassUtils.getModifiersForFieldOfClass(enhancer.getClassLoaderResolver(), objectIdClass, fmd.getName());
// Check if the PK field type is a PC (CompoundIdentity)
AbstractClassMetaData acmd = enhancer.getMetaDataManager().getMetaDataForClass(fmd.getType(), enhancer.getClassLoaderResolver());
if (acmd != null && acmd.getIdentityType() != IdentityType.NONDURABLE) {
// CompoundIdentity, this field of the PK is a PC
visitor.visitVarInsn(Opcodes.ALOAD, 3);
visitor.visitVarInsn(Opcodes.ALOAD, 1);
EnhanceUtils.addBIPUSHToMethod(visitor, fmd.getFieldId());
visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, getNamer().getObjectIdFieldSupplierAsmClassName(), "fetch" + typeMethodName + "Field", "(I)" + EnhanceUtils.getTypeDescriptorForEnhanceMethod(fmd.getType()));
if (typeMethodName.equals("Object")) {
visitor.visitTypeInsn(Opcodes.CHECKCAST, fmd.getTypeName().replace('.', '/'));
}
// Note that we swap JDOHelper.getObjectId(obj) for ((Persistable)obj).dnGetObjectId())
visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, getNamer().getPersistableAsmClassName(), getNamer().getGetObjectIdMethodName(), "()Ljava/lang/Object;", true);
// visitor.visitMethodInsn(Opcodes.INVOKESTATIC, getNamer().getHelperAsmClassName(), "getObjectId", "(Ljava/lang/Object;)Ljava/lang/Object;");
visitor.visitTypeInsn(Opcodes.CHECKCAST, acmd.getObjectidClass().replace('.', '/'));
// TODO Cater for property, and private field cases
visitor.visitFieldInsn(Opcodes.PUTFIELD, ACN_objectIdClass, fmd.getName(), "L" + acmd.getObjectidClass().replace('.', '/') + ";");
} else {
// Standard application-identity
if (fmd instanceof PropertyMetaData) {
// Field in PK is property, hence use setXXX in PK
visitor.visitVarInsn(Opcodes.ALOAD, 3);
visitor.visitVarInsn(Opcodes.ALOAD, 1);
EnhanceUtils.addBIPUSHToMethod(visitor, fmd.getFieldId());
visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, getNamer().getObjectIdFieldSupplierAsmClassName(), "fetch" + typeMethodName + "Field", "(I)" + EnhanceUtils.getTypeDescriptorForEnhanceMethod(fmd.getType()));
if (typeMethodName.equals("Object")) {
visitor.visitTypeInsn(Opcodes.CHECKCAST, fmd.getTypeName().replace('.', '/'));
}
visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, ACN_objectIdClass, ClassUtils.getJavaBeanSetterName(fmd.getName()), "(" + fieldTypeDesc + ")V");
} else if (Modifier.isPublic(pkFieldModifiers)) {
// Field in PK is public so update directly
visitor.visitVarInsn(Opcodes.ALOAD, 3);
visitor.visitVarInsn(Opcodes.ALOAD, 1);
EnhanceUtils.addBIPUSHToMethod(visitor, fmd.getFieldId());
visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, getNamer().getObjectIdFieldSupplierAsmClassName(), "fetch" + typeMethodName + "Field", "(I)" + EnhanceUtils.getTypeDescriptorForEnhanceMethod(fmd.getType()));
if (typeMethodName.equals("Object")) {
visitor.visitTypeInsn(Opcodes.CHECKCAST, fmd.getTypeName().replace('.', '/'));
}
visitor.visitFieldInsn(Opcodes.PUTFIELD, ACN_objectIdClass, fmd.getName(), fieldTypeDesc);
} else {
// Field in PK is protected/private so use reflection, generating
// "Field field = o.getClass().getDeclaredField("pmIDFloat");"
// "field.setAccessible(true);"
// "field.set(o, fs.fetchObjectField(1));"
visitor.visitVarInsn(Opcodes.ALOAD, 3);
visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;");
visitor.visitLdcInsn(fmd.getName());
visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Class", "getDeclaredField", "(Ljava/lang/String;)Ljava/lang/reflect/Field;");
visitor.visitVarInsn(Opcodes.ASTORE, 4);
if (reflectionFieldStart == null) {
reflectionFieldStart = new Label();
visitor.visitLabel(reflectionFieldStart);
}
visitor.visitVarInsn(Opcodes.ALOAD, 4);
visitor.visitInsn(Opcodes.ICONST_1);
visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/reflect/Field", "setAccessible", "(Z)V");
visitor.visitVarInsn(Opcodes.ALOAD, 4);
visitor.visitVarInsn(Opcodes.ALOAD, 3);
visitor.visitVarInsn(Opcodes.ALOAD, 1);
EnhanceUtils.addBIPUSHToMethod(visitor, fmd.getFieldId());
if (fmd.getTypeName().equals("boolean")) {
visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, getNamer().getObjectIdFieldSupplierAsmClassName(), "fetchBooleanField", "(I)Z");
visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/reflect/Field", "setBoolean", "(Ljava/lang/Object;Z)V");
} else if (fmd.getTypeName().equals("byte")) {
visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, getNamer().getObjectIdFieldSupplierAsmClassName(), "fetchByteField", "(I)B");
visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/reflect/Field", "setByte", "(Ljava/lang/Object;B)V");
} else if (fmd.getTypeName().equals("char")) {
visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, getNamer().getObjectIdFieldSupplierAsmClassName(), "fetchCharField", "(I)C");
visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/reflect/Field", "setChar", "(Ljava/lang/Object;C)V");
} else if (fmd.getTypeName().equals("double")) {
visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, getNamer().getObjectIdFieldSupplierAsmClassName(), "fetchDoubleField", "(I)D");
visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/reflect/Field", "setDouble", "(Ljava/lang/Object;D)V");
} else if (fmd.getTypeName().equals("float")) {
visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, getNamer().getObjectIdFieldSupplierAsmClassName(), "fetchFloatField", "(I)F");
visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/reflect/Field", "setFloat", "(Ljava/lang/Object;F)V");
} else if (fmd.getTypeName().equals("int")) {
visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, getNamer().getObjectIdFieldSupplierAsmClassName(), "fetchIntField", "(I)I");
visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/reflect/Field", "setInt", "(Ljava/lang/Object;I)V");
} else if (fmd.getTypeName().equals("long")) {
visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, getNamer().getObjectIdFieldSupplierAsmClassName(), "fetchLongField", "(I)J");
visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/reflect/Field", "setLong", "(Ljava/lang/Object;J)V");
} else if (fmd.getTypeName().equals("short")) {
visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, getNamer().getObjectIdFieldSupplierAsmClassName(), "fetchShortField", "(I)S");
visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/reflect/Field", "setShort", "(Ljava/lang/Object;S)V");
} else {
visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, getNamer().getObjectIdFieldSupplierAsmClassName(), "fetchObjectField", "(I)Ljava/lang/Object;");
visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/reflect/Field", "set", "(Ljava/lang/Object;Ljava/lang/Object;)V");
}
}
}
}
visitor.visitLabel(l1);
Label l20 = new Label();
visitor.visitJumpInsn(Opcodes.GOTO, l20);
visitor.visitLabel(l2);
visitor.visitFrame(Opcodes.F_FULL, 4, new Object[] { getClassEnhancer().getASMClassName(), getClassEnhancer().getNamer().getObjectIdFieldSupplierAsmClassName(), "java/lang/Object", ACN_objectIdClass }, 1, new Object[] { "java/lang/Exception" });
visitor.visitVarInsn(Opcodes.ASTORE, 4);
visitor.visitLabel(l20);
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], getNamer().getObjectIdFieldSupplierDescriptor(), null, startLabel, endLabel, 1);
visitor.visitLocalVariable(argNames[1], EnhanceUtils.CD_Object, null, startLabel, endLabel, 2);
visitor.visitLocalVariable("o", "L" + ACN_objectIdClass + ";", null, l0, endLabel, 3);
if (reflectionFieldStart != null) {
visitor.visitLocalVariable("field", "Ljava/lang/reflect/Field;", null, reflectionFieldStart, l2, 4);
visitor.visitMaxs(4, 5);
} else {
visitor.visitMaxs(3, 4);
}
}
}
} else {
// datastore/nondurable identity
Label startLabel = new Label();
visitor.visitLabel(startLabel);
visitor.visitInsn(Opcodes.RETURN);
Label endLabel = new Label();
visitor.visitLabel(endLabel);
visitor.visitLocalVariable("this", getClassEnhancer().getClassDescriptor(), null, startLabel, endLabel, 0);
visitor.visitLocalVariable(argNames[0], "L" + getNamer().getObjectIdFieldSupplierAsmClassName() + ";", null, startLabel, endLabel, 1);
visitor.visitLocalVariable(argNames[1], EnhanceUtils.CD_Object, null, startLabel, endLabel, 2);
visitor.visitMaxs(0, 3);
}
visitor.visitEnd();
}
use of org.datanucleus.enhancer.asm.Label in project datanucleus-core by datanucleus.
the class GetExecutionContext 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(), // TODO Put this in namer
"getExecutionContext", "(" + getNamer().getPersistableDescriptor() + ")" + getNamer().getExecutionContextDescriptor());
Label l2 = new Label();
visitor.visitJumpInsn(Opcodes.GOTO, l2);
visitor.visitLabel(l1);
visitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
visitor.visitInsn(Opcodes.ACONST_NULL);
visitor.visitLabel(l2);
visitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { getClassEnhancer().getNamer().getExecutionContextAsmClassName() });
visitor.visitInsn(Opcodes.ARETURN);
Label l3 = new Label();
visitor.visitLabel(l3);
visitor.visitLocalVariable("this", getClassEnhancer().getClassDescriptor(), null, l0, l3, 0);
visitor.visitMaxs(2, 1);
visitor.visitEnd();
}
use of org.datanucleus.enhancer.asm.Label in project datanucleus-core by datanucleus.
the class PrimaryKeyGenerator method addStringConstructor.
/**
* Method to add a constructor taking in a String.
* @param cw The ClassWriter to use
*/
protected void addStringConstructor(ClassWriter cw) {
if (DataNucleusEnhancer.LOGGER.isDebugEnabled()) {
DataNucleusEnhancer.LOGGER.debug(Localiser.msg("005020", pkClassName + "(String str)"));
}
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "(Ljava/lang/String;)V", null, null);
mv.visitCode();
int[] pkPositions = cmd.getPKMemberPositions();
Label[] fieldLabels = new Label[pkPositions.length];
Label startLabel = new Label();
mv.visitLabel(startLabel);
// Invoke default constructor of superclass (Object)
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
// StringTokenizer tokeniser = new StringTokenizer(str, {stringSeparator});
mv.visitTypeInsn(Opcodes.NEW, "java/util/StringTokenizer");
mv.visitInsn(Opcodes.DUP);
mv.visitVarInsn(Opcodes.ALOAD, 1);
mv.visitLdcInsn(stringSeparator);
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/StringTokenizer", "<init>", "(Ljava/lang/String;Ljava/lang/String;)V");
mv.visitVarInsn(Opcodes.ASTORE, 2);
Label l5 = new Label();
mv.visitLabel(l5);
// Get the next token and set the respective field from it
int astorePosition = 2;
for (int i = 0; i < pkPositions.length; i++) {
AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtRelativePosition(pkPositions[i]);
String typeName_ASM = mmd.getTypeName().replace('.', '/');
astorePosition++;
// String tokenX = tokeniser.nextToken();
mv.visitVarInsn(Opcodes.ALOAD, 2);
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/StringTokenizer", "nextToken", "()Ljava/lang/String;");
mv.visitVarInsn(Opcodes.ASTORE, astorePosition);
fieldLabels[i] = new Label();
mv.visitLabel(fieldLabels[i]);
mv.visitVarInsn(Opcodes.ALOAD, 0);
if (mmd.getType() == long.class || mmd.getType() == int.class || mmd.getType() == short.class) {
// Uses the following pattern (e.g for Integer)
// fieldX = Integer.valueOf(tokenX).intValue();
String type_desc = EnhanceUtils.getTypeDescriptorForType(mmd.getTypeName());
String wrapperClassName_ASM = "java/lang/Long";
String wrapperConverterMethod = "longValue";
if (mmd.getType() == int.class) {
wrapperClassName_ASM = "java/lang/Integer";
wrapperConverterMethod = "intValue";
} else if (mmd.getType() == short.class) {
wrapperClassName_ASM = "java/lang/Short";
wrapperConverterMethod = "shortValue";
}
mv.visitVarInsn(Opcodes.ALOAD, astorePosition);
mv.visitMethodInsn(Opcodes.INVOKESTATIC, wrapperClassName_ASM, "valueOf", "(Ljava/lang/String;)L" + wrapperClassName_ASM + ";");
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, wrapperClassName_ASM, wrapperConverterMethod, "()" + type_desc);
mv.visitFieldInsn(Opcodes.PUTFIELD, className_ASM, mmd.getName(), type_desc);
} else if (mmd.getType() == char.class) {
mv.visitVarInsn(Opcodes.ALOAD, astorePosition);
mv.visitInsn(Opcodes.ICONST_0);
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "charAt", "(I)C");
mv.visitFieldInsn(Opcodes.PUTFIELD, className_ASM, "field1", "C");
} else if (mmd.getType() == String.class) {
mv.visitVarInsn(Opcodes.ALOAD, astorePosition);
mv.visitFieldInsn(Opcodes.PUTFIELD, className_ASM, mmd.getName(), EnhanceUtils.getTypeDescriptorForType(mmd.getTypeName()));
} else if (mmd.getType() == Long.class || mmd.getType() == Integer.class || mmd.getType() == Short.class || mmd.getType() == BigInteger.class) {
// Uses the following pattern (e.g for Long)
// fieldX = Long.valueOf(tokenX);
mv.visitVarInsn(Opcodes.ALOAD, astorePosition);
mv.visitMethodInsn(Opcodes.INVOKESTATIC, typeName_ASM, "valueOf", "(Ljava/lang/String;)L" + typeName_ASM + ";");
mv.visitFieldInsn(Opcodes.PUTFIELD, className_ASM, mmd.getName(), "L" + typeName_ASM + ";");
} else if (mmd.getType() == Currency.class) {
// "fieldX = TypeX.newInstance(tokenX)"
mv.visitVarInsn(Opcodes.ALOAD, astorePosition);
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/util/Currency", "getInstance", "(Ljava/lang/String;)Ljava/util/Currency;");
mv.visitFieldInsn(Opcodes.PUTFIELD, className_ASM, mmd.getName(), "Ljava/util/Currency;");
} else if (mmd.getType() == TimeZone.class) {
// "fieldX = TimeZone.getTimeZone(tokenX)"
mv.visitVarInsn(Opcodes.ALOAD, astorePosition);
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/util/TimeZone", "getTimeZone", "(Ljava/lang/String;)Ljava/util/TimeZone;");
mv.visitFieldInsn(Opcodes.PUTFIELD, className_ASM, mmd.getName(), "Ljava/util/TimeZone;");
} else if (mmd.getType() == UUID.class) {
// "fieldX = UUID.fromString(tokenX)"
mv.visitVarInsn(Opcodes.ALOAD, astorePosition);
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/util/UUID", "fromString", "(Ljava/lang/String;)Ljava/util/UUID;");
mv.visitFieldInsn(Opcodes.PUTFIELD, className_ASM, mmd.getName(), "Ljava/util/UUID;");
} else if (Date.class.isAssignableFrom(mmd.getType())) {
// fieldX = new Date(new Long(tokenX).longValue());
mv.visitTypeInsn(Opcodes.NEW, typeName_ASM);
mv.visitInsn(Opcodes.DUP);
mv.visitTypeInsn(Opcodes.NEW, "java/lang/Long");
mv.visitInsn(Opcodes.DUP);
mv.visitVarInsn(Opcodes.ALOAD, astorePosition);
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Long", "<init>", "(Ljava/lang/String;)V");
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J");
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, typeName_ASM, "<init>", "(J)V");
mv.visitFieldInsn(Opcodes.PUTFIELD, className_ASM, mmd.getName(), EnhanceUtils.getTypeDescriptorForType(mmd.getTypeName()));
} else if (Calendar.class.isAssignableFrom(mmd.getType())) {
// fieldX = Calendar.getInstance();
// fieldX.setTimeInMillis(Long.valueOf(tokenX).longValue());
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/util/Calendar", "getInstance", "()Ljava/util/Calendar;");
mv.visitFieldInsn(Opcodes.PUTFIELD, className_ASM, mmd.getName(), "Ljava/util/Calendar;");
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitFieldInsn(Opcodes.GETFIELD, className_ASM, mmd.getName(), "Ljava/util/Calendar;");
mv.visitVarInsn(Opcodes.ALOAD, astorePosition);
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf", "(Ljava/lang/String;)Ljava/lang/Long;");
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J");
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/Calendar", "setTimeInMillis", "(J)V");
} else {
// "fieldX = new TypeX(tokenX)"
// TODO If this is compound identity and the related object uses SingleFieldIdentity then
// we need to use a different constructor with this value
String fieldTypeName = getTypeNameForField(mmd);
String fieldTypeName_ASM = fieldTypeName.replace('.', '/');
mv.visitTypeInsn(Opcodes.NEW, fieldTypeName_ASM);
mv.visitInsn(Opcodes.DUP);
mv.visitVarInsn(Opcodes.ALOAD, astorePosition);
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, fieldTypeName_ASM, "<init>", "(Ljava/lang/String;)V");
mv.visitFieldInsn(Opcodes.PUTFIELD, className_ASM, mmd.getName(), EnhanceUtils.getTypeDescriptorForType(fieldTypeName));
}
}
mv.visitInsn(Opcodes.RETURN);
Label endLabel = new Label();
mv.visitLabel(endLabel);
int variableNum = 0;
mv.visitLocalVariable("this", className_DescName, null, startLabel, endLabel, variableNum++);
mv.visitLocalVariable("str", "Ljava/lang/String;", null, startLabel, endLabel, variableNum++);
mv.visitLocalVariable("tokeniser", "Ljava/util/StringTokenizer;", null, l5, endLabel, variableNum++);
for (int i = 0; i < pkPositions.length; i++) {
mv.visitLocalVariable("token" + i, "Ljava/lang/String;", null, fieldLabels[i], endLabel, variableNum++);
}
mv.visitMaxs(6, variableNum);
mv.visitEnd();
}
use of org.datanucleus.enhancer.asm.Label in project datanucleus-core by datanucleus.
the class PrimaryKeyGenerator method addDefaultConstructor.
/**
* Method to add an empty default constructor.
* @param cw The ClassWriter to use
*/
protected void addDefaultConstructor(ClassWriter cw) {
if (DataNucleusEnhancer.LOGGER.isDebugEnabled()) {
DataNucleusEnhancer.LOGGER.debug(Localiser.msg("005020", pkClassName + "()"));
}
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
mv.visitCode();
Label startLabel = new Label();
mv.visitLabel(startLabel);
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
mv.visitInsn(Opcodes.RETURN);
Label endLabel = new Label();
mv.visitLabel(endLabel);
mv.visitLocalVariable("this", className_DescName, null, startLabel, endLabel, 0);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
Aggregations