From 0c03379206def4f5d3d1def26d86c093e95ce3b8 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Mon, 26 Nov 2018 14:49:03 +0300 Subject: [PATCH] Fix inability to catch exception when calling just created lambda --- .../dependency/DependencyGraphBuilder.java | 24 ++++--------------- tests/src/test/java/org/teavm/vm/VMTest.java | 15 ++++++++++++ 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java b/core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java index 73f0845c5..fd98f4200 100644 --- a/core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java +++ b/core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java @@ -31,7 +31,6 @@ import org.teavm.model.ClassReader; import org.teavm.model.ClassReaderSource; import org.teavm.model.ElementModifier; import org.teavm.model.FieldReference; -import org.teavm.model.Incoming; import org.teavm.model.IncomingReader; import org.teavm.model.Instruction; import org.teavm.model.InvokeDynamicInstruction; @@ -39,7 +38,6 @@ import org.teavm.model.MethodDescriptor; import org.teavm.model.MethodHandle; import org.teavm.model.MethodHolder; import org.teavm.model.MethodReference; -import org.teavm.model.Phi; import org.teavm.model.PhiReader; import org.teavm.model.Program; import org.teavm.model.RuntimeConstant; @@ -56,6 +54,7 @@ import org.teavm.model.instructions.InstructionReader; import org.teavm.model.instructions.InvocationType; import org.teavm.model.instructions.NullConstantInstruction; import org.teavm.model.text.ListingBuilder; +import org.teavm.model.util.BasicBlockSplitter; class DependencyGraphBuilder { private DependencyAnalyzer dependencyAnalyzer; @@ -191,6 +190,7 @@ class DependencyGraphBuilder { } ProgramEmitter pe = ProgramEmitter.create(program, dependencyAnalyzer.getClassSource()); boolean hasIndy = false; + BasicBlockSplitter splitter = new BasicBlockSplitter(program); for (int i = 0; i < program.basicBlockCount(); ++i) { BasicBlock block = program.basicBlockAt(i); for (Instruction insn : block) { @@ -216,23 +216,7 @@ class DependencyGraphBuilder { } hasIndy = true; - BasicBlock splitBlock = program.createBasicBlock(); - while (insn.getNext() != null) { - Instruction nextInsn = insn.getNext(); - nextInsn.delete(); - splitBlock.add(nextInsn); - } - - for (int k = 0; k < program.basicBlockCount() - 1; ++k) { - BasicBlock replaceBlock = program.basicBlockAt(k); - for (Phi phi : replaceBlock.getPhis()) { - for (Incoming incoming : phi.getIncomings()) { - if (incoming.getSource() == block) { - incoming.setSource(splitBlock); - } - } - } - } + BasicBlock splitBlock = splitter.split(block, insn); pe.enter(block); pe.setCurrentLocation(indy.getLocation()); @@ -256,8 +240,10 @@ class DependencyGraphBuilder { pe.addInstruction(assign); } pe.jump(splitBlock); + block = splitBlock; } } + splitter.fixProgram(); if (hasIndy && methodDep.method.getAnnotations().get(NoCache.class.getName()) == null) { methodDep.method.getAnnotations().add(new AnnotationHolder(NoCache.class.getName())); diff --git a/tests/src/test/java/org/teavm/vm/VMTest.java b/tests/src/test/java/org/teavm/vm/VMTest.java index a75a1932b..b1a6c8ee3 100644 --- a/tests/src/test/java/org/teavm/vm/VMTest.java +++ b/tests/src/test/java/org/teavm/vm/VMTest.java @@ -19,6 +19,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.fail; +import java.util.function.Supplier; import org.junit.Test; import org.junit.runner.RunWith; import org.teavm.interop.Async; @@ -38,6 +39,16 @@ public class VMTest { assertEquals(int[].class, array[0].getClass()); } + @Test + public void catchExceptionFromLambda() { + try { + Runnable r = () -> throwException(); + r.run(); + } catch (Throwable e) { + e.printStackTrace(); + } + } + @Test public void emptyMultiArrayCreated() { int[][] array = new int[0][0]; @@ -463,4 +474,8 @@ public class VMTest { static class DerivedClassWithConstantFields extends BaseClassWithConstantFields { } + + interface ScriptExecutionWrapper { + Object wrap(Supplier execution); + } } \ No newline at end of file