From a4f477329d0f063bd82a0442bde22d1df5ba1a66 Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Wed, 26 Feb 2014 17:54:25 +0400 Subject: [PATCH] Fixes bugs in try/catch --- .../java/lang/TSecurityException.java | 40 +++++++++++++++++++ .../dependency/DependencyGraphBuilder.java | 10 +++++ .../java/org/teavm/javascript/Decompiler.java | 3 ++ .../java/org/teavm/javascript/Renderer.java | 8 +++- .../org/teavm/model/util/ProgramUtils.java | 18 +++++++++ .../org/teavm/parsing/SSATransformer.java | 8 ++-- 6 files changed, 81 insertions(+), 6 deletions(-) create mode 100644 teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TSecurityException.java diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TSecurityException.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TSecurityException.java new file mode 100644 index 000000000..0e86cb4aa --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TSecurityException.java @@ -0,0 +1,40 @@ +/* + * Copyright 2014 Alexey Andreev. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.teavm.classlib.java.lang; + +/** + * + * @author Alexey Andreev + */ +public class TSecurityException extends TRuntimeException { + private static final long serialVersionUID = 720572643357872552L; + + public TSecurityException() { + super(); + } + + public TSecurityException(TString message, TThrowable cause) { + super(message, cause); + } + + public TSecurityException(TString message) { + super(message); + } + + public TSecurityException(TThrowable cause) { + super(cause); + } +} diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java index 2c72e65e6..b96ae6e54 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java @@ -60,6 +60,16 @@ class DependencyGraphBuilder { nodes[incoming.getValue().getIndex()].connect(nodes[phi.getReceiver().getIndex()]); } } + for (final TryCatchBlockReader tryCatch : block.readTryCatchBlocks()) { + useRunners.add(new Runnable() { + @Override + public void run() { + if (tryCatch.getExceptionType() != null) { + dependencyChecker.initClass(tryCatch.getExceptionType(), callerStack); + } + } + }); + } } dep.setUseRunner(new MultipleRunner(useRunners)); } diff --git a/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java b/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java index 88bc98e86..fcadfdf9b 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java @@ -213,6 +213,9 @@ public class Decompiler { if (node >= 0) { generator.currentBlock = program.basicBlockAt(node); int tmp = indexer.nodeAt(next); + if (tmp < 0) { + throw new IllegalArgumentException(); + } generator.nextBlock = next < indexer.size() ? program.basicBlockAt(tmp) : null; generator.statements.clear(); for (Instruction insn : generator.currentBlock.getInstructions()) { diff --git a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java index d2eace571..ad7052c3c 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java @@ -1268,8 +1268,12 @@ public class Renderer implements ExprVisitor, StatementVisitor { .ws().append("{").indent().softNewLine(); writer.append("$je").ws().append("=").ws().append("$e.$javaException;").softNewLine(); for (TryCatchStatement catchClause : sequence) { - writer.append("if").ws().append("($je && $je instanceof ").appendClass(catchClause.getExceptionType()) - .append(")").ws().append("{").indent().softNewLine(); + writer.append("if").ws().append("($je"); + if (catchClause.getExceptionType() != null) { + writer.ws().append("&&").ws().append("$je instanceof ") + .appendClass(catchClause.getExceptionType()); + } + writer.append(")").ws().append("{").indent().softNewLine(); if (statement.getExceptionVariable() != catchClause.getExceptionVariable()) { if (catchClause.getExceptionVariable() != null) { writer.append(variableName(catchClause.getExceptionVariable())).ws().append("=").ws() diff --git a/teavm-core/src/main/java/org/teavm/model/util/ProgramUtils.java b/teavm-core/src/main/java/org/teavm/model/util/ProgramUtils.java index 9c25eeaa1..8eff354be 100644 --- a/teavm-core/src/main/java/org/teavm/model/util/ProgramUtils.java +++ b/teavm-core/src/main/java/org/teavm/model/util/ProgramUtils.java @@ -25,6 +25,24 @@ import org.teavm.model.instructions.*; * @author Alexey Andreev */ public class ProgramUtils { + public static Graph buildControlFlowGraphWithoutTryCatch(Program program) { + GraphBuilder graphBuilder = new GraphBuilder(program.basicBlockCount()); + InstructionTransitionExtractor transitionExtractor = new InstructionTransitionExtractor(); + for (int i = 0; i < program.basicBlockCount(); ++i) { + BasicBlock block = program.basicBlockAt(i); + Instruction insn = block.getLastInstruction(); + if (insn != null) { + insn.acceptVisitor(transitionExtractor); + if (transitionExtractor.getTargets() != null) { + for (BasicBlock successor : transitionExtractor.getTargets()) { + graphBuilder.addEdge(i, successor.getIndex()); + } + } + } + } + return graphBuilder.build(); + } + public static Graph buildControlFlowGraph(Program program) { GraphBuilder graphBuilder = new GraphBuilder(program.basicBlockCount()); InstructionTransitionExtractor transitionExtractor = new InstructionTransitionExtractor(); diff --git a/teavm-core/src/main/java/org/teavm/parsing/SSATransformer.java b/teavm-core/src/main/java/org/teavm/parsing/SSATransformer.java index 4dc4224ab..b13f6cc72 100644 --- a/teavm-core/src/main/java/org/teavm/parsing/SSATransformer.java +++ b/teavm-core/src/main/java/org/teavm/parsing/SSATransformer.java @@ -32,7 +32,6 @@ public class SSATransformer { private Program program; private Graph cfg; private DominatorTree domTree; - private Graph domGraph; private int[][] domFrontiers; private Variable[] variableMap; private BasicBlock currentBlock; @@ -46,7 +45,7 @@ public class SSATransformer { } this.program = program; this.arguments = arguments; - cfg = ProgramUtils.buildControlFlowGraph(program); + cfg = ProgramUtils.buildControlFlowGraphWithoutTryCatch(program); domTree = GraphUtils.buildDominatorTree(cfg); domFrontiers = new int[cfg.size()][]; variableMap = new Variable[program.variableCount()]; @@ -103,11 +102,12 @@ public class SSATransformer { } private void renameVariables() { - domGraph = GraphUtils.buildDominatorGraph(domTree, program.basicBlockCount()); + DominatorTree domTree = GraphUtils.buildDominatorTree(ProgramUtils.buildControlFlowGraph(program)); + Graph domGraph = GraphUtils.buildDominatorGraph(domTree, program.basicBlockCount()); Task[] stack = new Task[cfg.size() * 2]; int head = 0; for (int i = 0; i < program.basicBlockCount(); ++i) { - if (domTree.immediateDominatorOf(i) < 0) { + if (domGraph.incomingEdgesCount(i) == 0) { Task task = new Task(); task.block = program.basicBlockAt(i); task.variables = Arrays.copyOf(variableMap, variableMap.length);