/** * Generate bytecodes for runtime class * * @return byte array containing bytecodes for runtime class * @throws Exception */ public byte[] genBytecode() throws Exception { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); FieldVisitor fv = null; MethodVisitor mv = null; ImplHelper.FieldDesc[] fieldDesc = ImplHelper.getFieldDesc(clazz); int isVariableLengthLayout = 0; final boolean itf = false; String superImpl = "java/lang/Object"; if (null == fieldDesc) { createBody = false; /* find layout superType */ for (Class<?> c : clazz.getInterfaces()) { if (Layout.class.isAssignableFrom(c)) { superImpl = ImplHelper.getImplClassName(c); } } } if (createBody) { eaCW.visit( 52, ACC_SUPER, implClassName + "$EffectiveAddressImpl", null, "java/lang/Object", new String[] {interfaceClassName + "$EffectiveAddress"}); eaCW.visitInnerClass( interfaceClassName + "$EffectiveAddress", interfaceClassName, "EffectiveAddress", ACC_PUBLIC + ACC_STATIC + ACC_ABSTRACT + ACC_INTERFACE); eaCW.visitInnerClass( implClassName + "$EffectiveAddressImpl", implClassName, "EffectiveAddressImpl", 0); { fv = eaCW.visitField( ACC_FINAL + ACC_SYNTHETIC, "this$0", "L" + implClassName + ";", null, null); fv.visitEnd(); } { eaMV = eaCW.visitMethod(0, "<init>", "(L" + implClassName + ";)V", null, null); eaMV.visitCode(); eaMV.visitVarInsn(ALOAD, 0); eaMV.visitVarInsn(ALOAD, 1); eaMV.visitFieldInsn( PUTFIELD, implClassName + "$EffectiveAddressImpl", "this$0", "L" + implClassName + ";"); eaMV.visitVarInsn(ALOAD, 0); eaMV.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false); eaMV.visitInsn(RETURN); eaMV.visitMaxs(2, 2); eaMV.visitEnd(); } } cw.visit( V1_8, ACC_PUBLIC + ACC_SUPER, implClassName, null, superImpl, new String[] {interfaceClassName}); if (createBody) { cw.visitInnerClass( implClassName + "$EffectiveAddressImpl", implClassName, "EffectiveAddressImpl", 0); } { mv = cw.visitMethod(0, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, superImpl, "<init>", "()V", false); mv.visitInsn(RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); } if (!createBody) { { fv = cw.visitField( ACC_PRIVATE + ACC_FINAL + ACC_STATIC, "unsafe", "Lsun/misc/Unsafe;", null, null); fv.visitEnd(); } cw.visitEnd(); return cw.toByteArray(); } for (int i = 0; i < fieldDesc.length; i++) { startWayPointCounter = wayPointCounter; if (!ImplHelper.isPointerType(fieldDesc[i].rawType)) { if (ImplHelper.isTypePrimitive(fieldDesc[i].sig)) { // getter mv = cw.visitMethod(ACC_PUBLIC, fieldDesc[i].name, "()" + fieldDesc[i].sig, null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, implClassName, "location", "Lcom/ibm/layout/Location;"); mv.visitMethodInsn(INVOKEVIRTUAL, "com/ibm/layout/Location", "getData", "()[B", itf); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, implClassName, "location", "Lcom/ibm/layout/Location;"); mv.visitMethodInsn(INVOKEVIRTUAL, "com/ibm/layout/Location", "getOffset", "()J", itf); if (wayPointCounter > 0) { mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn( INVOKESPECIAL, implClassName, "waypoint" + (wayPointCounter - 1), "()J", false); mv.visitInsn(LADD); } mv.visitLdcInsn(fieldDesc[i].offset); mv.visitInsn(LADD); mv.visitMethodInsn( INVOKESTATIC, "com/ibm/layout/gen/UnsafeImplHelper", "load" + fieldDesc[i].endian + ImplHelper.fieldSig2MethodType(fieldDesc[i].sig), "(Ljava/lang/Object;J)" + fieldDesc[i].sig, itf); if (fieldDesc[i].sig == "D") { mv.visitInsn(DRETURN); } else if (fieldDesc[i].sig == "J") { mv.visitInsn(LRETURN); } else if (fieldDesc[i].sig == "F") { mv.visitInsn(FRETURN); } else { mv.visitInsn(IRETURN); } mv.visitMaxs(5, 1); mv.visitEnd(); // setter mv = cw.visitMethod( ACC_PUBLIC, fieldDesc[i].name, "(" + fieldDesc[i].sig + ")V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, implClassName, "location", "Lcom/ibm/layout/Location;"); mv.visitMethodInsn(INVOKEVIRTUAL, "com/ibm/layout/Location", "getData", "()[B", itf); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, implClassName, "location", "Lcom/ibm/layout/Location;"); mv.visitMethodInsn(INVOKEVIRTUAL, "com/ibm/layout/Location", "getOffset", "()J", itf); mv.visitLdcInsn(fieldDesc[i].offset); if (wayPointCounter > 0) { mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn( INVOKESPECIAL, implClassName, "waypoint" + (wayPointCounter - 1), "()J", false); mv.visitInsn(LADD); } mv.visitInsn(LADD); if (fieldDesc[i].sig == "D") { mv.visitVarInsn(DLOAD, 1); } else if (fieldDesc[i].sig == "J") { mv.visitVarInsn(LLOAD, 1); } else if (fieldDesc[i].sig == "F") { mv.visitVarInsn(FLOAD, 1); } else { mv.visitVarInsn(ILOAD, 1); } mv.visitMethodInsn( INVOKESTATIC, "com/ibm/layout/gen/UnsafeImplHelper", "store" + fieldDesc[i].endian + ImplHelper.fieldSig2MethodType(fieldDesc[i].sig), "(Ljava/lang/Object;J" + fieldDesc[i].sig + ")V", itf); mv.visitInsn(RETURN); mv.visitMaxs(5, 2); mv.visitEnd(); } else if (fieldDesc[i].repeatCountMember != null) { { isVariableLengthLayout++; ImplHelper.FieldDesc repeatCountField = ImplHelper.findField(fieldDesc[i].repeatCountMember, fieldDesc); mv = cw.visitMethod( ACC_PUBLIC, fieldDesc[i].name, "()" + fieldDesc[i].sig, "()" + fieldDesc[i].elementImpl, null); mv.visitCode(); if ("" != fieldDesc[i].elementImpl) { mv.visitTypeInsn(NEW, fieldDesc[i].elementImpl); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, fieldDesc[i].elementImpl, "<init>", "()V", false); mv.visitVarInsn(ASTORE, 1); mv.visitTypeInsn(NEW, fieldDesc[i].impl); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 0); if (fieldDesc[i].priviliedgedUserClass) { FieldDesc header = ImplHelper.findField(fieldDesc[i].repeatCountMember, fieldDesc); boolean primitivePointer = ImplHelper.isTypePrimitive(header.sig); mv.visitMethodInsn( INVOKEVIRTUAL, implClassName, "EA", "()L" + interfaceClassName + "$EffectiveAddress;", false); if (primitivePointer) { mv.visitMethodInsn( INVOKEINTERFACE, interfaceClassName + "$EffectiveAddress", fieldDesc[i].repeatCountMember, "()L" + header.pointerSig + ";", true); } else { mv.visitMethodInsn( INVOKEINTERFACE, interfaceClassName + "$EffectiveAddress", fieldDesc[i].repeatCountMember, "()Lcom/ibm/layout/Pointer;", true); } if (fieldDesc[i].isVarSized) { mv.visitMethodInsn( INVOKESPECIAL, fieldDesc[i].impl, "<init>", "(Lcom/ibm/layout/PointerType;)V", false); } else { mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn( INVOKEVIRTUAL, fieldDesc[i].elementImpl, "sizeof", "()J", false); mv.visitMethodInsn( INVOKESPECIAL, fieldDesc[i].impl, "<init>", "(Lcom/ibm/layout/PointerType;J)V", false); } } else { mv.visitMethodInsn( INVOKEVIRTUAL, implClassName, fieldDesc[i].repeatCountMember, "()" + repeatCountField.sig, false); if (!repeatCountField.sig.equals("J")) { mv.visitInsn(I2L); } if (fieldDesc[i].isVarSized) { mv.visitMethodInsn(INVOKESPECIAL, fieldDesc[i].impl, "<init>", "(J)V", false); } else { mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn( INVOKEVIRTUAL, fieldDesc[i].elementImpl, "sizeof", "()J", false); mv.visitMethodInsn(INVOKESPECIAL, fieldDesc[i].impl, "<init>", "(JJ)V", false); } } mv.visitVarInsn(ASTORE, 2); mv.visitTypeInsn(NEW, "com/ibm/layout/Location"); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, implClassName, "location", "Lcom/ibm/layout/Location;"); mv.visitLdcInsn(fieldDesc[i].offset); if (wayPointCounter > 0) { mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn( INVOKESPECIAL, implClassName, "waypoint" + (wayPointCounter - 1), "()J", false); mv.visitInsn(LADD); } mv.visitMethodInsn( INVOKESPECIAL, "com/ibm/layout/Location", "<init>", "(Lcom/ibm/layout/Location;J)V", false); mv.visitVarInsn(ASTORE, 3); mv.visitVarInsn(ALOAD, 2); mv.visitVarInsn(ALOAD, 3); mv.visitMethodInsn( INVOKEINTERFACE, "com/ibm/layout/VLArray", "bindLocation", "(Lcom/ibm/layout/Location;)V", true); mv.visitVarInsn(ALOAD, 2); mv.visitInsn(ARETURN); if (fieldDesc[i].priviliedgedUserClass) { mv.visitMaxs(7, 4); } else { mv.visitMaxs(6, 4); } mv.visitEnd(); } else { throw new RuntimeException("primitive VLAs are unsupported"); } if ((isVariableLengthLayout == 1) && ((fieldDesc.length - 1) == i)) { mv = cw.visitMethod( ACC_PUBLIC, "bindLocation", "(Lcom/ibm/layout/Location;" + repeatCountField.sig + ")V", null, new String[] {"java/lang/UnsupportedOperationException"}); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(PUTFIELD, implClassName, "location", "Lcom/ibm/layout/Location;"); mv.visitVarInsn(ALOAD, 0); if (repeatCountField.sig.equals("J")) { mv.visitVarInsn(LLOAD, 2); } else { mv.visitVarInsn(ILOAD, 2); } mv.visitMethodInsn( INVOKEVIRTUAL, implClassName, fieldDesc[i].repeatCountMember, "(" + repeatCountField.sig + ")V", false); mv.visitInsn(RETURN); mv.visitMaxs(2, 3); mv.visitEnd(); } if (wayPointCounter == 0) { mv = cw.visitMethod(ACC_PRIVATE, "waypoint" + wayPointCounter++, "()J", null, null); mv.visitCode(); mv.visitLdcInsn(fieldDesc[i].offset); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn( INVOKEVIRTUAL, this.implClassName, fieldDesc[i].name, "()" + fieldDesc[i].sig, false); mv.visitMethodInsn(INVOKEINTERFACE, "com/ibm/layout/VLArray", "sizeof", "()J", true); mv.visitInsn(LADD); mv.visitInsn(LRETURN); mv.visitMaxs(4, 1); mv.visitEnd(); } else { long oldWayPoint = wayPointCounter - 1; mv = cw.visitMethod(ACC_PRIVATE, "waypoint" + wayPointCounter++, "()J", null, null); mv.visitCode(); mv.visitLdcInsn(fieldDesc[i].offset); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn( INVOKEVIRTUAL, this.implClassName, fieldDesc[i].name, "()" + fieldDesc[i].sig, false); mv.visitMethodInsn(INVOKEINTERFACE, "com/ibm/layout/VLArray", "sizeof", "()J", true); mv.visitInsn(LADD); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn( INVOKESPECIAL, this.implClassName, "waypoint" + oldWayPoint, "()J", false); mv.visitInsn(LADD); mv.visitInsn(LRETURN); mv.visitMaxs(4, 1); mv.visitEnd(); } { // access for EA class mv = cw.visitMethod( ACC_STATIC + ACC_SYNTHETIC, "access$" + (wayPointCounter), "(L" + this.implClassName + ";)J", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn( INVOKESPECIAL, this.implClassName, "waypoint" + (wayPointCounter - 1), "()J", false); mv.visitInsn(LRETURN); mv.visitMaxs(2, 1); mv.visitEnd(); } } } else if (fieldDesc[i].dims == null) { /* nested field */ mv = cw.visitMethod(ACC_PUBLIC, fieldDesc[i].name, "()" + fieldDesc[i].sig, null, null); mv.visitCode(); mv.visitTypeInsn(NEW, ImplHelper.getImplClassName(fieldDesc[i].rawType)); mv.visitInsn(DUP); mv.visitMethodInsn( INVOKESPECIAL, ImplHelper.getImplClassName(fieldDesc[i].rawType), "<init>", "()V", itf); mv.visitVarInsn(ASTORE, 1); mv.visitTypeInsn(NEW, "com/ibm/layout/Location"); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, this.implClassName, "location", "Lcom/ibm/layout/Location;"); mv.visitLdcInsn(fieldDesc[i].offset); if (wayPointCounter > 0) { mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn( INVOKESPECIAL, implClassName, "waypoint" + (wayPointCounter - 1), "()J", false); mv.visitInsn(LADD); } mv.visitMethodInsn( INVOKESPECIAL, "com/ibm/layout/Location", "<init>", "(Lcom/ibm/layout/Location;J)V", itf); mv.visitVarInsn(ASTORE, 2); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn( INVOKEVIRTUAL, ImplHelper.getImplClassName(fieldDesc[i].rawType), "bindLocation", "(Lcom/ibm/layout/Location;)V", itf); mv.visitVarInsn(ALOAD, 1); mv.visitInsn(ARETURN); mv.visitMaxs(5, 3); mv.visitEnd(); } else if (fieldDesc[i].dims.length == 1) { mv = cw.visitMethod( ACC_PUBLIC, fieldDesc[i].name, "()" + fieldDesc[i].sig, "()" + fieldDesc[i].sigGeneric, null); mv.visitCode(); if ("" != fieldDesc[i].elementImpl) { mv.visitTypeInsn(NEW, fieldDesc[i].elementImpl); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, fieldDesc[i].elementImpl, "<init>", "()V", itf); mv.visitVarInsn(ASTORE, 1); mv.visitTypeInsn(NEW, fieldDesc[i].impl); mv.visitInsn(DUP); mv.visitLdcInsn(fieldDesc[i].dims[0]); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, fieldDesc[i].elementImpl, "sizeof", "()J", itf); mv.visitMethodInsn(INVOKESPECIAL, fieldDesc[i].impl, "<init>", "(JJ)V", itf); mv.visitVarInsn(ASTORE, 2); mv.visitTypeInsn(NEW, "com/ibm/layout/Location"); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn( GETFIELD, this.implClassName, "location", "Lcom/ibm/layout/Location;"); mv.visitLdcInsn(fieldDesc[i].offset); if (wayPointCounter > 0) { mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn( INVOKESPECIAL, implClassName, "waypoint" + (wayPointCounter - 1), "()J", false); mv.visitInsn(LADD); } mv.visitMethodInsn( INVOKESPECIAL, "com/ibm/layout/Location", "<init>", "(Lcom/ibm/layout/Location;J)V", itf); mv.visitVarInsn(ASTORE, 3); mv.visitVarInsn(ALOAD, 2); mv.visitVarInsn(ALOAD, 3); mv.visitMethodInsn( INVOKEVIRTUAL, fieldDesc[i].impl, "bindLocation", "(Lcom/ibm/layout/Location;)V", itf); mv.visitVarInsn(ALOAD, 2); mv.visitInsn(ARETURN); mv.visitMaxs(6, 4); mv.visitEnd(); } else { mv.visitTypeInsn(NEW, fieldDesc[i].impl); mv.visitInsn(DUP); mv.visitLdcInsn(fieldDesc[i].dims[0]); mv.visitMethodInsn(INVOKESPECIAL, fieldDesc[i].impl, "<init>", "(J)V", itf); mv.visitVarInsn(ASTORE, 1); mv.visitTypeInsn(NEW, "com/ibm/layout/Location"); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn( GETFIELD, this.implClassName, "location", "Lcom/ibm/layout/Location;"); mv.visitLdcInsn(fieldDesc[i].offset); if (wayPointCounter > 0) { mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn( INVOKESPECIAL, implClassName, "waypoint" + (wayPointCounter - 1), "()J", false); mv.visitInsn(LADD); } mv.visitMethodInsn( INVOKESPECIAL, "com/ibm/layout/Location", "<init>", "(Lcom/ibm/layout/Location;J)V", itf); mv.visitVarInsn(ASTORE, 2); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn( INVOKEVIRTUAL, fieldDesc[i].impl, "bindLocation", "(Lcom/ibm/layout/Location;)V", itf); mv.visitVarInsn(ALOAD, 1); mv.visitInsn(ARETURN); mv.visitMaxs(5, 3); mv.visitEnd(); } } else if (fieldDesc[i].dims.length == 2) { if ("" != fieldDesc[i].elementImpl) { mv = cw.visitMethod( ACC_PUBLIC, fieldDesc[i].name, "()" + fieldDesc[i].sig, "()" + fieldDesc[i].sigGeneric, null); mv.visitCode(); mv.visitTypeInsn(NEW, fieldDesc[i].elementImpl); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, fieldDesc[i].elementImpl, "<init>", "()V", itf); mv.visitVarInsn(ASTORE, 1); mv.visitTypeInsn(NEW, fieldDesc[i].impl); mv.visitInsn(DUP); mv.visitLdcInsn(fieldDesc[i].dims[0]); mv.visitLdcInsn(fieldDesc[i].dims[1]); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, fieldDesc[i].elementImpl, "sizeof", "()J", itf); mv.visitMethodInsn(INVOKESPECIAL, fieldDesc[i].impl, "<init>", "(JJJ)V", itf); mv.visitVarInsn(ASTORE, 2); mv.visitTypeInsn(NEW, "com/ibm/layout/Location"); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn( GETFIELD, this.implClassName, "location", "Lcom/ibm/layout/Location;"); mv.visitLdcInsn(fieldDesc[i].offset); if (wayPointCounter > 0) { mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn( INVOKESPECIAL, implClassName, "waypoint" + (wayPointCounter - 1), "()J", false); mv.visitInsn(LADD); } mv.visitMethodInsn( INVOKESPECIAL, "com/ibm/layout/Location", "<init>", "(Lcom/ibm/layout/Location;J)V", itf); mv.visitVarInsn(ASTORE, 3); mv.visitVarInsn(ALOAD, 2); mv.visitVarInsn(ALOAD, 3); mv.visitMethodInsn( INVOKEVIRTUAL, fieldDesc[i].impl, "bindLocation", "(Lcom/ibm/layout/Location;)V", itf); mv.visitVarInsn(ALOAD, 2); mv.visitInsn(ARETURN); mv.visitMaxs(8, 4); mv.visitEnd(); } else { mv = cw.visitMethod( ACC_PUBLIC, fieldDesc[i].name, "()" + fieldDesc[i].sig, "()" + fieldDesc[i].sigGeneric, null); mv.visitCode(); mv.visitTypeInsn(NEW, fieldDesc[i].impl); mv.visitInsn(DUP); mv.visitLdcInsn(fieldDesc[i].dims[0]); mv.visitLdcInsn(fieldDesc[i].dims[1]); mv.visitMethodInsn(INVOKESPECIAL, fieldDesc[i].impl, "<init>", "(JJ)V", itf); mv.visitVarInsn(ASTORE, 1); mv.visitTypeInsn(NEW, "com/ibm/layout/Location"); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn( GETFIELD, this.implClassName, "location", "Lcom/ibm/layout/Location;"); mv.visitLdcInsn(fieldDesc[i].offset); if (wayPointCounter > 0) { mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn( INVOKESPECIAL, implClassName, "waypoint" + (wayPointCounter - 1), "()J", false); mv.visitInsn(LADD); } mv.visitMethodInsn( INVOKESPECIAL, "com/ibm/layout/Location", "<init>", "(Lcom/ibm/layout/Location;J)V", itf); mv.visitVarInsn(ASTORE, 2); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn( INVOKEVIRTUAL, fieldDesc[i].impl, "bindLocation", "(Lcom/ibm/layout/Location;)V", itf); mv.visitVarInsn(ALOAD, 1); mv.visitInsn(ARETURN); mv.visitMaxs(6, 3); mv.visitEnd(); } } } { boolean primitivePointer = ImplHelper.isTypePrimitive(fieldDesc[i].sig); eaMV = eaCW.visitMethod( ACC_PUBLIC, fieldDesc[i].name, primitivePointer ? "()L" + fieldDesc[i].pointerSig + ";" : "()Lcom/ibm/layout/Pointer;", primitivePointer ? null : "()L" + fieldDesc[i].pointerSig + ";", null); eaMV.visitCode(); if (primitivePointer) { eaMV.visitFieldInsn( GETSTATIC, "java/lang/" + ImplHelper.fieldSig2MethodTypeLongForm(fieldDesc[i].sig), "TYPE", "Ljava/lang/Class;"); eaMV.visitMethodInsn( INVOKESTATIC, "com/ibm/layout/LayoutType", "getPrimPointer", "(Ljava/lang/Class;)Lcom/ibm/layout/LayoutType;", true); eaMV.visitTypeInsn(CHECKCAST, fieldDesc[i].pointerSig); } else { if (null != fieldDesc[i].element) { eaMV.visitLdcInsn(Type.getType("L" + fieldDesc[i].element.replace(".", "/") + ";")); } else { eaMV.visitLdcInsn(Type.getType(fieldDesc[i].sig)); } eaMV.visitMethodInsn( INVOKESTATIC, "com/ibm/layout/LayoutType", "getPointer", "(Ljava/lang/Class;)Lcom/ibm/layout/Pointer;", true); } eaMV.visitVarInsn(ASTORE, 1); eaMV.visitVarInsn(ALOAD, 1); eaMV.visitTypeInsn(NEW, "com/ibm/layout/Location"); eaMV.visitInsn(DUP); eaMV.visitVarInsn(ALOAD, 0); eaMV.visitFieldInsn( GETFIELD, implClassName + "$EffectiveAddressImpl", "this$0", "L" + implClassName + ";"); eaMV.visitMethodInsn( INVOKESTATIC, implClassName, "access$0", "(L" + implClassName + ";)Lcom/ibm/layout/Location;", false); if (startWayPointCounter > 0) { eaMV.visitVarInsn(ALOAD, 0); eaMV.visitFieldInsn( GETFIELD, implClassName + "$EffectiveAddressImpl", "this$0", "L" + implClassName + ";"); eaMV.visitMethodInsn( INVOKESTATIC, implClassName, "access$" + (startWayPointCounter), "(L" + implClassName + ";)J", false); } eaMV.visitLdcInsn(new Long(fieldDesc[i].offset)); if (startWayPointCounter > 0) { eaMV.visitInsn(LADD); } eaMV.visitMethodInsn( INVOKESPECIAL, "com/ibm/layout/Location", "<init>", "(Lcom/ibm/layout/Location;J)V", false); if (primitivePointer) { eaMV.visitMethodInsn( INVOKEINTERFACE, "com/ibm/layout/" + ImplHelper.fieldSig2MethodType(fieldDesc[i].sig) + "Pointer", "bindLocation", "(Lcom/ibm/layout/Location;)V", true); } else { eaMV.visitMethodInsn( INVOKEINTERFACE, "com/ibm/layout/Pointer", "bindLocation", "(Lcom/ibm/layout/Location;)V", true); } eaMV.visitVarInsn(ALOAD, 1); eaMV.visitInsn(ARETURN); if (startWayPointCounter > 0) { eaMV.visitMaxs(8, 2); } else { eaMV.visitMaxs(6, 2); } eaMV.visitEnd(); } } { mv = cw.visitMethod(ACC_PUBLIC, "copyFrom", "(L" + implClassName + ";)V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn( INVOKESPECIAL, implClassName, "copyFrom", "(Lcom/ibm/layout/Layout;)V", itf); mv.visitInsn(RETURN); mv.visitMaxs(2, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null); mv.visitCode(); mv.visitTypeInsn(NEW, "java/lang/StringBuilder"); mv.visitInsn(DUP); mv.visitLdcInsn("("); mv.visitMethodInsn( INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V", false); for (int i = 0; i < fieldDesc.length; i++) { if (ImplHelper.isTypePrimitive(fieldDesc[i].sig)) { mv.visitLdcInsn(fieldDesc[i].name + ": "); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn( INVOKEVIRTUAL, implClassName, fieldDesc[i].name, "()" + fieldDesc[i].sig, false); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(" + ImplHelper.getByteCodeSig(fieldDesc[i].sig) + ")Ljava/lang/StringBuilder;", false); if (i < (fieldDesc.length - 1)) { mv.visitLdcInsn(", "); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false); } } else { mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn( INVOKEVIRTUAL, implClassName, fieldDesc[i].name, "()" + fieldDesc[i].sig, false); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;", false); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false); } } mv.visitLdcInsn(")"); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false); mv.visitInsn(ARETURN); mv.visitMaxs(3, 1); mv.visitEnd(); } if (isVariableLengthLayout > 0) { mv = cw.visitMethod(ACC_PUBLIC, "sizeof", "()J", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn( INVOKESPECIAL, implClassName, "waypoint" + (wayPointCounter - 1), "()J", false); mv.visitLdcInsn(new Long(getClassSize(fieldDesc))); mv.visitInsn(LADD); mv.visitInsn(LRETURN); mv.visitMaxs(4, 1); mv.visitEnd(); } else { mv = cw.visitMethod(ACC_PUBLIC, "sizeof", "()J", null, null); mv.visitCode(); mv.visitLdcInsn(new Long(getClassSize(fieldDesc))); mv.visitInsn(LRETURN); mv.visitMaxs(2, 1); mv.visitEnd(); } { mv = cw.visitMethod( ACC_PUBLIC, "EA", "()L" + interfaceClassName + "$EffectiveAddress;", null, null); mv.visitCode(); mv.visitTypeInsn(NEW, implClassName + "$EffectiveAddressImpl"); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn( INVOKESPECIAL, implClassName + "$EffectiveAddressImpl", "<init>", "(L" + implClassName + ";)V", false); mv.visitInsn(ARETURN); mv.visitMaxs(3, 1); mv.visitEnd(); } { mv = cw.visitMethod( ACC_STATIC + ACC_SYNTHETIC, "access$0", "(L" + implClassName + ";)Lcom/ibm/layout/Location;", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn( INVOKESPECIAL, implClassName, "getLocation", "()Lcom/ibm/layout/Location;", false); mv.visitInsn(ARETURN); mv.visitMaxs(1, 1); mv.visitEnd(); } { mv = cw.visitMethod( ACC_PRIVATE + ACC_FINAL, "getLocation", "()Lcom/ibm/layout/Location;", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, implClassName, "location", "Lcom/ibm/layout/Location;"); mv.visitInsn(ARETURN); mv.visitMaxs(1, 1); mv.visitEnd(); } if (isVariableLengthLayout == 1) { if (fieldDesc[fieldDesc.length - 1].repeatCountMember == null) { // not fixed header var tail isVariableLengthLayout++; } } ImplHelper.genLayoutTypeImpl(cw, mv, fv, implClassName, isVariableLengthLayout, false); ImplHelper.getLayoutImpl(cw, mv, implClassName); cw.visitEnd(); return cw.toByteArray(); }
/** * Instantiate GenLayout * * @param elementInterfaceClass, element type for Array */ public GenLayout(Class<? extends Layout> clazz) { this.clazz = clazz; this.interfaceClassName = ImplHelper.getInterfaceClassName(clazz); this.implClassName = ImplHelper.getImplClassName(clazz); }