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;
 	}