diff --git a/core/src/main/java/org/teavm/ast/decompilation/Decompiler.java b/core/src/main/java/org/teavm/ast/decompilation/Decompiler.java index 5dddbb6c6..7ad8f91aa 100644 --- a/core/src/main/java/org/teavm/ast/decompilation/Decompiler.java +++ b/core/src/main/java/org/teavm/ast/decompilation/Decompiler.java @@ -48,6 +48,7 @@ import org.teavm.model.MethodReference; import org.teavm.model.Program; import org.teavm.model.TextLocation; import org.teavm.model.TryCatchBlock; +import org.teavm.model.instructions.AssignInstruction; import org.teavm.model.instructions.BinaryBranchingInstruction; import org.teavm.model.instructions.BranchingInstruction; import org.teavm.model.instructions.JumpInstruction; @@ -299,13 +300,24 @@ public class Decompiler { if (exceptionHandlers[block.getIndex()]) { return false; } - if (block.instructionCount() != 1 || block.getExceptionVariable() != null) { + if (block.getExceptionVariable() != null) { return false; } Instruction instruction = block.getLastInstruction(); - return instruction instanceof JumpInstruction - || instruction instanceof BranchingInstruction - || instruction instanceof BinaryBranchingInstruction; + if (!(instruction instanceof JumpInstruction) + && !(instruction instanceof BranchingInstruction) + && !(instruction instanceof BinaryBranchingInstruction)) { + return false; + } + + while (instruction.getPrevious() != null) { + instruction = instruction.getPrevious(); + if (!(instruction instanceof AssignInstruction)) { + return false; + } + } + + return true; } private void closeExpiredBookmarks(StatementGenerator generator, List tryCatchBlocks) { diff --git a/core/src/main/java/org/teavm/model/util/InterferenceGraphBuilder.java b/core/src/main/java/org/teavm/model/util/InterferenceGraphBuilder.java index 97528b25d..8851c630b 100644 --- a/core/src/main/java/org/teavm/model/util/InterferenceGraphBuilder.java +++ b/core/src/main/java/org/teavm/model/util/InterferenceGraphBuilder.java @@ -27,24 +27,10 @@ class InterferenceGraphBuilder { } UsageExtractor useExtractor = new UsageExtractor(); DefinitionExtractor defExtractor = new DefinitionExtractor(); - TransitionExtractor succExtractor = new TransitionExtractor(); - List> outgoings = ProgramUtils.getPhiOutputs(program); - BitSet live = new BitSet(); for (int i = 0; i < program.basicBlockCount(); ++i) { BasicBlock block = program.basicBlockAt(i); - block.getLastInstruction().acceptVisitor(succExtractor); - BitSet liveOut = liveness.liveOut(i); - live.clear(); - for (int j = 0; j < liveOut.length(); ++j) { - if (liveOut.get(j)) { - live.set(j); - } - } - - for (Incoming outgoing : outgoings.get(i)) { - live.set(outgoing.getValue().getIndex()); - } + BitSet live = liveness.liveOut(i); for (Instruction insn = block.getLastInstruction(); insn != null; insn = insn.getPrevious()) { insn.acceptVisitor(useExtractor); @@ -69,18 +55,6 @@ class InterferenceGraphBuilder { } } - BitSet liveIn = liveness.liveIn(i); - live.clear(); - for (int j = 0; j < liveOut.length(); ++j) { - if (liveIn.get(j)) { - live.set(j); - } - } - - for (Phi phi : block.getPhis()) { - live.set(phi.getReceiver().getIndex()); - } - for (Phi phi : block.getPhis()) { connect(nodes, phi.getReceiver().getIndex(), live); } diff --git a/core/src/main/java/org/teavm/model/util/RegisterAllocator.java b/core/src/main/java/org/teavm/model/util/RegisterAllocator.java index 172761c38..b5a335eb4 100644 --- a/core/src/main/java/org/teavm/model/util/RegisterAllocator.java +++ b/core/src/main/java/org/teavm/model/util/RegisterAllocator.java @@ -32,6 +32,7 @@ import org.teavm.model.MethodReference; import org.teavm.model.Phi; import org.teavm.model.Program; import org.teavm.model.ProgramReader; +import org.teavm.model.TextLocation; import org.teavm.model.Variable; import org.teavm.model.instructions.AssignInstruction; import org.teavm.model.instructions.JumpInstruction; @@ -188,41 +189,22 @@ public class RegisterAllocator { DefinitionExtractor definitionExtractor = new DefinitionExtractor(); List nextInstructions = new ArrayList<>(); for (BasicBlock block : program.getBasicBlocks()) { + for (Phi phi : block.getPhis()) { + addExceptionHandlingCopies(catchIncomingsByVariable, phi.getReceiver(), block, + program, block.getFirstInstruction().getLocation(), nextInstructions); + } + + if (!nextInstructions.isEmpty()) { + block.addFirstAll(nextInstructions); + nextInstructions.clear(); + } + for (Instruction instruction : block) { instruction.acceptVisitor(definitionExtractor); Variable[] definedVariables = definitionExtractor.getDefinedVariables(); for (Variable definedVariable : definedVariables) { - if (definedVariable.getIndex() >= catchIncomingsByVariable.size()) { - continue; - } - List catchIncomings = catchIncomingsByVariable.get(definedVariable.getIndex()); - if (catchIncomings == null) { - continue; - } - - Incoming incoming = null; - for (Iterator iter = catchIncomings.iterator(); iter.hasNext();) { - if (iter.next().getValue() == definedVariable) { - iter.remove(); - break; - } - } - if (incoming == null) { - continue; - } - - Variable copy = program.createVariable(); - copy.setLabel(incoming.getPhi().getReceiver().getLabel()); - copy.setDebugName(incoming.getPhi().getReceiver().getDebugName()); - - AssignInstruction copyInstruction = new AssignInstruction(); - copyInstruction.setReceiver(copy); - copyInstruction.setAssignee(incoming.getValue()); - copyInstruction.setLocation(instruction.getLocation()); - - incoming.setValue(copy); - - nextInstructions.add(copyInstruction); + addExceptionHandlingCopies(catchIncomingsByVariable, definedVariable, block, + program, instruction.getLocation(), nextInstructions); } if (!nextInstructions.isEmpty()) { @@ -242,18 +224,48 @@ public class RegisterAllocator { Variable copy = program.createVariable(); copy.setLabel(incoming.getPhi().getReceiver().getLabel()); copy.setDebugName(incoming.getPhi().getReceiver().getDebugName()); - incoming.setValue(copy); AssignInstruction copyInstruction = new AssignInstruction(); copyInstruction.setReceiver(copy); copyInstruction.setAssignee(incoming.getValue()); copyInstruction.setLocation(block.getFirstInstruction().getLocation()); + incoming.setValue(copy); block.addFirst(copyInstruction); } } } + private void addExceptionHandlingCopies(List> catchIncomingsByVariable, Variable definedVariable, + BasicBlock block, Program program, TextLocation location, List nextInstructions) { + if (definedVariable.getIndex() >= catchIncomingsByVariable.size()) { + return; + } + List catchIncomings = catchIncomingsByVariable.get(definedVariable.getIndex()); + if (catchIncomings == null) { + return; + } + + for (Iterator iter = catchIncomings.iterator(); iter.hasNext();) { + Incoming incoming = iter.next(); + if (incoming.getSource() == block) { + Variable copy = program.createVariable(); + copy.setLabel(incoming.getPhi().getReceiver().getLabel()); + copy.setDebugName(incoming.getPhi().getReceiver().getDebugName()); + + AssignInstruction copyInstruction = new AssignInstruction(); + copyInstruction.setReceiver(copy); + copyInstruction.setAssignee(incoming.getValue()); + copyInstruction.setLocation(location); + + incoming.setValue(copy); + nextInstructions.add(copyInstruction); + + iter.remove(); + } + } + } + private void insertCopy(Incoming incoming, Map blockMap) { Phi phi = incoming.getPhi(); Program program = phi.getBasicBlock().getProgram(); diff --git a/core/src/main/resources/org/teavm/backend/c/runtime.c b/core/src/main/resources/org/teavm/backend/c/runtime.c index 63cf99848..0ff829447 100644 --- a/core/src/main/resources/org/teavm/backend/c/runtime.c +++ b/core/src/main/resources/org/teavm/backend/c/runtime.c @@ -276,9 +276,9 @@ void teavm_outOfMemory() { static char16_t* teavm_utf16ToUtf32(char16_t* source, char32_t* target) { char16_t c = *source; - if (c & 0xFC00 == 0xD800) { + if ((c & 0xFC00) == 0xD800) { char16_t n = *(source + 1); - if (n & 0xFC00 == 0xDC00) { + if ((n & 0xFC00) == 0xDC00) { *target = (((c & ~0xFC00) << 10) | (n & ~0xFC00)) + 0x10000; return source + 2; } diff --git a/tests/src/test/java/org/teavm/vm/VMTest.java b/tests/src/test/java/org/teavm/vm/VMTest.java index 68d3b4ec5..e4e19fe70 100644 --- a/tests/src/test/java/org/teavm/vm/VMTest.java +++ b/tests/src/test/java/org/teavm/vm/VMTest.java @@ -90,6 +90,7 @@ public class VMTest { int a = 23; try { a = Integer.parseInt("not a number"); + fail("Exception not thrown"); } catch (NumberFormatException e) { // do nothing }