Bug 547847 - [otdre] conflicting local indices in _OT$callOrig regarding
argument-less method
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 01d4555..0284d92 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
@@ -1,7 +1,7 @@
 /**********************************************************************

  * This file is part of "Object Teams Dynamic Runtime Environment"

  * 

- * Copyright 2009, 2015 Oliver Frank and others.

+ * Copyright 2009, 2019 Oliver Frank and others.

  * 

  * All rights reserved. This program and the accompanying materials

  * are made available under the terms of the Eclipse Public License v1.0

@@ -420,15 +420,16 @@
 	 * Add a local variable to be visible from 'start' to 'end'.

 	 * Checks whether a local variable of that name already exists, in which case we don't change anything.

 	 * TODO: should check if ranges of both variables overlap!

-	 * @param fullRange TODO

+	 * @param fullRange if true we do not check ranges but avoid *any* duplication by name

 	 */

 	protected void addLocal(MethodNode method, String selector, String desc, int slot, LabelNode start, LabelNode end, boolean fullRange) {

 		if (!IS_DEBUG) return;

-		if (fullRange) {

-			for (Object lv : method.localVariables) {

-				if (((LocalVariableNode)lv).name.equals(selector)) {

+		for (Object lv : method.localVariables) {

+			LocalVariableNode lvNode = (LocalVariableNode)lv;

+			if (lvNode.name.equals(selector)) {

+				if (fullRange||

+						(lvNode.start.equals(start) && lvNode.end.equals(end)))

 					return;

-				}

 			}

 		}

         method.localVariables.add(new LocalVariableNode(selector, desc, null, start, end, slot));

diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/MoveCodeToCallOrigAdapter.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/MoveCodeToCallOrigAdapter.java
index 3f68704..79e71e0 100644
--- a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/MoveCodeToCallOrigAdapter.java
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/MoveCodeToCallOrigAdapter.java
@@ -96,12 +96,13 @@
 			addLineNumber(newInstructions, line);

 		int boundMethodIdSlot = firstArgIndex;

 		

+		// move boundMethodId to a higher slot, to make lower slots available for original locals

+		newInstructions.add(new VarInsnNode(Opcodes.ILOAD, boundMethodIdSlot));

+		boundMethodIdSlot = orgMethod.maxLocals+1;

+		addLocal(callOrig, BOUND_METHOD_ID, "I", boundMethodIdSlot, start, end, false);

+		newInstructions.add(new VarInsnNode(Opcodes.ISTORE, boundMethodIdSlot));

+

 		if (args.length > 0) {

-			// move boundMethodId to a higher slot, to make lower slots available for original locals

-			newInstructions.add(new VarInsnNode(Opcodes.ILOAD, boundMethodIdSlot));

-			boundMethodIdSlot = orgMethod.maxLocals+1;

-			addLocal(callOrig, BOUND_METHOD_ID, "I", boundMethodIdSlot, start, end, false);

-			newInstructions.add(new VarInsnNode(Opcodes.ISTORE, boundMethodIdSlot));

 			

 			newInstructions.add(new VarInsnNode(Opcodes.ALOAD, firstArgIndex + argOffset + 1));

 			

@@ -128,8 +129,6 @@
 					addLocal(callOrig, origLocals.get(origLocalIdx).name, arg.getDescriptor(), slot, start, end, false);

 				slot += arg.getSize();

 			}

-		} else {

-			addLocal(callOrig, BOUND_METHOD_ID, "I", boundMethodIdSlot, start, end, false);

 		}

 

 		InsnList orgInstructions = orgMethod.instructions;