changes for working with TeaVM and compilation to JavaScript

This commit is contained in:
Julian Dolby 2017-01-03 20:58:16 -05:00
parent d85226fa93
commit 15c8d711db
13 changed files with 186 additions and 68 deletions

View File

@ -13,12 +13,14 @@ package com.ibm.wala.core.tests.basic;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import org.junit.Assert;
import org.junit.Test;
import com.ibm.wala.core.tests.util.WalaTestCase;
import com.ibm.wala.util.graph.INodeWithNumberedEdges;
import com.ibm.wala.util.graph.NumberedGraph;
import com.ibm.wala.util.graph.impl.DelegatingNumberedGraph;
@ -29,7 +31,7 @@ import com.ibm.wala.util.intset.IntSet;
import com.ibm.wala.util.intset.IntSetUtil;
import com.ibm.wala.util.intset.MutableIntSet;
public class FloydWarshallTest {
public class FloydWarshallTest extends WalaTestCase {
public static class Node implements INodeWithNumberedEdges {
private final int number;
@ -87,11 +89,16 @@ public class FloydWarshallTest {
@Override
public String toString() {
return "["+number+"]";
return "<"+number+">";
}
@Override
public boolean equals(Object o) {
return this == o;
}
}
private static NumberedGraph<Node> makeGraph() {
public static NumberedGraph<Node> makeGraph() {
NumberedGraph<Node> G = new DelegatingNumberedGraph<Node>();
for(int i = 0; i <= 8; i++) {
@ -142,19 +149,29 @@ public class FloydWarshallTest {
@Test
public void TestShortestPath() {
GetPath<Node> result = FloydWarshall.allPairsShortestPath(G);
Assert.assertEquals(result.getPath(G.getNode(1), G.getNode(3)), Collections.singletonList(G.getNode(2)));
Assert.assertEquals(result.getPath(G.getNode(5), G.getNode(8)), Collections.singletonList(G.getNode(7)));
Assert.assertEquals(result.getPath(G.getNode(1), G.getNode(7)), Arrays.asList(G.getNode(2),G.getNode(3),G.getNode(5)));
Assert.assertEquals(result.getPath(G.getNode(1), G.getNode(6)), Arrays.asList(G.getNode(2),G.getNode(3),G.getNode(4)));
assertEquals(result.getPath(G.getNode(1), G.getNode(3)), Collections.singletonList(G.getNode(2)));
assertEquals(result.getPath(G.getNode(5), G.getNode(8)), Collections.singletonList(G.getNode(7)));
assertEquals(result.getPath(G.getNode(1), G.getNode(7)), Arrays.asList(G.getNode(2),G.getNode(3),G.getNode(5)));
assertEquals(result.getPath(G.getNode(1), G.getNode(6)), Arrays.asList(G.getNode(2),G.getNode(3),G.getNode(4)));
}
@Test
public void TestShortestPaths() {
GetPaths<Node> result = FloydWarshall.allPairsShortestPaths(G);
Set<List<Node>> expectedPaths = expectedPaths(G);
Set<List<Node>> resultPaths = result.getPaths(G.getNode(1), G.getNode(8));
assertEquals(resultPaths.size(), expectedPaths.size());
for(List<Node> rp : resultPaths) {
Assert.assertTrue(expectedPaths.contains(rp));
}
}
public static Set<List<Node>> expectedPaths(NumberedGraph<Node> G) {
Set<List<Node>> paths = new HashSet<List<Node>>();
paths.add(Arrays.asList(G.getNode(2),G.getNode(3),G.getNode(4),G.getNode(6)));
paths.add(Arrays.asList(G.getNode(2),G.getNode(3),G.getNode(5),G.getNode(7)));
Assert.assertEquals(result.getPaths(G.getNode(1), G.getNode(8)), paths);
paths.add(new LinkedList<Node>(Arrays.asList(G.getNode(2),G.getNode(3),G.getNode(4),G.getNode(6))));
paths.add(new LinkedList<Node>(Arrays.asList(G.getNode(2),G.getNode(3),G.getNode(5),G.getNode(7))));
return paths;
}
}

View File

@ -106,7 +106,7 @@ public class GraphDataflowTest extends WalaTestCase {
/**
* @return a graph with the expected structure
*/
private static Graph<String> buildGraph() {
public static Graph<String> buildGraph() {
Graph<String> G = SlowSparseNumberedGraph.make();
for (int i = 0; i < nodeNames.length(); i++) {
String n = nodeNames.substring(i, i + 1);
@ -126,10 +126,10 @@ public class GraphDataflowTest extends WalaTestCase {
* Solve the dataflow system and return the result as a string
* @throws CancelException
*/
private static String solveNodeOnly(Graph<String> G) throws CancelException {
public static String solveNodeOnly(Graph<String> G) throws CancelException {
final OrdinalSetMapping<String> values = new MutableMapping<String>(nodes);
ITransferFunctionProvider<String, BitVectorVariable> functions = new ITransferFunctionProvider<String, BitVectorVariable>() {
@Override
public UnaryOperator<BitVectorVariable> getNodeTransferFunction(String node) {
return new BitVectorUnionConstant(values.getMappedIndex(node));
@ -164,7 +164,7 @@ public class GraphDataflowTest extends WalaTestCase {
return result2String(s);
}
private static String solveNodeEdge(Graph<String> G) throws CancelException {
public static String solveNodeEdge(Graph<String> G) throws CancelException {
final OrdinalSetMapping<String> values = new MutableMapping<String>(nodes);
ITransferFunctionProvider<String, BitVectorVariable> functions = new ITransferFunctionProvider<String, BitVectorVariable>() {

View File

@ -13,6 +13,7 @@ package com.ibm.wala.core.tests.util;
import java.io.IOException;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.runner.JUnitCore;
@ -83,4 +84,7 @@ public abstract class WalaTestCase {
JUnitCore.runClasses(testClass);
}
protected <T> void assertEquals(T x, T y) {
Assert.assertEquals("Expecting " + x + ", but got " + y, x, y);
}
}

View File

@ -208,7 +208,7 @@ public class DefaultFixedPointSystem<T extends IVariable<?>> implements IFixedPo
checkGraph();
}
Iterator<INodeWithNumber> order = Topological.makeTopologicalIter(graph);
Iterator<INodeWithNumber> order = Topological.makeTopologicalIter(graph).iterator();
int number = 0;
while (order.hasNext()) {
Object elt = order.next();

View File

@ -47,21 +47,21 @@ public class Pair<T,U> implements Serializable {
public Iterator<Object> iterator() {
return new Iterator<Object>() {
byte next = 1;
byte nextFlag = 1;
@Override
public boolean hasNext() {
return next > 0;
return nextFlag > 0;
}
@Override
public Object next() {
switch (next) {
switch (nextFlag) {
case 1 :
next++;
nextFlag++;
return fst;
case 2 :
next = 0;
nextFlag = 0;
return snd;
default :
throw new NoSuchElementException();

View File

@ -69,31 +69,31 @@ public class DelegatingNumberedNodeManager<T extends INodeWithNumber> implements
public Iterator<T> iterator() {
final INodeWithNumber[] arr = nodes;
return new Iterator<T>() {
int next = -1;
int nextCounter = -1;
{
advance();
}
void advance() {
for (int i = next + 1; i < arr.length; i++) {
for (int i = nextCounter + 1; i < arr.length; i++) {
if (arr[i] != null) {
next = i;
nextCounter = i;
return;
}
}
next = -1;
nextCounter = -1;
}
@Override
public boolean hasNext() {
return next != -1;
return nextCounter != -1;
}
@Override
@SuppressWarnings("unchecked")
public T next() {
if (hasNext()) {
int r = next;
int r = nextCounter;
advance();
return (T) arr[r];
} else {

View File

@ -10,6 +10,7 @@
*******************************************************************************/
package com.ibm.wala.util.graph.traverse;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Stack;
@ -24,7 +25,7 @@ import com.ibm.wala.util.graph.NumberedGraph;
* increasing discover time. This class follows the outNodes of the graph nodes to define the graph, but this behavior can be
* changed by overriding the getConnected method.
*/
public abstract class DFSDiscoverTimeIterator<T> extends Stack<T> implements Iterator<T> {
public abstract class DFSDiscoverTimeIterator<T> extends ArrayList<T> implements Iterator<T> {
/**
* an enumeration of all nodes to search from
@ -136,4 +137,23 @@ public abstract class DFSDiscoverTimeIterator<T> extends Stack<T> implements Ite
protected void visitEdge(T from, T to) {
// do nothing. subclasses will override.
}
private boolean empty() {
return size() == 0;
}
private void push(T elt) {
add(elt);
}
private T peek() {
return get(size()-1);
}
private T pop() {
T e = get(size()-1);
remove(size()-1);
return e;
}
}

View File

@ -10,9 +10,9 @@
*******************************************************************************/
package com.ibm.wala.util.graph.traverse;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Stack;
import com.ibm.wala.util.collections.EmptyIterator;
import com.ibm.wala.util.debug.UnimplementedError;
@ -23,7 +23,7 @@ import com.ibm.wala.util.graph.Graph;
* finishing time. This class follows the outNodes of the graph nodes to define the graph, but this behavior can be changed by
* overriding the getConnected method.
*/
public abstract class DFSFinishTimeIterator<T> extends Stack<T> implements Iterator<T> {
public abstract class DFSFinishTimeIterator<T> extends ArrayList<T> implements Iterator<T> {
/**
* the current next element in finishing time order
@ -53,6 +53,10 @@ public abstract class DFSFinishTimeIterator<T> extends Stack<T> implements Itera
theNextElement = roots.next();
}
private boolean empty() {
return size() == 0;
}
/**
* Return whether there are any more nodes left to enumerate.
*
@ -67,6 +71,20 @@ public abstract class DFSFinishTimeIterator<T> extends Stack<T> implements Itera
abstract void setPendingChildren(T v, Iterator<T> iterator);
private void push(T elt) {
add(elt);
}
private T peek() {
return get(size()-1);
}
private T pop() {
T e = get(size()-1);
remove(size()-1);
return e;
}
/**
* Find the next graph node in finishing time order.
*

View File

@ -28,7 +28,7 @@ import com.ibm.wala.util.graph.Graph;
* This class follows the outNodes of the graph nodes to define the graph, but this behavior can be changed by overriding the
* getConnected method.
*/
public class DFSPathFinder<T> extends Stack<T> {
public class DFSPathFinder<T> extends ArrayList<T> {
public static final long serialVersionUID = 9939900773328288L;
/**
@ -208,4 +208,23 @@ public class DFSPathFinder<T> extends Stack<T> {
protected Iterator<? extends T> getConnected(T n) {
return G.getSuccNodes(n);
}
private boolean empty() {
return size() == 0;
}
private void push(T elt) {
add(elt);
}
private T peek() {
return get(size()-1);
}
private T pop() {
T e = get(size()-1);
remove(size()-1);
return e;
}
}

View File

@ -10,6 +10,7 @@
*******************************************************************************/
package com.ibm.wala.util.graph.traverse;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
@ -100,7 +101,7 @@ public class FloydWarshall<T> {
public static <T> GetPath<T> allPairsShortestPath(final NumberedGraph<T> G) {
return new FloydWarshall<T>(G) {
int[][] next = new int[G.getNumberOfNodes()][G.getNumberOfNodes()];
@Override
protected void pathCallback(int i, int j, int k) {
next[i][j] = k;
@ -115,6 +116,22 @@ public class FloydWarshall<T> {
final int[][] paths = allPairsShortestPaths();
return new GetPath<T>() {
@Override
public String toString() {
String s = "";
for(int i = 0; i <= G.getMaxNumber(); i++) {
for(int j = 0; j <= G.getMaxNumber(); j++) {
try {
s += getPath(G.getNode(i), G.getNode(j));
} catch (UnsupportedOperationException e) {
}
}
}
return s;
}
@Override
public List<T> getPath(T from, T to) {
int fn = G.getNumber(from);
@ -154,7 +171,23 @@ public class FloydWarshall<T> {
private GetPaths<T> doit() {
final int[][] paths = allPairsShortestPaths();
return new GetPaths<T>() {
@Override
@Override
public String toString() {
List<Set<List<T>>> x = new ArrayList<Set<List<T>>>();
for(int i = 0; i <= G.getMaxNumber(); i++) {
for(int j = 0; j <= G.getMaxNumber(); j++) {
try {
x.add(getPaths(G.getNode(i), G.getNode(j)));
} catch (UnsupportedOperationException e) {
}
}
}
return x.toString();
}
@Override
public Set<List<T>> getPaths(final T from, final T to) {
int fn = G.getNumber(from);
int tn = G.getNumber(to);

View File

@ -26,29 +26,33 @@ public class Topological {
*
* @throws IllegalArgumentException if graph == null
*/
public static <T> Iterator<T> makeTopologicalIter(Graph<T> graph) throws IllegalArgumentException {
// the following code ensures a topological order over SCCs.
// note that the first two lines of the following give a topological
// order for dags, but that can get screwed up by cycles. so
// instead, we use Tarjan's SCC algorithm, which happens to
// visit nodes in an order consistent with a top. order over SCCs.
public static <T> Iterable<T> makeTopologicalIter(final Graph<T> graph) throws IllegalArgumentException {
if (graph == null) {
throw new IllegalArgumentException("graph == null");
}
// finish time is post-order
// note that if you pay attention only to the first representative
// of each SCC discovered, we have a top. order of these SCC
// representatives
Iterator<T> finishTime = DFS.iterateFinishTime(graph);
// reverse postorder is usual topological sort.
Iterator<T> rev = ReverseIterator.reverse(finishTime);
// the following statement helps out the GC; note that finishTime holds
// on to a large array
finishTime = null;
Graph<T> G_T = GraphInverter.invert(graph);
Iterator<T> order = DFS.iterateFinishTime(G_T, rev);
return order;
}
}
return new Iterable<T>() {
@Override
public Iterator<T> iterator() {
// the following code ensures a topological order over SCCs.
// note that the first two lines of the following give a topological
// order for dags, but that can get screwed up by cycles. so
// instead, we use Tarjan's SCC algorithm, which happens to
// visit nodes in an order consistent with a top. order over SCCs.
// finish time is post-order
// note that if you pay attention only to the first representative
// of each SCC discovered, we have a top. order of these SCC
// representatives
Iterator<T> finishTime = DFS.iterateFinishTime(graph);
// reverse postorder is usual topological sort.
Iterator<T> rev = ReverseIterator.reverse(finishTime);
// the following statement helps out the GC; note that finishTime holds
// on to a large array
finishTime = null;
Graph<T> G_T = GraphInverter.invert(graph);
return DFS.iterateFinishTime(G_T, rev);
};
};
}
}

View File

@ -17,10 +17,9 @@ import java.util.SortedSet;
import java.util.TreeSet;
import com.ibm.wala.util.collections.HashMapFactory;
import com.ibm.wala.util.graph.INodeWithNumber;
import com.ibm.wala.util.graph.NumberedGraph;
public class WelshPowell<T extends INodeWithNumber> {
public class WelshPowell<T> {
public static class ColoredVertices<T> {
private final boolean fullColoring;
@ -59,6 +58,10 @@ public class WelshPowell<T extends INodeWithNumber> {
this.numColors = numColors;
}
@Override
public String toString() {
return colors.toString();
}
}
public static <T> Comparator<T> defaultComparator(final NumberedGraph<T> G) {
@ -101,29 +104,29 @@ public class WelshPowell<T extends INodeWithNumber> {
int colored = 0;
for(T n : vertices) {
int id = n.getGraphNodeId();
int id = G.getNumber(n);
if (colors[id] == -1) {
colors[id] = currentColor;
colored++;
for(T m : vertices) {
if (colors[m.getGraphNodeId()] == -1) {
if (colors[G.getNumber(m)] == -1) {
color_me: {
for(Iterator<T> ps = G.getPredNodes(m); ps.hasNext(); ) {
T p = ps.next();
if (colors[ p.getGraphNodeId() ] == currentColor) {
if (colors[ G.getNumber(p) ] == currentColor) {
break color_me;
}
}
for(Iterator<T> ss = G.getSuccNodes(m); ss.hasNext(); ) {
T s = ss.next();
if (colors[s.getGraphNodeId()] == currentColor) {
if (colors[G.getNumber(s)] == currentColor) {
break color_me;
}
}
colors[m.getGraphNodeId()] = currentColor;
colors[G.getNumber(m)] = currentColor;
colored++;
if (currentColor == maxColors - 1) {

View File

@ -145,11 +145,11 @@ public final class BitSet<T> {
*/
public Iterator<T> iterator() {
return new Iterator<T>() {
private int next = -1;
private int nextCounter = -1;
{
for (int i = 0; i < vector.length(); i++) {
if (vector.get(i)) {
next = i;
nextCounter = i;
break;
}
}
@ -157,17 +157,17 @@ public final class BitSet<T> {
@Override
public boolean hasNext() {
return (next != -1);
return (nextCounter != -1);
}
@Override
public T next() {
T result = map.getMappedObject(next);
int start = next + 1;
next = -1;
T result = map.getMappedObject(nextCounter);
int start = nextCounter + 1;
nextCounter = -1;
for (int i = start; i < vector.length(); i++) {
if (vector.get(i)) {
next = i;
nextCounter = i;
break;
}
}