mirror of
https://github.com/apache/openjpa.git
synced 2025-03-06 08:29:08 +00:00
!32852 work on staticInitializer via ASM
sadly we cannot yet activate it as it uses LDC ops for classes which Serp does not understand as it is pre Java-1.4
This commit is contained in:
parent
92bb3b055a
commit
94d1874019
@ -597,11 +597,12 @@ public class PCEnhancer {
|
||||
if (_meta != null) {
|
||||
enhanceClass(pc);
|
||||
addFields(pc);
|
||||
//X TODO finish addStaticInitializer(classNodeTracker);
|
||||
AsmHelper.readIntoBCClass(pc, _pc);
|
||||
addStaticInitializer();
|
||||
|
||||
pc = AsmHelper.toClassNode(_pc);
|
||||
//X For now we cannot take the new version as it uses LDC for classes which Serp doesn't understand.
|
||||
//X So we can only enable it in a later step
|
||||
//X addStaticInitializer(pc);
|
||||
addStaticInitializer(); // removeme
|
||||
|
||||
addPCMethods(pc);
|
||||
|
||||
addAccessors();
|
||||
@ -857,7 +858,7 @@ public class PCEnhancer {
|
||||
LabelNode caseLabel = new LabelNode();
|
||||
switchNd.labels.add(caseLabel);
|
||||
instructions.add(caseLabel);
|
||||
instructions.add(new LdcInsnNode(_attrsToFields.get(fmd.getName())));
|
||||
instructions.add(AsmHelper.getLoadConstantInsn(_attrsToFields.get(fmd.getName())));
|
||||
instructions.add(new InsnNode(Opcodes.ARETURN));
|
||||
}
|
||||
|
||||
@ -876,7 +877,7 @@ public class PCEnhancer {
|
||||
instructions.add(caseLabel);
|
||||
switchNd.labels.add(caseLabel);
|
||||
switchNd.keys.add(propFmds.get(i));
|
||||
instructions.add(new LdcInsnNode(_attrsToFields.get(fmds[i].getName())));
|
||||
instructions.add(AsmHelper.getLoadConstantInsn(_attrsToFields.get(fmds[i].getName())));
|
||||
instructions.add(new InsnNode(Opcodes.ARETURN));
|
||||
}
|
||||
}
|
||||
@ -1219,7 +1220,7 @@ public class PCEnhancer {
|
||||
InsnList insns = new InsnList();
|
||||
|
||||
insns.add(new VarInsnNode(Opcodes.ALOAD, 0)); // this
|
||||
insns.add(new LdcInsnNode(fmd.getIndex()));
|
||||
insns.add(AsmHelper.getLoadConstantInsn(fmd.getIndex()));
|
||||
insns.add(new MethodInsnNode(Opcodes.INVOKESTATIC,
|
||||
Type.getInternalName(RedefinitionHelper.class),
|
||||
"accessingField",
|
||||
@ -1253,7 +1254,7 @@ public class PCEnhancer {
|
||||
InsnList insns = new InsnList();
|
||||
|
||||
insns.add(new VarInsnNode(Opcodes.ALOAD, 0)); // this
|
||||
insns.add(new LdcInsnNode(fmd.getIndex()));
|
||||
insns.add(AsmHelper.getLoadConstantInsn(fmd.getIndex()));
|
||||
|
||||
Class type = fmd.getDeclaredType();
|
||||
// we only have special signatures for primitives and Strings
|
||||
@ -1547,7 +1548,7 @@ public class PCEnhancer {
|
||||
// pcInheritedFieldCount field isn't initialized! so instead,
|
||||
// return <fields> + <superclass>.pcGetManagedFieldCount ()
|
||||
final InsnList instructions = getFieldCountMeth.instructions;
|
||||
instructions.add(new LdcInsnNode(_meta.getDeclaredFields().length));
|
||||
instructions.add(AsmHelper.getLoadConstantInsn(_meta.getDeclaredFields().length));
|
||||
if (_meta.getPCSuperclass() != null) {
|
||||
Class superClass = getType(_meta.getPCSuperclassMetaData());
|
||||
String superName = getCreateSubclass() ?
|
||||
@ -3284,6 +3285,7 @@ public class PCEnhancer {
|
||||
|
||||
@Deprecated
|
||||
private void addStaticInitializer() {
|
||||
AsmHelper.readIntoBCClass(pc, _pc);
|
||||
Code code = getOrCreateClassInitCode(true);
|
||||
if (_meta.getPCSuperclass() != null) {
|
||||
if (getCreateSubclass()) {
|
||||
@ -3368,6 +3370,7 @@ public class PCEnhancer {
|
||||
|
||||
code.vreturn();
|
||||
code.calculateMaxStack();
|
||||
pc = AsmHelper.toClassNode(_pc);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3380,91 +3383,97 @@ public class PCEnhancer {
|
||||
InsnList instructions = new InsnList();
|
||||
if (_meta.getPCSuperclass() != null) {
|
||||
if (getCreateSubclass()) {
|
||||
instructions.add(new LdcInsnNode(0));
|
||||
instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, classNode.name, INHERIT, Type.INT_TYPE.getDescriptor()));
|
||||
instructions.add(AsmHelper.getLoadConstantInsn(0));
|
||||
instructions.add(new FieldInsnNode(Opcodes.PUTSTATIC, classNode.name, INHERIT, Type.INT_TYPE.getDescriptor()));
|
||||
}
|
||||
else {
|
||||
// pcInheritedFieldCount = <superClass>.pcGetManagedFieldCount()
|
||||
instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, classNode.superName,
|
||||
PRE + "GetManagedFieldCount",
|
||||
Type.getMethodDescriptor(Type.INT_TYPE)));
|
||||
instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, classNode.name, INHERIT, Type.INT_TYPE.getDescriptor()));
|
||||
instructions.add(new FieldInsnNode(Opcodes.PUTSTATIC, classNode.name, INHERIT, Type.INT_TYPE.getDescriptor()));
|
||||
}
|
||||
|
||||
// pcPCSuperclass = <superClass>;
|
||||
// this intentionally calls getDescribedType() directly
|
||||
// instead of PCEnhancer.getType()
|
||||
instructions.add(new LdcInsnNode(Type.getType(_meta.getPCSuperclassMetaData().getDescribedType())));
|
||||
instructions.add(AsmHelper.getLoadConstantInsn(_meta.getPCSuperclassMetaData().getDescribedType()));
|
||||
instructions.add(new FieldInsnNode(Opcodes.PUTSTATIC, classNode.name, SUPER, Type.getDescriptor(Class.class)));
|
||||
}
|
||||
|
||||
// pcFieldNames = new String[] { "<name1>", "<name2>", ... };
|
||||
FieldMetaData[] fmds = _meta.getDeclaredFields();
|
||||
|
||||
/*
|
||||
|
||||
// pcFieldNames = new String[] { "<name1>", "<name2>", ... };
|
||||
FieldMetaData[] fmds = _meta.getDeclaredFields();
|
||||
code.constant().setValue(fmds.length);
|
||||
code.anewarray().setType(String.class);
|
||||
instructions.add(AsmHelper.getLoadConstantInsn(fmds.length));
|
||||
instructions.add(new TypeInsnNode(Opcodes.ANEWARRAY, Type.getInternalName(String.class)));
|
||||
for (int i = 0; i < fmds.length; i++) {
|
||||
code.dup();
|
||||
code.constant().setValue(i);
|
||||
code.constant().setValue(fmds[i].getName());
|
||||
code.aastore();
|
||||
instructions.add(new InsnNode(Opcodes.DUP));
|
||||
instructions.add(AsmHelper.getLoadConstantInsn(i));
|
||||
instructions.add(AsmHelper.getLoadConstantInsn(fmds[i].getName()));
|
||||
instructions.add(new InsnNode(Opcodes.AASTORE));
|
||||
}
|
||||
code.putstatic().setField(PRE + "FieldNames", String[].class);
|
||||
instructions.add(new FieldInsnNode(Opcodes.PUTSTATIC, classNode.name, PRE + "FieldNames", Type.getDescriptor(String[].class)));
|
||||
|
||||
// pcFieldTypes = new Class[] { <type1>.class, <type2>.class, ... };
|
||||
code.constant().setValue(fmds.length);
|
||||
code.anewarray().setType(Class.class);
|
||||
instructions.add(AsmHelper.getLoadConstantInsn(fmds.length));
|
||||
instructions.add(new TypeInsnNode(Opcodes.ANEWARRAY, Type.getInternalName(Class.class)));
|
||||
for (int i = 0; i < fmds.length; i++) {
|
||||
code.dup();
|
||||
code.constant().setValue(i);
|
||||
code.classconstant().setClass(fmds[i].getDeclaredType());
|
||||
code.aastore();
|
||||
instructions.add(new InsnNode(Opcodes.DUP));
|
||||
instructions.add(AsmHelper.getLoadConstantInsn(i));
|
||||
instructions.add(AsmHelper.getLoadConstantInsn(fmds[i].getDeclaredType()));
|
||||
instructions.add(new InsnNode(Opcodes.AASTORE));
|
||||
}
|
||||
code.putstatic().setField(PRE + "FieldTypes", Class[].class);
|
||||
instructions.add(new FieldInsnNode(Opcodes.PUTSTATIC, classNode.name, PRE + "FieldTypes", Type.getDescriptor(Class[].class)));
|
||||
|
||||
// pcFieldFlags = new byte[] { <flag1>, <flag2>, ... };
|
||||
code.constant().setValue(fmds.length);
|
||||
code.newarray().setType(byte.class);
|
||||
instructions.add(AsmHelper.getLoadConstantInsn(fmds.length));
|
||||
instructions.add(new IntInsnNode(Opcodes.NEWARRAY, Opcodes.T_BYTE));
|
||||
for (int i = 0; i < fmds.length; i++) {
|
||||
code.dup();
|
||||
code.constant().setValue(i);
|
||||
code.constant().setValue(getFieldFlag(fmds[i]));
|
||||
code.bastore();
|
||||
instructions.add(new InsnNode(Opcodes.DUP));
|
||||
instructions.add(AsmHelper.getLoadConstantInsn(i));
|
||||
instructions.add(AsmHelper.getLoadConstantInsn(getFieldFlag(fmds[i])));
|
||||
instructions.add(new InsnNode(Opcodes.BASTORE));
|
||||
}
|
||||
code.putstatic().setField(PRE + "FieldFlags", byte[].class);
|
||||
instructions.add(new FieldInsnNode(Opcodes.PUTSTATIC, classNode.name, PRE + "FieldFlags", Type.getDescriptor(byte[].class)));
|
||||
|
||||
/*
|
||||
// PCRegistry.register (cls,
|
||||
// pcFieldNames, pcFieldTypes, pcFieldFlags,
|
||||
// pcPCSuperclass, alias, new XXX ());
|
||||
code.classconstant().setClass(_meta.getDescribedType());
|
||||
code.getstatic().setField(PRE + "FieldNames", String[].class);
|
||||
code.getstatic().setField(PRE + "FieldTypes", Class[].class);
|
||||
code.getstatic().setField(PRE + "FieldFlags", byte[].class);
|
||||
code.getstatic().setField(SUPER, Class.class);
|
||||
instructions.add(AsmHelper.getLoadConstantInsn(_meta.getDescribedType()));
|
||||
instructions.add(new FieldInsnNode(Opcodes.GETSTATIC, classNode.name, PRE + "FieldNames", Type.getDescriptor(String[].class)));
|
||||
instructions.add(new FieldInsnNode(Opcodes.GETSTATIC, classNode.name, PRE + "FieldTypes", Type.getDescriptor(Class[].class)));
|
||||
instructions.add(new FieldInsnNode(Opcodes.GETSTATIC, classNode.name, PRE + "FieldFlags", Type.getDescriptor(byte[].class)));
|
||||
instructions.add(new FieldInsnNode(Opcodes.GETSTATIC, classNode.name, SUPER, Type.getDescriptor(Class.class)));
|
||||
|
||||
if (_meta.isMapped() || _meta.isAbstract())
|
||||
code.constant().setValue(_meta.getTypeAlias());
|
||||
else
|
||||
code.constant().setNull();
|
||||
|
||||
if (_pc.isAbstract())
|
||||
code.constant().setNull();
|
||||
if (_meta.isMapped() || _meta.isAbstract()) {
|
||||
instructions.add(AsmHelper.getLoadConstantInsn(_meta.getTypeAlias()));
|
||||
}
|
||||
else {
|
||||
code.anew().setType(_pc);
|
||||
code.dup();
|
||||
code.invokespecial().setMethod("<init>", void.class, null);
|
||||
instructions.add(new InsnNode(Opcodes.ACONST_NULL));
|
||||
}
|
||||
|
||||
code.invokestatic().setMethod(HELPERTYPE, "register", void.class,
|
||||
new Class[]{ Class.class, String[].class, Class[].class,
|
||||
byte[].class, Class.class, String.class, PCTYPE });
|
||||
if (_pc.isAbstract()) {
|
||||
instructions.add(new InsnNode(Opcodes.ACONST_NULL));
|
||||
}
|
||||
else {
|
||||
instructions.add(new TypeInsnNode(Opcodes.NEW, classNode.name));
|
||||
instructions.add(new InsnNode(Opcodes.DUP));
|
||||
instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL,
|
||||
classNode.name,
|
||||
"<init>",
|
||||
Type.getMethodDescriptor(Type.VOID_TYPE)));
|
||||
}
|
||||
|
||||
instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC,
|
||||
Type.getInternalName(HELPERTYPE),
|
||||
"register",
|
||||
Type.getMethodDescriptor(Type.VOID_TYPE,
|
||||
Type.getType(Class.class), Type.getType(String[].class),
|
||||
Type.getType(Class[].class), Type.getType(byte[].class),
|
||||
Type.getType(Class.class), Type.getType(String.class),
|
||||
Type.getType(PersistenceCapable.class))));
|
||||
|
||||
code.vreturn();
|
||||
code.calculateMaxStack();
|
||||
*/
|
||||
|
||||
// now add those instructions to the <clinit> method
|
||||
@ -3991,9 +4000,9 @@ public class PCEnhancer {
|
||||
}
|
||||
else {
|
||||
// add static initializer method if non exists
|
||||
MethodNode clinit = new MethodNode(Opcodes.ACC_STATIC | Opcodes.ACC_FINAL,
|
||||
MethodNode clinit = new MethodNode(Opcodes.ACC_STATIC,
|
||||
"<clinit>",
|
||||
Type.getMethodDescriptor(Type.VOID_TYPE),
|
||||
"()V",
|
||||
null, null);
|
||||
clinit.instructions.add(new InsnNode(Opcodes.RETURN));
|
||||
classNode.methods.add(clinit);
|
||||
@ -4483,8 +4492,8 @@ public class PCEnhancer {
|
||||
// Reflection.getXXX(this, Reflection.findField(...));
|
||||
|
||||
// Reflection.findField(declarer, fieldName, true);
|
||||
instructions.add(new LdcInsnNode(Type.getType(declarer)));
|
||||
instructions.add(new LdcInsnNode(fieldName));
|
||||
instructions.add(AsmHelper.getLoadConstantInsn(declarer));
|
||||
instructions.add(AsmHelper.getLoadConstantInsn(fieldName));
|
||||
instructions.add(new InsnNode(Opcodes.ICONST_1)); // true
|
||||
instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC,
|
||||
Type.getInternalName(Reflection.class),
|
||||
@ -4615,8 +4624,8 @@ public class PCEnhancer {
|
||||
if (getRedefine() || getCreateSubclass()) {
|
||||
// Reflection.set(this, Reflection.findField(...), value);
|
||||
// Reflection.findField(declarer, fieldName, true);
|
||||
instructions.add(new LdcInsnNode(Type.getType(declarer)));
|
||||
instructions.add(new LdcInsnNode(fieldName));
|
||||
instructions.add(AsmHelper.getLoadConstantInsn(declarer));
|
||||
instructions.add(AsmHelper.getLoadConstantInsn(fieldName));
|
||||
instructions.add(new InsnNode(Opcodes.ICONST_1)); // true
|
||||
instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC,
|
||||
Type.getInternalName(Reflection.class),
|
||||
@ -5214,7 +5223,7 @@ public class PCEnhancer {
|
||||
instructions.add(new InsnNode(Opcodes.ACONST_NULL));
|
||||
}
|
||||
else {
|
||||
instructions.add(new LdcInsnNode(value));
|
||||
instructions.add(AsmHelper.getLoadConstantInsn(value));
|
||||
}
|
||||
|
||||
// if redefining, then we must always reflect (or access the field
|
||||
@ -5428,7 +5437,7 @@ public class PCEnhancer {
|
||||
PRE + "GetEnhancementContractVersion",
|
||||
Type.getMethodDescriptor(Type.INT_TYPE),
|
||||
null, null);
|
||||
methodNode.instructions.add(new LdcInsnNode(ENHANCER_VERSION));
|
||||
methodNode.instructions.add(AsmHelper.getLoadConstantInsn(ENHANCER_VERSION));
|
||||
methodNode.instructions.add(new InsnNode(Opcodes.IRETURN));
|
||||
cnt.getClassNode().methods.add(methodNode);
|
||||
}
|
||||
|
@ -30,6 +30,9 @@ import org.apache.xbean.asm9.Type;
|
||||
import org.apache.xbean.asm9.tree.AbstractInsnNode;
|
||||
import org.apache.xbean.asm9.tree.ClassNode;
|
||||
import org.apache.xbean.asm9.tree.FieldInsnNode;
|
||||
import org.apache.xbean.asm9.tree.InsnNode;
|
||||
import org.apache.xbean.asm9.tree.IntInsnNode;
|
||||
import org.apache.xbean.asm9.tree.LdcInsnNode;
|
||||
import org.apache.xbean.asm9.tree.VarInsnNode;
|
||||
|
||||
import serp.bytecode.BCClass;
|
||||
@ -180,6 +183,77 @@ public final class AsmHelper {
|
||||
return Opcodes.ARETURN;
|
||||
}
|
||||
|
||||
public static AbstractInsnNode getLoadConstantInsn(Object val) {
|
||||
if (val == null) {
|
||||
return new InsnNode(Opcodes.ACONST_NULL);
|
||||
}
|
||||
if (val instanceof Integer) {
|
||||
final int iVal = ((Integer) val).intValue();
|
||||
switch (iVal) {
|
||||
case 0:
|
||||
return new InsnNode(Opcodes.ICONST_0);
|
||||
case 1:
|
||||
return new InsnNode(Opcodes.ICONST_1);
|
||||
case 2:
|
||||
return new InsnNode(Opcodes.ICONST_2);
|
||||
case 3:
|
||||
return new InsnNode(Opcodes.ICONST_3);
|
||||
case 4:
|
||||
return new InsnNode(Opcodes.ICONST_4);
|
||||
case 5:
|
||||
return new InsnNode(Opcodes.ICONST_5);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (iVal < 0 && iVal >= -128 || iVal >= 6 && iVal < 128) {
|
||||
// use bipush for small numbers
|
||||
return new IntInsnNode(Opcodes.BIPUSH, iVal);
|
||||
}
|
||||
else if (iVal < -128 && iVal >= -32768 || iVal >= 128 && iVal < 32768) {
|
||||
// use sipush for a bit bigger numbers
|
||||
return new IntInsnNode(Opcodes.SIPUSH, iVal);
|
||||
}
|
||||
}
|
||||
|
||||
if (val instanceof Class) {
|
||||
if (boolean.class.equals(val)) {
|
||||
return new FieldInsnNode(Opcodes.GETSTATIC, Type.getInternalName(Boolean.class), "TYPE",
|
||||
Type.getDescriptor(Class.class));
|
||||
}
|
||||
if (char.class.equals(val)) {
|
||||
return new FieldInsnNode(Opcodes.GETSTATIC, Type.getInternalName(Character.class), "TYPE",
|
||||
Type.getDescriptor(Class.class));
|
||||
}
|
||||
if (int.class.equals(val)) {
|
||||
return new FieldInsnNode(Opcodes.GETSTATIC, Type.getInternalName(Integer.class), "TYPE",
|
||||
Type.getDescriptor(Class.class));
|
||||
}
|
||||
if (long.class.equals(val)) {
|
||||
return new FieldInsnNode(Opcodes.GETSTATIC, Type.getInternalName(Long.class), "TYPE",
|
||||
Type.getDescriptor(Class.class));
|
||||
}
|
||||
if (byte.class.equals(val)) {
|
||||
return new FieldInsnNode(Opcodes.GETSTATIC, Type.getInternalName(Byte.class), "TYPE",
|
||||
Type.getDescriptor(Class.class));
|
||||
}
|
||||
if (short.class.equals(val)) {
|
||||
return new FieldInsnNode(Opcodes.GETSTATIC, Type.getInternalName(Short.class), "TYPE",
|
||||
Type.getDescriptor(Class.class));
|
||||
}
|
||||
if (float.class.equals(val)) {
|
||||
return new FieldInsnNode(Opcodes.GETSTATIC, Type.getInternalName(Float.class), "TYPE",
|
||||
Type.getDescriptor(Class.class));
|
||||
}
|
||||
if (double.class.equals(val)) {
|
||||
return new FieldInsnNode(Opcodes.GETSTATIC, Type.getInternalName(Double.class), "TYPE",
|
||||
Type.getDescriptor(Class.class));
|
||||
}
|
||||
return new LdcInsnNode(Type.getType((Class<?>) val));
|
||||
}
|
||||
|
||||
return new LdcInsnNode(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calclates the proper STORE instruction opcode for the given type
|
||||
*
|
||||
|
@ -69,6 +69,20 @@ public class SimpleEntity implements Serializable {
|
||||
public static final String NAMED_QUERY_WITH_POSITIONAL_PARAMS = "SelectWithPositionalParameter";
|
||||
public static final String NAMED_QUERY_WITH_NAMED_PARAMS = "SelectWithNamedParameter";
|
||||
|
||||
public static Integer dummy;
|
||||
|
||||
static {
|
||||
dummy = -32766;
|
||||
dummy = -32767;
|
||||
dummy = -32768;
|
||||
dummy = -32769;
|
||||
|
||||
dummy = 32765;
|
||||
dummy = 32766;
|
||||
dummy = 32767;
|
||||
dummy = 32768;
|
||||
}
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
@Column(name = "ID")
|
||||
|
Loading…
x
Reference in New Issue
Block a user