aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorchibash <chiba@javassist.org>2020-10-16 19:23:07 +0900
committerchibash <chiba@javassist.org>2020-10-16 19:23:07 +0900
commit1c4e31b9677d020a1e89aeebc6686396f9e6c68a (patch)
tree2056bc33e89038c42db6aa1b304f28e966022bc6 /src
parentb70a41bf522861698e48bc9f91f18bc4eb5b8520 (diff)
downloadjavassist-1c4e31b9677d020a1e89aeebc6686396f9e6c68a.tar.gz
javassist-1c4e31b9677d020a1e89aeebc6686396f9e6c68a.zip
fixes Issue #339
Diffstat (limited to 'src')
-rw-r--r--src/main/javassist/bytecode/StackMapTable.java9
-rw-r--r--src/test/javassist/bytecode/StackMapTest.java75
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());
+ }
}