some generics

git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@692 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
sjfink 2007-02-08 20:45:07 +00:00
parent e89006e2c9
commit a92bff31bb
35 changed files with 1070 additions and 1063 deletions

View File

@ -62,7 +62,7 @@ public class AstCallGraph extends ExplicitCallGraph {
}
class AstCGNode extends ExplicitNode {
private Set callbacks;
private Set<Function> callbacks;
private AstCGNode(IMethod method, Context context) {
super(method, context);
@ -73,8 +73,8 @@ public class AstCallGraph extends ExplicitCallGraph {
boolean done = false;
while (!done) {
try {
for (Iterator x = callbacks.iterator(); x.hasNext();) {
((Function) x.next()).apply(null);
for (Iterator<Function> x = callbacks.iterator(); x.hasNext();) {
x.next().apply(null);
}
} catch (ConcurrentModificationException e) {
done = false;
@ -87,12 +87,12 @@ public class AstCallGraph extends ExplicitCallGraph {
public void addCallback(Function callback) {
if (callbacks == null)
callbacks = new HashSet(1);
callbacks = new HashSet<Function>(1);
callbacks.add(callback);
}
private void fireCallbacksTransitive() {
for(Iterator nodes = DFS.iterateFinishTime(AstCallGraph.this, new NonNullSingletonIterator<CGNode>(this));
for(Iterator<CGNode> nodes = DFS.iterateFinishTime(AstCallGraph.this, new NonNullSingletonIterator<CGNode>(this));
nodes.hasNext(); )
{
((AstCGNode)nodes.next()).fireCallbacks();

View File

@ -10,17 +10,20 @@
*****************************************************************************/
package com.ibm.wala.cast.ipa.callgraph;
import com.ibm.wala.cast.loader.*;
import com.ibm.wala.classLoader.*;
import com.ibm.wala.ipa.callgraph.*;
import com.ibm.wala.ipa.callgraph.propagation.cfa.*;
import com.ibm.wala.ipa.cha.*;
import com.ibm.wala.ssa.*;
import java.util.Iterator;
import com.ibm.wala.cast.loader.AstMethod;
import com.ibm.wala.classLoader.CallSiteReference;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.callgraph.Context;
import com.ibm.wala.ipa.callgraph.propagation.cfa.ContextInsensitiveSSAInterpreter;
import com.ibm.wala.ipa.cha.ClassHierarchy;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.util.collections.EmptyIterator;
import com.ibm.wala.util.warnings.WarningSet;
import java.util.*;
public class AstContextInsensitiveSSAContextInterpreter
extends ContextInsensitiveSSAInterpreter
{
@ -33,7 +36,7 @@ public class AstContextInsensitiveSSAContextInterpreter
return method instanceof AstMethod;
}
public Iterator iterateCallSites(CGNode N, WarningSet warnings) {
public Iterator<CallSiteReference> iterateCallSites(CGNode N, WarningSet warnings) {
IR ir = getIR(N, warnings);
if (ir == null) {
return EmptyIterator.instance();

View File

@ -16,9 +16,9 @@ import java.util.*;
public interface AstPointerKeyFactory extends PointerKeyFactory {
Iterator getPointerKeysForReflectedFieldRead(InstanceKey I, InstanceKey F);
Iterator<PointerKey> getPointerKeysForReflectedFieldRead(InstanceKey I, InstanceKey F);
Iterator getPointerKeysForReflectedFieldWrite(InstanceKey I, InstanceKey F);
Iterator<PointerKey> getPointerKeysForReflectedFieldWrite(InstanceKey I, InstanceKey F);
PointerKey getPointerKeyForObjectCatalog(InstanceKey I);

View File

@ -105,14 +105,14 @@ public abstract class AstSSAPropagationCallGraphBuilder
.getPointerKeyForObjectCatalog(I);
}
public Iterator
public Iterator<PointerKey>
getPointerKeysForReflectedFieldRead(InstanceKey I, InstanceKey F)
{
return ((AstPointerKeyFactory)pointerKeyFactory)
.getPointerKeysForReflectedFieldRead(I, F);
}
public Iterator
public Iterator<PointerKey>
getPointerKeysForReflectedFieldWrite(InstanceKey I, InstanceKey F)
{
return ((AstPointerKeyFactory)pointerKeyFactory)
@ -290,10 +290,10 @@ public abstract class AstSSAPropagationCallGraphBuilder
if (AstTranslator.DEBUG_LEXICAL)
Trace.println("looking up lexical parent " + definer);
for(Iterator DS = getLexicalDefiners(node, definer).iterator();
for(Iterator<CGNode> DS = getLexicalDefiners(node, definer).iterator();
DS.hasNext(); )
{
final CGNode D = (CGNode) DS.next();
final CGNode D = DS.next();
Iterator PS = new NumberedDFSDiscoverTimeIterator(callGraph, node) {
/**
@ -346,12 +346,12 @@ public abstract class AstSSAPropagationCallGraphBuilder
public int hashCode() { return System.identityHashCode(this); }
}
private Set getLexicalDefiners(final CGNode opNode, final String definer) {
private Set<CGNode> getLexicalDefiners(final CGNode opNode, final String definer) {
if (definer == null) {
return Collections.singleton(callGraph.getFakeRootNode());
} else {
final Set result = new HashSet();
final Set<CGNode> result = new HashSet<CGNode>();
PointerKey F = getPointerKeyForLocal(opNode, 1);
IR ir = getCFAContextInterpreter().getIR(opNode, getWarnings());
@ -391,7 +391,7 @@ public abstract class AstSSAPropagationCallGraphBuilder
if (a == null) return b==null; else return a.equals(b);
}
private Set discoveredUpwardFunargs = new HashSet();
private Set<PointerKey> discoveredUpwardFunargs = new HashSet<PointerKey>();
private void addUpwardFunargConstraints(PointerKey lhs,
String name,
@ -680,21 +680,21 @@ public abstract class AstSSAPropagationCallGraphBuilder
PointerKey objCatalog = getPointerKeyForObjectCatalog(objKeys[o]);
for(int f = 0; f < fieldsKeys.length; f++) {
if (isLoadOperation) {
for(Iterator keys =
for(Iterator<PointerKey> keys =
getPointerKeysForReflectedFieldRead(objKeys[o], fieldsKeys[f]);
keys.hasNext(); )
{
PointerKey key = (PointerKey)keys.next();
PointerKey key = keys.next();
if (DEBUG_PROPERTIES) action.dump( key, true, true );
action.action( key );
}
} else {
system.newConstraint(objCatalog, fieldsKeys[f]);
for(Iterator keys =
for(Iterator<PointerKey> keys =
getPointerKeysForReflectedFieldWrite(objKeys[o],fieldsKeys[f]);
keys.hasNext(); )
{
PointerKey key = (PointerKey)keys.next();
PointerKey key = keys.next();
if (DEBUG_PROPERTIES) action.dump( key, true, true );
action.action( key );
}
@ -768,21 +768,21 @@ public abstract class AstSSAPropagationCallGraphBuilder
getPointerKeyForObjectCatalog(object);
for(int f = 0; f < fieldsKeys.length; f++) {
if (isLoadOperation) {
for(Iterator keys =
for(Iterator<PointerKey> keys =
getPointerKeysForReflectedFieldRead(object, fieldsKeys[f]);
keys.hasNext(); )
{
PointerKey key = (PointerKey)keys.next();
PointerKey key = keys.next();
if (DEBUG_PROPERTIES) action.dump(key, true, false);
action.action( key );
}
} else {
system.newConstraint(objCatalog, fieldsKeys[f]);
for(Iterator keys =
for(Iterator<PointerKey> keys =
getPointerKeysForReflectedFieldWrite(object,fieldsKeys[f]);
keys.hasNext(); )
{
PointerKey key = (PointerKey)keys.next();
PointerKey key = keys.next();
if (DEBUG_PROPERTIES) action.dump(key, true, false);
action.action( key );
}

View File

@ -130,8 +130,8 @@ public class CAstAnalysisScope extends AnalysisScope {
/**
* @return an Iterator <ClassLoaderReference>over the loaders.
*/
public Iterator getLoaders() {
return new NonNullSingletonIterator( theLoader );
public Iterator<ClassLoaderReference> getLoaders() {
return new NonNullSingletonIterator<ClassLoaderReference>( theLoader );
}
/**

View File

@ -37,7 +37,7 @@ public class DelegatingAstPointerKeys implements AstPointerKeyFactory {
return base.getFilteredPointerKeyForLocal(node, valueNumber, filter);
}
public PointerKey getPointerKeyForReturnValue(CGNode node){
public PointerKey getPointerKeyForReturnValue(CGNode node) {
return base.getPointerKeyForReturnValue(node);
}
@ -53,16 +53,17 @@ public class DelegatingAstPointerKeys implements AstPointerKeyFactory {
return new ObjectPropertyCatalogKey(I);
}
private final Map specificStringKeys = new HashMap();
// private final Map specificIndexKeys = new HashMap();
private final Map<IField, Set<PointerKey>> specificStringKeys = new HashMap<IField, Set<PointerKey>>();
// private final Map specificIndexKeys = new HashMap();
public PointerKey getPointerKeyForInstanceField(InstanceKey I, IField f) {
PointerKey fk = base.getPointerKeyForInstanceField(I, f);
if (! specificStringKeys.containsKey(f)) {
specificStringKeys.put(f, new HashSet());
if (!specificStringKeys.containsKey(f)) {
specificStringKeys.put(f, new HashSet<PointerKey>());
}
((Set)specificStringKeys.get(f)).add(fk);
specificStringKeys.get(f).add(fk);
return fk;
}
@ -71,35 +72,33 @@ public class DelegatingAstPointerKeys implements AstPointerKeyFactory {
return base.getPointerKeyForArrayContents(I);
}
public Iterator getPointerKeysForReflectedFieldRead(InstanceKey I, InstanceKey F) {
List result = new LinkedList();
public Iterator<PointerKey> getPointerKeysForReflectedFieldRead(InstanceKey I, InstanceKey F) {
List<PointerKey> result = new LinkedList<PointerKey>();
// FIXME: current only constant string are handled
if (F instanceof ConstantKey) {
Object v = ((ConstantKey)F).getValue();
Object v = ((ConstantKey) F).getValue();
if (v instanceof String) {
IField f =
I.getConcreteType().getField(Atom.findOrCreateUnicodeAtom((String)v));
result.add( getPointerKeyForInstanceField(I, f) );
IField f = I.getConcreteType().getField(Atom.findOrCreateUnicodeAtom((String) v));
result.add(getPointerKeyForInstanceField(I, f));
}
}
result.add(ReflectedFieldPointerKey.mapped(new ConcreteTypeKey(F.getConcreteType()), I));
return result.iterator();
}
public Iterator getPointerKeysForReflectedFieldWrite(InstanceKey I, InstanceKey F) {
public Iterator<PointerKey> getPointerKeysForReflectedFieldWrite(InstanceKey I, InstanceKey F) {
// FIXME: current only constant string are handled
if (F instanceof ConstantKey) {
Object v = ((ConstantKey)F).getValue();
Object v = ((ConstantKey) F).getValue();
if (v instanceof String) {
IField f =
I.getConcreteType().getField(Atom.findOrCreateUnicodeAtom((String)v));
return new NonNullSingletonIterator(getPointerKeyForInstanceField(I, f));
IField f = I.getConcreteType().getField(Atom.findOrCreateUnicodeAtom((String) v));
return new NonNullSingletonIterator<PointerKey>(getPointerKeyForInstanceField(I, f));
}
}
return new NonNullSingletonIterator(ReflectedFieldPointerKey.mapped(new ConcreteTypeKey(F.getConcreteType()), I));
return new NonNullSingletonIterator<PointerKey>(ReflectedFieldPointerKey.mapped(new ConcreteTypeKey(F.getConcreteType()), I));
}
}

View File

@ -30,7 +30,7 @@ import com.ibm.wala.util.warnings.WarningSet;
public class MiscellaneousHacksContextSelector implements ContextSelector
{
private final Set methodsToSpecialize;
private final Set<MethodReference> methodsToSpecialize;
private final ContextSelector specialPolicy;
private final ContextSelector basePolicy;
@ -42,7 +42,7 @@ public class MiscellaneousHacksContextSelector implements ContextSelector
{
basePolicy = base;
specialPolicy = special;
methodsToSpecialize = new HashSet();
methodsToSpecialize = new HashSet<MethodReference>();
for(int i = 0; i < descriptors.length; i++) {
String[] descr = descriptors[i];
switch (descr.length) {

View File

@ -10,7 +10,6 @@
*****************************************************************************/
package com.ibm.wala.cast.ipa.callgraph;
import com.ibm.wala.cast.ir.translator.*;
import com.ibm.wala.cast.loader.AstMethod.*;
import com.ibm.wala.classLoader.*;
@ -29,78 +28,83 @@ abstract public class ScopeMappingInstanceKeys implements InstanceKeyFactory {
protected abstract boolean needsScopeMappingKey(InstanceKey base);
private final PropagationCallGraphBuilder builder;
private final InstanceKeyFactory basic;
public class ScopeMappingInstanceKey implements InstanceKey {
private final InstanceKey base;
private final CGNode creator;
private final ScopeMap map;
private class ScopeMap extends HashMap {
private static final long serialVersionUID = 3645910671551712906L;
private void scan(int level, int toDo, LexicalParent parents[], CGNode node, Set parentNodes) {
private void scan(int level, int toDo, LexicalParent parents[], CGNode node, Set<CGNode> parentNodes) {
if (toDo > 0) {
int restoreIndex = -1;
LexicalParent restoreParent = null;
int restoreIndex = -1;
LexicalParent restoreParent = null;
if (AstTranslator.DEBUG_LEXICAL)
Trace.println(level + ": searching " + node + " for parents");
if (AstTranslator.DEBUG_LEXICAL)
Trace.println(level + ": searching " + node + " for parents");
for(int i = 0; i < parents.length; i++) {
for (int i = 0; i < parents.length; i++) {
if (parents[i] == null) continue;
if (parents[i] == null)
continue;
if (AstTranslator.DEBUG_LEXICAL)
Trace.println(level + ": searching " + parents[i]);
if (node.getMethod() == parents[i].getMethod()) {
if (containsKey(parents[i].getName()))
Assertions._assert(get(parents[i].getName()) == node);
else {
put( parents[i].getName(), node );
if (AstTranslator.DEBUG_LEXICAL)
Trace.println(level + ": Adding lexical parent " + parents[i].getName() + " for " + base + " at " + creator + "(toDo is now " + toDo +")");
}
if (AstTranslator.DEBUG_LEXICAL)
Trace.println(level + ": searching " + parents[i]);
toDo--;
restoreIndex = i;
restoreParent = parents[i];
parents[i] = null;
}
}
CallGraph CG = builder.getCallGraph();
Assertions._assert(CG.getPredNodes(node).hasNext() || toDo==0);
if (node.getMethod() == parents[i].getMethod()) {
if (containsKey(parents[i].getName()))
Assertions._assert(get(parents[i].getName()) == node);
else {
put(parents[i].getName(), node);
if (AstTranslator.DEBUG_LEXICAL)
Trace.println(level + ": Adding lexical parent " + parents[i].getName() + " for " + base + " at " + creator
+ "(toDo is now " + toDo + ")");
}
for(Iterator PS = CG.getPredNodes(node); PS.hasNext(); ) {
CGNode pred = (CGNode) PS.next();
if (pred != creator && !parentNodes.contains(pred)) {
parentNodes.add( pred );
scan(level+1, toDo, parents, pred, parentNodes);
parentNodes.remove(pred);
}
}
toDo--;
restoreIndex = i;
restoreParent = parents[i];
parents[i] = null;
}
}
if (restoreIndex != -1) {
parents[restoreIndex] = restoreParent;
}
}
CallGraph CG = builder.getCallGraph();
Assertions._assert(CG.getPredNodes(node).hasNext() || toDo == 0);
for (Iterator PS = CG.getPredNodes(node); PS.hasNext();) {
CGNode pred = (CGNode) PS.next();
if (pred != creator && !parentNodes.contains(pred)) {
parentNodes.add(pred);
scan(level + 1, toDo, parents, pred, parentNodes);
parentNodes.remove(pred);
}
}
if (restoreIndex != -1) {
parents[restoreIndex] = restoreParent;
}
}
}
private ScopeMap() {
LexicalParent[] parents = getParents(base);
if (AstTranslator.DEBUG_LEXICAL)
Trace.println("starting search for parents at " + creator);
if (AstTranslator.DEBUG_LEXICAL)
Trace.println("starting search for parents at " + creator);
scan( 0, parents.length, parents, creator, new HashSet(5));
scan(0, parents.length, parents, creator, new HashSet<CGNode>(5));
}
CGNode getDefiningNode(String definer) {
return (CGNode) get(definer);
return (CGNode) get(definer);
}
}
@ -115,21 +119,20 @@ abstract public class ScopeMappingInstanceKeys implements InstanceKeyFactory {
}
CGNode getDefiningNode(String definer) {
return map.getDefiningNode( definer );
return map.getDefiningNode(definer);
}
public int hashCode() {
return base.hashCode()*creator.hashCode();
public int hashCode() {
return base.hashCode() * creator.hashCode();
}
public boolean equals(Object o) {
return (o instanceof ScopeMappingInstanceKey) &&
((ScopeMappingInstanceKey)o).base.equals(base) &&
((ScopeMappingInstanceKey)o).creator.equals(creator);
return (o instanceof ScopeMappingInstanceKey) && ((ScopeMappingInstanceKey) o).base.equals(base)
&& ((ScopeMappingInstanceKey) o).creator.equals(creator);
}
public String toString() {
return "SMIK:"+base+"@"+creator;
return "SMIK:" + base + "@" + creator;
}
}
@ -162,10 +165,7 @@ abstract public class ScopeMappingInstanceKeys implements InstanceKeyFactory {
return basic.getInstanceKeyForClassObject(type);
}
public ScopeMappingInstanceKeys(
PropagationCallGraphBuilder builder,
InstanceKeyFactory basic)
{
public ScopeMappingInstanceKeys(PropagationCallGraphBuilder builder, InstanceKeyFactory basic) {
this.basic = basic;
this.builder = builder;
}

View File

@ -66,8 +66,8 @@ public abstract class ScriptEntryPoints implements Entrypoints {
this.scriptType = scriptType;
}
public Iterator iterator() {
Set ES = new HashSet();
public Iterator<ScriptEntryPoint> iterator() {
Set<ScriptEntryPoint> ES = new HashSet<ScriptEntryPoint>();
Iterator classes = scriptType.getClassLoader().iterateAllClasses();
while ( classes.hasNext() ) {
IClass cls = (IClass)classes.next();

View File

@ -18,9 +18,7 @@ import com.ibm.wala.util.intset.BitVector;
import java.util.*;
public class DelegatingCFG extends AbstractNumberedGraph<IBasicBlock>
implements ControlFlowGraph
{
public class DelegatingCFG extends AbstractNumberedGraph<IBasicBlock> implements ControlFlowGraph {
protected final ControlFlowGraph parent;
@ -28,46 +26,56 @@ public class DelegatingCFG extends AbstractNumberedGraph<IBasicBlock>
this.parent = parent;
}
protected NodeManager getNodeManager() {
protected NodeManager<IBasicBlock> getNodeManager() {
return parent;
}
protected EdgeManager getEdgeManager() {
protected EdgeManager<IBasicBlock> getEdgeManager() {
return parent;
}
public IBasicBlock entry() { return parent.entry(); }
public IBasicBlock entry() {
return parent.entry();
}
public IBasicBlock exit() { return parent.exit(); }
public IBasicBlock exit() {
return parent.exit();
}
public BitVector getCatchBlocks() { return parent.getCatchBlocks(); }
public BitVector getCatchBlocks() {
return parent.getCatchBlocks();
}
public IBasicBlock getBlockForInstruction(int index) {
return parent.getBlockForInstruction( index );
return parent.getBlockForInstruction(index);
}
public IInstruction[] getInstructions() { return parent.getInstructions(); }
public IInstruction[] getInstructions() {
return parent.getInstructions();
}
public int getProgramCounter(int index) {
return parent.getProgramCounter( index );
return parent.getProgramCounter(index);
}
public IMethod getMethod() { return parent.getMethod(); }
public Collection getExceptionalSuccessors(IBasicBlock b) {
return parent.getExceptionalSuccessors( b );
public IMethod getMethod() {
return parent.getMethod();
}
public Collection getNormalSuccessors(IBasicBlock b) {
return parent.getNormalSuccessors( b );
}
public Collection getExceptionalPredecessors(IBasicBlock b) {
return parent.getExceptionalPredecessors( b );
public Collection<IBasicBlock> getExceptionalSuccessors(IBasicBlock b) {
return parent.getExceptionalSuccessors(b);
}
public Collection getNormalPredecessors(IBasicBlock b) {
return parent.getNormalPredecessors( b );
public Collection<IBasicBlock> getNormalSuccessors(IBasicBlock b) {
return parent.getNormalSuccessors(b);
}
public Collection<IBasicBlock> getExceptionalPredecessors(IBasicBlock b) {
return parent.getExceptionalPredecessors(b);
}
public Collection<IBasicBlock> getNormalPredecessors(IBasicBlock b) {
return parent.getNormalPredecessors(b);
}
}

View File

@ -47,60 +47,60 @@ public class PrunedCFG extends AbstractNumberedGraph<IBasicBlock> implements Con
}
private static class FilteredCFGEdges implements NumberedEdgeManager {
private static class FilteredCFGEdges implements NumberedEdgeManager<IBasicBlock> {
private final ControlFlowGraph cfg;
private final NumberedNodeManager currentCFGNodes;
private final NumberedNodeManager<IBasicBlock> currentCFGNodes;
private final EdgeFilter filter;
FilteredCFGEdges(ControlFlowGraph cfg, NumberedNodeManager currentCFGNodes, EdgeFilter filter) {
FilteredCFGEdges(ControlFlowGraph cfg, NumberedNodeManager<IBasicBlock> currentCFGNodes, EdgeFilter filter) {
this.cfg = cfg;
this.filter = filter;
this.currentCFGNodes = currentCFGNodes;
}
public Iterator getExceptionalSuccessors(final IBasicBlock N) {
return new FilterIterator(cfg.getExceptionalSuccessors(N).iterator(), new Filter() {
public Iterator<IBasicBlock> getExceptionalSuccessors(final IBasicBlock N) {
return new FilterIterator<IBasicBlock>(cfg.getExceptionalSuccessors(N).iterator(), new Filter() {
public boolean accepts(Object o) {
return currentCFGNodes.containsNode(o) && filter.hasExceptionalEdge((IBasicBlock) N, (IBasicBlock) o);
return currentCFGNodes.containsNode((IBasicBlock) o) && filter.hasExceptionalEdge((IBasicBlock) N, (IBasicBlock) o);
}
});
}
public Iterator getNormalSuccessors(final IBasicBlock N) {
return new FilterIterator(cfg.getNormalSuccessors(N).iterator(), new Filter() {
public Iterator<IBasicBlock> getNormalSuccessors(final IBasicBlock N) {
return new FilterIterator<IBasicBlock>(cfg.getNormalSuccessors(N).iterator(), new Filter() {
public boolean accepts(Object o) {
return currentCFGNodes.containsNode(o) && filter.hasNormalEdge((IBasicBlock) N, (IBasicBlock) o);
return currentCFGNodes.containsNode((IBasicBlock)o) && filter.hasNormalEdge((IBasicBlock) N, (IBasicBlock) o);
}
});
}
public Iterator getExceptionalPredecessors(final IBasicBlock N) {
return new FilterIterator(cfg.getExceptionalPredecessors(N).iterator(), new Filter() {
public Iterator<IBasicBlock> getExceptionalPredecessors(final IBasicBlock N) {
return new FilterIterator<IBasicBlock>(cfg.getExceptionalPredecessors(N).iterator(), new Filter() {
public boolean accepts(Object o) {
return currentCFGNodes.containsNode(o) && filter.hasExceptionalEdge((IBasicBlock) o, (IBasicBlock) N);
return currentCFGNodes.containsNode((IBasicBlock)o) && filter.hasExceptionalEdge((IBasicBlock) o, (IBasicBlock) N);
}
});
}
public Iterator getNormalPredecessors(final IBasicBlock N) {
return new FilterIterator(cfg.getNormalPredecessors(N).iterator(), new Filter() {
public Iterator<IBasicBlock> getNormalPredecessors(final IBasicBlock N) {
return new FilterIterator<IBasicBlock>(cfg.getNormalPredecessors(N).iterator(), new Filter() {
public boolean accepts(Object o) {
return currentCFGNodes.containsNode(o) && filter.hasNormalEdge((IBasicBlock) o, (IBasicBlock) N);
return currentCFGNodes.containsNode((IBasicBlock)o) && filter.hasNormalEdge((IBasicBlock) o, (IBasicBlock) N);
}
});
}
public Iterator getSuccNodes(Object N) {
return new CompoundIterator(getNormalSuccessors((IBasicBlock) N), getExceptionalSuccessors((IBasicBlock) N));
public Iterator<IBasicBlock> getSuccNodes(IBasicBlock N) {
return new CompoundIterator<IBasicBlock>(getNormalSuccessors((IBasicBlock) N), getExceptionalSuccessors((IBasicBlock) N));
}
public int getSuccNodeCount(Object N) {
return new Iterator2Collection(getSuccNodes(N)).size();
public int getSuccNodeCount(IBasicBlock N) {
return new Iterator2Collection<IBasicBlock>(getSuccNodes(N)).size();
}
public IntSet getSuccNodeNumbers(Object N) {
public IntSet getSuccNodeNumbers(IBasicBlock N) {
MutableIntSet bits = IntSetUtil.make();
for (Iterator EE = getSuccNodes(N); EE.hasNext();) {
bits.add(((IBasicBlock) EE.next()).getNumber());
@ -109,15 +109,15 @@ public class PrunedCFG extends AbstractNumberedGraph<IBasicBlock> implements Con
return bits;
}
public Iterator getPredNodes(Object N) {
return new CompoundIterator(getNormalPredecessors((IBasicBlock) N), getExceptionalPredecessors((IBasicBlock) N));
public Iterator<IBasicBlock> getPredNodes(IBasicBlock N) {
return new CompoundIterator<IBasicBlock>(getNormalPredecessors((IBasicBlock) N), getExceptionalPredecessors((IBasicBlock) N));
}
public int getPredNodeCount(Object N) {
return new Iterator2Collection(getPredNodes(N)).size();
public int getPredNodeCount(IBasicBlock N) {
return new Iterator2Collection<IBasicBlock>(getPredNodes(N)).size();
}
public IntSet getPredNodeNumbers(Object N) {
public IntSet getPredNodeNumbers(IBasicBlock N) {
MutableIntSet bits = IntSetUtil.make();
for (Iterator EE = getPredNodes(N); EE.hasNext();) {
bits.add(((IBasicBlock) EE.next()).getNumber());
@ -126,7 +126,7 @@ public class PrunedCFG extends AbstractNumberedGraph<IBasicBlock> implements Con
return bits;
}
public boolean hasEdge(Object src, Object dst) {
public boolean hasEdge(IBasicBlock src, IBasicBlock dst) {
for (Iterator EE = getSuccNodes(src); EE.hasNext();) {
if (EE.next().equals(dst)) {
return true;
@ -136,46 +136,46 @@ public class PrunedCFG extends AbstractNumberedGraph<IBasicBlock> implements Con
return false;
}
public void addEdge(Object src, Object dst) {
public void addEdge(IBasicBlock src, IBasicBlock dst) {
throw new UnsupportedOperationException();
}
public void removeEdge(Object src, Object dst) {
public void removeEdge(IBasicBlock src, IBasicBlock dst) {
throw new UnsupportedOperationException();
}
public void removeAllIncidentEdges(Object node) {
public void removeAllIncidentEdges(IBasicBlock node) {
throw new UnsupportedOperationException();
}
public void removeIncomingEdges(Object node) {
public void removeIncomingEdges(IBasicBlock node) {
throw new UnsupportedOperationException();
}
public void removeOutgoingEdges(Object node) {
public void removeOutgoingEdges(IBasicBlock node) {
throw new UnsupportedOperationException();
}
}
private static class FilteredNodes implements NumberedNodeManager {
private final NumberedNodeManager nodes;
private static class FilteredNodes implements NumberedNodeManager<IBasicBlock> {
private final NumberedNodeManager<IBasicBlock> nodes;
private final Set subset;
FilteredNodes(NumberedNodeManager nodes, Set subset) {
FilteredNodes(NumberedNodeManager<IBasicBlock> nodes, Set subset) {
this.nodes = nodes;
this.subset = subset;
}
public int getNumber(Object N) {
public int getNumber(IBasicBlock N) {
if (subset.contains(N))
return nodes.getNumber(N);
else
return -1;
}
public Object getNode(int number) {
Object N = nodes.getNode(number);
public IBasicBlock getNode(int number) {
IBasicBlock N = nodes.getNode(number);
if (subset.contains(N))
return N;
else
@ -184,8 +184,8 @@ public class PrunedCFG extends AbstractNumberedGraph<IBasicBlock> implements Con
public int getMaxNumber() {
int max = -1;
for (Iterator NS = nodes.iterateNodes(); NS.hasNext();) {
Object N = NS.next();
for (Iterator<? extends IBasicBlock> NS = nodes.iterateNodes(); NS.hasNext();) {
IBasicBlock N = NS.next();
if (subset.contains(N) && getNumber(N) > max) {
max = getNumber(N);
}
@ -194,19 +194,19 @@ public class PrunedCFG extends AbstractNumberedGraph<IBasicBlock> implements Con
return max;
}
private Iterator filterNodes(Iterator nodeIterator) {
return new FilterIterator(nodeIterator, new Filter() {
private Iterator<IBasicBlock> filterNodes(Iterator nodeIterator) {
return new FilterIterator<IBasicBlock>(nodeIterator, new Filter() {
public boolean accepts(Object o) {
return subset.contains(o);
}
});
}
public Iterator iterateNodes(IntSet s) {
public Iterator<IBasicBlock> iterateNodes(IntSet s) {
return filterNodes(nodes.iterateNodes(s));
}
public Iterator iterateNodes() {
public Iterator<IBasicBlock> iterateNodes() {
return filterNodes(nodes.iterateNodes());
}
@ -214,15 +214,15 @@ public class PrunedCFG extends AbstractNumberedGraph<IBasicBlock> implements Con
return subset.size();
}
public void addNode(Object n) {
public void addNode(IBasicBlock n) {
throw new UnsupportedOperationException();
}
public void removeNode(Object n) {
public void removeNode(IBasicBlock n) {
throw new UnsupportedOperationException();
}
public boolean containsNode(Object N) {
public boolean containsNode(IBasicBlock N) {
return subset.contains(N);
}
}
@ -236,47 +236,47 @@ public class PrunedCFG extends AbstractNumberedGraph<IBasicBlock> implements Con
public PrunedCFG(final ControlFlowGraph cfg, final EdgeFilter filter) {
this.cfg = cfg;
Graph<IBasicBlock> temp = new AbstractNumberedGraph<IBasicBlock>() {
private final EdgeManager edges = new FilteredCFGEdges(cfg, cfg, filter);
private final EdgeManager<IBasicBlock> edges = new FilteredCFGEdges(cfg, cfg, filter);
protected NodeManager getNodeManager() {
protected NodeManager<IBasicBlock> getNodeManager() {
return cfg;
}
protected EdgeManager getEdgeManager() {
protected EdgeManager<IBasicBlock> getEdgeManager() {
return edges;
}
};
Set reachable = DFS.getReachableNodes(temp, Collections.singleton(cfg.entry()));
Set back = DFS.getReachableNodes(GraphInverter.invert(temp), Collections.singleton(cfg.exit()));
Set<IBasicBlock> reachable = DFS.getReachableNodes(temp, Collections.singleton(cfg.entry()));
Set<IBasicBlock> back = DFS.getReachableNodes(GraphInverter.invert(temp), Collections.singleton(cfg.exit()));
reachable.retainAll(back);
this.nodes = new FilteredNodes(cfg, reachable);
this.edges = new FilteredCFGEdges(cfg, nodes, filter);
}
protected NodeManager getNodeManager() {
protected NodeManager<IBasicBlock> getNodeManager() {
return nodes;
}
protected EdgeManager getEdgeManager() {
protected EdgeManager<IBasicBlock> getEdgeManager() {
return edges;
}
public Collection getExceptionalSuccessors(final IBasicBlock N) {
return new Iterator2Collection(edges.getExceptionalSuccessors(N));
public Collection<IBasicBlock> getExceptionalSuccessors(final IBasicBlock N) {
return new Iterator2Collection<IBasicBlock>(edges.getExceptionalSuccessors(N));
}
public Collection getNormalSuccessors(final IBasicBlock N) {
return new Iterator2Collection(edges.getNormalSuccessors(N));
public Collection<IBasicBlock> getNormalSuccessors(final IBasicBlock N) {
return new Iterator2Collection<IBasicBlock>(edges.getNormalSuccessors(N));
}
public Collection getExceptionalPredecessors(final IBasicBlock N) {
return new Iterator2Collection(edges.getExceptionalPredecessors(N));
public Collection<IBasicBlock> getExceptionalPredecessors(final IBasicBlock N) {
return new Iterator2Collection<IBasicBlock>(edges.getExceptionalPredecessors(N));
}
public Collection getNormalPredecessors(final IBasicBlock N) {
return new Iterator2Collection(edges.getNormalPredecessors(N));
public Collection<IBasicBlock> getNormalPredecessors(final IBasicBlock N) {
return new Iterator2Collection<IBasicBlock>(edges.getNormalPredecessors(N));
}
public IBasicBlock entry() {

View File

@ -21,30 +21,29 @@ import com.ibm.wala.ssa.SSAInstruction;
import com.ibm.wala.ssa.SSAOptions;
import com.ibm.wala.ssa.SSAPhiInstruction;
import com.ibm.wala.ssa.SymbolTable;
import com.ibm.wala.ssa.SSACFG.BasicBlock;
import com.ibm.wala.ssa.SSAOptions.DefaultValues;
import com.ibm.wala.util.collections.IntStack;
import com.ibm.wala.util.debug.Assertions;
import com.ibm.wala.util.graph.DominanceFrontiers;
import com.ibm.wala.util.graph.Graph;
/**
* Abstract core of traditional SSA conversion (Cytron et al.).
*
* This implementation is abstract in the sense that it is designed
* to work over the instrutions and CFG of a Domo IR, but it is
* abstract with respect to several integral portions of the
* traditional algorithm:
*
* This implementation is abstract in the sense that it is designed to work over
* the instrutions and CFG of a Domo IR, but it is abstract with respect to
* several integral portions of the traditional algorithm:
* <UL>
* <LI> The notion of uses and defs of a given instruction.
* <LI> Assignments (<def> := <use>) that are be copy-propagated away
* <LI> Which values are constants---i.e. have no definition.
* <LI> Any value numbers to be skipped during SSA construction
* <LI> Special initialization and exit block processing.
* <LI> The notion of uses and defs of a given instruction.
* <LI> Assignments (<def> := <use>) that are be copy-propagated away
* <LI> Which values are constants---i.e. have no definition.
* <LI> Any value numbers to be skipped during SSA construction
* <LI> Special initialization and exit block processing.
* </UL>
*
*
* @author Julian dolby (dolby@us.ibm.com)
*
*
*/
public abstract class AbstractSSAConversion {
@ -56,10 +55,8 @@ public abstract class AbstractSSAConversion {
protected abstract int getUse(SSAInstruction inst, int index);
protected abstract boolean isAssignInstruction(SSAInstruction inst);
protected abstract int getMaxValueNumber();
protected abstract boolean isLive(SSACFG.BasicBlock Y, int V);
@ -68,15 +65,12 @@ public abstract class AbstractSSAConversion {
protected abstract boolean isConstant(int valueNumber);
protected abstract int getNextNewValueNumber();
protected abstract void initializeVariables();
protected abstract void repairExit();
protected abstract void placeNewPhiAt(int value, SSACFG.BasicBlock Y);
protected abstract SSAPhiInstruction getPhi(SSACFG.BasicBlock B, int index);
@ -87,34 +81,41 @@ public abstract class AbstractSSAConversion {
protected abstract void repairPhiUse(SSACFG.BasicBlock BB, int phiIndex, int rvalIndex, int newRval);
protected abstract void repairInstructionUses(SSAInstruction inst, int index, int[] newUses);
protected abstract void repairInstructionDefs(SSAInstruction inst, int index, int[] newDefs, int[] newUses);
protected abstract void pushAssignment(SSAInstruction inst, int index, int newRhs);
protected abstract void popAssignment(SSAInstruction inst, int index);
protected final SSACFG CFG;
protected final DominanceFrontiers<IBasicBlock> DF;
private final Graph dominatorTree;
protected final int[] phiCounts;
protected final SSAInstruction[] instructions;
private final int flags[];
protected final SymbolTable symbolTable;
protected final DefaultValues defaultValues;
protected IntStack S[];
protected int C[];
protected int valueMap[];
private Set[] assignmentMap;
protected AbstractSSAConversion(IR ir, SSAOptions options) {
this.CFG = ir.getControlFlowGraph();
this.DF = new DominanceFrontiers(ir.getControlFlowGraph(), ir.getControlFlowGraph().entry());
this.DF = new DominanceFrontiers<IBasicBlock>(ir.getControlFlowGraph(), ir.getControlFlowGraph().entry());
this.dominatorTree = DF.dominatorTree();
this.flags = new int[2 * ir.getControlFlowGraph().getNumberOfNodes()];
this.instructions = ir.getInstructions();
@ -123,7 +124,6 @@ public abstract class AbstractSSAConversion {
this.defaultValues = options.getDefaultValues();
}
//
// top-level control
//
@ -133,7 +133,6 @@ public abstract class AbstractSSAConversion {
renameVariables();
}
//
// initialization
//
@ -149,22 +148,22 @@ public abstract class AbstractSSAConversion {
for (Iterator BBs = CFG.iterateNodes(); BBs.hasNext();) {
SSACFG.BasicBlock BB = (SSACFG.BasicBlock) BBs.next();
if (BB.getFirstInstructionIndex() >= 0) {
for(Iterator IS = BB.iterateAllInstructions(); IS.hasNext(); ) {
SSAInstruction inst = (SSAInstruction)IS.next();
if (inst != null) {
for (int j = 0; j < getNumberOfDefs(inst); j++) {
for (Iterator IS = BB.iterateAllInstructions(); IS.hasNext();) {
SSAInstruction inst = (SSAInstruction) IS.next();
if (inst != null) {
for (int j = 0; j < getNumberOfDefs(inst); j++) {
addDefiningBlock(assignmentMap, BB, getDef(inst, j));
}
}
}
}
}
}
}
}
private void addDefiningBlock(Set[] A, SSACFG.BasicBlock BB, int i) {
if (! skip(i)) {
private void addDefiningBlock(Set<SSACFG.BasicBlock>[] A, SSACFG.BasicBlock BB, int i) {
if (!skip(i)) {
if (A[i] == null) {
A[i] = new LinkedHashSet(2);
A[i] = new LinkedHashSet<SSACFG.BasicBlock>(2);
}
A[i].add(BB);
}
@ -182,7 +181,7 @@ public abstract class AbstractSSAConversion {
setWork(X, 0);
}
Set W = new LinkedHashSet();
Set<BasicBlock> W = new LinkedHashSet<BasicBlock>();
for (int V = 0; V < assignmentMap.length; V++) {
// some things (e.g. constants) have no defs at all
@ -191,7 +190,7 @@ public abstract class AbstractSSAConversion {
// ignore values as requested
if (skip(V))
continue;
continue;
IterCount++;
@ -202,15 +201,15 @@ public abstract class AbstractSSAConversion {
}
while (!W.isEmpty()) {
SSACFG.BasicBlock X = (SSACFG.BasicBlock) W.iterator().next();
SSACFG.BasicBlock X = W.iterator().next();
W.remove(X);
for (Iterator YS = DF.getDominanceFrontier(X); YS.hasNext();) {
SSACFG.BasicBlock Y = (SSACFG.BasicBlock) YS.next();
if (getHasAlready(Y) < IterCount) {
if (isLive(Y, V)) {
if (isLive(Y, V)) {
placeNewPhiAt(V, Y);
phiCounts[Y.getGraphNodeId()]++;
}
phiCounts[Y.getGraphNodeId()]++;
}
setHasAlready(Y, IterCount);
if (getWork(Y) < IterCount) {
setWork(Y, IterCount);
@ -238,15 +237,14 @@ public abstract class AbstractSSAConversion {
flags[BB.getGraphNodeId() * 2] = v;
}
//
// rename variables phase of traditional algorithm
//
private void renameVariables() {
for (int V = 1; V <= getMaxValueNumber(); V++) {
if (! skip(V)) {
C[V] = 0;
S[V] = new IntStack();
if (!skip(V)) {
C[V] = 0;
S[V] = new IntStack();
}
}
@ -262,27 +260,27 @@ public abstract class AbstractSSAConversion {
// first loop
for (int i = 0; i < phiCounts[id]; i++) {
SSAPhiInstruction phi = getPhi(X, i);
if (! skipRepair(phi, -1)) {
setPhi(X, i, repairPhiDefs(phi, makeNewDefs(phi)));
if (!skipRepair(phi, -1)) {
setPhi(X, i, repairPhiDefs(phi, makeNewDefs(phi)));
}
}
for (int i = Xf; i <= X.getLastInstructionIndex(); i++) {
SSAInstruction inst = instructions[i];
if (isAssignInstruction(inst)) {
int lhs = getDef(inst, 0);
int rhs = getUse(inst, 0);
int newRhs = skip(rhs)? rhs: top(rhs);
S[lhs].push( newRhs );
int lhs = getDef(inst, 0);
int rhs = getUse(inst, 0);
int newRhs = skip(rhs) ? rhs : top(rhs);
S[lhs].push(newRhs);
pushAssignment(inst, i, newRhs);
pushAssignment(inst, i, newRhs);
} else {
if (! skipRepair(inst, i)) {
int[] newUses = makeNewUses(inst);
repairInstructionUses(inst, i, newUses);
int[] newDefs = makeNewDefs(inst);
repairInstructionDefs(inst, i, newDefs, newUses);
}
if (!skipRepair(inst, i)) {
int[] newUses = makeNewUses(inst);
repairInstructionUses(inst, i, newUses);
int[] newDefs = makeNewDefs(inst);
repairInstructionDefs(inst, i, newDefs, newUses);
}
}
}
@ -295,10 +293,10 @@ public abstract class AbstractSSAConversion {
int Y_id = Y.getGraphNodeId();
int j = com.ibm.wala.cast.ir.cfg.Util.whichPred(CFG, Y, X);
for (int i = 0; i < phiCounts[Y_id]; i++) {
SSAPhiInstruction phi = getPhi(Y, i);
int oldUse = getUse(phi, j);
int newUse = skip(oldUse) ? oldUse: top(oldUse);
repairPhiUse(Y, i, j, newUse);
SSAPhiInstruction phi = getPhi(Y, i);
int oldUse = getUse(phi, j);
int newUse = skip(oldUse) ? oldUse : top(oldUse);
repairPhiUse(Y, i, j, newUse);
}
}
@ -309,31 +307,30 @@ public abstract class AbstractSSAConversion {
for (int i = 0; i < phiCounts[id]; i++) {
SSAInstruction A = getPhi(X, i);
for (int j = 0; j < getNumberOfDefs(A); j++) {
if (! skip(getDef(A, j))) {
S[valueMap[getDef(A, j)]].pop();
}
if (!skip(getDef(A, j))) {
S[valueMap[getDef(A, j)]].pop();
}
}
}
for (int i = Xf; i <= X.getLastInstructionIndex(); i++) {
SSAInstruction A = instructions[i];
if (isAssignInstruction(A)) {
S[ getDef(A, 0) ].pop();
popAssignment(A, i);
S[getDef(A, 0)].pop();
popAssignment(A, i);
} else if (A != null) {
for (int j = 0; j < getNumberOfDefs(A); j++) {
if (! skip(getDef(A, j))) {
S[valueMap[getDef(A, j)]].pop();
}
}
for (int j = 0; j < getNumberOfDefs(A); j++) {
if (!skip(getDef(A, j))) {
S[valueMap[getDef(A, j)]].pop();
}
}
}
}
}
private int[] makeNewUses(SSAInstruction inst) {
int[] newUses = new int[getNumberOfUses(inst)];
for (int j = 0; j < getNumberOfUses(inst); j++) {
newUses[j] =
skip(getUse(inst, j))? getUse(inst, j): top(getUse(inst, j));
newUses[j] = skip(getUse(inst, j)) ? getUse(inst, j) : top(getUse(inst, j));
}
return newUses;
@ -344,19 +341,19 @@ public abstract class AbstractSSAConversion {
for (int j = 0; j < getNumberOfDefs(inst); j++) {
if (skip(getDef(inst, j))) {
newDefs[j] = getDef(inst, j);
newDefs[j] = getDef(inst, j);
} else {
int ii = getNextNewValueNumber();
int ii = getNextNewValueNumber();
if (valueMap.length <= ii) {
int[] nvm = new int[valueMap.length * 2 + ii + 1];
System.arraycopy(valueMap, 0, nvm, 0, valueMap.length);
valueMap = nvm;
}
if (valueMap.length <= ii) {
int[] nvm = new int[valueMap.length * 2 + ii + 1];
System.arraycopy(valueMap, 0, nvm, 0, valueMap.length);
valueMap = nvm;
}
valueMap[ii] = getDef(inst, j);
S[getDef(inst, j)].push(ii);
newDefs[j] = ii;
valueMap[ii] = getDef(inst, j);
S[getDef(inst, j)].push(ii);
newDefs[j] = ii;
}
}
@ -366,24 +363,21 @@ public abstract class AbstractSSAConversion {
protected boolean skipRepair(SSAInstruction inst, int index) {
if (inst == null)
return true;
for(int i = 0; i < getNumberOfDefs(inst); i++)
if (! skip(getDef(inst, i))) return false;
for(int i = 0; i < getNumberOfUses(inst); i++)
if (! skip(getUse(inst, i))) return false;
for (int i = 0; i < getNumberOfDefs(inst); i++)
if (!skip(getDef(inst, i)))
return false;
for (int i = 0; i < getNumberOfUses(inst); i++)
if (!skip(getUse(inst, i)))
return false;
return true;
}
protected void fail(int v) {
Assertions._assert(
isConstant(v) || !S[v].isEmpty(),
"bad stack for " + v + " while SSA converting");
Assertions._assert(isConstant(v) || !S[v].isEmpty(), "bad stack for " + v + " while SSA converting");
}
protected boolean hasDefaultValue(int valueNumber) {
return
(defaultValues != null)
&&
(defaultValues.getDefaultValue(symbolTable, valueNumber) != -1);
return (defaultValues != null) && (defaultValues.getDefaultValue(symbolTable, valueNumber) != -1);
}
protected int getDefaultValue(int valueNumber) {
@ -391,11 +385,11 @@ public abstract class AbstractSSAConversion {
}
protected int top(int v) {
if (! (isConstant(v) || !S[v].isEmpty())) {
if (!(isConstant(v) || !S[v].isEmpty())) {
if (hasDefaultValue(v)) {
return getDefaultValue(v);
return getDefaultValue(v);
} else {
fail(v);
fail(v);
}
}

View File

@ -15,52 +15,53 @@ import java.util.Collection;
import com.ibm.wala.ssa.SSAInstruction;
import com.ibm.wala.ssa.SymbolTable;
import com.ibm.wala.ssa.ValueDecorator;
import com.ibm.wala.types.TypeReference;
import com.ibm.wala.util.debug.Assertions;
public class AstAssertInstruction extends SSAInstruction {
private final int value;
private final boolean fromSpecification;
public AstAssertInstruction(int value, boolean fromSpecification) {
this.value = value;
this.fromSpecification = fromSpecification;
}
public int getNumberOfUses() {
return 1;
}
public int getUse(int i) {
Assertions._assert(i == 0);
return value;
}
public SSAInstruction copyForSSA(int[] defs, int[] uses) {
return new AstAssertInstruction(uses==null? value: uses[0], fromSpecification);
}
private final int value;
public String toString(SymbolTable symbolTable, ValueDecorator d) {
return "assert " + getValueString(symbolTable, d, value) +
" (fromSpec: " + fromSpecification + ")";
}
private final boolean fromSpecification;
public void visit(IVisitor v) {
((AstInstructionVisitor)v).visitAssert(this);
}
public AstAssertInstruction(int value, boolean fromSpecification) {
this.value = value;
this.fromSpecification = fromSpecification;
}
public int hashCode() {
return 2177*value;
}
public int getNumberOfUses() {
return 1;
}
public Collection getExceptionTypes() {
return null;
}
public int getUse(int i) {
Assertions._assert(i == 0);
return value;
}
public boolean isFallThrough() {
return true;
}
public SSAInstruction copyForSSA(int[] defs, int[] uses) {
return new AstAssertInstruction(uses == null ? value : uses[0], fromSpecification);
}
public boolean isFromSpecification() {
return fromSpecification;
}
public String toString(SymbolTable symbolTable, ValueDecorator d) {
return "assert " + getValueString(symbolTable, d, value) + " (fromSpec: " + fromSpecification + ")";
}
public void visit(IVisitor v) {
((AstInstructionVisitor) v).visitAssert(this);
}
public int hashCode() {
return 2177 * value;
}
public Collection<TypeReference> getExceptionTypes() {
return null;
}
public boolean isFallThrough() {
return true;
}
public boolean isFromSpecification() {
return fromSpecification;
}
}

View File

@ -12,8 +12,12 @@ package com.ibm.wala.cast.ir.ssa;
import java.util.Collection;
import com.ibm.wala.ssa.*;
import com.ibm.wala.types.*;
import com.ibm.wala.ssa.SSAGetInstruction;
import com.ibm.wala.ssa.SSAInstruction;
import com.ibm.wala.ssa.SymbolTable;
import com.ibm.wala.ssa.ValueDecorator;
import com.ibm.wala.types.FieldReference;
import com.ibm.wala.types.TypeReference;
public class AstGlobalRead extends SSAGetInstruction {
@ -38,7 +42,7 @@ public class AstGlobalRead extends SSAGetInstruction {
return true;
}
public Collection getExceptionTypes() {
public Collection<TypeReference> getExceptionTypes() {
return null;
}

View File

@ -12,8 +12,12 @@ package com.ibm.wala.cast.ir.ssa;
import java.util.Collection;
import com.ibm.wala.ssa.*;
import com.ibm.wala.types.*;
import com.ibm.wala.ssa.SSAInstruction;
import com.ibm.wala.ssa.SSAPutInstruction;
import com.ibm.wala.ssa.SymbolTable;
import com.ibm.wala.ssa.ValueDecorator;
import com.ibm.wala.types.FieldReference;
import com.ibm.wala.types.TypeReference;
public class AstGlobalWrite extends SSAPutInstruction {
@ -38,7 +42,7 @@ public class AstGlobalWrite extends SSAPutInstruction {
return true;
}
public Collection getExceptionTypes() {
public Collection<TypeReference> getExceptionTypes() {
return null;
}

View File

@ -10,7 +10,6 @@
*****************************************************************************/
package com.ibm.wala.cast.ir.ssa;
import com.ibm.wala.cast.loader.*;
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
import com.ibm.wala.cfg.*;
@ -27,19 +26,16 @@ import java.util.*;
public class AstIRFactory implements IRFactory {
private final boolean keepIR;
private final Map keptIRs;
private final Map<IMethod, IR> keptIRs;
AstIRFactory(boolean keepIR) {
this.keepIR = keepIR;
this.keptIRs = (keepIR)? new HashMap(): null;
this.keptIRs = (keepIR) ? new HashMap<IMethod, IR>() : null;
}
public ControlFlowGraph makeCFG(final IMethod method,
final Context context,
final ClassHierarchy cha,
final WarningSet warnings)
{
return ((AstMethod)method).getControlFlowGraph();
public ControlFlowGraph makeCFG(final IMethod method, final Context context, final ClassHierarchy cha, final WarningSet warnings) {
return ((AstMethod) method).getControlFlowGraph();
}
public class AstIR extends IR {
@ -47,80 +43,63 @@ public class AstIRFactory implements IRFactory {
private void setCatchInstructions(SSACFG ssacfg, AbstractCFG oldcfg) {
for (int i = 0; i < oldcfg.getNumberOfNodes(); i++)
if (oldcfg.isCatchBlock(i)) {
ExceptionHandlerBasicBlock B =
(ExceptionHandlerBasicBlock) ssacfg.getNode(i);
B.setCatchInstruction((SSAGetCaughtExceptionInstruction)
getInstructions()[B.getFirstInstructionIndex()]);
}
if (oldcfg.isCatchBlock(i)) {
ExceptionHandlerBasicBlock B = (ExceptionHandlerBasicBlock) ssacfg.getNode(i);
B.setCatchInstruction((SSAGetCaughtExceptionInstruction) getInstructions()[B.getFirstInstructionIndex()]);
}
}
private void setupCatchTypes(SSACFG cfg, TypeReference[][] catchTypes) {
for (int i = 0; i < catchTypes.length; i++) {
if (catchTypes[i] != null) {
ExceptionHandlerBasicBlock bb =
(ExceptionHandlerBasicBlock) cfg.getNode(i);
for (int j = 0; j < catchTypes[i].length; j++) {
bb.addCaughtExceptionType(catchTypes[i][j]);
}
}
if (catchTypes[i] != null) {
ExceptionHandlerBasicBlock bb = (ExceptionHandlerBasicBlock) cfg.getNode(i);
for (int j = 0; j < catchTypes[i].length; j++) {
bb.addCaughtExceptionType(catchTypes[i][j]);
}
}
}
}
protected SSA2LocalMap getLocalMap() {
return localMap;
}
protected String instructionPosition(int instructionIndex) {
Position pos =
((AstMethod)getMethod()).getSourcePosition(instructionIndex);
Position pos = ((AstMethod) getMethod()).getSourcePosition(instructionIndex);
if (pos == null) {
return "";
} else {
return pos.toString();
return pos.toString();
}
}
private AstIR(AstMethod method,
SSAInstruction[] instructions,
SymbolTable symbolTable,
SSACFG cfg,
SSAOptions options)
{
private AstIR(AstMethod method, SSAInstruction[] instructions, SymbolTable symbolTable, SSACFG cfg, SSAOptions options) {
super(method, instructions, symbolTable, cfg, options);
setCatchInstructions(getControlFlowGraph(), method.cfg);
localMap = SSAConversion.convert(method, this, options);
setupCatchTypes(getControlFlowGraph(), method.catchTypes);
setupLocationMap();
}
}
public IR makeIR(final IMethod method,
final Context context,
final ClassHierarchy cha,
final SSAOptions options,
final WarningSet warnings)
{
public IR makeIR(final IMethod method, final Context context, final ClassHierarchy cha, final SSAOptions options,
final WarningSet warnings) {
Assertions._assert(method instanceof AstMethod, method.toString());
if (keepIR) {
if (keptIRs.containsKey(method)) {
return (IR) keptIRs.get(method);
return keptIRs.get(method);
}
}
AbstractCFG oldCfg = ((AstMethod)method).cfg;
SSAInstruction[] instrs = (SSAInstruction[])oldCfg.getInstructions();
AbstractCFG oldCfg = ((AstMethod) method).cfg;
SSAInstruction[] instrs = (SSAInstruction[]) oldCfg.getInstructions();
IR newIR =
new AstIR((AstMethod)method,
instrs,
((AstMethod)method).symtab,
new SSACFG(method, oldCfg, instrs, warnings),
options);
IR newIR = new AstIR((AstMethod) method, instrs, ((AstMethod) method).symtab, new SSACFG(method, oldCfg, instrs, warnings),
options);
if (keepIR) {
keptIRs.put(method, newIR);
@ -128,34 +107,25 @@ public class AstIRFactory implements IRFactory {
return newIR;
}
public static IRFactory makeDefaultFactory(final boolean keepAstIRs) {
return new DefaultIRFactory() {
private final AstIRFactory astFactory = new AstIRFactory(keepAstIRs);
public IR makeIR(IMethod method,
Context context,
ClassHierarchy cha,
SSAOptions options,
WarningSet warnings)
{
if (method instanceof AstMethod) {
return astFactory.makeIR(method, context, cha, options, warnings);
} else {
return super.makeIR(method, context, cha, options, warnings);
}
public IR makeIR(IMethod method, Context context, ClassHierarchy cha, SSAOptions options, WarningSet warnings) {
if (method instanceof AstMethod) {
return astFactory.makeIR(method, context, cha, options, warnings);
} else {
return super.makeIR(method, context, cha, options, warnings);
}
}
public ControlFlowGraph makeCFG(IMethod method,
Context context,
ClassHierarchy cha,
WarningSet warnings)
{
if (method instanceof AstMethod) {
return astFactory.makeCFG(method, context, cha, warnings);
} else {
return super.makeCFG(method, context, cha, warnings);
}
public ControlFlowGraph makeCFG(IMethod method, Context context, ClassHierarchy cha, WarningSet warnings) {
if (method instanceof AstMethod) {
return astFactory.makeCFG(method, context, cha, warnings);
} else {
return super.makeCFG(method, context, cha, warnings);
}
}
};
}

View File

@ -13,6 +13,7 @@ package com.ibm.wala.cast.ir.ssa;
import java.util.Collection;
import com.ibm.wala.ssa.SSAInstruction;
import com.ibm.wala.types.TypeReference;
public abstract class AstLexicalAccess extends SSAInstruction {
@ -71,7 +72,7 @@ public abstract class AstLexicalAccess extends SSAInstruction {
return true;
}
public Collection getExceptionTypes() {
public Collection<TypeReference> getExceptionTypes() {
return null;
}

View File

@ -10,9 +10,14 @@
*****************************************************************************/
package com.ibm.wala.cast.ir.ssa;
import com.ibm.wala.ssa.*;
import java.util.Collection;
import java.util.Collections;
import java.util.*;
import com.ibm.wala.ssa.SSAAbstractUnaryInstruction;
import com.ibm.wala.ssa.SSAInstruction;
import com.ibm.wala.ssa.SymbolTable;
import com.ibm.wala.ssa.ValueDecorator;
import com.ibm.wala.types.TypeReference;
public class EachElementGetInstruction extends SSAAbstractUnaryInstruction {
@ -34,7 +39,7 @@ public class EachElementGetInstruction extends SSAAbstractUnaryInstruction {
((AstInstructionVisitor) v).visitEachElementGet(this);
}
public Collection getExceptionTypes() {
return Collections.EMPTY_SET;
public Collection<TypeReference> getExceptionTypes() {
return Collections.emptySet();
}
}

View File

@ -10,9 +10,14 @@
*****************************************************************************/
package com.ibm.wala.cast.ir.ssa;
import com.ibm.wala.ssa.*;
import java.util.Collection;
import java.util.Collections;
import java.util.*;
import com.ibm.wala.ssa.SSAAbstractUnaryInstruction;
import com.ibm.wala.ssa.SSAInstruction;
import com.ibm.wala.ssa.SymbolTable;
import com.ibm.wala.ssa.ValueDecorator;
import com.ibm.wala.types.TypeReference;
public class EachElementHasNextInstruction extends SSAAbstractUnaryInstruction {
@ -34,7 +39,7 @@ public class EachElementHasNextInstruction extends SSAAbstractUnaryInstruction {
((AstInstructionVisitor) v).visitEachElementHasNext(this);
}
public Collection getExceptionTypes() {
return Collections.EMPTY_SET;
public Collection<TypeReference> getExceptionTypes() {
return Collections.emptySet();
}
}

View File

@ -10,9 +10,12 @@
*****************************************************************************/
package com.ibm.wala.cast.ir.ssa;
import com.ibm.wala.ssa.*;
import java.util.Collection;
import java.util.Collections;
import java.util.*;
import com.ibm.wala.ssa.SSAAbstractThrowInstruction;
import com.ibm.wala.ssa.SSAInstruction;
import com.ibm.wala.types.TypeReference;
public class NonExceptingThrowInstruction extends SSAAbstractThrowInstruction {
@ -31,8 +34,8 @@ public class NonExceptingThrowInstruction extends SSAAbstractThrowInstruction {
((AstInstructionVisitor)v).visitNonExceptingThrow(this);
}
public Collection getExceptionTypes() {
return Collections.EMPTY_SET;
public Collection<TypeReference> getExceptionTypes() {
return Collections.emptySet();
}
}

View File

@ -38,14 +38,17 @@ import com.ibm.wala.util.intset.MutableIntSet;
/**
* @author Julian Dolby
*
* Standard SSA conversion for local value numbers.
*
* Standard SSA conversion for local value numbers.
*/
public class SSAConversion extends AbstractSSAConversion {
public static boolean DEBUG = false;
public static boolean DEBUG_UNDO = true;
public static boolean DEBUG_NAMES = true;
public static boolean DUMP = false;
private final AstIR ir;
@ -66,32 +69,35 @@ public class SSAConversion extends AbstractSSAConversion {
// Copy propagation history
//
private final Map copyPropagationMap;
private final Stack R[];
private final Map<Object, CopyPropagationRecord> copyPropagationMap;
private final Stack<CopyPropagationRecord> R[];
private static class UseRecord {
final int instructionIndex;
final int useNumber;
private UseRecord(int instructionIndex, int useNumber) {
this.useNumber = useNumber;
this.instructionIndex = instructionIndex;
}
public int hashCode() {
return useNumber*instructionIndex;
return useNumber * instructionIndex;
}
public boolean equals(Object o) {
return (o instanceof UseRecord) &&
instructionIndex==((UseRecord)o).instructionIndex &&
useNumber==((UseRecord)o).useNumber;
return (o instanceof UseRecord) && instructionIndex == ((UseRecord) o).instructionIndex
&& useNumber == ((UseRecord) o).useNumber;
}
}
private class PhiUseRecord {
final int BBnumber;
final int phiNumber;
final int useNumber;
private PhiUseRecord(int BBnumber, int phiNumber, int useNumber) {
@ -99,68 +105,73 @@ public class SSAConversion extends AbstractSSAConversion {
this.phiNumber = phiNumber;
this.useNumber = useNumber;
}
public int hashCode() {
return phiNumber*BBnumber*useNumber;
return phiNumber * BBnumber * useNumber;
}
public boolean equals(Object o) {
return (o instanceof PhiUseRecord) &&
BBnumber==((PhiUseRecord)o).BBnumber &&
phiNumber==((PhiUseRecord)o).phiNumber &&
useNumber==((PhiUseRecord)o).useNumber;
return (o instanceof PhiUseRecord) && BBnumber == ((PhiUseRecord) o).BBnumber && phiNumber == ((PhiUseRecord) o).phiNumber
&& useNumber == ((PhiUseRecord) o).useNumber;
}
}
private class CopyPropagationRecord {
final int lhs;
final int rhs;
final int instructionIndex;
final Set renamedUses = new HashSet(2);
private final Set childRecords = new HashSet(1);
final Set<Object> renamedUses = new HashSet<Object>(2);
private final Set<CopyPropagationRecord> childRecords = new HashSet<CopyPropagationRecord>(1);
public int hashCode() {
return instructionIndex;
}
public boolean equals(Object o) {
return (o instanceof CopyPropagationRecord) &&
instructionIndex==((CopyPropagationRecord)o).instructionIndex;
return (o instanceof CopyPropagationRecord) && instructionIndex == ((CopyPropagationRecord) o).instructionIndex;
}
private CopyPropagationRecord(int instructionIndex, int lhs, int rhs) {
if (DEBUG_UNDO) Trace.println("new copy record for instruction #" + instructionIndex + ", rhs value is " + rhs);
if (DEBUG_UNDO)
Trace.println("new copy record for instruction #" + instructionIndex + ", rhs value is " + rhs);
this.lhs = lhs;
this.rhs = rhs;
this.instructionIndex = instructionIndex;
}
private void addChild(CopyPropagationRecord rec) {
if (DEBUG_UNDO) Trace.println("("+rec.instructionIndex+","+rec.rhs+") is a child of ("+instructionIndex+","+rhs+")");
if (DEBUG_UNDO)
Trace.println("(" + rec.instructionIndex + "," + rec.rhs + ") is a child of (" + instructionIndex + "," + rhs + ")");
childRecords.add(rec);
}
private void addUse(int instructionIndex, int use) {
if (DEBUG_UNDO) Trace.println("propagated use of (" + this.instructionIndex + "," + this.rhs + ") at use #" + use + " of instruction #" + instructionIndex);
if (DEBUG_UNDO)
Trace.println("propagated use of (" + this.instructionIndex + "," + this.rhs + ") at use #" + use + " of instruction #"
+ instructionIndex);
UseRecord rec = new UseRecord(instructionIndex, use);
copyPropagationMap.put(rec, this);
renamedUses.add( rec );
renamedUses.add(rec);
}
private void addUse(int BB, int phiNumber, int use) {
PhiUseRecord rec = new PhiUseRecord(BB, phiNumber, use);
copyPropagationMap.put(rec, this);
renamedUses.add( rec );
renamedUses.add(rec);
}
private SSAInstruction undo(SSAInstruction inst, int use, int val) {
int c = getNumberOfUses(inst);
int[] newUses = new int[ c ];
for(int i = 0; i < c; i++) {
if (i == use)
newUses[i] = val;
else
newUses[i] = getUse(inst, i);
int[] newUses = new int[c];
for (int i = 0; i < c; i++) {
if (i == use)
newUses[i] = val;
else
newUses[i] = getUse(inst, i);
}
return inst.copyForSSA(null, newUses);
@ -169,43 +180,45 @@ public class SSAConversion extends AbstractSSAConversion {
private void undo(int rhs) {
int lhs = symtab.newSymbol();
instructions[ instructionIndex ] = new AssignInstruction(lhs, rhs);
if (DEBUG_UNDO) Trace.println("recreating assignment at " + instructionIndex + " as " + lhs + " = " + rhs);
instructions[instructionIndex] = new AssignInstruction(lhs, rhs);
for(Iterator uses = renamedUses.iterator(); uses.hasNext(); ) {
Object x = uses.next();
if (x instanceof UseRecord) {
UseRecord use = (UseRecord)x;
int idx = use.instructionIndex;
SSAInstruction inst = instructions[ idx ];
if (DEBUG_UNDO)
Trace.println("recreating assignment at " + instructionIndex + " as " + lhs + " = " + rhs);
if (DEBUG_UNDO) Trace.println("Changing use #" + use.useNumber + " of inst #" + idx + " to val " + lhs);
for (Iterator<Object> uses = renamedUses.iterator(); uses.hasNext();) {
Object x = uses.next();
if (x instanceof UseRecord) {
UseRecord use = (UseRecord) x;
int idx = use.instructionIndex;
SSAInstruction inst = instructions[idx];
if (use.useNumber >= 0) {
instructions[idx] = undo(inst, use.useNumber, lhs);
} else {
lexicalInfo.getExposedUses(idx)[-use.useNumber - 1] = lhs;
}
copyPropagationMap.remove( use );
} else {
PhiUseRecord use = (PhiUseRecord)x;
int bb = use.BBnumber;
int phi = use.phiNumber;
SSACFG.BasicBlock BB = (SSACFG.BasicBlock)CFG.getNode(bb);
BB.addPhiForLocal(phi, (SSAPhiInstruction)undo(BB.getPhiForLocal(phi), use.useNumber, lhs));
copyPropagationMap.remove( use );
}
if (DEBUG_UNDO)
Trace.println("Changing use #" + use.useNumber + " of inst #" + idx + " to val " + lhs);
if (use.useNumber >= 0) {
instructions[idx] = undo(inst, use.useNumber, lhs);
} else {
lexicalInfo.getExposedUses(idx)[-use.useNumber - 1] = lhs;
}
copyPropagationMap.remove(use);
} else {
PhiUseRecord use = (PhiUseRecord) x;
int bb = use.BBnumber;
int phi = use.phiNumber;
SSACFG.BasicBlock BB = (SSACFG.BasicBlock) CFG.getNode(bb);
BB.addPhiForLocal(phi, (SSAPhiInstruction) undo(BB.getPhiForLocal(phi), use.useNumber, lhs));
copyPropagationMap.remove(use);
}
}
for(Iterator cs = childRecords.iterator(); cs.hasNext(); ) {
((CopyPropagationRecord)cs.next()).undo( lhs );
for (Iterator<CopyPropagationRecord> cs = childRecords.iterator(); cs.hasNext();) {
cs.next().undo(lhs);
}
}
public void undo() {
undo( this.rhs );
copyPropagationMap.remove( new UseRecord(instructionIndex, rhs) );
undo(this.rhs);
copyPropagationMap.remove(new UseRecord(instructionIndex, rhs));
}
}
@ -218,57 +231,55 @@ public class SSAConversion extends AbstractSSAConversion {
SSAInformation info = (SSAInformation) ir.getLocalMap();
info.copyUse(fromInst, fromUse, toInst, toUse);
}
//
// SSA2LocalMap implementation for SSAConversion
//
private class SSAInformation implements com.ibm.wala.ssa.IR.SSA2LocalMap {
public String[] getLocalNames(int pc, int vn) {
int v = skip(vn)||vn>=valueMap.length? vn: valueMap[vn];
int v = skip(vn) || vn >= valueMap.length ? vn : valueMap[vn];
String[][] namesData = debugInfo.getSourceNamesForValues();
if (namesData == null || namesData.length <= v)
return new String[0];
else
return namesData[v];
return new String[0];
else
return namesData[v];
}
private void undoCopyPropagation(int instructionIndex, int useNumber) {
if (DEBUG_UNDO)
Trace.println("undoing for use #" + useNumber + " of inst #" + instructionIndex);
Trace.println("undoing for use #" + useNumber + " of inst #" + instructionIndex);
UseRecord use = new UseRecord(instructionIndex, useNumber);
if (copyPropagationMap.containsKey(use)) {
((CopyPropagationRecord)copyPropagationMap.get(use)).undo();
copyPropagationMap.get(use).undo();
}
}
private void copyUse(int fromInst, int fromUse, int toInst, int toUse) {
UseRecord use = new UseRecord(fromInst, fromUse);
if (copyPropagationMap.containsKey(use)) {
((CopyPropagationRecord)copyPropagationMap.get(use)).addUse(toInst, toUse);
copyPropagationMap.get(use).addUse(toInst, toUse);
}
}
private Map getCopyHistory() {
private Map<Object, CopyPropagationRecord> getCopyHistory() {
return copyPropagationMap;
}
}
private CopyPropagationRecord topR(int v) {
if (R[v] != null && !R[v].isEmpty()) {
CopyPropagationRecord rec = (CopyPropagationRecord)R[v].peek();
CopyPropagationRecord rec = (CopyPropagationRecord) R[v].peek();
if (top(v) == rec.rhs) {
return rec;
return rec;
}
}
return null;
}
//
// implementation of AbstractSSAConversion hooks
//
@ -331,7 +342,7 @@ public class SSAConversion extends AbstractSSAConversion {
}
protected SSAPhiInstruction repairPhiDefs(SSAPhiInstruction phi, int[] newDefs) {
return (SSAPhiInstruction)phi.copyForSSA(newDefs, null);
return (SSAPhiInstruction) phi.copyForSSA(newDefs, null);
}
protected void repairPhiUse(SSACFG.BasicBlock BB, int phiIndex, int rvalIndex, int newRval) {
@ -340,11 +351,11 @@ public class SSAConversion extends AbstractSSAConversion {
int[] newUses = new int[getNumberOfUses(phi)];
for (int v = 0; v < newUses.length; v++) {
int oldUse = getUse(phi, v);
int newUse = (v==rvalIndex)? newRval: oldUse;
int newUse = (v == rvalIndex) ? newRval : oldUse;
newUses[v] = newUse;
if (v==rvalIndex && topR(oldUse) != null) {
topR(oldUse).addUse(BB.getGraphNodeId(), phiIndex, v);
if (v == rvalIndex && topR(oldUse) != null) {
topR(oldUse).addUse(BB.getGraphNodeId(), phiIndex, v);
}
}
@ -358,36 +369,36 @@ public class SSAConversion extends AbstractSSAConversion {
copyNames(rhs, lhs);
CopyPropagationRecord rec = new CopyPropagationRecord(index, lhs, newRhs);
R[lhs].push( rec );
R[lhs].push(rec);
if (topR(rhs) != null) {
topR(rhs).addChild( rec );
topR(rhs).addChild(rec);
}
}
protected void repairInstructionUses(SSAInstruction inst, int index, int[] newUses){
protected void repairInstructionUses(SSAInstruction inst, int index, int[] newUses) {
for (int j = 0; j < getNumberOfUses(inst); j++) {
if (topR(getUse(inst, j)) != null) {
topR(getUse(inst, j)).addUse(index, j);
topR(getUse(inst, j)).addUse(index, j);
}
}
int[] lexicalUses = lexicalInfo.getExposedUses(index);
if (lexicalUses != null) {
for(int j = 0; j < lexicalUses.length; j++) {
int lexicalUse = lexicalUses[j];
if (lexicalUse != -1 && !skip(lexicalUse)) {
if (S[lexicalUse].isEmpty()) {
lexicalUses[j] = -1;
} else {
int newUse = top(lexicalUse);
lexicalUses[j] = newUse;
for (int j = 0; j < lexicalUses.length; j++) {
int lexicalUse = lexicalUses[j];
if (lexicalUse != -1 && !skip(lexicalUse)) {
if (S[lexicalUse].isEmpty()) {
lexicalUses[j] = -1;
} else {
int newUse = top(lexicalUse);
if (topR(lexicalUse) != null) {
topR(lexicalUse).addUse(index, -j - 1);
}
}
}
lexicalUses[j] = newUse;
if (topR(lexicalUse) != null) {
topR(lexicalUse).addUse(index, -j - 1);
}
}
}
}
}
}
@ -405,18 +416,19 @@ public class SSAConversion extends AbstractSSAConversion {
}
protected boolean skipRepair(SSAInstruction inst, int index) {
if (! super.skipRepair(inst, index)) {
if (!super.skipRepair(inst, index)) {
return false;
}
if (index == -1) return true;
if (index == -1)
return true;
int[] lexicalUses = lexicalInfo.getExposedUses(index);
if (lexicalUses != null) {
for(int j = 0; j < lexicalUses.length; j++) {
if (! skip(lexicalUses[j])) {
return false;
}
for (int j = 0; j < lexicalUses.length; j++) {
if (!skip(lexicalUses[j])) {
return false;
}
}
}
@ -427,12 +439,11 @@ public class SSAConversion extends AbstractSSAConversion {
* @param ir
* @param options
*/
@SuppressWarnings("unchecked")
private SSAConversion(AstMethod M, AstIR ir, SSAOptions options) {
super(ir, options);
this.copyPropagationMap =
(ir.getLocalMap() instanceof SSAInformation)?
((SSAInformation)ir.getLocalMap()).getCopyHistory():
new HashMap();
this.copyPropagationMap = (ir.getLocalMap() instanceof SSAInformation) ? ((SSAInformation) ir.getLocalMap()).getCopyHistory()
: new HashMap<Object,CopyPropagationRecord>();
this.ir = ir;
this.debugInfo = M.debugInfo;
@ -440,24 +451,25 @@ public class SSAConversion extends AbstractSSAConversion {
this.symtab = ir.getSymbolTable();
this.R = new Stack[ir.getSymbolTable().getMaxValueNumber() + 1];
for(int i = 0; i < CFG.getNumberOfNodes(); i++) {
for (int i = 0; i < CFG.getNumberOfNodes(); i++) {
SSACFG.BasicBlock bb = (SSACFG.BasicBlock) CFG.getNode(i);
if (bb.hasPhi()) {
int n = 0;
for(Iterator X = bb.iteratePhis(); X.hasNext(); n++) X.next();
phiCounts[i] = n;
int n = 0;
for (Iterator X = bb.iteratePhis(); X.hasNext(); n++)
X.next();
phiCounts[i] = n;
}
}
this.nextSSAValue = ir.getNumberOfParameters()+1;
this.nextSSAValue = ir.getNumberOfParameters() + 1;
int[] exitLive = lexicalInfo.getExitExposedUses();
BitVector v = new BitVector();
if (exitLive != null)
for(int i = 0; i < exitLive.length; i++)
v.set( exitLive[i] );
if (exitLive != null)
for (int i = 0; i < exitLive.length; i++)
v.set(exitLive[i]);
this.liveness = LiveAnalysis.perform(CFG, symtab, v);
if (DEBUG) {
Trace.println(liveness);
}
@ -466,39 +478,36 @@ public class SSAConversion extends AbstractSSAConversion {
protected int getNextNewValueNumber() {
while (symtab.isConstant(nextSSAValue) || skip(nextSSAValue))
++nextSSAValue;
symtab.ensureSymbol( nextSSAValue );
symtab.ensureSymbol(nextSSAValue);
return nextSSAValue++;
}
private void copyNames(int to, int from) {
String[][] namesData = debugInfo.getSourceNamesForValues();
if (namesData != null &&
namesData.length > from &&
namesData[from] != null)
{
if (namesData != null && namesData.length > from && namesData[from] != null) {
if (namesData[to] == null) {
namesData[to] = namesData[from];
namesData[to] = namesData[from];
} else {
String[] newNames = new String[ namesData[from].length+namesData[to].length ];
System.arraycopy(namesData[from], 0, newNames, 0, namesData[from].length);
System.arraycopy(namesData[to], 0, newNames, namesData[from].length, namesData[to].length);
namesData[to] = newNames;
String[] newNames = new String[namesData[from].length + namesData[to].length];
System.arraycopy(namesData[from], 0, newNames, 0, namesData[from].length);
System.arraycopy(namesData[to], 0, newNames, namesData[from].length, namesData[to].length);
namesData[to] = newNames;
}
}
}
protected void initializeVariables() {
for (int V = 1; V <= getMaxValueNumber(); V++) {
if (! skip(V)) {
R[V] = new Stack();
if (!skip(V)) {
R[V] = new Stack();
}
}
int[] params = symtab.getParameterValueNumbers();
for (int i = 0; i < params.length; i++) {
if (! skip( params[i] )) {
S[params[i]].push( params[i] );
valueMap[ params[i] ] = params[i];
if (!skip(params[i])) {
S[params[i]].push(params[i]);
valueMap[params[i]] = params[i];
}
}
@ -507,11 +516,11 @@ public class SSAConversion extends AbstractSSAConversion {
protected void repairExit() {
int[] exitLives = lexicalInfo.getExitExposedUses();
if (exitLives != null) {
for(int i = 0; i < exitLives.length; i++) {
if (! skip(exitLives[i])) {
Assertions._assert(! S[exitLives[i]].isEmpty());
exitLives[i] = top(exitLives[i]);
}
for (int i = 0; i < exitLives.length; i++) {
if (!skip(exitLives[i])) {
Assertions._assert(!S[exitLives[i]].isEmpty());
exitLives[i] = top(exitLives[i]);
}
}
}
}
@ -521,8 +530,8 @@ public class SSAConversion extends AbstractSSAConversion {
//
protected void fail(int v) {
System.err.println( "during SSA conversion of the following IR:" );
System.err.println( ir );
System.err.println("during SSA conversion of the following IR:");
System.err.println(ir);
super.fail(v);
}
@ -534,18 +543,18 @@ public class SSAConversion extends AbstractSSAConversion {
super.perform();
if (DUMP) {
Trace.println( ir );
Trace.println(ir);
if (lexicalInfo != null) {
for(int i = 0; i < instructions.length; i++) {
int[] lexicalUses = lexicalInfo.getExposedUses(i);
if (lexicalUses != null) {
Trace.print("extra uses for " + instructions[i] + ": ");
for(int j = 0; j < lexicalUses.length; j++) {
Trace.print( new Integer(lexicalUses[j]).toString() + " " );
}
Trace.println("");
}
}
for (int i = 0; i < instructions.length; i++) {
int[] lexicalUses = lexicalInfo.getExposedUses(i);
if (lexicalUses != null) {
Trace.print("extra uses for " + instructions[i] + ": ");
for (int j = 0; j < lexicalUses.length; j++) {
Trace.print(new Integer(lexicalUses[j]).toString() + " ");
}
Trace.println("");
}
}
}
}
@ -556,23 +565,20 @@ public class SSAConversion extends AbstractSSAConversion {
IInstruction[] insts = ir.getInstructions();
MutableIntSet foundOne = new BitVectorIntSet();
MutableIntSet foundTwo = new BitVectorIntSet();
for(int i = 0; i < insts.length; i++) {
for (int i = 0; i < insts.length; i++) {
SSAInstruction inst = (SSAInstruction) insts[i];
if (inst != null) {
for(int j = 0; j < inst.getNumberOfDefs(); j++) {
int def = inst.getDef(j);
if (def != -1) {
if (foundOne.contains(def) ||
ir.getSymbolTable().isConstant(def) ||
def <= ir.getNumberOfParameters() ||
inst instanceof AssignInstruction)
{
foundTwo.add(def);
} else {
foundOne.add(def);
}
}
}
for (int j = 0; j < inst.getNumberOfDefs(); j++) {
int def = inst.getDef(j);
if (def != -1) {
if (foundOne.contains(def) || ir.getSymbolTable().isConstant(def) || def <= ir.getNumberOfParameters()
|| inst instanceof AssignInstruction) {
foundTwo.add(def);
} else {
foundOne.add(def);
}
}
}
}
}
@ -583,25 +589,24 @@ public class SSAConversion extends AbstractSSAConversion {
return convert(M, ir, options, valuesToConvert(ir));
}
public static SSA2LocalMap convert(AstMethod M,
final AstIR ir,
SSAOptions options,
final IntSet values)
{
public static SSA2LocalMap convert(AstMethod M, final AstIR ir, SSAOptions options, final IntSet values) {
try {
if (DEBUG) {
Trace.println("starting conversion for " + values);
Trace.println( ir );
Trace.println("starting conversion for " + values);
Trace.println(ir);
}
if (DEBUG_UNDO) Trace.println(">>> starting " + ir.getMethod());
if (DEBUG_UNDO)
Trace.println(">>> starting " + ir.getMethod());
SSAConversion ssa = new SSAConversion(M, ir, options) {
final int limit = ir.getSymbolTable().getMaxValueNumber();
protected boolean skip(int i) {
return (i >= 0) && (i <= limit) && (!values.contains(i));
}
final int limit = ir.getSymbolTable().getMaxValueNumber();
protected boolean skip(int i) {
return (i >= 0) && (i <= limit) && (!values.contains(i));
}
};
ssa.perform();
if (DEBUG_UNDO) Trace.println("<<< done " + ir.getMethod());
if (DEBUG_UNDO)
Trace.println("<<< done " + ir.getMethod());
return ssa.getComputedLocalMap();
} catch (RuntimeException e) {
Trace.println("exception " + e + " while converting:");

View File

@ -13,6 +13,7 @@ package com.ibm.wala.cast.ir.ssa.analysis;
import java.util.Iterator;
import com.ibm.wala.cfg.ControlFlowGraph;
import com.ibm.wala.cfg.IBasicBlock;
import com.ibm.wala.dataflow.graph.AbstractMeetOperator;
import com.ibm.wala.dataflow.graph.BitVectorSolver;
import com.ibm.wala.dataflow.graph.BitVectorUnion;
@ -152,15 +153,15 @@ public class LiveAnalysis {
}
}
final BitVectorSolver S = new BitVectorSolver(new IKilldallFramework() {
private final Graph G = GraphInverter.invert(cfg);
final BitVectorSolver<IBasicBlock> S = new BitVectorSolver<IBasicBlock>(new IKilldallFramework<IBasicBlock>() {
private final Graph<IBasicBlock> G = GraphInverter.invert(cfg);
public Graph getFlowGraph() {
public Graph<IBasicBlock> getFlowGraph() {
return G;
}
public ITransferFunctionProvider getTransferFunctionProvider() {
return new ITransferFunctionProvider() {
public ITransferFunctionProvider<IBasicBlock> getTransferFunctionProvider() {
return new ITransferFunctionProvider<IBasicBlock>() {
public boolean hasNodeTransferFunctions() {
return true;
@ -170,7 +171,7 @@ public class LiveAnalysis {
return false;
}
public UnaryOperator getNodeTransferFunction(Object node) {
public UnaryOperator getNodeTransferFunction(IBasicBlock node) {
if (((SSACFG.BasicBlock) node).isExitBlock()) {
return new ExitBlockGenKillOperator();
} else {
@ -178,7 +179,7 @@ public class LiveAnalysis {
}
}
public UnaryOperator getEdgeTransferFunction(Object s, Object d) {
public UnaryOperator getEdgeTransferFunction(IBasicBlock s, IBasicBlock d) {
Assertions.UNREACHABLE();
return null;
}

View File

@ -50,6 +50,7 @@ import com.ibm.wala.cast.util.CAstPrinter;
import com.ibm.wala.cfg.AbstractCFG;
import com.ibm.wala.cfg.IBasicBlock;
import com.ibm.wala.classLoader.IClassLoader;
import com.ibm.wala.classLoader.IField;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.shrikeBT.BinaryOpInstruction;
import com.ibm.wala.shrikeBT.ConditionalBranchInstruction;
@ -331,7 +332,7 @@ public abstract class AstTranslator extends CAstVisitor {
private int lastIndex = -2;
private final List instructions = new ArrayList();
private final List<SSAInstruction> instructions = new ArrayList<SSAInstruction>();
public int getNumber() {
return getGraphNodeId();
@ -389,7 +390,7 @@ public abstract class AstTranslator extends CAstVisitor {
return "PreBB" + number + ":" + firstIndex + ".." + lastIndex;
}
List instructions() {
List<SSAInstruction> instructions() {
return instructions;
}
@ -401,7 +402,7 @@ public abstract class AstTranslator extends CAstVisitor {
return null;
}
public Iterator iterateAllInstructions() {
public Iterator<SSAInstruction> iterateAllInstructions() {
return instructions.iterator();
}
}
@ -452,12 +453,12 @@ public abstract class AstTranslator extends CAstVisitor {
}
}
public final class IncipientCFG extends SparseNumberedGraph {
public final class IncipientCFG extends SparseNumberedGraph<PreBasicBlock> {
protected class Unwind {
private final Map unwindData = new LinkedHashMap();
private final Map<PreBasicBlock, UnwindState> unwindData = new LinkedHashMap<PreBasicBlock, UnwindState>();
private final Map code = new LinkedHashMap();
private final Map<Pair<UnwindState, Pair<PreBasicBlock, Boolean>>, PreBasicBlock> code = new LinkedHashMap<Pair<UnwindState, Pair<PreBasicBlock, Boolean>>, PreBasicBlock>();
void setUnwindState(PreBasicBlock block, UnwindState context) {
unwindData.put(block, context);
@ -468,7 +469,7 @@ public abstract class AstTranslator extends CAstVisitor {
}
public PreBasicBlock findOrCreateCode(PreBasicBlock source, PreBasicBlock target, boolean exception) {
UnwindState sourceContext = (UnwindState) unwindData.get(source);
UnwindState sourceContext = unwindData.get(source);
// no unwinding is needed, so jump to target block directly
if (sourceContext == null)
@ -477,16 +478,17 @@ public abstract class AstTranslator extends CAstVisitor {
WalkContext astContext = sourceContext.astContext;
UnwindState targetContext = null;
if (target != null)
targetContext = (UnwindState) unwindData.get(target);
targetContext = unwindData.get(target);
// in unwind context, but catch in same (or inner) unwind context
if (targetContext != null && targetContext.covers(sourceContext))
return target;
Pair key = new Pair(sourceContext, new Pair(target, exception ? Boolean.TRUE : Boolean.FALSE));
Pair<UnwindState, Pair<PreBasicBlock, Boolean>> key = new Pair<UnwindState, Pair<PreBasicBlock, Boolean>>(sourceContext,
new Pair<PreBasicBlock, Boolean>(target, exception ? Boolean.TRUE : Boolean.FALSE));
if (code.containsKey(key)) {
return (PreBasicBlock) code.get(key);
return code.get(key);
} else {
int e = -1;
@ -544,19 +546,19 @@ public abstract class AstTranslator extends CAstVisitor {
private Unwind unwind = null;
private final List blocks = new ArrayList();
private final List<PreBasicBlock> blocks = new ArrayList<PreBasicBlock>();
private final Map nodeToBlock = new LinkedHashMap();
private final Map<CAstNode, PreBasicBlock> nodeToBlock = new LinkedHashMap<CAstNode, PreBasicBlock>();
private final Map delayedEdges = new LinkedHashMap();
private final Map<Object, Set<Pair<PreBasicBlock, Boolean>>> delayedEdges = new LinkedHashMap<Object, Set<Pair<PreBasicBlock, Boolean>>>();
private final Object exitMarker = new Object();
private final Set deadBlocks = new LinkedHashSet();
private final Set<PreBasicBlock> deadBlocks = new LinkedHashSet<PreBasicBlock>();
private final Set normalToExit = new LinkedHashSet();
private final Set<PreBasicBlock> normalToExit = new LinkedHashSet<PreBasicBlock>();
private final Set exceptionalToExit = new LinkedHashSet();
private final Set<PreBasicBlock> exceptionalToExit = new LinkedHashSet<PreBasicBlock>();
private Position[] linePositions = new Position[10];
@ -620,11 +622,11 @@ public abstract class AstTranslator extends CAstVisitor {
}
private void addDelayedEdge(PreBasicBlock src, Object dst, boolean exception) {
Pair v = new Pair(src, exception ? Boolean.TRUE : Boolean.FALSE);
Pair<PreBasicBlock, Boolean> v = new Pair<PreBasicBlock, Boolean>(src, exception ? Boolean.TRUE : Boolean.FALSE);
if (delayedEdges.containsKey(dst))
((Set) delayedEdges.get(dst)).add(v);
delayedEdges.get(dst).add(v);
else {
Set s = new LinkedHashSet();
Set<Pair<PreBasicBlock, Boolean>> s = new LinkedHashSet<Pair<PreBasicBlock, Boolean>>();
s.add(v);
delayedEdges.put(dst, s);
}
@ -637,7 +639,7 @@ public abstract class AstTranslator extends CAstVisitor {
void makeExitBlock(PreBasicBlock bb) {
bb.makeExitBlock();
for (Iterator ps = getPredNodes(bb); ps.hasNext();)
for (Iterator<? extends PreBasicBlock> ps = getPredNodes(bb); ps.hasNext();)
normalToExit.add(ps.next());
checkForRealizedExitEdges(bb);
@ -649,14 +651,14 @@ public abstract class AstTranslator extends CAstVisitor {
private void checkForRealizedEdges(CAstNode n) {
if (delayedEdges.containsKey(n)) {
for (Iterator ss = ((Set) delayedEdges.get(n)).iterator(); ss.hasNext();) {
for (Iterator ss = delayedEdges.get(n).iterator(); ss.hasNext();) {
Pair s = (Pair) ss.next();
PreBasicBlock that = (PreBasicBlock) s.fst;
boolean exception = ((Boolean) s.snd).booleanValue();
if (unwind == null) {
addEdge(that, nodeToBlock.get(n));
} else {
PreBasicBlock target = (PreBasicBlock) nodeToBlock.get(n);
PreBasicBlock target = nodeToBlock.get(n);
addEdge(that, unwind.findOrCreateCode(that, target, exception));
}
}
@ -667,7 +669,7 @@ public abstract class AstTranslator extends CAstVisitor {
private void checkForRealizedExitEdges(PreBasicBlock n) {
if (delayedEdges.containsKey(exitMarker)) {
for (Iterator ss = ((Set) delayedEdges.get(exitMarker)).iterator(); ss.hasNext();) {
for (Iterator ss = delayedEdges.get(exitMarker).iterator(); ss.hasNext();) {
Pair s = (Pair) ss.next();
PreBasicBlock that = (PreBasicBlock) s.fst;
boolean exception = ((Boolean) s.snd).booleanValue();
@ -704,12 +706,12 @@ public abstract class AstTranslator extends CAstVisitor {
public void addPreEdge(CAstNode src, CAstNode dst, boolean exception) {
Assertions._assert(nodeToBlock.containsKey(src));
addPreEdge((PreBasicBlock) nodeToBlock.get(src), dst, exception);
addPreEdge(nodeToBlock.get(src), dst, exception);
}
public void addPreEdge(PreBasicBlock src, CAstNode dst, boolean exception) {
if (nodeToBlock.containsKey(dst)) {
PreBasicBlock target = (PreBasicBlock) nodeToBlock.get(dst);
PreBasicBlock target = nodeToBlock.get(dst);
if (DEBUG_CFG)
Trace.println("adding pre-edge " + src + " --> " + dst);
if (unwind == null) {
@ -726,7 +728,7 @@ public abstract class AstTranslator extends CAstVisitor {
public void addPreEdgeToExit(CAstNode src, boolean exception) {
Assertions._assert(nodeToBlock.containsKey(src));
addPreEdgeToExit((PreBasicBlock) nodeToBlock.get(src), exception);
addPreEdgeToExit(nodeToBlock.get(src), exception);
}
public void addPreEdgeToExit(PreBasicBlock src, boolean exception) {
@ -741,7 +743,7 @@ public abstract class AstTranslator extends CAstVisitor {
addDelayedEdge(src, exitMarker, exception);
}
public void addEdge(Object src, Object dst) {
public void addEdge(PreBasicBlock src, PreBasicBlock dst) {
super.addEdge(src, dst);
deadBlocks.remove(dst);
}
@ -751,7 +753,7 @@ public abstract class AstTranslator extends CAstVisitor {
}
public PreBasicBlock getBlock(CAstNode n) {
return (PreBasicBlock) nodeToBlock.get(n);
return nodeToBlock.get(n);
}
private void noteLinePosition(int instruction) {
@ -798,24 +800,24 @@ public abstract class AstTranslator extends CAstVisitor {
AstCFG(CAstEntity n, IncipientCFG icfg, SymbolTable symtab) {
super(null);
List blocks = icfg.blocks;
List<PreBasicBlock> blocks = icfg.blocks;
this.symtab = symtab;
functionName = n.getName();
instructionToBlockMap = new int[blocks.size()];
for (int i = 0; i < blocks.size(); i++)
instructionToBlockMap[i] = ((PreBasicBlock) blocks.get(i)).getLastInstructionIndex();
instructionToBlockMap[i] = blocks.get(i).getLastInstructionIndex();
for (int i = 0; i < blocks.size(); i++) {
PreBasicBlock block = (PreBasicBlock) blocks.get(i);
PreBasicBlock block = blocks.get(i);
this.addNode(block);
if (block.isCatchBlock()) {
setCatchBlock(i);
}
if (DEBUG_CFG)
Trace.println("added " + blocks.get(i) + " to final CFG as " + getNumber((IBasicBlock) blocks.get(i)));
Trace.println("added " + blocks.get(i) + " to final CFG as " + getNumber(blocks.get(i)));
}
if (DEBUG_CFG)
Trace.println(getMaxNumber() + " blocks total");
@ -823,7 +825,7 @@ public abstract class AstTranslator extends CAstVisitor {
init();
for (int i = 0; i < blocks.size(); i++) {
PreBasicBlock src = (PreBasicBlock) blocks.get(i);
PreBasicBlock src = blocks.get(i);
for (Iterator j = icfg.getSuccNodes(src); j.hasNext();) {
PreBasicBlock dst = (PreBasicBlock) j.next();
if (isCatchBlock(dst.getNumber()) || (dst.isExitBlock() && icfg.exceptionalToExit.contains(src))) {
@ -843,9 +845,9 @@ public abstract class AstTranslator extends CAstVisitor {
int x = 0;
instructions = new SSAInstruction[icfg.currentInstruction];
for (int i = 0; i < blocks.size(); i++) {
List bi = ((PreBasicBlock) blocks.get(i)).instructions();
List<SSAInstruction> bi = blocks.get(i).instructions();
for (int j = 0; j < bi.size(); j++) {
instructions[x++] = (SSAInstruction) bi.get(j);
instructions[x++] = bi.get(j);
}
}
}
@ -944,7 +946,7 @@ public abstract class AstTranslator extends CAstVisitor {
Symbol lookup(String name);
Iterator getAllNames();
Iterator<String> getAllNames();
int size();
@ -987,9 +989,9 @@ public abstract class AstTranslator extends CAstVisitor {
private abstract class AbstractScope implements Scope {
private final Scope parent;
private final Map values = new LinkedHashMap();
private final Map<String, Symbol> values = new LinkedHashMap<String, Symbol>();
private final Map caseInsensitiveNames = new LinkedHashMap();
private final Map<String, String> caseInsensitiveNames = new LinkedHashMap<String, String>();
protected abstract SymbolTable getUnderlyingSymtab();
@ -997,7 +999,7 @@ public abstract class AstTranslator extends CAstVisitor {
return getUnderlyingSymtab().getMaxValueNumber() + 1;
}
public Iterator getAllNames() {
public Iterator<String> getAllNames() {
return values.keySet().iterator();
}
@ -1061,7 +1063,7 @@ public abstract class AstTranslator extends CAstVisitor {
}
private final String mapName(String nm) {
String mappedName = (String) caseInsensitiveNames.get(nm.toLowerCase());
String mappedName = caseInsensitiveNames.get(nm.toLowerCase());
return (mappedName == null) ? nm : mappedName;
}
@ -1081,7 +1083,7 @@ public abstract class AstTranslator extends CAstVisitor {
public Symbol lookup(String nm) {
if (contains(nm)) {
return (Symbol) values.get(mapName(nm));
return values.get(mapName(nm));
} else {
Symbol scoped = parent.lookup(nm);
if (scoped != null && getEntityScope() == this && (isGlobal(scoped) || isLexicallyScoped(scoped))) {
@ -1089,7 +1091,7 @@ public abstract class AstTranslator extends CAstVisitor {
if (scoped.getDefiningScope().isCaseInsensitive(nm)) {
caseInsensitiveNames.put(nm.toLowerCase(), nm);
}
return (Symbol) values.get(nm);
return values.get(nm);
} else {
return scoped;
}
@ -1097,7 +1099,7 @@ public abstract class AstTranslator extends CAstVisitor {
}
public boolean contains(String nm) {
String mappedName = (String) caseInsensitiveNames.get(nm.toLowerCase());
String mappedName = caseInsensitiveNames.get(nm.toLowerCase());
return values.containsKey(mappedName == null ? nm : mappedName);
}
@ -1277,11 +1279,11 @@ public abstract class AstTranslator extends CAstVisitor {
}
private Scope makeGlobalScope() {
final Map globalSymbols = new LinkedHashMap();
final Map caseInsensitiveNames = new LinkedHashMap();
final Map<String, AbstractSymbol> globalSymbols = new LinkedHashMap<String, AbstractSymbol>();
final Map<String, String> caseInsensitiveNames = new LinkedHashMap<String, String>();
return new Scope() {
private final String mapName(String nm) {
String mappedName = (String) caseInsensitiveNames.get(nm.toLowerCase());
String mappedName = caseInsensitiveNames.get(nm.toLowerCase());
return (mappedName == null) ? nm : mappedName;
}
@ -1301,7 +1303,7 @@ public abstract class AstTranslator extends CAstVisitor {
return globalSymbols.size();
}
public Iterator getAllNames() {
public Iterator<String> getAllNames() {
return globalSymbols.keySet().iterator();
}
@ -1343,7 +1345,7 @@ public abstract class AstTranslator extends CAstVisitor {
throw new Error("cannot find " + name);
}
return (Symbol) globalSymbols.get(mapName(name));
return globalSymbols.get(mapName(name));
}
public void declare(final String name, boolean isFinal, boolean isCaseInsensitive, int vn) {
@ -1373,11 +1375,11 @@ public abstract class AstTranslator extends CAstVisitor {
}
protected Scope makeTypeScope(final CAstEntity type, final Scope parent) {
final Map typeSymbols = new LinkedHashMap();
final Map caseInsensitiveNames = new LinkedHashMap();
final Map<String, AbstractSymbol> typeSymbols = new LinkedHashMap<String, AbstractSymbol>();
final Map<String, String> caseInsensitiveNames = new LinkedHashMap<String, String>();
return new Scope() {
private final String mapName(String nm) {
String mappedName = (String) caseInsensitiveNames.get(nm.toLowerCase());
String mappedName = caseInsensitiveNames.get(nm.toLowerCase());
return (mappedName == null) ? nm : mappedName;
}
@ -1397,7 +1399,7 @@ public abstract class AstTranslator extends CAstVisitor {
return typeSymbols.size();
}
public Iterator getAllNames() {
public Iterator<String> getAllNames() {
return typeSymbols.keySet().iterator();
}
@ -1431,7 +1433,7 @@ public abstract class AstTranslator extends CAstVisitor {
public Symbol lookup(String nm) {
if (typeSymbols.containsKey(mapName(nm)))
return (Symbol) typeSymbols.get(mapName(nm));
return typeSymbols.get(mapName(nm));
else {
return parent.lookup(nm);
}
@ -1475,7 +1477,7 @@ public abstract class AstTranslator extends CAstVisitor {
Scope currentScope();
Set entityScopes();
Set<Scope> entityScopes();
IncipientCFG cfg();
@ -1520,7 +1522,7 @@ public abstract class AstTranslator extends CAstVisitor {
return parent.currentScope();
}
public Set entityScopes() {
public Set<Scope> entityScopes() {
return parent.entityScopes();
}
@ -1601,7 +1603,7 @@ public abstract class AstTranslator extends CAstVisitor {
private class CodeEntityContext extends EntityContext {
private final Scope topEntityScope;
private final Set allEntityScopes;
private final Set<Scope> allEntityScopes;
private final IncipientCFG cfg;
@ -1612,7 +1614,7 @@ public abstract class AstTranslator extends CAstVisitor {
this.topEntityScope = entityScope;
this.allEntityScopes = new HashSet();
this.allEntityScopes = new HashSet<Scope>();
this.allEntityScopes.add(entityScope);
cfg = new IncipientCFG();
@ -1630,7 +1632,7 @@ public abstract class AstTranslator extends CAstVisitor {
return topEntityScope;
}
public Set entityScopes() {
public Set<Scope> entityScopes() {
return allEntityScopes;
}
@ -1762,14 +1764,14 @@ public abstract class AstTranslator extends CAstVisitor {
}
if (accesses != null) {
Set parents = new LinkedHashSet();
Set<String> parents = new LinkedHashSet<String>();
for (Iterator ACS = accesses.iterator(); ACS.hasNext();) {
Access AC = (Access) ACS.next();
if (AC.variableDefiner != null) {
parents.add(AC.variableDefiner);
}
}
scopingParents = (String[]) parents.toArray(new String[parents.size()]);
scopingParents = parents.toArray(new String[parents.size()]);
if (DEBUG_LEXICAL) {
Trace.println("scoping parents of " + scope.getEntity());
@ -1810,7 +1812,7 @@ public abstract class AstTranslator extends CAstVisitor {
}
};
private final Map results = new LinkedHashMap();
private final Map<CAstNode, Integer> results = new LinkedHashMap<CAstNode, Integer>();
protected boolean hasValue(CAstNode n) {
return results.containsKey(n);
@ -1823,18 +1825,18 @@ public abstract class AstTranslator extends CAstVisitor {
public final int getValue(CAstNode n) {
if (results.containsKey(n))
return ((Integer) results.get(n)).intValue();
return results.get(n).intValue();
else {
Trace.println("no value for " + n.getKind());
return -1;
}
}
private final Map entityNames = new LinkedHashMap();
private final Map<CAstEntity, String> entityNames = new LinkedHashMap<CAstEntity, String>();
private final Map exposedNames = new LinkedHashMap();
private final Map<CAstEntity, LinkedHashSet<Pair<Pair<String, String>, Integer>>> exposedNames = new LinkedHashMap<CAstEntity, LinkedHashSet<Pair<Pair<String, String>, Integer>>>();
private final Map accesses = new LinkedHashMap();
private final Map<CAstEntity, LinkedHashSet<Access>> accesses = new LinkedHashMap<CAstEntity, LinkedHashSet<Access>>();
private void addEntityName(CAstEntity e, String name) {
entityNames.put(e, name);
@ -1842,15 +1844,17 @@ public abstract class AstTranslator extends CAstVisitor {
private void addAccess(CAstEntity e, Access access) {
if (!accesses.containsKey(e))
accesses.put(e, new LinkedHashSet());
((Set) accesses.get(e)).add(access);
accesses.put(e, new LinkedHashSet<Access>());
accesses.get(e).add(access);
}
private void addExposedName(CAstEntity entity, CAstEntity declaration, String name, int valueNumber) {
if (!exposedNames.containsKey(entity))
exposedNames.put(entity, new LinkedHashSet());
exposedNames.put(entity, new LinkedHashSet<Pair<Pair<String, String>, Integer>>());
((Set) exposedNames.get(entity)).add(new Pair(new Pair(name, getEntityName(declaration)), new Integer(valueNumber)));
exposedNames.get(entity).add(
new Pair<Pair<String, String>, Integer>(new Pair<String, String>(name, getEntityName(declaration)),
new Integer(valueNumber)));
}
private String getEntityName(CAstEntity e) {
@ -1938,19 +1942,19 @@ public abstract class AstTranslator extends CAstVisitor {
}
}
private String[] makeNameMap(Set scopes) {
private String[] makeNameMap(Set<Scope> scopes) {
// all scopes share the same underlying symtab, which is what
// size really refers to.
String[] map = new String[((Scope) scopes.iterator().next()).size() + 1];
String[] map = new String[scopes.iterator().next().size() + 1];
if (DEBUG_NAMES) {
Trace.println("names array of size " + map.length);
}
for (Iterator S = scopes.iterator(); S.hasNext();) {
Scope scope = (Scope) S.next();
for (Iterator I = scope.getAllNames(); I.hasNext();) {
String nm = (String) I.next();
for (Iterator<Scope> S = scopes.iterator(); S.hasNext();) {
Scope scope = S.next();
for (Iterator<String> I = scope.getAllNames(); I.hasNext();) {
String nm = I.next();
Symbol v = (Symbol) scope.lookup(nm);
// hack for new expression idiom in the Java translator
@ -2088,20 +2092,19 @@ public abstract class AstTranslator extends CAstVisitor {
String[] nms = makeNameMap(functionContext.entityScopes());
/*
Set reachableBlocks =
DFS.getReachableNodes(cfg, Collections.singleton(cfg.entry()));
Assertions._assert(reachableBlocks.size() == cfg.getNumberOfNodes(),
cfg.toString());
*/
* Set reachableBlocks = DFS.getReachableNodes(cfg,
* Collections.singleton(cfg.entry()));
* Assertions._assert(reachableBlocks.size() == cfg.getNumberOfNodes(),
* cfg.toString());
*/
// (put here to allow subclasses to handle stuff in scoped entities)
// assemble lexical information
patchLexicalAccesses(cfg.getInstructions(), (Set) accesses.get(n));
patchLexicalAccesses(cfg.getInstructions(), accesses.get(n));
LexicalInformation LI =
// TODO: Ask Julian if the below change is always correct
new AstLexicalInformation((AbstractScope) functionContext.currentScope(), cfg.getInstructions(), (Set) exposedNames.get(n),
(Set) accesses.get(n));
new AstLexicalInformation((AbstractScope) functionContext.currentScope(), cfg.getInstructions(), exposedNames.get(n), accesses
.get(n));
DebuggingInformation DBG = new AstDebuggingInformation(line, nms);
@ -2109,7 +2112,7 @@ public abstract class AstTranslator extends CAstVisitor {
defineFunction(n, parentContext, cfg, symtab, katch, catchTypes, LI, DBG);
}
private final Stack positions = new Stack();
private final Stack<Position> positions = new Stack<Position>();
protected Context makeLocalContext(Context context, CAstNode n) {
return new LocalContext((WalkContext) context, makeLocalScope(n, ((WalkContext) context).currentScope()));
@ -2121,7 +2124,7 @@ public abstract class AstTranslator extends CAstVisitor {
// FIXME: should it be possible to override visit() instead to do the below
// and then call super.visit?
private Map popPositionM = new LinkedHashMap();
private Map<CAstNode, Boolean> popPositionM = new LinkedHashMap<CAstNode, Boolean>();
protected boolean enterNode(CAstNode n, Context c, CAstVisitor visitor) {
WalkContext context = (WalkContext) c;
@ -2146,7 +2149,7 @@ public abstract class AstTranslator extends CAstVisitor {
protected void postProcessNode(CAstNode n, Context c, CAstVisitor visitor) {
WalkContext context = (WalkContext) c;
if (popPositionM.get(n) != null) {
context.cfg().setCurrentPosition((Position) positions.pop());
context.cfg().setCurrentPosition(positions.pop());
}
}
@ -2178,7 +2181,7 @@ public abstract class AstTranslator extends CAstVisitor {
int result = processFunctionExpr(n, c);
CAstEntity fn = (CAstEntity) n.getChild(0).getValue();
// FIXME: handle redefinitions of functions
if (! context.currentScope().contains(fn.getName())) {
if (!context.currentScope().contains(fn.getName())) {
context.currentScope().declare(fn.getName(), true, false, result);
}
}
@ -2667,7 +2670,7 @@ public abstract class AstTranslator extends CAstVisitor {
int[] dims = gatherArrayDims(n);
doArrayRead(context, temp, getValue(n.getChild(0)), n, dims);
int rval = processAssignOp(n, v, a, temp, !pre, c);
setValue(n, pre? rval: temp);
setValue(n, pre ? rval : temp);
doArrayWrite(context, getValue(n.getChild(0)), n, dims, rval);
}
@ -2694,7 +2697,7 @@ public abstract class AstTranslator extends CAstVisitor {
int temp = context.currentScope().allocateTempValue();
doFieldRead(context, temp, getValue(n.getChild(0)), n.getChild(1), n);
int rval = processAssignOp(n, v, a, temp, !pre, c);
setValue(n, pre? rval: temp);
setValue(n, pre ? rval : temp);
doFieldWrite(context, getValue(n.getChild(0)), n.getChild(1), n, rval);
}
@ -2729,8 +2732,7 @@ public abstract class AstTranslator extends CAstVisitor {
else if (context.currentScope().isLexicallyScoped(ls)) {
doLexicallyScopedWrite(context, nm, rval);
} else {
Assertions._assert(rval != -1,
CAstPrinter.print(n, c.top().getSourceMap()));
Assertions._assert(rval != -1, CAstPrinter.print(n, c.top().getSourceMap()));
doLocalWrite(context, nm, rval);
}
}
@ -2776,8 +2778,8 @@ public abstract class AstTranslator extends CAstVisitor {
private boolean isSimpleSwitch(CAstNode n, WalkContext context, CAstVisitor visitor) {
CAstControlFlowMap ctrl = context.getControlFlow();
Collection caseLabels = ctrl.getTargetLabels(n);
for (Iterator kases = caseLabels.iterator(); kases.hasNext();) {
Collection<IField> caseLabels = ctrl.getTargetLabels(n);
for (Iterator<IField> kases = caseLabels.iterator(); kases.hasNext();) {
Object x = kases.next();
if (x == CAstControlFlowMap.SWITCH_DEFAULT)
@ -2816,7 +2818,7 @@ public abstract class AstTranslator extends CAstVisitor {
boolean hasExplicitDefault = ctrl.getTarget(n, CAstControlFlowMap.SWITCH_DEFAULT) != null;
Collection caseLabels = ctrl.getTargetLabels(n);
Collection<IField> caseLabels = ctrl.getTargetLabels(n);
int cases = caseLabels.size();
if (hasExplicitDefault)
cases--;
@ -2839,7 +2841,7 @@ public abstract class AstTranslator extends CAstVisitor {
context.cfg().newBlock(true);
int cn = 0;
for (Iterator kases = caseLabels.iterator(); kases.hasNext();) {
for (Iterator<IField> kases = caseLabels.iterator(); kases.hasNext();) {
Object x = kases.next();
CAstNode target = ctrl.getTarget(n, x);
if (x == CAstControlFlowMap.SWITCH_DEFAULT) {
@ -2863,9 +2865,9 @@ public abstract class AstTranslator extends CAstVisitor {
visitor.visit(switchValue, context, visitor);
int v = getValue(switchValue);
Collection caseLabels = ctrl.getTargetLabels(n);
Map labelToBlock = new LinkedHashMap();
for (Iterator kases = caseLabels.iterator(); kases.hasNext();) {
Collection<IField> caseLabels = ctrl.getTargetLabels(n);
Map<Object, PreBasicBlock> labelToBlock = new LinkedHashMap<Object, PreBasicBlock>();
for (Iterator<IField> kases = caseLabels.iterator(); kases.hasNext();) {
Object x = kases.next();
if (x != CAstControlFlowMap.SWITCH_DEFAULT) {
walkNodes((CAstNode) x, context);
@ -2885,8 +2887,7 @@ public abstract class AstTranslator extends CAstVisitor {
visitor.visit(switchBody, context, visitor);
context.cfg().newBlock(true);
PreBasicBlock nextBlock = context.cfg().getCurrentBlock();
for (Iterator kases = caseLabels.iterator(); kases.hasNext();) {
for (Iterator<IField> kases = caseLabels.iterator(); kases.hasNext();) {
Object x = kases.next();
if (x != CAstControlFlowMap.SWITCH_DEFAULT) {
CAstNode target = ctrl.getTarget(n, x);
@ -2930,8 +2931,8 @@ public abstract class AstTranslator extends CAstVisitor {
context.cfg().addPreNode(n, context.getUnwindState());
context.cfg().newBlock(false);
Collection labels = context.getControlFlow().getTargetLabels(n);
for (Iterator iter = labels.iterator(); iter.hasNext();) {
Collection<IField> labels = context.getControlFlow().getTargetLabels(n);
for (Iterator<IField> iter = labels.iterator(); iter.hasNext();) {
Object label = iter.next();
CAstNode target = context.getControlFlow().getTarget(n, label);
if (target == CAstControlFlowMap.EXCEPTION_TO_EXIT)
@ -3080,17 +3081,16 @@ public abstract class AstTranslator extends CAstVisitor {
((WalkContext) c).cfg().addInstruction(new EachElementHasNextInstruction(result, getValue(n.getChild(0))));
}
protected boolean visitTypeLiteralExpr(CAstNode n, Context c, CAstVisitor visitor) {
protected boolean visitTypeLiteralExpr(CAstNode n, Context c, CAstVisitor visitor) {
return false;
}
protected void leaveTypeLiteralExpr(CAstNode n, Context c, CAstVisitor visitor) {
WalkContext wc = (WalkContext)c;
WalkContext wc = (WalkContext) c;
Assertions._assert(n.getChild(0).getKind() == CAstNode.CONSTANT);
String typeNameStr = (String) n.getChild(0).getValue();
TypeName typeName = TypeName.string2TypeName(typeNameStr);
TypeReference typeRef =
TypeReference.findOrCreate(loader.getReference(), typeName);
TypeReference typeRef = TypeReference.findOrCreate(loader.getReference(), typeName);
int result = wc.currentScope().allocateTempValue();
setValue(n, result);
@ -3131,7 +3131,7 @@ public abstract class AstTranslator extends CAstVisitor {
return t.globalScope;
}
public Set entityScopes() {
public Set<Scope> entityScopes() {
return Collections.singleton(t.globalScope);
}

View File

@ -11,31 +11,41 @@
package com.ibm.wala.cast.loader;
import com.ibm.wala.cast.tree.*;
import com.ibm.wala.classLoader.*;
import com.ibm.wala.ipa.cha.*;
import com.ibm.wala.shrikeCT.*;
import com.ibm.wala.types.*;
import com.ibm.wala.util.*;
import com.ibm.wala.util.debug.Assertions;
import java.net.URL;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.net.*;
import java.util.*;
import com.ibm.wala.cast.tree.CAstSourcePositionMap;
import com.ibm.wala.classLoader.IClass;
import com.ibm.wala.classLoader.IClassLoader;
import com.ibm.wala.classLoader.IField;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.ipa.cha.ClassHierarchyException;
import com.ibm.wala.shrikeCT.ClassConstants;
import com.ibm.wala.types.MethodReference;
import com.ibm.wala.types.Selector;
import com.ibm.wala.types.TypeName;
import com.ibm.wala.types.TypeReference;
import com.ibm.wala.util.Atom;
import com.ibm.wala.util.debug.Assertions;
abstract public class AstClass implements IClass, ClassConstants {
private final CAstSourcePositionMap.Position sourcePosition;
private final TypeName typeName;
private final IClassLoader loader;
private final short modifiers;
protected final Map declaredFields;
protected final Map declaredMethods;
protected final Map<Atom, IField> declaredFields;
protected final Map<Selector,IMethod> declaredMethods;
protected AstClass(CAstSourcePositionMap.Position sourcePosition,
TypeName typeName,
IClassLoader loader,
short modifiers,
Map declaredFields,
Map declaredMethods)
Map<Atom, IField> declaredFields,
Map<Selector,IMethod> declaredMethods)
{
this.sourcePosition = sourcePosition;
this.typeName = typeName;
@ -95,22 +105,22 @@ abstract public class AstClass implements IClass, ClassConstants {
public abstract IClass getSuperclass() throws ClassHierarchyException;
private Collection gatherInterfaces() throws ClassHierarchyException {
Set result = new HashSet();
private Collection<IClass> gatherInterfaces() throws ClassHierarchyException {
Set<IClass> result = new HashSet<IClass>();
result.addAll( getDirectInterfaces() );
if (getSuperclass() != null)
result.addAll( getSuperclass().getAllImplementedInterfaces() );
return result;
}
public abstract Collection getDirectInterfaces() throws ClassHierarchyException;
public abstract Collection<IClass> getDirectInterfaces() throws ClassHierarchyException;
public Collection getAllImplementedInterfaces() throws ClassHierarchyException {
public Collection<IClass> getAllImplementedInterfaces() throws ClassHierarchyException {
Assertions._assert(! isInterface());
return gatherInterfaces();
}
public Collection getAllAncestorInterfaces() throws ClassHierarchyException {
public Collection<IClass> getAllAncestorInterfaces() throws ClassHierarchyException {
Assertions._assert(isInterface());
return gatherInterfaces();
}
@ -122,7 +132,7 @@ abstract public class AstClass implements IClass, ClassConstants {
public IMethod getMethod(Selector selector) {
try {
if (declaredMethods.containsKey(selector)) {
return (IMethod)declaredMethods.get(selector);
return declaredMethods.get(selector);
} else if (getSuperclass() != null) {
return getSuperclass().getMethod(selector);
} else {
@ -137,7 +147,7 @@ abstract public class AstClass implements IClass, ClassConstants {
public IField getField(Atom name) {
try {
if (declaredFields.containsKey(name)) {
return (IField)declaredFields.get(name);
return declaredFields.get(name);
} else if (getSuperclass() != null) {
return getSuperclass().getField(name);
} else {
@ -153,10 +163,10 @@ abstract public class AstClass implements IClass, ClassConstants {
return declaredMethods.values();
}
public Collection getDeclaredInstanceFields() {
Set result = new HashSet();
for(Iterator FS = declaredFields.values().iterator(); FS.hasNext();) {
IField F = (IField) FS.next();
public Collection<IField> getDeclaredInstanceFields() {
Set<IField> result = new HashSet<IField>();
for(Iterator<IField> FS = declaredFields.values().iterator(); FS.hasNext();) {
IField F = FS.next();
if (! F.isStatic()) {
result.add( F );
}
@ -165,10 +175,10 @@ abstract public class AstClass implements IClass, ClassConstants {
return result;
}
public Collection getDeclaredStaticFields() {
Set result = new HashSet();
for(Iterator FS = declaredFields.values().iterator(); FS.hasNext();) {
IField F = (IField) FS.next();
public Collection<IField> getDeclaredStaticFields() {
Set<IField> result = new HashSet<IField>();
for(Iterator<IField> FS = declaredFields.values().iterator(); FS.hasNext();) {
IField F = FS.next();
if (F.isStatic()) {
result.add( F );
}
@ -177,8 +187,8 @@ abstract public class AstClass implements IClass, ClassConstants {
return result;
}
public Collection getAllInstanceFields() throws ClassHierarchyException {
Collection result = new HashSet();
public Collection<IField> getAllInstanceFields() throws ClassHierarchyException {
Collection<IField> result = new HashSet<IField>();
result.addAll( getDeclaredInstanceFields() );
if (getSuperclass() != null) {
result.addAll( getSuperclass().getAllInstanceFields() );
@ -187,8 +197,8 @@ abstract public class AstClass implements IClass, ClassConstants {
return result;
}
public Collection getAllStaticFields() throws ClassHierarchyException {
Collection result = new HashSet();
public Collection<IField> getAllStaticFields() throws ClassHierarchyException {
Collection<IField> result = new HashSet<IField>();
result.addAll( getDeclaredStaticFields() );
if (getSuperclass() != null) {
result.addAll( getSuperclass().getAllStaticFields() );
@ -197,16 +207,16 @@ abstract public class AstClass implements IClass, ClassConstants {
return result;
}
public Collection getAllFields() throws ClassHierarchyException {
Collection result = new HashSet();
public Collection<IField> getAllFields() throws ClassHierarchyException {
Collection<IField> result = new HashSet<IField>();
result.addAll( getAllInstanceFields() );
result.addAll( getAllStaticFields() );
return result;
}
public Collection getAllMethods() throws ClassHierarchyException {
Collection result = new HashSet();
for(Iterator ms = getDeclaredMethods().iterator(); ms.hasNext(); ) {
public Collection<IMethod> getAllMethods() throws ClassHierarchyException {
Collection<IMethod> result = new HashSet<IMethod>();
for(Iterator<IMethod> ms = getDeclaredMethods().iterator(); ms.hasNext(); ) {
result.add( ms.next() );
}
if (getSuperclass() != null) {

View File

@ -10,7 +10,6 @@
*****************************************************************************/
package com.ibm.wala.cast.loader;
import java.util.HashMap;
import java.util.Map;
@ -18,9 +17,11 @@ import com.ibm.wala.cast.tree.CAstSourcePositionMap;
import com.ibm.wala.classLoader.IClass;
import com.ibm.wala.classLoader.IClassLoader;
import com.ibm.wala.classLoader.IField;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.ipa.cha.ClassHierarchy;
import com.ibm.wala.ipa.cha.ClassHierarchyException;
import com.ibm.wala.types.FieldReference;
import com.ibm.wala.types.Selector;
import com.ibm.wala.types.TypeName;
import com.ibm.wala.types.TypeReference;
import com.ibm.wala.util.Atom;
@ -29,15 +30,16 @@ import com.ibm.wala.util.debug.Assertions;
public abstract class AstDynamicPropertyClass extends AstClass {
private final TypeReference defaultDescriptor;
protected AstDynamicPropertyClass(CAstSourcePositionMap.Position sourcePosition, TypeName typeName, IClassLoader loader, short modifiers, Map declaredMethods, TypeReference defaultDescriptor) {
super(sourcePosition, typeName, loader, modifiers, new HashMap(), declaredMethods);
protected AstDynamicPropertyClass(CAstSourcePositionMap.Position sourcePosition, TypeName typeName, IClassLoader loader,
short modifiers, Map<Selector, IMethod> declaredMethods, TypeReference defaultDescriptor) {
super(sourcePosition, typeName, loader, modifiers, new HashMap<Atom, IField>(), declaredMethods);
this.defaultDescriptor = defaultDescriptor;
}
public IField getField(final Atom name) {
try {
if (declaredFields.containsKey(name)) {
return (IField) declaredFields.get(name);
return declaredFields.get(name);
} else if (getSuperclass() != null) {
return getSuperclass().getField(name);
} else {
@ -88,11 +90,11 @@ public abstract class AstDynamicPropertyClass extends AstClass {
}
public ClassHierarchy getClassHierarchy() {
return AstDynamicPropertyClass.this.getClassHierarchy();
return AstDynamicPropertyClass.this.getClassHierarchy();
}
});
return (IField) declaredFields.get(name);
return declaredFields.get(name);
}
} catch (ClassHierarchyException e) {
Assertions.UNREACHABLE();

View File

@ -81,16 +81,16 @@ abstract public class AstFunctionClass implements IClass, ClassConstants {
return loader.lookupClass(superReference.getName(), getClassHierarchy());
}
public Collection getDirectInterfaces() {
return Collections.EMPTY_SET;
public Collection<IClass> getDirectInterfaces() {
return Collections.emptySet();
}
public Collection getAllImplementedInterfaces() {
return Collections.EMPTY_SET;
public Collection<IClass> getAllImplementedInterfaces() {
return Collections.emptySet();
}
public Collection getAllAncestorInterfaces() {
return Collections.EMPTY_SET;
public Collection<IClass> getAllAncestorInterfaces() {
return Collections.emptySet();
}
public IMethod getMethod(Selector selector) {
@ -137,27 +137,27 @@ abstract public class AstFunctionClass implements IClass, ClassConstants {
}
}
public Collection getDeclaredInstanceFields() {
return Collections.EMPTY_SET;
public Collection<IField> getDeclaredInstanceFields() {
return Collections.emptySet();
}
public Collection getDeclaredStaticFields() {
return Collections.EMPTY_SET;
public Collection<IField> getDeclaredStaticFields() {
return Collections.emptySet();
}
public Collection getAllInstanceFields() {
return Collections.EMPTY_SET;
public Collection<IField> getAllInstanceFields() {
return Collections.emptySet();
}
public Collection getAllStaticFields() {
return Collections.EMPTY_SET;
public Collection<IField> getAllStaticFields() {
return Collections.emptySet();
}
public Collection getAllFields() {
return Collections.EMPTY_SET;
public Collection<IField> getAllFields() {
return Collections.emptySet();
}
public Collection getAllMethods() {
public Collection<IMethod> getAllMethods() {
return Collections.singleton(functionBody);
}

View File

@ -72,5 +72,5 @@ public interface CAstControlFlowMap {
* Returns an iterator of all CAstNodes for which this map contains
* control flow mapping information.
*/
Collection getMappedNodes();
Collection<CAstNode> getMappedNodes();
}

View File

@ -16,7 +16,7 @@ package com.ibm.wala.cast.tree;
import java.util.*;
public class CAstQualifier {
public static final Set/* <CAstQualifier> */sQualifiers = new HashSet();
public static final Set/* <CAstQualifier> */<CAstQualifier>sQualifiers = new HashSet<CAstQualifier>();
public static final CAstQualifier CONST = new CAstQualifier("const");
public static final CAstQualifier STRICTFP = new CAstQualifier("strictfp");

View File

@ -53,6 +53,6 @@ public interface CAstSourcePositionMap {
* Returns an iterator of all CAstNodes for which this map contains
* source mapping information.
*/
Iterator getMappedNodes();
Iterator<CAstNode> getMappedNodes();
}

View File

@ -11,6 +11,7 @@
package com.ibm.wala.cast.tree.impl;
import com.ibm.wala.cast.tree.*;
import com.ibm.wala.classLoader.IField;
import java.util.*;
@ -32,7 +33,7 @@ public class CAstCloner {
}
private CAstNode copyNodes(CAstNode root, Map nodeMap) {
private CAstNode copyNodes(CAstNode root, Map<CAstNode, CAstNode> nodeMap) {
if (root instanceof CAstOperator) {
nodeMap.put(root, root);
return root;
@ -53,12 +54,12 @@ public class CAstCloner {
}
}
private CAstControlFlowMap copyFlow(Map nodeMap, CAstControlFlowMap orig) {
Collection oldSources = orig.getMappedNodes();
private CAstControlFlowMap copyFlow(Map<CAstNode, CAstNode> nodeMap, CAstControlFlowMap orig) {
Collection<CAstNode> oldSources = orig.getMappedNodes();
CAstControlFlowRecorder newMap = new CAstControlFlowRecorder();
for(Iterator NS = nodeMap.keySet().iterator(); NS.hasNext(); ) {
CAstNode old = (CAstNode) NS.next();
CAstNode newNode = (CAstNode) nodeMap.get(old);
for(Iterator<CAstNode> NS = nodeMap.keySet().iterator(); NS.hasNext(); ) {
CAstNode old = NS.next();
CAstNode newNode = nodeMap.get(old);
newMap.map(newNode, newNode);
if (oldSources.contains(old)) {
if (orig.getTarget(old, null) != null) {
@ -70,7 +71,7 @@ public class CAstCloner {
}
}
for(Iterator LS = orig.getTargetLabels(old).iterator(); LS.hasNext(); ) {
for(Iterator<IField> LS = orig.getTargetLabels(old).iterator(); LS.hasNext(); ) {
Object label = LS.next();
CAstNode oldTarget = orig.getTarget(old, label);
if (nodeMap.containsKey(oldTarget)) {
@ -86,15 +87,15 @@ public class CAstCloner {
}
private CAstSourcePositionMap
copySource(Map nodeMap, CAstSourcePositionMap orig)
copySource(Map<CAstNode, CAstNode> nodeMap, CAstSourcePositionMap orig)
{
if (orig == null) {
return null;
} else {
CAstSourcePositionRecorder newMap = new CAstSourcePositionRecorder();
for(Iterator NS = nodeMap.keySet().iterator(); NS.hasNext(); ) {
CAstNode old = (CAstNode) NS.next();
CAstNode newNode = (CAstNode) nodeMap.get(old);
for(Iterator<CAstNode> NS = nodeMap.keySet().iterator(); NS.hasNext(); ) {
CAstNode old = NS.next();
CAstNode newNode = nodeMap.get(old);
if (orig.getPosition(old) != null) {
newMap.setPosition(newNode, orig.getPosition(old));
@ -109,7 +110,7 @@ public class CAstCloner {
final CAstControlFlowMap cfg,
final CAstSourcePositionMap pos)
{
final Map nodes = new HashMap();
final Map<CAstNode, CAstNode> nodes = new HashMap<CAstNode, CAstNode>();
final CAstNode newRoot = copyNodes(root, nodes);
return new Clone() {
private CAstControlFlowMap theCfg = null;

View File

@ -10,21 +10,25 @@
*****************************************************************************/
package com.ibm.wala.cast.tree.impl;
import com.ibm.wala.cast.tree.*;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.io.*;
import java.net.*;
import java.util.*;
import com.ibm.wala.cast.tree.CAstNode;
import com.ibm.wala.cast.tree.CAstSourcePositionMap;
public class CAstSourcePositionRecorder implements CAstSourcePositionMap {
private final HashMap positions = new HashMap();
private final HashMap<CAstNode, Position> positions = new HashMap<CAstNode, Position>();
public Position getPosition(CAstNode n) {
return (Position) positions.get(n);
return positions.get(n);
}
public Iterator getMappedNodes() {
public Iterator<CAstNode> getMappedNodes() {
return positions.keySet().iterator();
}
@ -79,8 +83,8 @@ public class CAstSourcePositionRecorder implements CAstSourcePositionMap {
}
public void addAll(CAstSourcePositionMap other) {
for(Iterator nodes = other.getMappedNodes(); nodes.hasNext(); ) {
CAstNode node = (CAstNode) nodes.next();
for(Iterator<CAstNode> nodes = other.getMappedNodes(); nodes.hasNext(); ) {
CAstNode node = nodes.next();
setPosition(node, other.getPosition(node));
}
}

View File

@ -18,10 +18,10 @@ import com.ibm.wala.cast.tree.*;
import java.util.*;
public class CAstTypeDictionaryImpl implements CAstTypeDictionary {
private final Map/*<ASTType,CAstType>*/ fMap= new HashMap();
private final Map/*<ASTType,CAstType>*/<Object, CAstType> fMap= new HashMap<Object, CAstType>();
public CAstType getCAstTypeFor(Object/*ASTType*/ astType) {
return (CAstType) fMap.get(astType);
return fMap.get(astType);
}
public void map(Object/*ASTType*/ astType, CAstType castType) {

View File

@ -68,7 +68,7 @@ public abstract class CAstVisitor {
*/
protected Context makeUnwindContext(Context context, CAstNode n, CAstVisitor visitor) { return context; }
private final Map entityParents = new HashMap();
private final Map<CAstEntity, CAstEntity> entityParents = new HashMap<CAstEntity, CAstEntity>();
/**
* Get the parent entity for a given entity.
@ -76,7 +76,7 @@ public abstract class CAstVisitor {
* @return the parent entity for the given entity
*/
protected CAstEntity getParent(CAstEntity entity) {
return (CAstEntity) entityParents.get(entity);
return entityParents.get(entity);
}
/**

View File

@ -22,11 +22,11 @@ public class CAstFunctions {
if (f.accepts(tree)) {
return tree;
} else {
for(int i = 0; i < tree.getChildCount(); i++) {
CAstNode result = findIf(tree.getChild(i), f);
if (result != null) {
return result;
}
for (int i = 0; i < tree.getChildCount(); i++) {
CAstNode result = findIf(tree.getChild(i), f);
if (result != null) {
return result;
}
}
}
@ -36,36 +36,36 @@ public class CAstFunctions {
public static Iterator iterateNodes(final CAstNode tree) {
return new DFSDiscoverTimeIterator() {
private final Map pendingChildren = new HashMap();
private final Map<Object, Iterator> pendingChildren = new HashMap<Object, Iterator>();
protected Iterator getPendingChildren(Object n) {
return (Iterator) pendingChildren.get(n);
return pendingChildren.get(n);
}
protected void setPendingChildren(Object v, Iterator iterator) {
pendingChildren.put(v, iterator);
pendingChildren.put(v, iterator);
}
protected Iterator getConnected(final Object n) {
return new Iterator() {
private int i = 0;
return new Iterator() {
private int i = 0;
public boolean hasNext() {
return i < ((CAstNode)n).getChildCount();
}
public boolean hasNext() {
return i < ((CAstNode) n).getChildCount();
}
public Object next() {
return ((CAstNode)n).getChild(i++);
}
public Object next() {
return ((CAstNode) n).getChild(i++);
}
public void remove() {
throw new UnsupportedOperationException();
}
};
public void remove() {
throw new UnsupportedOperationException();
}
};
}
{
init(tree);
init(tree);
}
};
}
@ -73,5 +73,5 @@ public class CAstFunctions {
public static Iterator findAll(CAstNode tree, Filter f) {
return new FilterIterator(iterateNodes(tree), f);
}
}

View File

@ -25,13 +25,19 @@ import com.ibm.wala.util.debug.Trace;
public class CAstPattern {
private static boolean DEBUG_PARSER = false;
private static boolean DEBUG_MATCH = false;
private final static int CHILD_KIND = -1;
private final static int CHILDREN_KIND = -2;
private final static int REPEATED_PATTERN_KIND = -3;
private final static int ALTERNATIVE_PATTERN_KIND = -4;
private final static int OPTIONAL_PATTERN_KIND = -5;
private final static int REFERENCE_PATTERN_KIND = -6;
private final static int IGNORE_KIND = -99;
@ -39,61 +45,62 @@ public class CAstPattern {
private final String name;
private final int kind;
private final String value;
private final CAstPattern[] children;
private final Map references;
public static class Segments extends TreeMap {
private final String value;
private final CAstPattern[] children;
private final Map<String, CAstPattern> references;
public static class Segments extends TreeMap<String,Object> {
public CAstNode getSingle(String name) {
Assertions._assert(containsKey(name), name);
return (CAstNode) get(name);
}
public List getMultiple(String name) {
if (! containsKey(name)) {
return Collections.EMPTY_LIST;
public List<Object> getMultiple(String name) {
if (!containsKey(name)) {
return Collections.emptyList();
} else {
Object o = get(name);
if (o instanceof CAstNode) {
return Collections.singletonList(o);
} else {
Assertions._assert(o instanceof List);
return (List)o;
}
Object o = get(name);
if (o instanceof CAstNode) {
return Collections.singletonList(o);
} else {
Assertions._assert(o instanceof List);
return (List<Object>) o;
}
}
}
private void addAll(Segments other) {
for(Iterator xs = other.entrySet().iterator(); xs.hasNext(); ) {
Map.Entry e = (Map.Entry) xs.next();
String name = (String)e.getKey();
if (e.getValue() instanceof CAstNode) {
add(name, (CAstNode) e.getValue());
} else {
for(Iterator vs = ((List)e.getValue()).iterator();
vs.hasNext(); )
{
add(name, (CAstNode) vs.next());
}
}
for (Iterator xs = other.entrySet().iterator(); xs.hasNext();) {
Map.Entry e = (Map.Entry) xs.next();
String name = (String) e.getKey();
if (e.getValue() instanceof CAstNode) {
add(name, (CAstNode) e.getValue());
} else {
for (Iterator vs = ((List) e.getValue()).iterator(); vs.hasNext();) {
add(name, (CAstNode) vs.next());
}
}
}
}
private void add(String name, CAstNode result) {
if (containsKey(name)) {
Object o = get(name);
if (o instanceof List) {
((List)o).add(result);
} else {
Assertions._assert(o instanceof CAstNode);
List x = new ArrayList();
x.add(o);
x.add(result);
put(name, x);
}
Object o = get(name);
if (o instanceof List) {
((List<CAstNode>) o).add(result);
} else {
Assertions._assert(o instanceof CAstNode);
List<Object> x = new ArrayList<Object>();
x.add(o);
x.add(result);
put(name, x);
}
} else {
put(name, result);
put(name, result);
}
}
}
@ -114,7 +121,7 @@ public class CAstPattern {
this.references = null;
}
public CAstPattern(String patternName, Map references) {
public CAstPattern(String patternName, Map<String, CAstPattern> references) {
this.name = null;
this.kind = REFERENCE_PATTERN_KIND;
this.value = patternName;
@ -133,7 +140,7 @@ public class CAstPattern {
if (kind == REFERENCE_PATTERN_KIND) {
sb.append("ref:").append(value);
} else {
sb.append("literal:").append(value);
sb.append("literal:").append(value);
}
} else if (kind == CHILD_KIND) {
sb.append("*");
@ -151,22 +158,20 @@ public class CAstPattern {
if (children != null) {
sb.append("(");
for(int i = 0; i < children.length; i++) {
sb.append( children[i].toString() );
if (i == children.length-1) {
sb.append(")");
} else {
sb.append(",");
}
for (int i = 0; i < children.length; i++) {
sb.append(children[i].toString());
if (i == children.length - 1) {
sb.append(")");
} else {
sb.append(",");
}
}
}
return sb.toString();
}
private static boolean
matchChildren(CAstNode tree, int i, CAstPattern[] cs, int j, Segments s)
{
private static boolean matchChildren(CAstNode tree, int i, CAstPattern[] cs, int j, Segments s) {
if (i >= tree.getChildCount() && j >= cs.length) {
return true;
} else if (i < tree.getChildCount() && j >= cs.length) {
@ -176,160 +181,151 @@ public class CAstPattern {
case CHILDREN_KIND:
case OPTIONAL_PATTERN_KIND:
case REPEATED_PATTERN_KIND:
return matchChildren(tree, i, cs, j+1, s);
return matchChildren(tree, i, cs, j + 1, s);
default:
return false;
return false;
}
} else {
if (cs[j].kind == CHILD_KIND) {
if (DEBUG_MATCH) {
Trace.println("* matches "+CAstPrinter.print(tree.getChild(i)));
}
if (DEBUG_MATCH) {
Trace.println("* matches " + CAstPrinter.print(tree.getChild(i)));
}
if (s != null && cs[j].name != null) {
s.add(cs[j].name, tree.getChild(i));
}
return matchChildren(tree, i+1, cs, j+1, s);
if (s != null && cs[j].name != null) {
s.add(cs[j].name, tree.getChild(i));
}
return matchChildren(tree, i + 1, cs, j + 1, s);
} else if (cs[j].kind == CHILDREN_KIND) {
if (tryMatchChildren(tree, i, cs, j+1, s)) {
if (tryMatchChildren(tree, i, cs, j + 1, s)) {
if (DEBUG_MATCH) {
Trace.println("** matches nothing");
}
if (DEBUG_MATCH) {
Trace.println("** matches nothing");
}
return true;
return true;
} else {
} else {
if (DEBUG_MATCH) {
Trace.println(
"** matches " + CAstPrinter.print(tree.getChild(i)));
}
if (DEBUG_MATCH) {
Trace.println("** matches " + CAstPrinter.print(tree.getChild(i)));
}
if (s != null && cs[j].name != null) {
s.add(cs[j].name, tree.getChild(i) );
}
if (s != null && cs[j].name != null) {
s.add(cs[j].name, tree.getChild(i));
}
return matchChildren(tree, i+1, cs, j, s);
}
return matchChildren(tree, i + 1, cs, j, s);
}
} else if (cs[j].kind == REPEATED_PATTERN_KIND) {
CAstPattern repeatedPattern = cs[j].children[0];
if (repeatedPattern.tryMatch(tree.getChild(i), s)) {
if (s != null && cs[j].name != null) {
s.add(cs[j].name, tree.getChild(i) );
}
CAstPattern repeatedPattern = cs[j].children[0];
if (repeatedPattern.tryMatch(tree.getChild(i), s)) {
if (s != null && cs[j].name != null) {
s.add(cs[j].name, tree.getChild(i));
}
if (DEBUG_MATCH) {
Trace.println(
cs[j] + " matches " + CAstPrinter.print(tree.getChild(i)));
}
if (DEBUG_MATCH) {
Trace.println(cs[j] + " matches " + CAstPrinter.print(tree.getChild(i)));
}
return matchChildren(tree, i+1, cs, j, s);
return matchChildren(tree, i + 1, cs, j, s);
} else {
} else {
if (DEBUG_MATCH) {
Trace.println(cs[j] + " matches nothing");
}
if (DEBUG_MATCH) {
Trace.println(cs[j] + " matches nothing");
}
return matchChildren(tree, i, cs, j+1, s);
}
return matchChildren(tree, i, cs, j + 1, s);
}
} else if (cs[j].kind == OPTIONAL_PATTERN_KIND) {
if (tryMatchChildren(tree, i, cs, j+1, s)) {
if (tryMatchChildren(tree, i, cs, j + 1, s)) {
if (DEBUG_MATCH) {
Trace.println(cs[j] + " matches nothing");
}
if (DEBUG_MATCH) {
Trace.println(cs[j] + " matches nothing");
}
return true;
} else {
CAstPattern optionalPattern = cs[j].children[0];
if (optionalPattern.tryMatch(tree.getChild(i), s)) {
return true;
} else {
CAstPattern optionalPattern = cs[j].children[0];
if (optionalPattern.tryMatch(tree.getChild(i), s)) {
if (DEBUG_MATCH) {
Trace.println(
cs[j] + " matches " + CAstPrinter.print(tree.getChild(i)));
}
if (DEBUG_MATCH) {
Trace.println(cs[j] + " matches " + CAstPrinter.print(tree.getChild(i)));
}
return matchChildren(tree, i+1, cs, j+1, s);
} else {
return false;
}
}
return matchChildren(tree, i + 1, cs, j + 1, s);
} else {
return false;
}
}
} else {
return
cs[j].match(tree.getChild(i), s)
&&
matchChildren(tree, i+1, cs, j+1, s);
return cs[j].match(tree.getChild(i), s) && matchChildren(tree, i + 1, cs, j + 1, s);
}
}
}
public boolean match(CAstNode tree, Segments s) {
if (DEBUG_MATCH) {
Trace.println("matching "+this+" against "+CAstPrinter.print(tree));
Trace.println("matching " + this + " against " + CAstPrinter.print(tree));
}
if (kind == REFERENCE_PATTERN_KIND) {
return ((CAstPattern)references.get(value)).match(tree, s);
return references.get(value).match(tree, s);
} else if (kind == ALTERNATIVE_PATTERN_KIND) {
for(int i = 0; i < children.length; i++) {
if (children[i].tryMatch(tree, s)) {
for (int i = 0; i < children.length; i++) {
if (children[i].tryMatch(tree, s)) {
if (s != null && name != null) s.add(name, tree);
return true;
}
if (s != null && name != null)
s.add(name, tree);
return true;
}
}
if (DEBUG_MATCH) {
Trace.println("match failed (a)");
Trace.println("match failed (a)");
}
return false;
} else {
if ( (value == null)?
tree.getKind() != kind:
( tree.getKind()!=CAstNode.CONSTANT
||
!value.equals(tree.getValue().toString()) ) )
{
if (DEBUG_MATCH) {
Trace.println("match failed (b)");
}
if ((value == null) ? tree.getKind() != kind : (tree.getKind() != CAstNode.CONSTANT || !value.equals(tree.getValue()
.toString()))) {
if (DEBUG_MATCH) {
Trace.println("match failed (b)");
}
return false;
return false;
}
if (s != null && name != null) s.add(name, tree);
if (s != null && name != null)
s.add(name, tree);
if (children == null || children.length == 0) {
if (DEBUG_MATCH && tree.getChildCount() != 0) {
Trace.println("match failed (c)");
}
return tree.getChildCount() == 0;
if (DEBUG_MATCH && tree.getChildCount() != 0) {
Trace.println("match failed (c)");
}
return tree.getChildCount() == 0;
} else {
return matchChildren(tree, 0, children, 0, s);
return matchChildren(tree, 0, children, 0, s);
}
}
}
private static boolean
tryMatchChildren(CAstNode tree, int i, CAstPattern[] cs, int j, Segments s)
{
private static boolean tryMatchChildren(CAstNode tree, int i, CAstPattern[] cs, int j, Segments s) {
if (s == null) {
return matchChildren(tree, i, cs, j, s);
} else {
Segments ss = new Segments();
boolean result = matchChildren(tree, i, cs, j, ss);
if (result) s.addAll(ss);
if (result)
s.addAll(ss);
return result;
}
}
@ -340,7 +336,8 @@ public class CAstPattern {
} else {
Segments ss = new Segments();
boolean result = match(tree, ss);
if (result) s.addAll(ss);
if (result)
s.addAll(ss);
return result;
}
}
@ -367,36 +364,37 @@ public class CAstPattern {
}
private static class Parser {
private final Map namedPatterns = new HashMap();
private final Map<String, CAstPattern> namedPatterns = new HashMap<String, CAstPattern>();
private final String patternString;
private int start;
private int end;
private Parser(String patternString) {
this.patternString = patternString;
}
// private Parser(String patternString, int start) {
// this(patternString);
// this.start = start;
// }
// private Parser(String patternString, int start) {
// this(patternString);
// this.start = start;
// }
private String parseName(boolean internal) {
if (patternString.charAt(start) == (internal?'{':'<')) {
int nameStart = start+1;
int nameEnd = patternString.indexOf(internal?'}':'>', nameStart);
start = nameEnd + 1;
return patternString.substring(nameStart, nameEnd);
if (patternString.charAt(start) == (internal ? '{' : '<')) {
int nameStart = start + 1;
int nameEnd = patternString.indexOf(internal ? '}' : '>', nameStart);
start = nameEnd + 1;
return patternString.substring(nameStart, nameEnd);
} else {
return null;
return null;
}
}
public CAstPattern parse()
throws NoSuchFieldException, IllegalAccessException
{
public CAstPattern parse() throws NoSuchFieldException, IllegalAccessException {
if (DEBUG_PARSER) {
Trace.println("parsing " + patternString.substring(start));
Trace.println("parsing " + patternString.substring(start));
}
String internalName = parseName(true);
@ -404,103 +402,92 @@ public class CAstPattern {
CAstPattern result;
if (patternString.charAt(start) == '`') {
int strEnd = patternString.indexOf('`', start+1);
end = strEnd+1;
String patternName = patternString.substring(start+1, strEnd);
Assertions._assert(internalName == null);
result = new CAstPattern(patternName, namedPatterns);
int strEnd = patternString.indexOf('`', start + 1);
end = strEnd + 1;
String patternName = patternString.substring(start + 1, strEnd);
Assertions._assert(internalName == null);
result = new CAstPattern(patternName, namedPatterns);
} else if (patternString.charAt(start) == '"') {
int strEnd = patternString.indexOf('"', start+1);
end = strEnd+1;
result =
new CAstPattern(
name,
patternString.substring(start+1, strEnd));
int strEnd = patternString.indexOf('"', start + 1);
end = strEnd + 1;
result = new CAstPattern(name, patternString.substring(start + 1, strEnd));
} else if (patternString.startsWith("**", start)) {
end = start+2;
result = new CAstPattern(name, CHILDREN_KIND, null);
end = start + 2;
result = new CAstPattern(name, CHILDREN_KIND, null);
} else if (patternString.startsWith("*", start)) {
end = start+1;
result = new CAstPattern(name, CHILD_KIND, null);
end = start + 1;
result = new CAstPattern(name, CHILD_KIND, null);
} else if (patternString.startsWith("|(", start)) {
List alternatives = new ArrayList();
start += 2;
do {
alternatives.add( parse() );
start = end+2;
} while (patternString.startsWith("||", end));
Assertions._assert(patternString.startsWith(")|", end), patternString);
end += 2;
result = new CAstPattern(name,
ALTERNATIVE_PATTERN_KIND,
(CAstPattern[])
alternatives.toArray(new CAstPattern[alternatives.size()]));
List<CAstPattern> alternatives = new ArrayList<CAstPattern>();
start += 2;
do {
alternatives.add(parse());
start = end + 2;
} while (patternString.startsWith("||", end));
Assertions._assert(patternString.startsWith(")|", end), patternString);
end += 2;
result = new CAstPattern(name, ALTERNATIVE_PATTERN_KIND, alternatives.toArray(new CAstPattern[alternatives.size()]));
} else if (patternString.startsWith("@(", start)) {
start += 2;
CAstPattern children[] = new CAstPattern[]{ parse() };
Assertions._assert( patternString.startsWith(")@", end) );
end += 2;
start += 2;
CAstPattern children[] = new CAstPattern[] { parse() };
Assertions._assert(patternString.startsWith(")@", end));
end += 2;
if (DEBUG_PARSER) {
Trace.println("repeated pattern: " + children[0]);
}
if (DEBUG_PARSER) {
Trace.println("repeated pattern: " + children[0]);
}
result = new CAstPattern(name, REPEATED_PATTERN_KIND, children);
result = new CAstPattern(name, REPEATED_PATTERN_KIND, children);
} else if (patternString.startsWith("?(", start)) {
start += 2;
CAstPattern children[] = new CAstPattern[]{ parse() };
Assertions._assert( patternString.startsWith(")?", end) );
end += 2;
start += 2;
CAstPattern children[] = new CAstPattern[] { parse() };
Assertions._assert(patternString.startsWith(")?", end));
end += 2;
if (DEBUG_PARSER) {
Trace.println("optional pattern: " + children[0]);
}
if (DEBUG_PARSER) {
Trace.println("optional pattern: " + children[0]);
}
result = new CAstPattern(name, OPTIONAL_PATTERN_KIND, children);
result = new CAstPattern(name, OPTIONAL_PATTERN_KIND, children);
} else {
int kindEnd = patternString.indexOf('(', start);
String kindStr = patternString.substring(start, kindEnd);
Field kindField = CAstNode.class.getField(kindStr);
int kind = kindField.getInt(null);
int kindEnd = patternString.indexOf('(', start);
String kindStr = patternString.substring(start, kindEnd);
Field kindField = CAstNode.class.getField(kindStr);
int kind = kindField.getInt(null);
if (patternString.charAt(kindEnd+1) == ')') {
end = kindEnd+2;
result = new CAstPattern(name, kind, null);
} else {
List children = new ArrayList();
start = patternString.indexOf('(', start) + 1;
do {
children.add( parse() );
start = end+1;
if (DEBUG_PARSER) {
Trace.println(
"parsing children: " + patternString.substring(end));
}
} while (patternString.charAt(end) == ',');
Assertions._assert(patternString.charAt(end) == ')');
end++;
if (patternString.charAt(kindEnd + 1) == ')') {
end = kindEnd + 2;
result = new CAstPattern(name, kind, null);
result = new CAstPattern(
name,
kind,
(CAstPattern[])
children.toArray(new CAstPattern[children.size()]));
}
} else {
List<CAstPattern> children = new ArrayList<CAstPattern>();
start = patternString.indexOf('(', start) + 1;
do {
children.add(parse());
start = end + 1;
if (DEBUG_PARSER) {
Trace.println("parsing children: " + patternString.substring(end));
}
} while (patternString.charAt(end) == ',');
Assertions._assert(patternString.charAt(end) == ')');
end++;
result = new CAstPattern(name, kind, children.toArray(new CAstPattern[children.size()]));
}
}
if (internalName != null) {
namedPatterns.put(internalName, result);
namedPatterns.put(internalName, result);
}
return result;