From 3a4d0300ff876bab290e14b6725efe7d1416bed6 Mon Sep 17 00:00:00 2001 From: aclement Date: Fri, 1 Dec 2006 11:18:53 +0000 Subject: [PATCH] fix for unusual bytecode sequence around ctor-call join point --- .../org/aspectj/weaver/bcel/BcelShadow.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) 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 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 +// 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."":(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: +// 65: return + + // if we attempt to match on the ctor call to StringBuffer. 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); -- 2.39.5