Bug 397182 - Prepare OTDT for new (dynamic) weaver
- callin-to-constructor (passes 3/4)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/bytecode/OTDynCallinBindingsAttribute.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/bytecode/OTDynCallinBindingsAttribute.java
index c622712..d3b7018 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/bytecode/OTDynCallinBindingsAttribute.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/bytecode/OTDynCallinBindingsAttribute.java
@@ -244,7 +244,7 @@
 				baseFlags |= BaseMethod.CALLIN;
 			if (baseSpec.isStatic())
 				baseFlags |= BaseMethod.STATIC;
-			mapping.addBaseMethod(i, baseSpec.selector, baseSpec.signature(), baseSpec.resolvedMethod.declaringClass.constantPoolName(), baseSpec.getCallinId(this.theTeam), baseFlags, baseSpec.getTranslationFlags());
+			mapping.addBaseMethod(i, baseSpec.codegenSeletor(), baseSpec.signature(), baseSpec.resolvedMethod.declaringClass.constantPoolName(), baseSpec.getCallinId(this.theTeam), baseFlags, baseSpec.getTranslationFlags());
 		}
 		mapping.setSMAPinfo(callinDecl);
 		this.mappings.add(mapping);
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 7952497..2afde55 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
@@ -208,6 +208,7 @@
 	 */

 	@Override

 	protected void moveCodeToCallOrig(Method boundMethod, int boundMethodId) {

+		if (boundMethod.getName().equals("<init>")) return; // don't move constructor code

 		assert (isTransformationActive) : "No transformation active";

 		nodes.add(new MoveCodeToCallOrigAdapter(this, boundMethod, boundMethodId));

 	}

diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/CreateCallAllBindingsCallInOrgMethod.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/CreateCallAllBindingsCallInOrgMethod.java
index bb067c4..6dfb191 100644
--- a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/CreateCallAllBindingsCallInOrgMethod.java
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/CreateCallAllBindingsCallInOrgMethod.java
@@ -21,6 +21,7 @@
 import org.eclipse.objectteams.otredyn.transformer.names.ConstantMembers;

 import org.objectweb.asm.Opcodes;

 import org.objectweb.asm.Type;

+import org.objectweb.asm.tree.AbstractInsnNode;

 import org.objectweb.asm.tree.InsnList;

 import org.objectweb.asm.tree.InsnNode;

 import org.objectweb.asm.tree.IntInsnNode;

@@ -54,28 +55,80 @@
 	@Override

 	public void transform() {

 		MethodNode method = getMethod(orgMethod);

-		method.instructions.clear();

+

+//		if (method.name.equals("<init>")) {

+//			int size = method.instructions.size();

+//			for (int i = 0; i < size; i++) {

+//				AbstractInsnNode insn = method.instructions.get(i);

+//				System.out.println(insn+" "+insn.getOpcode());

+//			}

+//		}

+//		System.out.println("================");

+

+		AbstractInsnNode insertBefore = null;

+		if (orgMethod.getName().equals("<init>")) {

+			// keep instructions, find insertion point:

+			int last = method.instructions.size();

+			LabelNode callAll = new LabelNode();

+			while (--last >= 0) {

+				if (method.instructions.get(last).getOpcode() == Opcodes.RETURN) {

+					AbstractInsnNode ret = method.instructions.get(last);

+					method.instructions.set(ret, callAll);					

+					insertBefore = callAll;

+					break;

+				}

+			}

+			if (insertBefore == null)

+				throw new IllegalStateException("Insertion point for weaving into ctor not found!!!");

+

+// FIXME: triggers NPE in MethodVisitor.visitMaxs

+//			// replace RETURN with GOTO

+//			for (int i=0; i<last; i++) {

+//				AbstractInsnNode current = method.instructions.get(i);

+//				if (current.getOpcode() == Opcodes.RETURN)

+//					method.instructions.set(current, new JumpInsnNode(Opcodes.GOTO, callAll));

+//			}

+

+		} else {

+			method.instructions.clear();

+		}

 

 		// start of try-block:

+		InsnList newInstructions = new InsnList();

 		LabelNode start = new LabelNode();

-		method.instructions.add(start);

+		newInstructions.add(start);

 

 		// put this on the stack

-		method.instructions.add(new IntInsnNode(Opcodes.ALOAD, 0));

+		newInstructions.add(new IntInsnNode(Opcodes.ALOAD, 0));

 		// put boundMethodId on the stack

-		method.instructions.add(createLoadIntConstant(boundMethodId));

+		newInstructions.add(createLoadIntConstant(boundMethodId));

 		Type[] args = Type.getArgumentTypes(method.desc);

 		// box the arguments

-		method.instructions.add(getBoxingInstructions(args, false));

+		newInstructions.add(getBoxingInstructions(args, false));

 

 		// this.callAllBindings(boundMethodId, args);

-		method.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,

+		newInstructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,

 				this.name, ConstantMembers.callAllBindingsClient.getName(),

 				ConstantMembers.callAllBindingsClient.getSignature()));

 		Type returnType = Type.getReturnType(method.desc);

-		method.instructions

+		newInstructions

 				.add(getUnboxingInstructionsForReturnValue(returnType));

+		

+		if (insertBefore != null) {

+			method.instructions.insertBefore(insertBefore, newInstructions);

+			method.instructions.remove(insertBefore); // remove extra RETURN

+		} else {

+			method.instructions.add(newInstructions);

+		}

 

+//		if (method.name.equals("<init>")) {

+//			int size = method.instructions.size();

+//			for (int i = 0; i < size; i++) {

+//				AbstractInsnNode insn = method.instructions.get(i);

+//				System.out.println(insn+" "+insn.getOpcode());

+//			}

+//		}

+		

 		// catch and unwrap SneakyException:

 		addCatchSneakyException(method, start);

 

diff --git a/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/callinbinding/CallinMethodBinding.java b/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/callinbinding/CallinMethodBinding.java
index 561f953..3cffef7 100644
--- a/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/callinbinding/CallinMethodBinding.java
+++ b/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/callinbinding/CallinMethodBinding.java
@@ -33,7 +33,7 @@
 	// Static initializer to specify tests subset using TESTS_* static variables
 	// All specified tests which does not belong to the class are skipped...
 	static {
-//		TESTS_NAMES = new String[] { "test4143_callinToTeamMethod" };
+//		TESTS_NAMES = new String[] { "test4146_callinToConstructor4" };
 //		TESTS_NUMBERS = new int[] { 1459 };
 //		TESTS_RANGE = new int[] { 1097, -1 };
 	}
@@ -7896,23 +7896,23 @@
     public void test4146_callinToConstructor3() {
     	runConformTest(
     		new String[] {
-    			"Team4146ctc1.java",
-    			"public team class Team4146ctc1 {\n" +
-    			"	protected class R playedBy T4146ctc1 {\n" +
+    			"Team4146ctc3.java",
+    			"public team class Team4146ctc3 {\n" +
+    			"	protected class R playedBy T4146ctc3 {\n" +
     			"		void print(String prefix, int n) {\n" +
     			"			for (int i=0; i<n; i++)\n" +
     			"				System.out.print(prefix);\n" +
     			"		}" +
-    			"		print <- after T4146ctc1;\n" +
+    			"		print <- after T4146ctc3;\n" +
     			"	}\n" +
     			"	public static void main(String... args) {\n" +
-    			"		new Team4146ctc1().activate();\n" +
-    			"		new T4146ctc1(\"_\", 3).test();\n" +
+    			"		new Team4146ctc3().activate();\n" +
+    			"		new T4146ctc3(\"_\", 3).test();\n" +
     			"	}\n" +
     			"}\n",
-    			"T4146ctc1.java",
-    			"public class T4146ctc1 {\n" +
-    			"	T4146ctc1(String prefix, int n) { System.out.print('O'); }\n" +
+    			"T4146ctc3.java",
+    			"public class T4146ctc3 {\n" +
+    			"	T4146ctc3(String prefix, int n) { System.out.print('O'); }\n" +
     			"	public void test() { System.out.print('!'); }\n" +
     			"}\n"
     		},
@@ -7923,23 +7923,23 @@
     public void test4146_callinToConstructor4() {
     	runConformTest(
     		new String[] {
-    			"Team4146ctc1.java",
-    			"public team class Team4146ctc1 {\n" +
-    			"	protected class R playedBy T4146ctc1 {\n" +
+    			"Team4146ctc4.java",
+    			"public team class Team4146ctc4 {\n" +
+    			"	protected class R playedBy T4146ctc4 {\n" +
     			"		void print(String prefix, int n) {\n" +
     			"			for (int i=0; i<n; i++)\n" +
     			"				System.out.print(prefix);\n" +
     			"		}" +
-    			"		print <- after T4146ctc1;\n" +
+    			"		print <- after T4146ctc4;\n" +
     			"	}\n" +
     			"	public static void main(String... args) {\n" +
-    			"		new Team4146ctc1().activate();\n" +
-    			"		new T4146ctc1(\"_\", 3).test();\n" +
+    			"		new Team4146ctc4().activate();\n" +
+    			"		new T4146ctc4(\"_\", 3).test();\n" +
     			"	}\n" +
     			"}\n",
-    			"T4146ctc1.java",
-    			"public class T4146ctc1 {\n" +
-    			"	T4146ctc1(String prefix, int n) {\n" +
+    			"T4146ctc4.java",
+    			"public class T4146ctc4 {\n" +
+    			"	T4146ctc4(String prefix, int n) {\n" +
     			"		if (n == 3) {\n" +
     			"			System.out.print('O');\n" +
     			"			return;\n" +