Bug 443588 - [otdre] AIOOBE in ASM due to bad replacement of return
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AbstractTransformableClassNode.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AbstractTransformableClassNode.java
index 3bd0b12..3b6bb7a 100644
--- a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AbstractTransformableClassNode.java
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AbstractTransformableClassNode.java
@@ -231,7 +231,6 @@
 	 * @param instructions

 	 * @param returnType

 	 */

-	@SuppressWarnings("unchecked")

 	protected void replaceReturn(InsnList instructions, Type returnType) {

 		if (returnType.getSort() != Type.OBJECT &&

 				returnType.getSort() != Type.ARRAY &&

@@ -240,9 +239,9 @@
 			while (orgMethodIter.hasNext()) {

 				AbstractInsnNode orgMethodNode = orgMethodIter.next();

 				if (orgMethodNode.getOpcode() == returnType.getOpcode(Opcodes.IRETURN)) {

+					instructions.insertBefore(orgMethodNode, AsmTypeHelper.getBoxingInstructionForType(returnType));

+					instructions.insertBefore(orgMethodNode, new InsnNode(Opcodes.ARETURN));

 					instructions.remove(orgMethodNode);

-					instructions.add(AsmTypeHelper.getBoxingInstructionForType(returnType));

-					instructions.add(new InsnNode(Opcodes.ARETURN));

 				}

 			}

 		} else if (returnType.getSort() == Type.VOID) {

@@ -250,11 +249,11 @@
 			while (orgMethodIter.hasNext()) {

 				AbstractInsnNode orgMethodNode = orgMethodIter.next();

 				if (orgMethodNode.getOpcode() == Opcodes.RETURN) {

+					instructions.insertBefore(orgMethodNode, new InsnNode(Opcodes.ACONST_NULL));

+					instructions.insertBefore(orgMethodNode, new InsnNode(Opcodes.ARETURN));

 					instructions.remove(orgMethodNode);

 				}

 			}

-			instructions.add(new InsnNode(Opcodes.ACONST_NULL));

-			instructions.add(new InsnNode(Opcodes.ARETURN));

 		}

 	}

 

diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AsmWritableBoundClass.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AsmWritableBoundClass.java
index 49c94e7..ce8deb8 100644
--- a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AsmWritableBoundClass.java
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AsmWritableBoundClass.java
@@ -112,11 +112,19 @@
 		

 		reader = new ClassReader(allocateAndGetBytecode());

 

-		writer = new LoaderAwareClassWriter(reader, ClassWriter.COMPUTE_FRAMES, this.loader);

+		writer = getClassWriter();

 		multiAdapter = new MultiClassAdapter(writer);

 		nodes = new ArrayList<AbstractTransformableClassNode>();

 		isTransformationActive = true;

 	}

+

+	LoaderAwareClassWriter getClassWriter() {

+		int flags = ClassWriter.COMPUTE_FRAMES;

+// DEBUG: when frame computation throws an exception, enable dumping of class file without frames computed:

+//		if (getName().contains("JUnitLaunchConfigurationDelegate"))

+//			flags = 0;

+		return new LoaderAwareClassWriter(reader, flags, this.loader);

+	}

 	

 	/**

 	 * Is the class manipulated right now.

@@ -141,7 +149,7 @@
 			reader = new ClassReader(allocateAndGetBytecode());

 			reader.accept(node, ClassReader.SKIP_FRAMES);

 			if (node.transform()) {

-				writer = new LoaderAwareClassWriter(reader, ClassWriter.COMPUTE_FRAMES, this.loader);

+				writer = getClassWriter();

 				node.accept(writer);

 				setBytecode(writer.toByteArray());

 			}