]> source.dussan.org Git - javassist.git/commitdiff
fixed JASSIST-177
authorchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>
Sun, 25 Nov 2012 18:40:56 +0000 (18:40 +0000)
committerchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>
Sun, 25 Nov 2012 18:40:56 +0000 (18:40 +0000)
git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@691 30ef5769-5b8d-40dd-aea6-55b5d6557bb3

javassist.jar
src/main/javassist/CtBehavior.java
src/test/javassist/JvstTest4.java
src/test/test4/AfterTest.java [new file with mode: 0644]

index 42b02760baf555e79f8fca9be21c930970c87102..b8f4ca3430e5b90ba682367ec7fc016f85444d0b 100644 (file)
Binary files a/javassist.jar and b/javassist.jar differ
index 1ca8408b549e92cdc687c01e7ea08cc03123999a..73ac277a321c338ce67d706ef2282368b7a4313c 100644 (file)
@@ -826,35 +826,44 @@ public abstract class CtBehavior extends CtMember {
             // finally clause for exceptions
             int handlerLen = insertAfterHandler(asFinally, b, rtype, varNo,
                                                 jv, src);
-            // finally clause for normal termination
-            insertAfterAdvice(b, jv, src, pool, rtype, varNo);
-
-            ca.setMaxStack(b.getMaxStack());
-            ca.setMaxLocals(b.getMaxLocals());
-
-            int gapPos = iterator.append(b.get());
-            iterator.append(b.getExceptionTable(), gapPos);
-
+            int handlerPos = iterator.getCodeLength();
             if (asFinally)
-                ca.getExceptionTable().add(getStartPosOfBody(ca), gapPos, gapPos, 0); 
-
-            int gapLen = iterator.getCodeLength() - gapPos - handlerLen;
-            int subr = iterator.getCodeLength() - gapLen;
+                ca.getExceptionTable().add(getStartPosOfBody(ca), handlerPos, handlerPos, 0); 
 
+            int adviceLen = 0;
+            int advicePos = 0;
+            boolean noReturn = true;
             while (iterator.hasNext()) {
                 int pos = iterator.next();
-                if (pos >= subr)
+                if (pos >= handlerPos)
                     break;
 
                 int c = iterator.byteAt(pos);
                 if (c == Opcode.ARETURN || c == Opcode.IRETURN
                     || c == Opcode.FRETURN || c == Opcode.LRETURN
                     || c == Opcode.DRETURN || c == Opcode.RETURN) {
-                    insertGoto(iterator, subr, pos);
-                    subr = iterator.getCodeLength() - gapLen;
+                    if (noReturn) {
+                        // finally clause for normal termination
+                        adviceLen = insertAfterAdvice(b, jv, src, pool, rtype, varNo);
+                        handlerPos = iterator.append(b.get());
+                        iterator.append(b.getExceptionTable(), handlerPos);
+                        advicePos = iterator.getCodeLength() - adviceLen;
+                        handlerLen = advicePos - handlerPos;
+                        noReturn = false;
+                    }
+                    insertGoto(iterator, advicePos, pos);
+                    advicePos = iterator.getCodeLength() - adviceLen;
+                    handlerPos = advicePos - handlerLen;
                 }
             }
 
+            if (noReturn) {
+                handlerPos = iterator.append(b.get());
+                iterator.append(b.getExceptionTable(), handlerPos);
+            }
+
+            ca.setMaxStack(b.getMaxStack());
+            ca.setMaxLocals(b.getMaxLocals());
             methodInfo.rebuildStackMapIf6(cc.getClassPool(), cc.getClassFile2());
         }
         catch (NotFoundException e) {
@@ -868,10 +877,11 @@ public abstract class CtBehavior extends CtMember {
         }
     }
 
-    private void insertAfterAdvice(Bytecode code, Javac jv, String src,
-                                   ConstPool cp, CtClass rtype, int varNo)
+    private int insertAfterAdvice(Bytecode code, Javac jv, String src,
+                                  ConstPool cp, CtClass rtype, int varNo)
         throws CompileError
     {
+        int pc = code.currentPc();
         if (rtype == CtClass.voidType) {
             code.addOpcode(Opcode.ACONST_NULL);
             code.addAstore(varNo);
@@ -889,6 +899,8 @@ public abstract class CtBehavior extends CtMember {
             else
                 code.addOpcode(Opcode.ARETURN);
         }
+
+        return code.currentPc() - pc;
     }
 
     /*
index 76f139bdebae9a762b3888c740e5afa9b714c030..7cf6178a13833d6e94fc36d2ab1542fd7dbfa44d 100644 (file)
@@ -784,4 +784,37 @@ public class JvstTest4 extends JvstTestRoot {
                      + "org.apache.hadoop.mapreduce.Mapper<java.lang.Object, org.apache.hadoop.io.Text, "
                      + "org.apache.hadoop.io.Text, org.apache.hadoop.io.IntWritable>.Context) void", s);
     }
+
+    public void testAfter() throws Exception {
+        CtClass cc = sloader.get("test4.AfterTest");
+        CtMethod m1 = cc.getDeclaredMethod("m1");
+        m1.insertAfter("print();");
+        CtMethod m2 = cc.getDeclaredMethod("m2");
+        m2.insertAfter("print();");
+        CtMethod m3 = cc.getDeclaredMethod("m3");
+        m3.insertAfter("print();");
+        CtMethod m4 = cc.getDeclaredMethod("m4");
+        m4.insertAfter("print();");
+
+        CtMethod mm1 = cc.getDeclaredMethod("mm1");
+        mm1.insertAfter("print();", true);
+        CtMethod mm2 = cc.getDeclaredMethod("mm2");
+        mm2.insertAfter("print();", true);
+        CtMethod mm3 = cc.getDeclaredMethod("mm3");
+        mm3.insertAfter("print();", true);
+        CtMethod mm4 = cc.getDeclaredMethod("mm4");
+        mm4.insertAfter("print();", true);
+
+        cc.writeFile();
+        Object obj = make(cc.getName());
+        assertEquals(131, invoke(obj, "test1"));
+        assertEquals(112, invoke(obj, "test2"));
+        assertEquals(10, invoke(obj, "test3"));
+        assertEquals(100, invoke(obj, "test4"));
+
+        assertEquals(131, invoke(obj, "test11"));
+        assertEquals(112, invoke(obj, "test22"));
+        assertEquals(10, invoke(obj, "test33"));
+        assertEquals(100, invoke(obj, "test44"));
+    }
 }
diff --git a/src/test/test4/AfterTest.java b/src/test/test4/AfterTest.java
new file mode 100644 (file)
index 0000000..3ba3650
--- /dev/null
@@ -0,0 +1,119 @@
+package test4;
+
+public class AfterTest {
+    public void print() { System.out.println("test4.AfterTest"); }
+
+    public int test1() { return m1(10) + m1(-10); }
+
+    public int m1(int i) {
+        if (i > 0)
+            i = i + 10;
+        else
+            return -i;
+
+        i = i + 100;
+        return i + 1;
+    }
+
+    public int test2() throws Exception { return m2(1); }
+
+    public int m2(int i) throws Exception {
+        if (i > 10)
+            throw new Exception();
+        else if (i > 0)
+            i = i + 10;
+        else
+            return -i;
+
+        i = i + 100;
+        return i + 1;
+    }
+
+    public int test3() throws Exception { return m3(-10); }
+
+    public int m3(int i) throws Exception {
+        if (i > 10)
+            throw new Exception();
+        else if (i > 0)
+            i = i + 10;
+        else
+            return -i;
+
+        i = i + 100;
+        throw new Exception();
+    }
+
+    public int test4() throws Exception {
+        try {
+            return m4(-10);
+        }
+        catch (Exception e) {
+            return 100;
+        }
+    }
+
+    public int m4(int i) throws Exception {
+        if (i > 0)
+            i = i + 10;
+
+        i = i + 100;
+        throw new Exception();
+    }
+
+    public int test11() { return mm1(10) + mm1(-10); }
+
+    public int mm1(int i) {
+        if (i > 0)
+            i = i + 10;
+        else
+            return -i;
+
+        i = i + 100;
+        return i + 1;
+    }
+
+    public int test22() throws Exception { return mm2(1); }
+
+    public int mm2(int i) throws Exception {
+        if (i > 10)
+            throw new Exception();
+        else if (i > 0)
+            i = i + 10;
+        else
+            return -i;
+
+        i = i + 100;
+        return i + 1;
+    }
+
+    public int test33() throws Exception { return mm3(-10); }
+
+    public int mm3(int i) throws Exception {
+        if (i > 10)
+            throw new Exception();
+        else if (i > 0)
+            i = i + 10;
+        else
+            return -i;
+
+        i = i + 100;
+        throw new Exception();
+    }
+
+    public int test44() throws Exception {
+        try {
+            return mm4(-10);
+        }
+        catch (Exception e) {
+            return 100;
+        }
+    }
+
+    public int mm4(int i) throws Exception {
+        if (i > 0)
+            i = i + 10;
+
+        i = i + 100;
+        throw new Exception();
+    }
+}