diff options
author | chibash <chiba@javassist.org> | 2020-10-16 19:23:07 +0900 |
---|---|---|
committer | chibash <chiba@javassist.org> | 2020-10-16 19:23:07 +0900 |
commit | 1c4e31b9677d020a1e89aeebc6686396f9e6c68a (patch) | |
tree | 2056bc33e89038c42db6aa1b304f28e966022bc6 /src | |
parent | b70a41bf522861698e48bc9f91f18bc4eb5b8520 (diff) | |
download | javassist-1c4e31b9677d020a1e89aeebc6686396f9e6c68a.tar.gz javassist-1c4e31b9677d020a1e89aeebc6686396f9e6c68a.zip |
fixes Issue #339
Diffstat (limited to 'src')
-rw-r--r-- | src/main/javassist/bytecode/StackMapTable.java | 9 | ||||
-rw-r--r-- | src/test/javassist/bytecode/StackMapTest.java | 75 |
2 files changed, 82 insertions, 2 deletions
diff --git a/src/main/javassist/bytecode/StackMapTable.java b/src/main/javassist/bytecode/StackMapTable.java index 9b8e5fae..81622200 100644 --- a/src/main/javassist/bytecode/StackMapTable.java +++ b/src/main/javassist/bytecode/StackMapTable.java @@ -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; diff --git a/src/test/javassist/bytecode/StackMapTest.java b/src/test/javassist/bytecode/StackMapTest.java index 07ee50be..7ea415a9 100644 --- a/src/test/javassist/bytecode/StackMapTest.java +++ b/src/test/javassist/bytecode/StackMapTest.java @@ -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()); + } } |