[lwjgl] 20/35: Add no-asm-support.patch

Markus Koschany apo at moszumanska.debian.org
Sat Apr 9 20:38:50 UTC 2016


This is an automated email from the git hooks/post-receive script.

apo pushed a commit to branch master
in repository lwjgl.

commit 6bd7f8d65bf1201b87cb049b2d8de041a429caa1
Author: Markus Koschany <apo at debian.org>
Date:   Sat Apr 9 20:29:08 2016 +0200

    Add no-asm-support.patch
---
 debian/patches/no-asm-support.patch | 2480 +++++++++++++++++++++++++++++++++++
 debian/patches/series               |    1 +
 2 files changed, 2481 insertions(+)

diff --git a/debian/patches/no-asm-support.patch b/debian/patches/no-asm-support.patch
new file mode 100644
index 0000000..ee44c23
--- /dev/null
+++ b/debian/patches/no-asm-support.patch
@@ -0,0 +1,2480 @@
+From: Markus Koschany <apo at debian.org>
+Date: Sat, 9 Apr 2016 20:28:48 +0200
+Subject: no asm support
+
+---
+ .../org/lwjgl/test/mapped/TestMappedObject.java    |   87 --
+ .../test/opengl/sprites/SpriteShootoutMapped.java  |  838 -------------
+ .../lwjgl/util/mapped/MappedObjectClassLoader.java |  193 ---
+ .../lwjgl/util/mapped/MappedObjectTransformer.java | 1319 --------------------
+ 4 files changed, 2437 deletions(-)
+ delete mode 100644 src/java/org/lwjgl/test/mapped/TestMappedObject.java
+ delete mode 100644 src/java/org/lwjgl/test/opengl/sprites/SpriteShootoutMapped.java
+ delete mode 100644 src/java/org/lwjgl/util/mapped/MappedObjectClassLoader.java
+ delete mode 100644 src/java/org/lwjgl/util/mapped/MappedObjectTransformer.java
+
+diff --git a/src/java/org/lwjgl/test/mapped/TestMappedObject.java b/src/java/org/lwjgl/test/mapped/TestMappedObject.java
+deleted file mode 100644
+index 0ae560e..0000000
+--- a/src/java/org/lwjgl/test/mapped/TestMappedObject.java
++++ /dev/null
+@@ -1,87 +0,0 @@
+-/*
+- * Copyright (c) 2002-2011 LWJGL Project
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions are
+- * met:
+- *
+- * * Redistributions of source code must retain the above copyright
+- *   notice, this list of conditions and the following disclaimer.
+- *
+- * * Redistributions in binary form must reproduce the above copyright
+- *   notice, this list of conditions and the following disclaimer in the
+- *   documentation and/or other materials provided with the distribution.
+- *
+- * * Neither the name of 'LWJGL' nor the names of
+- *   its contributors may be used to endorse or promote products derived
+- *   from this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.lwjgl.test.mapped;
+-
+-import org.lwjgl.util.mapped.MappedObjectClassLoader;
+-import org.lwjgl.util.mapped.MappedObjectTransformer;
+-
+-/** @author Riven */
+- at SuppressWarnings("static-access")
+-public class TestMappedObject {
+-
+-	static {
+-		boolean assertsEnabled = false;
+-		assert assertsEnabled = true; // Intentional side effect!!!
+-		if ( !assertsEnabled )
+-			throw new RuntimeException("Asserts must be enabled for this test.");
+-	}
+-
+-	public static void main(String[] args) throws Exception {
+-		MappedObjectTransformer.register(MappedFloat.class);
+-		MappedObjectTransformer.register(MappedVec2.class);
+-		MappedObjectTransformer.register(MappedVec3.class);
+-		MappedObjectTransformer.register(MappedSomething.class);
+-		MappedObjectTransformer.register(MappedObjectTests3.Xyz.class);
+-		MappedObjectTransformer.register(MappedObjectTests4.MappedPointer.class);
+-		MappedObjectTransformer.register(MappedObjectTests4.MappedCacheLinePadded.class);
+-		MappedObjectTransformer.register(MappedObjectTests4.MappedFieldCacheLinePadded.class);
+-
+-		if ( MappedObjectClassLoader.fork(TestMappedObject.class, args) ) {
+-			return;
+-		}
+-
+-		MappedObjectTests1.testViewField();
+-
+-		MappedObjectTests2.testFields();
+-
+-		// MappedObjectBench.benchmarkMapped();
+-		// MappedObjectBench.benchmarkInstances();
+-		// MappedObjectBench.benchmarkIndirectArray();
+-		// MappedObjectBench.benchmarkDirectArray();
+-		// MappedObjectBench.benchmarkUnsafe();
+-
+-		MappedObjectTests3.testMappedBuffer();
+-		MappedObjectTests3.testForeach();
+-		MappedObjectTests3.testConstructor();
+-		MappedObjectTests3.testMappedSet();
+-
+-		MappedObjectTests4.testLocalView();
+-		//MappedObjectTests4.testLWJGL();
+-		MappedObjectTests4.testPointer();
+-		MappedObjectTests4.testCacheLineAlignment();
+-		MappedObjectTests4.testCacheLinePadding();
+-		MappedObjectTests4.testCacheLinePaddingPOJO();
+-
+-		System.out.println("done");
+-	}
+-
+-}
+\ No newline at end of file
+diff --git a/src/java/org/lwjgl/test/opengl/sprites/SpriteShootoutMapped.java b/src/java/org/lwjgl/test/opengl/sprites/SpriteShootoutMapped.java
+deleted file mode 100644
+index 83805d1..0000000
+--- a/src/java/org/lwjgl/test/opengl/sprites/SpriteShootoutMapped.java
++++ /dev/null
+@@ -1,838 +0,0 @@
+-/*
+- * Copyright (c) 2002-2011 LWJGL Project
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions are
+- * met:
+- *
+- * * Redistributions of source code must retain the above copyright
+- *   notice, this list of conditions and the following disclaimer.
+- *
+- * * Redistributions in binary form must reproduce the above copyright
+- *   notice, this list of conditions and the following disclaimer in the
+- *   documentation and/or other materials provided with the distribution.
+- *
+- * * Neither the name of 'LWJGL' nor the names of
+- *   its contributors may be used to endorse or promote products derived
+- *   from this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.lwjgl.test.opengl.sprites;
+-
+-import org.lwjgl.BufferUtils;
+-import org.lwjgl.LWJGLException;
+-import org.lwjgl.Sys;
+-import org.lwjgl.input.Keyboard;
+-import org.lwjgl.input.Mouse;
+-import org.lwjgl.opengl.*;
+-import org.lwjgl.util.mapped.MappedObject;
+-import org.lwjgl.util.mapped.MappedObjectClassLoader;
+-import org.lwjgl.util.mapped.MappedObjectTransformer;
+-import org.lwjgl.util.mapped.MappedType;
+-
+-import java.awt.image.BufferedImage;
+-import java.awt.image.Raster;
+-import java.io.IOException;
+-import java.nio.ByteBuffer;
+-import java.util.Random;
+-import javax.imageio.ImageIO;
+-
+-import static org.lwjgl.opengl.EXTTransformFeedback.*;
+-import static org.lwjgl.opengl.GL11.*;
+-import static org.lwjgl.opengl.GL12.*;
+-import static org.lwjgl.opengl.GL15.*;
+-import static org.lwjgl.opengl.GL20.*;
+-import static org.lwjgl.opengl.GL30.*;
+-
+-/**
+- * Sprite rendering demo. Three implementations are supported:
+- * a) CPU animation + BufferData VBO update.
+- * b) CPU animation + MapBufferRange VBO update.
+- * c) GPU animation using transform feedback with a vertex shader.
+- *
+- * @author Spasi
+- * @since 18/3/2011
+- */
+-public final class SpriteShootoutMapped {
+-
+-	static final int SCREEN_WIDTH  = 800;
+-	static final int SCREEN_HEIGHT = 600;
+-
+-	private static final int ANIMATION_TICKS = 60;
+-
+-	private boolean run       = true;
+-	private boolean render    = true;
+-	private boolean colorMask = true;
+-	private boolean animate   = true;
+-	private boolean smooth;
+-	private boolean vsync;
+-
+-	int ballSize  = 42;
+-	int ballCount = 100 * 1000;
+-
+-	private SpriteRenderer renderer;
+-
+-	// OpenGL stuff
+-	private int texID;
+-	private int texBigID;
+-	private int texSmallID;
+-
+-	long animateTime;
+-
+-	private SpriteShootoutMapped() {
+-	}
+-
+-	public static void main(String[] args) {
+-		MappedObjectTransformer.register(Pixel4b.class);
+-		MappedObjectTransformer.register(Pixel3b.class);
+-		MappedObjectTransformer.register(Sprite.class);
+-		MappedObjectTransformer.register(SpriteRender.class);
+-
+-		if ( MappedObjectClassLoader.fork(SpriteShootoutMapped.class, args) )
+-			return;
+-
+-		try {
+-			new SpriteShootoutMapped().start();
+-		} catch (LWJGLException e) {
+-			e.printStackTrace();
+-		}
+-	}
+-
+-	private void start() throws LWJGLException {
+-		try {
+-			initGL();
+-
+-			final ContextCapabilities caps = GLContext.getCapabilities();
+-			if ( !true && (caps.OpenGL30 || caps.GL_EXT_transform_feedback) )
+-				renderer = new SpriteRendererTF();
+-			else if ( true && caps.GL_ARB_map_buffer_range )
+-				renderer = new SpriteRendererMapped();
+-			else
+-				renderer = new SpriteRendererPlain();
+-
+-			updateBalls(ballCount);
+-			run();
+-		} catch (Throwable t) {
+-			t.printStackTrace();
+-		} finally {
+-			destroy();
+-		}
+-	}
+-
+-	private void initGL() throws LWJGLException {
+-		Display.setLocation((Display.getDisplayMode().getWidth() - SCREEN_WIDTH) / 2,
+-		                    (Display.getDisplayMode().getHeight() - SCREEN_HEIGHT) / 2);
+-		Display.setDisplayMode(new DisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT));
+-		Display.setTitle("Sprite Shootout");
+-		Display.create();
+-		//Display.create(new PixelFormat(), new ContextAttribs(4, 1).withProfileCompatibility(true).withDebug(true));
+-		//AMDDebugOutput.glDebugMessageCallbackAMD(new AMDDebugOutputCallback());
+-
+-		if ( !GLContext.getCapabilities().OpenGL20 )
+-			throw new RuntimeException("OpenGL 2.0 is required for this demo.");
+-
+-		// Setup viewport
+-
+-		glMatrixMode(GL_PROJECTION);
+-		glLoadIdentity();
+-		glOrtho(0, SCREEN_WIDTH, 0, SCREEN_HEIGHT, -1.0, 1.0);
+-
+-		glMatrixMode(GL_MODELVIEW);
+-		glLoadIdentity();
+-		glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
+-
+-		glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
+-
+-		// Create textures
+-
+-		try {
+-			texSmallID = createTexture("res/ball_sm.png");
+-			texBigID = createTexture("res/ball.png");
+-		} catch (IOException e) {
+-			e.printStackTrace();
+-			System.exit(-1);
+-		}
+-		texID = texBigID;
+-
+-		// Setup rendering state
+-
+-		glEnable(GL_BLEND);
+-		glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+-
+-		glEnable(GL_ALPHA_TEST);
+-		glAlphaFunc(GL_GREATER, 0.0f);
+-
+-		glColorMask(colorMask, colorMask, colorMask, false);
+-		glDepthMask(false);
+-		glDisable(GL_DEPTH_TEST);
+-
+-		// Setup geometry
+-
+-		glEnableClientState(GL_VERTEX_ARRAY);
+-
+-		Util.checkGLError();
+-	}
+-
+-	private static int createTexture(final String path) throws IOException {
+-		final BufferedImage img = ImageIO.read(SpriteShootoutMapped.class.getClassLoader().getResource(path));
+-
+-		final int w = img.getWidth();
+-		final int h = img.getHeight();
+-
+-		final ByteBuffer buffer = readImage(img);
+-
+-		final int texID = glGenTextures();
+-
+-		glBindTexture(GL_TEXTURE_2D, texID);
+-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+-		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, buffer);
+-
+-		return texID;
+-	}
+-
+-	public static class Pixel4b extends MappedObject {
+-
+-		public byte r, g, b, a;
+-
+-	}
+-
+-	@MappedType(align = 3)
+-	public static class Pixel3b extends MappedObject {
+-
+-		public byte r, g, b;
+-
+-	}
+-
+-	private static ByteBuffer readImage(final BufferedImage img) throws IOException {
+-		final Raster raster = img.getRaster();
+-
+-		final int bands = raster.getNumBands();
+-
+-		final int w = img.getWidth();
+-		final int h = img.getHeight();
+-
+-		final int count = w * h;
+-
+-		final byte[] pixels = new byte[count * bands];
+-		raster.getDataElements(0, 0, w, h, pixels);
+-
+-		if ( bands == 4 ) {
+-			Pixel4b p = Pixel4b.malloc(count);
+-
+-			int b = 0;
+-			for ( int i = 0; i < count; i++, b += 4 ) {
+-				// Pre-multiply alpha
+-				final float a = unpackUByte01(pixels[b + 3]);
+-
+-				p.view = i;
+-				p.r = packUByte01(unpackUByte01(pixels[b + 2]) * a);
+-				p.g = packUByte01(unpackUByte01(pixels[b + 1]) * a);
+-				p.b = packUByte01(unpackUByte01(pixels[b + 0]) * a);
+-				p.a = pixels[b + 3];
+-			}
+-
+-			return p.backingByteBuffer();
+-		} else if ( bands == 3 ) {
+-			Pixel3b p = Pixel3b.malloc(count);
+-
+-			int b = 0;
+-			for ( int i = 0; i < count; i++, b += 3 ) {
+-				p.view = i;
+-				p.r = pixels[b + 2];
+-				p.g = pixels[b + 1];
+-				p.b = pixels[b + 0];
+-			}
+-
+-			return p.backingByteBuffer();
+-		} else {
+-			ByteBuffer p = BufferUtils.createByteBuffer(count * bands);
+-			p.put(pixels, 0, p.capacity());
+-			p.flip();
+-			return p;
+-		}
+-
+-	}
+-
+-	private static float unpackUByte01(final byte x) {
+-		return (x & 0xFF) / 255.0f;
+-	}
+-
+-	private static byte packUByte01(final float x) {
+-		return (byte)(x * 255.0f);
+-	}
+-
+-	private void updateBalls(final int count) {
+-		System.out.println("NUMBER OF BALLS: " + count);
+-		renderer.updateBalls(ballCount);
+-	}
+-
+-	private void run() {
+-		long startTime = System.currentTimeMillis() + 5000;
+-		long fps = 0;
+-
+-		long time = Sys.getTime();
+-		final int ticksPerUpdate = (int)(Sys.getTimerResolution() / ANIMATION_TICKS);
+-
+-		renderer.render(false, true, 0);
+-
+-		while ( run ) {
+-			Display.processMessages();
+-			handleInput();
+-
+-			glClear(GL_COLOR_BUFFER_BIT);
+-
+-			final long currTime = Sys.getTime();
+-			final int delta = (int)(currTime - time);
+-			if ( smooth || delta >= ticksPerUpdate ) {
+-				renderer.render(render, animate, delta);
+-				time = currTime;
+-			} else
+-				renderer.render(render, false, 0);
+-
+-			Display.update(false);
+-			//Display.sync(60);
+-
+-			if ( startTime > System.currentTimeMillis() ) {
+-				fps++;
+-			} else {
+-				long timeUsed = 5000 + (startTime - System.currentTimeMillis());
+-				startTime = System.currentTimeMillis() + 5000;
+-				System.out.println("FPS: " + (Math.round(fps / (timeUsed / 1000.0) * 10) / 10.0) + ", Balls: " + ballCount);
+-				System.out.println("Animation: " + animateTime / fps);
+-				animateTime = 0;
+-				fps = 0;
+-			}
+-		}
+-	}
+-
+-	private void handleInput() {
+-		if ( Display.isCloseRequested() )
+-			run = false;
+-
+-		while ( Keyboard.next() ) {
+-			if ( Keyboard.getEventKeyState() )
+-				continue;
+-
+-			switch ( Keyboard.getEventKey() ) {
+-				case Keyboard.KEY_1:
+-				case Keyboard.KEY_2:
+-				case Keyboard.KEY_3:
+-				case Keyboard.KEY_4:
+-				case Keyboard.KEY_5:
+-				case Keyboard.KEY_6:
+-				case Keyboard.KEY_7:
+-				case Keyboard.KEY_8:
+-				case Keyboard.KEY_9:
+-				case Keyboard.KEY_0:
+-					ballCount = 1 << (Keyboard.getEventKey() - Keyboard.KEY_1);
+-					updateBalls(ballCount);
+-					break;
+-				case Keyboard.KEY_ADD:
+-				case Keyboard.KEY_SUBTRACT:
+-					int mult;
+-					if ( Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT) )
+-						mult = 1000;
+-					else if ( Keyboard.isKeyDown(Keyboard.KEY_LMENU) || Keyboard.isKeyDown(Keyboard.KEY_RMENU) )
+-						mult = 100;
+-					else if ( Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || Keyboard.isKeyDown(Keyboard.KEY_RCONTROL) )
+-						mult = 10;
+-					else
+-						mult = 1;
+-					if ( Keyboard.getEventKey() == Keyboard.KEY_SUBTRACT )
+-						mult = -mult;
+-					ballCount += mult * 100;
+-					if ( ballCount <= 0 )
+-						ballCount = 1;
+-					updateBalls(ballCount);
+-					break;
+-				case Keyboard.KEY_ESCAPE:
+-					run = false;
+-					break;
+-				case Keyboard.KEY_A:
+-					animate = !animate;
+-					System.out.println("Animation is now " + (animate ? "on" : "off") + ".");
+-					break;
+-				case Keyboard.KEY_C:
+-					colorMask = !colorMask;
+-					glColorMask(colorMask, colorMask, colorMask, false);
+-					System.out.println("Color mask is now " + (colorMask ? "on" : "off") + ".");
+-					// Disable alpha test when color mask is off, else we get no benefit.
+-					if ( colorMask ) {
+-						glEnable(GL_BLEND);
+-						glEnable(GL_ALPHA_TEST);
+-					} else {
+-						glDisable(GL_BLEND);
+-						glDisable(GL_ALPHA_TEST);
+-					}
+-					break;
+-				case Keyboard.KEY_R:
+-					render = !render;
+-					System.out.println("Rendering is now " + (render ? "on" : "off") + ".");
+-					break;
+-				case Keyboard.KEY_S:
+-					smooth = !smooth;
+-					System.out.println("Smooth animation is now " + (smooth ? "on" : "off") + ".");
+-					break;
+-				case Keyboard.KEY_T:
+-					if ( texID == texBigID ) {
+-						texID = texSmallID;
+-						ballSize = 16;
+-					} else {
+-						texID = texBigID;
+-						ballSize = 42;
+-					}
+-					renderer.updateBallSize();
+-					glBindTexture(GL_TEXTURE_2D, texID);
+-					System.out.println("Now using the " + (texID == texBigID ? "big" : "small") + " texture.");
+-					break;
+-				case Keyboard.KEY_V:
+-					vsync = !vsync;
+-					Display.setVSyncEnabled(vsync);
+-					System.out.println("VSYNC is now " + (vsync ? "enabled" : "disabled") + ".");
+-					break;
+-			}
+-		}
+-
+-		while ( Mouse.next() ) ;
+-	}
+-
+-	private void destroy() {
+-		Display.destroy();
+-	}
+-
+-	public static class Sprite extends MappedObject {
+-
+-		public float dx, x;
+-		public float dy, y;
+-
+-	}
+-
+-	public static class SpriteRender extends MappedObject {
+-
+-		public float x, y;
+-
+-	}
+-
+-	private abstract class SpriteRenderer {
+-
+-		protected Sprite sprites;
+-
+-		protected int spriteCount;
+-
+-		protected int vshID;
+-		protected int progID;
+-
+-		protected void createProgram() {
+-			final int fshID = glCreateShader(GL_FRAGMENT_SHADER);
+-			glShaderSource(fshID, "uniform sampler2D COLOR_MAP;\n" +
+-			                      "void main(void) {\n" +
+-			                      "     gl_FragColor = texture2D(COLOR_MAP, gl_PointCoord);\n" +
+-			                      "}");
+-			glCompileShader(fshID);
+-			if ( glGetShaderi(fshID, GL_COMPILE_STATUS) == GL_FALSE ) {
+-				System.out.println(glGetShaderInfoLog(fshID, glGetShaderi(fshID, GL_INFO_LOG_LENGTH)));
+-				throw new RuntimeException("Failed to compile fragment shader.");
+-			}
+-
+-			progID = glCreateProgram();
+-			glAttachShader(progID, vshID);
+-			glAttachShader(progID, fshID);
+-			glLinkProgram(progID);
+-			if ( glGetProgrami(progID, GL_LINK_STATUS) == GL_FALSE ) {
+-				System.out.println(glGetProgramInfoLog(progID, glGetProgrami(progID, GL_INFO_LOG_LENGTH)));
+-				throw new RuntimeException("Failed to link shader program.");
+-			}
+-
+-			glUseProgram(progID);
+-			glUniform1i(glGetUniformLocation(progID, "COLOR_MAP"), 0);
+-
+-			updateBallSize();
+-
+-			glEnableClientState(GL_VERTEX_ARRAY);
+-		}
+-
+-		public void updateBallSize() {
+-			glPointSize(ballSize);
+-		}
+-
+-		public abstract void updateBalls(int count);
+-
+-		protected abstract void render(boolean render, boolean animate, int delta);
+-
+-	}
+-
+-	private abstract class SpriteRendererBatched extends SpriteRenderer {
+-
+-		protected static final int BALLS_PER_BATCH = 10 * 1000;
+-
+-		SpriteRendererBatched() {
+-			vshID = glCreateShader(GL_VERTEX_SHADER);
+-			glShaderSource(vshID, "void main(void) {\n" +
+-			                      "     gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" +
+-			                      "}");
+-			glCompileShader(vshID);
+-			if ( glGetShaderi(vshID, GL_COMPILE_STATUS) == GL_FALSE ) {
+-				System.out.println(glGetShaderInfoLog(vshID, glGetShaderi(vshID, GL_INFO_LOG_LENGTH)));
+-				throw new RuntimeException("Failed to compile vertex shader.");
+-			}
+-
+-			createProgram();
+-		}
+-
+-		public void updateBalls(final int count) {
+-			final Random random = new Random();
+-
+-			final Sprite newSprites = Sprite.malloc(count);
+-			if ( sprites != null ) {
+-				sprites.view = 0;
+-				sprites.copyRange(newSprites, Math.min(count, spriteCount));
+-			}
+-
+-			if ( count > spriteCount ) {
+-				for ( int i = spriteCount; i < count; i++ ) {
+-					newSprites.view = i;
+-
+-					newSprites.x = (int)(random.nextFloat() * (SCREEN_WIDTH - ballSize) + ballSize * 0.5f);
+-					newSprites.y = (int)(random.nextFloat() * (SCREEN_HEIGHT - ballSize) + ballSize * 0.5f);
+-					newSprites.dx = random.nextFloat() * 0.4f - 0.2f;
+-					newSprites.dy = random.nextFloat() * 0.4f - 0.2f;
+-				}
+-			}
+-
+-			sprites = newSprites;
+-			spriteCount = count;
+-		}
+-
+-		protected void animate(
+-			final Sprite sprite,
+-			final SpriteRender spriteRender,
+-			final int ballSize, final int ballIndex, final int batchSize, final int delta
+-		) {
+-			final float ballRadius = ballSize * 0.5f;
+-			final float boundW = SCREEN_WIDTH - ballRadius;
+-			final float boundH = SCREEN_HEIGHT - ballRadius;
+-
+-			final Sprite[] sprites = sprite.asArray();
+-			final SpriteRender[] spritesRender = spriteRender.asArray();
+-			for ( int b = ballIndex, r = 0, len = (ballIndex + batchSize); b < len; b++, r++ ) {
+-				float dx = sprites[b].dx;
+-				float x = sprites[b].x;
+-
+-				x += dx * delta;
+-				if ( x < ballRadius ) {
+-					x = ballRadius;
+-					dx = -dx;
+-				} else if ( x > boundW ) {
+-					x = boundW;
+-					dx = -dx;
+-				}
+-
+-				sprites[b].dx = dx;
+-				sprites[b].x = x;
+-				spritesRender[r].x = x;
+-
+-				float dy = sprites[b].dy;
+-				float y = sprites[b].y;
+-
+-				y += dy * delta;
+-				if ( y < ballRadius ) {
+-					y = ballRadius;
+-					dy = -dy;
+-				} else if ( y > boundH ) {
+-					y = boundH;
+-					dy = -dy;
+-				}
+-
+-				sprites[b].dy = dy;
+-				sprites[b].y = y;
+-				spritesRender[r].y = y;
+-			}
+-		}
+-
+-	}
+-
+-	private class SpriteRendererPlain extends SpriteRendererBatched {
+-
+-		private final int DATA_PER_BATCH = BALLS_PER_BATCH * 2 * 4; // balls * 2 floats * 4 bytes
+-
+-		protected int[] animVBO;
+-
+-		private SpriteRender spritesRender;
+-
+-		SpriteRendererPlain() {
+-			System.out.println("Shootout Implementation: CPU animation & BufferData");
+-			spritesRender = SpriteRender.malloc(BALLS_PER_BATCH);
+-		}
+-
+-		public void updateBalls(final int count) {
+-			super.updateBalls(count);
+-
+-			final int batchCount = count / BALLS_PER_BATCH + (count % BALLS_PER_BATCH == 0 ? 0 : 1);
+-			if ( animVBO != null && batchCount == animVBO.length )
+-				return;
+-
+-			final int[] newAnimVBO = new int[batchCount];
+-			if ( animVBO != null ) {
+-				System.arraycopy(animVBO, 0, newAnimVBO, 0, Math.min(animVBO.length, newAnimVBO.length));
+-				for ( int i = newAnimVBO.length; i < animVBO.length; i++ )
+-					glDeleteBuffers(animVBO[i]);
+-			}
+-			for ( int i = animVBO == null ? 0 : animVBO.length; i < newAnimVBO.length; i++ ) {
+-				newAnimVBO[i] = glGenBuffers();
+-				glBindBuffer(GL_ARRAY_BUFFER, newAnimVBO[i]);
+-			}
+-
+-			animVBO = newAnimVBO;
+-		}
+-
+-		public void render(final boolean render, final boolean animate, final int delta) {
+-			int batchSize = Math.min(ballCount, BALLS_PER_BATCH);
+-			int ballIndex = 0;
+-			int batchIndex = 0;
+-			while ( ballIndex < ballCount ) {
+-				glBindBuffer(GL_ARRAY_BUFFER, animVBO[batchIndex]);
+-
+-				if ( animate )
+-					animate(ballIndex, batchSize, delta);
+-
+-				if ( render ) {
+-					glVertexPointer(2, GL_FLOAT, 0, 0);
+-					glDrawArrays(GL_POINTS, 0, batchSize);
+-				}
+-
+-				ballIndex += batchSize;
+-				batchSize = Math.min(ballCount - ballIndex, BALLS_PER_BATCH);
+-				batchIndex++;
+-			}
+-		}
+-
+-		private void animate(final int ballIndex, final int batchSize, final int delta) {
+-			animate(
+-				sprites, spritesRender,
+-				ballSize, ballIndex, batchSize, delta
+-			);
+-
+-			glBufferData(GL_ARRAY_BUFFER, DATA_PER_BATCH, GL_STREAM_DRAW);
+-			glBufferSubData(GL_ARRAY_BUFFER, 0, spritesRender.backingByteBuffer());
+-		}
+-
+-	}
+-
+-	private class SpriteRendererMapped extends SpriteRendererBatched {
+-
+-		private StreamVBO animVBO;
+-
+-		SpriteRendererMapped() {
+-			System.out.println("Shootout Implementation: CPU animation & MapBufferRange");
+-		}
+-
+-		public void updateBalls(final int count) {
+-			super.updateBalls(count);
+-
+-			if ( animVBO != null )
+-				animVBO.destroy();
+-
+-			animVBO = new StreamVBO(GL_ARRAY_BUFFER, ballCount * (2 * 4));
+-		}
+-
+-		public void render(final boolean render, final boolean animate, final int delta) {
+-			int batchSize = Math.min(ballCount, BALLS_PER_BATCH);
+-			int ballIndex = 0;
+-			while ( ballIndex < ballCount ) {
+-				if ( animate ) {
+-					final ByteBuffer buffer = animVBO.map(batchSize * (2 * 4));
+-
+-					long t0 = System.nanoTime();
+-					animate(sprites, SpriteRender.<SpriteRender>map(buffer), ballSize, ballIndex, batchSize, delta);
+-					long t1 = System.nanoTime();
+-
+-					animateTime += t1 - t0;
+-
+-					animVBO.unmap();
+-				}
+-
+-				if ( render ) {
+-					glVertexPointer(2, GL_FLOAT, 0, ballIndex * (2 * 4));
+-					glDrawArrays(GL_POINTS, 0, batchSize);
+-				}
+-
+-				ballIndex += batchSize;
+-				batchSize = Math.min(ballCount - ballIndex, BALLS_PER_BATCH);
+-			}
+-		}
+-
+-	}
+-
+-	private class SpriteRendererTF extends SpriteRenderer {
+-
+-		private int progIDTF;
+-		private int ballSizeLoc;
+-		private int deltaLoc;
+-
+-		private int[] tfVBO = new int[2];
+-		private int currVBO;
+-
+-		SpriteRendererTF() {
+-			System.out.println("Shootout Implementation: TF GPU animation");
+-
+-			// Transform-feedback program
+-
+-			final int vshID = glCreateShader(GL_VERTEX_SHADER);
+-			glShaderSource(vshID, "#version 130\n" +
+-			                      "const float WIDTH = " + SCREEN_WIDTH + ";\n" +
+-			                      "const float HEIGHT = " + SCREEN_HEIGHT + ";\n" +
+-			                      "uniform float ballSize;\n" + // ballSize / 2
+-			                      "uniform float delta;\n" +
+-			                      "void main(void) {\n" +
+-			                      "     vec4 anim = gl_Vertex;\n" +
+-			                      "     anim.xy = anim.xy + anim.zw * delta;\n" +
+-			                      "     vec2 animC = clamp(anim.xy, vec2(ballSize), vec2(WIDTH - ballSize, HEIGHT - ballSize));\n" +
+-			                      "     if ( anim.x != animC.x ) anim.z = -anim.z;\n" +
+-			                      "     if ( anim.y != animC.y ) anim.w = -anim.w;\n" +
+-			                      "     gl_Position = vec4(animC, anim.zw);\n" +
+-			                      "}");
+-			glCompileShader(vshID);
+-			if ( glGetShaderi(vshID, GL_COMPILE_STATUS) == GL_FALSE ) {
+-				System.out.println(glGetShaderInfoLog(vshID, glGetShaderi(vshID, GL_INFO_LOG_LENGTH)));
+-				throw new RuntimeException("Failed to compile vertex shader.");
+-			}
+-
+-			progIDTF = glCreateProgram();
+-			glAttachShader(progIDTF, vshID);
+-			glTransformFeedbackVaryings(progIDTF, new CharSequence[] { "gl_Position" }, GL_SEPARATE_ATTRIBS);
+-			glLinkProgram(progIDTF);
+-			if ( glGetProgrami(progIDTF, GL_LINK_STATUS) == GL_FALSE ) {
+-				System.out.println(glGetProgramInfoLog(progIDTF, glGetProgrami(progIDTF, GL_INFO_LOG_LENGTH)));
+-				throw new RuntimeException("Failed to link shader program.");
+-			}
+-
+-			glUseProgram(progIDTF);
+-
+-			ballSizeLoc = glGetUniformLocation(progIDTF, "ballSize");
+-			deltaLoc = glGetUniformLocation(progIDTF, "delta");
+-
+-			glUniform1f(ballSizeLoc, ballSize * 0.5f);
+-
+-			// -----------------
+-
+-			this.vshID = glCreateShader(GL_VERTEX_SHADER);
+-			glShaderSource(this.vshID, "void main(void) {\n" +
+-			                           "     gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" +
+-			                           "}");
+-			glCompileShader(this.vshID);
+-			if ( glGetShaderi(this.vshID, GL_COMPILE_STATUS) == GL_FALSE ) {
+-				System.out.println(glGetShaderInfoLog(this.vshID, glGetShaderi(this.vshID, GL_INFO_LOG_LENGTH)));
+-				throw new RuntimeException("Failed to compile vertex shader.");
+-			}
+-
+-			createProgram();
+-		}
+-
+-		public void updateBallSize() {
+-			glUseProgram(progIDTF);
+-			glUniform1f(ballSizeLoc, ballSize * 0.5f);
+-
+-			glUseProgram(progID);
+-			super.updateBallSize();
+-		}
+-
+-		private void doUpdateBalls(final int count) {
+-			final Random random = new Random();
+-
+-			final Sprite newSprites = Sprite.malloc(count);
+-			if ( sprites != null ) {
+-				sprites.view = 0;
+-				sprites.copyRange(newSprites, Math.min(count, spriteCount));
+-			}
+-
+-			if ( count > spriteCount ) {
+-				for ( int i = spriteCount; i < count; i++ ) {
+-					newSprites.view = i;
+-
+-					newSprites.x = (int)(random.nextFloat() * (SCREEN_WIDTH - ballSize) + ballSize * 0.5f);
+-					newSprites.y = (int)(random.nextFloat() * (SCREEN_HEIGHT - ballSize) + ballSize * 0.5f);
+-					newSprites.dx = random.nextFloat() * 0.4f - 0.2f;
+-					newSprites.dy = random.nextFloat() * 0.4f - 0.2f;
+-				}
+-			}
+-
+-			sprites = newSprites;
+-			spriteCount = count;
+-		}
+-
+-		public void updateBalls(final int count) {
+-			if ( tfVBO[0] != 0 ) {
+-				// Fetch current animation state
+-				glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sprites.backingByteBuffer());
+-			}
+-
+-			doUpdateBalls(count);
+-
+-			if ( tfVBO[0] != 0 ) {
+-				for ( int i = 0; i < tfVBO.length; i++ )
+-					glDeleteBuffers(tfVBO[i]);
+-			}
+-
+-			for ( int i = 0; i < tfVBO.length; i++ ) {
+-				tfVBO[i] = glGenBuffers();
+-				glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, tfVBO[i]);
+-				glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sprites.backingByteBuffer(), GL_STATIC_DRAW);
+-			}
+-
+-			glBindBuffer(GL_ARRAY_BUFFER, tfVBO[0]);
+-			glVertexPointer(2, GL_FLOAT, (4 * 4), 0);
+-		}
+-
+-		public void render(final boolean render, final boolean animate, final int delta) {
+-			if ( animate ) {
+-				glUseProgram(progIDTF);
+-				glUniform1f(deltaLoc, delta);
+-
+-				final int vbo = currVBO;
+-				currVBO = 1 - currVBO;
+-
+-				glBindBuffer(GL_ARRAY_BUFFER, tfVBO[vbo]);
+-				glVertexPointer(4, GL_FLOAT, 0, 0);
+-
+-				glEnable(GL_RASTERIZER_DISCARD);
+-				if ( GLContext.getCapabilities().OpenGL30 ) {
+-					glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfVBO[1 - vbo]);
+-
+-					glBeginTransformFeedback(GL_POINTS);
+-					glDrawArrays(GL_POINTS, 0, ballCount);
+-					glEndTransformFeedback();
+-				} else {
+-					glBindBufferBaseEXT(GL_TRANSFORM_FEEDBACK_BUFFER_EXT, 0, tfVBO[1 - vbo]);
+-
+-					glBeginTransformFeedbackEXT(GL_POINTS);
+-					glDrawArrays(GL_POINTS, 0, ballCount);
+-					glEndTransformFeedbackEXT();
+-				}
+-				glDisable(GL_RASTERIZER_DISCARD);
+-
+-				glUseProgram(progID);
+-				glVertexPointer(2, GL_FLOAT, (4 * 4), 0);
+-			}
+-
+-			if ( render )
+-				glDrawArrays(GL_POINTS, 0, ballCount);
+-		}
+-
+-	}
+-
+-}
+\ No newline at end of file
+diff --git a/src/java/org/lwjgl/util/mapped/MappedObjectClassLoader.java b/src/java/org/lwjgl/util/mapped/MappedObjectClassLoader.java
+deleted file mode 100644
+index 463823f..0000000
+--- a/src/java/org/lwjgl/util/mapped/MappedObjectClassLoader.java
++++ /dev/null
+@@ -1,193 +0,0 @@
+-/*
+- * Copyright (c) 2002-2011 LWJGL Project
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions are
+- * met:
+- *
+- * * Redistributions of source code must retain the above copyright
+- *   notice, this list of conditions and the following disclaimer.
+- *
+- * * Redistributions in binary form must reproduce the above copyright
+- *   notice, this list of conditions and the following disclaimer in the
+- *   documentation and/or other materials provided with the distribution.
+- *
+- * * Neither the name of 'LWJGL' nor the names of
+- *   its contributors may be used to endorse or promote products derived
+- *   from this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.lwjgl.util.mapped;
+-
+-import org.lwjgl.LWJGLUtil;
+-
+-import java.io.IOException;
+-import java.io.InputStream;
+-import java.lang.reflect.InvocationTargetException;
+-import java.lang.reflect.Method;
+-import java.net.URLClassLoader;
+-
+-/**
+- * This classloader is responsible for applying the bytecode transformation to mapped objects.
+- * The transformation can either be applied using a Java agent, or with the convenient {@link #fork} method.
+- *
+- * @author Riven
+- */
+-public class MappedObjectClassLoader extends URLClassLoader {
+-
+-	static final String MAPPEDOBJECT_PACKAGE_PREFIX = MappedObjectClassLoader.class.getPackage().getName() + ".";
+-
+-	static boolean FORKED;
+-
+-	/**
+-	 * Forks the specified class containing a main method, passing the specified arguments. See
+-	 * {@link org.lwjgl.test.mapped.TestMappedObject} for example usage.
+-	 *
+-	 * @param mainClass the class containing the main method
+-	 * @param args      the arguments to pass
+-	 *
+-	 * @return true if the fork was successful.
+-	 */
+-	public static boolean fork(Class<?> mainClass, String[] args) {
+-		if ( FORKED ) {
+-			return false;
+-		}
+-
+-		FORKED = true;
+-
+-		try {
+-			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 });
+-		} catch (InvocationTargetException exc) {
+-			Thread.currentThread().getUncaughtExceptionHandler().uncaughtException(Thread.currentThread(), exc.getCause());
+-		} catch (Throwable cause) {
+-			throw new Error("failed to fork", cause);
+-		}
+-
+-		return true;
+-	}
+-
+-	private MappedObjectClassLoader(Class<?> mainClass) {
+-		super(((URLClassLoader)mainClass.getClassLoader()).getURLs());
+-	}
+-
+-	protected synchronized Class<?> loadMappedObject() throws ClassNotFoundException {
+-		final String name = MappedObject.class.getName();
+-		String className = name.replace('.', '/');
+-
+-		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_ACTIVITY )
+-			printActivity(className, t0, t1);
+-
+-		Class<?> clazz = super.defineClass(name, bytecode, 0, bytecode.length);
+-		resolveClass(clazz);
+-		return clazz;
+-	}
+-
+-	private static long total_time_transforming;
+-
+-	@Override
+-	protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
+-		if ( name.startsWith("java.")
+-		     || name.startsWith("javax.")
+-		     || name.startsWith("sun.")
+-		     || name.startsWith("sunw.")
+-		     || name.startsWith("org.objectweb.asm.")
+-			)
+-			return super.loadClass(name, resolve);
+-
+-		final String className = name.replace('.', '/');
+-		final boolean inThisPackage = name.startsWith(MAPPEDOBJECT_PACKAGE_PREFIX);
+-
+-		if ( inThisPackage && (
+-			name.equals(MappedObjectClassLoader.class.getName())
+-			|| name.equals((MappedObjectTransformer.class.getName()))
+-			|| name.equals((CacheUtil.class.getName()))
+-		) )
+-			return super.loadClass(name, resolve);
+-
+-		byte[] bytecode = readStream(this.getResourceAsStream(className.concat(".class")));
+-
+-		// Classes in this package do not get transformed, but need to go through here because we have transformed MappedObject.
+-		if ( !(inThisPackage && name.substring(MAPPEDOBJECT_PACKAGE_PREFIX.length()).indexOf('.') == -1) ) {
+-			long t0 = System.nanoTime();
+-			final byte[] newBytecode = MappedObjectTransformer.transformMappedAPI(className, bytecode);
+-			long t1 = System.nanoTime();
+-
+-			total_time_transforming += (t1 - t0);
+-
+-			if ( bytecode != newBytecode ) {
+-				bytecode = newBytecode;
+-				if ( MappedObjectTransformer.PRINT_ACTIVITY )
+-					printActivity(className, t0, t1);
+-			}
+-		}
+-
+-		Class<?> clazz = super.defineClass(name, bytecode, 0, bytecode.length);
+-		if ( resolve )
+-			resolveClass(clazz);
+-		return clazz;
+-	}
+-
+-	private static void printActivity(final String className, final long t0, final long t1) {
+-		final StringBuilder msg = new StringBuilder(MappedObjectClassLoader.class.getSimpleName() + ": " + className);
+-
+-		if ( MappedObjectTransformer.PRINT_TIMING )
+-			msg.append("\n\ttransforming took " + (t1 - t0) / 1000 + " micros (total: " + (total_time_transforming / 1000 / 1000) + "ms)");
+-
+-		LWJGLUtil.log(msg);
+-	}
+-
+-	private static byte[] readStream(InputStream in) {
+-		byte[] bytecode = new byte[256];
+-		int len = 0;
+-		try {
+-			while ( true ) {
+-				if ( bytecode.length == len )
+-					bytecode = copyOf(bytecode, len * 2);
+-				int got = in.read(bytecode, len, bytecode.length - len);
+-				if ( got == -1 )
+-					break;
+-				len += got;
+-			}
+-		} catch (IOException exc) {
+-			// stop!
+-		} finally {
+-			try {
+-				in.close();
+-			} catch (IOException exc) {
+-				// ignore...
+-			}
+-		}
+-		return copyOf(bytecode, len);
+-	}
+-
+-	private static byte[] copyOf(byte[] original, int newLength) {
+-		byte[] copy = new byte[newLength];
+-		System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
+-		return copy;
+-	}
+-
+-}
+\ No newline at end of file
+diff --git a/src/java/org/lwjgl/util/mapped/MappedObjectTransformer.java b/src/java/org/lwjgl/util/mapped/MappedObjectTransformer.java
+deleted file mode 100644
+index c34c14e..0000000
+--- a/src/java/org/lwjgl/util/mapped/MappedObjectTransformer.java
++++ /dev/null
+@@ -1,1319 +0,0 @@
+-/*
+- * Copyright (c) 2002-2011 LWJGL Project
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions are
+- * met:
+- *
+- * * Redistributions of source code must retain the above copyright
+- *   notice, this list of conditions and the following disclaimer.
+- *
+- * * Redistributions in binary form must reproduce the above copyright
+- *   notice, this list of conditions and the following disclaimer in the
+- *   documentation and/or other materials provided with the distribution.
+- *
+- * * Neither the name of 'LWJGL' nor the names of
+- *   its contributors may be used to endorse or promote products derived
+- *   from this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.lwjgl.util.mapped;
+-
+-import org.lwjgl.BufferUtils;
+-import org.lwjgl.LWJGLUtil;
+-import org.lwjgl.MemoryUtil;
+-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;
+-import java.io.StringWriter;
+-import java.lang.reflect.Field;
+-import java.lang.reflect.Modifier;
+-import java.nio.Buffer;
+-import java.nio.ByteBuffer;
+-import java.util.HashMap;
+-import java.util.Map;
+-
+-import static org.objectweb.asm.ClassWriter.*;
+-import static org.objectweb.asm.Opcodes.*;
+-
+-/**
+- * This class implements the bytecode transformation that mapped object go through.
+- * Mapped object classes need to first be registered with the transformer, see {@link #register(Class)}.
+- * <p/>
+- * The transformer supports some debugging tools, enabled through JVM system properties:<br/>
+- * org.lwjgl.util.mapped.PrintTiming=true, prints timing information for the transformation step.<br/>
+- * org.lwjgl.util.mapped.PrintActivity=true, prints activity information.<br/>
+- * org.lwjgl.util.mapped.PrintBytecode=true, prints the transformed bytecode.<br/>
+- * org.lwjgl.util.Debug must also be set to true for the above to work.
+- *
+- * @author Riven
+- */
+-public class MappedObjectTransformer {
+-
+-	static final boolean PRINT_ACTIVITY = LWJGLUtil.DEBUG && LWJGLUtil.getPrivilegedBoolean("org.lwjgl.util.mapped.PrintActivity");
+-	static final boolean PRINT_TIMING   = PRINT_ACTIVITY && LWJGLUtil.getPrivilegedBoolean("org.lwjgl.util.mapped.PrintTiming");
+-	static final boolean PRINT_BYTECODE = LWJGLUtil.DEBUG && LWJGLUtil.getPrivilegedBoolean("org.lwjgl.util.mapped.PrintBytecode");
+-
+-	static final Map<String, MappedSubtypeInfo> className_to_subtype;
+-
+-	static final String MAPPED_OBJECT_JVM = jvmClassName(MappedObject.class);
+-	static final String MAPPED_HELPER_JVM = jvmClassName(MappedHelper.class);
+-
+-	static final String MAPPEDSET_PREFIX = jvmClassName(MappedSet.class);
+-	static final String MAPPED_SET2_JVM  = jvmClassName(MappedSet2.class);
+-	static final String MAPPED_SET3_JVM  = jvmClassName(MappedSet3.class);
+-	static final String MAPPED_SET4_JVM  = jvmClassName(MappedSet4.class);
+-
+-	static final String CACHE_LINE_PAD_JVM = "L" + jvmClassName(CacheLinePad.class) + ";";
+-
+-	// 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";
+-	static final String CAPACITY_METHOD_NAME    = "capacity"; // Used for .asArray().length
+-
+-	// Internal methods
+-	static final String VIEW_CONSTRUCTOR_NAME = "constructView$LWJGL"; // Used by runViewConstructor
+-
+-	static final Map<Integer, String> OPCODE_TO_NAME   = new HashMap<Integer, String>();
+-	static final Map<Integer, String> INSNTYPE_TO_NAME = new HashMap<Integer, String>();
+-
+-	static boolean is_currently_computing_frames;
+-
+-	static {
+-		getClassEnums(Opcodes.class, OPCODE_TO_NAME, "V1_", "ACC_", "T_", "F_", "MH_");
+-		getClassEnums(AbstractInsnNode.class, INSNTYPE_TO_NAME);
+-
+-		className_to_subtype = new HashMap<String, MappedSubtypeInfo>();
+-
+-		{
+-			// HACK: required for mapped.view++
+-			//
+-			// because the compiler generates:
+-			// => GETFIELD MappedObject.view
+-			// => ICONST_1
+-			// => IADD
+-			// => PUTFIELD MyMappedType.view
+-			//
+-			// instead of:
+-			// => GETFIELD MyMappedType.view
+-			// => ICONST_1
+-			// => IADD
+-			// => PUTFIELD MyMappedType.view
+-			//
+-			className_to_subtype.put(MAPPED_OBJECT_JVM, new MappedSubtypeInfo(MAPPED_OBJECT_JVM, null, -1, -1, -1, false));
+-		}
+-
+-		final String vmName = System.getProperty("java.vm.name");
+-		if ( vmName != null && !vmName.contains("Server") ) {
+-			System.err.println("Warning: " + MappedObject.class.getSimpleName() + "s have inferiour performance on Client VMs, please consider switching to a Server VM.");
+-		}
+-	}
+-
+-	/**
+-	 * Registers a class as a mapped object.
+-	 * The class must extend {@link org.lwjgl.util.mapped.MappedObject} and be annotated with {@link org.lwjgl.util.mapped.MappedField}.
+-	 *
+-	 * @param type the mapped object class.
+-	 */
+-	public static void register(Class<? extends MappedObject> type) {
+-		if ( MappedObjectClassLoader.FORKED )
+-			return;
+-
+-		final MappedType mapped = type.getAnnotation(MappedType.class);
+-
+-		if ( mapped != null && mapped.padding() < 0 )
+-			throw new ClassFormatError("Invalid mapped type padding: " + mapped.padding());
+-
+-		if ( type.getEnclosingClass() != null && !Modifier.isStatic(type.getModifiers()) )
+-			throw new InternalError("only top-level or static inner classes are allowed");
+-
+-		final String className = jvmClassName(type);
+-		final Map<String, FieldInfo> fields = new HashMap<String, FieldInfo>();
+-
+-		long sizeof = 0;
+-		for ( Field field : type.getDeclaredFields() ) {
+-			FieldInfo fieldInfo = registerField(mapped == null || mapped.autoGenerateOffsets(), className, sizeof, field);
+-			if ( fieldInfo == null )
+-				continue;
+-
+-			fields.put(field.getName(), fieldInfo);
+-
+-			sizeof = Math.max(sizeof, fieldInfo.offset + fieldInfo.lengthPadded);
+-		}
+-
+-		int align = 4;
+-		int padding = 0;
+-		boolean cacheLinePadded = false;
+-
+-		if ( mapped != null ) {
+-			align = mapped.align();
+-			if ( mapped.cacheLinePadding() ) {
+-				if ( mapped.padding() != 0 )
+-					throw new ClassFormatError("Mapped type padding cannot be specified together with cacheLinePadding.");
+-
+-				final int cacheLineMod = (int)(sizeof % CacheUtil.getCacheLineSize());
+-				if ( cacheLineMod != 0 )
+-					padding = CacheUtil.getCacheLineSize() - cacheLineMod;
+-
+-				cacheLinePadded = true;
+-			} else
+-				padding = mapped.padding();
+-		}
+-
+-		sizeof += padding;
+-
+-		final MappedSubtypeInfo mappedType = new MappedSubtypeInfo(className, fields, (int)sizeof, align, padding, cacheLinePadded);
+-		if ( className_to_subtype.put(className, mappedType) != null )
+-			throw new InternalError("duplicate mapped type: " + mappedType.className);
+-	}
+-
+-	private static FieldInfo registerField(final boolean autoGenerateOffsets, final String className, long advancingOffset, final Field field) {
+-		if ( Modifier.isStatic(field.getModifiers()) ) // static fields are never mapped
+-			return null;
+-
+-		// we only support primitives and ByteBuffers
+-		if ( !field.getType().isPrimitive() && field.getType() != ByteBuffer.class )
+-			throw new ClassFormatError("field '" + className + "." + field.getName() + "' not supported: " + field.getType());
+-
+-		MappedField meta = field.getAnnotation(MappedField.class);
+-		if ( meta == null && !autoGenerateOffsets )
+-			throw new ClassFormatError("field '" + className + "." + field.getName() + "' missing annotation " + MappedField.class.getName() + ": " + className);
+-
+-		Pointer pointer = field.getAnnotation(Pointer.class);
+-		if ( pointer != null && field.getType() != long.class )
+-			throw new ClassFormatError("The @Pointer annotation can only be used on long fields. @Pointer field found: " + className + "." + field.getName() + ": " + field.getType());
+-
+-		if ( Modifier.isVolatile(field.getModifiers()) && (pointer != null || field.getType() == ByteBuffer.class) )
+-			throw new ClassFormatError("The volatile keyword is not supported for @Pointer or ByteBuffer fields. Volatile field found: " + className + "." + field.getName() + ": " + field.getType());
+-
+-		// quick hack
+-		long byteLength;
+-		if ( field.getType() == long.class || field.getType() == double.class ) {
+-			if ( pointer == null )
+-				byteLength = 8;
+-			else
+-				byteLength = MappedObjectUnsafe.INSTANCE.addressSize();
+-		} else if ( field.getType() == double.class )
+-			byteLength = 8;
+-		else if ( field.getType() == int.class || field.getType() == float.class )
+-			byteLength = 4;
+-		else if ( field.getType() == char.class || field.getType() == short.class )
+-			byteLength = 2;
+-		else if ( field.getType() == byte.class )
+-			byteLength = 1;
+-		else if ( field.getType() == ByteBuffer.class ) {
+-			byteLength = meta.byteLength();
+-			if ( byteLength < 0 )
+-				throw new IllegalStateException("invalid byte length for mapped ByteBuffer field: " + className + "." + field.getName() + " [length=" + byteLength + "]");
+-		} else
+-			throw new ClassFormatError(field.getType().getName());
+-
+-		if ( field.getType() != ByteBuffer.class && (advancingOffset % byteLength) != 0 )
+-			throw new IllegalStateException("misaligned mapped type: " + className + "." + field.getName());
+-
+-		CacheLinePad pad = field.getAnnotation(CacheLinePad.class);
+-
+-		long byteOffset = advancingOffset;
+-		if ( meta != null && meta.byteOffset() != -1 ) {
+-			if ( meta.byteOffset() < 0 )
+-				throw new ClassFormatError("Invalid field byte offset: " + className + "." + field.getName() + " [byteOffset=" + meta.byteOffset() + "]");
+-			if ( pad != null )
+-				throw new ClassFormatError("A field byte offset cannot be specified together with cache-line padding: " + className + "." + field.getName());
+-
+-			byteOffset = meta.byteOffset();
+-		}
+-
+-		long byteLengthPadded = byteLength;
+-		if ( pad != null ) {
+-			// Pad before
+-			if ( pad.before() && byteOffset % CacheUtil.getCacheLineSize() != 0 )
+-				byteOffset += CacheUtil.getCacheLineSize() - (byteOffset & (CacheUtil.getCacheLineSize() - 1));
+-
+-			// Pad after
+-			if ( pad.after() && (byteOffset + byteLength) % CacheUtil.getCacheLineSize() != 0 )
+-				byteLengthPadded += CacheUtil.getCacheLineSize() - (byteOffset + byteLength) % CacheUtil.getCacheLineSize();
+-
+-			assert !pad.before() || (byteOffset % CacheUtil.getCacheLineSize() == 0);
+-			assert !pad.after() || ((byteOffset + byteLengthPadded) % CacheUtil.getCacheLineSize() == 0);
+-		}
+-
+-		if ( PRINT_ACTIVITY )
+-			LWJGLUtil.log(MappedObjectTransformer.class.getSimpleName() + ": " + className + "." + field.getName() + " [type=" + field.getType().getSimpleName() + ", offset=" + byteOffset + "]");
+-
+-		return new FieldInfo(byteOffset, byteLength, byteLengthPadded, Type.getType(field.getType()), Modifier.isVolatile(field.getModifiers()), pointer != null);
+-	}
+-
+-	/** 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,
+-				CAPACITY_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) {
+-
+-			@Override
+-			protected String getCommonSuperClass(String a, String b) {
+-				// HACK: prevent user-code static-initialization-blocks to be executed
+-				if ( is_currently_computing_frames && !a.startsWith("java/") || !b.startsWith("java/") )
+-					return "java/lang/Object";
+-
+-				return super.getCommonSuperClass(a, b);
+-			}
+-
+-		};
+-
+-		final TransformationAdapter ta = new TransformationAdapter(cw, className);
+-
+-		ClassVisitor cv = ta;
+-		if ( className_to_subtype.containsKey(className) ) // Do a first pass to generate address getters
+-			cv = getMethodGenAdapter(className, cv);
+-
+-		new ClassReader(bytecode).accept(cv, ClassReader.SKIP_FRAMES);
+-
+-		if ( !ta.transformed )
+-			return bytecode;
+-
+-		bytecode = cw.toByteArray();
+-		if ( PRINT_BYTECODE )
+-			printBytecode(bytecode);
+-
+-		return bytecode;
+-	}
+-
+-	private static ClassAdapter getMethodGenAdapter(final String className, final ClassVisitor cv) {
+-		return new ClassAdapter(cv) {
+-
+-			@Override
+-			public void visitEnd() {
+-				final MappedSubtypeInfo mappedSubtype = className_to_subtype.get(className);
+-
+-				generateViewAddressGetter();
+-				generateCapacity();
+-				generateAlignGetter(mappedSubtype);
+-				generateSizeofGetter();
+-				generateNext();
+-
+-				for ( String fieldName : mappedSubtype.fields.keySet() ) {
+-					final FieldInfo field = mappedSubtype.fields.get(fieldName);
+-
+-					if ( field.type.getDescriptor().length() > 1 ) {  // ByteBuffer, getter only
+-						generateByteBufferGetter(fieldName, field);
+-					} else {
+-						generateFieldGetter(fieldName, field);
+-						generateFieldSetter(fieldName, field);
+-					}
+-				}
+-
+-				super.visitEnd();
+-			}
+-
+-			private void generateViewAddressGetter() {
+-				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");
+-				mv.visitVarInsn(ILOAD, 1);
+-				mv.visitFieldInsn(GETSTATIC, className, "SIZEOF", "I");
+-				mv.visitInsn(IMUL);
+-				mv.visitInsn(I2L);
+-				mv.visitInsn(LADD);
+-				if ( MappedObject.CHECKS ) {
+-					mv.visitInsn(DUP2);
+-					mv.visitVarInsn(ALOAD, 0);
+-					mv.visitMethodInsn(INVOKESTATIC, MAPPED_HELPER_JVM, "checkAddress", "(JL" + MAPPED_OBJECT_JVM + ";)V");
+-				}
+-				mv.visitInsn(LRETURN);
+-				mv.visitMaxs(3, 2);
+-				mv.visitEnd();
+-			}
+-
+-			private void generateCapacity() {
+-				// return (backingByteBuffer().capacity() + (int)(MemoryUtil.getAddress0(backingByteBuffer()) - baseAddress)) / SIZEOF;
+-				MethodVisitor mv = super.visitMethod(ACC_PUBLIC, CAPACITY_METHOD_NAME, "()I", null, null);
+-				mv.visitCode();
+-				mv.visitVarInsn(ALOAD, 0);
+-				mv.visitMethodInsn(INVOKEVIRTUAL, MAPPED_OBJECT_JVM, "backingByteBuffer", "()L" + jvmClassName(ByteBuffer.class) + ";");
+-				mv.visitInsn(DUP);
+-				mv.visitMethodInsn(INVOKEVIRTUAL, jvmClassName(ByteBuffer.class), "capacity", "()I");
+-				mv.visitInsn(SWAP);
+-				mv.visitMethodInsn(INVOKESTATIC, jvmClassName(MemoryUtil.class), "getAddress0", "(L" + jvmClassName(Buffer.class) + ";)J");
+-				mv.visitVarInsn(ALOAD, 0);
+-				mv.visitFieldInsn(GETFIELD, MAPPED_OBJECT_JVM, "baseAddress", "J");
+-				mv.visitInsn(LSUB);
+-				mv.visitInsn(L2I);
+-				mv.visitInsn(IADD);
+-				mv.visitFieldInsn(GETSTATIC, className, "SIZEOF", "I");
+-				mv.visitInsn(IDIV);
+-				mv.visitInsn(IRETURN);
+-				mv.visitMaxs(3, 1);
+-				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 String fieldName, final FieldInfo field) {
+-				MethodVisitor mv = super.visitMethod(ACC_PUBLIC | ACC_STATIC, getterName(fieldName), "(L" + className + ";I)" + field.type.getDescriptor(), null, null);
+-				mv.visitCode();
+-				mv.visitVarInsn(ALOAD, 0);
+-				mv.visitVarInsn(ILOAD, 1);
+-				mv.visitMethodInsn(INVOKEVIRTUAL, className, VIEWADDRESS_METHOD_NAME, "(I)J");
+-				visitIntNode(mv, (int)field.offset);
+-				mv.visitInsn(I2L);
+-				mv.visitInsn(LADD);
+-				visitIntNode(mv, (int)field.length);
+-				mv.visitMethodInsn(INVOKESTATIC, MAPPED_HELPER_JVM, "newBuffer", "(JI)L" + jvmClassName(ByteBuffer.class) + ";");
+-				mv.visitInsn(ARETURN);
+-				mv.visitMaxs(3, 2);
+-				mv.visitEnd();
+-			}
+-
+-			private void generateFieldGetter(final String fieldName, final FieldInfo field) {
+-				MethodVisitor mv = super.visitMethod(ACC_PUBLIC | ACC_STATIC, getterName(fieldName), "(L" + className + ";I)" + field.type.getDescriptor(), null, null);
+-				mv.visitCode();
+-				mv.visitVarInsn(ALOAD, 0);
+-				mv.visitVarInsn(ILOAD, 1);
+-				mv.visitMethodInsn(INVOKEVIRTUAL, className, VIEWADDRESS_METHOD_NAME, "(I)J");
+-				visitIntNode(mv, (int)field.offset);
+-				mv.visitInsn(I2L);
+-				mv.visitInsn(LADD);
+-				mv.visitMethodInsn(INVOKESTATIC, MAPPED_HELPER_JVM, field.getAccessType() + "get", "(J)" + field.type.getDescriptor());
+-				mv.visitInsn(field.type.getOpcode(IRETURN));
+-				mv.visitMaxs(3, 2);
+-				mv.visitEnd();
+-			}
+-
+-			private void generateFieldSetter(final String fieldName, final FieldInfo field) {
+-				MethodVisitor mv = super.visitMethod(ACC_PUBLIC | ACC_STATIC, setterName(fieldName), "(L" + className + ";I" + field.type.getDescriptor() + ")V", null, null);
+-				mv.visitCode();
+-				int load = 0;
+-				switch ( field.type.getSort() ) {
+-					case Type.BOOLEAN:
+-					case Type.CHAR:
+-					case Type.BYTE:
+-					case Type.SHORT:
+-					case Type.INT:
+-						load = ILOAD;
+-						break;
+-					case Type.FLOAT:
+-						load = FLOAD;
+-						break;
+-					case Type.LONG:
+-						load = LLOAD;
+-						break;
+-					case Type.DOUBLE:
+-						load = DLOAD;
+-						break;
+-				}
+-				mv.visitVarInsn(load, 2);
+-				mv.visitVarInsn(ALOAD, 0);
+-				mv.visitVarInsn(ILOAD, 1);
+-				mv.visitMethodInsn(INVOKEVIRTUAL, className, VIEWADDRESS_METHOD_NAME, "(I)J");
+-				visitIntNode(mv, (int)field.offset);
+-				mv.visitInsn(I2L);
+-				mv.visitInsn(LADD);
+-				mv.visitMethodInsn(INVOKESTATIC, MAPPED_HELPER_JVM, field.getAccessType() + "put", "(" + field.type.getDescriptor() + "J)V");
+-				mv.visitInsn(RETURN);
+-				mv.visitMaxs(4, 4);
+-				mv.visitEnd();
+-			}
+-
+-		};
+-	}
+-
+-	private static class TransformationAdapter extends ClassAdapter {
+-
+-		final String className;
+-
+-		boolean transformed;
+-
+-		TransformationAdapter(final ClassVisitor cv, final String className) {
+-			super(cv);
+-			this.className = className;
+-		}
+-
+-		@Override
+-		public FieldVisitor visitField(final int access, final String name, final String desc, final String signature, final Object value) {
+-			// remove redirected fields
+-			final MappedSubtypeInfo mappedSubtype = className_to_subtype.get(className);
+-			if ( mappedSubtype != null && mappedSubtype.fields.containsKey(name) ) {
+-				if ( PRINT_ACTIVITY )
+-					LWJGLUtil.log(MappedObjectTransformer.class.getSimpleName() + ": discarding field: " + className + "." + name + ":" + desc);
+-				return null;
+-			}
+-
+-			if ( (access & ACC_STATIC) == 0 ) {
+-				return new FieldNode(access, name, desc, signature, value) {
+-					public void visitEnd() {
+-						if ( visibleAnnotations == null ) { // early-out
+-							accept(cv);
+-							return;
+-						}
+-
+-						boolean before = false;
+-						boolean after = false;
+-						int byteLength = 0;
+-						for ( AnnotationNode pad : visibleAnnotations ) {
+-							if ( CACHE_LINE_PAD_JVM.equals(pad.desc) ) {
+-								if ( "J".equals(desc) || "D".equals(desc) )
+-									byteLength = 8;
+-								else if ( "I".equals(desc) || "F".equals(desc) )
+-									byteLength = 4;
+-								else if ( "S".equals(desc) || "C".equals(desc) )
+-									byteLength = 2;
+-								else if ( "B".equals(desc) || "Z".equals(desc) )
+-									byteLength = 1;
+-								else
+-									throw new ClassFormatError("The @CacheLinePad annotation cannot be used on non-primitive fields: " + className + "." + name);
+-
+-								transformed = true;
+-
+-								after = true;
+-								if ( pad.values != null ) {
+-									for ( int i = 0; i < pad.values.size(); i += 2 ) {
+-										final boolean value = pad.values.get(i + 1).equals(Boolean.TRUE);
+-										if ( "before".equals(pad.values.get(i)) )
+-											before = value;
+-										else
+-											after = value;
+-									}
+-								}
+-								break;
+-							}
+-						}
+-
+-						/*
+-							We make the fields public to force the JVM to keep the fields in the object.
+-							Instead of using only longs or integers, we use the same type as the original
+-							field. That's because modern JVMs usually reorder fields by type:
+-							longs, then doubles, then integers, then booleans, etc. This way it's more
+-							likely that the padding will work as expected.
+-						 */
+-
+-						if ( before ) {
+-							final int count = CacheUtil.getCacheLineSize() / byteLength - 1;
+-							for ( int i = count; i >= 1; i-- )
+-								cv.visitField(access | ACC_PUBLIC | ACC_SYNTHETIC, name + "$PAD_" + i, desc, signature, null);
+-						}
+-
+-						accept(cv);
+-
+-						if ( after ) {
+-							final int count = CacheUtil.getCacheLineSize() / byteLength - 1;
+-							for ( int i = 1; i <= count; i++ )
+-								cv.visitField(access | ACC_PUBLIC | ACC_SYNTHETIC, name + "$PAD" + i, desc, signature, null);
+-						}
+-					}
+-				};
+-			} else
+-				return super.visitField(access, name, desc, signature, value);
+-		}
+-
+-		@Override
+-		public MethodVisitor visitMethod(final int access, String name, final String desc, final String signature, final String[] exceptions) {
+-			// Move MappedSubtype constructors to another method
+-			if ( "<init>".equals(name) ) {
+-				final MappedSubtypeInfo mappedSubtype = className_to_subtype.get(className);
+-				if ( mappedSubtype != null ) {
+-					if ( !"()V".equals(desc) )
+-						throw new ClassFormatError(className + " can only have a default constructor, found: " + desc);
+-
+-					final MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
+-					mv.visitVarInsn(ALOAD, 0);
+-					mv.visitMethodInsn(INVOKESPECIAL, MAPPED_OBJECT_JVM, "<init>", "()V");
+-					mv.visitInsn(RETURN);
+-					mv.visitMaxs(0, 0);
+-
+-					// put the method body in another method
+-					name = VIEW_CONSTRUCTOR_NAME;
+-				}
+-			}
+-
+-			final MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
+-			return new MethodNode(access, name, desc, signature, exceptions) {
+-
+-				/** When true, the method has touched a mapped object and needs to be transformed. We track this
+-				 * so we can skip the expensive frame analysis and tree API usage. */
+-				boolean needsTransformation;
+-
+-				@Override
+-				public void visitMaxs(int a, int b) {
+-					try {
+-						is_currently_computing_frames = true;
+-						super.visitMaxs(a, b);
+-					} finally {
+-						is_currently_computing_frames = false;
+-					}
+-				}
+-
+-				@Override
+-				public void visitFieldInsn(final int opcode, final String owner, final String name, final String desc) {
+-					if ( className_to_subtype.containsKey(owner) || owner.startsWith(MAPPEDSET_PREFIX) )
+-						needsTransformation = true;
+-
+-					super.visitFieldInsn(opcode, owner, name, desc);
+-				}
+-
+-				@Override
+-				public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) {
+-					if ( className_to_subtype.containsKey(owner) )
+-						needsTransformation = true;
+-
+-					super.visitMethodInsn(opcode, owner, name, desc);
+-				}
+-
+-				@Override
+-				public void visitEnd() {
+-					if ( needsTransformation ) { // Early-out for methods that do not touch a mapped object.
+-						//System.err.println("\nTRANSFORMING: " + className + "." + name + desc);
+-						transformed = true;
+-						try {
+-							transformMethod(analyse());
+-						} catch (Exception e) {
+-							throw new RuntimeException(e);
+-						}
+-					}
+-
+-					// Pass the instruction stream to the adapter's MethodVisitor
+-					accept(mv);
+-				}
+-
+-				private Frame<BasicValue>[] analyse() throws AnalyzerException {
+-					final Analyzer<BasicValue> a = new Analyzer<BasicValue>(new SimpleVerifier());
+-					a.analyze(className, this);
+-					return a.getFrames();
+-				}
+-
+-				private void transformMethod(final Frame<BasicValue>[] frames) {
+-					final InsnList instructions = this.instructions;
+-
+-					final Map<Integer, MappedSubtypeInfo> arrayVars = new HashMap<Integer, MappedSubtypeInfo>();
+-
+-					/*
+-					We need this map because we insert/remove instructions from the stream and we need a way
+-					to match each original instruction with the corresponding frame.
+-					TODO: Can we keep track of everything more efficiently without a map?
+-					 */
+-					final Map<AbstractInsnNode, Frame<BasicValue>> frameMap = new HashMap<AbstractInsnNode, Frame<BasicValue>>();
+-					for ( int i = 0; i < frames.length; i++ )
+-						frameMap.put(instructions.get(i), frames[i]);
+-
+-					for ( int i = 0; i < instructions.size(); i++ ) { // f is a separate cursor for frames
+-						final AbstractInsnNode instruction = instructions.get(i);
+-
+-						//System.out.println("MAIN LOOP #" + i + " - " + getOpcodeName(instruction));
+-
+-						switch ( instruction.getType() ) {
+-							case AbstractInsnNode.VAR_INSN:
+-								if ( instruction.getOpcode() == ALOAD ) {
+-									VarInsnNode varInsn = (VarInsnNode)instruction;
+-									final MappedSubtypeInfo mappedSubtype = arrayVars.get(varInsn.var);
+-									if ( mappedSubtype != null )
+-										i = transformArrayAccess(instructions, i, frameMap, varInsn, mappedSubtype, varInsn.var);
+-								}
+-								break;
+-							case AbstractInsnNode.FIELD_INSN:
+-								FieldInsnNode fieldInsn = (FieldInsnNode)instruction;
+-
+-								final InsnList list = transformFieldAccess(fieldInsn);
+-								if ( list != null )
+-									i = replace(instructions, i, instruction, list);
+-
+-								break;
+-							case AbstractInsnNode.METHOD_INSN:
+-								MethodInsnNode methodInsn = (MethodInsnNode)instruction;
+-								final MappedSubtypeInfo mappedType = className_to_subtype.get(methodInsn.owner);
+-								if ( mappedType != null )
+-									i = transformMethodCall(instructions, i, frameMap, methodInsn, mappedType, arrayVars);
+-								break;
+-						}
+-					}
+-				}
+-			};
+-		}
+-	}
+-
+-	static int transformMethodCall(final InsnList instructions, int i, final Map<AbstractInsnNode, Frame<BasicValue>> frameMap, final MethodInsnNode methodInsn, final MappedSubtypeInfo mappedType, final Map<Integer, MappedSubtypeInfo> arrayVars) {
+-		switch ( methodInsn.getOpcode() ) {
+-			case INVOKEVIRTUAL:
+-				if ( "asArray".equals(methodInsn.name) && methodInsn.desc.equals("()[L" + MAPPED_OBJECT_JVM + ";") ) {
+-					// Go forward and store the local variable index.
+-					// We only allow this pattern: INVOKEVIRTUAL -> CHECKCAST -> ASTORE.
+-					// We remove the first two and store the target MappedSubtype in the ASTORE variable
+-					AbstractInsnNode nextInstruction;
+-					checkInsnAfterIsArray(nextInstruction = methodInsn.getNext(), CHECKCAST);
+-					checkInsnAfterIsArray(nextInstruction = nextInstruction.getNext(), ASTORE);
+-
+-					final Frame<BasicValue> frame = frameMap.get(nextInstruction);
+-					final String targetType = frame.getStack(frame.getStackSize() - 1).getType().getElementType().getInternalName();
+-					if ( !methodInsn.owner.equals(targetType) ) {
+-						/*
+-						This may happen with the current API, like so:
+-							MappedA foo = MappedA.malloc(...);
+-							MappedB[] cursor = foo.asArray();
+-						We have to parameterize MappedObject to avoid this.
+-						 */
+-						throw new ClassCastException("Source: " + methodInsn.owner + " - Target: " + targetType);
+-					}
+-
+-					final VarInsnNode varInstruction = (VarInsnNode)nextInstruction;
+-
+-					arrayVars.put(varInstruction.var, mappedType);
+-
+-					instructions.remove(methodInsn.getNext()); // Remove CHECKCAST
+-					instructions.remove(methodInsn); // Remove INVOKEVIRTUAL
+-				}
+-
+-				if ( "dup".equals(methodInsn.name) && methodInsn.desc.equals("()L" + MAPPED_OBJECT_JVM + ";") ) {
+-					i = replace(instructions, i, methodInsn, generateDupInstructions(methodInsn));
+-					break;
+-				}
+-
+-				if ( "slice".equals(methodInsn.name) && methodInsn.desc.equals("()L" + MAPPED_OBJECT_JVM + ";") ) {
+-					i = replace(instructions, i, methodInsn, generateSliceInstructions(methodInsn));
+-					break;
+-				}
+-
+-				if ( "runViewConstructor".equals(methodInsn.name) && "()V".equals(methodInsn.desc) ) {
+-					i = replace(instructions, i, methodInsn, generateRunViewConstructorInstructions(methodInsn));
+-					break;
+-				}
+-
+-				if ( "copyTo".equals(methodInsn.name) && methodInsn.desc.equals("(L" + MAPPED_OBJECT_JVM + ";)V") ) {
+-					i = replace(instructions, i, methodInsn, generateCopyToInstructions(mappedType));
+-					break;
+-				}
+-
+-				if ( "copyRange".equals(methodInsn.name) && methodInsn.desc.equals("(L" + MAPPED_OBJECT_JVM + ";I)V") ) {
+-					i = replace(instructions, i, methodInsn, generateCopyRangeInstructions(mappedType));
+-					break;
+-				}
+-
+-				break;
+-			case INVOKESPECIAL:
+-				// super() in VIEW_CONSTRUCTOR_NAME, remove
+-				if ( methodInsn.owner.equals(MAPPED_OBJECT_JVM) && "<init>".equals(methodInsn.name) && "()V".equals(methodInsn.desc) ) {
+-					instructions.remove(methodInsn.getPrevious()); // ALOAD
+-					instructions.remove(methodInsn); // INVOKESPECIAL
+-
+-					i -= 2;
+-				}
+-				break;
+-			case INVOKESTATIC:
+-				boolean isMapDirectMethod = "map".equals(methodInsn.name) && methodInsn.desc.equals("(JI)L" + MAPPED_OBJECT_JVM + ";");
+-				boolean isMapBufferMethod = "map".equals(methodInsn.name) && methodInsn.desc.equals("(Ljava/nio/ByteBuffer;)L" + MAPPED_OBJECT_JVM + ";");
+-				boolean isMallocMethod = "malloc".equals(methodInsn.name) && methodInsn.desc.equals("(I)L" + MAPPED_OBJECT_JVM + ";");
+-
+-				if ( (isMapDirectMethod || isMapBufferMethod) || isMallocMethod )
+-					i = replace(instructions, i, methodInsn, generateMapInstructions(mappedType, methodInsn.owner, isMapDirectMethod, isMallocMethod));
+-				break;
+-		}
+-
+-		return i;
+-	}
+-
+-	private static InsnList generateCopyRangeInstructions(final MappedSubtypeInfo mappedType) {
+-		final InsnList list = new InsnList();
+-
+-		// stack: instances, target, this
+-		list.add(getIntNode(mappedType.sizeof));
+-		// stack: sizeof, instances, target, this
+-		list.add(new InsnNode(IMUL));
+-		// stack: bytes, target, this
+-		list.add(new MethodInsnNode(INVOKESTATIC, MAPPED_HELPER_JVM, "copy", "(L" + MAPPED_OBJECT_JVM + ";L" + MAPPED_OBJECT_JVM + ";I)V"));
+-		// stack: -
+-
+-		return list;
+-	}
+-
+-	private static InsnList generateCopyToInstructions(final MappedSubtypeInfo mappedType) {
+-		final InsnList list = new InsnList();
+-
+-		// stack: target, this
+-		list.add(getIntNode(mappedType.sizeof - mappedType.padding));
+-		// stack: sizeof, target, this
+-		list.add(new MethodInsnNode(INVOKESTATIC, MAPPED_HELPER_JVM, "copy", "(L" + MAPPED_OBJECT_JVM + ";L" + MAPPED_OBJECT_JVM + ";I)V"));
+-		// stack: -
+-
+-		return list;
+-	}
+-
+-	private static InsnList generateRunViewConstructorInstructions(final MethodInsnNode methodInsn) {
+-		final InsnList list = new InsnList();
+-
+-		// stack: this
+-		list.add(new InsnNode(DUP));
+-		// stack: this, this
+-		list.add(new MethodInsnNode(INVOKEVIRTUAL, methodInsn.owner, VIEW_CONSTRUCTOR_NAME, "()V"));
+-		// stack: this
+-
+-		return list;
+-	}
+-
+-	private static InsnList generateSliceInstructions(final MethodInsnNode methodInsn) {
+-		final InsnList list = new InsnList();
+-
+-		// stack: this
+-		list.add(new TypeInsnNode(NEW, methodInsn.owner));
+-		// stack: new, this
+-		list.add(new InsnNode(DUP));
+-		// stack: new, new, this
+-		list.add(new MethodInsnNode(INVOKESPECIAL, methodInsn.owner, "<init>", "()V"));
+-		// stack: new, this
+-		list.add(new MethodInsnNode(INVOKESTATIC, MAPPED_HELPER_JVM, "slice", "(L" + MAPPED_OBJECT_JVM + ";L" + MAPPED_OBJECT_JVM + ";)L" + MAPPED_OBJECT_JVM + ";"));
+-		// stack: new
+-
+-		return list;
+-	}
+-
+-	private static InsnList generateDupInstructions(final MethodInsnNode methodInsn) {
+-		final InsnList list = new InsnList();
+-
+-		// stack: this
+-		list.add(new TypeInsnNode(NEW, methodInsn.owner));
+-		// stack: new, this
+-		list.add(new InsnNode(DUP));
+-		// stack: new, new, this
+-		list.add(new MethodInsnNode(INVOKESPECIAL, methodInsn.owner, "<init>", "()V"));
+-		// stack: new, this
+-		list.add(new MethodInsnNode(INVOKESTATIC, MAPPED_HELPER_JVM, "dup", "(L" + MAPPED_OBJECT_JVM + ";L" + MAPPED_OBJECT_JVM + ";)L" + MAPPED_OBJECT_JVM + ";"));
+-		// stack: new
+-
+-		return list;
+-	}
+-
+-	private static InsnList generateMapInstructions(final MappedSubtypeInfo mappedType, final String className, final boolean mapDirectMethod, final boolean mallocMethod) {
+-		final InsnList trg = new InsnList();
+-
+-		if ( mallocMethod ) {
+-			// stack: count
+-			trg.add(getIntNode(mappedType.sizeof));
+-			// stack: sizeof, count
+-			trg.add(new InsnNode(IMUL));
+-			// stack: bytes
+-			trg.add(new MethodInsnNode(INVOKESTATIC, mappedType.cacheLinePadded ? jvmClassName(CacheUtil.class) : jvmClassName(BufferUtils.class), "createByteBuffer", "(I)L" + jvmClassName(ByteBuffer.class) + ";"));
+-			// stack: buffer
+-		} else if ( mapDirectMethod ) {
+-			// stack: capacity, address
+-			trg.add(new MethodInsnNode(INVOKESTATIC, MAPPED_HELPER_JVM, "newBuffer", "(JI)L" + jvmClassName(ByteBuffer.class) + ";"));
+-			// stack: buffer
+-		}
+-
+-		// stack: buffer
+-		trg.add(new TypeInsnNode(NEW, className));
+-		// stack: new, buffer
+-		trg.add(new InsnNode(DUP));
+-		// stack: new, new, buffer
+-		trg.add(new MethodInsnNode(INVOKESPECIAL, className, "<init>", "()V"));
+-		// stack: new, buffer
+-		trg.add(new InsnNode(DUP_X1));
+-		// stack: new, buffer, new
+-		trg.add(new InsnNode(SWAP));
+-		// stack: buffer, new, new
+-		trg.add(getIntNode(mappedType.align));
+-		// stack: int, buffer, new, new
+-		trg.add(getIntNode(mappedType.sizeof));
+-		// stack: int, int, buffer, new, new
+-		trg.add(new MethodInsnNode(INVOKESTATIC, MAPPED_HELPER_JVM, "setup", "(L" + MAPPED_OBJECT_JVM + ";Ljava/nio/ByteBuffer;II)V"));
+-		// stack: new
+-
+-		return trg;
+-	}
+-
+-	static InsnList transformFieldAccess(final FieldInsnNode fieldInsn) {
+-		final MappedSubtypeInfo mappedSubtype;
+-		mappedSubtype = className_to_subtype.get(fieldInsn.owner);
+-		if ( mappedSubtype == null ) { // early out
+-			// MappedSet.view
+-			outer:
+-			if ( "view".equals(fieldInsn.name) && fieldInsn.owner.startsWith(MAPPEDSET_PREFIX) )
+-				return generateSetViewInstructions(fieldInsn);
+-
+-			return null; // early out
+-		}
+-
+-		if ( "SIZEOF".equals(fieldInsn.name) )
+-			return generateSIZEOFInstructions(fieldInsn, mappedSubtype);
+-
+-		if ( "view".equals(fieldInsn.name) )
+-			return generateViewInstructions(fieldInsn, mappedSubtype);
+-
+-		if ( "baseAddress".equals(fieldInsn.name) || "viewAddress".equals(fieldInsn.name) ) {
+-			return generateAddressInstructions(fieldInsn);
+-		}
+-
+-		final FieldInfo field = mappedSubtype.fields.get(fieldInsn.name);
+-		if ( field == null ) // early out
+-			return null;
+-
+-		// now we're going to transform ByteBuffer-typed field access
+-		if ( fieldInsn.desc.equals("L" + jvmClassName(ByteBuffer.class) + ";") )
+-			return generateByteBufferInstructions(fieldInsn, mappedSubtype, field.offset);
+-
+-		// we're now going to transform the field access
+-		return generateFieldInstructions(fieldInsn, field);
+-	}
+-
+-	private static InsnList generateSetViewInstructions(final FieldInsnNode fieldInsn) {
+-		if ( fieldInsn.getOpcode() == GETFIELD )
+-			throwAccessErrorOnReadOnlyField(fieldInsn.owner, fieldInsn.name);
+-		if ( fieldInsn.getOpcode() != PUTFIELD )
+-			throw new InternalError();
+-
+-		final InsnList list = new InsnList();
+-
+-		// stack: index, this
+-		if ( MAPPED_SET2_JVM.equals(fieldInsn.owner) )
+-			list.add(new MethodInsnNode(INVOKESTATIC, MAPPED_HELPER_JVM, "put_views", "(L" + MAPPED_SET2_JVM + ";I)V"));
+-		else if ( MAPPED_SET3_JVM.equals(fieldInsn.owner) )
+-			list.add(new MethodInsnNode(INVOKESTATIC, MAPPED_HELPER_JVM, "put_views", "(L" + MAPPED_SET3_JVM + ";I)V"));
+-		else if ( MAPPED_SET4_JVM.equals(fieldInsn.owner) )
+-			list.add(new MethodInsnNode(INVOKESTATIC, MAPPED_HELPER_JVM, "put_views", "(L" + MAPPED_SET4_JVM + ";I)V"));
+-		else
+-			throw new InternalError();
+-		// stack: -
+-
+-		return list;
+-	}
+-
+-	private static InsnList generateSIZEOFInstructions(final FieldInsnNode fieldInsn, final MappedSubtypeInfo mappedSubtype) {
+-		if ( !"I".equals(fieldInsn.desc) )
+-			throw new InternalError();
+-
+-		final InsnList list = new InsnList();
+-
+-		if ( fieldInsn.getOpcode() == GETSTATIC ) {
+-			list.add(getIntNode(mappedSubtype.sizeof));
+-			return list;
+-		}
+-
+-		if ( fieldInsn.getOpcode() == PUTSTATIC )
+-			throwAccessErrorOnReadOnlyField(fieldInsn.owner, fieldInsn.name);
+-
+-		throw new InternalError();
+-	}
+-
+-	private static InsnList generateViewInstructions(final FieldInsnNode fieldInsn, final MappedSubtypeInfo mappedSubtype) {
+-		if ( !"I".equals(fieldInsn.desc) )
+-			throw new InternalError();
+-
+-		final InsnList list = new InsnList();
+-
+-		if ( fieldInsn.getOpcode() == GETFIELD ) {
+-			if ( mappedSubtype.sizeof_shift != 0 ) {
+-				// stack: instance
+-				list.add(getIntNode(mappedSubtype.sizeof_shift));
+-				// stack: sizeof, instance
+-				list.add(new MethodInsnNode(INVOKESTATIC, MAPPED_HELPER_JVM, "get_view_shift", "(L" + MAPPED_OBJECT_JVM + ";I)I"));
+-				// stack: view
+-			} else {
+-				// stack: instance
+-				list.add(getIntNode(mappedSubtype.sizeof));
+-				// stack: sizeof, instance
+-				list.add(new MethodInsnNode(INVOKESTATIC, MAPPED_HELPER_JVM, "get_view", "(L" + MAPPED_OBJECT_JVM + ";I)I"));
+-				// stack: view
+-			}
+-			return list;
+-		}
+-
+-		if ( fieldInsn.getOpcode() == PUTFIELD ) {
+-			if ( mappedSubtype.sizeof_shift != 0 ) {
+-				// stack: view, instance
+-				list.add(getIntNode(mappedSubtype.sizeof_shift));
+-				// stack: sizeof, view, instance
+-				list.add(new MethodInsnNode(INVOKESTATIC, MAPPED_HELPER_JVM, "put_view_shift", "(L" + MAPPED_OBJECT_JVM + ";II)V"));
+-				// stack: -
+-			} else {
+-				// stack: view, instance
+-				list.add(getIntNode(mappedSubtype.sizeof));
+-				// stack: sizeof, view, instance
+-				list.add(new MethodInsnNode(INVOKESTATIC, MAPPED_HELPER_JVM, "put_view", "(L" + MAPPED_OBJECT_JVM + ";II)V"));
+-				// stack: -
+-			}
+-			return list;
+-		}
+-
+-		throw new InternalError();
+-	}
+-
+-	private static InsnList generateAddressInstructions(final FieldInsnNode fieldInsn) {
+-		if ( !"J".equals(fieldInsn.desc) )
+-			throw new IllegalStateException();
+-
+-		if ( fieldInsn.getOpcode() == GETFIELD ) // do not change a thing
+-			return null;
+-
+-		if ( fieldInsn.getOpcode() == PUTFIELD )
+-			throwAccessErrorOnReadOnlyField(fieldInsn.owner, fieldInsn.name);
+-
+-		throw new InternalError();
+-	}
+-
+-	private static InsnList generateByteBufferInstructions(final FieldInsnNode fieldInsn, final MappedSubtypeInfo mappedSubtype, final long fieldOffset) {
+-		if ( fieldInsn.getOpcode() == PUTFIELD )
+-			throwAccessErrorOnReadOnlyField(fieldInsn.owner, fieldInsn.name);
+-
+-		if ( fieldInsn.getOpcode() == GETFIELD ) {
+-			final InsnList list = new InsnList();
+-
+-			// stack: ref
+-			list.add(new FieldInsnNode(GETFIELD, mappedSubtype.className, "viewAddress", "J"));
+-			// stack: long
+-			list.add(new LdcInsnNode(fieldOffset));
+-			// stack: long, long
+-			list.add(new InsnNode(LADD));
+-			// stack: long
+-			list.add(new LdcInsnNode(mappedSubtype.fields.get(fieldInsn.name).length));
+-			// stack: long, long
+-			list.add(new InsnNode(L2I));
+-			// stack: int, long
+-			list.add(new MethodInsnNode(INVOKESTATIC, MAPPED_HELPER_JVM, "newBuffer", "(JI)L" + jvmClassName(ByteBuffer.class) + ";"));
+-			// stack: buffer
+-
+-			return list;
+-		}
+-
+-		throw new InternalError();
+-	}
+-
+-	private static InsnList generateFieldInstructions(final FieldInsnNode fieldInsn, final FieldInfo field) {
+-		final InsnList list = new InsnList();
+-
+-		if ( fieldInsn.getOpcode() == PUTFIELD ) {
+-			// stack: value, ref
+-			list.add(getIntNode((int)field.offset));
+-			// stack: fieldOffset, value, ref
+-			list.add(new MethodInsnNode(INVOKESTATIC, MAPPED_HELPER_JVM, field.getAccessType() + "put", "(L" + MAPPED_OBJECT_JVM + ";" + fieldInsn.desc + "I)V"));
+-			// stack -
+-			return list;
+-		}
+-
+-		if ( fieldInsn.getOpcode() == GETFIELD ) {
+-			// stack: ref
+-			list.add(getIntNode((int)field.offset));
+-			// stack: fieldOffset, ref
+-			list.add(new MethodInsnNode(INVOKESTATIC, MAPPED_HELPER_JVM, field.getAccessType() + "get", "(L" + MAPPED_OBJECT_JVM + ";I)" + fieldInsn.desc));
+-			// stack: -
+-			return list;
+-		}
+-
+-		throw new InternalError();
+-	}
+-
+-	static int transformArrayAccess(final InsnList instructions, int i, final Map<AbstractInsnNode, Frame<BasicValue>> frameMap, final VarInsnNode loadInsn, final MappedSubtypeInfo mappedSubtype, final int var) {
+-		// We need to go forward in time to find how we use the array var
+-		final int loadStackSize = frameMap.get(loadInsn).getStackSize() + 1;
+-
+-		AbstractInsnNode nextInsn = loadInsn;
+-
+-		while ( true ) {
+-			nextInsn = nextInsn.getNext();
+-			if ( nextInsn == null )
+-				throw new InternalError();
+-
+-			Frame<BasicValue> frame = frameMap.get(nextInsn);
+-			if ( frame == null )
+-				continue;
+-
+-			int stackSize = frame.getStackSize();
+-
+-			if ( stackSize == loadStackSize + 1 && nextInsn.getOpcode() == AALOAD ) {
+-				final AbstractInsnNode aaLoadInsn = nextInsn;
+-
+-				while ( true ) {
+-					nextInsn = nextInsn.getNext();
+-					if ( nextInsn == null )
+-						break;
+-
+-					frame = frameMap.get(nextInsn);
+-					if ( frame == null )
+-						continue;
+-					stackSize = frame.getStackSize();
+-
+-					if ( stackSize == loadStackSize + 1 && nextInsn.getOpcode() == PUTFIELD ) {
+-						final FieldInsnNode fieldInsn = (FieldInsnNode)nextInsn;
+-
+-						// stack: value, view, ref
+-						instructions.insert(nextInsn, new MethodInsnNode(INVOKESTATIC, mappedSubtype.className, setterName(fieldInsn.name), "(L" + mappedSubtype.className + ";I" + fieldInsn.desc + ")V"));
+-						// stack: -
+-						instructions.remove(nextInsn);
+-
+-						break;
+-					} else if ( stackSize == loadStackSize && nextInsn.getOpcode() == GETFIELD ) {
+-						final FieldInsnNode fieldInsn = (FieldInsnNode)nextInsn;
+-
+-						// stack: view, ref
+-						instructions.insert(nextInsn, new MethodInsnNode(INVOKESTATIC, mappedSubtype.className, getterName(fieldInsn.name), "(L" + mappedSubtype.className + ";I)" + fieldInsn.desc));
+-						// stack: value
+-						instructions.remove(nextInsn);
+-
+-						break;
+-					} else if ( stackSize == loadStackSize && nextInsn.getOpcode() == DUP && nextInsn.getNext().getOpcode() == GETFIELD ) {
+-						// May happen with operator+assignment (e.g. cursor[i].value += 10)
+-						final FieldInsnNode fieldInsn = (FieldInsnNode)nextInsn.getNext();
+-
+-						final MethodInsnNode getter = new MethodInsnNode(INVOKESTATIC, mappedSubtype.className, getterName(fieldInsn.name), "(L" + mappedSubtype.className + ";I)" + fieldInsn.desc);
+-
+-						// stack: view, ref
+-						instructions.insert(nextInsn, new InsnNode(DUP2));
+-						// stack: view, ref, view, ref
+-						instructions.insert(nextInsn.getNext(), getter);
+-						// stack: value, view, ref
+-
+-						instructions.remove(nextInsn);
+-						instructions.remove(fieldInsn);
+-
+-						nextInsn = getter;
+-						continue;
+-					} else if ( stackSize < loadStackSize )
+-						throw new ClassFormatError("Invalid " + mappedSubtype.className + " view array usage detected: " + getOpcodeName(nextInsn));
+-				}
+-
+-				instructions.remove(aaLoadInsn);
+-
+-				return i;
+-			} else if ( stackSize == loadStackSize && nextInsn.getOpcode() == ARRAYLENGTH ) {
+-				if ( LWJGLUtil.DEBUG && loadInsn.getNext() != nextInsn )
+-					throw new InternalError();
+-
+-				instructions.remove(nextInsn);
+-				loadInsn.var = var;
+-				instructions.insert(loadInsn, new MethodInsnNode(INVOKEVIRTUAL, mappedSubtype.className, CAPACITY_METHOD_NAME, "()I"));
+-
+-				return i + 1;
+-			} else if ( stackSize < loadStackSize ) // Consumed by something other than AALOAD or ARRAYLENGTH
+-				throw new ClassFormatError("Invalid " + mappedSubtype.className + " view array usage detected: " + getOpcodeName(nextInsn));
+-		}
+-	}
+-
+-	private static class FieldInfo {
+-
+-		final long    offset;
+-		final long    length;
+-		final long    lengthPadded;
+-		final Type    type;
+-		final boolean isVolatile;
+-		final boolean isPointer;
+-
+-		FieldInfo(final long offset, final long length, final long lengthPadded, final Type type, final boolean isVolatile, final boolean isPointer) {
+-			this.offset = offset;
+-			this.length = length;
+-			this.lengthPadded = lengthPadded;
+-			this.type = type;
+-			this.isVolatile = isVolatile;
+-			this.isPointer = isPointer;
+-		}
+-
+-		String getAccessType() {
+-			return isPointer ? "a" : type.getDescriptor().toLowerCase() + (isVolatile ? "v" : "");
+-		}
+-
+-	}
+-
+-	private static class MappedSubtypeInfo {
+-
+-		final String className;
+-
+-		final int     sizeof;
+-		final int     sizeof_shift;
+-		final int     align;
+-		final int     padding;
+-		final boolean cacheLinePadded;
+-
+-		final Map<String, FieldInfo> fields;
+-
+-		MappedSubtypeInfo(String className, Map<String, FieldInfo> fields, int sizeof, int align, int padding, final boolean cacheLinePadded) {
+-			this.className = className;
+-
+-			this.sizeof = sizeof;
+-			if ( ((sizeof - 1) & sizeof) == 0 )
+-				this.sizeof_shift = getPoT(sizeof);
+-			else
+-				this.sizeof_shift = 0;
+-			this.align = align;
+-			this.padding = padding;
+-			this.cacheLinePadded = cacheLinePadded;
+-
+-			this.fields = fields;
+-		}
+-
+-		private static int getPoT(int value) {
+-			int pot = -1;
+-			while ( value > 0 ) {
+-				pot++;
+-				value >>= 1;
+-			}
+-			return pot;
+-		}
+-
+-	}
+-
+-	// -------------------------------------------------------
+-	// -------------------[ MACROS & UTILS ]------------------
+-	// -------------------------------------------------------
+-
+-	private static void getClassEnums(final Class clazz, final Map<Integer, String> map, final String... prefixFilters) {
+-		try {
+-			OUTER:
+-			for ( Field field : clazz.getFields() ) {
+-				if ( !Modifier.isStatic(field.getModifiers()) || field.getType() != int.class )
+-					continue;
+-
+-				for ( String filter : prefixFilters ) {
+-					if ( field.getName().startsWith(filter) )
+-						continue OUTER;
+-				}
+-
+-				if ( map.put((Integer)field.get(null), field.getName()) != null )
+-					throw new IllegalStateException();
+-			}
+-		} catch (Exception e) {
+-			e.printStackTrace();
+-		}
+-	}
+-
+-	static String getOpcodeName(final AbstractInsnNode insn) {
+-		final String op = OPCODE_TO_NAME.get(insn.getOpcode());
+-		return INSNTYPE_TO_NAME.get(insn.getType()) + ": " + insn.getOpcode() + (op == null ? "" : " [" + OPCODE_TO_NAME.get(insn.getOpcode()) + "]");
+-	}
+-
+-	static String jvmClassName(Class<?> type) {
+-		return type.getName().replace('.', '/');
+-	}
+-
+-	static String getterName(final String fieldName) {
+-		return "get$" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1) + "$LWJGL";
+-	}
+-
+-	static String setterName(final String fieldName) {
+-		return "set$" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1) + "$LWJGL";
+-	}
+-
+-	private static void checkInsnAfterIsArray(final AbstractInsnNode instruction, final int opcode) {
+-		if ( instruction == null )
+-			throw new ClassFormatError("Unexpected end of instructions after .asArray() method.");
+-
+-		if ( instruction.getOpcode() != opcode )
+-			throw new ClassFormatError("The result of .asArray() must be stored to a local variable. Found: " + getOpcodeName(instruction));
+-	}
+-
+-	static AbstractInsnNode getIntNode(final int value) {
+-		if ( value <= 5 && -1 <= value )
+-			return new InsnNode(ICONST_M1 + value + 1);
+-
+-		if ( value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE )
+-			return new IntInsnNode(BIPUSH, value);
+-
+-		if ( value >= Short.MIN_VALUE && value <= Short.MAX_VALUE )
+-			return new IntInsnNode(SIPUSH, value);
+-
+-		return new LdcInsnNode(value);
+-	}
+-
+-	static void visitIntNode(final MethodVisitor mv, final int value) {
+-		if ( value <= 5 && -1 <= value )
+-			mv.visitInsn(ICONST_M1 + value + 1);
+-		else if ( value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE )
+-			mv.visitIntInsn(BIPUSH, value);
+-		else if ( value >= Short.MIN_VALUE && value <= Short.MAX_VALUE )
+-			mv.visitIntInsn(SIPUSH, value);
+-		else
+-			mv.visitLdcInsn(value);
+-	}
+-
+-	/** Replace an instruction with a list of instructions. */
+-	static int replace(final InsnList instructions, final int i, final AbstractInsnNode location, final InsnList list) {
+-		final int size = list.size();
+-
+-		instructions.insert(location, list);
+-		instructions.remove(location);
+-
+-		return i + (size - 1);
+-	}
+-
+-	private static void throwAccessErrorOnReadOnlyField(String className, String fieldName) {
+-		throw new IllegalAccessError("The " + className + "." + fieldName + " field is final.");
+-	}
+-
+-	private static void printBytecode(byte[] bytecode) {
+-		StringWriter sw = new StringWriter();
+-		ClassVisitor tracer = new TraceClassVisitor(new ClassWriter(0), new PrintWriter(sw));
+-		new ClassReader(bytecode).accept(tracer, 0);
+-		String dump = sw.toString();
+-
+-		LWJGLUtil.log(dump);
+-	}
+-
+-}
+\ No newline at end of file
diff --git a/debian/patches/series b/debian/patches/series
index 0b1e96c..fde7631 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -4,3 +4,4 @@ allarchs.patch
 ppc64el.patch
 systemjinput.patch
 build-failure.patch
+no-asm-support.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/lwjgl.git



More information about the pkg-java-commits mailing list