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" +