From f6103ec00bd05b9f43c00e45c6f6b7fbcc95b493 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Sat, 28 Jan 2017 22:39:44 +0300 Subject: [PATCH] Copy exception variables when splitting async programs. Fix https://github.com/konsoletyper/teavm/issues/230 --- .../teavm/model/util/AsyncProgramSplitter.java | 9 +++++++++ tests/src/test/java/org/teavm/vm/VMTest.java | 16 ++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/core/src/main/java/org/teavm/model/util/AsyncProgramSplitter.java b/core/src/main/java/org/teavm/model/util/AsyncProgramSplitter.java index dfcd9af61..9b2780fa7 100644 --- a/core/src/main/java/org/teavm/model/util/AsyncProgramSplitter.java +++ b/core/src/main/java/org/teavm/model/util/AsyncProgramSplitter.java @@ -95,6 +95,10 @@ public class AsyncProgramSplitter { // If we met asynchronous invocation... // Copy portion of current block from last occurrence (or from start) to i'th instruction. + if (sourceBlock.getExceptionVariable() != null) { + targetBlock.setExceptionVariable(targetBlock.getProgram().variableAt( + sourceBlock.getExceptionVariable().getIndex())); + } targetBlock.addAll(ProgramUtils.copyInstructions(last, insn, targetBlock.getProgram())); targetBlock.getTryCatchBlocks().addAll(ProgramUtils.copyTryCatches(sourceBlock, targetBlock.getProgram())); @@ -140,6 +144,11 @@ public class AsyncProgramSplitter { step.targetPart = part; part.originalBlocks[targetBlock.getIndex()] = step.source; } + + if (sourceBlock.getExceptionVariable() != null) { + targetBlock.setExceptionVariable(targetBlock.getProgram().variableAt( + sourceBlock.getExceptionVariable().getIndex())); + } targetBlock.addAll(ProgramUtils.copyInstructions(last, null, targetBlock.getProgram())); targetBlock.getTryCatchBlocks().addAll(ProgramUtils.copyTryCatches(sourceBlock, targetBlock.getProgram())); targetBlock.setExceptionVariable(sourceBlock.getExceptionVariable()); diff --git a/tests/src/test/java/org/teavm/vm/VMTest.java b/tests/src/test/java/org/teavm/vm/VMTest.java index 93f92ca2b..6a68de92c 100644 --- a/tests/src/test/java/org/teavm/vm/VMTest.java +++ b/tests/src/test/java/org/teavm/vm/VMTest.java @@ -165,12 +165,28 @@ public class VMTest { } } + @Test + @SkipJVM + public void asyncExceptionHandler() { + try { + throw new RuntimeException("OK"); + } catch (RuntimeException e) { + assertEquals("OK", suspendAndReturn(e).getMessage()); + } + } + @Async private static native void throwExceptionAsync(); private static void throwExceptionAsync(AsyncCallback callback) { callback.error(new RuntimeException("OK")); } + @Async + private static native T suspendAndReturn(T value); + private static void suspendAndReturn(T value, AsyncCallback callback) { + callback.complete(value); + } + @JSBody(script = "return [1, 2]") private static native int[] createArray();