Bug 473590 - [otdre] confusion about when to populate _OT$access /
_OT$callOrig or not
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/AbstractBoundClass.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/AbstractBoundClass.java
index bdd65a6..0981474 100644
--- a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/AbstractBoundClass.java
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/AbstractBoundClass.java
@@ -139,7 +139,7 @@
// not completed WeavingTasks for callin bindings mapped by the method,
// that has to be woven
- private Map<Method, WeavingTask> openBindingTasks;
+ public Map<Method, WeavingTask> openBindingTasks;
// completed WeavingTasks for decapsulation bindings mapped by the member,
// that was woven
@@ -581,6 +581,8 @@
* It redefines the class, if it is not called while loading
*/
public synchronized void handleTaskList() {
+ if (isTransformationActive()) return;
+
Set<Map.Entry<Method, WeavingTask>> bindingEntrySet = openBindingTasks
.entrySet();
@@ -645,14 +647,14 @@
} else {
//No, so weave this class and delegate to the super class
weaveBindingInNotImplementedMethod(task);
- }
- if (weavingContext.isWeavable(getSuperClassName())) {
AbstractBoundClass superclass = getSuperclass();
- Method superMethod = superclass.getMethod(method, task);
- if (superMethod != null) {
- WeavingTask newTask = new WeavingTask(WeavingTaskType.WEAVE_BINDING_OF_SUBCLASS, superMethod, task);
- superclass.addWeavingTask(newTask, true/*standBy*/);
- affectedClasses.add(superclass);
+ if (weavingContext.isWeavable(getSuperClassName())) {
+ Method superMethod = superclass.getMethod(method, task);
+ if (superMethod != null) {
+ WeavingTask newTask = new WeavingTask(WeavingTaskType.WEAVE_BINDING_OF_SUBCLASS, superMethod, task);
+ superclass.addWeavingTask(newTask, true/*standBy*/);
+ affectedClasses.add(superclass);
+ }
}
}
@@ -906,6 +908,11 @@
}
}
}
+
+ public void addWeavingOfSubclassTask(String methodName, String signature, boolean isStatic) {
+ int flags = isStatic ? IBinding.STATIC_BASE : 0;
+ addBindingWeavingTask(new WeavingTask(WeavingTaskType.WEAVE_BINDING_OF_SUBCLASS, methodName, signature, flags, isStatic));
+ }
/**
* Merge tasks of two AbstractBoundClasses (this class and a other).
@@ -1064,6 +1071,8 @@
protected abstract void prepareForFirstStaticTransformation();
public abstract boolean isFirstTransformation();
+
+ public boolean isLoaded() { return isLoaded; }
protected abstract void createDispatchCodeInOrgMethod(Method boundMethod,
int joinpointId, int boundMethodId);
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 004f890..5d9c172 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
@@ -19,6 +19,7 @@
import java.util.List;
import java.util.ListIterator;
+import org.eclipse.objectteams.otredyn.bytecode.AbstractBoundClass;
import org.eclipse.objectteams.otredyn.bytecode.Method;
import org.eclipse.objectteams.otredyn.transformer.names.ClassNames;
import org.objectweb.asm.Opcodes;
@@ -286,8 +287,11 @@
}
protected void replaceSuperCallsWithCallToCallOrig(InsnList instructions, List<MethodInsnNode> superCalls,
- boolean returnsJLObject, IBoundMethodIdInsnProvider insnProvider) {
+ boolean returnsJLObject, AbstractBoundClass superclass, IBoundMethodIdInsnProvider insnProvider) {
for (MethodInsnNode oldNode : superCalls) {
+
+ superclass.addWeavingOfSubclassTask(oldNode.name, oldNode.desc, oldNode.getOpcode() == Opcodes.INVOKESTATIC);
+
Type[] args = Type.getArgumentTypes(oldNode.desc);
Type returnType = Type.getReturnType(oldNode.desc);
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 10246fe..5552049 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
@@ -22,6 +22,7 @@
import java.util.List;
import org.eclipse.objectteams.otredyn.bytecode.AbstractBoundClass;
+import org.eclipse.objectteams.otredyn.bytecode.AbstractTeam;
import org.eclipse.objectteams.otredyn.bytecode.Field;
import org.eclipse.objectteams.otredyn.bytecode.IBytecodeProvider;
import org.eclipse.objectteams.otredyn.bytecode.Method;
@@ -204,6 +205,9 @@
isTransformationActive = false;
isFirstTransformation = false;
releaseBytecode();
+ AbstractTeam mySuper = getSuperclass();
+ if (mySuper != null && !mySuper.openBindingTasks.isEmpty() && mySuper.isLoaded())
+ mySuper.handleTaskList();
}
/**
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/CreateFieldAccessAdapter.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/CreateFieldAccessAdapter.java
index 40af15c..8b26460 100644
--- a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/CreateFieldAccessAdapter.java
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/CreateFieldAccessAdapter.java
@@ -93,6 +93,10 @@
//write access
instructions.add(writeAccess);
+ //put "this" on the stack
+ if (!field.isStatic())
+ instructions.add(new IntInsnNode(Opcodes.ALOAD, 0));
+
//put "args" on the stack
instructions.add(new IntInsnNode(Opcodes.ALOAD, firstArgIndex + 2));
//get the first element of "args"
@@ -111,9 +115,6 @@
//save value in field
instructions.add(new FieldInsnNode(Opcodes.PUTSTATIC, name, field.getName(), field.getSignature()));
} else {
- //put "this" on the stack
- instructions.add(new IntInsnNode(Opcodes.ALOAD, 0));
- instructions.add(new InsnNode(Opcodes.SWAP));
//save value in field
instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, name, field.getName(), field.getSignature()));
}
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 e9e3351..1365204 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
@@ -20,6 +20,7 @@
import java.util.List;
import java.util.ListIterator;
+import org.eclipse.objectteams.otredyn.bytecode.AbstractBoundClass;
import org.eclipse.objectteams.otredyn.bytecode.Method;
import org.eclipse.objectteams.otredyn.transformer.IWeavingContext;
import org.eclipse.objectteams.otredyn.transformer.names.ConstantMembers;
@@ -46,6 +47,7 @@
private int argOffset; // used to skip synth args if the callOrig method itself is a statid role method
private Method callOrig;
private boolean superIsWeavable = true;
+ private AbstractBoundClass superclass;
public MoveCodeToCallOrigAdapter(AsmWritableBoundClass clazz, Method method, int boundMethodId, IWeavingContext weavingContext) {
this.method = method;
@@ -60,6 +62,8 @@
}
if (weavingContext != null)
superIsWeavable = weavingContext.isWeavable(clazz.getSuperClassName());
+ if (superIsWeavable)
+ superclass = clazz.getSuperclass();
}
public boolean transform() {
@@ -147,7 +151,7 @@
if (toReplace.isEmpty())
return;
// replace:
- replaceSuperCallsWithCallToCallOrig(instructions, toReplace, true, new IBoundMethodIdInsnProvider() {
+ replaceSuperCallsWithCallToCallOrig(instructions, toReplace, true, superclass, new IBoundMethodIdInsnProvider() {
@Override public AbstractInsnNode getLoadBoundMethodIdInsn(MethodInsnNode methodInsn) {
return new IntInsnNode(Opcodes.ILOAD, boundMethodIdSlot);
}
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/ReplaceWickedSuperCallsAdapter.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/ReplaceWickedSuperCallsAdapter.java
index 9aa8b50..d1500c7 100644
--- a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/ReplaceWickedSuperCallsAdapter.java
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/ReplaceWickedSuperCallsAdapter.java
@@ -126,7 +126,7 @@
List<MethodInsnNode> superCallsToReplace = toWeave.getValue();
Type returnType = Type.getReturnType(enclosingMethod.desc);
boolean returnsJLObject = returnType.getSort() == Type.OBJECT ? returnType.getInternalName().equals(OBJECT_SLASH) : false;
- replaceSuperCallsWithCallToCallOrig(instructions, superCallsToReplace, returnsJLObject, this);
+ replaceSuperCallsWithCallToCallOrig(instructions, superCallsToReplace, returnsJLObject, superclass, this);
}
return true;
}