]> source.dussan.org Git - javassist.git/commitdiff
fixes Issue #339
authorchibash <chiba@javassist.org>
Fri, 16 Oct 2020 10:23:07 +0000 (19:23 +0900)
committerchibash <chiba@javassist.org>
Fri, 16 Oct 2020 10:23:07 +0000 (19:23 +0900)
Readme.html
javassist.jar
src/main/javassist/bytecode/StackMapTable.java
src/test/javassist/bytecode/StackMapTest.java

index 914e912e3016f9cd012af418e34d640f5faceb69..247962a5b48e5b33e8cec80d1c5a87218666c79f 100644 (file)
@@ -293,7 +293,7 @@ see javassist.Dump.
 
 <p>-version 3.28
 <ul>
-       <li>GitHub Issue #328.
+       <li>GitHub Issue #328, #339.
 </ul>
 
 <p>-version 3.27 on March 19, 2020
index b1f107b73cd3f0e2eb9ec4daa34845914e27c850..26c4046980eeed00b2bcbbf0a5a38fec9d5202d6 100644 (file)
Binary files a/javassist.jar and b/javassist.jar differ
index 9b8e5fae45f1d3abf00f081b067fe324bc4981c1..816222008ab6d2b4a3c6f48a896702f7a5159d0d 100644 (file)
@@ -881,7 +881,11 @@ public class StackMapTable extends AttributeInfo {
             position = oldPos + offsetDelta + (oldPos == 0 ? 0 : 1);
             boolean match;
             if (exclusive)
-                match = oldPos < where  && where <= position;
+                // We optimize this expression by hand:
+                //   match = (oldPos == 0 && where == 0 && (0 < position || 0 == position))
+                //           || oldPos < where  && where <= position;
+                match = (oldPos == 0 && where == 0)
+                        || oldPos < where  && where <= position;
             else
                 match = oldPos <= where  && where < position;
 
@@ -931,7 +935,8 @@ public class StackMapTable extends AttributeInfo {
             position = oldPos + offsetDelta + (oldPos == 0 ? 0 : 1);
             boolean match;
             if (exclusive)
-                match = oldPos < where  && where <= position;
+                match = (oldPos == 0 && where == 0)
+                        || oldPos < where  && where <= position;
             else
                 match = oldPos <= where  && where < position;
 
index 07ee50bed895c613b4cb2a683c25007cba9b273f..7ea415a97aed7b904acd9f5f9c3942ca11d91513 100644 (file)
@@ -848,4 +848,79 @@ public class StackMapTest extends TestCase {
         cc.writeFile();
         Object t1 = make(cc.getName());
     }
+
+    public static class C8 {
+        int value = 0;
+        int loop = 0;
+        int loop2 = 1;
+        public void foo(int i) { value += i; }
+        public void bar(int i) { value += i; }
+        public void foo2(int i) { value += i; }
+        public void bar2(int i) { value += i; }
+    }
+
+    public static class C9 extends C8 {
+        public void foo(int i) {
+            while(true) {
+                loop--;
+                if (loop < 0)
+                    break;
+            }
+            value += i;
+        }
+        public void bar(int i) {
+            value += i;
+            for (int k = 0; i < 10; k++)
+                loop += k;
+        }
+        public void foo2(int i) {
+            while(true) {
+                loop2--;
+                if (loop2 < 0)
+                    break;
+            }
+            value += i;
+            for (int k = 0; k < 3; k++)
+                loop2--;
+        }
+        public void bar2(int i) {
+            value += i;
+            for (int k = 0; i < 10; k++)
+                loop += k;
+        }
+        public int run() {
+            foo(1);
+            bar(10);
+            foo2(100);
+            bar2(1000);
+            return value;
+        }
+    }
+
+    public void testIssue339() throws Exception {
+        CtClass cc0 = loader.get("javassist.bytecode.StackMapTest$C8");
+        CtClass cc = loader.get("javassist.bytecode.StackMapTest$C9");
+
+        testIssue339b(cc, cc0, "foo", true);
+        testIssue339b(cc, cc0, "bar", true);
+        testIssue339b(cc, cc0, "foo2", false);
+        testIssue339b(cc, cc0, "bar2", false);
+
+        cc.writeFile();
+        Object t1 = make(cc.getName());
+        assertEquals(2322, invoke(t1, "run"));
+    }
+
+    public void testIssue339b(CtClass cc, CtClass cc0, String name, boolean exclusive) throws Exception {
+        Bytecode newCode = new Bytecode(cc.getClassFile().constPool);
+        newCode.addAload(0); // Loads 'this'
+        newCode.addIload(1); // Loads method param 1 (int)
+        newCode.addInvokespecial(cc0.getName(), name, "(I)V");
+        CodeAttribute ca = cc.getDeclaredMethod(name).getMethodInfo().getCodeAttribute();
+        CodeIterator ci = ca.iterator();
+        if (exclusive)
+            ci.insertEx(newCode.get());
+        else
+            ci.insert(newCode.get());
+    }
 }