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;