Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fix and test for issue#6:

"Local vars not restored properly after exception is thrown"

Thanks to ntherning (https://github.com/ntherning) for both the
test case and the fix.

	modified:   src/kilim/analysis/MethodWeaver.java
	modified:   test/kilim/test/TestYieldExceptions.java
	modified:   test/kilim/test/ex/ExCatch.java
  • Loading branch information...
commit 4e59bbbe500e45814469c9a6f235d64dd6f73807 1 parent 1b54ce9
@kilim authored
View
14 src/kilim/analysis/MethodWeaver.java
@@ -415,15 +415,17 @@ private void genException(MethodVisitor mv, BasicBlock bb, List<CallWeaver> cwLi
VMType.loadVar(mv, VMType.TOBJECT, getFiberVar());
mv.visitMethodInsn(INVOKEVIRTUAL, FIBER_CLASS, "upEx", "()I");
// fiber.pc is on stack
- Label[] labels = new Label[cwList.size() + 1];
- labels[0] = resumeLabel;
+ Label[] labels = new Label[cwList.size()];
+ int[] keys = new int[cwList.size()];
for (int i = 0; i < cwList.size(); i++) {
- labels[i + 1] = new Label();
+ labels[i] = new Label();
+ keys[i] = callWeavers.indexOf(cwList.get(i)) + 1;
}
- mv.visitTableSwitchInsn(0, cwList.size(), resumeLabel, labels);
- int i = 1;
+
+ mv.visitLookupSwitchInsn(resumeLabel, keys, labels);
+ int i = 0;
for (CallWeaver cw: cwList) {
- if (i > 1) {
+ if (i > 0) {
// This is the jump (to normal exception handling) for the previous
// switch case.
mv.visitJumpInsn(GOTO, resumeLabel);
View
5 test/kilim/test/TestYieldExceptions.java
@@ -39,4 +39,9 @@ public void testNestedException() throws Exception {
public void testTryCatchFinally() throws Exception {
TestYield.runTask(new kilim.test.ex.ExCatch(3));
}
+
+
+ public void testPausableBlocksBeforeCatch() throws Exception {
+ TestYield.runTask(new kilim.test.ex.ExCatch(4));
+ }
}
View
27 test/kilim/test/ex/ExCatch.java
@@ -30,6 +30,7 @@ private void test() throws Pausable {
case 1: pausableCatch(); break;
case 2: nestedPausableCatch(); break;
case 3: tryCatchFinally(); break;
+ case 4: pausableBeforeCatch(); break;
default: throw new IllegalStateException("Unknown test case: " + testCase);
}
}
@@ -72,6 +73,32 @@ void pausableCatch() throws Pausable {
verify(l);
}
+ // Issue#6 on github. A pausable block before the catch block.
+ void pausableBeforeCatch() throws Pausable {
+ int foo = 0;
+ Task.sleep(1);
+ if (foo != 0) throw new RuntimeException("Expected 0");
+
+ foo = 1;
+ Task.sleep(1);
+ if (foo != 1) throw new RuntimeException("Expected 1");
+
+ foo = 2;
+ Task.sleep(1);
+ if (foo != 2) throw new RuntimeException("Expected 2");
+
+ try {
+ foo = 3;
+ throwEx();
+ } catch (Throwable t) {
+ if (foo != 3) throw new RuntimeException("Expected 3");
+ }
+ }
+ private static void throwEx() throws Pausable {
+ Task.sleep(1);
+ throw new RuntimeException();
+ }
+
void tryCatchFinally() throws Pausable {
short sh = fsh;
String s = fs;
Please sign in to comment.
Something went wrong with that request. Please try again.