com.dragome.compiler.graph.Node Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dragome-bytecode-js-compiler Show documentation
Show all versions of dragome-bytecode-js-compiler Show documentation
Dragome SDK module: bytecode to javascript compiler
/*
* Copyright 2005 by Wolfgang Kuehn
* Created on 12.11.2005
*/
package com.dragome.compiler.graph;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import com.dragome.compiler.ast.ASTNodeStack;
import com.dragome.compiler.ast.Block;
import com.dragome.compiler.ast.Expression;
import com.dragome.compiler.ast.IfStatement;
import com.dragome.compiler.graph.transformation.Transformation;
public class Node
{
public class Reference
{
public Node source;
public boolean isBackward= false;
}
public static int NON_HEADER= 0;
public static int REDUCIBLE= 1;
public static int IRREDUCIBLE= 2;
String id;
Set inEdges= new LinkedHashSet();
Set outEdges= new LinkedHashSet();
Graph graph;
private int currentPc= -1;
private int initialPc= -1;
public ASTNodeStack stack= new ASTNodeStack();
public Block block= new Block();
public boolean closed= false;
protected int preOrderIndex= -1;
private Node domParent;
private Set domChildren= new LinkedHashSet();
IfStatement ifStmt;
public Expression switchExpression;
public Transformation trans;
public Collection jsrCallers= new LinkedHashSet();
public boolean isSwitchHeader= false;
public Node(Graph theGraph, int pc)
{
this(theGraph);
setInitialPc(pc);
}
public Node(Graph theGraph)
{
graph= theGraph;
}
public int getComplexity()
{
Node node= this;
int complexity= 0;
while (node.trans != null)
{
complexity++;
node= node.trans.header;
}
return complexity;
}
public int getCurrentPc()
{
return currentPc;
}
public void setCurrentPc(int pc)
{
currentPc= pc;
}
public void close()
{
closed= true;
}
public void addEdge(Edge e)
{
if (e.source == this)
{
if (!outEdges.add(e))
{
throw new RuntimeException("\n" + this + "\nalready bound to " + e);
}
}
if (e.target == this)
{
if (!inEdges.add(e))
{
throw new RuntimeException("" + this + " already bound to " + e);
}
}
}
public String toString()
{
String s= getClass().getName();
s= s.replaceFirst(".*\\.", "");
s+= " " + id + "[" + initialPc + ", " + currentPc + "]";
if (domParent != null)
s+= " dominated by " + domParent.id;
if (isLoopHeader())
s+= " LH";
return s;
}
public String describe()
{
String s= toString();
Iterator iter= outEdges.iterator();
while (iter.hasNext())
{
Edge e= (Edge) iter.next();
s+= "\n\t" + e;
}
return s;
}
public Set getInEdges()
{
return inEdges;
}
public Edge getSelfEdge()
{
Iterator iterator= inEdges.iterator();
while (iterator.hasNext())
{
Edge edge= (Edge) iterator.next();
if (edge.source == this)
return edge;
}
return null;
}
public Set getOutEdges()
{
return outEdges;
}
public Edge[] getOutEdgesArray()
{
return outEdges.toArray(new Edge[outEdges.size()]);
}
public Edge[] getInEdgesArray()
{
return inEdges.toArray(new Edge[inEdges.size()]);
}
public int getPreOrderIndex()
{
return preOrderIndex;
}
public void setPreOrderIndex(int thePreOrderIndex)
{
preOrderIndex= thePreOrderIndex;
}
public Set succs()
{
Set list= new LinkedHashSet();
Edge[] edges= getOutEdgesArray();
for (int i= edges.length - 1; i >= 0; i--)
{
list.add(edges[i].target);
}
return list;
}
public Set preds()
{
Set list= new LinkedHashSet();
Iterator iter= inEdges.iterator();
while (iter.hasNext())
{
Edge e= (Edge) iter.next();
list.add(e.source);
}
return list;
}
public Node getPred()
{
int count= inEdges.size();
if (count != 1)
throw new RuntimeException("Requested unique predecessor, found " + count);
return inEdges.iterator().next().source;
}
public Node getSucc()
{
return getOutEdge().target;
}
public Edge getLocalOutEdgeOrNull()
{
Edge outEdge= null;
Iterator iter= outEdges.iterator();
while (iter.hasNext())
{
Edge edge= (Edge) iter.next();
if (outEdge != null)
new RuntimeException("Found multiple local out-edges");
outEdge= edge;
}
return outEdge;
}
public Edge getOutEdge()
{
int count= outEdges.size();
if (count != 1)
throw new RuntimeException("Requested unique successor, found " + count);
return outEdges.iterator().next();
}
public boolean isDomAncestor(Node node)
{
do
{
if (node == null)
return false;
if (node == this)
return true;
node= node.getDomParent();
}
while (true);
}
public Set getDomChildren()
{
return domChildren;
}
public Node getDomChild()
{
if (domChildren.size() != 1)
throw new RuntimeException("Node must have single child");
return getDomChildren().iterator().next();
}
public Node getDomParent()
{
return domParent;
}
public void setDomParent(Node newDomParent)
{
if (domParent != null)
{
domParent.domChildren.remove(this);
}
domParent= newDomParent;
// Add this Block to its new dominator's children.
if (domParent != null)
{
domParent.domChildren.add(this);
}
}
public boolean isBranch()
{
Edge[] edges= getOutEdgesArray();
if (edges.length != 2)
return false;
if (edges[0] instanceof ConditionalEdge && edges[1] instanceof ConditionalEdge)
return true;
if ((edges[0] instanceof ConditionalEdge) || (edges[1] instanceof ConditionalEdge))
throw new RuntimeException("Node must not have mixed edges");
return false;
}
public ConditionalEdge getConditionalEdge(boolean trueFalse)
{
if (!isBranch())
throw new RuntimeException("Node must be a branch");
Iterator iter= outEdges.iterator();
Edge edge= iter.next();
if (!trueFalse)
edge= iter.next();
return (ConditionalEdge) edge;
}
public String getId()
{
return id;
}
public int getInitialPc()
{
return initialPc;
}
public Graph getGraph()
{
return graph;
}
public void setInitialPc(int theInitialPc)
{
initialPc= theInitialPc;
currentPc= theInitialPc;
}
public boolean isLoopHeader()
{
Iterator iter= inEdges.iterator();
while (iter.hasNext())
{
Edge edge= (Edge) iter.next();
if (edge.isBackEdge())
return true;
}
return false;
}
public boolean hasSelfEdges()
{
Iterator iter= outEdges.iterator();
while (iter.hasNext())
{
Edge edge= (Edge) iter.next();
if (edge.target == this)
return true;
}
return false;
}
}