Fix inability to catch exception when calling just created lambda

This commit is contained in:
Alexey Andreev 2018-11-26 14:49:03 +03:00
parent 85f901362f
commit 0c03379206
2 changed files with 20 additions and 19 deletions

View File

@ -31,7 +31,6 @@ import org.teavm.model.ClassReader;
import org.teavm.model.ClassReaderSource; import org.teavm.model.ClassReaderSource;
import org.teavm.model.ElementModifier; import org.teavm.model.ElementModifier;
import org.teavm.model.FieldReference; import org.teavm.model.FieldReference;
import org.teavm.model.Incoming;
import org.teavm.model.IncomingReader; import org.teavm.model.IncomingReader;
import org.teavm.model.Instruction; import org.teavm.model.Instruction;
import org.teavm.model.InvokeDynamicInstruction; import org.teavm.model.InvokeDynamicInstruction;
@ -39,7 +38,6 @@ import org.teavm.model.MethodDescriptor;
import org.teavm.model.MethodHandle; import org.teavm.model.MethodHandle;
import org.teavm.model.MethodHolder; import org.teavm.model.MethodHolder;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
import org.teavm.model.Phi;
import org.teavm.model.PhiReader; import org.teavm.model.PhiReader;
import org.teavm.model.Program; import org.teavm.model.Program;
import org.teavm.model.RuntimeConstant; 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.InvocationType;
import org.teavm.model.instructions.NullConstantInstruction; import org.teavm.model.instructions.NullConstantInstruction;
import org.teavm.model.text.ListingBuilder; import org.teavm.model.text.ListingBuilder;
import org.teavm.model.util.BasicBlockSplitter;
class DependencyGraphBuilder { class DependencyGraphBuilder {
private DependencyAnalyzer dependencyAnalyzer; private DependencyAnalyzer dependencyAnalyzer;
@ -191,6 +190,7 @@ class DependencyGraphBuilder {
} }
ProgramEmitter pe = ProgramEmitter.create(program, dependencyAnalyzer.getClassSource()); ProgramEmitter pe = ProgramEmitter.create(program, dependencyAnalyzer.getClassSource());
boolean hasIndy = false; boolean hasIndy = false;
BasicBlockSplitter splitter = new BasicBlockSplitter(program);
for (int i = 0; i < program.basicBlockCount(); ++i) { for (int i = 0; i < program.basicBlockCount(); ++i) {
BasicBlock block = program.basicBlockAt(i); BasicBlock block = program.basicBlockAt(i);
for (Instruction insn : block) { for (Instruction insn : block) {
@ -216,23 +216,7 @@ class DependencyGraphBuilder {
} }
hasIndy = true; hasIndy = true;
BasicBlock splitBlock = program.createBasicBlock(); BasicBlock splitBlock = splitter.split(block, insn);
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);
}
}
}
}
pe.enter(block); pe.enter(block);
pe.setCurrentLocation(indy.getLocation()); pe.setCurrentLocation(indy.getLocation());
@ -256,8 +240,10 @@ class DependencyGraphBuilder {
pe.addInstruction(assign); pe.addInstruction(assign);
} }
pe.jump(splitBlock); pe.jump(splitBlock);
block = splitBlock;
} }
} }
splitter.fixProgram();
if (hasIndy && methodDep.method.getAnnotations().get(NoCache.class.getName()) == null) { if (hasIndy && methodDep.method.getAnnotations().get(NoCache.class.getName()) == null) {
methodDep.method.getAnnotations().add(new AnnotationHolder(NoCache.class.getName())); methodDep.method.getAnnotations().add(new AnnotationHolder(NoCache.class.getName()));

View File

@ -19,6 +19,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import java.util.function.Supplier;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.teavm.interop.Async; import org.teavm.interop.Async;
@ -38,6 +39,16 @@ public class VMTest {
assertEquals(int[].class, array[0].getClass()); assertEquals(int[].class, array[0].getClass());
} }
@Test
public void catchExceptionFromLambda() {
try {
Runnable r = () -> throwException();
r.run();
} catch (Throwable e) {
e.printStackTrace();
}
}
@Test @Test
public void emptyMultiArrayCreated() { public void emptyMultiArrayCreated() {
int[][] array = new int[0][0]; int[][] array = new int[0][0];
@ -463,4 +474,8 @@ public class VMTest {
static class DerivedClassWithConstantFields extends BaseClassWithConstantFields { static class DerivedClassWithConstantFields extends BaseClassWithConstantFields {
} }
interface ScriptExecutionWrapper {
Object wrap(Supplier<Object> execution);
}
} }