added container access to ModuleEntry

This commit is contained in:
Julian Dolby 2013-06-25 11:53:58 -04:00
parent 068d0f0908
commit 3015d1c5f9
14 changed files with 172 additions and 19 deletions

View File

@ -159,6 +159,7 @@ public abstract class IRTests {
return ea;
}
@Override
public void check(CallGraph callGraph) {
MethodReference srcMethod = descriptorToMethodRef(this.srcDescriptor, callGraph.getClassHierarchy());
Set<CGNode> srcNodes = callGraph.getNodes(srcMethod);
@ -213,6 +214,7 @@ public abstract class IRTests {
this.definingLineNumber = definingLineNumber;
}
@Override
public void check(CallGraph cg) {
MethodReference mref = descriptorToMethodRef(method, cg.getClassHierarchy());
@ -278,6 +280,7 @@ public abstract class IRTests {
public final Set<ClassAnnotation> classAnnotations = HashSetFactory.make();
public final Set<MethodAnnotation> methodAnnotations = HashSetFactory.make();
@Override
public void check(CallGraph cg) {
classes: for(ClassAnnotation ca : classAnnotations) {
IClass cls = cg.getClassHierarchy().lookupClass(TypeReference.findOrCreate(ClassLoaderReference.Application, ca.className));
@ -476,7 +479,7 @@ public abstract class IRTests {
if (f.isDirectory()) {
engine.addSourceModule(new SourceDirectoryTreeModule(f));
} else {
engine.addSourceModule(new SourceFileModule(f, srcFileName));
engine.addSourceModule(new SourceFileModule(f, srcFileName, null));
}
}
}

View File

@ -734,6 +734,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
if (pointsToSet == null || pointsToSet.getBackingSet() == null)
continue;
pointsToSet.getBackingSet().foreach(new IntSetAction() {
@Override
public void act(int ikId) {
Set<Pair<CGNode, Integer>> s = ret.get(ikId);
if (s == null) {

View File

@ -18,7 +18,7 @@ public class MappedSourceFileModule extends SourceFileModule implements MappedSo
private final FileMapping fileMapping;
public MappedSourceFileModule(File f, String fileName, FileMapping fileMapping) {
super(f, fileName);
super(f, fileName, null);
this.fileMapping = fileMapping;
}
@ -27,6 +27,7 @@ public class MappedSourceFileModule extends SourceFileModule implements MappedSo
this.fileMapping = fileMapping;
}
@Override
public FileMapping getMapping() {
return fileMapping;
}

View File

@ -50,6 +50,7 @@ public class AstIRFactory implements IRFactory {
this.astFactory = astFactory;
}
@Override
public IR makeIR(IMethod method, Context context, SSAOptions options) {
if (method instanceof AstMethod) {
return astFactory.makeIR(method, context, options);
@ -58,6 +59,7 @@ public class AstIRFactory implements IRFactory {
}
}
@Override
public ControlFlowGraph makeCFG(IMethod method, Context context) {
if (method instanceof AstMethod) {
return astFactory.makeCFG(method, context);
@ -96,12 +98,14 @@ public class AstIRFactory implements IRFactory {
}
}
@Override
protected SSA2LocalMap getLocalMap() {
return localMap;
}
@Override
protected String instructionPosition(int instructionIndex) {
Position pos = ((AstMethod) getMethod()).getSourcePosition(instructionIndex);
Position pos = getMethod().getSourcePosition(instructionIndex);
if (pos == null) {
return "";
} else {
@ -109,6 +113,11 @@ public class AstIRFactory implements IRFactory {
}
}
@Override
public AstMethod getMethod() {
return (AstMethod)super.getMethod();
}
private AstIR(AstMethod method, SSAInstruction[] instructions, SymbolTable symbolTable, SSACFG cfg, SSAOptions options) {
super(method, instructions, symbolTable, cfg, options);
@ -130,6 +139,7 @@ public class AstIRFactory implements IRFactory {
}
}
@Override
public IR makeIR(final IMethod method, final Context context, final SSAOptions options) {
assert method instanceof AstMethod : method.toString();
@ -148,6 +158,7 @@ public class AstIRFactory implements IRFactory {
return new AstDefaultIRFactory();
}
@Override
public boolean contextIsIrrelevant(IMethod method) {
return true;
}

View File

@ -81,10 +81,12 @@ public class SSAConversion extends AbstractSSAConversion {
this.instructionIndex = instructionIndex;
}
@Override
public int hashCode() {
return useNumber * instructionIndex;
}
@Override
public boolean equals(Object o) {
return (o instanceof UseRecord) && instructionIndex == ((UseRecord) o).instructionIndex
&& useNumber == ((UseRecord) o).useNumber;
@ -104,10 +106,12 @@ public class SSAConversion extends AbstractSSAConversion {
this.useNumber = useNumber;
}
@Override
public int hashCode() {
return phiNumber * BBnumber * useNumber;
}
@Override
public boolean equals(Object o) {
return (o instanceof PhiUseRecord) && BBnumber == ((PhiUseRecord) o).BBnumber && phiNumber == ((PhiUseRecord) o).phiNumber
&& useNumber == ((PhiUseRecord) o).useNumber;
@ -123,10 +127,12 @@ public class SSAConversion extends AbstractSSAConversion {
private final Set<CopyPropagationRecord> childRecords = HashSetFactory.make(1);
@Override
public int hashCode() {
return instructionIndex;
}
@Override
public boolean equals(Object o) {
return (o instanceof CopyPropagationRecord) && instructionIndex == ((CopyPropagationRecord) o).instructionIndex;
}
@ -232,6 +238,7 @@ public class SSAConversion extends AbstractSSAConversion {
//
private class SSAInformation implements com.ibm.wala.ssa.IR.SSA2LocalMap {
@Override
public String[] getLocalNames(int pc, int vn) {
int v = skip(vn) || vn >= valueMap.length ? vn : valueMap[vn];
String[][] namesData = debugInfo.getSourceNamesForValues();
@ -279,34 +286,42 @@ public class SSAConversion extends AbstractSSAConversion {
// implementation of AbstractSSAConversion hooks
//
@Override
protected int getNumberOfDefs(SSAInstruction inst) {
return inst.getNumberOfDefs();
}
@Override
protected int getDef(SSAInstruction inst, int index) {
return inst.getDef(index);
}
@Override
protected int getNumberOfUses(SSAInstruction inst) {
return inst.getNumberOfUses();
}
@Override
protected int getUse(SSAInstruction inst, int index) {
return inst.getUse(index);
}
@Override
protected boolean isAssignInstruction(SSAInstruction inst) {
return inst instanceof AssignInstruction;
}
@Override
protected int getMaxValueNumber() {
return symtab.getMaxValueNumber();
}
@Override
protected boolean skip(int vn) {
return false;
}
@Override
protected boolean isLive(SSACFG.BasicBlock Y, int V) {
return (liveness.isLiveEntry(Y, V));
}
@ -315,6 +330,7 @@ public class SSAConversion extends AbstractSSAConversion {
BB.addPhiForLocal(phiCounts[BB.getGraphNodeId()], phi);
}
@Override
protected void placeNewPhiAt(int value, SSACFG.BasicBlock Y) {
int[] params = new int[CFG.getPredNodeCount(Y)];
for (int i = 0; i < params.length; i++)
@ -328,18 +344,22 @@ public class SSAConversion extends AbstractSSAConversion {
addPhi(Y, phi);
}
@Override
protected SSAPhiInstruction getPhi(SSACFG.BasicBlock B, int index) {
return B.getPhiForLocal(index);
}
@Override
protected void setPhi(SSACFG.BasicBlock B, int index, SSAPhiInstruction inst) {
B.addPhiForLocal(index, inst);
}
@Override
protected SSAPhiInstruction repairPhiDefs(SSAPhiInstruction phi, int[] newDefs) {
return (SSAPhiInstruction) phi.copyForSSA(CFG.getMethod().getDeclaringClass().getClassLoader().getInstructionFactory(), newDefs, null);
}
@Override
protected void repairPhiUse(SSACFG.BasicBlock BB, int phiIndex, int rvalIndex, int newRval) {
SSAPhiInstruction phi = getPhi(BB, phiIndex);
@ -357,6 +377,7 @@ public class SSAConversion extends AbstractSSAConversion {
phi.setValues(newUses);
}
@Override
protected void pushAssignment(SSAInstruction inst, int index, int newRhs) {
int lhs = getDef(inst, 0);
int rhs = getUse(inst, 0);
@ -370,6 +391,7 @@ public class SSAConversion extends AbstractSSAConversion {
}
}
@Override
protected void repairInstructionUses(SSAInstruction inst, int index, int[] newUses) {
for (int j = 0; j < getNumberOfUses(inst); j++) {
if (topR(getUse(inst, j)) != null) {
@ -398,18 +420,22 @@ public class SSAConversion extends AbstractSSAConversion {
}
}
@Override
protected void repairInstructionDefs(SSAInstruction inst, int index, int[] newDefs, int[] newUses) {
instructions[index] = inst.copyForSSA(CFG.getMethod().getDeclaringClass().getClassLoader().getInstructionFactory(), newDefs, newUses);
}
@Override
protected void popAssignment(SSAInstruction inst, int index) {
instructions[index] = null;
}
@Override
protected boolean isConstant(int valueNumber) {
return symtab.isConstant(valueNumber);
}
@Override
protected boolean skipRepair(SSAInstruction inst, int index) {
if (!super.skipRepair(inst, index)) {
return false;
@ -475,6 +501,7 @@ public class SSAConversion extends AbstractSSAConversion {
}
}
@Override
protected int getNextNewValueNumber() {
while (symtab.isConstant(nextSSAValue) || skip(nextSSAValue))
++nextSSAValue;
@ -499,6 +526,7 @@ public class SSAConversion extends AbstractSSAConversion {
}
}
@Override
protected void initializeVariables() {
for (int V = 1; V <= getMaxValueNumber(); V++) {
if (!skip(V)) {
@ -516,6 +544,7 @@ public class SSAConversion extends AbstractSSAConversion {
}
@Override
protected void repairExit() {
int[] exitLives = lexicalInfo.getExitExposedUses();
if (exitLives != null) {
@ -532,6 +561,7 @@ public class SSAConversion extends AbstractSSAConversion {
// Global control.
//
@Override
protected void fail(int v) {
System.err.println("during SSA conversion of the following IR:");
System.err.println(ir);
@ -542,6 +572,7 @@ public class SSAConversion extends AbstractSSAConversion {
return computedLocalMap;
}
@Override
public void perform() {
super.perform();
@ -603,6 +634,7 @@ public class SSAConversion extends AbstractSSAConversion {
SSAConversion ssa = new SSAConversion(M, ir, options) {
final int limit = ir.getSymbolTable().getMaxValueNumber();
@Override
protected boolean skip(int i) {
return (i >= 0) && (i <= limit) && (!values.contains(i));
}

View File

@ -32,6 +32,8 @@ public abstract class AbstractNestedJarFileModule implements Module {
private static final boolean DEBUG = false;
private final Module container;
/**
* For efficiency, we cache the byte[] holding each ZipEntry's contents; this will help avoid multiple unzipping TODO: use a soft
* reference?
@ -39,6 +41,10 @@ public abstract class AbstractNestedJarFileModule implements Module {
private HashMap<String, byte[]> cache = null;
protected abstract InputStream getNestedContents() throws IOException;
protected AbstractNestedJarFileModule(Module container) {
this.container = container;
}
public InputStream getInputStream(String name) {
populateCache();
@ -92,6 +98,7 @@ public abstract class AbstractNestedJarFileModule implements Module {
/*
* @see com.ibm.wala.classLoader.Module#getEntries()
*/
@Override
public Iterator<ModuleEntry> getEntries() {
populateCache();
final Iterator<String> it = cache.keySet().iterator();
@ -109,16 +116,19 @@ public abstract class AbstractNestedJarFileModule implements Module {
}
}
@Override
public boolean hasNext() {
return next != null;
}
@Override
public ModuleEntry next() {
ModuleEntry result = new Entry(next);
advance();
return result;
}
@Override
public void remove() {
Assertions.UNREACHABLE();
}
@ -139,13 +149,21 @@ public abstract class AbstractNestedJarFileModule implements Module {
/*
* @see com.ibm.wala.classLoader.ModuleEntry#getName()
*/
@Override
public String getName() {
return name;
}
@Override
public Module getContainer() {
return container;
}
/*
* @see com.ibm.wala.classLoader.ModuleEntry#isClassFile()
*/
@Override
public boolean isClassFile() {
return FileSuffixes.isClassFile(getName());
}
@ -153,6 +171,7 @@ public abstract class AbstractNestedJarFileModule implements Module {
/*
* @see com.ibm.wala.classLoader.ModuleEntry#getInputStream()
*/
@Override
public InputStream getInputStream() {
return AbstractNestedJarFileModule.this.getInputStream(name);
}
@ -160,6 +179,7 @@ public abstract class AbstractNestedJarFileModule implements Module {
/*
* @see com.ibm.wala.classLoader.ModuleEntry#isModuleFile()
*/
@Override
public boolean isModuleFile() {
return false;
}
@ -167,6 +187,7 @@ public abstract class AbstractNestedJarFileModule implements Module {
/*
* @see com.ibm.wala.classLoader.ModuleEntry#asModule()
*/
@Override
public Module asModule() {
Assertions.UNREACHABLE();
return null;
@ -180,6 +201,7 @@ public abstract class AbstractNestedJarFileModule implements Module {
/*
* @see com.ibm.wala.classLoader.ModuleEntry#getClassName()
*/
@Override
public String getClassName() {
return FileSuffixes.stripSuffix(getName());
}
@ -187,6 +209,7 @@ public abstract class AbstractNestedJarFileModule implements Module {
/*
* @see com.ibm.wala.classLoader.ModuleEntry#isSourceFile()
*/
@Override
public boolean isSourceFile() {
return FileSuffixes.isSourceFile(getName());
}

View File

@ -34,6 +34,7 @@ public abstract class AbstractURLModule implements Module, ModuleEntry {
return url;
}
@Override
public String getName() {
try {
URLConnection con = url.openConnection();
@ -47,6 +48,7 @@ public abstract class AbstractURLModule implements Module, ModuleEntry {
}
}
@Override
public InputStream getInputStream() {
try {
return url.openConnection().getInputStream();
@ -56,21 +58,31 @@ public abstract class AbstractURLModule implements Module, ModuleEntry {
}
}
@Override
public boolean isModuleFile() {
return false;
}
@Override
public Module asModule() throws UnimplementedError {
Assertions.UNREACHABLE();
return null;
}
@Override
public String getClassName() throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
@Override
public Iterator<ModuleEntry> getEntries() {
return new NonNullSingletonIterator<ModuleEntry>(this);
}
@Override
public Module getContainer() {
// URLs are freestanding, without containers
return null;
}
}

View File

@ -24,8 +24,8 @@ public class ClassFileModule extends FileModule {
private final String className;
public ClassFileModule(File f) throws InvalidClassFileException {
super(f);
public ClassFileModule(File f, Module container) throws InvalidClassFileException {
super(f, container);
ShrikeClassReaderHandle reader = new ShrikeClassReaderHandle(this);
ImmutableByteArray name = ImmutableByteArray.make(reader.get().getName());
className = name.toString();
@ -37,14 +37,17 @@ public class ClassFileModule extends FileModule {
return "ClassFileModule:" + getFile();
}
@Override
public boolean isClassFile() {
return true;
}
@Override
public String getClassName() {
return className;
}
@Override
public boolean isSourceFile() {
return false;
}

View File

@ -37,38 +37,47 @@ public class CompoundModule implements ModuleEntry, Module, SourceModule {
return stuff;
}
@Override
public Iterator<ModuleEntry> getEntries() {
return new NonNullSingletonIterator<ModuleEntry>(this);
}
@Override
public boolean isModuleFile() {
return false;
}
@Override
public Module asModule() {
throw new UnsupportedOperationException();
}
@Override
public String getClassName() {
throw new UnsupportedOperationException();
}
@Override
public String getName() {
return name.toString();
}
@Override
public URL getURL() {
return name;
}
@Override
public boolean isClassFile() {
return false;
}
@Override
public boolean isSourceFile() {
return true;
}
@Override
public InputStream getInputStream() {
return new InputStream() {
private int index = 0;
@ -146,8 +155,15 @@ public class CompoundModule implements ModuleEntry, Module, SourceModule {
}
}
@Override
public Reader getInputReader() {
return new Reader();
}
@Override
public Module getContainer() {
// stitched together module has no single container
return null;
}
}

View File

@ -27,11 +27,14 @@ public abstract class FileModule implements Module, ModuleEntry {
private final File file;
public FileModule(File f) throws IllegalArgumentException {
private final Module container;
public FileModule(File f, Module container) throws IllegalArgumentException {
if (f == null) {
throw new IllegalArgumentException("f is null");
}
this.file = f;
this.container = container;
if (!f.exists()) {
throw new IllegalArgumentException("bad file " + f.getAbsolutePath());
}
@ -44,6 +47,7 @@ public abstract class FileModule implements Module, ModuleEntry {
/*
* @see com.ibm.wala.classLoader.Module#getEntries()
*/
@Override
public Iterator<ModuleEntry> getEntries() {
return new NonNullSingletonIterator<ModuleEntry>(this);
}
@ -69,6 +73,7 @@ public abstract class FileModule implements Module, ModuleEntry {
/*
* @see com.ibm.wala.classLoader.ModuleEntry#getName()
*/
@Override
public String getName() {
return file.getName();
}
@ -76,6 +81,7 @@ public abstract class FileModule implements Module, ModuleEntry {
/*
* @see com.ibm.wala.classLoader.ModuleEntry#getInputStream()
*/
@Override
public InputStream getInputStream() {
try {
if (!file.exists()) {
@ -92,6 +98,7 @@ public abstract class FileModule implements Module, ModuleEntry {
/*
* @see com.ibm.wala.classLoader.ModuleEntry#isModuleFile()
*/
@Override
public boolean isModuleFile() {
return false;
}
@ -103,8 +110,15 @@ public abstract class FileModule implements Module, ModuleEntry {
return file;
}
@Override
public Module asModule() throws UnimplementedError {
Assertions.UNREACHABLE("implement me");
return null;
}
@Override
public Module getContainer() {
return container;
}
}

View File

@ -26,17 +26,15 @@ public class JarFileEntry implements ModuleEntry {
private final JarFileModule jarFileModule;
private final JarFile jarFile;
protected JarFileEntry(String entryName, JarFileModule jarFile) {
this.entryName = entryName;
this.jarFileModule = jarFile;
this.jarFile = jarFile.getJarFile();
}
/*
* @see com.ibm.wala.classLoader.ModuleEntry#getName()
*/
@Override
public String getName() {
return entryName;
}
@ -44,6 +42,7 @@ public class JarFileEntry implements ModuleEntry {
/*
* @see com.ibm.wala.classLoader.ModuleEntry#isClassFile()
*/
@Override
public boolean isClassFile() {
return FileSuffixes.isClassFile(getName());
}
@ -51,8 +50,10 @@ public class JarFileEntry implements ModuleEntry {
/*
* @see com.ibm.wala.classLoader.ModuleEntry#getInputStream()
*/
@Override
public InputStream getInputStream() {
try {
JarFile jarFile = jarFileModule.getJarFile();
return jarFile.getInputStream(jarFile.getEntry(entryName));
} catch (Exception e) {
// TODO Auto-generated catch block
@ -67,18 +68,18 @@ public class JarFileEntry implements ModuleEntry {
*/
public long getSize() {
// TODO: cache this?
return jarFile.getEntry(entryName).getSize();
return jarFileModule.getJarFile().getEntry(entryName).getSize();
}
@Override
public String toString() {
// TODO Auto-generated method stub
return jarFile.getName() + ":" + getName();
return jarFileModule.getJarFile().getName() + ":" + getName();
}
/*
* @see com.ibm.wala.classLoader.ModuleEntry#isModuleFile()
*/
@Override
public boolean isModuleFile() {
return FileSuffixes.isJarFile(getName()) || FileSuffixes.isWarFile(getName());
}
@ -86,26 +87,29 @@ public class JarFileEntry implements ModuleEntry {
/*
* @see com.ibm.wala.classLoader.ModuleEntry#asModule()
*/
@Override
public Module asModule() {
return new NestedJarFileModule(jarFileModule, jarFile.getEntry(entryName));
return new NestedJarFileModule(jarFileModule, jarFileModule.getJarFile().getEntry(entryName));
}
public JarFile getJarFile() {
return jarFile;
return jarFileModule.getJarFile();
}
protected JarFileModule getJarFileModule() {
@Override
public JarFileModule getContainer() {
return jarFileModule;
}
@Override
public int hashCode() {
return entryName.hashCode() * 5059 + jarFile.hashCode();
return entryName.hashCode() * 5059 + jarFileModule.getJarFile().hashCode();
}
/*
* @see com.ibm.wala.classLoader.ModuleEntry#getClassName()
*/
@Override
public String getClassName() {
return FileSuffixes.stripSuffix(getName());
}
@ -113,6 +117,7 @@ public class JarFileEntry implements ModuleEntry {
/*
* @see com.ibm.wala.classLoader.ModuleEntry#isSourceFile()
*/
@Override
public boolean isSourceFile() {
return FileSuffixes.isSourceFile(getName());
}

View File

@ -228,6 +228,7 @@ public final class ShrikeClass extends JVMClass<IClassLoader> {
return getAnnotations(false);
}
@Override
public Collection<Annotation> getAnnotations() {
Collection<Annotation> result = HashSetFactory.make();
try {
@ -430,4 +431,8 @@ public final class ShrikeClass extends JVMClass<IClassLoader> {
}
return null;
}
public Module getContainer() {
return reader.getModuleEntry().getContainer();
}
}

View File

@ -24,14 +24,14 @@ import com.ibm.wala.util.io.FileSuffixes;
public class SourceFileModule extends FileModule implements Module, ModuleEntry, SourceModule {
private final String fileName;
public SourceFileModule(File f, String fileName) {
super(f);
public SourceFileModule(File f, String fileName, Module container) {
super(f, container);
this.fileName = fileName;
}
public SourceFileModule(File f, SourceFileModule clonedFrom) {
super(f);
super(f, clonedFrom.getContainer());
if (clonedFrom == null) {
throw new IllegalArgumentException("clonedFrom is null");
}
@ -46,6 +46,7 @@ public class SourceFileModule extends FileModule implements Module, ModuleEntry,
/*
* @see com.ibm.wala.classLoader.ModuleEntry#isClassFile()
*/
@Override
public boolean isClassFile() {
return false;
}
@ -53,6 +54,7 @@ public class SourceFileModule extends FileModule implements Module, ModuleEntry,
/*
* @see com.ibm.wala.classLoader.ModuleEntry#getClassName()
*/
@Override
public String getClassName() {
return FileSuffixes.stripSuffix(fileName).replace(File.separator.charAt(0), '/');
}
@ -60,14 +62,17 @@ public class SourceFileModule extends FileModule implements Module, ModuleEntry,
/*
* @see com.ibm.wala.classLoader.ModuleEntry#isSourceFile()
*/
@Override
public boolean isSourceFile() {
return true;
}
@Override
public Reader getInputReader() {
return new InputStreamReader(getInputStream());
}
@Override
public URL getURL() {
try {
return getFile().toURI().toURL();

View File

@ -188,6 +188,7 @@ public class ExplicitCallGraph extends BasicCallGraph<SSAContextInterpreter> imp
protected Iterator<CallSiteReference> getPossibleSites(final CGNode to) {
final int n = getCallGraph().getNumber(to);
return new FilterIterator<CallSiteReference>(iterateCallSites(), new Filter() {
@Override
public boolean accepts(Object o) {
IntSet s = getPossibleTargetNumbers((CallSiteReference) o);
return s == null ? false : s.contains(n);
@ -297,6 +298,7 @@ public class ExplicitCallGraph extends BasicCallGraph<SSAContextInterpreter> imp
allTargets.clear();
}
@Override
public IR getIR() {
if (getMethod().isSynthetic()) {
// disable local cache in this case, as context interpreters
@ -311,6 +313,7 @@ public class ExplicitCallGraph extends BasicCallGraph<SSAContextInterpreter> imp
return ir;
}
@Override
public DefUse getDU() {
if (getMethod().isSynthetic()) {
// disable local cache in this case, as context interpreters
@ -329,10 +332,12 @@ public class ExplicitCallGraph extends BasicCallGraph<SSAContextInterpreter> imp
return ExplicitCallGraph.this;
}
@Override
public Iterator<CallSiteReference> iterateCallSites() {
return getCallGraph().getInterpreter(this).iterateCallSites(this);
}
@Override
public Iterator<NewSiteReference> iterateNewSites() {
return getCallGraph().getInterpreter(this).iterateNewSites(this);
}
@ -345,6 +350,7 @@ public class ExplicitCallGraph extends BasicCallGraph<SSAContextInterpreter> imp
/*
* @see com.ibm.wala.ipa.callgraph.CallGraph#getClassHierarchy()
*/
@Override
public IClassHierarchy getClassHierarchy() {
return cha;
}
@ -352,6 +358,7 @@ public class ExplicitCallGraph extends BasicCallGraph<SSAContextInterpreter> imp
protected class ExplicitEdgeManager implements NumberedEdgeManager<CGNode> {
final IntFunction<CGNode> toNode = new IntFunction<CGNode>() {
@Override
public CGNode apply(int i) {
CGNode result = getNode(i);
// if (Assertions.verifyAssertions && result == null) {
@ -367,17 +374,20 @@ public class ExplicitCallGraph extends BasicCallGraph<SSAContextInterpreter> imp
final IBinaryNaturalRelation predecessors = new BasicNaturalRelation(new byte[] { BasicNaturalRelation.SIMPLE_SPACE_STINGY },
BasicNaturalRelation.SIMPLE);
@Override
public IntSet getSuccNodeNumbers(CGNode node) {
ExplicitNode n = (ExplicitNode) node;
return n.getAllTargetNumbers();
}
@Override
public IntSet getPredNodeNumbers(CGNode node) {
ExplicitNode n = (ExplicitNode) node;
int y = getNumber(n);
return predecessors.getRelated(y);
}
@Override
public Iterator<CGNode> getPredNodes(CGNode N) {
IntSet s = getPredNodeNumbers(N);
if (s == null) {
@ -387,22 +397,26 @@ public class ExplicitCallGraph extends BasicCallGraph<SSAContextInterpreter> imp
}
}
@Override
public int getPredNodeCount(CGNode N) {
ExplicitNode n = (ExplicitNode) N;
int y = getNumber(n);
return predecessors.getRelatedCount(y);
}
@Override
public Iterator<CGNode> getSuccNodes(CGNode N) {
ExplicitNode n = (ExplicitNode) N;
return new IntMapIterator<CGNode>(n.getAllTargetNumbers().intIterator(), toNode);
}
@Override
public int getSuccNodeCount(CGNode N) {
ExplicitNode n = (ExplicitNode) N;
return n.getAllTargetNumbers().size();
}
@Override
public void addEdge(CGNode src, CGNode dst) {
// we assume that this is called from ExplicitNode.addTarget().
// so we only have to track the inverse edge.
@ -411,6 +425,7 @@ public class ExplicitCallGraph extends BasicCallGraph<SSAContextInterpreter> imp
predecessors.add(y, x);
}
@Override
public void removeEdge(CGNode src, CGNode dst) {
int x = getNumber(src);
int y = getNumber(dst);
@ -422,20 +437,24 @@ public class ExplicitCallGraph extends BasicCallGraph<SSAContextInterpreter> imp
predecessors.add(y, x);
}
@Override
public void removeAllIncidentEdges(CGNode node) {
Assertions.UNREACHABLE();
}
@Override
public void removeIncomingEdges(CGNode node) {
Assertions.UNREACHABLE();
}
@Override
public void removeOutgoingEdges(CGNode node) {
Assertions.UNREACHABLE();
}
@Override
public boolean hasEdge(CGNode src, CGNode dst) {
int x = getNumber(src);
int y = getNumber(dst);
@ -455,6 +474,7 @@ public class ExplicitCallGraph extends BasicCallGraph<SSAContextInterpreter> imp
return new ExplicitEdgeManager();
}
@Override
public int getNumberOfTargets(CGNode node, CallSiteReference site) {
if (!containsNode(node)) {
throw new IllegalArgumentException("node not in callgraph " + node);
@ -464,6 +484,7 @@ public class ExplicitCallGraph extends BasicCallGraph<SSAContextInterpreter> imp
return n.getNumberOfTargets(site);
}
@Override
public Iterator<CallSiteReference> getPossibleSites(CGNode src, CGNode target) {
if (!containsNode(src)) {
throw new IllegalArgumentException("node not in callgraph " + src);
@ -476,6 +497,7 @@ public class ExplicitCallGraph extends BasicCallGraph<SSAContextInterpreter> imp
return n.getPossibleSites(target);
}
@Override
public Set<CGNode> getPossibleTargets(CGNode node, CallSiteReference site) {
if (!containsNode(node)) {
throw new IllegalArgumentException("node not in callgraph " + node);