]> source.dussan.org Git - aspectj.git/commitdiff
fix for unusual bytecode sequence around ctor-call join point
authoraclement <aclement>
Fri, 1 Dec 2006 11:18:53 +0000 (11:18 +0000)
committeraclement <aclement>
Fri, 1 Dec 2006 11:18:53 +0000 (11:18 +0000)
weaver/src/org/aspectj/weaver/bcel/BcelShadow.java

index cb47bb9a0f587102205aede70252d4d7bee66e81..edc49f78bc12611153a3aacacd029f315a855900 100644 (file)
@@ -32,6 +32,7 @@ import org.aspectj.apache.bcel.generic.BranchInstruction;
 import org.aspectj.apache.bcel.generic.ConstantPoolGen;
 import org.aspectj.apache.bcel.generic.DUP;
 import org.aspectj.apache.bcel.generic.DUP_X1;
+import org.aspectj.apache.bcel.generic.DUP_X2;
 import org.aspectj.apache.bcel.generic.FieldInstruction;
 import org.aspectj.apache.bcel.generic.INVOKEINTERFACE;
 import org.aspectj.apache.bcel.generic.INVOKESPECIAL;
@@ -198,6 +199,7 @@ public class BcelShadow extends Shadow {
                int depth = 1;
                InstructionHandle ih = range.getStart();
 
+               // Go back from where we are looking for 'NEW' that takes us to a stack depth of 0.   INVOKESPECIAL <init> 
                while (true) {
                        Instruction inst = ih.getInstruction();
                        if (inst instanceof INVOKESPECIAL
@@ -206,7 +208,42 @@ public class BcelShadow extends Shadow {
                        } else if (inst instanceof NEW) {
                                depth--;
                                if (depth == 0) break;
+                       } else if (inst instanceof DUP_X2) {
+                               // This code seen in the wild (by Brad):
+//                             40:  new     #12; //class java/lang/StringBuffer
+//                             STACK: STRINGBUFFER
+//                              43:  dup
+//                             STACK: STRINGBUFFER/STRINGBUFFER
+//                              44:  aload_0
+//                             STACK: STRINGBUFFER/STRINGBUFFER/THIS
+//                              45:  dup_x2
+//                             STACK: THIS/STRINGBUFFER/STRINGBUFFER/THIS
+//                              46:  getfield        #36; //Field value:Ljava/lang/String;
+//                             STACK: THIS/STRINGBUFFER/STRINGBUFFER/STRING<value>
+//                              49:  invokestatic    #37; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
+//                             STACK: THIS/STRINGBUFFER/STRINGBUFFER/STRING
+//                              52:  invokespecial   #19; //Method java/lang/StringBuffer."<init>":(Ljava/lang/String;)V
+//                             STACK: THIS/STRINGBUFFER
+//                              55:  aload_1
+//                             STACK: THIS/STRINGBUFFER/LOCAL1
+//                              56:  invokevirtual   #22; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
+//                             STACK: THIS/STRINGBUFFER
+//                              59:  invokevirtual   #34; //Method java/lang/StringBuffer.toString:()Ljava/lang/String;
+//                             STACK: THIS/STRING
+//                              62:  putfield        #36; //Field value:Ljava/lang/String;
+//                             STACK: <empty>
+//                              65:  return
+                               
+                               // if we attempt to match on the ctor call to StringBuffer.<init> then we get into trouble.
+                               // if we simply delete the new/dup pair without fixing up the dup_x2 then the dup_x2 will fail due to there
+                               // not being 3 elements on the stack for it to work with.  The fix *in this situation* is to change it to
+                               // a simple 'dup'
+                               
+                               // this fix is *not* very clean - but a general purpose decent solution will take much longer and this
+                               // bytecode sequence has only been seen once in the wild.
+                               ih.setInstruction(InstructionConstants.DUP);
                        }
+                       
                        ih = ih.getPrev();
                }
                // now IH points to the NEW.  We're followed by the DUP, and that is followed
@@ -214,6 +251,8 @@ public class BcelShadow extends Shadow {
                InstructionHandle newHandle = ih;
                InstructionHandle endHandle = newHandle.getNext();
                InstructionHandle nextHandle;
+               //
+               
                if (endHandle.getInstruction() instanceof DUP) {
                        nextHandle = endHandle.getNext();                       
                        retargetFrom(newHandle, nextHandle);