aboutsummaryrefslogtreecommitdiffstats
path: root/weaver
diff options
context:
space:
mode:
authoraclement <aclement>2006-12-01 11:18:53 +0000
committeraclement <aclement>2006-12-01 11:18:53 +0000
commit3a4d0300ff876bab290e14b6725efe7d1416bed6 (patch)
tree66f2fb2f811390a9952da2cd65688995f7eee86d /weaver
parentc1aa8a278d257909a8d747d169b3fea09b031ba0 (diff)
downloadaspectj-3a4d0300ff876bab290e14b6725efe7d1416bed6.tar.gz
aspectj-3a4d0300ff876bab290e14b6725efe7d1416bed6.zip
fix for unusual bytecode sequence around ctor-call join point
Diffstat (limited to 'weaver')
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/BcelShadow.java39
1 files changed, 39 insertions, 0 deletions
diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java b/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java
index cb47bb9a0..edc49f78b 100644
--- a/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java
+++ b/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java
@@ -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);