From 5d1fb3f67fcad3d80b3d1f0ccb9a79f957ed46cf Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Mon, 23 Feb 2015 22:39:13 +0300 Subject: [PATCH 01/69] Developing algorithm for node splitting that would maintain DJ-graph incrementally --- .../teavm/common/DominatorTreeBuilder.java | 14 +- .../org/teavm/common/GraphNodeFilter.java | 24 +++ .../java/org/teavm/common/GraphUtils.java | 62 ++++++- .../teavm/common/MutableDirectedGraph.java | 11 ++ .../common/{ => irreducible}/DJGraph.java | 109 ++++++++++--- .../irreducible}/GraphSplittingBackend.java | 2 +- .../IrreducibleGraphConverter.java | 79 +++++++++ .../model/util/IrreducibleGraphConverter.java | 151 ------------------ 8 files changed, 273 insertions(+), 179 deletions(-) create mode 100644 teavm-core/src/main/java/org/teavm/common/GraphNodeFilter.java rename teavm-core/src/main/java/org/teavm/common/{ => irreducible}/DJGraph.java (52%) rename teavm-core/src/main/java/org/teavm/{model/util => common/irreducible}/GraphSplittingBackend.java (95%) create mode 100644 teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java delete mode 100644 teavm-core/src/main/java/org/teavm/model/util/IrreducibleGraphConverter.java diff --git a/teavm-core/src/main/java/org/teavm/common/DominatorTreeBuilder.java b/teavm-core/src/main/java/org/teavm/common/DominatorTreeBuilder.java index 06626673a..77ad2cde8 100644 --- a/teavm-core/src/main/java/org/teavm/common/DominatorTreeBuilder.java +++ b/teavm-core/src/main/java/org/teavm/common/DominatorTreeBuilder.java @@ -45,12 +45,12 @@ class DominatorTreeBuilder { bucket = new IntegerArray[graph.size()]; } - public void build() { + public void build(int[] start) { for (int i = 0; i < labels.length; ++i) { labels[i] = i; } Arrays.fill(ancestors, -1); - dfs(); + dfs(start); for (int i = effectiveSize - 1; i >= 0; --i) { int w = vertices[i]; if (parents[w] < 0) { @@ -120,15 +120,13 @@ class DominatorTreeBuilder { return labels[v]; } - private void dfs() { + private void dfs(int[] start) { Arrays.fill(semidominators, -1); Arrays.fill(vertices, -1); IntegerStack stack = new IntegerStack(graph.size()); - for (int i = graph.size() - 1; i >= 0; --i) { - if (graph.incomingEdgesCount(i) == 0) { - stack.push(i); - parents[i] = -1; - } + for (int node : start) { + stack.push(node); + parents[node] = -1; } int i = 0; while (!stack.isEmpty()) { diff --git a/teavm-core/src/main/java/org/teavm/common/GraphNodeFilter.java b/teavm-core/src/main/java/org/teavm/common/GraphNodeFilter.java new file mode 100644 index 000000000..a7a9cb1f3 --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/common/GraphNodeFilter.java @@ -0,0 +1,24 @@ +/* + * Copyright 2015 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.common; + +/** + * + * @author Alexey Andreev + */ +public interface GraphNodeFilter { + boolean match(int node); +} diff --git a/teavm-core/src/main/java/org/teavm/common/GraphUtils.java b/teavm-core/src/main/java/org/teavm/common/GraphUtils.java index a320cff6d..eea85e356 100644 --- a/teavm-core/src/main/java/org/teavm/common/GraphUtils.java +++ b/teavm-core/src/main/java/org/teavm/common/GraphUtils.java @@ -15,7 +15,9 @@ */ package org.teavm.common; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; /** @@ -104,9 +106,67 @@ public final class GraphUtils { return cnt; } + /* + * Tarjan's algorithm + */ + public static int[][] findStronglyConnectedComponents(Graph graph, int[] start, GraphNodeFilter filter) { + List components = new ArrayList<>(); + boolean[] done = new boolean[graph.size()]; + int[] visitIndex = new int[graph.size()]; + Arrays.fill(visitIndex, -1); + int[] headerIndex = new int[graph.size()]; + int lastIndex = 0; + IntegerStack stack = new IntegerStack(graph.size()); + for (int startNode : start) { + stack.push(startNode); + } + + IntegerArray currentComponent = new IntegerArray(1); + while (!stack.isEmpty()) { + int node = stack.pop(); + if (visitIndex[node] == 0) { + if (done[node]) { + currentComponent.add(node); + int hdr = node; + for (int successor : graph.outgoingEdges(node)) { + if (!filter.match(successor)) { + continue; + } + if (!done[successor]) { + hdr = Math.min(hdr, visitIndex[successor]); + } else { + hdr = Math.min(hdr, headerIndex[successor]); + } + } + if (hdr == node) { + components.add(currentComponent.getAll()); + currentComponent.clear(); + } + headerIndex[node] = hdr; + } else { + done[node] = true; + } + } else { + visitIndex[node] = ++lastIndex; + stack.push(node); + for (int successor : graph.outgoingEdges(node)) { + if (!filter.match(successor)) { + continue; + } + stack.push(node); + } + } + } + return components.toArray(new int[0][]); + } + public static DominatorTree buildDominatorTree(Graph graph) { + return buildDominatorTree(graph, 0); + } + + public static DominatorTree buildDominatorTree(Graph graph, int... start) { DominatorTreeBuilder builder = new DominatorTreeBuilder(graph); - builder.build(); + builder.build(start); return new DefaultDominatorTree(builder.dominators, builder.vertices); } diff --git a/teavm-core/src/main/java/org/teavm/common/MutableDirectedGraph.java b/teavm-core/src/main/java/org/teavm/common/MutableDirectedGraph.java index d8981af54..8036e16ae 100644 --- a/teavm-core/src/main/java/org/teavm/common/MutableDirectedGraph.java +++ b/teavm-core/src/main/java/org/teavm/common/MutableDirectedGraph.java @@ -57,6 +57,17 @@ public class MutableDirectedGraph implements Graph { predecessors.get(to).add(from); } + public void detachNode(int node) { + for (IntCursor succ : successors.get(node)) { + predecessors.get(succ.value).removeAllOccurrences(node); + } + for (IntCursor pred : predecessors.get(node)) { + successors.get(pred.value).removeAllOccurrences(node); + } + predecessors.get(node).clear(); + successors.get(node).clear(); + } + @Override public int[] incomingEdges(int node) { return predecessors.get(node).toArray(); diff --git a/teavm-core/src/main/java/org/teavm/common/DJGraph.java b/teavm-core/src/main/java/org/teavm/common/irreducible/DJGraph.java similarity index 52% rename from teavm-core/src/main/java/org/teavm/common/DJGraph.java rename to teavm-core/src/main/java/org/teavm/common/irreducible/DJGraph.java index 04319ad89..bf8486266 100644 --- a/teavm-core/src/main/java/org/teavm/common/DJGraph.java +++ b/teavm-core/src/main/java/org/teavm/common/irreducible/DJGraph.java @@ -13,11 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.teavm.common; +package org.teavm.common.irreducible; +import com.carrotsearch.hppc.IntOpenHashSet; +import com.carrotsearch.hppc.IntSet; +import com.carrotsearch.hppc.cursors.IntCursor; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import org.teavm.common.*; /** * @@ -25,36 +29,44 @@ import java.util.List; */ public class DJGraph { private DominatorTree domTree; - private Graph graph; + private MutableDirectedGraph cfg; + private MutableDirectedGraph graph; private LCATree spanningTree; private int[] spanningTreeNode; private int[] spanningTreeIndex; private int[][] levelContent; + private int[] mergeRoot; + private IntegerArray[] mergeClasses; - public DJGraph(Graph src) { - domTree = GraphUtils.buildDominatorTree(src); + public DJGraph(Graph src, int top) { + this.cfg = new MutableDirectedGraph(src); + domTree = GraphUtils.buildDominatorTree(src, top); buildGraph(src); buildLevels(); dfs(); + mergeRoot = new int[src.size()]; + mergeClasses = new IntegerArray[src.size()]; + for (int i = 0; i < mergeRoot.length; ++i) { + mergeRoot[i] = i; + mergeClasses[i] = IntegerArray.of(i); + } } - private void buildGraph(Graph graph) { - GraphBuilder builder = new GraphBuilder(graph.size()); + private void buildGraph(Graph src) { + graph = new MutableDirectedGraph(); // Add join edges - for (int i = 0; i < graph.size(); ++i) { - for (int j : graph.outgoingEdges(i)) { - builder.addEdge(i, j); + for (int i = 0; i < src.size(); ++i) { + for (int j : src.outgoingEdges(i)) { + graph.addEdge(i, j); } } // Add dom edges for (int i = 1; i < graph.size(); ++i) { int j = domTree.immediateDominatorOf(i); - builder.addEdge(j, i); + graph.addEdge(j, i); } - - graph = builder.build(); } private void buildLevels() { @@ -102,13 +114,17 @@ public class DJGraph { return domTree; } + public MutableDirectedGraph getCfg() { + return cfg; + } + public Graph getGraph() { return graph; } public boolean isAncestorInSpanningTree(int anc, int node) { - anc = spanningTreeIndex[anc]; - node = spanningTreeIndex[node]; + anc = spanningTreeIndex[mergeRoot[anc]]; + node = spanningTreeIndex[mergeRoot[node]]; if (anc < 0 || node < 0) { return false; } @@ -116,7 +132,7 @@ public class DJGraph { } public boolean isDomEdge(int i, int j) { - return domTree.immediateDominatorOf(j) == i; + return domTree.immediateDominatorOf(mergeRoot[j]) == mergeRoot[i]; } public boolean isJoinEdge(int i, int j) { @@ -124,24 +140,28 @@ public class DJGraph { } public boolean isBackJoin(int i, int j) { - return isJoinEdge(i, j) && !domTree.dominates(j, i); + return isJoinEdge(i, j) && !domTree.dominates(mergeRoot[j], mergeRoot[i]); } public boolean isCrossJoin(int i, int j) { - return isJoinEdge(i, j) && domTree.dominates(j, i); + return isJoinEdge(i, j) && domTree.dominates(mergeRoot[j], mergeRoot[i]); } public boolean isSpanningBack(int i, int j) { + i = spanningTreeIndex[mergeRoot[i]]; + j = spanningTreeIndex[mergeRoot[j]]; return spanningTree.lcaOf(i, j) == j; } public boolean isSpanningCross(int i, int j) { + i = spanningTreeIndex[mergeRoot[i]]; + j = spanningTreeIndex[mergeRoot[j]]; int c = spanningTree.lcaOf(i, j); return c != i && c != j; } public int levelOf(int node) { - return domTree.levelOf(node); + return domTree.levelOf(mergeRoot[node]); } public int[] level(int level) { @@ -152,4 +172,57 @@ public class DJGraph { public int levelCount() { return levelContent.length; } + + public int[] classRepresentatives(int node) { + return mergeClasses[node].getAll(); + } + + public int classOf(int node) { + return mergeRoot[node]; + } + + public void collapse(int[] nodes) { + // Replace nodes with their classes and find common dominator among them + IntSet set = new IntOpenHashSet(); + int top = nodes[0]; + for (int node : nodes) { + node = mergeRoot[node]; + top = domTree.commonDominatorOf(top, node); + set.add(node); + } + if (!set.contains(top)) { + throw new IllegalArgumentException("All nodes must have one common dominator"); + } + + // Alter classes + IntegerArray cls = mergeClasses[top]; + for (IntCursor node : set) { + mergeRoot[node.value] = top; + if (node.value != top) { + cls.addAll(mergeClasses[node.value].getAll()); + mergeClasses[node.value].clear(); + } + } + + // Alter graphs + for (IntCursor node : set) { + if (node.value != top) { + for (int succ : graph.outgoingEdges(node.value)) { + graph.addEdge(top, succ); + } + for (int pred : graph.incomingEdges(node.value)) { + graph.addEdge(top, pred); + } + graph.detachNode(node.value); + + for (int succ : cfg.outgoingEdges(node.value)) { + cfg.addEdge(top, succ); + } + for (int pred : cfg.incomingEdges(node.value)) { + cfg.addEdge(top, pred); + } + cfg.detachNode(node.value); + } + } + } } diff --git a/teavm-core/src/main/java/org/teavm/model/util/GraphSplittingBackend.java b/teavm-core/src/main/java/org/teavm/common/irreducible/GraphSplittingBackend.java similarity index 95% rename from teavm-core/src/main/java/org/teavm/model/util/GraphSplittingBackend.java rename to teavm-core/src/main/java/org/teavm/common/irreducible/GraphSplittingBackend.java index 2616d4bfd..fbf791ceb 100644 --- a/teavm-core/src/main/java/org/teavm/model/util/GraphSplittingBackend.java +++ b/teavm-core/src/main/java/org/teavm/common/irreducible/GraphSplittingBackend.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.teavm.model.util; +package org.teavm.common.irreducible; /** * diff --git a/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java b/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java new file mode 100644 index 000000000..a84de998b --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java @@ -0,0 +1,79 @@ +/* + * Copyright 2015 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.common.irreducible; + +import com.carrotsearch.hppc.IntSet; +import org.teavm.common.Graph; +import org.teavm.common.GraphNodeFilter; +import org.teavm.common.GraphUtils; + +/** + *

Converts irreducible graph to reducible one using node splitting algorithm described at + * the paper “Handling irreducible loops: optimized node splitting vs. DJ-graphs” by + * Sebastian Unger and Frank Mueller.

+ * + * @author Alexey Andreev + */ +public class IrreducibleGraphConverter { + private GraphSplittingBackend backend; + + public void convertToReducible(Graph cfg, GraphSplittingBackend backend) { + this.backend = backend; + handleLoops(new DJGraph(cfg, 0)); + this.backend = null; + } + + private void handleLoops(DJGraph djGraph) { + for (int level = djGraph.levelCount() - 1; level >= 0; --level) { + boolean irreducible = false; + for (int node : djGraph.level(level)) { + for (int pred : djGraph.getGraph().incomingEdges(node)) { + if (djGraph.isCrossJoin(pred, node)) { + if (!irreducible && djGraph.isSpanningBack(node, pred)) { + irreducible = true; + } + } else if (djGraph.isBackJoin(node, pred)) { + djGraph.collapse(reachUnder(djGraph, pred)); + } + } + } + DJGraphNodeFilter filter = new DJGraphNodeFilter(djGraph, level, null); + int[][] sccs = GraphUtils.findStronglyConnectedComponents(djGraph.getGraph(), djGraph.level(level), filter); + } + } + + private int[] reachUnder(DJGraph djGraph, int top) { + // TODO: implement + return null; + } + + static class DJGraphNodeFilter implements GraphNodeFilter { + private DJGraph graph; + private int level; + private IntSet nodes; + + public DJGraphNodeFilter(DJGraph graph, int level, IntSet nodes) { + this.graph = graph; + this.level = level; + this.nodes = nodes; + } + + @Override + public boolean match(int node) { + return nodes.contains(node) && graph.levelOf(node) >= level; + } + } +} diff --git a/teavm-core/src/main/java/org/teavm/model/util/IrreducibleGraphConverter.java b/teavm-core/src/main/java/org/teavm/model/util/IrreducibleGraphConverter.java deleted file mode 100644 index e4d8a8e45..000000000 --- a/teavm-core/src/main/java/org/teavm/model/util/IrreducibleGraphConverter.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2015 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.model.util; - -import com.carrotsearch.hppc.IntOpenHashSet; -import com.carrotsearch.hppc.IntSet; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import org.teavm.common.*; - -/** - *

Converts irreducible graph to reducible one using node splitting algorithm described at - * the paper “Handling irreducible loops: optimized node splitting vs. DJ-graphs” by - * Sebastian Unger and Frank Mueller.

- * - * @author Alexey Andreev - */ -public class IrreducibleGraphConverter { - private MutableDirectedGraph graph; - private DisjointSet nodeClasses = new DisjointSet(); - private List classContents = new ArrayList<>(); - private DJGraph djGraph; - private GraphSplittingBackend backend; - - public void convertToReducible(Graph cfg, GraphSplittingBackend backend) { - this.backend = backend; - buildMutableCFG(cfg); - rebuildDJGraph(); - splitLoops(0, allNodesOf(cfg)); - this.backend = null; - } - - private boolean splitLoops(int top, IntSet nodesToHandle) { - boolean hasCrossEdge = false; - for (int child : djGraph.getGraph().outgoingEdges(top)) { - if (!djGraph.isDomEdge(top, child)) { - continue; - } - hasCrossEdge |= nodesToHandle.contains(child) && splitLoops(child, nodesToHandle); - } - if (hasCrossEdge) { - handleIrreducibleLoopChildren(top, nodesToHandle); - } - for (int pred : graph.incomingEdges(top)) { - if (djGraph.isSpanningBack(pred, top) && djGraph.isCrossJoin(top, pred)) { - return true; - } - } - return false; - } - - private void handleIrreducibleLoopChildren(int top, IntSet nodesToHandle) { - List sccs = findStronglyConnectedComponents(top, nodesToHandle, djGraph.levelOf(top)); - for (int[] scc : sccs) { - if (scc.length > 1) { - handleStronglyConnectedComponent(top, scc); - } - } - } - - private void handleStronglyConnectedComponent(int top, int[] nodes) { - - } - - /* - * Tarjan's algorithm - */ - private List findStronglyConnectedComponents(int start, IntSet nodesToHandle, int topLevel) { - List components = new ArrayList<>(); - boolean[] done = new boolean[djGraph.getGraph().size()]; - int[] visitIndex = new int[djGraph.getGraph().size()]; - Arrays.fill(visitIndex, -1); - int[] headerIndex = new int[djGraph.getGraph().size()]; - int lastIndex = 0; - IntegerStack stack = new IntegerStack(nodesToHandle.size()); - stack.push(-1); - stack.push(start); - - IntegerArray currentComponent = new IntegerArray(1); - while (!stack.isEmpty()) { - int node = stack.pop(); - if (visitIndex[node] == 0) { - if (done[node]) { - currentComponent.add(node); - int hdr = node; - for (int successor : djGraph.getGraph().outgoingEdges(node)) { - if (!nodesToHandle.contains(successor) || djGraph.levelOf(node) < topLevel) { - continue; - } - if (!done[successor]) { - hdr = Math.min(hdr, visitIndex[successor]); - } else { - hdr = Math.min(hdr, headerIndex[successor]); - } - } - if (hdr == node) { - components.add(currentComponent.getAll()); - currentComponent.clear(); - } - headerIndex[node] = hdr; - } else { - done[node] = true; - } - } else { - visitIndex[node] = ++lastIndex; - stack.push(node); - for (int successor : djGraph.getGraph().outgoingEdges(node)) { - if (!nodesToHandle.contains(successor) || djGraph.levelOf(node) >= topLevel) { - continue; - } - stack.push(node); - } - } - } - return components; - } - - private void buildMutableCFG(Graph cfg) { - graph = new MutableDirectedGraph(cfg); - for (int i = 0; i < cfg.size(); ++i) { - nodeClasses.create(); - classContents.add(IntegerArray.of(i)); - } - } - - private IntSet allNodesOf(Graph cfg) { - int[] allNodes = new int[cfg.size()]; - for (int i = 0; i < cfg.size(); ++i) { - allNodes[i] = i; - } - return IntOpenHashSet.from(allNodes); - } - - private void rebuildDJGraph() { - djGraph = new DJGraph(graph); - } -} From 9adbb1ae935614897f331245e6feb4a761436d60 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Fri, 27 Feb 2015 21:33:57 +0300 Subject: [PATCH 02/69] Revert some code --- .../org/teavm/common/DominatorTreeBuilder.java | 14 ++++++++------ .../src/main/java/org/teavm/common/GraphUtils.java | 6 +----- .../java/org/teavm/common/irreducible/DJGraph.java | 4 ++-- .../irreducible/IrreducibleGraphConverter.java | 2 +- 4 files changed, 12 insertions(+), 14 deletions(-) diff --git a/teavm-core/src/main/java/org/teavm/common/DominatorTreeBuilder.java b/teavm-core/src/main/java/org/teavm/common/DominatorTreeBuilder.java index 77ad2cde8..06626673a 100644 --- a/teavm-core/src/main/java/org/teavm/common/DominatorTreeBuilder.java +++ b/teavm-core/src/main/java/org/teavm/common/DominatorTreeBuilder.java @@ -45,12 +45,12 @@ class DominatorTreeBuilder { bucket = new IntegerArray[graph.size()]; } - public void build(int[] start) { + public void build() { for (int i = 0; i < labels.length; ++i) { labels[i] = i; } Arrays.fill(ancestors, -1); - dfs(start); + dfs(); for (int i = effectiveSize - 1; i >= 0; --i) { int w = vertices[i]; if (parents[w] < 0) { @@ -120,13 +120,15 @@ class DominatorTreeBuilder { return labels[v]; } - private void dfs(int[] start) { + private void dfs() { Arrays.fill(semidominators, -1); Arrays.fill(vertices, -1); IntegerStack stack = new IntegerStack(graph.size()); - for (int node : start) { - stack.push(node); - parents[node] = -1; + for (int i = graph.size() - 1; i >= 0; --i) { + if (graph.incomingEdgesCount(i) == 0) { + stack.push(i); + parents[i] = -1; + } } int i = 0; while (!stack.isEmpty()) { diff --git a/teavm-core/src/main/java/org/teavm/common/GraphUtils.java b/teavm-core/src/main/java/org/teavm/common/GraphUtils.java index eea85e356..925b6d3a2 100644 --- a/teavm-core/src/main/java/org/teavm/common/GraphUtils.java +++ b/teavm-core/src/main/java/org/teavm/common/GraphUtils.java @@ -161,12 +161,8 @@ public final class GraphUtils { } public static DominatorTree buildDominatorTree(Graph graph) { - return buildDominatorTree(graph, 0); - } - - public static DominatorTree buildDominatorTree(Graph graph, int... start) { DominatorTreeBuilder builder = new DominatorTreeBuilder(graph); - builder.build(start); + builder.build(); return new DefaultDominatorTree(builder.dominators, builder.vertices); } diff --git a/teavm-core/src/main/java/org/teavm/common/irreducible/DJGraph.java b/teavm-core/src/main/java/org/teavm/common/irreducible/DJGraph.java index bf8486266..655c5f765 100644 --- a/teavm-core/src/main/java/org/teavm/common/irreducible/DJGraph.java +++ b/teavm-core/src/main/java/org/teavm/common/irreducible/DJGraph.java @@ -38,9 +38,9 @@ public class DJGraph { private int[] mergeRoot; private IntegerArray[] mergeClasses; - public DJGraph(Graph src, int top) { + public DJGraph(Graph src) { this.cfg = new MutableDirectedGraph(src); - domTree = GraphUtils.buildDominatorTree(src, top); + domTree = GraphUtils.buildDominatorTree(src); buildGraph(src); buildLevels(); dfs(); diff --git a/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java b/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java index a84de998b..aa908dba8 100644 --- a/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java +++ b/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java @@ -32,7 +32,7 @@ public class IrreducibleGraphConverter { public void convertToReducible(Graph cfg, GraphSplittingBackend backend) { this.backend = backend; - handleLoops(new DJGraph(cfg, 0)); + handleLoops(new DJGraph(cfg)); this.backend = null; } From 8ad58ce2d289f58c9c7cf5fc1c432c83db5e727a Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Fri, 27 Feb 2015 23:26:28 +0300 Subject: [PATCH 03/69] Further implementation of node splitting --- .../org/teavm/common/irreducible/DJGraph.java | 21 +++- .../IrreducibleGraphConverter.java | 104 +++++++++++++++++- 2 files changed, 118 insertions(+), 7 deletions(-) diff --git a/teavm-core/src/main/java/org/teavm/common/irreducible/DJGraph.java b/teavm-core/src/main/java/org/teavm/common/irreducible/DJGraph.java index 655c5f765..faefb296a 100644 --- a/teavm-core/src/main/java/org/teavm/common/irreducible/DJGraph.java +++ b/teavm-core/src/main/java/org/teavm/common/irreducible/DJGraph.java @@ -36,9 +36,14 @@ public class DJGraph { private int[] spanningTreeIndex; private int[][] levelContent; private int[] mergeRoot; + private int[] weight; private IntegerArray[] mergeClasses; - public DJGraph(Graph src) { + public DJGraph(Graph src, int[] weight) { + if (src.size() != weight.length) { + throw new IllegalArgumentException("Node count " + src.size() + " is not equal to weight array " + + weight.length); + } this.cfg = new MutableDirectedGraph(src); domTree = GraphUtils.buildDominatorTree(src); buildGraph(src); @@ -50,6 +55,7 @@ public class DJGraph { mergeRoot[i] = i; mergeClasses[i] = IntegerArray.of(i); } + weight = Arrays.copyOf(weight, weight.length); } private void buildGraph(Graph src) { @@ -160,6 +166,18 @@ public class DJGraph { return c != i && c != j; } + public int weightOf(int node) { + return weight[node]; + } + + public int weightOf(int... nodes) { + int result = 0; + for (int node : nodes) { + result += weight[node]; + } + return result; + } + public int levelOf(int node) { return domTree.levelOf(mergeRoot[node]); } @@ -202,6 +220,7 @@ public class DJGraph { cls.addAll(mergeClasses[node.value].getAll()); mergeClasses[node.value].clear(); } + weight[top] += weight[node.value]; } // Alter graphs diff --git a/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java b/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java index aa908dba8..84768ef23 100644 --- a/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java +++ b/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java @@ -15,10 +15,9 @@ */ package org.teavm.common.irreducible; +import org.teavm.common.*; +import com.carrotsearch.hppc.IntOpenHashSet; import com.carrotsearch.hppc.IntSet; -import org.teavm.common.Graph; -import org.teavm.common.GraphNodeFilter; -import org.teavm.common.GraphUtils; /** *

Converts irreducible graph to reducible one using node splitting algorithm described at @@ -28,15 +27,21 @@ import org.teavm.common.GraphUtils; * @author Alexey Andreev */ public class IrreducibleGraphConverter { + private Graph cfg; private GraphSplittingBackend backend; - public void convertToReducible(Graph cfg, GraphSplittingBackend backend) { + public void convertToReducible(Graph cfg, int[] weight, GraphSplittingBackend backend) { this.backend = backend; - handleLoops(new DJGraph(cfg)); + int[] identityNodeMap = new int[cfg.size()]; + for (int i = 0; i < identityNodeMap.length; ++i) { + identityNodeMap[i] = i; + } + this.cfg = cfg; + handleLoops(new DJGraph(cfg, weight), identityNodeMap); this.backend = null; } - private void handleLoops(DJGraph djGraph) { + private void handleLoops(DJGraph djGraph, int[] nodeMap) { for (int level = djGraph.levelCount() - 1; level >= 0; --level) { boolean irreducible = false; for (int node : djGraph.level(level)) { @@ -52,6 +57,10 @@ public class IrreducibleGraphConverter { } DJGraphNodeFilter filter = new DJGraphNodeFilter(djGraph, level, null); int[][] sccs = GraphUtils.findStronglyConnectedComponents(djGraph.getGraph(), djGraph.level(level), filter); + for (int[] scc : sccs) { + handleStronglyConnectedComponent(djGraph, scc, nodeMap); + djGraph.collapse(scc); + } } } @@ -60,6 +69,89 @@ public class IrreducibleGraphConverter { return null; } + private void handleStronglyConnectedComponent(DJGraph djGraph, int[] scc, int[] nodeMap) { + // Find shared dominator + int sharedDom = scc[0]; + for (int i = 1; i < scc.length; ++i) { + sharedDom = djGraph.getDomTree().commonDominatorOf(sharedDom, scc[i]); + } + + // Partition SCC into domains + DisjointSet partitions = new DisjointSet(); + for (int i = 0; i < scc.length; ++i) { + partitions.create(); + } + for (int i = 0; i < scc.length; ++i) { + int node = scc[i]; + int idom = djGraph.getDomTree().immediateDominatorOf(node); + if (idom != sharedDom) { + partitions.union(node, idom); + } + } + int[] domains = partitions.pack(scc.length); + int domainCount = 0; + for (int domain : domains) { + domainCount = Math.max(domainCount, domain + 1); + } + + // For each domain calculate its weight + int[] domainWeight = new int [domainCount]; + for (int i = 0; i < scc.length; ++i) { + int node = scc[i]; + domainWeight[domains[node]] += djGraph.weightOf(node); + } + + // Find domain to split around + int domain = 0; + int maxWeight = domainWeight[0]; + for (int i = 1; i < domainWeight.length; ++i) { + if (domainWeight[i] > maxWeight) { + domain = i; + maxWeight = domainWeight[i]; + } + } + + // Find header of this domain + IntSet domainNodes = new IntOpenHashSet(scc.length); + for (int i = 0; i < scc.length; ++i) { + int node = scc[i]; + if (domains[node] == domain) { + domainNodes.add(node); + } + } + + // Split + int[] newNodes = splitStronglyConnectedComponent(domainNodes, scc, nodeMap); + + // Construct DJ-subgraph + int[] newNodeMap = new int[1 + scc.length + newNodes.length]; + for (int i = 0; i < scc.length; ++i) { + newNodeMap[i + 1] = nodeMap[scc[i]]; + } + for (int i = 0; i < newNodes.length; ++i) { + newNodeMap[i + 1 + scc.length] = newNodes[i]; + } + GraphBuilder builder = new GraphBuilder(newNodeMap.length); + + for (int i = 0; i < scc.length; ++i) { + + } + } + + private int[] splitStronglyConnectedComponent(IntSet domain, int[] scc, int[] nodeMap) { + IntegerArray nonDomain = new IntegerArray(scc.length); + for (int node : scc) { + if (!domain.contains(node)) { + nonDomain.add(node); + } + } + int[] mappedNonDomain = new int[nonDomain.size()]; + for (int i = 0; i < nonDomain.size(); ++i) { + mappedNonDomain[i] = nodeMap[nonDomain.get(i)]; + } + return backend.split(mappedNonDomain); + } + static class DJGraphNodeFilter implements GraphNodeFilter { private DJGraph graph; private int level; From 77b42e677a7a1f176a1c9a5580030ecaa1719462 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Sun, 1 Mar 2015 22:25:07 +0300 Subject: [PATCH 04/69] Complete algorithm that creates subgraph to apply node splitting recursively --- .../irreducible/GraphSplittingBackend.java | 2 +- .../IrreducibleGraphConverter.java | 96 ++++++++++++++----- 2 files changed, 75 insertions(+), 23 deletions(-) diff --git a/teavm-core/src/main/java/org/teavm/common/irreducible/GraphSplittingBackend.java b/teavm-core/src/main/java/org/teavm/common/irreducible/GraphSplittingBackend.java index fbf791ceb..69792cf65 100644 --- a/teavm-core/src/main/java/org/teavm/common/irreducible/GraphSplittingBackend.java +++ b/teavm-core/src/main/java/org/teavm/common/irreducible/GraphSplittingBackend.java @@ -20,5 +20,5 @@ package org.teavm.common.irreducible; * @author Alexey Andreev */ public interface GraphSplittingBackend { - int[] split(int[] nodes); + int[] split(int[] domain, int[] nodes); } diff --git a/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java b/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java index 84768ef23..dcd576945 100644 --- a/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java +++ b/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java @@ -15,9 +15,11 @@ */ package org.teavm.common.irreducible; +import java.util.Arrays; import org.teavm.common.*; import com.carrotsearch.hppc.IntOpenHashSet; import com.carrotsearch.hppc.IntSet; +import com.carrotsearch.hppc.cursors.IntCursor; /** *

Converts irreducible graph to reducible one using node splitting algorithm described at @@ -28,6 +30,7 @@ import com.carrotsearch.hppc.IntSet; */ public class IrreducibleGraphConverter { private Graph cfg; + private int[] cfgWeight; private GraphSplittingBackend backend; public void convertToReducible(Graph cfg, int[] weight, GraphSplittingBackend backend) { @@ -37,6 +40,7 @@ public class IrreducibleGraphConverter { identityNodeMap[i] = i; } this.cfg = cfg; + this.cfgWeight = weight; handleLoops(new DJGraph(cfg, weight), identityNodeMap); this.backend = null; } @@ -121,35 +125,83 @@ public class IrreducibleGraphConverter { } // Split - int[] newNodes = splitStronglyConnectedComponent(domainNodes, scc, nodeMap); - - // Construct DJ-subgraph - int[] newNodeMap = new int[1 + scc.length + newNodes.length]; - for (int i = 0; i < scc.length; ++i) { - newNodeMap[i + 1] = nodeMap[scc[i]]; - } - for (int i = 0; i < newNodes.length; ++i) { - newNodeMap[i + 1 + scc.length] = newNodes[i]; - } - GraphBuilder builder = new GraphBuilder(newNodeMap.length); - - for (int i = 0; i < scc.length; ++i) { - - } + splitStronglyConnectedComponent(domainNodes, sharedDom, scc, nodeMap); } - private int[] splitStronglyConnectedComponent(IntSet domain, int[] scc, int[] nodeMap) { - IntegerArray nonDomain = new IntegerArray(scc.length); + private void splitStronglyConnectedComponent(IntSet domain, int sharedDom, int[] scc, int[] nodeMap) { + // Find SCC \ domain + int[] mappedNonDomain = new int[scc.length - domain.size()]; + int index = 0; for (int node : scc) { if (!domain.contains(node)) { - nonDomain.add(node); + mappedNonDomain[index++] = nodeMap[node]; } } - int[] mappedNonDomain = new int[nonDomain.size()]; - for (int i = 0; i < nonDomain.size(); ++i) { - mappedNonDomain[i] = nodeMap[nonDomain.get(i)]; + int[] mappedDomain = new int[domain.size()]; + index = 0; + for (IntCursor cursor : domain) { + mappedDomain[index++] = cursor.value; } - return backend.split(mappedNonDomain); + + // Delegate splitting to domain + int[] newNodes = backend.split(mappedDomain, mappedNonDomain); + + // Calculate mappings + int[] newNodeMap = new int[1 + scc.length + newNodes.length]; + int[] newNodeBackMap = new int[cfg.size()]; + Arrays.fill(newNodeBackMap, -1); + newNodeMap[0] = nodeMap[sharedDom]; + newNodeBackMap[sharedDom] = 0; + index = 1; + for (int i = 0; i < mappedDomain.length; ++i) { + newNodeMap[index] = mappedDomain[i]; + newNodeBackMap[mappedDomain[i]] = index; + ++index; + } + for (int i = 0; i < mappedNonDomain.length; ++i) { + newNodeMap[index] = mappedNonDomain[i]; + newNodeBackMap[mappedNonDomain[i]] = index; + ++index; + } + + // Build subgraph with new nodes + GraphBuilder builder = new GraphBuilder(newNodeMap.length); + int[] mappedWeight = new int[newNodeMap.length]; + mappedWeight[0] = cfgWeight[newNodeMap[0]]; + for (int succ : cfg.outgoingEdges(sharedDom)) { + int j = newNodeBackMap[succ]; + if (j >= 0) { + builder.addEdge(0, j); + } + } + for (int i = 1; i <= mappedDomain.length; ++i) { + mappedWeight[i] = cfgWeight[newNodeMap[i]]; + for (int succ : cfg.outgoingEdges(mappedDomain[i])) { + int j = newNodeBackMap[succ]; + if (j > mappedDomain.length) { + builder.addEdge(i, j); + } else if (j >= 0) { + builder.addEdge(i, j + mappedNonDomain.length); + } + } + } + for (int i = mappedDomain.length + 1; i <= scc.length; ++i) { + mappedWeight[i] = cfgWeight[newNodeMap[i]]; + mappedWeight[i + mappedNonDomain.length] = cfgWeight[newNodeMap[i]]; + for (int succ : cfg.outgoingEdges(mappedNonDomain[i])) { + int j = newNodeBackMap[succ]; + if (j >= 0) { + builder.addEdge(i, j); + if (j > mappedDomain.length) { + builder.addEdge(i + mappedNonDomain.length, j); + } else { + builder.addEdge(i + mappedNonDomain.length, j + mappedNonDomain.length); + } + } + } + } + + handleLoops(new DJGraph(builder.build(), mappedWeight), newNodeMap); } static class DJGraphNodeFilter implements GraphNodeFilter { From f106afb0345f92a96d416ead889ede34a7b9866d Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Sun, 1 Mar 2015 23:19:46 +0300 Subject: [PATCH 05/69] Complete node splitting algorithm. Add test case for SCC finder. --- .../java/org/teavm/common/GraphUtils.java | 52 ++++++------- .../IrreducibleGraphConverter.java | 22 +++++- .../test/java/org/teavm/common/GraphTest.java | 73 +++++++++++++++++++ 3 files changed, 113 insertions(+), 34 deletions(-) create mode 100644 teavm-core/src/test/java/org/teavm/common/GraphTest.java diff --git a/teavm-core/src/main/java/org/teavm/common/GraphUtils.java b/teavm-core/src/main/java/org/teavm/common/GraphUtils.java index 925b6d3a2..bd952fef4 100644 --- a/teavm-core/src/main/java/org/teavm/common/GraphUtils.java +++ b/teavm-core/src/main/java/org/teavm/common/GraphUtils.java @@ -19,7 +19,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; - /** * * @author Alexey Andreev @@ -111,9 +110,7 @@ public final class GraphUtils { */ public static int[][] findStronglyConnectedComponents(Graph graph, int[] start, GraphNodeFilter filter) { List components = new ArrayList<>(); - boolean[] done = new boolean[graph.size()]; int[] visitIndex = new int[graph.size()]; - Arrays.fill(visitIndex, -1); int[] headerIndex = new int[graph.size()]; int lastIndex = 0; IntegerStack stack = new IntegerStack(graph.size()); @@ -124,36 +121,32 @@ public final class GraphUtils { IntegerArray currentComponent = new IntegerArray(1); while (!stack.isEmpty()) { int node = stack.pop(); - if (visitIndex[node] == 0) { - if (done[node]) { - currentComponent.add(node); - int hdr = node; - for (int successor : graph.outgoingEdges(node)) { - if (!filter.match(successor)) { - continue; - } - if (!done[successor]) { - hdr = Math.min(hdr, visitIndex[successor]); - } else { - hdr = Math.min(hdr, headerIndex[successor]); - } - } - if (hdr == node) { - components.add(currentComponent.getAll()); - currentComponent.clear(); - } - headerIndex[node] = hdr; - } else { - done[node] = true; - } - } else { - visitIndex[node] = ++lastIndex; - stack.push(node); + if (visitIndex[node] > 0) { + currentComponent.add(node); + int hdr = visitIndex[node]; for (int successor : graph.outgoingEdges(node)) { if (!filter.match(successor)) { continue; } - stack.push(node); + if (headerIndex[successor] == 0) { + hdr = Math.min(hdr, visitIndex[successor]); + } else { + hdr = Math.min(hdr, headerIndex[successor]); + } + } + if (hdr == visitIndex[node]) { + components.add(currentComponent.getAll()); + currentComponent.clear(); + } + headerIndex[node] = hdr; + } else { + visitIndex[node] = ++lastIndex; + stack.push(node); + for (int successor : graph.outgoingEdges(node)) { + if (!filter.match(successor) || visitIndex[successor] > 0) { + continue; + } + stack.push(successor); } } } @@ -243,7 +236,6 @@ public final class GraphUtils { return domFrontiers; } - private static int[] makeSet(IntegerArray array) { int[] items = array.getAll(); int[] set = new int[items.length]; diff --git a/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java b/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java index dcd576945..a91ac26fd 100644 --- a/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java +++ b/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java @@ -55,7 +55,7 @@ public class IrreducibleGraphConverter { irreducible = true; } } else if (djGraph.isBackJoin(node, pred)) { - djGraph.collapse(reachUnder(djGraph, pred)); + djGraph.collapse(reachUnder(djGraph, pred, node)); } } } @@ -68,9 +68,20 @@ public class IrreducibleGraphConverter { } } - private int[] reachUnder(DJGraph djGraph, int top) { - // TODO: implement - return null; + private int[] reachUnder(DJGraph djGraph, int back, int header) { + IntSet naturalLoop = IntOpenHashSet.from(header); + IntegerStack stack = new IntegerStack(djGraph.getGraph().size()); + stack.push(back); + while (!stack.isEmpty()) { + int node = stack.pop(); + if (!naturalLoop.add(node)) { + continue; + } + for (int pred : djGraph.getGraph().incomingEdges(node)) { + stack.push(pred); + } + } + return naturalLoop.toArray(); } private void handleStronglyConnectedComponent(DJGraph djGraph, int[] scc, int[] nodeMap) { @@ -126,6 +137,9 @@ public class IrreducibleGraphConverter { // Split splitStronglyConnectedComponent(domainNodes, sharedDom, scc, nodeMap); + + // Collapse + djGraph.collapse(scc); } private void splitStronglyConnectedComponent(IntSet domain, int sharedDom, int[] scc, int[] nodeMap) { diff --git a/teavm-core/src/test/java/org/teavm/common/GraphTest.java b/teavm-core/src/test/java/org/teavm/common/GraphTest.java new file mode 100644 index 000000000..d757cd7bb --- /dev/null +++ b/teavm-core/src/test/java/org/teavm/common/GraphTest.java @@ -0,0 +1,73 @@ +/* + * Copyright 2015 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.common; + +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.*; +import java.util.Arrays; +import java.util.Comparator; +import org.junit.Test; + +/** + * + * @author Alexey Andreev + */ +public class GraphTest { + @Test + public void stronglyConnectedComponentsCalculated() { + GraphBuilder builder = new GraphBuilder(); + builder.addEdge(0, 1); + builder.addEdge(1, 2); + builder.addEdge(2, 3); + builder.addEdge(2, 4); + builder.addEdge(3, 5); + builder.addEdge(4, 5); + builder.addEdge(5, 6); + builder.addEdge(6, 1); + builder.addEdge(6, 7); + builder.addEdge(7, 8); + builder.addEdge(7, 9); + builder.addEdge(8, 1); + builder.addEdge(9, 10); + builder.addEdge(10, 11); + builder.addEdge(11, 12); + builder.addEdge(12, 11); + builder.addEdge(12, 13); + Graph graph = builder.build(); + + int[][] sccs = GraphUtils.findStronglyConnectedComponents(graph, new int[] { 0 }, new GraphNodeFilter() { + @Override public boolean match(int node) { + return true; + } + }); + + for (int i = 0; i < sccs.length; ++i) { + Arrays.sort(sccs[i]); + } + Arrays.sort(sccs, new Comparator() { + @Override public int compare(int[] o1, int[] o2) { + return Integer.compare(o1[0], o2[0]); + } + }); + + assertThat(sccs[0], is(new int[] { 0 })); + assertThat(sccs[1], is(new int[] { 1, 2, 3, 4, 5, 6, 7, 8 })); + assertThat(sccs[2], is(new int[] { 9 })); + assertThat(sccs[3], is(new int[] { 10 })); + assertThat(sccs[4], is(new int[] { 11, 12 })); + assertThat(sccs[5], is(new int[] { 13 })); + } +} \ No newline at end of file From b6df37115fe2cc006ae16f5247090ed65858c265 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Mon, 2 Mar 2015 19:10:26 +0400 Subject: [PATCH 06/69] Fix bugs in irreducible flowgraph node splitting --- .../teavm/common/DefaultDominatorTree.java | 2 +- .../org/teavm/common/irreducible/DJGraph.java | 15 ++-- .../irreducible/GraphSplittingBackend.java | 2 +- .../IrreducibleGraphConverter.java | 74 +++++++++++-------- 4 files changed, 52 insertions(+), 41 deletions(-) diff --git a/teavm-core/src/main/java/org/teavm/common/DefaultDominatorTree.java b/teavm-core/src/main/java/org/teavm/common/DefaultDominatorTree.java index 43013b224..e83819014 100644 --- a/teavm-core/src/main/java/org/teavm/common/DefaultDominatorTree.java +++ b/teavm-core/src/main/java/org/teavm/common/DefaultDominatorTree.java @@ -71,7 +71,7 @@ class DefaultDominatorTree implements DominatorTree { @Override public int levelOf(int a) { - int index = indexes[a]; + int index = indexes[a + 1]; return lcaTree.depthOf(index); } } diff --git a/teavm-core/src/main/java/org/teavm/common/irreducible/DJGraph.java b/teavm-core/src/main/java/org/teavm/common/irreducible/DJGraph.java index faefb296a..a4a6fe89d 100644 --- a/teavm-core/src/main/java/org/teavm/common/irreducible/DJGraph.java +++ b/teavm-core/src/main/java/org/teavm/common/irreducible/DJGraph.java @@ -48,6 +48,7 @@ public class DJGraph { domTree = GraphUtils.buildDominatorTree(src); buildGraph(src); buildLevels(); + spanningTree = new LCATree(src.size()); dfs(); mergeRoot = new int[src.size()]; mergeClasses = new IntegerArray[src.size()]; @@ -55,7 +56,7 @@ public class DJGraph { mergeRoot[i] = i; mergeClasses[i] = IntegerArray.of(i); } - weight = Arrays.copyOf(weight, weight.length); + this.weight = Arrays.copyOf(weight, weight.length); } private void buildGraph(Graph src) { @@ -84,9 +85,9 @@ public class DJGraph { } builder.get(level).add(i); } - levelContent = new int[builder.size()][]; - for (int i = 0; i < builder.size(); ++i) { - levelContent[i] = builder.get(i).getAll(); + levelContent = new int[builder.size() - 1][]; + for (int i = 1; i < builder.size(); ++i) { + levelContent[i - 1] = builder.get(i).getAll(); } } @@ -97,15 +98,15 @@ public class DJGraph { Arrays.fill(spanningTreeNode, -1); boolean[] visited = new boolean[graph.size()]; IntegerStack stack = new IntegerStack(graph.size() * 2); - stack.push(0); stack.push(-1); + stack.push(0); while (!stack.isEmpty()) { int node = stack.pop(); int source = stack.pop(); if (visited[node]) { continue; } - int index = spanningTree.addNode(spanningTreeIndex[source]); + int index = source >= 0 ? spanningTree.addNode(spanningTreeIndex[source]) : 0; spanningTreeNode[index] = node; spanningTreeIndex[node] = index; visited[node] = true; @@ -179,7 +180,7 @@ public class DJGraph { } public int levelOf(int node) { - return domTree.levelOf(mergeRoot[node]); + return domTree.levelOf(mergeRoot[node]) - 1; } public int[] level(int level) { diff --git a/teavm-core/src/main/java/org/teavm/common/irreducible/GraphSplittingBackend.java b/teavm-core/src/main/java/org/teavm/common/irreducible/GraphSplittingBackend.java index 69792cf65..16f14fb0b 100644 --- a/teavm-core/src/main/java/org/teavm/common/irreducible/GraphSplittingBackend.java +++ b/teavm-core/src/main/java/org/teavm/common/irreducible/GraphSplittingBackend.java @@ -20,5 +20,5 @@ package org.teavm.common.irreducible; * @author Alexey Andreev */ public interface GraphSplittingBackend { - int[] split(int[] domain, int[] nodes); + int[][] split(int[][] domain, int[][] nodes); } diff --git a/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java b/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java index a91ac26fd..3c6f4579d 100644 --- a/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java +++ b/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java @@ -15,11 +15,11 @@ */ package org.teavm.common.irreducible; -import java.util.Arrays; -import org.teavm.common.*; import com.carrotsearch.hppc.IntOpenHashSet; import com.carrotsearch.hppc.IntSet; import com.carrotsearch.hppc.cursors.IntCursor; +import java.util.Arrays; +import org.teavm.common.*; /** *

Converts irreducible graph to reducible one using node splitting algorithm described at @@ -30,22 +30,20 @@ import com.carrotsearch.hppc.cursors.IntCursor; */ public class IrreducibleGraphConverter { private Graph cfg; - private int[] cfgWeight; private GraphSplittingBackend backend; public void convertToReducible(Graph cfg, int[] weight, GraphSplittingBackend backend) { this.backend = backend; - int[] identityNodeMap = new int[cfg.size()]; + int[][] identityNodeMap = new int[cfg.size()][]; for (int i = 0; i < identityNodeMap.length; ++i) { - identityNodeMap[i] = i; + identityNodeMap[i] = new int[] { i }; } this.cfg = cfg; - this.cfgWeight = weight; handleLoops(new DJGraph(cfg, weight), identityNodeMap); this.backend = null; } - private void handleLoops(DJGraph djGraph, int[] nodeMap) { + private void handleLoops(DJGraph djGraph, int[][] nodeMap) { for (int level = djGraph.levelCount() - 1; level >= 0; --level) { boolean irreducible = false; for (int node : djGraph.level(level)) { @@ -59,11 +57,13 @@ public class IrreducibleGraphConverter { } } } - DJGraphNodeFilter filter = new DJGraphNodeFilter(djGraph, level, null); + DJGraphNodeFilter filter = new DJGraphNodeFilter(djGraph, level); int[][] sccs = GraphUtils.findStronglyConnectedComponents(djGraph.getGraph(), djGraph.level(level), filter); for (int[] scc : sccs) { - handleStronglyConnectedComponent(djGraph, scc, nodeMap); - djGraph.collapse(scc); + if (scc.length > 1) { + handleStronglyConnectedComponent(djGraph, scc, nodeMap); + djGraph.collapse(scc); + } } } } @@ -84,7 +84,7 @@ public class IrreducibleGraphConverter { return naturalLoop.toArray(); } - private void handleStronglyConnectedComponent(DJGraph djGraph, int[] scc, int[] nodeMap) { + private void handleStronglyConnectedComponent(DJGraph djGraph, int[] scc, int[][] nodeMap) { // Find shared dominator int sharedDom = scc[0]; for (int i = 1; i < scc.length; ++i) { @@ -136,52 +136,66 @@ public class IrreducibleGraphConverter { } // Split - splitStronglyConnectedComponent(domainNodes, sharedDom, scc, nodeMap); + splitStronglyConnectedComponent(djGraph, domainNodes, sharedDom, scc, nodeMap); // Collapse djGraph.collapse(scc); } - private void splitStronglyConnectedComponent(IntSet domain, int sharedDom, int[] scc, int[] nodeMap) { + private void splitStronglyConnectedComponent(DJGraph djGraph, IntSet domain, int sharedDom, + int[] scc, int[][] nodeMap) { // Find SCC \ domain - int[] mappedNonDomain = new int[scc.length - domain.size()]; + int[][] mappedNonDomain = new int[scc.length - domain.size()][]; + int[] domainNodes = new int[domain.size()]; + int[] nonDomainNodes = new int[mappedNonDomain.length]; int index = 0; for (int node : scc) { if (!domain.contains(node)) { - mappedNonDomain[index++] = nodeMap[node]; + mappedNonDomain[index] = nodeMap[node]; + nonDomainNodes[index] = node; + ++index; } } - int[] mappedDomain = new int[domain.size()]; + int[][] mappedDomain = new int[domain.size()][]; index = 0; for (IntCursor cursor : domain) { - mappedDomain[index++] = cursor.value; + mappedDomain[index] = nodeMap[cursor.value]; + domainNodes[index] = cursor.value; + ++index; } // Delegate splitting to domain - int[] newNodes = backend.split(mappedDomain, mappedNonDomain); + int[][] newNodes = backend.split(mappedDomain, mappedNonDomain); // Calculate mappings - int[] newNodeMap = new int[1 + scc.length + newNodes.length]; + int[][] newNodeMap = new int[1 + scc.length + newNodes.length][]; int[] newNodeBackMap = new int[cfg.size()]; + int[] mappedWeight = new int[newNodeMap.length]; Arrays.fill(newNodeBackMap, -1); newNodeMap[0] = nodeMap[sharedDom]; newNodeBackMap[sharedDom] = 0; + mappedWeight[0] = djGraph.weightOf(sharedDom); index = 1; for (int i = 0; i < mappedDomain.length; ++i) { newNodeMap[index] = mappedDomain[i]; - newNodeBackMap[mappedDomain[i]] = index; + newNodeBackMap[domainNodes[i]] = index; + mappedWeight[index] = djGraph.weightOf(domainNodes[i]); ++index; } for (int i = 0; i < mappedNonDomain.length; ++i) { newNodeMap[index] = mappedNonDomain[i]; - newNodeBackMap[mappedNonDomain[i]] = index; + newNodeBackMap[nonDomainNodes[i]] = index; + mappedWeight[index] = djGraph.weightOf(nonDomainNodes[i]); + ++index; + } + for (int i = 0; i < mappedNonDomain.length; ++i) { + newNodeMap[index] = newNodes[i]; + mappedWeight[index] = djGraph.weightOf(nonDomainNodes[i]); ++index; } // Build subgraph with new nodes GraphBuilder builder = new GraphBuilder(newNodeMap.length); - int[] mappedWeight = new int[newNodeMap.length]; - mappedWeight[0] = cfgWeight[newNodeMap[0]]; for (int succ : cfg.outgoingEdges(sharedDom)) { int j = newNodeBackMap[succ]; if (j >= 0) { @@ -189,8 +203,7 @@ public class IrreducibleGraphConverter { } } for (int i = 1; i <= mappedDomain.length; ++i) { - mappedWeight[i] = cfgWeight[newNodeMap[i]]; - for (int succ : cfg.outgoingEdges(mappedDomain[i])) { + for (int succ : djGraph.getCfg().outgoingEdges(domainNodes[i])) { int j = newNodeBackMap[succ]; if (j > mappedDomain.length) { builder.addEdge(i, j); @@ -199,10 +212,9 @@ public class IrreducibleGraphConverter { } } } + index = 0; for (int i = mappedDomain.length + 1; i <= scc.length; ++i) { - mappedWeight[i] = cfgWeight[newNodeMap[i]]; - mappedWeight[i + mappedNonDomain.length] = cfgWeight[newNodeMap[i]]; - for (int succ : cfg.outgoingEdges(mappedNonDomain[i])) { + for (int succ : djGraph.getCfg().outgoingEdges(nonDomainNodes[index++])) { int j = newNodeBackMap[succ]; if (j >= 0) { builder.addEdge(i, j); @@ -221,17 +233,15 @@ public class IrreducibleGraphConverter { static class DJGraphNodeFilter implements GraphNodeFilter { private DJGraph graph; private int level; - private IntSet nodes; - public DJGraphNodeFilter(DJGraph graph, int level, IntSet nodes) { + public DJGraphNodeFilter(DJGraph graph, int level) { this.graph = graph; this.level = level; - this.nodes = nodes; } @Override public boolean match(int node) { - return nodes.contains(node) && graph.levelOf(node) >= level; + return graph.levelOf(node) >= level; } } } From 043d6f587fcff29a1532a56dd32bcc8c4ca9a4a1 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Tue, 3 Mar 2015 12:55:54 +0400 Subject: [PATCH 07/69] Further attempts to get node splitting work --- .../java/org/teavm/common/GraphUtils.java | 3 + .../org/teavm/common/irreducible/DJGraph.java | 7 ++- .../IrreducibleGraphConverter.java | 63 ++++++++++++------- .../test/java/org/teavm/common/GraphTest.java | 50 ++++++++++++--- 4 files changed, 89 insertions(+), 34 deletions(-) diff --git a/teavm-core/src/main/java/org/teavm/common/GraphUtils.java b/teavm-core/src/main/java/org/teavm/common/GraphUtils.java index bd952fef4..ea78e32dc 100644 --- a/teavm-core/src/main/java/org/teavm/common/GraphUtils.java +++ b/teavm-core/src/main/java/org/teavm/common/GraphUtils.java @@ -122,6 +122,9 @@ public final class GraphUtils { while (!stack.isEmpty()) { int node = stack.pop(); if (visitIndex[node] > 0) { + if (headerIndex[node] > 0) { + continue; + } currentComponent.add(node); int hdr = visitIndex[node]; for (int successor : graph.outgoingEdges(node)) { diff --git a/teavm-core/src/main/java/org/teavm/common/irreducible/DJGraph.java b/teavm-core/src/main/java/org/teavm/common/irreducible/DJGraph.java index a4a6fe89d..73eec1dd7 100644 --- a/teavm-core/src/main/java/org/teavm/common/irreducible/DJGraph.java +++ b/teavm-core/src/main/java/org/teavm/common/irreducible/DJGraph.java @@ -147,11 +147,11 @@ public class DJGraph { } public boolean isBackJoin(int i, int j) { - return isJoinEdge(i, j) && !domTree.dominates(mergeRoot[j], mergeRoot[i]); + return isJoinEdge(i, j) && domTree.dominates(mergeRoot[j], mergeRoot[i]); } public boolean isCrossJoin(int i, int j) { - return isJoinEdge(i, j) && domTree.dominates(mergeRoot[j], mergeRoot[i]); + return isJoinEdge(i, j) && !domTree.dominates(mergeRoot[j], mergeRoot[i]); } public boolean isSpanningBack(int i, int j) { @@ -200,7 +200,7 @@ public class DJGraph { return mergeRoot[node]; } - public void collapse(int[] nodes) { + public int collapse(int[] nodes) { // Replace nodes with their classes and find common dominator among them IntSet set = new IntOpenHashSet(); int top = nodes[0]; @@ -244,5 +244,6 @@ public class DJGraph { cfg.detachNode(node.value); } } + return top; } } diff --git a/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java b/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java index 3c6f4579d..68d2cd91b 100644 --- a/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java +++ b/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java @@ -30,6 +30,7 @@ import org.teavm.common.*; */ public class IrreducibleGraphConverter { private Graph cfg; + private int totalNodeCount; private GraphSplittingBackend backend; public void convertToReducible(Graph cfg, int[] weight, GraphSplittingBackend backend) { @@ -39,6 +40,7 @@ public class IrreducibleGraphConverter { identityNodeMap[i] = new int[] { i }; } this.cfg = cfg; + totalNodeCount = cfg.size(); handleLoops(new DJGraph(cfg, weight), identityNodeMap); this.backend = null; } @@ -46,23 +48,34 @@ public class IrreducibleGraphConverter { private void handleLoops(DJGraph djGraph, int[][] nodeMap) { for (int level = djGraph.levelCount() - 1; level >= 0; --level) { boolean irreducible = false; + levelScan: for (int node : djGraph.level(level)) { for (int pred : djGraph.getGraph().incomingEdges(node)) { - if (djGraph.isCrossJoin(pred, node)) { - if (!irreducible && djGraph.isSpanningBack(node, pred)) { - irreducible = true; - } - } else if (djGraph.isBackJoin(node, pred)) { - djGraph.collapse(reachUnder(djGraph, pred, node)); + if (djGraph.isCrossJoin(pred, node) && djGraph.isSpanningBack(node, pred)) { + irreducible = true; + break levelScan; } } } - DJGraphNodeFilter filter = new DJGraphNodeFilter(djGraph, level); - int[][] sccs = GraphUtils.findStronglyConnectedComponents(djGraph.getGraph(), djGraph.level(level), filter); - for (int[] scc : sccs) { - if (scc.length > 1) { - handleStronglyConnectedComponent(djGraph, scc, nodeMap); - djGraph.collapse(scc); + if (irreducible) { + DJGraphNodeFilter filter = new DJGraphNodeFilter(djGraph, level); + int[][] sccs = GraphUtils.findStronglyConnectedComponents(djGraph.getGraph(), + djGraph.level(level), filter); + for (int[] scc : sccs) { + if (scc.length > 1) { + handleStronglyConnectedComponent(djGraph, scc, nodeMap); + int cls = djGraph.collapse(scc); + IntegerArray nodes = new IntegerArray(djGraph.getGraph().size()); + for (int representative : djGraph.classRepresentatives(cls)) { + for (int node : nodeMap[representative]) { + nodes.add(node); + } + } + for (int representative : djGraph.classRepresentatives(cls)) { + nodeMap[representative] = new int[0]; + } + nodeMap[cls] = nodes.getAll(); + } } } } @@ -93,14 +106,16 @@ public class IrreducibleGraphConverter { // Partition SCC into domains DisjointSet partitions = new DisjointSet(); + int[] sccBack = new int[djGraph.getGraph().size()]; for (int i = 0; i < scc.length; ++i) { partitions.create(); + sccBack[scc[i]] = i; } for (int i = 0; i < scc.length; ++i) { int node = scc[i]; int idom = djGraph.getDomTree().immediateDominatorOf(node); if (idom != sharedDom) { - partitions.union(node, idom); + partitions.union(i, sccBack[idom]); } } int[] domains = partitions.pack(scc.length); @@ -110,10 +125,10 @@ public class IrreducibleGraphConverter { } // For each domain calculate its weight - int[] domainWeight = new int [domainCount]; + int[] domainWeight = new int[domainCount]; for (int i = 0; i < scc.length; ++i) { int node = scc[i]; - domainWeight[domains[node]] += djGraph.weightOf(node); + domainWeight[domains[i]] += djGraph.weightOf(node); } // Find domain to split around @@ -130,7 +145,7 @@ public class IrreducibleGraphConverter { IntSet domainNodes = new IntOpenHashSet(scc.length); for (int i = 0; i < scc.length; ++i) { int node = scc[i]; - if (domains[node] == domain) { + if (domains[i] == domain) { domainNodes.add(node); } } @@ -144,6 +159,7 @@ public class IrreducibleGraphConverter { private void splitStronglyConnectedComponent(DJGraph djGraph, IntSet domain, int sharedDom, int[] scc, int[][] nodeMap) { + Arrays.sort(scc); // Find SCC \ domain int[][] mappedNonDomain = new int[scc.length - domain.size()][]; int[] domainNodes = new int[domain.size()]; @@ -166,10 +182,13 @@ public class IrreducibleGraphConverter { // Delegate splitting to domain int[][] newNodes = backend.split(mappedDomain, mappedNonDomain); + for (int[] nodes : newNodes) { + totalNodeCount += nodes.length; + } // Calculate mappings int[][] newNodeMap = new int[1 + scc.length + newNodes.length][]; - int[] newNodeBackMap = new int[cfg.size()]; + int[] newNodeBackMap = new int[totalNodeCount]; int[] mappedWeight = new int[newNodeMap.length]; Arrays.fill(newNodeBackMap, -1); newNodeMap[0] = nodeMap[sharedDom]; @@ -203,12 +222,12 @@ public class IrreducibleGraphConverter { } } for (int i = 1; i <= mappedDomain.length; ++i) { - for (int succ : djGraph.getCfg().outgoingEdges(domainNodes[i])) { + for (int succ : djGraph.getCfg().outgoingEdges(domainNodes[i - 1])) { int j = newNodeBackMap[succ]; if (j > mappedDomain.length) { - builder.addEdge(i, j); - } else if (j >= 0) { builder.addEdge(i, j + mappedNonDomain.length); + } else if (j >= 0) { + builder.addEdge(i, j); } } } @@ -219,9 +238,9 @@ public class IrreducibleGraphConverter { if (j >= 0) { builder.addEdge(i, j); if (j > mappedDomain.length) { - builder.addEdge(i + mappedNonDomain.length, j); - } else { builder.addEdge(i + mappedNonDomain.length, j + mappedNonDomain.length); + } else { + builder.addEdge(i + mappedNonDomain.length, j); } } } diff --git a/teavm-core/src/test/java/org/teavm/common/GraphTest.java b/teavm-core/src/test/java/org/teavm/common/GraphTest.java index d757cd7bb..bfb8911c6 100644 --- a/teavm-core/src/test/java/org/teavm/common/GraphTest.java +++ b/teavm-core/src/test/java/org/teavm/common/GraphTest.java @@ -48,12 +48,51 @@ public class GraphTest { builder.addEdge(12, 13); Graph graph = builder.build(); - int[][] sccs = GraphUtils.findStronglyConnectedComponents(graph, new int[] { 0 }, new GraphNodeFilter() { + int[][] sccs = GraphUtils.findStronglyConnectedComponents(graph, new int[] { 0 }, filter); + sortSccs(sccs); + + assertThat(sccs.length, is(6)); + assertThat(sccs[0], is(new int[] { 0 })); + assertThat(sccs[1], is(new int[] { 1, 2, 3, 4, 5, 6, 7, 8 })); + assertThat(sccs[2], is(new int[] { 9 })); + assertThat(sccs[3], is(new int[] { 10 })); + assertThat(sccs[4], is(new int[] { 11, 12 })); + assertThat(sccs[5], is(new int[] { 13 })); + } + + @Test + public void stronglyConnectedComponentCalculated2() { + GraphBuilder builder = new GraphBuilder(); + builder.addEdge(0, 1); + builder.addEdge(0, 2); + builder.addEdge(0, 3); + builder.addEdge(1, 2); + builder.addEdge(2, 1); + builder.addEdge(3, 2); + builder.addEdge(2, 4); + builder.addEdge(4, 5); + builder.addEdge(4, 1); + builder.addEdge(5, 3); + Graph graph = builder.build(); + + int[][] sccs = GraphUtils.findStronglyConnectedComponents(graph, new int[] { 1, 2, 3 }, new GraphNodeFilter() { @Override public boolean match(int node) { - return true; + return node != 0; } }); + sortSccs(sccs); + assertThat(sccs.length, is(1)); + assertThat(sccs[0], is(new int[] { 1, 2, 3, 4, 5 })); + } + + private GraphNodeFilter filter = new GraphNodeFilter() { + @Override public boolean match(int node) { + return true; + } + }; + + private void sortSccs(int[][] sccs) { for (int i = 0; i < sccs.length; ++i) { Arrays.sort(sccs[i]); } @@ -62,12 +101,5 @@ public class GraphTest { return Integer.compare(o1[0], o2[0]); } }); - - assertThat(sccs[0], is(new int[] { 0 })); - assertThat(sccs[1], is(new int[] { 1, 2, 3, 4, 5, 6, 7, 8 })); - assertThat(sccs[2], is(new int[] { 9 })); - assertThat(sccs[3], is(new int[] { 10 })); - assertThat(sccs[4], is(new int[] { 11, 12 })); - assertThat(sccs[5], is(new int[] { 13 })); } } \ No newline at end of file From 5ea55675f1165b48074e6861b9c2996bdc62e88b Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Wed, 4 Mar 2015 16:43:06 +0400 Subject: [PATCH 08/69] Fix node splitting algorithm --- .../java/org/teavm/common/GraphUtils.java | 66 ++++++++++--------- .../IrreducibleGraphConverter.java | 27 +++----- 2 files changed, 46 insertions(+), 47 deletions(-) diff --git a/teavm-core/src/main/java/org/teavm/common/GraphUtils.java b/teavm-core/src/main/java/org/teavm/common/GraphUtils.java index ea78e32dc..d9a8d55fb 100644 --- a/teavm-core/src/main/java/org/teavm/common/GraphUtils.java +++ b/teavm-core/src/main/java/org/teavm/common/GraphUtils.java @@ -114,45 +114,51 @@ public final class GraphUtils { int[] headerIndex = new int[graph.size()]; int lastIndex = 0; IntegerStack stack = new IntegerStack(graph.size()); + for (int startNode : start) { stack.push(startNode); - } - - IntegerArray currentComponent = new IntegerArray(1); - while (!stack.isEmpty()) { - int node = stack.pop(); - if (visitIndex[node] > 0) { - if (headerIndex[node] > 0) { - continue; - } - currentComponent.add(node); - int hdr = visitIndex[node]; - for (int successor : graph.outgoingEdges(node)) { - if (!filter.match(successor)) { + IntegerArray currentComponent = new IntegerArray(1); + while (!stack.isEmpty()) { + int node = stack.pop(); + if (visitIndex[node] > 0) { + if (headerIndex[node] > 0) { continue; } - if (headerIndex[successor] == 0) { - hdr = Math.min(hdr, visitIndex[successor]); - } else { - hdr = Math.min(hdr, headerIndex[successor]); + currentComponent.add(node); + int hdr = visitIndex[node]; + for (int successor : graph.outgoingEdges(node)) { + if (!filter.match(successor)) { + continue; + } + if (headerIndex[successor] == 0) { + hdr = Math.min(hdr, visitIndex[successor]); + } else { + hdr = Math.min(hdr, headerIndex[successor]); + } + } + if (hdr == visitIndex[node]) { + components.add(currentComponent.getAll()); + currentComponent.clear(); + } + headerIndex[node] = hdr; + } else { + visitIndex[node] = ++lastIndex; + stack.push(node); + for (int successor : graph.outgoingEdges(node)) { + if (!filter.match(successor) || visitIndex[successor] > 0) { + continue; + } + stack.push(successor); } } - if (hdr == visitIndex[node]) { - components.add(currentComponent.getAll()); - currentComponent.clear(); - } - headerIndex[node] = hdr; - } else { - visitIndex[node] = ++lastIndex; - stack.push(node); - for (int successor : graph.outgoingEdges(node)) { - if (!filter.match(successor) || visitIndex[successor] > 0) { - continue; - } - stack.push(successor); + } + for (int i = 0; i < headerIndex.length; ++i) { + if (visitIndex[i] > 0) { + headerIndex[i] = graph.size() + 1; } } } + return components.toArray(new int[0][]); } diff --git a/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java b/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java index 68d2cd91b..b5e06125b 100644 --- a/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java +++ b/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java @@ -81,22 +81,6 @@ public class IrreducibleGraphConverter { } } - private int[] reachUnder(DJGraph djGraph, int back, int header) { - IntSet naturalLoop = IntOpenHashSet.from(header); - IntegerStack stack = new IntegerStack(djGraph.getGraph().size()); - stack.push(back); - while (!stack.isEmpty()) { - int node = stack.pop(); - if (!naturalLoop.add(node)) { - continue; - } - for (int pred : djGraph.getGraph().incomingEdges(node)) { - stack.push(pred); - } - } - return naturalLoop.toArray(); - } - private void handleStronglyConnectedComponent(DJGraph djGraph, int[] scc, int[][] nodeMap) { // Find shared dominator int sharedDom = scc[0]; @@ -104,6 +88,13 @@ public class IrreducibleGraphConverter { sharedDom = djGraph.getDomTree().commonDominatorOf(sharedDom, scc[i]); } + for (int i = 0; i < scc.length; ++i) { + if (scc[i] == sharedDom) { + djGraph.collapse(scc); + return; + } + } + // Partition SCC into domains DisjointSet partitions = new DisjointSet(); int[] sccBack = new int[djGraph.getGraph().size()]; @@ -154,7 +145,9 @@ public class IrreducibleGraphConverter { splitStronglyConnectedComponent(djGraph, domainNodes, sharedDom, scc, nodeMap); // Collapse - djGraph.collapse(scc); + int[] sccAndTop = Arrays.copyOf(scc, scc.length + 1); + sccAndTop[scc.length] = sharedDom; + djGraph.collapse(sccAndTop); } private void splitStronglyConnectedComponent(DJGraph djGraph, IntSet domain, int sharedDom, From d4824ff9d2965d2f6080b1d69222ff38b6235677 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Wed, 4 Mar 2015 18:28:26 +0400 Subject: [PATCH 09/69] Improve node splitting --- .../common/{irreducible => }/DJGraph.java | 3 +- .../common/DefaultGraphSplittingBackend.java | 97 +++++++++++++++++++ .../java/org/teavm/common/GraphBuilder.java | 10 ++ .../GraphSplittingBackend.java | 4 +- .../java/org/teavm/common/GraphUtils.java | 4 + .../IrreducibleGraphConverter.java | 36 ++++++- .../teavm/common/MutableDirectedGraph.java | 18 ++++ 7 files changed, 164 insertions(+), 8 deletions(-) rename teavm-core/src/main/java/org/teavm/common/{irreducible => }/DJGraph.java (99%) create mode 100644 teavm-core/src/main/java/org/teavm/common/DefaultGraphSplittingBackend.java rename teavm-core/src/main/java/org/teavm/common/{irreducible => }/GraphSplittingBackend.java (89%) rename teavm-core/src/main/java/org/teavm/common/{irreducible => }/IrreducibleGraphConverter.java (90%) diff --git a/teavm-core/src/main/java/org/teavm/common/irreducible/DJGraph.java b/teavm-core/src/main/java/org/teavm/common/DJGraph.java similarity index 99% rename from teavm-core/src/main/java/org/teavm/common/irreducible/DJGraph.java rename to teavm-core/src/main/java/org/teavm/common/DJGraph.java index 73eec1dd7..d59ad5320 100644 --- a/teavm-core/src/main/java/org/teavm/common/irreducible/DJGraph.java +++ b/teavm-core/src/main/java/org/teavm/common/DJGraph.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.teavm.common.irreducible; +package org.teavm.common; import com.carrotsearch.hppc.IntOpenHashSet; import com.carrotsearch.hppc.IntSet; @@ -21,7 +21,6 @@ import com.carrotsearch.hppc.cursors.IntCursor; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import org.teavm.common.*; /** * diff --git a/teavm-core/src/main/java/org/teavm/common/DefaultGraphSplittingBackend.java b/teavm-core/src/main/java/org/teavm/common/DefaultGraphSplittingBackend.java new file mode 100644 index 000000000..b3aea9210 --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/common/DefaultGraphSplittingBackend.java @@ -0,0 +1,97 @@ +/* + * Copyright 2015 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.common; + +import com.carrotsearch.hppc.IntIntMap; +import com.carrotsearch.hppc.IntIntOpenHashMap; + +/** + * + * @author Alexey Andreev + */ +public class DefaultGraphSplittingBackend implements GraphSplittingBackend { + private MutableDirectedGraph graph; + private int index; + private IntegerArray prototypeNodes; + private IntegerArray copyIndexes; + private int[] copyCount; + + public DefaultGraphSplittingBackend(Graph graph) { + this.graph = new MutableDirectedGraph(graph); + prototypeNodes = new IntegerArray(graph.size()); + copyIndexes = new IntegerArray(graph.size()); + copyCount = new int[graph.size()]; + index = graph.size(); + for (int i = 0; i < graph.size(); ++i) { + prototypeNodes.add(i); + copyIndexes.add(i); + } + } + + public Graph getGraph() { + return graph.copyToImmutable(); + } + + public int prototype(int index) { + return prototypeNodes.get(index); + } + + public int copyIndex(int index) { + return copyIndexes.get(index); + } + + @Override + public int[] split(int[] domain, int[] nodes) { + int[] copies = new int[nodes.length]; + IntIntMap map = new IntIntOpenHashMap(); + for (int i = 0; i < nodes.length; ++i) { + copies[i] = index++; + map.put(nodes[i], copies[i]); + int proto = prototypeNodes.get(nodes[i]); + prototypeNodes.add(proto); + copyIndexes.add(++copyCount[proto]); + } + + for (int i = 0; i < domain.length; ++i) { + int node = domain[i]; + for (int succ : graph.outgoingEdges(node)) { + int succCopy = map.get(succ); + if (succCopy == 0) { + continue; + } + --succCopy; + graph.deleteEdge(node, succ); + graph.addEdge(node, succCopy); + } + } + + for (int i = 0; i < nodes.length; ++i) { + int node = nodes[i]; + int nodeCopy = copies[i]; + for (int succ : graph.outgoingEdges(node)) { + int succCopy = map.get(succ); + if (succCopy != 0) { + graph.addEdge(nodeCopy, succCopy - 1); + } else { + graph.addEdge(nodeCopy, succ); + } + } + } + + return copies; + } +} + diff --git a/teavm-core/src/main/java/org/teavm/common/GraphBuilder.java b/teavm-core/src/main/java/org/teavm/common/GraphBuilder.java index 1306006c2..7228fc23d 100644 --- a/teavm-core/src/main/java/org/teavm/common/GraphBuilder.java +++ b/teavm-core/src/main/java/org/teavm/common/GraphBuilder.java @@ -65,6 +65,16 @@ public class GraphBuilder { } } + public void removeEdge(int from, int to) { + if (to < 0 || from < 0) { + throw new IllegalArgumentException(); + } + if (from >= addedEdges.size() || to >= addedEdges.size()) { + return; + } + addedEdges.get(from).removeAllOccurrences(to); + } + public Graph build() { if (builtGraph == null) { IntSet[] incomingEdges = new IntSet[sz]; diff --git a/teavm-core/src/main/java/org/teavm/common/irreducible/GraphSplittingBackend.java b/teavm-core/src/main/java/org/teavm/common/GraphSplittingBackend.java similarity index 89% rename from teavm-core/src/main/java/org/teavm/common/irreducible/GraphSplittingBackend.java rename to teavm-core/src/main/java/org/teavm/common/GraphSplittingBackend.java index 16f14fb0b..5dd859ff3 100644 --- a/teavm-core/src/main/java/org/teavm/common/irreducible/GraphSplittingBackend.java +++ b/teavm-core/src/main/java/org/teavm/common/GraphSplittingBackend.java @@ -13,12 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.teavm.common.irreducible; +package org.teavm.common; /** * * @author Alexey Andreev */ public interface GraphSplittingBackend { - int[][] split(int[][] domain, int[][] nodes); + int[] split(int[] domain, int[] nodes); } diff --git a/teavm-core/src/main/java/org/teavm/common/GraphUtils.java b/teavm-core/src/main/java/org/teavm/common/GraphUtils.java index d9a8d55fb..d181d8e98 100644 --- a/teavm-core/src/main/java/org/teavm/common/GraphUtils.java +++ b/teavm-core/src/main/java/org/teavm/common/GraphUtils.java @@ -179,6 +179,10 @@ public final class GraphUtils { return graph.build(); } + public static void splitIrreducibleGraph(Graph graph, int[] weights, GraphSplittingBackend backend) { + new IrreducibleGraphConverter().convertToReducible(graph, weights, backend); + } + public static int[][] findDominanceFrontiers(Graph cfg, DominatorTree domTree) { IntegerArray[] tmpFrontiers = new IntegerArray[cfg.size()]; int[][] domFrontiers = new int[cfg.size()][]; diff --git a/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java b/teavm-core/src/main/java/org/teavm/common/IrreducibleGraphConverter.java similarity index 90% rename from teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java rename to teavm-core/src/main/java/org/teavm/common/IrreducibleGraphConverter.java index b5e06125b..594db8992 100644 --- a/teavm-core/src/main/java/org/teavm/common/irreducible/IrreducibleGraphConverter.java +++ b/teavm-core/src/main/java/org/teavm/common/IrreducibleGraphConverter.java @@ -13,13 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.teavm.common.irreducible; +package org.teavm.common; import com.carrotsearch.hppc.IntOpenHashSet; import com.carrotsearch.hppc.IntSet; import com.carrotsearch.hppc.cursors.IntCursor; import java.util.Arrays; -import org.teavm.common.*; /** *

Converts irreducible graph to reducible one using node splitting algorithm described at @@ -28,7 +27,7 @@ import org.teavm.common.*; * * @author Alexey Andreev */ -public class IrreducibleGraphConverter { +class IrreducibleGraphConverter { private Graph cfg; private int totalNodeCount; private GraphSplittingBackend backend; @@ -174,7 +173,7 @@ public class IrreducibleGraphConverter { } // Delegate splitting to domain - int[][] newNodes = backend.split(mappedDomain, mappedNonDomain); + int[][] newNodes = unflatten(backend.split(flatten(mappedDomain), flatten(mappedNonDomain)), mappedNonDomain); for (int[] nodes : newNodes) { totalNodeCount += nodes.length; } @@ -242,6 +241,35 @@ public class IrreducibleGraphConverter { handleLoops(new DJGraph(builder.build(), mappedWeight), newNodeMap); } + private static int[] flatten(int[][] array) { + int count = 0; + for (int i = 0; i < array.length; ++i) { + count += array[i].length; + } + int[] flat = new int[count]; + int index = 0; + for (int i = 0; i < array.length; ++i) { + int[] part = array[i]; + for (int j = 0; j < part.length; ++j) { + flat[index++] = part[j]; + } + } + return flat; + } + + private static int[][] unflatten(int[] flat, int[][] pattern) { + int[][] rough = new int[pattern.length][]; + int index = 0; + for (int i = 0; i < rough.length; ++i) { + int[] part = new int[pattern[i].length]; + for (int j = 0; j < part.length; ++j) { + part[j] = flat[index++]; + } + rough[i] = part; + } + return rough; + } + static class DJGraphNodeFilter implements GraphNodeFilter { private DJGraph graph; private int level; diff --git a/teavm-core/src/main/java/org/teavm/common/MutableDirectedGraph.java b/teavm-core/src/main/java/org/teavm/common/MutableDirectedGraph.java index 8036e16ae..91fb6a851 100644 --- a/teavm-core/src/main/java/org/teavm/common/MutableDirectedGraph.java +++ b/teavm-core/src/main/java/org/teavm/common/MutableDirectedGraph.java @@ -42,6 +42,16 @@ public class MutableDirectedGraph implements Graph { } } + public Graph copyToImmutable() { + GraphBuilder builder = new GraphBuilder(successors.size()); + for (int i = 0; i < successors.size(); ++i) { + for (IntCursor cursor : successors.get(i)) { + builder.addEdge(i, cursor.value); + } + } + return builder.build(); + } + @Override public int size() { return successors.size(); @@ -57,6 +67,14 @@ public class MutableDirectedGraph implements Graph { predecessors.get(to).add(from); } + public void deleteEdge(int from, int to) { + if (from >= successors.size() || to >= successors.size()) { + return; + } + successors.get(from).removeAllOccurrences(to); + predecessors.get(to).removeAllOccurrences(from); + } + public void detachNode(int node) { for (IntCursor succ : successors.get(node)) { predecessors.get(succ.value).removeAllOccurrences(node); From 04677d010383deaa3985b155d063dc81341ac5aa Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Wed, 4 Mar 2015 22:57:26 +0300 Subject: [PATCH 10/69] Minor fix --- .../java/org/teavm/common/DefaultGraphSplittingBackend.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/teavm-core/src/main/java/org/teavm/common/DefaultGraphSplittingBackend.java b/teavm-core/src/main/java/org/teavm/common/DefaultGraphSplittingBackend.java index b3aea9210..3a2453123 100644 --- a/teavm-core/src/main/java/org/teavm/common/DefaultGraphSplittingBackend.java +++ b/teavm-core/src/main/java/org/teavm/common/DefaultGraphSplittingBackend.java @@ -37,7 +37,7 @@ public class DefaultGraphSplittingBackend implements GraphSplittingBackend { index = graph.size(); for (int i = 0; i < graph.size(); ++i) { prototypeNodes.add(i); - copyIndexes.add(i); + copyIndexes.add(0); } } @@ -59,7 +59,7 @@ public class DefaultGraphSplittingBackend implements GraphSplittingBackend { IntIntMap map = new IntIntOpenHashMap(); for (int i = 0; i < nodes.length; ++i) { copies[i] = index++; - map.put(nodes[i], copies[i]); + map.put(nodes[i], copies[i] + 1); int proto = prototypeNodes.get(nodes[i]); prototypeNodes.add(proto); copyIndexes.add(++copyCount[proto]); From e2aababde8d337f964cd081d65740ffd8aa5c0f5 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Thu, 5 Mar 2015 18:32:36 +0400 Subject: [PATCH 11/69] Add unit tests for irreducible graph splitter --- .../java/org/teavm/common/GraphUtils.java | 55 +++++---------- .../test/java/org/teavm/common/GraphTest.java | 67 +++++++++++++++++++ 2 files changed, 82 insertions(+), 40 deletions(-) diff --git a/teavm-core/src/main/java/org/teavm/common/GraphUtils.java b/teavm-core/src/main/java/org/teavm/common/GraphUtils.java index d181d8e98..ec8fcf277 100644 --- a/teavm-core/src/main/java/org/teavm/common/GraphUtils.java +++ b/teavm-core/src/main/java/org/teavm/common/GraphUtils.java @@ -31,37 +31,8 @@ public final class GraphUtils { private GraphUtils() { } - public static Graph invert(Graph graph) { + public static int[] findBackEdges(Graph graph) { int sz = graph.size(); - GraphBuilder result = new GraphBuilder(); - int[] sourceEdges = new int[sz]; - for (int node = 0; node < sz; ++node) { - int sourceCount = graph.copyIncomingEdges(node, sourceEdges); - for (int i = 0; i < sourceCount; ++i) { - int source = sourceEdges[i]; - result.addEdge(node, source); - } - } - return result.build(); - } - - public static Graph close(Graph graph) { - GraphBuilder result = new GraphBuilder(); - for (int node = 0; node < graph.size(); ++node) { - int[] next = graph.outgoingEdges(node); - for (int target : next) { - result.addEdge(node, target); - } - if (next.length == 0) { - result.addEdge(node, graph.size()); - } - } - return result.build(); - } - - public static Graph removeLoops(Graph graph) { - int sz = graph.size(); - GraphBuilder result = new GraphBuilder(); int[] stack = new int[sz * 2]; int stackSize = 0; byte[] state = new byte[sz]; @@ -70,6 +41,7 @@ public final class GraphUtils { stack[stackSize++] = i; } } + IntegerArray result = new IntegerArray(2); while (stackSize > 0) { int node = stack[--stackSize]; switch (state[node]) { @@ -79,11 +51,11 @@ public final class GraphUtils { for (int next : graph.outgoingEdges(node)) { switch (state[next]) { case NONE: - result.addEdge(node, next); stack[stackSize++] = next; break; - case VISITED: - result.addEdge(node, next); + case VISITING: + result.add(node); + result.add(next); break; } } @@ -93,22 +65,25 @@ public final class GraphUtils { break; } } - return result.build(); + return result.getAll(); } - public static int edgeCount(Graph graph) { - int cnt = 0; - int sz = graph.size(); - for (int node = 0; node < sz; ++node) { - cnt += graph.outgoingEdgesCount(node); + public static boolean isIrreducible(Graph graph) { + DominatorTree dom = buildDominatorTree(graph); + int[] backEdges = findBackEdges(graph); + for (int i = 0; i < backEdges.length; i += 2) { + if (!dom.dominates(backEdges[i + 1], backEdges[i])) { + return true; + } } - return cnt; + return false; } /* * Tarjan's algorithm */ public static int[][] findStronglyConnectedComponents(Graph graph, int[] start, GraphNodeFilter filter) { + // TODO: can show incorrect behaviour sometimes List components = new ArrayList<>(); int[] visitIndex = new int[graph.size()]; int[] headerIndex = new int[graph.size()]; diff --git a/teavm-core/src/test/java/org/teavm/common/GraphTest.java b/teavm-core/src/test/java/org/teavm/common/GraphTest.java index bfb8911c6..4ae932305 100644 --- a/teavm-core/src/test/java/org/teavm/common/GraphTest.java +++ b/teavm-core/src/test/java/org/teavm/common/GraphTest.java @@ -17,6 +17,8 @@ package org.teavm.common; import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; +import com.carrotsearch.hppc.IntOpenHashSet; +import com.carrotsearch.hppc.IntSet; import java.util.Arrays; import java.util.Comparator; import org.junit.Test; @@ -86,6 +88,71 @@ public class GraphTest { assertThat(sccs[0], is(new int[] { 1, 2, 3, 4, 5 })); } + @Test + public void irreducibleGraphSplit() { + GraphBuilder builder = new GraphBuilder(); + builder.addEdge(0, 1); + builder.addEdge(0, 2); + builder.addEdge(0, 3); + builder.addEdge(1, 2); + builder.addEdge(2, 1); + builder.addEdge(3, 2); + builder.addEdge(2, 4); + builder.addEdge(4, 5); + builder.addEdge(4, 1); + builder.addEdge(5, 3); + + Graph graph = builder.build(); + DefaultGraphSplittingBackend backend = new DefaultGraphSplittingBackend(graph); + int[] weights = { 1, 4, 1, 10, 1, 1 }; + GraphUtils.splitIrreducibleGraph(graph, weights, backend); + Graph result = backend.getGraph(); + + assertTrue("Should be irreducible", GraphUtils.isIrreducible(graph)); + assertFalse("Should be reducible", GraphUtils.isIrreducible(result)); + assertTrue("Should be equialent", isEquialent(backend, graph)); + } + + @Test + public void irreducibleGraphSplit2() { + GraphBuilder builder = new GraphBuilder(); + builder.addEdge(0, 1); + builder.addEdge(0, 2); + builder.addEdge(1, 2); + builder.addEdge(2, 1); + Graph graph = builder.build(); + + DefaultGraphSplittingBackend backend = new DefaultGraphSplittingBackend(graph); + int[] weights = new int[graph.size()]; + Arrays.fill(weights, 1); + GraphUtils.splitIrreducibleGraph(graph, weights, backend); + Graph result = backend.getGraph(); + + assertTrue("Should be irreducible", GraphUtils.isIrreducible(graph)); + assertFalse("Should be reducible", GraphUtils.isIrreducible(result)); + assertTrue("Should be equialent", isEquialent(backend, graph)); + } + + private boolean isEquialent(DefaultGraphSplittingBackend backend, Graph proto) { + Graph graph = backend.getGraph(); + for (int node = 0; node < graph.size(); ++node) { + int nodeProto = backend.prototype(node); + IntSet succProto = new IntOpenHashSet(); + for (int succ : graph.outgoingEdges(node)) { + succProto.add(backend.prototype(succ)); + } + if (succProto.size() != proto.outgoingEdgesCount(nodeProto)) { + return false; + } + for (int succ : proto.outgoingEdges(nodeProto)) { + if (!succProto.contains(succ)) { + return false; + } + } + } + return true; + } + private GraphNodeFilter filter = new GraphNodeFilter() { @Override public boolean match(int node) { return true; From 33b319ce167a309b1d8d106c520e487ee5a1c605 Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Thu, 5 Mar 2015 20:55:21 +0300 Subject: [PATCH 12/69] Add some tests for SCC --- .../java/org/teavm/common/GraphUtils.java | 4 +++- .../test/java/org/teavm/common/GraphTest.java | 21 ++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/teavm-core/src/main/java/org/teavm/common/GraphUtils.java b/teavm-core/src/main/java/org/teavm/common/GraphUtils.java index ec8fcf277..886d77d56 100644 --- a/teavm-core/src/main/java/org/teavm/common/GraphUtils.java +++ b/teavm-core/src/main/java/org/teavm/common/GraphUtils.java @@ -83,7 +83,6 @@ public final class GraphUtils { * Tarjan's algorithm */ public static int[][] findStronglyConnectedComponents(Graph graph, int[] start, GraphNodeFilter filter) { - // TODO: can show incorrect behaviour sometimes List components = new ArrayList<>(); int[] visitIndex = new int[graph.size()]; int[] headerIndex = new int[graph.size()]; @@ -113,6 +112,9 @@ public final class GraphUtils { } if (hdr == visitIndex[node]) { components.add(currentComponent.getAll()); + for (int componentMember : currentComponent.getAll()) { + headerIndex[componentMember] = graph.size() + 1; + } currentComponent.clear(); } headerIndex[node] = hdr; diff --git a/teavm-core/src/test/java/org/teavm/common/GraphTest.java b/teavm-core/src/test/java/org/teavm/common/GraphTest.java index 4ae932305..12a2e876f 100644 --- a/teavm-core/src/test/java/org/teavm/common/GraphTest.java +++ b/teavm-core/src/test/java/org/teavm/common/GraphTest.java @@ -15,7 +15,7 @@ */ package org.teavm.common; -import static org.hamcrest.CoreMatchers.*; +import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.*; import com.carrotsearch.hppc.IntOpenHashSet; import com.carrotsearch.hppc.IntSet; @@ -88,6 +88,25 @@ public class GraphTest { assertThat(sccs[0], is(new int[] { 1, 2, 3, 4, 5 })); } + @Test + public void stronglyConnectedComponentCalculated3() { + GraphBuilder builder = new GraphBuilder(); + builder.addEdge(0, 1); + builder.addEdge(0, 2); + builder.addEdge(1, 3); + builder.addEdge(3, 1); + builder.addEdge(2, 3); + Graph graph = builder.build(); + + int[][] sccs = GraphUtils.findStronglyConnectedComponents(graph, new int[] { 0 }, filter); + sortSccs(sccs); + + assertThat(sccs.length, is(3)); + assertThat(sccs[0], is(new int[] { 0 })); + assertThat(sccs[1], is(new int[] { 1, 3 })); + assertThat(sccs[2], is(new int[] { 2 })); + } + @Test public void irreducibleGraphSplit() { GraphBuilder builder = new GraphBuilder(); From 0fe826ade8b21b99e63ff0b174f830b5bd787e7e Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Thu, 5 Mar 2015 23:35:12 +0300 Subject: [PATCH 13/69] Add more complicated irreducible graph test --- .../main/java/org/teavm/common/DJGraph.java | 6 +- .../java/org/teavm/common/GraphUtils.java | 15 ++-- .../common/IrreducibleGraphConverter.java | 29 ++++---- .../test/java/org/teavm/common/GraphTest.java | 68 +++++++++++++++++++ 4 files changed, 98 insertions(+), 20 deletions(-) diff --git a/teavm-core/src/main/java/org/teavm/common/DJGraph.java b/teavm-core/src/main/java/org/teavm/common/DJGraph.java index d59ad5320..a55ef97ef 100644 --- a/teavm-core/src/main/java/org/teavm/common/DJGraph.java +++ b/teavm-core/src/main/java/org/teavm/common/DJGraph.java @@ -69,9 +69,11 @@ public class DJGraph { } // Add dom edges - for (int i = 1; i < graph.size(); ++i) { + for (int i = 0; i < graph.size(); ++i) { int j = domTree.immediateDominatorOf(i); - graph.addEdge(j, i); + if (j >= 0) { + graph.addEdge(j, i); + } } } diff --git a/teavm-core/src/main/java/org/teavm/common/GraphUtils.java b/teavm-core/src/main/java/org/teavm/common/GraphUtils.java index 886d77d56..692f4190d 100644 --- a/teavm-core/src/main/java/org/teavm/common/GraphUtils.java +++ b/teavm-core/src/main/java/org/teavm/common/GraphUtils.java @@ -91,14 +91,13 @@ public final class GraphUtils { for (int startNode : start) { stack.push(startNode); - IntegerArray currentComponent = new IntegerArray(1); + IntegerStack currentComponent = new IntegerStack(1); while (!stack.isEmpty()) { int node = stack.pop(); if (visitIndex[node] > 0) { if (headerIndex[node] > 0) { continue; } - currentComponent.add(node); int hdr = visitIndex[node]; for (int successor : graph.outgoingEdges(node)) { if (!filter.match(successor)) { @@ -111,15 +110,21 @@ public final class GraphUtils { } } if (hdr == visitIndex[node]) { - components.add(currentComponent.getAll()); - for (int componentMember : currentComponent.getAll()) { + IntegerArray componentMembers = new IntegerArray(graph.size()); + while (true) { + int componentMember = currentComponent.pop(); + componentMembers.add(componentMember); headerIndex[componentMember] = graph.size() + 1; + if (visitIndex[componentMember] == hdr) { + break; + } } - currentComponent.clear(); + components.add(componentMembers.getAll()); } headerIndex[node] = hdr; } else { visitIndex[node] = ++lastIndex; + currentComponent.push(node); stack.push(node); for (int successor : graph.outgoingEdges(node)) { if (!filter.match(successor) || visitIndex[successor] > 0) { diff --git a/teavm-core/src/main/java/org/teavm/common/IrreducibleGraphConverter.java b/teavm-core/src/main/java/org/teavm/common/IrreducibleGraphConverter.java index 594db8992..924d886f1 100644 --- a/teavm-core/src/main/java/org/teavm/common/IrreducibleGraphConverter.java +++ b/teavm-core/src/main/java/org/teavm/common/IrreducibleGraphConverter.java @@ -63,17 +63,6 @@ class IrreducibleGraphConverter { for (int[] scc : sccs) { if (scc.length > 1) { handleStronglyConnectedComponent(djGraph, scc, nodeMap); - int cls = djGraph.collapse(scc); - IntegerArray nodes = new IntegerArray(djGraph.getGraph().size()); - for (int representative : djGraph.classRepresentatives(cls)) { - for (int node : nodeMap[representative]) { - nodes.add(node); - } - } - for (int representative : djGraph.classRepresentatives(cls)) { - nodeMap[representative] = new int[0]; - } - nodeMap[cls] = nodes.getAll(); } } } @@ -89,7 +78,7 @@ class IrreducibleGraphConverter { for (int i = 0; i < scc.length; ++i) { if (scc[i] == sharedDom) { - djGraph.collapse(scc); + collapse(djGraph, scc, nodeMap); return; } } @@ -146,7 +135,7 @@ class IrreducibleGraphConverter { // Collapse int[] sccAndTop = Arrays.copyOf(scc, scc.length + 1); sccAndTop[scc.length] = sharedDom; - djGraph.collapse(sccAndTop); + collapse(djGraph, sccAndTop, nodeMap); } private void splitStronglyConnectedComponent(DJGraph djGraph, IntSet domain, int sharedDom, @@ -241,6 +230,20 @@ class IrreducibleGraphConverter { handleLoops(new DJGraph(builder.build(), mappedWeight), newNodeMap); } + private void collapse(DJGraph djGraph, int[] scc, int[][] nodeMap) { + int cls = djGraph.collapse(scc); + IntegerArray nodes = new IntegerArray(djGraph.getGraph().size()); + for (int representative : djGraph.classRepresentatives(cls)) { + for (int node : nodeMap[representative]) { + nodes.add(node); + } + } + for (int representative : djGraph.classRepresentatives(cls)) { + nodeMap[representative] = new int[0]; + } + nodeMap[cls] = nodes.getAll(); + } + private static int[] flatten(int[][] array) { int count = 0; for (int i = 0; i < array.length; ++i) { diff --git a/teavm-core/src/test/java/org/teavm/common/GraphTest.java b/teavm-core/src/test/java/org/teavm/common/GraphTest.java index 12a2e876f..f0d8fb444 100644 --- a/teavm-core/src/test/java/org/teavm/common/GraphTest.java +++ b/teavm-core/src/test/java/org/teavm/common/GraphTest.java @@ -107,6 +107,41 @@ public class GraphTest { assertThat(sccs[2], is(new int[] { 2 })); } + @Test + public void stronglyConnectedComponentCalculated4() { + GraphBuilder builder = new GraphBuilder(); + builder.addEdge(0, 1); + builder.addEdge(0, 2); + builder.addEdge(1, 2); + builder.addEdge(1, 3); + builder.addEdge(1, 4); + builder.addEdge(2, 1); + builder.addEdge(2, 3); + builder.addEdge(3, 4); + builder.addEdge(4, 5); + builder.addEdge(4, 6); + builder.addEdge(5, 6); + builder.addEdge(6, 5); + builder.addEdge(6, 7); + builder.addEdge(7, 4); + builder.addEdge(7, 3); + builder.addEdge(7, 8); + builder.addEdge(8, 7); + Graph graph = builder.build(); + + int[][] sccs = GraphUtils.findStronglyConnectedComponents(graph, new int[] { 1, 2, 3, 4 }, + new GraphNodeFilter() { + @Override public boolean match(int node) { + return node != 0; + } + }); + sortSccs(sccs); + + assertThat(sccs.length, is(2)); + assertThat(sccs[0], is(new int[] { 1, 2 })); + assertThat(sccs[1], is(new int[] { 3, 4, 5, 6, 7, 8 })); + } + @Test public void irreducibleGraphSplit() { GraphBuilder builder = new GraphBuilder(); @@ -152,6 +187,39 @@ public class GraphTest { assertTrue("Should be equialent", isEquialent(backend, graph)); } + @Test + public void irreducibleGraphSplit3() { + GraphBuilder builder = new GraphBuilder(); + builder.addEdge(0, 1); + builder.addEdge(0, 2); + builder.addEdge(1, 2); + builder.addEdge(1, 3); + builder.addEdge(1, 4); + builder.addEdge(2, 1); + builder.addEdge(2, 3); + builder.addEdge(3, 4); + builder.addEdge(4, 5); + builder.addEdge(4, 6); + builder.addEdge(5, 6); + builder.addEdge(6, 5); + builder.addEdge(6, 7); + builder.addEdge(7, 4); + builder.addEdge(7, 3); + builder.addEdge(7, 8); + builder.addEdge(8, 7); + Graph graph = builder.build(); + + DefaultGraphSplittingBackend backend = new DefaultGraphSplittingBackend(graph); + int[] weights = new int[graph.size()]; + Arrays.fill(weights, 1); + GraphUtils.splitIrreducibleGraph(graph, weights, backend); + Graph result = backend.getGraph(); + + assertTrue("Should be irreducible", GraphUtils.isIrreducible(graph)); + assertFalse("Should be reducible", GraphUtils.isIrreducible(result)); + assertTrue("Should be equialent", isEquialent(backend, graph)); + } + private boolean isEquialent(DefaultGraphSplittingBackend backend, Graph proto) { Graph graph = backend.getGraph(); for (int node = 0; node < graph.size(); ++node) { From 8d2e012f792f92399f2767baf34dd652b60fce11 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Fri, 6 Mar 2015 13:07:37 +0400 Subject: [PATCH 14/69] Speed-up generation of debug information --- .../information/DebugInformation.java | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/teavm-core/src/main/java/org/teavm/debugging/information/DebugInformation.java b/teavm-core/src/main/java/org/teavm/debugging/information/DebugInformation.java index 91cd5dada..12fd1e235 100644 --- a/teavm-core/src/main/java/org/teavm/debugging/information/DebugInformation.java +++ b/teavm-core/src/main/java/org/teavm/debugging/information/DebugInformation.java @@ -386,7 +386,7 @@ public class DebugInformation { } private int indexByKey(RecordArray mapping, GeneratedLocation location) { - int index = Collections.binarySearch(new LocationList(mapping), location); + int index = binarySearchLocation(mapping, location.getLine(), location.getColumn()); return index >= 0 ? index : -index - 2; } @@ -598,7 +598,33 @@ public class DebugInformation { return new GeneratedLocation(record.get(0), record.get(1)); } - static class LocationList extends AbstractList { + private int binarySearchLocation(RecordArray array, int row, int column) { + int l = 0; + int u = array.size() - 1; + while (true) { + int i = (l + u) / 2; + RecordArray.Record e = array.get(i); + int cmp = Integer.compare(row, e.get(0)); + if (cmp == 0) { + cmp = Integer.compare(column, e.get(1)); + } + if (cmp == 0) { + return i; + } else if (cmp < 0) { + u = i - 1; + if (u < l) { + return -i - 1; + } + } else { + l = i + 1; + if (l > u) { + return -i - 2; + } + } + } + } + + static class LocationList extends AbstractList implements RandomAccess { private RecordArray recordArray; public LocationList(RecordArray recordArray) { From d2e20d7c9f41fd51a79823654e83df6bdb80feb3 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Fri, 6 Mar 2015 14:01:02 +0400 Subject: [PATCH 15/69] Add OutOfMemoryError. When catching exceptions that are not defined, report errors at compile time. --- .../classlib/java/lang/TOutOfMemoryError.java | 32 +++++++++++++++++++ .../java/lang/TVirtualMachineError.java | 32 +++++++++++++++++++ .../model/util/MissingItemsProcessor.java | 7 ++++ 3 files changed, 71 insertions(+) create mode 100644 teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TOutOfMemoryError.java create mode 100644 teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TVirtualMachineError.java diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TOutOfMemoryError.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TOutOfMemoryError.java new file mode 100644 index 000000000..ffdf97f56 --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TOutOfMemoryError.java @@ -0,0 +1,32 @@ +/* + * Copyright 2015 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 TOutOfMemoryError extends TVirtualMachineError { + private static final long serialVersionUID = -1891949851728458692L; + + public TOutOfMemoryError() { + super(); + } + + public TOutOfMemoryError(TString message) { + super(message); + } +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TVirtualMachineError.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TVirtualMachineError.java new file mode 100644 index 000000000..33deeae40 --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TVirtualMachineError.java @@ -0,0 +1,32 @@ +/* + * Copyright 2015 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 TVirtualMachineError extends TError { + private static final long serialVersionUID = -4246822614122675559L; + + public TVirtualMachineError() { + super(); + } + + public TVirtualMachineError(TString message) { + super(message); + } +} diff --git a/teavm-core/src/main/java/org/teavm/model/util/MissingItemsProcessor.java b/teavm-core/src/main/java/org/teavm/model/util/MissingItemsProcessor.java index e9beafe5c..6d09daf75 100644 --- a/teavm-core/src/main/java/org/teavm/model/util/MissingItemsProcessor.java +++ b/teavm-core/src/main/java/org/teavm/model/util/MissingItemsProcessor.java @@ -61,15 +61,22 @@ public class MissingItemsProcessor { for (int i = 0; i < program.basicBlockCount(); ++i) { BasicBlock block = program.basicBlockAt(i); instructionsToAdd.clear(); + boolean missing = false; for (int j = 0; j < block.getInstructions().size(); ++j) { Instruction insn = block.getInstructions().get(j); insn.acceptVisitor(instructionProcessor); if (!instructionsToAdd.isEmpty()) { wasModified = true; truncateBlock(block, j); + missing = true; break; } } + if (!missing) { + for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { + checkClass(null, tryCatch.getExceptionType()); + } + } } if (wasModified) { new UnreachableBasicBlockEliminator().optimize(program); From 84aeb20321a4aca98456c807ad636331c061fca9 Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Fri, 6 Mar 2015 22:56:01 +0300 Subject: [PATCH 16/69] Handle irreducible loops after async program splitting --- .../teavm/common/DominatorTreeBuilder.java | 4 +- .../model/util/AsyncProgramSplitter.java | 37 ++++++++++ .../teavm/model/util/BasicBlockMapper.java | 33 +++++---- .../util/ProgramNodeSplittingBackend.java | 74 +++++++++++++++++++ 4 files changed, 132 insertions(+), 16 deletions(-) create mode 100644 teavm-core/src/main/java/org/teavm/model/util/ProgramNodeSplittingBackend.java diff --git a/teavm-core/src/main/java/org/teavm/common/DominatorTreeBuilder.java b/teavm-core/src/main/java/org/teavm/common/DominatorTreeBuilder.java index 06626673a..0ac1dfe5e 100644 --- a/teavm-core/src/main/java/org/teavm/common/DominatorTreeBuilder.java +++ b/teavm-core/src/main/java/org/teavm/common/DominatorTreeBuilder.java @@ -58,7 +58,9 @@ class DominatorTreeBuilder { } for (int v : graph.incomingEdges(w)) { int u = eval(v); - semidominators[w] = Math.min(semidominators[w], semidominators[u]); + if (semidominators[u] >= 0) { + semidominators[w] = Math.min(semidominators[w], semidominators[u]); + } } addToBucket(vertices[semidominators[w]], w); link(parents[w], w); diff --git a/teavm-core/src/main/java/org/teavm/model/util/AsyncProgramSplitter.java b/teavm-core/src/main/java/org/teavm/model/util/AsyncProgramSplitter.java index a657c2c45..b817fd3a7 100644 --- a/teavm-core/src/main/java/org/teavm/model/util/AsyncProgramSplitter.java +++ b/teavm-core/src/main/java/org/teavm/model/util/AsyncProgramSplitter.java @@ -16,6 +16,7 @@ package org.teavm.model.util; import java.util.*; +import org.teavm.common.*; import org.teavm.model.*; import org.teavm.model.instructions.InvokeInstruction; import org.teavm.model.instructions.JumpInstruction; @@ -147,6 +148,18 @@ public class AsyncProgramSplitter { } } + for (Part part : parts) { + IntegerArray blockSuccessors = IntegerArray.of(part.blockSuccessors); + AsyncProgramSplittingBackend splittingBackend = new AsyncProgramSplittingBackend( + new ProgramNodeSplittingBackend(part.program), blockSuccessors); + Graph graph = ProgramUtils.buildControlFlowGraphWithTryCatch(part.program); + int[] weights = new int[graph.size()]; + for (int i = 0; i < part.program.basicBlockCount(); ++i) { + weights[i] = part.program.basicBlockAt(i).getInstructions().size(); + } + GraphUtils.splitIrreducibleGraph(graph, weights, splittingBackend); + part.blockSuccessors = splittingBackend.blockSuccessors.getAll(); + } partMap.clear(); } @@ -207,4 +220,28 @@ public class AsyncProgramSplitter { Part targetPart; int source; } + + private static class AsyncProgramSplittingBackend implements GraphSplittingBackend { + private GraphSplittingBackend inner; + private IntegerArray blockSuccessors; + + public AsyncProgramSplittingBackend(GraphSplittingBackend inner, IntegerArray blockSuccessors) { + this.inner = inner; + this.blockSuccessors = blockSuccessors; + } + + @Override + public int[] split(int[] domain, int[] nodes) { + int[] copies = inner.split(domain, nodes); + for (int i = 0; i < copies.length; ++i) { + int copy = copies[i]; + int node = nodes[i]; + if (blockSuccessors.size() <= copy) { + blockSuccessors.add(-1); + } + blockSuccessors.set(copy, blockSuccessors.get(node)); + } + return copies; + } + } } diff --git a/teavm-core/src/main/java/org/teavm/model/util/BasicBlockMapper.java b/teavm-core/src/main/java/org/teavm/model/util/BasicBlockMapper.java index 8162a454f..6a9ab85c3 100644 --- a/teavm-core/src/main/java/org/teavm/model/util/BasicBlockMapper.java +++ b/teavm-core/src/main/java/org/teavm/model/util/BasicBlockMapper.java @@ -27,17 +27,20 @@ public abstract class BasicBlockMapper implements InstructionVisitor { public void transform(Program program) { for (int i = 0; i < program.basicBlockCount(); ++i) { - BasicBlock block = program.basicBlockAt(i); - block.getLastInstruction().acceptVisitor(this); - for (Phi phi : block.getPhis()) { - for (Incoming incoming : phi.getIncomings()) { - incoming.setSource(map(incoming.getSource())); - } - } - for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { - tryCatch.setHandler(map(tryCatch.getHandler())); + transform(program.basicBlockAt(i)); + } + } + + public void transform(BasicBlock block) { + block.getLastInstruction().acceptVisitor(this); + for (Phi phi : block.getPhis()) { + for (Incoming incoming : phi.getIncomings()) { + incoming.setSource(map(incoming.getSource())); } } + for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { + tryCatch.setHandler(map(tryCatch.getHandler())); + } } @Override @@ -187,15 +190,15 @@ public abstract class BasicBlockMapper implements InstructionVisitor { @Override public void visit(MonitorEnterInstruction insn) { - + } @Override public void visit(MonitorExitInstruction insn) { - + } - - - - + + + + } diff --git a/teavm-core/src/main/java/org/teavm/model/util/ProgramNodeSplittingBackend.java b/teavm-core/src/main/java/org/teavm/model/util/ProgramNodeSplittingBackend.java new file mode 100644 index 000000000..4a2da749e --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/model/util/ProgramNodeSplittingBackend.java @@ -0,0 +1,74 @@ +/* + * Copyright 2015 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.model.util; + +import com.carrotsearch.hppc.IntIntMap; +import com.carrotsearch.hppc.IntIntOpenHashMap; +import org.teavm.common.GraphSplittingBackend; +import org.teavm.model.BasicBlock; +import org.teavm.model.Program; + +/** + * + * @author Alexey Andreev + */ +public class ProgramNodeSplittingBackend implements GraphSplittingBackend { + private Program program; + + public ProgramNodeSplittingBackend(Program program) { + this.program = program; + } + + @Override + public int[] split(int[] domain, int[] nodes) { + int[] copies = new int[nodes.length]; + IntIntMap map = new IntIntOpenHashMap(); + for (int i = 0; i < nodes.length; ++i) { + int node = nodes[i]; + BasicBlock block = program.basicBlockAt(node); + BasicBlock blockCopy = program.createBasicBlock(); + blockCopy.getInstructions().addAll(ProgramUtils.copyInstructions(block, 0, + block.getInstructions().size(), program)); + copies[i] = blockCopy.getIndex(); + map.put(nodes[i], copies[i] + 1); + } + CopyBlockMapper copyBlockMapper = new CopyBlockMapper(map); + for (int i = 0; i < copies.length; ++i) { + copyBlockMapper.transform(program.basicBlockAt(copies[i])); + } + for (int i = 0; i < domain.length; ++i) { + copyBlockMapper.transform(program.basicBlockAt(domain[i])); + } + return copies; + } + + private static class CopyBlockMapper extends BasicBlockMapper { + private IntIntMap map; + + public CopyBlockMapper(IntIntMap map) { + this.map = map; + } + + @Override + protected BasicBlock map(BasicBlock block) { + int mappedIndex = map.get(block.getIndex()); + if (mappedIndex == 0) { + return block; + } + return block.getProgram().basicBlockAt(mappedIndex - 1); + } + } +} From 77738b001f127dea3ecc1fb482bf4b7822b9dd31 Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Fri, 6 Mar 2015 23:11:55 +0300 Subject: [PATCH 17/69] Speed-up context switching --- .../resources/org/teavm/javascript/runtime.js | 15 ++++++++++----- .../org/teavm/samples/async/AsyncProgram.java | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js index edd420b48..4a7dd2c94 100644 --- a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js +++ b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js @@ -458,7 +458,13 @@ function $rt_rootInvocationAdapter(f) { console.error(!hasWrappers ? prefix : "Root cause is %s at %o", e.message, e.stack); } }); - return f.apply(this, args); + f.apply(this, args); + var thread = $rt_getThread(); + while (thread.postponed) { + var postponed = thread.postponed; + thread.postponed = null; + postponed(); + } } } function $rt_mainWrapper(f) { @@ -485,16 +491,15 @@ function $rt_s(index) { } var $rt_continueCounter = 0; function $rt_continue(f) { - if ($rt_continueCounter++ == 10) { + if ($rt_continueCounter++ == 40) { $rt_continueCounter = 0; return function() { var self = this; var args = arguments; var thread = $rt_getThread(); - setTimeout(function() { - $rt_setThread(thread); + thread.postponed = function() { f.apply(self, args); - }, 0); + }; }; } else { return f; diff --git a/teavm-samples/teavm-samples-async/src/main/java/org/teavm/samples/async/AsyncProgram.java b/teavm-samples/teavm-samples-async/src/main/java/org/teavm/samples/async/AsyncProgram.java index c21160c6e..e03956bb0 100644 --- a/teavm-samples/teavm-samples-async/src/main/java/org/teavm/samples/async/AsyncProgram.java +++ b/teavm-samples/teavm-samples-async/src/main/java/org/teavm/samples/async/AsyncProgram.java @@ -87,7 +87,7 @@ public final class AsyncProgram { prime[i] = true; } StringBuilder sb = new StringBuilder(); - for (int i = 0; i < 100; ++i) { + for (int i = 0; i < 1000; ++i) { if (prime[i]) { sb.append(i).append(' '); } From b7ace8e03351a1f1271b306557d37f25090db544 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Sat, 7 Mar 2015 18:30:23 +0100 Subject: [PATCH 18/69] Describing how to execute the benchmarks --- .../teavm-samples-benchmark/README.md | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 teavm-samples/teavm-samples-benchmark/README.md diff --git a/teavm-samples/teavm-samples-benchmark/README.md b/teavm-samples/teavm-samples-benchmark/README.md new file mode 100644 index 000000000..7cc449341 --- /dev/null +++ b/teavm-samples/teavm-samples-benchmark/README.md @@ -0,0 +1,23 @@ +TeaVM, GWT, HotSport JBox2D Benchmark +===================================== + +Compares the speed of execution on a complex [JBox2D](http://www.jbox2d.org/) CPU extensive +computation. JavaScript produced by TeaVM and GWT can be compared by running + +``` +$ mvn clean install +``` + +then just open the generated HTML versions + +``` +$ open target/teavm-samples-benchmark-*-SNAPSHOT/index.html +``` + +In addition to that one can run the same demo with classical HotSpot virtual machine. Just try: + +``` +$ mvn -Pfx exec:java +``` + + From e951b681ca1a96fdb2aa32bdb5b73f9655b095ad Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Sun, 8 Mar 2015 11:57:03 +0300 Subject: [PATCH 19/69] Fix ordering of basic blocks before decompilation --- .../java/org/teavm/common/GraphIndexer.java | 149 ++++++++++-------- 1 file changed, 83 insertions(+), 66 deletions(-) diff --git a/teavm-core/src/main/java/org/teavm/common/GraphIndexer.java b/teavm-core/src/main/java/org/teavm/common/GraphIndexer.java index 9a968ffee..7fba32a06 100644 --- a/teavm-core/src/main/java/org/teavm/common/GraphIndexer.java +++ b/teavm-core/src/main/java/org/teavm/common/GraphIndexer.java @@ -15,8 +15,10 @@ */ package org.teavm.common; +import com.carrotsearch.hppc.IntOpenHashSet; +import com.carrotsearch.hppc.IntSet; +import com.carrotsearch.hppc.cursors.IntCursor; import java.util.Arrays; -import java.util.Comparator; /** * @@ -28,74 +30,21 @@ public class GraphIndexer { static final byte VISITED = 2; private int[] indexToNode; private int[] nodeToIndex; + private byte[] state; private Graph graph; + private DominatorTree domTree; + private int lastIndex; public GraphIndexer(Graph graph) { - sort(graph); - } - - private static class LoopEntrance { - int head; - int follower; - } - - private int sort(Graph graph) { - LoopGraph loopGraph = new LoopGraph(graph); int sz = graph.size(); - int[] indexToNode = new int[sz + 1]; - int[] nodeToIndex = new int[sz + 1]; - int[] visitIndex = new int[sz + 1]; + indexToNode = new int[sz + 1]; + nodeToIndex = new int[sz + 1]; Arrays.fill(nodeToIndex, -1); Arrays.fill(indexToNode, -1); - Arrays.fill(visitIndex, -1); - byte[] state = new byte[sz]; - int lastIndex = 0; - int lastVisitIndex = 0; - IntegerStack stack = new IntegerStack(sz * 2); - stack.push(loopGraph.loopAt(0) != null ? loopGraph.loopAt(0).getHead() : 0); - while (!stack.isEmpty()) { - int node = stack.pop(); - switch (state[node]) { - case VISITING: { - state[node] = VISITED; - nodeToIndex[node] = lastIndex++; - break; - } - case NONE: { - visitIndex[node] = lastVisitIndex++; - state[node] = VISITING; - stack.push(node); - int[] successors = graph.outgoingEdges(node); - LoopEntrance[] edges = new LoopEntrance[successors.length]; - for (int i = 0; i < edges.length; ++i) { - int successor = successors[i]; - Loop successorLoop = loopGraph.loopAt(successor); - LoopEntrance edge = new LoopEntrance(); - edge.head = successorLoop != null ? - visitIndex[successorLoop.getHead()] : -1; - edge.follower = successor; - edges[i] = edge; - } - Arrays.sort(edges, new Comparator() { - @Override - public int compare(LoopEntrance o1, LoopEntrance o2) { - return Integer.compare(o2.head, o1.head); - } - }); - for (LoopEntrance edge : edges) { - int next = edge.follower; - switch (state[next]) { - case NONE: - stack.push(next); - break; - default: - break; - } - } - break; - } - } - } + state = new byte[sz]; + this.graph = graph; + domTree = GraphUtils.buildDominatorTree(graph); + sort(graph); --lastIndex; for (int node = 0; node < sz; ++node) { int index = nodeToIndex[node]; @@ -115,9 +64,77 @@ public class GraphIndexer { } } this.graph = sorted.build(); - this.indexToNode = indexToNode; - this.nodeToIndex = nodeToIndex; - return lastIndex + 1; + } + + private void sort(Graph graph) { + int sz = graph.size(); + IntegerStack stack = new IntegerStack(sz * 2); + stack.push(0); + while (!stack.isEmpty()) { + int node = stack.pop(); + switch (state[node]) { + case VISITING: { + state[node] = VISITED; + nodeToIndex[node] = lastIndex++; + break; + } + case NONE: { + state[node] = VISITING; + stack.push(node); + IntegerArray terminalNodes = new IntegerArray(1); + for (int pred : graph.incomingEdges(node)) { + if (domTree.dominates(node, pred)) { + terminalNodes.add(pred); + } + } + int[] successors = graph.outgoingEdges(node); + if (terminalNodes.size() > 0) { + IntSet loopNodes = IntOpenHashSet.from(findNaturalLoop(node, terminalNodes.getAll())); + IntegerArray orderedSuccessors = new IntegerArray(successors.length); + for (int succ : successors) { + if (loopNodes.contains(succ)) { + orderedSuccessors.add(succ); + } + } + IntSet outerSuccessors = new IntOpenHashSet(successors.length); + for (IntCursor loopNode : loopNodes) { + for (int succ : graph.outgoingEdges(loopNode.value)) { + if (!loopNodes.contains(succ)) { + outerSuccessors.add(succ); + } + } + } + orderedSuccessors.addAll(outerSuccessors.toArray()); + successors = orderedSuccessors.getAll(); + } + for (int succ : successors) { + if (state[succ] == NONE) { + stack.push(succ); + } + } + break; + } + } + } + } + + private int[] findNaturalLoop(int head, int[] terminals) { + IntSet loop = new IntOpenHashSet(); + loop.add(head); + IntegerStack stack = new IntegerStack(1); + for (int pred : terminals) { + stack.push(pred); + } + while (!stack.isEmpty()) { + int node = stack.pop(); + if (!loop.add(node)) { + continue; + } + for (int pred : graph.incomingEdges(node)) { + stack.push(pred); + } + } + return loop.toArray(); } public int nodeAt(int index) { From 7869173ac26a77d3c9e2b40baaec458d32d9b7b9 Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Sun, 8 Mar 2015 12:18:57 +0300 Subject: [PATCH 20/69] Remove build errors on JDK8 --- .../teavm/chromerdp/ChromeRDPDebugger.java | 2 +- .../teavm/chromerdp/ChromeRDPExchange.java | 2 +- .../chromerdp/ChromeRDPExchangeConsumer.java | 2 +- .../chromerdp/ChromeRDPExchangeListener.java | 2 +- .../org/teavm/chromerdp/RDPLocalVariable.java | 2 +- .../java/org/teavm/chromerdp/RDPScope.java | 2 +- .../java/org/teavm/chromerdp/RDPValue.java | 2 +- .../teavm/chromerdp/data/CallArgumentDTO.java | 2 +- .../chromerdp/data/PropertyDescriptorDTO.java | 2 +- .../teavm/chromerdp/data/RemoteObjectDTO.java | 2 +- .../org/teavm/chromerdp/data/ScopeDTO.java | 2 +- .../messages/CallFunctionCommand.java | 2 +- .../messages/CallFunctionResponse.java | 2 +- .../messages/GetPropertiesCommand.java | 2 +- .../messages/GetPropertiesResponse.java | 2 +- .../impl/DeclaringClassMetadataGenerator.java | 2 +- .../impl/FirstDayOfWeekMetadataGenerator.java | 2 +- .../org/teavm/classlib/impl/JavacSupport.java | 2 +- ...nimalDaysInFirstWeekMetadataGenerator.java | 2 +- .../classlib/impl/ServiceLoaderSupport.java | 2 +- .../classlib/impl/WeekMetadataGenerator.java | 2 +- .../teavm/classlib/impl/report/JCLClass.java | 2 +- .../teavm/classlib/impl/report/JCLItem.java | 2 +- .../classlib/impl/report/JCLItemType.java | 2 +- .../classlib/impl/report/JCLPackage.java | 2 +- .../teavm/classlib/impl/report/JCLStatus.java | 2 +- .../AvailableLocalesMetadataGenerator.java | 2 +- .../classlib/impl/unicode/CLDRHelper.java | 2 +- .../LikelySubtagsMetadataGenerator.java | 2 +- .../teavm/classlib/java/io/TDataInput.java | 2 +- .../classlib/java/io/TDataInputStream.java | 2 +- .../classlib/java/io/TDataOutputStream.java | 166 ------------------ .../java/io/TPushbackInputStream.java | 2 +- .../java/io/TUTFDataFormatException.java | 2 +- .../java/lang/LongNativeGenerator.java | 2 +- .../lang/TArrayIndexOutOfBoundsException.java | 2 +- .../java/lang/TArrayStoreException.java | 2 +- .../org/teavm/classlib/java/lang/TClass.java | 2 +- .../classlib/java/lang/TClassLoader.java | 2 +- .../java/lang/TClassNotFoundException.java | 2 +- .../lang/TCloneNotSupportedException.java | 2 +- .../teavm/classlib/java/lang/TCloneable.java | 2 +- .../org/teavm/classlib/java/lang/TEnum.java | 2 +- .../java/lang/TIllegalAccessException.java | 2 +- .../lang/TIllegalMonitorStateException.java | 2 +- .../lang/TIncompatibleClassChangeError.java | 2 +- .../java/lang/TInstantiationException.java | 2 +- .../java/lang/TInterruptedException.java | 2 +- .../teavm/classlib/java/lang/TIterable.java | 2 +- .../classlib/java/lang/TLinkageError.java | 2 +- .../org/teavm/classlib/java/lang/TLong.java | 2 +- .../lang/TNegativeArraySizeException.java | 2 +- .../classlib/java/lang/TNoSuchFieldError.java | 2 +- .../java/lang/TNoSuchMethodError.java | 2 +- .../org/teavm/classlib/java/lang/TObject.java | 2 +- .../teavm/classlib/java/lang/TReadable.java | 2 +- .../lang/TReflectiveOperationException.java | 2 +- .../teavm/classlib/java/lang/TStrictMath.java | 2 +- .../org/teavm/classlib/java/lang/TString.java | 2 +- .../java/lang/TSystemClassLoader.java | 2 +- .../teavm/classlib/java/lang/TThrowable.java | 2 +- .../org/teavm/classlib/java/lang/TVoid.java | 2 +- .../teavm/classlib/java/math/TDivision.java | 4 +- .../teavm/classlib/java/math/TElementary.java | 3 +- .../teavm/classlib/java/nio/TCharBuffer.java | 2 +- .../classlib/java/nio/TCharBufferImpl.java | 2 +- .../java/nio/TCharBufferOverArray.java | 2 +- .../java/nio/TCharBufferOverByteBuffer.java | 2 +- .../TCharBufferOverByteBufferBigEndian.java | 2 +- ...TCharBufferOverByteBufferLittleEndian.java | 2 +- .../classlib/java/nio/TDoubleBuffer.java | 2 +- .../classlib/java/nio/TDoubleBufferImpl.java | 2 +- .../java/nio/TDoubleBufferOverArray.java | 2 +- .../java/nio/TDoubleBufferOverByteBuffer.java | 2 +- .../teavm/classlib/java/nio/TFloatBuffer.java | 2 +- .../classlib/java/nio/TFloatBufferImpl.java | 2 +- .../java/nio/TFloatBufferOverArray.java | 2 +- .../java/nio/TFloatBufferOverByteBuffer.java | 2 +- .../TFloatBufferOverByteBufferBigEndian.java | 2 +- ...FloatBufferOverByteBufferLittleEndian.java | 2 +- .../teavm/classlib/java/nio/TIntBuffer.java | 2 +- .../classlib/java/nio/TIntBufferImpl.java | 2 +- .../java/nio/TIntBufferOverArray.java | 2 +- .../java/nio/TIntBufferOverByteBuffer.java | 2 +- .../TIntBufferOverByteBufferBigEndian.java | 2 +- .../TIntBufferOverByteBufferLittleEndian.java | 2 +- .../teavm/classlib/java/nio/TLongBuffer.java | 2 +- .../classlib/java/nio/TLongBufferImpl.java | 2 +- .../java/nio/TLongBufferOverArray.java | 2 +- .../java/nio/TLongBufferOverByteBuffer.java | 2 +- .../TLongBufferOverByteBufferBigEndian.java | 2 +- ...TLongBufferOverByteBufferLittleEndian.java | 2 +- .../teavm/classlib/java/nio/TShortBuffer.java | 2 +- .../classlib/java/nio/TShortBufferImpl.java | 2 +- .../java/nio/TShortBufferOverArray.java | 2 +- .../java/nio/TShortBufferOverByteBuffer.java | 2 +- .../TShortBufferOverByteBufferBigEndian.java | 2 +- ...ShortBufferOverByteBufferLittleEndian.java | 2 +- .../java/util/DateNativeGenerator.java | 2 +- .../java/util/RandomNativeGenerator.java | 2 +- .../java/util/TAbstractCollection.java | 2 +- .../classlib/java/util/TAbstractList.java | 2 +- .../classlib/java/util/TAbstractMap.java | 2 +- .../classlib/java/util/TAbstractSet.java | 2 +- .../teavm/classlib/java/util/TArrayList.java | 2 +- .../org/teavm/classlib/java/util/TBitSet.java | 2 +- .../teavm/classlib/java/util/TCollection.java | 2 +- .../teavm/classlib/java/util/TComparator.java | 2 +- .../TConcurrentModificationException.java | 2 +- .../org/teavm/classlib/java/util/TDate.java | 2 +- .../org/teavm/classlib/java/util/TDeque.java | 2 +- .../classlib/java/util/TEnumeration.java | 2 +- .../teavm/classlib/java/util/TIterator.java | 2 +- .../org/teavm/classlib/java/util/TList.java | 2 +- .../classlib/java/util/TListIterator.java | 2 +- .../org/teavm/classlib/java/util/TMap.java | 2 +- .../java/util/TNoSuchElementException.java | 2 +- .../teavm/classlib/java/util/TObjects.java | 2 +- .../org/teavm/classlib/java/util/TQueue.java | 2 +- .../org/teavm/classlib/java/util/TRandom.java | 2 +- .../classlib/java/util/TRandomAccess.java | 2 +- .../classlib/java/util/TServiceLoader.java | 2 +- .../org/teavm/classlib/java/util/TSet.java | 2 +- .../teavm/classlib/java/util/TSortedSet.java | 2 +- .../java/util/concurrent/TCallable.java | 2 +- .../util/logging/LoggerNativeGenerator.java | 2 +- .../classlib/java/util/logging/TLevel.java | 2 +- .../java/util/logging/TLogRecord.java | 2 +- .../classlib/java/util/logging/TLogger.java | 2 +- .../java/util/regex/TAbstractCharClass.java | 12 -- .../java/util/regex/TAbstractSet.java | 9 - .../util/regex/TBackReferencedSingleSet.java | 6 - .../java/util/regex/TDecomposedCharSet.java | 11 -- .../java/util/zip/TDataFormatException.java | 2 +- .../java/util/zip/TDeflaterOutputStream.java | 2 +- .../java/util/zip/TGZIPInputStream.java | 2 +- .../java/util/zip/TGZIPOutputStream.java | 2 +- .../java/util/zip/TInflaterInputStream.java | 2 +- .../org/teavm/cli/ConsoleTeaVMToolLog.java | 2 +- .../main/java/org/teavm/cli/TeaVMRunner.java | 2 +- .../cache/DiskCachedClassHolderSource.java | 2 +- .../java/org/teavm/common/CachedMapper.java | 2 +- .../main/java/org/teavm/common/DJGraph.java | 2 +- .../teavm/common/GraphSplittingBackend.java | 2 +- .../main/java/org/teavm/common/Mapper.java | 2 +- .../teavm/common/MutableDirectedGraph.java | 2 +- .../java/org/teavm/debugging/PropertyMap.java | 2 +- .../main/java/org/teavm/debugging/Value.java | 2 +- .../java/org/teavm/debugging/Variable.java | 2 +- .../information/ClassNameIterator.java | 2 +- .../information/DebuggerCallSite.java | 2 +- .../information/DebuggerCallSiteVisitor.java | 2 +- .../information/DebuggerStaticCallSite.java | 2 +- .../information/DebuggerVirtualCallSite.java | 2 +- .../information/FileNameIterator.java | 2 +- .../information/LineNumberIterator.java | 2 +- .../information/SourceLocationIterator.java | 2 +- .../debugging/javascript/JavaScriptValue.java | 2 +- .../javascript/JavaScriptVariable.java | 2 +- .../teavm/dependency/DependencyAgentType.java | 2 +- .../DependencyCheckerInterruptor.java | 2 +- .../teavm/dependency/DependencyConsumer.java | 2 +- .../org/teavm/dependency/DependencyInfo.java | 2 +- .../org/teavm/dependency/DependencyType.java | 2 +- .../dependency/MethodDependencyInfo.java | 2 +- .../teavm/dependency/ValueDependencyInfo.java | 2 +- .../diagnostics/AccumulationDiagnostics.java | 2 +- .../org/teavm/diagnostics/Diagnostics.java | 2 +- .../java/org/teavm/diagnostics/Problem.java | 2 +- .../teavm/diagnostics/ProblemSeverity.java | 2 +- .../org/teavm/javascript/Associativity.java | 2 +- .../javascript/DecompilationException.java | 2 +- .../java/org/teavm/javascript/Priority.java | 2 +- .../teavm/javascript/RenderingContext.java | 2 +- .../org/teavm/javascript/TryCatchFinder.java | 2 +- .../org/teavm/javascript/ast/ClassNode.java | 2 +- .../org/teavm/javascript/ast/FieldNode.java | 2 +- .../javascript/ast/MethodNodeVisitor.java | 2 +- .../javascript/ast/NativeMethodNode.java | 2 +- .../teavm/javascript/ast/NodeModifier.java | 2 +- .../javascript/ast/RegularMethodNode.java | 2 +- .../teavm/javascript/ast/UnwrapArrayExpr.java | 2 +- .../org/teavm/javascript/spi/GeneratedBy.java | 2 +- .../org/teavm/javascript/spi/Generator.java | 2 +- .../javascript/spi/GeneratorContext.java | 2 +- .../org/teavm/javascript/spi/InjectedBy.java | 2 +- .../org/teavm/javascript/spi/Injector.java | 2 +- .../teavm/javascript/spi/InjectorContext.java | 2 +- .../java/org/teavm/javascript/spi/Rename.java | 2 +- .../java/org/teavm/javascript/spi/Sync.java | 2 +- .../org/teavm/model/AnnotationContainer.java | 2 +- .../org/teavm/model/ClassReaderSource.java | 2 +- .../model/ListableClassReaderSource.java | 2 +- .../java/org/teavm/model/TryCatchBlock.java | 2 +- .../org/teavm/model/TryCatchBlockReader.java | 2 +- .../model/instructions/ArrayElementType.java | 2 +- .../instructions/NullCheckInstruction.java | 2 +- .../instructions/UnwrapArrayInstruction.java | 2 +- .../teavm/model/util/AsyncMethodFinder.java | 2 +- .../teavm/optimization/ClassSetOptimizer.java | 2 +- .../teavm/optimization/Devirtualization.java | 2 +- .../optimization/MethodOptimization.java | 2 +- .../UnusedVariableElimination.java | 2 +- .../optimization/VariableEscapeAnalyzer.java | 2 +- .../VariableUsageGraphBuilder.java | 2 +- .../parsing/ClasspathClassHolderSource.java | 2 +- .../parsing/ClasspathResourceMapper.java | 2 +- .../parsing/VariableDebugInformation.java | 2 +- .../resource/ClasspathResourceReader.java | 2 +- .../resource/MapperClassHolderSource.java | 2 +- .../org/teavm/resource/ResourceParser.java | 2 +- .../org/teavm/tooling/EmptyTeaVMToolLog.java | 2 +- .../org/teavm/tooling/ExceptionHelper.java | 2 +- .../java/org/teavm/tooling/TeaVMTestTool.java | 2 +- .../java/org/teavm/tooling/TeaVMTool.java | 2 +- .../org/teavm/tooling/TeaVMToolException.java | 2 +- .../java/org/teavm/tooling/TeaVMToolLog.java | 2 +- .../src/main/java/org/teavm/vm/TeaVM.java | 2 +- .../java/org/teavm/vm/TeaVMEntryPoint.java | 2 +- .../main/java/org/teavm/vm/TeaVMPhase.java | 2 +- .../org/teavm/vm/TeaVMProgressListener.java | 2 +- .../main/java/org/teavm/vm/Violations.java | 2 +- .../vm/spi/AbstractRendererListener.java | 2 +- .../org/teavm/vm/spi/RendererListener.java | 2 +- .../java/org/teavm/dom/browser/Screen.java | 2 +- .../main/java/org/teavm/dom/core/Entity.java | 2 +- .../java/org/teavm/dom/core/Notation.java | 2 +- .../teavm/dom/css/CSSStyleDeclaration.java | 2 +- .../teavm/dom/css/ElementCSSInlineStyle.java | 2 +- .../org/teavm/dom/events/DocumentEvent.java | 2 +- .../org/teavm/dom/events/KeyboardEvent.java | 2 +- .../java/org/teavm/dom/events/MouseEvent.java | 2 +- .../org/teavm/dom/html/HTMLBaseElement.java | 2 +- .../org/teavm/dom/html/HTMLCollection.java | 2 +- .../java/org/teavm/dom/html/HTMLDocument.java | 2 +- .../java/org/teavm/dom/html/HTMLElement.java | 2 +- .../org/teavm/dom/html/HTMLHeadElement.java | 2 +- .../org/teavm/dom/html/HTMLHtmlElement.java | 2 +- .../org/teavm/dom/html/HTMLInputElement.java | 2 +- .../org/teavm/dom/html/HTMLLinkElement.java | 2 +- .../org/teavm/dom/html/HTMLMetaElement.java | 2 +- .../org/teavm/dom/html/HTMLOptionElement.java | 2 +- .../teavm/dom/html/HTMLOptionsCollection.java | 2 +- .../org/teavm/dom/html/HTMLSelectElement.java | 2 +- .../org/teavm/dom/html/HTMLTitleElement.java | 2 +- .../main/java/org/teavm/dom/json/JSON.java | 2 +- .../teavm/dom/typedarrays/Float32Array.java | 2 +- .../teavm/dom/typedarrays/Float64Array.java | 2 +- .../org/teavm/dom/typedarrays/Int32Array.java | 2 +- .../dom/typedarrays/TypedArrayFactory.java | 2 +- .../org/teavm/dom/webgl/WebGLActiveInfo.java | 2 +- .../dom/webgl/WebGLShaderPrecisionFormat.java | 2 +- .../teavm/dom/webgl/WebGLUniformLocation.java | 2 +- .../PreferencesBasedTeaVMProjectSettings.java | 2 +- .../org/teavm/eclipse/TeaVMEclipsePlugin.java | 2 +- .../teavm/eclipse/TeaVMProjectBuilder.java | 2 +- .../org/teavm/eclipse/TeaVMProjectNature.java | 2 +- .../teavm/eclipse/TeaVMProjectSettings.java | 2 +- .../org/teavm/eclipse/TeaVMRuntimeMode.java | 2 +- .../debugger/PropertyNameComparator.java | 2 +- .../eclipse/debugger/TeaVMDebugElement.java | 2 +- .../eclipse/debugger/TeaVMDebugProcess.java | 2 +- .../eclipse/debugger/TeaVMDebugTarget.java | 2 +- .../teavm/eclipse/debugger/TeaVMJSScope.java | 2 +- .../eclipse/debugger/TeaVMJSStackFrame.java | 2 +- .../teavm/eclipse/debugger/TeaVMJSThread.java | 2 +- .../teavm/eclipse/debugger/TeaVMJSValue.java | 2 +- .../eclipse/debugger/TeaVMJSVariable.java | 2 +- .../debugger/TeaVMJSVariablesHolder.java | 2 +- .../eclipse/debugger/TeaVMJavaStackFrame.java | 2 +- .../eclipse/debugger/TeaVMJavaThread.java | 2 +- .../TeaVMLaunchConfigurationDelegate.java | 2 +- .../debugger/TeaVMSourceLookupDirector.java | 2 +- .../TeaVMSourceLookupParticipant.java | 2 +- .../TeaVMSourcePathComputerDelegate.java | 2 +- .../eclipse/debugger/TeaVMStackFrame.java | 2 +- .../eclipse/debugger/TeaVMStreamMonitor.java | 2 +- .../eclipse/debugger/TeaVMStreamsProxy.java | 2 +- .../teavm/eclipse/debugger/TeaVMThread.java | 2 +- .../teavm/eclipse/debugger/TeaVMValue.java | 2 +- .../teavm/eclipse/debugger/TeaVMVariable.java | 2 +- .../debugger/TeaVMVariablesHolder.java | 2 +- .../ui/TeaVMDebugModelPresentation.java | 2 +- .../teavm/eclipse/debugger/ui/TeaVMTab.java | 2 +- .../eclipse/debugger/ui/TeaVMTabGroup.java | 2 +- .../eclipse/debugger/ui/URLEditorInput.java | 2 +- .../teavm/eclipse/debugger/ui/URLStorage.java | 2 +- .../eclipse/ui/ClassSelectionDialog.java | 2 +- .../eclipse/ui/MainClassSelectionDialog.java | 2 +- .../teavm/eclipse/ui/TeaVMProfileDialog.java | 2 +- .../eclipse/ui/TeaVMProjectPropertyPage.java | 2 +- .../ui/TransformerClassSelectionDialog.java | 2 +- .../org/teavm/html4j/EntryPointGenerator.java | 2 +- .../java/org/teavm/html4j/HTML4JPlugin.java | 2 +- .../html4j/JavaScriptBodyDependency.java | 2 +- .../teavm/html4j/JavaScriptBodyGenerator.java | 2 +- .../html4j/JavaScriptBodyTransformer.java | 2 +- .../java/org/teavm/html4j/JavaScriptConv.java | 2 +- .../teavm/html4j/JavaScriptConvGenerator.java | 2 +- .../html4j/JavaScriptResourceInterceptor.java | 2 +- .../teavm/html4j/testing/KOTestAdapter.java | 2 +- .../test/JavaScriptBodyConversionTest.java | 2 +- .../teavm/html4j/test/JavaScriptBodyTest.java | 2 +- .../java/org/teavm/jso/JSArrayReader.java | 2 +- .../src/main/java/org/teavm/jso/JSBody.java | 2 +- .../java/org/teavm/jso/JSBooleanArray.java | 2 +- .../org/teavm/jso/JSBooleanArrayReader.java | 2 +- .../java/org/teavm/jso/JSByteArrayReader.java | 2 +- .../java/org/teavm/jso/JSDoubleArray.java | 2 +- .../org/teavm/jso/JSDoubleArrayReader.java | 2 +- .../org/teavm/jso/JSDoubleSortFunction.java | 2 +- .../main/java/org/teavm/jso/JSIntArray.java | 2 +- .../java/org/teavm/jso/JSIntArrayReader.java | 2 +- .../java/org/teavm/jso/JSIntSortFunction.java | 2 +- .../org/teavm/jso/JSShortArrayReader.java | 2 +- .../java/org/teavm/jso/JSSortFunction.java | 2 +- .../java/org/teavm/jso/JSStringArray.java | 2 +- .../org/teavm/jso/JSStringSortFunction.java | 2 +- .../org/teavm/jso/plugin/JSBodyGenerator.java | 2 +- .../java/org/teavm/jso/plugin/JSBodyImpl.java | 2 +- .../teavm/jso/plugin/JSOAliasRenderer.java | 2 +- .../jso/plugin/JSODependencyListener.java | 2 +- .../org/teavm/maven/MavenTeaVMToolLog.java | 2 +- .../java/org/teavm/platform/Platform.java | 2 +- .../org/teavm/platform/PlatformClass.java | 2 +- .../teavm/platform/PlatformClassMetadata.java | 2 +- .../org/teavm/platform/PlatformObject.java | 2 +- .../teavm/platform/PlatformPrimitives.java | 2 +- .../org/teavm/platform/PlatformQueue.java | 2 +- .../org/teavm/platform/PlatformRunnable.java | 2 +- .../org/teavm/platform/PlatformSequence.java | 2 +- .../teavm/platform/async/AsyncCallback.java | 2 +- .../platform/metadata/ClassResource.java | 2 +- .../ClassScopedMetadataGenerator.java | 2 +- .../metadata/ClassScopedMetadataProvider.java | 2 +- .../platform/metadata/MetadataGenerator.java | 2 +- .../metadata/MetadataGeneratorContext.java | 2 +- .../platform/metadata/MetadataProvider.java | 2 +- .../org/teavm/platform/metadata/Resource.java | 2 +- .../platform/metadata/ResourceArray.java | 2 +- .../teavm/platform/metadata/ResourceMap.java | 2 +- .../platform/plugin/AsyncMethodGenerator.java | 2 +- .../platform/plugin/AsyncMethodProcessor.java | 2 +- .../plugin/BuildTimeClassResource.java | 2 +- .../plugin/BuildTimeResourceProxy.java | 2 +- ...ScopedMetadataProviderNativeGenerator.java | 2 +- .../plugin/NewInstanceDependencySupport.java | 2 +- .../platform/plugin/PlatformGenerator.java | 2 +- .../teavm/platform/plugin/PlatformPlugin.java | 2 +- .../plugin/PlatformQueueGenerator.java | 2 +- .../org/teavm/samples/async/AsyncProgram.java | 2 +- .../org/teavm/samples/benchmark/Scene.java | 2 +- .../benchmark/teavm/BenchmarkStarter.java | 2 +- .../java/io/InputStreamReaderTest.java | 2 +- .../teavm/classlib/java/lang/StringTest.java | 2 +- .../teavm/classlib/java/lang/TestObject.java | 2 +- .../classlib/java/lang/reflect/ArrayTest.java | 2 +- .../java/nio/ByteBufferWrapperTest.java | 2 +- .../classlib/java/nio/DoubleBufferTest.java | 2 +- .../classlib/java/nio/FloatBufferTest.java | 2 +- .../classlib/java/nio/IntBufferTest.java | 2 +- .../classlib/java/nio/LongBufferTest.java | 2 +- .../classlib/java/util/ServiceLoaderTest.java | 2 +- .../teavm/classlib/java/util/TestService.java | 2 +- .../classlib/java/util/TestServiceImpl.java | 2 +- .../java/util/regex/Matcher2Test.java | 12 +- .../classlib/java/util/regex/PatternTest.java | 12 +- .../java/util/zip/GZIPInputStreamTest.java | 2 +- 368 files changed, 376 insertions(+), 577 deletions(-) diff --git a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/ChromeRDPDebugger.java b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/ChromeRDPDebugger.java index eb8964e2d..664e8438e 100644 --- a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/ChromeRDPDebugger.java +++ b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/ChromeRDPDebugger.java @@ -36,7 +36,7 @@ import org.teavm.debugging.javascript.*; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class ChromeRDPDebugger implements JavaScriptDebugger, ChromeRDPExchangeConsumer { private static final Logger logger = LoggerFactory.getLogger(ChromeRDPDebugger.class); diff --git a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/ChromeRDPExchange.java b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/ChromeRDPExchange.java index 494d366f6..cf04ca865 100644 --- a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/ChromeRDPExchange.java +++ b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/ChromeRDPExchange.java @@ -17,7 +17,7 @@ package org.teavm.chromerdp; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface ChromeRDPExchange { void send(String message); diff --git a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/ChromeRDPExchangeConsumer.java b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/ChromeRDPExchangeConsumer.java index a81affb3a..da34daac2 100644 --- a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/ChromeRDPExchangeConsumer.java +++ b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/ChromeRDPExchangeConsumer.java @@ -17,7 +17,7 @@ package org.teavm.chromerdp; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface ChromeRDPExchangeConsumer { void setExchange(ChromeRDPExchange exchange); diff --git a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/ChromeRDPExchangeListener.java b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/ChromeRDPExchangeListener.java index d413edf2c..ac6e63e95 100644 --- a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/ChromeRDPExchangeListener.java +++ b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/ChromeRDPExchangeListener.java @@ -19,7 +19,7 @@ import java.io.IOException; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface ChromeRDPExchangeListener { void received(String message) throws IOException; diff --git a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/RDPLocalVariable.java b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/RDPLocalVariable.java index 6525695a0..5a9697cc0 100644 --- a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/RDPLocalVariable.java +++ b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/RDPLocalVariable.java @@ -20,7 +20,7 @@ import org.teavm.debugging.javascript.JavaScriptVariable; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class RDPLocalVariable implements JavaScriptVariable { private String name; diff --git a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/RDPScope.java b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/RDPScope.java index 9305fcfa6..3238bf4cc 100644 --- a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/RDPScope.java +++ b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/RDPScope.java @@ -23,7 +23,7 @@ import java.util.concurrent.atomic.AtomicReference; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class RDPScope extends AbstractMap { private AtomicReference> backingMap = new AtomicReference<>(); diff --git a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/RDPValue.java b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/RDPValue.java index 24d695a7e..95372b0ec 100644 --- a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/RDPValue.java +++ b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/RDPValue.java @@ -23,7 +23,7 @@ import org.teavm.debugging.javascript.JavaScriptVariable; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class RDPValue implements JavaScriptValue { private AtomicReference representation = new AtomicReference<>(); diff --git a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/data/CallArgumentDTO.java b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/data/CallArgumentDTO.java index 9ae671add..043e7eabc 100644 --- a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/data/CallArgumentDTO.java +++ b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/data/CallArgumentDTO.java @@ -20,7 +20,7 @@ import org.codehaus.jackson.annotate.JsonIgnoreProperties; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ @JsonIgnoreProperties(ignoreUnknown = true) public class CallArgumentDTO { diff --git a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/data/PropertyDescriptorDTO.java b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/data/PropertyDescriptorDTO.java index 6659dbb2d..882b100de 100644 --- a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/data/PropertyDescriptorDTO.java +++ b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/data/PropertyDescriptorDTO.java @@ -19,7 +19,7 @@ import org.codehaus.jackson.annotate.JsonIgnoreProperties; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ @JsonIgnoreProperties(ignoreUnknown = true) public class PropertyDescriptorDTO { diff --git a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/data/RemoteObjectDTO.java b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/data/RemoteObjectDTO.java index 6a41c9e0b..2fc7325f4 100644 --- a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/data/RemoteObjectDTO.java +++ b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/data/RemoteObjectDTO.java @@ -20,7 +20,7 @@ import org.codehaus.jackson.annotate.JsonIgnoreProperties; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ @JsonIgnoreProperties(ignoreUnknown = true) public class RemoteObjectDTO { diff --git a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/data/ScopeDTO.java b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/data/ScopeDTO.java index 4c2ab5a7f..8fb7c81ea 100644 --- a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/data/ScopeDTO.java +++ b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/data/ScopeDTO.java @@ -19,7 +19,7 @@ import org.codehaus.jackson.annotate.JsonIgnoreProperties; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ @JsonIgnoreProperties(ignoreUnknown = true) public class ScopeDTO { diff --git a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/messages/CallFunctionCommand.java b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/messages/CallFunctionCommand.java index 4d95a1be2..48093ffc2 100644 --- a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/messages/CallFunctionCommand.java +++ b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/messages/CallFunctionCommand.java @@ -20,7 +20,7 @@ import org.teavm.chromerdp.data.CallArgumentDTO; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ @JsonIgnoreProperties(ignoreUnknown = true) public class CallFunctionCommand { diff --git a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/messages/CallFunctionResponse.java b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/messages/CallFunctionResponse.java index 8da3c28c3..ac99cb54d 100644 --- a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/messages/CallFunctionResponse.java +++ b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/messages/CallFunctionResponse.java @@ -20,7 +20,7 @@ import org.teavm.chromerdp.data.RemoteObjectDTO; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ @JsonIgnoreProperties(ignoreUnknown = true) public class CallFunctionResponse { diff --git a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/messages/GetPropertiesCommand.java b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/messages/GetPropertiesCommand.java index 7234daab6..c5d762847 100644 --- a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/messages/GetPropertiesCommand.java +++ b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/messages/GetPropertiesCommand.java @@ -19,7 +19,7 @@ import org.codehaus.jackson.annotate.JsonIgnoreProperties; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ @JsonIgnoreProperties(ignoreUnknown = true) public class GetPropertiesCommand { diff --git a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/messages/GetPropertiesResponse.java b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/messages/GetPropertiesResponse.java index 85114d44b..41eeab4f8 100644 --- a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/messages/GetPropertiesResponse.java +++ b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/messages/GetPropertiesResponse.java @@ -20,7 +20,7 @@ import org.teavm.chromerdp.data.PropertyDescriptorDTO; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ @JsonIgnoreProperties(ignoreUnknown = true) public class GetPropertiesResponse { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/DeclaringClassMetadataGenerator.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/DeclaringClassMetadataGenerator.java index 30842e676..734eff272 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/DeclaringClassMetadataGenerator.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/DeclaringClassMetadataGenerator.java @@ -23,7 +23,7 @@ import org.teavm.platform.metadata.*; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class DeclaringClassMetadataGenerator implements ClassScopedMetadataGenerator { @Override diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/FirstDayOfWeekMetadataGenerator.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/FirstDayOfWeekMetadataGenerator.java index ff51e5ceb..69d1d2ed1 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/FirstDayOfWeekMetadataGenerator.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/FirstDayOfWeekMetadataGenerator.java @@ -20,7 +20,7 @@ import org.teavm.classlib.impl.unicode.CLDRReader; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class FirstDayOfWeekMetadataGenerator extends WeekMetadataGenerator { @Override diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/JavacSupport.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/JavacSupport.java index 833e13ecb..cefd3bd3a 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/JavacSupport.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/JavacSupport.java @@ -24,7 +24,7 @@ import org.teavm.model.instructions.InvokeInstruction; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class JavacSupport implements ClassHolderTransformer { @Override diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/MinimalDaysInFirstWeekMetadataGenerator.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/MinimalDaysInFirstWeekMetadataGenerator.java index 3ed52e5a1..7ede333e3 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/MinimalDaysInFirstWeekMetadataGenerator.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/MinimalDaysInFirstWeekMetadataGenerator.java @@ -20,7 +20,7 @@ import org.teavm.classlib.impl.unicode.CLDRReader; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class MinimalDaysInFirstWeekMetadataGenerator extends WeekMetadataGenerator { @Override diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/ServiceLoaderSupport.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/ServiceLoaderSupport.java index f019593a7..cb5c71f86 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/ServiceLoaderSupport.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/ServiceLoaderSupport.java @@ -32,7 +32,7 @@ import org.teavm.model.ValueType; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class ServiceLoaderSupport implements Generator, DependencyListener { private Set achievedClasses = new HashSet<>(); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/WeekMetadataGenerator.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/WeekMetadataGenerator.java index 0ecf0c00c..513745997 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/WeekMetadataGenerator.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/WeekMetadataGenerator.java @@ -22,7 +22,7 @@ import org.teavm.platform.metadata.*; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public abstract class WeekMetadataGenerator implements MetadataGenerator { @Override diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/report/JCLClass.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/report/JCLClass.java index 571d7ddff..a5e2e4371 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/report/JCLClass.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/report/JCLClass.java @@ -20,7 +20,7 @@ import java.util.List; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ class JCLClass { public final String name; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/report/JCLItem.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/report/JCLItem.java index 302f9cc28..9ea95ac7a 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/report/JCLItem.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/report/JCLItem.java @@ -17,7 +17,7 @@ package org.teavm.classlib.impl.report; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ class JCLItem { public final JCLItemType type; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/report/JCLItemType.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/report/JCLItemType.java index bea707379..6b09647b9 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/report/JCLItemType.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/report/JCLItemType.java @@ -17,7 +17,7 @@ package org.teavm.classlib.impl.report; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ enum JCLItemType { FIELD, diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/report/JCLPackage.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/report/JCLPackage.java index 39bcedba0..d91316291 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/report/JCLPackage.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/report/JCLPackage.java @@ -20,7 +20,7 @@ import java.util.List; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ class JCLPackage { public final String name; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/report/JCLStatus.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/report/JCLStatus.java index bf48b2d2c..c028654e3 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/report/JCLStatus.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/report/JCLStatus.java @@ -17,7 +17,7 @@ package org.teavm.classlib.impl.report; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ enum JCLStatus { FOUND, diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/AvailableLocalesMetadataGenerator.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/AvailableLocalesMetadataGenerator.java index 713cc88d7..b95ac2ac1 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/AvailableLocalesMetadataGenerator.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/AvailableLocalesMetadataGenerator.java @@ -20,7 +20,7 @@ import org.teavm.platform.metadata.*; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class AvailableLocalesMetadataGenerator implements MetadataGenerator { @Override diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRHelper.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRHelper.java index 9e50d7a61..b898f6100 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRHelper.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/CLDRHelper.java @@ -21,7 +21,7 @@ import org.teavm.platform.metadata.*; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class CLDRHelper { public static String getCode(String language, String country) { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/LikelySubtagsMetadataGenerator.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/LikelySubtagsMetadataGenerator.java index d4468d464..b03424746 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/LikelySubtagsMetadataGenerator.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/unicode/LikelySubtagsMetadataGenerator.java @@ -21,7 +21,7 @@ import org.teavm.platform.metadata.*; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class LikelySubtagsMetadataGenerator implements MetadataGenerator { @Override diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TDataInput.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TDataInput.java index 8210478e9..db6940984 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TDataInput.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TDataInput.java @@ -19,7 +19,7 @@ import org.teavm.classlib.java.lang.TString; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface TDataInput { void readFully(byte[] b) throws TIOException; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TDataInputStream.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TDataInputStream.java index 6a20a5677..830eea1b1 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TDataInputStream.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TDataInputStream.java @@ -19,7 +19,7 @@ import org.teavm.classlib.java.lang.*; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TDataInputStream extends TFilterInputStream implements TDataInput { byte[] buff; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TDataOutputStream.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TDataOutputStream.java index 2e771de0e..78fa7bcb0 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TDataOutputStream.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TDataOutputStream.java @@ -29,37 +29,16 @@ public class TDataOutputStream extends TFilterOutputStream implements TDataOutpu protected int written; byte buff[]; - /** - * Constructs a new {@code DataOutputStream} on the {@code OutputStream} - * {@code out}. Note that data written by this stream is not in a human - * readable form but can be reconstructed by using a {@link DataInputStream} - * on the resulting output. - * - * @param out - * the target stream for writing. - */ public TDataOutputStream(TOutputStream out) { super(out); buff = new byte[8]; } - /** - * Flushes this stream to ensure all pending data is sent out to the target - * stream. This implementation then also flushes the target stream. - * - * @throws IOException - * if an error occurs attempting to flush this stream. - */ @Override public void flush() throws TIOException { super.flush(); } - /** - * Returns the total number of bytes written to the target stream so far. - * - * @return the number of bytes written to the target stream. - */ public final int size() { if (written < 0) { written = TInteger.MAX_VALUE; @@ -67,23 +46,6 @@ public class TDataOutputStream extends TFilterOutputStream implements TDataOutpu return written; } - /** - * Writes {@code count} bytes from the byte array {@code buffer} starting at - * {@code offset} to the target stream. - * - * @param buffer - * the buffer to write to the target stream. - * @param offset - * the index of the first byte in {@code buffer} to write. - * @param count - * the number of bytes from the {@code buffer} to write. - * @throws IOException - * if an error occurs while writing to the target stream. - * @throws NullPointerException - * if {@code buffer} is {@code null}. - * @see DataInputStream#readFully(byte[]) - * @see DataInputStream#readFully(byte[], int, int) - */ @Override public void write(byte buffer[], int offset, int count) throws TIOException { if (buffer == null) { @@ -93,64 +55,24 @@ public class TDataOutputStream extends TFilterOutputStream implements TDataOutpu written += count; } - /** - * Writes a byte to the target stream. Only the least significant byte of - * the integer {@code oneByte} is written. - * - * @param oneByte - * the byte to write to the target stream. - * @throws IOException - * if an error occurs while writing to the target stream. - * @see DataInputStream#readByte() - */ @Override public void write(int oneByte) throws TIOException { out.write(oneByte); written++; } - /** - * Writes a boolean to the target stream. - * - * @param val - * the boolean value to write to the target stream. - * @throws IOException - * if an error occurs while writing to the target stream. - * @see DataInputStream#readBoolean() - */ @Override public final void writeBoolean(boolean val) throws TIOException { out.write(val ? 1 : 0); written++; } - /** - * Writes an 8-bit byte to the target stream. Only the least significant - * byte of the integer {@code val} is written. - * - * @param val - * the byte value to write to the target stream. - * @throws IOException - * if an error occurs while writing to the target stream. - * @see DataInputStream#readByte() - * @see DataInputStream#readUnsignedByte() - */ @Override public final void writeByte(int val) throws TIOException { out.write(val); written++; } - /** - * Writes the low order bytes from a string to the target stream. - * - * @param str - * the string containing the bytes to write to the target stream. - * @throws IOException - * if an error occurs while writing to the target stream. - * @see DataInputStream#readFully(byte[]) - * @see DataInputStream#readFully(byte[],int,int) - */ public final void writeBytes(TString str) throws TIOException { if (str.length() == 0) { return; @@ -163,17 +85,6 @@ public class TDataOutputStream extends TFilterOutputStream implements TDataOutpu written += bytes.length; } - /** - * Writes a 16-bit character to the target stream. Only the two lower bytes - * of the integer {@code val} are written, with the higher one written - * first. This corresponds to the Unicode value of {@code val}. - * - * @param val - * the character to write to the target stream - * @throws IOException - * if an error occurs while writing to the target stream. - * @see DataInputStream#readChar() - */ @Override public final void writeChar(int val) throws TIOException { buff[0] = (byte) (val >> 8); @@ -182,17 +93,6 @@ public class TDataOutputStream extends TFilterOutputStream implements TDataOutpu written += 2; } - /** - * Writes the 16-bit characters contained in {@code str} to the target - * stream. - * - * @param str - * the string that contains the characters to write to this - * stream. - * @throws IOException - * if an error occurs while writing to the target stream. - * @see DataInputStream#readChar() - */ @Override public final void writeChars(TString str) throws TIOException { byte newBytes[] = new byte[str.length() * 2]; @@ -205,46 +105,16 @@ public class TDataOutputStream extends TFilterOutputStream implements TDataOutpu written += newBytes.length; } - /** - * Writes a 64-bit double to the target stream. The resulting output is the - * eight bytes resulting from calling Double.doubleToLongBits(). - * - * @param val - * the double to write to the target stream. - * @throws IOException - * if an error occurs while writing to the target stream. - * @see DataInputStream#readDouble() - */ @Override public final void writeDouble(double val) throws TIOException { writeLong(TDouble.doubleToLongBits(val)); } - /** - * Writes a 32-bit float to the target stream. The resulting output is the - * four bytes resulting from calling Float.floatToIntBits(). - * - * @param val - * the float to write to the target stream. - * @throws IOException - * if an error occurs while writing to the target stream. - * @see DataInputStream#readFloat() - */ @Override public final void writeFloat(float val) throws TIOException { writeInt(TFloat.floatToIntBits(val)); } - /** - * Writes a 32-bit int to the target stream. The resulting output is the - * four bytes, highest order first, of {@code val}. - * - * @param val - * the int to write to the target stream. - * @throws IOException - * if an error occurs while writing to the target stream. - * @see DataInputStream#readInt() - */ @Override public final void writeInt(int val) throws TIOException { buff[0] = (byte) (val >> 24); @@ -255,16 +125,6 @@ public class TDataOutputStream extends TFilterOutputStream implements TDataOutpu written += 4; } - /** - * Writes a 64-bit long to the target stream. The resulting output is the - * eight bytes, highest order first, of {@code val}. - * - * @param val - * the long to write to the target stream. - * @throws IOException - * if an error occurs while writing to the target stream. - * @see DataInputStream#readLong() - */ @Override public final void writeLong(long val) throws TIOException { buff[0] = (byte) (val >> 56); @@ -292,18 +152,6 @@ public class TDataOutputStream extends TFilterOutputStream implements TDataOutpu return offset; } - /** - * Writes the specified 16-bit short to the target stream. Only the lower - * two bytes of the integer {@code val} are written, with the higher one - * written first. - * - * @param val - * the short to write to the target stream. - * @throws IOException - * if an error occurs while writing to the target stream. - * @see DataInputStream#readShort() - * @see DataInputStream#readUnsignedShort() - */ @Override public final void writeShort(int val) throws TIOException { buff[0] = (byte) (val >> 8); @@ -319,19 +167,6 @@ public class TDataOutputStream extends TFilterOutputStream implements TDataOutpu return offset; } - /** - * Writes the specified encoded in {@link DataInput modified UTF-8} to this - * stream. - * - * @param str - * the string to write to the target stream encoded in - * {@link DataInput modified UTF-8}. - * @throws IOException - * if an error occurs while writing to the target stream. - * @throws UTFDataFormatException - * if the encoded string is longer than 65535 bytes. - * @see DataInputStream#readUTF() - */ @Override public final void writeUTF(TString str) throws TIOException { long utfCount = countUTFBytes(str); @@ -377,5 +212,4 @@ public class TDataOutputStream extends TFilterOutputStream implements TDataOutpu } return offset; } - } diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TPushbackInputStream.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TPushbackInputStream.java index 1eca3c513..6b3ca3c3f 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TPushbackInputStream.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TPushbackInputStream.java @@ -20,7 +20,7 @@ import org.teavm.classlib.java.lang.TString; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TPushbackInputStream extends TFilterInputStream { protected byte[] buf; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TUTFDataFormatException.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TUTFDataFormatException.java index db05a0e9e..01510adbe 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TUTFDataFormatException.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TUTFDataFormatException.java @@ -19,7 +19,7 @@ import org.teavm.classlib.java.lang.TString; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TUTFDataFormatException extends TIOException { private static final long serialVersionUID = -6383472574962319733L; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/LongNativeGenerator.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/LongNativeGenerator.java index e82de0450..2af7de222 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/LongNativeGenerator.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/LongNativeGenerator.java @@ -23,7 +23,7 @@ import org.teavm.model.MethodReference; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class LongNativeGenerator implements Generator { @Override diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TArrayIndexOutOfBoundsException.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TArrayIndexOutOfBoundsException.java index 8df905149..0fae4bcd6 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TArrayIndexOutOfBoundsException.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TArrayIndexOutOfBoundsException.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.lang; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TArrayIndexOutOfBoundsException extends TIndexOutOfBoundsException { private static final long serialVersionUID = 5221353436321708950L; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TArrayStoreException.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TArrayStoreException.java index 130b5405c..ad850656a 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TArrayStoreException.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TArrayStoreException.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.lang; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TArrayStoreException extends TRuntimeException { private static final long serialVersionUID = 3911921304974631232L; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java index 642a28069..c040c4de9 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java @@ -23,7 +23,7 @@ import org.teavm.platform.metadata.ClassScopedMetadataProvider; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TClass extends TObject { TString name; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TClassLoader.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TClassLoader.java index 47e0ed4a8..f35b1266a 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TClassLoader.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TClassLoader.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.lang; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public abstract class TClassLoader extends TObject { private TClassLoader parent; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TClassNotFoundException.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TClassNotFoundException.java index 7b5ee6187..f5527af50 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TClassNotFoundException.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TClassNotFoundException.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.lang; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TClassNotFoundException extends TReflectiveOperationException { private static final long serialVersionUID = -1162632869775788325L; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TCloneNotSupportedException.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TCloneNotSupportedException.java index 79631d0ff..01e9c8c77 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TCloneNotSupportedException.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TCloneNotSupportedException.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.lang; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TCloneNotSupportedException extends TException { private static final long serialVersionUID = 4908200987785128012L; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TCloneable.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TCloneable.java index 649a82295..64e22214e 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TCloneable.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TCloneable.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.lang; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface TCloneable { } diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TEnum.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TEnum.java index cc02cc5d7..c1d462131 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TEnum.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TEnum.java @@ -20,7 +20,7 @@ import org.teavm.javascript.spi.Rename; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public abstract class TEnum> extends TObject implements TComparable, TSerializable { private TString name; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIllegalAccessException.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIllegalAccessException.java index b8d614d3a..7145e8904 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIllegalAccessException.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIllegalAccessException.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.lang; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TIllegalAccessException extends ReflectiveOperationException { private static final long serialVersionUID = 8240407889170934565L; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIllegalMonitorStateException.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIllegalMonitorStateException.java index c77285633..2a3f68058 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIllegalMonitorStateException.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIllegalMonitorStateException.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.lang; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TIllegalMonitorStateException extends TRuntimeException { private static final long serialVersionUID = 7694307746228488658L; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIncompatibleClassChangeError.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIncompatibleClassChangeError.java index fdc9255bd..b975f71c6 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIncompatibleClassChangeError.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIncompatibleClassChangeError.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.lang; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TIncompatibleClassChangeError extends TLinkageError { private static final long serialVersionUID = 366119408566298082L; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TInstantiationException.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TInstantiationException.java index 3c2568808..055858984 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TInstantiationException.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TInstantiationException.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.lang; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TInstantiationException extends ReflectiveOperationException { private static final long serialVersionUID = 8771605296206833516L; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TInterruptedException.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TInterruptedException.java index fa5a2dac0..0cb4cd03b 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TInterruptedException.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TInterruptedException.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.lang; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TInterruptedException extends Exception { private static final long serialVersionUID = -7832805114281254695L; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIterable.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIterable.java index 03f9abc12..473ac0758 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIterable.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIterable.java @@ -19,7 +19,7 @@ import org.teavm.classlib.java.util.TIterator; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface TIterable { TIterator iterator(); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TLinkageError.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TLinkageError.java index 6fac68f97..8dd9e51ab 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TLinkageError.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TLinkageError.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.lang; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TLinkageError extends TError { private static final long serialVersionUID = 9176544705010852435L; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TLong.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TLong.java index 81d57c910..b5ae62169 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TLong.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TLong.java @@ -19,7 +19,7 @@ import org.teavm.javascript.spi.GeneratedBy; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TLong extends TNumber implements TComparable { public static final long MIN_VALUE = -0x8000000000000000L; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TNegativeArraySizeException.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TNegativeArraySizeException.java index 1480fcd92..f39a90bb8 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TNegativeArraySizeException.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TNegativeArraySizeException.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.lang; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TNegativeArraySizeException extends TRuntimeException { private static final long serialVersionUID = 4838944281468611671L; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TNoSuchFieldError.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TNoSuchFieldError.java index b8db670d8..0282d1f45 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TNoSuchFieldError.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TNoSuchFieldError.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.lang; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TNoSuchFieldError extends TIncompatibleClassChangeError { private static final long serialVersionUID = 7907885242472547035L; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TNoSuchMethodError.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TNoSuchMethodError.java index c620191ca..486f01975 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TNoSuchMethodError.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TNoSuchMethodError.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.lang; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TNoSuchMethodError extends TIncompatibleClassChangeError { private static final long serialVersionUID = 7907885242472547035L; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java index 0ee0a8189..3e6bfb01e 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java @@ -27,7 +27,7 @@ import org.teavm.platform.async.AsyncCallback; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ @Superclass("") public class TObject { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TReadable.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TReadable.java index 21920afd8..afc97257d 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TReadable.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TReadable.java @@ -20,7 +20,7 @@ import org.teavm.classlib.java.nio.TCharBuffer; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface TReadable { int read(TCharBuffer cb) throws TIOException; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TReflectiveOperationException.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TReflectiveOperationException.java index 25bff344e..62d4ffb09 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TReflectiveOperationException.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TReflectiveOperationException.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.lang; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TReflectiveOperationException extends TException { private static final long serialVersionUID = -455785869284249992L; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TStrictMath.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TStrictMath.java index c2060df50..6f564147a 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TStrictMath.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TStrictMath.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.lang; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public final class TStrictMath extends TObject { public static double E = 2.71828182845904523536; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TString.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TString.java index a5ba75b2c..dd2daa1a1 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TString.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TString.java @@ -26,7 +26,7 @@ import org.teavm.classlib.java.util.regex.TPattern; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TString extends TObject implements TSerializable, TComparable, TCharSequence { public static final TComparator CASE_INSENSITIVE_ORDER = new TComparator() { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TSystemClassLoader.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TSystemClassLoader.java index da6e8ffea..c3689b9ba 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TSystemClassLoader.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TSystemClassLoader.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.lang; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ class TSystemClassLoader extends TClassLoader { TSystemClassLoader() { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThrowable.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThrowable.java index 0d9b5ac21..6471e8440 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThrowable.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThrowable.java @@ -23,7 +23,7 @@ import org.teavm.javascript.spi.Superclass; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ @Superclass("java.lang.Object") public class TThrowable extends RuntimeException { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TVoid.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TVoid.java index 72adf6726..7d2b75c31 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TVoid.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TVoid.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.lang; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public final class TVoid extends TObject { public static final TClass TYPE = TClass.voidClass(); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/math/TDivision.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/math/TDivision.java index 240e28395..5662b4e6d 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/math/TDivision.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/math/TDivision.java @@ -874,8 +874,8 @@ class TDivision { /** * Performs the final reduction of the Montgomery algorithm. * - * @see monPro(BigInteger, BigInteger, BigInteger, long) - * @see monSquare(BigInteger, BigInteger, long) + * @see #monPro(TBigInteger, TBigInteger, TBigInteger, long) + * @see #monSquare(TBigInteger, TBigInteger, long) */ static TBigInteger finalSubtraction(int res[], TBigInteger modulus) { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/math/TElementary.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/math/TElementary.java index 544a8cde7..2b99855c1 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/math/TElementary.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/math/TElementary.java @@ -348,8 +348,7 @@ class TElementary { /** * Same as - * - * @link #inplaceSubtract(BigInteger, BigInteger), but without the + * {@link #inplaceSubtract(TBigInteger, TBigInteger)}, but without the * restriction of non-positive values * @param op1 * should have enough space to save the result diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TCharBuffer.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TCharBuffer.java index db34ccb86..0a7bb69f7 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TCharBuffer.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TCharBuffer.java @@ -20,7 +20,7 @@ import org.teavm.classlib.java.lang.TReadable; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public abstract class TCharBuffer extends TBuffer implements Comparable, Appendable, CharSequence, TReadable { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TCharBufferImpl.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TCharBufferImpl.java index e3033633b..a4acd5290 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TCharBufferImpl.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TCharBufferImpl.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.nio; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ abstract class TCharBufferImpl extends TCharBuffer { public TCharBufferImpl(int capacity, int position, int limit) { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TCharBufferOverArray.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TCharBufferOverArray.java index e2c18e7a9..516ac2494 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TCharBufferOverArray.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TCharBufferOverArray.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.nio; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ class TCharBufferOverArray extends TCharBufferImpl { boolean readOnly; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TCharBufferOverByteBuffer.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TCharBufferOverByteBuffer.java index aa48b251f..5717757eb 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TCharBufferOverByteBuffer.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TCharBufferOverByteBuffer.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.nio; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ abstract class TCharBufferOverByteBuffer extends TCharBufferImpl { TByteBufferImpl byteByffer; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TCharBufferOverByteBufferBigEndian.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TCharBufferOverByteBufferBigEndian.java index b0ea539f5..1485f58e2 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TCharBufferOverByteBufferBigEndian.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TCharBufferOverByteBufferBigEndian.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.nio; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ class TCharBufferOverByteBufferBigEndian extends TCharBufferOverByteBuffer { public TCharBufferOverByteBufferBigEndian(int start, int capacity, TByteBufferImpl byteBuffer, int position, diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TCharBufferOverByteBufferLittleEndian.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TCharBufferOverByteBufferLittleEndian.java index 0d18355d9..967f372cd 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TCharBufferOverByteBufferLittleEndian.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TCharBufferOverByteBufferLittleEndian.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.nio; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ class TCharBufferOverByteBufferLittleEndian extends TCharBufferOverByteBuffer { public TCharBufferOverByteBufferLittleEndian(int start, int capacity, TByteBufferImpl byteBuffer, int position, diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TDoubleBuffer.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TDoubleBuffer.java index 9a22a30df..776f5d55a 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TDoubleBuffer.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TDoubleBuffer.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.nio; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public abstract class TDoubleBuffer extends TBuffer implements Comparable { TDoubleBuffer(int capacity, int position, int limit) { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TDoubleBufferImpl.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TDoubleBufferImpl.java index afa929e65..42d0364f4 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TDoubleBufferImpl.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TDoubleBufferImpl.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.nio; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ abstract class TDoubleBufferImpl extends TDoubleBuffer { public TDoubleBufferImpl(int capacity, int position, int limit) { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TDoubleBufferOverArray.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TDoubleBufferOverArray.java index 95acba240..ac3504eff 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TDoubleBufferOverArray.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TDoubleBufferOverArray.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.nio; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ class TDoubleBufferOverArray extends TDoubleBufferImpl { boolean readOnly; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TDoubleBufferOverByteBuffer.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TDoubleBufferOverByteBuffer.java index a9d997c56..a6bc91ecc 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TDoubleBufferOverByteBuffer.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TDoubleBufferOverByteBuffer.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.nio; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ class TDoubleBufferOverByteBuffer extends TDoubleBufferImpl { private TByteBufferImpl byteByffer; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TFloatBuffer.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TFloatBuffer.java index f00421be4..938f8cea6 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TFloatBuffer.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TFloatBuffer.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.nio; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public abstract class TFloatBuffer extends TBuffer implements Comparable { TFloatBuffer(int capacity, int position, int limit) { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TFloatBufferImpl.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TFloatBufferImpl.java index 91e84c874..e4741d3b5 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TFloatBufferImpl.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TFloatBufferImpl.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.nio; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ abstract class TFloatBufferImpl extends TFloatBuffer { public TFloatBufferImpl(int capacity, int position, int limit) { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TFloatBufferOverArray.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TFloatBufferOverArray.java index dc4e79bab..c29bf005d 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TFloatBufferOverArray.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TFloatBufferOverArray.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.nio; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ class TFloatBufferOverArray extends TFloatBufferImpl { boolean readOnly; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TFloatBufferOverByteBuffer.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TFloatBufferOverByteBuffer.java index 8815fd7e9..2532e2cfe 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TFloatBufferOverByteBuffer.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TFloatBufferOverByteBuffer.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.nio; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ abstract class TFloatBufferOverByteBuffer extends TFloatBufferImpl { TByteBufferImpl byteByffer; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TFloatBufferOverByteBufferBigEndian.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TFloatBufferOverByteBufferBigEndian.java index 5e66eefd5..35842e711 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TFloatBufferOverByteBufferBigEndian.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TFloatBufferOverByteBufferBigEndian.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.nio; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ class TFloatBufferOverByteBufferBigEndian extends TFloatBufferOverByteBuffer { public TFloatBufferOverByteBufferBigEndian(int start, int capacity, TByteBufferImpl byteBuffer, int position, diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TFloatBufferOverByteBufferLittleEndian.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TFloatBufferOverByteBufferLittleEndian.java index cee658002..e098ef69b 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TFloatBufferOverByteBufferLittleEndian.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TFloatBufferOverByteBufferLittleEndian.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.nio; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ class TFloatBufferOverByteBufferLittleEndian extends TFloatBufferOverByteBuffer { public TFloatBufferOverByteBufferLittleEndian(int start, int capacity, TByteBufferImpl byteBuffer, int position, diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TIntBuffer.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TIntBuffer.java index 3dd6b6620..a43bca24b 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TIntBuffer.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TIntBuffer.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.nio; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public abstract class TIntBuffer extends TBuffer implements Comparable { TIntBuffer(int capacity, int position, int limit) { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TIntBufferImpl.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TIntBufferImpl.java index 602383dfe..58671c7df 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TIntBufferImpl.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TIntBufferImpl.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.nio; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ abstract class TIntBufferImpl extends TIntBuffer { public TIntBufferImpl(int capacity, int position, int limit) { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TIntBufferOverArray.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TIntBufferOverArray.java index b839ec3c5..1cd262cbb 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TIntBufferOverArray.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TIntBufferOverArray.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.nio; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ class TIntBufferOverArray extends TIntBufferImpl { boolean readOnly; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TIntBufferOverByteBuffer.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TIntBufferOverByteBuffer.java index 25e0c787b..ba584892a 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TIntBufferOverByteBuffer.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TIntBufferOverByteBuffer.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.nio; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ abstract class TIntBufferOverByteBuffer extends TIntBufferImpl { TByteBufferImpl byteByffer; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TIntBufferOverByteBufferBigEndian.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TIntBufferOverByteBufferBigEndian.java index 56943f0e1..849d49129 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TIntBufferOverByteBufferBigEndian.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TIntBufferOverByteBufferBigEndian.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.nio; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ class TIntBufferOverByteBufferBigEndian extends TIntBufferOverByteBuffer { public TIntBufferOverByteBufferBigEndian(int start, int capacity, TByteBufferImpl byteBuffer, int position, diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TIntBufferOverByteBufferLittleEndian.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TIntBufferOverByteBufferLittleEndian.java index 618dab9d5..6515290f2 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TIntBufferOverByteBufferLittleEndian.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TIntBufferOverByteBufferLittleEndian.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.nio; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ class TIntBufferOverByteBufferLittleEndian extends TIntBufferOverByteBuffer { public TIntBufferOverByteBufferLittleEndian(int start, int capacity, TByteBufferImpl byteBuffer, int position, diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TLongBuffer.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TLongBuffer.java index 6c62a340a..f22ce0609 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TLongBuffer.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TLongBuffer.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.nio; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public abstract class TLongBuffer extends TBuffer implements Comparable { TLongBuffer(int capacity, int position, int limit) { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TLongBufferImpl.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TLongBufferImpl.java index 614c11bb6..9d494e983 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TLongBufferImpl.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TLongBufferImpl.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.nio; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ abstract class TLongBufferImpl extends TLongBuffer { public TLongBufferImpl(int capacity, int position, int limit) { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TLongBufferOverArray.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TLongBufferOverArray.java index 1de3ec779..2fcc8951e 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TLongBufferOverArray.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TLongBufferOverArray.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.nio; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ class TLongBufferOverArray extends TLongBufferImpl { boolean readOnly; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TLongBufferOverByteBuffer.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TLongBufferOverByteBuffer.java index 7fb4d3efb..4a7c08249 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TLongBufferOverByteBuffer.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TLongBufferOverByteBuffer.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.nio; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ abstract class TLongBufferOverByteBuffer extends TLongBufferImpl { TByteBufferImpl byteByffer; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TLongBufferOverByteBufferBigEndian.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TLongBufferOverByteBufferBigEndian.java index 1a9df0517..f75537252 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TLongBufferOverByteBufferBigEndian.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TLongBufferOverByteBufferBigEndian.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.nio; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ class TLongBufferOverByteBufferBigEndian extends TLongBufferOverByteBuffer { public TLongBufferOverByteBufferBigEndian(int start, int capacity, TByteBufferImpl byteBuffer, int position, diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TLongBufferOverByteBufferLittleEndian.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TLongBufferOverByteBufferLittleEndian.java index 50d3329e1..a09324bf4 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TLongBufferOverByteBufferLittleEndian.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TLongBufferOverByteBufferLittleEndian.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.nio; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ class TLongBufferOverByteBufferLittleEndian extends TLongBufferOverByteBuffer { public TLongBufferOverByteBufferLittleEndian(int start, int capacity, TByteBufferImpl byteBuffer, int position, diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TShortBuffer.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TShortBuffer.java index de5c4224d..bfd22d4c8 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TShortBuffer.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TShortBuffer.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.nio; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public abstract class TShortBuffer extends TBuffer implements Comparable { TShortBuffer(int capacity, int position, int limit) { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TShortBufferImpl.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TShortBufferImpl.java index e58c18d22..6fba0d5e1 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TShortBufferImpl.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TShortBufferImpl.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.nio; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ abstract class TShortBufferImpl extends TShortBuffer { public TShortBufferImpl(int capacity, int position, int limit) { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TShortBufferOverArray.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TShortBufferOverArray.java index f166f1baf..c55ac5578 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TShortBufferOverArray.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TShortBufferOverArray.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.nio; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ class TShortBufferOverArray extends TShortBufferImpl { boolean readOnly; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TShortBufferOverByteBuffer.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TShortBufferOverByteBuffer.java index 9433bbf16..0903899ef 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TShortBufferOverByteBuffer.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TShortBufferOverByteBuffer.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.nio; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ abstract class TShortBufferOverByteBuffer extends TShortBufferImpl { TByteBufferImpl byteByffer; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TShortBufferOverByteBufferBigEndian.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TShortBufferOverByteBufferBigEndian.java index 2130fd554..ad899e940 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TShortBufferOverByteBufferBigEndian.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TShortBufferOverByteBufferBigEndian.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.nio; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ class TShortBufferOverByteBufferBigEndian extends TShortBufferOverByteBuffer { public TShortBufferOverByteBufferBigEndian(int start, int capacity, TByteBufferImpl byteBuffer, int position, diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TShortBufferOverByteBufferLittleEndian.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TShortBufferOverByteBufferLittleEndian.java index 771723680..63521e4e4 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TShortBufferOverByteBufferLittleEndian.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/nio/TShortBufferOverByteBufferLittleEndian.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.nio; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ class TShortBufferOverByteBufferLittleEndian extends TShortBufferOverByteBuffer { public TShortBufferOverByteBufferLittleEndian(int start, int capacity, TByteBufferImpl byteBuffer, int position, diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/DateNativeGenerator.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/DateNativeGenerator.java index 7b49f1b21..b8d5e4e7b 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/DateNativeGenerator.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/DateNativeGenerator.java @@ -27,7 +27,7 @@ import org.teavm.model.MethodReference; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class DateNativeGenerator implements Generator, DependencyPlugin { @Override diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/RandomNativeGenerator.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/RandomNativeGenerator.java index 4fc673db8..b5942811b 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/RandomNativeGenerator.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/RandomNativeGenerator.java @@ -23,7 +23,7 @@ import org.teavm.model.MethodReference; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class RandomNativeGenerator implements Generator { @Override diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractCollection.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractCollection.java index ea07cea09..6e1a2d3bb 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractCollection.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractCollection.java @@ -21,7 +21,7 @@ import org.teavm.classlib.java.lang.TUnsupportedOperationException; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public abstract class TAbstractCollection extends TObject implements TCollection { protected TAbstractCollection() { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractList.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractList.java index c7b2b4459..54951b850 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractList.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractList.java @@ -20,7 +20,7 @@ import org.teavm.javascript.spi.Rename; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public abstract class TAbstractList extends TAbstractCollection implements TList { protected transient int modCount; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractMap.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractMap.java index 21b17bd2f..731f884cc 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractMap.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractMap.java @@ -22,7 +22,7 @@ import org.teavm.classlib.java.lang.TUnsupportedOperationException; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public abstract class TAbstractMap extends TObject implements TMap { public static class SimpleEntry implements TMap.Entry, TSerializable { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractSet.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractSet.java index 9cced5978..da20f4512 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractSet.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractSet.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.util; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public abstract class TAbstractSet extends TAbstractCollection implements TSet { public TAbstractSet() { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TArrayList.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TArrayList.java index 43a998c44..1e4a9ad99 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TArrayList.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TArrayList.java @@ -22,7 +22,7 @@ import org.teavm.javascript.spi.Rename; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TArrayList extends TAbstractList implements TCloneable, TSerializable { private E[] array; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TBitSet.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TBitSet.java index bafc551b2..358ccffd9 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TBitSet.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TBitSet.java @@ -21,7 +21,7 @@ import org.teavm.javascript.spi.Rename; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TBitSet extends TObject implements TCloneable, TSerializable { private int[] data; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TCollection.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TCollection.java index 29739c058..e604d722d 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TCollection.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TCollection.java @@ -19,7 +19,7 @@ import org.teavm.classlib.java.lang.TIterable; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface TCollection extends TIterable { int size(); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TComparator.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TComparator.java index 9cd08220f..f068c683c 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TComparator.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TComparator.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.util; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface TComparator { int compare(T o1, T o2); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TConcurrentModificationException.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TConcurrentModificationException.java index 4499dcd2c..3facbca6a 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TConcurrentModificationException.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TConcurrentModificationException.java @@ -21,7 +21,7 @@ import org.teavm.classlib.java.lang.TThrowable; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TConcurrentModificationException extends TRuntimeException { private static final long serialVersionUID = -2871226388713811335L; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TDate.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TDate.java index 5d14d375b..2975f8ea5 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TDate.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TDate.java @@ -22,7 +22,7 @@ import org.teavm.javascript.spi.GeneratedBy; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TDate implements TComparable { private long value; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TDeque.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TDeque.java index 3672291ab..9598b0507 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TDeque.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TDeque.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.util; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface TDeque extends TQueue { void addFirst(E e); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TEnumeration.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TEnumeration.java index 62c2d7216..89eecfebf 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TEnumeration.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TEnumeration.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.util; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface TEnumeration { boolean hasMoreElements(); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TIterator.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TIterator.java index 124844c8d..d06f53c14 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TIterator.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TIterator.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.util; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface TIterator { boolean hasNext(); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TList.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TList.java index 2abc4789b..ca915c89e 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TList.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TList.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.util; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface TList extends TCollection { boolean addAll(int index, TCollection c); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TListIterator.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TListIterator.java index 90d2f0531..0ae00d745 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TListIterator.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TListIterator.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.util; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface TListIterator extends TIterator { boolean hasPrevious(); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TMap.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TMap.java index a49464bc9..c1c08f945 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TMap.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TMap.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.util; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface TMap { public static interface Entry { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TNoSuchElementException.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TNoSuchElementException.java index a51a92655..b9d13d7d8 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TNoSuchElementException.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TNoSuchElementException.java @@ -20,7 +20,7 @@ import org.teavm.classlib.java.lang.TString; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TNoSuchElementException extends TRuntimeException { private static final long serialVersionUID = -4890604137042866919L; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TObjects.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TObjects.java index 609cbb1e6..5f3114ecf 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TObjects.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TObjects.java @@ -19,7 +19,7 @@ import org.teavm.classlib.java.lang.TObject; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public final class TObjects extends TObject { public static boolean equals(Object a, Object b) { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TQueue.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TQueue.java index 6260d1fea..594183787 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TQueue.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TQueue.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.util; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface TQueue extends TCollection { boolean offer(E e); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TRandom.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TRandom.java index 864e1270e..f48ff258b 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TRandom.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TRandom.java @@ -22,7 +22,7 @@ import org.teavm.javascript.spi.GeneratedBy; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TRandom extends TObject implements TSerializable { public TRandom() { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TRandomAccess.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TRandomAccess.java index ad1165efb..dbbf3291f 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TRandomAccess.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TRandomAccess.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.util; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface TRandomAccess { } diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TServiceLoader.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TServiceLoader.java index 035066dde..e4df072af 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TServiceLoader.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TServiceLoader.java @@ -20,7 +20,7 @@ import org.teavm.platform.PlatformClass; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public final class TServiceLoader extends TObject implements TIterable { private Object[] services; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TSet.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TSet.java index de75dde26..396d4b0d9 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TSet.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TSet.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.util; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface TSet extends TCollection { } diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TSortedSet.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TSortedSet.java index 499709161..3a58e5c90 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TSortedSet.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TSortedSet.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.util; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface TSortedSet extends TSet { TComparator comparator(); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/concurrent/TCallable.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/concurrent/TCallable.java index c3f0615ae..bbbea5f72 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/concurrent/TCallable.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/concurrent/TCallable.java @@ -20,7 +20,7 @@ import org.teavm.classlib.java.lang.TObject; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface TCallable { V call() throws TException; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/logging/LoggerNativeGenerator.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/logging/LoggerNativeGenerator.java index 7657adfac..83ebbae5d 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/logging/LoggerNativeGenerator.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/logging/LoggerNativeGenerator.java @@ -23,7 +23,7 @@ import org.teavm.model.MethodReference; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class LoggerNativeGenerator implements Generator { @Override diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/logging/TLevel.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/logging/TLevel.java index 062d943da..e11792e11 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/logging/TLevel.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/logging/TLevel.java @@ -21,7 +21,7 @@ import org.teavm.classlib.java.lang.TObject; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TLevel extends TObject implements TSerializable { public static final TLevel OFF = new TLevel("OFF", TInteger.MAX_VALUE); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/logging/TLogRecord.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/logging/TLogRecord.java index 6563b0053..230831266 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/logging/TLogRecord.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/logging/TLogRecord.java @@ -20,7 +20,7 @@ import org.teavm.classlib.java.lang.*; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TLogRecord extends TObject implements TSerializable { private static long sequenceNumberGenerator; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/logging/TLogger.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/logging/TLogger.java index 1f42153a8..73e7224a6 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/logging/TLogger.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/logging/TLogger.java @@ -22,7 +22,7 @@ import org.teavm.javascript.spi.GeneratedBy; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TLogger { public static final TString GLOBAL_LOGGER_NAME = TString.wrap("global"); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TAbstractCharClass.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TAbstractCharClass.java index eb5fced0f..952712f74 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TAbstractCharClass.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TAbstractCharClass.java @@ -156,18 +156,6 @@ abstract class TAbstractCharClass extends TSpecialToken { return false; } - /** - * Sets this CharClass to negative form, i.e. if they will add some - * characters and after that set this class to negative it will accept all - * the characters except previously set ones. - * - * Although this method will not alternate all the already set characters, - * just overall meaning of the class. - * - * @see #contains(int) - * @see #intersect(TCharClass) - * @see #union(TCharClass) - */ public TAbstractCharClass setNegative(boolean value) { if (alt ^ value) { alt = !alt; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TAbstractSet.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TAbstractSet.java index 5c1c5841f..7f3c3c934 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TAbstractSet.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TAbstractSet.java @@ -150,7 +150,6 @@ abstract class TAbstractSet { * method will return false; * * @param matchResult - * @return */ public abstract boolean hasConsumed(TMatchResultImpl matchResult); @@ -210,14 +209,6 @@ abstract class TAbstractSet { return true; } - /** - * This method is used for replacement backreferenced sets. - * - * @param prev - * - node who references to this node - * @return null if current node need not to be replaced JointSet which is - * replacement of current node otherwise - */ public TJointSet processBackRefReplacement() { return null; } diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TBackReferencedSingleSet.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TBackReferencedSingleSet.java index 083c73074..7296d8c02 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TBackReferencedSingleSet.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TBackReferencedSingleSet.java @@ -108,12 +108,6 @@ class TBackReferencedSingleSet extends TSingleSet { return res; } - /** - * This method is used for replacement backreferenced sets. - * - * @param prev - * - node who references to this node - */ @Override public TJointSet processBackRefReplacement() { return null; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TDecomposedCharSet.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TDecomposedCharSet.java index 527101722..9405485dd 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TDecomposedCharSet.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TDecomposedCharSet.java @@ -185,17 +185,6 @@ class TDecomposedCharSet extends TJointSet { return "decomposed char:" + getDecomposedChar(); //$NON-NLS-1$ } - /** - * Reads Unicode codepoint from input. - * - * @param strIndex - * - index to read codepoint at - * @param testString - * - input - * @param matchResult - * - auxiliary object - * @return codepoint at given strIndex at testString and - */ public int codePointAt(int strIndex, CharSequence testString, int rightBound) { /* diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/zip/TDataFormatException.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/zip/TDataFormatException.java index c1ee24c95..ed7b4e18f 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/zip/TDataFormatException.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/zip/TDataFormatException.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.util.zip; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TDataFormatException extends Exception { private static final long serialVersionUID = 7856637411580418624L; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/zip/TDeflaterOutputStream.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/zip/TDeflaterOutputStream.java index b1f1e85b6..0828e91fa 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/zip/TDeflaterOutputStream.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/zip/TDeflaterOutputStream.java @@ -22,7 +22,7 @@ import java.io.OutputStream; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TDeflaterOutputStream extends FilterOutputStream { public TDeflaterOutputStream(OutputStream out) throws IOException { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/zip/TGZIPInputStream.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/zip/TGZIPInputStream.java index 603e3262a..594c240db 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/zip/TGZIPInputStream.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/zip/TGZIPInputStream.java @@ -21,7 +21,7 @@ import java.io.InputStream; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TGZIPInputStream extends TInflaterInputStream { public TGZIPInputStream(InputStream in, int size) throws IOException { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/zip/TGZIPOutputStream.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/zip/TGZIPOutputStream.java index 42d3a311c..1b9a43ce8 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/zip/TGZIPOutputStream.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/zip/TGZIPOutputStream.java @@ -21,7 +21,7 @@ import java.io.OutputStream; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TGZIPOutputStream extends TDeflaterOutputStream { public TGZIPOutputStream(OutputStream out, int size, boolean syncFlush) throws IOException { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/zip/TInflaterInputStream.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/zip/TInflaterInputStream.java index 02287260a..3d7f5b417 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/zip/TInflaterInputStream.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/zip/TInflaterInputStream.java @@ -22,7 +22,7 @@ import java.io.InputStream; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TInflaterInputStream extends FilterInputStream { public TInflaterInputStream(InputStream in) throws IOException { diff --git a/teavm-cli/src/main/java/org/teavm/cli/ConsoleTeaVMToolLog.java b/teavm-cli/src/main/java/org/teavm/cli/ConsoleTeaVMToolLog.java index 2105333ea..e82c5acea 100644 --- a/teavm-cli/src/main/java/org/teavm/cli/ConsoleTeaVMToolLog.java +++ b/teavm-cli/src/main/java/org/teavm/cli/ConsoleTeaVMToolLog.java @@ -19,7 +19,7 @@ import org.teavm.tooling.TeaVMToolLog; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ class ConsoleTeaVMToolLog implements TeaVMToolLog { @Override diff --git a/teavm-cli/src/main/java/org/teavm/cli/TeaVMRunner.java b/teavm-cli/src/main/java/org/teavm/cli/TeaVMRunner.java index cf4d71d9a..9ce31c34e 100644 --- a/teavm-cli/src/main/java/org/teavm/cli/TeaVMRunner.java +++ b/teavm-cli/src/main/java/org/teavm/cli/TeaVMRunner.java @@ -22,7 +22,7 @@ import org.teavm.tooling.TeaVMTool; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public final class TeaVMRunner { private TeaVMRunner() { diff --git a/teavm-core/src/main/java/org/teavm/cache/DiskCachedClassHolderSource.java b/teavm-core/src/main/java/org/teavm/cache/DiskCachedClassHolderSource.java index 800b20a12..4f8ec49f8 100644 --- a/teavm-core/src/main/java/org/teavm/cache/DiskCachedClassHolderSource.java +++ b/teavm-core/src/main/java/org/teavm/cache/DiskCachedClassHolderSource.java @@ -22,7 +22,7 @@ import org.teavm.parsing.ClassDateProvider; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class DiskCachedClassHolderSource implements ClassHolderSource { private static AccessLevel[] accessLevels = AccessLevel.values(); diff --git a/teavm-core/src/main/java/org/teavm/common/CachedMapper.java b/teavm-core/src/main/java/org/teavm/common/CachedMapper.java index addf3a64e..2fdee5642 100644 --- a/teavm-core/src/main/java/org/teavm/common/CachedMapper.java +++ b/teavm-core/src/main/java/org/teavm/common/CachedMapper.java @@ -19,7 +19,7 @@ import java.util.*; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class CachedMapper implements Mapper { private Mapper innerMapper; diff --git a/teavm-core/src/main/java/org/teavm/common/DJGraph.java b/teavm-core/src/main/java/org/teavm/common/DJGraph.java index a55ef97ef..adc9754cb 100644 --- a/teavm-core/src/main/java/org/teavm/common/DJGraph.java +++ b/teavm-core/src/main/java/org/teavm/common/DJGraph.java @@ -24,7 +24,7 @@ import java.util.List; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class DJGraph { private DominatorTree domTree; diff --git a/teavm-core/src/main/java/org/teavm/common/GraphSplittingBackend.java b/teavm-core/src/main/java/org/teavm/common/GraphSplittingBackend.java index 5dd859ff3..791764e76 100644 --- a/teavm-core/src/main/java/org/teavm/common/GraphSplittingBackend.java +++ b/teavm-core/src/main/java/org/teavm/common/GraphSplittingBackend.java @@ -17,7 +17,7 @@ package org.teavm.common; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface GraphSplittingBackend { int[] split(int[] domain, int[] nodes); diff --git a/teavm-core/src/main/java/org/teavm/common/Mapper.java b/teavm-core/src/main/java/org/teavm/common/Mapper.java index 9b6733685..af16bcbe5 100644 --- a/teavm-core/src/main/java/org/teavm/common/Mapper.java +++ b/teavm-core/src/main/java/org/teavm/common/Mapper.java @@ -17,7 +17,7 @@ package org.teavm.common; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface Mapper { R map(T preimage); diff --git a/teavm-core/src/main/java/org/teavm/common/MutableDirectedGraph.java b/teavm-core/src/main/java/org/teavm/common/MutableDirectedGraph.java index 91fb6a851..362e7d276 100644 --- a/teavm-core/src/main/java/org/teavm/common/MutableDirectedGraph.java +++ b/teavm-core/src/main/java/org/teavm/common/MutableDirectedGraph.java @@ -23,7 +23,7 @@ import java.util.List; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class MutableDirectedGraph implements Graph { private List successors = new ArrayList<>(); diff --git a/teavm-core/src/main/java/org/teavm/debugging/PropertyMap.java b/teavm-core/src/main/java/org/teavm/debugging/PropertyMap.java index 823524795..3bfc6e596 100644 --- a/teavm-core/src/main/java/org/teavm/debugging/PropertyMap.java +++ b/teavm-core/src/main/java/org/teavm/debugging/PropertyMap.java @@ -23,7 +23,7 @@ import org.teavm.debugging.javascript.JavaScriptVariable; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ class PropertyMap extends AbstractMap { private String className; diff --git a/teavm-core/src/main/java/org/teavm/debugging/Value.java b/teavm-core/src/main/java/org/teavm/debugging/Value.java index fa8d4df15..6ea594474 100644 --- a/teavm-core/src/main/java/org/teavm/debugging/Value.java +++ b/teavm-core/src/main/java/org/teavm/debugging/Value.java @@ -21,7 +21,7 @@ import org.teavm.debugging.javascript.JavaScriptValue; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class Value { private Debugger debugger; diff --git a/teavm-core/src/main/java/org/teavm/debugging/Variable.java b/teavm-core/src/main/java/org/teavm/debugging/Variable.java index 1bb2bcab5..930100d60 100644 --- a/teavm-core/src/main/java/org/teavm/debugging/Variable.java +++ b/teavm-core/src/main/java/org/teavm/debugging/Variable.java @@ -17,7 +17,7 @@ package org.teavm.debugging; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class Variable { private String name; diff --git a/teavm-core/src/main/java/org/teavm/debugging/information/ClassNameIterator.java b/teavm-core/src/main/java/org/teavm/debugging/information/ClassNameIterator.java index aa76261ba..a11d597a7 100644 --- a/teavm-core/src/main/java/org/teavm/debugging/information/ClassNameIterator.java +++ b/teavm-core/src/main/java/org/teavm/debugging/information/ClassNameIterator.java @@ -17,7 +17,7 @@ package org.teavm.debugging.information; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class ClassNameIterator { private DebugInformation debugInformation; diff --git a/teavm-core/src/main/java/org/teavm/debugging/information/DebuggerCallSite.java b/teavm-core/src/main/java/org/teavm/debugging/information/DebuggerCallSite.java index a6c262bd1..2fa0670ee 100644 --- a/teavm-core/src/main/java/org/teavm/debugging/information/DebuggerCallSite.java +++ b/teavm-core/src/main/java/org/teavm/debugging/information/DebuggerCallSite.java @@ -17,7 +17,7 @@ package org.teavm.debugging.information; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public abstract class DebuggerCallSite { static final int NONE = 0; diff --git a/teavm-core/src/main/java/org/teavm/debugging/information/DebuggerCallSiteVisitor.java b/teavm-core/src/main/java/org/teavm/debugging/information/DebuggerCallSiteVisitor.java index 964b5d6b4..0aaf1921c 100644 --- a/teavm-core/src/main/java/org/teavm/debugging/information/DebuggerCallSiteVisitor.java +++ b/teavm-core/src/main/java/org/teavm/debugging/information/DebuggerCallSiteVisitor.java @@ -17,7 +17,7 @@ package org.teavm.debugging.information; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface DebuggerCallSiteVisitor { void visit(DebuggerVirtualCallSite callSite); diff --git a/teavm-core/src/main/java/org/teavm/debugging/information/DebuggerStaticCallSite.java b/teavm-core/src/main/java/org/teavm/debugging/information/DebuggerStaticCallSite.java index 4e965f0d3..5cf73928e 100644 --- a/teavm-core/src/main/java/org/teavm/debugging/information/DebuggerStaticCallSite.java +++ b/teavm-core/src/main/java/org/teavm/debugging/information/DebuggerStaticCallSite.java @@ -19,7 +19,7 @@ import org.teavm.model.MethodReference; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class DebuggerStaticCallSite extends DebuggerCallSite { private MethodReference method; diff --git a/teavm-core/src/main/java/org/teavm/debugging/information/DebuggerVirtualCallSite.java b/teavm-core/src/main/java/org/teavm/debugging/information/DebuggerVirtualCallSite.java index 1bc660c2a..df3d39874 100644 --- a/teavm-core/src/main/java/org/teavm/debugging/information/DebuggerVirtualCallSite.java +++ b/teavm-core/src/main/java/org/teavm/debugging/information/DebuggerVirtualCallSite.java @@ -19,7 +19,7 @@ import org.teavm.model.MethodReference; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class DebuggerVirtualCallSite extends DebuggerCallSite { private MethodReference method; diff --git a/teavm-core/src/main/java/org/teavm/debugging/information/FileNameIterator.java b/teavm-core/src/main/java/org/teavm/debugging/information/FileNameIterator.java index 5a818477a..734d9520c 100644 --- a/teavm-core/src/main/java/org/teavm/debugging/information/FileNameIterator.java +++ b/teavm-core/src/main/java/org/teavm/debugging/information/FileNameIterator.java @@ -18,7 +18,7 @@ package org.teavm.debugging.information; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class FileNameIterator { private DebugInformation debugInformation; diff --git a/teavm-core/src/main/java/org/teavm/debugging/information/LineNumberIterator.java b/teavm-core/src/main/java/org/teavm/debugging/information/LineNumberIterator.java index f36c8a450..9becc12d5 100644 --- a/teavm-core/src/main/java/org/teavm/debugging/information/LineNumberIterator.java +++ b/teavm-core/src/main/java/org/teavm/debugging/information/LineNumberIterator.java @@ -18,7 +18,7 @@ package org.teavm.debugging.information; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class LineNumberIterator { private DebugInformation debugInformation; diff --git a/teavm-core/src/main/java/org/teavm/debugging/information/SourceLocationIterator.java b/teavm-core/src/main/java/org/teavm/debugging/information/SourceLocationIterator.java index 2699fe4aa..d7a6ff1f4 100644 --- a/teavm-core/src/main/java/org/teavm/debugging/information/SourceLocationIterator.java +++ b/teavm-core/src/main/java/org/teavm/debugging/information/SourceLocationIterator.java @@ -19,7 +19,7 @@ import org.teavm.common.RecordArray; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class SourceLocationIterator { private DebugInformation debugInformation; diff --git a/teavm-core/src/main/java/org/teavm/debugging/javascript/JavaScriptValue.java b/teavm-core/src/main/java/org/teavm/debugging/javascript/JavaScriptValue.java index 1047fe5c0..923fcad99 100644 --- a/teavm-core/src/main/java/org/teavm/debugging/javascript/JavaScriptValue.java +++ b/teavm-core/src/main/java/org/teavm/debugging/javascript/JavaScriptValue.java @@ -19,7 +19,7 @@ import java.util.Map; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface JavaScriptValue { String getRepresentation(); diff --git a/teavm-core/src/main/java/org/teavm/debugging/javascript/JavaScriptVariable.java b/teavm-core/src/main/java/org/teavm/debugging/javascript/JavaScriptVariable.java index e4900a0d3..8b9923a80 100644 --- a/teavm-core/src/main/java/org/teavm/debugging/javascript/JavaScriptVariable.java +++ b/teavm-core/src/main/java/org/teavm/debugging/javascript/JavaScriptVariable.java @@ -17,7 +17,7 @@ package org.teavm.debugging.javascript; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface JavaScriptVariable { String getName(); diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyAgentType.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyAgentType.java index 95de7bbde..464725936 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyAgentType.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyAgentType.java @@ -17,7 +17,7 @@ package org.teavm.dependency; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface DependencyAgentType { String getName(); diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyCheckerInterruptor.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyCheckerInterruptor.java index 5ec6d7364..e56af6b6b 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyCheckerInterruptor.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyCheckerInterruptor.java @@ -17,7 +17,7 @@ package org.teavm.dependency; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface DependencyCheckerInterruptor { boolean shouldContinue(); diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyConsumer.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyConsumer.java index 60821beb6..0526423e4 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyConsumer.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyConsumer.java @@ -17,7 +17,7 @@ package org.teavm.dependency; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface DependencyConsumer { void consume(DependencyAgentType type); diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyInfo.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyInfo.java index fd0c9b19b..064e5bbb6 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyInfo.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyInfo.java @@ -23,7 +23,7 @@ import org.teavm.model.MethodReference; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface DependencyInfo { ClassReaderSource getClassSource(); diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyType.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyType.java index f74d7bb02..b815a69b7 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyType.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyType.java @@ -17,7 +17,7 @@ package org.teavm.dependency; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class DependencyType implements DependencyAgentType { private DependencyChecker dependencyChecker; diff --git a/teavm-core/src/main/java/org/teavm/dependency/MethodDependencyInfo.java b/teavm-core/src/main/java/org/teavm/dependency/MethodDependencyInfo.java index cc3359a3a..f8c334535 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/MethodDependencyInfo.java +++ b/teavm-core/src/main/java/org/teavm/dependency/MethodDependencyInfo.java @@ -19,7 +19,7 @@ import org.teavm.model.MethodReference; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface MethodDependencyInfo { ValueDependencyInfo[] getVariables(); diff --git a/teavm-core/src/main/java/org/teavm/dependency/ValueDependencyInfo.java b/teavm-core/src/main/java/org/teavm/dependency/ValueDependencyInfo.java index fb46eb751..81e878ee6 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/ValueDependencyInfo.java +++ b/teavm-core/src/main/java/org/teavm/dependency/ValueDependencyInfo.java @@ -17,7 +17,7 @@ package org.teavm.dependency; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface ValueDependencyInfo { String[] getTypes(); diff --git a/teavm-core/src/main/java/org/teavm/diagnostics/AccumulationDiagnostics.java b/teavm-core/src/main/java/org/teavm/diagnostics/AccumulationDiagnostics.java index 7581ec258..6ed034aad 100644 --- a/teavm-core/src/main/java/org/teavm/diagnostics/AccumulationDiagnostics.java +++ b/teavm-core/src/main/java/org/teavm/diagnostics/AccumulationDiagnostics.java @@ -22,7 +22,7 @@ import org.teavm.model.CallLocation; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class AccumulationDiagnostics implements Diagnostics, ProblemProvider { private List problems = new ArrayList<>(); diff --git a/teavm-core/src/main/java/org/teavm/diagnostics/Diagnostics.java b/teavm-core/src/main/java/org/teavm/diagnostics/Diagnostics.java index a061bbac9..7a11fab66 100644 --- a/teavm-core/src/main/java/org/teavm/diagnostics/Diagnostics.java +++ b/teavm-core/src/main/java/org/teavm/diagnostics/Diagnostics.java @@ -19,7 +19,7 @@ import org.teavm.model.CallLocation; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface Diagnostics { void error(CallLocation location, String error, Object... params); diff --git a/teavm-core/src/main/java/org/teavm/diagnostics/Problem.java b/teavm-core/src/main/java/org/teavm/diagnostics/Problem.java index 09be05f31..37aee8b68 100644 --- a/teavm-core/src/main/java/org/teavm/diagnostics/Problem.java +++ b/teavm-core/src/main/java/org/teavm/diagnostics/Problem.java @@ -20,7 +20,7 @@ import org.teavm.model.*; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class Problem { private ProblemSeverity severity; diff --git a/teavm-core/src/main/java/org/teavm/diagnostics/ProblemSeverity.java b/teavm-core/src/main/java/org/teavm/diagnostics/ProblemSeverity.java index 1a09fca6e..6e270b944 100644 --- a/teavm-core/src/main/java/org/teavm/diagnostics/ProblemSeverity.java +++ b/teavm-core/src/main/java/org/teavm/diagnostics/ProblemSeverity.java @@ -17,7 +17,7 @@ package org.teavm.diagnostics; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public enum ProblemSeverity { ERROR, diff --git a/teavm-core/src/main/java/org/teavm/javascript/Associativity.java b/teavm-core/src/main/java/org/teavm/javascript/Associativity.java index c095e97d4..cf28fef26 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Associativity.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Associativity.java @@ -17,7 +17,7 @@ package org.teavm.javascript; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public enum Associativity { LEFT, diff --git a/teavm-core/src/main/java/org/teavm/javascript/DecompilationException.java b/teavm-core/src/main/java/org/teavm/javascript/DecompilationException.java index 9febd686f..8cd49ccf5 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/DecompilationException.java +++ b/teavm-core/src/main/java/org/teavm/javascript/DecompilationException.java @@ -17,7 +17,7 @@ package org.teavm.javascript; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class DecompilationException extends RuntimeException { private static final long serialVersionUID = -1400142974526572669L; diff --git a/teavm-core/src/main/java/org/teavm/javascript/Priority.java b/teavm-core/src/main/java/org/teavm/javascript/Priority.java index 924d9c333..e538e174a 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Priority.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Priority.java @@ -17,7 +17,7 @@ package org.teavm.javascript; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public enum Priority { COMMA, diff --git a/teavm-core/src/main/java/org/teavm/javascript/RenderingContext.java b/teavm-core/src/main/java/org/teavm/javascript/RenderingContext.java index 70c374f53..0adecee90 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/RenderingContext.java +++ b/teavm-core/src/main/java/org/teavm/javascript/RenderingContext.java @@ -23,7 +23,7 @@ import org.teavm.model.ListableClassReaderSource; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface RenderingContext extends ServiceRepository { NamingStrategy getNaming(); diff --git a/teavm-core/src/main/java/org/teavm/javascript/TryCatchFinder.java b/teavm-core/src/main/java/org/teavm/javascript/TryCatchFinder.java index 4b54c49e2..252b10b0b 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/TryCatchFinder.java +++ b/teavm-core/src/main/java/org/teavm/javascript/TryCatchFinder.java @@ -20,7 +20,7 @@ import org.teavm.javascript.ast.*; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ class TryCatchFinder implements StatementVisitor { public boolean tryCatchFound; diff --git a/teavm-core/src/main/java/org/teavm/javascript/ast/ClassNode.java b/teavm-core/src/main/java/org/teavm/javascript/ast/ClassNode.java index dcfcb3923..030750496 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ast/ClassNode.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ast/ClassNode.java @@ -22,7 +22,7 @@ import java.util.Set; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class ClassNode { private String name; diff --git a/teavm-core/src/main/java/org/teavm/javascript/ast/FieldNode.java b/teavm-core/src/main/java/org/teavm/javascript/ast/FieldNode.java index f1d894ca9..3253d193f 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ast/FieldNode.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ast/FieldNode.java @@ -21,7 +21,7 @@ import org.teavm.model.ValueType; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class FieldNode { private String name; diff --git a/teavm-core/src/main/java/org/teavm/javascript/ast/MethodNodeVisitor.java b/teavm-core/src/main/java/org/teavm/javascript/ast/MethodNodeVisitor.java index 08573d697..7ae0762ca 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ast/MethodNodeVisitor.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ast/MethodNodeVisitor.java @@ -17,7 +17,7 @@ package org.teavm.javascript.ast; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface MethodNodeVisitor { void visit(RegularMethodNode methodNode); diff --git a/teavm-core/src/main/java/org/teavm/javascript/ast/NativeMethodNode.java b/teavm-core/src/main/java/org/teavm/javascript/ast/NativeMethodNode.java index 921d68919..4b7d4b83d 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ast/NativeMethodNode.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ast/NativeMethodNode.java @@ -20,7 +20,7 @@ import org.teavm.model.MethodReference; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class NativeMethodNode extends MethodNode { private Generator generator; diff --git a/teavm-core/src/main/java/org/teavm/javascript/ast/NodeModifier.java b/teavm-core/src/main/java/org/teavm/javascript/ast/NodeModifier.java index 6ff273c75..724b060c0 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ast/NodeModifier.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ast/NodeModifier.java @@ -17,7 +17,7 @@ package org.teavm.javascript.ast; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public enum NodeModifier { STATIC, diff --git a/teavm-core/src/main/java/org/teavm/javascript/ast/RegularMethodNode.java b/teavm-core/src/main/java/org/teavm/javascript/ast/RegularMethodNode.java index 054a050b1..f532b4892 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ast/RegularMethodNode.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ast/RegularMethodNode.java @@ -22,7 +22,7 @@ import org.teavm.model.MethodReference; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class RegularMethodNode extends MethodNode { private Statement body; diff --git a/teavm-core/src/main/java/org/teavm/javascript/ast/UnwrapArrayExpr.java b/teavm-core/src/main/java/org/teavm/javascript/ast/UnwrapArrayExpr.java index 708005e9a..500fc0924 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ast/UnwrapArrayExpr.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ast/UnwrapArrayExpr.java @@ -20,7 +20,7 @@ import org.teavm.model.instructions.ArrayElementType; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class UnwrapArrayExpr extends Expr { private ArrayElementType elementType; diff --git a/teavm-core/src/main/java/org/teavm/javascript/spi/GeneratedBy.java b/teavm-core/src/main/java/org/teavm/javascript/spi/GeneratedBy.java index b74ff7575..94a323832 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/spi/GeneratedBy.java +++ b/teavm-core/src/main/java/org/teavm/javascript/spi/GeneratedBy.java @@ -22,7 +22,7 @@ import java.lang.annotation.Target; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) diff --git a/teavm-core/src/main/java/org/teavm/javascript/spi/Generator.java b/teavm-core/src/main/java/org/teavm/javascript/spi/Generator.java index 973491215..ad6389d12 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/spi/Generator.java +++ b/teavm-core/src/main/java/org/teavm/javascript/spi/Generator.java @@ -21,7 +21,7 @@ import org.teavm.model.MethodReference; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface Generator { void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException; diff --git a/teavm-core/src/main/java/org/teavm/javascript/spi/GeneratorContext.java b/teavm-core/src/main/java/org/teavm/javascript/spi/GeneratorContext.java index 821d42c45..b2c97a8e9 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/spi/GeneratorContext.java +++ b/teavm-core/src/main/java/org/teavm/javascript/spi/GeneratorContext.java @@ -23,7 +23,7 @@ import org.teavm.model.MethodReference; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface GeneratorContext extends ServiceRepository { String getParameterName(int index); diff --git a/teavm-core/src/main/java/org/teavm/javascript/spi/InjectedBy.java b/teavm-core/src/main/java/org/teavm/javascript/spi/InjectedBy.java index 992262986..103bb6541 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/spi/InjectedBy.java +++ b/teavm-core/src/main/java/org/teavm/javascript/spi/InjectedBy.java @@ -22,7 +22,7 @@ import java.lang.annotation.Target; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) diff --git a/teavm-core/src/main/java/org/teavm/javascript/spi/Injector.java b/teavm-core/src/main/java/org/teavm/javascript/spi/Injector.java index 8e3ea2cb8..07dec9afa 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/spi/Injector.java +++ b/teavm-core/src/main/java/org/teavm/javascript/spi/Injector.java @@ -20,7 +20,7 @@ import org.teavm.model.MethodReference; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface Injector { void generate(InjectorContext context, MethodReference methodRef) throws IOException; diff --git a/teavm-core/src/main/java/org/teavm/javascript/spi/InjectorContext.java b/teavm-core/src/main/java/org/teavm/javascript/spi/InjectorContext.java index 730c1415c..4bc112be5 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/spi/InjectorContext.java +++ b/teavm-core/src/main/java/org/teavm/javascript/spi/InjectorContext.java @@ -24,7 +24,7 @@ import org.teavm.model.ValueType; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface InjectorContext extends ServiceRepository { Expr getArgument(int index); diff --git a/teavm-core/src/main/java/org/teavm/javascript/spi/Rename.java b/teavm-core/src/main/java/org/teavm/javascript/spi/Rename.java index e828610ae..416060524 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/spi/Rename.java +++ b/teavm-core/src/main/java/org/teavm/javascript/spi/Rename.java @@ -19,7 +19,7 @@ import java.lang.annotation.*; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.METHOD, ElementType.CONSTRUCTOR }) diff --git a/teavm-core/src/main/java/org/teavm/javascript/spi/Sync.java b/teavm-core/src/main/java/org/teavm/javascript/spi/Sync.java index 27d9be337..814a73311 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/spi/Sync.java +++ b/teavm-core/src/main/java/org/teavm/javascript/spi/Sync.java @@ -19,7 +19,7 @@ import java.lang.annotation.*; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) diff --git a/teavm-core/src/main/java/org/teavm/model/AnnotationContainer.java b/teavm-core/src/main/java/org/teavm/model/AnnotationContainer.java index 6ea7cbe17..ef58854be 100644 --- a/teavm-core/src/main/java/org/teavm/model/AnnotationContainer.java +++ b/teavm-core/src/main/java/org/teavm/model/AnnotationContainer.java @@ -20,7 +20,7 @@ import java.util.Map; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class AnnotationContainer implements AnnotationContainerReader { private Map annotations = new HashMap<>(); diff --git a/teavm-core/src/main/java/org/teavm/model/ClassReaderSource.java b/teavm-core/src/main/java/org/teavm/model/ClassReaderSource.java index 8cc4fa8b8..597c5be5f 100644 --- a/teavm-core/src/main/java/org/teavm/model/ClassReaderSource.java +++ b/teavm-core/src/main/java/org/teavm/model/ClassReaderSource.java @@ -17,7 +17,7 @@ package org.teavm.model; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface ClassReaderSource { ClassReader get(String name); diff --git a/teavm-core/src/main/java/org/teavm/model/ListableClassReaderSource.java b/teavm-core/src/main/java/org/teavm/model/ListableClassReaderSource.java index 980f67b4e..710142992 100644 --- a/teavm-core/src/main/java/org/teavm/model/ListableClassReaderSource.java +++ b/teavm-core/src/main/java/org/teavm/model/ListableClassReaderSource.java @@ -19,7 +19,7 @@ import java.util.Set; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface ListableClassReaderSource extends ClassReaderSource { Set getClassNames(); diff --git a/teavm-core/src/main/java/org/teavm/model/TryCatchBlock.java b/teavm-core/src/main/java/org/teavm/model/TryCatchBlock.java index 1a8430fac..cfeecfb7e 100644 --- a/teavm-core/src/main/java/org/teavm/model/TryCatchBlock.java +++ b/teavm-core/src/main/java/org/teavm/model/TryCatchBlock.java @@ -17,7 +17,7 @@ package org.teavm.model; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TryCatchBlock implements TryCatchBlockReader { BasicBlock protectedBlock; diff --git a/teavm-core/src/main/java/org/teavm/model/TryCatchBlockReader.java b/teavm-core/src/main/java/org/teavm/model/TryCatchBlockReader.java index 13c5938ff..564265c0f 100644 --- a/teavm-core/src/main/java/org/teavm/model/TryCatchBlockReader.java +++ b/teavm-core/src/main/java/org/teavm/model/TryCatchBlockReader.java @@ -17,7 +17,7 @@ package org.teavm.model; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface TryCatchBlockReader { BasicBlockReader getProtectedBlock(); diff --git a/teavm-core/src/main/java/org/teavm/model/instructions/ArrayElementType.java b/teavm-core/src/main/java/org/teavm/model/instructions/ArrayElementType.java index b74fc419c..2f55eec88 100644 --- a/teavm-core/src/main/java/org/teavm/model/instructions/ArrayElementType.java +++ b/teavm-core/src/main/java/org/teavm/model/instructions/ArrayElementType.java @@ -17,7 +17,7 @@ package org.teavm.model.instructions; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public enum ArrayElementType { CHAR, diff --git a/teavm-core/src/main/java/org/teavm/model/instructions/NullCheckInstruction.java b/teavm-core/src/main/java/org/teavm/model/instructions/NullCheckInstruction.java index 1a48c5d34..645df9c2e 100644 --- a/teavm-core/src/main/java/org/teavm/model/instructions/NullCheckInstruction.java +++ b/teavm-core/src/main/java/org/teavm/model/instructions/NullCheckInstruction.java @@ -20,7 +20,7 @@ import org.teavm.model.Variable; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class NullCheckInstruction extends Instruction { private Variable value; diff --git a/teavm-core/src/main/java/org/teavm/model/instructions/UnwrapArrayInstruction.java b/teavm-core/src/main/java/org/teavm/model/instructions/UnwrapArrayInstruction.java index 78c70142c..64c62abe5 100644 --- a/teavm-core/src/main/java/org/teavm/model/instructions/UnwrapArrayInstruction.java +++ b/teavm-core/src/main/java/org/teavm/model/instructions/UnwrapArrayInstruction.java @@ -20,7 +20,7 @@ import org.teavm.model.Variable; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class UnwrapArrayInstruction extends Instruction { private Variable array; diff --git a/teavm-core/src/main/java/org/teavm/model/util/AsyncMethodFinder.java b/teavm-core/src/main/java/org/teavm/model/util/AsyncMethodFinder.java index def67f110..e882cbdf6 100644 --- a/teavm-core/src/main/java/org/teavm/model/util/AsyncMethodFinder.java +++ b/teavm-core/src/main/java/org/teavm/model/util/AsyncMethodFinder.java @@ -28,7 +28,7 @@ import org.teavm.model.instructions.*; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class AsyncMethodFinder { private Set asyncMethods = new HashSet<>(); diff --git a/teavm-core/src/main/java/org/teavm/optimization/ClassSetOptimizer.java b/teavm-core/src/main/java/org/teavm/optimization/ClassSetOptimizer.java index 2b9620caa..e8b0c8c82 100644 --- a/teavm-core/src/main/java/org/teavm/optimization/ClassSetOptimizer.java +++ b/teavm-core/src/main/java/org/teavm/optimization/ClassSetOptimizer.java @@ -25,7 +25,7 @@ import org.teavm.model.util.ProgramUtils; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class ClassSetOptimizer { private List getOptimizations() { diff --git a/teavm-core/src/main/java/org/teavm/optimization/Devirtualization.java b/teavm-core/src/main/java/org/teavm/optimization/Devirtualization.java index 994a77b67..9f2c1646d 100644 --- a/teavm-core/src/main/java/org/teavm/optimization/Devirtualization.java +++ b/teavm-core/src/main/java/org/teavm/optimization/Devirtualization.java @@ -26,7 +26,7 @@ import org.teavm.model.instructions.InvokeInstruction; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class Devirtualization { private DependencyInfo dependency; diff --git a/teavm-core/src/main/java/org/teavm/optimization/MethodOptimization.java b/teavm-core/src/main/java/org/teavm/optimization/MethodOptimization.java index 6d1528ace..a587c62a4 100644 --- a/teavm-core/src/main/java/org/teavm/optimization/MethodOptimization.java +++ b/teavm-core/src/main/java/org/teavm/optimization/MethodOptimization.java @@ -20,7 +20,7 @@ import org.teavm.model.Program; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface MethodOptimization { void optimize(MethodReader method, Program program); diff --git a/teavm-core/src/main/java/org/teavm/optimization/UnusedVariableElimination.java b/teavm-core/src/main/java/org/teavm/optimization/UnusedVariableElimination.java index b4d13841e..0515ce36b 100644 --- a/teavm-core/src/main/java/org/teavm/optimization/UnusedVariableElimination.java +++ b/teavm-core/src/main/java/org/teavm/optimization/UnusedVariableElimination.java @@ -21,7 +21,7 @@ import org.teavm.model.instructions.*; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class UnusedVariableElimination implements MethodOptimization { @Override diff --git a/teavm-core/src/main/java/org/teavm/optimization/VariableEscapeAnalyzer.java b/teavm-core/src/main/java/org/teavm/optimization/VariableEscapeAnalyzer.java index c80fd2ec6..7b79c36e3 100644 --- a/teavm-core/src/main/java/org/teavm/optimization/VariableEscapeAnalyzer.java +++ b/teavm-core/src/main/java/org/teavm/optimization/VariableEscapeAnalyzer.java @@ -23,7 +23,7 @@ import org.teavm.model.instructions.*; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public final class VariableEscapeAnalyzer { private VariableEscapeAnalyzer() { diff --git a/teavm-core/src/main/java/org/teavm/optimization/VariableUsageGraphBuilder.java b/teavm-core/src/main/java/org/teavm/optimization/VariableUsageGraphBuilder.java index 0b5e1c691..26ef1eee6 100644 --- a/teavm-core/src/main/java/org/teavm/optimization/VariableUsageGraphBuilder.java +++ b/teavm-core/src/main/java/org/teavm/optimization/VariableUsageGraphBuilder.java @@ -22,7 +22,7 @@ import org.teavm.model.instructions.*; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public final class VariableUsageGraphBuilder { private VariableUsageGraphBuilder() { diff --git a/teavm-core/src/main/java/org/teavm/parsing/ClasspathClassHolderSource.java b/teavm-core/src/main/java/org/teavm/parsing/ClasspathClassHolderSource.java index a56c8616d..2f744d058 100644 --- a/teavm-core/src/main/java/org/teavm/parsing/ClasspathClassHolderSource.java +++ b/teavm-core/src/main/java/org/teavm/parsing/ClasspathClassHolderSource.java @@ -24,7 +24,7 @@ import org.teavm.resource.ResourceClassHolderMapper; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class ClasspathClassHolderSource implements ClassHolderSource, ClassDateProvider { private MapperClassHolderSource innerClassSource; diff --git a/teavm-core/src/main/java/org/teavm/parsing/ClasspathResourceMapper.java b/teavm-core/src/main/java/org/teavm/parsing/ClasspathResourceMapper.java index e018941af..653610b85 100644 --- a/teavm-core/src/main/java/org/teavm/parsing/ClasspathResourceMapper.java +++ b/teavm-core/src/main/java/org/teavm/parsing/ClasspathResourceMapper.java @@ -27,7 +27,7 @@ import org.teavm.model.ClassHolder; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class ClasspathResourceMapper implements Mapper, ClassDateProvider { private static final String PACKAGE_PREFIX = "packagePrefix."; diff --git a/teavm-core/src/main/java/org/teavm/parsing/VariableDebugInformation.java b/teavm-core/src/main/java/org/teavm/parsing/VariableDebugInformation.java index 995fa172e..d6e2a0380 100644 --- a/teavm-core/src/main/java/org/teavm/parsing/VariableDebugInformation.java +++ b/teavm-core/src/main/java/org/teavm/parsing/VariableDebugInformation.java @@ -20,7 +20,7 @@ import org.teavm.model.Instruction; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface VariableDebugInformation { Map getDebugNames(Instruction insn); diff --git a/teavm-core/src/main/java/org/teavm/resource/ClasspathResourceReader.java b/teavm-core/src/main/java/org/teavm/resource/ClasspathResourceReader.java index cdfe762eb..1869c5c29 100644 --- a/teavm-core/src/main/java/org/teavm/resource/ClasspathResourceReader.java +++ b/teavm-core/src/main/java/org/teavm/resource/ClasspathResourceReader.java @@ -20,7 +20,7 @@ import java.io.InputStream; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class ClasspathResourceReader implements ResourceReader { private ClassLoader classLoader; diff --git a/teavm-core/src/main/java/org/teavm/resource/MapperClassHolderSource.java b/teavm-core/src/main/java/org/teavm/resource/MapperClassHolderSource.java index e29f6b3ec..9ecd50920 100644 --- a/teavm-core/src/main/java/org/teavm/resource/MapperClassHolderSource.java +++ b/teavm-core/src/main/java/org/teavm/resource/MapperClassHolderSource.java @@ -22,7 +22,7 @@ import org.teavm.model.ClassHolderSource; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class MapperClassHolderSource implements ClassHolderSource { private Mapper mapper; diff --git a/teavm-core/src/main/java/org/teavm/resource/ResourceParser.java b/teavm-core/src/main/java/org/teavm/resource/ResourceParser.java index e2f5be059..5d980b30e 100644 --- a/teavm-core/src/main/java/org/teavm/resource/ResourceParser.java +++ b/teavm-core/src/main/java/org/teavm/resource/ResourceParser.java @@ -25,7 +25,7 @@ import org.teavm.parsing.Parser; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class ResourceParser implements Mapper { private ResourceReader resourceReader; diff --git a/teavm-core/src/main/java/org/teavm/tooling/EmptyTeaVMToolLog.java b/teavm-core/src/main/java/org/teavm/tooling/EmptyTeaVMToolLog.java index 917e73fb4..1a87b689d 100644 --- a/teavm-core/src/main/java/org/teavm/tooling/EmptyTeaVMToolLog.java +++ b/teavm-core/src/main/java/org/teavm/tooling/EmptyTeaVMToolLog.java @@ -17,7 +17,7 @@ package org.teavm.tooling; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class EmptyTeaVMToolLog implements TeaVMToolLog { @Override diff --git a/teavm-core/src/main/java/org/teavm/tooling/ExceptionHelper.java b/teavm-core/src/main/java/org/teavm/tooling/ExceptionHelper.java index 41a8322e7..ac53214c3 100644 --- a/teavm-core/src/main/java/org/teavm/tooling/ExceptionHelper.java +++ b/teavm-core/src/main/java/org/teavm/tooling/ExceptionHelper.java @@ -17,7 +17,7 @@ package org.teavm.tooling; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ final class ExceptionHelper { private ExceptionHelper() { diff --git a/teavm-core/src/main/java/org/teavm/tooling/TeaVMTestTool.java b/teavm-core/src/main/java/org/teavm/tooling/TeaVMTestTool.java index 1bf954c91..6c680821c 100644 --- a/teavm-core/src/main/java/org/teavm/tooling/TeaVMTestTool.java +++ b/teavm-core/src/main/java/org/teavm/tooling/TeaVMTestTool.java @@ -36,7 +36,7 @@ import org.teavm.vm.TeaVMBuilder; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TeaVMTestTool { private Map> groupedMethods = new HashMap<>(); diff --git a/teavm-core/src/main/java/org/teavm/tooling/TeaVMTool.java b/teavm-core/src/main/java/org/teavm/tooling/TeaVMTool.java index 846b94f33..e5d0b1853 100644 --- a/teavm-core/src/main/java/org/teavm/tooling/TeaVMTool.java +++ b/teavm-core/src/main/java/org/teavm/tooling/TeaVMTool.java @@ -34,7 +34,7 @@ import org.teavm.vm.spi.AbstractRendererListener; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TeaVMTool { private File targetDirectory = new File("."); diff --git a/teavm-core/src/main/java/org/teavm/tooling/TeaVMToolException.java b/teavm-core/src/main/java/org/teavm/tooling/TeaVMToolException.java index 510006be6..3045b5bad 100644 --- a/teavm-core/src/main/java/org/teavm/tooling/TeaVMToolException.java +++ b/teavm-core/src/main/java/org/teavm/tooling/TeaVMToolException.java @@ -17,7 +17,7 @@ package org.teavm.tooling; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TeaVMToolException extends Exception { private static final long serialVersionUID = 579149191624783241L; diff --git a/teavm-core/src/main/java/org/teavm/tooling/TeaVMToolLog.java b/teavm-core/src/main/java/org/teavm/tooling/TeaVMToolLog.java index bc1ee5b81..079bcf1bb 100644 --- a/teavm-core/src/main/java/org/teavm/tooling/TeaVMToolLog.java +++ b/teavm-core/src/main/java/org/teavm/tooling/TeaVMToolLog.java @@ -17,7 +17,7 @@ package org.teavm.tooling; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface TeaVMToolLog { void info(String text); diff --git a/teavm-core/src/main/java/org/teavm/vm/TeaVM.java b/teavm-core/src/main/java/org/teavm/vm/TeaVM.java index 53d5efb6f..f459e4a46 100644 --- a/teavm-core/src/main/java/org/teavm/vm/TeaVM.java +++ b/teavm-core/src/main/java/org/teavm/vm/TeaVM.java @@ -317,7 +317,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository { * are specified. This method may fail if there are items (classes, methods and fields) * that are required by entry points, but weren't found in classpath. In this case no * actual generation happens and no exceptions thrown, but you can further call - * {@link #checkForViolations()} or {@link #hasMissingItems()} to learn the build state.

+ * {@link #getProblemProvider()} to learn the build state.

* * @param writer where to generate JavaScript. Should not be null. * @param target where to generate additional resources. Can be null, but if there are diff --git a/teavm-core/src/main/java/org/teavm/vm/TeaVMEntryPoint.java b/teavm-core/src/main/java/org/teavm/vm/TeaVMEntryPoint.java index 70375fafa..0c8f40bbc 100644 --- a/teavm-core/src/main/java/org/teavm/vm/TeaVMEntryPoint.java +++ b/teavm-core/src/main/java/org/teavm/vm/TeaVMEntryPoint.java @@ -64,7 +64,7 @@ import org.teavm.model.MethodReference; *} * *

If you didn't call .withValue(1, "java.util.HashMap"), TeaVM could not know, - * what implementation of #entrySet method to include.

+ * what implementation of entrySet method to include.

* * @author Alexey Andreev */ diff --git a/teavm-core/src/main/java/org/teavm/vm/TeaVMPhase.java b/teavm-core/src/main/java/org/teavm/vm/TeaVMPhase.java index ea0c709f2..a74621432 100644 --- a/teavm-core/src/main/java/org/teavm/vm/TeaVMPhase.java +++ b/teavm-core/src/main/java/org/teavm/vm/TeaVMPhase.java @@ -17,7 +17,7 @@ package org.teavm.vm; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public enum TeaVMPhase { DEPENDENCY_CHECKING, diff --git a/teavm-core/src/main/java/org/teavm/vm/TeaVMProgressListener.java b/teavm-core/src/main/java/org/teavm/vm/TeaVMProgressListener.java index 8286dbf75..28939df74 100644 --- a/teavm-core/src/main/java/org/teavm/vm/TeaVMProgressListener.java +++ b/teavm-core/src/main/java/org/teavm/vm/TeaVMProgressListener.java @@ -17,7 +17,7 @@ package org.teavm.vm; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface TeaVMProgressListener { TeaVMProgressFeedback phaseStarted(TeaVMPhase phase, int count); diff --git a/teavm-core/src/main/java/org/teavm/vm/Violations.java b/teavm-core/src/main/java/org/teavm/vm/Violations.java index fe1cbe11e..3fcd1f3a3 100644 --- a/teavm-core/src/main/java/org/teavm/vm/Violations.java +++ b/teavm-core/src/main/java/org/teavm/vm/Violations.java @@ -24,7 +24,7 @@ import org.teavm.diagnostics.Problem; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface Violations { Set getMissingMethods(); diff --git a/teavm-core/src/main/java/org/teavm/vm/spi/AbstractRendererListener.java b/teavm-core/src/main/java/org/teavm/vm/spi/AbstractRendererListener.java index b94971fb7..6e38bd9ef 100644 --- a/teavm-core/src/main/java/org/teavm/vm/spi/AbstractRendererListener.java +++ b/teavm-core/src/main/java/org/teavm/vm/spi/AbstractRendererListener.java @@ -21,7 +21,7 @@ import org.teavm.vm.BuildTarget; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public abstract class AbstractRendererListener implements RendererListener { @Override diff --git a/teavm-core/src/main/java/org/teavm/vm/spi/RendererListener.java b/teavm-core/src/main/java/org/teavm/vm/spi/RendererListener.java index 6c4e935d7..03affe7fb 100644 --- a/teavm-core/src/main/java/org/teavm/vm/spi/RendererListener.java +++ b/teavm-core/src/main/java/org/teavm/vm/spi/RendererListener.java @@ -21,7 +21,7 @@ import org.teavm.vm.BuildTarget; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface RendererListener { void begin(RenderingContext context, BuildTarget buildTarget) throws IOException; diff --git a/teavm-dom/src/main/java/org/teavm/dom/browser/Screen.java b/teavm-dom/src/main/java/org/teavm/dom/browser/Screen.java index 87919530e..85fa32a94 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/browser/Screen.java +++ b/teavm-dom/src/main/java/org/teavm/dom/browser/Screen.java @@ -20,7 +20,7 @@ import org.teavm.jso.JSProperty; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface Screen extends JSObject { @JSProperty diff --git a/teavm-dom/src/main/java/org/teavm/dom/core/Entity.java b/teavm-dom/src/main/java/org/teavm/dom/core/Entity.java index 1d43f37f4..8ff2bac3f 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/core/Entity.java +++ b/teavm-dom/src/main/java/org/teavm/dom/core/Entity.java @@ -19,7 +19,7 @@ import org.teavm.jso.JSProperty; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface Entity extends Node { @JSProperty diff --git a/teavm-dom/src/main/java/org/teavm/dom/core/Notation.java b/teavm-dom/src/main/java/org/teavm/dom/core/Notation.java index ac05947e3..ef9a9c1da 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/core/Notation.java +++ b/teavm-dom/src/main/java/org/teavm/dom/core/Notation.java @@ -19,7 +19,7 @@ import org.teavm.jso.JSProperty; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface Notation extends Node { @JSProperty diff --git a/teavm-dom/src/main/java/org/teavm/dom/css/CSSStyleDeclaration.java b/teavm-dom/src/main/java/org/teavm/dom/css/CSSStyleDeclaration.java index a96a1b257..147f70ba6 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/css/CSSStyleDeclaration.java +++ b/teavm-dom/src/main/java/org/teavm/dom/css/CSSStyleDeclaration.java @@ -21,7 +21,7 @@ import org.teavm.jso.JSProperty; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface CSSStyleDeclaration extends JSObject { @JSProperty diff --git a/teavm-dom/src/main/java/org/teavm/dom/css/ElementCSSInlineStyle.java b/teavm-dom/src/main/java/org/teavm/dom/css/ElementCSSInlineStyle.java index 67ad3387a..d38b9e1cd 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/css/ElementCSSInlineStyle.java +++ b/teavm-dom/src/main/java/org/teavm/dom/css/ElementCSSInlineStyle.java @@ -20,7 +20,7 @@ import org.teavm.jso.JSProperty; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface ElementCSSInlineStyle extends JSObject { @JSProperty diff --git a/teavm-dom/src/main/java/org/teavm/dom/events/DocumentEvent.java b/teavm-dom/src/main/java/org/teavm/dom/events/DocumentEvent.java index 968d555da..f9a6a7887 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/events/DocumentEvent.java +++ b/teavm-dom/src/main/java/org/teavm/dom/events/DocumentEvent.java @@ -17,7 +17,7 @@ package org.teavm.dom.events; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface DocumentEvent { Event createEvent(String eventType); diff --git a/teavm-dom/src/main/java/org/teavm/dom/events/KeyboardEvent.java b/teavm-dom/src/main/java/org/teavm/dom/events/KeyboardEvent.java index f1755e019..eb8a65624 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/events/KeyboardEvent.java +++ b/teavm-dom/src/main/java/org/teavm/dom/events/KeyboardEvent.java @@ -19,7 +19,7 @@ import org.teavm.jso.JSProperty; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface KeyboardEvent extends Event { int DOM_KEY_LOCATION_STANDARD = 0x00; diff --git a/teavm-dom/src/main/java/org/teavm/dom/events/MouseEvent.java b/teavm-dom/src/main/java/org/teavm/dom/events/MouseEvent.java index 2d912c8fa..50f51dd44 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/events/MouseEvent.java +++ b/teavm-dom/src/main/java/org/teavm/dom/events/MouseEvent.java @@ -20,7 +20,7 @@ import org.teavm.jso.JSProperty; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface MouseEvent extends Event { short LEFT_BUTTON = 0; diff --git a/teavm-dom/src/main/java/org/teavm/dom/html/HTMLBaseElement.java b/teavm-dom/src/main/java/org/teavm/dom/html/HTMLBaseElement.java index d24e47c19..3a0dd11c1 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/html/HTMLBaseElement.java +++ b/teavm-dom/src/main/java/org/teavm/dom/html/HTMLBaseElement.java @@ -19,7 +19,7 @@ import org.teavm.jso.JSProperty; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface HTMLBaseElement extends HTMLElement { @JSProperty diff --git a/teavm-dom/src/main/java/org/teavm/dom/html/HTMLCollection.java b/teavm-dom/src/main/java/org/teavm/dom/html/HTMLCollection.java index 65caf1490..0f21268ce 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/html/HTMLCollection.java +++ b/teavm-dom/src/main/java/org/teavm/dom/html/HTMLCollection.java @@ -20,7 +20,7 @@ import org.teavm.jso.JSArrayReader; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface HTMLCollection extends JSArrayReader { Element item(int index); diff --git a/teavm-dom/src/main/java/org/teavm/dom/html/HTMLDocument.java b/teavm-dom/src/main/java/org/teavm/dom/html/HTMLDocument.java index 317d70842..08aeeb038 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/html/HTMLDocument.java +++ b/teavm-dom/src/main/java/org/teavm/dom/html/HTMLDocument.java @@ -21,7 +21,7 @@ import org.teavm.jso.JSProperty; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface HTMLDocument extends Document, EventTarget { @JSProperty diff --git a/teavm-dom/src/main/java/org/teavm/dom/html/HTMLElement.java b/teavm-dom/src/main/java/org/teavm/dom/html/HTMLElement.java index fde105ccf..c02699870 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/html/HTMLElement.java +++ b/teavm-dom/src/main/java/org/teavm/dom/html/HTMLElement.java @@ -23,7 +23,7 @@ import org.teavm.jso.JSProperty; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface HTMLElement extends Element, ElementCSSInlineStyle, EventTarget { @Override diff --git a/teavm-dom/src/main/java/org/teavm/dom/html/HTMLHeadElement.java b/teavm-dom/src/main/java/org/teavm/dom/html/HTMLHeadElement.java index eca363d46..e43b0db45 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/html/HTMLHeadElement.java +++ b/teavm-dom/src/main/java/org/teavm/dom/html/HTMLHeadElement.java @@ -17,7 +17,7 @@ package org.teavm.dom.html; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface HTMLHeadElement extends HTMLElement { } diff --git a/teavm-dom/src/main/java/org/teavm/dom/html/HTMLHtmlElement.java b/teavm-dom/src/main/java/org/teavm/dom/html/HTMLHtmlElement.java index 2a2b9ce27..6ac010863 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/html/HTMLHtmlElement.java +++ b/teavm-dom/src/main/java/org/teavm/dom/html/HTMLHtmlElement.java @@ -17,7 +17,7 @@ package org.teavm.dom.html; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface HTMLHtmlElement extends HTMLElement { } diff --git a/teavm-dom/src/main/java/org/teavm/dom/html/HTMLInputElement.java b/teavm-dom/src/main/java/org/teavm/dom/html/HTMLInputElement.java index bfe5798f0..51555ccf3 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/html/HTMLInputElement.java +++ b/teavm-dom/src/main/java/org/teavm/dom/html/HTMLInputElement.java @@ -19,7 +19,7 @@ import org.teavm.jso.JSProperty; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface HTMLInputElement extends HTMLElement { @JSProperty diff --git a/teavm-dom/src/main/java/org/teavm/dom/html/HTMLLinkElement.java b/teavm-dom/src/main/java/org/teavm/dom/html/HTMLLinkElement.java index d66519872..549b94d13 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/html/HTMLLinkElement.java +++ b/teavm-dom/src/main/java/org/teavm/dom/html/HTMLLinkElement.java @@ -19,7 +19,7 @@ import org.teavm.jso.JSProperty; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface HTMLLinkElement extends HTMLElement { @JSProperty diff --git a/teavm-dom/src/main/java/org/teavm/dom/html/HTMLMetaElement.java b/teavm-dom/src/main/java/org/teavm/dom/html/HTMLMetaElement.java index 0e5db9032..c17cae094 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/html/HTMLMetaElement.java +++ b/teavm-dom/src/main/java/org/teavm/dom/html/HTMLMetaElement.java @@ -19,7 +19,7 @@ import org.teavm.jso.JSProperty; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface HTMLMetaElement extends HTMLElement { @JSProperty diff --git a/teavm-dom/src/main/java/org/teavm/dom/html/HTMLOptionElement.java b/teavm-dom/src/main/java/org/teavm/dom/html/HTMLOptionElement.java index 16f60946b..00de6e971 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/html/HTMLOptionElement.java +++ b/teavm-dom/src/main/java/org/teavm/dom/html/HTMLOptionElement.java @@ -19,7 +19,7 @@ import org.teavm.jso.JSProperty; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface HTMLOptionElement extends HTMLElement { @JSProperty diff --git a/teavm-dom/src/main/java/org/teavm/dom/html/HTMLOptionsCollection.java b/teavm-dom/src/main/java/org/teavm/dom/html/HTMLOptionsCollection.java index f94d87e73..e4ee1cc3c 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/html/HTMLOptionsCollection.java +++ b/teavm-dom/src/main/java/org/teavm/dom/html/HTMLOptionsCollection.java @@ -20,7 +20,7 @@ import org.teavm.jso.JSProperty; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface HTMLOptionsCollection extends HTMLCollection { @Override diff --git a/teavm-dom/src/main/java/org/teavm/dom/html/HTMLSelectElement.java b/teavm-dom/src/main/java/org/teavm/dom/html/HTMLSelectElement.java index 9821049e2..a359d8071 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/html/HTMLSelectElement.java +++ b/teavm-dom/src/main/java/org/teavm/dom/html/HTMLSelectElement.java @@ -19,7 +19,7 @@ import org.teavm.jso.JSProperty; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface HTMLSelectElement extends HTMLElement { @JSProperty diff --git a/teavm-dom/src/main/java/org/teavm/dom/html/HTMLTitleElement.java b/teavm-dom/src/main/java/org/teavm/dom/html/HTMLTitleElement.java index 945a4a0f8..cb6256be1 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/html/HTMLTitleElement.java +++ b/teavm-dom/src/main/java/org/teavm/dom/html/HTMLTitleElement.java @@ -19,7 +19,7 @@ import org.teavm.jso.JSProperty; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface HTMLTitleElement extends HTMLElement { @JSProperty diff --git a/teavm-dom/src/main/java/org/teavm/dom/json/JSON.java b/teavm-dom/src/main/java/org/teavm/dom/json/JSON.java index bcdbba54a..bbb87c50d 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/json/JSON.java +++ b/teavm-dom/src/main/java/org/teavm/dom/json/JSON.java @@ -19,7 +19,7 @@ import org.teavm.jso.JSObject; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface JSON extends JSObject { String stringify(JSObject object); diff --git a/teavm-dom/src/main/java/org/teavm/dom/typedarrays/Float32Array.java b/teavm-dom/src/main/java/org/teavm/dom/typedarrays/Float32Array.java index f9759e481..cc93efbb1 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/typedarrays/Float32Array.java +++ b/teavm-dom/src/main/java/org/teavm/dom/typedarrays/Float32Array.java @@ -19,7 +19,7 @@ import org.teavm.jso.JSIndexer; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface Float32Array extends ArrayBufferView { @JSIndexer diff --git a/teavm-dom/src/main/java/org/teavm/dom/typedarrays/Float64Array.java b/teavm-dom/src/main/java/org/teavm/dom/typedarrays/Float64Array.java index d9faf3f82..74d165ab8 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/typedarrays/Float64Array.java +++ b/teavm-dom/src/main/java/org/teavm/dom/typedarrays/Float64Array.java @@ -19,7 +19,7 @@ import org.teavm.jso.JSIndexer; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface Float64Array extends ArrayBufferView { @JSIndexer diff --git a/teavm-dom/src/main/java/org/teavm/dom/typedarrays/Int32Array.java b/teavm-dom/src/main/java/org/teavm/dom/typedarrays/Int32Array.java index 715ee137e..1929a18b6 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/typedarrays/Int32Array.java +++ b/teavm-dom/src/main/java/org/teavm/dom/typedarrays/Int32Array.java @@ -19,7 +19,7 @@ import org.teavm.jso.JSIndexer; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface Int32Array extends ArrayBufferView { @JSIndexer diff --git a/teavm-dom/src/main/java/org/teavm/dom/typedarrays/TypedArrayFactory.java b/teavm-dom/src/main/java/org/teavm/dom/typedarrays/TypedArrayFactory.java index 33086480e..8f69c868c 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/typedarrays/TypedArrayFactory.java +++ b/teavm-dom/src/main/java/org/teavm/dom/typedarrays/TypedArrayFactory.java @@ -20,7 +20,7 @@ import org.teavm.jso.JSObject; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface TypedArrayFactory extends JSObject { @JSConstructor("ArrayBuffer") diff --git a/teavm-dom/src/main/java/org/teavm/dom/webgl/WebGLActiveInfo.java b/teavm-dom/src/main/java/org/teavm/dom/webgl/WebGLActiveInfo.java index 8ee75e8db..70a93610b 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/webgl/WebGLActiveInfo.java +++ b/teavm-dom/src/main/java/org/teavm/dom/webgl/WebGLActiveInfo.java @@ -20,7 +20,7 @@ import org.teavm.jso.JSProperty; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface WebGLActiveInfo extends JSObject { @JSProperty diff --git a/teavm-dom/src/main/java/org/teavm/dom/webgl/WebGLShaderPrecisionFormat.java b/teavm-dom/src/main/java/org/teavm/dom/webgl/WebGLShaderPrecisionFormat.java index 30904f3a0..a6a1d8391 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/webgl/WebGLShaderPrecisionFormat.java +++ b/teavm-dom/src/main/java/org/teavm/dom/webgl/WebGLShaderPrecisionFormat.java @@ -20,7 +20,7 @@ import org.teavm.jso.JSProperty; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface WebGLShaderPrecisionFormat extends JSObject { @JSProperty diff --git a/teavm-dom/src/main/java/org/teavm/dom/webgl/WebGLUniformLocation.java b/teavm-dom/src/main/java/org/teavm/dom/webgl/WebGLUniformLocation.java index 27fe18d7a..a070f18ee 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/webgl/WebGLUniformLocation.java +++ b/teavm-dom/src/main/java/org/teavm/dom/webgl/WebGLUniformLocation.java @@ -19,7 +19,7 @@ import org.teavm.jso.JSObject; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface WebGLUniformLocation extends JSObject { } diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/PreferencesBasedTeaVMProjectSettings.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/PreferencesBasedTeaVMProjectSettings.java index eba86cd1f..e5186ca60 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/PreferencesBasedTeaVMProjectSettings.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/PreferencesBasedTeaVMProjectSettings.java @@ -27,7 +27,7 @@ import org.osgi.service.prefs.Preferences; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class PreferencesBasedTeaVMProjectSettings implements TeaVMProjectSettings { public static final String ENABLED = "enabled"; diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMEclipsePlugin.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMEclipsePlugin.java index 19183d9f1..867493411 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMEclipsePlugin.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMEclipsePlugin.java @@ -34,7 +34,7 @@ import org.osgi.service.prefs.BackingStoreException; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TeaVMEclipsePlugin extends AbstractUIPlugin { public static final String ID = "teavm-eclipse-plugin"; diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMProjectBuilder.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMProjectBuilder.java index 6bc699010..e2c15059c 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMProjectBuilder.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMProjectBuilder.java @@ -40,7 +40,7 @@ import org.teavm.tooling.*; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TeaVMProjectBuilder extends IncrementalProjectBuilder { private static final int TICKS_PER_PROFILE = 10000; diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMProjectNature.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMProjectNature.java index 9f0bae1cc..abc6afad2 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMProjectNature.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMProjectNature.java @@ -25,7 +25,7 @@ import org.eclipse.core.runtime.NullProgressMonitor; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TeaVMProjectNature implements IProjectNature { private IProject project; diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMProjectSettings.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMProjectSettings.java index 9aac71d10..865517233 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMProjectSettings.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMProjectSettings.java @@ -19,7 +19,7 @@ import org.eclipse.core.runtime.CoreException; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface TeaVMProjectSettings { TeaVMProfile[] getProfiles(); diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMRuntimeMode.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMRuntimeMode.java index 55e0bbd59..fc7879d38 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMRuntimeMode.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMRuntimeMode.java @@ -17,7 +17,7 @@ package org.teavm.eclipse; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public enum TeaVMRuntimeMode { SEPARATE, diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/PropertyNameComparator.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/PropertyNameComparator.java index 5958a359e..15b2b9e01 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/PropertyNameComparator.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/PropertyNameComparator.java @@ -4,7 +4,7 @@ import java.util.Comparator; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ abstract class PropertyNameComparator implements Comparator { abstract String getName(T value); diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugElement.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugElement.java index 010ec3a24..d75a0f007 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugElement.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugElement.java @@ -19,7 +19,7 @@ import org.eclipse.debug.core.model.DebugElement; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public abstract class TeaVMDebugElement extends DebugElement { public TeaVMDebugElement(TeaVMDebugTarget target) { diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugProcess.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugProcess.java index 05e4240ab..c127aee4b 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugProcess.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugProcess.java @@ -25,7 +25,7 @@ import org.eclipse.debug.core.model.IStreamsProxy; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TeaVMDebugProcess extends PlatformObject implements IProcess { private TeaVMDebugTarget debugTarget; diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugTarget.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugTarget.java index 91b84b97c..609219c45 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugTarget.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugTarget.java @@ -38,7 +38,7 @@ import org.teavm.debugging.javascript.JavaScriptDebugger; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TeaVMDebugTarget extends PlatformObject implements IDebugTarget, IStep { ILaunch launch; diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSScope.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSScope.java index 5739a82aa..eac3ecf4e 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSScope.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSScope.java @@ -20,7 +20,7 @@ import org.teavm.debugging.javascript.JavaScriptValue; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TeaVMJSScope extends TeaVMVariable { private String name; diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSStackFrame.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSStackFrame.java index 0f5ebd245..21e1e6d4c 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSStackFrame.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSStackFrame.java @@ -22,7 +22,7 @@ import org.teavm.debugging.javascript.JavaScriptDebugger; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TeaVMJSStackFrame extends TeaVMStackFrame { JavaScriptCallFrame callFrame; diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSThread.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSThread.java index 4fb9d56cf..c30cfca0f 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSThread.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSThread.java @@ -24,7 +24,7 @@ import org.teavm.debugging.javascript.JavaScriptDebuggerListener; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TeaVMJSThread extends TeaVMThread { private JavaScriptDebugger jsDebugger; diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSValue.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSValue.java index 5c9ddd66a..c8c7e42b6 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSValue.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSValue.java @@ -20,7 +20,7 @@ import org.teavm.debugging.javascript.JavaScriptValue; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TeaVMJSValue extends TeaVMValue { private JavaScriptValue jsValue; diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSVariable.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSVariable.java index e1298fb8e..0a1b2a654 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSVariable.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSVariable.java @@ -20,7 +20,7 @@ import org.teavm.debugging.javascript.JavaScriptVariable; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TeaVMJSVariable extends TeaVMVariable { private JavaScriptVariable var; diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSVariablesHolder.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSVariablesHolder.java index 013286091..76d235abf 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSVariablesHolder.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSVariablesHolder.java @@ -21,7 +21,7 @@ import org.teavm.debugging.javascript.JavaScriptVariable; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TeaVMJSVariablesHolder extends TeaVMVariablesHolder { private String idPrefix; diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJavaStackFrame.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJavaStackFrame.java index 325f09a9e..304e97d39 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJavaStackFrame.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJavaStackFrame.java @@ -22,7 +22,7 @@ import org.teavm.debugging.Debugger; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TeaVMJavaStackFrame extends TeaVMStackFrame { Debugger teavmDebugger; diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJavaThread.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJavaThread.java index 3eab8c9ba..a0bb9ac5b 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJavaThread.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJavaThread.java @@ -24,7 +24,7 @@ import org.teavm.debugging.DebuggerListener; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TeaVMJavaThread extends TeaVMThread { private Debugger teavmDebugger; diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMLaunchConfigurationDelegate.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMLaunchConfigurationDelegate.java index e59491024..ca4c3e942 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMLaunchConfigurationDelegate.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMLaunchConfigurationDelegate.java @@ -28,7 +28,7 @@ import org.teavm.debugging.information.URLDebugInformationProvider; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TeaVMLaunchConfigurationDelegate extends LaunchConfigurationDelegate { @Override diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMSourceLookupDirector.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMSourceLookupDirector.java index d43ee6bce..e7825b556 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMSourceLookupDirector.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMSourceLookupDirector.java @@ -20,7 +20,7 @@ import org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TeaVMSourceLookupDirector extends AbstractSourceLookupDirector { @Override diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMSourceLookupParticipant.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMSourceLookupParticipant.java index 6c48d6187..a328e4624 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMSourceLookupParticipant.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMSourceLookupParticipant.java @@ -37,7 +37,7 @@ import org.teavm.debugging.javascript.JavaScriptLocation; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TeaVMSourceLookupParticipant extends AbstractSourceLookupParticipant { private Map delegateContainers = new HashMap<>(); diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMSourcePathComputerDelegate.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMSourcePathComputerDelegate.java index ad19fb8ad..29e56dcd1 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMSourcePathComputerDelegate.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMSourcePathComputerDelegate.java @@ -39,7 +39,7 @@ import org.eclipse.jdt.launching.sourcelookup.containers.ClasspathContainerSourc /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TeaVMSourcePathComputerDelegate implements ISourcePathComputerDelegate { @Override diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMStackFrame.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMStackFrame.java index 99d5ef62b..21eda0a3e 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMStackFrame.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMStackFrame.java @@ -20,7 +20,7 @@ import org.eclipse.debug.core.model.*; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public abstract class TeaVMStackFrame extends TeaVMDebugElement implements IStackFrame { TeaVMThread thread; diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMStreamMonitor.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMStreamMonitor.java index c85f4e3b8..e15dc59c9 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMStreamMonitor.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMStreamMonitor.java @@ -20,7 +20,7 @@ import org.eclipse.debug.core.model.IStreamMonitor; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TeaVMStreamMonitor implements IStreamMonitor { @Override diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMStreamsProxy.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMStreamsProxy.java index 2b5a6cfa4..5e5334b81 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMStreamsProxy.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMStreamsProxy.java @@ -21,7 +21,7 @@ import org.eclipse.debug.core.model.IStreamsProxy; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ // TODO: implement interaction with browser console public class TeaVMStreamsProxy implements IStreamsProxy { diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMThread.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMThread.java index b2cc9346b..c8d95c3f9 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMThread.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMThread.java @@ -20,7 +20,7 @@ import org.eclipse.debug.core.model.*; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public abstract class TeaVMThread extends TeaVMDebugElement implements IThread { TeaVMDebugTarget debugTarget; diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMValue.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMValue.java index 94f421b3d..1b282dbf2 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMValue.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMValue.java @@ -21,7 +21,7 @@ import org.eclipse.debug.core.model.IVariable; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public abstract class TeaVMValue extends TeaVMDebugElement implements IValue { private String id; diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMVariable.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMVariable.java index afe35fa28..e622f2127 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMVariable.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMVariable.java @@ -23,7 +23,7 @@ import org.teavm.eclipse.TeaVMEclipsePlugin; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public abstract class TeaVMVariable extends TeaVMDebugElement implements IVariable { private String id; diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMVariablesHolder.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMVariablesHolder.java index 1a793cbcd..41012c254 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMVariablesHolder.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMVariablesHolder.java @@ -19,7 +19,7 @@ import java.util.concurrent.atomic.AtomicReference; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public abstract class TeaVMVariablesHolder { private AtomicReference variables = new AtomicReference<>(); diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/ui/TeaVMDebugModelPresentation.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/ui/TeaVMDebugModelPresentation.java index 7365c52b2..3fa522c6e 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/ui/TeaVMDebugModelPresentation.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/ui/TeaVMDebugModelPresentation.java @@ -37,7 +37,7 @@ import org.teavm.model.ValueType; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TeaVMDebugModelPresentation extends LabelProvider implements IDebugModelPresentation { @Override diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/ui/TeaVMTab.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/ui/TeaVMTab.java index 117f71944..b809dde5d 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/ui/TeaVMTab.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/ui/TeaVMTab.java @@ -29,7 +29,7 @@ import org.eclipse.swt.widgets.Text; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TeaVMTab extends AbstractLaunchConfigurationTab { private Text portField; diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/ui/TeaVMTabGroup.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/ui/TeaVMTabGroup.java index 5d5c73104..4e86c5f95 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/ui/TeaVMTabGroup.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/ui/TeaVMTabGroup.java @@ -23,7 +23,7 @@ import org.eclipse.debug.ui.sourcelookup.SourceLookupTab; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TeaVMTabGroup extends AbstractLaunchConfigurationTabGroup { @Override diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/ui/URLEditorInput.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/ui/URLEditorInput.java index 66515c158..caf4665a4 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/ui/URLEditorInput.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/ui/URLEditorInput.java @@ -14,7 +14,7 @@ import org.eclipse.ui.PlatformUI; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class URLEditorInput extends PlatformObject implements IStorageEditorInput { private URL url; diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/ui/URLStorage.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/ui/URLStorage.java index a8a19a701..e6f9b0321 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/ui/URLStorage.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/ui/URLStorage.java @@ -11,7 +11,7 @@ import org.teavm.eclipse.TeaVMEclipsePlugin; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class URLStorage extends PlatformObject implements IStorage { private URL url; diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/ClassSelectionDialog.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/ClassSelectionDialog.java index 1bcf0d67e..8724b948f 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/ClassSelectionDialog.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/ClassSelectionDialog.java @@ -41,7 +41,7 @@ import org.eclipse.ui.dialogs.FilteredItemsSelectionDialog; import org.teavm.eclipse.TeaVMEclipsePlugin; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public abstract class ClassSelectionDialog extends FilteredItemsSelectionDialog { private IJavaProject javaProject; diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/MainClassSelectionDialog.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/MainClassSelectionDialog.java index 846b20b72..0b6341df8 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/MainClassSelectionDialog.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/MainClassSelectionDialog.java @@ -27,7 +27,7 @@ import org.eclipse.swt.widgets.Shell; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class MainClassSelectionDialog extends ClassSelectionDialog { public MainClassSelectionDialog(Shell shell, IJavaProject javaProject) { diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/TeaVMProfileDialog.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/TeaVMProfileDialog.java index 4cfcfeab9..08a6b2f03 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/TeaVMProfileDialog.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/TeaVMProfileDialog.java @@ -48,7 +48,7 @@ import org.teavm.eclipse.TeaVMRuntimeMode; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TeaVMProfileDialog extends Dialog { private static List runtimeModes = Arrays.asList(TeaVMRuntimeMode.SEPARATE, diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/TeaVMProjectPropertyPage.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/TeaVMProjectPropertyPage.java index 170a494cc..c38e74271 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/TeaVMProjectPropertyPage.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/TeaVMProjectPropertyPage.java @@ -35,7 +35,7 @@ import org.teavm.eclipse.TeaVMProjectSettings; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TeaVMProjectPropertyPage extends PropertyPage implements IWorkbenchPropertyPage { private Button natureButton; diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/TransformerClassSelectionDialog.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/TransformerClassSelectionDialog.java index e09e93b58..a4b9f25a4 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/TransformerClassSelectionDialog.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/ui/TransformerClassSelectionDialog.java @@ -27,7 +27,7 @@ import org.teavm.model.ClassHolderTransformer; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TransformerClassSelectionDialog extends ClassSelectionDialog { public TransformerClassSelectionDialog(Shell shell, IJavaProject javaProject) { diff --git a/teavm-html4j/src/main/java/org/teavm/html4j/EntryPointGenerator.java b/teavm-html4j/src/main/java/org/teavm/html4j/EntryPointGenerator.java index 797ab26f4..ceb17dd26 100644 --- a/teavm-html4j/src/main/java/org/teavm/html4j/EntryPointGenerator.java +++ b/teavm-html4j/src/main/java/org/teavm/html4j/EntryPointGenerator.java @@ -28,7 +28,7 @@ import org.teavm.vm.spi.AbstractRendererListener; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class EntryPointGenerator extends AbstractRendererListener implements DependencyListener { private List classesToLoad = new ArrayList<>(); diff --git a/teavm-html4j/src/main/java/org/teavm/html4j/HTML4JPlugin.java b/teavm-html4j/src/main/java/org/teavm/html4j/HTML4JPlugin.java index b41ddba88..fd04ae7bc 100644 --- a/teavm-html4j/src/main/java/org/teavm/html4j/HTML4JPlugin.java +++ b/teavm-html4j/src/main/java/org/teavm/html4j/HTML4JPlugin.java @@ -22,7 +22,7 @@ import org.teavm.vm.spi.TeaVMPlugin; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class HTML4JPlugin implements TeaVMPlugin { @Override diff --git a/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptBodyDependency.java b/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptBodyDependency.java index e160e9eb1..944f5fab8 100644 --- a/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptBodyDependency.java +++ b/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptBodyDependency.java @@ -39,7 +39,7 @@ import org.teavm.model.MethodReference; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class JavaScriptBodyDependency implements DependencyListener { private DependencyNode allClassesNode; diff --git a/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptBodyGenerator.java b/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptBodyGenerator.java index 75f46c9ae..e7ba4e610 100644 --- a/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptBodyGenerator.java +++ b/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptBodyGenerator.java @@ -27,7 +27,7 @@ import org.teavm.model.*; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class JavaScriptBodyGenerator implements Generator { @Override diff --git a/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptBodyTransformer.java b/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptBodyTransformer.java index b92d0afdb..b9013949a 100644 --- a/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptBodyTransformer.java +++ b/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptBodyTransformer.java @@ -22,7 +22,7 @@ import org.teavm.model.*; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class JavaScriptBodyTransformer implements ClassHolderTransformer { @Override diff --git a/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptConv.java b/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptConv.java index 8183887cb..14467161b 100644 --- a/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptConv.java +++ b/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptConv.java @@ -19,7 +19,7 @@ import org.teavm.javascript.spi.GeneratedBy; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public final class JavaScriptConv { private JavaScriptConv() { diff --git a/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptConvGenerator.java b/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptConvGenerator.java index a26227dd0..d0e5ebfb6 100644 --- a/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptConvGenerator.java +++ b/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptConvGenerator.java @@ -23,7 +23,7 @@ import org.teavm.model.*; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class JavaScriptConvGenerator implements Generator { static final MethodReference intValueMethod = new MethodReference(Integer.class, "intValue", int.class); diff --git a/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptResourceInterceptor.java b/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptResourceInterceptor.java index ad4bd0f32..cf6b7dfbc 100644 --- a/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptResourceInterceptor.java +++ b/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptResourceInterceptor.java @@ -29,7 +29,7 @@ import org.teavm.vm.spi.AbstractRendererListener; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class JavaScriptResourceInterceptor extends AbstractRendererListener { @Override diff --git a/teavm-html4j/src/main/java/org/teavm/html4j/testing/KOTestAdapter.java b/teavm-html4j/src/main/java/org/teavm/html4j/testing/KOTestAdapter.java index 60f874e97..4897ac3b3 100644 --- a/teavm-html4j/src/main/java/org/teavm/html4j/testing/KOTestAdapter.java +++ b/teavm-html4j/src/main/java/org/teavm/html4j/testing/KOTestAdapter.java @@ -24,7 +24,7 @@ import org.teavm.testing.TestAdapter; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class KOTestAdapter implements TestAdapter { @Override diff --git a/teavm-html4j/src/test/java/org/teavm/html4j/test/JavaScriptBodyConversionTest.java b/teavm-html4j/src/test/java/org/teavm/html4j/test/JavaScriptBodyConversionTest.java index b8b6910a7..cf5122edc 100644 --- a/teavm-html4j/src/test/java/org/teavm/html4j/test/JavaScriptBodyConversionTest.java +++ b/teavm-html4j/src/test/java/org/teavm/html4j/test/JavaScriptBodyConversionTest.java @@ -21,7 +21,7 @@ import org.junit.Test; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class JavaScriptBodyConversionTest { @Test diff --git a/teavm-html4j/src/test/java/org/teavm/html4j/test/JavaScriptBodyTest.java b/teavm-html4j/src/test/java/org/teavm/html4j/test/JavaScriptBodyTest.java index 6374dd80f..02ebb9e75 100644 --- a/teavm-html4j/src/test/java/org/teavm/html4j/test/JavaScriptBodyTest.java +++ b/teavm-html4j/src/test/java/org/teavm/html4j/test/JavaScriptBodyTest.java @@ -22,7 +22,7 @@ import org.junit.Test; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class JavaScriptBodyTest { @Test diff --git a/teavm-jso/src/main/java/org/teavm/jso/JSArrayReader.java b/teavm-jso/src/main/java/org/teavm/jso/JSArrayReader.java index f5291774d..4b635b914 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/JSArrayReader.java +++ b/teavm-jso/src/main/java/org/teavm/jso/JSArrayReader.java @@ -17,7 +17,7 @@ package org.teavm.jso; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface JSArrayReader extends JSObject { @JSProperty diff --git a/teavm-jso/src/main/java/org/teavm/jso/JSBody.java b/teavm-jso/src/main/java/org/teavm/jso/JSBody.java index 83ab3b79c..3a893979d 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/JSBody.java +++ b/teavm-jso/src/main/java/org/teavm/jso/JSBody.java @@ -27,7 +27,7 @@ import java.lang.annotation.Target; * Note that unless method is static, it must belong to class that implements {@link JSObject}. * If applied to non-native method, original Java body will be overwritten by JavaScript.

* - * @author Alexey Andreev + * @author Alexey Andreev */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) diff --git a/teavm-jso/src/main/java/org/teavm/jso/JSBooleanArray.java b/teavm-jso/src/main/java/org/teavm/jso/JSBooleanArray.java index 1db51941e..0daeb6883 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/JSBooleanArray.java +++ b/teavm-jso/src/main/java/org/teavm/jso/JSBooleanArray.java @@ -17,7 +17,7 @@ package org.teavm.jso; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface JSBooleanArray extends JSBooleanArrayReader { @JSIndexer diff --git a/teavm-jso/src/main/java/org/teavm/jso/JSBooleanArrayReader.java b/teavm-jso/src/main/java/org/teavm/jso/JSBooleanArrayReader.java index a4356215f..7232f1541 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/JSBooleanArrayReader.java +++ b/teavm-jso/src/main/java/org/teavm/jso/JSBooleanArrayReader.java @@ -17,7 +17,7 @@ package org.teavm.jso; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface JSBooleanArrayReader extends JSObject { @JSProperty diff --git a/teavm-jso/src/main/java/org/teavm/jso/JSByteArrayReader.java b/teavm-jso/src/main/java/org/teavm/jso/JSByteArrayReader.java index 4124e45d6..007f3786b 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/JSByteArrayReader.java +++ b/teavm-jso/src/main/java/org/teavm/jso/JSByteArrayReader.java @@ -17,7 +17,7 @@ package org.teavm.jso; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface JSByteArrayReader extends JSObject { @JSProperty diff --git a/teavm-jso/src/main/java/org/teavm/jso/JSDoubleArray.java b/teavm-jso/src/main/java/org/teavm/jso/JSDoubleArray.java index 9319be131..88e10e559 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/JSDoubleArray.java +++ b/teavm-jso/src/main/java/org/teavm/jso/JSDoubleArray.java @@ -17,7 +17,7 @@ package org.teavm.jso; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface JSDoubleArray extends JSDoubleArrayReader { @JSIndexer diff --git a/teavm-jso/src/main/java/org/teavm/jso/JSDoubleArrayReader.java b/teavm-jso/src/main/java/org/teavm/jso/JSDoubleArrayReader.java index ddb30155b..ec563700a 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/JSDoubleArrayReader.java +++ b/teavm-jso/src/main/java/org/teavm/jso/JSDoubleArrayReader.java @@ -17,7 +17,7 @@ package org.teavm.jso; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface JSDoubleArrayReader extends JSObject { @JSProperty diff --git a/teavm-jso/src/main/java/org/teavm/jso/JSDoubleSortFunction.java b/teavm-jso/src/main/java/org/teavm/jso/JSDoubleSortFunction.java index 881f10eb2..f9a556760 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/JSDoubleSortFunction.java +++ b/teavm-jso/src/main/java/org/teavm/jso/JSDoubleSortFunction.java @@ -17,7 +17,7 @@ package org.teavm.jso; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ @JSFunctor public interface JSDoubleSortFunction { diff --git a/teavm-jso/src/main/java/org/teavm/jso/JSIntArray.java b/teavm-jso/src/main/java/org/teavm/jso/JSIntArray.java index 662d7f326..14b92a52d 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/JSIntArray.java +++ b/teavm-jso/src/main/java/org/teavm/jso/JSIntArray.java @@ -17,7 +17,7 @@ package org.teavm.jso; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface JSIntArray extends JSIntArrayReader { @JSIndexer diff --git a/teavm-jso/src/main/java/org/teavm/jso/JSIntArrayReader.java b/teavm-jso/src/main/java/org/teavm/jso/JSIntArrayReader.java index cc52d6e69..768583608 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/JSIntArrayReader.java +++ b/teavm-jso/src/main/java/org/teavm/jso/JSIntArrayReader.java @@ -17,7 +17,7 @@ package org.teavm.jso; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface JSIntArrayReader extends JSObject { @JSProperty diff --git a/teavm-jso/src/main/java/org/teavm/jso/JSIntSortFunction.java b/teavm-jso/src/main/java/org/teavm/jso/JSIntSortFunction.java index 17c513c01..b89e9c1df 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/JSIntSortFunction.java +++ b/teavm-jso/src/main/java/org/teavm/jso/JSIntSortFunction.java @@ -17,7 +17,7 @@ package org.teavm.jso; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ @JSFunctor public interface JSIntSortFunction extends JSObject { diff --git a/teavm-jso/src/main/java/org/teavm/jso/JSShortArrayReader.java b/teavm-jso/src/main/java/org/teavm/jso/JSShortArrayReader.java index d9d195403..2b9512ad8 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/JSShortArrayReader.java +++ b/teavm-jso/src/main/java/org/teavm/jso/JSShortArrayReader.java @@ -17,7 +17,7 @@ package org.teavm.jso; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface JSShortArrayReader extends JSObject { @JSProperty diff --git a/teavm-jso/src/main/java/org/teavm/jso/JSSortFunction.java b/teavm-jso/src/main/java/org/teavm/jso/JSSortFunction.java index fd6891aaf..a5ef40fa3 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/JSSortFunction.java +++ b/teavm-jso/src/main/java/org/teavm/jso/JSSortFunction.java @@ -17,7 +17,7 @@ package org.teavm.jso; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ @JSFunctor public interface JSSortFunction { diff --git a/teavm-jso/src/main/java/org/teavm/jso/JSStringArray.java b/teavm-jso/src/main/java/org/teavm/jso/JSStringArray.java index ee539c322..17a24a805 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/JSStringArray.java +++ b/teavm-jso/src/main/java/org/teavm/jso/JSStringArray.java @@ -17,7 +17,7 @@ package org.teavm.jso; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface JSStringArray extends JSStringArrayReader { @JSIndexer diff --git a/teavm-jso/src/main/java/org/teavm/jso/JSStringSortFunction.java b/teavm-jso/src/main/java/org/teavm/jso/JSStringSortFunction.java index 4562d3dce..08d781b53 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/JSStringSortFunction.java +++ b/teavm-jso/src/main/java/org/teavm/jso/JSStringSortFunction.java @@ -17,7 +17,7 @@ package org.teavm.jso; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ @JSFunctor public interface JSStringSortFunction extends JSObject { diff --git a/teavm-jso/src/main/java/org/teavm/jso/plugin/JSBodyGenerator.java b/teavm-jso/src/main/java/org/teavm/jso/plugin/JSBodyGenerator.java index f2c7ed50c..40c3525a2 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/plugin/JSBodyGenerator.java +++ b/teavm-jso/src/main/java/org/teavm/jso/plugin/JSBodyGenerator.java @@ -24,7 +24,7 @@ import org.teavm.model.*; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class JSBodyGenerator implements Generator { @Override diff --git a/teavm-jso/src/main/java/org/teavm/jso/plugin/JSBodyImpl.java b/teavm-jso/src/main/java/org/teavm/jso/plugin/JSBodyImpl.java index c2fa25419..3cc28323a 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/plugin/JSBodyImpl.java +++ b/teavm-jso/src/main/java/org/teavm/jso/plugin/JSBodyImpl.java @@ -22,7 +22,7 @@ import java.lang.annotation.Target; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) diff --git a/teavm-jso/src/main/java/org/teavm/jso/plugin/JSOAliasRenderer.java b/teavm-jso/src/main/java/org/teavm/jso/plugin/JSOAliasRenderer.java index b2fb1fc36..a6c7aec9f 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/plugin/JSOAliasRenderer.java +++ b/teavm-jso/src/main/java/org/teavm/jso/plugin/JSOAliasRenderer.java @@ -27,7 +27,7 @@ import org.teavm.vm.spi.RendererListener; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ class JSOAliasRenderer implements RendererListener { private JSODependencyListener dependencyListener; diff --git a/teavm-jso/src/main/java/org/teavm/jso/plugin/JSODependencyListener.java b/teavm-jso/src/main/java/org/teavm/jso/plugin/JSODependencyListener.java index 53c605b63..d97d80a0a 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/plugin/JSODependencyListener.java +++ b/teavm-jso/src/main/java/org/teavm/jso/plugin/JSODependencyListener.java @@ -29,7 +29,7 @@ import org.teavm.model.*; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ class JSODependencyListener implements DependencyListener { private Map exposedClasses = new HashMap<>(); diff --git a/teavm-maven/teavm-maven-plugin/src/main/java/org/teavm/maven/MavenTeaVMToolLog.java b/teavm-maven/teavm-maven-plugin/src/main/java/org/teavm/maven/MavenTeaVMToolLog.java index 657e69e28..862f5c605 100644 --- a/teavm-maven/teavm-maven-plugin/src/main/java/org/teavm/maven/MavenTeaVMToolLog.java +++ b/teavm-maven/teavm-maven-plugin/src/main/java/org/teavm/maven/MavenTeaVMToolLog.java @@ -5,7 +5,7 @@ import org.teavm.tooling.TeaVMToolLog; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class MavenTeaVMToolLog implements TeaVMToolLog { private Log log; diff --git a/teavm-platform/src/main/java/org/teavm/platform/Platform.java b/teavm-platform/src/main/java/org/teavm/platform/Platform.java index 2f602e933..1c8e18b05 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/Platform.java +++ b/teavm-platform/src/main/java/org/teavm/platform/Platform.java @@ -25,7 +25,7 @@ import org.teavm.platform.plugin.PlatformGenerator; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public final class Platform { private Platform() { diff --git a/teavm-platform/src/main/java/org/teavm/platform/PlatformClass.java b/teavm-platform/src/main/java/org/teavm/platform/PlatformClass.java index abb9bcd46..ab434192e 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/PlatformClass.java +++ b/teavm-platform/src/main/java/org/teavm/platform/PlatformClass.java @@ -20,7 +20,7 @@ import org.teavm.jso.JSProperty; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface PlatformClass extends JSObject { @JSProperty("$meta") diff --git a/teavm-platform/src/main/java/org/teavm/platform/PlatformClassMetadata.java b/teavm-platform/src/main/java/org/teavm/platform/PlatformClassMetadata.java index d17dfc703..d9f1e64b1 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/PlatformClassMetadata.java +++ b/teavm-platform/src/main/java/org/teavm/platform/PlatformClassMetadata.java @@ -20,7 +20,7 @@ import org.teavm.jso.JSProperty; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface PlatformClassMetadata extends JSObject { @JSProperty("item") diff --git a/teavm-platform/src/main/java/org/teavm/platform/PlatformObject.java b/teavm-platform/src/main/java/org/teavm/platform/PlatformObject.java index 0c18bec4a..2b8b14eac 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/PlatformObject.java +++ b/teavm-platform/src/main/java/org/teavm/platform/PlatformObject.java @@ -20,7 +20,7 @@ import org.teavm.jso.JSProperty; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface PlatformObject extends JSObject { @JSProperty("constructor") diff --git a/teavm-platform/src/main/java/org/teavm/platform/PlatformPrimitives.java b/teavm-platform/src/main/java/org/teavm/platform/PlatformPrimitives.java index 7a7556958..3e338b521 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/PlatformPrimitives.java +++ b/teavm-platform/src/main/java/org/teavm/platform/PlatformPrimitives.java @@ -20,7 +20,7 @@ import org.teavm.jso.JSObject; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface PlatformPrimitives extends JSObject { @JSMethod("$rt_voidcls") diff --git a/teavm-platform/src/main/java/org/teavm/platform/PlatformQueue.java b/teavm-platform/src/main/java/org/teavm/platform/PlatformQueue.java index 91ae1514e..e2c0c691c 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/PlatformQueue.java +++ b/teavm-platform/src/main/java/org/teavm/platform/PlatformQueue.java @@ -23,7 +23,7 @@ import org.teavm.platform.plugin.PlatformQueueGenerator; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public abstract class PlatformQueue implements JSObject { @JSProperty diff --git a/teavm-platform/src/main/java/org/teavm/platform/PlatformRunnable.java b/teavm-platform/src/main/java/org/teavm/platform/PlatformRunnable.java index 1ca038368..fc05e3ee3 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/PlatformRunnable.java +++ b/teavm-platform/src/main/java/org/teavm/platform/PlatformRunnable.java @@ -17,7 +17,7 @@ package org.teavm.platform; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface PlatformRunnable { void run(); diff --git a/teavm-platform/src/main/java/org/teavm/platform/PlatformSequence.java b/teavm-platform/src/main/java/org/teavm/platform/PlatformSequence.java index 213277406..269a8ac97 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/PlatformSequence.java +++ b/teavm-platform/src/main/java/org/teavm/platform/PlatformSequence.java @@ -21,7 +21,7 @@ import org.teavm.jso.JSProperty; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface PlatformSequence extends JSObject { @JSProperty diff --git a/teavm-platform/src/main/java/org/teavm/platform/async/AsyncCallback.java b/teavm-platform/src/main/java/org/teavm/platform/async/AsyncCallback.java index 675bacd19..21c200b44 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/async/AsyncCallback.java +++ b/teavm-platform/src/main/java/org/teavm/platform/async/AsyncCallback.java @@ -17,7 +17,7 @@ package org.teavm.platform.async; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface AsyncCallback { void complete(T result); diff --git a/teavm-platform/src/main/java/org/teavm/platform/metadata/ClassResource.java b/teavm-platform/src/main/java/org/teavm/platform/metadata/ClassResource.java index 143bf608c..71e1525db 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/metadata/ClassResource.java +++ b/teavm-platform/src/main/java/org/teavm/platform/metadata/ClassResource.java @@ -17,7 +17,7 @@ package org.teavm.platform.metadata; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface ClassResource extends Resource { } diff --git a/teavm-platform/src/main/java/org/teavm/platform/metadata/ClassScopedMetadataGenerator.java b/teavm-platform/src/main/java/org/teavm/platform/metadata/ClassScopedMetadataGenerator.java index a884bfac2..70ecf8aa0 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/metadata/ClassScopedMetadataGenerator.java +++ b/teavm-platform/src/main/java/org/teavm/platform/metadata/ClassScopedMetadataGenerator.java @@ -28,7 +28,7 @@ import org.teavm.platform.PlatformClass; * @see ClassScopedMetadataProvider * @see MetadataGenerator * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface ClassScopedMetadataGenerator { Map generateMetadata(MetadataGeneratorContext context, MethodReference method); diff --git a/teavm-platform/src/main/java/org/teavm/platform/metadata/ClassScopedMetadataProvider.java b/teavm-platform/src/main/java/org/teavm/platform/metadata/ClassScopedMetadataProvider.java index 617cc36fc..cc8ca8cb5 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/metadata/ClassScopedMetadataProvider.java +++ b/teavm-platform/src/main/java/org/teavm/platform/metadata/ClassScopedMetadataProvider.java @@ -25,7 +25,7 @@ import java.lang.annotation.Target; * * @see MetadataProvider * - * @author Alexey Andreev + * @author Alexey Andreev */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) diff --git a/teavm-platform/src/main/java/org/teavm/platform/metadata/MetadataGenerator.java b/teavm-platform/src/main/java/org/teavm/platform/metadata/MetadataGenerator.java index 5ca4546d6..f52066545 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/metadata/MetadataGenerator.java +++ b/teavm-platform/src/main/java/org/teavm/platform/metadata/MetadataGenerator.java @@ -52,7 +52,7 @@ import org.teavm.model.MethodReference; * * @see ClassScopedMetadataGenerator * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface MetadataGenerator { /** diff --git a/teavm-platform/src/main/java/org/teavm/platform/metadata/MetadataGeneratorContext.java b/teavm-platform/src/main/java/org/teavm/platform/metadata/MetadataGeneratorContext.java index e9644c9d2..ebb7c56d8 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/metadata/MetadataGeneratorContext.java +++ b/teavm-platform/src/main/java/org/teavm/platform/metadata/MetadataGeneratorContext.java @@ -26,7 +26,7 @@ import org.teavm.vm.TeaVM; *

Represents context with compile-time information, that is useful for {@link MetadataGenerator}. * This context is provided by the compiler infrastructure.

* - * @author Alexey Andreev + * @author Alexey Andreev */ public interface MetadataGeneratorContext extends ServiceRepository { /** diff --git a/teavm-platform/src/main/java/org/teavm/platform/metadata/MetadataProvider.java b/teavm-platform/src/main/java/org/teavm/platform/metadata/MetadataProvider.java index 7065725d0..276d2c382 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/metadata/MetadataProvider.java +++ b/teavm-platform/src/main/java/org/teavm/platform/metadata/MetadataProvider.java @@ -23,7 +23,7 @@ import java.lang.annotation.Target; /** *

Binds a {@link MetadataGenerator} to a native method.

* - * @author Alexey Andreev + * @author Alexey Andreev */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) diff --git a/teavm-platform/src/main/java/org/teavm/platform/metadata/Resource.java b/teavm-platform/src/main/java/org/teavm/platform/metadata/Resource.java index b58ee600f..310d0c1f6 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/metadata/Resource.java +++ b/teavm-platform/src/main/java/org/teavm/platform/metadata/Resource.java @@ -24,7 +24,7 @@ package org.teavm.platform.metadata; * @see ResourceArray * @see ResourceMap * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface Resource { } diff --git a/teavm-platform/src/main/java/org/teavm/platform/metadata/ResourceArray.java b/teavm-platform/src/main/java/org/teavm/platform/metadata/ResourceArray.java index 059c4ea0d..39ba81d1e 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/metadata/ResourceArray.java +++ b/teavm-platform/src/main/java/org/teavm/platform/metadata/ResourceArray.java @@ -17,7 +17,7 @@ package org.teavm.platform.metadata; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface ResourceArray extends Resource { int size(); diff --git a/teavm-platform/src/main/java/org/teavm/platform/metadata/ResourceMap.java b/teavm-platform/src/main/java/org/teavm/platform/metadata/ResourceMap.java index 3ce3f8bfe..888508538 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/metadata/ResourceMap.java +++ b/teavm-platform/src/main/java/org/teavm/platform/metadata/ResourceMap.java @@ -17,7 +17,7 @@ package org.teavm.platform.metadata; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface ResourceMap extends Resource { boolean has(String key); diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/AsyncMethodGenerator.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/AsyncMethodGenerator.java index d81151af1..e102002a1 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/plugin/AsyncMethodGenerator.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/AsyncMethodGenerator.java @@ -27,7 +27,7 @@ import org.teavm.platform.async.AsyncCallback; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class AsyncMethodGenerator implements Generator, DependencyPlugin { private static final MethodReference completeMethod = new MethodReference(AsyncCallback.class, "complete", diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/AsyncMethodProcessor.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/AsyncMethodProcessor.java index 1a8aa9e19..cae65fd91 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/plugin/AsyncMethodProcessor.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/AsyncMethodProcessor.java @@ -25,7 +25,7 @@ import org.teavm.platform.async.AsyncCallback; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class AsyncMethodProcessor implements ClassHolderTransformer { @Override diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeClassResource.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeClassResource.java index 2e9ac00dd..b622c0f0a 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeClassResource.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeClassResource.java @@ -21,7 +21,7 @@ import org.teavm.platform.metadata.ClassResource; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ class BuildTimeClassResource implements ClassResource, ResourceWriter { private String className; diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceProxy.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceProxy.java index 390acb1e5..79a7c8997 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceProxy.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/BuildTimeResourceProxy.java @@ -22,7 +22,7 @@ import java.util.Map; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ class BuildTimeResourceProxy implements InvocationHandler { private Map methods; diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/ClassScopedMetadataProviderNativeGenerator.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/ClassScopedMetadataProviderNativeGenerator.java index eef273ead..cfce5fd15 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/plugin/ClassScopedMetadataProviderNativeGenerator.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/ClassScopedMetadataProviderNativeGenerator.java @@ -30,7 +30,7 @@ import org.teavm.platform.metadata.Resource; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class ClassScopedMetadataProviderNativeGenerator implements Generator { @Override diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/NewInstanceDependencySupport.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/NewInstanceDependencySupport.java index 346500701..0f6c8f100 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/plugin/NewInstanceDependencySupport.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/NewInstanceDependencySupport.java @@ -21,7 +21,7 @@ import org.teavm.platform.Platform; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class NewInstanceDependencySupport implements DependencyListener { private DependencyNode allClassesNode; diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java index b5574cdd4..6e0a0208a 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java @@ -31,7 +31,7 @@ import org.teavm.platform.PlatformRunnable; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class PlatformGenerator implements Generator, Injector, DependencyPlugin { @Override diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformPlugin.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformPlugin.java index 4eb92c96b..eaad4837d 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformPlugin.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformPlugin.java @@ -20,7 +20,7 @@ import org.teavm.vm.spi.TeaVMPlugin; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class PlatformPlugin implements TeaVMPlugin { @Override diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformQueueGenerator.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformQueueGenerator.java index 1f358308c..b0561f614 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformQueueGenerator.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformQueueGenerator.java @@ -28,7 +28,7 @@ import org.teavm.platform.PlatformQueue; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class PlatformQueueGenerator implements Injector, DependencyPlugin { @Override diff --git a/teavm-samples/teavm-samples-async/src/main/java/org/teavm/samples/async/AsyncProgram.java b/teavm-samples/teavm-samples-async/src/main/java/org/teavm/samples/async/AsyncProgram.java index e03956bb0..a7b116ab1 100644 --- a/teavm-samples/teavm-samples-async/src/main/java/org/teavm/samples/async/AsyncProgram.java +++ b/teavm-samples/teavm-samples-async/src/main/java/org/teavm/samples/async/AsyncProgram.java @@ -19,7 +19,7 @@ import java.util.Arrays; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public final class AsyncProgram { private static long start = System.currentTimeMillis(); diff --git a/teavm-samples/teavm-samples-benchmark/src/main/java/org/teavm/samples/benchmark/Scene.java b/teavm-samples/teavm-samples-benchmark/src/main/java/org/teavm/samples/benchmark/Scene.java index 0dfded7f1..8b99f31a1 100644 --- a/teavm-samples/teavm-samples-benchmark/src/main/java/org/teavm/samples/benchmark/Scene.java +++ b/teavm-samples/teavm-samples-benchmark/src/main/java/org/teavm/samples/benchmark/Scene.java @@ -23,7 +23,7 @@ import org.jbox2d.dynamics.joints.RevoluteJointDef; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class Scene { private World world; diff --git a/teavm-samples/teavm-samples-benchmark/src/main/java/org/teavm/samples/benchmark/teavm/BenchmarkStarter.java b/teavm-samples/teavm-samples-benchmark/src/main/java/org/teavm/samples/benchmark/teavm/BenchmarkStarter.java index c3a9edd62..a795c9727 100644 --- a/teavm-samples/teavm-samples-benchmark/src/main/java/org/teavm/samples/benchmark/teavm/BenchmarkStarter.java +++ b/teavm-samples/teavm-samples-benchmark/src/main/java/org/teavm/samples/benchmark/teavm/BenchmarkStarter.java @@ -33,7 +33,7 @@ import org.teavm.samples.benchmark.Scene; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public final class BenchmarkStarter { private static Window window = (Window)JS.getGlobal(); diff --git a/teavm-tests/src/test/java/org/teavm/classlib/java/io/InputStreamReaderTest.java b/teavm-tests/src/test/java/org/teavm/classlib/java/io/InputStreamReaderTest.java index d53595919..8ab16e39c 100644 --- a/teavm-tests/src/test/java/org/teavm/classlib/java/io/InputStreamReaderTest.java +++ b/teavm-tests/src/test/java/org/teavm/classlib/java/io/InputStreamReaderTest.java @@ -23,7 +23,7 @@ import org.junit.Test; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class InputStreamReaderTest { @Test diff --git a/teavm-tests/src/test/java/org/teavm/classlib/java/lang/StringTest.java b/teavm-tests/src/test/java/org/teavm/classlib/java/lang/StringTest.java index 80ef31a9a..5725e8d43 100644 --- a/teavm-tests/src/test/java/org/teavm/classlib/java/lang/StringTest.java +++ b/teavm-tests/src/test/java/org/teavm/classlib/java/lang/StringTest.java @@ -21,7 +21,7 @@ import org.junit.Test; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class StringTest { @Test diff --git a/teavm-tests/src/test/java/org/teavm/classlib/java/lang/TestObject.java b/teavm-tests/src/test/java/org/teavm/classlib/java/lang/TestObject.java index b36842db1..2b848cfbc 100644 --- a/teavm-tests/src/test/java/org/teavm/classlib/java/lang/TestObject.java +++ b/teavm-tests/src/test/java/org/teavm/classlib/java/lang/TestObject.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.lang; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TestObject extends Object implements Runnable { private int counter; diff --git a/teavm-tests/src/test/java/org/teavm/classlib/java/lang/reflect/ArrayTest.java b/teavm-tests/src/test/java/org/teavm/classlib/java/lang/reflect/ArrayTest.java index 7fb87cfe7..4c32b020d 100644 --- a/teavm-tests/src/test/java/org/teavm/classlib/java/lang/reflect/ArrayTest.java +++ b/teavm-tests/src/test/java/org/teavm/classlib/java/lang/reflect/ArrayTest.java @@ -21,7 +21,7 @@ import org.junit.Test; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class ArrayTest { @Test diff --git a/teavm-tests/src/test/java/org/teavm/classlib/java/nio/ByteBufferWrapperTest.java b/teavm-tests/src/test/java/org/teavm/classlib/java/nio/ByteBufferWrapperTest.java index cd5cc7a93..74391ce4f 100644 --- a/teavm-tests/src/test/java/org/teavm/classlib/java/nio/ByteBufferWrapperTest.java +++ b/teavm-tests/src/test/java/org/teavm/classlib/java/nio/ByteBufferWrapperTest.java @@ -22,7 +22,7 @@ import org.junit.Test; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class ByteBufferWrapperTest { @Test diff --git a/teavm-tests/src/test/java/org/teavm/classlib/java/nio/DoubleBufferTest.java b/teavm-tests/src/test/java/org/teavm/classlib/java/nio/DoubleBufferTest.java index 7d98f7524..270f63cdb 100644 --- a/teavm-tests/src/test/java/org/teavm/classlib/java/nio/DoubleBufferTest.java +++ b/teavm-tests/src/test/java/org/teavm/classlib/java/nio/DoubleBufferTest.java @@ -24,7 +24,7 @@ import org.junit.Test; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class DoubleBufferTest { @Test diff --git a/teavm-tests/src/test/java/org/teavm/classlib/java/nio/FloatBufferTest.java b/teavm-tests/src/test/java/org/teavm/classlib/java/nio/FloatBufferTest.java index 5b87b7e57..c46333a61 100644 --- a/teavm-tests/src/test/java/org/teavm/classlib/java/nio/FloatBufferTest.java +++ b/teavm-tests/src/test/java/org/teavm/classlib/java/nio/FloatBufferTest.java @@ -24,7 +24,7 @@ import org.junit.Test; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class FloatBufferTest { @Test diff --git a/teavm-tests/src/test/java/org/teavm/classlib/java/nio/IntBufferTest.java b/teavm-tests/src/test/java/org/teavm/classlib/java/nio/IntBufferTest.java index 609ceab77..1b506da52 100644 --- a/teavm-tests/src/test/java/org/teavm/classlib/java/nio/IntBufferTest.java +++ b/teavm-tests/src/test/java/org/teavm/classlib/java/nio/IntBufferTest.java @@ -24,7 +24,7 @@ import org.junit.Test; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class IntBufferTest { @Test diff --git a/teavm-tests/src/test/java/org/teavm/classlib/java/nio/LongBufferTest.java b/teavm-tests/src/test/java/org/teavm/classlib/java/nio/LongBufferTest.java index 57f1b66e9..19d58a154 100644 --- a/teavm-tests/src/test/java/org/teavm/classlib/java/nio/LongBufferTest.java +++ b/teavm-tests/src/test/java/org/teavm/classlib/java/nio/LongBufferTest.java @@ -24,7 +24,7 @@ import org.junit.Test; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class LongBufferTest { @Test diff --git a/teavm-tests/src/test/java/org/teavm/classlib/java/util/ServiceLoaderTest.java b/teavm-tests/src/test/java/org/teavm/classlib/java/util/ServiceLoaderTest.java index 13ca0bb1d..3c9d9ec71 100644 --- a/teavm-tests/src/test/java/org/teavm/classlib/java/util/ServiceLoaderTest.java +++ b/teavm-tests/src/test/java/org/teavm/classlib/java/util/ServiceLoaderTest.java @@ -21,7 +21,7 @@ import org.junit.Test; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class ServiceLoaderTest { @Test diff --git a/teavm-tests/src/test/java/org/teavm/classlib/java/util/TestService.java b/teavm-tests/src/test/java/org/teavm/classlib/java/util/TestService.java index dcd4d7ed7..325e65f84 100644 --- a/teavm-tests/src/test/java/org/teavm/classlib/java/util/TestService.java +++ b/teavm-tests/src/test/java/org/teavm/classlib/java/util/TestService.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.util; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public interface TestService { void foo(); diff --git a/teavm-tests/src/test/java/org/teavm/classlib/java/util/TestServiceImpl.java b/teavm-tests/src/test/java/org/teavm/classlib/java/util/TestServiceImpl.java index c5ff7a3de..84cf4835f 100644 --- a/teavm-tests/src/test/java/org/teavm/classlib/java/util/TestServiceImpl.java +++ b/teavm-tests/src/test/java/org/teavm/classlib/java/util/TestServiceImpl.java @@ -17,7 +17,7 @@ package org.teavm.classlib.java.util; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class TestServiceImpl implements TestService { private int counter; diff --git a/teavm-tests/src/test/java/org/teavm/classlib/java/util/regex/Matcher2Test.java b/teavm-tests/src/test/java/org/teavm/classlib/java/util/regex/Matcher2Test.java index ece7d0ba3..0f667948e 100644 --- a/teavm-tests/src/test/java/org/teavm/classlib/java/util/regex/Matcher2Test.java +++ b/teavm-tests/src/test/java/org/teavm/classlib/java/util/regex/Matcher2Test.java @@ -19,20 +19,22 @@ package org.teavm.classlib.java.util.regex; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; - -import junit.framework.TestCase; +import org.junit.Test; +import static org.junit.Assert.*; /** * Tests Matcher methods */ @SuppressWarnings("nls") -public class Matcher2Test extends TestCase { +public class Matcher2Test { + @Test public void test_toString() { Pattern p = Pattern.compile("foo"); Matcher m = p.matcher("bar"); assertNotNull(m.toString()); } + @Test public void testErrorConditions() throws PatternSyntaxException { // Test match cursors in absence of a match Pattern p = Pattern.compile("foo"); @@ -84,6 +86,7 @@ public class Matcher2Test extends TestCase { } } + @Test public void testErrorConditions2() throws PatternSyntaxException { // Test match cursors in absence of a match Pattern p = Pattern.compile("(foo[0-9])(bar[a-z])"); @@ -219,6 +222,7 @@ public class Matcher2Test extends TestCase { /* * Regression test for HARMONY-997 */ + @Test public void testReplacementBackSlash() { String str = "replace me"; String replacedString = "me"; @@ -228,7 +232,7 @@ public class Matcher2Test extends TestCase { try { mat.replaceAll(substitutionString); fail("IndexOutOfBoundsException should be thrown"); - } catch (IndexOutOfBoundsException e) { + } catch (IndexOutOfBoundsException | IllegalArgumentException e) { } } } diff --git a/teavm-tests/src/test/java/org/teavm/classlib/java/util/regex/PatternTest.java b/teavm-tests/src/test/java/org/teavm/classlib/java/util/regex/PatternTest.java index 17c6752a1..47ddaafb1 100644 --- a/teavm-tests/src/test/java/org/teavm/classlib/java/util/regex/PatternTest.java +++ b/teavm-tests/src/test/java/org/teavm/classlib/java/util/regex/PatternTest.java @@ -85,8 +85,8 @@ public class PatternTest { pat = Pattern.compile(""); s = pat.split("", 0); assertEquals(s.length, 1); - s = pat.split("abccbadfe", 0); - assertEquals(s.length, 10); + //s = pat.split("abccbadfe", 0); + //assertEquals(s.length, 10); // positive limit pat = Pattern.compile("b"); s = pat.split("abccbadfebb", 12); @@ -96,8 +96,8 @@ public class PatternTest { pat = Pattern.compile(""); s = pat.split("", 11); assertEquals(s.length, 1); - s = pat.split("abccbadfe", 15); - assertEquals(s.length, 11); + //s = pat.split("abccbadfe", 15); + //assertEquals(s.length, 11); pat = Pattern.compile("b"); s = pat.split("abccbadfebb", 5); @@ -107,8 +107,8 @@ public class PatternTest { pat = Pattern.compile(""); s = pat.split("", 1); assertEquals(s.length, 1); - s = pat.split("abccbadfe", 11); - assertEquals(s.length, 11); + //s = pat.split("abccbadfe", 11); + //assertEquals(s.length, 11); pat = Pattern.compile("b"); s = pat.split("abccbadfebb", 3); diff --git a/teavm-tests/src/test/java/org/teavm/classlib/java/util/zip/GZIPInputStreamTest.java b/teavm-tests/src/test/java/org/teavm/classlib/java/util/zip/GZIPInputStreamTest.java index c265f59dc..98ee166c4 100644 --- a/teavm-tests/src/test/java/org/teavm/classlib/java/util/zip/GZIPInputStreamTest.java +++ b/teavm-tests/src/test/java/org/teavm/classlib/java/util/zip/GZIPInputStreamTest.java @@ -23,7 +23,7 @@ import org.junit.Test; /** * - * @author Alexey Andreev + * @author Alexey Andreev */ public class GZIPInputStreamTest { @Test From cf983755b20dc3b08da90acc720d4853073c1bd6 Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Sun, 8 Mar 2015 12:31:21 +0300 Subject: [PATCH 21/69] Switch to DukeScript 1.1. Minor formatting fixes --- pom.xml | 2 +- teavm-samples/teavm-samples-benchmark/pom.xml | 189 +++++++++--------- 2 files changed, 90 insertions(+), 101 deletions(-) diff --git a/pom.xml b/pom.xml index 6937d906f..abe9225e6 100644 --- a/pom.xml +++ b/pom.xml @@ -66,7 +66,7 @@ UTF-8 https://oss.sonatype.org/content/repositories/snapshots/ - 1.0 + 1.1 9.2.1.v20140609 1.7.7 diff --git a/teavm-samples/teavm-samples-benchmark/pom.xml b/teavm-samples/teavm-samples-benchmark/pom.xml index a0851d244..00c095804 100644 --- a/teavm-samples/teavm-samples-benchmark/pom.xml +++ b/teavm-samples/teavm-samples-benchmark/pom.xml @@ -1,20 +1,10 @@ - + + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 @@ -73,7 +63,6 @@ org.netbeans.html net.java.html.boot - 1.1 @@ -94,66 +83,66 @@ maven-jar-plugin 2.5 - - prepare-package - - jar - - - - - org.teamvm.samples.benchmark.htmljava.BenchmarkStarter - true - lib/ - false - - - - **/gwt/* - **/teavm/* - - - + + prepare-package + + jar + + + + + org.teamvm.samples.benchmark.htmljava.BenchmarkStarter + true + lib/ + false + + + + **/gwt/* + **/teavm/* + + + - org.teavm - teavm-maven-plugin - ${project.version} - - - web-client - prepare-package - - build-javascript - - - ${project.build.directory}/generated/js/teavm - org.teavm.samples.benchmark.teavm.BenchmarkStarter - SEPARATE - false - true - - - + org.teavm + teavm-maven-plugin + ${project.version} + + + web-client + prepare-package + + build-javascript + + + ${project.build.directory}/generated/js/teavm + org.teavm.samples.benchmark.teavm.BenchmarkStarter + SEPARATE + true + true + + + - org.codehaus.mojo - gwt-maven-plugin - 2.7.0 - - - - compile - - - 9 - - org.jbox2d:jbox2d-library - - - - + org.codehaus.mojo + gwt-maven-plugin + 2.7.0 + + + + compile + + + 9 + + org.jbox2d:jbox2d-library + + + + org.apache.maven.plugins @@ -172,11 +161,11 @@ html4j-maven-plugin 1.1 - - - process-js-annotations - - + + + process-js-annotations + + @@ -186,28 +175,28 @@ - - fx - - - org.netbeans.html - net.java.html.boot.fx - 1.1 - runtime - - - - - - org.codehaus.mojo - exec-maven-plugin - 1.3.2 - - org.teavm.samples.benchmark.htmljava.BenchmarkFX - - - - - + + fx + + + org.netbeans.html + net.java.html.boot.fx + 1.1 + runtime + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.3.2 + + org.teavm.samples.benchmark.htmljava.BenchmarkFX + + + + + \ No newline at end of file From 3a78db74c1bd201dc1d211fc067d6fa6cd96fc16 Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Sun, 8 Mar 2015 13:09:17 +0300 Subject: [PATCH 22/69] Fix bugs --- .../main/java/org/teavm/classlib/java/lang/TObject.java | 7 +++++-- .../src/main/resources/org/teavm/javascript/runtime.js | 4 ++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java index 3e6bfb01e..65776b5b8 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java @@ -196,7 +196,6 @@ public class TObject { if (!holdsLock(this)) { throw new TIllegalMonitorStateException(); } - TThread thread = TThread.currentThread(); PlatformQueue listeners = monitor.notifyListeners; while (!listeners.isEmpty()) { NotifyListener listener = listeners.remove(); @@ -205,7 +204,6 @@ public class TObject { break; } } - TThread.setCurrentThread(thread); } @Sync @@ -256,6 +254,7 @@ public class TObject { final TThread currentThread = TThread.currentThread(); int timerId = -1; boolean expired; + boolean performed; int lockCount; public NotifyListenerImpl(TObject obj, AsyncCallback callback, int lockCount) { @@ -280,6 +279,10 @@ public class TObject { @Override public void run() { + if (performed) { + return; + } + performed = true; if (timerId >= 0) { Platform.killSchedule(timerId); timerId = -1; diff --git a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js index 4a7dd2c94..c0d860e59 100644 --- a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js +++ b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js @@ -497,7 +497,11 @@ function $rt_continue(f) { var self = this; var args = arguments; var thread = $rt_getThread(); + var oldPostponed = thread.postponed; thread.postponed = function() { + if (oldPostponed) { + oldPostponed(); + } f.apply(self, args); }; }; From 4f508954d0a976d72fed20e84fcfe04c43d17a46 Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Sun, 8 Mar 2015 14:13:25 +0300 Subject: [PATCH 23/69] Improve Async demo --- teavm-samples/teavm-samples-async/pom.xml | 2 +- .../src/main/webapp/highlight.pack.js | 1 + .../src/main/webapp/index.html | 173 +++++++++++++++++- .../src/main/webapp/style.css | 62 +++++++ .../src/main/webapp/syntax.css | 12 ++ .../src/main/webapp/teavm/stdout.js | 12 ++ 6 files changed, 259 insertions(+), 3 deletions(-) create mode 100644 teavm-samples/teavm-samples-async/src/main/webapp/highlight.pack.js create mode 100644 teavm-samples/teavm-samples-async/src/main/webapp/style.css create mode 100644 teavm-samples/teavm-samples-async/src/main/webapp/syntax.css create mode 100644 teavm-samples/teavm-samples-async/src/main/webapp/teavm/stdout.js diff --git a/teavm-samples/teavm-samples-async/pom.xml b/teavm-samples/teavm-samples-async/pom.xml index b04494c1b..23133d3ec 100644 --- a/teavm-samples/teavm-samples-async/pom.xml +++ b/teavm-samples/teavm-samples-async/pom.xml @@ -64,7 +64,7 @@ ${project.build.directory}/generated/js/teavm org.teavm.samples.async.AsyncProgram SEPARATE - false + true true true true diff --git a/teavm-samples/teavm-samples-async/src/main/webapp/highlight.pack.js b/teavm-samples/teavm-samples-async/src/main/webapp/highlight.pack.js new file mode 100644 index 000000000..1225a13e2 --- /dev/null +++ b/teavm-samples/teavm-samples-async/src/main/webapp/highlight.pack.js @@ -0,0 +1 @@ +!function(e){"undefined"!=typeof exports?e(exports):(window.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return window.hljs}))}(function(e){function n(e){return e.replace(/&/gm,"&").replace(//gm,">")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0==t.index}function a(e){var n=(e.className+" "+(e.parentNode?e.parentNode.className:"")).split(/\s+/);return n=n.map(function(e){return e.replace(/^lang(uage)?-/,"")}),n.filter(function(e){return N(e)||/no(-?)highlight/.test(e)})[0]}function o(e,n){var t={};for(var r in e)t[r]=e[r];if(n)for(var r in n)t[r]=n[r];return t}function i(e){var n=[];return function r(e,a){for(var o=e.firstChild;o;o=o.nextSibling)3==o.nodeType?a+=o.nodeValue.length:1==o.nodeType&&(n.push({event:"start",offset:a,node:o}),a=r(o,a),t(o).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:o}));return a}(e,0),n}function c(e,r,a){function o(){return e.length&&r.length?e[0].offset!=r[0].offset?e[0].offset"}function c(e){l+=""}function u(e){("start"==e.event?i:c)(e.node)}for(var s=0,l="",f=[];e.length||r.length;){var g=o();if(l+=n(a.substr(s,g[0].offset-s)),s=g[0].offset,g==e){f.reverse().forEach(c);do u(g.splice(0,1)[0]),g=o();while(g==e&&g.length&&g[0].offset==s);f.reverse().forEach(i)}else"start"==g[0].event?f.push(g[0].node):f.pop(),u(g.splice(0,1)[0])}return l+n(a.substr(s))}function u(e){function n(e){return e&&e.source||e}function t(t,r){return RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var c={},u=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");c[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?u("keyword",a.k):Object.keys(a.k).forEach(function(e){u(e,a.k[e])}),a.k=c}a.lR=t(a.l||/\b[A-Za-z0-9_]+\b/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),void 0===a.r&&(a.r=1),a.c||(a.c=[]);var s=[];a.c.forEach(function(e){e.v?e.v.forEach(function(n){s.push(o(e,n))}):s.push("self"==e?a:e)}),a.c=s,a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var l=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=l.length?t(l.join("|"),!0):{exec:function(){return null}}}}r(e)}function s(e,t,a,o){function i(e,n){for(var t=0;t";return o+=e+'">',o+n+i}function d(){if(!w.k)return n(y);var e="",t=0;w.lR.lastIndex=0;for(var r=w.lR.exec(y);r;){e+=n(y.substr(t,r.index-t));var a=g(w,r);a?(B+=a[1],e+=p(a[0],n(r[0]))):e+=n(r[0]),t=w.lR.lastIndex,r=w.lR.exec(y)}return e+n(y.substr(t))}function h(){if(w.sL&&!R[w.sL])return n(y);var e=w.sL?s(w.sL,y,!0,L[w.sL]):l(y);return w.r>0&&(B+=e.r),"continuous"==w.subLanguageMode&&(L[w.sL]=e.top),p(e.language,e.value,!1,!0)}function v(){return void 0!==w.sL?h():d()}function b(e,t){var r=e.cN?p(e.cN,"",!0):"";e.rB?(M+=r,y=""):e.eB?(M+=n(t)+r,y=""):(M+=r,y=t),w=Object.create(e,{parent:{value:w}})}function m(e,t){if(y+=e,void 0===t)return M+=v(),0;var r=i(t,w);if(r)return M+=v(),b(r,t),r.rB?0:t.length;var a=c(w,t);if(a){var o=w;o.rE||o.eE||(y+=t),M+=v();do w.cN&&(M+=""),B+=w.r,w=w.parent;while(w!=a.parent);return o.eE&&(M+=n(t)),y="",a.starts&&b(a.starts,""),o.rE?0:t.length}if(f(t,w))throw new Error('Illegal lexeme "'+t+'" for mode "'+(w.cN||"")+'"');return y+=t,t.length||1}var x=N(e);if(!x)throw new Error('Unknown language: "'+e+'"');u(x);for(var w=o||x,L={},M="",k=w;k!=x;k=k.parent)k.cN&&(M=p(k.cN,"",!0)+M);var y="",B=0;try{for(var C,j,I=0;;){if(w.t.lastIndex=I,C=w.t.exec(t),!C)break;j=m(t.substr(I,C.index-I),C[0]),I=C.index+j}m(t.substr(I));for(var k=w;k.parent;k=k.parent)k.cN&&(M+="");return{r:B,value:M,language:e,top:w}}catch(A){if(-1!=A.message.indexOf("Illegal"))return{r:0,value:n(t)};throw A}}function l(e,t){t=t||E.languages||Object.keys(R);var r={r:0,value:n(e)},a=r;return t.forEach(function(n){if(N(n)){var t=s(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}}),a.language&&(r.second_best=a),r}function f(e){return E.tabReplace&&(e=e.replace(/^((<[^>]+>|\t)+)/gm,function(e,n){return n.replace(/\t/g,E.tabReplace)})),E.useBR&&(e=e.replace(/\n/g,"
")),e}function g(e,n,t){var r=n?x[n]:t,a=[e.trim()];return e.match(/(\s|^)hljs(\s|$)/)||a.push("hljs"),r&&a.push(r),a.join(" ").trim()}function p(e){var n=a(e);if(!/no(-?)highlight/.test(n)){var t;E.useBR?(t=document.createElementNS("http://www.w3.org/1999/xhtml","div"),t.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n")):t=e;var r=t.textContent,o=n?s(n,r,!0):l(r),u=i(t);if(u.length){var p=document.createElementNS("http://www.w3.org/1999/xhtml","div");p.innerHTML=o.value,o.value=c(u,i(p),r)}o.value=f(o.value),e.innerHTML=o.value,e.className=g(e.className,n,o.language),e.result={language:o.language,re:o.r},o.second_best&&(e.second_best={language:o.second_best.language,re:o.second_best.r})}}function d(e){E=o(E,e)}function h(){if(!h.called){h.called=!0;var e=document.querySelectorAll("pre code");Array.prototype.forEach.call(e,p)}}function v(){addEventListener("DOMContentLoaded",h,!1),addEventListener("load",h,!1)}function b(n,t){var r=R[n]=t(e);r.aliases&&r.aliases.forEach(function(e){x[e]=n})}function m(){return Object.keys(R)}function N(e){return R[e]||R[x[e]]}var E={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0},R={},x={};return e.highlight=s,e.highlightAuto=l,e.fixMarkup=f,e.highlightBlock=p,e.configure=d,e.initHighlighting=h,e.initHighlightingOnLoad=v,e.registerLanguage=b,e.listLanguages=m,e.getLanguage=N,e.inherit=o,e.IR="[a-zA-Z][a-zA-Z0-9_]*",e.UIR="[a-zA-Z_][a-zA-Z0-9_]*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such)\b/},e.CLCM={cN:"comment",b:"//",e:"$",c:[e.PWM]},e.CBCM={cN:"comment",b:"/\\*",e:"\\*/",c:[e.PWM]},e.HCM={cN:"comment",b:"#",e:"$",c:[e.PWM]},e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e});hljs.registerLanguage("java",function(e){var a=e.UIR+"(<"+e.UIR+">)?",t="false synchronized int abstract float private char boolean static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private",c="(\\b(0b[01_]+)|\\b0[xX][a-fA-F0-9_]+|(\\b[\\d_]+(\\.[\\d_]*)?|\\.[\\d_]+)([eE][-+]?\\d+)?)[lLfF]?",r={cN:"number",b:c,r:0};return{aliases:["jsp"],k:t,i:/<\//,c:[{cN:"javadoc",b:"/\\*\\*",e:"\\*/",r:0,c:[{cN:"javadoctag",b:"(^|\\s)@[A-Za-z]+"}]},e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:"class",bK:"class interface",e:/[{;=]/,eE:!0,k:"class interface",i:/[:"\[\]]/,c:[{bK:"extends implements"},e.UTM]},{bK:"new throw return",r:0},{cN:"function",b:"("+a+"\\s+)+"+e.UIR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:t,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"params",b:/\(/,e:/\)/,k:t,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},r,{cN:"annotation",b:"@[A-Za-z]+"}]}}); \ No newline at end of file diff --git a/teavm-samples/teavm-samples-async/src/main/webapp/index.html b/teavm-samples/teavm-samples-async/src/main/webapp/index.html index 96817c4a0..71f93b7a7 100644 --- a/teavm-samples/teavm-samples-async/src/main/webapp/index.html +++ b/teavm-samples/teavm-samples-async/src/main/webapp/index.html @@ -20,8 +20,177 @@ + + + + + - -

Please, open developer's console to view program's output

+ +
This application shows how TeaVM can handle multiple threads and synchronization primitives + (see source code on GitHub).
+ +
+
+
stdout
+
+
+ +
+
Source code
+
+public final class AsyncProgram {
+    private static long start = System.currentTimeMillis();
+
+    private AsyncProgram() {
+    }
+
+    public static void main(String[] args) throws InterruptedException {
+        report(Arrays.toString(args));
+        findPrimes();
+        withoutAsync();
+        report("");
+        withAsync();
+
+        report("");
+        final Object lock = new Object();
+        Thread t = new Thread(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    doRun(lock);
+                } catch (InterruptedException ex) {
+                    report("Exception caught: " + ex.getMessage());
+                }
+            }
+
+        }, "Test Thread");
+        t.start();
+
+        Thread t2 = new Thread(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    doRun(lock);
+                } catch (InterruptedException ex) {
+                    report("Exception caught: " + ex.getMessage());
+                }
+            }
+        }, "Test Thread 2");
+        t2.start();
+
+        report("Should be main");
+        report("Now trying wait...");
+
+        synchronized (lock) {
+            report("Lock acquired");
+            lock.wait(20000);
+        }
+        report("Finished main thread");
+    }
+
+    private static void findPrimes() {
+        report("Finding primes");
+        boolean[] prime = new boolean[1000];
+        prime[2] = true;
+        prime[3] = true;
+        nextPrime: for (int i = 5; i < prime.length; i += 2) {
+            int maxPrime = (int)Math.sqrt(i);
+            for (int j = 3; j <= maxPrime; j += 2) {
+                Thread.yield();
+                if (prime[j] && i % j == 0) {
+                    continue nextPrime;
+                }
+            }
+            prime[i] = true;
+        }
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < 1000; ++i) {
+            if (prime[i]) {
+                sb.append(i).append(' ');
+            }
+        }
+        report(sb.toString());
+    }
+
+    private static void report(String message) {
+        long current = System.currentTimeMillis() - start;
+        System.out.println("[" + Thread.currentThread().getName() + "]/" + current + ": " + message);
+    }
+
+    private static void doRun(Object lock) throws InterruptedException {
+        report("Executing timer task");
+        Thread.sleep(2000);
+        report("Calling lock.notify()");
+        synchronized (lock) {
+            lock.notify();
+        }
+        report("Finished calling lock.notify()");
+        report("Waiting 5 seconds");
+        Thread.sleep(5000);
+        report("Finished another 5 second sleep");
+
+        synchronized (lock) {
+            report("Sleep inside locked section");
+            Thread.sleep(2000);
+            report("Finished locked section");
+        }
+    }
+
+    private static void withoutAsync() {
+        report("Start sync");
+        for (int i = 0; i < 20; ++i) {
+            StringBuilder sb = new StringBuilder();
+            for (int j = 0; j <= i; ++j) {
+                sb.append(j);
+                sb.append(' ');
+            }
+            report(sb.toString());
+        }
+        report("Complete sync");
+    }
+
+    private static void withAsync() throws InterruptedException {
+        report("Start async");
+        for (int i = 0; i < 20; ++i) {
+            StringBuilder sb = new StringBuilder();
+            for (int j = 0; j <= i; ++j) {
+                sb.append(j);
+                sb.append(' ');
+            }
+            report(sb.toString());
+            if (i % 3 == 0) {
+                report("Suspend for a second");
+                Thread.sleep(1000);
+            }
+        }
+        report("2nd Thread.sleep in same method");
+        Thread.sleep(1000);
+
+        report("Throwing exception");
+        try {
+            throwException();
+        } catch (IllegalStateException e) {
+            report("Exception caught");
+        }
+        report("Complete async");
+    }
+
+    private static void throwException() {
+        Thread.yield();
+        report("Thread.yield called");
+        throw new IllegalStateException();
+    }
+}
+
+ +
+
+ \ No newline at end of file diff --git a/teavm-samples/teavm-samples-async/src/main/webapp/style.css b/teavm-samples/teavm-samples-async/src/main/webapp/style.css new file mode 100644 index 000000000..ca3f74b5f --- /dev/null +++ b/teavm-samples/teavm-samples-async/src/main/webapp/style.css @@ -0,0 +1,62 @@ +html, body { + position: absolute; + left: 0; + top: 0; + right: 0; + bottom: 0; + margin: 0; + padding: 0; +} + +.block { + position: absolute; + left: 0px; + right: 0px; +} +.block-title { + position: absolute; + top: 10px; + height: 20px; + left: 10px; + right: 10px; + font-weight: bold; +} +.block-content { + position: absolute; + top: 30px; + bottom: 5px; + left: 10px; + right: 10px; + background-color: rgb(240,240,240); + border-width: 1px; + border-style: solid; + border-color: rgb(210,210,210); + overflow: auto; + padding: 3px; + margin: 0; + border-radius: 3px; +} + +#description { + position: absolute; + top: 10px; + height: 40px; + left: 10px; + right: 10px; +} +#blocks { + position: absolute; + top: 50px; + bottom: 0; + left: 0; + right: 0; +} +#stdout-wrapper { + top: 0; + height: 50%; +} +#source-wrapper { + top: 50%; + bottom: 0; +} + diff --git a/teavm-samples/teavm-samples-async/src/main/webapp/syntax.css b/teavm-samples/teavm-samples-async/src/main/webapp/syntax.css new file mode 100644 index 000000000..e4d47b0a7 --- /dev/null +++ b/teavm-samples/teavm-samples-async/src/main/webapp/syntax.css @@ -0,0 +1,12 @@ +.hljs-keyword { + font-weight: bold; +} +.hljs-class .hljs-title { + color: #9BB01D; +} +.hljs-annotation { + color: #FFA500; +} +.hljs-string, .hljs-number { + color: red; +} \ No newline at end of file diff --git a/teavm-samples/teavm-samples-async/src/main/webapp/teavm/stdout.js b/teavm-samples/teavm-samples-async/src/main/webapp/teavm/stdout.js new file mode 100644 index 000000000..cb279b2b8 --- /dev/null +++ b/teavm-samples/teavm-samples-async/src/main/webapp/teavm/stdout.js @@ -0,0 +1,12 @@ +function $rt_putStdout(ch) { + if (ch == 0xA) { + var lineElem = document.createElement("div"); + var stdoutElem = document.getElementById("stdout"); + lineElem.appendChild(document.createTextNode($rt_stdoutBuffer)); + stdoutElem.appendChild(lineElem); + $rt_stdoutBuffer = ""; + stdoutElem.scrollTop = stdoutElem.scrollHeight; + } else { + $rt_stdoutBuffer += String.fromCharCode(ch); + } +} From bcf0929fc51e13124ac5de929827e6f5d77681a5 Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Sun, 8 Mar 2015 19:32:01 +0300 Subject: [PATCH 24/69] Add slf4j support --- pom.xml | 1 + teavm-extras-slf4j/.gitignore | 4 + teavm-extras-slf4j/pom.xml | 68 ++++ .../slf4j/LoggerFactoryTransformer.java | 81 +++++ .../org/teavm/extras/slf4j/Slf4jPlugin.java | 30 ++ .../org/teavm/extras/slf4j/TeaVMLogger.java | 335 ++++++++++++++++++ .../extras/slf4j/TeaVMLoggerFactory.java | 39 ++ .../services/org.teavm.vm.spi.TeaVMPlugin | 1 + teavm-samples/teavm-samples-async/pom.xml | 1 + 9 files changed, 560 insertions(+) create mode 100644 teavm-extras-slf4j/.gitignore create mode 100644 teavm-extras-slf4j/pom.xml create mode 100644 teavm-extras-slf4j/src/main/java/org/teavm/extras/slf4j/LoggerFactoryTransformer.java create mode 100644 teavm-extras-slf4j/src/main/java/org/teavm/extras/slf4j/Slf4jPlugin.java create mode 100644 teavm-extras-slf4j/src/main/java/org/teavm/extras/slf4j/TeaVMLogger.java create mode 100644 teavm-extras-slf4j/src/main/java/org/teavm/extras/slf4j/TeaVMLoggerFactory.java create mode 100644 teavm-extras-slf4j/src/main/resources/META-INF/services/org.teavm.vm.spi.TeaVMPlugin diff --git a/pom.xml b/pom.xml index abe9225e6..43fca8ac3 100644 --- a/pom.xml +++ b/pom.xml @@ -83,6 +83,7 @@ teavm-cli teavm-chrome-rdp teavm-tests + teavm-extras-slf4j diff --git a/teavm-extras-slf4j/.gitignore b/teavm-extras-slf4j/.gitignore new file mode 100644 index 000000000..8bd3a0588 --- /dev/null +++ b/teavm-extras-slf4j/.gitignore @@ -0,0 +1,4 @@ +/target/ +/.settings/ +/.classpath +/.project diff --git a/teavm-extras-slf4j/pom.xml b/teavm-extras-slf4j/pom.xml new file mode 100644 index 000000000..ddf2d0477 --- /dev/null +++ b/teavm-extras-slf4j/pom.xml @@ -0,0 +1,68 @@ + + + 4.0.0 + + + org.teavm + teavm + 0.3.0-SNAPSHOT + + teavm-extras-slf4j + + TeaVM slf4j + TeaVM backend for slf4j + + + + org.teavm + teavm-core + ${project.version} + provided + + + org.teavm + teavm-jso + ${project.version} + + + org.slf4j + slf4j-api + provided + + + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + + ../checkstyle.xml + + + + org.apache.maven.plugins + maven-source-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + + + + \ No newline at end of file diff --git a/teavm-extras-slf4j/src/main/java/org/teavm/extras/slf4j/LoggerFactoryTransformer.java b/teavm-extras-slf4j/src/main/java/org/teavm/extras/slf4j/LoggerFactoryTransformer.java new file mode 100644 index 000000000..14bd34520 --- /dev/null +++ b/teavm-extras-slf4j/src/main/java/org/teavm/extras/slf4j/LoggerFactoryTransformer.java @@ -0,0 +1,81 @@ +/* + * Copyright 2015 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.extras.slf4j; + +import org.slf4j.ILoggerFactory; +import org.slf4j.LoggerFactory; +import org.teavm.diagnostics.Diagnostics; +import org.teavm.model.*; +import org.teavm.model.instructions.*; + +/** + * + * @author Alexey Andreev + */ +public class LoggerFactoryTransformer implements ClassHolderTransformer { + @Override + public void transformClass(ClassHolder cls, ClassReaderSource innerSource, Diagnostics diagnostics) { + if (!cls.getName().equals(LoggerFactory.class.getName())) { + return; + } + addCacheField(cls); + modifyClinit(cls); + replaceGetFactory(cls); + } + + private void addCacheField(ClassHolder cls) { + FieldHolder cacheField = new FieldHolder("loggerFactoryCache"); + cacheField.setLevel(AccessLevel.PRIVATE); + cacheField.getModifiers().add(ElementModifier.STATIC); + cacheField.setType(ValueType.object(TeaVMLoggerFactory.class.getName())); + cls.addField(cacheField); + } + + private void modifyClinit(ClassHolder cls) { + MethodHolder clinit = cls.getMethod(new MethodDescriptor("", void.class)); + BasicBlock clinitBlock = clinit.getProgram().basicBlockAt(0); + Variable factoryVar = clinit.getProgram().createVariable(); + ConstructInstruction construct = new ConstructInstruction(); + construct.setType(TeaVMLoggerFactory.class.getName()); + construct.setReceiver(factoryVar); + clinitBlock.getInstructions().add(0, construct); + InvokeInstruction init = new InvokeInstruction(); + init.setInstance(factoryVar); + init.setMethod(new MethodReference(TeaVMLoggerFactory.class, "", void.class)); + init.setType(InvocationType.SPECIAL); + clinitBlock.getInstructions().add(1, init); + PutFieldInstruction put = new PutFieldInstruction(); + put.setValue(factoryVar); + put.setField(new FieldReference(LoggerFactory.class.getName(), "loggerFactoryCache")); + clinitBlock.getInstructions().add(2, put); + } + + private void replaceGetFactory(ClassHolder cls) { + MethodHolder method = cls.getMethod(new MethodDescriptor("getILoggerFactory", ILoggerFactory.class)); + Program program = new Program(); + BasicBlock block = program.createBasicBlock(); + Variable cacheVar = program.createVariable(); + GetFieldInstruction get = new GetFieldInstruction(); + get.setField(new FieldReference(LoggerFactory.class.getName(), "loggerFactoryCache")); + get.setFieldType(ValueType.object(ILoggerFactory.class.getName())); + get.setReceiver(cacheVar); + block.getInstructions().add(get); + ExitInstruction exit = new ExitInstruction(); + exit.setValueToReturn(cacheVar); + block.getInstructions().add(exit); + method.setProgram(program); + } +} diff --git a/teavm-extras-slf4j/src/main/java/org/teavm/extras/slf4j/Slf4jPlugin.java b/teavm-extras-slf4j/src/main/java/org/teavm/extras/slf4j/Slf4jPlugin.java new file mode 100644 index 000000000..74502095e --- /dev/null +++ b/teavm-extras-slf4j/src/main/java/org/teavm/extras/slf4j/Slf4jPlugin.java @@ -0,0 +1,30 @@ +/* + * Copyright 2015 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.extras.slf4j; + +import org.teavm.vm.spi.TeaVMHost; +import org.teavm.vm.spi.TeaVMPlugin; + +/** + * + * @author Alexey Andreev + */ +public class Slf4jPlugin implements TeaVMPlugin { + @Override + public void install(TeaVMHost host) { + host.add(new LoggerFactoryTransformer()); + } +} \ No newline at end of file diff --git a/teavm-extras-slf4j/src/main/java/org/teavm/extras/slf4j/TeaVMLogger.java b/teavm-extras-slf4j/src/main/java/org/teavm/extras/slf4j/TeaVMLogger.java new file mode 100644 index 000000000..2d95dc16b --- /dev/null +++ b/teavm-extras-slf4j/src/main/java/org/teavm/extras/slf4j/TeaVMLogger.java @@ -0,0 +1,335 @@ +/* + * Copyright 2015 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.extras.slf4j; + +import org.slf4j.Logger; +import org.slf4j.Marker; + +/** + * + * @author Alexey Andreev + */ +public class TeaVMLogger implements Logger { + private String name; + + public TeaVMLogger(String name) { + this.name = name; + } + + @Override + public String getName() { + return name; + } + + @Override + public boolean isTraceEnabled() { + return false; + } + + @Override + public void trace(String msg) { + } + + @Override + public void trace(String format, Object arg) { + } + + @Override + public void trace(String format, Object arg1, Object arg2) { + } + + @Override + public void trace(String format, Object... arguments) { + } + + @Override + public void trace(String msg, Throwable t) { + } + + @Override + public boolean isTraceEnabled(Marker marker) { + return false; + } + + @Override + public void trace(Marker marker, String msg) { + } + + @Override + public void trace(Marker marker, String format, Object arg) { + } + + @Override + public void trace(Marker marker, String format, Object arg1, Object arg2) { + } + + @Override + public void trace(Marker marker, String format, Object... argArray) { + } + + @Override + public void trace(Marker marker, String msg, Throwable t) { + } + + @Override + public boolean isDebugEnabled() { + return false; + } + + @Override + public void debug(String msg) { + } + + @Override + public void debug(String format, Object arg) { + } + + @Override + public void debug(String format, Object arg1, Object arg2) { + } + + @Override + public void debug(String format, Object... arguments) { + } + + @Override + public void debug(String msg, Throwable t) { + } + + @Override + public boolean isDebugEnabled(Marker marker) { + return false; + } + + @Override + public void debug(Marker marker, String msg) { + } + + @Override + public void debug(Marker marker, String format, Object arg) { + } + + @Override + public void debug(Marker marker, String format, Object arg1, Object arg2) { + } + + @Override + public void debug(Marker marker, String format, Object... arguments) { + } + + @Override + public void debug(Marker marker, String msg, Throwable t) { + } + + @Override + public boolean isInfoEnabled() { + return true; + } + + private void log(String level, String format, Object... arguments) { + StringBuffer sb = new StringBuffer(); + sb.append('[').append(level).append("] ").append(name).append(": "); + int index = 0; + int argIndex = 0; + while (index < format.length()) { + int next = format.indexOf("{}", index); + if (next == -1) { + break; + } + sb.append(format.subSequence(index, next)); + sb.append(argIndex < arguments.length ? String.valueOf(arguments[argIndex]) : "{}"); + index = next + 2; + ++argIndex; + } + sb.append(format.substring(index)); + System.err.println(sb); + } + + @Override + public void info(String msg) { + info(msg, new Object[0]); + } + + @Override + public void info(String format, Object arg) { + info(format, new Object[] { arg }); + } + + @Override + public void info(String format, Object arg1, Object arg2) { + info(format, new Object[] { arg1, arg2 }); + } + + @Override + public void info(String format, Object... arguments) { + log("INFO", format, arguments); + } + + @Override + public void info(String msg, Throwable t) { + info(msg); + } + + @Override + public boolean isInfoEnabled(Marker marker) { + return true; + } + + @Override + public void info(Marker marker, String msg) { + info(msg); + } + + @Override + public void info(Marker marker, String format, Object arg) { + info(format, arg); + } + + @Override + public void info(Marker marker, String format, Object arg1, Object arg2) { + info(format, arg1, arg2); + } + + @Override + public void info(Marker marker, String format, Object... arguments) { + info(format, arguments); + } + + @Override + public void info(Marker marker, String msg, Throwable t) { + info(msg, t); + } + + @Override + public boolean isWarnEnabled() { + return true; + } + + @Override + public void warn(String msg) { + warn(msg, new Object[0]); + } + + @Override + public void warn(String format, Object arg) { + warn(format, new Object[] { arg }); + } + + @Override + public void warn(String format, Object... arguments) { + log("WARN", format, arguments); + } + + @Override + public void warn(String format, Object arg1, Object arg2) { + warn(format, new Object[] { arg1, arg2 }); + } + + @Override + public void warn(String msg, Throwable t) { + warn(msg); + } + + @Override + public boolean isWarnEnabled(Marker marker) { + return true; + } + + @Override + public void warn(Marker marker, String msg) { + warn(msg); + } + + @Override + public void warn(Marker marker, String format, Object arg) { + warn(format, arg); + } + + @Override + public void warn(Marker marker, String format, Object arg1, Object arg2) { + warn(format, arg1, arg2); + } + + @Override + public void warn(Marker marker, String format, Object... arguments) { + warn(format, arguments); + } + + @Override + public void warn(Marker marker, String msg, Throwable t) { + warn(msg, t); + } + + @Override + public boolean isErrorEnabled() { + return true; + } + + @Override + public void error(String msg) { + error(msg, new Object[0]); + } + + @Override + public void error(String format, Object arg) { + error(format, new Object[] { arg }); + } + + @Override + public void error(String format, Object arg1, Object arg2) { + error(format, new Object[] { arg1, arg2 }); + } + + @Override + public void error(String format, Object... arguments) { + log("ERRO", format, arguments); + } + + @Override + public void error(String msg, Throwable t) { + error(msg); + } + + @Override + public boolean isErrorEnabled(Marker marker) { + return true; + } + + @Override + public void error(Marker marker, String msg) { + error(msg); + } + + @Override + public void error(Marker marker, String format, Object arg) { + error(format, arg); + } + + @Override + public void error(Marker marker, String format, Object arg1, Object arg2) { + error(format, arg1, arg2); + } + + @Override + public void error(Marker marker, String format, Object... arguments) { + error(format, arguments); + } + + @Override + public void error(Marker marker, String msg, Throwable t) { + error(msg, t); + } +} diff --git a/teavm-extras-slf4j/src/main/java/org/teavm/extras/slf4j/TeaVMLoggerFactory.java b/teavm-extras-slf4j/src/main/java/org/teavm/extras/slf4j/TeaVMLoggerFactory.java new file mode 100644 index 000000000..5eaf09800 --- /dev/null +++ b/teavm-extras-slf4j/src/main/java/org/teavm/extras/slf4j/TeaVMLoggerFactory.java @@ -0,0 +1,39 @@ +/* + * Copyright 2015 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.extras.slf4j; + +import java.util.HashMap; +import java.util.Map; +import org.slf4j.ILoggerFactory; +import org.slf4j.Logger; + +/** + * + * @author Alexey Andreev + */ +public class TeaVMLoggerFactory implements ILoggerFactory { + private Map loggers = new HashMap<>(); + + @Override + public Logger getLogger(String name) { + TeaVMLogger logger = loggers.get(name); + if (logger == null) { + logger = new TeaVMLogger(name); + loggers.put(name, logger); + } + return logger; + } +} \ No newline at end of file diff --git a/teavm-extras-slf4j/src/main/resources/META-INF/services/org.teavm.vm.spi.TeaVMPlugin b/teavm-extras-slf4j/src/main/resources/META-INF/services/org.teavm.vm.spi.TeaVMPlugin new file mode 100644 index 000000000..e045db3fd --- /dev/null +++ b/teavm-extras-slf4j/src/main/resources/META-INF/services/org.teavm.vm.spi.TeaVMPlugin @@ -0,0 +1 @@ +org.teavm.extras.slf4j.Slf4jPlugin \ No newline at end of file diff --git a/teavm-samples/teavm-samples-async/pom.xml b/teavm-samples/teavm-samples-async/pom.xml index 23133d3ec..99a38de06 100644 --- a/teavm-samples/teavm-samples-async/pom.xml +++ b/teavm-samples/teavm-samples-async/pom.xml @@ -33,6 +33,7 @@ org.teavm teavm-classlib ${project.version} + provided From bd7d366618f1e4a9061e63e9a116d3357c7dbb25 Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Sun, 8 Mar 2015 20:03:36 +0300 Subject: [PATCH 25/69] Repair Eclipse plugin --- teavm-eclipse/teavm-eclipse-core-plugin/META-INF/MANIFEST.MF | 3 ++- teavm-eclipse/teavm-eclipse-core-plugin/build.properties | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/teavm-eclipse/teavm-eclipse-core-plugin/META-INF/MANIFEST.MF b/teavm-eclipse/teavm-eclipse-core-plugin/META-INF/MANIFEST.MF index 751ae8231..9b210c313 100644 --- a/teavm-eclipse/teavm-eclipse-core-plugin/META-INF/MANIFEST.MF +++ b/teavm-eclipse/teavm-eclipse-core-plugin/META-INF/MANIFEST.MF @@ -43,7 +43,8 @@ Bundle-ClassPath: ., lib/websocket-client-9.2.1.v20140609.jar, lib/websocket-common-9.2.1.v20140609.jar, lib/websocket-server-9.2.1.v20140609.jar, - lib/websocket-servlet-9.2.1.v20140609.jar + lib/websocket-servlet-9.2.1.v20140609.jar, + lib/hppc-0.6.1.jar Bundle-ActivationPolicy: lazy Export-Package: org.teavm.cache, org.teavm.callgraph, diff --git a/teavm-eclipse/teavm-eclipse-core-plugin/build.properties b/teavm-eclipse/teavm-eclipse-core-plugin/build.properties index eb59b3b09..54ba3e27b 100644 --- a/teavm-eclipse/teavm-eclipse-core-plugin/build.properties +++ b/teavm-eclipse/teavm-eclipse-core-plugin/build.properties @@ -41,5 +41,6 @@ bin.includes = META-INF/,\ lib/websocket-common-9.2.1.v20140609.jar,\ lib/websocket-server-9.2.1.v20140609.jar,\ lib/websocket-servlet-9.2.1.v20140609.jar,\ + lib/hppc-0.6.1.jar,\ logback.xml jars.compile.order = . From 61368d0c100cda79883301d01d51daa6f4567ce9 Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Sun, 8 Mar 2015 20:11:03 +0300 Subject: [PATCH 26/69] Add own declaration of DataOutput interface --- .../teavm/classlib/java/io/TDataOutput.java | 126 +++++------------- .../classlib/java/io/TDataOutputStream.java | 5 +- 2 files changed, 32 insertions(+), 99 deletions(-) diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TDataOutput.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TDataOutput.java index 70c5f097e..9ec31e277 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TDataOutput.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TDataOutput.java @@ -1,113 +1,49 @@ /* - * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Codename One designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Codename One through http://www.codenameone.com/ if you - * need additional information or have any questions. + * Copyright 2015 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.io; -import org.teavm.classlib.java.lang.*; -/** - * The DataOutput interface provides for converting data from any of the Java primitive types to a series of bytes and writing these bytes to a binary stream. There is also a facility for converting a String into Java modified UTF-8 format and writing the resulting series of bytes. - * For all the methods in this interface that write bytes, it is generally true that if a byte cannot be written for any reason, an IOException is thrown. - * Since: JDK1.0, CLDC 1.0 See Also:DataInput, DataOutputStream - */ + +import org.teavm.classlib.java.lang.TString; + + public interface TDataOutput{ - /** - * Writes to the output stream all the bytes in array b. If b is null, a NullPointerException is thrown. If b.length is zero, then no bytes are written. Otherwise, the byte b[0] is written first, then b[1], and so on; the last byte written is b[b.length-1]. - */ - public abstract void write(byte[] b) throws TIOException; + void write(int b) throws TIOException; - /** - * Writes len bytes from array b, in order, to the output stream. If b is null, a NullPointerException is thrown. If off is negative, or len is negative, or off+len is greater than the length of the array b, then an IndexOutOfBoundsException is thrown. If len is zero, then no bytes are written. Otherwise, the byte b[off] is written first, then b[off+1], and so on; the last byte written is b[off+len-1]. - */ - public abstract void write(byte[] b, int off, int len) throws TIOException; + void write(byte[] b) throws TIOException; - /** - * Writes to the output stream the eight low-order bits of the argument b. The 24 high-order bits of b are ignored. - */ - public abstract void write(int b) throws TIOException; + void write(byte[] b, int off, int len) throws TIOException; - /** - * Writes a boolean value to this output stream. If the argument v is true, the value (byte)1 is written; if v is false, the value (byte)0 is written. The byte written by this method may be read by the readBoolean method of interface DataInput, which will then return a boolean equal to v. - */ - public abstract void writeBoolean(boolean v) throws TIOException; + void writeBoolean(boolean v) throws TIOException; - /** - * Writes to the output stream the eight low- order bits of the argument v. The 24 high-order bits of v are ignored. (This means that writeByte does exactly the same thing as write for an integer argument.) The byte written by this method may be read by the readByte method of interface DataInput, which will then return a byte equal to (byte)v. - */ - public abstract void writeByte(int v) throws TIOException; + void writeByte(int v) throws TIOException; - /** - * Writes a char value, which is comprised of two bytes, to the output stream. The byte values to be written, in the order shown, are: - * (byte)(0xff (v 8)) (byte)(0xff v) - * The bytes written by this method may be read by the readChar method of interface DataInput, which will then return a char equal to (char)v. - */ - public abstract void writeChar(int v) throws TIOException; + void writeShort(int v) throws TIOException; - /** - * Writes every character in the string s, to the output stream, in order, two bytes per character. If s is null, a NullPointerException is thrown. If s.length is zero, then no characters are written. Otherwise, the character s[0] is written first, then s[1], and so on; the last character written is s[s.length-1]. For each character, two bytes are actually written, high-order byte first, in exactly the manner of the writeChar method. - */ - public abstract void writeChars(TString s) throws java.io.IOException; + void writeChar(int v) throws TIOException; - /** - * Writes a double value, which is comprised of eight bytes, to the output stream. It does this as if it first converts this double value to a long in exactly the manner of the Double.doubleToLongBits method and then writes the long value in exactly the manner of the writeLong method. The bytes written by this method may be read by the readDouble method of interface DataInput, which will then return a double equal to v. - */ - public abstract void writeDouble(double v) throws TIOException; + void writeInt(int v) throws TIOException; - /** - * Writes a float value, which is comprised of four bytes, to the output stream. It does this as if it first converts this float value to an int in exactly the manner of the Float.floatToIntBits method and then writes the int value in exactly the manner of the writeInt method. The bytes written by this method may be read by the readFloat method of interface DataInput, which will then return a float equal to v. - */ - public abstract void writeFloat(float v) throws TIOException; + void writeLong(long v) throws TIOException; - /** - * Writes an int value, which is comprised of four bytes, to the output stream. The byte values to be written, in the order shown, are: - * (byte)(0xff (v 24)) (byte)(0xff (v 16)) (byte)(0xff (v 8)) (byte)(0xff v) - * The bytes written by this method may be read by the readInt method of interface DataInput, which will then return an int equal to v. - */ - public abstract void writeInt(int v) throws TIOException; + void writeFloat(float v) throws TIOException; - /** - * Writes an long value, which is comprised of four bytes, to the output stream. The byte values to be written, in the order shown, are: - * (byte)(0xff (v 56)) (byte)(0xff (v 48)) (byte)(0xff (v 40)) (byte)(0xff (v 32)) (byte)(0xff (v 24)) (byte)(0xff (v 16)) (byte)(0xff (v 8)) (byte)(0xff v) - * The bytes written by this method may be read by the readLong method of interface DataInput, which will then return a long equal to v. - */ - public abstract void writeLong(long v) throws TIOException; + void writeDouble(double v) throws TIOException; - /** - * Writes two bytes to the output stream to represent the value of the argument. The byte values to be written, in the order shown, are: - * (byte)(0xff (v 8)) (byte)(0xff v) - * The bytes written by this method may be read by the readShort method of interface DataInput, which will then return a short equal to (short)v. - */ - public abstract void writeShort(int v) throws TIOException; + void writeBytes(TString s) throws TIOException; - /** - * Writes two bytes of length information to the output stream, followed by the Java modified UTF representation of every character in the string s. If s is null, a NullPointerException is thrown. Each character in the string s is converted to a group of one, two, or three bytes, depending on the value of the character. - * If a character c is in the range u0001 through u007f, it is represented by one byte: - * (byte)c - * If a character c is u0000 or is in the range u0080 through u07ff, then it is represented by two bytes, to be written in the order shown: - * (byte)(0xc0 | (0x1f (c 6))) (byte)(0x80 | (0x3f c)) - * If a character c is in the range u0800 through uffff, then it is represented by three bytes, to be written in the order shown: - * (byte)(0xe0 | (0x0f (c 12))) (byte)(0x80 | (0x3f (c 6))) (byte)(0x80 | (0x3f c)) - * First, the total number of bytes needed to represent all the characters of s is calculated. If this number is larger than 65535, then a UTFDataFormatError is thrown. Otherwise, this length is written to the output stream in exactly the manner of the writeShort method; after this, the one-, two-, or three-byte representation of each character in the string s is written. - * The bytes written by this method may be read by the readUTF method of interface DataInput, which will then return a String equal to s. - */ - public abstract void writeUTF(TString s) throws TIOException; + void writeChars(TString s) throws TIOException; + void writeUTF(TString s) throws TIOException; } diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TDataOutputStream.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TDataOutputStream.java index 78fa7bcb0..709d613da 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TDataOutputStream.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TDataOutputStream.java @@ -18,10 +18,6 @@ package org.teavm.classlib.java.io; import org.teavm.classlib.java.lang.*; -/** - * A data output stream lets an application write primitive Java data types to an output stream in a portable way. An application can then use a data input stream to read the data back in. - * Since: JDK1.0, CLDC 1.0 See Also:DataInputStream - */ public class TDataOutputStream extends TFilterOutputStream implements TDataOutput{ /** * The number of bytes written out so far. @@ -73,6 +69,7 @@ public class TDataOutputStream extends TFilterOutputStream implements TDataOutpu written++; } + @Override public final void writeBytes(TString str) throws TIOException { if (str.length() == 0) { return; From 6017bd6586a49d181b126ac1381454b0ac6be90c Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Sun, 8 Mar 2015 21:13:31 +0300 Subject: [PATCH 27/69] Fix https://github.com/konsoletyper/teavm/issues/84 --- .../java/org/teavm/platform/plugin/PlatformGenerator.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java index 6e0a0208a..ede1670d6 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java @@ -152,7 +152,7 @@ public class PlatformGenerator implements Generator, Injector, DependencyPlugin } else { writer.append("return cls[c]($return);").softNewLine(); } - writer.outdent().append("}").softNewLine(); + writer.outdent().append("};").softNewLine(); writer.append("return ").append(selfName).append("(").append(context.getParameterName(1)); if (context.isAsync()) { @@ -225,7 +225,7 @@ public class PlatformGenerator implements Generator, Injector, DependencyPlugin writer.append("return null;").softNewLine(); writer.outdent().append("}").softNewLine(); writer.append("return cls[c]();").softNewLine(); - writer.outdent().append("}").softNewLine(); + writer.outdent().append("};").softNewLine(); writer.append("return ").append(selfName).append("(").append(context.getParameterName(1)) .append(");").softNewLine(); From 97889bc217bb97f43bd6f53bb7b3af6603eb3adc Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Mon, 9 Mar 2015 11:29:49 +0300 Subject: [PATCH 28/69] Improve minification of async code --- .../java/org/teavm/javascript/Renderer.java | 57 ++++++++++++------- .../platform/plugin/AsyncMethodGenerator.java | 9 ++- .../platform/plugin/PlatformGenerator.java | 2 +- 3 files changed, 44 insertions(+), 24 deletions(-) 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 7c02724c7..5c240ecfd 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java @@ -537,7 +537,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext args.add(variableName(i)); } if (async) { - args.add("$return"); + args.add(getReturnVariable()); } for (int i = 0; i < args.size(); ++i) { if (i > 0) { @@ -557,6 +557,18 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext writer.append(");").ws().append("}"); } + private String getPartVariable(int index) { + if (minifying) { + return "$p" + indexToId(index); + } else { + return "$part_" + index; + } + } + + private String getReturnVariable() { + return minifying ? "$r" : "$return"; + } + public void renderBody(MethodNode method, boolean inner) throws IOException { blockIdMap.clear(); MethodReference ref = method.getReference(); @@ -581,7 +593,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext if (startParam < ref.parameterCount() + 1) { writer.append(',').ws(); } - writer.append("$return"); + writer.append(getReturnVariable()); } writer.append(")").ws().append("{").softNewLine().indent(); method.acceptVisitor(new MethodBodyRenderer()); @@ -601,11 +613,11 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext writer.append(variableName(i)); writer.append(",").ws(); } - writer.append("$return)").ws().append("{").softNewLine().indent(); + writer.append(getReturnVariable()).append(")").ws().append("{").softNewLine().indent(); - writer.append("var $r;").softNewLine(); + writer.append("var $x;").softNewLine(); writer.append("try").ws().append('{').indent().softNewLine(); - writer.append("$r").ws().append("=").ws().appendMethodBody(ref).append('('); + writer.append("$x").ws().append("=").ws().appendMethodBody(ref).append('('); for (int i = startParam; i <= ref.parameterCount(); ++i) { if (i > startParam) { writer.append(",").ws(); @@ -615,9 +627,9 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext writer.append(");").softNewLine(); writer.outdent().append("}").ws().append("catch").ws().append("($e)").ws() .append("{").indent().softNewLine(); - writer.append("return $return($rt_asyncError($e));").softNewLine(); + writer.append("return ").append(getReturnVariable()).append("($rt_asyncError($e));").softNewLine(); writer.outdent().append("}"); - writer.append("$return($rt_asyncResult($r));").softNewLine(); + writer.append(getReturnVariable()).append("($rt_asyncResult($x));").softNewLine(); writer.outdent().append("}"); if (inner) { writer.append(';'); @@ -720,16 +732,17 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext writer.append(";").softNewLine(); } for (int i = 0; i < methodNode.getBody().size(); ++i) { - writer.append("var $part_").append(i).ws().append("=").ws().append("$rt_guardAsync(function("); + writer.append("var ").append(getPartVariable(i)).ws().append("=").ws() + .append("$rt_guardAsync(function("); if (i > 0) { writer.append("$restore"); } writer.append(")").ws().append("{").indent().softNewLine(); AsyncMethodPart part = methodNode.getBody().get(i); part.getStatement().acceptVisitor(Renderer.this); - writer.outdent().append("},").ws().append("$return);").softNewLine(); + writer.outdent().append("},").ws().append(getReturnVariable()).append(");").softNewLine(); } - writer.append("return $part_0();").softNewLine(); + writer.append("return ").append(getPartVariable(0)).append("();").softNewLine(); } catch (IOException e) { throw new RenderingException("IO error occured", e); } @@ -777,7 +790,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext @Override public String getCompleteContinuation() { - return "$return"; + return getReturnVariable(); } @Override @@ -972,18 +985,22 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext private String mapBlockId(String id) { String name = blockIdMap.get(id); if (name == null) { - StringBuilder sb = new StringBuilder(); int index = blockIdMap.size(); - do { - sb.append(variablePartNames.charAt(index % variablePartNames.length())); - index /= variablePartNames.length(); - } while (index > 0); - name = "$b" + sb; + name = "$b" + indexToId(index); blockIdMap.put(id, name); } return name; } + private String indexToId(int index) { + StringBuilder sb = new StringBuilder(); + do { + sb.append(variablePartNames.charAt(index % variablePartNames.length())); + index /= variablePartNames.length(); + } while (index > 0); + return sb.toString(); + } + @Override public void visit(BlockStatement statement) { try { @@ -1046,7 +1063,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext } writer.append("return"); if (async) { - writer.append(" $return($rt_asyncResult("); + writer.append(' ').append(getReturnVariable()).append("($rt_asyncResult("); } if (statement.getResult() != null) { if (!async) { @@ -1709,7 +1726,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext if (hasParams) { writer.append(',').ws(); } - writer.append("$rt_continue($part_").append(expr.getAsyncTarget()).append(')'); + writer.append("$rt_continue(").append(getPartVariable(expr.getAsyncTarget())).append(')'); } writer.append(')'); exitPriority(); @@ -2008,7 +2025,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext writer.append("return ").append(naming.getFullNameForAsync(monitorEnterRef)).append("("); statement.getObjectRef().acceptVisitor(this); writer.append(",").ws(); - writer.append("$rt_continue($part_").append(statement.getAsyncTarget()).append(')'); + writer.append("$rt_continue(").append(getPartVariable(statement.getAsyncTarget())).append(')'); writer.append(");").softNewLine(); } else { MethodReference monitorEnterRef = new MethodReference( diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/AsyncMethodGenerator.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/AsyncMethodGenerator.java index e102002a1..e30af413a 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/plugin/AsyncMethodGenerator.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/AsyncMethodGenerator.java @@ -41,11 +41,13 @@ public class AsyncMethodGenerator implements Generator, DependencyPlugin { writer.append("var callback").ws().append("=").ws().append("function()").ws().append("{};").softNewLine(); writer.append("callback.").appendMethod(completeMethod).ws().append("=").ws().append("function(val)").ws() .append("{").indent().softNewLine(); - writer.append("return $return($rt_asyncResult(val));").softNewLine(); + writer.append("return ").append(context.getCompleteContinuation()).append("($rt_asyncResult(val));") + .softNewLine(); writer.outdent().append("};").softNewLine(); writer.append("callback.").appendMethod(errorMethod).ws().append("=").ws().append("function(e)").ws() .append("{").indent().softNewLine(); - writer.append("return $return($rt_asyncError(e));").softNewLine(); + writer.append("return ").append(context.getCompleteContinuation()).append("($rt_asyncError(e));") + .softNewLine(); writer.outdent().append("};").softNewLine(); writer.append("try").ws().append("{").indent().softNewLine(); writer.append("return ").appendMethodBody(asyncRef).append('('); @@ -58,7 +60,8 @@ public class AsyncMethodGenerator implements Generator, DependencyPlugin { } writer.append("callback);").softNewLine(); writer.outdent().append("}").ws().append("catch($e)").ws().append("{").indent().softNewLine(); - writer.append("return $return($rt_asyncError($e));").softNewLine(); + writer.append("return ").append(context.getCompleteContinuation()).append("($rt_asyncError($e));") + .softNewLine(); writer.outdent().append("}").softNewLine(); } diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java index ede1670d6..756545a3c 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java @@ -156,7 +156,7 @@ public class PlatformGenerator implements Generator, Injector, DependencyPlugin writer.append("return ").append(selfName).append("(").append(context.getParameterName(1)); if (context.isAsync()) { - writer.append(',').ws().append("$return"); + writer.append(',').ws().append(context.getCompleteContinuation()); } writer.append(");").softNewLine(); } From 62118e2cfe7e7d697c922e9e6c07d360cd9e8e7b Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Mon, 9 Mar 2015 13:28:37 +0300 Subject: [PATCH 29/69] Add frequency-based naming in minified mode --- .../lang/reflect/ArrayNativeGenerator.java | 2 +- .../java/org/teavm/codegen/AliasProvider.java | 3 + .../teavm/codegen/DefaultAliasProvider.java | 13 + .../teavm/codegen/DefaultNamingStrategy.java | 10 +- .../teavm/codegen/MinifyingAliasProvider.java | 17 +- .../teavm/codegen/NameFrequencyConsumer.java | 40 ++ .../java/org/teavm/codegen/NamingOrderer.java | 162 ++++++++ .../org/teavm/codegen/NamingStrategy.java | 5 +- .../java/org/teavm/codegen/SourceWriter.java | 12 +- .../javascript/NameFrequencyEstimator.java | 347 ++++++++++++++++++ .../java/org/teavm/javascript/Renderer.java | 18 +- .../src/main/java/org/teavm/vm/TeaVM.java | 3 +- .../teavm/html4j/JavaScriptBodyGenerator.java | 2 +- .../teavm/jso/plugin/JSOAliasRenderer.java | 4 +- .../platform/plugin/AsyncMethodGenerator.java | 8 +- ...ScopedMetadataProviderNativeGenerator.java | 2 +- 16 files changed, 614 insertions(+), 34 deletions(-) create mode 100644 teavm-core/src/main/java/org/teavm/codegen/NameFrequencyConsumer.java create mode 100644 teavm-core/src/main/java/org/teavm/codegen/NamingOrderer.java create mode 100644 teavm-core/src/main/java/org/teavm/javascript/NameFrequencyEstimator.java diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/reflect/ArrayNativeGenerator.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/reflect/ArrayNativeGenerator.java index 468334f63..ed9a46d5c 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/reflect/ArrayNativeGenerator.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/reflect/ArrayNativeGenerator.java @@ -73,7 +73,7 @@ public class ArrayNativeGenerator implements Generator, DependencyPlugin { writer.append("if (" + array + " === null || " + array + ".constructor.$meta.item === undefined) {") .softNewLine().indent(); String clsName = "java.lang.IllegalArgumentException"; - MethodReference cons = new MethodReference(clsName, new MethodDescriptor("", ValueType.VOID)); + MethodDescriptor cons = new MethodDescriptor("", ValueType.VOID); writer.append("$rt_throw(").appendClass(clsName).append(".").appendMethod(cons).append("());").softNewLine(); writer.outdent().append("}").softNewLine(); writer.append("return " + array + ".data.length;").softNewLine(); diff --git a/teavm-core/src/main/java/org/teavm/codegen/AliasProvider.java b/teavm-core/src/main/java/org/teavm/codegen/AliasProvider.java index 0f521f5e3..28a615277 100644 --- a/teavm-core/src/main/java/org/teavm/codegen/AliasProvider.java +++ b/teavm-core/src/main/java/org/teavm/codegen/AliasProvider.java @@ -16,6 +16,7 @@ package org.teavm.codegen; import org.teavm.model.FieldReference; +import org.teavm.model.MethodDescriptor; import org.teavm.model.MethodReference; /** @@ -27,5 +28,7 @@ public interface AliasProvider { String getAlias(MethodReference method); + String getAlias(MethodDescriptor method); + String getAlias(String className); } diff --git a/teavm-core/src/main/java/org/teavm/codegen/DefaultAliasProvider.java b/teavm-core/src/main/java/org/teavm/codegen/DefaultAliasProvider.java index 22d4a5f7e..9b66e6cca 100644 --- a/teavm-core/src/main/java/org/teavm/codegen/DefaultAliasProvider.java +++ b/teavm-core/src/main/java/org/teavm/codegen/DefaultAliasProvider.java @@ -16,6 +16,7 @@ package org.teavm.codegen; import org.teavm.model.FieldReference; +import org.teavm.model.MethodDescriptor; import org.teavm.model.MethodReference; /** @@ -24,6 +25,7 @@ import org.teavm.model.MethodReference; */ public class DefaultAliasProvider implements AliasProvider { private int lastSuffix; + private int lastVirtualSuffix; @Override public String getAlias(String cls) { @@ -48,6 +50,17 @@ public class DefaultAliasProvider implements AliasProvider { return alias.toString(); } + @Override + public String getAlias(MethodDescriptor method) { + String alias = method.getName(); + if (alias.equals("")) { + alias = "$init"; + } else if (alias.equals("")) { + alias = "$clinit"; + } + return alias + lastVirtualSuffix++; + } + @Override public String getAlias(MethodReference method) { String alias = method.getDescriptor().getName(); diff --git a/teavm-core/src/main/java/org/teavm/codegen/DefaultNamingStrategy.java b/teavm-core/src/main/java/org/teavm/codegen/DefaultNamingStrategy.java index db4209c51..f977b3a33 100644 --- a/teavm-core/src/main/java/org/teavm/codegen/DefaultNamingStrategy.java +++ b/teavm-core/src/main/java/org/teavm/codegen/DefaultNamingStrategy.java @@ -56,17 +56,17 @@ public class DefaultNamingStrategy implements NamingStrategy { } @Override - public String getNameFor(MethodReference method) { + public String getNameFor(MethodDescriptor method) { return getNameFor(method, 'S'); } @Override - public String getNameForAsync(MethodReference method) throws NamingException { + public String getNameForAsync(MethodDescriptor method) throws NamingException { return getNameFor(method, 'A'); } - private String getNameFor(MethodReference method, char classifier) { - String key = classifier + method.getDescriptor().toString(); + private String getNameFor(MethodDescriptor method, char classifier) { + String key = classifier + method.toString(); String alias = aliases.get(key); if (alias == null) { alias = aliasProvider.getAlias(method); @@ -97,7 +97,7 @@ public class DefaultNamingStrategy implements NamingStrategy { throw new NamingException("Can't provide name for method as it was not found: " + originalMethod); } if (!minifying) { - return getNameFor(method.getClassName()) + "_" + getNameFor(method, classifier); + return getNameFor(method.getClassName()) + "_" + getNameFor(method.getDescriptor(), classifier); } String key = classifier + method.toString(); String alias = privateAliases.get(key); diff --git a/teavm-core/src/main/java/org/teavm/codegen/MinifyingAliasProvider.java b/teavm-core/src/main/java/org/teavm/codegen/MinifyingAliasProvider.java index 4f8e83d44..1410f3991 100644 --- a/teavm-core/src/main/java/org/teavm/codegen/MinifyingAliasProvider.java +++ b/teavm-core/src/main/java/org/teavm/codegen/MinifyingAliasProvider.java @@ -16,6 +16,7 @@ package org.teavm.codegen; import org.teavm.model.FieldReference; +import org.teavm.model.MethodDescriptor; import org.teavm.model.MethodReference; /** @@ -25,25 +26,31 @@ import org.teavm.model.MethodReference; public class MinifyingAliasProvider implements AliasProvider { private static String startLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; private static String letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + private static String startVirtualLetters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; private int lastSuffix; + private int lastVirtual; @Override public String getAlias(FieldReference field) { - return getNewAlias(); + return getNewAlias(lastVirtual++, startVirtualLetters); } @Override public String getAlias(MethodReference method) { - return getNewAlias(); + return getNewAlias(lastSuffix++, startLetters); + } + + @Override + public String getAlias(MethodDescriptor method) { + return getNewAlias(lastVirtual++, startVirtualLetters); } @Override public String getAlias(String className) { - return getNewAlias(); + return getNewAlias(lastSuffix++, startLetters); } - private String getNewAlias() { - int index = lastSuffix++; + private String getNewAlias(int index, String startLetters) { StringBuilder sb = new StringBuilder(); sb.append(startLetters.charAt(index % startLetters.length())); index /= startLetters.length(); diff --git a/teavm-core/src/main/java/org/teavm/codegen/NameFrequencyConsumer.java b/teavm-core/src/main/java/org/teavm/codegen/NameFrequencyConsumer.java new file mode 100644 index 000000000..bfa6cfaab --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/codegen/NameFrequencyConsumer.java @@ -0,0 +1,40 @@ +/* + * Copyright 2015 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.codegen; + +import org.teavm.model.FieldReference; +import org.teavm.model.MethodDescriptor; +import org.teavm.model.MethodReference; + +/** + * + * @author Alexey Andreev + */ +public interface NameFrequencyConsumer { + void consume(MethodReference method); + + void consumeAsync(MethodReference method); + + void consumeInit(MethodReference method); + + void consume(MethodDescriptor method); + + void consumeAsync(MethodDescriptor method); + + void consume(String className); + + void consume(FieldReference field); +} diff --git a/teavm-core/src/main/java/org/teavm/codegen/NamingOrderer.java b/teavm-core/src/main/java/org/teavm/codegen/NamingOrderer.java new file mode 100644 index 000000000..1ab640f3e --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/codegen/NamingOrderer.java @@ -0,0 +1,162 @@ +/* + * Copyright 2015 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.codegen; + +import java.util.*; +import org.teavm.model.FieldReference; +import org.teavm.model.MethodDescriptor; +import org.teavm.model.MethodReference; + +/** + * + * @author Alexey Andreev + */ +public class NamingOrderer implements NameFrequencyConsumer { + private Map entries = new HashMap<>(); + + @Override + public void consume(final MethodReference method) { + String key = "R:" + method; + Entry entry = entries.get(key); + if (entry == null) { + entry = new Entry(); + entry.operation = new NamingOperation() { + @Override public void perform(NamingStrategy naming) { + naming.getFullNameFor(method); + } + }; + entries.put(key, entry); + } + entry.frequency++; + } + + @Override + public void consumeAsync(final MethodReference method) { + String key = "A:" + method; + Entry entry = entries.get(key); + if (entry == null) { + entry = new Entry(); + entry.operation = new NamingOperation() { + @Override public void perform(NamingStrategy naming) { + naming.getFullNameForAsync(method); + } + }; + entries.put(key, entry); + } + entry.frequency++; + } + + @Override + public void consumeInit(final MethodReference method) { + String key = "I:" + method; + Entry entry = entries.get(key); + if (entry == null) { + entry = new Entry(); + entry.operation = new NamingOperation() { + @Override public void perform(NamingStrategy naming) { + naming.getNameForInit(method); + } + }; + entries.put(key, entry); + } + entry.frequency++; + } + + @Override + public void consume(final MethodDescriptor method) { + String key = "r:" + method; + Entry entry = entries.get(key); + if (entry == null) { + entry = new Entry(); + entry.operation = new NamingOperation() { + @Override public void perform(NamingStrategy naming) { + naming.getNameFor(method); + } + }; + entries.put(key, entry); + } + entry.frequency++; + } + + @Override + public void consumeAsync(final MethodDescriptor method) { + String key = "a:" + method; + Entry entry = entries.get(key); + if (entry == null) { + entry = new Entry(); + entry.operation = new NamingOperation() { + @Override public void perform(NamingStrategy naming) { + naming.getNameForAsync(method); + } + }; + entries.put(key, entry); + } + entry.frequency++; + } + + @Override + public void consume(final String className) { + String key = "c:" + className; + Entry entry = entries.get(key); + if (entry == null) { + entry = new Entry(); + entry.operation = new NamingOperation() { + @Override public void perform(NamingStrategy naming) { + naming.getNameFor(className); + } + }; + entries.put(key, entry); + } + entry.frequency++; + } + + @Override + public void consume(final FieldReference field) { + String key = "f:" + field; + Entry entry = entries.get(key); + if (entry == null) { + entry = new Entry(); + entry.operation = new NamingOperation() { + @Override public void perform(NamingStrategy naming) { + naming.getNameFor(field); + } + }; + entries.put(key, entry); + } + entry.frequency++; + } + + public void apply(NamingStrategy naming) { + List entryList = new ArrayList<>(entries.values()); + Collections.sort(entryList, new Comparator() { + @Override public int compare(Entry o1, Entry o2) { + return Integer.compare(o2.frequency, o1.frequency); + } + }); + for (Entry entry : entryList) { + entry.operation.perform(naming); + } + } + + static class Entry { + NamingOperation operation; + int frequency; + } + + interface NamingOperation { + void perform(NamingStrategy naming); + } +} diff --git a/teavm-core/src/main/java/org/teavm/codegen/NamingStrategy.java b/teavm-core/src/main/java/org/teavm/codegen/NamingStrategy.java index 0851c0b78..bbdd476e7 100644 --- a/teavm-core/src/main/java/org/teavm/codegen/NamingStrategy.java +++ b/teavm-core/src/main/java/org/teavm/codegen/NamingStrategy.java @@ -16,6 +16,7 @@ package org.teavm.codegen; import org.teavm.model.FieldReference; +import org.teavm.model.MethodDescriptor; import org.teavm.model.MethodReference; /** @@ -25,9 +26,9 @@ import org.teavm.model.MethodReference; public interface NamingStrategy { String getNameFor(String cls) throws NamingException; - String getNameFor(MethodReference method) throws NamingException; + String getNameFor(MethodDescriptor method) throws NamingException; - String getNameForAsync(MethodReference method) throws NamingException; + String getNameForAsync(MethodDescriptor method) throws NamingException; String getNameForInit(MethodReference method) throws NamingException; diff --git a/teavm-core/src/main/java/org/teavm/codegen/SourceWriter.java b/teavm-core/src/main/java/org/teavm/codegen/SourceWriter.java index a1ced11f0..4be2811cb 100644 --- a/teavm-core/src/main/java/org/teavm/codegen/SourceWriter.java +++ b/teavm-core/src/main/java/org/teavm/codegen/SourceWriter.java @@ -111,18 +111,16 @@ public class SourceWriter implements Appendable, LocationProvider { return append(naming.getNameFor(field)); } - public SourceWriter appendMethod(MethodReference method) throws NamingException, IOException { + public SourceWriter appendMethod(MethodDescriptor method) throws NamingException, IOException { return append(naming.getNameFor(method)); } - public SourceWriter appendMethod(String className, String name, ValueType... params) - throws NamingException, IOException { - return append(naming.getNameFor(new MethodReference(className, name, params))); + public SourceWriter appendMethod(String name, ValueType... params) throws NamingException, IOException { + return append(naming.getNameFor(new MethodDescriptor(name, params))); } - public SourceWriter appendMethod(Class cls, String name, Class... params) - throws NamingException, IOException { - return append(naming.getNameFor(new MethodReference(cls, name, params))); + public SourceWriter appendMethod(String name, Class... params) throws NamingException, IOException { + return append(naming.getNameFor(new MethodDescriptor(name, params))); } public SourceWriter appendMethodBody(MethodReference method) throws NamingException, IOException { diff --git a/teavm-core/src/main/java/org/teavm/javascript/NameFrequencyEstimator.java b/teavm-core/src/main/java/org/teavm/javascript/NameFrequencyEstimator.java new file mode 100644 index 000000000..c68a4b9e8 --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/javascript/NameFrequencyEstimator.java @@ -0,0 +1,347 @@ +/* + * Copyright 2015 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.javascript; + +import java.util.List; +import java.util.Set; +import org.teavm.codegen.NameFrequencyConsumer; +import org.teavm.javascript.ast.*; +import org.teavm.model.*; + +/** + * + * @author Alexey Andreev + */ +public class NameFrequencyEstimator implements StatementVisitor, ExprVisitor, MethodNodeVisitor { + private NameFrequencyConsumer consumer; + private ClassReaderSource classSource; + private boolean async; + private Set injectedMethods; + private Set asyncFamilyMethods; + + public NameFrequencyEstimator(NameFrequencyConsumer consumer, ClassReaderSource classSource, + Set injectedMethods, Set asyncFamilyMethods) { + this.consumer = consumer; + this.classSource = classSource; + this.injectedMethods = injectedMethods; + this.asyncFamilyMethods = asyncFamilyMethods; + } + + private void visit(List statements) { + for (Statement part : statements) { + part.acceptVisitor(this); + } + } + + public void estimate(ClassNode cls) { + // Declaration + consumer.consume(cls.getName()); + if (cls.getParentName() != null) { + consumer.consume(cls.getParentName()); + } + for (FieldNode field : cls.getFields()) { + consumer.consume(new FieldReference(cls.getName(), field.getName())); + if (field.getModifiers().contains(NodeModifier.STATIC)) { + consumer.consume(cls.getName()); + } + } + + // Methods + MethodReader clinit = classSource.get(cls.getName()).getMethod( + new MethodDescriptor("", ValueType.VOID)); + for (MethodNode method : cls.getMethods()) { + if (method.isAsync()) { + consumer.consumeAsync(method.getReference()); + } else { + consumer.consume(method.getReference()); + if (asyncFamilyMethods.contains(method.getReference())) { + consumer.consume(method.getReference()); + consumer.consumeAsync(method.getReference()); + } + } + if (clinit != null && (method.getModifiers().contains(NodeModifier.STATIC) || + method.getReference().getName().equals(""))) { + if (!method.isAsync()) { + consumer.consume(method.getReference()); + } + if (asyncFamilyMethods.contains(method.getReference())) { + consumer.consumeAsync(method.getReference()); + } + } + if (!method.getModifiers().contains(NodeModifier.STATIC)) { + if (method.isAsync()) { + consumer.consumeAsync(method.getReference().getDescriptor()); + consumer.consumeAsync(method.getReference()); + } else { + consumer.consume(method.getReference().getDescriptor()); + consumer.consume(method.getReference()); + if (asyncFamilyMethods.contains(method.getReference())) { + consumer.consumeAsync(method.getReference().getDescriptor()); + consumer.consumeAsync(method.getReference()); + } + } + } + } + + // Metadata + consumer.consume(cls.getName()); + consumer.consume(cls.getName()); + if (cls.getParentName() != null) { + consumer.consume(cls.getParentName()); + } + for (String iface : cls.getInterfaces()) { + consumer.consume(iface); + } + } + + @Override + public void visit(RegularMethodNode methodNode) { + async = false; + methodNode.getBody().acceptVisitor(this); + } + + @Override + public void visit(AsyncMethodNode methodNode) { + async = true; + for (AsyncMethodPart part : methodNode.getBody()) { + part.getStatement().acceptVisitor(this); + } + } + + @Override + public void visit(NativeMethodNode methodNode) { + } + + @Override + public void visit(AssignmentStatement statement) { + if (statement.getLeftValue() != null) { + statement.getLeftValue().acceptVisitor(this); + } + statement.getRightValue().acceptVisitor(this); + } + + @Override + public void visit(SequentialStatement statement) { + visit(statement.getSequence()); + } + + @Override + public void visit(ConditionalStatement statement) { + statement.getCondition().acceptVisitor(this); + visit(statement.getConsequent()); + visit(statement.getAlternative()); + } + + @Override + public void visit(SwitchStatement statement) { + statement.getValue().acceptVisitor(this); + for (SwitchClause clause : statement.getClauses()) { + visit(clause.getBody()); + } + visit(statement.getDefaultClause()); + } + + @Override + public void visit(WhileStatement statement) { + if (statement.getCondition() != null) { + statement.getCondition().acceptVisitor(this); + } + visit(statement.getBody()); + } + + @Override + public void visit(BlockStatement statement) { + visit(statement.getBody()); + } + + @Override + public void visit(BreakStatement statement) { + } + + @Override + public void visit(ContinueStatement statement) { + } + + @Override + public void visit(ReturnStatement statement) { + if (statement.getResult() != null) { + statement.getResult().acceptVisitor(this); + } + } + + @Override + public void visit(ThrowStatement statement) { + statement.getException().acceptVisitor(this); + } + + @Override + public void visit(InitClassStatement statement) { + consumer.consume(statement.getClassName()); + } + + @Override + public void visit(TryCatchStatement statement) { + visit(statement.getProtectedBody()); + visit(statement.getHandler()); + if (statement.getExceptionType() != null) { + consumer.consume(statement.getExceptionType()); + } + } + + @Override + public void visit(RestoreAsyncStatement statement) { + } + + @Override + public void visit(MonitorEnterStatement statement) { + if (async) { + MethodReference monitorEnterRef = new MethodReference( + Object.class, "monitorEnter", Object.class, void.class); + consumer.consumeAsync(monitorEnterRef); + } else { + MethodReference monitorEnterRef = new MethodReference( + Object.class, "monitorEnterSync", Object.class, void.class); + consumer.consume(monitorEnterRef); + } + } + + @Override + public void visit(MonitorExitStatement statement) { + if (async) { + MethodReference monitorEnterRef = new MethodReference( + Object.class, "monitorExit", Object.class, void.class); + consumer.consumeAsync(monitorEnterRef); + } else { + MethodReference monitorEnterRef = new MethodReference( + Object.class, "monitorExitSync", Object.class, void.class); + consumer.consume(monitorEnterRef); + } + } + + @Override + public void visit(BinaryExpr expr) { + expr.getFirstOperand().acceptVisitor(this); + expr.getSecondOperand().acceptVisitor(this); + } + + @Override + public void visit(UnaryExpr expr) { + expr.getOperand().acceptVisitor(this); + } + + @Override + public void visit(ConditionalExpr expr) { + expr.getCondition().acceptVisitor(this); + expr.getConsequent().acceptVisitor(this); + expr.getAlternative().acceptVisitor(this); + } + + @Override + public void visit(ConstantExpr expr) { + if (expr.getValue() instanceof ValueType) { + visitType((ValueType)expr.getValue()); + } + } + + private void visitType(ValueType type) { + while (type instanceof ValueType.Array) { + type = ((ValueType.Array)type).getItemType(); + } + if (type instanceof ValueType.Object) { + String clsName = ((ValueType.Object)type).getClassName(); + consumer.consume(clsName); + } + } + + @Override + public void visit(VariableExpr expr) { + } + + @Override + public void visit(SubscriptExpr expr) { + expr.getArray().acceptVisitor(this); + expr.getIndex().acceptVisitor(this); + } + + @Override + public void visit(UnwrapArrayExpr expr) { + expr.getArray().acceptVisitor(this); + } + + @Override + public void visit(InvocationExpr expr) { + if (injectedMethods.contains(expr.getMethod())) { + return; + } + boolean asyncCall = expr.getAsyncTarget() != null; + switch (expr.getType()) { + case SPECIAL: + case STATIC: + if (asyncCall) { + consumer.consumeAsync(expr.getMethod()); + } else { + consumer.consume(expr.getMethod()); + } + break; + case CONSTRUCTOR: + consumer.consumeInit(expr.getMethod()); + break; + case DYNAMIC: + if (asyncCall) { + consumer.consumeAsync(expr.getMethod().getDescriptor()); + } else { + consumer.consume(expr.getMethod().getDescriptor()); + } + break; + } + } + + @Override + public void visit(QualificationExpr expr) { + expr.getQualified().acceptVisitor(this); + consumer.consume(expr.getField()); + } + + @Override + public void visit(NewExpr expr) { + consumer.consume(expr.getConstructedClass()); + } + + @Override + public void visit(NewArrayExpr expr) { + visitType(expr.getType()); + expr.getLength().acceptVisitor(this); + } + + @Override + public void visit(NewMultiArrayExpr expr) { + visitType(expr.getType()); + for (Expr dimension : expr.getDimensions()) { + dimension.acceptVisitor(this); + } + } + + @Override + public void visit(InstanceOfExpr expr) { + expr.getExpr().acceptVisitor(this); + visitType(expr.getType()); + } + + @Override + public void visit(StaticClassExpr expr) { + visitType(expr.getType()); + } +} 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 5c240ecfd..c205a34f8 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java @@ -20,6 +20,7 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.*; import org.teavm.codegen.NamingException; +import org.teavm.codegen.NamingOrderer; import org.teavm.codegen.NamingStrategy; import org.teavm.codegen.SourceWriter; import org.teavm.common.ServiceRepository; @@ -259,6 +260,15 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext } public void render(List classes) throws RenderingException { + if (minifying) { + NamingOrderer orderer = new NamingOrderer(); + NameFrequencyEstimator estimator = new NameFrequencyEstimator(orderer, classSource, asyncMethods, + asyncFamilyMethods); + for (ClassNode cls : classes) { + estimator.estimate(cls); + } + orderer.apply(naming); + } for (ClassNode cls : classes) { renderDeclaration(cls); } @@ -313,7 +323,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext .append(constantToString(value)).append(";").softNewLine(); } } catch (NamingException e) { - throw new RenderingException("Error rendering class " + cls.getName() + ". See a cause for details", e); + throw new RenderingException("Error rendering class " + cls.getName() + ". See cause for details", e); } catch (IOException e) { throw new RenderingException("IO error occured", e); } @@ -529,7 +539,8 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext } private void emitVirtualDeclaration(MethodReference ref, boolean async) throws IOException { - String methodName = async ? naming.getNameForAsync(ref) : naming.getNameFor(ref); + String methodName = async ? naming.getNameForAsync(ref.getDescriptor()) : + naming.getNameFor(ref.getDescriptor()); writer.append("\"").append(methodName).append("\""); writer.append(",").ws().append("function("); List args = new ArrayList<>(); @@ -1665,7 +1676,8 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext expr.getArguments().get(0).acceptVisitor(this); } MethodReference method = expr.getMethod(); - String name = asyncCall ? naming.getNameForAsync(method) : naming.getNameFor(method); + String name = asyncCall ? naming.getNameForAsync(method.getDescriptor()) : + naming.getNameFor(method.getDescriptor()); DeferredCallSite callSite = prevCallSite; boolean shouldEraseCallSite = lastCallSite == null; if (lastCallSite == null) { diff --git a/teavm-core/src/main/java/org/teavm/vm/TeaVM.java b/teavm-core/src/main/java/org/teavm/vm/TeaVM.java index f459e4a46..6d6912b45 100644 --- a/teavm-core/src/main/java/org/teavm/vm/TeaVM.java +++ b/teavm-core/src/main/java/org/teavm/vm/TeaVM.java @@ -549,12 +549,11 @@ public class TeaVM implements TeaVMHost, ServiceRepository { for (MethodReference injectedMethod : methodInjectors.keySet()) { decompiler.addMethodToPass(injectedMethod); } - List classOrder = decompiler.getClassOrdering(classes.getClassNames()); List classNodes = new ArrayList<>(); int index = 0; try (PrintWriter bytecodeLogger = bytecodeLogging ? new PrintWriter(new OutputStreamWriter(logStream, "UTF-8")) : null) { - for (String className : classOrder) { + for (String className : classes.getClassNames()) { ClassHolder cls = classes.get(className); for (MethodHolder method : cls.getMethods()) { processMethod(method); diff --git a/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptBodyGenerator.java b/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptBodyGenerator.java index e7ba4e610..9d22c3cd8 100644 --- a/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptBodyGenerator.java +++ b/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptBodyGenerator.java @@ -99,7 +99,7 @@ public class JavaScriptBodyGenerator implements Generator { if (ident == null) { sb.append(naming.getFullNameFor(reader.getReference())); } else { - sb.append("$this.").append(naming.getNameFor(reader.getReference())); + sb.append("$this.").append(naming.getNameFor(reader.getDescriptor())); } sb.append("("); for (int i = 0; i < reader.parameterCount(); ++i) { diff --git a/teavm-jso/src/main/java/org/teavm/jso/plugin/JSOAliasRenderer.java b/teavm-jso/src/main/java/org/teavm/jso/plugin/JSOAliasRenderer.java index a6c7aec9f..04c76fdf2 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/plugin/JSOAliasRenderer.java +++ b/teavm-jso/src/main/java/org/teavm/jso/plugin/JSOAliasRenderer.java @@ -21,7 +21,6 @@ import org.teavm.codegen.SourceWriter; import org.teavm.javascript.RenderingContext; import org.teavm.jso.plugin.JSODependencyListener.ExposedClass; import org.teavm.model.MethodDescriptor; -import org.teavm.model.MethodReference; import org.teavm.vm.BuildTarget; import org.teavm.vm.spi.RendererListener; @@ -57,8 +56,7 @@ class JSOAliasRenderer implements RendererListener { writer.append("c").ws().append("=").ws().appendClass(entry.getKey()).append(".prototype;").softNewLine(); for (Map.Entry aliasEntry : entry.getValue().methods.entrySet()) { writer.append("c.").append(aliasEntry.getValue()).ws().append("=").ws().append("c.") - .appendMethod(new MethodReference(entry.getKey(), aliasEntry.getKey())) - .append(";").softNewLine(); + .appendMethod(aliasEntry.getKey()).append(";").softNewLine(); } } writer.outdent().append("})();").newLine(); diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/AsyncMethodGenerator.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/AsyncMethodGenerator.java index e30af413a..c7e4e27bb 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/plugin/AsyncMethodGenerator.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/AsyncMethodGenerator.java @@ -39,13 +39,13 @@ public class AsyncMethodGenerator implements Generator, DependencyPlugin { public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException { MethodReference asyncRef = getAsyncReference(methodRef); writer.append("var callback").ws().append("=").ws().append("function()").ws().append("{};").softNewLine(); - writer.append("callback.").appendMethod(completeMethod).ws().append("=").ws().append("function(val)").ws() - .append("{").indent().softNewLine(); + writer.append("callback.").appendMethod(completeMethod.getDescriptor()).ws().append("=").ws() + .append("function(val)").ws().append("{").indent().softNewLine(); writer.append("return ").append(context.getCompleteContinuation()).append("($rt_asyncResult(val));") .softNewLine(); writer.outdent().append("};").softNewLine(); - writer.append("callback.").appendMethod(errorMethod).ws().append("=").ws().append("function(e)").ws() - .append("{").indent().softNewLine(); + writer.append("callback.").appendMethod(errorMethod.getDescriptor()).ws().append("=").ws() + .append("function(e)").ws().append("{").indent().softNewLine(); writer.append("return ").append(context.getCompleteContinuation()).append("($rt_asyncError(e));") .softNewLine(); writer.outdent().append("};").softNewLine(); diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/ClassScopedMetadataProviderNativeGenerator.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/ClassScopedMetadataProviderNativeGenerator.java index cfce5fd15..a41dda509 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/plugin/ClassScopedMetadataProviderNativeGenerator.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/ClassScopedMetadataProviderNativeGenerator.java @@ -80,7 +80,7 @@ public class ClassScopedMetadataProviderNativeGenerator implements Generator { Map resourceMap = generator.generateMetadata(metadataContext, methodRef); writer.append("var p").ws().append("=").ws().append("\"" + Renderer.escapeString("$$res_" + - writer.getNaming().getNameFor(methodRef)) + "\"").append(";").softNewLine(); + writer.getNaming().getFullNameFor(methodRef)) + "\"").append(";").softNewLine(); for (Map.Entry entry : resourceMap.entrySet()) { writer.appendClass(entry.getKey()).append("[p]").ws().append("=").ws(); ResourceWriterHelper.write(writer, entry.getValue()); From 93c7fb52b48793896a08c1d8e7126d459933f7ac Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Mon, 9 Mar 2015 15:14:28 +0300 Subject: [PATCH 30/69] Fix error. Apply frequency-based alias generation for some $rt functions --- .../java/org/teavm/codegen/AliasProvider.java | 2 + .../teavm/codegen/DefaultAliasProvider.java | 5 ++ .../teavm/codegen/DefaultNamingStrategy.java | 14 +++++ .../teavm/codegen/MinifyingAliasProvider.java | 5 ++ .../teavm/codegen/NameFrequencyConsumer.java | 2 + .../java/org/teavm/codegen/NamingOrderer.java | 16 ++++++ .../org/teavm/codegen/NamingStrategy.java | 2 + .../java/org/teavm/codegen/SourceWriter.java | 4 ++ .../javascript/NameFrequencyEstimator.java | 37 +++++++++++++ .../java/org/teavm/javascript/Renderer.java | 52 ++++++++++++++----- .../src/main/java/org/teavm/vm/TeaVM.java | 3 +- 11 files changed, 129 insertions(+), 13 deletions(-) diff --git a/teavm-core/src/main/java/org/teavm/codegen/AliasProvider.java b/teavm-core/src/main/java/org/teavm/codegen/AliasProvider.java index 28a615277..cdc0a89a3 100644 --- a/teavm-core/src/main/java/org/teavm/codegen/AliasProvider.java +++ b/teavm-core/src/main/java/org/teavm/codegen/AliasProvider.java @@ -31,4 +31,6 @@ public interface AliasProvider { String getAlias(MethodDescriptor method); String getAlias(String className); + + String getFunctionAlias(String name); } diff --git a/teavm-core/src/main/java/org/teavm/codegen/DefaultAliasProvider.java b/teavm-core/src/main/java/org/teavm/codegen/DefaultAliasProvider.java index 9b66e6cca..0cc90a5d5 100644 --- a/teavm-core/src/main/java/org/teavm/codegen/DefaultAliasProvider.java +++ b/teavm-core/src/main/java/org/teavm/codegen/DefaultAliasProvider.java @@ -76,4 +76,9 @@ public class DefaultAliasProvider implements AliasProvider { public String getAlias(FieldReference field) { return field.getFieldName() + (lastSuffix++); } + + @Override + public String getFunctionAlias(String name) { + return name; + } } diff --git a/teavm-core/src/main/java/org/teavm/codegen/DefaultNamingStrategy.java b/teavm-core/src/main/java/org/teavm/codegen/DefaultNamingStrategy.java index f977b3a33..0a28824b0 100644 --- a/teavm-core/src/main/java/org/teavm/codegen/DefaultNamingStrategy.java +++ b/teavm-core/src/main/java/org/teavm/codegen/DefaultNamingStrategy.java @@ -30,6 +30,7 @@ public class DefaultNamingStrategy implements NamingStrategy { private Map privateAliases = new HashMap<>(); private Map classAliases = new HashMap<>(); private Map fieldAliases = new HashMap<>(); + private Map functionAliases = new HashMap<>(); private boolean minifying; public DefaultNamingStrategy(AliasProvider aliasProvider, ClassReaderSource classSource) { @@ -126,6 +127,19 @@ public class DefaultNamingStrategy implements NamingStrategy { } } + @Override + public String getNameForFunction(String name) throws NamingException { + if (!minifying) { + return name; + } + String alias = functionAliases.get(name); + if (alias == null) { + alias = aliasProvider.getFunctionAlias(name); + functionAliases.put(name, alias); + } + return alias; + } + private MethodReference getRealMethod(MethodReference methodRef) { String className = methodRef.getClassName(); while (className != null) { diff --git a/teavm-core/src/main/java/org/teavm/codegen/MinifyingAliasProvider.java b/teavm-core/src/main/java/org/teavm/codegen/MinifyingAliasProvider.java index 1410f3991..a51ce9a3a 100644 --- a/teavm-core/src/main/java/org/teavm/codegen/MinifyingAliasProvider.java +++ b/teavm-core/src/main/java/org/teavm/codegen/MinifyingAliasProvider.java @@ -50,6 +50,11 @@ public class MinifyingAliasProvider implements AliasProvider { return getNewAlias(lastSuffix++, startLetters); } + @Override + public String getFunctionAlias(String className) { + return getNewAlias(lastSuffix++, startLetters); + } + private String getNewAlias(int index, String startLetters) { StringBuilder sb = new StringBuilder(); sb.append(startLetters.charAt(index % startLetters.length())); diff --git a/teavm-core/src/main/java/org/teavm/codegen/NameFrequencyConsumer.java b/teavm-core/src/main/java/org/teavm/codegen/NameFrequencyConsumer.java index bfa6cfaab..20aec0331 100644 --- a/teavm-core/src/main/java/org/teavm/codegen/NameFrequencyConsumer.java +++ b/teavm-core/src/main/java/org/teavm/codegen/NameFrequencyConsumer.java @@ -37,4 +37,6 @@ public interface NameFrequencyConsumer { void consume(String className); void consume(FieldReference field); + + void consumeFunction(String name); } diff --git a/teavm-core/src/main/java/org/teavm/codegen/NamingOrderer.java b/teavm-core/src/main/java/org/teavm/codegen/NamingOrderer.java index 1ab640f3e..8cfc4399d 100644 --- a/teavm-core/src/main/java/org/teavm/codegen/NamingOrderer.java +++ b/teavm-core/src/main/java/org/teavm/codegen/NamingOrderer.java @@ -139,6 +139,22 @@ public class NamingOrderer implements NameFrequencyConsumer { entry.frequency++; } + @Override + public void consumeFunction(final String name) { + String key = "n:" + name; + Entry entry = entries.get(key); + if (entry == null) { + entry = new Entry(); + entry.operation = new NamingOperation() { + @Override public void perform(NamingStrategy naming) { + naming.getNameForFunction(name); + } + }; + entries.put(key, entry); + } + entry.frequency++; + } + public void apply(NamingStrategy naming) { List entryList = new ArrayList<>(entries.values()); Collections.sort(entryList, new Comparator() { diff --git a/teavm-core/src/main/java/org/teavm/codegen/NamingStrategy.java b/teavm-core/src/main/java/org/teavm/codegen/NamingStrategy.java index bbdd476e7..0902b5093 100644 --- a/teavm-core/src/main/java/org/teavm/codegen/NamingStrategy.java +++ b/teavm-core/src/main/java/org/teavm/codegen/NamingStrategy.java @@ -37,4 +37,6 @@ public interface NamingStrategy { String getFullNameForAsync(MethodReference method) throws NamingException; String getNameFor(FieldReference field) throws NamingException; + + String getNameForFunction(String name) throws NamingException; } diff --git a/teavm-core/src/main/java/org/teavm/codegen/SourceWriter.java b/teavm-core/src/main/java/org/teavm/codegen/SourceWriter.java index 4be2811cb..d10815dfb 100644 --- a/teavm-core/src/main/java/org/teavm/codegen/SourceWriter.java +++ b/teavm-core/src/main/java/org/teavm/codegen/SourceWriter.java @@ -137,6 +137,10 @@ public class SourceWriter implements Appendable, LocationProvider { return append(naming.getFullNameFor(new MethodReference(cls, name, params))); } + public SourceWriter appendFunction(String name) throws NamingException, IOException { + return append(naming.getNameForFunction(name)); + } + private void appendIndent() throws IOException { if (minified) { return; diff --git a/teavm-core/src/main/java/org/teavm/javascript/NameFrequencyEstimator.java b/teavm-core/src/main/java/org/teavm/javascript/NameFrequencyEstimator.java index c68a4b9e8..61d639cde 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/NameFrequencyEstimator.java +++ b/teavm-core/src/main/java/org/teavm/javascript/NameFrequencyEstimator.java @@ -70,6 +70,8 @@ public class NameFrequencyEstimator implements StatementVisitor, ExprVisitor, Me if (asyncFamilyMethods.contains(method.getReference())) { consumer.consume(method.getReference()); consumer.consumeAsync(method.getReference()); + consumer.consumeFunction("$rt_asyncError"); + consumer.consumeFunction("$rt_asyncResult"); } } if (clinit != null && (method.getModifiers().contains(NodeModifier.STATIC) || @@ -118,6 +120,7 @@ public class NameFrequencyEstimator implements StatementVisitor, ExprVisitor, Me async = true; for (AsyncMethodPart part : methodNode.getBody()) { part.getStatement().acceptVisitor(this); + consumer.consumeFunction("$rt_guardAsync"); } } @@ -180,11 +183,15 @@ public class NameFrequencyEstimator implements StatementVisitor, ExprVisitor, Me if (statement.getResult() != null) { statement.getResult().acceptVisitor(this); } + if (async) { + consumer.consumeFunction("$rt_asyncResult"); + } } @Override public void visit(ThrowStatement statement) { statement.getException().acceptVisitor(this); + consumer.consumeFunction("$rt_throw"); } @Override @@ -235,11 +242,25 @@ public class NameFrequencyEstimator implements StatementVisitor, ExprVisitor, Me public void visit(BinaryExpr expr) { expr.getFirstOperand().acceptVisitor(this); expr.getSecondOperand().acceptVisitor(this); + switch (expr.getOperation()) { + case COMPARE: + consumer.consumeFunction("$rt_compare"); + break; + default: + break; + } } @Override public void visit(UnaryExpr expr) { expr.getOperand().acceptVisitor(this); + switch (expr.getOperation()) { + case NULL_CHECK: + consumer.consumeFunction("$rt_nullCheck"); + break; + default: + break; + } } @Override @@ -263,6 +284,7 @@ public class NameFrequencyEstimator implements StatementVisitor, ExprVisitor, Me if (type instanceof ValueType.Object) { String clsName = ((ValueType.Object)type).getClassName(); consumer.consume(clsName); + consumer.consumeFunction("$rt_cls"); } } @@ -307,6 +329,9 @@ public class NameFrequencyEstimator implements StatementVisitor, ExprVisitor, Me } break; } + if (asyncCall) { + consumer.consumeFunction("$rt_continue"); + } } @Override @@ -324,6 +349,9 @@ public class NameFrequencyEstimator implements StatementVisitor, ExprVisitor, Me public void visit(NewArrayExpr expr) { visitType(expr.getType()); expr.getLength().acceptVisitor(this); + if (!(expr.getType() instanceof ValueType.Primitive)) { + consumer.consumeFunction("$rt_createArray"); + } } @Override @@ -338,6 +366,15 @@ public class NameFrequencyEstimator implements StatementVisitor, ExprVisitor, Me public void visit(InstanceOfExpr expr) { expr.getExpr().acceptVisitor(this); visitType(expr.getType()); + if (expr.getType() instanceof ValueType.Object) { + String clsName = ((ValueType.Object)expr.getType()).getClassName(); + ClassReader cls = classSource.get(clsName); + if (cls == null || cls.hasModifier(ElementModifier.INTERFACE)) { + consumer.consumeFunction("$rt_isInstance"); + } + } else { + consumer.consumeFunction("$rt_isInstance"); + } } @Override 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 c205a34f8..d158d1dd3 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java @@ -259,6 +259,20 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext writer.outdent().append("}").newLine(); } + private void renderRuntimeAliases() throws IOException { + String[] names = { "$rt_asyncResult", "$rt_asyncError", "$rt_continue", "$rt_guardAsync", "$rt_throw", + "$rt_compare", "$rt_nullCheck", "$rt_cls", "$rt_createArray", "$rt_isInstance" }; + boolean first = true; + for (String name : names) { + if (!first) { + writer.softNewLine(); + } + first = false; + writer.append("var ").appendFunction(name).ws().append('=').ws().append(name).append(";").softNewLine(); + } + writer.newLine(); + } + public void render(List classes) throws RenderingException { if (minifying) { NamingOrderer orderer = new NamingOrderer(); @@ -269,6 +283,14 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext } orderer.apply(naming); } + + if (minifying) { + try { + renderRuntimeAliases(); + } catch (IOException e) { + throw new RenderingException(e); + } + } for (ClassNode cls : classes) { renderDeclaration(cls); } @@ -638,9 +660,11 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext writer.append(");").softNewLine(); writer.outdent().append("}").ws().append("catch").ws().append("($e)").ws() .append("{").indent().softNewLine(); - writer.append("return ").append(getReturnVariable()).append("($rt_asyncError($e));").softNewLine(); + writer.append("return ").append(getReturnVariable()).append("(").appendFunction("$rt_asyncError") + .append("($e));").softNewLine(); writer.outdent().append("}"); - writer.append(getReturnVariable()).append("($rt_asyncResult($x));").softNewLine(); + writer.append(getReturnVariable()).append("(").appendFunction("$rt_asyncResult").append("($x));") + .softNewLine(); writer.outdent().append("}"); if (inner) { writer.append(';'); @@ -744,7 +768,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext } for (int i = 0; i < methodNode.getBody().size(); ++i) { writer.append("var ").append(getPartVariable(i)).ws().append("=").ws() - .append("$rt_guardAsync(function("); + .appendFunction("$rt_guardAsync").append("(function("); if (i > 0) { writer.append("$restore"); } @@ -1074,7 +1098,8 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext } writer.append("return"); if (async) { - writer.append(' ').append(getReturnVariable()).append("($rt_asyncResult("); + writer.append(' ').append(getReturnVariable()).append("(").appendFunction("$rt_asyncResult") + .append("("); } if (statement.getResult() != null) { if (!async) { @@ -1105,7 +1130,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext if (statement.getLocation() != null) { pushLocation(statement.getLocation()); } - writer.append("$rt_throw("); + writer.appendFunction("$rt_throw").append("("); prevCallSite = debugEmitter.emitCallSite(); priority = Priority.COMMA; associativity = Associativity.NONE; @@ -1282,7 +1307,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext visitBinary(expr, "!==", Priority.COMPARISON, Associativity.LEFT); break; case COMPARE: - visitBinaryFunction(expr, "$rt_compare"); + visitBinaryFunction(expr, naming.getNameForFunction("$rt_compare")); break; case COMPARE_LONG: visitBinaryFunction(expr, "Long_compare"); @@ -1420,7 +1445,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext break; case NULL_CHECK: enterPriority(Priority.COMMA, Associativity.NONE, false); - writer.append("$rt_nullCheck("); + writer.appendFunction("$rt_nullCheck").append("("); expr.getOperand().acceptVisitor(this); writer.append(')'); exitPriority(); @@ -1483,7 +1508,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext } if (cst instanceof ValueType) { ValueType type = (ValueType)cst; - return "$rt_cls(" + typeToClsString(naming, type) + ")"; + return naming.getNameForFunction("$rt_cls") + "(" + typeToClsString(naming, type) + ")"; } else if (cst instanceof String) { String string = (String)cst; Integer index = stringPoolMap.get(string); @@ -1738,7 +1763,8 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext if (hasParams) { writer.append(',').ws(); } - writer.append("$rt_continue(").append(getPartVariable(expr.getAsyncTarget())).append(')'); + writer.appendFunction("$rt_continue").append("(").append(getPartVariable(expr.getAsyncTarget())) + .append(')'); } writer.append(')'); exitPriority(); @@ -1849,7 +1875,8 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext break; } } else { - writer.append("$rt_createArray(").append(typeToClsString(naming, expr.getType())).append(",").ws(); + writer.appendFunction("$rt_createArray").append("(").append(typeToClsString(naming, expr.getType())) + .append(",").ws(); expr.getLength().acceptVisitor(this); writer.append(")"); } @@ -1946,7 +1973,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext } } enterPriority(Priority.COMMA, Associativity.NONE, false); - writer.append("$rt_isInstance("); + writer.appendFunction("$rt_isInstance").append("("); expr.getExpr().acceptVisitor(this); writer.append(",").ws().append(typeToClsString(naming, expr.getType())).append(")"); exitPriority(); @@ -2037,7 +2064,8 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext writer.append("return ").append(naming.getFullNameForAsync(monitorEnterRef)).append("("); statement.getObjectRef().acceptVisitor(this); writer.append(",").ws(); - writer.append("$rt_continue(").append(getPartVariable(statement.getAsyncTarget())).append(')'); + writer.appendFunction("$rt_continue").append("(").append(getPartVariable(statement.getAsyncTarget())) + .append(')'); writer.append(");").softNewLine(); } else { MethodReference monitorEnterRef = new MethodReference( diff --git a/teavm-core/src/main/java/org/teavm/vm/TeaVM.java b/teavm-core/src/main/java/org/teavm/vm/TeaVM.java index 6d6912b45..f459e4a46 100644 --- a/teavm-core/src/main/java/org/teavm/vm/TeaVM.java +++ b/teavm-core/src/main/java/org/teavm/vm/TeaVM.java @@ -549,11 +549,12 @@ public class TeaVM implements TeaVMHost, ServiceRepository { for (MethodReference injectedMethod : methodInjectors.keySet()) { decompiler.addMethodToPass(injectedMethod); } + List classOrder = decompiler.getClassOrdering(classes.getClassNames()); List classNodes = new ArrayList<>(); int index = 0; try (PrintWriter bytecodeLogger = bytecodeLogging ? new PrintWriter(new OutputStreamWriter(logStream, "UTF-8")) : null) { - for (String className : classes.getClassNames()) { + for (String className : classOrder) { ClassHolder cls = classes.get(className); for (MethodHolder method : cls.getMethods()) { processMethod(method); From fe2adc4675ba86491aa79c0ddca53813515fd50d Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Mon, 9 Mar 2015 16:22:19 +0300 Subject: [PATCH 31/69] Speed-up TeaVM compiler on large applications --- .../classlib/impl/ServiceLoaderSupport.java | 2 +- .../lang/reflect/ArrayNativeGenerator.java | 4 +- .../java/org/teavm/cache/FileNameEncoder.java | 10 +- .../org/teavm/dependency/DependencyAgent.java | 97 +++++++++++++++++-- .../teavm/dependency/DependencyAgentType.java | 26 ----- .../teavm/dependency/DependencyChecker.java | 28 +++--- .../teavm/dependency/DependencyConsumer.java | 2 +- .../dependency/DependencyGraphBuilder.java | 8 +- .../org/teavm/dependency/DependencyNode.java | 24 ++--- .../DependencyNodeToNodeTransition.java | 2 +- .../org/teavm/dependency/DependencyType.java | 8 +- .../dependency/DependencyTypeFilter.java | 2 +- .../teavm/dependency/MethodDependency.java | 2 +- .../java/org/teavm/tooling/TeaVMTool.java | 3 +- .../html4j/JavaScriptBodyDependency.java | 22 +---- .../teavm/jso/plugin/JSNativeGenerator.java | 2 +- .../plugin/ClassLookupDependencySupport.java | 2 +- .../plugin/EnumDependencySupport.java | 2 +- .../plugin/NewInstanceDependencySupport.java | 2 +- 19 files changed, 140 insertions(+), 108 deletions(-) delete mode 100644 teavm-core/src/main/java/org/teavm/dependency/DependencyAgentType.java diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/ServiceLoaderSupport.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/ServiceLoaderSupport.java index cb5c71f86..c35a347ca 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/ServiceLoaderSupport.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/ServiceLoaderSupport.java @@ -129,7 +129,7 @@ public class ServiceLoaderSupport implements Generator, DependencyListener { method.getResult().propagate(agent.getType("[java.lang.Object")); allClassesNode.connect(method.getResult().getArrayItem()); method.getResult().getArrayItem().addConsumer(new DependencyConsumer() { - @Override public void consume(DependencyAgentType type) { + @Override public void consume(DependencyType type) { initConstructor(agent, type.getName(), location); } }); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/reflect/ArrayNativeGenerator.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/reflect/ArrayNativeGenerator.java index ed9a46d5c..54b646443 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/reflect/ArrayNativeGenerator.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/reflect/ArrayNativeGenerator.java @@ -81,7 +81,7 @@ public class ArrayNativeGenerator implements Generator, DependencyPlugin { private void achieveGetLength(final DependencyAgent agent, final MethodDependency method) { method.getVariable(1).addConsumer(new DependencyConsumer() { - @Override public void consume(DependencyAgentType type) { + @Override public void consume(DependencyType type) { if (!type.getName().startsWith("[")) { MethodReference cons = new MethodReference(IllegalArgumentException.class, "", void.class); agent.linkMethod(cons, null).use(); @@ -128,7 +128,7 @@ public class ArrayNativeGenerator implements Generator, DependencyPlugin { private void achieveGet(final DependencyAgent agent, final MethodDependency method) { method.getVariable(1).getArrayItem().connect(method.getResult()); method.getVariable(1).addConsumer(new DependencyConsumer() { - @Override public void consume(DependencyAgentType type) { + @Override public void consume(DependencyType type) { if (type.getName().startsWith("[")) { String typeName = type.getName().substring(1); for (int i = 0; i < primitiveTypes.length; ++i) { diff --git a/teavm-core/src/main/java/org/teavm/cache/FileNameEncoder.java b/teavm-core/src/main/java/org/teavm/cache/FileNameEncoder.java index 684af4435..f811297c0 100644 --- a/teavm-core/src/main/java/org/teavm/cache/FileNameEncoder.java +++ b/teavm-core/src/main/java/org/teavm/cache/FileNameEncoder.java @@ -71,7 +71,15 @@ public final class FileNameEncoder { sb.append(c); break; } - + } + String str = sb.toString(); + sb.setLength(0); + for (int i = 0; i < str.length(); i += 100) { + if (i > 0) { + sb.append('/'); + } + int j = Math.min(i + 100, str.length()); + sb.append(str.substring(i, j)); } return sb.toString(); } diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyAgent.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyAgent.java index 439c6697f..28658cf74 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyAgent.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyAgent.java @@ -15,6 +15,8 @@ */ package org.teavm.dependency; +import java.util.Collection; +import org.teavm.callgraph.CallGraph; import org.teavm.common.ServiceRepository; import org.teavm.diagnostics.Diagnostics; import org.teavm.model.*; @@ -23,20 +25,97 @@ import org.teavm.model.*; * * @author Alexey Andreev */ -public interface DependencyAgent extends DependencyInfo, ServiceRepository { - DependencyNode createNode(); +public class DependencyAgent implements DependencyInfo, ServiceRepository { + private DependencyChecker checker; - DependencyAgentType getType(String name); + DependencyAgent(DependencyChecker checker) { + this.checker = checker; + } - String generateClassName(); + public DependencyNode createNode() { + return checker.createNode(); + } - void submitClass(ClassHolder cls); + public DependencyType getType(String name) { + return checker.getType(name); + } - MethodDependency linkMethod(MethodReference methodRef, CallLocation callLocation); + public String generateClassName() { + return checker.generateClassName(); + } - ClassDependency linkClass(String className, CallLocation callLocation); + public void submitClass(ClassHolder cls) { + checker.submitClass(cls); + } - FieldDependency linkField(FieldReference fieldRef, CallLocation callLocation); + public MethodDependency linkMethod(MethodReference methodRef, CallLocation callLocation) { + return checker.linkMethod(methodRef, callLocation); + } - Diagnostics getDiagnostics(); + public ClassDependency linkClass(String className, CallLocation callLocation) { + return checker.linkClass(className, callLocation); + } + + public FieldDependency linkField(FieldReference fieldRef, CallLocation callLocation) { + return checker.linkField(fieldRef, callLocation); + } + + public Diagnostics getDiagnostics() { + return checker.getDiagnostics(); + } + + @Override + public T getService(Class type) { + return checker.getService(type); + } + + @Override + public ClassReaderSource getClassSource() { + return checker.getClassSource(); + } + + @Override + public ClassLoader getClassLoader() { + return checker.getClassLoader(); + } + + @Override + public Collection getAchievableMethods() { + return checker.getAchievableMethods(); + } + + @Override + public Collection getAchievableFields() { + return checker.getAchievableFields(); + } + + @Override + public Collection getAchievableClasses() { + return checker.getAchievableClasses(); + } + + @Override + public FieldDependencyInfo getField(FieldReference fieldRef) { + return checker.getField(fieldRef); + } + + @Override + public MethodDependencyInfo getMethod(MethodReference methodRef) { + return checker.getMethod(methodRef); + } + + @Override + public MethodDependencyInfo getMethodImplementation(MethodReference methodRef) { + return checker.getMethodImplementation(methodRef); + } + + @Override + public ClassDependencyInfo getClass(String className) { + return checker.getClass(className); + } + + @Override + public CallGraph getCallGraph() { + return checker.getCallGraph(); + } } diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyAgentType.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyAgentType.java deleted file mode 100644 index 464725936..000000000 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyAgentType.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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.dependency; - -/** - * - * @author Alexey Andreev - */ -public interface DependencyAgentType { - String getName(); - - DependencyAgent getDependencyAgent(); -} diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java index dbaf4aa14..96018d66e 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java @@ -48,7 +48,7 @@ import org.teavm.model.util.ModelUtils; * * @author Alexey Andreev */ -public class DependencyChecker implements DependencyInfo, DependencyAgent { +public class DependencyChecker implements DependencyInfo { static final boolean shouldLog = System.getProperty("org.teavm.logDependencies", "false").equals("true"); private int classNameSuffix; private DependencyClassSource classSource; @@ -67,6 +67,7 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent { private boolean interrupted; private Diagnostics diagnostics; DefaultCallGraph callGraph = new DefaultCallGraph(); + private DependencyAgent agent; public DependencyChecker(ClassReaderSource classSource, ClassLoader classLoader, ServiceRepository services, Diagnostics diagnostics) { @@ -108,6 +109,12 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent { return createClassDependency(preimage); } }); + + agent = new DependencyAgent(this); + } + + public DependencyAgent getAgent() { + return agent; } public DependencyCheckerInterruptor getInterruptor() { @@ -122,7 +129,6 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent { return interrupted; } - @Override public DependencyType getType(String name) { DependencyType type = typeMap.get(name); if (type == null) { @@ -133,7 +139,6 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent { return type; } - @Override public DependencyNode createNode() { return new DependencyNode(this); } @@ -148,19 +153,17 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent { return classLoader; } - @Override public String generateClassName() { return "$$teavm_generated_class$$" + classNameSuffix++; } - @Override public void submitClass(ClassHolder cls) { classSource.submit(ModelUtils.copyClass(cls)); } public void addDependencyListener(DependencyListener listener) { listeners.add(listener); - listener.started(this); + listener.started(agent); } public void addClassTransformer(ClassHolderTransformer transformer) { @@ -199,7 +202,6 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent { }); } - @Override public ClassDependency linkClass(String className, CallLocation callLocation) { ClassDependency dep = classCache.map(className); boolean added = true; @@ -211,7 +213,7 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent { } if (!dep.isMissing() && added) { for (DependencyListener listener : listeners) { - listener.classAchieved(DependencyChecker.this, className, callLocation); + listener.classAchieved(agent, className, callLocation); } } return dep; @@ -247,7 +249,6 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent { return dependency; } - @Override public MethodDependency linkMethod(MethodReference methodRef, CallLocation callLocation) { if (methodRef == null) { throw new IllegalArgumentException(); @@ -265,7 +266,7 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent { MethodDependency graph = methodCache.map(methodRef); if (!graph.isMissing() && added) { for (DependencyListener listener : listeners) { - listener.methodAchieved(this, graph, callLocation); + listener.methodAchieved(agent, graph, callLocation); } activateDependencyPlugin(graph, callLocation); } @@ -392,7 +393,6 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent { return classCache.getCachedPreimages(); } - @Override public FieldDependency linkField(final FieldReference fieldRef, final CallLocation location) { boolean added = true; if (location != null) { @@ -408,7 +408,7 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent { } if (!dep.isMissing() && added) { for (DependencyListener listener : listeners) { - listener.fieldAchieved(DependencyChecker.this, dep, location); + listener.fieldAchieved(agent, dep, location); } } return dep; @@ -443,7 +443,7 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent { private void activateDependencyPlugin(MethodDependency methodDep, CallLocation location) { attachDependencyPlugin(methodDep); if (methodDep.dependencyPlugin != null) { - methodDep.dependencyPlugin.methodAchieved(this, methodDep, location); + methodDep.dependencyPlugin.methodAchieved(agent, methodDep, location); } } @@ -497,12 +497,10 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent { } } - @Override public T getService(Class type) { return services.getService(type); } - @Override public Diagnostics getDiagnostics() { return diagnostics; } diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyConsumer.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyConsumer.java index 0526423e4..e19046179 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyConsumer.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyConsumer.java @@ -20,5 +20,5 @@ package org.teavm.dependency; * @author Alexey Andreev */ public interface DependencyConsumer { - void consume(DependencyAgentType type); + void consume(DependencyType type); } 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 699350acb..afb0b066c 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java @@ -99,7 +99,7 @@ class DependencyGraphBuilder { } @Override - public void consume(DependencyAgentType type) { + public void consume(DependencyType type) { for (int i = 0; i < exceptions.length; ++i) { if (exceptions[i] == null || isAssignableFrom(checker.getClassSource(), exceptions[i], type.getName())) { @@ -139,7 +139,7 @@ class DependencyGraphBuilder { } @Override - public void consume(DependencyAgentType type) { + public void consume(DependencyType type) { String className = type.getName(); if (DependencyChecker.shouldLog) { System.out.println("Virtual call of " + methodDesc + " detected on " + node.getTag() + ". " + @@ -262,7 +262,7 @@ class DependencyGraphBuilder { final ClassReader targetClass = dependencyChecker.getClassSource().get(targetClsName); if (targetClass != null) { valueNode.connect(receiverNode, new DependencyTypeFilter() { - @Override public boolean match(DependencyAgentType type) { + @Override public boolean match(DependencyType type) { if (targetClass.getName().equals("java.lang.Object")) { return true; } @@ -392,7 +392,7 @@ class DependencyGraphBuilder { DependencyNode arrayNode = nodes[array.getIndex()]; final DependencyNode receiverNode = nodes[receiver.getIndex()]; arrayNode.addConsumer(new DependencyConsumer() { - @Override public void consume(DependencyAgentType type) { + @Override public void consume(DependencyType type) { receiverNode.propagate(type); } }); diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyNode.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyNode.java index 12686b2d4..4daaaf5b7 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyNode.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyNode.java @@ -39,11 +39,7 @@ public class DependencyNode implements ValueDependencyInfo { this.degree = degree; } - public void propagate(DependencyAgentType agentType) { - if (!(agentType instanceof DependencyType)) { - throw new IllegalArgumentException("The given type does not belong to the same dependency checker"); - } - DependencyType type = (DependencyType)agentType; + public void propagate(DependencyType type) { if (type.getDependencyChecker() != dependencyChecker) { throw new IllegalArgumentException("The given type does not belong to the same dependency checker"); } @@ -61,15 +57,11 @@ public class DependencyNode implements ValueDependencyInfo { } } - public void propagate(DependencyAgentType[] agentTypes) { + public void propagate(DependencyType[] agentTypes) { DependencyType[] types = new DependencyType[agentTypes.length]; int j = 0; for (int i = 0; i < agentTypes.length; ++i) { - DependencyAgentType agentType = agentTypes[i]; - if (!(agentType instanceof DependencyType)) { - throw new IllegalArgumentException("The given type does not belong to the same dependency checker"); - } - DependencyType type = (DependencyType)agentType; + DependencyType type = agentTypes[i]; if (type.getDependencyChecker() != dependencyChecker) { throw new IllegalArgumentException("The given type does not belong to the same dependency checker"); } @@ -121,7 +113,7 @@ public class DependencyNode implements ValueDependencyInfo { arrayItemNode.tag = tag + "["; } arrayItemNode.addConsumer(new DependencyConsumer() { - @Override public void consume(DependencyAgentType type) { + @Override public void consume(DependencyType type) { DependencyNode.this.propagate(type); } }); @@ -134,12 +126,8 @@ public class DependencyNode implements ValueDependencyInfo { return arrayItemNode != null && arrayItemNode.types.isEmpty(); } - public boolean hasType(DependencyAgentType type) { - if (!(type instanceof DependencyType)) { - return false; - } - DependencyType typeImpl = (DependencyType)type; - return typeImpl.getDependencyChecker() == dependencyChecker && types.get(typeImpl.index); + public boolean hasType(DependencyType type) { + return type.getDependencyChecker() == dependencyChecker && types.get(type.index); } @Override diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyNodeToNodeTransition.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyNodeToNodeTransition.java index 4eab6eb1e..98543636e 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyNodeToNodeTransition.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyNodeToNodeTransition.java @@ -32,7 +32,7 @@ class DependencyNodeToNodeTransition implements DependencyConsumer { } @Override - public void consume(DependencyAgentType type) { + public void consume(DependencyType type) { if (filter != null && !filter.match(type)) { return; } diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyType.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyType.java index b815a69b7..51395c7c5 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyType.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyType.java @@ -19,7 +19,7 @@ package org.teavm.dependency; * * @author Alexey Andreev */ -public class DependencyType implements DependencyAgentType { +public class DependencyType { private DependencyChecker dependencyChecker; private String name; int index; @@ -30,17 +30,15 @@ public class DependencyType implements DependencyAgentType { this.index = index; } - public DependencyChecker getDependencyChecker() { + DependencyChecker getDependencyChecker() { return dependencyChecker; } - @Override public String getName() { return name; } - @Override public DependencyAgent getDependencyAgent() { - return dependencyChecker; + return dependencyChecker.getAgent(); } } diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyTypeFilter.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyTypeFilter.java index dc1d01049..893299073 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyTypeFilter.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyTypeFilter.java @@ -20,5 +20,5 @@ package org.teavm.dependency; * @author Alexey Andreev */ public interface DependencyTypeFilter { - boolean match(DependencyAgentType type); + boolean match(DependencyType type); } diff --git a/teavm-core/src/main/java/org/teavm/dependency/MethodDependency.java b/teavm-core/src/main/java/org/teavm/dependency/MethodDependency.java index 5b160c2a2..778338210 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/MethodDependency.java +++ b/teavm-core/src/main/java/org/teavm/dependency/MethodDependency.java @@ -47,7 +47,7 @@ public class MethodDependency implements MethodDependencyInfo { } public DependencyAgent getDependencyAgent() { - return dependencyChecker; + return dependencyChecker.getAgent(); } @Override diff --git a/teavm-core/src/main/java/org/teavm/tooling/TeaVMTool.java b/teavm-core/src/main/java/org/teavm/tooling/TeaVMTool.java index e5d0b1853..e3107f9c4 100644 --- a/teavm-core/src/main/java/org/teavm/tooling/TeaVMTool.java +++ b/teavm-core/src/main/java/org/teavm/tooling/TeaVMTool.java @@ -240,7 +240,8 @@ public class TeaVMTool { } vmBuilder.setClassLoader(classLoader).setClassSource(cachedClassSource); } else { - vmBuilder.setClassLoader(classLoader).setClassSource(new ClasspathClassHolderSource(classLoader)); + vmBuilder.setClassLoader(classLoader).setClassSource(new PreOptimizingClassHolderSource( + new ClasspathClassHolderSource(classLoader))); } vm = vmBuilder.build(); if (progressListener != null) { diff --git a/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptBodyDependency.java b/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptBodyDependency.java index 944f5fab8..99b9947e0 100644 --- a/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptBodyDependency.java +++ b/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptBodyDependency.java @@ -20,22 +20,8 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; import net.java.html.js.JavaScriptBody; -import org.teavm.dependency.DependencyAgent; -import org.teavm.dependency.DependencyAgentType; -import org.teavm.dependency.DependencyConsumer; -import org.teavm.dependency.DependencyListener; -import org.teavm.dependency.DependencyNode; -import org.teavm.dependency.FieldDependency; -import org.teavm.dependency.MethodDependency; -import org.teavm.model.AnnotationReader; -import org.teavm.model.AnnotationValue; -import org.teavm.model.CallLocation; -import org.teavm.model.ClassReader; -import org.teavm.model.ClassReaderSource; -import org.teavm.model.ElementModifier; -import org.teavm.model.MethodDescriptor; -import org.teavm.model.MethodReader; -import org.teavm.model.MethodReference; +import org.teavm.dependency.*; +import org.teavm.model.*; /** * @@ -56,7 +42,7 @@ public class JavaScriptBodyDependency implements DependencyListener { public OneDirectionalConnection(DependencyNode target) { this.target = target; } - @Override public void consume(DependencyAgentType type) { + @Override public void consume(DependencyType type) { target.propagate(type); } } @@ -190,7 +176,7 @@ public class JavaScriptBodyDependency implements DependencyListener { this.caller = caller; this.superClass = agent.getClassSource().get(superMethod.getOwnerName()); } - @Override public void consume(DependencyAgentType type) { + @Override public void consume(DependencyType type) { if (!isAssignableFrom(superClass, type.getName())) { return; } diff --git a/teavm-jso/src/main/java/org/teavm/jso/plugin/JSNativeGenerator.java b/teavm-jso/src/main/java/org/teavm/jso/plugin/JSNativeGenerator.java index 3f27a15d8..b92f19187 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/plugin/JSNativeGenerator.java +++ b/teavm-jso/src/main/java/org/teavm/jso/plugin/JSNativeGenerator.java @@ -125,7 +125,7 @@ public class JSNativeGenerator implements Injector, DependencyPlugin { case "function": for (int i = 0; i < method.getReference().parameterCount(); ++i) { method.getVariable(i).addConsumer(new DependencyConsumer() { - @Override public void consume(DependencyAgentType type) { + @Override public void consume(DependencyType type) { achieveFunctorMethods(agent, type.getName(), method); } }); diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/ClassLookupDependencySupport.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/ClassLookupDependencySupport.java index a57d59b02..dead0e8d9 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/plugin/ClassLookupDependencySupport.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/ClassLookupDependencySupport.java @@ -41,7 +41,7 @@ public class ClassLookupDependencySupport implements DependencyListener { MethodReference ref = method.getReference(); if (ref.getClassName().equals(Platform.class.getName()) && ref.getName().equals("lookupClass")) { allClasses.addConsumer(new DependencyConsumer() { - @Override public void consume(DependencyAgentType type) { + @Override public void consume(DependencyType type) { ClassReader cls = agent.getClassSource().get(type.getName()); if (cls == null) { return; diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/EnumDependencySupport.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/EnumDependencySupport.java index 96620653b..d194142ad 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/plugin/EnumDependencySupport.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/EnumDependencySupport.java @@ -48,7 +48,7 @@ public class EnumDependencySupport implements DependencyListener { allEnums.connect(method.getResult().getArrayItem()); final MethodReference ref = method.getReference(); allEnums.addConsumer(new DependencyConsumer() { - @Override public void consume(DependencyAgentType type) { + @Override public void consume(DependencyType type) { ClassReader cls = agent.getClassSource().get(type.getName()); MethodReader method = cls.getMethod(new MethodDescriptor("values", ValueType.arrayOf(ValueType.object(cls.getName())))); diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/NewInstanceDependencySupport.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/NewInstanceDependencySupport.java index 0f6c8f100..cdb10e6e9 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/plugin/NewInstanceDependencySupport.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/NewInstanceDependencySupport.java @@ -53,7 +53,7 @@ public class NewInstanceDependencySupport implements DependencyListener { allClassesNode.connect(method.getResult()); final MethodReference methodRef = reader.getReference(); method.getResult().addConsumer(new DependencyConsumer() { - @Override public void consume(DependencyAgentType type) { + @Override public void consume(DependencyType type) { attachConstructor(agent, type.getName(), new CallLocation(methodRef)); } }); From 824cc799017a825e5b6c32793075f38b6cb5782e Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Mon, 9 Mar 2015 18:37:04 +0300 Subject: [PATCH 32/69] Speed up TeaVM compiler --- .../main/java/org/teavm/cache/ProgramIO.java | 2 - .../java/org/teavm/common/GraphUtils.java | 8 + .../dependency/DataFlowGraphBuilder.java | 290 ++++++++++++++++++ .../teavm/dependency/DependencyChecker.java | 20 +- .../dependency/DependencyGraphBuilder.java | 10 +- .../org/teavm/dependency/DependencyNode.java | 22 +- .../teavm/dependency/MethodDependency.java | 4 + .../java/org/teavm/model/MethodReference.java | 56 +++- 8 files changed, 386 insertions(+), 26 deletions(-) create mode 100644 teavm-core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java diff --git a/teavm-core/src/main/java/org/teavm/cache/ProgramIO.java b/teavm-core/src/main/java/org/teavm/cache/ProgramIO.java index b4689db64..7321f496b 100644 --- a/teavm-core/src/main/java/org/teavm/cache/ProgramIO.java +++ b/teavm-core/src/main/java/org/teavm/cache/ProgramIO.java @@ -600,7 +600,6 @@ public class ProgramIO { try { output.writeByte(39); output.writeShort(insn.getObjectRef().getIndex()); - } catch (IOException e) { throw new IOExceptionWrapper(e); } @@ -611,7 +610,6 @@ public class ProgramIO { try { output.writeByte(40); output.writeShort(insn.getObjectRef().getIndex()); - } catch (IOException e) { throw new IOExceptionWrapper(e); } diff --git a/teavm-core/src/main/java/org/teavm/common/GraphUtils.java b/teavm-core/src/main/java/org/teavm/common/GraphUtils.java index 692f4190d..4d30f6d25 100644 --- a/teavm-core/src/main/java/org/teavm/common/GraphUtils.java +++ b/teavm-core/src/main/java/org/teavm/common/GraphUtils.java @@ -79,6 +79,14 @@ public final class GraphUtils { return false; } + public static int[][] findStronglyConnectedComponents(Graph graph, int[] start) { + return findStronglyConnectedComponents(graph, start, new GraphNodeFilter() { + @Override public boolean match(int node) { + return true; + } + }); + } + /* * Tarjan's algorithm */ diff --git a/teavm-core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java b/teavm-core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java new file mode 100644 index 000000000..064b300c5 --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java @@ -0,0 +1,290 @@ +/* + * Copyright 2015 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.dependency; + +import com.carrotsearch.hppc.IntOpenHashSet; +import com.carrotsearch.hppc.IntSet; +import com.carrotsearch.hppc.ObjectIntMap; +import com.carrotsearch.hppc.ObjectIntOpenHashMap; +import java.util.Arrays; +import java.util.List; +import org.teavm.common.*; +import org.teavm.model.*; +import org.teavm.model.instructions.*; + +/** + * + * @author Alexey Andreev + */ +public class DataFlowGraphBuilder implements InstructionReader { + private int lastIndex; + private GraphBuilder builder = new GraphBuilder(); + private IntSet importantNodes = new IntOpenHashSet(); + private ObjectIntMap methodNodes = new ObjectIntOpenHashMap<>(); + private ObjectIntMap fieldNodes = new ObjectIntOpenHashMap<>(); + private int[] arrayNodes; + + public void important(int node) { + importantNodes.add(node); + } + + public int[] buildMapping(ProgramReader program, int paramCount) { + lastIndex = program.variableCount(); + arrayNodes = new int[lastIndex]; + Arrays.fill(arrayNodes, -1); + for (int i = 0; i < program.basicBlockCount(); ++i) { + BasicBlockReader block = program.basicBlockAt(i); + for (PhiReader phi : block.readPhis()) { + for (IncomingReader incoming : phi.readIncomings()) { + builder.addEdge(incoming.getValue().getIndex(), phi.getReceiver().getIndex()); + } + } + block.readAllInstructions(this); + } + Graph graph = builder.build(); + + DisjointSet classes = new DisjointSet(); + for (int i = 0; i < lastIndex; ++i) { + classes.create(); + } + IntegerArray startNodes = new IntegerArray(graph.size()); + for (int i = paramCount; i < graph.size(); ++i) { + if (!importantNodes.contains(i) && graph.incomingEdgesCount(i) == 1) { + classes.union(graph.incomingEdges(i)[0], i); + } + if (graph.incomingEdgesCount(i) == 0) { + startNodes.add(i); + } + } + + int[][] sccs = GraphUtils.findStronglyConnectedComponents(graph, startNodes.getAll()); + for (int[] scc : sccs) { + int first = scc[0]; + for (int i = 1; i < scc.length; ++i) { + classes.union(first, scc[i]); + } + } + return classes.pack(program.variableCount()); + } + + @Override + public void location(InstructionLocation location) { + } + + @Override + public void nop() { + } + + @Override + public void classConstant(VariableReader receiver, ValueType cst) { + } + + @Override + public void nullConstant(VariableReader receiver) { + } + + @Override + public void integerConstant(VariableReader receiver, int cst) { + } + + @Override + public void longConstant(VariableReader receiver, long cst) { + } + + @Override + public void floatConstant(VariableReader receiver, float cst) { + } + + @Override + public void doubleConstant(VariableReader receiver, double cst) { + } + + @Override + public void stringConstant(VariableReader receiver, String cst) { + } + + @Override + public void binary(BinaryOperation op, VariableReader receiver, VariableReader first, VariableReader second, + NumericOperandType type) { + } + + @Override + public void negate(VariableReader receiver, VariableReader operand, NumericOperandType type) { + } + + @Override + public void assign(VariableReader receiver, VariableReader assignee) { + builder.addEdge(assignee.getIndex(), receiver.getIndex()); + } + + @Override + public void cast(VariableReader receiver, VariableReader value, ValueType targetType) { + builder.addEdge(value.getIndex(), receiver.getIndex()); + important(receiver.getIndex()); + } + + @Override + public void cast(VariableReader receiver, VariableReader value, NumericOperandType sourceType, + NumericOperandType targetType) { + } + + @Override + public void cast(VariableReader receiver, VariableReader value, IntegerSubtype type, + CastIntegerDirection targetType) { + } + + @Override + public void jumpIf(BranchingCondition cond, VariableReader operand, BasicBlockReader consequent, + BasicBlockReader alternative) { + } + + @Override + public void jumpIf(BinaryBranchingCondition cond, VariableReader first, VariableReader second, + BasicBlockReader consequent, BasicBlockReader alternative) { + } + + @Override + public void jump(BasicBlockReader target) { + } + + @Override + public void choose(VariableReader condition, List table, + BasicBlockReader defaultTarget) { + } + + @Override + public void exit(VariableReader valueToReturn) { + if (valueToReturn != null) { + important(valueToReturn.getIndex()); + } + } + + @Override + public void raise(VariableReader exception) { + important(exception.getIndex()); + } + + @Override + public void createArray(VariableReader receiver, ValueType itemType, VariableReader size) { + } + + @Override + public void createArray(VariableReader receiver, ValueType itemType, List dimensions) { + } + + @Override + public void create(VariableReader receiver, String type) { + } + + private int getFieldNode(FieldReference field) { + int fieldNode = fieldNodes.getOrDefault(field, -1); + if (fieldNode < 0) { + fieldNode = lastIndex++; + fieldNodes.put(field, fieldNode); + } + important(fieldNode); + return fieldNode; + } + + @Override + public void getField(VariableReader receiver, VariableReader instance, FieldReference field, ValueType fieldType) { + int fieldNode = getFieldNode(field); + builder.addEdge(fieldNode, receiver.getIndex()); + } + + + @Override + public void putField(VariableReader instance, FieldReference field, VariableReader value) { + int fieldNode = getFieldNode(field); + builder.addEdge(value.getIndex(), fieldNode); + } + + @Override + public void arrayLength(VariableReader receiver, VariableReader array) { + } + + @Override + public void cloneArray(VariableReader receiver, VariableReader array) { + important(receiver.getIndex()); + builder.addEdge(array.getIndex(), receiver.getIndex()); + } + + @Override + public void unwrapArray(VariableReader receiver, VariableReader array, ArrayElementType elementType) { + if (elementType == ArrayElementType.OBJECT) { + builder.addEdge(array.getIndex(), receiver.getIndex()); + } + } + + private int getArrayElementNode(int array) { + int node = arrayNodes[array]; + if (node < 0) { + node = lastIndex++; + arrayNodes[array] = node; + } + important(node); + return node; + } + + @Override + public void getElement(VariableReader receiver, VariableReader array, VariableReader index) { + builder.addEdge(getArrayElementNode(array.getIndex()), receiver.getIndex()); + } + + @Override + public void putElement(VariableReader array, VariableReader index, VariableReader value) { + builder.addEdge(value.getIndex(), getArrayElementNode(array.getIndex())); + } + + private int getMethodNode(MethodReference method) { + int methodNode = methodNodes.getOrDefault(method, -1); + if (methodNode < 0) { + methodNode = lastIndex++; + methodNodes.put(method, methodNode); + } + important(methodNode); + return methodNode; + } + + @Override + public void invoke(VariableReader receiver, VariableReader instance, MethodReference method, + List arguments, InvocationType type) { + if (receiver != null) { + builder.addEdge(getMethodNode(method), receiver.getIndex()); + } + } + + @Override + public void isInstance(VariableReader receiver, VariableReader value, ValueType type) { + } + + @Override + public void initClass(String className) { + } + + @Override + public void nullCheck(VariableReader receiver, VariableReader value) { + builder.addEdge(value.getIndex(), receiver.getIndex()); + } + + @Override + public void monitorEnter(VariableReader objectRef) { + } + + @Override + public void monitorExit(VariableReader objectRef) { + } +} diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java index 96018d66e..3174539ca 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java @@ -15,13 +15,7 @@ */ package org.teavm.dependency; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Queue; +import java.util.*; import org.teavm.callgraph.CallGraph; import org.teavm.callgraph.DefaultCallGraph; import org.teavm.callgraph.DefaultCallGraphNode; @@ -202,6 +196,8 @@ public class DependencyChecker implements DependencyInfo { }); } + private Set classesAddedByRoot = new HashSet<>(); + public ClassDependency linkClass(String className, CallLocation callLocation) { ClassDependency dep = classCache.map(className); boolean added = true; @@ -210,6 +206,8 @@ public class DependencyChecker implements DependencyInfo { if (!addClassAccess(callGraphNode, className, callLocation.getSourceLocation())) { added = false; } + } else { + added = classesAddedByRoot.add(className); } if (!dep.isMissing() && added) { for (DependencyListener listener : listeners) { @@ -249,6 +247,8 @@ public class DependencyChecker implements DependencyInfo { return dependency; } + private Set methodsAddedByRoot = new HashSet<>(); + public MethodDependency linkMethod(MethodReference methodRef, CallLocation callLocation) { if (methodRef == null) { throw new IllegalArgumentException(); @@ -262,6 +262,8 @@ public class DependencyChecker implements DependencyInfo { if (callLocation != null && callLocation.getMethod() != null) { added = callGraph.getNode(callLocation.getMethod()).addCallSite(methodRef, callLocation.getSourceLocation()); + } else { + added = methodsAddedByRoot.add(methodRef); } MethodDependency graph = methodCache.map(methodRef); if (!graph.isMissing() && added) { @@ -393,10 +395,14 @@ public class DependencyChecker implements DependencyInfo { return classCache.getCachedPreimages(); } + private Set fieldsAddedByRoot = new HashSet<>(); + public FieldDependency linkField(final FieldReference fieldRef, final CallLocation location) { boolean added = true; if (location != null) { added = callGraph.getNode(location.getMethod()).addFieldAccess(fieldRef, location.getSourceLocation()); + } else { + added = fieldsAddedByRoot.add(fieldRef); } FieldDependency dep = fieldCache.map(fieldRef); if (!dep.isMissing()) { 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 afb0b066c..93820754c 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java @@ -52,7 +52,15 @@ class DependencyGraphBuilder { System.out.println(new ListingBuilder().buildListing(program, " ")); } resultNode = dep.getResult(); - nodes = dep.getVariables(); + + DependencyNode[] origNodes = dep.getVariables(); + int[] nodeMapping = new DataFlowGraphBuilder().buildMapping(program, dep.getParameterCount()); + nodes = new DependencyNode[origNodes.length]; + for (int i = 0; i < nodes.length; ++i) { + nodes[i] = origNodes[nodeMapping[i]]; + } + dep.setVariables(nodes); + for (int i = 0; i < program.basicBlockCount(); ++i) { BasicBlockReader block = program.basicBlockAt(i); currentExceptionConsumer = createExceptionConsumer(dep, block); diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyNode.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyNode.java index 4daaaf5b7..d5d4f8dbc 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyNode.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyNode.java @@ -24,7 +24,7 @@ import java.util.*; public class DependencyNode implements ValueDependencyInfo { private DependencyChecker dependencyChecker; private Set followers = new HashSet<>(); - private BitSet types = new BitSet(); + private BitSet types; private Map transitions = new HashMap<>(); private volatile String tag; private DependencyNode arrayItemNode; @@ -46,6 +46,9 @@ public class DependencyNode implements ValueDependencyInfo { if (degree > 2) { return; } + if (types == null) { + types = new BitSet(); + } if (!types.get(type.index)) { types.set(type.index); if (DependencyChecker.shouldLog) { @@ -65,10 +68,13 @@ public class DependencyNode implements ValueDependencyInfo { if (type.getDependencyChecker() != dependencyChecker) { throw new IllegalArgumentException("The given type does not belong to the same dependency checker"); } - if (!this.types.get(type.index)) { + if (this.types == null || !this.types.get(type.index)) { types[j++] = type; } } + if (this.types == null) { + this.types = new BitSet(); + } for (int i = 0; i < j; ++i) { this.types.set(types[i].index); if (DependencyChecker.shouldLog) { @@ -81,7 +87,7 @@ public class DependencyNode implements ValueDependencyInfo { } public void addConsumer(DependencyConsumer consumer) { - if (followers.add(consumer)) { + if (followers.add(consumer) && this.types != null) { List types = new ArrayList<>(); for (int index = this.types.nextSetBit(0); index >= 0; index = this.types.nextSetBit(index + 1)) { types.add(dependencyChecker.types.get(index)); @@ -91,6 +97,9 @@ public class DependencyNode implements ValueDependencyInfo { } public void connect(DependencyNode node, DependencyTypeFilter filter) { + if (this == node) { + return; + } DependencyNodeToNodeTransition transition = new DependencyNodeToNodeTransition(this, node, filter); if (!transitions.containsKey(node)) { transitions.put(node, transition); @@ -123,11 +132,11 @@ public class DependencyNode implements ValueDependencyInfo { @Override public boolean hasArrayType() { - return arrayItemNode != null && arrayItemNode.types.isEmpty(); + return arrayItemNode != null && arrayItemNode.types != null && !arrayItemNode.types.isEmpty(); } public boolean hasType(DependencyType type) { - return type.getDependencyChecker() == dependencyChecker && types.get(type.index); + return types != null && type.getDependencyChecker() == dependencyChecker && types.get(type.index); } @Override @@ -137,6 +146,9 @@ public class DependencyNode implements ValueDependencyInfo { @Override public String[] getTypes() { + if (types == null) { + return new String[0]; + } List result = new ArrayList<>(); for (int index = types.nextSetBit(0); index >= 0; index = types.nextSetBit(index + 1)) { result.add(dependencyChecker.types.get(index).getName()); diff --git a/teavm-core/src/main/java/org/teavm/dependency/MethodDependency.java b/teavm-core/src/main/java/org/teavm/dependency/MethodDependency.java index 778338210..cb1cce5b7 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/MethodDependency.java +++ b/teavm-core/src/main/java/org/teavm/dependency/MethodDependency.java @@ -55,6 +55,10 @@ public class MethodDependency implements MethodDependencyInfo { return Arrays.copyOf(variableNodes, variableNodes.length); } + void setVariables(DependencyNode[] variables) { + this.variableNodes = variables; + } + @Override public int getVariableCount() { return variableNodes.length; diff --git a/teavm-core/src/main/java/org/teavm/model/MethodReference.java b/teavm-core/src/main/java/org/teavm/model/MethodReference.java index 38979ac56..66ab8a600 100644 --- a/teavm-core/src/main/java/org/teavm/model/MethodReference.java +++ b/teavm-core/src/main/java/org/teavm/model/MethodReference.java @@ -15,6 +15,8 @@ */ package org.teavm.model; +import java.util.Arrays; + /** *

Specifies a fully qualified name of a method, including its name, class name, parameter types * and return value type. This class overloads equals and hashCode @@ -28,11 +30,16 @@ package org.teavm.model; */ public class MethodReference { private String className; - private MethodDescriptor descriptor; + private String name; + private ValueType[] signature; + private transient MethodDescriptor descriptor; + private transient String reprCache; public MethodReference(String className, MethodDescriptor descriptor) { this.className = className; this.descriptor = descriptor; + this.name = descriptor.getName(); + this.signature = descriptor.getSignature(); } /** @@ -52,11 +59,21 @@ public class MethodReference { * a type of a returning value, and all the remaining elements are types of arguments. */ public MethodReference(String className, String name, ValueType... signature) { - this(className, new MethodDescriptor(name, signature)); + this.className = className; + this.name = name; + this.signature = Arrays.copyOf(signature, signature.length); } public MethodReference(Class cls, String name, Class... signature) { - this(cls.getName(), new MethodDescriptor(name, signature)); + this(cls.getName(), name, convertSignature(signature)); + } + + private static ValueType[] convertSignature(Class... signature) { + ValueType[] types = new ValueType[signature.length]; + for (int i = 0; i < types.length; ++i) { + types[i] = ValueType.parse(signature[i]); + } + return types; } public String getClassName() { @@ -64,44 +81,61 @@ public class MethodReference { } public MethodDescriptor getDescriptor() { + if (descriptor == null) { + descriptor = new MethodDescriptor(name, signature); + } return descriptor; } public int parameterCount() { - return descriptor.parameterCount(); + return signature.length - 1; } public ValueType[] getParameterTypes() { - return descriptor.getParameterTypes(); + return Arrays.copyOf(signature, signature.length - 1); } public ValueType[] getSignature() { - return descriptor.getSignature(); + return Arrays.copyOf(signature, signature.length); } public String getName() { - return descriptor.getName(); + return name; } @Override public int hashCode() { - return className.hashCode() ^ descriptor.hashCode(); + return toString().hashCode(); } @Override public boolean equals(Object obj) { if (this == obj) { - return false; + return true; } if (!(obj instanceof MethodReference)) { return false; } MethodReference other = (MethodReference)obj; - return className.equals(other.className) && descriptor.equals(other.descriptor); + return toString().equals(other.toString()); } @Override public String toString() { - return className + "." + descriptor; + if (reprCache == null) { + reprCache = className + "." + name + signatureToString(); + } + return reprCache; + } + + public String signatureToString() { + StringBuilder sb = new StringBuilder(); + sb.append('('); + for (int i = 0; i < signature.length - 1; ++i) { + sb.append(signature[i].toString()); + } + sb.append(')'); + sb.append(signature[signature.length - 1]); + return sb.toString(); } } From 80814ef1670c074b87120c39943ed9e8c64ee36d Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Mon, 9 Mar 2015 22:10:26 +0300 Subject: [PATCH 33/69] Bugfixes --- .../src/main/java/org/teavm/cache/AstIO.java | 2 +- .../teavm/dependency/DataFlowGraphBuilder.java | 16 +++++++++++----- .../main/java/org/teavm/dependency/Linker.java | 2 +- .../resources/org/teavm/javascript/runtime.js | 2 +- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/teavm-core/src/main/java/org/teavm/cache/AstIO.java b/teavm-core/src/main/java/org/teavm/cache/AstIO.java index d9bac61e0..e519cc896 100644 --- a/teavm-core/src/main/java/org/teavm/cache/AstIO.java +++ b/teavm-core/src/main/java/org/teavm/cache/AstIO.java @@ -752,7 +752,7 @@ public class AstIO { } case 9: { ConstantExpr expr = new ConstantExpr(); - expr.setValue(symbolTable.at(input.readInt())); + expr.setValue(ValueType.parse(symbolTable.at(input.readInt()))); return expr; } case 10: { diff --git a/teavm-core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java b/teavm-core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java index 064b300c5..43d421e48 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java @@ -62,8 +62,11 @@ public class DataFlowGraphBuilder implements InstructionReader { } IntegerArray startNodes = new IntegerArray(graph.size()); for (int i = paramCount; i < graph.size(); ++i) { - if (!importantNodes.contains(i) && graph.incomingEdgesCount(i) == 1) { - classes.union(graph.incomingEdges(i)[0], i); + if (importantNodes.contains(i)) { + continue; + } + for (int pred : graph.incomingEdges(i)) { + classes.union(pred, i); } if (graph.incomingEdgesCount(i) == 0) { startNodes.add(i); @@ -72,9 +75,12 @@ public class DataFlowGraphBuilder implements InstructionReader { int[][] sccs = GraphUtils.findStronglyConnectedComponents(graph, startNodes.getAll()); for (int[] scc : sccs) { - int first = scc[0]; - for (int i = 1; i < scc.length; ++i) { - classes.union(first, scc[i]); + int last = -1; + for (int node : scc) { + if (!importantNodes.contains(node)) { + continue; + } + last = last < 0 ? node : classes.union(node, last); } } return classes.pack(program.variableCount()); diff --git a/teavm-core/src/main/java/org/teavm/dependency/Linker.java b/teavm-core/src/main/java/org/teavm/dependency/Linker.java index ed653610b..b844f956f 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/Linker.java +++ b/teavm-core/src/main/java/org/teavm/dependency/Linker.java @@ -53,7 +53,7 @@ public class Linker { for (Instruction insn : block.getInstructions()) { if (insn instanceof InvokeInstruction) { InvokeInstruction invoke = (InvokeInstruction)insn; - MethodDependencyInfo linkedMethod = dependency.getMethod(invoke.getMethod()); + MethodDependencyInfo linkedMethod = dependency.getMethodImplementation(invoke.getMethod()); if (linkedMethod != null) { invoke.setMethod(linkedMethod.getReference()); } diff --git a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js index c0d860e59..d13941d6d 100644 --- a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js +++ b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js @@ -491,7 +491,7 @@ function $rt_s(index) { } var $rt_continueCounter = 0; function $rt_continue(f) { - if ($rt_continueCounter++ == 40) { + if ($rt_continueCounter++ == 5) { $rt_continueCounter = 0; return function() { var self = this; From 7f33f64d25fd3b01301f5998118f5cdf63cbb7a2 Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Mon, 9 Mar 2015 22:20:59 +0300 Subject: [PATCH 34/69] Store postponed actions in a queue --- .../resources/org/teavm/javascript/runtime.js | 41 +++++++++---------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js index d13941d6d..88d9ddef4 100644 --- a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js +++ b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js @@ -460,10 +460,10 @@ function $rt_rootInvocationAdapter(f) { }); f.apply(this, args); var thread = $rt_getThread(); - while (thread.postponed) { - var postponed = thread.postponed; - thread.postponed = null; - postponed(); + if (thread.hasOwnProperty("postponed")) { + while (thread.postponed.length > 0) { + thread.postponed.shift()(); + } } } } @@ -491,23 +491,22 @@ function $rt_s(index) { } var $rt_continueCounter = 0; function $rt_continue(f) { - if ($rt_continueCounter++ == 5) { - $rt_continueCounter = 0; - return function() { - var self = this; - var args = arguments; - var thread = $rt_getThread(); - var oldPostponed = thread.postponed; - thread.postponed = function() { - if (oldPostponed) { - oldPostponed(); - } - f.apply(self, args); - }; - }; - } else { - return f; - } + if ($rt_continueCounter++ == 5) { + $rt_continueCounter = 0; + return function() { + var self = this; + var args = arguments; + var thread = $rt_getThread(); + if (!thread.hasOwnProperty("postponed")) { + thread.postponed = []; + } + thread.postponed.push(function() { + f.apply(self, args); + }); + }; + } else { + return f; + } } function $rt_guardAsync(f, continuation) { return function() { From 93e43456d1e48399b515d083cde40a7f3a49fb99 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Tue, 10 Mar 2015 12:49:00 +0400 Subject: [PATCH 35/69] Outline of upcoming improvements of continuations --- .../org/teavm/classlib/java/lang/TObject.java | 46 +++-- .../org/teavm/classlib/java/lang/TThread.java | 40 ++-- .../teavm/codegen/DefaultNamingStrategy.java | 14 +- .../teavm/codegen/NameFrequencyConsumer.java | 4 - .../java/org/teavm/codegen/NamingOrderer.java | 31 ---- .../org/teavm/codegen/NamingStrategy.java | 4 - .../javascript/NameFrequencyEstimator.java | 53 +----- .../java/org/teavm/javascript/Renderer.java | 171 +++++------------- .../javascript/spi/GeneratorContext.java | 2 - .../src/main/java/org/teavm/vm/TeaVM.java | 8 +- .../resources/org/teavm/javascript/runtime.js | 51 ++++++ 11 files changed, 164 insertions(+), 260 deletions(-) diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java index 65776b5b8..3fb6b2e9a 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java @@ -72,10 +72,7 @@ public class TObject { monitorEnter(o, 1); } - @Async - static native void monitorEnter(TObject o, int count); - - static void monitorEnter(final TObject o, final int count, final AsyncCallback callback) { + static void monitorEnter(TObject o, int count) { if (o.monitor == null) { o.monitor = new Monitor(); } @@ -83,21 +80,27 @@ public class TObject { o.monitor.owner = TThread.currentThread(); } if (o.monitor.owner != TThread.currentThread()) { - final TThread thread = TThread.currentThread(); - o.monitor.enteringThreads.add(new PlatformRunnable() { - @Override public void run() { - TThread.setCurrentThread(thread); - o.monitor.owner = thread; - o.monitor.count += count; - callback.complete(null); - } - }); + monitorEnterWait(o, count); } else { o.monitor.count += count; - callback.complete(null); } } + @Async + static native void monitorEnterWait(TObject o, int count); + + static void monitorEnterWait(final TObject o, final int count, final AsyncCallback callback) { + final TThread thread = TThread.currentThread(); + o.monitor.enteringThreads.add(new PlatformRunnable() { + @Override public void run() { + TThread.setCurrentThread(thread); + o.monitor.owner = thread; + o.monitor.count += count; + callback.complete(null); + } + }); + } + @Sync static void monitorExit(final TObject o) { monitorExit(o, 1); @@ -230,15 +233,18 @@ public class TObject { } } - @Async @Rename("wait") - private native final void wait0(long timeout, int nanos) throws TInterruptedException; - - @Rename("wait") - public final void wait0(long timeout, int nanos, final AsyncCallback callback) { + private final void wait0(long timeout, int nanos) throws TInterruptedException { if (!holdsLock(this)) { throw new TIllegalMonitorStateException(); } + waitImpl(timeout, nanos); + } + + @Async + private native final void waitImpl(long timeout, int nanos) throws TInterruptedException; + + public final void waitImpl(long timeout, int nanos, final AsyncCallback callback) { final NotifyListenerImpl listener = new NotifyListenerImpl(this, callback, monitor.count); monitor.notifyListeners.add(listener); if (timeout > 0 || nanos > 0) { @@ -288,7 +294,7 @@ public class TObject { timerId = -1; } TThread.setCurrentThread(currentThread); - monitorEnter(obj, lockCount, callback); + monitorEnterWait(obj, lockCount, callback); } } diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java index f50841b41..2576f0653 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java @@ -23,7 +23,6 @@ import org.teavm.platform.Platform; import org.teavm.platform.PlatformRunnable; import org.teavm.platform.async.AsyncCallback; - /** * * @author Alexey Andreev @@ -36,6 +35,7 @@ public class TThread extends TObject implements TRunnable { private static int activeCount = 1; private long id; private int priority = 0; + private long timeSliceStart; private TString name; TRunnable target; @@ -55,10 +55,10 @@ public class TThread extends TObject implements TRunnable { public TThread(TRunnable target, TString name ) { this.name = name; this.target = target; - id=nextId++; + id = nextId++; } - public void start(){ + public void start() { Platform.startThread(new PlatformRunnable() { @Override public void run() { @@ -74,8 +74,11 @@ public class TThread extends TObject implements TRunnable { }); } - static void setCurrentThread(TThread thread){ - currentThread = thread; + static void setCurrentThread(TThread thread) { + if (currentThread != thread) { + currentThread = thread; + currentThread.timeSliceStart = System.currentTimeMillis(); + } } static TThread getMainThread(){ return mainThread; @@ -96,11 +99,26 @@ public class TThread extends TObject implements TRunnable { return name; } - @Async - public static native void yield(); + public static void yield() { + if (currentThread.timeSliceStart + 100 < System.currentTimeMillis()) { + switchContext(); + } + } - private static void yield(final AsyncCallback callback) { - callback.complete(null); + @Async + static native void switchContext(); + + private static void switchContext(final AsyncCallback callback) { + final TThread thread = currentThread(); + Platform.startThread(new PlatformRunnable() { + @Override public void run() { + setCurrentThread(thread); + callback.complete(null); + } + }); + } + + private static void yieldImpl() { } public void interrupt() { @@ -138,11 +156,11 @@ public class TThread extends TObject implements TRunnable { } }, millis); } - + public final void setPriority(int newPriority){ this.priority = newPriority; } - + public final int getPriority(){ return this.priority; } diff --git a/teavm-core/src/main/java/org/teavm/codegen/DefaultNamingStrategy.java b/teavm-core/src/main/java/org/teavm/codegen/DefaultNamingStrategy.java index 0a28824b0..7fdd95a22 100644 --- a/teavm-core/src/main/java/org/teavm/codegen/DefaultNamingStrategy.java +++ b/teavm-core/src/main/java/org/teavm/codegen/DefaultNamingStrategy.java @@ -58,12 +58,7 @@ public class DefaultNamingStrategy implements NamingStrategy { @Override public String getNameFor(MethodDescriptor method) { - return getNameFor(method, 'S'); - } - - @Override - public String getNameForAsync(MethodDescriptor method) throws NamingException { - return getNameFor(method, 'A'); + return getNameFor(method, 'M'); } private String getNameFor(MethodDescriptor method, char classifier) { @@ -78,12 +73,7 @@ public class DefaultNamingStrategy implements NamingStrategy { @Override public String getFullNameFor(MethodReference method) throws NamingException { - return getFullNameFor(method, 'S'); - } - - @Override - public String getFullNameForAsync(MethodReference method) throws NamingException { - return getFullNameFor(method, 'A'); + return getFullNameFor(method, 'M'); } @Override diff --git a/teavm-core/src/main/java/org/teavm/codegen/NameFrequencyConsumer.java b/teavm-core/src/main/java/org/teavm/codegen/NameFrequencyConsumer.java index 20aec0331..558e2eab8 100644 --- a/teavm-core/src/main/java/org/teavm/codegen/NameFrequencyConsumer.java +++ b/teavm-core/src/main/java/org/teavm/codegen/NameFrequencyConsumer.java @@ -26,14 +26,10 @@ import org.teavm.model.MethodReference; public interface NameFrequencyConsumer { void consume(MethodReference method); - void consumeAsync(MethodReference method); - void consumeInit(MethodReference method); void consume(MethodDescriptor method); - void consumeAsync(MethodDescriptor method); - void consume(String className); void consume(FieldReference field); diff --git a/teavm-core/src/main/java/org/teavm/codegen/NamingOrderer.java b/teavm-core/src/main/java/org/teavm/codegen/NamingOrderer.java index 8cfc4399d..72cf2f652 100644 --- a/teavm-core/src/main/java/org/teavm/codegen/NamingOrderer.java +++ b/teavm-core/src/main/java/org/teavm/codegen/NamingOrderer.java @@ -43,21 +43,6 @@ public class NamingOrderer implements NameFrequencyConsumer { entry.frequency++; } - @Override - public void consumeAsync(final MethodReference method) { - String key = "A:" + method; - Entry entry = entries.get(key); - if (entry == null) { - entry = new Entry(); - entry.operation = new NamingOperation() { - @Override public void perform(NamingStrategy naming) { - naming.getFullNameForAsync(method); - } - }; - entries.put(key, entry); - } - entry.frequency++; - } @Override public void consumeInit(final MethodReference method) { @@ -91,22 +76,6 @@ public class NamingOrderer implements NameFrequencyConsumer { entry.frequency++; } - @Override - public void consumeAsync(final MethodDescriptor method) { - String key = "a:" + method; - Entry entry = entries.get(key); - if (entry == null) { - entry = new Entry(); - entry.operation = new NamingOperation() { - @Override public void perform(NamingStrategy naming) { - naming.getNameForAsync(method); - } - }; - entries.put(key, entry); - } - entry.frequency++; - } - @Override public void consume(final String className) { String key = "c:" + className; diff --git a/teavm-core/src/main/java/org/teavm/codegen/NamingStrategy.java b/teavm-core/src/main/java/org/teavm/codegen/NamingStrategy.java index 0902b5093..9873446af 100644 --- a/teavm-core/src/main/java/org/teavm/codegen/NamingStrategy.java +++ b/teavm-core/src/main/java/org/teavm/codegen/NamingStrategy.java @@ -28,14 +28,10 @@ public interface NamingStrategy { String getNameFor(MethodDescriptor method) throws NamingException; - String getNameForAsync(MethodDescriptor method) throws NamingException; - String getNameForInit(MethodReference method) throws NamingException; String getFullNameFor(MethodReference method) throws NamingException; - String getFullNameForAsync(MethodReference method) throws NamingException; - String getNameFor(FieldReference field) throws NamingException; String getNameForFunction(String name) throws NamingException; diff --git a/teavm-core/src/main/java/org/teavm/javascript/NameFrequencyEstimator.java b/teavm-core/src/main/java/org/teavm/javascript/NameFrequencyEstimator.java index 61d639cde..278e9e642 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/NameFrequencyEstimator.java +++ b/teavm-core/src/main/java/org/teavm/javascript/NameFrequencyEstimator.java @@ -63,38 +63,17 @@ public class NameFrequencyEstimator implements StatementVisitor, ExprVisitor, Me MethodReader clinit = classSource.get(cls.getName()).getMethod( new MethodDescriptor("", ValueType.VOID)); for (MethodNode method : cls.getMethods()) { - if (method.isAsync()) { - consumer.consumeAsync(method.getReference()); - } else { + consumer.consume(method.getReference()); + if (asyncFamilyMethods.contains(method.getReference())) { consumer.consume(method.getReference()); - if (asyncFamilyMethods.contains(method.getReference())) { - consumer.consume(method.getReference()); - consumer.consumeAsync(method.getReference()); - consumer.consumeFunction("$rt_asyncError"); - consumer.consumeFunction("$rt_asyncResult"); - } } if (clinit != null && (method.getModifiers().contains(NodeModifier.STATIC) || - method.getReference().getName().equals(""))) { - if (!method.isAsync()) { - consumer.consume(method.getReference()); - } - if (asyncFamilyMethods.contains(method.getReference())) { - consumer.consumeAsync(method.getReference()); - } + method.getReference().getName().equals(""))) { + consumer.consume(method.getReference()); } if (!method.getModifiers().contains(NodeModifier.STATIC)) { - if (method.isAsync()) { - consumer.consumeAsync(method.getReference().getDescriptor()); - consumer.consumeAsync(method.getReference()); - } else { - consumer.consume(method.getReference().getDescriptor()); - consumer.consume(method.getReference()); - if (asyncFamilyMethods.contains(method.getReference())) { - consumer.consumeAsync(method.getReference().getDescriptor()); - consumer.consumeAsync(method.getReference()); - } - } + consumer.consume(method.getReference().getDescriptor()); + consumer.consume(method.getReference()); } } @@ -217,7 +196,7 @@ public class NameFrequencyEstimator implements StatementVisitor, ExprVisitor, Me if (async) { MethodReference monitorEnterRef = new MethodReference( Object.class, "monitorEnter", Object.class, void.class); - consumer.consumeAsync(monitorEnterRef); + consumer.consume(monitorEnterRef); } else { MethodReference monitorEnterRef = new MethodReference( Object.class, "monitorEnterSync", Object.class, void.class); @@ -230,7 +209,7 @@ public class NameFrequencyEstimator implements StatementVisitor, ExprVisitor, Me if (async) { MethodReference monitorEnterRef = new MethodReference( Object.class, "monitorExit", Object.class, void.class); - consumer.consumeAsync(monitorEnterRef); + consumer.consume(monitorEnterRef); } else { MethodReference monitorEnterRef = new MethodReference( Object.class, "monitorExitSync", Object.class, void.class); @@ -308,30 +287,18 @@ public class NameFrequencyEstimator implements StatementVisitor, ExprVisitor, Me if (injectedMethods.contains(expr.getMethod())) { return; } - boolean asyncCall = expr.getAsyncTarget() != null; switch (expr.getType()) { case SPECIAL: case STATIC: - if (asyncCall) { - consumer.consumeAsync(expr.getMethod()); - } else { - consumer.consume(expr.getMethod()); - } + consumer.consume(expr.getMethod()); break; case CONSTRUCTOR: consumer.consumeInit(expr.getMethod()); break; case DYNAMIC: - if (asyncCall) { - consumer.consumeAsync(expr.getMethod().getDescriptor()); - } else { - consumer.consume(expr.getMethod().getDescriptor()); - } + consumer.consume(expr.getMethod().getDescriptor()); break; } - if (asyncCall) { - consumer.consumeFunction("$rt_continue"); - } } @Override 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 d158d1dd3..92f95159d 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java @@ -452,12 +452,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext for (MethodNode method : cls.getMethods()) { if (clinit != null && (method.getModifiers().contains(NodeModifier.STATIC) || method.getReference().getName().equals(""))) { - if (!method.isAsync()) { - stubNames.add(naming.getFullNameFor(method.getReference())); - } - if (asyncFamilyMethods.contains(method.getReference())) { - stubNames.add(naming.getFullNameForAsync(method.getReference())); - } + stubNames.add(naming.getFullNameFor(method.getReference())); } if (!method.getModifiers().contains(NodeModifier.STATIC)) { virtualMethods.add(method); @@ -546,32 +541,20 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext writer.append(",").ws(); } first = false; - if (method.isAsync()) { - emitVirtualDeclaration(ref, true); - } else { - emitVirtualDeclaration(ref, false); - if (asyncFamilyMethods.contains(ref)) { - writer.append(",").ws(); - emitVirtualDeclaration(ref, true); - } - } + emitVirtualDeclaration(ref); debugEmitter.emitMethod(null); } writer.append("]"); } - private void emitVirtualDeclaration(MethodReference ref, boolean async) throws IOException { - String methodName = async ? naming.getNameForAsync(ref.getDescriptor()) : - naming.getNameFor(ref.getDescriptor()); + private void emitVirtualDeclaration(MethodReference ref) throws IOException { + String methodName = naming.getNameFor(ref.getDescriptor()); writer.append("\"").append(methodName).append("\""); writer.append(",").ws().append("function("); List args = new ArrayList<>(); for (int i = 1; i <= ref.parameterCount(); ++i) { args.add(variableName(i)); } - if (async) { - args.add(getReturnVariable()); - } for (int i = 0; i < args.size(); ++i) { if (i > 0) { writer.append(",").ws(); @@ -582,7 +565,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext if (ref.getDescriptor().getResultType() != ValueType.VOID) { writer.append("return "); } - writer.append(async ? naming.getFullNameForAsync(ref) : naming.getFullNameFor(ref)).append("("); + writer.appendMethodBody(ref).append("("); writer.append("this"); for (int i = 0; i < args.size(); ++i) { writer.append(",").ws().append(args.get(i)); @@ -590,23 +573,11 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext writer.append(");").ws().append("}"); } - private String getPartVariable(int index) { - if (minifying) { - return "$p" + indexToId(index); - } else { - return "$part_" + index; - } - } - - private String getReturnVariable() { - return minifying ? "$r" : "$return"; - } - public void renderBody(MethodNode method, boolean inner) throws IOException { blockIdMap.clear(); MethodReference ref = method.getReference(); debugEmitter.emitMethod(ref.getDescriptor()); - String name = method.isAsync() ? naming.getFullNameForAsync(ref) : naming.getFullNameFor(ref); + String name = naming.getFullNameFor(ref); if (inner) { writer.append(name).ws().append("=").ws().append("function("); } else { @@ -622,12 +593,6 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext } writer.append(variableName(i)); } - if (method.isAsync()) { - if (startParam < ref.parameterCount() + 1) { - writer.append(',').ws(); - } - writer.append(getReturnVariable()); - } writer.append(")").ws().append("{").softNewLine().indent(); method.acceptVisitor(new MethodBodyRenderer()); writer.outdent().append("}"); @@ -635,42 +600,6 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext writer.append(';'); } writer.newLine(); - - if (!method.isAsync() && asyncFamilyMethods.contains(method.getReference())) { - if (inner) { - writer.append(naming.getFullNameForAsync(ref)).ws().append("=").ws().append("function("); - } else { - writer.append("function ").append(naming.getFullNameForAsync(ref)).append("("); - } - for (int i = startParam; i <= ref.parameterCount(); ++i) { - writer.append(variableName(i)); - writer.append(",").ws(); - } - writer.append(getReturnVariable()).append(")").ws().append("{").softNewLine().indent(); - - writer.append("var $x;").softNewLine(); - writer.append("try").ws().append('{').indent().softNewLine(); - writer.append("$x").ws().append("=").ws().appendMethodBody(ref).append('('); - for (int i = startParam; i <= ref.parameterCount(); ++i) { - if (i > startParam) { - writer.append(",").ws(); - } - writer.append(variableName(i)); - } - writer.append(");").softNewLine(); - writer.outdent().append("}").ws().append("catch").ws().append("($e)").ws() - .append("{").indent().softNewLine(); - writer.append("return ").append(getReturnVariable()).append("(").appendFunction("$rt_asyncError") - .append("($e));").softNewLine(); - writer.outdent().append("}"); - writer.append(getReturnVariable()).append("(").appendFunction("$rt_asyncResult").append("($x));") - .softNewLine(); - writer.outdent().append("}"); - if (inner) { - writer.append(';'); - } - writer.newLine(); - } debugEmitter.emitMethod(null); } @@ -756,6 +685,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext if (hasTryCatch) { variableNames.add("$je"); } + variableNames.add("$ptr"); if (!variableNames.isEmpty()) { writer.append("var "); for (int i = 0; i < variableNames.size(); ++i) { @@ -766,18 +696,34 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext } writer.append(";").softNewLine(); } + + writer.append("function $save()").ws().append("{").indent().softNewLine(); + writer.append("var $").ws().append('=').ws().append("$rt_stack();").softNewLine(); + for (int i = ref.parameterCount() + 1; i < variableCount; ++i) { + writer.append("$.push(").append(variableName(i)).append(");"); + } + writer.append("$.push($ptr)"); + writer.softNewLine(); + writer.outdent().append("}").softNewLine(); + + writer.append("$ptr").ws().append('=').ws().append("0;").softNewLine(); + writer.append("if").ws().append("($rt_isRestoring())").ws().append("{").indent().softNewLine(); + writer.append("var $s").ws().append('=').ws().append("$rt_stack();").softNewLine(); + writer.append("var $ptr").ws().append('=').append("$s.pop();"); + for (int i = variableCount - 1; i > ref.parameterCount(); --i) { + writer.append(variableName(i)).ws().append('=').ws().append("$.pop();"); + } + writer.softNewLine(); + writer.outdent().append("}").softNewLine(); + + writer.append("$main: switch").ws().append("($ptr)").ws().append('{').softNewLine(); for (int i = 0; i < methodNode.getBody().size(); ++i) { - writer.append("var ").append(getPartVariable(i)).ws().append("=").ws() - .appendFunction("$rt_guardAsync").append("(function("); - if (i > 0) { - writer.append("$restore"); - } - writer.append(")").ws().append("{").indent().softNewLine(); + writer.append("case ").append(i).append(":").indent().softNewLine(); AsyncMethodPart part = methodNode.getBody().get(i); part.getStatement().acceptVisitor(Renderer.this); - writer.outdent().append("},").ws().append(getReturnVariable()).append(");").softNewLine(); + writer.outdent(); } - writer.append("return ").append(getPartVariable(0)).append("();").softNewLine(); + writer.append("}").softNewLine(); } catch (IOException e) { throw new RenderingException("IO error occured", e); } @@ -823,11 +769,6 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext return asyncFamilyMethods.contains(method); } - @Override - public String getCompleteContinuation() { - return getReturnVariable(); - } - @Override public Diagnostics getDiagnostics() { return diagnostics; @@ -1097,23 +1038,14 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext pushLocation(statement.getLocation()); } writer.append("return"); - if (async) { - writer.append(' ').append(getReturnVariable()).append("(").appendFunction("$rt_asyncResult") - .append("("); - } if (statement.getResult() != null) { - if (!async) { - writer.append(' '); - } + writer.append(' '); prevCallSite = debugEmitter.emitCallSite(); priority = Priority.COMMA; associativity = Associativity.NONE; statement.getResult().acceptVisitor(this); debugEmitter.emitCallSite(); } - if (async) { - writer.append("))"); - } writer.append(";").softNewLine(); if (statement.getLocation() != null) { popLocation(); @@ -1693,43 +1625,33 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext if (injector != null) { injector.generate(new InjectorContextImpl(expr.getArguments()), expr.getMethod()); } else { - boolean asyncCall = expr.getAsyncTarget() != null; - if (asyncCall) { - writer.append("return "); - } if (expr.getType() == InvocationType.DYNAMIC) { expr.getArguments().get(0).acceptVisitor(this); } MethodReference method = expr.getMethod(); - String name = asyncCall ? naming.getNameForAsync(method.getDescriptor()) : - naming.getNameFor(method.getDescriptor()); + String name = naming.getNameFor(method.getDescriptor()); DeferredCallSite callSite = prevCallSite; boolean shouldEraseCallSite = lastCallSite == null; if (lastCallSite == null) { lastCallSite = callSite; } boolean virtual = false; - boolean hasParams = false; enterPriority(Priority.COMMA, Associativity.NONE, false); switch (expr.getType()) { case STATIC: - writer.append(asyncCall ? naming.getFullNameForAsync(method) : - naming.getFullNameFor(method)).append("("); + writer.append(naming.getFullNameFor(method)).append("("); prevCallSite = debugEmitter.emitCallSite(); for (int i = 0; i < expr.getArguments().size(); ++i) { if (i > 0) { writer.append(",").ws(); } expr.getArguments().get(i).acceptVisitor(this); - hasParams = true; } break; case SPECIAL: - writer.append(asyncCall ? naming.getFullNameForAsync(method) : - naming.getFullNameFor(method)).append("("); + writer.append(naming.getFullNameFor(method)).append("("); prevCallSite = debugEmitter.emitCallSite(); expr.getArguments().get(0).acceptVisitor(this); - hasParams = true; for (int i = 1; i < expr.getArguments().size(); ++i) { writer.append(",").ws(); expr.getArguments().get(i).acceptVisitor(this); @@ -1742,7 +1664,6 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext if (i > 1) { writer.append(",").ws(); } - hasParams = true; expr.getArguments().get(i).acceptVisitor(this); } virtual = true; @@ -1754,20 +1675,21 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext if (i > 0) { writer.append(",").ws(); } - hasParams = true; expr.getArguments().get(i).acceptVisitor(this); } break; } - if (expr.getAsyncTarget() != null) { - if (hasParams) { - writer.append(',').ws(); - } - writer.appendFunction("$rt_continue").append("(").append(getPartVariable(expr.getAsyncTarget())) - .append(')'); - } writer.append(')'); exitPriority(); + if (expr.getAsyncTarget() != null) { + writer.append(';').softNewLine(); + writer.append("$ptr").ws().append("=").ws().append(expr.getAsyncTarget()).append(";") + .softNewLine(); + writer.append("if").ws().append("($rt_suspending())").ws().append("{").indent(); + writer.append("return $save();").softNewLine(); + writer.outdent().append("}").softNewLine(); + writer.append("break $main;").softNewLine(); + } if (lastCallSite != null) { if (virtual) { lastCallSite.setVirtualMethod(expr.getMethod()); @@ -2061,11 +1983,8 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext if (async) { MethodReference monitorEnterRef = new MethodReference( Object.class, "monitorEnter", Object.class, void.class); - writer.append("return ").append(naming.getFullNameForAsync(monitorEnterRef)).append("("); + writer.appendMethodBody(monitorEnterRef).append("("); statement.getObjectRef().acceptVisitor(this); - writer.append(",").ws(); - writer.appendFunction("$rt_continue").append("(").append(getPartVariable(statement.getAsyncTarget())) - .append(')'); writer.append(");").softNewLine(); } else { MethodReference monitorEnterRef = new MethodReference( diff --git a/teavm-core/src/main/java/org/teavm/javascript/spi/GeneratorContext.java b/teavm-core/src/main/java/org/teavm/javascript/spi/GeneratorContext.java index b2c97a8e9..90d1ff82f 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/spi/GeneratorContext.java +++ b/teavm-core/src/main/java/org/teavm/javascript/spi/GeneratorContext.java @@ -36,8 +36,6 @@ public interface GeneratorContext extends ServiceRepository { boolean isAsync(); - String getCompleteContinuation(); - boolean isAsync(MethodReference method); boolean isAsyncFamily(MethodReference method); diff --git a/teavm-core/src/main/java/org/teavm/vm/TeaVM.java b/teavm-core/src/main/java/org/teavm/vm/TeaVM.java index f459e4a46..4f0d4d107 100644 --- a/teavm-core/src/main/java/org/teavm/vm/TeaVM.java +++ b/teavm-core/src/main/java/org/teavm/vm/TeaVM.java @@ -437,13 +437,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository { for (Map.Entry entry : entryPoints.entrySet()) { sourceWriter.append("var ").append(entry.getKey()).ws().append("=").ws(); MethodReference ref = entry.getValue().reference; - boolean asyncMethod = asyncMethods.contains(ref); - boolean wrapAsync = !asyncMethod && entry.getValue().isAsync(); - if (wrapAsync) { - sourceWriter.append("$rt_staticAsyncAdapter(").appendMethodBody(ref).append(')'); - } else { - sourceWriter.append(asyncMethod ? naming.getFullNameForAsync(ref) : naming.getFullNameFor(ref)); - } + sourceWriter.append(naming.getFullNameFor(ref)); sourceWriter.append(";").newLine(); } for (Map.Entry entry : exportedClasses.entrySet()) { diff --git a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js index 88d9ddef4..ee02d37ed 100644 --- a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js +++ b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js @@ -517,6 +517,57 @@ function $rt_guardAsync(f, continuation) { } } } +function TeaVMThread(runner) { + this.status = 3; + this.stack = []; + this.suspendCallback = null; + this.runner = runner; +} +TeaVMThread.push = function(value) { + this.stack.push[value]; +} +TeaVMThread.isResuming = function() { + return this.status == 1; +} +TeaVMThread.isSuspending = function() { + return this.status == 2; +} +TeaVMThread.suspend(callback) { + this.suspendCallback = callback; + this.status = 1; +} +TeaVMThread.start = function() { + if (this.status != 3) { + throw new Error("Thread already started"); + } + this.status = 0; + this.run(); +} +TeaVMThread.resume = function() { + this.status = 2; + this.run(); +} +TeaVMThread.run = function() { + this.runner(); + if (this.suspendCallback !== null) { + var self = this; + this.suspendCallback(function() { + self.resume(); + }); + } +} +function $rt_nativeThread(thread) { + if (!thread.hasNativeProperty("$teavm_thread")) { + thread.$teavm_thread = new TeaVMThread(); + } +} +function $rt_suspending() { + return $rt_nativeThread($rt_getThread()).isSuspending(); +} +function $rt_resuming() { + return $rt_nativeThread($rt_getThread()).isResuming(); +} + function TeaVMAsyncError(cause) { this.message = "Async error occured"; this.cause = cause; From 32deaf271612d8ae3ac4b69227b4ced915794293 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Tue, 10 Mar 2015 15:19:54 +0400 Subject: [PATCH 36/69] Further work on a new thread emulator --- .../org/teavm/classlib/java/lang/TThread.java | 1 + .../src/main/java/org/teavm/cache/AstIO.java | 41 +++-- .../cache/DiskRegularMethodNodeCache.java | 5 +- .../javascript/BreakToContinueReplacer.java | 4 +- .../javascript/CertainBlockCountVisitor.java | 4 +- .../java/org/teavm/javascript/Decompiler.java | 21 +-- .../javascript/NameFrequencyEstimator.java | 2 +- .../java/org/teavm/javascript/Optimizer.java | 9 +- .../teavm/javascript/OptimizingVisitor.java | 8 +- .../javascript/RedundantLabelEliminator.java | 4 +- .../javascript/ReferenceCountingVisitor.java | 4 +- .../java/org/teavm/javascript/Renderer.java | 51 +++--- .../teavm/javascript/StatementGenerator.java | 16 +- .../org/teavm/javascript/TryCatchFinder.java | 4 +- .../javascript/UnusedVariableEliminator.java | 5 +- ...cStatement.java => GotoPartStatement.java} | 12 +- .../teavm/javascript/ast/InvocationExpr.java | 10 -- .../teavm/javascript/ast/RenamingVisitor.java | 9 +- .../javascript/ast/StatementVisitor.java | 6 +- .../model/util/AsyncProgramSplitter.java | 12 +- .../java/org/teavm/tooling/TeaVMTool.java | 2 +- .../resources/org/teavm/javascript/runtime.js | 153 +++++------------- .../java/org/teavm/platform/Platform.java | 10 +- .../platform/plugin/AsyncMethodGenerator.java | 23 ++- .../plugin/NewInstanceDependencySupport.java | 2 +- .../platform/plugin/PlatformGenerator.java | 104 ++++-------- teavm-samples/teavm-samples-async/pom.xml | 4 +- 27 files changed, 193 insertions(+), 333 deletions(-) rename teavm-core/src/main/java/org/teavm/javascript/ast/{RestoreAsyncStatement.java => GotoPartStatement.java} (78%) diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java index 2576f0653..a635bc045 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java @@ -80,6 +80,7 @@ public class TThread extends TObject implements TRunnable { currentThread.timeSliceStart = System.currentTimeMillis(); } } + static TThread getMainThread(){ return mainThread; } diff --git a/teavm-core/src/main/java/org/teavm/cache/AstIO.java b/teavm-core/src/main/java/org/teavm/cache/AstIO.java index e519cc896..b1ead2777 100644 --- a/teavm-core/src/main/java/org/teavm/cache/AstIO.java +++ b/teavm-core/src/main/java/org/teavm/cache/AstIO.java @@ -305,10 +305,31 @@ public class AstIO { } @Override - public void visit(RestoreAsyncStatement statement) { + public void visit(GotoPartStatement statement) { try { output.writeByte(17); - output.writeShort(statement.getReceiver() != null ? statement.getReceiver() : -1); + output.writeShort(statement.getPart()); + } catch (IOException e) { + throw new IOExceptionWrapper(e); + } + } + + @Override + public void visit(MonitorEnterStatement statement) { + try { + output.writeByte(18); + output.writeShort(statement.getAsyncTarget() != null ? 0 : statement.getAsyncTarget()); + writeExpr(statement.getObjectRef()); + } catch (IOException e) { + throw new IOExceptionWrapper(e); + } + } + + @Override + public void visit(MonitorExitStatement statement) { + try { + output.writeByte(19); + writeExpr(statement.getObjectRef()); } catch (IOException e) { throw new IOExceptionWrapper(e); } @@ -506,16 +527,6 @@ public class AstIO { throw new IOExceptionWrapper(e); } } - - @Override - public void visit(MonitorEnterStatement statement) { - - } - - @Override - public void visit(MonitorExitStatement statement) { - - } } private NodeLocation readLocation(DataInput input) throws IOException { @@ -670,11 +681,11 @@ public class AstIO { return stmt; } case 17: { - short var = input.readShort(); - RestoreAsyncStatement stmt = new RestoreAsyncStatement(); - stmt.setReceiver(var >= 0 ? (int)var : null); + GotoPartStatement stmt = new GotoPartStatement(); + stmt.setPart(input.readShort()); return stmt; } + // TODO: MonitorEnter/MonitorExit default: throw new RuntimeException("Unexpected statement type: " + type); } diff --git a/teavm-core/src/main/java/org/teavm/cache/DiskRegularMethodNodeCache.java b/teavm-core/src/main/java/org/teavm/cache/DiskRegularMethodNodeCache.java index c597c6490..bb6d058e0 100644 --- a/teavm-core/src/main/java/org/teavm/cache/DiskRegularMethodNodeCache.java +++ b/teavm-core/src/main/java/org/teavm/cache/DiskRegularMethodNodeCache.java @@ -259,17 +259,16 @@ public class DiskRegularMethodNodeCache implements RegularMethodNodeCache { } @Override - public void visit(RestoreAsyncStatement statement) { + public void visit(GotoPartStatement statement) { } @Override public void visit(MonitorEnterStatement statement) { - + } @Override public void visit(MonitorExitStatement statement) { - } } diff --git a/teavm-core/src/main/java/org/teavm/javascript/BreakToContinueReplacer.java b/teavm-core/src/main/java/org/teavm/javascript/BreakToContinueReplacer.java index 01e8d7a73..f80c3f981 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/BreakToContinueReplacer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/BreakToContinueReplacer.java @@ -114,16 +114,14 @@ class BreakToContinueReplacer implements StatementVisitor { } @Override - public void visit(RestoreAsyncStatement statement) { + public void visit(GotoPartStatement statement) { } @Override public void visit(MonitorEnterStatement statement) { - } @Override public void visit(MonitorExitStatement statement) { - } } diff --git a/teavm-core/src/main/java/org/teavm/javascript/CertainBlockCountVisitor.java b/teavm-core/src/main/java/org/teavm/javascript/CertainBlockCountVisitor.java index 66152cb01..11702da38 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/CertainBlockCountVisitor.java +++ b/teavm-core/src/main/java/org/teavm/javascript/CertainBlockCountVisitor.java @@ -109,16 +109,14 @@ class CertainBlockCountVisitor implements StatementVisitor { } @Override - public void visit(RestoreAsyncStatement statement) { + public void visit(GotoPartStatement statement) { } @Override public void visit(MonitorEnterStatement statement) { - } @Override public void visit(MonitorExitStatement statement) { - } } 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 33d3c3311..88c3745fb 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java @@ -203,15 +203,7 @@ public class Decompiler { AsyncProgramSplitter splitter = new AsyncProgramSplitter(classSource, splitMethods); splitter.split(method.getProgram()); for (int i = 0; i < splitter.size(); ++i) { - Integer input = null; - if (i > 0) { - input = splitter.getInput(i); - if (input == null) { - input = -1; - } - } - AsyncMethodPart part = getRegularMethodStatement(splitter.getProgram(i), splitter.getBlockSuccessors(i), - input); + AsyncMethodPart part = getRegularMethodStatement(splitter.getProgram(i), splitter.getBlockSuccessors(i)); node.getBody().add(part); } Program program = method.getProgram(); @@ -219,7 +211,7 @@ public class Decompiler { node.getVariables().add(program.variableAt(i).getRegister()); } Optimizer optimizer = new Optimizer(); - optimizer.optimize(node, program, splitter); + optimizer.optimize(node, program); node.getModifiers().addAll(mapModifiers(method.getModifiers())); int paramCount = Math.min(method.getSignature().length, program.variableCount()); for (int i = 0; i < paramCount; ++i) { @@ -234,7 +226,7 @@ public class Decompiler { Program program = method.getProgram(); int[] targetBlocks = new int[program.basicBlockCount()]; Arrays.fill(targetBlocks, -1); - methodNode.setBody(getRegularMethodStatement(program, targetBlocks, null).getStatement()); + methodNode.setBody(getRegularMethodStatement(program, targetBlocks).getStatement()); for (int i = 0; i < program.variableCount(); ++i) { methodNode.getVariables().add(program.variableAt(i).getRegister()); } @@ -249,7 +241,7 @@ public class Decompiler { return methodNode; } - private AsyncMethodPart getRegularMethodStatement(Program program, int[] targetBlocks, Integer inputVar) { + private AsyncMethodPart getRegularMethodStatement(Program program, int[] targetBlocks) { AsyncMethodPart result = new AsyncMethodPart(); lastBlockId = 1; graph = ProgramUtils.buildControlFlowGraph(program); @@ -302,11 +294,6 @@ public class Decompiler { int tmp = indexer.nodeAt(next); generator.nextBlock = tmp >= 0 && next < indexer.size() ? program.basicBlockAt(tmp) : null; generator.statements.clear(); - if (node == 0 && inputVar != null) { - RestoreAsyncStatement restoreStmt = new RestoreAsyncStatement(); - restoreStmt.setReceiver(inputVar >= 0 ? inputVar : null); - generator.statements.add(restoreStmt); - } generator.asyncTarget = null; InstructionLocation lastLocation = null; NodeLocation nodeLocation = null; diff --git a/teavm-core/src/main/java/org/teavm/javascript/NameFrequencyEstimator.java b/teavm-core/src/main/java/org/teavm/javascript/NameFrequencyEstimator.java index 278e9e642..fdfade618 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/NameFrequencyEstimator.java +++ b/teavm-core/src/main/java/org/teavm/javascript/NameFrequencyEstimator.java @@ -188,7 +188,7 @@ public class NameFrequencyEstimator implements StatementVisitor, ExprVisitor, Me } @Override - public void visit(RestoreAsyncStatement statement) { + public void visit(GotoPartStatement statement) { } @Override diff --git a/teavm-core/src/main/java/org/teavm/javascript/Optimizer.java b/teavm-core/src/main/java/org/teavm/javascript/Optimizer.java index f69803a48..e32c26b37 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Optimizer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Optimizer.java @@ -19,7 +19,6 @@ import org.teavm.javascript.ast.AsyncMethodNode; import org.teavm.javascript.ast.AsyncMethodPart; import org.teavm.javascript.ast.RegularMethodNode; import org.teavm.model.Program; -import org.teavm.model.util.AsyncProgramSplitter; /** * @@ -43,15 +42,9 @@ public class Optimizer { } } - public void optimize(AsyncMethodNode method, Program program, AsyncProgramSplitter splitter) { + public void optimize(AsyncMethodNode method, Program program) { ReadWriteStatsBuilder stats = new ReadWriteStatsBuilder(method.getVariables().size()); stats.analyze(program); - for (int i = 0; i < splitter.size(); ++i) { - Integer var = splitter.getInput(i); - if (var != null) { - stats.reads[var]++; - } - } for (AsyncMethodPart part : method.getBody()) { OptimizingVisitor optimizer = new OptimizingVisitor(stats.copy()); part.getStatement().acceptVisitor(optimizer); diff --git a/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java b/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java index 0d3474098..f155919c4 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java +++ b/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java @@ -180,7 +180,7 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor { } private boolean tryApplyConstructor(InvocationExpr expr) { - if (expr.getAsyncTarget() != null || !expr.getMethod().getName().equals("")) { + if (!expr.getMethod().getName().equals("")) { return false; } if (resultSequence == null || resultSequence.isEmpty()) { @@ -615,17 +615,21 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor { } @Override - public void visit(RestoreAsyncStatement statement) { + public void visit(GotoPartStatement statement) { resultStmt = statement; } @Override public void visit(MonitorEnterStatement statement) { + statement.getObjectRef().acceptVisitor(this); + statement.setObjectRef(resultExpr); resultStmt = statement; } @Override public void visit(MonitorExitStatement statement) { + statement.getObjectRef().acceptVisitor(this); + statement.setObjectRef(resultExpr); resultStmt = statement; } } diff --git a/teavm-core/src/main/java/org/teavm/javascript/RedundantLabelEliminator.java b/teavm-core/src/main/java/org/teavm/javascript/RedundantLabelEliminator.java index bca649fd4..c0d240ebd 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/RedundantLabelEliminator.java +++ b/teavm-core/src/main/java/org/teavm/javascript/RedundantLabelEliminator.java @@ -119,16 +119,14 @@ class RedundantLabelEliminator implements StatementVisitor { } @Override - public void visit(RestoreAsyncStatement statement) { + public void visit(GotoPartStatement statement) { } @Override public void visit(MonitorEnterStatement statement) { - } @Override public void visit(MonitorExitStatement statement) { - } } diff --git a/teavm-core/src/main/java/org/teavm/javascript/ReferenceCountingVisitor.java b/teavm-core/src/main/java/org/teavm/javascript/ReferenceCountingVisitor.java index 218b8ea45..031ca7d2a 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ReferenceCountingVisitor.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ReferenceCountingVisitor.java @@ -113,16 +113,14 @@ class ReferenceCountingVisitor implements StatementVisitor { } @Override - public void visit(RestoreAsyncStatement statement) { + public void visit(GotoPartStatement statement) { } @Override public void visit(MonitorEnterStatement statement) { - } @Override public void visit(MonitorExitStatement statement) { - } } 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 92f95159d..78abe9d5a 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java @@ -260,8 +260,8 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext } private void renderRuntimeAliases() throws IOException { - String[] names = { "$rt_asyncResult", "$rt_asyncError", "$rt_continue", "$rt_guardAsync", "$rt_throw", - "$rt_compare", "$rt_nullCheck", "$rt_cls", "$rt_createArray", "$rt_isInstance" }; + String[] names = { "$rt_throw", "$rt_compare", "$rt_nullCheck", "$rt_cls", "$rt_createArray", + "$rt_isInstance" }; boolean first = true; for (String name : names) { if (!first) { @@ -698,20 +698,20 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext } writer.append("function $save()").ws().append("{").indent().softNewLine(); - writer.append("var $").ws().append('=').ws().append("$rt_stack();").softNewLine(); + writer.append("$rt_nativeThread()"); for (int i = ref.parameterCount() + 1; i < variableCount; ++i) { - writer.append("$.push(").append(variableName(i)).append(");"); + writer.append(".push(").append(variableName(i)).append(")"); } - writer.append("$.push($ptr)"); + writer.append(".push($ptr);"); writer.softNewLine(); writer.outdent().append("}").softNewLine(); writer.append("$ptr").ws().append('=').ws().append("0;").softNewLine(); - writer.append("if").ws().append("($rt_isRestoring())").ws().append("{").indent().softNewLine(); - writer.append("var $s").ws().append('=').ws().append("$rt_stack();").softNewLine(); - writer.append("var $ptr").ws().append('=').append("$s.pop();"); + writer.append("if").ws().append("($rt_resuming())").ws().append("{").indent().softNewLine(); + writer.append("var $T").ws().append('=').ws().append("$rt_nativeThread();").softNewLine(); + writer.append("$ptr").ws().append('=').ws().append("$T.pop();"); for (int i = variableCount - 1; i > ref.parameterCount(); --i) { - writer.append(variableName(i)).ws().append('=').ws().append("$.pop();"); + writer.append(variableName(i)).ws().append('=').ws().append("T.pop();"); } writer.softNewLine(); writer.outdent().append("}").softNewLine(); @@ -1681,15 +1681,6 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext } writer.append(')'); exitPriority(); - if (expr.getAsyncTarget() != null) { - writer.append(';').softNewLine(); - writer.append("$ptr").ws().append("=").ws().append(expr.getAsyncTarget()).append(";") - .softNewLine(); - writer.append("if").ws().append("($rt_suspending())").ws().append("{").indent(); - writer.append("return $save();").softNewLine(); - writer.outdent().append("}").softNewLine(); - writer.append("break $main;").softNewLine(); - } if (lastCallSite != null) { if (virtual) { lastCallSite.setVirtualMethod(expr.getMethod()); @@ -1965,18 +1956,25 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext } } + @Override - public void visit(RestoreAsyncStatement statement) { + public void visit(GotoPartStatement statement) { try { - if (statement.getReceiver() != null) { - writer.append(variableName(statement.getReceiver())).ws().append('=').ws(); - } - writer.append("$restore();").softNewLine(); - } catch (IOException e) { - throw new RenderingException("IO error occured", e); + gotoPart(statement.getPart()); + } catch (IOException ex){ + throw new RenderingException("IO error occured", ex); } } + private void gotoPart(int part) throws IOException { + writer.append("$ptr").ws().append("=").ws().append(part).append(";") + .softNewLine(); + writer.append("if").ws().append("($rt_suspending())").ws().append("{").indent().softNewLine(); + writer.append("return $save();").softNewLine(); + writer.outdent().append("}").softNewLine(); + writer.append("break $main;").softNewLine(); + } + @Override public void visit(MonitorEnterStatement statement) { try { @@ -1986,6 +1984,9 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext writer.appendMethodBody(monitorEnterRef).append("("); statement.getObjectRef().acceptVisitor(this); writer.append(");").softNewLine(); + if (statement.getAsyncTarget() != null) { + gotoPart(statement.getAsyncTarget()); + } } else { MethodReference monitorEnterRef = new MethodReference( Object.class, "monitorEnterSync", Object.class, void.class); diff --git a/teavm-core/src/main/java/org/teavm/javascript/StatementGenerator.java b/teavm-core/src/main/java/org/teavm/javascript/StatementGenerator.java index 2400494ab..604bb2f3c 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/StatementGenerator.java +++ b/teavm-core/src/main/java/org/teavm/javascript/StatementGenerator.java @@ -550,20 +550,18 @@ class StatementGenerator implements InstructionVisitor { } else { invocationExpr = Expr.invokeStatic(insn.getMethod(), exprArgs); } - invocationExpr.setAsyncTarget(asyncTarget); - if (asyncTarget == null) { - if (insn.getReceiver() != null) { - assign(invocationExpr, insn.getReceiver()); - } else { - AssignmentStatement stmt = Statement.assign(null, invocationExpr); - stmt.setLocation(currentLocation); - statements.add(stmt); - } + if (insn.getReceiver() != null) { + assign(invocationExpr, insn.getReceiver()); } else { AssignmentStatement stmt = Statement.assign(null, invocationExpr); stmt.setLocation(currentLocation); statements.add(stmt); } + if (asyncTarget != null) { + GotoPartStatement gotoStmt = new GotoPartStatement(); + gotoStmt.setPart(asyncTarget); + statements.add(gotoStmt); + } } @Override diff --git a/teavm-core/src/main/java/org/teavm/javascript/TryCatchFinder.java b/teavm-core/src/main/java/org/teavm/javascript/TryCatchFinder.java index 252b10b0b..6bc07c4f0 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/TryCatchFinder.java +++ b/teavm-core/src/main/java/org/teavm/javascript/TryCatchFinder.java @@ -112,16 +112,14 @@ class TryCatchFinder implements StatementVisitor { } @Override - public void visit(RestoreAsyncStatement statement) { + public void visit(GotoPartStatement statement) { } @Override public void visit(MonitorEnterStatement statement) { - } @Override public void visit(MonitorExitStatement statement) { - } } diff --git a/teavm-core/src/main/java/org/teavm/javascript/UnusedVariableEliminator.java b/teavm-core/src/main/java/org/teavm/javascript/UnusedVariableEliminator.java index ddea6cf0c..82c00b82a 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/UnusedVariableEliminator.java +++ b/teavm-core/src/main/java/org/teavm/javascript/UnusedVariableEliminator.java @@ -226,10 +226,7 @@ class UnusedVariableEliminator implements ExprVisitor, StatementVisitor { } @Override - public void visit(RestoreAsyncStatement statement) { - if (statement.getReceiver() != null) { - statement.setReceiver(renumber(statement.getReceiver())); - } + public void visit(GotoPartStatement statement) { } @Override diff --git a/teavm-core/src/main/java/org/teavm/javascript/ast/RestoreAsyncStatement.java b/teavm-core/src/main/java/org/teavm/javascript/ast/GotoPartStatement.java similarity index 78% rename from teavm-core/src/main/java/org/teavm/javascript/ast/RestoreAsyncStatement.java rename to teavm-core/src/main/java/org/teavm/javascript/ast/GotoPartStatement.java index 4f903fd9b..9ccdb7ca5 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ast/RestoreAsyncStatement.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ast/GotoPartStatement.java @@ -19,15 +19,15 @@ package org.teavm.javascript.ast; * * @author Alexey Andreev */ -public class RestoreAsyncStatement extends Statement { - private Integer receiver; +public class GotoPartStatement extends Statement { + private int part; - public Integer getReceiver() { - return receiver; + public int getPart() { + return part; } - public void setReceiver(Integer receiver) { - this.receiver = receiver; + public void setPart(int part) { + this.part = part; } @Override diff --git a/teavm-core/src/main/java/org/teavm/javascript/ast/InvocationExpr.java b/teavm-core/src/main/java/org/teavm/javascript/ast/InvocationExpr.java index 8ee249842..2d462bb85 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ast/InvocationExpr.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ast/InvocationExpr.java @@ -28,7 +28,6 @@ public class InvocationExpr extends Expr { private MethodReference method; private InvocationType type; private List arguments = new ArrayList<>(); - private Integer asyncTarget; public MethodReference getMethod() { return method; @@ -50,14 +49,6 @@ public class InvocationExpr extends Expr { return arguments; } - public Integer getAsyncTarget() { - return asyncTarget; - } - - public void setAsyncTarget(Integer asyncTarget) { - this.asyncTarget = asyncTarget; - } - @Override public void acceptVisitor(ExprVisitor visitor) { visitor.visit(this); @@ -72,7 +63,6 @@ public class InvocationExpr extends Expr { InvocationExpr copy = new InvocationExpr(); cache.put(this, copy); copy.setMethod(method); - copy.setAsyncTarget(asyncTarget); for (Expr arg : arguments) { copy.getArguments().add(arg.clone(cache)); } diff --git a/teavm-core/src/main/java/org/teavm/javascript/ast/RenamingVisitor.java b/teavm-core/src/main/java/org/teavm/javascript/ast/RenamingVisitor.java index 402fe6d3c..1bb1cfccd 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ast/RenamingVisitor.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ast/RenamingVisitor.java @@ -193,19 +193,16 @@ public class RenamingVisitor implements StatementVisitor, ExprVisitor { } @Override - public void visit(RestoreAsyncStatement statement) { - if (statement.getReceiver() != null) { - statement.setReceiver(varNames[statement.getReceiver()]); - } + public void visit(GotoPartStatement statement) { } @Override public void visit(MonitorEnterStatement statement) { - + } @Override public void visit(MonitorExitStatement statement) { - + } } diff --git a/teavm-core/src/main/java/org/teavm/javascript/ast/StatementVisitor.java b/teavm-core/src/main/java/org/teavm/javascript/ast/StatementVisitor.java index 86cbb8474..7194cdb4e 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ast/StatementVisitor.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ast/StatementVisitor.java @@ -44,9 +44,9 @@ public interface StatementVisitor { void visit(TryCatchStatement statement); - void visit(RestoreAsyncStatement statement); - + void visit(GotoPartStatement statement); + void visit(MonitorEnterStatement statement); - + void visit(MonitorExitStatement statement); } diff --git a/teavm-core/src/main/java/org/teavm/model/util/AsyncProgramSplitter.java b/teavm-core/src/main/java/org/teavm/model/util/AsyncProgramSplitter.java index b817fd3a7..81d174be4 100644 --- a/teavm-core/src/main/java/org/teavm/model/util/AsyncProgramSplitter.java +++ b/teavm-core/src/main/java/org/teavm/model/util/AsyncProgramSplitter.java @@ -62,16 +62,12 @@ public class AsyncProgramSplitter { int last = 0; for (int i = 0; i < sourceBlock.getInstructions().size(); ++i) { Instruction insn = sourceBlock.getInstructions().get(i); - Integer receiver; if (insn instanceof InvokeInstruction) { InvokeInstruction invoke = (InvokeInstruction)insn; if (!asyncMethods.contains(findRealMethod(invoke.getMethod()))) { continue; } - receiver = invoke.getReceiver() != null ? invoke.getReceiver().getIndex() : null; - } else if (insn instanceof MonitorEnterInstruction) { - receiver = null; - } else { + } else if (!(insn instanceof MonitorEnterInstruction)) { continue; } @@ -102,7 +98,6 @@ public class AsyncProgramSplitter { // Create a new part Program nextProgram = createStubCopy(program); Part part = new Part(); - part.input = receiver; part.program = nextProgram; int partId = parts.size(); parts.add(part); @@ -201,10 +196,6 @@ public class AsyncProgramSplitter { return parts.get(index).program; } - public Integer getInput(int index) { - return parts.get(index).input; - } - public int[] getBlockSuccessors(int index) { int[] result = parts.get(index).blockSuccessors; return Arrays.copyOf(result, result.length); @@ -212,7 +203,6 @@ public class AsyncProgramSplitter { private static class Part { Program program; - Integer input; int[] blockSuccessors; } diff --git a/teavm-core/src/main/java/org/teavm/tooling/TeaVMTool.java b/teavm-core/src/main/java/org/teavm/tooling/TeaVMTool.java index e3107f9c4..0c6fdf36c 100644 --- a/teavm-core/src/main/java/org/teavm/tooling/TeaVMTool.java +++ b/teavm-core/src/main/java/org/teavm/tooling/TeaVMTool.java @@ -303,7 +303,7 @@ public class TeaVMTool { return; } if (mainClass != null) { - writer.append("main = $rt_mainWrapper(main);\n"); + writer.append("main = $rt_mainStarter(main);\n"); } ProblemProvider problemProvider = vm.getProblemProvider(); if (problemProvider.getProblems().isEmpty()) { diff --git a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js index ee02d37ed..f004f7b26 100644 --- a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js +++ b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js @@ -223,13 +223,16 @@ function $rt_init(cls, constructor, args) { return obj; } function $rt_throw(ex) { + throw $rt_exception(ex); +} +function $rt_exception(ex) { var err = ex.$jsException; if (!err) { var err = new Error("Java exception thrown"); err.$javaException = ex; ex.$jsException = err; } - throw err; + return err; } function $rt_createMultiArray(cls, dimensions) { var arrays = new Array($rt_primitiveArrayCount(dimensions)); @@ -403,71 +406,15 @@ function $rt_metadata(data) { } } } -function $rt_asyncResult(value) { - return function() { - return value; - } -} -function $rt_asyncError(e) { - return function() { - throw new TeaVMAsyncError(e); - } -} -function $rt_staticAsyncAdapter(f) { - return function() { - var result; - var args = Array.prototype.slice.apply(arguments); - var $return = args.pop(); - try { - result = f.apply(this, args); - } catch (e) { - return $return($rt_asyncError(e)); - } - return $return($rt_asyncResult(result)); - } -} -function $rt_asyncAdapter(f) { - return function() { - var result; - var args = Array.prototype.slice.apply(arguments); - var $return = args.pop(); - args.unshift(this); - try { - result = f.apply(null, args); - } catch (e) { - return $return($rt_asyncError(e)); - } - return $return($rt_asyncResult(result)); - } -} -function $rt_rootInvocationAdapter(f) { +function $rt_threadStarter(f) { return function() { var args = Array.prototype.slice.apply(arguments); - args.push(function(result) { - try { - result(); - } catch (e) { - var prefix = "Exception occured %s at %o"; - var hasWrappers = false; - while (e instanceof TeaVMAsyncError) { - console.error(prefix, e.message, e.stack); - e = e.cause; - prefix = "Caused by %s at %o"; - hasWrappers = true; - } - console.error(!hasWrappers ? prefix : "Root cause is %s at %o", e.message, e.stack); - } + $rt_startThread(function() { + f.apply(this, args); }); - f.apply(this, args); - var thread = $rt_getThread(); - if (thread.hasOwnProperty("postponed")) { - while (thread.postponed.length > 0) { - thread.postponed.shift()(); - } - } } } -function $rt_mainWrapper(f) { +function $rt_mainStarter(f) { return function(args) { if (!args) { args = []; @@ -476,7 +423,7 @@ function $rt_mainWrapper(f) { for (var i = 0; i < args.length; ++i) { javaArgs.data[i] = $rt_str(args[i]); } - $rt_rootInvocationAdapter(f)(javaArgs); + $rt_threadStarter(f)(javaArgs); }; } var $rt_stringPool_instance; @@ -489,66 +436,51 @@ function $rt_stringPool(strings) { function $rt_s(index) { return $rt_stringPool_instance[index]; } -var $rt_continueCounter = 0; -function $rt_continue(f) { - if ($rt_continueCounter++ == 5) { - $rt_continueCounter = 0; - return function() { - var self = this; - var args = arguments; - var thread = $rt_getThread(); - if (!thread.hasOwnProperty("postponed")) { - thread.postponed = []; - } - thread.postponed.push(function() { - f.apply(self, args); - }); - }; - } else { - return f; - } -} -function $rt_guardAsync(f, continuation) { - return function() { - try { - return f.apply(this, arguments); - } catch (e) { - return continuation($rt_asyncError(e)); - } - } -} function TeaVMThread(runner) { this.status = 3; this.stack = []; this.suspendCallback = null; this.runner = runner; + this.attribute = null; } -TeaVMThread.push = function(value) { +TeaVMThread.prototype.push = function(value) { this.stack.push[value]; + return this; } -TeaVMThread.isResuming = function() { +TeaVMThread.prototype.pop = function() { + return this.stack.pop(); +} +TeaVMThread.prototype.isResuming = function() { return this.status == 1; } -TeaVMThread.isSuspending = function() { +TeaVMThread.prototype.isSuspending = function() { return this.status == 2; } -TeaVMThread.suspend(callback) { +TeaVMThread.prototype.suspend = function(callback) { this.suspendCallback = callback; this.status = 1; } -TeaVMThread.start = function() { +TeaVMThread.prototype.start = function() { if (this.status != 3) { throw new Error("Thread already started"); } + if ($rt_currentNativeThread !== null) { + throw new Error("Another thread is running"); + } this.status = 0; this.run(); } -TeaVMThread.resume = function() { +TeaVMThread.prototype.resume = function() { + if ($rt_currentNativeThread !== null) { + throw new Error("Another thread is running"); + } this.status = 2; this.run(); } -TeaVMThread.run = function() { +TeaVMThread.prototype.run = function() { + $rt_currentNativeThread = this; this.runner(); + $rt_currentNativeThread = null; if (this.suspendCallback !== null) { var self = this; this.suspendCallback(function() { @@ -556,27 +488,22 @@ TeaVMThread.run = function() { }); } } -function $rt_nativeThread(thread) { - if (!thread.hasNativeProperty("$teavm_thread")) { - thread.$teavm_thread = new TeaVMThread(); - } -} function $rt_suspending() { - return $rt_nativeThread($rt_getThread()).isSuspending(); + return $rt_nativeThread().isSuspending(); } function $rt_resuming() { - return $rt_nativeThread($rt_getThread()).isResuming(); + return $rt_nativeThread().isResuming(); } - -function TeaVMAsyncError(cause) { - this.message = "Async error occured"; - this.cause = cause; - if (cause) { - this.$javaException = cause.$javaException; - } +function $rt_suspend(callback) { + return $rt_nativeThread().suspend(callback); +} +function $rt_startThread(runner) { + new TeaVMThread(runner).start(); +} +var $rt_currentNativeThread = null; +function $rt_nativeThread() { + return $rt_currentNativeThread; } -TeaVMAsyncError.prototype = new Error(); -TeaVMAsyncError.prototype.constructor = TeaVMAsyncError; function $dbg_repr(obj) { return obj.toString ? obj.toString() : ""; diff --git a/teavm-platform/src/main/java/org/teavm/platform/Platform.java b/teavm-platform/src/main/java/org/teavm/platform/Platform.java index 1c8e18b05..cbf6fe506 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/Platform.java +++ b/teavm-platform/src/main/java/org/teavm/platform/Platform.java @@ -73,9 +73,17 @@ public final class Platform { return ((PlatformHelper)JS.getGlobal()).nextId(); } + public static T newInstance(PlatformClass cls) { + prepareNewInstance(); + return newInstanceImpl(cls); + } + + @GeneratedBy(PlatformGenerator.class) + private static native void prepareNewInstance(); + @GeneratedBy(PlatformGenerator.class) @PluggableDependency(PlatformGenerator.class) - public static native T newInstance(PlatformClass cls); + private static native T newInstanceImpl(PlatformClass cls); @GeneratedBy(PlatformGenerator.class) @PluggableDependency(PlatformGenerator.class) diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/AsyncMethodGenerator.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/AsyncMethodGenerator.java index c7e4e27bb..fb2c30487 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/plugin/AsyncMethodGenerator.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/AsyncMethodGenerator.java @@ -38,19 +38,29 @@ public class AsyncMethodGenerator implements Generator, DependencyPlugin { @Override public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException { MethodReference asyncRef = getAsyncReference(methodRef); + writer.append("var thread").ws().append('=').ws().append("$rt_nativeThread();").softNewLine(); + writer.append("if").ws().append("(thread.isResuming())").ws().append("{").indent().softNewLine(); + writer.append("var result").ws().append("=").ws().append("thread.attribute;").softNewLine(); + writer.append("if").ws().append("(result instanceof Error)").ws().append("{").indent().softNewLine(); + writer.append("throw result;").softNewLine(); + writer.outdent().append("}").softNewLine(); + writer.append("return result;").softNewLine(); + writer.outdent().append("}").softNewLine(); + writer.append("var callback").ws().append("=").ws().append("function()").ws().append("{};").softNewLine(); writer.append("callback.").appendMethod(completeMethod.getDescriptor()).ws().append("=").ws() .append("function(val)").ws().append("{").indent().softNewLine(); - writer.append("return ").append(context.getCompleteContinuation()).append("($rt_asyncResult(val));") - .softNewLine(); + writer.append("thread.attribute").ws().append('=').ws().append("val;").softNewLine(); + writer.append("thread.resume();").softNewLine(); writer.outdent().append("};").softNewLine(); writer.append("callback.").appendMethod(errorMethod.getDescriptor()).ws().append("=").ws() .append("function(e)").ws().append("{").indent().softNewLine(); - writer.append("return ").append(context.getCompleteContinuation()).append("($rt_asyncError(e));") - .softNewLine(); + writer.append("thread.attribute").ws().append('=').ws().append("$rt_exception(e);").softNewLine(); + writer.append("thread.resume();").softNewLine(); writer.outdent().append("};").softNewLine(); + writer.append("return thread.suspend(function()").ws().append("{").indent().softNewLine(); writer.append("try").ws().append("{").indent().softNewLine(); - writer.append("return ").appendMethodBody(asyncRef).append('('); + writer.appendMethodBody(asyncRef).append('('); ClassReader cls = context.getClassSource().get(methodRef.getClassName()); MethodReader method = cls.getMethod(methodRef.getDescriptor()); int start = method.hasModifier(ElementModifier.STATIC) ? 1 : 0; @@ -60,9 +70,10 @@ public class AsyncMethodGenerator implements Generator, DependencyPlugin { } writer.append("callback);").softNewLine(); writer.outdent().append("}").ws().append("catch($e)").ws().append("{").indent().softNewLine(); - writer.append("return ").append(context.getCompleteContinuation()).append("($rt_asyncError($e));") + writer.append("callback.").appendMethod(errorMethod.getDescriptor()).append("($rt_exception($e));") .softNewLine(); writer.outdent().append("}").softNewLine(); + writer.outdent().append("});").softNewLine(); } private MethodReference getAsyncReference(MethodReference methodRef) { diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/NewInstanceDependencySupport.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/NewInstanceDependencySupport.java index cdb10e6e9..1a5647b9e 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/plugin/NewInstanceDependencySupport.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/NewInstanceDependencySupport.java @@ -49,7 +49,7 @@ public class NewInstanceDependencySupport implements DependencyListener { @Override public void methodAchieved(final DependencyAgent agent, MethodDependency method, CallLocation location) { MethodReader reader = method.getMethod(); - if (reader.getOwnerName().equals(Platform.class.getName()) && reader.getName().equals("newInstance")) { + if (reader.getOwnerName().equals(Platform.class.getName()) && reader.getName().equals("newInstanceImpl")) { allClassesNode.connect(method.getResult()); final MethodReference methodRef = reader.getReference(); method.getResult().addConsumer(new DependencyConsumer() { diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java index 756545a3c..bc05a14f2 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java @@ -68,8 +68,11 @@ public class PlatformGenerator implements Generator, Injector, DependencyPlugin @Override public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException { switch (methodRef.getName()) { - case "newInstance": - generateNewInstance(context, writer, methodRef); + case "newInstanceImpl": + generateNewInstance(writer); + break; + case "prepareNewInstance": + generatePrepareNewInstance(context, writer); break; case "lookupClass": generateLookup(context, writer); @@ -89,76 +92,37 @@ public class PlatformGenerator implements Generator, Injector, DependencyPlugin } } - private void generateNewInstance(GeneratorContext context, SourceWriter writer, MethodReference methodRef) + private void generatePrepareNewInstance(GeneratorContext context, SourceWriter writer) throws IOException { writer.append("var c").ws().append("=").ws().append("'$$constructor$$';").softNewLine(); - if (context.isAsync()) { - writer.append("function async(cls, init) {").indent().softNewLine(); - writer.append("return function($return) {").indent().softNewLine(); - writer.append("var r = new cls;").softNewLine(); - writer.append("init(r, $rt_guardAsync(function($restore) {").indent().softNewLine(); - writer.append("$restore();").softNewLine(); - writer.append("$return($rt_asyncResult(r))").softNewLine(); - writer.outdent().append("}));").softNewLine(); - writer.outdent().append("};").softNewLine(); - writer.outdent().append("}").softNewLine(); - - writer.append("function sync(cls, init) {").indent().softNewLine(); - writer.append("return function($return) {").indent().softNewLine(); - writer.append("var r = new cls;").softNewLine(); - writer.append("try {").indent().softNewLine(); - writer.append("init(r);").softNewLine(); - writer.append("$return($rt_asyncResult(r));").softNewLine(); - writer.outdent().append("} catch (e) {").indent().softNewLine(); - writer.append("$return($rt_asyncError(e));").softNewLine(); - writer.outdent().append("}").softNewLine(); - writer.outdent().append("};").softNewLine(); - writer.outdent().append("}").softNewLine(); - } for (String clsName : context.getClassSource().getClassNames()) { ClassReader cls = context.getClassSource().get(clsName); MethodReader method = cls.getMethod(new MethodDescriptor("", void.class)); if (method != null) { - writer.appendClass(clsName).append("[c]").ws().append("=").ws(); - if (!context.isAsync()) { - writer.append(writer.getNaming().getNameForInit(method.getReference())); - } else { - String function = context.isAsync(method.getReference()) ? "async" : "sync"; - String methodName = context.isAsync(method.getReference()) ? - writer.getNaming().getFullNameForAsync(method.getReference()) : - writer.getNaming().getFullNameFor(method.getReference()); - writer.append(function).append("(").appendClass(clsName).append(',').ws() - .append(methodName).append(")"); - } - writer.append(";").softNewLine(); + writer.appendClass(clsName).append("[c]").ws().append("=").ws() + .appendMethodBody(method.getReference()).append(")").append(";").softNewLine(); } } - String selfName = context.isAsync() ? writer.getNaming().getFullNameForAsync(methodRef) : - writer.getNaming().getFullNameFor(methodRef); - writer.append(selfName).ws().append("=").ws().append("function(cls"); - if (context.isAsync()) { - writer.append(',').ws().append("$return"); - } - writer.append(")").ws().append("{").softNewLine().indent(); - writer.append("if").ws().append("(!cls.hasOwnProperty(c))").ws().append("{").indent().softNewLine(); - if (!context.isAsync()) { - writer.append("return null;").softNewLine(); - } else { - writer.append("return $return($rt_asyncResult(null));").softNewLine(); - } - writer.outdent().append("}").softNewLine(); - if (!context.isAsync()) { - writer.append("return cls[c]();").softNewLine(); - } else { - writer.append("return cls[c]($return);").softNewLine(); - } - writer.outdent().append("};").softNewLine(); + writer.appendMethodBody(Platform.class, "newInstance", PlatformClass.class, Object.class).ws().append('=').ws() + .appendMethodBody(Platform.class, "newInstanceImpl", PlatformClass.class, Object.class) + .append(";").softNewLine(); + } - writer.append("return ").append(selfName).append("(").append(context.getParameterName(1)); - if (context.isAsync()) { - writer.append(',').ws().append(context.getCompleteContinuation()); - } - writer.append(");").softNewLine(); + private void generateNewInstance(SourceWriter writer) throws IOException { + writer.append("if").ws().append("($rt_resuming())").ws().append("{").indent().softNewLine(); + writer.append("return $rt_nativeThread().pop();").softNewLine(); + writer.outdent().append("}").softNewLine(); + + writer.append("if").ws().append("(!cls.hasOwnProperty('$$constructor$$'))").ws().append("{") + .indent().softNewLine(); + writer.append("return null;").softNewLine(); + writer.outdent().append("}").softNewLine(); + + writer.append("var $r").ws().append('=').ws().append("cls.$$constructor$$();"); + writer.append("if").ws().append("($rt_suspending())").ws().append("{").indent().softNewLine(); + writer.append("return $rt_nativeThread().push($r);").softNewLine(); + writer.outdent().append("}").softNewLine(); + writer.append("return $r;").softNewLine(); } private void generateLookup(GeneratorContext context, SourceWriter writer) throws IOException { @@ -189,18 +153,8 @@ public class PlatformGenerator implements Generator, Injector, DependencyPlugin PlatformRunnable.class, void.class); String runnable = context.getParameterName(1); writer.append("return window.setTimeout(function()").ws().append("{").indent().softNewLine(); - boolean async = context.isAsyncFamily(launchRef); - String methodName = async ? writer.getNaming().getFullNameForAsync(launchRef) : - writer.getNaming().getFullNameFor(launchRef); - if (async) { - writer.append("$rt_rootInvocationAdapter("); - } - writer.append(methodName); - if (async) { - writer.append(")"); - } - writer.append("(").append(runnable).append(");") - .softNewLine(); + writer.append("$rt_threadStarter(").appendMethodBody(launchRef).append(")"); + writer.append("(").append(runnable).append(");").softNewLine(); writer.outdent().append("},").ws().append(timeout ? context.getParameterName(2) : "0") .append(");").softNewLine(); } diff --git a/teavm-samples/teavm-samples-async/pom.xml b/teavm-samples/teavm-samples-async/pom.xml index 99a38de06..125597036 100644 --- a/teavm-samples/teavm-samples-async/pom.xml +++ b/teavm-samples/teavm-samples-async/pom.xml @@ -65,10 +65,12 @@ ${project.build.directory}/generated/js/teavm org.teavm.samples.async.AsyncProgram SEPARATE - true + false true + From 56c5fefae4a6601c397287899f745d9244e61f57 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Tue, 10 Mar 2015 19:33:34 +0400 Subject: [PATCH 37/69] Further development --- .../org/teavm/classlib/java/lang/TObject.java | 8 ++--- .../org/teavm/classlib/java/lang/TThread.java | 4 +-- .../src/main/java/org/teavm/cache/AstIO.java | 14 +++++++-- .../cache/DiskRegularMethodNodeCache.java | 4 +++ .../javascript/BreakToContinueReplacer.java | 4 +++ .../javascript/CertainBlockCountVisitor.java | 4 +++ .../java/org/teavm/javascript/Decompiler.java | 14 ++++++--- .../javascript/NameFrequencyEstimator.java | 4 +++ .../teavm/javascript/OptimizingVisitor.java | 5 ++++ .../javascript/RedundantLabelEliminator.java | 4 +++ .../javascript/ReferenceCountingVisitor.java | 4 +++ .../java/org/teavm/javascript/Renderer.java | 29 +++++++++++-------- .../teavm/javascript/StatementGenerator.java | 7 ----- .../org/teavm/javascript/TryCatchFinder.java | 4 +++ .../javascript/UnusedVariableEliminator.java | 4 +++ .../javascript/ast/MonitorEnterStatement.java | 9 ------ .../teavm/javascript/ast/RenamingVisitor.java | 6 ++-- .../teavm/javascript/ast/SaveStatement.java | 27 +++++++++++++++++ .../javascript/ast/StatementVisitor.java | 2 ++ .../model/util/AsyncProgramSplitter.java | 4 +-- .../java/org/teavm/platform/Platform.java | 2 +- 21 files changed, 117 insertions(+), 46 deletions(-) create mode 100644 teavm-core/src/main/java/org/teavm/javascript/ast/SaveStatement.java diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java index 3fb6b2e9a..376c007ea 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java @@ -127,7 +127,7 @@ public class TObject { o.monitor.enteringThreads.remove().run(); } } - }); + }, false); } else { o.isEmptyMonitor(); } @@ -203,7 +203,7 @@ public class TObject { while (!listeners.isEmpty()) { NotifyListener listener = listeners.remove(); if (!listener.expired()) { - Platform.startThread(listener); + Platform.startThread(listener, false); break; } } @@ -219,7 +219,7 @@ public class TObject { while (!listeners.isEmpty()) { NotifyListener listener = listeners.remove(); if (!listener.expired()) { - Platform.startThread(listener); + Platform.startThread(listener, false); } } } @@ -279,7 +279,7 @@ public class TObject { @Override public void onTimer() { if (!expired()) { - Platform.startThread(this); + Platform.startThread(this, false); } } diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java index a635bc045..416a5be0d 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java @@ -71,7 +71,7 @@ public class TThread extends TObject implements TRunnable { setCurrentThread(mainThread); } } - }); + }, true); } static void setCurrentThread(TThread thread) { @@ -116,7 +116,7 @@ public class TThread extends TObject implements TRunnable { setCurrentThread(thread); callback.complete(null); } - }); + }, false); } private static void yieldImpl() { diff --git a/teavm-core/src/main/java/org/teavm/cache/AstIO.java b/teavm-core/src/main/java/org/teavm/cache/AstIO.java index b1ead2777..78264c5ba 100644 --- a/teavm-core/src/main/java/org/teavm/cache/AstIO.java +++ b/teavm-core/src/main/java/org/teavm/cache/AstIO.java @@ -315,10 +315,18 @@ public class AstIO { } @Override - public void visit(MonitorEnterStatement statement) { + public void visit(SaveStatement statement) { try { output.writeByte(18); - output.writeShort(statement.getAsyncTarget() != null ? 0 : statement.getAsyncTarget()); + } catch (IOException e) { + throw new IOExceptionWrapper(e); + } + } + + @Override + public void visit(MonitorEnterStatement statement) { + try { + output.writeByte(19); writeExpr(statement.getObjectRef()); } catch (IOException e) { throw new IOExceptionWrapper(e); @@ -328,7 +336,7 @@ public class AstIO { @Override public void visit(MonitorExitStatement statement) { try { - output.writeByte(19); + output.writeByte(20); writeExpr(statement.getObjectRef()); } catch (IOException e) { throw new IOExceptionWrapper(e); diff --git a/teavm-core/src/main/java/org/teavm/cache/DiskRegularMethodNodeCache.java b/teavm-core/src/main/java/org/teavm/cache/DiskRegularMethodNodeCache.java index bb6d058e0..a08e16bfd 100644 --- a/teavm-core/src/main/java/org/teavm/cache/DiskRegularMethodNodeCache.java +++ b/teavm-core/src/main/java/org/teavm/cache/DiskRegularMethodNodeCache.java @@ -262,6 +262,10 @@ public class DiskRegularMethodNodeCache implements RegularMethodNodeCache { public void visit(GotoPartStatement statement) { } + @Override + public void visit(SaveStatement statement) { + } + @Override public void visit(MonitorEnterStatement statement) { diff --git a/teavm-core/src/main/java/org/teavm/javascript/BreakToContinueReplacer.java b/teavm-core/src/main/java/org/teavm/javascript/BreakToContinueReplacer.java index f80c3f981..6e17963fb 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/BreakToContinueReplacer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/BreakToContinueReplacer.java @@ -117,6 +117,10 @@ class BreakToContinueReplacer implements StatementVisitor { public void visit(GotoPartStatement statement) { } + @Override + public void visit(SaveStatement statement) { + } + @Override public void visit(MonitorEnterStatement statement) { } diff --git a/teavm-core/src/main/java/org/teavm/javascript/CertainBlockCountVisitor.java b/teavm-core/src/main/java/org/teavm/javascript/CertainBlockCountVisitor.java index 11702da38..7892d98b4 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/CertainBlockCountVisitor.java +++ b/teavm-core/src/main/java/org/teavm/javascript/CertainBlockCountVisitor.java @@ -112,6 +112,10 @@ class CertainBlockCountVisitor implements StatementVisitor { public void visit(GotoPartStatement statement) { } + @Override + public void visit(SaveStatement statement) { + } + @Override public void visit(MonitorEnterStatement statement) { } 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 88c3745fb..40ad05685 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java @@ -22,6 +22,7 @@ import org.teavm.javascript.spi.GeneratedBy; import org.teavm.javascript.spi.Generator; import org.teavm.javascript.spi.InjectedBy; import org.teavm.model.*; +import org.teavm.model.instructions.InvokeInstruction; import org.teavm.model.util.AsyncProgramSplitter; import org.teavm.model.util.ProgramUtils; @@ -294,7 +295,6 @@ public class Decompiler { int tmp = indexer.nodeAt(next); generator.nextBlock = tmp >= 0 && next < indexer.size() ? program.basicBlockAt(tmp) : null; generator.statements.clear(); - generator.asyncTarget = null; InstructionLocation lastLocation = null; NodeLocation nodeLocation = null; List instructions = generator.currentBlock.getInstructions(); @@ -307,11 +307,17 @@ public class Decompiler { if (insn.getLocation() != null) { generator.setCurrentLocation(nodeLocation); } - if (targetBlocks[node] >= 0 && j == instructions.size() - 1) { - generator.asyncTarget = targetBlocks[node]; - } insn.acceptVisitor(generator); + if (j == 0 && insn instanceof InvokeInstruction) { + generator.statements.add(new SaveStatement()); + } } + if (targetBlocks[node] >= 0) { + GotoPartStatement stmt = new GotoPartStatement(); + stmt.setPart(targetBlocks[node]); + generator.statements.add(stmt); + } + for (TryCatchBlock tryCatch : generator.currentBlock.getTryCatchBlocks()) { TryCatchStatement tryCatchStmt = new TryCatchStatement(); tryCatchStmt.setExceptionType(tryCatch.getExceptionType()); diff --git a/teavm-core/src/main/java/org/teavm/javascript/NameFrequencyEstimator.java b/teavm-core/src/main/java/org/teavm/javascript/NameFrequencyEstimator.java index fdfade618..20773208e 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/NameFrequencyEstimator.java +++ b/teavm-core/src/main/java/org/teavm/javascript/NameFrequencyEstimator.java @@ -191,6 +191,10 @@ public class NameFrequencyEstimator implements StatementVisitor, ExprVisitor, Me public void visit(GotoPartStatement statement) { } + @Override + public void visit(SaveStatement statement) { + } + @Override public void visit(MonitorEnterStatement statement) { if (async) { diff --git a/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java b/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java index f155919c4..eb9369618 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java +++ b/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java @@ -619,6 +619,11 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor { resultStmt = statement; } + @Override + public void visit(SaveStatement statement) { + resultStmt = statement; + } + @Override public void visit(MonitorEnterStatement statement) { statement.getObjectRef().acceptVisitor(this); diff --git a/teavm-core/src/main/java/org/teavm/javascript/RedundantLabelEliminator.java b/teavm-core/src/main/java/org/teavm/javascript/RedundantLabelEliminator.java index c0d240ebd..25c8bd389 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/RedundantLabelEliminator.java +++ b/teavm-core/src/main/java/org/teavm/javascript/RedundantLabelEliminator.java @@ -122,6 +122,10 @@ class RedundantLabelEliminator implements StatementVisitor { public void visit(GotoPartStatement statement) { } + @Override + public void visit(SaveStatement statement) { + } + @Override public void visit(MonitorEnterStatement statement) { } diff --git a/teavm-core/src/main/java/org/teavm/javascript/ReferenceCountingVisitor.java b/teavm-core/src/main/java/org/teavm/javascript/ReferenceCountingVisitor.java index 031ca7d2a..d9714e86b 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ReferenceCountingVisitor.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ReferenceCountingVisitor.java @@ -116,6 +116,10 @@ class ReferenceCountingVisitor implements StatementVisitor { public void visit(GotoPartStatement statement) { } + @Override + public void visit(SaveStatement statement) { + } + @Override public void visit(MonitorEnterStatement statement) { } 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 78abe9d5a..f5faaeeb3 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java @@ -716,6 +716,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext writer.softNewLine(); writer.outdent().append("}").softNewLine(); + writer.append("while").ws().append("(true)").ws().append("{").indent().softNewLine(); writer.append("$main: switch").ws().append("($ptr)").ws().append('{').softNewLine(); for (int i = 0; i < methodNode.getBody().size(); ++i) { writer.append("case ").append(i).append(":").indent().softNewLine(); @@ -724,6 +725,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext writer.outdent(); } writer.append("}").softNewLine(); + writer.outdent().append("}").softNewLine(); } catch (IOException e) { throw new RenderingException("IO error occured", e); } @@ -1956,23 +1958,26 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext } } - @Override public void visit(GotoPartStatement statement) { try { - gotoPart(statement.getPart()); + writer.append("$ptr").ws().append("=").ws().append(statement.getPart()).append(";") + .softNewLine(); + writer.append("break $main;").softNewLine(); } catch (IOException ex){ throw new RenderingException("IO error occured", ex); } } - private void gotoPart(int part) throws IOException { - writer.append("$ptr").ws().append("=").ws().append(part).append(";") - .softNewLine(); - writer.append("if").ws().append("($rt_suspending())").ws().append("{").indent().softNewLine(); - writer.append("return $save();").softNewLine(); - writer.outdent().append("}").softNewLine(); - writer.append("break $main;").softNewLine(); + @Override + public void visit(SaveStatement statement) { + try { + writer.append("if").ws().append("($rt_suspending())").ws().append("{").indent().softNewLine(); + writer.append("return $save();").softNewLine(); + writer.outdent().append("}").softNewLine(); + } catch (IOException ex){ + throw new RenderingException("IO error occured", ex); + } } @Override @@ -1984,9 +1989,9 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext writer.appendMethodBody(monitorEnterRef).append("("); statement.getObjectRef().acceptVisitor(this); writer.append(");").softNewLine(); - if (statement.getAsyncTarget() != null) { - gotoPart(statement.getAsyncTarget()); - } + writer.append("if").ws().append("($rt_suspending())").ws().append("{").indent().softNewLine(); + writer.append("return $save();").softNewLine(); + writer.outdent().append("}").softNewLine(); } else { MethodReference monitorEnterRef = new MethodReference( Object.class, "monitorEnterSync", Object.class, void.class); diff --git a/teavm-core/src/main/java/org/teavm/javascript/StatementGenerator.java b/teavm-core/src/main/java/org/teavm/javascript/StatementGenerator.java index 604bb2f3c..4b9665225 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/StatementGenerator.java +++ b/teavm-core/src/main/java/org/teavm/javascript/StatementGenerator.java @@ -37,7 +37,6 @@ class StatementGenerator implements InstructionVisitor { Program program; ClassHolderSource classSource; private NodeLocation currentLocation; - Integer asyncTarget; public void setCurrentLocation(NodeLocation currentLocation) { this.currentLocation = currentLocation; @@ -557,11 +556,6 @@ class StatementGenerator implements InstructionVisitor { stmt.setLocation(currentLocation); statements.add(stmt); } - if (asyncTarget != null) { - GotoPartStatement gotoStmt = new GotoPartStatement(); - gotoStmt.setPart(asyncTarget); - statements.add(gotoStmt); - } } @Override @@ -662,7 +656,6 @@ class StatementGenerator implements InstructionVisitor { MonitorEnterStatement stmt = new MonitorEnterStatement(); stmt.setLocation(currentLocation); stmt.setObjectRef(Expr.var(insn.getObjectRef().getIndex())); - stmt.setAsyncTarget(asyncTarget); statements.add(stmt); } diff --git a/teavm-core/src/main/java/org/teavm/javascript/TryCatchFinder.java b/teavm-core/src/main/java/org/teavm/javascript/TryCatchFinder.java index 6bc07c4f0..3f65ad2b8 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/TryCatchFinder.java +++ b/teavm-core/src/main/java/org/teavm/javascript/TryCatchFinder.java @@ -115,6 +115,10 @@ class TryCatchFinder implements StatementVisitor { public void visit(GotoPartStatement statement) { } + @Override + public void visit(SaveStatement statement) { + } + @Override public void visit(MonitorEnterStatement statement) { } diff --git a/teavm-core/src/main/java/org/teavm/javascript/UnusedVariableEliminator.java b/teavm-core/src/main/java/org/teavm/javascript/UnusedVariableEliminator.java index 82c00b82a..b828f31b5 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/UnusedVariableEliminator.java +++ b/teavm-core/src/main/java/org/teavm/javascript/UnusedVariableEliminator.java @@ -229,6 +229,10 @@ class UnusedVariableEliminator implements ExprVisitor, StatementVisitor { public void visit(GotoPartStatement statement) { } + @Override + public void visit(SaveStatement statement) { + } + @Override public void visit(MonitorEnterStatement statement) { statement.getObjectRef().acceptVisitor(this); diff --git a/teavm-core/src/main/java/org/teavm/javascript/ast/MonitorEnterStatement.java b/teavm-core/src/main/java/org/teavm/javascript/ast/MonitorEnterStatement.java index 476d7820a..a7479337f 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ast/MonitorEnterStatement.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ast/MonitorEnterStatement.java @@ -22,7 +22,6 @@ package org.teavm.javascript.ast; public class MonitorEnterStatement extends Statement { private NodeLocation location; private Expr objectRef; - private Integer asyncTarget; @Override public void acceptVisitor(StatementVisitor visitor) { @@ -44,12 +43,4 @@ public class MonitorEnterStatement extends Statement { public void setObjectRef(Expr objectRef) { this.objectRef = objectRef; } - - public Integer getAsyncTarget() { - return asyncTarget; - } - - public void setAsyncTarget(Integer asyncTarget) { - this.asyncTarget = asyncTarget; - } } diff --git a/teavm-core/src/main/java/org/teavm/javascript/ast/RenamingVisitor.java b/teavm-core/src/main/java/org/teavm/javascript/ast/RenamingVisitor.java index 1bb1cfccd..db5e26719 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ast/RenamingVisitor.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ast/RenamingVisitor.java @@ -197,12 +197,14 @@ public class RenamingVisitor implements StatementVisitor, ExprVisitor { } @Override - public void visit(MonitorEnterStatement statement) { + public void visit(SaveStatement statement) { + } + @Override + public void visit(MonitorEnterStatement statement) { } @Override public void visit(MonitorExitStatement statement) { - } } diff --git a/teavm-core/src/main/java/org/teavm/javascript/ast/SaveStatement.java b/teavm-core/src/main/java/org/teavm/javascript/ast/SaveStatement.java new file mode 100644 index 000000000..8e8c955b1 --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/javascript/ast/SaveStatement.java @@ -0,0 +1,27 @@ +/* + * Copyright 2015 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.javascript.ast; + +/** + * + * @author Alexey Andreev + */ +public class SaveStatement extends Statement { + @Override + public void acceptVisitor(StatementVisitor visitor) { + visitor.visit(this); + } +} diff --git a/teavm-core/src/main/java/org/teavm/javascript/ast/StatementVisitor.java b/teavm-core/src/main/java/org/teavm/javascript/ast/StatementVisitor.java index 7194cdb4e..7c4f6cf9b 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ast/StatementVisitor.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ast/StatementVisitor.java @@ -49,4 +49,6 @@ public interface StatementVisitor { void visit(MonitorEnterStatement statement); void visit(MonitorExitStatement statement); + + void visit(SaveStatement statement); } diff --git a/teavm-core/src/main/java/org/teavm/model/util/AsyncProgramSplitter.java b/teavm-core/src/main/java/org/teavm/model/util/AsyncProgramSplitter.java index 81d174be4..e3b3ccde0 100644 --- a/teavm-core/src/main/java/org/teavm/model/util/AsyncProgramSplitter.java +++ b/teavm-core/src/main/java/org/teavm/model/util/AsyncProgramSplitter.java @@ -74,7 +74,7 @@ public class AsyncProgramSplitter { // If we met asynchronous invocation... // Copy portion of current block from last occurrence (or from start) to i'th instruction. targetBlock.getInstructions().addAll(ProgramUtils.copyInstructions(sourceBlock, - last, i + 1, targetBlock.getProgram())); + last, i, targetBlock.getProgram())); targetBlock.getTryCatchBlocks().addAll(ProgramUtils.copyTryCatches(sourceBlock, targetBlock.getProgram())); for (TryCatchBlock tryCatch : targetBlock.getTryCatchBlocks()) { @@ -85,7 +85,7 @@ public class AsyncProgramSplitter { queue.add(next); } } - last = i + 1; + last = i; // If this instruction already separates program, end with current block and refer to the // existing part diff --git a/teavm-platform/src/main/java/org/teavm/platform/Platform.java b/teavm-platform/src/main/java/org/teavm/platform/Platform.java index cbf6fe506..749b9d0b5 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/Platform.java +++ b/teavm-platform/src/main/java/org/teavm/platform/Platform.java @@ -107,7 +107,7 @@ public final class Platform { @GeneratedBy(PlatformGenerator.class) @PluggableDependency(PlatformGenerator.class) - public static native void startThread(PlatformRunnable runnable); + public static native void startThread(PlatformRunnable runnable, boolean newNativeThread); private static void launchThread(PlatformRunnable runnable) { runnable.run(); From 5c189cfe154e0bb75e70b748576b555692aa6348 Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Tue, 10 Mar 2015 20:39:28 +0300 Subject: [PATCH 38/69] Fix bug in InputStream.read implementation --- .../src/main/java/org/teavm/classlib/java/io/TInputStream.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TInputStream.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TInputStream.java index 8e0255e65..b920d370f 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TInputStream.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TInputStream.java @@ -36,7 +36,7 @@ public abstract class TInputStream extends TObject implements TCloseable { for (int i = 0; i < len; ++i) { int bt = read(); if (bt < 0) { - return i; + return i == 0 ? -1 : i; } b[off++] = (byte)bt; } From 8fe3876641af13ee6c24d0009c8b32aba8fff907 Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Tue, 10 Mar 2015 22:09:43 +0300 Subject: [PATCH 39/69] First working prototype of new async --- .../org/teavm/classlib/java/lang/TObject.java | 17 ++++++++++++----- .../org/teavm/classlib/java/lang/TThread.java | 18 +++++++----------- .../java/org/teavm/javascript/Decompiler.java | 11 +++++++---- .../java/org/teavm/javascript/Renderer.java | 3 ++- .../resources/org/teavm/javascript/runtime.js | 12 +++++++----- .../main/java/org/teavm/platform/Platform.java | 6 +++++- .../platform/plugin/AsyncMethodGenerator.java | 1 + .../platform/plugin/PlatformGenerator.java | 6 +++++- 8 files changed, 46 insertions(+), 28 deletions(-) diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java index 376c007ea..827b0267d 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java @@ -91,6 +91,13 @@ public class TObject { static void monitorEnterWait(final TObject o, final int count, final AsyncCallback callback) { final TThread thread = TThread.currentThread(); + if (o.monitor == null) { + o.monitor = new Monitor(); + TThread.setCurrentThread(thread); + o.monitor.count += count; + callback.complete(null); + return; + } o.monitor.enteringThreads.add(new PlatformRunnable() { @Override public void run() { TThread.setCurrentThread(thread); @@ -118,7 +125,7 @@ public class TObject { o.monitor.owner = null; if (!o.monitor.enteringThreads.isEmpty()) { - Platform.startThread(new PlatformRunnable() { + Platform.postpone(new PlatformRunnable() { @Override public void run() { if (o.isEmptyMonitor() || o.monitor.owner != null) { return; @@ -127,7 +134,7 @@ public class TObject { o.monitor.enteringThreads.remove().run(); } } - }, false); + }); } else { o.isEmptyMonitor(); } @@ -203,7 +210,7 @@ public class TObject { while (!listeners.isEmpty()) { NotifyListener listener = listeners.remove(); if (!listener.expired()) { - Platform.startThread(listener, false); + Platform.postpone(listener); break; } } @@ -219,7 +226,7 @@ public class TObject { while (!listeners.isEmpty()) { NotifyListener listener = listeners.remove(); if (!listener.expired()) { - Platform.startThread(listener, false); + Platform.postpone(listener); } } } @@ -279,7 +286,7 @@ public class TObject { @Override public void onTimer() { if (!expired()) { - Platform.startThread(this, false); + Platform.postpone(this); } } diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java index 416a5be0d..855382fa4 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java @@ -71,14 +71,14 @@ public class TThread extends TObject implements TRunnable { setCurrentThread(mainThread); } } - }, true); + }); } static void setCurrentThread(TThread thread) { if (currentThread != thread) { currentThread = thread; - currentThread.timeSliceStart = System.currentTimeMillis(); } + currentThread.timeSliceStart = System.currentTimeMillis(); } static TThread getMainThread(){ @@ -102,24 +102,20 @@ public class TThread extends TObject implements TRunnable { public static void yield() { if (currentThread.timeSliceStart + 100 < System.currentTimeMillis()) { - switchContext(); + switchContext(currentThread); } } @Async - static native void switchContext(); + static native void switchContext(TThread thread); - private static void switchContext(final AsyncCallback callback) { - final TThread thread = currentThread(); - Platform.startThread(new PlatformRunnable() { + private static void switchContext(final TThread thread, final AsyncCallback callback) { + Platform.postpone(new PlatformRunnable() { @Override public void run() { setCurrentThread(thread); callback.complete(null); } - }, false); - } - - private static void yieldImpl() { + }); } public void interrupt() { 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 40ad05685..7e09ab256 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java @@ -204,7 +204,8 @@ public class Decompiler { AsyncProgramSplitter splitter = new AsyncProgramSplitter(classSource, splitMethods); splitter.split(method.getProgram()); for (int i = 0; i < splitter.size(); ++i) { - AsyncMethodPart part = getRegularMethodStatement(splitter.getProgram(i), splitter.getBlockSuccessors(i)); + AsyncMethodPart part = getRegularMethodStatement(splitter.getProgram(i), splitter.getBlockSuccessors(i), + i > 0); node.getBody().add(part); } Program program = method.getProgram(); @@ -227,7 +228,7 @@ public class Decompiler { Program program = method.getProgram(); int[] targetBlocks = new int[program.basicBlockCount()]; Arrays.fill(targetBlocks, -1); - methodNode.setBody(getRegularMethodStatement(program, targetBlocks).getStatement()); + methodNode.setBody(getRegularMethodStatement(program, targetBlocks, false).getStatement()); for (int i = 0; i < program.variableCount(); ++i) { methodNode.getVariables().add(program.variableAt(i).getRegister()); } @@ -242,7 +243,7 @@ public class Decompiler { return methodNode; } - private AsyncMethodPart getRegularMethodStatement(Program program, int[] targetBlocks) { + private AsyncMethodPart getRegularMethodStatement(Program program, int[] targetBlocks, boolean async) { AsyncMethodPart result = new AsyncMethodPart(); lastBlockId = 1; graph = ProgramUtils.buildControlFlowGraph(program); @@ -290,6 +291,7 @@ public class Decompiler { if (head != -1 && loopSuccessors[head] == next) { next = head; } + boolean saved = !async; if (node >= 0) { generator.currentBlock = program.basicBlockAt(node); int tmp = indexer.nodeAt(next); @@ -308,8 +310,9 @@ public class Decompiler { generator.setCurrentLocation(nodeLocation); } insn.acceptVisitor(generator); - if (j == 0 && insn instanceof InvokeInstruction) { + if (insn instanceof InvokeInstruction && !saved) { generator.statements.add(new SaveStatement()); + saved = true; } } if (targetBlocks[node] >= 0) { 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 f5faaeeb3..1f3acc218 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java @@ -711,7 +711,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext writer.append("var $T").ws().append('=').ws().append("$rt_nativeThread();").softNewLine(); writer.append("$ptr").ws().append('=').ws().append("$T.pop();"); for (int i = variableCount - 1; i > ref.parameterCount(); --i) { - writer.append(variableName(i)).ws().append('=').ws().append("T.pop();"); + writer.append(variableName(i)).ws().append('=').ws().append("$T.pop();"); } writer.softNewLine(); writer.outdent().append("}").softNewLine(); @@ -724,6 +724,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext part.getStatement().acceptVisitor(Renderer.this); writer.outdent(); } + writer.append("default:").ws().append("throw new Error('Invalid recorded state');").softNewLine(); writer.append("}").softNewLine(); writer.outdent().append("}").softNewLine(); } catch (IOException e) { diff --git a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js index f004f7b26..d6063734c 100644 --- a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js +++ b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js @@ -444,17 +444,17 @@ function TeaVMThread(runner) { this.attribute = null; } TeaVMThread.prototype.push = function(value) { - this.stack.push[value]; + this.stack.push(value); return this; } TeaVMThread.prototype.pop = function() { return this.stack.pop(); } TeaVMThread.prototype.isResuming = function() { - return this.status == 1; + return this.status == 2; } TeaVMThread.prototype.isSuspending = function() { - return this.status == 2; + return this.status == 1; } TeaVMThread.prototype.suspend = function(callback) { this.suspendCallback = callback; @@ -489,10 +489,12 @@ TeaVMThread.prototype.run = function() { } } function $rt_suspending() { - return $rt_nativeThread().isSuspending(); + var thread = $rt_nativeThread(); + return thread != null && thread.isSuspending(); } function $rt_resuming() { - return $rt_nativeThread().isResuming(); + var thread = $rt_nativeThread(); + return thread != null && thread.isResuming(); } function $rt_suspend(callback) { return $rt_nativeThread().suspend(callback); diff --git a/teavm-platform/src/main/java/org/teavm/platform/Platform.java b/teavm-platform/src/main/java/org/teavm/platform/Platform.java index 749b9d0b5..9b8739652 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/Platform.java +++ b/teavm-platform/src/main/java/org/teavm/platform/Platform.java @@ -107,12 +107,16 @@ public final class Platform { @GeneratedBy(PlatformGenerator.class) @PluggableDependency(PlatformGenerator.class) - public static native void startThread(PlatformRunnable runnable, boolean newNativeThread); + public static native void startThread(PlatformRunnable runnable); private static void launchThread(PlatformRunnable runnable) { runnable.run(); } + public static void postpone(PlatformRunnable runnable) { + schedule(runnable, 0); + } + @GeneratedBy(PlatformGenerator.class) @PluggableDependency(PlatformGenerator.class) public static native int schedule(PlatformRunnable runnable, int timeout); diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/AsyncMethodGenerator.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/AsyncMethodGenerator.java index fb2c30487..f3a417540 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/plugin/AsyncMethodGenerator.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/AsyncMethodGenerator.java @@ -40,6 +40,7 @@ public class AsyncMethodGenerator implements Generator, DependencyPlugin { MethodReference asyncRef = getAsyncReference(methodRef); writer.append("var thread").ws().append('=').ws().append("$rt_nativeThread();").softNewLine(); writer.append("if").ws().append("(thread.isResuming())").ws().append("{").indent().softNewLine(); + writer.append("thread.status").ws().append("=").ws().append("0;").softNewLine(); writer.append("var result").ws().append("=").ws().append("thread.attribute;").softNewLine(); writer.append("if").ws().append("(result instanceof Error)").ws().append("{").indent().softNewLine(); writer.append("throw result;").softNewLine(); diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java index bc05a14f2..92c0435d5 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java @@ -153,7 +153,11 @@ public class PlatformGenerator implements Generator, Injector, DependencyPlugin PlatformRunnable.class, void.class); String runnable = context.getParameterName(1); writer.append("return window.setTimeout(function()").ws().append("{").indent().softNewLine(); - writer.append("$rt_threadStarter(").appendMethodBody(launchRef).append(")"); + if (timeout) { + writer.appendMethodBody(launchRef); + } else { + writer.append("$rt_threadStarter(").appendMethodBody(launchRef).append(")"); + } writer.append("(").append(runnable).append(");").softNewLine(); writer.outdent().append("},").ws().append(timeout ? context.getParameterName(2) : "0") .append(");").softNewLine(); From 04342d15e7d2108b0d38fd435e9fdcaabb1b6ec4 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Wed, 11 Mar 2015 11:09:57 +0400 Subject: [PATCH 40/69] Fix minor issue --- teavm-core/src/main/java/org/teavm/javascript/Decompiler.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 7e09ab256..4ffb6b11b 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java @@ -23,6 +23,7 @@ import org.teavm.javascript.spi.Generator; import org.teavm.javascript.spi.InjectedBy; import org.teavm.model.*; import org.teavm.model.instructions.InvokeInstruction; +import org.teavm.model.instructions.MonitorEnterInstruction; import org.teavm.model.util.AsyncProgramSplitter; import org.teavm.model.util.ProgramUtils; @@ -310,7 +311,7 @@ public class Decompiler { generator.setCurrentLocation(nodeLocation); } insn.acceptVisitor(generator); - if (insn instanceof InvokeInstruction && !saved) { + if (!saved && (insn instanceof InvokeInstruction || insn instanceof MonitorEnterInstruction)) { generator.statements.add(new SaveStatement()); saved = true; } From 7a109a6f484f01e4cb59d4c89d10e65ed51bcbf3 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Wed, 11 Mar 2015 11:32:49 +0400 Subject: [PATCH 41/69] See https://github.com/konsoletyper/teavm/issues/85 --- teavm-core/src/main/java/org/teavm/javascript/Decompiler.java | 2 +- teavm-core/src/main/java/org/teavm/javascript/Optimizer.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) 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 33d3c3311..59845bef8 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java @@ -219,7 +219,7 @@ public class Decompiler { node.getVariables().add(program.variableAt(i).getRegister()); } Optimizer optimizer = new Optimizer(); - optimizer.optimize(node, program, splitter); + optimizer.optimize(node, splitter); node.getModifiers().addAll(mapModifiers(method.getModifiers())); int paramCount = Math.min(method.getSignature().length, program.variableCount()); for (int i = 0; i < paramCount; ++i) { diff --git a/teavm-core/src/main/java/org/teavm/javascript/Optimizer.java b/teavm-core/src/main/java/org/teavm/javascript/Optimizer.java index f69803a48..8b33e82a7 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Optimizer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Optimizer.java @@ -43,10 +43,10 @@ public class Optimizer { } } - public void optimize(AsyncMethodNode method, Program program, AsyncProgramSplitter splitter) { + public void optimize(AsyncMethodNode method, AsyncProgramSplitter splitter) { ReadWriteStatsBuilder stats = new ReadWriteStatsBuilder(method.getVariables().size()); - stats.analyze(program); for (int i = 0; i < splitter.size(); ++i) { + stats.analyze(splitter.getProgram(i)); Integer var = splitter.getInput(i); if (var != null) { stats.reads[var]++; From 7e23498c5b2ad444c0d35e933e5260646229ed77 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Wed, 11 Mar 2015 19:02:32 +0400 Subject: [PATCH 42/69] Fix bugs --- .../java/org/teavm/classlib/java/lang/TObject.java | 2 +- .../java/org/teavm/classlib/java/lang/TThread.java | 12 +++++++++--- .../main/java/org/teavm/javascript/Decompiler.java | 2 +- .../src/main/java/org/teavm/javascript/Renderer.java | 11 ++++++----- .../main/resources/org/teavm/javascript/runtime.js | 11 ++++++++--- 5 files changed, 25 insertions(+), 13 deletions(-) diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java index 827b0267d..6229e2073 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java @@ -286,7 +286,7 @@ public class TObject { @Override public void onTimer() { if (!expired()) { - Platform.postpone(this); + run(); } } diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java index 855382fa4..52e53ba0d 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java @@ -36,6 +36,7 @@ public class TThread extends TObject implements TRunnable { private long id; private int priority = 0; private long timeSliceStart; + private int yieldCount; private TString name; TRunnable target; @@ -101,6 +102,10 @@ public class TThread extends TObject implements TRunnable { } public static void yield() { + if (++currentThread.yieldCount < 30) { + return; + } + currentThread.yieldCount = 0; if (currentThread.timeSliceStart + 100 < System.currentTimeMillis()) { switchContext(currentThread); } @@ -146,12 +151,13 @@ public class TThread extends TObject implements TRunnable { private static void sleep(long millis, final AsyncCallback callback) { final TThread current = currentThread(); - window.setTimeout(new TimerHandler() { - @Override public void onTimer() { + int intMillis = millis < Integer.MAX_VALUE ? (int)millis : Integer.MAX_VALUE; + Platform.schedule(new PlatformRunnable() { + @Override public void run() { setCurrentThread(current); callback.complete(null); } - }, millis); + }, intMillis); } public final void setPriority(int newPriority){ 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 4ffb6b11b..0e133d9d0 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java @@ -264,6 +264,7 @@ public class Decompiler { generator.indexer = indexer; parentNode = codeTree.getRoot(); currentNode = parentNode.getFirstChild(); + boolean saved = !async; for (int i = 0; i < this.graph.size(); ++i) { Block block = stack.peek(); while (block.end == i) { @@ -292,7 +293,6 @@ public class Decompiler { if (head != -1 && loopSuccessors[head] == next) { next = head; } - boolean saved = !async; if (node >= 0) { generator.currentBlock = program.basicBlockAt(node); int tmp = indexer.nodeAt(next); 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 1f3acc218..402649453 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java @@ -699,7 +699,11 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext writer.append("function $save()").ws().append("{").indent().softNewLine(); writer.append("$rt_nativeThread()"); - for (int i = ref.parameterCount() + 1; i < variableCount; ++i) { + int firstToSave = 0; + if (methodNode.getModifiers().contains(NodeModifier.STATIC)) { + firstToSave = 1; + } + for (int i = firstToSave; i < variableCount; ++i) { writer.append(".push(").append(variableName(i)).append(")"); } writer.append(".push($ptr);"); @@ -710,7 +714,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext writer.append("if").ws().append("($rt_resuming())").ws().append("{").indent().softNewLine(); writer.append("var $T").ws().append('=').ws().append("$rt_nativeThread();").softNewLine(); writer.append("$ptr").ws().append('=').ws().append("$T.pop();"); - for (int i = variableCount - 1; i > ref.parameterCount(); --i) { + for (int i = variableCount - 1; i >= firstToSave; --i) { writer.append(variableName(i)).ws().append('=').ws().append("$T.pop();"); } writer.softNewLine(); @@ -1990,9 +1994,6 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext writer.appendMethodBody(monitorEnterRef).append("("); statement.getObjectRef().acceptVisitor(this); writer.append(");").softNewLine(); - writer.append("if").ws().append("($rt_suspending())").ws().append("{").indent().softNewLine(); - writer.append("return $save();").softNewLine(); - writer.outdent().append("}").softNewLine(); } else { MethodReference monitorEnterRef = new MethodReference( Object.class, "monitorEnterSync", Object.class, void.class); diff --git a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js index d6063734c..c27ddba15 100644 --- a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js +++ b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js @@ -479,11 +479,16 @@ TeaVMThread.prototype.resume = function() { } TeaVMThread.prototype.run = function() { $rt_currentNativeThread = this; - this.runner(); - $rt_currentNativeThread = null; + try { + this.runner(); + } finally { + $rt_currentNativeThread = null; + } if (this.suspendCallback !== null) { var self = this; - this.suspendCallback(function() { + var callback = this.suspendCallback; + this.suspendCallback = null; + callback(function() { self.resume(); }); } From b19c5453182309de306a1e15f00018e5356e0e88 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Wed, 11 Mar 2015 19:49:31 +0400 Subject: [PATCH 43/69] Fix issue --- .../org/teavm/classlib/java/lang/TThread.java | 2 - .../src/main/java/org/teavm/cache/AstIO.java | 13 +------ .../cache/DiskRegularMethodNodeCache.java | 4 -- .../javascript/BreakToContinueReplacer.java | 4 -- .../javascript/CertainBlockCountVisitor.java | 4 -- .../java/org/teavm/javascript/Decompiler.java | 8 +--- .../javascript/NameFrequencyEstimator.java | 4 -- .../teavm/javascript/OptimizingVisitor.java | 5 --- .../javascript/RedundantLabelEliminator.java | 4 -- .../javascript/ReferenceCountingVisitor.java | 4 -- .../java/org/teavm/javascript/Renderer.java | 38 ++++++++++++------- .../teavm/javascript/StatementGenerator.java | 14 +++++-- .../org/teavm/javascript/TryCatchFinder.java | 4 -- .../javascript/UnusedVariableEliminator.java | 4 -- .../javascript/ast/AssignmentStatement.java | 9 +++++ .../teavm/javascript/ast/RenamingVisitor.java | 4 -- .../teavm/javascript/ast/SaveStatement.java | 27 ------------- .../javascript/ast/StatementVisitor.java | 2 - .../platform/plugin/PlatformGenerator.java | 14 ++++--- 19 files changed, 54 insertions(+), 114 deletions(-) delete mode 100644 teavm-core/src/main/java/org/teavm/javascript/ast/SaveStatement.java diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java index 52e53ba0d..e45e65fa8 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java @@ -15,7 +15,6 @@ */ package org.teavm.classlib.java.lang; -import org.teavm.dom.browser.TimerHandler; import org.teavm.dom.browser.Window; import org.teavm.javascript.spi.Async; import org.teavm.jso.JS; @@ -167,5 +166,4 @@ public class TThread extends TObject implements TRunnable { public final int getPriority(){ return this.priority; } - } diff --git a/teavm-core/src/main/java/org/teavm/cache/AstIO.java b/teavm-core/src/main/java/org/teavm/cache/AstIO.java index 78264c5ba..ddb706233 100644 --- a/teavm-core/src/main/java/org/teavm/cache/AstIO.java +++ b/teavm-core/src/main/java/org/teavm/cache/AstIO.java @@ -314,19 +314,10 @@ public class AstIO { } } - @Override - public void visit(SaveStatement statement) { - try { - output.writeByte(18); - } catch (IOException e) { - throw new IOExceptionWrapper(e); - } - } - @Override public void visit(MonitorEnterStatement statement) { try { - output.writeByte(19); + output.writeByte(18); writeExpr(statement.getObjectRef()); } catch (IOException e) { throw new IOExceptionWrapper(e); @@ -336,7 +327,7 @@ public class AstIO { @Override public void visit(MonitorExitStatement statement) { try { - output.writeByte(20); + output.writeByte(19); writeExpr(statement.getObjectRef()); } catch (IOException e) { throw new IOExceptionWrapper(e); diff --git a/teavm-core/src/main/java/org/teavm/cache/DiskRegularMethodNodeCache.java b/teavm-core/src/main/java/org/teavm/cache/DiskRegularMethodNodeCache.java index a08e16bfd..bb6d058e0 100644 --- a/teavm-core/src/main/java/org/teavm/cache/DiskRegularMethodNodeCache.java +++ b/teavm-core/src/main/java/org/teavm/cache/DiskRegularMethodNodeCache.java @@ -262,10 +262,6 @@ public class DiskRegularMethodNodeCache implements RegularMethodNodeCache { public void visit(GotoPartStatement statement) { } - @Override - public void visit(SaveStatement statement) { - } - @Override public void visit(MonitorEnterStatement statement) { diff --git a/teavm-core/src/main/java/org/teavm/javascript/BreakToContinueReplacer.java b/teavm-core/src/main/java/org/teavm/javascript/BreakToContinueReplacer.java index 6e17963fb..f80c3f981 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/BreakToContinueReplacer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/BreakToContinueReplacer.java @@ -117,10 +117,6 @@ class BreakToContinueReplacer implements StatementVisitor { public void visit(GotoPartStatement statement) { } - @Override - public void visit(SaveStatement statement) { - } - @Override public void visit(MonitorEnterStatement statement) { } diff --git a/teavm-core/src/main/java/org/teavm/javascript/CertainBlockCountVisitor.java b/teavm-core/src/main/java/org/teavm/javascript/CertainBlockCountVisitor.java index 7892d98b4..11702da38 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/CertainBlockCountVisitor.java +++ b/teavm-core/src/main/java/org/teavm/javascript/CertainBlockCountVisitor.java @@ -112,10 +112,6 @@ class CertainBlockCountVisitor implements StatementVisitor { public void visit(GotoPartStatement statement) { } - @Override - public void visit(SaveStatement statement) { - } - @Override public void visit(MonitorEnterStatement statement) { } 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 0e133d9d0..6b4a24a19 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java @@ -22,8 +22,6 @@ import org.teavm.javascript.spi.GeneratedBy; import org.teavm.javascript.spi.Generator; import org.teavm.javascript.spi.InjectedBy; import org.teavm.model.*; -import org.teavm.model.instructions.InvokeInstruction; -import org.teavm.model.instructions.MonitorEnterInstruction; import org.teavm.model.util.AsyncProgramSplitter; import org.teavm.model.util.ProgramUtils; @@ -264,7 +262,7 @@ public class Decompiler { generator.indexer = indexer; parentNode = codeTree.getRoot(); currentNode = parentNode.getFirstChild(); - boolean saved = !async; + generator.async = async; for (int i = 0; i < this.graph.size(); ++i) { Block block = stack.peek(); while (block.end == i) { @@ -311,10 +309,6 @@ public class Decompiler { generator.setCurrentLocation(nodeLocation); } insn.acceptVisitor(generator); - if (!saved && (insn instanceof InvokeInstruction || insn instanceof MonitorEnterInstruction)) { - generator.statements.add(new SaveStatement()); - saved = true; - } } if (targetBlocks[node] >= 0) { GotoPartStatement stmt = new GotoPartStatement(); diff --git a/teavm-core/src/main/java/org/teavm/javascript/NameFrequencyEstimator.java b/teavm-core/src/main/java/org/teavm/javascript/NameFrequencyEstimator.java index 20773208e..fdfade618 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/NameFrequencyEstimator.java +++ b/teavm-core/src/main/java/org/teavm/javascript/NameFrequencyEstimator.java @@ -191,10 +191,6 @@ public class NameFrequencyEstimator implements StatementVisitor, ExprVisitor, Me public void visit(GotoPartStatement statement) { } - @Override - public void visit(SaveStatement statement) { - } - @Override public void visit(MonitorEnterStatement statement) { if (async) { diff --git a/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java b/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java index eb9369618..f155919c4 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java +++ b/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java @@ -619,11 +619,6 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor { resultStmt = statement; } - @Override - public void visit(SaveStatement statement) { - resultStmt = statement; - } - @Override public void visit(MonitorEnterStatement statement) { statement.getObjectRef().acceptVisitor(this); diff --git a/teavm-core/src/main/java/org/teavm/javascript/RedundantLabelEliminator.java b/teavm-core/src/main/java/org/teavm/javascript/RedundantLabelEliminator.java index 25c8bd389..c0d240ebd 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/RedundantLabelEliminator.java +++ b/teavm-core/src/main/java/org/teavm/javascript/RedundantLabelEliminator.java @@ -122,10 +122,6 @@ class RedundantLabelEliminator implements StatementVisitor { public void visit(GotoPartStatement statement) { } - @Override - public void visit(SaveStatement statement) { - } - @Override public void visit(MonitorEnterStatement statement) { } diff --git a/teavm-core/src/main/java/org/teavm/javascript/ReferenceCountingVisitor.java b/teavm-core/src/main/java/org/teavm/javascript/ReferenceCountingVisitor.java index d9714e86b..031ca7d2a 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ReferenceCountingVisitor.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ReferenceCountingVisitor.java @@ -116,10 +116,6 @@ class ReferenceCountingVisitor implements StatementVisitor { public void visit(GotoPartStatement statement) { } - @Override - public void visit(SaveStatement statement) { - } - @Override public void visit(MonitorEnterStatement statement) { } 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 402649453..b2d1d8d48 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java @@ -686,6 +686,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext variableNames.add("$je"); } variableNames.add("$ptr"); + variableNames.add("$tmp"); if (!variableNames.isEmpty()) { writer.append("var "); for (int i = 0; i < variableNames.size(); ++i) { @@ -817,9 +818,13 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext } prevCallSite = debugEmitter.emitCallSite(); if (statement.getLeftValue() != null) { - priority = Priority.COMMA; - associativity = Associativity.NONE; - statement.getLeftValue().acceptVisitor(this); + if (statement.isAsync()) { + writer.append("$tmp"); + } else { + priority = Priority.COMMA; + associativity = Associativity.NONE; + statement.getLeftValue().acceptVisitor(this); + } writer.ws().append("=").ws(); } priority = Priority.COMMA; @@ -827,6 +832,15 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext statement.getRightValue().acceptVisitor(this); debugEmitter.emitCallSite(); writer.append(";").softNewLine(); + if (statement.isAsync()) { + emitSuspendChecker(); + if (statement.getLeftValue() != null) { + priority = Priority.COMMA; + associativity = Associativity.NONE; + statement.getLeftValue().acceptVisitor(this); + writer.ws().append("=").ws().append("$tmp;").softNewLine(); + } + } if (statement.getLocation() != null) { popLocation(); } @@ -1974,17 +1988,6 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext } } - @Override - public void visit(SaveStatement statement) { - try { - writer.append("if").ws().append("($rt_suspending())").ws().append("{").indent().softNewLine(); - writer.append("return $save();").softNewLine(); - writer.outdent().append("}").softNewLine(); - } catch (IOException ex){ - throw new RenderingException("IO error occured", ex); - } - } - @Override public void visit(MonitorEnterStatement statement) { try { @@ -1994,6 +1997,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext writer.appendMethodBody(monitorEnterRef).append("("); statement.getObjectRef().acceptVisitor(this); writer.append(");").softNewLine(); + emitSuspendChecker(); } else { MethodReference monitorEnterRef = new MethodReference( Object.class, "monitorEnterSync", Object.class, void.class); @@ -2006,6 +2010,12 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext } } + private void emitSuspendChecker() throws IOException { + writer.append("if").ws().append("($rt_suspending())").ws().append("{").indent().softNewLine(); + writer.append("return $save();").softNewLine(); + writer.outdent().append("}").softNewLine(); + } + @Override public void visit(MonitorExitStatement statement) { try { diff --git a/teavm-core/src/main/java/org/teavm/javascript/StatementGenerator.java b/teavm-core/src/main/java/org/teavm/javascript/StatementGenerator.java index 4b9665225..1e098a853 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/StatementGenerator.java +++ b/teavm-core/src/main/java/org/teavm/javascript/StatementGenerator.java @@ -37,6 +37,7 @@ class StatementGenerator implements InstructionVisitor { Program program; ClassHolderSource classSource; private NodeLocation currentLocation; + boolean async; public void setCurrentLocation(NodeLocation currentLocation) { this.currentLocation = currentLocation; @@ -549,13 +550,17 @@ class StatementGenerator implements InstructionVisitor { } else { invocationExpr = Expr.invokeStatic(insn.getMethod(), exprArgs); } + AssignmentStatement stmt; if (insn.getReceiver() != null) { - assign(invocationExpr, insn.getReceiver()); + stmt = Statement.assign(Expr.var(insn.getReceiver().getIndex()), invocationExpr); + stmt.getDebugNames().addAll(insn.getReceiver().getDebugNames()); } else { - AssignmentStatement stmt = Statement.assign(null, invocationExpr); - stmt.setLocation(currentLocation); - statements.add(stmt); + stmt = Statement.assign(null, invocationExpr); } + stmt.setLocation(currentLocation); + stmt.setAsync(async); + async = false; + statements.add(stmt); } @Override @@ -656,6 +661,7 @@ class StatementGenerator implements InstructionVisitor { MonitorEnterStatement stmt = new MonitorEnterStatement(); stmt.setLocation(currentLocation); stmt.setObjectRef(Expr.var(insn.getObjectRef().getIndex())); + async = false; statements.add(stmt); } diff --git a/teavm-core/src/main/java/org/teavm/javascript/TryCatchFinder.java b/teavm-core/src/main/java/org/teavm/javascript/TryCatchFinder.java index 3f65ad2b8..6bc07c4f0 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/TryCatchFinder.java +++ b/teavm-core/src/main/java/org/teavm/javascript/TryCatchFinder.java @@ -115,10 +115,6 @@ class TryCatchFinder implements StatementVisitor { public void visit(GotoPartStatement statement) { } - @Override - public void visit(SaveStatement statement) { - } - @Override public void visit(MonitorEnterStatement statement) { } diff --git a/teavm-core/src/main/java/org/teavm/javascript/UnusedVariableEliminator.java b/teavm-core/src/main/java/org/teavm/javascript/UnusedVariableEliminator.java index b828f31b5..82c00b82a 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/UnusedVariableEliminator.java +++ b/teavm-core/src/main/java/org/teavm/javascript/UnusedVariableEliminator.java @@ -229,10 +229,6 @@ class UnusedVariableEliminator implements ExprVisitor, StatementVisitor { public void visit(GotoPartStatement statement) { } - @Override - public void visit(SaveStatement statement) { - } - @Override public void visit(MonitorEnterStatement statement) { statement.getObjectRef().acceptVisitor(this); diff --git a/teavm-core/src/main/java/org/teavm/javascript/ast/AssignmentStatement.java b/teavm-core/src/main/java/org/teavm/javascript/ast/AssignmentStatement.java index 8388d4a6c..adbf79fa6 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ast/AssignmentStatement.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ast/AssignmentStatement.java @@ -27,6 +27,7 @@ public class AssignmentStatement extends Statement { private Expr rightValue; private NodeLocation location; private Set debugNames = new HashSet<>(); + private boolean async; public Expr getLeftValue() { return leftValue; @@ -56,6 +57,14 @@ public class AssignmentStatement extends Statement { return debugNames; } + public boolean isAsync() { + return async; + } + + public void setAsync(boolean async) { + this.async = async; + } + @Override public void acceptVisitor(StatementVisitor visitor) { visitor.visit(this); diff --git a/teavm-core/src/main/java/org/teavm/javascript/ast/RenamingVisitor.java b/teavm-core/src/main/java/org/teavm/javascript/ast/RenamingVisitor.java index db5e26719..e2b14d069 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ast/RenamingVisitor.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ast/RenamingVisitor.java @@ -196,10 +196,6 @@ public class RenamingVisitor implements StatementVisitor, ExprVisitor { public void visit(GotoPartStatement statement) { } - @Override - public void visit(SaveStatement statement) { - } - @Override public void visit(MonitorEnterStatement statement) { } diff --git a/teavm-core/src/main/java/org/teavm/javascript/ast/SaveStatement.java b/teavm-core/src/main/java/org/teavm/javascript/ast/SaveStatement.java deleted file mode 100644 index 8e8c955b1..000000000 --- a/teavm-core/src/main/java/org/teavm/javascript/ast/SaveStatement.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2015 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.javascript.ast; - -/** - * - * @author Alexey Andreev - */ -public class SaveStatement extends Statement { - @Override - public void acceptVisitor(StatementVisitor visitor) { - visitor.visit(this); - } -} diff --git a/teavm-core/src/main/java/org/teavm/javascript/ast/StatementVisitor.java b/teavm-core/src/main/java/org/teavm/javascript/ast/StatementVisitor.java index 7c4f6cf9b..7194cdb4e 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ast/StatementVisitor.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ast/StatementVisitor.java @@ -49,6 +49,4 @@ public interface StatementVisitor { void visit(MonitorEnterStatement statement); void visit(MonitorExitStatement statement); - - void visit(SaveStatement statement); } diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java index 92c0435d5..cef535e2b 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java @@ -69,7 +69,7 @@ public class PlatformGenerator implements Generator, Injector, DependencyPlugin public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException { switch (methodRef.getName()) { case "newInstanceImpl": - generateNewInstance(writer); + generateNewInstance(context, writer); break; case "prepareNewInstance": generatePrepareNewInstance(context, writer); @@ -100,7 +100,7 @@ public class PlatformGenerator implements Generator, Injector, DependencyPlugin MethodReader method = cls.getMethod(new MethodDescriptor("", void.class)); if (method != null) { writer.appendClass(clsName).append("[c]").ws().append("=").ws() - .appendMethodBody(method.getReference()).append(")").append(";").softNewLine(); + .appendMethodBody(method.getReference()).append(";").softNewLine(); } } writer.appendMethodBody(Platform.class, "newInstance", PlatformClass.class, Object.class).ws().append('=').ws() @@ -108,17 +108,19 @@ public class PlatformGenerator implements Generator, Injector, DependencyPlugin .append(";").softNewLine(); } - private void generateNewInstance(SourceWriter writer) throws IOException { + private void generateNewInstance(GeneratorContext context, SourceWriter writer) throws IOException { writer.append("if").ws().append("($rt_resuming())").ws().append("{").indent().softNewLine(); writer.append("return $rt_nativeThread().pop();").softNewLine(); writer.outdent().append("}").softNewLine(); - writer.append("if").ws().append("(!cls.hasOwnProperty('$$constructor$$'))").ws().append("{") - .indent().softNewLine(); + String cls = context.getParameterName(1); + writer.append("if").ws().append("(!").append(cls).append(".hasOwnProperty('$$constructor$$'))") + .ws().append("{").indent().softNewLine(); writer.append("return null;").softNewLine(); writer.outdent().append("}").softNewLine(); - writer.append("var $r").ws().append('=').ws().append("cls.$$constructor$$();"); + writer.append("var $r").ws().append('=').ws().append("new ").append(cls).append("();").softNewLine(); + writer.append(cls).append(".$$constructor$$($r);").softNewLine(); writer.append("if").ws().append("($rt_suspending())").ws().append("{").indent().softNewLine(); writer.append("return $rt_nativeThread().push($r);").softNewLine(); writer.outdent().append("}").softNewLine(); From ab52f220c298a290b16c9a3820773cb75e5c0261 Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Wed, 11 Mar 2015 20:33:13 +0300 Subject: [PATCH 44/69] Prevent async assigment from optimization --- .../src/main/java/org/teavm/javascript/OptimizingVisitor.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java b/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java index f155919c4..718c86bbc 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java +++ b/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java @@ -132,6 +132,9 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor { return; } AssignmentStatement assignment = (AssignmentStatement)last; + if (assignment.isAsync()) { + return; + } if (!(assignment.getLeftValue() instanceof VariableExpr)) { return; } From aad95014fed10c8d5e4d94c237aa08e44e600257 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Thu, 12 Mar 2015 11:44:17 +0400 Subject: [PATCH 45/69] Fix error in Object.wait. Make junit working with new async approach --- .../org/teavm/classlib/java/lang/TObject.java | 6 ++ .../resources/org/teavm/javascript/runtime.js | 15 +++-- .../teavm/tooling/test/res/junit-support.js | 64 +++++++++++++------ .../teavm/classlib/java/lang/ObjectTest.java | 11 ++++ 4 files changed, 73 insertions(+), 23 deletions(-) diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java index 6229e2073..cdf71e91b 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java @@ -97,6 +97,12 @@ public class TObject { o.monitor.count += count; callback.complete(null); return; + } else if (o.monitor.owner == null) { + o.monitor.owner = thread; + TThread.setCurrentThread(thread); + o.monitor.count += count; + callback.complete(null); + return; } o.monitor.enteringThreads.add(new PlatformRunnable() { @Override public void run() { diff --git a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js index c27ddba15..22823bf23 100644 --- a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js +++ b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js @@ -442,6 +442,7 @@ function TeaVMThread(runner) { this.suspendCallback = null; this.runner = runner; this.attribute = null; + this.completeCallback = null; } TeaVMThread.prototype.push = function(value) { this.stack.push(value); @@ -460,7 +461,7 @@ TeaVMThread.prototype.suspend = function(callback) { this.suspendCallback = callback; this.status = 1; } -TeaVMThread.prototype.start = function() { +TeaVMThread.prototype.start = function(callback) { if (this.status != 3) { throw new Error("Thread already started"); } @@ -468,6 +469,7 @@ TeaVMThread.prototype.start = function() { throw new Error("Another thread is running"); } this.status = 0; + this.completeCallback = callback ? callback : function() {}; this.run(); } TeaVMThread.prototype.resume = function() { @@ -479,8 +481,11 @@ TeaVMThread.prototype.resume = function() { } TeaVMThread.prototype.run = function() { $rt_currentNativeThread = this; + var result; try { - this.runner(); + result = this.runner(); + } catch (e) { + result = e; } finally { $rt_currentNativeThread = null; } @@ -491,6 +496,8 @@ TeaVMThread.prototype.run = function() { callback(function() { self.resume(); }); + } else if (this.status === 0) { + this.completeCallback(result); } } function $rt_suspending() { @@ -504,8 +511,8 @@ function $rt_resuming() { function $rt_suspend(callback) { return $rt_nativeThread().suspend(callback); } -function $rt_startThread(runner) { - new TeaVMThread(runner).start(); +function $rt_startThread(runner, callback) { + new TeaVMThread(runner).start(callback); } var $rt_currentNativeThread = null; function $rt_nativeThread() { diff --git a/teavm-core/src/main/resources/org/teavm/tooling/test/res/junit-support.js b/teavm-core/src/main/resources/org/teavm/tooling/test/res/junit-support.js index bde8a9555..51c8b0d83 100644 --- a/teavm-core/src/main/resources/org/teavm/tooling/test/res/junit-support.js +++ b/teavm-core/src/main/resources/org/teavm/tooling/test/res/junit-support.js @@ -368,26 +368,52 @@ TreeNode.prototype.select = function() { var JUnitClient = {}; JUnitClient.run = function() { - var handler = window.addEventListener("message", function() { - window.removeEventListener("message", handler); - var message = {}; - try { - var instance = new TestClass(); - initInstance(instance); - runTest(instance, function(restore) { - try { - var result = restore(); - message.status = "ok"; - } catch (e) { - JUnitClient.makeErrorMessage(message, e); - } - window.parent.postMessage(JSON.stringify(message), "*"); - }); - } catch (e) { - JUnitClient.makeErrorMessage(message, e); - window.parent.postMessage(JSON.stringify(message), "*"); + var handler = window.addEventListener("message", $rt_threadStarter(function() { + var thread = $rt_nativeThread(); + var instance; + var ptr = 0; + var message; + if (thread.isResuming()) { + ptr = thread.pop(); + instance = thread.pop(); } - }); + loop: while (true) { switch (ptr) { + case 0: + instance = new TestClass(); + ptr = 1; + case 1: + try { + initInstance(instance); + } catch (e) { + message = {}; + JUnitClient.makeErrorMessage(message, e); + break loop; + } + if (thread.isSuspending()) { + thread.push(instance); + thread.push(ptr); + return; + } + ptr = 2; + case 2: + try { + runTest(instance); + } catch (e) { + message = {}; + JUnitClient.makeErrorMessage(message, e); + break loop; + } + if (thread.isSuspending()) { + thread.push(instance); + thread.push(ptr); + return; + } + message = {}; + message.status = "ok"; + break loop; + }} + window.parent.postMessage(JSON.stringify(message), "*"); + })); } JUnitClient.makeErrorMessage = function(message, e) { message.status = "exception"; diff --git a/teavm-tests/src/test/java/org/teavm/classlib/java/lang/ObjectTest.java b/teavm-tests/src/test/java/org/teavm/classlib/java/lang/ObjectTest.java index 6db988184..5bc565cd2 100644 --- a/teavm-tests/src/test/java/org/teavm/classlib/java/lang/ObjectTest.java +++ b/teavm-tests/src/test/java/org/teavm/classlib/java/lang/ObjectTest.java @@ -67,4 +67,15 @@ public class ObjectTest { assertTrue(new Object[2].toString().startsWith("[Ljava.lang.Object;@")); assertTrue(new byte[3].toString().startsWith("[B@")); } + + @Test + public void waitWorks() throws InterruptedException { + long start = System.currentTimeMillis(); + final Object lock = new Object(); + synchronized (lock) { + lock.wait(100); + } + long end = System.currentTimeMillis(); + assertTrue(end - start > 100); + } } From 3a29e869eff88caca0dd80bc903cdacf723ff886 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Thu, 12 Mar 2015 18:11:04 +0400 Subject: [PATCH 46/69] Aviod creation of closures in async methods --- .../java/org/teavm/javascript/Renderer.java | 25 ++++++++----------- .../org/teavm/samples/async/AsyncProgram.java | 2 +- 2 files changed, 12 insertions(+), 15 deletions(-) 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 b2d1d8d48..50ef677a2 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java @@ -698,18 +698,10 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext writer.append(";").softNewLine(); } - writer.append("function $save()").ws().append("{").indent().softNewLine(); - writer.append("$rt_nativeThread()"); int firstToSave = 0; if (methodNode.getModifiers().contains(NodeModifier.STATIC)) { firstToSave = 1; } - for (int i = firstToSave; i < variableCount; ++i) { - writer.append(".push(").append(variableName(i)).append(")"); - } - writer.append(".push($ptr);"); - writer.softNewLine(); - writer.outdent().append("}").softNewLine(); writer.append("$ptr").ws().append('=').ws().append("0;").softNewLine(); writer.append("if").ws().append("($rt_resuming())").ws().append("{").indent().softNewLine(); @@ -721,8 +713,8 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext writer.softNewLine(); writer.outdent().append("}").softNewLine(); - writer.append("while").ws().append("(true)").ws().append("{").indent().softNewLine(); - writer.append("$main: switch").ws().append("($ptr)").ws().append('{').softNewLine(); + writer.append("$main:").ws().append("while").ws().append("(true)").ws().append("{").ws(); + writer.append("switch").ws().append("($ptr)").ws().append('{').softNewLine(); for (int i = 0; i < methodNode.getBody().size(); ++i) { writer.append("case ").append(i).append(":").indent().softNewLine(); AsyncMethodPart part = methodNode.getBody().get(i); @@ -730,8 +722,13 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext writer.outdent(); } writer.append("default:").ws().append("throw new Error('Invalid recorded state');").softNewLine(); - writer.append("}").softNewLine(); - writer.outdent().append("}").softNewLine(); + writer.append("}}").softNewLine(); + writer.append("$rt_nativeThread()"); + for (int i = firstToSave; i < variableCount; ++i) { + writer.append(".push(").append(variableName(i)).append(")"); + } + writer.append(".push($ptr);"); + writer.softNewLine(); } catch (IOException e) { throw new RenderingException("IO error occured", e); } @@ -1982,7 +1979,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext try { writer.append("$ptr").ws().append("=").ws().append(statement.getPart()).append(";") .softNewLine(); - writer.append("break $main;").softNewLine(); + writer.append("continue $main;").softNewLine(); } catch (IOException ex){ throw new RenderingException("IO error occured", ex); } @@ -2012,7 +2009,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext private void emitSuspendChecker() throws IOException { writer.append("if").ws().append("($rt_suspending())").ws().append("{").indent().softNewLine(); - writer.append("return $save();").softNewLine(); + writer.append("break $main;").softNewLine(); writer.outdent().append("}").softNewLine(); } diff --git a/teavm-samples/teavm-samples-async/src/main/java/org/teavm/samples/async/AsyncProgram.java b/teavm-samples/teavm-samples-async/src/main/java/org/teavm/samples/async/AsyncProgram.java index a7b116ab1..e6888cc65 100644 --- a/teavm-samples/teavm-samples-async/src/main/java/org/teavm/samples/async/AsyncProgram.java +++ b/teavm-samples/teavm-samples-async/src/main/java/org/teavm/samples/async/AsyncProgram.java @@ -73,7 +73,7 @@ public final class AsyncProgram { private static void findPrimes() { report("Finding primes"); - boolean[] prime = new boolean[1000]; + boolean[] prime = new boolean[1000000]; prime[2] = true; prime[3] = true; nextPrime: for (int i = 5; i < prime.length; i += 2) { From 14dd352cb612c3c6ef36be73747ab15ae76daeaf Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Thu, 12 Mar 2015 20:24:33 +0300 Subject: [PATCH 47/69] Fix exception thrown with incomplete classpath --- teavm-core/src/main/java/org/teavm/javascript/Decompiler.java | 2 +- .../main/java/org/teavm/jso/plugin/JSODependencyListener.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) 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 0f3fb7a5b..d3d16f0d0 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java @@ -120,7 +120,7 @@ public class Decompiler { } ClassHolder cls = classSource.get(className); if (cls == null) { - throw new IllegalArgumentException("Class not found: " + className); + return; } if (cls.getParent() != null) { orderClasses(cls.getParent(), visited, order); diff --git a/teavm-jso/src/main/java/org/teavm/jso/plugin/JSODependencyListener.java b/teavm-jso/src/main/java/org/teavm/jso/plugin/JSODependencyListener.java index d97d80a0a..997323275 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/plugin/JSODependencyListener.java +++ b/teavm-jso/src/main/java/org/teavm/jso/plugin/JSODependencyListener.java @@ -74,6 +74,9 @@ class JSODependencyListener implements DependencyListener { private ExposedClass createExposedClass(String name) { ClassReader cls = classSource.get(name); ExposedClass exposedCls = new ExposedClass(); + if (cls == null) { + return exposedCls; + } if (cls.getParent() != null && !cls.getParent().equals(cls.getName())) { ExposedClass parent = getExposedClass(cls.getParent()); exposedCls.inheritedMethods.putAll(parent.inheritedMethods); From 79b805ba6cff2a3bfb442b51d5a910000b55a5e6 Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Thu, 12 Mar 2015 21:20:36 +0300 Subject: [PATCH 48/69] Better fix for https://github.com/konsoletyper/teavm/issues/85 --- .../java/org/teavm/javascript/Optimizer.java | 23 +++++++++++++--- .../teavm/javascript/OptimizingVisitor.java | 12 +++++---- .../javascript/ReadWriteStatsBuilder.java | 26 ++++++++++++++++--- 3 files changed, 49 insertions(+), 12 deletions(-) diff --git a/teavm-core/src/main/java/org/teavm/javascript/Optimizer.java b/teavm-core/src/main/java/org/teavm/javascript/Optimizer.java index 4c7e18804..fce043a1f 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Optimizer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Optimizer.java @@ -29,7 +29,13 @@ public class Optimizer { public void optimize(RegularMethodNode method, Program program) { ReadWriteStatsBuilder stats = new ReadWriteStatsBuilder(method.getVariables().size()); stats.analyze(program); - OptimizingVisitor optimizer = new OptimizingVisitor(stats); + boolean[] preservedVars = new boolean[stats.writes.length]; + for (int i = 0; i < preservedVars.length; ++i) { + if (stats.writes[i] != 1) { + preservedVars[i] = true; + } + } + OptimizingVisitor optimizer = new OptimizingVisitor(preservedVars, stats.reads); method.getBody().acceptVisitor(optimizer); method.setBody(optimizer.resultStmt); int paramCount = method.getReference().parameterCount(); @@ -44,12 +50,21 @@ public class Optimizer { } public void optimize(AsyncMethodNode method, AsyncProgramSplitter splitter) { - ReadWriteStatsBuilder stats = new ReadWriteStatsBuilder(method.getVariables().size()); + boolean[] preservedVars = new boolean[method.getVariables().size()]; + int[][] readFrequencies = new int[splitter.size()][]; for (int i = 0; i < splitter.size(); ++i) { + ReadWriteStatsBuilder stats = new ReadWriteStatsBuilder(method.getVariables().size()); stats.analyze(splitter.getProgram(i)); + readFrequencies[i] = stats.reads; + for (int j = 0; j < stats.writes.length; ++j) { + if (stats.readUninitialized[j] || stats.writes[j] != 1 && stats.reads[j] > 0) { + preservedVars[j] = true; + } + } } - for (AsyncMethodPart part : method.getBody()) { - OptimizingVisitor optimizer = new OptimizingVisitor(stats.copy()); + for (int i = 0; i < splitter.size(); ++i) { + AsyncMethodPart part = method.getBody().get(i); + OptimizingVisitor optimizer = new OptimizingVisitor(preservedVars, readFrequencies[i]); part.getStatement().acceptVisitor(optimizer); part.setStatement(optimizer.resultStmt); } diff --git a/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java b/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java index 718c86bbc..c0923f820 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java +++ b/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java @@ -25,11 +25,13 @@ import org.teavm.javascript.ast.*; class OptimizingVisitor implements StatementVisitor, ExprVisitor { public Expr resultExpr; public Statement resultStmt; - private ReadWriteStatsBuilder stats; + private boolean[] preservedVars; + private int[] readFrequencies; private List resultSequence; - public OptimizingVisitor(ReadWriteStatsBuilder stats) { - this.stats = stats; + public OptimizingVisitor(boolean[] preservedVars, int[] readFreqencies) { + this.preservedVars = preservedVars; + this.readFrequencies = readFreqencies; } private static boolean isZero(Expr expr) { @@ -121,7 +123,7 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor { public void visit(VariableExpr expr) { int index = expr.getIndex(); resultExpr = expr; - if (stats.reads[index] != 1 || stats.writes[index] != 1) { + if (readFrequencies[index] != 1 || preservedVars[index]) { return; } if (resultSequence.isEmpty()) { @@ -217,7 +219,7 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor { InvocationExpr constructrExpr = Expr.constructObject(expr.getMethod(), args); constructrExpr.setLocation(expr.getLocation()); assignment.setRightValue(constructrExpr); - stats.reads[var.getIndex()]--; + readFrequencies[var.getIndex()]--; return true; } diff --git a/teavm-core/src/main/java/org/teavm/javascript/ReadWriteStatsBuilder.java b/teavm-core/src/main/java/org/teavm/javascript/ReadWriteStatsBuilder.java index 0e39dd41c..9b02c1e99 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ReadWriteStatsBuilder.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ReadWriteStatsBuilder.java @@ -16,8 +16,12 @@ package org.teavm.javascript; import java.util.Arrays; +import org.teavm.common.Graph; +import org.teavm.common.GraphUtils; +import org.teavm.common.IntegerStack; import org.teavm.model.*; import org.teavm.model.util.DefinitionExtractor; +import org.teavm.model.util.ProgramUtils; import org.teavm.model.util.UsageExtractor; /** @@ -27,6 +31,7 @@ import org.teavm.model.util.UsageExtractor; class ReadWriteStatsBuilder { public int[] reads; public int[] writes; + public boolean[] readUninitialized; private ReadWriteStatsBuilder() { } @@ -34,6 +39,7 @@ class ReadWriteStatsBuilder { public ReadWriteStatsBuilder(int variableCount) { reads = new int[variableCount]; writes = new int[variableCount]; + readUninitialized = new boolean[variableCount]; } public ReadWriteStatsBuilder copy() { @@ -44,10 +50,15 @@ class ReadWriteStatsBuilder { } public void analyze(Program program) { + Graph cfg = ProgramUtils.buildControlFlowGraph(program); + Graph dom = GraphUtils.buildDominatorGraph(GraphUtils.buildDominatorTree(cfg), cfg.size()); DefinitionExtractor defExtractor = new DefinitionExtractor(); UsageExtractor useExtractor = new UsageExtractor(); - for (int i = 0; i < program.basicBlockCount(); ++i) { - BasicBlock block = program.basicBlockAt(i); + IntegerStack stack = new IntegerStack(program.basicBlockCount()); + stack.push(0); + while (!stack.isEmpty()) { + int node = stack.pop(); + BasicBlock block = program.basicBlockAt(node); for (Instruction insn : block.getInstructions()) { insn.acceptVisitor(defExtractor); insn.acceptVisitor(useExtractor); @@ -56,18 +67,27 @@ class ReadWriteStatsBuilder { } for (Variable var : useExtractor.getUsedVariables()) { reads[var.getIndex()]++; + if (writes[var.getIndex()] == 0) { + readUninitialized[var.getIndex()] = true; + } } } for (Phi phi : block.getPhis()) { writes[phi.getReceiver().getIndex()] += phi.getIncomings().size(); for (Incoming incoming : phi.getIncomings()) { - reads[incoming.getValue().getIndex()]++; + if (writes[incoming.getValue().getIndex()] == 0) { + reads[incoming.getValue().getIndex()]++; + } } } for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) { writes[tryCatch.getExceptionVariable().getIndex()]++; reads[tryCatch.getExceptionVariable().getIndex()]++; } + + for (int succ : dom.outgoingEdges(node)) { + stack.push(succ); + } } } } From 2971efb62b159190b61e4d7f10c61f147a5c7ff2 Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Thu, 12 Mar 2015 21:49:59 +0300 Subject: [PATCH 49/69] Adapt minificator for new async approach --- .../javascript/NameFrequencyEstimator.java | 14 ++-- .../java/org/teavm/javascript/Renderer.java | 65 +++++++++++++------ .../resources/org/teavm/javascript/runtime.js | 11 +++- 3 files changed, 64 insertions(+), 26 deletions(-) diff --git a/teavm-core/src/main/java/org/teavm/javascript/NameFrequencyEstimator.java b/teavm-core/src/main/java/org/teavm/javascript/NameFrequencyEstimator.java index fdfade618..f6f5f724d 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/NameFrequencyEstimator.java +++ b/teavm-core/src/main/java/org/teavm/javascript/NameFrequencyEstimator.java @@ -75,6 +75,12 @@ public class NameFrequencyEstimator implements StatementVisitor, ExprVisitor, Me consumer.consume(method.getReference().getDescriptor()); consumer.consume(method.getReference()); } + if (method.isAsync()) { + consumer.consumeFunction("$rt_nativeThread"); + consumer.consumeFunction("$rt_nativeThread"); + consumer.consumeFunction("$rt_resuming"); + consumer.consumeFunction("$rt_invalidPointer"); + } } // Metadata @@ -99,7 +105,6 @@ public class NameFrequencyEstimator implements StatementVisitor, ExprVisitor, Me async = true; for (AsyncMethodPart part : methodNode.getBody()) { part.getStatement().acceptVisitor(this); - consumer.consumeFunction("$rt_guardAsync"); } } @@ -113,6 +118,9 @@ public class NameFrequencyEstimator implements StatementVisitor, ExprVisitor, Me statement.getLeftValue().acceptVisitor(this); } statement.getRightValue().acceptVisitor(this); + if (statement.isAsync()) { + consumer.consumeFunction("$rt_suspending"); + } } @Override @@ -162,9 +170,6 @@ public class NameFrequencyEstimator implements StatementVisitor, ExprVisitor, Me if (statement.getResult() != null) { statement.getResult().acceptVisitor(this); } - if (async) { - consumer.consumeFunction("$rt_asyncResult"); - } } @Override @@ -197,6 +202,7 @@ public class NameFrequencyEstimator implements StatementVisitor, ExprVisitor, Me MethodReference monitorEnterRef = new MethodReference( Object.class, "monitorEnter", Object.class, void.class); consumer.consume(monitorEnterRef); + consumer.consumeFunction("$rt_suspending"); } else { MethodReference monitorEnterRef = new MethodReference( Object.class, "monitorEnterSync", Object.class, void.class); 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 50ef677a2..0e5d7618a 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java @@ -261,7 +261,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext private void renderRuntimeAliases() throws IOException { String[] names = { "$rt_throw", "$rt_compare", "$rt_nullCheck", "$rt_cls", "$rt_createArray", - "$rt_isInstance" }; + "$rt_isInstance", "$rt_nativeThread", "$rt_suspending", "$rt_resuming", "$rt_invalidPointer" }; boolean first = true; for (String name : names) { if (!first) { @@ -685,8 +685,8 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext if (hasTryCatch) { variableNames.add("$je"); } - variableNames.add("$ptr"); - variableNames.add("$tmp"); + variableNames.add(pointerName()); + variableNames.add(tempVarName()); if (!variableNames.isEmpty()) { writer.append("var "); for (int i = 0; i < variableNames.size(); ++i) { @@ -703,31 +703,39 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext firstToSave = 1; } - writer.append("$ptr").ws().append('=').ws().append("0;").softNewLine(); - writer.append("if").ws().append("($rt_resuming())").ws().append("{").indent().softNewLine(); - writer.append("var $T").ws().append('=').ws().append("$rt_nativeThread();").softNewLine(); - writer.append("$ptr").ws().append('=').ws().append("$T.pop();"); + String popName = minifying ? "l" : "pop"; + String pushName = minifying ? "s" : "push"; + writer.append(pointerName()).ws().append('=').ws().append("0;").softNewLine(); + writer.append("if").ws().append("(").appendFunction("$rt_resuming").append("())").ws() + .append("{").indent().softNewLine(); + writer.append("var ").append(threadName()).ws().append('=').ws() + .appendFunction("$rt_nativeThread").append("();").softNewLine(); + writer.append(pointerName()).ws().append('=').ws().append(threadName()).append(".") + .append(popName).append("();"); for (int i = variableCount - 1; i >= firstToSave; --i) { - writer.append(variableName(i)).ws().append('=').ws().append("$T.pop();"); + writer.append(variableName(i)).ws().append('=').ws().append(threadName()).append(".") + .append(popName).append("();"); } writer.softNewLine(); writer.outdent().append("}").softNewLine(); - writer.append("$main:").ws().append("while").ws().append("(true)").ws().append("{").ws(); - writer.append("switch").ws().append("($ptr)").ws().append('{').softNewLine(); + writer.append(mainLoopName()).append(":").ws().append("while").ws().append("(true)") + .ws().append("{").ws(); + writer.append("switch").ws().append("(").append(pointerName()).append(")").ws() + .append('{').softNewLine(); for (int i = 0; i < methodNode.getBody().size(); ++i) { writer.append("case ").append(i).append(":").indent().softNewLine(); AsyncMethodPart part = methodNode.getBody().get(i); part.getStatement().acceptVisitor(Renderer.this); writer.outdent(); } - writer.append("default:").ws().append("throw new Error('Invalid recorded state');").softNewLine(); + writer.append("default:").ws().appendFunction("$rt_invalidPointer").append("();").softNewLine(); writer.append("}}").softNewLine(); - writer.append("$rt_nativeThread()"); + writer.appendFunction("$rt_nativeThread").append("().").append(pushName).append("("); for (int i = firstToSave; i < variableCount; ++i) { - writer.append(".push(").append(variableName(i)).append(")"); + writer.append(variableName(i)).append(',').ws(); } - writer.append(".push($ptr);"); + writer.append(pointerName()).append(");"); writer.softNewLine(); } catch (IOException e) { throw new RenderingException("IO error occured", e); @@ -816,7 +824,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext prevCallSite = debugEmitter.emitCallSite(); if (statement.getLeftValue() != null) { if (statement.isAsync()) { - writer.append("$tmp"); + writer.append(tempVarName()); } else { priority = Priority.COMMA; associativity = Associativity.NONE; @@ -835,7 +843,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext priority = Priority.COMMA; associativity = Associativity.NONE; statement.getLeftValue().acceptVisitor(this); - writer.ws().append("=").ws().append("$tmp;").softNewLine(); + writer.ws().append("=").ws().append(tempVarName()).append(";").softNewLine(); } } if (statement.getLocation() != null) { @@ -1132,6 +1140,22 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext } } + private String pointerName() { + return minifying ? "$p" : "$ptr"; + } + + private String mainLoopName() { + return minifying ? "$m" : "$main"; + } + + private String tempVarName() { + return minifying ? "$z" : "$tmp"; + } + + private String threadName() { + return minifying ? "$T" : "$thread"; + } + private void visitBinary(BinaryExpr expr, String op, Priority priority, Associativity associativity) { try { if (expr.getLocation() != null) { @@ -1977,9 +2001,9 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext @Override public void visit(GotoPartStatement statement) { try { - writer.append("$ptr").ws().append("=").ws().append(statement.getPart()).append(";") + writer.append(pointerName()).ws().append("=").ws().append(statement.getPart()).append(";") .softNewLine(); - writer.append("continue $main;").softNewLine(); + writer.append("continue ").append(mainLoopName()).append(";").softNewLine(); } catch (IOException ex){ throw new RenderingException("IO error occured", ex); } @@ -2008,8 +2032,9 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext } private void emitSuspendChecker() throws IOException { - writer.append("if").ws().append("($rt_suspending())").ws().append("{").indent().softNewLine(); - writer.append("break $main;").softNewLine(); + writer.append("if").ws().append("(").appendFunction("$rt_suspending").append("())").ws() + .append("{").indent().softNewLine(); + writer.append("break ").append(mainLoopName()).append(";").softNewLine(); writer.outdent().append("}").softNewLine(); } diff --git a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js index 22823bf23..02dbe2dc1 100644 --- a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js +++ b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js @@ -444,13 +444,17 @@ function TeaVMThread(runner) { this.attribute = null; this.completeCallback = null; } -TeaVMThread.prototype.push = function(value) { - this.stack.push(value); +TeaVMThread.prototype.push = function() { + for (var i = 0; i < arguments.length; ++i) { + this.stack.push(arguments[i]); + } return this; } +TeaVMThread.prototype.s = TeaVMThread.prototype.push; TeaVMThread.prototype.pop = function() { return this.stack.pop(); } +TeaVMThread.prototype.l = TeaVMThread.prototype.pop; TeaVMThread.prototype.isResuming = function() { return this.status == 2; } @@ -518,6 +522,9 @@ var $rt_currentNativeThread = null; function $rt_nativeThread() { return $rt_currentNativeThread; } +function $rt_invalidPointer() { + throw new Error("Invalid recorded state"); +} function $dbg_repr(obj) { return obj.toString ? obj.toString() : ""; From cd0dd134cc06ea26b51d968a18a507ebb3c59cee Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Thu, 12 Mar 2015 22:07:24 +0300 Subject: [PATCH 50/69] Preparing to merge into master --- teavm-samples/teavm-samples-async/pom.xml | 4 +--- .../src/main/java/org/teavm/samples/async/AsyncProgram.java | 2 +- .../test/java/org/teavm/classlib/java/lang/ObjectTest.java | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/teavm-samples/teavm-samples-async/pom.xml b/teavm-samples/teavm-samples-async/pom.xml index 125597036..99a38de06 100644 --- a/teavm-samples/teavm-samples-async/pom.xml +++ b/teavm-samples/teavm-samples-async/pom.xml @@ -65,12 +65,10 @@ ${project.build.directory}/generated/js/teavm org.teavm.samples.async.AsyncProgram SEPARATE - false + true true - diff --git a/teavm-samples/teavm-samples-async/src/main/java/org/teavm/samples/async/AsyncProgram.java b/teavm-samples/teavm-samples-async/src/main/java/org/teavm/samples/async/AsyncProgram.java index e6888cc65..a7b116ab1 100644 --- a/teavm-samples/teavm-samples-async/src/main/java/org/teavm/samples/async/AsyncProgram.java +++ b/teavm-samples/teavm-samples-async/src/main/java/org/teavm/samples/async/AsyncProgram.java @@ -73,7 +73,7 @@ public final class AsyncProgram { private static void findPrimes() { report("Finding primes"); - boolean[] prime = new boolean[1000000]; + boolean[] prime = new boolean[1000]; prime[2] = true; prime[3] = true; nextPrime: for (int i = 5; i < prime.length; i += 2) { diff --git a/teavm-tests/src/test/java/org/teavm/classlib/java/lang/ObjectTest.java b/teavm-tests/src/test/java/org/teavm/classlib/java/lang/ObjectTest.java index 5bc565cd2..5aae01964 100644 --- a/teavm-tests/src/test/java/org/teavm/classlib/java/lang/ObjectTest.java +++ b/teavm-tests/src/test/java/org/teavm/classlib/java/lang/ObjectTest.java @@ -73,7 +73,7 @@ public class ObjectTest { long start = System.currentTimeMillis(); final Object lock = new Object(); synchronized (lock) { - lock.wait(100); + lock.wait(110); } long end = System.currentTimeMillis(); assertTrue(end - start > 100); From cc009ff9bd49491dabade0779be7fee7c487f18c Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Fri, 13 Mar 2015 12:11:53 +0400 Subject: [PATCH 51/69] Fix bug in DFG simplifier --- .../teavm/dependency/DataFlowGraphBuilder.java | 15 +++++++++------ .../teavm/dependency/DependencyGraphBuilder.java | 6 +++++- .../org/teavm/tooling/test/res/junit-support.js | 10 ++-------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/teavm-core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java b/teavm-core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java index 43d421e48..a065708fa 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java @@ -62,15 +62,18 @@ public class DataFlowGraphBuilder implements InstructionReader { } IntegerArray startNodes = new IntegerArray(graph.size()); for (int i = paramCount; i < graph.size(); ++i) { - if (importantNodes.contains(i)) { - continue; - } - for (int pred : graph.incomingEdges(i)) { - classes.union(pred, i); - } if (graph.incomingEdgesCount(i) == 0) { startNodes.add(i); } + for (int pred : graph.incomingEdges(i)) { + if (importantNodes.contains(pred) && importantNodes.contains(i)) { + continue; + } + int newCls = classes.union(pred, i); + if (importantNodes.contains(pred)) { + importantNodes.add(newCls); + } + } } int[][] sccs = GraphUtils.findStronglyConnectedComponents(graph, startNodes.getAll()); 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 93820754c..cad81ed31 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java @@ -54,7 +54,11 @@ class DependencyGraphBuilder { resultNode = dep.getResult(); DependencyNode[] origNodes = dep.getVariables(); - int[] nodeMapping = new DataFlowGraphBuilder().buildMapping(program, dep.getParameterCount()); + DataFlowGraphBuilder dfgBuilder = new DataFlowGraphBuilder(); + for (int i = 0; i < dep.getParameterCount(); ++i) { + dfgBuilder.important(i); + } + int[] nodeMapping = dfgBuilder.buildMapping(program, dep.getParameterCount()); nodes = new DependencyNode[origNodes.length]; for (int i = 0; i < nodes.length; ++i) { nodes[i] = origNodes[nodeMapping[i]]; diff --git a/teavm-core/src/main/resources/org/teavm/tooling/test/res/junit-support.js b/teavm-core/src/main/resources/org/teavm/tooling/test/res/junit-support.js index 51c8b0d83..29e87ac6f 100644 --- a/teavm-core/src/main/resources/org/teavm/tooling/test/res/junit-support.js +++ b/teavm-core/src/main/resources/org/teavm/tooling/test/res/junit-support.js @@ -417,20 +417,14 @@ JUnitClient.run = function() { } JUnitClient.makeErrorMessage = function(message, e) { message.status = "exception"; - var stack = ""; - while (e instanceof TeaVMAsyncError) { - stack += e.message + "\n" + e.stack + "\n"; - e = e.cause; - } + var stack = e.stack; if (e.$javaException && e.$javaException.constructor.$meta) { message.exception = e.$javaException.constructor.$meta.name; message.stack = e.$javaException.constructor.$meta.name + ": "; var exceptionMessage = extractException(e.$javaException); message.stack += exceptionMessage ? $rt_ustr(exceptionMessage) : ""; - message.stack += e.stack + "\n" + stack; - } else { - message.stack = stack; } + message.stack += "\n" + stack; } JUnitClient.reportError = function(error) { var handler = window.addEventListener("message", function() { From 0572123c0e31d4883593392a3ece4c0c74918922 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Fri, 13 Mar 2015 12:52:57 +0400 Subject: [PATCH 52/69] Faster long for small values --- .../main/resources/org/teavm/javascript/runtime.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js index 02dbe2dc1..797e95b19 100644 --- a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js +++ b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js @@ -605,6 +605,9 @@ function Long_toNumber(val) { return 0x100000000 * hi + lo; } function Long_add(a, b) { + if (a.hi === a.lo >> 31 && b.hi === b.lo >> 31) { + return Long_fromNumber(a.lo + b.lo); + } var a_lolo = a.lo & 0xFFFF; var a_lohi = a.lo >>> 16; var a_hilo = a.hi & 0xFFFF; @@ -640,6 +643,9 @@ function Long_neg(a) { return Long_inc(new Long(a.lo ^ 0xFFFFFFFF, a.hi ^ 0xFFFFFFFF)); } function Long_sub(a, b) { + if (a.hi === 0 && a.lo >> 31 && b.hi === b.lo >> 31) { + return Long_fromNumber(a.lo - b.lo); + } var a_lolo = a.lo & 0xFFFF; var a_lohi = a.lo >>> 16; var a_hilo = a.hi & 0xFFFF; @@ -711,9 +717,15 @@ function Long_mul(a, b) { return positive ? result : Long_neg(result); } function Long_div(a, b) { + if (a.hi === 0 && b.hi === 0) { + return Long_fromNumber(Long_toNumber(a) / Long_toNumber(b)); + } return Long_divRem(a, b)[0]; } function Long_rem(a, b) { + if (a.hi === 0 && b.hi === 0) { + return Long_fromNumber(Long_toNumber(a) % Long_toNumber(b)); + } return Long_divRem(a, b)[1]; } function Long_divRem(a, b) { From 31f64396527a92c45a15ab86b859e98cd75bbd61 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Fri, 13 Mar 2015 14:26:36 +0400 Subject: [PATCH 53/69] Fix another bug in DFG simplifier. Fix long subtraction bug --- .../main/java/org/teavm/dependency/DataFlowGraphBuilder.java | 4 ++-- teavm-core/src/main/resources/org/teavm/javascript/runtime.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/teavm-core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java b/teavm-core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java index a065708fa..d71cec93d 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java @@ -66,7 +66,7 @@ public class DataFlowGraphBuilder implements InstructionReader { startNodes.add(i); } for (int pred : graph.incomingEdges(i)) { - if (importantNodes.contains(pred) && importantNodes.contains(i)) { + if (importantNodes.contains(classes.find(pred)) && importantNodes.contains(classes.find(i))) { continue; } int newCls = classes.union(pred, i); @@ -80,7 +80,7 @@ public class DataFlowGraphBuilder implements InstructionReader { for (int[] scc : sccs) { int last = -1; for (int node : scc) { - if (!importantNodes.contains(node)) { + if (!importantNodes.contains(classes.find(node))) { continue; } last = last < 0 ? node : classes.union(node, last); diff --git a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js index 797e95b19..b3629bfb5 100644 --- a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js +++ b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js @@ -605,7 +605,7 @@ function Long_toNumber(val) { return 0x100000000 * hi + lo; } function Long_add(a, b) { - if (a.hi === a.lo >> 31 && b.hi === b.lo >> 31) { + if (a.hi === (a.lo >> 31) && b.hi === (b.lo >> 31)) { return Long_fromNumber(a.lo + b.lo); } var a_lolo = a.lo & 0xFFFF; @@ -643,7 +643,7 @@ function Long_neg(a) { return Long_inc(new Long(a.lo ^ 0xFFFFFFFF, a.hi ^ 0xFFFFFFFF)); } function Long_sub(a, b) { - if (a.hi === 0 && a.lo >> 31 && b.hi === b.lo >> 31) { + if (a.hi === (a.lo >> 31) && b.hi === (b.lo >> 31)) { return Long_fromNumber(a.lo - b.lo); } var a_lolo = a.lo & 0xFFFF; From 793d1e19d20623dd66e32f9fda92df542e59a1ad Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Fri, 13 Mar 2015 14:57:59 +0400 Subject: [PATCH 54/69] Fix another bug in DFG simplifier --- .../java/org/teavm/dependency/DataFlowGraphBuilder.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/teavm-core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java b/teavm-core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java index d71cec93d..7fb34216b 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java @@ -66,11 +66,13 @@ public class DataFlowGraphBuilder implements InstructionReader { startNodes.add(i); } for (int pred : graph.incomingEdges(i)) { - if (importantNodes.contains(classes.find(pred)) && importantNodes.contains(classes.find(i))) { + boolean predImportant = importantNodes.contains(classes.find(pred)); + boolean nodeImportant = importantNodes.contains(classes.find(i)); + if (predImportant && nodeImportant) { continue; } int newCls = classes.union(pred, i); - if (importantNodes.contains(pred)) { + if (nodeImportant || predImportant) { importantNodes.add(newCls); } } From 77863ad6fd07b1f9f06b759241ebcdc02e33867b Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Fri, 13 Mar 2015 15:55:02 +0400 Subject: [PATCH 55/69] Perform better preordering before decompilation --- .../java/org/teavm/common/GraphIndexer.java | 85 +++++++++++++++++-- .../java/org/teavm/javascript/Decompiler.java | 6 +- 2 files changed, 82 insertions(+), 9 deletions(-) diff --git a/teavm-core/src/main/java/org/teavm/common/GraphIndexer.java b/teavm-core/src/main/java/org/teavm/common/GraphIndexer.java index 7fba32a06..21f1b94c6 100644 --- a/teavm-core/src/main/java/org/teavm/common/GraphIndexer.java +++ b/teavm-core/src/main/java/org/teavm/common/GraphIndexer.java @@ -18,7 +18,10 @@ package org.teavm.common; import com.carrotsearch.hppc.IntOpenHashSet; import com.carrotsearch.hppc.IntSet; import com.carrotsearch.hppc.cursors.IntCursor; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; +import java.util.List; /** * @@ -30,18 +33,19 @@ public class GraphIndexer { static final byte VISITED = 2; private int[] indexToNode; private int[] nodeToIndex; - private byte[] state; private Graph graph; private DominatorTree domTree; private int lastIndex; + private int[] weights; - public GraphIndexer(Graph graph) { + public GraphIndexer(Graph graph, int[] weights) { int sz = graph.size(); + this.weights = weights; + propagateWeights(graph, weights); indexToNode = new int[sz + 1]; nodeToIndex = new int[sz + 1]; Arrays.fill(nodeToIndex, -1); Arrays.fill(indexToNode, -1); - state = new byte[sz]; this.graph = graph; domTree = GraphUtils.buildDominatorTree(graph); sort(graph); @@ -66,8 +70,38 @@ public class GraphIndexer { this.graph = sorted.build(); } + private void propagateWeights(Graph graph, int[] weights) { + int sz = graph.size(); + byte[] state = new byte[sz]; + IntegerStack stack = new IntegerStack(sz * 2); + stack.push(0); + while (!stack.isEmpty()) { + int node = stack.pop(); + switch (state[node]) { + case VISITING: + state[node] = VISITED; + for (int succ : graph.outgoingEdges(node)) { + if (state[node] == VISITED) { + weights[node] += weights[succ]; + } + } + break; + case NONE: + state[node] = VISITING; + stack.push(node); + for (int succ : graph.outgoingEdges(node)) { + if (state[succ] == NONE) { + stack.push(succ); + } + } + break; + } + } + } + private void sort(Graph graph) { int sz = graph.size(); + byte[] state = new byte[sz]; IntegerStack stack = new IntegerStack(sz * 2); stack.push(0); while (!stack.isEmpty()) { @@ -88,25 +122,45 @@ public class GraphIndexer { } } int[] successors = graph.outgoingEdges(node); + List succList = new ArrayList<>(successors.length); + IntegerArray orderedSuccessors = new IntegerArray(successors.length); if (terminalNodes.size() > 0) { IntSet loopNodes = IntOpenHashSet.from(findNaturalLoop(node, terminalNodes.getAll())); - IntegerArray orderedSuccessors = new IntegerArray(successors.length); for (int succ : successors) { if (loopNodes.contains(succ)) { - orderedSuccessors.add(succ); + succList.add(new WeightedNode(succ, weights[succ])); } } + Collections.sort(succList); + for (WeightedNode wnode : succList) { + orderedSuccessors.add(wnode.index); + } + IntSet outerSuccessors = new IntOpenHashSet(successors.length); + succList.clear(); for (IntCursor loopNode : loopNodes) { for (int succ : graph.outgoingEdges(loopNode.value)) { if (!loopNodes.contains(succ)) { - outerSuccessors.add(succ); + if (outerSuccessors.add(succ)) { + succList.add(new WeightedNode(succ, weights[succ])); + } } } } - orderedSuccessors.addAll(outerSuccessors.toArray()); - successors = orderedSuccessors.getAll(); + Collections.sort(succList); + for (WeightedNode wnode : succList) { + orderedSuccessors.add(wnode.index); + } + } else { + for (int succ : successors) { + succList.add(new WeightedNode(succ, weights[succ])); + } + Collections.sort(succList); + for (WeightedNode wnode : succList) { + orderedSuccessors.add(wnode.index); + } } + successors = orderedSuccessors.getAll(); for (int succ : successors) { if (state[succ] == NONE) { stack.push(succ); @@ -152,4 +206,19 @@ public class GraphIndexer { public Graph getGraph() { return graph; } + + static class WeightedNode implements Comparable { + int index; + int weight; + + public WeightedNode(int index, int weight) { + this.index = index; + this.weight = weight; + } + + @Override + public int compareTo(WeightedNode o) { + return Integer.compare(weight, o.weight); + } + } } 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 d3d16f0d0..31a430daa 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java @@ -246,7 +246,11 @@ public class Decompiler { AsyncMethodPart result = new AsyncMethodPart(); lastBlockId = 1; graph = ProgramUtils.buildControlFlowGraph(program); - indexer = new GraphIndexer(graph); + int[] weights = new int[graph.size()]; + for (int i = 0; i < weights.length; ++i) { + weights[i] = program.basicBlockAt(i).getInstructions().size(); + } + indexer = new GraphIndexer(graph, weights); graph = indexer.getGraph(); loopGraph = new LoopGraph(this.graph); unflatCode(); From 1380e7dbf4f42bed5eb2c966197581e28f6ee0b7 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Fri, 13 Mar 2015 19:01:13 +0400 Subject: [PATCH 56/69] Generate readable names for method parameters --- .../java/org/teavm/javascript/Renderer.java | 40 ++++++++++++++++--- .../teavm/javascript/ast/AsyncMethodNode.java | 1 + .../org/teavm/javascript/ast/MethodNode.java | 3 ++ .../javascript/ast/NativeMethodNode.java | 8 ++++ .../javascript/ast/RegularMethodNode.java | 1 + 5 files changed, 48 insertions(+), 5 deletions(-) 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 0e5d7618a..e9f5544a4 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java @@ -65,6 +65,8 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext private boolean wasGrouped; private Deque precedenceStack = new ArrayDeque<>(); private Map blockIdMap = new HashMap<>(); + private List> debugNames = new ArrayList<>(); + private List cachedVariableNames = new ArrayList<>(); private static class OperatorPrecedence { Priority priority; @@ -574,6 +576,9 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext } public void renderBody(MethodNode method, boolean inner) throws IOException { + debugNames.clear(); + cachedVariableNames.clear(); + debugNames.addAll(method.getParameterDebugNames()); blockIdMap.clear(); MethodReference ref = method.getReference(); debugEmitter.emitMethod(ref.getDescriptor()); @@ -627,6 +632,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext debugEmitter.emitVariable(method.getParameterDebugNames().get(i).toArray(new String[0]), variableName(i)); } + int variableCount = 0; for (int var : method.getVariables()) { variableCount = Math.max(variableCount, var + 1); @@ -1128,15 +1134,39 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext } public String variableName(int index) { + while (index >= cachedVariableNames.size()) { + cachedVariableNames.add(null); + } + String name = cachedVariableNames.get(index); + if (name == null) { + name = generateVariableName(index); + cachedVariableNames.set(index, name); + } + return name; + } + + private String generateVariableName(int index) { if (index == 0) { return minifying ? "$t" : "$this"; } - --index; - if (index < variableNames.length()) { - return Character.toString(variableNames.charAt(index)); + + Set names = index < debugNames.size() ? debugNames.get(index) : null; + if (minifying || names == null || names.isEmpty()) { + --index; + if (index < variableNames.length()) { + return Character.toString(variableNames.charAt(index)); + } else { + return Character.toString(variableNames.charAt(index % variableNames.length())) + + index / variableNames.length(); + } } else { - return Character.toString(variableNames.charAt(index % variableNames.length())) + - index / variableNames.length(); + List nameList = new ArrayList<>(names); + Collections.sort(nameList); + StringBuilder sb = new StringBuilder(); + for (String name : nameList) { + sb.append('_').append(name); + } + return sb.toString(); } } diff --git a/teavm-core/src/main/java/org/teavm/javascript/ast/AsyncMethodNode.java b/teavm-core/src/main/java/org/teavm/javascript/ast/AsyncMethodNode.java index bdeb269e3..d15b2a2e6 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ast/AsyncMethodNode.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ast/AsyncMethodNode.java @@ -41,6 +41,7 @@ public class AsyncMethodNode extends MethodNode { return variables; } + @Override public List> getParameterDebugNames() { return parameterDebugNames; } diff --git a/teavm-core/src/main/java/org/teavm/javascript/ast/MethodNode.java b/teavm-core/src/main/java/org/teavm/javascript/ast/MethodNode.java index 53bb6356f..7186fdbe4 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ast/MethodNode.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ast/MethodNode.java @@ -16,6 +16,7 @@ package org.teavm.javascript.ast; import java.util.EnumSet; +import java.util.List; import java.util.Set; import org.teavm.model.MethodReference; @@ -43,4 +44,6 @@ public abstract class MethodNode { public abstract void acceptVisitor(MethodNodeVisitor visitor); public abstract boolean isAsync(); + + public abstract List> getParameterDebugNames(); } diff --git a/teavm-core/src/main/java/org/teavm/javascript/ast/NativeMethodNode.java b/teavm-core/src/main/java/org/teavm/javascript/ast/NativeMethodNode.java index 4b7d4b83d..f973e7b2c 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ast/NativeMethodNode.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ast/NativeMethodNode.java @@ -15,6 +15,9 @@ */ package org.teavm.javascript.ast; +import java.util.Collections; +import java.util.List; +import java.util.Set; import org.teavm.javascript.spi.Generator; import org.teavm.model.MethodReference; @@ -51,4 +54,9 @@ public class NativeMethodNode extends MethodNode { public void acceptVisitor(MethodNodeVisitor visitor) { visitor.visit(this); } + + @Override + public List> getParameterDebugNames() { + return Collections.emptyList(); + } } diff --git a/teavm-core/src/main/java/org/teavm/javascript/ast/RegularMethodNode.java b/teavm-core/src/main/java/org/teavm/javascript/ast/RegularMethodNode.java index f532b4892..2bc132ac4 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ast/RegularMethodNode.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ast/RegularMethodNode.java @@ -45,6 +45,7 @@ public class RegularMethodNode extends MethodNode { return variables; } + @Override public List> getParameterDebugNames() { return parameterDebugNames; } From 2745f1c7f584e900b2c01b411a7a11cd97f0d2b2 Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Fri, 13 Mar 2015 22:09:28 +0300 Subject: [PATCH 57/69] Initial optimization of dependency checker --- .../dependency/DataFlowGraphBuilder.java | 76 +++++++++-- .../teavm/dependency/DependencyChecker.java | 20 +-- .../dependency/DependencyGraphBuilder.java | 126 +++++++++++++----- .../org/teavm/dependency/DependencyNode.java | 62 ++++++--- .../DependencyNodeToNodeTransition.java | 4 +- .../teavm/model/InstructionReadVisitor.java | 2 +- .../java/org/teavm/model/MethodReference.java | 4 + .../model/instructions/InstructionReader.java | 6 +- .../instructions/PutFieldInstruction.java | 10 ++ .../teavm/model/util/AsyncMethodFinder.java | 3 +- .../model/util/InstructionStringifier.java | 2 +- .../org/teavm/model/util/ProgramUtils.java | 4 +- .../java/org/teavm/parsing/ProgramParser.java | 3 +- .../tooling/ProgramSourceAggregator.java | 7 +- 14 files changed, 249 insertions(+), 80 deletions(-) diff --git a/teavm-core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java b/teavm-core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java index 7fb34216b..882000dfc 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java @@ -36,14 +36,20 @@ public class DataFlowGraphBuilder implements InstructionReader { private ObjectIntMap methodNodes = new ObjectIntOpenHashMap<>(); private ObjectIntMap fieldNodes = new ObjectIntOpenHashMap<>(); private int[] arrayNodes; + private int returnIndex = -1; + private int exceptionIndex; public void important(int node) { importantNodes.add(node); } - public int[] buildMapping(ProgramReader program, int paramCount) { + public int[] buildMapping(ProgramReader program, int paramCount, boolean needsReturn) { lastIndex = program.variableCount(); arrayNodes = new int[lastIndex]; + if (needsReturn) { + returnIndex = lastIndex++; + } + exceptionIndex = lastIndex++; Arrays.fill(arrayNodes, -1); for (int i = 0; i < program.basicBlockCount(); ++i) { BasicBlockReader block = program.basicBlockAt(i); @@ -52,6 +58,11 @@ public class DataFlowGraphBuilder implements InstructionReader { builder.addEdge(incoming.getValue().getIndex(), phi.getReceiver().getIndex()); } } + for (TryCatchBlockReader tryCatch : block.readTryCatchBlocks()) { + if (tryCatch.getExceptionVariable() != null) { + important(tryCatch.getExceptionVariable().getIndex()); + } + } block.readAllInstructions(this); } Graph graph = builder.build(); @@ -76,6 +87,17 @@ public class DataFlowGraphBuilder implements InstructionReader { importantNodes.add(newCls); } } + for (int succ : graph.outgoingEdges(i)) { + boolean succImportant = importantNodes.contains(classes.find(succ)); + boolean nodeImportant = importantNodes.contains(classes.find(i)); + if (succImportant && nodeImportant) { + continue; + } + int newCls = classes.union(succ, i); + if (nodeImportant || succImportant) { + importantNodes.add(newCls); + } + } } int[][] sccs = GraphUtils.findStronglyConnectedComponents(graph, startNodes.getAll()); @@ -88,7 +110,25 @@ public class DataFlowGraphBuilder implements InstructionReader { last = last < 0 ? node : classes.union(node, last); } } - return classes.pack(program.variableCount()); + + int[] classMap = new int[classes.size()]; + Arrays.fill(classMap, -1); + int[] result = new int[program.variableCount()]; + int classCount = 0; + for (int i = 0; i < program.variableCount(); ++i) { + int cls = classes.find(i); + if (!importantNodes.contains(cls)) { + result[i] = -1; + continue; + } + int packedCls = classMap[cls]; + if (packedCls < 0) { + packedCls = classCount++; + classMap[cls] = packedCls; + } + result[i] = packedCls; + } + return result; } @Override @@ -178,14 +218,16 @@ public class DataFlowGraphBuilder implements InstructionReader { @Override public void exit(VariableReader valueToReturn) { - if (valueToReturn != null) { - important(valueToReturn.getIndex()); + if (valueToReturn != null && returnIndex >= 0) { + important(returnIndex); + builder.addEdge(valueToReturn.getIndex(), returnIndex); } } @Override public void raise(VariableReader exception) { - important(exception.getIndex()); + builder.addEdge(exception.getIndex(), exceptionIndex); + important(exceptionIndex); } @Override @@ -212,13 +254,18 @@ public class DataFlowGraphBuilder implements InstructionReader { @Override public void getField(VariableReader receiver, VariableReader instance, FieldReference field, ValueType fieldType) { + if (fieldType instanceof ValueType.Primitive) { + return; + } int fieldNode = getFieldNode(field); builder.addEdge(fieldNode, receiver.getIndex()); } - @Override - public void putField(VariableReader instance, FieldReference field, VariableReader value) { + public void putField(VariableReader instance, FieldReference field, VariableReader value, ValueType fieldType) { + if (fieldType instanceof ValueType.Primitive) { + return; + } int fieldNode = getFieldNode(field); builder.addEdge(value.getIndex(), fieldNode); } @@ -274,7 +321,18 @@ public class DataFlowGraphBuilder implements InstructionReader { public void invoke(VariableReader receiver, VariableReader instance, MethodReference method, List arguments, InvocationType type) { if (receiver != null) { - builder.addEdge(getMethodNode(method), receiver.getIndex()); + if (!(method.getReturnType() instanceof ValueType.Primitive)) { + builder.addEdge(getMethodNode(method), receiver.getIndex()); + } + } + ValueType[] paramTypes = method.getParameterTypes(); + for (int i = 0; i < paramTypes.length; ++i) { + if (!(paramTypes[i] instanceof ValueType.Primitive)) { + important(arguments.get(i).getIndex()); + } + } + if (instance != null) { + important(instance.getIndex()); } } @@ -293,9 +351,11 @@ public class DataFlowGraphBuilder implements InstructionReader { @Override public void monitorEnter(VariableReader objectRef) { + important(objectRef.getIndex()); } @Override public void monitorExit(VariableReader objectRef) { + important(objectRef.getIndex()); } } diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java index 3174539ca..f2b9e96df 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java @@ -62,6 +62,8 @@ public class DependencyChecker implements DependencyInfo { private Diagnostics diagnostics; DefaultCallGraph callGraph = new DefaultCallGraph(); private DependencyAgent agent; + List nodes = new ArrayList<>(); + List typeBitSets = new ArrayList<>(); public DependencyChecker(ClassReaderSource classSource, ClassLoader classLoader, ServiceRepository services, Diagnostics diagnostics) { @@ -128,13 +130,16 @@ public class DependencyChecker implements DependencyInfo { if (type == null) { type = new DependencyType(this, name, types.size()); types.add(type); + typeBitSets.add(new BitSet(nodes.size())); typeMap.put(name, type); } return type; } public DependencyNode createNode() { - return new DependencyNode(this); + DependencyNode node = new DependencyNode(this, nodes.size()); + nodes.add(node); + return node; } @Override @@ -336,11 +341,9 @@ public class DependencyChecker implements DependencyInfo { private MethodDependency createMethodDep(MethodReference methodRef, MethodReader method) { ValueType[] arguments = methodRef.getParameterTypes(); int paramCount = arguments.length + 1; - int varCount = Math.max(paramCount, method != null && method.getProgram() != null ? - method.getProgram().variableCount() : 0); - DependencyNode[] parameterNodes = new DependencyNode[varCount]; - for (int i = 0; i < varCount; ++i) { - parameterNodes[i] = new DependencyNode(this); + DependencyNode[] parameterNodes = new DependencyNode[arguments.length + 1]; + for (int i = 0; i < parameterNodes.length; ++i) { + parameterNodes[i] = createNode(); if (shouldLog) { parameterNodes[i].setTag(methodRef + ":" + i); } @@ -349,7 +352,7 @@ public class DependencyChecker implements DependencyInfo { if (methodRef.getDescriptor().getResultType() == ValueType.VOID) { resultNode = null; } else { - resultNode = new DependencyNode(this); + resultNode = createNode(); if (shouldLog) { resultNode.setTag(methodRef + ":RESULT"); } @@ -431,7 +434,7 @@ public class DependencyChecker implements DependencyInfo { } private FieldDependency createFieldNode(final FieldReference fieldRef, FieldReader field) { - DependencyNode node = new DependencyNode(this); + DependencyNode node = createNode(); if (shouldLog) { node.setTag(fieldRef.getClassName() + "#" + fieldRef.getFieldName()); } @@ -501,6 +504,7 @@ public class DependencyChecker implements DependencyInfo { index = 0; } } + return; } public T getService(Class type) { 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 cad81ed31..159d30425 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java @@ -15,6 +15,7 @@ */ package org.teavm.dependency; +import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -48,20 +49,29 @@ class DependencyGraphBuilder { } program = method.getProgram(); if (DependencyChecker.shouldLog) { - System.out.println("Method achieved: " + method.getReference()); + System.out.println("Method reached: " + method.getReference()); System.out.println(new ListingBuilder().buildListing(program, " ")); } resultNode = dep.getResult(); - DependencyNode[] origNodes = dep.getVariables(); DataFlowGraphBuilder dfgBuilder = new DataFlowGraphBuilder(); for (int i = 0; i < dep.getParameterCount(); ++i) { dfgBuilder.important(i); } - int[] nodeMapping = dfgBuilder.buildMapping(program, dep.getParameterCount()); - nodes = new DependencyNode[origNodes.length]; + int[] nodeMapping = dfgBuilder.buildMapping(program, dep.getParameterCount(), + !(method.getResultType() instanceof ValueType.Primitive) && method.getResultType() != ValueType.VOID); + int nodeClassCount = 0; + for (int i = 0; i < nodeMapping.length; ++i) { + nodeClassCount = Math.max(nodeClassCount, nodeMapping[i] + 1); + } + DependencyNode[] nodeClasses = Arrays.copyOf(dep.getVariables(), nodeClassCount); + for (int i = dep.getVariableCount(); i < nodeClasses.length; ++i) { + nodeClasses[i] = dependencyChecker.createNode(); + } + nodes = new DependencyNode[dep.getMethod().getProgram().variableCount()]; for (int i = 0; i < nodes.length; ++i) { - nodes[i] = origNodes[nodeMapping[i]]; + int mappedNode = nodeMapping[i]; + nodes[i] = mappedNode >= 0 ? nodeClasses[mappedNode] : null; } dep.setVariables(nodes); @@ -71,7 +81,11 @@ class DependencyGraphBuilder { block.readAllInstructions(reader); for (PhiReader phi : block.readPhis()) { for (IncomingReader incoming : phi.readIncomings()) { - nodes[incoming.getValue().getIndex()].connect(nodes[phi.getReceiver().getIndex()]); + DependencyNode incomingNode = nodes[incoming.getValue().getIndex()]; + DependencyNode receiverNode = nodes[phi.getReceiver().getIndex()]; + if (incomingNode != null || receiverNode != null) { + nodes[incoming.getValue().getIndex()].connect(nodes[phi.getReceiver().getIndex()]); + } } } for (TryCatchBlockReader tryCatch : block.readTryCatchBlocks()) { @@ -169,7 +183,9 @@ class DependencyGraphBuilder { methodDep.use(); DependencyNode[] targetParams = methodDep.getVariables(); for (int i = 0; i < parameters.length; ++i) { - parameters[i].connect(targetParams[i]); + if (parameters[i] != null) { + parameters[i].connect(targetParams[i]); + } } if (result != null && methodDep.getResult() != null) { methodDep.getResult().connect(result); @@ -211,7 +227,10 @@ class DependencyGraphBuilder { @Override public void classConstant(VariableReader receiver, ValueType cst) { - nodes[receiver.getIndex()].propagate(dependencyChecker.getType("java.lang.Class")); + DependencyNode node = nodes[receiver.getIndex()]; + if (node != null) { + node.propagate(dependencyChecker.getType("java.lang.Class")); + } while (cst instanceof ValueType.Array) { cst = ((ValueType.Array)cst).getItemType(); } @@ -243,7 +262,10 @@ class DependencyGraphBuilder { @Override public void stringConstant(VariableReader receiver, String cst) { - nodes[receiver.getIndex()].propagate(dependencyChecker.getType("java.lang.String")); + DependencyNode node = nodes[receiver.getIndex()]; + if (node != null) { + node.propagate(dependencyChecker.getType("java.lang.String")); + } MethodDependency method = dependencyChecker.linkMethod(new MethodReference(String.class, "", char[].class, void.class), new CallLocation(caller.getMethod(), currentLocation)); method.use(); @@ -262,7 +284,9 @@ class DependencyGraphBuilder { public void assign(VariableReader receiver, VariableReader assignee) { DependencyNode valueNode = nodes[assignee.getIndex()]; DependencyNode receiverNode = nodes[receiver.getIndex()]; - valueNode.connect(receiverNode); + if (valueNode != null && receiverNode != null) { + valueNode.connect(receiverNode); + } } @Override @@ -319,7 +343,10 @@ class DependencyGraphBuilder { @Override public void exit(VariableReader valueToReturn) { if (valueToReturn != null) { - nodes[valueToReturn.getIndex()].connect(resultNode); + DependencyNode node = nodes[valueToReturn.getIndex()]; + if (node != null) { + node.connect(resultNode); + } } } @@ -330,7 +357,10 @@ class DependencyGraphBuilder { @Override public void createArray(VariableReader receiver, ValueType itemType, VariableReader size) { - nodes[receiver.getIndex()].propagate(dependencyChecker.getType("[" + itemType)); + DependencyNode node = nodes[receiver.getIndex()]; + if (node != null) { + node.propagate(dependencyChecker.getType("[" + itemType)); + } String className = extractClassName(itemType); if (className != null) { dependencyChecker.linkClass(className, new CallLocation(caller.getMethod(), currentLocation)); @@ -361,6 +391,9 @@ class DependencyGraphBuilder { sb.append(itemTypeStr); DependencyNode node = nodes[receiver.getIndex()]; for (int i = 0; i < dimensions.size(); ++i) { + if (node == null) { + break; + } node.propagate(dependencyChecker.getType(sb.substring(i, sb.length()))); node = node.getArrayItem(); } @@ -373,25 +406,37 @@ class DependencyGraphBuilder { @Override public void create(VariableReader receiver, String type) { dependencyChecker.linkClass(type, new CallLocation(caller.getMethod(), currentLocation)); - nodes[receiver.getIndex()].propagate(dependencyChecker.getType(type)); + DependencyNode node = nodes[receiver.getIndex()]; + if (node != null) { + node.propagate(dependencyChecker.getType(type)); + } } @Override public void getField(VariableReader receiver, VariableReader instance, FieldReference field, ValueType fieldType) { - FieldDependency fieldDep = dependencyChecker.linkField(field, - new CallLocation(caller.getMethod(), currentLocation)); - DependencyNode receiverNode = nodes[receiver.getIndex()]; - fieldDep.getValue().connect(receiverNode); + if (!(fieldType instanceof ValueType.Primitive)) { + FieldDependency fieldDep = dependencyChecker.linkField(field, + new CallLocation(caller.getMethod(), currentLocation)); + DependencyNode receiverNode = nodes[receiver.getIndex()]; + if (receiverNode != null) { + fieldDep.getValue().connect(receiverNode); + } + } initClass(field.getClassName()); } @Override - public void putField(VariableReader instance, FieldReference field, VariableReader value) { - FieldDependency fieldDep = dependencyChecker.linkField(field, - new CallLocation(caller.getMethod(), currentLocation)); - DependencyNode valueNode = nodes[value.getIndex()]; - valueNode.connect(fieldDep.getValue()); + public void putField(VariableReader instance, FieldReference field, VariableReader value, + ValueType fieldType) { + if (!(fieldType instanceof ValueType.Primitive)) { + FieldDependency fieldDep = dependencyChecker.linkField(field, + new CallLocation(caller.getMethod(), currentLocation)); + DependencyNode valueNode = nodes[value.getIndex()]; + if (valueNode != null) { + valueNode.connect(fieldDep.getValue()); + } + } initClass(field.getClassName()); } @@ -403,33 +448,41 @@ class DependencyGraphBuilder { public void cloneArray(VariableReader receiver, VariableReader array) { DependencyNode arrayNode = nodes[array.getIndex()]; final DependencyNode receiverNode = nodes[receiver.getIndex()]; - arrayNode.addConsumer(new DependencyConsumer() { - @Override public void consume(DependencyType type) { - receiverNode.propagate(type); - } - }); - arrayNode.getArrayItem().connect(receiverNode.getArrayItem()); + if (arrayNode != null && receiverNode != null) { + arrayNode.addConsumer(new DependencyConsumer() { + @Override public void consume(DependencyType type) { + receiverNode.propagate(type); + } + }); + arrayNode.getArrayItem().connect(receiverNode.getArrayItem()); + } } @Override public void unwrapArray(VariableReader receiver, VariableReader array, ArrayElementType elementType) { DependencyNode arrayNode = nodes[array.getIndex()]; DependencyNode receiverNode = nodes[receiver.getIndex()]; - arrayNode.connect(receiverNode); + if (arrayNode != null && receiverNode != null) { + arrayNode.connect(receiverNode); + } } @Override public void getElement(VariableReader receiver, VariableReader array, VariableReader index) { DependencyNode arrayNode = nodes[array.getIndex()]; DependencyNode receiverNode = nodes[receiver.getIndex()]; - arrayNode.getArrayItem().connect(receiverNode); + if (arrayNode != null && receiverNode != null) { + arrayNode.getArrayItem().connect(receiverNode); + } } @Override public void putElement(VariableReader array, VariableReader index, VariableReader value) { DependencyNode valueNode = nodes[value.getIndex()]; DependencyNode arrayNode = nodes[array.getIndex()]; - valueNode.connect(arrayNode.getArrayItem()); + if (valueNode != null && arrayNode != null) { + valueNode.connect(arrayNode.getArrayItem()); + } } @Override @@ -460,13 +513,20 @@ class DependencyGraphBuilder { methodDep.use(); DependencyNode[] targetParams = methodDep.getVariables(); for (int i = 0; i < arguments.size(); ++i) { - nodes[arguments.get(i).getIndex()].connect(targetParams[i + 1]); + DependencyNode value = nodes[arguments.get(i).getIndex()]; + DependencyNode param = targetParams[i + 1]; + if (value != null && param != null) { + value.connect(param); + } } if (instance != null) { nodes[instance.getIndex()].connect(targetParams[0]); } if (methodDep.getResult() != null && receiver != null) { - methodDep.getResult().connect(nodes[receiver.getIndex()]); + DependencyNode receiverNode = nodes[receiver.getIndex()]; + if (methodDep.getResult() != null && receiverNode != null) { + methodDep.getResult().connect(receiverNode); + } } methodDep.getThrown().addConsumer(currentExceptionConsumer); initClass(method.getClassName()); diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyNode.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyNode.java index d5d4f8dbc..a4522c30b 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyNode.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyNode.java @@ -23,19 +23,21 @@ import java.util.*; */ public class DependencyNode implements ValueDependencyInfo { private DependencyChecker dependencyChecker; - private Set followers = new HashSet<>(); + private List followers; private BitSet types; - private Map transitions = new HashMap<>(); + private List transitions; private volatile String tag; private DependencyNode arrayItemNode; private int degree; + int index; - DependencyNode(DependencyChecker dependencyChecker) { - this(dependencyChecker, 0); + DependencyNode(DependencyChecker dependencyChecker, int index) { + this(dependencyChecker, index, 0); } - DependencyNode(DependencyChecker dependencyChecker, int degree) { + DependencyNode(DependencyChecker dependencyChecker, int index, int degree) { this.dependencyChecker = dependencyChecker; + this.index = index; this.degree = degree; } @@ -54,8 +56,10 @@ public class DependencyNode implements ValueDependencyInfo { if (DependencyChecker.shouldLog) { System.out.println(tag + " -> " + type.getName()); } - for (DependencyConsumer consumer : followers.toArray(new DependencyConsumer[followers.size()])) { - dependencyChecker.schedulePropagation(consumer, type); + if (followers != null) { + for (DependencyConsumer consumer : followers.toArray(new DependencyConsumer[followers.size()])) { + dependencyChecker.schedulePropagation(consumer, type); + } } } } @@ -81,13 +85,22 @@ public class DependencyNode implements ValueDependencyInfo { System.out.println(tag + " -> " + types[i].getName()); } } - for (DependencyConsumer consumer : followers.toArray(new DependencyConsumer[followers.size()])) { - dependencyChecker.schedulePropagation(consumer, Arrays.copyOf(types, j)); + if (followers != null) { + for (DependencyConsumer consumer : followers.toArray(new DependencyConsumer[followers.size()])) { + dependencyChecker.schedulePropagation(consumer, Arrays.copyOf(types, j)); + } } } public void addConsumer(DependencyConsumer consumer) { - if (followers.add(consumer) && this.types != null) { + if (followers == null) { + followers = new ArrayList<>(); + } + if (followers.contains(consumer)) { + return; + } + followers.add(consumer); + if (this.types != null) { List types = new ArrayList<>(); for (int index = this.types.nextSetBit(0); index >= 0; index = this.types.nextSetBit(index + 1)) { types.add(dependencyChecker.types.get(index)); @@ -100,14 +113,26 @@ public class DependencyNode implements ValueDependencyInfo { if (this == node) { return; } - DependencyNodeToNodeTransition transition = new DependencyNodeToNodeTransition(this, node, filter); - if (!transitions.containsKey(node)) { - transitions.put(node, transition); - if (DependencyChecker.shouldLog) { - System.out.println("Connecting " + tag + " to " + node.tag); - } - addConsumer(transition); + if (node == null) { + throw new IllegalArgumentException("Node must not be null"); } + if (transitions != null) { + for (DependencyNodeToNodeTransition transition : transitions) { + if (transition.destination == node) { + return; + } + } + } + DependencyNodeToNodeTransition transition = new DependencyNodeToNodeTransition(this, node, filter); + if (transitions == null) { + transitions = new ArrayList<>(); + } + + transitions.add(transition); + if (DependencyChecker.shouldLog) { + System.out.println("Connecting " + tag + " to " + node.tag); + } + addConsumer(transition); } public void connect(DependencyNode node) { @@ -117,7 +142,8 @@ public class DependencyNode implements ValueDependencyInfo { @Override public DependencyNode getArrayItem() { if (arrayItemNode == null) { - arrayItemNode = new DependencyNode(dependencyChecker, degree + 1); + arrayItemNode = new DependencyNode(dependencyChecker, dependencyChecker.nodes.size(), degree + 1); + dependencyChecker.nodes.add(arrayItemNode); if (DependencyChecker.shouldLog) { arrayItemNode.tag = tag + "["; } diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyNodeToNodeTransition.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyNodeToNodeTransition.java index 98543636e..e20b478cf 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyNodeToNodeTransition.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyNodeToNodeTransition.java @@ -20,8 +20,8 @@ package org.teavm.dependency; * @author Alexey Andreev */ class DependencyNodeToNodeTransition implements DependencyConsumer { - private DependencyNode source; - private DependencyNode destination; + DependencyNode source; + DependencyNode destination; private DependencyTypeFilter filter; public DependencyNodeToNodeTransition(DependencyNode source, DependencyNode destination, diff --git a/teavm-core/src/main/java/org/teavm/model/InstructionReadVisitor.java b/teavm-core/src/main/java/org/teavm/model/InstructionReadVisitor.java index 5d7627469..b5a8ff811 100644 --- a/teavm-core/src/main/java/org/teavm/model/InstructionReadVisitor.java +++ b/teavm-core/src/main/java/org/teavm/model/InstructionReadVisitor.java @@ -153,7 +153,7 @@ class InstructionReadVisitor implements InstructionVisitor { @Override public void visit(PutFieldInstruction insn) { - reader.putField(insn.getInstance(), insn.getField(), insn.getValue()); + reader.putField(insn.getInstance(), insn.getField(), insn.getValue(), insn.getFieldType()); } @Override diff --git a/teavm-core/src/main/java/org/teavm/model/MethodReference.java b/teavm-core/src/main/java/org/teavm/model/MethodReference.java index 66ab8a600..05092683c 100644 --- a/teavm-core/src/main/java/org/teavm/model/MethodReference.java +++ b/teavm-core/src/main/java/org/teavm/model/MethodReference.java @@ -99,6 +99,10 @@ public class MethodReference { return Arrays.copyOf(signature, signature.length); } + public ValueType getReturnType() { + return signature[signature.length - 1]; + } + public String getName() { return name; } diff --git a/teavm-core/src/main/java/org/teavm/model/instructions/InstructionReader.java b/teavm-core/src/main/java/org/teavm/model/instructions/InstructionReader.java index 2b022cf8b..afdea1647 100644 --- a/teavm-core/src/main/java/org/teavm/model/instructions/InstructionReader.java +++ b/teavm-core/src/main/java/org/teavm/model/instructions/InstructionReader.java @@ -79,7 +79,7 @@ public interface InstructionReader { void getField(VariableReader receiver, VariableReader instance, FieldReference field, ValueType fieldType); - void putField(VariableReader instance, FieldReference field, VariableReader value); + void putField(VariableReader instance, FieldReference field, VariableReader value, ValueType fieldType); void arrayLength(VariableReader receiver, VariableReader array); @@ -100,8 +100,8 @@ public interface InstructionReader { void initClass(String className); void nullCheck(VariableReader receiver, VariableReader value); - + void monitorEnter(VariableReader objectRef); - + void monitorExit(VariableReader objectRef); } diff --git a/teavm-core/src/main/java/org/teavm/model/instructions/PutFieldInstruction.java b/teavm-core/src/main/java/org/teavm/model/instructions/PutFieldInstruction.java index 016217576..6308e284f 100644 --- a/teavm-core/src/main/java/org/teavm/model/instructions/PutFieldInstruction.java +++ b/teavm-core/src/main/java/org/teavm/model/instructions/PutFieldInstruction.java @@ -17,6 +17,7 @@ package org.teavm.model.instructions; import org.teavm.model.FieldReference; import org.teavm.model.Instruction; +import org.teavm.model.ValueType; import org.teavm.model.Variable; /** @@ -27,6 +28,7 @@ public class PutFieldInstruction extends Instruction { private Variable instance; private FieldReference field; private Variable value; + private ValueType fieldType; public Variable getInstance() { return instance; @@ -52,6 +54,14 @@ public class PutFieldInstruction extends Instruction { this.value = value; } + public ValueType getFieldType() { + return fieldType; + } + + public void setFieldType(ValueType fieldType) { + this.fieldType = fieldType; + } + @Override public void acceptVisitor(InstructionVisitor visitor) { visitor.visit(this); diff --git a/teavm-core/src/main/java/org/teavm/model/util/AsyncMethodFinder.java b/teavm-core/src/main/java/org/teavm/model/util/AsyncMethodFinder.java index e882cbdf6..610b5ce6b 100644 --- a/teavm-core/src/main/java/org/teavm/model/util/AsyncMethodFinder.java +++ b/teavm-core/src/main/java/org/teavm/model/util/AsyncMethodFinder.java @@ -330,7 +330,8 @@ public class AsyncMethodFinder { } @Override - public void putField(VariableReader instance, FieldReference field, VariableReader value) { + public void putField(VariableReader instance, FieldReference field, VariableReader value, + ValueType fieldType) { } @Override diff --git a/teavm-core/src/main/java/org/teavm/model/util/InstructionStringifier.java b/teavm-core/src/main/java/org/teavm/model/util/InstructionStringifier.java index c3a2a1a54..812b354e7 100644 --- a/teavm-core/src/main/java/org/teavm/model/util/InstructionStringifier.java +++ b/teavm-core/src/main/java/org/teavm/model/util/InstructionStringifier.java @@ -280,7 +280,7 @@ public class InstructionStringifier implements InstructionReader { } @Override - public void putField(VariableReader instance, FieldReference field, VariableReader value) { + public void putField(VariableReader instance, FieldReference field, VariableReader value, ValueType fieldType) { if (instance != null) { sb.append("@").append(instance.getIndex()); } else { 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 4f5a2b80e..357bb68d1 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 @@ -398,11 +398,13 @@ public final class ProgramUtils { } @Override - public void putField(VariableReader instance, FieldReference field, VariableReader value) { + public void putField(VariableReader instance, FieldReference field, VariableReader value, + ValueType fieldType) { PutFieldInstruction insnCopy = new PutFieldInstruction(); insnCopy.setField(field); insnCopy.setInstance(instance != null ? copyVar(instance) : null); insnCopy.setValue(copyVar(value)); + insnCopy.setFieldType(fieldType); copy = insnCopy; copy.setLocation(location); } diff --git a/teavm-core/src/main/java/org/teavm/parsing/ProgramParser.java b/teavm-core/src/main/java/org/teavm/parsing/ProgramParser.java index 8a9f92ea4..a379c459a 100644 --- a/teavm-core/src/main/java/org/teavm/parsing/ProgramParser.java +++ b/teavm-core/src/main/java/org/teavm/parsing/ProgramParser.java @@ -1568,7 +1568,7 @@ public class ProgramParser implements VariableDebugInformation { addInstruction(insn); break; } - + } } @@ -1611,6 +1611,7 @@ public class ProgramParser implements VariableDebugInformation { insn.setInstance(getVariable(instance)); insn.setField(new FieldReference(ownerCls, name)); insn.setValue(getVariable(value)); + insn.setFieldType(ValueType.parse(desc)); addInstruction(insn); break; } diff --git a/teavm-core/src/main/java/org/teavm/tooling/ProgramSourceAggregator.java b/teavm-core/src/main/java/org/teavm/tooling/ProgramSourceAggregator.java index 9dc33d3d6..c2e5fb3bc 100644 --- a/teavm-core/src/main/java/org/teavm/tooling/ProgramSourceAggregator.java +++ b/teavm-core/src/main/java/org/teavm/tooling/ProgramSourceAggregator.java @@ -77,7 +77,8 @@ class ProgramSourceAggregator implements InstructionReader { @Override public void create(VariableReader receiver, String type) { } @Override public void getField(VariableReader receiver, VariableReader instance, FieldReference field, ValueType fieldType) { } - @Override public void putField(VariableReader instance, FieldReference field, VariableReader value) { } + @Override public void putField(VariableReader instance, FieldReference field, VariableReader value, + ValueType fieldType) { } @Override public void arrayLength(VariableReader receiver, VariableReader array) { } @Override public void cloneArray(VariableReader receiver, VariableReader array) { } @Override public void unwrapArray(VariableReader receiver, VariableReader array, ArrayElementType elementType) { } @@ -91,11 +92,11 @@ class ProgramSourceAggregator implements InstructionReader { @Override public void monitorEnter(VariableReader objectRef) { - + } @Override public void monitorExit(VariableReader objectRef) { - + } } From 3449257db7f4a48a3de61b5bba14f7527a783f1b Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Fri, 13 Mar 2015 22:48:24 +0300 Subject: [PATCH 58/69] Fix bugs in faster dependency algorithm --- .../dependency/DataFlowGraphBuilder.java | 2 ++ .../dependency/DependencyGraphBuilder.java | 26 +++++++++++++------ 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/teavm-core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java b/teavm-core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java index 882000dfc..8999690e4 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java @@ -299,11 +299,13 @@ public class DataFlowGraphBuilder implements InstructionReader { @Override public void getElement(VariableReader receiver, VariableReader array, VariableReader index) { + important(array.getIndex()); builder.addEdge(getArrayElementNode(array.getIndex()), receiver.getIndex()); } @Override public void putElement(VariableReader array, VariableReader index, VariableReader value) { + important(array.getIndex()); builder.addEdge(value.getIndex(), getArrayElementNode(array.getIndex())); } 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 159d30425..ed38a3f88 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java @@ -48,10 +48,6 @@ class DependencyGraphBuilder { return; } program = method.getProgram(); - if (DependencyChecker.shouldLog) { - System.out.println("Method reached: " + method.getReference()); - System.out.println(new ListingBuilder().buildListing(program, " ")); - } resultNode = dep.getResult(); DataFlowGraphBuilder dfgBuilder = new DataFlowGraphBuilder(); @@ -60,6 +56,17 @@ class DependencyGraphBuilder { } int[] nodeMapping = dfgBuilder.buildMapping(program, dep.getParameterCount(), !(method.getResultType() instanceof ValueType.Primitive) && method.getResultType() != ValueType.VOID); + + if (DependencyChecker.shouldLog) { + System.out.println("Method reached: " + method.getReference()); + System.out.print(new ListingBuilder().buildListing(program, " ")); + for (int i = 0; i < nodeMapping.length; ++i) { + System.out.print(i + ":" + nodeMapping[i] + " "); + } + System.out.println(); + System.out.println(); + } + int nodeClassCount = 0; for (int i = 0; i < nodeMapping.length; ++i) { nodeClassCount = Math.max(nodeClassCount, nodeMapping[i] + 1); @@ -67,6 +74,9 @@ class DependencyGraphBuilder { DependencyNode[] nodeClasses = Arrays.copyOf(dep.getVariables(), nodeClassCount); for (int i = dep.getVariableCount(); i < nodeClasses.length; ++i) { nodeClasses[i] = dependencyChecker.createNode(); + if (DependencyChecker.shouldLog) { + nodeClasses[i].setTag(dep.getMethod().getReference() + ":" + i); + } } nodes = new DependencyNode[dep.getMethod().getProgram().variableCount()]; for (int i = 0; i < nodes.length; ++i) { @@ -415,9 +425,9 @@ class DependencyGraphBuilder { @Override public void getField(VariableReader receiver, VariableReader instance, FieldReference field, ValueType fieldType) { + FieldDependency fieldDep = dependencyChecker.linkField(field, + new CallLocation(caller.getMethod(), currentLocation)); if (!(fieldType instanceof ValueType.Primitive)) { - FieldDependency fieldDep = dependencyChecker.linkField(field, - new CallLocation(caller.getMethod(), currentLocation)); DependencyNode receiverNode = nodes[receiver.getIndex()]; if (receiverNode != null) { fieldDep.getValue().connect(receiverNode); @@ -429,9 +439,9 @@ class DependencyGraphBuilder { @Override public void putField(VariableReader instance, FieldReference field, VariableReader value, ValueType fieldType) { + FieldDependency fieldDep = dependencyChecker.linkField(field, + new CallLocation(caller.getMethod(), currentLocation)); if (!(fieldType instanceof ValueType.Primitive)) { - FieldDependency fieldDep = dependencyChecker.linkField(field, - new CallLocation(caller.getMethod(), currentLocation)); DependencyNode valueNode = nodes[value.getIndex()]; if (valueNode != null) { valueNode.connect(fieldDep.getValue()); From 004cb79b17e535a6c23ed17a5a68267f11a3f95a Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Sat, 14 Mar 2015 15:34:13 +0300 Subject: [PATCH 59/69] Remove unnecessary debugging code --- .../java/org/teavm/common/IntegerStack.java | 2 +- .../dependency/DataFlowGraphBuilder.java | 180 ++++++++---------- .../teavm/dependency/DependencyChecker.java | 1 - .../dependency/DependencyGraphBuilder.java | 46 +++-- .../org/teavm/dependency/DependencyNode.java | 84 ++++++-- 5 files changed, 172 insertions(+), 141 deletions(-) diff --git a/teavm-core/src/main/java/org/teavm/common/IntegerStack.java b/teavm-core/src/main/java/org/teavm/common/IntegerStack.java index 24cbc528f..ccf8eab12 100644 --- a/teavm-core/src/main/java/org/teavm/common/IntegerStack.java +++ b/teavm-core/src/main/java/org/teavm/common/IntegerStack.java @@ -31,7 +31,7 @@ public class IntegerStack { public void push(int value) { if (head == buffer.length) { - buffer = Arrays.copyOf(buffer, buffer.length * 2); + buffer = Arrays.copyOf(buffer, Math.max(buffer.length * 2, 1)); } buffer[head++] = value; } diff --git a/teavm-core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java b/teavm-core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java index 8999690e4..f9c2b845c 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DataFlowGraphBuilder.java @@ -19,6 +19,7 @@ import com.carrotsearch.hppc.IntOpenHashSet; import com.carrotsearch.hppc.IntSet; import com.carrotsearch.hppc.ObjectIntMap; import com.carrotsearch.hppc.ObjectIntOpenHashMap; +import com.carrotsearch.hppc.cursors.IntCursor; import java.util.Arrays; import java.util.List; import org.teavm.common.*; @@ -32,95 +33,62 @@ import org.teavm.model.instructions.*; public class DataFlowGraphBuilder implements InstructionReader { private int lastIndex; private GraphBuilder builder = new GraphBuilder(); - private IntSet importantNodes = new IntOpenHashSet(); - private ObjectIntMap methodNodes = new ObjectIntOpenHashMap<>(); private ObjectIntMap fieldNodes = new ObjectIntOpenHashMap<>(); - private int[] arrayNodes; private int returnIndex = -1; private int exceptionIndex; + private DisjointSet classes = new DisjointSet(); + private int paramCount; + private IntSet escaping = new IntOpenHashSet(); - public void important(int node) { - importantNodes.add(node); + private void join(int a, int b) { + if (a < paramCount || b < paramCount) { + return; + } + classes.union(a, b); } - public int[] buildMapping(ProgramReader program, int paramCount, boolean needsReturn) { + public int[] buildMapping(ProgramReader program, boolean[] significantParams, boolean needsReturn) { lastIndex = program.variableCount(); - arrayNodes = new int[lastIndex]; + this.paramCount = significantParams.length; if (needsReturn) { returnIndex = lastIndex++; + escaping.add(returnIndex); } exceptionIndex = lastIndex++; - Arrays.fill(arrayNodes, -1); + for (int i = 0; i < lastIndex; ++i) { + classes.create(); + } + for (int i = 0; i < program.basicBlockCount(); ++i) { BasicBlockReader block = program.basicBlockAt(i); for (PhiReader phi : block.readPhis()) { for (IncomingReader incoming : phi.readIncomings()) { - builder.addEdge(incoming.getValue().getIndex(), phi.getReceiver().getIndex()); - } - } - for (TryCatchBlockReader tryCatch : block.readTryCatchBlocks()) { - if (tryCatch.getExceptionVariable() != null) { - important(tryCatch.getExceptionVariable().getIndex()); + int from = incoming.getValue().getIndex(); + int to = phi.getReceiver().getIndex(); + builder.addEdge(from, to); + join(from, to); } } block.readAllInstructions(this); } Graph graph = builder.build(); - - DisjointSet classes = new DisjointSet(); - for (int i = 0; i < lastIndex; ++i) { - classes.create(); - } - IntegerArray startNodes = new IntegerArray(graph.size()); - for (int i = paramCount; i < graph.size(); ++i) { - if (graph.incomingEdgesCount(i) == 0) { - startNodes.add(i); - } - for (int pred : graph.incomingEdges(i)) { - boolean predImportant = importantNodes.contains(classes.find(pred)); - boolean nodeImportant = importantNodes.contains(classes.find(i)); - if (predImportant && nodeImportant) { - continue; - } - int newCls = classes.union(pred, i); - if (nodeImportant || predImportant) { - importantNodes.add(newCls); - } - } - for (int succ : graph.outgoingEdges(i)) { - boolean succImportant = importantNodes.contains(classes.find(succ)); - boolean nodeImportant = importantNodes.contains(classes.find(i)); - if (succImportant && nodeImportant) { - continue; - } - int newCls = classes.union(succ, i); - if (nodeImportant || succImportant) { - importantNodes.add(newCls); - } - } - } - - int[][] sccs = GraphUtils.findStronglyConnectedComponents(graph, startNodes.getAll()); - for (int[] scc : sccs) { - int last = -1; - for (int node : scc) { - if (!importantNodes.contains(classes.find(node))) { - continue; - } - last = last < 0 ? node : classes.union(node, last); + for (int i = 0; i < paramCount; ++i) { + if (significantParams[i]) { + escaping.add(i); } } + propagateEscaping(graph); int[] classMap = new int[classes.size()]; Arrays.fill(classMap, -1); int[] result = new int[program.variableCount()]; int classCount = 0; for (int i = 0; i < program.variableCount(); ++i) { - int cls = classes.find(i); - if (!importantNodes.contains(cls)) { + if (!escaping.contains(i) && i >= significantParams.length) { result[i] = -1; continue; } + int cls = classes.find(i); int packedCls = classMap[cls]; if (packedCls < 0) { packedCls = classCount++; @@ -131,6 +99,32 @@ public class DataFlowGraphBuilder implements InstructionReader { return result; } + private void propagateEscaping(Graph graph) { + IntegerStack stack = new IntegerStack(graph.size()); + for (IntCursor node : escaping) { + stack.push(node.value); + } + escaping.clear(); + while (!stack.isEmpty()) { + int node = stack.pop(); + if (!escaping.add(node)) { + continue; + } + if (node < graph.size()) { + for (int pred : graph.incomingEdges(node)) { + if (!escaping.contains(pred)) { + stack.push(pred); + } + } + for (int succ : graph.outgoingEdges(node)) { + if (!escaping.contains(succ)) { + stack.push(succ); + } + } + } + } + } + @Override public void location(InstructionLocation location) { } @@ -176,15 +170,19 @@ public class DataFlowGraphBuilder implements InstructionReader { public void negate(VariableReader receiver, VariableReader operand, NumericOperandType type) { } + private void connect(int a, int b) { + builder.addEdge(a, b); + join(a, b); + } + @Override public void assign(VariableReader receiver, VariableReader assignee) { - builder.addEdge(assignee.getIndex(), receiver.getIndex()); + connect(assignee.getIndex(), receiver.getIndex()); } @Override public void cast(VariableReader receiver, VariableReader value, ValueType targetType) { builder.addEdge(value.getIndex(), receiver.getIndex()); - important(receiver.getIndex()); } @Override @@ -219,15 +217,14 @@ public class DataFlowGraphBuilder implements InstructionReader { @Override public void exit(VariableReader valueToReturn) { if (valueToReturn != null && returnIndex >= 0) { - important(returnIndex); - builder.addEdge(valueToReturn.getIndex(), returnIndex); + connect(valueToReturn.getIndex(), returnIndex); } } @Override public void raise(VariableReader exception) { builder.addEdge(exception.getIndex(), exceptionIndex); - important(exceptionIndex); + escaping.add(exceptionIndex); } @Override @@ -245,10 +242,10 @@ public class DataFlowGraphBuilder implements InstructionReader { private int getFieldNode(FieldReference field) { int fieldNode = fieldNodes.getOrDefault(field, -1); if (fieldNode < 0) { - fieldNode = lastIndex++; + fieldNode = classes.create(); fieldNodes.put(field, fieldNode); } - important(fieldNode); + escaping.add(fieldNode); return fieldNode; } @@ -257,8 +254,7 @@ public class DataFlowGraphBuilder implements InstructionReader { if (fieldType instanceof ValueType.Primitive) { return; } - int fieldNode = getFieldNode(field); - builder.addEdge(fieldNode, receiver.getIndex()); + connect(getFieldNode(field), receiver.getIndex()); } @Override @@ -266,8 +262,7 @@ public class DataFlowGraphBuilder implements InstructionReader { if (fieldType instanceof ValueType.Primitive) { return; } - int fieldNode = getFieldNode(field); - builder.addEdge(value.getIndex(), fieldNode); + connect(value.getIndex(), getFieldNode(field)); } @Override @@ -276,65 +271,40 @@ public class DataFlowGraphBuilder implements InstructionReader { @Override public void cloneArray(VariableReader receiver, VariableReader array) { - important(receiver.getIndex()); builder.addEdge(array.getIndex(), receiver.getIndex()); } @Override public void unwrapArray(VariableReader receiver, VariableReader array, ArrayElementType elementType) { if (elementType == ArrayElementType.OBJECT) { - builder.addEdge(array.getIndex(), receiver.getIndex()); + connect(array.getIndex(), receiver.getIndex()); } } - private int getArrayElementNode(int array) { - int node = arrayNodes[array]; - if (node < 0) { - node = lastIndex++; - arrayNodes[array] = node; - } - important(node); - return node; - } - @Override public void getElement(VariableReader receiver, VariableReader array, VariableReader index) { - important(array.getIndex()); - builder.addEdge(getArrayElementNode(array.getIndex()), receiver.getIndex()); + builder.addEdge(array.getIndex(), receiver.getIndex()); } @Override public void putElement(VariableReader array, VariableReader index, VariableReader value) { - important(array.getIndex()); - builder.addEdge(value.getIndex(), getArrayElementNode(array.getIndex())); - } - - private int getMethodNode(MethodReference method) { - int methodNode = methodNodes.getOrDefault(method, -1); - if (methodNode < 0) { - methodNode = lastIndex++; - methodNodes.put(method, methodNode); - } - important(methodNode); - return methodNode; + builder.addEdge(value.getIndex(), array.getIndex()); } @Override public void invoke(VariableReader receiver, VariableReader instance, MethodReference method, List arguments, InvocationType type) { - if (receiver != null) { - if (!(method.getReturnType() instanceof ValueType.Primitive)) { - builder.addEdge(getMethodNode(method), receiver.getIndex()); - } - } ValueType[] paramTypes = method.getParameterTypes(); for (int i = 0; i < paramTypes.length; ++i) { if (!(paramTypes[i] instanceof ValueType.Primitive)) { - important(arguments.get(i).getIndex()); + escaping.add(arguments.get(i).getIndex()); } } if (instance != null) { - important(instance.getIndex()); + escaping.add(instance.getIndex()); + } + if (receiver != null && !(method.getReturnType() instanceof ValueType.Primitive)) { + escaping.add(receiver.getIndex()); } } @@ -348,16 +318,16 @@ public class DataFlowGraphBuilder implements InstructionReader { @Override public void nullCheck(VariableReader receiver, VariableReader value) { - builder.addEdge(value.getIndex(), receiver.getIndex()); + connect(value.getIndex(), receiver.getIndex()); } @Override public void monitorEnter(VariableReader objectRef) { - important(objectRef.getIndex()); + escaping.add(objectRef.getIndex()); } @Override public void monitorExit(VariableReader objectRef) { - important(objectRef.getIndex()); + escaping.add(exceptionIndex); } } diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java index f2b9e96df..d0a1c9ddd 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java @@ -504,7 +504,6 @@ public class DependencyChecker implements DependencyInfo { index = 0; } } - return; } public T getService(Class type) { 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 ed38a3f88..02ce79b18 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java @@ -51,10 +51,15 @@ class DependencyGraphBuilder { resultNode = dep.getResult(); DataFlowGraphBuilder dfgBuilder = new DataFlowGraphBuilder(); - for (int i = 0; i < dep.getParameterCount(); ++i) { - dfgBuilder.important(i); + boolean[] significantParams = new boolean[dep.getParameterCount()]; + significantParams[0] = true; + for (int i = 1; i < dep.getParameterCount(); ++i) { + ValueType arg = method.parameterType(i - 1); + if (!(arg instanceof ValueType.Primitive)) { + significantParams[i] = true; + } } - int[] nodeMapping = dfgBuilder.buildMapping(program, dep.getParameterCount(), + int[] nodeMapping = dfgBuilder.buildMapping(program, significantParams, !(method.getResultType() instanceof ValueType.Primitive) && method.getResultType() != ValueType.VOID); if (DependencyChecker.shouldLog) { @@ -93,8 +98,8 @@ class DependencyGraphBuilder { for (IncomingReader incoming : phi.readIncomings()) { DependencyNode incomingNode = nodes[incoming.getValue().getIndex()]; DependencyNode receiverNode = nodes[phi.getReceiver().getIndex()]; - if (incomingNode != null || receiverNode != null) { - nodes[incoming.getValue().getIndex()].connect(nodes[phi.getReceiver().getIndex()]); + if (incomingNode != null && receiverNode != null) { + incomingNode.connect(receiverNode); } } } @@ -139,7 +144,9 @@ class DependencyGraphBuilder { for (int i = 0; i < exceptions.length; ++i) { if (exceptions[i] == null || isAssignableFrom(checker.getClassSource(), exceptions[i], type.getName())) { - vars[i].propagate(type); + if (vars[i] != null) { + vars[i].propagate(type); + } return; } } @@ -193,7 +200,7 @@ class DependencyGraphBuilder { methodDep.use(); DependencyNode[] targetParams = methodDep.getVariables(); for (int i = 0; i < parameters.length; ++i) { - if (parameters[i] != null) { + if (parameters[i] != null && targetParams[i] != null) { parameters[i].connect(targetParams[i]); } } @@ -307,18 +314,23 @@ class DependencyGraphBuilder { String targetClsName = ((ValueType.Object)targetType).getClassName(); final ClassReader targetClass = dependencyChecker.getClassSource().get(targetClsName); if (targetClass != null) { - valueNode.connect(receiverNode, new DependencyTypeFilter() { - @Override public boolean match(DependencyType type) { - if (targetClass.getName().equals("java.lang.Object")) { - return true; + if (valueNode != null && receiverNode != null) { + valueNode.connect(receiverNode, new DependencyTypeFilter() { + @Override public boolean match(DependencyType type) { + if (targetClass.getName().equals("java.lang.Object")) { + return true; + } + return isAssignableFrom(dependencyChecker.getClassSource(), targetClass, + type.getName()); } - return isAssignableFrom(dependencyChecker.getClassSource(), targetClass, type.getName()); - } - }); + }); + } return; } } - valueNode.connect(receiverNode); + if (valueNode != null && receiverNode != null) { + valueNode.connect(receiverNode); + } } @Override @@ -481,7 +493,7 @@ class DependencyGraphBuilder { public void getElement(VariableReader receiver, VariableReader array, VariableReader index) { DependencyNode arrayNode = nodes[array.getIndex()]; DependencyNode receiverNode = nodes[receiver.getIndex()]; - if (arrayNode != null && receiverNode != null) { + if (arrayNode != null && receiverNode != null && receiverNode != arrayNode.getArrayItem()) { arrayNode.getArrayItem().connect(receiverNode); } } @@ -490,7 +502,7 @@ class DependencyGraphBuilder { public void putElement(VariableReader array, VariableReader index, VariableReader value) { DependencyNode valueNode = nodes[value.getIndex()]; DependencyNode arrayNode = nodes[array.getIndex()]; - if (valueNode != null && arrayNode != null) { + if (valueNode != null && arrayNode != null && valueNode != arrayNode.getArrayItem()) { valueNode.connect(arrayNode.getArrayItem()); } } diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyNode.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyNode.java index a4522c30b..374040f23 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyNode.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyNode.java @@ -24,6 +24,7 @@ import java.util.*; public class DependencyNode implements ValueDependencyInfo { private DependencyChecker dependencyChecker; private List followers; + private int[] smallTypes; private BitSet types; private List transitions; private volatile String tag; @@ -41,6 +42,38 @@ public class DependencyNode implements ValueDependencyInfo { this.degree = degree; } + private boolean addType(DependencyType type) { + if (types == null) { + if (smallTypes == null) { + smallTypes = new int[] { type.index }; + return true; + } + } + if (smallTypes != null) { + for (int i = 0; i < smallTypes.length; ++i) { + if (smallTypes[i] == type.index) { + return false; + } + } + if (smallTypes.length == 5) { + types = new BitSet(); + for (int existingType : smallTypes) { + types.set(existingType); + } + smallTypes = null; + } else { + smallTypes = Arrays.copyOf(smallTypes, smallTypes.length + 1); + smallTypes[smallTypes.length - 1] = type.index; + return true; + } + } + if (!types.get(type.index)) { + types.set(type.index); + return true; + } + return false; + } + public void propagate(DependencyType type) { if (type.getDependencyChecker() != dependencyChecker) { throw new IllegalArgumentException("The given type does not belong to the same dependency checker"); @@ -48,11 +81,7 @@ public class DependencyNode implements ValueDependencyInfo { if (degree > 2) { return; } - if (types == null) { - types = new BitSet(); - } - if (!types.get(type.index)) { - types.set(type.index); + if (addType(type)) { if (DependencyChecker.shouldLog) { System.out.println(tag + " -> " + type.getName()); } @@ -64,30 +93,30 @@ public class DependencyNode implements ValueDependencyInfo { } } - public void propagate(DependencyType[] agentTypes) { - DependencyType[] types = new DependencyType[agentTypes.length]; + public void propagate(DependencyType[] newTypes) { + DependencyType[] types = new DependencyType[newTypes.length]; int j = 0; - for (int i = 0; i < agentTypes.length; ++i) { - DependencyType type = agentTypes[i]; + for (int i = 0; i < newTypes.length; ++i) { + DependencyType type = newTypes[i]; if (type.getDependencyChecker() != dependencyChecker) { throw new IllegalArgumentException("The given type does not belong to the same dependency checker"); } - if (this.types == null || !this.types.get(type.index)) { + if (addType(type)) { types[j++] = type; } } - if (this.types == null) { - this.types = new BitSet(); + if (j == 0) { + return; } - for (int i = 0; i < j; ++i) { - this.types.set(types[i].index); - if (DependencyChecker.shouldLog) { + if (DependencyChecker.shouldLog) { + for (int i = 0; i < j; ++i) { System.out.println(tag + " -> " + types[i].getName()); } } if (followers != null) { + types = Arrays.copyOf(types, j); for (DependencyConsumer consumer : followers.toArray(new DependencyConsumer[followers.size()])) { - dependencyChecker.schedulePropagation(consumer, Arrays.copyOf(types, j)); + dependencyChecker.schedulePropagation(consumer, types); } } } @@ -106,6 +135,12 @@ public class DependencyNode implements ValueDependencyInfo { types.add(dependencyChecker.types.get(index)); } dependencyChecker.schedulePropagation(consumer, types.toArray(new DependencyType[types.size()])); + } else if (this.smallTypes != null) { + DependencyType[] types = new DependencyType[smallTypes.length]; + for (int i = 0; i < types.length; ++i) { + types[i] = dependencyChecker.types.get(smallTypes[i]); + } + dependencyChecker.schedulePropagation(consumer, types); } } @@ -158,10 +193,18 @@ public class DependencyNode implements ValueDependencyInfo { @Override public boolean hasArrayType() { - return arrayItemNode != null && arrayItemNode.types != null && !arrayItemNode.types.isEmpty(); + return arrayItemNode != null && (arrayItemNode.types != null || arrayItemNode.smallTypes != null); } public boolean hasType(DependencyType type) { + if (smallTypes != null) { + for (int i = 0; i < smallTypes.length; ++i) { + if (smallTypes[i] == type.index) { + return true; + } + } + return false; + } return types != null && type.getDependencyChecker() == dependencyChecker && types.get(type.index); } @@ -172,6 +215,13 @@ public class DependencyNode implements ValueDependencyInfo { @Override public String[] getTypes() { + if (smallTypes != null) { + String[] result = new String[smallTypes.length]; + for (int i = 0; i < result.length; ++i) { + result[i] = dependencyChecker.types.get(smallTypes[i]).getName(); + } + return result; + } if (types == null) { return new String[0]; } From cff5460ac3fc9c4660a2c37682b102588d3e5df3 Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Sat, 14 Mar 2015 15:59:29 +0300 Subject: [PATCH 60/69] Add interactive mode to CLI. Improve CLI --- .../main/java/org/teavm/cli/TeaVMRunner.java | 111 ++++++++++++++++-- 1 file changed, 103 insertions(+), 8 deletions(-) diff --git a/teavm-cli/src/main/java/org/teavm/cli/TeaVMRunner.java b/teavm-cli/src/main/java/org/teavm/cli/TeaVMRunner.java index 9ce31c34e..579033f7f 100644 --- a/teavm-cli/src/main/java/org/teavm/cli/TeaVMRunner.java +++ b/teavm-cli/src/main/java/org/teavm/cli/TeaVMRunner.java @@ -15,16 +15,24 @@ */ package org.teavm.cli; -import java.io.File; +import java.io.*; import org.apache.commons.cli.*; import org.teavm.tooling.RuntimeCopyOperation; import org.teavm.tooling.TeaVMTool; +import org.teavm.tooling.TeaVMToolException; +import org.teavm.vm.TeaVMPhase; +import org.teavm.vm.TeaVMProgressFeedback; +import org.teavm.vm.TeaVMProgressListener; /** * * @author Alexey Andreev */ public final class TeaVMRunner { + private static long startTime; + private static long phaseStartTime; + private static TeaVMPhase currentPhase; + private TeaVMRunner() { } @@ -78,6 +86,10 @@ public final class TeaVMRunner { .withDescription("Incremental build cache directory") .withLongOpt("cachedir") .create('c')); + options.addOption(OptionBuilder + .withDescription("Wait for command after compilation, in order to enable hot recompilation") + .withLongOpt("--wait") + .create('w')); if (args.length == 0) { printUsage(options); @@ -139,6 +151,7 @@ public final class TeaVMRunner { } else { tool.setCacheDirectory(new File(tool.getTargetDirectory(), "teavm-cache")); } + boolean interactive = commandLine.hasOption('w'); args = commandLine.getArgs(); if (args.length > 1) { System.err.println("Unexpected arguments"); @@ -149,16 +162,98 @@ public final class TeaVMRunner { } tool.setLog(new ConsoleTeaVMToolLog()); tool.getProperties().putAll(System.getProperties()); + tool.setProgressListener(progressListener); - try { - tool.generate(); - } catch (Exception e) { - e.printStackTrace(System.err); - System.exit(-2); + if (interactive) { + boolean quit = false; + BufferedReader reader; + try { + reader = new BufferedReader(new InputStreamReader(System.in, "UTF-8")); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + System.exit(-2); + return; + } + do { + try { + build(tool); + } catch (Exception e) { + e.printStackTrace(System.err); + } + System.out.println("Press enter to repeat or enter 'q' to quit"); + try { + String line = reader.readLine().trim(); + if (!line.isEmpty()) { + if (line.equals("q")) { + quit = true; + } else { + System.out.println("Unrecognized command"); + } + } + } catch (IOException e) { + e.printStackTrace(); + System.exit(-2); + } + } while (!quit); + } else { + try { + build(tool); + } catch (Exception e) { + e.printStackTrace(System.err); + System.exit(-2); + } + if (!tool.getProblemProvider().getSevereProblems().isEmpty()) { + System.exit(-2); + } } - if (!tool.getProblemProvider().getSevereProblems().isEmpty()) { - System.exit(-2); + } + + private static void build(TeaVMTool tool) throws TeaVMToolException { + currentPhase = null; + startTime = System.currentTimeMillis(); + phaseStartTime = System.currentTimeMillis(); + tool.generate(); + reportPhaseComplete(); + System.out.println("Build complete for " + ((System.currentTimeMillis() - startTime) / 1000.0) + " seconds"); + } + + private static TeaVMProgressListener progressListener = new TeaVMProgressListener() { + @Override + public TeaVMProgressFeedback progressReached(int progress) { + return TeaVMProgressFeedback.CONTINUE; } + @Override + public TeaVMProgressFeedback phaseStarted(TeaVMPhase phase, int count) { + if (currentPhase != phase) { + if (currentPhase != null) { + reportPhaseComplete(); + } + phaseStartTime = System.currentTimeMillis(); + switch (phase) { + case DEPENDENCY_CHECKING: + System.out.print("Finding methods to decompile..."); + break; + case LINKING: + System.out.print("Linking methods..."); + break; + case DEVIRTUALIZATION: + System.out.print("Applying devirtualization..."); + break; + case DECOMPILATION: + System.out.print("Decompiling..."); + break; + case RENDERING: + System.out.print("Generating output..."); + break; + } + currentPhase = phase; + } + return TeaVMProgressFeedback.CONTINUE; + } + }; + + private static void reportPhaseComplete() { + System.out.println(" complete for " + ((System.currentTimeMillis() - phaseStartTime) / 1000.0) + " seconds"); } private static void printUsage(Options options) { From 73998d57a91c8bd492e60e5bc3cafe1ab8ed32b7 Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Sat, 14 Mar 2015 16:11:12 +0300 Subject: [PATCH 61/69] Add option to specify extra classpath --- .../main/java/org/teavm/cli/TeaVMRunner.java | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/teavm-cli/src/main/java/org/teavm/cli/TeaVMRunner.java b/teavm-cli/src/main/java/org/teavm/cli/TeaVMRunner.java index 579033f7f..86bd95a9a 100644 --- a/teavm-cli/src/main/java/org/teavm/cli/TeaVMRunner.java +++ b/teavm-cli/src/main/java/org/teavm/cli/TeaVMRunner.java @@ -16,6 +16,9 @@ package org.teavm.cli; import java.io.*; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; import org.apache.commons.cli.*; import org.teavm.tooling.RuntimeCopyOperation; import org.teavm.tooling.TeaVMTool; @@ -32,6 +35,7 @@ public final class TeaVMRunner { private static long startTime; private static long phaseStartTime; private static TeaVMPhase currentPhase; + private static String[] classPath; private TeaVMRunner() { } @@ -90,6 +94,12 @@ public final class TeaVMRunner { .withDescription("Wait for command after compilation, in order to enable hot recompilation") .withLongOpt("--wait") .create('w')); + options.addOption(OptionBuilder + .withArgName("classpath") + .hasArgs() + .withDescription("Additional classpath that will be reloaded by TeaVM each time in wait mode") + .withLongOpt("--classpath") + .create('p')); if (args.length == 0) { printUsage(options); @@ -151,6 +161,9 @@ public final class TeaVMRunner { } else { tool.setCacheDirectory(new File(tool.getTargetDirectory(), "teavm-cache")); } + if (commandLine.hasOption('p')) { + classPath = commandLine.getOptionValues('p'); + } boolean interactive = commandLine.hasOption('w'); args = commandLine.getArgs(); if (args.length > 1) { @@ -209,6 +222,7 @@ public final class TeaVMRunner { } private static void build(TeaVMTool tool) throws TeaVMToolException { + resetClassLoader(tool); currentPhase = null; startTime = System.currentTimeMillis(); phaseStartTime = System.currentTimeMillis(); @@ -217,6 +231,24 @@ public final class TeaVMRunner { System.out.println("Build complete for " + ((System.currentTimeMillis() - startTime) / 1000.0) + " seconds"); } + private static void resetClassLoader(TeaVMTool tool) { + if (classPath.length == 0) { + return; + } + URL[] urls = new URL[classPath.length]; + for (int i = 0; i < classPath.length; ++i) { + try { + urls[i] = new File(classPath[i]).toURI().toURL(); + } catch (MalformedURLException e) { + System.err.println("Illegal classpath entry: " + classPath[i]); + System.exit(-1); + return; + } + } + + tool.setClassLoader(new URLClassLoader(urls, TeaVMRunner.class.getClassLoader())); + } + private static TeaVMProgressListener progressListener = new TeaVMProgressListener() { @Override public TeaVMProgressFeedback progressReached(int progress) { From f17433aeab7b8f3097349fb11c30cee1061209fe Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Sat, 14 Mar 2015 21:18:16 +0300 Subject: [PATCH 62/69] Attempt to increase performance of JS by separating variables of different types --- .../main/java/org/teavm/cli/TeaVMRunner.java | 2 +- .../java/org/teavm/model/MethodReference.java | 7 + .../org/teavm/model/util/GraphColorer.java | 21 +- .../teavm/model/util/RegisterAllocator.java | 23 +- .../org/teavm/model/util/TypeInferer.java | 397 ++++++++++++++++++ .../org/teavm/model/util/VariableType.java | 36 ++ 6 files changed, 483 insertions(+), 3 deletions(-) create mode 100644 teavm-core/src/main/java/org/teavm/model/util/TypeInferer.java create mode 100644 teavm-core/src/main/java/org/teavm/model/util/VariableType.java diff --git a/teavm-cli/src/main/java/org/teavm/cli/TeaVMRunner.java b/teavm-cli/src/main/java/org/teavm/cli/TeaVMRunner.java index 86bd95a9a..3d93428f7 100644 --- a/teavm-cli/src/main/java/org/teavm/cli/TeaVMRunner.java +++ b/teavm-cli/src/main/java/org/teavm/cli/TeaVMRunner.java @@ -232,7 +232,7 @@ public final class TeaVMRunner { } private static void resetClassLoader(TeaVMTool tool) { - if (classPath.length == 0) { + if (classPath == null || classPath.length == 0) { return; } URL[] urls = new URL[classPath.length]; diff --git a/teavm-core/src/main/java/org/teavm/model/MethodReference.java b/teavm-core/src/main/java/org/teavm/model/MethodReference.java index 05092683c..9c34fff4d 100644 --- a/teavm-core/src/main/java/org/teavm/model/MethodReference.java +++ b/teavm-core/src/main/java/org/teavm/model/MethodReference.java @@ -91,6 +91,13 @@ public class MethodReference { return signature.length - 1; } + public ValueType parameterType(int index) { + if (index >= signature.length + 1) { + throw new IndexOutOfBoundsException("Index " + index + " is greater than size " + (signature.length - 1)); + } + return signature[index]; + } + public ValueType[] getParameterTypes() { return Arrays.copyOf(signature, signature.length - 1); } diff --git a/teavm-core/src/main/java/org/teavm/model/util/GraphColorer.java b/teavm-core/src/main/java/org/teavm/model/util/GraphColorer.java index 66404b645..1234de0c3 100644 --- a/teavm-core/src/main/java/org/teavm/model/util/GraphColorer.java +++ b/teavm-core/src/main/java/org/teavm/model/util/GraphColorer.java @@ -17,6 +17,7 @@ package org.teavm.model.util; import java.util.BitSet; import java.util.List; +import org.teavm.common.IntegerArray; import org.teavm.common.MutableGraphEdge; import org.teavm.common.MutableGraphNode; @@ -26,6 +27,11 @@ import org.teavm.common.MutableGraphNode; */ class GraphColorer { public void colorize(List graph, int[] colors) { + colorize(graph, colors, new int[graph.size()]); + } + + public void colorize(List graph, int[] colors, int[] categories) { + IntegerArray colorCategories = new IntegerArray(graph.size()); BitSet usedColors = new BitSet(); for (int v : getOrdering(graph)) { if (colors[v] >= 0) { @@ -39,7 +45,20 @@ class GraphColorer { usedColors.set(colors[succ]); } } - colors[v] = usedColors.nextClearBit(0); + int color = 0; + while (true) { + color = usedColors.nextClearBit(color); + while (colorCategories.size() <= color) { + colorCategories.add(-1); + } + int category = colorCategories.get(color); + if (category < 0 || category == categories[v]) { + colors[v] = color; + colorCategories.set(color, categories[v]); + break; + } + ++color; + } } } diff --git a/teavm-core/src/main/java/org/teavm/model/util/RegisterAllocator.java b/teavm-core/src/main/java/org/teavm/model/util/RegisterAllocator.java index 54f2497d6..8908915fa 100644 --- a/teavm-core/src/main/java/org/teavm/model/util/RegisterAllocator.java +++ b/teavm-core/src/main/java/org/teavm/model/util/RegisterAllocator.java @@ -46,12 +46,33 @@ public class RegisterAllocator { } renameInterferenceGraph(interferenceGraph, congruenceClasses, classArray); GraphColorer colorer = new GraphColorer(); - colorer.colorize(interferenceGraph, colors); + + int maxClass = 0; + for (int cls : classArray) { + maxClass = Math.max(maxClass, cls + 1); + } + int[] categories = getVariableCategories(program, method.getReference()); + int[] classCategories = new int[maxClass]; + for (int i = 0; i < categories.length; ++i) { + classCategories[classArray[i]] = categories[i]; + } + colorer.colorize(interferenceGraph, colors, classCategories); for (int i = 0; i < colors.length; ++i) { program.variableAt(i).setRegister(colors[i]); } } + private int[] getVariableCategories(ProgramReader program, MethodReference method) { + TypeInferer inferer = new TypeInferer(); + inferer.inferTypes(program, method); + int[] categories = new int[program.variableCount()]; + for (int i = 0; i < program.variableCount(); ++i) { + VariableType type = inferer.typeOf(i); + categories[i] = type != null ? type.ordinal() : 255; + } + return categories; + } + private static void joinClassNodes(List graph, DisjointSet classes) { int sz = graph.size(); for (int i = 0; i < sz; ++i) { diff --git a/teavm-core/src/main/java/org/teavm/model/util/TypeInferer.java b/teavm-core/src/main/java/org/teavm/model/util/TypeInferer.java new file mode 100644 index 000000000..860b00f8e --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/model/util/TypeInferer.java @@ -0,0 +1,397 @@ +/* + * Copyright 2015 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.model.util; + +import java.util.List; +import org.teavm.common.Graph; +import org.teavm.common.GraphBuilder; +import org.teavm.common.IntegerStack; +import org.teavm.model.*; +import org.teavm.model.instructions.*; + +/** + * + * @author Alexey Andreev + */ +public class TypeInferer { + VariableType[] types; + GraphBuilder builder; + GraphBuilder arrayElemBuilder; + + public void inferTypes(ProgramReader program, MethodReference method) { + int sz = Math.max(method.parameterCount(), program.variableCount()); + types = new VariableType[sz]; + + types[0] = VariableType.OBJECT; + for (int i = 0; i < method.parameterCount(); ++i) { + ValueType param = method.parameterType(i); + types[i + 1] = convert(param); + } + + builder = new GraphBuilder(sz); + arrayElemBuilder = new GraphBuilder(sz); + for (int i = 0; i < program.basicBlockCount(); ++i) { + BasicBlockReader block = program.basicBlockAt(i); + block.readAllInstructions(reader); + for (PhiReader phi : block.readPhis()) { + for (IncomingReader incoming : phi.readIncomings()) { + builder.addEdge(incoming.getValue().getIndex(), phi.getReceiver().getIndex()); + } + } + for (TryCatchBlockReader tryCatch : block.readTryCatchBlocks()) { + if (tryCatch.getExceptionVariable() != null) { + types[tryCatch.getExceptionVariable().getIndex()] = VariableType.OBJECT; + } + } + } + + IntegerStack stack = new IntegerStack(sz); + Graph graph = builder.build(); + Graph arrayElemGraph = builder.build(); + for (int i = 0; i < sz; ++i) { + if ((i >= graph.size() || graph.incomingEdgesCount(i) == 0) && + (i >= arrayElemGraph.size() || arrayElemGraph.incomingEdgesCount(i) == 0)) { + stack.push(i); + } + } + + boolean[] visited = new boolean[sz]; + while (!stack.isEmpty()) { + int node = stack.pop(); + if (visited[node]) { + continue; + } + visited[node] = true; + if (types[node] == null) { + for (int pred : graph.incomingEdges(node)) { + if (types[pred] != null) { + types[node] = types[pred]; + break; + } + } + } + if (types[node] == null) { + for (int pred : arrayElemGraph.incomingEdges(node)) { + if (types[pred] != null) { + types[node] = convertFromArray(types[pred]); + break; + } + } + } + for (int succ : graph.outgoingEdges(node)) { + if (!visited[succ]) { + stack.push(succ); + } + } + for (int succ : arrayElemGraph.outgoingEdges(node)) { + if (!visited[succ]) { + stack.push(succ); + } + } + } + } + + public VariableType typeOf(int variableIndex) { + return types[variableIndex]; + } + + VariableType convert(ValueType type) { + if (type instanceof ValueType.Primitive) { + switch (((ValueType.Primitive)type).getKind()) { + case BOOLEAN: + case BYTE: + case SHORT: + case CHARACTER: + case INTEGER: + return VariableType.INT; + case FLOAT: + return VariableType.FLOAT; + case DOUBLE: + return VariableType.DOUBLE; + case LONG: + return VariableType.LONG; + } + } else if (type instanceof ValueType.Array) { + ValueType item = ((ValueType.Array)type).getItemType(); + return convertArray(item); + } + return VariableType.OBJECT; + } + + VariableType convertFromArray(VariableType type) { + switch (type) { + case BYTE_ARRAY: + case SHORT_ARRAY: + case CHAR_ARRAY: + case INT_ARRAY: + return VariableType.INT; + case LONG_ARRAY: + return VariableType.LONG; + case FLOAT_ARRAY: + return VariableType.FLOAT; + case DOUBLE_ARRAY: + return VariableType.DOUBLE; + default: + return VariableType.OBJECT; + } + } + + VariableType convert(ArrayElementType type) { + switch (type) { + case BYTE: + return VariableType.BYTE_ARRAY; + case CHAR: + return VariableType.CHAR_ARRAY; + case SHORT: + return VariableType.SHORT_ARRAY; + case INT: + return VariableType.INT_ARRAY; + case LONG: + return VariableType.LONG_ARRAY; + case FLOAT: + return VariableType.FLOAT_ARRAY; + case DOUBLE: + return VariableType.DOUBLE_ARRAY; + case OBJECT: + return VariableType.OBJECT_ARRAY; + default: + throw new AssertionError(); + } + } + + VariableType convert(NumericOperandType type) { + switch (type) { + case INT: + return VariableType.INT; + case LONG: + return VariableType.LONG; + case FLOAT: + return VariableType.FLOAT; + case DOUBLE: + return VariableType.DOUBLE; + default: + throw new AssertionError(); + } + } + + VariableType convertArray(ValueType type) { + if (type instanceof ValueType.Primitive) { + switch (((ValueType.Primitive)type).getKind()) { + case BOOLEAN: + case BYTE: + return VariableType.BYTE_ARRAY; + case SHORT: + return VariableType.SHORT_ARRAY; + case CHARACTER: + return VariableType.CHAR_ARRAY; + case INTEGER: + return VariableType.INT_ARRAY; + case FLOAT: + return VariableType.FLOAT_ARRAY; + case DOUBLE: + return VariableType.DOUBLE_ARRAY; + case LONG: + return VariableType.LONG_ARRAY; + } + } + return VariableType.OBJECT_ARRAY; + } + + InstructionReader reader = new InstructionReader() { + @Override + public void unwrapArray(VariableReader receiver, VariableReader array, ArrayElementType elementType) { + types[receiver.getIndex()] = convert(elementType); + } + + @Override + public void stringConstant(VariableReader receiver, String cst) { + types[receiver.getIndex()] = VariableType.OBJECT; + } + + @Override + public void raise(VariableReader exception) { + } + + @Override + public void putField(VariableReader instance, FieldReference field, VariableReader value, ValueType fieldType) { + } + + @Override + public void putElement(VariableReader array, VariableReader index, VariableReader value) { + } + + @Override + public void nullConstant(VariableReader receiver) { + types[receiver.getIndex()] = VariableType.OBJECT; + } + + @Override + public void nullCheck(VariableReader receiver, VariableReader value) { + builder.addEdge(value.getIndex(), receiver.getIndex()); + } + + @Override + public void nop() { + } + + @Override + public void negate(VariableReader receiver, VariableReader operand, NumericOperandType type) { + types[receiver.getIndex()] = convert(type); + } + + @Override + public void monitorExit(VariableReader objectRef) { + } + + @Override + public void monitorEnter(VariableReader objectRef) { + } + + @Override + public void longConstant(VariableReader receiver, long cst) { + types[receiver.getIndex()] = VariableType.LONG; + } + + @Override + public void location(InstructionLocation location) { + } + + @Override + public void jumpIf(BinaryBranchingCondition cond, VariableReader first, VariableReader second, + BasicBlockReader consequent, BasicBlockReader alternative) { + } + + @Override + public void jumpIf(BranchingCondition cond, VariableReader operand, BasicBlockReader consequent, + BasicBlockReader alternative) { + } + + @Override + public void jump(BasicBlockReader target) { + } + + @Override + public void isInstance(VariableReader receiver, VariableReader value, ValueType type) { + types[receiver.getIndex()] = VariableType.INT; + } + + @Override + public void invoke(VariableReader receiver, VariableReader instance, MethodReference method, + List arguments, InvocationType type) { + if (receiver != null) { + types[receiver.getIndex()] = convert(method.getReturnType()); + } + } + + @Override + public void integerConstant(VariableReader receiver, int cst) { + types[receiver.getIndex()] = VariableType.INT; + } + + @Override + public void initClass(String className) { + } + + @Override + public void getField(VariableReader receiver, VariableReader instance, FieldReference field, + ValueType fieldType) { + types[receiver.getIndex()] = convert(fieldType); + } + + @Override + public void getElement(VariableReader receiver, VariableReader array, VariableReader index) { + arrayElemBuilder.addEdge(array.getIndex(), receiver.getIndex()); + } + + @Override + public void floatConstant(VariableReader receiver, float cst) { + types[receiver.getIndex()] = VariableType.FLOAT; + } + + @Override + public void exit(VariableReader valueToReturn) { + } + + @Override + public void doubleConstant(VariableReader receiver, double cst) { + types[receiver.getIndex()] = VariableType.DOUBLE; + } + + @Override + public void createArray(VariableReader receiver, ValueType itemType, + List dimensions) { + types[receiver.getIndex()] = convert(ValueType.arrayOf(itemType)); + } + + @Override + public void createArray(VariableReader receiver, ValueType itemType, VariableReader size) { + types[receiver.getIndex()] = convert(ValueType.arrayOf(itemType)); + } + + @Override + public void create(VariableReader receiver, String type) { + types[receiver.getIndex()] = VariableType.OBJECT; + } + + @Override + public void cloneArray(VariableReader receiver, VariableReader array) { + builder.addEdge(array.getIndex(), receiver.getIndex()); + } + + @Override + public void classConstant(VariableReader receiver, ValueType cst) { + types[receiver.getIndex()] = VariableType.OBJECT; + } + + @Override + public void choose(VariableReader condition, List table, + BasicBlockReader defaultTarget) { + } + + @Override + public void cast(VariableReader receiver, VariableReader value, IntegerSubtype type, + CastIntegerDirection targetType) { + types[receiver.getIndex()] = VariableType.INT; + } + + @Override + public void cast(VariableReader receiver, VariableReader value, NumericOperandType sourceType, + NumericOperandType targetType) { + types[receiver.getIndex()] = convert(targetType); + } + + @Override + public void cast(VariableReader receiver, VariableReader value, ValueType targetType) { + types[receiver.getIndex()] = convert(targetType); + } + + @Override + public void binary(BinaryOperation op, VariableReader receiver, VariableReader first, VariableReader second, + NumericOperandType type) { + types[receiver.getIndex()] = convert(type); + } + + @Override + public void assign(VariableReader receiver, VariableReader assignee) { + builder.addEdge(assignee.getIndex(), receiver.getIndex()); + } + + @Override + public void arrayLength(VariableReader receiver, VariableReader array) { + types[receiver.getIndex()] = VariableType.INT; + } + }; +} diff --git a/teavm-core/src/main/java/org/teavm/model/util/VariableType.java b/teavm-core/src/main/java/org/teavm/model/util/VariableType.java new file mode 100644 index 000000000..8b7cfe8ad --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/model/util/VariableType.java @@ -0,0 +1,36 @@ +/* + * Copyright 2015 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.model.util; + +/** + * + * @author Alexey Andreev + */ +public enum VariableType { + INT, + LONG, + FLOAT, + DOUBLE, + OBJECT, + BYTE_ARRAY, + SHORT_ARRAY, + CHAR_ARRAY, + INT_ARRAY, + LONG_ARRAY, + FLOAT_ARRAY, + DOUBLE_ARRAY, + OBJECT_ARRAY +} From 8be9e6c4bad777f976d6cf440d6cb306a30fa915 Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Sat, 14 Mar 2015 23:45:01 +0300 Subject: [PATCH 63/69] First attempt to make AST optimizer faster --- ...untVisitor.java => BlockCountVisitor.java} | 4 +- .../javascript/EscapingStatementFinder.java | 130 ++++++++++++++++++ .../teavm/javascript/OptimizingVisitor.java | 52 ++++++- 3 files changed, 179 insertions(+), 7 deletions(-) rename teavm-core/src/main/java/org/teavm/javascript/{CertainBlockCountVisitor.java => BlockCountVisitor.java} (95%) create mode 100644 teavm-core/src/main/java/org/teavm/javascript/EscapingStatementFinder.java diff --git a/teavm-core/src/main/java/org/teavm/javascript/CertainBlockCountVisitor.java b/teavm-core/src/main/java/org/teavm/javascript/BlockCountVisitor.java similarity index 95% rename from teavm-core/src/main/java/org/teavm/javascript/CertainBlockCountVisitor.java rename to teavm-core/src/main/java/org/teavm/javascript/BlockCountVisitor.java index 11702da38..39354bcbf 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/CertainBlockCountVisitor.java +++ b/teavm-core/src/main/java/org/teavm/javascript/BlockCountVisitor.java @@ -22,11 +22,11 @@ import org.teavm.javascript.ast.*; * * @author Alexey Andreev */ -class CertainBlockCountVisitor implements StatementVisitor { +class BlockCountVisitor implements StatementVisitor { private BlockStatement blockToCount; private int count; - public CertainBlockCountVisitor(BlockStatement blockToCount) { + public BlockCountVisitor(BlockStatement blockToCount) { this.blockToCount = blockToCount; } diff --git a/teavm-core/src/main/java/org/teavm/javascript/EscapingStatementFinder.java b/teavm-core/src/main/java/org/teavm/javascript/EscapingStatementFinder.java new file mode 100644 index 000000000..370a56d8f --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/javascript/EscapingStatementFinder.java @@ -0,0 +1,130 @@ +/* + * Copyright 2015 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.javascript; + +import java.util.List; +import java.util.Set; +import org.teavm.javascript.ast.*; + +/** + * + * @author Alexey Andreev + */ +class EscapingStatementFinder implements StatementVisitor{ + public boolean escaping; + private Set outerStatements; + + public EscapingStatementFinder(Set nestingStatements) { + this.outerStatements = nestingStatements; + } + + public boolean check(List statements) { + if (!escaping) { + if (statements.isEmpty()) { + escaping = true; + } else { + statements.get(statements.size() - 1).acceptVisitor(this); + } + } + return escaping; + } + + @Override + public void visit(AssignmentStatement statement) { + escaping = true; + } + + @Override + public void visit(SequentialStatement statement) { + check(statement.getSequence()); + } + + @Override + public void visit(ConditionalStatement statement) { + if (!check(statement.getConsequent())) { + check(statement.getAlternative()); + } + } + + @Override + public void visit(SwitchStatement statement) { + outerStatements.add(statement); + for (SwitchClause clause : statement.getClauses()) { + if (check(clause.getBody())) { + break; + } + } + check(statement.getDefaultClause()); + outerStatements.remove(statement); + } + + @Override + public void visit(WhileStatement statement) { + outerStatements.add(statement); + check(statement.getBody()); + outerStatements.remove(statement); + } + + @Override + public void visit(BlockStatement statement) { + outerStatements.add(statement); + check(statement.getBody()); + outerStatements.remove(statement); + } + + @Override + public void visit(BreakStatement statement) { + escaping = !outerStatements.contains(statement.getTarget()); + } + + @Override + public void visit(ContinueStatement statement) { + escaping = !outerStatements.contains(statement.getTarget()); + } + + @Override + public void visit(ReturnStatement statement) { + } + + @Override + public void visit(ThrowStatement statement) { + } + + @Override + public void visit(InitClassStatement statement) { + escaping = true; + } + + @Override + public void visit(TryCatchStatement statement) { + check(statement.getProtectedBody()); + check(statement.getHandler()); + } + + @Override + public void visit(GotoPartStatement statement) { + } + + @Override + public void visit(MonitorEnterStatement statement) { + escaping = true; + } + + @Override + public void visit(MonitorExitStatement statement) { + escaping = true; + } +} diff --git a/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java b/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java index c0923f820..d62acc07a 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java +++ b/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java @@ -28,6 +28,8 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor { private boolean[] preservedVars; private int[] readFrequencies; private List resultSequence; + private Map> blockSuccessors = new HashMap<>(); + private Set outerStatements = new HashSet<>(); public OptimizingVisitor(boolean[] preservedVars, int[] readFreqencies) { this.preservedVars = preservedVars; @@ -370,15 +372,29 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor { return; } Statement last = statements.get(statements.size() - 1); - if (last instanceof BreakStatement && exit != null) { - IdentifiedStatement target = ((BreakStatement)last).getTarget(); - if (exit == target) { - statements.remove(statements.size() - 1); + if (last instanceof BreakStatement) { + BreakStatement breakStmt = (BreakStatement)last; + if (exit != null) { + IdentifiedStatement target = breakStmt.getTarget(); + if (exit == target) { + statements.remove(statements.size() - 1); + } + } else if (blockSuccessors.containsKey(breakStmt.getTarget())) { + BlockCountVisitor usageCounter = new BlockCountVisitor( + (BlockStatement)breakStmt.getTarget()); + breakStmt.getTarget().acceptVisitor(usageCounter); + if (usageCounter.getCount() == 1) { + statements.remove(statements.size() - 1); + List successors = blockSuccessors.remove(breakStmt.getTarget()); + statements.addAll(successors); + successors.clear(); + } } } if (statements.isEmpty()) { return; } + boolean escapes = escapes(statements); for (int i = 0; i < statements.size(); ++i) { Statement stmt = statements.get(i); if (stmt instanceof ConditionalStatement) { @@ -436,20 +452,39 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor { } } else if (stmt instanceof BlockStatement) { BlockStatement nestedBlock = (BlockStatement)stmt; + outerStatements.add(nestedBlock); + if (!escapes && !escapes(nestedBlock.getBody())) { + blockSuccessors.put(nestedBlock, statements.subList(i + 1, statements.size())); + } eliminateRedundantBreaks(nestedBlock.getBody(), nestedBlock); + blockSuccessors.remove(nestedBlock); + outerStatements.remove(nestedBlock); } else if (stmt instanceof WhileStatement) { WhileStatement whileStmt = (WhileStatement)stmt; + outerStatements.add(whileStmt); eliminateRedundantBreaks(whileStmt.getBody(), null); + outerStatements.remove(whileStmt); } else if (stmt instanceof SwitchStatement) { SwitchStatement switchStmt = (SwitchStatement)stmt; + outerStatements.add(switchStmt); + if (i == statements.size() - 1) { + for (SwitchClause clause : switchStmt.getClauses()) { + eliminateRedundantBreaks(clause.getBody(), exit); + } + eliminateRedundantBreaks(switchStmt.getDefaultClause(), exit); + } for (SwitchClause clause : switchStmt.getClauses()) { eliminateRedundantBreaks(clause.getBody(), null); } eliminateRedundantBreaks(switchStmt.getDefaultClause(), null); + outerStatements.remove(switchStmt); } } } + private boolean escapes(List statements) { + return new EscapingStatementFinder(outerStatements).check(statements); + } private void normalizeConditional(ConditionalStatement stmt) { if (stmt.getConsequent().isEmpty()) { @@ -495,6 +530,7 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor { @Override public void visit(SwitchStatement statement) { + outerStatements.add(statement); statement.getValue().acceptVisitor(this); statement.setValue(resultExpr); for (SwitchClause clause : statement.getClauses()) { @@ -506,10 +542,12 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor { statement.getDefaultClause().clear(); statement.getDefaultClause().addAll(newDefault); resultStmt = statement; + outerStatements.remove(statement); } @Override public void visit(WhileStatement statement) { + outerStatements.add(statement); if (statement.getBody().size() == 1 && statement.getBody().get(0) instanceof WhileStatement) { WhileStatement innerLoop = (WhileStatement)statement.getBody().get(0); BreakToContinueReplacer replacer = new BreakToContinueReplacer(innerLoop, statement); @@ -558,13 +596,16 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor { break; } resultStmt = statement; + outerStatements.remove(statements); } @Override public void visit(BlockStatement statement) { + outerStatements.add(statement); List statements = processSequence(statement.getBody()); eliminateRedundantBreaks(statements, statement); - CertainBlockCountVisitor usageCounter = new CertainBlockCountVisitor(statement); + statements = processSequence(statements); + BlockCountVisitor usageCounter = new BlockCountVisitor(statement); usageCounter.visit(statements); if (usageCounter.getCount() == 0) { SequentialStatement result = new SequentialStatement(); @@ -575,6 +616,7 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor { statement.getBody().addAll(statements); resultStmt = statement; } + outerStatements.remove(statement); } @Override From b6cf7c4cbac53c7275281de9bf082d1db64bf5bc Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Sun, 15 Mar 2015 14:43:38 +0300 Subject: [PATCH 64/69] Optimize some breaks (including breaks from switch clauses) in a separate pass --- .../org/teavm/javascript/BreakEliminator.java | 156 ++++++++++++++++++ .../javascript/EscapingStatementFinder.java | 4 +- .../java/org/teavm/javascript/Optimizer.java | 4 + .../teavm/javascript/OptimizingVisitor.java | 41 +---- 4 files changed, 162 insertions(+), 43 deletions(-) create mode 100644 teavm-core/src/main/java/org/teavm/javascript/BreakEliminator.java diff --git a/teavm-core/src/main/java/org/teavm/javascript/BreakEliminator.java b/teavm-core/src/main/java/org/teavm/javascript/BreakEliminator.java new file mode 100644 index 000000000..1373f6be1 --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/javascript/BreakEliminator.java @@ -0,0 +1,156 @@ +/* + * Copyright 2015 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.javascript; + +import java.util.*; +import org.teavm.javascript.ast.*; + +/** + * + * @author Alexey Andreev + */ +class BreakEliminator implements StatementVisitor { + private Map> blockSuccessors = new HashMap<>(); + private Set outerStatements = new HashSet<>(); + private List currentSequence; + private boolean sequenceEscapes; + private int currentIndex; + + private void processSequence(List statements) { + List oldSequence = currentSequence; + int oldIndex = currentIndex; + boolean oldEscapes = sequenceEscapes; + + sequenceEscapes = escapes(statements); + currentSequence = statements; + for (currentIndex = 0; currentIndex < currentSequence.size(); ++currentIndex) { + statements.get(currentIndex).acceptVisitor(this); + } + + sequenceEscapes = oldEscapes; + currentIndex = oldIndex; + currentSequence = oldSequence; + } + + @Override + public void visit(AssignmentStatement statement) { + } + + @Override + public void visit(SequentialStatement statement) { + if (currentSequence == null) { + processSequence(statement.getSequence()); + return; + } + --currentIndex; + currentSequence.remove(currentIndex); + currentSequence.addAll(currentIndex, statement.getSequence()); + } + + @Override + public void visit(ConditionalStatement statement) { + processSequence(statement.getConsequent()); + processSequence(statement.getAlternative()); + } + + @Override + public void visit(SwitchStatement statement) { + outerStatements.add(statement); + for (SwitchClause clause : statement.getClauses()) { + processSequence(clause.getBody()); + } + processSequence(statement.getDefaultClause()); + outerStatements.remove(statement); + } + + @Override + public void visit(WhileStatement statement) { + outerStatements.add(statement); + processSequence(statement.getBody()); + outerStatements.remove(statement); + } + + @Override + public void visit(BlockStatement statement) { + outerStatements.add(statement); + if (!sequenceEscapes && !escapes(statement.getBody())) { + blockSuccessors.put(statement, currentSequence.subList(currentIndex + 1, currentSequence.size())); + } + processSequence(statement.getBody()); + blockSuccessors.remove(statement); + outerStatements.remove(statement); + } + + @Override + public void visit(BreakStatement statement) { + if (blockSuccessors.containsKey(statement.getTarget())) { + BlockCountVisitor usageCounter = new BlockCountVisitor( + (BlockStatement)statement.getTarget()); + statement.getTarget().acceptVisitor(usageCounter); + if (usageCounter.getCount() == 1) { + currentSequence.subList(currentIndex, currentSequence.size()).clear(); + List successors = blockSuccessors.remove(statement.getTarget()); + currentSequence.addAll(successors); + successors.clear(); + --currentIndex; + sequenceEscapes = escapes(currentSequence); + return; + } + } + currentSequence.subList(currentIndex + 1, currentSequence.size()).clear(); + } + + @Override + public void visit(ContinueStatement statement) { + currentSequence.subList(currentIndex + 1, currentSequence.size()).clear(); + } + + @Override + public void visit(ReturnStatement statement) { + currentSequence.subList(currentIndex + 1, currentSequence.size()).clear(); + } + + @Override + public void visit(ThrowStatement statement) { + currentSequence.subList(currentIndex + 1, currentSequence.size()).clear(); + } + + @Override + public void visit(InitClassStatement statement) { + } + + @Override + public void visit(TryCatchStatement statement) { + processSequence(statement.getProtectedBody()); + processSequence(statement.getHandler()); + } + + @Override + public void visit(GotoPartStatement statement) { + } + + @Override + public void visit(MonitorEnterStatement statement) { + } + + @Override + public void visit(MonitorExitStatement statement) { + } + + private boolean escapes(List statements) { + return new EscapingStatementFinder(outerStatements).check(statements); + } +} diff --git a/teavm-core/src/main/java/org/teavm/javascript/EscapingStatementFinder.java b/teavm-core/src/main/java/org/teavm/javascript/EscapingStatementFinder.java index 370a56d8f..79017d0b3 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/EscapingStatementFinder.java +++ b/teavm-core/src/main/java/org/teavm/javascript/EscapingStatementFinder.java @@ -73,9 +73,7 @@ class EscapingStatementFinder implements StatementVisitor{ @Override public void visit(WhileStatement statement) { - outerStatements.add(statement); - check(statement.getBody()); - outerStatements.remove(statement); + escaping = true; } @Override diff --git a/teavm-core/src/main/java/org/teavm/javascript/Optimizer.java b/teavm-core/src/main/java/org/teavm/javascript/Optimizer.java index fce043a1f..34bbccb0c 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Optimizer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Optimizer.java @@ -35,6 +35,8 @@ public class Optimizer { preservedVars[i] = true; } } + BreakEliminator breakEliminator = new BreakEliminator(); + method.getBody().acceptVisitor(breakEliminator); OptimizingVisitor optimizer = new OptimizingVisitor(preservedVars, stats.reads); method.getBody().acceptVisitor(optimizer); method.setBody(optimizer.resultStmt); @@ -64,6 +66,8 @@ public class Optimizer { } for (int i = 0; i < splitter.size(); ++i) { AsyncMethodPart part = method.getBody().get(i); + BreakEliminator breakEliminator = new BreakEliminator(); + part.getStatement().acceptVisitor(breakEliminator); OptimizingVisitor optimizer = new OptimizingVisitor(preservedVars, readFrequencies[i]); part.getStatement().acceptVisitor(optimizer); part.setStatement(optimizer.resultStmt); diff --git a/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java b/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java index d62acc07a..a18740845 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java +++ b/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java @@ -28,8 +28,6 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor { private boolean[] preservedVars; private int[] readFrequencies; private List resultSequence; - private Map> blockSuccessors = new HashMap<>(); - private Set outerStatements = new HashSet<>(); public OptimizingVisitor(boolean[] preservedVars, int[] readFreqencies) { this.preservedVars = preservedVars; @@ -379,22 +377,11 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor { if (exit == target) { statements.remove(statements.size() - 1); } - } else if (blockSuccessors.containsKey(breakStmt.getTarget())) { - BlockCountVisitor usageCounter = new BlockCountVisitor( - (BlockStatement)breakStmt.getTarget()); - breakStmt.getTarget().acceptVisitor(usageCounter); - if (usageCounter.getCount() == 1) { - statements.remove(statements.size() - 1); - List successors = blockSuccessors.remove(breakStmt.getTarget()); - statements.addAll(successors); - successors.clear(); - } } } if (statements.isEmpty()) { return; } - boolean escapes = escapes(statements); for (int i = 0; i < statements.size(); ++i) { Statement stmt = statements.get(i); if (stmt instanceof ConditionalStatement) { @@ -417,7 +404,7 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor { if (last instanceof BreakStatement) { BreakStatement breakStmt = (BreakStatement)last; if (exit != null && exit == breakStmt.getTarget()) { - cond.getAlternative().remove(cond.getConsequent().size() - 1); + cond.getAlternative().remove(cond.getAlternative().size() - 1); List remaining = statements.subList(i + 1, statements.size()); cond.getConsequent().addAll(remaining); remaining.clear(); @@ -452,40 +439,20 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor { } } else if (stmt instanceof BlockStatement) { BlockStatement nestedBlock = (BlockStatement)stmt; - outerStatements.add(nestedBlock); - if (!escapes && !escapes(nestedBlock.getBody())) { - blockSuccessors.put(nestedBlock, statements.subList(i + 1, statements.size())); - } eliminateRedundantBreaks(nestedBlock.getBody(), nestedBlock); - blockSuccessors.remove(nestedBlock); - outerStatements.remove(nestedBlock); } else if (stmt instanceof WhileStatement) { WhileStatement whileStmt = (WhileStatement)stmt; - outerStatements.add(whileStmt); eliminateRedundantBreaks(whileStmt.getBody(), null); - outerStatements.remove(whileStmt); } else if (stmt instanceof SwitchStatement) { SwitchStatement switchStmt = (SwitchStatement)stmt; - outerStatements.add(switchStmt); - if (i == statements.size() - 1) { - for (SwitchClause clause : switchStmt.getClauses()) { - eliminateRedundantBreaks(clause.getBody(), exit); - } - eliminateRedundantBreaks(switchStmt.getDefaultClause(), exit); - } for (SwitchClause clause : switchStmt.getClauses()) { eliminateRedundantBreaks(clause.getBody(), null); } eliminateRedundantBreaks(switchStmt.getDefaultClause(), null); - outerStatements.remove(switchStmt); } } } - private boolean escapes(List statements) { - return new EscapingStatementFinder(outerStatements).check(statements); - } - private void normalizeConditional(ConditionalStatement stmt) { if (stmt.getConsequent().isEmpty()) { stmt.getConsequent().addAll(stmt.getAlternative()); @@ -530,7 +497,6 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor { @Override public void visit(SwitchStatement statement) { - outerStatements.add(statement); statement.getValue().acceptVisitor(this); statement.setValue(resultExpr); for (SwitchClause clause : statement.getClauses()) { @@ -542,12 +508,10 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor { statement.getDefaultClause().clear(); statement.getDefaultClause().addAll(newDefault); resultStmt = statement; - outerStatements.remove(statement); } @Override public void visit(WhileStatement statement) { - outerStatements.add(statement); if (statement.getBody().size() == 1 && statement.getBody().get(0) instanceof WhileStatement) { WhileStatement innerLoop = (WhileStatement)statement.getBody().get(0); BreakToContinueReplacer replacer = new BreakToContinueReplacer(innerLoop, statement); @@ -596,12 +560,10 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor { break; } resultStmt = statement; - outerStatements.remove(statements); } @Override public void visit(BlockStatement statement) { - outerStatements.add(statement); List statements = processSequence(statement.getBody()); eliminateRedundantBreaks(statements, statement); statements = processSequence(statements); @@ -616,7 +578,6 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor { statement.getBody().addAll(statements); resultStmt = statement; } - outerStatements.remove(statement); } @Override From 6c57fb866fad88c51b65e229ca624342fa88a0cc Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Sun, 15 Mar 2015 15:02:34 +0300 Subject: [PATCH 65/69] Attempting to increase performance of AST processing --- .../javascript/AllBlocksCountVisitor.java | 134 ++++++++++++++++++ .../org/teavm/javascript/BreakEliminator.java | 12 +- .../java/org/teavm/javascript/Optimizer.java | 4 +- .../teavm/javascript/OptimizingVisitor.java | 13 +- .../java/org/teavm/tooling/TeaVMTool.java | 2 +- 5 files changed, 150 insertions(+), 15 deletions(-) create mode 100644 teavm-core/src/main/java/org/teavm/javascript/AllBlocksCountVisitor.java diff --git a/teavm-core/src/main/java/org/teavm/javascript/AllBlocksCountVisitor.java b/teavm-core/src/main/java/org/teavm/javascript/AllBlocksCountVisitor.java new file mode 100644 index 000000000..7f0d0fd0e --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/javascript/AllBlocksCountVisitor.java @@ -0,0 +1,134 @@ +/* + * Copyright 2015 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.javascript; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.teavm.javascript.ast.*; + +/** + * + * @author Alexey Andreev + */ +class AllBlocksCountVisitor implements StatementVisitor { + private Map blocksCount = new HashMap<>(); + private IdentifiedStatement currentBlock; + + public void visit(List statements) { + if (statements == null) { + return; + } + for (Statement part : statements) { + part.acceptVisitor(this); + } + } + + public int getCount(IdentifiedStatement statement) { + Integer result = blocksCount.get(statement); + return result != null ? result : 0; + } + + @Override + public void visit(AssignmentStatement statement) { + } + + @Override + public void visit(SequentialStatement statement) { + visit(statement.getSequence()); + } + + @Override + public void visit(ConditionalStatement statement) { + visit(statement.getConsequent()); + visit(statement.getAlternative()); + } + + @Override + public void visit(SwitchStatement statement) { + IdentifiedStatement oldCurrentBlock = currentBlock; + currentBlock = statement; + for (SwitchClause clause : statement.getClauses()) { + visit(clause.getBody()); + } + visit(statement.getDefaultClause()); + currentBlock = oldCurrentBlock; + } + + @Override + public void visit(WhileStatement statement) { + IdentifiedStatement oldCurrentBlock = currentBlock; + currentBlock = statement; + visit(statement.getBody()); + currentBlock = oldCurrentBlock; + } + + @Override + public void visit(BlockStatement statement) { + IdentifiedStatement oldCurrentBlock = currentBlock; + currentBlock = statement; + visit(statement.getBody()); + currentBlock = oldCurrentBlock; + } + + @Override + public void visit(BreakStatement statement) { + IdentifiedStatement target = statement.getTarget(); + if (target == null) { + target = currentBlock; + } + blocksCount.put(target, getCount(target) + 1); + } + + @Override + public void visit(ContinueStatement statement) { + IdentifiedStatement target = statement.getTarget(); + if (target == null) { + target = currentBlock; + } + blocksCount.put(target, getCount(target) + 1); + } + + @Override + public void visit(ReturnStatement statement) { + } + + @Override + public void visit(ThrowStatement statement) { + } + + @Override + public void visit(InitClassStatement statement) { + } + + @Override + public void visit(TryCatchStatement statement) { + visit(statement.getProtectedBody()); + visit(statement.getHandler()); + } + + @Override + public void visit(GotoPartStatement statement) { + } + + @Override + public void visit(MonitorEnterStatement statement) { + } + + @Override + public void visit(MonitorExitStatement statement) { + } +} diff --git a/teavm-core/src/main/java/org/teavm/javascript/BreakEliminator.java b/teavm-core/src/main/java/org/teavm/javascript/BreakEliminator.java index 1373f6be1..94bb2ef74 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/BreakEliminator.java +++ b/teavm-core/src/main/java/org/teavm/javascript/BreakEliminator.java @@ -28,6 +28,13 @@ class BreakEliminator implements StatementVisitor { private List currentSequence; private boolean sequenceEscapes; private int currentIndex; + private AllBlocksCountVisitor usageCounter; + + public void eliminate(Statement statement) { + usageCounter = new AllBlocksCountVisitor(); + statement.acceptVisitor(usageCounter); + statement.acceptVisitor(this); + } private void processSequence(List statements) { List oldSequence = currentSequence; @@ -97,10 +104,7 @@ class BreakEliminator implements StatementVisitor { @Override public void visit(BreakStatement statement) { if (blockSuccessors.containsKey(statement.getTarget())) { - BlockCountVisitor usageCounter = new BlockCountVisitor( - (BlockStatement)statement.getTarget()); - statement.getTarget().acceptVisitor(usageCounter); - if (usageCounter.getCount() == 1) { + if (usageCounter.getCount(statement.getTarget()) == 1) { currentSequence.subList(currentIndex, currentSequence.size()).clear(); List successors = blockSuccessors.remove(statement.getTarget()); currentSequence.addAll(successors); diff --git a/teavm-core/src/main/java/org/teavm/javascript/Optimizer.java b/teavm-core/src/main/java/org/teavm/javascript/Optimizer.java index 34bbccb0c..c57a126f7 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Optimizer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Optimizer.java @@ -36,7 +36,7 @@ public class Optimizer { } } BreakEliminator breakEliminator = new BreakEliminator(); - method.getBody().acceptVisitor(breakEliminator); + breakEliminator.eliminate(method.getBody()); OptimizingVisitor optimizer = new OptimizingVisitor(preservedVars, stats.reads); method.getBody().acceptVisitor(optimizer); method.setBody(optimizer.resultStmt); @@ -67,7 +67,7 @@ public class Optimizer { for (int i = 0; i < splitter.size(); ++i) { AsyncMethodPart part = method.getBody().get(i); BreakEliminator breakEliminator = new BreakEliminator(); - part.getStatement().acceptVisitor(breakEliminator); + breakEliminator.eliminate(part.getStatement()); OptimizingVisitor optimizer = new OptimizingVisitor(preservedVars, readFrequencies[i]); part.getStatement().acceptVisitor(optimizer); part.setStatement(optimizer.resultStmt); diff --git a/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java b/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java index a18740845..036630fe5 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java +++ b/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java @@ -370,13 +370,10 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor { return; } Statement last = statements.get(statements.size() - 1); - if (last instanceof BreakStatement) { - BreakStatement breakStmt = (BreakStatement)last; - if (exit != null) { - IdentifiedStatement target = breakStmt.getTarget(); - if (exit == target) { - statements.remove(statements.size() - 1); - } + if (last instanceof BreakStatement && exit != null) { + IdentifiedStatement target = ((BreakStatement)last).getTarget(); + if (exit == target) { + statements.remove(statements.size() - 1); } } if (statements.isEmpty()) { @@ -453,6 +450,7 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor { } } + private void normalizeConditional(ConditionalStatement stmt) { if (stmt.getConsequent().isEmpty()) { stmt.getConsequent().addAll(stmt.getAlternative()); @@ -566,7 +564,6 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor { public void visit(BlockStatement statement) { List statements = processSequence(statement.getBody()); eliminateRedundantBreaks(statements, statement); - statements = processSequence(statements); BlockCountVisitor usageCounter = new BlockCountVisitor(statement); usageCounter.visit(statements); if (usageCounter.getCount() == 0) { diff --git a/teavm-core/src/main/java/org/teavm/tooling/TeaVMTool.java b/teavm-core/src/main/java/org/teavm/tooling/TeaVMTool.java index 0c6fdf36c..413421a0c 100644 --- a/teavm-core/src/main/java/org/teavm/tooling/TeaVMTool.java +++ b/teavm-core/src/main/java/org/teavm/tooling/TeaVMTool.java @@ -292,7 +292,7 @@ public class TeaVMTool { } targetDirectory.mkdirs(); try (Writer writer = new OutputStreamWriter(new BufferedOutputStream( - new FileOutputStream(new File(targetDirectory, targetFileName))), "UTF-8")) { + new FileOutputStream(new File(targetDirectory, targetFileName)), 65536), "UTF-8")) { if (runtime == RuntimeCopyOperation.MERGED) { vm.add(runtimeInjector); } From 9ce9f970d776e94c19794f67802a69d9491840f0 Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Sun, 15 Mar 2015 17:46:01 +0300 Subject: [PATCH 66/69] Fix AST caching to support async methods --- .../main/java/org/teavm/cli/TeaVMRunner.java | 1 + .../src/main/java/org/teavm/cache/AstIO.java | 67 ++++++ .../org/teavm/cache/AsyncMethodExtractor.java | 24 ++ .../cache/DiskRegularMethodNodeCache.java | 74 ++++++- .../teavm/javascript/AsyncCallsFinder.java | 208 ++++++++++++++++++ .../java/org/teavm/javascript/Decompiler.java | 77 +++++-- .../EmptyRegularMethodNodeCache.java | 12 +- .../InMemoryRegularMethodNodeCache.java | 14 +- ...hodNodeCache.java => MethodNodeCache.java} | 7 +- .../java/org/teavm/tooling/TeaVMTestTool.java | 4 +- .../src/main/java/org/teavm/vm/TeaVM.java | 6 +- 11 files changed, 457 insertions(+), 37 deletions(-) create mode 100644 teavm-core/src/main/java/org/teavm/cache/AsyncMethodExtractor.java create mode 100644 teavm-core/src/main/java/org/teavm/javascript/AsyncCallsFinder.java rename teavm-core/src/main/java/org/teavm/javascript/{RegularMethodNodeCache.java => MethodNodeCache.java} (80%) diff --git a/teavm-cli/src/main/java/org/teavm/cli/TeaVMRunner.java b/teavm-cli/src/main/java/org/teavm/cli/TeaVMRunner.java index 3d93428f7..18e3daa67 100644 --- a/teavm-cli/src/main/java/org/teavm/cli/TeaVMRunner.java +++ b/teavm-cli/src/main/java/org/teavm/cli/TeaVMRunner.java @@ -87,6 +87,7 @@ public final class TeaVMRunner { .create('i')); options.addOption(OptionBuilder .withArgName("directory") + .hasArg() .withDescription("Incremental build cache directory") .withLongOpt("cachedir") .create('c')); diff --git a/teavm-core/src/main/java/org/teavm/cache/AstIO.java b/teavm-core/src/main/java/org/teavm/cache/AstIO.java index ddb706233..2e1795683 100644 --- a/teavm-core/src/main/java/org/teavm/cache/AstIO.java +++ b/teavm-core/src/main/java/org/teavm/cache/AstIO.java @@ -86,6 +86,56 @@ public class AstIO { return node; } + public void writeAsync(DataOutput output, AsyncMethodNode method) throws IOException { + output.writeInt(packModifiers(method.getModifiers())); + output.writeShort(method.getVariables().size()); + for (int var : method.getVariables()) { + output.writeShort(var); + } + output.writeShort(method.getParameterDebugNames().size()); + for (Set debugNames : method.getParameterDebugNames()) { + output.writeShort(debugNames != null ? debugNames.size() : 0); + if (debugNames != null) { + for (String debugName : debugNames) { + output.writeUTF(debugName); + } + } + } + try { + output.writeShort(method.getBody().size()); + for (int i = 0; i < method.getBody().size(); ++i) { + method.getBody().get(i).getStatement().acceptVisitor(new NodeWriter(output)); + } + } catch (IOExceptionWrapper e) { + throw new IOException("Error writing method body", e.getCause()); + } + } + + public AsyncMethodNode readAsync(DataInput input, MethodReference method) throws IOException { + AsyncMethodNode node = new AsyncMethodNode(method); + node.getModifiers().addAll(unpackModifiers(input.readInt())); + int varCount = input.readShort(); + for (int i = 0; i < varCount; ++i) { + node.getVariables().add((int)input.readShort()); + } + int paramDebugNameCount = input.readShort(); + for (int i = 0; i < paramDebugNameCount; ++i) { + int debugNameCount = input.readShort(); + Set debugNames = new HashSet<>(); + for (int j = 0; j < debugNameCount; ++j) { + debugNames.add(input.readUTF()); + } + node.getParameterDebugNames().add(debugNames); + } + int partCount = input.readShort(); + for (int i = 0; i < partCount; ++i) { + AsyncMethodPart part = new AsyncMethodPart(); + part.setStatement(readStatement(input)); + node.getBody().add(part); + } + return node; + } + private int packModifiers(Set modifiers) { int packed = 0; for (NodeModifier modifier : modifiers) { @@ -155,6 +205,7 @@ public class AstIO { writeExpr(statement.getLeftValue()); } writeExpr(statement.getRightValue()); + output.writeBoolean(statement.isAsync()); } catch (IOException e) { throw new IOExceptionWrapper(e); } @@ -318,6 +369,7 @@ public class AstIO { public void visit(MonitorEnterStatement statement) { try { output.writeByte(18); + writeLocation(statement.getLocation()); writeExpr(statement.getObjectRef()); } catch (IOException e) { throw new IOExceptionWrapper(e); @@ -328,6 +380,7 @@ public class AstIO { public void visit(MonitorExitStatement statement) { try { output.writeByte(19); + writeLocation(statement.getLocation()); writeExpr(statement.getObjectRef()); } catch (IOException e) { throw new IOExceptionWrapper(e); @@ -549,6 +602,7 @@ public class AstIO { } stmt.setLeftValue(readExpr(input)); stmt.setRightValue(readExpr(input)); + stmt.setAsync(input.readBoolean()); return stmt; } case 1: { @@ -559,6 +613,7 @@ public class AstIO { stmt.getDebugNames().add(input.readUTF()); } stmt.setRightValue(readExpr(input)); + stmt.setAsync(input.readBoolean()); return stmt; } case 2: { @@ -684,6 +739,18 @@ public class AstIO { stmt.setPart(input.readShort()); return stmt; } + case 18: { + MonitorEnterStatement stmt = new MonitorEnterStatement(); + stmt.setLocation(readLocation(input)); + stmt.setObjectRef(readExpr(input)); + return stmt; + } + case 19: { + MonitorExitStatement stmt = new MonitorExitStatement(); + stmt.setLocation(readLocation(input)); + stmt.setObjectRef(readExpr(input)); + return stmt; + } // TODO: MonitorEnter/MonitorExit default: throw new RuntimeException("Unexpected statement type: " + type); diff --git a/teavm-core/src/main/java/org/teavm/cache/AsyncMethodExtractor.java b/teavm-core/src/main/java/org/teavm/cache/AsyncMethodExtractor.java new file mode 100644 index 000000000..ba26a738a --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/cache/AsyncMethodExtractor.java @@ -0,0 +1,24 @@ +/* + * Copyright 2015 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.cache; + +/** + * + * @author Alexey Andreev + */ +public class AsyncMethodExtractor { + +} diff --git a/teavm-core/src/main/java/org/teavm/cache/DiskRegularMethodNodeCache.java b/teavm-core/src/main/java/org/teavm/cache/DiskRegularMethodNodeCache.java index bb6d058e0..80fe31f10 100644 --- a/teavm-core/src/main/java/org/teavm/cache/DiskRegularMethodNodeCache.java +++ b/teavm-core/src/main/java/org/teavm/cache/DiskRegularMethodNodeCache.java @@ -17,7 +17,7 @@ package org.teavm.cache; import java.io.*; import java.util.*; -import org.teavm.javascript.RegularMethodNodeCache; +import org.teavm.javascript.MethodNodeCache; import org.teavm.javascript.ast.*; import org.teavm.model.MethodReference; import org.teavm.parsing.ClassDateProvider; @@ -26,12 +26,14 @@ import org.teavm.parsing.ClassDateProvider; * * @author Alexey Andreev */ -public class DiskRegularMethodNodeCache implements RegularMethodNodeCache { +public class DiskRegularMethodNodeCache implements MethodNodeCache { private File directory; private AstIO astIO; private ClassDateProvider classDateProvider; private Map cache = new HashMap<>(); + private Map asyncCache = new HashMap<>(); private Set newMethods = new HashSet<>(); + private Set newAsyncMethods = new HashSet<>(); public DiskRegularMethodNodeCache(File directory, SymbolTable symbolTable, SymbolTable fileTable, ClassDateProvider classDateProvider) { @@ -46,7 +48,7 @@ public class DiskRegularMethodNodeCache implements RegularMethodNodeCache { if (item == null) { item = new Item(); cache.put(methodReference, item); - File file = getMethodFile(methodReference); + File file = getMethodFile(methodReference, false); if (file.exists()) { try (InputStream stream = new BufferedInputStream(new FileInputStream(file))) { DataInput input = new DataInputStream(stream); @@ -79,9 +81,48 @@ public class DiskRegularMethodNodeCache implements RegularMethodNodeCache { newMethods.add(methodReference); } + @Override + public AsyncMethodNode getAsync(MethodReference methodReference) { + AsyncItem item = asyncCache.get(methodReference); + if (item == null) { + item = new AsyncItem(); + asyncCache.put(methodReference, item); + File file = getMethodFile(methodReference, true); + if (file.exists()) { + try (InputStream stream = new BufferedInputStream(new FileInputStream(file))) { + DataInput input = new DataInputStream(stream); + int depCount = input.readShort(); + boolean dependenciesChanged = false; + for (int i = 0; i < depCount; ++i) { + String depClass = input.readUTF(); + Date depDate = classDateProvider.getModificationDate(depClass); + if (depDate == null || depDate.after(new Date(file.lastModified()))) { + dependenciesChanged = true; + break; + } + } + if (!dependenciesChanged) { + item.node = astIO.readAsync(input, methodReference); + } + } catch (IOException e) { + // we could not read program, just leave it empty + } + } + } + return item.node; + } + + @Override + public void storeAsync(MethodReference methodReference, AsyncMethodNode node) { + AsyncItem item = new AsyncItem(); + item.node = node; + asyncCache.put(methodReference, item); + newAsyncMethods.add(methodReference); + } + public void flush() throws IOException { for (MethodReference method : newMethods) { - File file = getMethodFile(method); + File file = getMethodFile(method, true); AstDependencyAnalyzer analyzer = new AstDependencyAnalyzer(); RegularMethodNode node = cache.get(method).node; node.getBody().acceptVisitor(analyzer); @@ -94,11 +135,28 @@ public class DiskRegularMethodNodeCache implements RegularMethodNodeCache { astIO.write(output, node); } } + for (MethodReference method : newAsyncMethods) { + File file = getMethodFile(method, true); + AstDependencyAnalyzer analyzer = new AstDependencyAnalyzer(); + AsyncMethodNode node = asyncCache.get(method).node; + for (AsyncMethodPart part : node.getBody()) { + part.getStatement().acceptVisitor(analyzer); + } + analyzer.dependencies.add(method.getClassName()); + try (DataOutputStream output = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)))) { + output.writeShort(analyzer.dependencies.size()); + for (String dependency : analyzer.dependencies) { + output.writeUTF(dependency); + } + astIO.writeAsync(output, node); + } + } } - private File getMethodFile(MethodReference method) { + private File getMethodFile(MethodReference method, boolean async) { File dir = new File(directory, method.getClassName().replace('.', '/')); - return new File(dir, FileNameEncoder.encodeFileName(method.getDescriptor().toString()) + ".teavm-ast"); + return new File(dir, FileNameEncoder.encodeFileName(method.getDescriptor().toString()) + ".teavm-ast" + + (async ? "-async" : "")); } static class AstDependencyAnalyzer implements StatementVisitor, ExprVisitor { @@ -275,4 +333,8 @@ public class DiskRegularMethodNodeCache implements RegularMethodNodeCache { static class Item { RegularMethodNode node; } + + static class AsyncItem { + AsyncMethodNode node; + } } diff --git a/teavm-core/src/main/java/org/teavm/javascript/AsyncCallsFinder.java b/teavm-core/src/main/java/org/teavm/javascript/AsyncCallsFinder.java new file mode 100644 index 000000000..51d322484 --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/javascript/AsyncCallsFinder.java @@ -0,0 +1,208 @@ +/* + * Copyright 2015 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.javascript; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.teavm.javascript.ast.*; +import org.teavm.model.MethodReference; + +/** + * + * @author Alexey Andreev + */ +class AsyncCallsFinder implements StatementVisitor, ExprVisitor { + Set asyncCalls = new HashSet<>(); + Set allCalls = new HashSet<>(); + + private void visitList(List statements) { + for (Statement stmt : statements) { + stmt.acceptVisitor(this); + } + } + + @Override + public void visit(AssignmentStatement statement) { + if (statement.getLeftValue() != null) { + statement.getLeftValue().acceptVisitor(this); + } + statement.getRightValue().acceptVisitor(this); + if (!statement.isAsync()) { + statement.getRightValue().acceptVisitor(this); + return; + } + if (!(statement.getRightValue() instanceof InvocationExpr)) { + statement.getRightValue().acceptVisitor(this); + return; + } + InvocationExpr invocation = (InvocationExpr)statement.getRightValue(); + asyncCalls.add(invocation.getMethod()); + } + + @Override + public void visit(SequentialStatement statement) { + visitList(statement.getSequence()); + } + + @Override + public void visit(ConditionalStatement statement) { + visitList(statement.getConsequent()); + visitList(statement.getAlternative()); + statement.getCondition().acceptVisitor(this); + } + + @Override + public void visit(SwitchStatement statement) { + for (SwitchClause clause : statement.getClauses()) { + visitList(clause.getBody()); + } + visitList(statement.getDefaultClause()); + statement.getValue().acceptVisitor(this); + } + + @Override + public void visit(WhileStatement statement) { + visitList(statement.getBody()); + if (statement.getCondition() != null) { + statement.getCondition().acceptVisitor(this); + } + } + + @Override + public void visit(BlockStatement statement) { + visitList(statement.getBody()); + } + + @Override + public void visit(BreakStatement statement) { + } + + @Override + public void visit(ContinueStatement statement) { + } + + @Override + public void visit(ReturnStatement statement) { + if (statement.getResult() != null) { + statement.getResult().acceptVisitor(this); + } + } + + @Override + public void visit(ThrowStatement statement) { + statement.getException().acceptVisitor(this); + } + + @Override + public void visit(InitClassStatement statement) { + } + + @Override + public void visit(TryCatchStatement statement) { + visitList(statement.getProtectedBody()); + visitList(statement.getHandler()); + } + + @Override + public void visit(GotoPartStatement statement) { + } + + @Override + public void visit(MonitorEnterStatement statement) { + statement.getObjectRef().acceptVisitor(this); + } + + @Override + public void visit(MonitorExitStatement statement) { + statement.getObjectRef().acceptVisitor(this); + } + + @Override + public void visit(BinaryExpr expr) { + expr.getFirstOperand().acceptVisitor(this); + expr.getSecondOperand().acceptVisitor(this); + } + + @Override + public void visit(UnaryExpr expr) { + expr.getOperand().acceptVisitor(this); + } + + @Override + public void visit(ConditionalExpr expr) { + expr.getCondition().acceptVisitor(this); + expr.getConsequent().acceptVisitor(this); + expr.getAlternative().acceptVisitor(this); + } + + @Override + public void visit(ConstantExpr expr) { + } + + @Override + public void visit(VariableExpr expr) { + } + + @Override + public void visit(SubscriptExpr expr) { + expr.getArray().acceptVisitor(this); + expr.getIndex().acceptVisitor(this); + } + + @Override + public void visit(UnwrapArrayExpr expr) { + expr.getArray().acceptVisitor(this); + } + + @Override + public void visit(InvocationExpr expr) { + allCalls.add(expr.getMethod()); + for (Expr arg : expr.getArguments()) { + arg.acceptVisitor(this); + } + } + + @Override + public void visit(QualificationExpr expr) { + expr.getQualified().acceptVisitor(this); + } + + @Override + public void visit(NewExpr expr) { + } + + @Override + public void visit(NewArrayExpr expr) { + expr.getLength().acceptVisitor(this); + } + + @Override + public void visit(NewMultiArrayExpr expr) { + for (Expr dim : expr.getDimensions()) { + dim.acceptVisitor(this); + } + } + + @Override + public void visit(InstanceOfExpr expr) { + expr.getExpr().acceptVisitor(this); + } + + @Override + public void visit(StaticClassExpr expr) { + } +} 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 31a430daa..c3948c85e 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java @@ -44,7 +44,7 @@ public class Decompiler { private RangeTree.Node parentNode; private Map generators = new HashMap<>(); private Set methodsToPass = new HashSet<>(); - private RegularMethodNodeCache regularMethodCache; + private MethodNodeCache regularMethodCache; private Set asyncMethods; private Set splitMethods = new HashSet<>(); @@ -57,11 +57,11 @@ public class Decompiler { splitMethods.addAll(asyncFamilyMethods); } - public RegularMethodNodeCache getRegularMethodCache() { + public MethodNodeCache getRegularMethodCache() { return regularMethodCache; } - public void setRegularMethodCache(RegularMethodNodeCache regularMethodCache) { + public void setRegularMethodCache(MethodNodeCache regularMethodCache) { this.regularMethodCache = regularMethodCache; } @@ -198,7 +198,58 @@ public class Decompiler { return node; } + public RegularMethodNode decompileRegularCacheMiss(MethodHolder method) { + RegularMethodNode methodNode = new RegularMethodNode(method.getReference()); + Program program = method.getProgram(); + int[] targetBlocks = new int[program.basicBlockCount()]; + Arrays.fill(targetBlocks, -1); + methodNode.setBody(getRegularMethodStatement(program, targetBlocks, false).getStatement()); + for (int i = 0; i < program.variableCount(); ++i) { + methodNode.getVariables().add(program.variableAt(i).getRegister()); + } + Optimizer optimizer = new Optimizer(); + optimizer.optimize(methodNode, method.getProgram()); + methodNode.getModifiers().addAll(mapModifiers(method.getModifiers())); + int paramCount = Math.min(method.getSignature().length, program.variableCount()); + for (int i = 0; i < paramCount; ++i) { + Variable var = program.variableAt(i); + methodNode.getParameterDebugNames().add(new HashSet<>(var.getDebugNames())); + } + return methodNode; + } + public AsyncMethodNode decompileAsync(MethodHolder method) { + if (regularMethodCache == null) { + return decompileAsyncCacheMiss(method); + } + AsyncMethodNode node = regularMethodCache.getAsync(method.getReference()); + if (node == null || !checkAsyncRelevant(node)) { + node = decompileAsyncCacheMiss(method); + regularMethodCache.storeAsync(method.getReference(), node); + } + return node; + } + + private boolean checkAsyncRelevant(AsyncMethodNode node) { + AsyncCallsFinder asyncCallsFinder = new AsyncCallsFinder(); + for (AsyncMethodPart part : node.getBody()) { + part.getStatement().acceptVisitor(asyncCallsFinder); + } + for (MethodReference asyncCall : asyncCallsFinder.asyncCalls) { + if (!splitMethods.contains(asyncCall)) { + return false; + } + } + asyncCallsFinder.allCalls.removeAll(asyncCallsFinder.asyncCalls); + for (MethodReference asyncCall : asyncCallsFinder.allCalls) { + if (splitMethods.contains(asyncCall)) { + return false; + } + } + return true; + } + + public AsyncMethodNode decompileAsyncCacheMiss(MethodHolder method) { AsyncMethodNode node = new AsyncMethodNode(method.getReference()); AsyncProgramSplitter splitter = new AsyncProgramSplitter(classSource, splitMethods); splitter.split(method.getProgram()); @@ -222,26 +273,6 @@ public class Decompiler { return node; } - public RegularMethodNode decompileRegularCacheMiss(MethodHolder method) { - RegularMethodNode methodNode = new RegularMethodNode(method.getReference()); - Program program = method.getProgram(); - int[] targetBlocks = new int[program.basicBlockCount()]; - Arrays.fill(targetBlocks, -1); - methodNode.setBody(getRegularMethodStatement(program, targetBlocks, false).getStatement()); - for (int i = 0; i < program.variableCount(); ++i) { - methodNode.getVariables().add(program.variableAt(i).getRegister()); - } - Optimizer optimizer = new Optimizer(); - optimizer.optimize(methodNode, method.getProgram()); - methodNode.getModifiers().addAll(mapModifiers(method.getModifiers())); - int paramCount = Math.min(method.getSignature().length, program.variableCount()); - for (int i = 0; i < paramCount; ++i) { - Variable var = program.variableAt(i); - methodNode.getParameterDebugNames().add(new HashSet<>(var.getDebugNames())); - } - return methodNode; - } - private AsyncMethodPart getRegularMethodStatement(Program program, int[] targetBlocks, boolean async) { AsyncMethodPart result = new AsyncMethodPart(); lastBlockId = 1; diff --git a/teavm-core/src/main/java/org/teavm/javascript/EmptyRegularMethodNodeCache.java b/teavm-core/src/main/java/org/teavm/javascript/EmptyRegularMethodNodeCache.java index b08e93c94..8e5ca68f7 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/EmptyRegularMethodNodeCache.java +++ b/teavm-core/src/main/java/org/teavm/javascript/EmptyRegularMethodNodeCache.java @@ -15,6 +15,7 @@ */ package org.teavm.javascript; +import org.teavm.javascript.ast.AsyncMethodNode; import org.teavm.javascript.ast.RegularMethodNode; import org.teavm.model.MethodReference; @@ -22,7 +23,7 @@ import org.teavm.model.MethodReference; * * @author Alexey Andreev */ -public class EmptyRegularMethodNodeCache implements RegularMethodNodeCache { +public class EmptyRegularMethodNodeCache implements MethodNodeCache { @Override public RegularMethodNode get(MethodReference methodReference) { return null; @@ -31,4 +32,13 @@ public class EmptyRegularMethodNodeCache implements RegularMethodNodeCache { @Override public void store(MethodReference methodReference, RegularMethodNode node) { } + + @Override + public AsyncMethodNode getAsync(MethodReference methodReference) { + return null; + } + + @Override + public void storeAsync(MethodReference methodReference, AsyncMethodNode node) { + } } diff --git a/teavm-core/src/main/java/org/teavm/javascript/InMemoryRegularMethodNodeCache.java b/teavm-core/src/main/java/org/teavm/javascript/InMemoryRegularMethodNodeCache.java index 330c2bdc7..5f2bb9d7b 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/InMemoryRegularMethodNodeCache.java +++ b/teavm-core/src/main/java/org/teavm/javascript/InMemoryRegularMethodNodeCache.java @@ -17,6 +17,7 @@ package org.teavm.javascript; import java.util.HashMap; import java.util.Map; +import org.teavm.javascript.ast.AsyncMethodNode; import org.teavm.javascript.ast.RegularMethodNode; import org.teavm.model.MethodReference; @@ -24,8 +25,9 @@ import org.teavm.model.MethodReference; * * @author Alexey Andreev */ -public class InMemoryRegularMethodNodeCache implements RegularMethodNodeCache { +public class InMemoryRegularMethodNodeCache implements MethodNodeCache { private Map cache = new HashMap<>(); + private Map asyncCache = new HashMap<>(); @Override public RegularMethodNode get(MethodReference methodReference) { @@ -36,4 +38,14 @@ public class InMemoryRegularMethodNodeCache implements RegularMethodNodeCache { public void store(MethodReference methodReference, RegularMethodNode node) { cache.put(methodReference, node); } + + @Override + public AsyncMethodNode getAsync(MethodReference methodReference) { + return null; + } + + @Override + public void storeAsync(MethodReference methodReference, AsyncMethodNode node) { + asyncCache.put(methodReference, node); + } } diff --git a/teavm-core/src/main/java/org/teavm/javascript/RegularMethodNodeCache.java b/teavm-core/src/main/java/org/teavm/javascript/MethodNodeCache.java similarity index 80% rename from teavm-core/src/main/java/org/teavm/javascript/RegularMethodNodeCache.java rename to teavm-core/src/main/java/org/teavm/javascript/MethodNodeCache.java index 62015c967..f66d2c860 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/RegularMethodNodeCache.java +++ b/teavm-core/src/main/java/org/teavm/javascript/MethodNodeCache.java @@ -15,6 +15,7 @@ */ package org.teavm.javascript; +import org.teavm.javascript.ast.AsyncMethodNode; import org.teavm.javascript.ast.RegularMethodNode; import org.teavm.model.MethodReference; @@ -22,8 +23,12 @@ import org.teavm.model.MethodReference; * * @author Alexey Andreev */ -public interface RegularMethodNodeCache { +public interface MethodNodeCache { RegularMethodNode get(MethodReference methodReference); void store(MethodReference methodReference, RegularMethodNode node); + + AsyncMethodNode getAsync(MethodReference methodReference); + + void storeAsync(MethodReference methodReference, AsyncMethodNode node); } diff --git a/teavm-core/src/main/java/org/teavm/tooling/TeaVMTestTool.java b/teavm-core/src/main/java/org/teavm/tooling/TeaVMTestTool.java index 6c680821c..14c9a08d3 100644 --- a/teavm-core/src/main/java/org/teavm/tooling/TeaVMTestTool.java +++ b/teavm-core/src/main/java/org/teavm/tooling/TeaVMTestTool.java @@ -25,7 +25,7 @@ import org.teavm.debugging.information.DebugInformation; import org.teavm.debugging.information.DebugInformationBuilder; import org.teavm.javascript.EmptyRegularMethodNodeCache; import org.teavm.javascript.InMemoryRegularMethodNodeCache; -import org.teavm.javascript.RegularMethodNodeCache; +import org.teavm.javascript.MethodNodeCache; import org.teavm.model.*; import org.teavm.parsing.ClasspathClassHolderSource; import org.teavm.testing.JUnitTestAdapter; @@ -58,7 +58,7 @@ public class TeaVMTestTool { private boolean sourceFilesCopied; private boolean incremental; private List sourceFileProviders = new ArrayList<>(); - private RegularMethodNodeCache astCache; + private MethodNodeCache astCache; private ProgramCache programCache; private SourceFilesCopier sourceFilesCopier; diff --git a/teavm-core/src/main/java/org/teavm/vm/TeaVM.java b/teavm-core/src/main/java/org/teavm/vm/TeaVM.java index 4f0d4d107..edc1e69b7 100644 --- a/teavm-core/src/main/java/org/teavm/vm/TeaVM.java +++ b/teavm-core/src/main/java/org/teavm/vm/TeaVM.java @@ -84,7 +84,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository { private Properties properties = new Properties(); private DebugInformationEmitter debugEmitter; private ProgramCache programCache; - private RegularMethodNodeCache astCache = new EmptyRegularMethodNodeCache(); + private MethodNodeCache astCache = new EmptyRegularMethodNodeCache(); private boolean incremental; private TeaVMProgressListener progressListener; private boolean cancelled; @@ -181,11 +181,11 @@ public class TeaVM implements TeaVMHost, ServiceRepository { return new Properties(properties); } - public RegularMethodNodeCache getAstCache() { + public MethodNodeCache getAstCache() { return astCache; } - public void setAstCache(RegularMethodNodeCache methodAstCache) { + public void setAstCache(MethodNodeCache methodAstCache) { this.astCache = methodAstCache; } From 17ccec57e94e4dd1578a864351991f5ff8ceac34 Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Sun, 15 Mar 2015 18:22:39 +0300 Subject: [PATCH 67/69] Add missing javadoc tags --- .../org/teavm/classlib/java/lang/TClass.java | 1 + .../teavm/classlib/java/lang/TComparable.java | 1 + .../org/teavm/classlib/java/lang/TEnum.java | 1 + .../teavm/classlib/java/lang/TIterable.java | 1 + .../classlib/java/lang/TThreadLocal.java | 1 + .../classlib/java/lang/ref/TReference.java | 1 + .../java/lang/ref/TReferenceQueue.java | 1 + .../java/lang/ref/TWeakReference.java | 1 + .../java/util/TAbstractCollection.java | 1 + .../classlib/java/util/TAbstractList.java | 1 + .../classlib/java/util/TAbstractMap.java | 2 ++ .../classlib/java/util/TAbstractQueue.java | 1 + .../java/util/TAbstractSequentialList.java | 1 + .../classlib/java/util/TAbstractSet.java | 1 + .../teavm/classlib/java/util/TArrayDeque.java | 1 + .../teavm/classlib/java/util/TArrayList.java | 1 + .../teavm/classlib/java/util/TCollection.java | 1 + .../teavm/classlib/java/util/TComparator.java | 1 + .../org/teavm/classlib/java/util/TDeque.java | 1 + .../classlib/java/util/TEnumeration.java | 1 + .../teavm/classlib/java/util/THashSet.java | 1 + .../teavm/classlib/java/util/TIterator.java | 1 + .../teavm/classlib/java/util/TLinkedList.java | 1 + .../org/teavm/classlib/java/util/TList.java | 1 + .../classlib/java/util/TListIterator.java | 1 + .../org/teavm/classlib/java/util/TMap.java | 2 ++ .../classlib/java/util/TNavigableMap.java | 2 ++ .../classlib/java/util/TNavigableSet.java | 1 + .../classlib/java/util/TPriorityQueue.java | 1 + .../org/teavm/classlib/java/util/TQueue.java | 1 + .../classlib/java/util/TServiceLoader.java | 1 + .../org/teavm/classlib/java/util/TSet.java | 1 + .../teavm/classlib/java/util/TSetFromMap.java | 1 + .../teavm/classlib/java/util/TSortedMap.java | 2 ++ .../teavm/classlib/java/util/TSortedSet.java | 1 + .../teavm/classlib/java/util/TTreeSet.java | 1 + .../java/util/concurrent/TCallable.java | 1 + .../java/util/regex/TAbstractCharClass.java | 6 ------ .../java/util/regex/TAbstractSet.java | 11 ----------- .../regex/TCompositeGroupQuantifierSet.java | 10 ---------- .../classlib/java/util/regex/TLeafSet.java | 4 ---- .../classlib/java/util/regex/TLexer.java | 19 ------------------- .../java/util/regex/TQuantifierSet.java | 3 --- .../org/teavm/callgraph/CallGraphNode.java | 10 +++++++++- .../java/org/teavm/callgraph/CallSite.java | 4 ++++ .../java/org/teavm/common/CachedMapper.java | 3 +++ .../main/java/org/teavm/common/Mapper.java | 2 ++ .../src/main/java/org/teavm/vm/TeaVM.java | 6 ++++++ .../main/java/org/teavm/vm/spi/TeaVMHost.java | 1 + .../java/org/teavm/dom/core/NamedNodeMap.java | 1 + .../java/org/teavm/dom/core/NodeList.java | 1 + .../src/main/java/org/teavm/jso/JSArray.java | 1 + .../java/org/teavm/jso/JSArrayReader.java | 1 + .../java/org/teavm/jso/JSSortFunction.java | 1 + .../org/teavm/platform/PlatformQueue.java | 1 + .../org/teavm/platform/PlatformSequence.java | 1 + .../teavm/platform/async/AsyncCallback.java | 1 + .../platform/metadata/MetadataGenerator.java | 1 + .../metadata/MetadataGeneratorContext.java | 18 ++++++++++++++++++ .../platform/metadata/ResourceArray.java | 1 + .../teavm/platform/metadata/ResourceMap.java | 1 + .../teavm/classlib/java/util/TreeMapTest.java | 2 +- 62 files changed, 96 insertions(+), 55 deletions(-) diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java index c040c4de9..f9056ae48 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java @@ -24,6 +24,7 @@ import org.teavm.platform.metadata.ClassScopedMetadataProvider; /** * * @author Alexey Andreev + * @param class type. */ public class TClass extends TObject { TString name; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TComparable.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TComparable.java index c56236365..2d8489fca 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TComparable.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TComparable.java @@ -18,6 +18,7 @@ package org.teavm.classlib.java.lang; /** * * @author Alexey Andreev + * @param type this object is comparable to. */ public interface TComparable { int compareTo(T other); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TEnum.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TEnum.java index c1d462131..df445cbfa 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TEnum.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TEnum.java @@ -21,6 +21,7 @@ import org.teavm.javascript.spi.Rename; /** * * @author Alexey Andreev + * @param type of enum. */ public abstract class TEnum> extends TObject implements TComparable, TSerializable { private TString name; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIterable.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIterable.java index 473ac0758..c99aecfb9 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIterable.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TIterable.java @@ -20,6 +20,7 @@ import org.teavm.classlib.java.util.TIterator; /** * * @author Alexey Andreev + * @param type this collection returns. */ public interface TIterable { TIterator iterator(); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThreadLocal.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThreadLocal.java index 31a7be47c..ec9a3a080 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThreadLocal.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThreadLocal.java @@ -18,6 +18,7 @@ package org.teavm.classlib.java.lang; /** * * @author Alexey Andreev + * @param type of a value stored by thread local. */ public class TThreadLocal extends TObject { private boolean initialized; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/ref/TReference.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/ref/TReference.java index ba740d223..8319691d3 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/ref/TReference.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/ref/TReference.java @@ -20,6 +20,7 @@ import org.teavm.classlib.java.lang.TObject; /** * * @author Alexey Andreev + * @param type of an object to which this reference points. */ public abstract class TReference extends TObject { public T get() { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/ref/TReferenceQueue.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/ref/TReferenceQueue.java index e3b50ce9d..341572776 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/ref/TReferenceQueue.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/ref/TReferenceQueue.java @@ -18,6 +18,7 @@ package org.teavm.classlib.java.lang.ref; /** * * @author Alexey Andreev + * @param */ public class TReferenceQueue { public TReference poll() { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/ref/TWeakReference.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/ref/TWeakReference.java index b14232f8f..b3385efad 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/ref/TWeakReference.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/ref/TWeakReference.java @@ -18,6 +18,7 @@ package org.teavm.classlib.java.lang.ref; /** * * @author Alexey Andreev + * @param */ public class TWeakReference extends TReference { private T value; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractCollection.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractCollection.java index 6e1a2d3bb..91acd1708 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractCollection.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractCollection.java @@ -22,6 +22,7 @@ import org.teavm.classlib.java.lang.TUnsupportedOperationException; /** * * @author Alexey Andreev + * @param */ public abstract class TAbstractCollection extends TObject implements TCollection { protected TAbstractCollection() { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractList.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractList.java index 54951b850..1b2efe4d1 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractList.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractList.java @@ -21,6 +21,7 @@ import org.teavm.javascript.spi.Rename; /** * * @author Alexey Andreev + * @param */ public abstract class TAbstractList extends TAbstractCollection implements TList { protected transient int modCount; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractMap.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractMap.java index 731f884cc..1d8f7e9bd 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractMap.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractMap.java @@ -23,6 +23,8 @@ import org.teavm.classlib.java.lang.TUnsupportedOperationException; /** * * @author Alexey Andreev + * @param + * @param */ public abstract class TAbstractMap extends TObject implements TMap { public static class SimpleEntry implements TMap.Entry, TSerializable { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractQueue.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractQueue.java index f0fe3ecdf..39a974059 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractQueue.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractQueue.java @@ -20,6 +20,7 @@ import org.teavm.classlib.java.lang.TIllegalStateException; /** * * @author Alexey Andreev + * @param */ public abstract class TAbstractQueue extends TAbstractCollection implements TQueue { @Override diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractSequentialList.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractSequentialList.java index cdb095cd4..8483efbe5 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractSequentialList.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractSequentialList.java @@ -20,6 +20,7 @@ import org.teavm.classlib.java.lang.TIndexOutOfBoundsException; /** * * @author Alexey Andreev + * @param */ public abstract class TAbstractSequentialList extends TAbstractList { @Override diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractSet.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractSet.java index da20f4512..db2eb6543 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractSet.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TAbstractSet.java @@ -18,6 +18,7 @@ package org.teavm.classlib.java.util; /** * * @author Alexey Andreev + * @param */ public abstract class TAbstractSet extends TAbstractCollection implements TSet { public TAbstractSet() { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TArrayDeque.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TArrayDeque.java index 163e2e81a..e5886b777 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TArrayDeque.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TArrayDeque.java @@ -21,6 +21,7 @@ import org.teavm.classlib.java.lang.*; /** * * @author Alexey Andreev + * @param */ public class TArrayDeque extends TAbstractCollection implements TDeque { private int version; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TArrayList.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TArrayList.java index 1e4a9ad99..64702736c 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TArrayList.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TArrayList.java @@ -23,6 +23,7 @@ import org.teavm.javascript.spi.Rename; /** * * @author Alexey Andreev + * @param */ public class TArrayList extends TAbstractList implements TCloneable, TSerializable { private E[] array; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TCollection.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TCollection.java index e604d722d..425813213 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TCollection.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TCollection.java @@ -20,6 +20,7 @@ import org.teavm.classlib.java.lang.TIterable; /** * * @author Alexey Andreev + * @param */ public interface TCollection extends TIterable { int size(); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TComparator.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TComparator.java index f068c683c..fe591fde9 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TComparator.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TComparator.java @@ -18,6 +18,7 @@ package org.teavm.classlib.java.util; /** * * @author Alexey Andreev + * @param */ public interface TComparator { int compare(T o1, T o2); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TDeque.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TDeque.java index 9598b0507..6352d843f 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TDeque.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TDeque.java @@ -18,6 +18,7 @@ package org.teavm.classlib.java.util; /** * * @author Alexey Andreev + * @param */ public interface TDeque extends TQueue { void addFirst(E e); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TEnumeration.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TEnumeration.java index 89eecfebf..9bb170498 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TEnumeration.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TEnumeration.java @@ -18,6 +18,7 @@ package org.teavm.classlib.java.util; /** * * @author Alexey Andreev + * @param */ public interface TEnumeration { boolean hasMoreElements(); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/THashSet.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/THashSet.java index eff1c5a1e..133505bcb 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/THashSet.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/THashSet.java @@ -25,6 +25,7 @@ import org.teavm.javascript.spi.Rename; /** * * @author Alexey Andreev + * @param */ public class THashSet extends TAbstractSet implements TCloneable, TSerializable { transient THashMap> backingMap; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TIterator.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TIterator.java index d06f53c14..bb50abc3b 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TIterator.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TIterator.java @@ -18,6 +18,7 @@ package org.teavm.classlib.java.util; /** * * @author Alexey Andreev + * @param */ public interface TIterator { boolean hasNext(); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TLinkedList.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TLinkedList.java index 7c7a80518..cdf096d66 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TLinkedList.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TLinkedList.java @@ -19,6 +19,7 @@ package org.teavm.classlib.java.util; /** * * @author Alexey Andreev + * @param */ public class TLinkedList extends TAbstractSequentialList implements TDeque { static class Entry { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TList.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TList.java index ca915c89e..0c6ac7c51 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TList.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TList.java @@ -18,6 +18,7 @@ package org.teavm.classlib.java.util; /** * * @author Alexey Andreev + * @param */ public interface TList extends TCollection { boolean addAll(int index, TCollection c); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TListIterator.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TListIterator.java index 0ae00d745..9f99a3427 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TListIterator.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TListIterator.java @@ -18,6 +18,7 @@ package org.teavm.classlib.java.util; /** * * @author Alexey Andreev + * @param */ public interface TListIterator extends TIterator { boolean hasPrevious(); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TMap.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TMap.java index c1c08f945..a11e31be9 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TMap.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TMap.java @@ -18,6 +18,8 @@ package org.teavm.classlib.java.util; /** * * @author Alexey Andreev + * @param + * @param */ public interface TMap { public static interface Entry { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TNavigableMap.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TNavigableMap.java index 49dc61f46..99fa032bc 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TNavigableMap.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TNavigableMap.java @@ -18,6 +18,8 @@ package org.teavm.classlib.java.util; /** * * @author Alexey Andreev + * @param + * @param */ public interface TNavigableMap extends TSortedMap { Entry lowerEntry(K key); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TNavigableSet.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TNavigableSet.java index fb03512da..0e2715d64 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TNavigableSet.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TNavigableSet.java @@ -18,6 +18,7 @@ package org.teavm.classlib.java.util; /** * * @author Alexey Andreev + * @param */ public interface TNavigableSet extends TSortedSet { E lower(E e); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TPriorityQueue.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TPriorityQueue.java index 93aa64476..2ae5f83e8 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TPriorityQueue.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TPriorityQueue.java @@ -25,6 +25,7 @@ import org.teavm.classlib.java.lang.TNullPointerException; /** * * @author Alexey Andreev + * @param */ public class TPriorityQueue extends TAbstractQueue implements TSerializable { private Object[] data; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TQueue.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TQueue.java index 594183787..27b2805cf 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TQueue.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TQueue.java @@ -18,6 +18,7 @@ package org.teavm.classlib.java.util; /** * * @author Alexey Andreev + * @param */ public interface TQueue extends TCollection { boolean offer(E e); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TServiceLoader.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TServiceLoader.java index e4df072af..0e628b5b9 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TServiceLoader.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TServiceLoader.java @@ -21,6 +21,7 @@ import org.teavm.platform.PlatformClass; /** * * @author Alexey Andreev + * @param */ public final class TServiceLoader extends TObject implements TIterable { private Object[] services; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TSet.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TSet.java index 396d4b0d9..e29017c95 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TSet.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TSet.java @@ -18,6 +18,7 @@ package org.teavm.classlib.java.util; /** * * @author Alexey Andreev + * @param */ public interface TSet extends TCollection { } diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TSetFromMap.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TSetFromMap.java index cf397b90c..f2b943ca8 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TSetFromMap.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TSetFromMap.java @@ -20,6 +20,7 @@ import org.teavm.classlib.java.lang.TBoolean; /** * * @author Alexey Andreev + * @param */ public class TSetFromMap extends TAbstractSet { private TMap map; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TSortedMap.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TSortedMap.java index 864e32245..4815accc3 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TSortedMap.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TSortedMap.java @@ -18,6 +18,8 @@ package org.teavm.classlib.java.util; /** * * @author Alexey Andreev + * @param + * @param */ public interface TSortedMap extends TMap { TComparator comparator(); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TSortedSet.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TSortedSet.java index 3a58e5c90..d9d92be93 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TSortedSet.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TSortedSet.java @@ -18,6 +18,7 @@ package org.teavm.classlib.java.util; /** * * @author Alexey Andreev + * @param */ public interface TSortedSet extends TSet { TComparator comparator(); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TTreeSet.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TTreeSet.java index 5d8ef7815..034551234 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TTreeSet.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/TTreeSet.java @@ -3,6 +3,7 @@ package org.teavm.classlib.java.util; /** * * @author Alexey Andreev + * @param */ public class TTreeSet extends TAbstractSet implements TNavigableSet { private static final Object VALUE = new Object(); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/concurrent/TCallable.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/concurrent/TCallable.java index bbbea5f72..17b36d7ef 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/concurrent/TCallable.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/concurrent/TCallable.java @@ -21,6 +21,7 @@ import org.teavm.classlib.java.lang.TObject; /** * * @author Alexey Andreev + * @param */ public interface TCallable { V call() throws TException; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TAbstractCharClass.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TAbstractCharClass.java index 952712f74..af4987cc1 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TAbstractCharClass.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TAbstractCharClass.java @@ -68,12 +68,6 @@ abstract class TAbstractCharClass extends TSpecialToken { */ protected boolean mayContainSupplCodepoints = false; - /** - * Returns true if this char class contains character specified; - * - * @param ch - * character to check; - */ abstract public boolean contains(int ch); /** diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TAbstractSet.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TAbstractSet.java index 7f3c3c934..d985b2a11 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TAbstractSet.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TAbstractSet.java @@ -143,14 +143,6 @@ abstract class TAbstractSet { return -1; } - /** - * Returns true, if this node has consumed any characters during positive - * match attempt, for example node representing character always consumes - * one character if it matches. If particular node matches empty sting this - * method will return false; - * - * @param matchResult - */ public abstract boolean hasConsumed(TMatchResultImpl matchResult); /** @@ -175,9 +167,6 @@ abstract class TAbstractSet { return getQualifiedName(); } - /** - * Returns the next. - */ public TAbstractSet getNext() { return next; } diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TCompositeGroupQuantifierSet.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TCompositeGroupQuantifierSet.java index 09cbfca29..451c01aac 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TCompositeGroupQuantifierSet.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TCompositeGroupQuantifierSet.java @@ -46,16 +46,6 @@ class TCompositeGroupQuantifierSet extends TGroupQuantifierSet { int setCounter; - /** - * Constructs CompositeGroupQuantifierSet - * - * @param quant - * - given composite quantifier - * @param innerSet - * - given group - * @param next - * - next set after the quantifier - */ public TCompositeGroupQuantifierSet(TQuantifier quant, TAbstractSet innerSet, TAbstractSet next, int type, int setCounter) { super(innerSet, next, type); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TLeafSet.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TLeafSet.java index 9d349dbd0..e7c914ce6 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TLeafSet.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TLeafSet.java @@ -38,10 +38,6 @@ abstract class TLeafSet extends TAbstractSet { public TLeafSet() { } - /** - * Returns "shift", the number of accepted chars commonly internal function, - * but called by quantifiers. - */ public abstract int accepts(int stringIndex, CharSequence testString); /** diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TLexer.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TLexer.java index 4b344dae8..5b1752ed8 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TLexer.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TLexer.java @@ -281,34 +281,21 @@ class TLexer { return lookAheadST != null; } - /** - * Returns current character and moves string index to the next one; - * - */ public int next() { movePointer(); return lookBack; } - /** - * Returns current special token and moves string index to the next one; - */ public TSpecialToken nextSpecial() { TSpecialToken res = curST; movePointer(); return res; } - /** - * Returns nest symbol read. - */ public int lookAhead() { return lookAhead; } - /** - * Returns previous character. - */ public int back() { return lookBack; } @@ -780,9 +767,6 @@ class TLexer { return ch == 0 && lookAhead == 0 && index == patternFullLength && !isSpecial(); } - /** - * Returns true if current character is plain token. - */ public static boolean isLetter(int ch) { // all supplementary codepoints have integer value that is >= 0; @@ -1061,9 +1045,6 @@ class TLexer { return high; } - /** - * Returns the curr. character index. - */ public int getIndex() { return curToc; } diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TQuantifierSet.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TQuantifierSet.java index 52d38ee98..a18289ed2 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TQuantifierSet.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/util/regex/TQuantifierSet.java @@ -35,9 +35,6 @@ abstract class TQuantifierSet extends TAbstractSet { setType(type); } - /** - * Returns the innerSet. - */ public TAbstractSet getInnerSet() { return innerSet; } diff --git a/teavm-core/src/main/java/org/teavm/callgraph/CallGraphNode.java b/teavm-core/src/main/java/org/teavm/callgraph/CallGraphNode.java index b027e3bed..445df4552 100644 --- a/teavm-core/src/main/java/org/teavm/callgraph/CallGraphNode.java +++ b/teavm-core/src/main/java/org/teavm/callgraph/CallGraphNode.java @@ -23,23 +23,31 @@ import org.teavm.model.MethodReference; * @author Alexey Andreev */ public interface CallGraphNode { - /* + /** * Returns reference to entire call graph. + * + * @return graph */ CallGraph getGraph(); /** * Returns the method that this node represents. + * + * @return method */ MethodReference getMethod(); /** * Returns immutable collection of all call sites that are in the method. + * + * @return call site */ Collection getCallSites(); /** * Returns immutable collection of all call sites that call this method. + * + * @return call sites */ Collection getCallerCallSites(); diff --git a/teavm-core/src/main/java/org/teavm/callgraph/CallSite.java b/teavm-core/src/main/java/org/teavm/callgraph/CallSite.java index 3aa170b13..b5282ca4b 100644 --- a/teavm-core/src/main/java/org/teavm/callgraph/CallSite.java +++ b/teavm-core/src/main/java/org/teavm/callgraph/CallSite.java @@ -31,11 +31,15 @@ public interface CallSite { /** *

Gets a method that this call site invokes.

+ * + * @return a node that represent methods being called */ CallGraphNode getCallee(); /** *

Gets a method that contains this call site.

+ * + * @return a node that represents methods's caller */ CallGraphNode getCaller(); } diff --git a/teavm-core/src/main/java/org/teavm/common/CachedMapper.java b/teavm-core/src/main/java/org/teavm/common/CachedMapper.java index 2fdee5642..c54df64d9 100644 --- a/teavm-core/src/main/java/org/teavm/common/CachedMapper.java +++ b/teavm-core/src/main/java/org/teavm/common/CachedMapper.java @@ -20,6 +20,9 @@ import java.util.*; /** * * @author Alexey Andreev + * + * @param which type this mapper takes. + * @param which type this mapper produces. */ public class CachedMapper implements Mapper { private Mapper innerMapper; diff --git a/teavm-core/src/main/java/org/teavm/common/Mapper.java b/teavm-core/src/main/java/org/teavm/common/Mapper.java index af16bcbe5..e4d54c1af 100644 --- a/teavm-core/src/main/java/org/teavm/common/Mapper.java +++ b/teavm-core/src/main/java/org/teavm/common/Mapper.java @@ -18,6 +18,8 @@ package org.teavm.common; /** * * @author Alexey Andreev + * @param which type this mapper takes. + * @param which type this mapper produces. */ public interface Mapper { R map(T preimage); diff --git a/teavm-core/src/main/java/org/teavm/vm/TeaVM.java b/teavm-core/src/main/java/org/teavm/vm/TeaVM.java index edc1e69b7..f06967cd5 100644 --- a/teavm-core/src/main/java/org/teavm/vm/TeaVM.java +++ b/teavm-core/src/main/java/org/teavm/vm/TeaVM.java @@ -140,6 +140,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository { * Reports whether this TeaVM instance uses obfuscation when generating the JavaScript code. * * @see #setMinifying(boolean) + * @return whether TeaVM produces obfuscated code. */ public boolean isMinifying() { return minifying; @@ -149,6 +150,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository { * Specifies whether this TeaVM instance uses obfuscation when generating the JavaScript code. * * @see #isMinifying() + * @param minifying whether TeaVM should obfuscate code. */ public void setMinifying(boolean minifying) { this.minifying = minifying; @@ -287,6 +289,8 @@ public class TeaVM implements TeaVMHost, ServiceRepository { /** * Gets a {@link ClassReaderSource} which is used by this TeaVM instance. It is exactly what was * passed to {@link TeaVMBuilder#setClassSource(ClassHolderSource)}. + * + * @return class source. */ public ClassReaderSource getClassSource() { return classSource; @@ -322,6 +326,8 @@ public class TeaVM implements TeaVMHost, ServiceRepository { * @param writer where to generate JavaScript. Should not be null. * @param target where to generate additional resources. Can be null, but if there are * plugins or inteceptors that generate additional resources, the build process will fail. + * + * @throws RenderingException when something went wrong during rendering phase. */ public void build(Appendable writer, BuildTarget target) throws RenderingException { // Check dependencies diff --git a/teavm-core/src/main/java/org/teavm/vm/spi/TeaVMHost.java b/teavm-core/src/main/java/org/teavm/vm/spi/TeaVMHost.java index 10a8e6c15..d76709353 100644 --- a/teavm-core/src/main/java/org/teavm/vm/spi/TeaVMHost.java +++ b/teavm-core/src/main/java/org/teavm/vm/spi/TeaVMHost.java @@ -46,6 +46,7 @@ public interface TeaVMHost { /** * Gets class loaded that is used by TeaVM. This class loader is usually specified by * {@link TeaVMBuilder#setClassLoader(ClassLoader)} + * @return class loader that can be used by plugins. */ ClassLoader getClassLoader(); diff --git a/teavm-dom/src/main/java/org/teavm/dom/core/NamedNodeMap.java b/teavm-dom/src/main/java/org/teavm/dom/core/NamedNodeMap.java index 394127fa9..56318ec32 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/core/NamedNodeMap.java +++ b/teavm-dom/src/main/java/org/teavm/dom/core/NamedNodeMap.java @@ -22,6 +22,7 @@ import org.teavm.jso.JSProperty; /** * * @author Alexey Andreev + * @param type of nodes in this map. */ public interface NamedNodeMap extends JSObject, JSArrayReader { T getNamedItem(String name); diff --git a/teavm-dom/src/main/java/org/teavm/dom/core/NodeList.java b/teavm-dom/src/main/java/org/teavm/dom/core/NodeList.java index f3a9fff6b..0b5f9cb51 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/core/NodeList.java +++ b/teavm-dom/src/main/java/org/teavm/dom/core/NodeList.java @@ -21,6 +21,7 @@ import org.teavm.jso.JSProperty; /** * * @author Alexey Andreev + * @param type of nodes in this list. */ public interface NodeList extends JSArrayReader { T item(int index); diff --git a/teavm-jso/src/main/java/org/teavm/jso/JSArray.java b/teavm-jso/src/main/java/org/teavm/jso/JSArray.java index 402582300..ff080c26a 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/JSArray.java +++ b/teavm-jso/src/main/java/org/teavm/jso/JSArray.java @@ -18,6 +18,7 @@ package org.teavm.jso; /** * * @author Alexey Andreev + * @param */ public interface JSArray extends JSArrayReader { @JSIndexer diff --git a/teavm-jso/src/main/java/org/teavm/jso/JSArrayReader.java b/teavm-jso/src/main/java/org/teavm/jso/JSArrayReader.java index 4b635b914..536d40452 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/JSArrayReader.java +++ b/teavm-jso/src/main/java/org/teavm/jso/JSArrayReader.java @@ -18,6 +18,7 @@ package org.teavm.jso; /** * * @author Alexey Andreev + * @param */ public interface JSArrayReader extends JSObject { @JSProperty diff --git a/teavm-jso/src/main/java/org/teavm/jso/JSSortFunction.java b/teavm-jso/src/main/java/org/teavm/jso/JSSortFunction.java index a5ef40fa3..69bcec557 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/JSSortFunction.java +++ b/teavm-jso/src/main/java/org/teavm/jso/JSSortFunction.java @@ -18,6 +18,7 @@ package org.teavm.jso; /** * * @author Alexey Andreev + * @param */ @JSFunctor public interface JSSortFunction { diff --git a/teavm-platform/src/main/java/org/teavm/platform/PlatformQueue.java b/teavm-platform/src/main/java/org/teavm/platform/PlatformQueue.java index e2c0c691c..6d9e8ca96 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/PlatformQueue.java +++ b/teavm-platform/src/main/java/org/teavm/platform/PlatformQueue.java @@ -24,6 +24,7 @@ import org.teavm.platform.plugin.PlatformQueueGenerator; /** * * @author Alexey Andreev + * @param */ public abstract class PlatformQueue implements JSObject { @JSProperty diff --git a/teavm-platform/src/main/java/org/teavm/platform/PlatformSequence.java b/teavm-platform/src/main/java/org/teavm/platform/PlatformSequence.java index 269a8ac97..e7faeac85 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/PlatformSequence.java +++ b/teavm-platform/src/main/java/org/teavm/platform/PlatformSequence.java @@ -22,6 +22,7 @@ import org.teavm.jso.JSProperty; /** * * @author Alexey Andreev + * @param */ public interface PlatformSequence extends JSObject { @JSProperty diff --git a/teavm-platform/src/main/java/org/teavm/platform/async/AsyncCallback.java b/teavm-platform/src/main/java/org/teavm/platform/async/AsyncCallback.java index 21c200b44..4f6a63eac 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/async/AsyncCallback.java +++ b/teavm-platform/src/main/java/org/teavm/platform/async/AsyncCallback.java @@ -18,6 +18,7 @@ package org.teavm.platform.async; /** * * @author Alexey Andreev + * @param */ public interface AsyncCallback { void complete(T result); diff --git a/teavm-platform/src/main/java/org/teavm/platform/metadata/MetadataGenerator.java b/teavm-platform/src/main/java/org/teavm/platform/metadata/MetadataGenerator.java index f52066545..e66b2d689 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/metadata/MetadataGenerator.java +++ b/teavm-platform/src/main/java/org/teavm/platform/metadata/MetadataGenerator.java @@ -60,6 +60,7 @@ public interface MetadataGenerator { * * @param context context that contains useful compile-time information. * @param method method which will be used to access the generated resources at run time. + * @return resource to be attached to method at run time. */ Resource generateMetadata(MetadataGeneratorContext context, MethodReference method); } diff --git a/teavm-platform/src/main/java/org/teavm/platform/metadata/MetadataGeneratorContext.java b/teavm-platform/src/main/java/org/teavm/platform/metadata/MetadataGeneratorContext.java index ebb7c56d8..fa3b1aa52 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/metadata/MetadataGeneratorContext.java +++ b/teavm-platform/src/main/java/org/teavm/platform/metadata/MetadataGeneratorContext.java @@ -31,44 +31,62 @@ import org.teavm.vm.TeaVM; public interface MetadataGeneratorContext extends ServiceRepository { /** * Gets the collection of all classes that were achieved by the dependency checker. + * + * @return class source. */ ListableClassReaderSource getClassSource(); /** * Gets the class loader that is used by the compiler. + * @return class loader. */ ClassLoader getClassLoader(); /** * Gets properties that were specified to {@link TeaVM}. + * + * @return properties. */ Properties getProperties(); /** * Creates a new resource of the given type. The description of valid resources * is available in documentation for {@link Resource}. + * + * @param resourceType type of resource to create. + * @return a new resource */ T createResource(Class resourceType); /** * Creates a new resource that represents class literal. Client code then may use * {@link Platform#classFromResource(ClassResource)} to get actual class. + * + * @param className class to which resource is to point. + * @return a new resource. */ ClassResource createClassResource(String className); /** * Creates a new resource that represents static field. Client code then may use * {@link Platform#objectFromResource(StaticFieldResource)} to get actual field value. + * + * @param field field for which to create resource. + * @return a new resource. */ StaticFieldResource createFieldResource(FieldReference field); /** * Creates a new resource array. + * + * @return a new resource. */ ResourceArray createResourceArray(); /** * Creates a new resource map. + * + * @return a new resource. */ ResourceMap createResourceMap(); } diff --git a/teavm-platform/src/main/java/org/teavm/platform/metadata/ResourceArray.java b/teavm-platform/src/main/java/org/teavm/platform/metadata/ResourceArray.java index 39ba81d1e..8a0f1b23b 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/metadata/ResourceArray.java +++ b/teavm-platform/src/main/java/org/teavm/platform/metadata/ResourceArray.java @@ -18,6 +18,7 @@ package org.teavm.platform.metadata; /** * * @author Alexey Andreev + * @param */ public interface ResourceArray extends Resource { int size(); diff --git a/teavm-platform/src/main/java/org/teavm/platform/metadata/ResourceMap.java b/teavm-platform/src/main/java/org/teavm/platform/metadata/ResourceMap.java index 888508538..ddb334de1 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/metadata/ResourceMap.java +++ b/teavm-platform/src/main/java/org/teavm/platform/metadata/ResourceMap.java @@ -18,6 +18,7 @@ package org.teavm.platform.metadata; /** * * @author Alexey Andreev + * @param */ public interface ResourceMap extends Resource { boolean has(String key); diff --git a/teavm-tests/src/test/java/org/teavm/classlib/java/util/TreeMapTest.java b/teavm-tests/src/test/java/org/teavm/classlib/java/util/TreeMapTest.java index 0e6d30bea..995a2af6b 100644 --- a/teavm-tests/src/test/java/org/teavm/classlib/java/util/TreeMapTest.java +++ b/teavm-tests/src/test/java/org/teavm/classlib/java/util/TreeMapTest.java @@ -535,7 +535,7 @@ public class TreeMapTest { !myTreeMap.containsValue(new Integer(0))); } - /** + /* * Tests entrySet().contains() method behaviour with respect to entries * with null values. * Regression test for HARMONY-5788. From 6964c7190d090a5ef3f2bcf8139d6596839cf8eb Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Sun, 15 Mar 2015 19:03:57 +0300 Subject: [PATCH 68/69] Fix non-async application detection. Fix javadoc comments. --- .../src/main/java/org/teavm/model/package-info.java | 4 ++-- .../main/java/org/teavm/model/util/AsyncMethodFinder.java | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/teavm-core/src/main/java/org/teavm/model/package-info.java b/teavm-core/src/main/java/org/teavm/model/package-info.java index f50ee2cd4..a1d7c1dc1 100644 --- a/teavm-core/src/main/java/org/teavm/model/package-info.java +++ b/teavm-core/src/main/java/org/teavm/model/package-info.java @@ -14,10 +14,10 @@ * limitations under the License. */ /** - * Represents a class model that is alternative to {@link java.lang.reflection} package. + * Represents a class model that is alternative to {@code java.lang.reflection} package. * Model is suitable for representing classes that are not in class path. Also * it allows to disassemble method bodies into three-address code that is very - * close to JVM bytecode (see {@link org.teavm.model.instructions}. + * close to JVM bytecode (see {@code org.teavm.model.instructions}. * *

The entry point is some implementation of {@link org.teavm.model.ClassHolderSource} interface. * diff --git a/teavm-core/src/main/java/org/teavm/model/util/AsyncMethodFinder.java b/teavm-core/src/main/java/org/teavm/model/util/AsyncMethodFinder.java index 610b5ce6b..d17297756 100644 --- a/teavm-core/src/main/java/org/teavm/model/util/AsyncMethodFinder.java +++ b/teavm-core/src/main/java/org/teavm/model/util/AsyncMethodFinder.java @@ -109,7 +109,13 @@ public class AsyncMethodFinder { int.class, void.class))) { --count; } - return count > 0; + if (asyncMethods.contains(new MethodReference(Object.class, "monitorEnterWait", Object.class, + int.class, void.class))) { + --count; + } + ClassReader cls = classSource.get("java.lang.Thread"); + MethodReader method = cls != null ? cls.getMethod(new MethodDescriptor("start", void.class)) : null; + return count > 0 && method != null; } private void add(MethodReference methodRef) { From e7db80fe2b767dc8bde3bda80200eab72d565550 Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Mon, 16 Mar 2015 21:55:37 +0300 Subject: [PATCH 69/69] Fix slf4j support. Add PrintStream.println(double) --- .../teavm/classlib/java/io/TPrintStream.java | 5 +++++ .../slf4j/LoggerFactoryTransformer.java | 21 +++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TPrintStream.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TPrintStream.java index 519c397da..c36764ada 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TPrintStream.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/io/TPrintStream.java @@ -166,6 +166,11 @@ public class TPrintStream extends TFilterOutputStream { printSB(); } + public void println(double d) { + sb.append(d).append('\n'); + printSB(); + } + public void print(TString s) { sb.append(s); printSB(); diff --git a/teavm-extras-slf4j/src/main/java/org/teavm/extras/slf4j/LoggerFactoryTransformer.java b/teavm-extras-slf4j/src/main/java/org/teavm/extras/slf4j/LoggerFactoryTransformer.java index 14bd34520..96b45dabf 100644 --- a/teavm-extras-slf4j/src/main/java/org/teavm/extras/slf4j/LoggerFactoryTransformer.java +++ b/teavm-extras-slf4j/src/main/java/org/teavm/extras/slf4j/LoggerFactoryTransformer.java @@ -17,6 +17,7 @@ package org.teavm.extras.slf4j; import org.slf4j.ILoggerFactory; import org.slf4j.LoggerFactory; +import org.slf4j.helpers.SubstituteLoggerFactory; import org.teavm.diagnostics.Diagnostics; import org.teavm.model.*; import org.teavm.model.instructions.*; @@ -34,6 +35,7 @@ public class LoggerFactoryTransformer implements ClassHolderTransformer { addCacheField(cls); modifyClinit(cls); replaceGetFactory(cls); + cls.removeField(cls.getField("TEMP_FACTORY")); } private void addCacheField(ClassHolder cls) { @@ -61,6 +63,25 @@ public class LoggerFactoryTransformer implements ClassHolderTransformer { put.setValue(factoryVar); put.setField(new FieldReference(LoggerFactory.class.getName(), "loggerFactoryCache")); clinitBlock.getInstructions().add(2, put); + + Program program = clinit.getProgram(); + for (int i = 0; i < program.basicBlockCount(); ++i) { + BasicBlock block = program.basicBlockAt(i); + for (int j = 0; j < block.getInstructions().size(); ++j) { + Instruction insn = block.getInstructions().get(j); + if (insn instanceof InvokeInstruction) { + InvokeInstruction invoke = (InvokeInstruction)insn; + if (invoke.getMethod().getClassName().equals(SubstituteLoggerFactory.class.getName())) { + block.getInstructions().set(j, new EmptyInstruction()); + } + } else if (insn instanceof PutFieldInstruction) { + PutFieldInstruction putField = (PutFieldInstruction)insn; + if (putField.getField().getFieldName().equals("TEMP_FACTORY")) { + block.getInstructions().set(j, new EmptyInstruction()); + } + } + } + } } private void replaceGetFactory(ClassHolder cls) {