diff --git a/src/java/org/lwjgl/test/mapped/MappedObjectTests1.java b/src/java/org/lwjgl/test/mapped/MappedObjectTests1.java index 88d10773..976da621 100644 --- a/src/java/org/lwjgl/test/mapped/MappedObjectTests1.java +++ b/src/java/org/lwjgl/test/mapped/MappedObjectTests1.java @@ -60,8 +60,8 @@ public class MappedObjectTests1 { { MappedFloat vecs1 = MappedFloat.malloc(1234); - assert (vecs1.sizeof == MappedFloat.SIZEOF); - assert (vecs1.sizeof * 1234 == vecs1.backingByteBuffer().capacity()); + assert (vecs1.getSizeof() == MappedFloat.SIZEOF); + assert (vecs1.getSizeof() * 1234 == vecs1.backingByteBuffer().capacity()); assert (MappedFloat.SIZEOF * 1234 == vecs1.backingByteBuffer().capacity()); } diff --git a/src/java/org/lwjgl/test/mapped/MappedObjectTests2.java b/src/java/org/lwjgl/test/mapped/MappedObjectTests2.java index 7ffb462f..c8daac74 100644 --- a/src/java/org/lwjgl/test/mapped/MappedObjectTests2.java +++ b/src/java/org/lwjgl/test/mapped/MappedObjectTests2.java @@ -44,7 +44,7 @@ public class MappedObjectTests2 { System.out.println(vecs.viewAddress); // test read-access - System.out.println(vecs.align); // test read-access + System.out.println(vecs.getAlign()); // test read-access System.out.println(MappedVec3.SIZEOF); // test read-access } @@ -91,7 +91,7 @@ public class MappedObjectTests2 { vecs.view = 1; long a2 = vecs.viewAddress; assert (a2 - a1 == MappedVec3.SIZEOF); - assert (a2 - a1 == vecs.sizeof); + assert (a2 - a1 == vecs.getSizeof()); vecs.view = 0; } } diff --git a/src/java/org/lwjgl/util/mapped/MappedForeach.java b/src/java/org/lwjgl/util/mapped/MappedForeach.java index a4469fac..ed75d3dc 100644 --- a/src/java/org/lwjgl/util/mapped/MappedForeach.java +++ b/src/java/org/lwjgl/util/mapped/MappedForeach.java @@ -58,7 +58,7 @@ final class MappedForeach implements Iterable { } public T next() { - MappedHelper.put_view(mapped, this.index++, mapped.sizeof); + mapped.setViewAddress(mapped.getViewAddress(this.index++)); return mapped; } diff --git a/src/java/org/lwjgl/util/mapped/MappedHelper.java b/src/java/org/lwjgl/util/mapped/MappedHelper.java index bc3b4152..a6890ae7 100644 --- a/src/java/org/lwjgl/util/mapped/MappedHelper.java +++ b/src/java/org/lwjgl/util/mapped/MappedHelper.java @@ -55,11 +55,9 @@ public class MappedHelper { if ( LWJGLUtil.CHECKS && align <= 0 ) throw new IllegalArgumentException("invalid alignment"); - mo.align = align; if ( LWJGLUtil.CHECKS && (sizeof <= 0 || sizeof % align != 0) ) throw new IllegalStateException("sizeof not a multiple of alignment"); - mo.sizeof = sizeof; long addr = MemoryUtil.getAddress(buffer); if ( LWJGLUtil.CHECKS && addr % align != 0 ) @@ -107,8 +105,6 @@ public class MappedHelper { public static MappedObject dup(MappedObject src, MappedObject dst) { dst.baseAddress = src.baseAddress; dst.viewAddress = src.viewAddress; - dst.align = src.align; - dst.sizeof = src.sizeof; dst.preventGC = src.preventGC; return dst; } @@ -116,8 +112,6 @@ public class MappedHelper { public static MappedObject slice(MappedObject src, MappedObject dst) { dst.baseAddress = src.viewAddress; // ! dst.viewAddress = src.viewAddress; - dst.align = src.align; - dst.sizeof = src.sizeof; dst.preventGC = src.preventGC; return dst; } diff --git a/src/java/org/lwjgl/util/mapped/MappedObject.java b/src/java/org/lwjgl/util/mapped/MappedObject.java index 6760b12d..a77bcd8d 100644 --- a/src/java/org/lwjgl/util/mapped/MappedObject.java +++ b/src/java/org/lwjgl/util/mapped/MappedObject.java @@ -50,11 +50,11 @@ import java.nio.ByteBuffer; * * @author Riven */ -public class MappedObject { +public abstract class MappedObject { static final boolean CHECKS = LWJGLUtil.getPrivilegedBoolean("org.lwjgl.util.mapped.Checks"); - public MappedObject() { + protected MappedObject() { // } @@ -64,11 +64,8 @@ public class MappedObject { /** The mapped object view memory address, in bytes. Read-only. */ public long viewAddress; - /** The mapped object memory alignment, in bytes. Read-only. */ - public int align; - - /** The mapped object memory sizeof, in bytes. Read-only. */ - public int sizeof; + /** The mapped buffer. */ + ByteBuffer preventGC; /** * Holds the value of sizeof of the sub-type of this MappedObject
@@ -87,6 +84,12 @@ public class MappedObject { */ public int view; + protected final long getViewAddress(final int view) { + // No call-site modification for this, we override in every subclass instead, + // so that we can use it in MappedForeach. + throw new InternalError("type not registered"); + } + public final void setViewAddress(final long address) { if ( CHECKS ) checkAddress(address); @@ -96,8 +99,8 @@ public class MappedObject { final void checkAddress(final long address) { final long base = MemoryUtil.getAddress0(preventGC); final int offset = (int)(address - base); - if ( address < base || preventGC.capacity() < (offset + this.sizeof) ) - throw new IndexOutOfBoundsException(Integer.toString(offset / sizeof)); + if ( address < base || preventGC.capacity() < (offset + getSizeof()) ) + throw new IndexOutOfBoundsException(Integer.toString(offset / getSizeof())); } final void checkRange(final int bytes) { @@ -108,6 +111,27 @@ public class MappedObject { throw new BufferOverflowException(); } + /** The mapped object memory alignment, in bytes. Read-only. */ + /** + * Returns the mapped object memory alignment, in bytes. + * + * @return the memory alignment + */ + public final int getAlign() { + // No call-site modification for this, we override in every subclass instead. + throw new InternalError("type not registered"); + } + + /** + * Returns the mapped object memory sizeof, in bytes. + * + * @return the sizeof value + */ + public final int getSizeof() { + // No call-site modification for this, we override in every subclass instead. + throw new InternalError("type not registered"); + } + /** * Creates a MappedObject instance, mapping the memory region of the specified direct ByteBuffer. *

@@ -178,22 +202,18 @@ public class MappedObject { * Any code in the default constructor will not run automatically. This method * can be used to run execute that code on the current view. */ - public final void runViewConstructor() { + public final void runViewConstructor() { // any method that calls this method will have its call-site modified throw new InternalError("type not registered"); } /** Moves the current view to the next element. */ public final void next() { - // any method that calls this method will have its call-site modified + // No call-site modification for this, we override in every subclass instead, + // so that we can use it in MappedSetX. throw new InternalError("type not registered"); } - /** Moves the current view to the next element. Non-transformed implementation for MappedSets. */ - final void nextSet() { - setViewAddress(viewAddress + sizeof); - } - /** * Copies and amount of SIZEOF bytes, from the current * mapped object, to the specified mapped object. @@ -232,14 +252,12 @@ public class MappedObject { throw new InternalError("type not registered"); } - ByteBuffer preventGC; - /** * Returns the {@link java.nio.ByteBuffer} that backs this mapped object. * * @return the backing buffer */ - public ByteBuffer backingByteBuffer() { + public final ByteBuffer backingByteBuffer() { return this.preventGC; } diff --git a/src/java/org/lwjgl/util/mapped/MappedObjectClassLoader.java b/src/java/org/lwjgl/util/mapped/MappedObjectClassLoader.java index feec2e7d..df6a1d4e 100644 --- a/src/java/org/lwjgl/util/mapped/MappedObjectClassLoader.java +++ b/src/java/org/lwjgl/util/mapped/MappedObjectClassLoader.java @@ -73,7 +73,9 @@ public class MappedObjectClassLoader extends URLClassLoader { FORKED = true; try { - URLClassLoader loader = new MappedObjectClassLoader(mainClass); + MappedObjectClassLoader loader = new MappedObjectClassLoader(mainClass); + loader.loadMappedObject(); + Class replacedMainClass = loader.loadClass(mainClass.getName()); Method mainMethod = replacedMainClass.getMethod("main", String[].class); mainMethod.invoke(null, new Object[] { args }); @@ -90,6 +92,28 @@ public class MappedObjectClassLoader extends URLClassLoader { super(((URLClassLoader)mainClass.getClassLoader()).getURLs()); } + protected synchronized Class loadMappedObject() throws ClassNotFoundException { + final String name = MappedObject.class.getName(); + String className = name.replace('.', '/'); + + if ( MappedObjectTransformer.PRINT_ACTIVITY ) + LWJGLUtil.log(MappedObjectClassLoader.class.getSimpleName() + ": " + className); + + byte[] bytecode = readStream(this.getResourceAsStream(className.concat(".class"))); + + long t0 = System.nanoTime(); + bytecode = MappedObjectTransformer.transformMappedObject(bytecode); + long t1 = System.nanoTime(); + total_time_transforming += (t1 - t0); + + if ( MappedObjectTransformer.PRINT_TIMING ) + LWJGLUtil.log("transforming " + className + " took " + (t1 - t0) / 1000 + " micros (total: " + (total_time_transforming / 1000 / 1000) + "ms)"); + + Class clazz = super.defineClass(name, bytecode, 0, bytecode.length); + resolveClass(clazz); + return clazz; + } + private static long total_time_transforming; @Override @@ -104,10 +128,8 @@ public class MappedObjectClassLoader extends URLClassLoader { if ( name.startsWith("sunw.") ) return super.loadClass(name, resolve); - // never transform classes in this very package, sub-packages should be transformed - if ( name.startsWith(MAPPEDOBJECT_PACKAGE_PREFIX) ) - if ( name.substring(MAPPEDOBJECT_PACKAGE_PREFIX.length()).indexOf('.') == -1 ) - return super.loadClass(name, resolve); + if ( name.equals(MappedObjectClassLoader.class.getName()) ) + return super.loadClass(name, resolve); String className = name.replace('.', '/'); @@ -116,13 +138,16 @@ public class MappedObjectClassLoader extends URLClassLoader { byte[] bytecode = readStream(this.getResourceAsStream(className.concat(".class"))); - long t0 = System.nanoTime(); - bytecode = MappedObjectTransformer.transformMappedAPI(className, bytecode); - long t1 = System.nanoTime(); - total_time_transforming += (t1 - t0); + // Classes in this package do not get transformed, but need to go through here because we have transformed MappedObject. + if ( !(name.startsWith(MAPPEDOBJECT_PACKAGE_PREFIX) && name.substring(MAPPEDOBJECT_PACKAGE_PREFIX.length()).indexOf('.') == -1) ) { + long t0 = System.nanoTime(); + bytecode = MappedObjectTransformer.transformMappedAPI(className, bytecode); + long t1 = System.nanoTime(); - if ( MappedObjectTransformer.PRINT_TIMING ) - LWJGLUtil.log("transforming " + className + " took " + (t1 - t0) / 1000 + " micros (total: " + (total_time_transforming / 1000 / 1000) + "ms)"); + total_time_transforming += (t1 - t0); + if ( MappedObjectTransformer.PRINT_TIMING ) + LWJGLUtil.log("transforming " + className + " took " + (t1 - t0) / 1000 + " micros (total: " + (total_time_transforming / 1000 / 1000) + "ms)"); + } Class clazz = super.defineClass(name, bytecode, 0, bytecode.length); if ( resolve ) diff --git a/src/java/org/lwjgl/util/mapped/MappedObjectTransformer.java b/src/java/org/lwjgl/util/mapped/MappedObjectTransformer.java index 305b2ef8..a11e3010 100644 --- a/src/java/org/lwjgl/util/mapped/MappedObjectTransformer.java +++ b/src/java/org/lwjgl/util/mapped/MappedObjectTransformer.java @@ -35,6 +35,7 @@ import org.lwjgl.LWJGLUtil; import org.objectweb.asm.*; import org.objectweb.asm.tree.*; import org.objectweb.asm.tree.analysis.*; +import org.objectweb.asm.tree.analysis.Frame; import org.objectweb.asm.util.TraceClassVisitor; import java.io.PrintWriter; @@ -76,9 +77,15 @@ public class MappedObjectTransformer { static final String MAPPED_SET3_JVM = jvmClassName(MappedSet3.class); static final String MAPPED_SET4_JVM = jvmClassName(MappedSet4.class); - static final String LENGTH_METHOD_NAME = "length$LWJGL"; - static final String VIEWADDRESS_METHOD_NAME = "getViewAddress$LWJGL"; - static final String VIEW_CONSTRUCTOR_NAME = "constructView$LWJGL"; + // Public methods + static final String VIEWADDRESS_METHOD_NAME = "getViewAddress"; + static final String NEXT_METHOD_NAME = "next"; + static final String ALIGN_METHOD_NAME = "getAlign"; + static final String SIZEOF_METHOD_NAME = "getSizeof"; + + // Internal methods + static final String LENGTH_METHOD_NAME = "length$LWJGL"; // Used for .asArray().length + static final String VIEW_CONSTRUCTOR_NAME = "constructView$LWJGL"; // Used by runViewConstructor static final Map OPCODE_TO_NAME = new HashMap(); static final Map INSNTYPE_TO_NAME = new HashMap(); @@ -122,9 +129,6 @@ public class MappedObjectTransformer { * @param type the mapped object class. */ public static void register(Class type) { - if ( MappedObjectClassLoader.FORKED ) - return; - final MappedType mapped = type.getAnnotation(MappedType.class); if ( mapped == null ) throw new InternalError("missing " + MappedType.class.getName() + " annotation"); @@ -185,6 +189,34 @@ public class MappedObjectTransformer { return (int)byteLength; } + /** Removes final from methods that will be overriden by subclasses. */ + static byte[] transformMappedObject(byte[] bytecode) { + final ClassWriter cw = new ClassWriter(0); + + ClassVisitor cv = new ClassAdapter(cw) { + + private final String[] DEFINALIZE_LIST = { + VIEWADDRESS_METHOD_NAME, + NEXT_METHOD_NAME, + ALIGN_METHOD_NAME, + SIZEOF_METHOD_NAME, + }; + + public MethodVisitor visitMethod(int access, final String name, final String desc, final String signature, final String[] exceptions) { + for ( String method : DEFINALIZE_LIST ) { + if ( name.equals(method) ) { + access &= ~ACC_FINAL; + break; + } + } + return super.visitMethod(access, name, desc, signature, exceptions); + } + }; + + new ClassReader(bytecode).accept(cv, 0); + return cw.toByteArray(); + } + static byte[] transformMappedAPI(final String className, byte[] bytecode) { final ClassWriter cw = new ClassWriter(COMPUTE_FRAMES) { @@ -203,8 +235,7 @@ public class MappedObjectTransformer { if ( className_to_subtype.containsKey(className) ) // Do a first pass to generate address getters cv = getMethodGenAdapter(className, cv); - //cr.accept(cv, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES); - new ClassReader(bytecode).accept(cv, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES); + new ClassReader(bytecode).accept(cv, ClassReader.SKIP_FRAMES); bytecode = cw.toByteArray(); if ( PRINT_BYTECODE ) @@ -218,10 +249,13 @@ public class MappedObjectTransformer { @Override public void visitEnd() { + final MappedSubtypeInfo mappedSubtype = className_to_subtype.get(className); + generateViewAddressGetter(); generateLengthGetter(); - - final MappedSubtypeInfo mappedSubtype = className_to_subtype.get(className); + generateAlignGetter(mappedSubtype); + generateSizeofGetter(); + generateNext(); for ( String fieldName : mappedSubtype.fieldToOffset.keySet() ) { final Type type = mappedSubtype.fieldToType.get(fieldName); @@ -238,7 +272,7 @@ public class MappedObjectTransformer { } private void generateViewAddressGetter() { - MethodVisitor mv = super.visitMethod(ACC_PUBLIC | ACC_STATIC, VIEWADDRESS_METHOD_NAME, "(L" + className + ";I)J", null, null); + MethodVisitor mv = super.visitMethod(ACC_PUBLIC, VIEWADDRESS_METHOD_NAME, "(I)J", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, MAPPED_OBJECT_JVM, "baseAddress", "J"); @@ -266,7 +300,7 @@ public class MappedObjectTransformer { MethodVisitor mv = super.visitMethod(ACC_PUBLIC | ACC_STATIC, LENGTH_METHOD_NAME, "(L" + className + ";)I", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKEVIRTUAL, className, "backingByteBuffer", "()L" + jvmClassName(ByteBuffer.class) + ";"); + mv.visitMethodInsn(INVOKEVIRTUAL, MAPPED_OBJECT_JVM, "backingByteBuffer", "()L" + jvmClassName(ByteBuffer.class) + ";"); mv.visitMethodInsn(INVOKEVIRTUAL, jvmClassName(ByteBuffer.class), "capacity", "()I"); mv.visitFieldInsn(GETSTATIC, className, "SIZEOF", "I"); mv.visitInsn(IDIV); @@ -275,12 +309,45 @@ public class MappedObjectTransformer { mv.visitEnd(); } + private void generateAlignGetter(final MappedSubtypeInfo mappedSubtype) { + MethodVisitor mv = super.visitMethod(ACC_PUBLIC, ALIGN_METHOD_NAME, "()I", null, null); + mv.visitCode(); + visitIntNode(mv, mappedSubtype.sizeof); + mv.visitInsn(IRETURN); + mv.visitMaxs(1, 1); + mv.visitEnd(); + } + + private void generateSizeofGetter() { + MethodVisitor mv = super.visitMethod(ACC_PUBLIC, SIZEOF_METHOD_NAME, "()I", null, null); + mv.visitCode(); + mv.visitFieldInsn(GETSTATIC, className, "SIZEOF", "I"); + mv.visitInsn(IRETURN); + mv.visitMaxs(1, 1); + mv.visitEnd(); + } + + private void generateNext() { + MethodVisitor mv = super.visitMethod(ACC_PUBLIC, NEXT_METHOD_NAME, "()V", null, null); + mv.visitCode(); + mv.visitVarInsn(ALOAD, 0); + mv.visitInsn(DUP); + mv.visitFieldInsn(GETFIELD, MAPPED_OBJECT_JVM, "viewAddress", "J"); + mv.visitFieldInsn(GETSTATIC, className, "SIZEOF", "I"); + mv.visitInsn(I2L); + mv.visitInsn(LADD); + mv.visitMethodInsn(INVOKEVIRTUAL, className, "setViewAddress", "(J)V"); + mv.visitInsn(RETURN); + mv.visitMaxs(3, 1); + mv.visitEnd(); + } + private void generateByteBufferGetter(final MappedSubtypeInfo mappedSubtype, final String fieldName, final Type type) { MethodVisitor mv = super.visitMethod(ACC_PUBLIC | ACC_STATIC, getterName(fieldName), "(L" + className + ";I)" + type.getDescriptor(), null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 1); - mv.visitMethodInsn(INVOKESTATIC, className, VIEWADDRESS_METHOD_NAME, "(L" + className + ";I)J"); + mv.visitMethodInsn(INVOKEVIRTUAL, className, VIEWADDRESS_METHOD_NAME, "(I)J"); visitIntNode(mv, mappedSubtype.fieldToOffset.get(fieldName).intValue()); mv.visitInsn(I2L); mv.visitInsn(LADD); @@ -296,13 +363,13 @@ public class MappedObjectTransformer { mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 1); - mv.visitMethodInsn(INVOKESTATIC, className, VIEWADDRESS_METHOD_NAME, "(L" + className + ";I)J"); + mv.visitMethodInsn(INVOKEVIRTUAL, className, VIEWADDRESS_METHOD_NAME, "(I)J"); visitIntNode(mv, mappedSubtype.fieldToOffset.get(fieldName).intValue()); mv.visitInsn(I2L); mv.visitInsn(LADD); mv.visitMethodInsn(INVOKESTATIC, MAPPED_HELPER_JVM, type.getDescriptor().toLowerCase() + "get", "(J)" + type.getDescriptor()); mv.visitInsn(type.getOpcode(IRETURN)); - mv.visitMaxs(2, 2); + mv.visitMaxs(3, 2); mv.visitEnd(); } @@ -331,13 +398,13 @@ public class MappedObjectTransformer { mv.visitVarInsn(load, 2); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ILOAD, 1); - mv.visitMethodInsn(INVOKESTATIC, className, VIEWADDRESS_METHOD_NAME, "(L" + className + ";I)J"); + mv.visitMethodInsn(INVOKEVIRTUAL, className, VIEWADDRESS_METHOD_NAME, "(I)J"); visitIntNode(mv, mappedSubtype.fieldToOffset.get(fieldName).intValue()); mv.visitInsn(I2L); mv.visitInsn(LADD); mv.visitMethodInsn(INVOKESTATIC, MAPPED_HELPER_JVM, type.getDescriptor().toLowerCase() + "put", "(" + type.getDescriptor() + "J)V"); mv.visitInsn(RETURN); - mv.visitMaxs(3, 3); + mv.visitMaxs(4, 3); mv.visitEnd(); } @@ -415,12 +482,14 @@ public class MappedObjectTransformer { @Override public void visitEnd() { - if ( needsTransformation ) // Early-out for methods that do not touch a mapped object. + if ( needsTransformation ) { // Early-out for methods that do not touch a mapped object. + //System.err.println("\nTRANSFORMING: " + className + "." + name + desc); try { transformMethod(analyse()); } catch (Exception e) { throw new RuntimeException(e); } + } // Pass the instruction stream to the adapter's MethodVisitor accept(mv); @@ -433,8 +502,6 @@ public class MappedObjectTransformer { } private void transformMethod(final Frame[] frames) { - //System.err.println("\nTRANSFORMING: " + className + " - " + name + desc); - final InsnList instructions = this.instructions; final Map arrayVars = new HashMap(); @@ -540,10 +607,6 @@ public class MappedObjectTransformer { break; } - if ( "next".equals(methodInsn.name) && "()V".equals(methodInsn.desc) ) { - i = replace(instructions, i, methodInsn, generateNextInstructions(mappedType)); - break; - } break; case INVOKESPECIAL: // super() in VIEW_CONSTRUCTOR_NAME, remove @@ -567,18 +630,6 @@ public class MappedObjectTransformer { return i; } - private static InsnList generateNextInstructions(final MappedSubtypeInfo mappedType) { - final InsnList list = new InsnList(); - - // stack: this - list.add(getIntNode(mappedType.sizeof)); - // stack: sizeof, this - list.add(new MethodInsnNode(INVOKESTATIC, MAPPED_HELPER_JVM, "put_view_next", "(L" + MAPPED_OBJECT_JVM + ";I)V")); - // stack: - - - return list; - } - private static InsnList generateCopyRangeInstructions(final MappedSubtypeInfo mappedType) { final InsnList list = new InsnList(); @@ -705,9 +756,6 @@ public class MappedObjectTransformer { if ( "view".equals(fieldInsn.name) ) return generateViewInstructions(fieldInsn, mappedSubtype); - if ( "align".equals(fieldInsn.name) || "sizeof".equals(fieldInsn.name) ) - return generateAlignSizeofInstructions(fieldInsn, mappedSubtype); - if ( "baseAddress".equals(fieldInsn.name) || "viewAddress".equals(fieldInsn.name) ) { return generateAddressInstructions(fieldInsn); } @@ -806,29 +854,6 @@ public class MappedObjectTransformer { throw new InternalError(); } - private static InsnList generateAlignSizeofInstructions(final FieldInsnNode fieldInsn, final MappedSubtypeInfo mappedSubtype) { - if ( !"I".equals(fieldInsn.desc) ) - throw new InternalError(); - - if ( fieldInsn.getOpcode() == GETFIELD ) { - final InsnList list = new InsnList(); - - // stack: instance - list.add(new InsnNode(POP)); - // stack: - - if ( "sizeof".equals(fieldInsn.name) ) - list.add(getIntNode(mappedSubtype.sizeof)); - else if ( "align".equals(fieldInsn.name) ) - list.add(getIntNode(mappedSubtype.align)); - // stack: int - return list; - } - - if ( fieldInsn.getOpcode() == PUTFIELD ) - throwAccessErrorOnReadOnlyField(fieldInsn.owner, fieldInsn.name); - throw new InternalError(); - } - private static InsnList generateAddressInstructions(final FieldInsnNode fieldInsn) { if ( !"J".equals(fieldInsn.desc) ) throw new IllegalStateException(); @@ -961,7 +986,7 @@ public class MappedObjectTransformer { nextInsn = getter; continue; } else if ( stackSize < loadStackSize ) - throw new ClassFormatError("Invalid .asArray() usage detected: " + getOpcodeName(nextInsn)); + throw new ClassFormatError("Invalid " + mappedSubtype.className + " view array usage detected: " + getOpcodeName(nextInsn)); } instructions.remove(aaLoadInsn); diff --git a/src/java/org/lwjgl/util/mapped/MappedSet2.java b/src/java/org/lwjgl/util/mapped/MappedSet2.java index 30287929..aedaaffa 100644 --- a/src/java/org/lwjgl/util/mapped/MappedSet2.java +++ b/src/java/org/lwjgl/util/mapped/MappedSet2.java @@ -44,13 +44,13 @@ public class MappedSet2 { public int view; void view(int view) { - MappedHelper.put_view(this.a, view, this.a.sizeof); - MappedHelper.put_view(this.b, view, this.b.sizeof); + a.setViewAddress(a.getViewAddress(view)); + b.setViewAddress(b.getViewAddress(view)); } public void next() { - this.a.nextSet(); - this.b.nextSet(); + this.a.next(); + this.b.next(); } } \ No newline at end of file diff --git a/src/java/org/lwjgl/util/mapped/MappedSet3.java b/src/java/org/lwjgl/util/mapped/MappedSet3.java index bcef2cb9..a2f33699 100644 --- a/src/java/org/lwjgl/util/mapped/MappedSet3.java +++ b/src/java/org/lwjgl/util/mapped/MappedSet3.java @@ -45,15 +45,15 @@ public class MappedSet3 { public int view; void view(int view) { - MappedHelper.put_view(this.a, view, this.a.sizeof); - MappedHelper.put_view(this.b, view, this.b.sizeof); - MappedHelper.put_view(this.c, view, this.c.sizeof); + a.setViewAddress(a.getViewAddress(view)); + b.setViewAddress(b.getViewAddress(view)); + c.setViewAddress(c.getViewAddress(view)); } public void next() { - this.a.nextSet(); - this.b.nextSet(); - this.c.nextSet(); + this.a.next(); + this.b.next(); + this.c.next(); } } \ No newline at end of file diff --git a/src/java/org/lwjgl/util/mapped/MappedSet4.java b/src/java/org/lwjgl/util/mapped/MappedSet4.java index c986244d..749fc6af 100644 --- a/src/java/org/lwjgl/util/mapped/MappedSet4.java +++ b/src/java/org/lwjgl/util/mapped/MappedSet4.java @@ -46,16 +46,16 @@ public class MappedSet4 { public int view; void view(int view) { - MappedHelper.put_view(this.a, view, this.a.sizeof); - MappedHelper.put_view(this.b, view, this.b.sizeof); - MappedHelper.put_view(this.c, view, this.c.sizeof); - MappedHelper.put_view(this.d, view, this.d.sizeof); + a.setViewAddress(a.getViewAddress(view)); + b.setViewAddress(b.getViewAddress(view)); + c.setViewAddress(c.getViewAddress(view)); + d.setViewAddress(d.getViewAddress(view)); } public void next() { - this.a.nextSet(); - this.b.nextSet(); - this.c.nextSet(); - this.d.nextSet(); + this.a.next(); + this.b.next(); + this.c.next(); + this.d.next(); } } \ No newline at end of file