change ControlFlowGraph.getExceptionalSuccessors to return a List, in order of increasing catch scope
git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@1822 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
parent
516adf98aa
commit
d445f0861a
|
@ -10,9 +10,11 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package com.ibm.wala.cfg;
|
package com.ibm.wala.cfg;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import com.ibm.wala.classLoader.IMethod;
|
import com.ibm.wala.classLoader.IMethod;
|
||||||
import com.ibm.wala.shrikeBT.Constants;
|
import com.ibm.wala.shrikeBT.Constants;
|
||||||
|
@ -35,6 +37,8 @@ import com.ibm.wala.util.intset.BitVector;
|
||||||
import com.ibm.wala.util.intset.FixedSizeBitVector;
|
import com.ibm.wala.util.intset.FixedSizeBitVector;
|
||||||
import com.ibm.wala.util.intset.IntSet;
|
import com.ibm.wala.util.intset.IntSet;
|
||||||
import com.ibm.wala.util.intset.MutableSparseIntSet;
|
import com.ibm.wala.util.intset.MutableSparseIntSet;
|
||||||
|
import com.ibm.wala.util.intset.SimpleIntVector;
|
||||||
|
import com.ibm.wala.util.intset.SimpleVector;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -63,8 +67,16 @@ public abstract class AbstractCFG<T extends IBasicBlock> implements ControlFlowG
|
||||||
/**
|
/**
|
||||||
* An object to track not-to-exit exceptional edges in this cfg
|
* An object to track not-to-exit exceptional edges in this cfg
|
||||||
*/
|
*/
|
||||||
final private SparseNumberedEdgeManager<T> exceptionalEdgeManager = new SparseNumberedEdgeManager<T>(nodeManager,
|
final private SparseNumberedEdgeManager<T> exceptionalEdgeManager = new SparseNumberedEdgeManager<T>(nodeManager, 0,
|
||||||
0, BasicNaturalRelation.SIMPLE);
|
BasicNaturalRelation.SIMPLE);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An object to track not-to-exit exceptional edges in this cfg, indexed by
|
||||||
|
* block number. exceptionalEdges[i] is a list of block numbers that are
|
||||||
|
* non-exit exceptional successors of block i, in order of increasing "catch
|
||||||
|
* scope".
|
||||||
|
*/
|
||||||
|
final private SimpleVector<SimpleIntVector> exceptionalSuccessors = new SimpleVector<SimpleIntVector>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Which basic blocks have a normal edge to exit()?
|
* Which basic blocks have a normal edge to exit()?
|
||||||
|
@ -316,13 +328,23 @@ public abstract class AbstractCFG<T extends IBasicBlock> implements ControlFlowG
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param number
|
||||||
|
* of a basic block
|
||||||
|
* @return the exceptional successors of the basic block, in order of
|
||||||
|
* increasing catch scope.
|
||||||
|
*/
|
||||||
private Iterator<T> iterateExceptionalSuccessors(int number) {
|
private Iterator<T> iterateExceptionalSuccessors(int number) {
|
||||||
if (exceptionalEdgeManager.hasAnySuccessor(number)) {
|
if (exceptionalEdgeManager.hasAnySuccessor(number)) {
|
||||||
if (exceptionalToExit.get(number)) {
|
List<T> result = new ArrayList<T>();
|
||||||
return IteratorPlusOne.make(exceptionalEdgeManager.getSuccNodes(number), exit());
|
SimpleIntVector v = exceptionalSuccessors.get(number);
|
||||||
} else {
|
for (int i = 0; i <= v.getMaxIndex(); i++) {
|
||||||
return exceptionalEdgeManager.getSuccNodes(number);
|
result.add(getNode(v.get(i)));
|
||||||
}
|
}
|
||||||
|
if (exceptionalToExit.get(number)) {
|
||||||
|
result.add(exit);
|
||||||
|
}
|
||||||
|
return result.iterator();
|
||||||
} else {
|
} else {
|
||||||
if (exceptionalToExit.get(number)) {
|
if (exceptionalToExit.get(number)) {
|
||||||
return new NonNullSingletonIterator<T>(exit());
|
return new NonNullSingletonIterator<T>(exit());
|
||||||
|
@ -479,8 +501,6 @@ public abstract class AbstractCFG<T extends IBasicBlock> implements ControlFlowG
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param src
|
|
||||||
* @param dst
|
|
||||||
* @throws IllegalArgumentException
|
* @throws IllegalArgumentException
|
||||||
* if dst is null
|
* if dst is null
|
||||||
*/
|
*/
|
||||||
|
@ -492,6 +512,12 @@ public abstract class AbstractCFG<T extends IBasicBlock> implements ControlFlowG
|
||||||
exceptionalToExit.set(getNumber(src));
|
exceptionalToExit.set(getNumber(src));
|
||||||
} else {
|
} else {
|
||||||
exceptionalEdgeManager.addEdge(src, dst);
|
exceptionalEdgeManager.addEdge(src, dst);
|
||||||
|
SimpleIntVector v = exceptionalSuccessors.get(getNumber(src));
|
||||||
|
if (v == null) {
|
||||||
|
v = new SimpleIntVector(-1);
|
||||||
|
exceptionalSuccessors.set(getNumber(src), v);
|
||||||
|
}
|
||||||
|
v.set(v.getMaxIndex() + 1, getNumber(dst));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -574,11 +600,15 @@ public abstract class AbstractCFG<T extends IBasicBlock> implements ControlFlowG
|
||||||
/*
|
/*
|
||||||
* @see com.ibm.wala.cfg.ControlFlowGraph#getExceptionalSuccessors(com.ibm.wala.cfg.T)
|
* @see com.ibm.wala.cfg.ControlFlowGraph#getExceptionalSuccessors(com.ibm.wala.cfg.T)
|
||||||
*/
|
*/
|
||||||
public Collection<T> getExceptionalSuccessors(T b) {
|
public List<T> getExceptionalSuccessors(T b) {
|
||||||
if (b == null) {
|
if (b == null) {
|
||||||
throw new IllegalArgumentException("b is null");
|
throw new IllegalArgumentException("b is null");
|
||||||
}
|
}
|
||||||
return Iterator2Collection.toCollection(iterateExceptionalSuccessors(b.getNumber()));
|
List<T> result = new ArrayList<T>();
|
||||||
|
for (Iterator<T> it = iterateExceptionalSuccessors(b.getNumber()); it.hasNext();) {
|
||||||
|
result.add(it.next());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
package com.ibm.wala.cfg;
|
package com.ibm.wala.cfg;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import com.ibm.wala.classLoader.IMethod;
|
import com.ibm.wala.classLoader.IMethod;
|
||||||
import com.ibm.wala.shrikeBT.IInstruction;
|
import com.ibm.wala.shrikeBT.IInstruction;
|
||||||
|
@ -66,13 +67,15 @@ public interface ControlFlowGraph<T extends IBasicBlock> extends NumberedGraph<T
|
||||||
public IMethod getMethod();
|
public IMethod getMethod();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The order of blocks returned should be arbitrary but deterministic.
|
* The order of blocks returned must indicate the exception-handling scope.
|
||||||
|
* So the first block is the first candidate catch block, and so on.
|
||||||
|
* With this invariant one can compute the exceptional control flow for
|
||||||
|
* a given exception type.
|
||||||
*
|
*
|
||||||
* @param b
|
|
||||||
* @return the basic blocks which may be reached from b via exceptional
|
* @return the basic blocks which may be reached from b via exceptional
|
||||||
* control flow
|
* control flow
|
||||||
*/
|
*/
|
||||||
public Collection<T> getExceptionalSuccessors(T b);
|
public List<T> getExceptionalSuccessors(T b);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The order of blocks returned should be arbitrary but deterministic.
|
* The order of blocks returned should be arbitrary but deterministic.
|
||||||
|
|
|
@ -351,23 +351,17 @@ public class InducedCFG extends AbstractCFG<InducedCFG.BasicBlock> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param b
|
|
||||||
*/
|
|
||||||
private void addNormalEdgeTo(BasicBlock b) {
|
private void addNormalEdgeTo(BasicBlock b) {
|
||||||
addNormalEdge(this, b);
|
addNormalEdge(this, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param b
|
|
||||||
*/
|
|
||||||
private void addExceptionalEdgeTo(BasicBlock b) {
|
private void addExceptionalEdgeTo(BasicBlock b) {
|
||||||
addExceptionalEdge(this, b);
|
addExceptionalEdge(this, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method computeOutgoingEdges.
|
|
||||||
*/
|
|
||||||
private void computeOutgoingEdges() {
|
private void computeOutgoingEdges() {
|
||||||
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
|
|
|
@ -226,9 +226,6 @@ public class ShrikeCFG extends AbstractCFG<ShrikeCFG.BasicBlock> {
|
||||||
return ShrikeCFG.this.isCatchBlock(getNumber());
|
return ShrikeCFG.this.isCatchBlock(getNumber());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method computeOutgoingEdges.
|
|
||||||
*/
|
|
||||||
private void computeOutgoingEdges() {
|
private void computeOutgoingEdges() {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Trace.println("Block " + this + ": computeOutgoingEdges()");
|
Trace.println("Block " + this + ": computeOutgoingEdges()");
|
||||||
|
@ -377,38 +374,16 @@ public class ShrikeCFG extends AbstractCFG<ShrikeCFG.BasicBlock> {
|
||||||
return hs;
|
return hs;
|
||||||
}
|
}
|
||||||
|
|
||||||
// /**
|
|
||||||
// * @return true iff exception extends RuntimeException or Error
|
|
||||||
// */
|
|
||||||
// private boolean isUndeclaredType(IClass exception) {
|
|
||||||
// IClass re = cha.lookupClass(TypeReference.JavaLangRuntimeException);
|
|
||||||
// IClass error = cha.lookupClass(TypeReference.JavaLangError);
|
|
||||||
// boolean result = cha.isSubclassOf(exception, re) ||
|
|
||||||
// cha.isSubclassOf(exception, error);
|
|
||||||
// return result;
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param b
|
|
||||||
*/
|
|
||||||
private void addNormalEdgeTo(BasicBlock b) {
|
private void addNormalEdgeTo(BasicBlock b) {
|
||||||
addNormalEdge(this, b);
|
addNormalEdge(this, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param b
|
|
||||||
*/
|
|
||||||
private void addExceptionalEdgeTo(BasicBlock b) {
|
private void addExceptionalEdgeTo(BasicBlock b) {
|
||||||
addExceptionalEdge(this, b);
|
addExceptionalEdge(this, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method getLastInstructionIndex.
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public int getLastInstructionIndex() {
|
|
||||||
|
|
||||||
|
public int getLastInstructionIndex() {
|
||||||
if (this == entry() || this == exit()) {
|
if (this == entry() || this == exit()) {
|
||||||
// these are the special end blocks
|
// these are the special end blocks
|
||||||
return -2;
|
return -2;
|
||||||
|
@ -422,16 +397,10 @@ public class ShrikeCFG extends AbstractCFG<ShrikeCFG.BasicBlock> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method getFirstInstructionIndex.
|
|
||||||
*/
|
|
||||||
public int getFirstInstructionIndex() {
|
public int getFirstInstructionIndex() {
|
||||||
return startIndex;
|
return startIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see java.lang.Object#toString()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "BB[Shrike]" + getNumber() + " - " + method.getDeclaringClass().getReference().getName() + "." + method.getName();
|
return "BB[Shrike]" + getNumber() + " - " + method.getDeclaringClass().getReference().getName() + "." + method.getName();
|
||||||
|
@ -481,9 +450,6 @@ public class ShrikeCFG extends AbstractCFG<ShrikeCFG.BasicBlock> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see java.lang.Object#toString()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuffer s = new StringBuffer("");
|
StringBuffer s = new StringBuffer("");
|
||||||
|
@ -502,29 +468,17 @@ public class ShrikeCFG extends AbstractCFG<ShrikeCFG.BasicBlock> {
|
||||||
return s.toString();
|
return s.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method getMaxStackHeight.
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public int getMaxStackHeight() {
|
public int getMaxStackHeight() {
|
||||||
return method.getMaxStackHeight();
|
return method.getMaxStackHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method getMaxLocals
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public int getMaxLocals() {
|
public int getMaxLocals() {
|
||||||
return method.getMaxLocals();
|
return method.getMaxLocals();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the exceptionHandlers.
|
|
||||||
*
|
|
||||||
* @return Set
|
|
||||||
*/
|
|
||||||
public Set<ExceptionHandler> getExceptionHandlers() {
|
public Set<ExceptionHandler> getExceptionHandlers() {
|
||||||
return exceptionHandlers;
|
return exceptionHandlers;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,10 +10,11 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package com.ibm.wala.cfg;
|
package com.ibm.wala.cfg;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import com.ibm.wala.classLoader.IMethod;
|
import com.ibm.wala.classLoader.IMethod;
|
||||||
import com.ibm.wala.shrikeBT.IInstruction;
|
import com.ibm.wala.shrikeBT.IInstruction;
|
||||||
|
@ -24,7 +25,6 @@ import com.ibm.wala.ssa.SSAPiInstruction;
|
||||||
import com.ibm.wala.ssa.SSAThrowInstruction;
|
import com.ibm.wala.ssa.SSAThrowInstruction;
|
||||||
import com.ibm.wala.util.IteratorPlusOne;
|
import com.ibm.wala.util.IteratorPlusOne;
|
||||||
import com.ibm.wala.util.collections.EmptyIterator;
|
import com.ibm.wala.util.collections.EmptyIterator;
|
||||||
import com.ibm.wala.util.collections.HashSetFactory;
|
|
||||||
import com.ibm.wala.util.debug.Assertions;
|
import com.ibm.wala.util.debug.Assertions;
|
||||||
import com.ibm.wala.util.debug.Trace;
|
import com.ibm.wala.util.debug.Trace;
|
||||||
import com.ibm.wala.util.debug.UnimplementedError;
|
import com.ibm.wala.util.debug.UnimplementedError;
|
||||||
|
@ -477,14 +477,14 @@ public class TwoExitCFG implements ControlFlowGraph<ISSABasicBlock> {
|
||||||
/*
|
/*
|
||||||
* @see com.ibm.wala.cfg.ControlFlowGraph#getExceptionalSuccessors(com.ibm.wala.cfg.ISSABasicBlock)
|
* @see com.ibm.wala.cfg.ControlFlowGraph#getExceptionalSuccessors(com.ibm.wala.cfg.ISSABasicBlock)
|
||||||
*/
|
*/
|
||||||
public Collection<ISSABasicBlock> getExceptionalSuccessors(ISSABasicBlock b) {
|
public List<ISSABasicBlock> getExceptionalSuccessors(ISSABasicBlock b) {
|
||||||
if (b == null) {
|
if (b == null) {
|
||||||
throw new IllegalArgumentException("b is null");
|
throw new IllegalArgumentException("b is null");
|
||||||
}
|
}
|
||||||
if (b.equals(exceptionalExit)) {
|
if (b.equals(exceptionalExit)) {
|
||||||
return Collections.emptySet();
|
return Collections.emptyList();
|
||||||
} else {
|
} else {
|
||||||
HashSet<ISSABasicBlock> c = HashSetFactory.make(getSuccNodeCount(b));
|
List<ISSABasicBlock> c = new ArrayList<ISSABasicBlock>(getSuccNodeCount(b));
|
||||||
for (Iterator<ISSABasicBlock> it = delegate.getExceptionalSuccessors(b).iterator(); it.hasNext(); ) {
|
for (Iterator<ISSABasicBlock> it = delegate.getExceptionalSuccessors(b).iterator(); it.hasNext(); ) {
|
||||||
ISSABasicBlock o = it.next();
|
ISSABasicBlock o = it.next();
|
||||||
if (o.equals(delegate.exit())) {
|
if (o.equals(delegate.exit())) {
|
||||||
|
|
|
@ -681,12 +681,6 @@ public abstract class ShrikeBTMethod implements IMethod, BytecodeConstants {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method getHandlers.
|
|
||||||
*
|
|
||||||
* @return ExceptionHandler[][]
|
|
||||||
* @throws InvalidClassFileException
|
|
||||||
*/
|
|
||||||
public ExceptionHandler[][] getHandlers() throws InvalidClassFileException {
|
public ExceptionHandler[][] getHandlers() throws InvalidClassFileException {
|
||||||
if (getBCInfo().decoder == null) {
|
if (getBCInfo().decoder == null) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -696,18 +690,16 @@ public abstract class ShrikeBTMethod implements IMethod, BytecodeConstants {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method getParameterType. By convention, for a non-static method,
|
* By convention, for a non-static method, getParameterType(0) is the this
|
||||||
* getParameterType(0) is the this pointer
|
* pointer
|
||||||
*
|
|
||||||
* @param i
|
|
||||||
* @return TypeReference
|
|
||||||
*/
|
*/
|
||||||
public TypeReference getParameterType(int i) {
|
public TypeReference getParameterType(int i) {
|
||||||
if (!isStatic()) {
|
if (!isStatic()) {
|
||||||
if (i == 0)
|
if (i == 0) {
|
||||||
return declaringClass.getReference();
|
return declaringClass.getReference();
|
||||||
else
|
} else {
|
||||||
return getReference().getParameterType(i - 1);
|
return getReference().getParameterType(i - 1);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return getReference().getParameterType(i);
|
return getReference().getParameterType(i);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,9 +10,11 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
package com.ibm.wala.ipa.cfg;
|
package com.ibm.wala.ipa.cfg;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
@ -282,8 +284,12 @@ public class PrunedCFG<T extends IBasicBlock> extends AbstractNumberedGraph<T> i
|
||||||
return edges;
|
return edges;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<T> getExceptionalSuccessors(final T N) {
|
public List<T> getExceptionalSuccessors(final T N) {
|
||||||
return Iterator2Collection.toCollection(edges.getExceptionalSuccessors(N));
|
ArrayList<T> result = new ArrayList<T>();
|
||||||
|
for (Iterator<T> it = edges.getExceptionalSuccessors(N); it.hasNext(); ) {
|
||||||
|
result.add(it.next());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<T> getNormalSuccessors(final T N) {
|
public Collection<T> getNormalSuccessors(final T N) {
|
||||||
|
|
|
@ -83,8 +83,8 @@ public abstract class IR {
|
||||||
private Map<SSAInstruction, ISSABasicBlock> instruction2Block;
|
private Map<SSAInstruction, ISSABasicBlock> instruction2Block;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* subclasses must provide a source name mapping, if they want one
|
* subclasses must provide a source name mapping, if they want one (or null
|
||||||
* (or null otherwise)
|
* otherwise)
|
||||||
*/
|
*/
|
||||||
protected abstract SSA2LocalMap getLocalMap();
|
protected abstract SSA2LocalMap getLocalMap();
|
||||||
|
|
||||||
|
@ -143,7 +143,8 @@ public abstract class IR {
|
||||||
* Create a string representation, with decoration for each variable
|
* Create a string representation, with decoration for each variable
|
||||||
*
|
*
|
||||||
* @param d
|
* @param d
|
||||||
* an object which provides string decorators for variables in the IR
|
* an object which provides string decorators for variables in the
|
||||||
|
* IR
|
||||||
*/
|
*/
|
||||||
public String toString(ValueDecorator d) {
|
public String toString(ValueDecorator d) {
|
||||||
StringBuffer result = new StringBuffer(method.toString());
|
StringBuffer result = new StringBuffer(method.toString());
|
||||||
|
@ -468,7 +469,8 @@ public abstract class IR {
|
||||||
/**
|
/**
|
||||||
* @param site
|
* @param site
|
||||||
* @return the invoke instructions corresponding to this call site
|
* @return the invoke instructions corresponding to this call site
|
||||||
* @throws IllegalArgumentException if site is null
|
* @throws IllegalArgumentException
|
||||||
|
* if site is null
|
||||||
*/
|
*/
|
||||||
public SSAAbstractInvokeInstruction[] getCalls(CallSiteReference site) {
|
public SSAAbstractInvokeInstruction[] getCalls(CallSiteReference site) {
|
||||||
if (site == null) {
|
if (site == null) {
|
||||||
|
@ -487,7 +489,8 @@ public abstract class IR {
|
||||||
/**
|
/**
|
||||||
* @param site
|
* @param site
|
||||||
* @return the instruction indices corresponding to this call site
|
* @return the instruction indices corresponding to this call site
|
||||||
* @throws IllegalArgumentException if site is null
|
* @throws IllegalArgumentException
|
||||||
|
* if site is null
|
||||||
*/
|
*/
|
||||||
public IntSet getCallInstructionIndices(CallSiteReference site) {
|
public IntSet getCallInstructionIndices(CallSiteReference site) {
|
||||||
if (site == null) {
|
if (site == null) {
|
||||||
|
@ -563,7 +566,8 @@ public abstract class IR {
|
||||||
* @param site
|
* @param site
|
||||||
* a call site in this method
|
* a call site in this method
|
||||||
* @return the basic block corresponding to this instruction
|
* @return the basic block corresponding to this instruction
|
||||||
* @throws IllegalArgumentException if site is null
|
* @throws IllegalArgumentException
|
||||||
|
* if site is null
|
||||||
*/
|
*/
|
||||||
public ISSABasicBlock[] getBasicBlocksForCall(final CallSiteReference site) {
|
public ISSABasicBlock[] getBasicBlocksForCall(final CallSiteReference site) {
|
||||||
if (site == null) {
|
if (site == null) {
|
||||||
|
@ -596,7 +600,7 @@ public abstract class IR {
|
||||||
instruction2Block = HashMapFactory.make();
|
instruction2Block = HashMapFactory.make();
|
||||||
for (ISSABasicBlock b : cfg) {
|
for (ISSABasicBlock b : cfg) {
|
||||||
for (IInstruction s : b) {
|
for (IInstruction s : b) {
|
||||||
instruction2Block.put((SSAInstruction)s, b);
|
instruction2Block.put((SSAInstruction) s, b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,6 @@ import com.ibm.wala.util.MapIterator;
|
||||||
import com.ibm.wala.util.ShrikeUtil;
|
import com.ibm.wala.util.ShrikeUtil;
|
||||||
import com.ibm.wala.util.collections.EmptyIterator;
|
import com.ibm.wala.util.collections.EmptyIterator;
|
||||||
import com.ibm.wala.util.collections.HashMapFactory;
|
import com.ibm.wala.util.collections.HashMapFactory;
|
||||||
import com.ibm.wala.util.collections.HashSetFactory;
|
|
||||||
import com.ibm.wala.util.collections.Iterator2Collection;
|
import com.ibm.wala.util.collections.Iterator2Collection;
|
||||||
import com.ibm.wala.util.debug.Assertions;
|
import com.ibm.wala.util.debug.Assertions;
|
||||||
import com.ibm.wala.util.debug.Trace;
|
import com.ibm.wala.util.debug.Trace;
|
||||||
|
@ -907,13 +906,13 @@ public class SSACFG implements ControlFlowGraph<ISSABasicBlock> {
|
||||||
/*
|
/*
|
||||||
* @see com.ibm.wala.cfg.ControlFlowGraph#getExceptionalSuccessors(com.ibm.wala.cfg.IBasicBlock)
|
* @see com.ibm.wala.cfg.ControlFlowGraph#getExceptionalSuccessors(com.ibm.wala.cfg.IBasicBlock)
|
||||||
*/
|
*/
|
||||||
public Collection<ISSABasicBlock> getExceptionalSuccessors(final ISSABasicBlock b) {
|
public List<ISSABasicBlock> getExceptionalSuccessors(final ISSABasicBlock b) {
|
||||||
if (b == null) {
|
if (b == null) {
|
||||||
throw new IllegalArgumentException("b is null");
|
throw new IllegalArgumentException("b is null");
|
||||||
}
|
}
|
||||||
final IBasicBlock n = cfg.getNode(b.getNumber());
|
final IBasicBlock n = cfg.getNode(b.getNumber());
|
||||||
final Iterator i = cfg.getExceptionalSuccessors(n).iterator();
|
final Iterator i = cfg.getExceptionalSuccessors(n).iterator();
|
||||||
final Collection<ISSABasicBlock> c = HashSetFactory.make(getSuccNodeCount(b));
|
final List<ISSABasicBlock> c = new ArrayList<ISSABasicBlock>(getSuccNodeCount(b));
|
||||||
for (; i.hasNext();) {
|
for (; i.hasNext();) {
|
||||||
final IBasicBlock s = (IBasicBlock) i.next();
|
final IBasicBlock s = (IBasicBlock) i.next();
|
||||||
c.add(basicBlocks[cfg.getNumber(s)]);
|
c.add(basicBlocks[cfg.getNumber(s)]);
|
||||||
|
|
|
@ -125,10 +125,10 @@ public class ExplodedControlFlowGraph implements ControlFlowGraph<ExplodedContro
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<ExplodedBasicBlock> getExceptionalSuccessors(ExplodedBasicBlock eb) {
|
public List<ExplodedBasicBlock> getExceptionalSuccessors(ExplodedBasicBlock eb) {
|
||||||
assert eb != null;
|
assert eb != null;
|
||||||
if (eb.equals(exit)) {
|
if (eb.equals(exit)) {
|
||||||
return Collections.emptySet();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
if (eb.isEntryBlock() || eb.instructionIndex == eb.original.getLastInstructionIndex()) {
|
if (eb.isEntryBlock() || eb.instructionIndex == eb.original.getLastInstructionIndex()) {
|
||||||
List<ExplodedBasicBlock> result = new ArrayList<ExplodedBasicBlock>();
|
List<ExplodedBasicBlock> result = new ArrayList<ExplodedBasicBlock>();
|
||||||
|
@ -142,7 +142,7 @@ public class ExplodedControlFlowGraph implements ControlFlowGraph<ExplodedContro
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
return Collections.emptySet();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -386,6 +386,10 @@ public class ExplodedControlFlowGraph implements ControlFlowGraph<ExplodedContro
|
||||||
return instructionIndex;
|
return instructionIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ExplodedControlFlowGraph getCFG() {
|
||||||
|
return ExplodedControlFlowGraph.this;
|
||||||
|
}
|
||||||
|
|
||||||
public IMethod getMethod() {
|
public IMethod getMethod() {
|
||||||
Assertions.UNREACHABLE();
|
Assertions.UNREACHABLE();
|
||||||
return null;
|
return null;
|
||||||
|
|
Loading…
Reference in New Issue