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;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
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.IntSet;
|
||||
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
|
||||
*/
|
||||
final private SparseNumberedEdgeManager<T> exceptionalEdgeManager = new SparseNumberedEdgeManager<T>(nodeManager,
|
||||
0, BasicNaturalRelation.SIMPLE);
|
||||
final private SparseNumberedEdgeManager<T> exceptionalEdgeManager = new SparseNumberedEdgeManager<T>(nodeManager, 0,
|
||||
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()?
|
||||
|
@ -186,7 +198,7 @@ public abstract class AbstractCFG<T extends IBasicBlock> implements ControlFlowG
|
|||
|
||||
/**
|
||||
* @param number
|
||||
* number of a basic block in this cfg
|
||||
* number of a basic block in this cfg
|
||||
*/
|
||||
boolean hasAnyNormalOut(int number) {
|
||||
return (fallThru.get(number) || normalEdgeManager.getSuccNodeCount(number) > 0 || normalToExit.get(number));
|
||||
|
@ -194,7 +206,7 @@ public abstract class AbstractCFG<T extends IBasicBlock> implements ControlFlowG
|
|||
|
||||
/**
|
||||
* @param number
|
||||
* number of a basic block in this cfg
|
||||
* number of a basic block in this cfg
|
||||
*/
|
||||
private int getNumberOfNormalOut(int number) {
|
||||
int xtra = 0;
|
||||
|
@ -209,7 +221,7 @@ public abstract class AbstractCFG<T extends IBasicBlock> implements ControlFlowG
|
|||
|
||||
/**
|
||||
* @param number
|
||||
* number of a basic block in this cfg
|
||||
* number of a basic block in this cfg
|
||||
*/
|
||||
public int getNumberOfExceptionalOut(int number) {
|
||||
int xtra = 0;
|
||||
|
@ -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) {
|
||||
if (exceptionalEdgeManager.hasAnySuccessor(number)) {
|
||||
if (exceptionalToExit.get(number)) {
|
||||
return IteratorPlusOne.make(exceptionalEdgeManager.getSuccNodes(number), exit());
|
||||
} else {
|
||||
return exceptionalEdgeManager.getSuccNodes(number);
|
||||
List<T> result = new ArrayList<T>();
|
||||
SimpleIntVector v = exceptionalSuccessors.get(number);
|
||||
for (int i = 0; i <= v.getMaxIndex(); i++) {
|
||||
result.add(getNode(v.get(i)));
|
||||
}
|
||||
if (exceptionalToExit.get(number)) {
|
||||
result.add(exit);
|
||||
}
|
||||
return result.iterator();
|
||||
} else {
|
||||
if (exceptionalToExit.get(number)) {
|
||||
return new NonNullSingletonIterator<T>(exit());
|
||||
|
@ -463,7 +485,7 @@ public abstract class AbstractCFG<T extends IBasicBlock> implements ControlFlowG
|
|||
* @param src
|
||||
* @param dst
|
||||
* @throws IllegalArgumentException
|
||||
* if dst is null
|
||||
* if dst is null
|
||||
*/
|
||||
public void addNormalEdge(T src, T dst) {
|
||||
if (dst == null) {
|
||||
|
@ -479,10 +501,8 @@ public abstract class AbstractCFG<T extends IBasicBlock> implements ControlFlowG
|
|||
}
|
||||
|
||||
/**
|
||||
* @param src
|
||||
* @param dst
|
||||
* @throws IllegalArgumentException
|
||||
* if dst is null
|
||||
* if dst is null
|
||||
*/
|
||||
public void addExceptionalEdge(T src, T dst) {
|
||||
if (dst == null) {
|
||||
|
@ -492,6 +512,12 @@ public abstract class AbstractCFG<T extends IBasicBlock> implements ControlFlowG
|
|||
exceptionalToExit.set(getNumber(src));
|
||||
} else {
|
||||
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)
|
||||
*/
|
||||
public Collection<T> getExceptionalSuccessors(T b) {
|
||||
public List<T> getExceptionalSuccessors(T b) {
|
||||
if (b == 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;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.shrikeBT.IInstruction;
|
||||
|
@ -66,13 +67,15 @@ public interface ControlFlowGraph<T extends IBasicBlock> extends NumberedGraph<T
|
|||
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
|
||||
* control flow
|
||||
*/
|
||||
public Collection<T> getExceptionalSuccessors(T b);
|
||||
public List<T> getExceptionalSuccessors(T b);
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
addNormalEdge(this, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param b
|
||||
*/
|
||||
|
||||
private void addExceptionalEdgeTo(BasicBlock b) {
|
||||
addExceptionalEdge(this, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method computeOutgoingEdges.
|
||||
*/
|
||||
|
||||
private void computeOutgoingEdges() {
|
||||
|
||||
if (DEBUG) {
|
||||
|
|
|
@ -226,9 +226,6 @@ public class ShrikeCFG extends AbstractCFG<ShrikeCFG.BasicBlock> {
|
|||
return ShrikeCFG.this.isCatchBlock(getNumber());
|
||||
}
|
||||
|
||||
/**
|
||||
* Method computeOutgoingEdges.
|
||||
*/
|
||||
private void computeOutgoingEdges() {
|
||||
if (DEBUG) {
|
||||
Trace.println("Block " + this + ": computeOutgoingEdges()");
|
||||
|
@ -377,38 +374,16 @@ public class ShrikeCFG extends AbstractCFG<ShrikeCFG.BasicBlock> {
|
|||
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) {
|
||||
addNormalEdge(this, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param b
|
||||
*/
|
||||
private void addExceptionalEdgeTo(BasicBlock b) {
|
||||
addExceptionalEdge(this, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getLastInstructionIndex.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public int getLastInstructionIndex() {
|
||||
|
||||
public int getLastInstructionIndex() {
|
||||
if (this == entry() || this == exit()) {
|
||||
// these are the special end blocks
|
||||
return -2;
|
||||
|
@ -422,16 +397,10 @@ public class ShrikeCFG extends AbstractCFG<ShrikeCFG.BasicBlock> {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getFirstInstructionIndex.
|
||||
*/
|
||||
public int getFirstInstructionIndex() {
|
||||
return startIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
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
|
||||
public String toString() {
|
||||
StringBuffer s = new StringBuffer("");
|
||||
|
@ -502,29 +468,17 @@ public class ShrikeCFG extends AbstractCFG<ShrikeCFG.BasicBlock> {
|
|||
return s.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getMaxStackHeight.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
|
||||
public int getMaxStackHeight() {
|
||||
return method.getMaxStackHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getMaxLocals
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
|
||||
public int getMaxLocals() {
|
||||
return method.getMaxLocals();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the exceptionHandlers.
|
||||
*
|
||||
* @return Set
|
||||
*/
|
||||
|
||||
public Set<ExceptionHandler> getExceptionHandlers() {
|
||||
return exceptionHandlers;
|
||||
}
|
||||
|
|
|
@ -10,10 +10,11 @@
|
|||
*******************************************************************************/
|
||||
package com.ibm.wala.cfg;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
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.util.IteratorPlusOne;
|
||||
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.Trace;
|
||||
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)
|
||||
*/
|
||||
public Collection<ISSABasicBlock> getExceptionalSuccessors(ISSABasicBlock b) {
|
||||
public List<ISSABasicBlock> getExceptionalSuccessors(ISSABasicBlock b) {
|
||||
if (b == null) {
|
||||
throw new IllegalArgumentException("b is null");
|
||||
}
|
||||
if (b.equals(exceptionalExit)) {
|
||||
return Collections.emptySet();
|
||||
return Collections.emptyList();
|
||||
} 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(); ) {
|
||||
ISSABasicBlock o = it.next();
|
||||
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 {
|
||||
if (getBCInfo().decoder == null) {
|
||||
return null;
|
||||
|
@ -696,18 +690,16 @@ public abstract class ShrikeBTMethod implements IMethod, BytecodeConstants {
|
|||
}
|
||||
|
||||
/**
|
||||
* Method getParameterType. By convention, for a non-static method,
|
||||
* getParameterType(0) is the this pointer
|
||||
*
|
||||
* @param i
|
||||
* @return TypeReference
|
||||
* By convention, for a non-static method, getParameterType(0) is the this
|
||||
* pointer
|
||||
*/
|
||||
public TypeReference getParameterType(int i) {
|
||||
if (!isStatic()) {
|
||||
if (i == 0)
|
||||
if (i == 0) {
|
||||
return declaringClass.getReference();
|
||||
else
|
||||
} else {
|
||||
return getReference().getParameterType(i - 1);
|
||||
}
|
||||
} else {
|
||||
return getReference().getParameterType(i);
|
||||
}
|
||||
|
|
|
@ -10,9 +10,11 @@
|
|||
*****************************************************************************/
|
||||
package com.ibm.wala.ipa.cfg;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -282,8 +284,12 @@ public class PrunedCFG<T extends IBasicBlock> extends AbstractNumberedGraph<T> i
|
|||
return edges;
|
||||
}
|
||||
|
||||
public Collection<T> getExceptionalSuccessors(final T N) {
|
||||
return Iterator2Collection.toCollection(edges.getExceptionalSuccessors(N));
|
||||
public List<T> getExceptionalSuccessors(final T 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) {
|
||||
|
|
|
@ -76,15 +76,15 @@ public abstract class IR {
|
|||
* Mapping from PEI program counters to instruction[] indices
|
||||
*/
|
||||
final private Map<ProgramCounter, Integer> peiMapping = HashMapFactory.make();
|
||||
|
||||
|
||||
/**
|
||||
* Mapping from SSAInstruction to Basic Block, computed lazily
|
||||
*/
|
||||
private Map<SSAInstruction, ISSABasicBlock> instruction2Block;
|
||||
|
||||
/**
|
||||
* subclasses must provide a source name mapping, if they want one
|
||||
* (or null otherwise)
|
||||
* subclasses must provide a source name mapping, if they want one (or null
|
||||
* otherwise)
|
||||
*/
|
||||
protected abstract SSA2LocalMap getLocalMap();
|
||||
|
||||
|
@ -97,9 +97,9 @@ public abstract class IR {
|
|||
* keep this package private: all calls should be through SSACache
|
||||
*
|
||||
* @param method
|
||||
* the method to construct SSA form for
|
||||
* the method to construct SSA form for
|
||||
* @param options
|
||||
* governing ssa construction options
|
||||
* governing ssa construction options
|
||||
*/
|
||||
protected IR(IMethod method, SSAInstruction[] instructions, SymbolTable symbolTable, SSACFG cfg, SSAOptions options) {
|
||||
if (method == null) {
|
||||
|
@ -143,7 +143,8 @@ public abstract class IR {
|
|||
* Create a string representation, with decoration for each variable
|
||||
*
|
||||
* @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) {
|
||||
StringBuffer result = new StringBuffer(method.toString());
|
||||
|
@ -179,7 +180,7 @@ public abstract class IR {
|
|||
StringBuffer x = new StringBuffer(j + " " + instructions[j].toString(symbolTable, d));
|
||||
StringStuff.padWithSpaces(x, 45);
|
||||
result.append(x);
|
||||
result.append(instructionPosition(j));
|
||||
result.append(instructionPosition(j));
|
||||
result.append("\n");
|
||||
}
|
||||
}
|
||||
|
@ -389,7 +390,7 @@ public abstract class IR {
|
|||
* visit each normal (non-phi, non-pi, non-catch) instruction in this IR
|
||||
*
|
||||
* @param v
|
||||
* a visitor
|
||||
* a visitor
|
||||
*/
|
||||
public void visitNormalInstructions(SSAInstruction.Visitor v) {
|
||||
for (Iterator i = iterateNormalInstructions(); i.hasNext();) {
|
||||
|
@ -401,7 +402,7 @@ public abstract class IR {
|
|||
* visit each instruction in this IR
|
||||
*
|
||||
* @param v
|
||||
* a visitor
|
||||
* a visitor
|
||||
*/
|
||||
public void visitAllInstructions(SSAInstruction.Visitor v) {
|
||||
for (Iterator i = iterateAllInstructions(); i.hasNext();) {
|
||||
|
@ -468,7 +469,8 @@ public abstract class IR {
|
|||
/**
|
||||
* @param 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) {
|
||||
if (site == null) {
|
||||
|
@ -487,7 +489,8 @@ public abstract class IR {
|
|||
/**
|
||||
* @param 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) {
|
||||
if (site == null) {
|
||||
|
@ -516,7 +519,7 @@ public abstract class IR {
|
|||
|
||||
/**
|
||||
* @param pc
|
||||
* a program counter
|
||||
* a program counter
|
||||
* @return the instruction (a PEI) at this program counter
|
||||
*/
|
||||
public SSAInstruction getPEI(ProgramCounter pc) {
|
||||
|
@ -561,9 +564,10 @@ public abstract class IR {
|
|||
|
||||
/**
|
||||
* @param site
|
||||
* a call site in this method
|
||||
* a call site in this method
|
||||
* @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) {
|
||||
if (site == null) {
|
||||
|
@ -578,12 +582,12 @@ public abstract class IR {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is space-inefficient. Use with care.
|
||||
* This is space-inefficient. Use with care.
|
||||
*
|
||||
* Be very careful; note the strange identity semantics of SSAInstruction,
|
||||
* using ==. You can't mix SSAInstructions and IRs freely.
|
||||
* using ==. You can't mix SSAInstructions and IRs freely.
|
||||
*/
|
||||
public ISSABasicBlock getBasicBlockForInstruction(SSAInstruction s) {
|
||||
if (instruction2Block == null) {
|
||||
|
@ -596,11 +600,11 @@ public abstract class IR {
|
|||
instruction2Block = HashMapFactory.make();
|
||||
for (ISSABasicBlock b : cfg) {
|
||||
for (IInstruction s : b) {
|
||||
instruction2Block.put((SSAInstruction)s, b);
|
||||
instruction2Block.put((SSAInstruction) s, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* TODO: why do we need this? We should enforce instructions == null if
|
||||
* necessary, I think.
|
||||
|
@ -620,9 +624,9 @@ public abstract class IR {
|
|||
|
||||
/**
|
||||
* @param index
|
||||
* an index into the IR instruction array
|
||||
* an index into the IR instruction array
|
||||
* @param vn
|
||||
* a value number
|
||||
* a value number
|
||||
* @return if we know that immediately after the given program counter, v_vn
|
||||
* corresponds to one or more locals and local variable names are
|
||||
* available, the name of the locals which v_vn represents. Otherwise,
|
||||
|
@ -643,9 +647,9 @@ public abstract class IR {
|
|||
public interface SSA2LocalMap {
|
||||
/**
|
||||
* @param index
|
||||
* an index into the IR instruction array
|
||||
* an index into the IR instruction array
|
||||
* @param vn
|
||||
* a value number
|
||||
* a value number
|
||||
* @return if we know that immediately after the given program counter, v_vn
|
||||
* corresponds to one or more locals and local variable names are
|
||||
* available, the name of the locals which v_vn represents.
|
||||
|
|
|
@ -33,7 +33,6 @@ import com.ibm.wala.util.MapIterator;
|
|||
import com.ibm.wala.util.ShrikeUtil;
|
||||
import com.ibm.wala.util.collections.EmptyIterator;
|
||||
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.debug.Assertions;
|
||||
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)
|
||||
*/
|
||||
public Collection<ISSABasicBlock> getExceptionalSuccessors(final ISSABasicBlock b) {
|
||||
public List<ISSABasicBlock> getExceptionalSuccessors(final ISSABasicBlock b) {
|
||||
if (b == null) {
|
||||
throw new IllegalArgumentException("b is null");
|
||||
}
|
||||
final IBasicBlock n = cfg.getNode(b.getNumber());
|
||||
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();) {
|
||||
final IBasicBlock s = (IBasicBlock) i.next();
|
||||
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;
|
||||
if (eb.equals(exit)) {
|
||||
return Collections.emptySet();
|
||||
return Collections.emptyList();
|
||||
}
|
||||
if (eb.isEntryBlock() || eb.instructionIndex == eb.original.getLastInstructionIndex()) {
|
||||
List<ExplodedBasicBlock> result = new ArrayList<ExplodedBasicBlock>();
|
||||
|
@ -142,7 +142,7 @@ public class ExplodedControlFlowGraph implements ControlFlowGraph<ExplodedContro
|
|||
}
|
||||
return result;
|
||||
} else {
|
||||
return Collections.emptySet();
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -385,6 +385,10 @@ public class ExplodedControlFlowGraph implements ControlFlowGraph<ExplodedContro
|
|||
public int getLastInstructionIndex() {
|
||||
return instructionIndex;
|
||||
}
|
||||
|
||||
public ExplodedControlFlowGraph getCFG() {
|
||||
return ExplodedControlFlowGraph.this;
|
||||
}
|
||||
|
||||
public IMethod getMethod() {
|
||||
Assertions.UNREACHABLE();
|
||||
|
|
Loading…
Reference in New Issue