miscellaneous housekeeping
git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@1364 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
parent
dd8d708fc3
commit
8864b70d50
|
@ -79,7 +79,7 @@ public class BasicHeapGraph extends HeapGraph {
|
||||||
this.pointerAnalysis = P;
|
this.pointerAnalysis = P;
|
||||||
this.callGraph = callGraph;
|
this.callGraph = callGraph;
|
||||||
|
|
||||||
final OrdinalSetMapping<PointerKey> pointerKeys = getPointerKeys(P);
|
final OrdinalSetMapping<PointerKey> pointerKeys = getPointerKeys();
|
||||||
final NumberedNodeManager<Object> nodeMgr = new NumberedNodeManager<Object>() {
|
final NumberedNodeManager<Object> nodeMgr = new NumberedNodeManager<Object>() {
|
||||||
public Iterator<Object> iterator() {
|
public Iterator<Object> iterator() {
|
||||||
return new CompoundIterator<Object>(pointerKeys.iterator(), P.getInstanceKeyMapping().iterator());
|
return new CompoundIterator<Object>(pointerKeys.iterator(), P.getInstanceKeyMapping().iterator());
|
||||||
|
@ -208,10 +208,7 @@ public class BasicHeapGraph extends HeapGraph {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private OrdinalSetMapping<PointerKey> getPointerKeys() {
|
||||||
*
|
|
||||||
*/
|
|
||||||
private OrdinalSetMapping<PointerKey> getPointerKeys(PointerAnalysis pointerAnalysis) {
|
|
||||||
MutableMapping<PointerKey> result = new MutableMapping<PointerKey>();
|
MutableMapping<PointerKey> result = new MutableMapping<PointerKey>();
|
||||||
|
|
||||||
for (Iterator<PointerKey> it = pointerAnalysis.getPointerKeys().iterator(); it.hasNext();) {
|
for (Iterator<PointerKey> it = pointerAnalysis.getPointerKeys().iterator(); it.hasNext();) {
|
||||||
|
|
|
@ -63,7 +63,6 @@ import com.ibm.wala.util.warnings.Warning;
|
||||||
import com.ibm.wala.util.warnings.WarningSet;
|
import com.ibm.wala.util.warnings.WarningSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* Logic to interpret "factory" methods in context.
|
* Logic to interpret "factory" methods in context.
|
||||||
*
|
*
|
||||||
* @author sfink
|
* @author sfink
|
||||||
|
@ -97,7 +96,7 @@ public class FactoryBypassInterpreter implements RTAContextInterpreter, SSAConte
|
||||||
/**
|
/**
|
||||||
* Keep track of analysis warnings
|
* Keep track of analysis warnings
|
||||||
*/
|
*/
|
||||||
private WarningSet warnings;
|
private WarningSet warningsSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User-defined reflection specification
|
* User-defined reflection specification
|
||||||
|
@ -113,7 +112,7 @@ public class FactoryBypassInterpreter implements RTAContextInterpreter, SSAConte
|
||||||
*/
|
*/
|
||||||
public FactoryBypassInterpreter(AnalysisOptions options, ReflectionSpecification userSpec, WarningSet warnings) {
|
public FactoryBypassInterpreter(AnalysisOptions options, ReflectionSpecification userSpec, WarningSet warnings) {
|
||||||
this.options = options;
|
this.options = options;
|
||||||
this.warnings = warnings;
|
this.warningsSet = warnings;
|
||||||
this.userSpec = userSpec;
|
this.userSpec = userSpec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,10 +338,10 @@ public class FactoryBypassInterpreter implements RTAContextInterpreter, SSAConte
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Trace.println("Found no implementors of type " + T);
|
Trace.println("Found no implementors of type " + T);
|
||||||
}
|
}
|
||||||
warnings.add(NoSubtypesWarning.create(T));
|
warningsSet.add(NoSubtypesWarning.create(T));
|
||||||
}
|
}
|
||||||
if (implementors.size() > CONE_BOUND) {
|
if (implementors.size() > CONE_BOUND) {
|
||||||
warnings.add(ManySubtypesWarning.create(T, implementors.size()));
|
warningsSet.add(ManySubtypesWarning.create(T, implementors.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
addStatementsForSetOfTypes(implementors.iterator());
|
addStatementsForSetOfTypes(implementors.iterator());
|
||||||
|
@ -355,10 +354,10 @@ public class FactoryBypassInterpreter implements RTAContextInterpreter, SSAConte
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Trace.println("Found no subclasses of type " + T);
|
Trace.println("Found no subclasses of type " + T);
|
||||||
}
|
}
|
||||||
warnings.add(NoSubtypesWarning.create(T));
|
warningsSet.add(NoSubtypesWarning.create(T));
|
||||||
}
|
}
|
||||||
if (subclasses.size() > CONE_BOUND) {
|
if (subclasses.size() > CONE_BOUND) {
|
||||||
warnings.add(ManySubtypesWarning.create(T, subclasses.size()));
|
warningsSet.add(ManySubtypesWarning.create(T, subclasses.size()));
|
||||||
}
|
}
|
||||||
addStatementsForSetOfTypes(subclasses.iterator());
|
addStatementsForSetOfTypes(subclasses.iterator());
|
||||||
}
|
}
|
||||||
|
@ -375,7 +374,7 @@ public class FactoryBypassInterpreter implements RTAContextInterpreter, SSAConte
|
||||||
private TypeAbstraction interceptType(TypeAbstraction T) {
|
private TypeAbstraction interceptType(TypeAbstraction T) {
|
||||||
TypeReference type = T.getType().getReference();
|
TypeReference type = T.getType().getReference();
|
||||||
if (type.equals(TypeReference.JavaIoSerializable)) {
|
if (type.equals(TypeReference.JavaIoSerializable)) {
|
||||||
warnings.add(IgnoreSerializableWarning.create());
|
warningsSet.add(IgnoreSerializableWarning.create());
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
return T;
|
return T;
|
||||||
|
@ -623,7 +622,7 @@ public class FactoryBypassInterpreter implements RTAContextInterpreter, SSAConte
|
||||||
* @see com.ibm.wala.ipa.callgraph.propagation.rta.RTAContextInterpreter#setWarnings(com.ibm.wala.util.warnings.WarningSet)
|
* @see com.ibm.wala.ipa.callgraph.propagation.rta.RTAContextInterpreter#setWarnings(com.ibm.wala.util.warnings.WarningSet)
|
||||||
*/
|
*/
|
||||||
public void setWarnings(WarningSet newWarnings) {
|
public void setWarnings(WarningSet newWarnings) {
|
||||||
this.warnings = newWarnings;
|
this.warningsSet = newWarnings;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -882,9 +882,9 @@ public abstract class AbstractIntStackMachine implements FixedPointConstants {
|
||||||
/**
|
/**
|
||||||
* Initialize the visitor used to perform the flow functions
|
* Initialize the visitor used to perform the flow functions
|
||||||
*/
|
*/
|
||||||
protected void init(BasicStackMachineVisitor visitor, com.ibm.wala.shrikeBT.Instruction.Visitor edgeVisitor) {
|
protected void init(BasicStackMachineVisitor v, com.ibm.wala.shrikeBT.Instruction.Visitor ev) {
|
||||||
this.visitor = visitor;
|
this.visitor = v;
|
||||||
this.edgeVisitor = edgeVisitor;
|
this.edgeVisitor = ev;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean needsNodeFlow() {
|
public boolean needsNodeFlow() {
|
||||||
|
|
|
@ -115,7 +115,7 @@ public class TypeInference extends SSAInference implements FixedPointConstants {
|
||||||
if (klass != null) {
|
if (klass != null) {
|
||||||
v.setType(new ConeType(klass));
|
v.setType(new ConeType(klass));
|
||||||
} else {
|
} else {
|
||||||
v.setType(ConeType.TOP);
|
v.setType(TypeAbstraction.TOP);
|
||||||
// v.setType(BOTTOM);
|
// v.setType(BOTTOM);
|
||||||
}
|
}
|
||||||
} else if (doPrimitives) {
|
} else if (doPrimitives) {
|
||||||
|
@ -432,13 +432,10 @@ public class TypeInference extends SSAInference implements FixedPointConstants {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
IClass klass = cha.lookupClass(elementType);
|
IClass klass = cha.lookupClass(elementType);
|
||||||
// if (Assertions.verifyAssertions) {
|
|
||||||
// Assertions._assert(klass != null);
|
|
||||||
// }
|
|
||||||
if (klass != null) {
|
if (klass != null) {
|
||||||
t.setType(new ConeType(klass));
|
t.setType(new ConeType(klass));
|
||||||
} else {
|
} else {
|
||||||
t.setType(ConeType.TOP);
|
t.setType(TypeAbstraction.TOP);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CHANGED;
|
return CHANGED;
|
||||||
|
@ -583,12 +580,11 @@ public class TypeInference extends SSAInference implements FixedPointConstants {
|
||||||
if (doPrimitives) {
|
if (doPrimitives) {
|
||||||
result = new DeclaredTypeOperator(PrimitiveType.BOOLEAN);
|
result = new DeclaredTypeOperator(PrimitiveType.BOOLEAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitGetCaughtException(SSAGetCaughtExceptionInstruction instruction) {
|
public void visitGetCaughtException(SSAGetCaughtExceptionInstruction instruction) {
|
||||||
TypeAbstraction type = meetDeclaredExceptionTypes(instruction, cha);
|
TypeAbstraction type = meetDeclaredExceptionTypes(instruction);
|
||||||
result = new DeclaredTypeOperator(type);
|
result = new DeclaredTypeOperator(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -602,7 +598,7 @@ public class TypeInference extends SSAInference implements FixedPointConstants {
|
||||||
result = piOp;
|
result = piOp;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TypeAbstraction meetDeclaredExceptionTypes(SSAGetCaughtExceptionInstruction s, IClassHierarchy cha) {
|
private TypeAbstraction meetDeclaredExceptionTypes(SSAGetCaughtExceptionInstruction s) {
|
||||||
ExceptionHandlerBasicBlock bb = (ExceptionHandlerBasicBlock) ir.getControlFlowGraph().getNode(s.getBasicBlockNumber());
|
ExceptionHandlerBasicBlock bb = (ExceptionHandlerBasicBlock) ir.getControlFlowGraph().getNode(s.getBasicBlockNumber());
|
||||||
Iterator it = bb.getCaughtExceptionTypes();
|
Iterator it = bb.getCaughtExceptionTypes();
|
||||||
TypeReference t = (TypeReference) it.next();
|
TypeReference t = (TypeReference) it.next();
|
||||||
|
|
|
@ -75,7 +75,7 @@ public class CFGCache {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
processResetLogic(m);
|
processResetLogic();
|
||||||
|
|
||||||
Pair<IMethod,Context> p = new Pair<IMethod,Context>(m, C);
|
Pair<IMethod,Context> p = new Pair<IMethod,Context>(m, C);
|
||||||
Object ref = dictionary.get(p);
|
Object ref = dictionary.get(p);
|
||||||
|
@ -90,7 +90,7 @@ public class CFGCache {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processResetLogic(IMethod m) {
|
private void processResetLogic() {
|
||||||
resetCount++;
|
resetCount++;
|
||||||
if (resetCount == RESET_INTERVAL) {
|
if (resetCount == RESET_INTERVAL) {
|
||||||
reset();
|
reset();
|
||||||
|
|
|
@ -48,7 +48,7 @@ public class ArrayClass implements IClass, Constants {
|
||||||
if (Assertions.verifyAssertions) {
|
if (Assertions.verifyAssertions) {
|
||||||
TypeReference elementType = type.getInnermostElementType();
|
TypeReference elementType = type.getInnermostElementType();
|
||||||
if (!elementType.isPrimitiveType()) {
|
if (!elementType.isPrimitiveType()) {
|
||||||
IClass klass = loader.lookupClass(elementType.getName(), cha);
|
IClass klass = loader.lookupClass(elementType.getName());
|
||||||
if (klass == null) {
|
if (klass == null) {
|
||||||
Assertions.UNREACHABLE("caller should not attempt to create an array with type " + type);
|
Assertions.UNREACHABLE("caller should not attempt to create an array with type " + type);
|
||||||
}
|
}
|
||||||
|
@ -114,14 +114,14 @@ public class ArrayClass implements IClass, Constants {
|
||||||
// 1) [Ljava/lang/Object
|
// 1) [Ljava/lang/Object
|
||||||
// 2) [? for primitive arrays (null from getElementClass)
|
// 2) [? for primitive arrays (null from getElementClass)
|
||||||
if (elt == null || elt.getReference() == TypeReference.JavaLangObject) {
|
if (elt == null || elt.getReference() == TypeReference.JavaLangObject) {
|
||||||
return loader.lookupClass(TypeReference.JavaLangObject.getName(), getClassHierarchy());
|
return loader.lookupClass(TypeReference.JavaLangObject.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
// else it is array of super of element type (yuck)
|
// else it is array of super of element type (yuck)
|
||||||
else {
|
else {
|
||||||
TypeReference eltSuperRef = elt.getSuperclass().getReference();
|
TypeReference eltSuperRef = elt.getSuperclass().getReference();
|
||||||
TypeReference superRef = TypeReference.findOrCreateArrayOf(eltSuperRef);
|
TypeReference superRef = TypeReference.findOrCreateArrayOf(eltSuperRef);
|
||||||
return elt.getSuperclass().getClassLoader().lookupClass(superRef.getName(), getClassHierarchy());
|
return elt.getSuperclass().getClassLoader().lookupClass(superRef.getName());
|
||||||
}
|
}
|
||||||
} catch (ClassHierarchyException e) {
|
} catch (ClassHierarchyException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -134,7 +134,7 @@ public class ArrayClass implements IClass, Constants {
|
||||||
* @see com.ibm.wala.classLoader.IClass#getMethod(com.ibm.wala.classLoader.Selector)
|
* @see com.ibm.wala.classLoader.IClass#getMethod(com.ibm.wala.classLoader.Selector)
|
||||||
*/
|
*/
|
||||||
public IMethod getMethod(Selector sig) {
|
public IMethod getMethod(Selector sig) {
|
||||||
return loader.lookupClass(TypeReference.JavaLangObject.getName(), getClassHierarchy()).getMethod(sig);
|
return loader.lookupClass(TypeReference.JavaLangObject.getName()).getMethod(sig);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IField getField(Atom name) {
|
public IField getField(Atom name) {
|
||||||
|
@ -194,7 +194,7 @@ public class ArrayClass implements IClass, Constants {
|
||||||
if (elementType.isPrimitiveType()) {
|
if (elementType.isPrimitiveType()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return loader.lookupClass(elementType.getName(), getClassHierarchy());
|
return loader.lookupClass(elementType.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -223,8 +223,8 @@ public class ArrayClass implements IClass, Constants {
|
||||||
*/
|
*/
|
||||||
public Collection<IClass> getAllImplementedInterfaces() {
|
public Collection<IClass> getAllImplementedInterfaces() {
|
||||||
HashSet<IClass> result = HashSetFactory.make(2);
|
HashSet<IClass> result = HashSetFactory.make(2);
|
||||||
result.add(loader.lookupClass(TypeReference.array_interfaces[0], getClassHierarchy()));
|
result.add(loader.lookupClass(TypeReference.array_interfaces[0]));
|
||||||
result.add(loader.lookupClass(TypeReference.array_interfaces[1], getClassHierarchy()));
|
result.add(loader.lookupClass(TypeReference.array_interfaces[1]));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,7 +256,7 @@ public class ArrayClass implements IClass, Constants {
|
||||||
if (elementType.isPrimitiveType()) {
|
if (elementType.isPrimitiveType()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return loader.lookupClass(elementType.getName(), getClassHierarchy());
|
return loader.lookupClass(elementType.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -62,7 +62,7 @@ public class ArrayClassLoader {
|
||||||
arrayClass = arrayClasses.get(type);
|
arrayClass = arrayClasses.get(type);
|
||||||
if (arrayClass == null) {
|
if (arrayClass == null) {
|
||||||
// check that the element class is loadable. If not, return null.
|
// check that the element class is loadable. If not, return null.
|
||||||
IClass elementCls = delegator.lookupClass(elementType.getName(), cha);
|
IClass elementCls = delegator.lookupClass(elementType.getName());
|
||||||
if (elementCls == null) {
|
if (elementCls == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,6 +96,7 @@ public class ClassLoaderFactoryImpl implements ClassLoaderFactory {
|
||||||
cl = new ClassLoaderImpl(classLoaderReference, scope.getArrayClassLoader(), parent, exclusions, cha, warnings);
|
cl = new ClassLoaderImpl(classLoaderReference, scope.getArrayClassLoader(), parent, exclusions, cha, warnings);
|
||||||
} else
|
} else
|
||||||
try {
|
try {
|
||||||
|
// this is fragile. why are we doing things this way again?
|
||||||
Class<?> impl = Class.forName(implClass);
|
Class<?> impl = Class.forName(implClass);
|
||||||
Constructor<?> ctor = impl.getDeclaredConstructor(new Class[] { ClassLoaderReference.class, IClassLoader.class,
|
Constructor<?> ctor = impl.getDeclaredConstructor(new Class[] { ClassLoaderReference.class, IClassLoader.class,
|
||||||
SetOfClasses.class, IClassHierarchy.class, WarningSet.class });
|
SetOfClasses.class, IClassHierarchy.class, WarningSet.class });
|
||||||
|
@ -109,8 +110,6 @@ public class ClassLoaderFactoryImpl implements ClassLoaderFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author sfink
|
|
||||||
*
|
|
||||||
* A waring when we fail to load an appropriate class loader implementation
|
* A waring when we fail to load an appropriate class loader implementation
|
||||||
*/
|
*/
|
||||||
private static class InvalidClassLoaderImplementation extends Warning {
|
private static class InvalidClassLoaderImplementation extends Warning {
|
||||||
|
|
|
@ -400,7 +400,7 @@ public class ClassLoaderImpl implements IClassLoader {
|
||||||
return loadedClasses.get(className);
|
return loadedClasses.get(className);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IClass lookupClass(TypeName className, IClassHierarchy cha) {
|
public IClass lookupClass(TypeName className) {
|
||||||
if (className == null) {
|
if (className == null) {
|
||||||
throw new IllegalArgumentException("className is null");
|
throw new IllegalArgumentException("className is null");
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@ import java.util.Collection;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
|
||||||
import com.ibm.wala.types.ClassLoaderReference;
|
import com.ibm.wala.types.ClassLoaderReference;
|
||||||
import com.ibm.wala.types.TypeName;
|
import com.ibm.wala.types.TypeName;
|
||||||
import com.ibm.wala.util.Atom;
|
import com.ibm.wala.util.Atom;
|
||||||
|
@ -37,7 +36,7 @@ public interface IClassLoader {
|
||||||
* @return the IClass defined by this class loader that
|
* @return the IClass defined by this class loader that
|
||||||
* corresponds to the given class name, or null if not found.
|
* corresponds to the given class name, or null if not found.
|
||||||
*/
|
*/
|
||||||
public abstract IClass lookupClass(TypeName className, IClassHierarchy cha);
|
public abstract IClass lookupClass(TypeName className);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the ClassLoaderReference for this class loader.
|
* Return the ClassLoaderReference for this class loader.
|
||||||
|
@ -46,7 +45,7 @@ public interface IClassLoader {
|
||||||
public abstract ClassLoaderReference getReference();
|
public abstract ClassLoaderReference getReference();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return an Iterator of all classees loaded by this loader
|
* @return an Iterator of all classes loaded by this loader
|
||||||
*/
|
*/
|
||||||
public abstract Iterator<IClass> iterateAllClasses();
|
public abstract Iterator<IClass> iterateAllClasses();
|
||||||
|
|
||||||
|
|
|
@ -284,12 +284,12 @@ public final class ShrikeClass implements IClass {
|
||||||
|
|
||||||
if (superName == null) {
|
if (superName == null) {
|
||||||
if (!getReference().equals(TypeReference.JavaLangObject)) {
|
if (!getReference().equals(TypeReference.JavaLangObject)) {
|
||||||
superClass = loader.lookupClass(TypeReference.JavaLangObject.getName(), getClassHierarchy());
|
superClass = loader.lookupClass(TypeReference.JavaLangObject.getName());
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
superClass = loader.lookupClass(TypeName.findOrCreate(superName), getClassHierarchy());
|
superClass = loader.lookupClass(TypeName.findOrCreate(superName));
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Trace.println("got superclass " + superClass + " for " + this);
|
Trace.println("got superclass " + superClass + " for " + this);
|
||||||
}
|
}
|
||||||
|
@ -387,7 +387,7 @@ public final class ShrikeClass implements IClass {
|
||||||
for (int i = 0; i < interfaces.length; i++) {
|
for (int i = 0; i < interfaces.length; i++) {
|
||||||
ImmutableByteArray name = interfaces[i];
|
ImmutableByteArray name = interfaces[i];
|
||||||
IClass klass = null;
|
IClass klass = null;
|
||||||
klass = loader.lookupClass(TypeName.findOrCreate(name), getClassHierarchy());
|
klass = loader.lookupClass(TypeName.findOrCreate(name));
|
||||||
if (klass == null) {
|
if (klass == null) {
|
||||||
warnings.add(ClassNotFoundWarning.create(name));
|
warnings.add(ClassNotFoundWarning.create(name));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -104,7 +104,7 @@ public class ShrikeIRFactory implements IRFactory {
|
||||||
|
|
||||||
{
|
{
|
||||||
SSABuilder builder = new SSABuilder((ShrikeCTMethod) method, newCfg, shrikeCFG, newInstrs, symbolTable, buildLocalMap,
|
SSABuilder builder = new SSABuilder((ShrikeCTMethod) method, newCfg, shrikeCFG, newInstrs, symbolTable, buildLocalMap,
|
||||||
options.getUsePiNodes(), warnings);
|
options.getUsePiNodes());
|
||||||
builder.build();
|
builder.build();
|
||||||
if (buildLocalMap)
|
if (buildLocalMap)
|
||||||
localMap = builder.getLocalMap();
|
localMap = builder.getLocalMap();
|
||||||
|
|
|
@ -24,6 +24,7 @@ import com.ibm.wala.types.TypeReference;
|
||||||
import com.ibm.wala.util.Atom;
|
import com.ibm.wala.util.Atom;
|
||||||
import com.ibm.wala.util.bytecode.BytecodeStream;
|
import com.ibm.wala.util.bytecode.BytecodeStream;
|
||||||
import com.ibm.wala.util.debug.Assertions;
|
import com.ibm.wala.util.debug.Assertions;
|
||||||
|
import com.ibm.wala.util.debug.UnimplementedError;
|
||||||
import com.ibm.wala.util.warnings.WarningSet;
|
import com.ibm.wala.util.warnings.WarningSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -237,16 +238,22 @@ public class SyntheticMethod implements IMethod {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param options options governing SSA construction
|
||||||
|
*/
|
||||||
public SSAInstruction[] getStatements(SSAOptions options) {
|
public SSAInstruction[] getStatements(SSAOptions options) {
|
||||||
return NO_STATEMENTS;
|
return NO_STATEMENTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* @see com.ibm.wala.classLoader.IMethod#getIR(com.ibm.wala.util.WarningSet)
|
/**
|
||||||
|
* Most subclasses should override this.
|
||||||
|
*
|
||||||
|
* @param options options governing IR conversion
|
||||||
|
* @param warnings object to record analysis warnings
|
||||||
*/
|
*/
|
||||||
public IR makeIR(SSAOptions options, WarningSet warnings) {
|
public IR makeIR(SSAOptions options, WarningSet warnings) throws UnimplementedError {
|
||||||
Assertions.UNREACHABLE("haven't implemented IR yet for class " + getClass());
|
throw new UnimplementedError("haven't implemented IR yet for class " + getClass());
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -419,17 +419,16 @@ public class ExplodedSupergraphPath<T> {
|
||||||
*/
|
*/
|
||||||
public static <T> ExplodedSupergraphPath<T> summarize(ISupergraph<T,?> supergraph, ExplodedSupergraphPath<T> path) {
|
public static <T> ExplodedSupergraphPath<T> summarize(ISupergraph<T,?> supergraph, ExplodedSupergraphPath<T> path) {
|
||||||
pruneForCallReturn(supergraph, path);
|
pruneForCallReturn(supergraph, path);
|
||||||
// System.err.println("pruned path A: " + p);
|
pruneBoringCalls(path);
|
||||||
pruneBoringCalls(supergraph, path);
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a brief(er) summary of a path, which excludes call/return pairs in
|
* Create a briefer summary of a path, which excludes call/return pairs in
|
||||||
* which no state transitions occur
|
* which no state transitions occur
|
||||||
* @throws IllegalArgumentException if path is null
|
* @throws IllegalArgumentException if path is null
|
||||||
*/
|
*/
|
||||||
public static <T> void pruneBoringCalls(ISupergraph supergraph, ExplodedSupergraphPath<T> path) {
|
public static <T> void pruneBoringCalls(ExplodedSupergraphPath<T> path) {
|
||||||
if (path == null) {
|
if (path == null) {
|
||||||
throw new IllegalArgumentException("path is null");
|
throw new IllegalArgumentException("path is null");
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,17 +97,6 @@ public class PartiallyCollapsedSupergraph extends AbstractGraph<Object> implemen
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @param cg
|
|
||||||
* Governing call graph
|
|
||||||
* @param noCollapse
|
|
||||||
* set of nodes in the call graph which cannot be collapsed
|
|
||||||
* @param warnings
|
|
||||||
* object to track analysis warnings
|
|
||||||
*/
|
|
||||||
public PartiallyCollapsedSupergraph(CallGraph cg, CFGCache cfgCache, Collection<CGNode> noCollapse, WarningSet warnings) {
|
|
||||||
this(cg, noCollapse, IndiscriminateFilter.singleton(), warnings);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param cg
|
* @param cg
|
||||||
|
|
|
@ -84,7 +84,7 @@ public class EMFScopeWrapper extends AnalysisScope {
|
||||||
|
|
||||||
private final String scopeFile;
|
private final String scopeFile;
|
||||||
|
|
||||||
private final ClassLoader loader;
|
private final ClassLoader classloader;
|
||||||
|
|
||||||
private static final Object SUCCESS = new Object();
|
private static final Object SUCCESS = new Object();
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ public class EMFScopeWrapper extends AnalysisScope {
|
||||||
* files provided)
|
* files provided)
|
||||||
*/
|
*/
|
||||||
protected EMFScopeWrapper(final ClassLoader loader) {
|
protected EMFScopeWrapper(final ClassLoader loader) {
|
||||||
this.loader = loader;
|
this.classloader = loader;
|
||||||
this.scopeFile = null;
|
this.scopeFile = null;
|
||||||
this.exclusionsFile = null;
|
this.exclusionsFile = null;
|
||||||
}
|
}
|
||||||
|
@ -108,7 +108,7 @@ public class EMFScopeWrapper extends AnalysisScope {
|
||||||
public EMFScopeWrapper(String scopeFile, String exclusionsFile, ClassLoader loader, boolean scopeAsFile) {
|
public EMFScopeWrapper(String scopeFile, String exclusionsFile, ClassLoader loader, boolean scopeAsFile) {
|
||||||
super();
|
super();
|
||||||
this.scopeFile = scopeFile;
|
this.scopeFile = scopeFile;
|
||||||
this.loader = loader;
|
this.classloader = loader;
|
||||||
|
|
||||||
if (DEBUG_LEVEL > 0) {
|
if (DEBUG_LEVEL > 0) {
|
||||||
Trace.println(getClass() + " ctor " + scopeFile);
|
Trace.println(getClass() + " ctor " + scopeFile);
|
||||||
|
@ -164,9 +164,7 @@ public class EMFScopeWrapper extends AnalysisScope {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param m
|
|
||||||
*/
|
|
||||||
private void processModule(EModule m, final ClassLoaderReference loader) {
|
private void processModule(EModule m, final ClassLoaderReference loader) {
|
||||||
JavaScopeSwitch sw = new JavaScopeSwitch() {
|
JavaScopeSwitch sw = new JavaScopeSwitch() {
|
||||||
|
|
||||||
|
@ -356,7 +354,7 @@ public class EMFScopeWrapper extends AnalysisScope {
|
||||||
* @return an EMF scope object
|
* @return an EMF scope object
|
||||||
*/
|
*/
|
||||||
private EJavaAnalysisScope readScope() {
|
private EJavaAnalysisScope readScope() {
|
||||||
InputStream s = loader.getResourceAsStream(scopeFile);
|
InputStream s = classloader.getResourceAsStream(scopeFile);
|
||||||
if (s == null) {
|
if (s == null) {
|
||||||
Assertions.UNREACHABLE("failed to open scope file: " + scopeFile);
|
Assertions.UNREACHABLE("failed to open scope file: " + scopeFile);
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,7 @@ public class FILiveObjectAnalysis implements ILiveObjectAnalysis {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean mayBeLive(CGNode allocMethod, int allocPC, CGNode m, int instructionIndex) throws WalaException {
|
public boolean mayBeLive(CGNode allocMethod, int allocPC, CGNode m, int instructionIndex) throws WalaException {
|
||||||
NewSiteReference site = TrivialMethodEscape.findAlloc(callGraph, allocMethod, allocPC);
|
NewSiteReference site = TrivialMethodEscape.findAlloc(allocMethod, allocPC);
|
||||||
InstanceKey ik = heapGraph.getHeapModel().getInstanceKeyForAllocation(allocMethod, site);
|
InstanceKey ik = heapGraph.getHeapModel().getInstanceKeyForAllocation(allocMethod, site);
|
||||||
return mayBeLive(ik, m, instructionIndex);
|
return mayBeLive(ik, m, instructionIndex);
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,7 +98,7 @@ public class TrivialMethodEscape implements IMethodEscapeAnalysis, INodeEscapeAn
|
||||||
// instances := set of instance key allocated at <allocMethod, allocPC>
|
// instances := set of instance key allocated at <allocMethod, allocPC>
|
||||||
for (Iterator it = allocN.iterator(); it.hasNext();) {
|
for (Iterator it = allocN.iterator(); it.hasNext();) {
|
||||||
CGNode n = (CGNode) it.next();
|
CGNode n = (CGNode) it.next();
|
||||||
NewSiteReference site = findAlloc(cg, n, allocPC);
|
NewSiteReference site = findAlloc(n, allocPC);
|
||||||
InstanceKey ik = hg.getHeapModel().getInstanceKeyForAllocation(n, site);
|
InstanceKey ik = hg.getHeapModel().getInstanceKeyForAllocation(n, site);
|
||||||
if (ik == null) {
|
if (ik == null) {
|
||||||
throw new WalaException("could not get instance key at site " + site + " in " + n);
|
throw new WalaException("could not get instance key at site " + site + " in " + n);
|
||||||
|
@ -138,7 +138,7 @@ public class TrivialMethodEscape implements IMethodEscapeAnalysis, INodeEscapeAn
|
||||||
* @return the NewSiteReference for the allocation
|
* @return the NewSiteReference for the allocation
|
||||||
* @throws WalaException
|
* @throws WalaException
|
||||||
*/
|
*/
|
||||||
static NewSiteReference findAlloc(CallGraph cg, CGNode n, int allocPC) throws WalaException {
|
static NewSiteReference findAlloc(CGNode n, int allocPC) throws WalaException {
|
||||||
for (Iterator it = n.iterateNewSites(); it.hasNext();) {
|
for (Iterator it = n.iterateNewSites(); it.hasNext();) {
|
||||||
NewSiteReference site = (NewSiteReference) it.next();
|
NewSiteReference site = (NewSiteReference) it.next();
|
||||||
if (site.getProgramCounter() == allocPC) {
|
if (site.getProgramCounter() == allocPC) {
|
||||||
|
|
|
@ -214,12 +214,6 @@ public class AnalysisScope {
|
||||||
return loadersByName.get(name);
|
return loadersByName.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method classLoaderName2Ref.
|
|
||||||
*
|
|
||||||
* @param clName
|
|
||||||
* @return ClassLoaderReference
|
|
||||||
*/
|
|
||||||
protected ClassLoaderReference classLoaderName2Ref(String clName) {
|
protected ClassLoaderReference classLoaderName2Ref(String clName) {
|
||||||
return getLoader(Atom.findOrCreateUnicodeAtom(clName));
|
return getLoader(Atom.findOrCreateUnicodeAtom(clName));
|
||||||
}
|
}
|
||||||
|
@ -235,16 +229,10 @@ public class AnalysisScope {
|
||||||
loaderImplByRef.put(ref, implClass);
|
loaderImplByRef.put(ref, implClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return an Iterator <ClassLoaderReference>over the loaders.
|
|
||||||
*/
|
|
||||||
public Collection<ClassLoaderReference> getLoaders() {
|
public Collection<ClassLoaderReference> getLoaders() {
|
||||||
return Collections.unmodifiableCollection(loadersByName.values());
|
return Collections.unmodifiableCollection(loadersByName.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the number of loaders.
|
|
||||||
*/
|
|
||||||
public int getNumberOfLoaders() {
|
public int getNumberOfLoaders() {
|
||||||
return loadersByName.values().size();
|
return loadersByName.values().size();
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,20 +131,20 @@ public abstract class Entrypoint implements BytecodeConstants {
|
||||||
TypeAbstraction a;
|
TypeAbstraction a;
|
||||||
if (p[0].isPrimitiveType()) {
|
if (p[0].isPrimitiveType()) {
|
||||||
a = PrimitiveType.getPrimitive(p[0]);
|
a = PrimitiveType.getPrimitive(p[0]);
|
||||||
for(i = 1; i < p.length; i++) {
|
for (i = 1; i < p.length; i++) {
|
||||||
a = a.meet(PrimitiveType.getPrimitive(p[i]));
|
a = a.meet(PrimitiveType.getPrimitive(p[i]));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
IClassHierarchy cha = m.getClassHierarchy();
|
IClassHierarchy cha = m.getClassHierarchy();
|
||||||
IClass p0 = cha.lookupClass(p[0]);
|
IClass p0 = cha.lookupClass(p[0]);
|
||||||
a = new ConeType(p0);
|
a = new ConeType(p0);
|
||||||
for(i = 1; i < p.length; i++) {
|
for (i = 1; i < p.length; i++) {
|
||||||
IClass pi = cha.lookupClass(p[i]);
|
IClass pi = cha.lookupClass(p[i]);
|
||||||
a = a.meet(new ConeType(pi));
|
a = a.meet(new ConeType(pi));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return m.addPhi(a.getTypeReference(), values);
|
return m.addPhi(values);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -226,7 +226,7 @@ public abstract class AbstractRootMethod extends SyntheticMethod {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int addPhi(TypeReference type, int[] values) {
|
public int addPhi(int[] values) {
|
||||||
int result = nextLocal++;
|
int result = nextLocal++;
|
||||||
SSAPhiInstruction phi = new SSAPhiInstruction(result, values);
|
SSAPhiInstruction phi = new SSAPhiInstruction(result, values);
|
||||||
statements.add(phi);
|
statements.add(phi);
|
||||||
|
|
|
@ -344,7 +344,11 @@ public abstract class BasicCallGraph extends AbstractNumberedGraph<CGNode> imple
|
||||||
return (result == null) ? empty : result;
|
return (result == null) ? empty : result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SSAContextInterpreter getInterpreter(CGNode node) {
|
/**
|
||||||
|
* @param node a call graph node we want information about
|
||||||
|
* @return an object that knows how to interpret information about the node
|
||||||
|
*/
|
||||||
|
protected SSAContextInterpreter getInterpreter(CGNode node) {
|
||||||
return interpreter;
|
return interpreter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -828,9 +828,9 @@ public class Util {
|
||||||
|
|
||||||
return new ZeroOneContainerCFABuilder(cha, warnings, options, appSelector, appInterpreter, options.getReflectionSpec()) {
|
return new ZeroOneContainerCFABuilder(cha, warnings, options, appSelector, appInterpreter, options.getReflectionSpec()) {
|
||||||
@Override
|
@Override
|
||||||
protected ZeroXInstanceKeys makeInstanceKeys(IClassHierarchy cha, WarningSet warnings, AnalysisOptions options,
|
protected ZeroXInstanceKeys makeInstanceKeys(IClassHierarchy c, WarningSet w, AnalysisOptions o,
|
||||||
SSAContextInterpreter contextInterpreter) {
|
SSAContextInterpreter contextInterpreter) {
|
||||||
ZeroXInstanceKeys zik = new ZeroXInstanceKeys(options, cha, contextInterpreter, warnings, ZeroXInstanceKeys.ALLOCATIONS);
|
ZeroXInstanceKeys zik = new ZeroXInstanceKeys(o, c, contextInterpreter, w, ZeroXInstanceKeys.ALLOCATIONS);
|
||||||
return zik;
|
return zik;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,21 +13,13 @@ package com.ibm.wala.ipa.callgraph.propagation;
|
||||||
import com.ibm.wala.fixedpoint.impl.AbstractOperator;
|
import com.ibm.wala.fixedpoint.impl.AbstractOperator;
|
||||||
import com.ibm.wala.fixedpoint.impl.UnaryStatement;
|
import com.ibm.wala.fixedpoint.impl.UnaryStatement;
|
||||||
import com.ibm.wala.fixpoint.IVariable;
|
import com.ibm.wala.fixpoint.IVariable;
|
||||||
import com.ibm.wala.fixpoint.IntSetVariable;
|
|
||||||
import com.ibm.wala.util.debug.VerboseAction;
|
|
||||||
import com.ibm.wala.util.intset.IntSet;
|
|
||||||
import com.ibm.wala.util.intset.IntSetUtil;
|
|
||||||
import com.ibm.wala.util.intset.MutableSharedBitVectorIntSet;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* A specialized equation class introduced for efficiency
|
||||||
* A apecialized equation class introduced for efficiency
|
|
||||||
*
|
*
|
||||||
* @author sfink
|
* @author sfink
|
||||||
*/
|
*/
|
||||||
public final class AssignEquation extends UnaryStatement implements VerboseAction {
|
public final class AssignEquation extends UnaryStatement {
|
||||||
|
|
||||||
private final boolean DEBUG = false;
|
|
||||||
|
|
||||||
AssignEquation(IVariable lhs, IVariable rhs) {
|
AssignEquation(IVariable lhs, IVariable rhs) {
|
||||||
super(lhs, rhs);
|
super(lhs, rhs);
|
||||||
|
@ -47,24 +39,4 @@ public final class AssignEquation extends UnaryStatement implements VerboseActio
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void performVerboseAction() {
|
|
||||||
if (DEBUG) {
|
|
||||||
IntSetVariable lhs = (IntSetVariable) getLHS();
|
|
||||||
IntSetVariable rhs = (IntSetVariable) getRightHandSide();
|
|
||||||
System.err.println("LHS " + ((lhs.getValue() == null) ? "null" : lhs.getValue().getClass().toString()));
|
|
||||||
System.err.println("RHS " + ((rhs.getValue() == null) ? "null" : rhs.getValue().getClass().toString()));
|
|
||||||
if (lhs.getValue() instanceof MutableSharedBitVectorIntSet) {
|
|
||||||
if (rhs.getValue() instanceof MutableSharedBitVectorIntSet) {
|
|
||||||
MutableSharedBitVectorIntSet a = (MutableSharedBitVectorIntSet) lhs.getValue();
|
|
||||||
MutableSharedBitVectorIntSet b = (MutableSharedBitVectorIntSet) rhs.getValue();
|
|
||||||
System.err.println("Shared? " + MutableSharedBitVectorIntSet.sameSharedPart(a, b));
|
|
||||||
IntSet diff = IntSetUtil.diff(a,b);
|
|
||||||
System.err.println("Diff a/b" + diff.size() + " " + diff);
|
|
||||||
diff = IntSetUtil.diff(b,a);
|
|
||||||
System.err.println("Diff b/a" + diff.size() + " " + diff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -345,7 +345,7 @@ public class PointerAnalysisImpl extends AbstractPointerAnalysis {
|
||||||
OrdinalSet ep = getPointsToSet(e);
|
OrdinalSet ep = getPointsToSet(e);
|
||||||
for (Iterator it2 = ep.iterator(); it2.hasNext();) {
|
for (Iterator it2 = ep.iterator(); it2.hasNext();) {
|
||||||
InstanceKey ik = (InstanceKey) it2.next();
|
InstanceKey ik = (InstanceKey) it2.next();
|
||||||
if (SSAPropagationCallGraphBuilder.catches(caughtTypes, ik.getConcreteType(), getCallGraph().getClassHierarchy())) {
|
if (PropagationCallGraphBuilder.catches(caughtTypes, ik.getConcreteType(), getCallGraph().getClassHierarchy())) {
|
||||||
S.add(instanceKeys.getMappedIndex(ik));
|
S.add(instanceKeys.getMappedIndex(ik));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -362,7 +362,7 @@ public class PointerAnalysisImpl extends AbstractPointerAnalysis {
|
||||||
InstanceKey ik = SSAPropagationCallGraphBuilder.getInstanceKeyForPEI(node, peiLoc, type, iKeyFactory);
|
InstanceKey ik = SSAPropagationCallGraphBuilder.getInstanceKeyForPEI(node, peiLoc, type, iKeyFactory);
|
||||||
ConcreteTypeKey ck = (ConcreteTypeKey) ik;
|
ConcreteTypeKey ck = (ConcreteTypeKey) ik;
|
||||||
IClass klass = ck.getType();
|
IClass klass = ck.getType();
|
||||||
if (SSAPropagationCallGraphBuilder.catches(caughtTypes, klass, getCallGraph().getClassHierarchy())) {
|
if (PropagationCallGraphBuilder.catches(caughtTypes, klass, getCallGraph().getClassHierarchy())) {
|
||||||
S.add(instanceKeys.getMappedIndex(SSAPropagationCallGraphBuilder
|
S.add(instanceKeys.getMappedIndex(SSAPropagationCallGraphBuilder
|
||||||
.getInstanceKeyForPEI(node, peiLoc, type, iKeyFactory)));
|
.getInstanceKeyForPEI(node, peiLoc, type, iKeyFactory)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -209,7 +209,7 @@ public class PointerFlowGraph extends AbstractGraph<PointerKey> {
|
||||||
Assertions._assert(!processedNodes.contains(node));
|
Assertions._assert(!processedNodes.contains(node));
|
||||||
}
|
}
|
||||||
processedNodes.add(node);
|
processedNodes.add(node);
|
||||||
IR ir = getIR(cg, node);
|
IR ir = getIR(node);
|
||||||
if (ir != null) {
|
if (ir != null) {
|
||||||
visit(node, ir);
|
visit(node, ir);
|
||||||
} else {
|
} else {
|
||||||
|
@ -217,7 +217,7 @@ public class PointerFlowGraph extends AbstractGraph<PointerKey> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IR getIR(CallGraph cg, CGNode node) {
|
private static IR getIR(CGNode node) {
|
||||||
wipeCount++;
|
wipeCount++;
|
||||||
if (wipeCount > WIPE_THRESHOLD) {
|
if (wipeCount > WIPE_THRESHOLD) {
|
||||||
wipeCount = 0;
|
wipeCount = 0;
|
||||||
|
@ -465,7 +465,7 @@ public class PointerFlowGraph extends AbstractGraph<PointerKey> {
|
||||||
CGNode target = (CGNode) it.next();
|
CGNode target = (CGNode) it.next();
|
||||||
|
|
||||||
// some methods, like unmodelled natives, do not have IR.
|
// some methods, like unmodelled natives, do not have IR.
|
||||||
if (getIR(cg, target) == null)
|
if (getIR(target) == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// handle parameter passing
|
// handle parameter passing
|
||||||
|
|
|
@ -483,7 +483,7 @@ public class PropagationSystem extends DefaultFixedPointSolver {
|
||||||
for (int i = 1; i < dim; i++) {
|
for (int i = 1; i < dim; i++) {
|
||||||
TypeReference jlo = makeArray(TypeReference.JavaLangObject, i);
|
TypeReference jlo = makeArray(TypeReference.JavaLangObject, i);
|
||||||
IClass jloClass = null;
|
IClass jloClass = null;
|
||||||
jloClass = aClass.getClassLoader().lookupClass(jlo.getName(), aClass.getClassHierarchy());
|
jloClass = aClass.getClassLoader().lookupClass(jlo.getName());
|
||||||
MutableIntSet set = findOrCreateSparseSetForClass(jloClass);
|
MutableIntSet set = findOrCreateSparseSetForClass(jloClass);
|
||||||
set.add(index);
|
set.add(index);
|
||||||
}
|
}
|
||||||
|
@ -502,7 +502,7 @@ public class PropagationSystem extends DefaultFixedPointSolver {
|
||||||
IClass I = (IClass) it.next();
|
IClass I = (IClass) it.next();
|
||||||
TypeReference iArrayRef = makeArray(I.getReference(), dim);
|
TypeReference iArrayRef = makeArray(I.getReference(), dim);
|
||||||
IClass iArrayClass = null;
|
IClass iArrayClass = null;
|
||||||
iArrayClass = I.getClassLoader().lookupClass(iArrayRef.getName(), I.getClassHierarchy());
|
iArrayClass = I.getClassLoader().lookupClass(iArrayRef.getName());
|
||||||
MutableIntSet set = findOrCreateSparseSetForClass(iArrayClass);
|
MutableIntSet set = findOrCreateSparseSetForClass(iArrayClass);
|
||||||
set.add(index);
|
set.add(index);
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
|
@ -527,7 +527,7 @@ public class PropagationSystem extends DefaultFixedPointSolver {
|
||||||
while (T != null) {
|
while (T != null) {
|
||||||
TypeReference tArrayRef = makeArray(T.getReference(), dim);
|
TypeReference tArrayRef = makeArray(T.getReference(), dim);
|
||||||
IClass tArrayClass = null;
|
IClass tArrayClass = null;
|
||||||
tArrayClass = T.getClassLoader().lookupClass(tArrayRef.getName(), T.getClassHierarchy());
|
tArrayClass = T.getClassLoader().lookupClass(tArrayRef.getName());
|
||||||
MutableIntSet set = findOrCreateSparseSetForClass(tArrayClass);
|
MutableIntSet set = findOrCreateSparseSetForClass(tArrayClass);
|
||||||
set.add(index);
|
set.add(index);
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
|
|
|
@ -21,19 +21,24 @@ import com.ibm.wala.analysis.reflection.CloneInterpreter;
|
||||||
import com.ibm.wala.analysis.reflection.Malleable;
|
import com.ibm.wala.analysis.reflection.Malleable;
|
||||||
import com.ibm.wala.cfg.ControlFlowGraph;
|
import com.ibm.wala.cfg.ControlFlowGraph;
|
||||||
import com.ibm.wala.cfg.IBasicBlock;
|
import com.ibm.wala.cfg.IBasicBlock;
|
||||||
import com.ibm.wala.classLoader.*;
|
import com.ibm.wala.classLoader.ArrayClass;
|
||||||
|
import com.ibm.wala.classLoader.CallSiteReference;
|
||||||
|
import com.ibm.wala.classLoader.IClass;
|
||||||
|
import com.ibm.wala.classLoader.IField;
|
||||||
|
import com.ibm.wala.classLoader.IMethod;
|
||||||
|
import com.ibm.wala.classLoader.NewSiteReference;
|
||||||
|
import com.ibm.wala.classLoader.ProgramCounter;
|
||||||
import com.ibm.wala.fixedpoint.impl.UnaryOperator;
|
import com.ibm.wala.fixedpoint.impl.UnaryOperator;
|
||||||
import com.ibm.wala.fixpoint.IVariable;
|
import com.ibm.wala.fixpoint.IVariable;
|
||||||
import com.ibm.wala.fixpoint.IntSetVariable;
|
import com.ibm.wala.fixpoint.IntSetVariable;
|
||||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
|
||||||
import com.ibm.wala.ipa.callgraph.ContextKey;
|
import com.ibm.wala.ipa.callgraph.ContextKey;
|
||||||
import com.ibm.wala.ipa.callgraph.impl.ExplicitCallGraph;
|
import com.ibm.wala.ipa.callgraph.impl.ExplicitCallGraph;
|
||||||
import com.ibm.wala.ipa.callgraph.impl.FakeRootMethod;
|
import com.ibm.wala.ipa.callgraph.impl.FakeRootMethod;
|
||||||
import com.ibm.wala.ipa.callgraph.impl.FakeWorldClinitMethod;
|
import com.ibm.wala.ipa.callgraph.impl.FakeWorldClinitMethod;
|
||||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
|
||||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||||
|
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||||
import com.ibm.wala.shrikeBT.ConditionalBranchInstruction;
|
import com.ibm.wala.shrikeBT.ConditionalBranchInstruction;
|
||||||
import com.ibm.wala.shrikeBT.IInstruction;
|
import com.ibm.wala.shrikeBT.IInstruction;
|
||||||
import com.ibm.wala.shrikeBT.IInvokeInstruction;
|
import com.ibm.wala.shrikeBT.IInvokeInstruction;
|
||||||
|
@ -449,7 +454,7 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
||||||
}
|
}
|
||||||
ConcreteTypeKey ck = (ConcreteTypeKey) ik;
|
ConcreteTypeKey ck = (ConcreteTypeKey) ik;
|
||||||
IClass klass = ck.getType();
|
IClass klass = ck.getType();
|
||||||
if (SSAPropagationCallGraphBuilder.catches(catchClasses, klass, cha)) {
|
if (PropagationCallGraphBuilder.catches(catchClasses, klass, cha)) {
|
||||||
system.newConstraint(exceptionVar, getInstanceKeyForPEI(node, peiLoc, type, instanceKeyFactory));
|
system.newConstraint(exceptionVar, getInstanceKeyForPEI(node, peiLoc, type, instanceKeyFactory));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -477,14 +482,6 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return true iff there's a unique catch block which catches all exceptions
|
|
||||||
* thrown by a certain call site.
|
|
||||||
*/
|
|
||||||
static boolean hasUniqueCatchBlock(SSAAbstractInvokeInstruction call, CGNode node, CallGraph cg) {
|
|
||||||
return hasUniqueCatchBlock(call, node.getIR(new WarningSet()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* precondition: hasUniqueCatchBlock(call,node,cg)
|
* precondition: hasUniqueCatchBlock(call,node,cg)
|
||||||
*
|
*
|
||||||
|
|
|
@ -62,11 +62,6 @@ public class DefaultSSAInterpreter extends DefaultRTAInterpreter implements SSAC
|
||||||
return getCFAInterpreter(node).getNumberOfStatements(node, warnings);
|
return getCFAInterpreter(node).getNumberOfStatements(node, warnings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean understands(IMethod method, Context context) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterator<NewSiteReference> iterateNewSites(CGNode node) {
|
public Iterator<NewSiteReference> iterateNewSites(CGNode node) {
|
||||||
return getCFAInterpreter(node).iterateNewSites(node);
|
return getCFAInterpreter(node).iterateNewSites(node);
|
||||||
|
|
|
@ -14,7 +14,6 @@ import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import com.ibm.wala.cfg.CFGCache;
|
|
||||||
import com.ibm.wala.cfg.ControlFlowGraph;
|
import com.ibm.wala.cfg.ControlFlowGraph;
|
||||||
import com.ibm.wala.cfg.IBasicBlock;
|
import com.ibm.wala.cfg.IBasicBlock;
|
||||||
import com.ibm.wala.cfg.TwoExitCFG;
|
import com.ibm.wala.cfg.TwoExitCFG;
|
||||||
|
@ -103,7 +102,7 @@ public class InterproceduralCFG implements NumberedGraph<BasicBlockInContext> {
|
||||||
* @param warnings
|
* @param warnings
|
||||||
* an object to track analysis warnings
|
* an object to track analysis warnings
|
||||||
*/
|
*/
|
||||||
public InterproceduralCFG(CallGraph CG, CFGCache cfgCache, WarningSet warnings) {
|
public InterproceduralCFG(CallGraph CG, WarningSet warnings) {
|
||||||
this(CG, IndiscriminateFilter.singleton(), false, warnings);
|
this(CG, IndiscriminateFilter.singleton(), false, warnings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -350,7 +350,7 @@ public class ClassHierarchy implements IClassHierarchy {
|
||||||
throw new UnimplementedError("factory.getLoader failed " + e);
|
throw new UnimplementedError("factory.getLoader failed " + e);
|
||||||
}
|
}
|
||||||
IClass declaredClass;
|
IClass declaredClass;
|
||||||
declaredClass = loader.lookupClass(ref.getDeclaringClass().getName(), this);
|
declaredClass = loader.lookupClass(ref.getDeclaringClass().getName());
|
||||||
if (declaredClass == null) {
|
if (declaredClass == null) {
|
||||||
return Collections.emptySet();
|
return Collections.emptySet();
|
||||||
}
|
}
|
||||||
|
@ -789,7 +789,7 @@ public class ClassHierarchy implements IClassHierarchy {
|
||||||
ClassLoaderReference loaderRef = A.getClassLoader();
|
ClassLoaderReference loaderRef = A.getClassLoader();
|
||||||
for (int i = 0; i < loaders.length; i++) {
|
for (int i = 0; i < loaders.length; i++) {
|
||||||
if (loaders[i].getReference().equals(loaderRef)) {
|
if (loaders[i].getReference().equals(loaderRef)) {
|
||||||
IClass klass = loaders[i].lookupClass(A.getName(), this);
|
IClass klass = loaders[i].lookupClass(A.getName());
|
||||||
if (klass != null) {
|
if (klass != null) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Trace.println("lookupClass: got " + klass);
|
Trace.println("lookupClass: got " + klass);
|
||||||
|
|
|
@ -34,6 +34,7 @@ import com.ibm.wala.ipa.slicer.Statement.Kind;
|
||||||
import com.ibm.wala.shrikeBT.IInstruction;
|
import com.ibm.wala.shrikeBT.IInstruction;
|
||||||
import com.ibm.wala.ssa.DefUse;
|
import com.ibm.wala.ssa.DefUse;
|
||||||
import com.ibm.wala.ssa.IR;
|
import com.ibm.wala.ssa.IR;
|
||||||
|
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
|
||||||
import com.ibm.wala.ssa.SSAArrayLengthInstruction;
|
import com.ibm.wala.ssa.SSAArrayLengthInstruction;
|
||||||
import com.ibm.wala.ssa.SSAArrayReferenceInstruction;
|
import com.ibm.wala.ssa.SSAArrayReferenceInstruction;
|
||||||
import com.ibm.wala.ssa.SSACheckCastInstruction;
|
import com.ibm.wala.ssa.SSACheckCastInstruction;
|
||||||
|
@ -41,7 +42,6 @@ import com.ibm.wala.ssa.SSAFieldAccessInstruction;
|
||||||
import com.ibm.wala.ssa.SSAGetCaughtExceptionInstruction;
|
import com.ibm.wala.ssa.SSAGetCaughtExceptionInstruction;
|
||||||
import com.ibm.wala.ssa.SSAInstanceofInstruction;
|
import com.ibm.wala.ssa.SSAInstanceofInstruction;
|
||||||
import com.ibm.wala.ssa.SSAInstruction;
|
import com.ibm.wala.ssa.SSAInstruction;
|
||||||
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
|
|
||||||
import com.ibm.wala.ssa.SSANewInstruction;
|
import com.ibm.wala.ssa.SSANewInstruction;
|
||||||
import com.ibm.wala.ssa.SSAPhiInstruction;
|
import com.ibm.wala.ssa.SSAPhiInstruction;
|
||||||
import com.ibm.wala.ssa.SSAPiInstruction;
|
import com.ibm.wala.ssa.SSAPiInstruction;
|
||||||
|
@ -92,7 +92,7 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
|
||||||
|
|
||||||
private final PointerAnalysis pa;
|
private final PointerAnalysis pa;
|
||||||
|
|
||||||
private final ExtendedHeapModel h;
|
private final ExtendedHeapModel heapModel;
|
||||||
|
|
||||||
private final Map<CGNode, OrdinalSet<PointerKey>> mod;
|
private final Map<CGNode, OrdinalSet<PointerKey>> mod;
|
||||||
|
|
||||||
|
@ -117,18 +117,18 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
|
||||||
throw new IllegalArgumentException("node is null");
|
throw new IllegalArgumentException("node is null");
|
||||||
}
|
}
|
||||||
this.node = node;
|
this.node = node;
|
||||||
this.h = pa == null ? null : new DelegatingExtendedHeapModel(pa.getHeapModel());
|
this.heapModel = pa == null ? null : new DelegatingExtendedHeapModel(pa.getHeapModel());
|
||||||
this.pa = pa;
|
this.pa = pa;
|
||||||
this.dOptions = dOptions;
|
this.dOptions = dOptions;
|
||||||
this.mod = mod;
|
this.mod = mod;
|
||||||
this.exclusions = exclusions;
|
this.exclusions = exclusions;
|
||||||
instructionIndices = computeInstructionIndices(node.getIR(new WarningSet()));
|
instructionIndices = computeInstructionIndices(node.getIR(new WarningSet()));
|
||||||
createNodes(mod, ref, dOptions, cOptions);
|
createNodes(ref, cOptions);
|
||||||
createScalarEdges(dOptions, cOptions);
|
createScalarEdges(cOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createScalarEdges(DataDependenceOptions dOptions, ControlDependenceOptions cOptions) {
|
private void createScalarEdges(ControlDependenceOptions cOptions) {
|
||||||
createScalarDataDependenceEdges(dOptions);
|
createScalarDataDependenceEdges();
|
||||||
createControlDependenceEdges(cOptions);
|
createControlDependenceEdges(cOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,7 +226,7 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
|
||||||
* @param pa
|
* @param pa
|
||||||
* @param mod
|
* @param mod
|
||||||
*/
|
*/
|
||||||
private void createScalarDataDependenceEdges(DataDependenceOptions dOptions) {
|
private void createScalarDataDependenceEdges() {
|
||||||
if (dOptions.equals(DataDependenceOptions.NONE)) {
|
if (dOptions.equals(DataDependenceOptions.NONE)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -450,12 +450,8 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
|
||||||
/**
|
/**
|
||||||
* Create heap data dependence edges in this PDG relevant to a particular
|
* Create heap data dependence edges in this PDG relevant to a particular
|
||||||
* statement.
|
* statement.
|
||||||
*
|
|
||||||
* @param pa
|
|
||||||
* @param mod
|
|
||||||
*/
|
*/
|
||||||
private void createHeapDataDependenceEdges(final PointerKey pk, PointerAnalysis pa, Map<CGNode, OrdinalSet<PointerKey>> mod,
|
private void createHeapDataDependenceEdges(final PointerKey pk) {
|
||||||
DataDependenceOptions dOptions) {
|
|
||||||
|
|
||||||
if (locationsHandled.contains(pk)) {
|
if (locationsHandled.contains(pk)) {
|
||||||
return;
|
return;
|
||||||
|
@ -480,7 +476,8 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
|
||||||
System.err.println("Location " + pk);
|
System.err.println("Location " + pk);
|
||||||
}
|
}
|
||||||
|
|
||||||
// in reaching defs calcuation, exclude heap statements that are irrelevant.
|
// in reaching defs calculation, exclude heap statements that are
|
||||||
|
// irrelevant.
|
||||||
Filter f = new Filter() {
|
Filter f = new Filter() {
|
||||||
public boolean accepts(Object o) {
|
public boolean accepts(Object o) {
|
||||||
if (o instanceof HeapStatement) {
|
if (o instanceof HeapStatement) {
|
||||||
|
@ -677,17 +674,16 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
|
||||||
*
|
*
|
||||||
* @param dOptions
|
* @param dOptions
|
||||||
*/
|
*/
|
||||||
private void createNodes(Map<CGNode, OrdinalSet<PointerKey>> mod, Map<CGNode, OrdinalSet<PointerKey>> ref,
|
private void createNodes(Map<CGNode, OrdinalSet<PointerKey>> ref, ControlDependenceOptions cOptions) {
|
||||||
DataDependenceOptions dOptions, ControlDependenceOptions cOptions) {
|
|
||||||
IR ir = node.getIR(new WarningSet());
|
IR ir = node.getIR(new WarningSet());
|
||||||
|
|
||||||
if (ir != null) {
|
if (ir != null) {
|
||||||
Collection<SSAInstruction> visited = createNormalStatements(ir, mod, ref, dOptions);
|
Collection<SSAInstruction> visited = createNormalStatements(ir, ref);
|
||||||
createSpecialStatements(ir, visited);
|
createSpecialStatements(ir, visited);
|
||||||
}
|
}
|
||||||
|
|
||||||
createCalleeParams(ref, dOptions);
|
createCalleeParams(ref);
|
||||||
createReturnStatements(mod, dOptions);
|
createReturnStatements();
|
||||||
|
|
||||||
if (!cOptions.equals(ControlDependenceOptions.NONE)) {
|
if (!cOptions.equals(ControlDependenceOptions.NONE)) {
|
||||||
addNode(new MethodEntryStatement(node));
|
addNode(new MethodEntryStatement(node));
|
||||||
|
@ -703,7 +699,7 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
|
||||||
* this node. These are logically parameters in the SDG.
|
* this node. These are logically parameters in the SDG.
|
||||||
* @param dOptions
|
* @param dOptions
|
||||||
*/
|
*/
|
||||||
private void createReturnStatements(Map<CGNode, OrdinalSet<PointerKey>> mod, DataDependenceOptions dOptions) {
|
private void createReturnStatements() {
|
||||||
ArrayList<Statement> list = new ArrayList<Statement>();
|
ArrayList<Statement> list = new ArrayList<Statement>();
|
||||||
if (!node.getMethod().getReturnType().equals(TypeReference.Void)) {
|
if (!node.getMethod().getReturnType().equals(TypeReference.Void)) {
|
||||||
ParamStatement.NormalReturnCallee n = new ParamStatement.NormalReturnCallee(node);
|
ParamStatement.NormalReturnCallee n = new ParamStatement.NormalReturnCallee(node);
|
||||||
|
@ -732,9 +728,8 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
|
||||||
* @param ref
|
* @param ref
|
||||||
* the set of heap locations which may be read (transitively) by
|
* the set of heap locations which may be read (transitively) by
|
||||||
* this node. These are logically parameters in the SDG.
|
* this node. These are logically parameters in the SDG.
|
||||||
* @param dOptions
|
|
||||||
*/
|
*/
|
||||||
private void createCalleeParams(Map<CGNode, OrdinalSet<PointerKey>> ref, DataDependenceOptions dOptions) {
|
private void createCalleeParams(Map<CGNode, OrdinalSet<PointerKey>> ref) {
|
||||||
|
|
||||||
ArrayList<Statement> list = new ArrayList<Statement>();
|
ArrayList<Statement> list = new ArrayList<Statement>();
|
||||||
for (int i = 1; i <= node.getMethod().getNumberOfParameters(); i++) {
|
for (int i = 1; i <= node.getMethod().getNumberOfParameters(); i++) {
|
||||||
|
@ -785,8 +780,7 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
|
||||||
* @param options
|
* @param options
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private Collection<SSAInstruction> createNormalStatements(IR ir, Map<CGNode, OrdinalSet<PointerKey>> mod,
|
private Collection<SSAInstruction> createNormalStatements(IR ir, Map<CGNode, OrdinalSet<PointerKey>> ref) {
|
||||||
Map<CGNode, OrdinalSet<PointerKey>> ref, DataDependenceOptions dOptions) {
|
|
||||||
Collection<SSAInstruction> visited = HashSetFactory.make();
|
Collection<SSAInstruction> visited = HashSetFactory.make();
|
||||||
// create a node for every normal instruction in the IR
|
// create a node for every normal instruction in the IR
|
||||||
SSAInstruction[] instructions = ir.getInstructions();
|
SSAInstruction[] instructions = ir.getInstructions();
|
||||||
|
@ -802,7 +796,7 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
|
||||||
visited.add(s);
|
visited.add(s);
|
||||||
}
|
}
|
||||||
if (s instanceof SSAAbstractInvokeInstruction) {
|
if (s instanceof SSAAbstractInvokeInstruction) {
|
||||||
addParamPassingStatements((SSAAbstractInvokeInstruction) s, mod, ref, dOptions);
|
addParamPassingStatements((SSAAbstractInvokeInstruction) s, ref);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return visited;
|
return visited;
|
||||||
|
@ -814,8 +808,7 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
|
||||||
*
|
*
|
||||||
* @param dOptions
|
* @param dOptions
|
||||||
*/
|
*/
|
||||||
private void addParamPassingStatements(SSAAbstractInvokeInstruction call, Map<CGNode, OrdinalSet<PointerKey>> mod,
|
private void addParamPassingStatements(SSAAbstractInvokeInstruction call, Map<CGNode, OrdinalSet<PointerKey>> ref) {
|
||||||
Map<CGNode, OrdinalSet<PointerKey>> ref, DataDependenceOptions dOptions) {
|
|
||||||
|
|
||||||
Collection<Statement> params = MapUtil.findOrCreateSet(callerParamStatements, call.getCallSite());
|
Collection<Statement> params = MapUtil.findOrCreateSet(callerParamStatements, call.getCallSite());
|
||||||
Collection<Statement> rets = MapUtil.findOrCreateSet(callerReturnStatements, call.getCallSite());
|
Collection<Statement> rets = MapUtil.findOrCreateSet(callerReturnStatements, call.getCallSite());
|
||||||
|
@ -920,9 +913,9 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
|
||||||
case NORMAL:
|
case NORMAL:
|
||||||
NormalStatement st = (NormalStatement) N;
|
NormalStatement st = (NormalStatement) N;
|
||||||
if (!(IGNORE_ALLOC_HEAP_DEFS && st.getInstruction() instanceof SSANewInstruction)) {
|
if (!(IGNORE_ALLOC_HEAP_DEFS && st.getInstruction() instanceof SSANewInstruction)) {
|
||||||
Collection<PointerKey> ref = ModRef.getRef(node, h, pa, st.getInstruction(), exclusions);
|
Collection<PointerKey> ref = ModRef.getRef(node, heapModel, pa, st.getInstruction(), exclusions);
|
||||||
for (PointerKey pk : ref) {
|
for (PointerKey pk : ref) {
|
||||||
createHeapDataDependenceEdges(pk, pa, mod, dOptions);
|
createHeapDataDependenceEdges(pk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -931,7 +924,7 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
|
||||||
case HEAP_RET_CALLEE:
|
case HEAP_RET_CALLEE:
|
||||||
case HEAP_RET_CALLER:
|
case HEAP_RET_CALLER:
|
||||||
HeapStatement h = (HeapStatement) N;
|
HeapStatement h = (HeapStatement) N;
|
||||||
createHeapDataDependenceEdges(h.getLocation(), pa, mod, dOptions);
|
createHeapDataDependenceEdges(h.getLocation());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -940,9 +933,9 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
|
||||||
case NORMAL:
|
case NORMAL:
|
||||||
NormalStatement st = (NormalStatement) N;
|
NormalStatement st = (NormalStatement) N;
|
||||||
if (!(IGNORE_ALLOC_HEAP_DEFS && st.getInstruction() instanceof SSANewInstruction)) {
|
if (!(IGNORE_ALLOC_HEAP_DEFS && st.getInstruction() instanceof SSANewInstruction)) {
|
||||||
Collection<PointerKey> ref = ModRef.getMod(node, h, pa, st.getInstruction(), exclusions);
|
Collection<PointerKey> ref = ModRef.getMod(node, heapModel, pa, st.getInstruction(), exclusions);
|
||||||
for (PointerKey pk : ref) {
|
for (PointerKey pk : ref) {
|
||||||
createHeapDataDependenceEdges(pk, pa, mod, dOptions);
|
createHeapDataDependenceEdges(pk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -951,7 +944,7 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
|
||||||
case HEAP_RET_CALLEE:
|
case HEAP_RET_CALLEE:
|
||||||
case HEAP_RET_CALLER:
|
case HEAP_RET_CALLER:
|
||||||
HeapStatement h = (HeapStatement) N;
|
HeapStatement h = (HeapStatement) N;
|
||||||
createHeapDataDependenceEdges(h.getLocation(), pa, mod, dOptions);
|
createHeapDataDependenceEdges(h.getLocation());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,6 @@ import com.ibm.wala.util.intset.SparseIntSet;
|
||||||
* A wrapper around an SDG to make it look like a supergraph for tabulation.
|
* A wrapper around an SDG to make it look like a supergraph for tabulation.
|
||||||
*
|
*
|
||||||
* @author sjfink
|
* @author sjfink
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
class SDGSupergraph implements ISupergraph<Statement, PDG> {
|
class SDGSupergraph implements ISupergraph<Statement, PDG> {
|
||||||
|
|
||||||
|
@ -39,7 +38,7 @@ class SDGSupergraph implements ISupergraph<Statement, PDG> {
|
||||||
/**
|
/**
|
||||||
* We are interested in flow to or from the following statement.
|
* We are interested in flow to or from the following statement.
|
||||||
*/
|
*/
|
||||||
private final Statement src;
|
private final Statement srcStatement;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do a backward slice?
|
* Do a backward slice?
|
||||||
|
@ -48,7 +47,7 @@ class SDGSupergraph implements ISupergraph<Statement, PDG> {
|
||||||
|
|
||||||
public SDGSupergraph(ISDG sdg, Statement src, boolean backward) {
|
public SDGSupergraph(ISDG sdg, Statement src, boolean backward) {
|
||||||
this.sdg = sdg;
|
this.sdg = sdg;
|
||||||
this.src = src;
|
this.srcStatement = src;
|
||||||
this.backward = backward;
|
this.backward = backward;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,6 +56,9 @@ class SDGSupergraph implements ISupergraph<Statement, PDG> {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see com.ibm.wala.dataflow.IFDS.ISupergraph#classifyEdge(java.lang.Object, java.lang.Object)
|
||||||
|
*/
|
||||||
public byte classifyEdge(Statement src, Statement dest) {
|
public byte classifyEdge(Statement src, Statement dest) {
|
||||||
Assertions.UNREACHABLE();
|
Assertions.UNREACHABLE();
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -162,7 +164,7 @@ class SDGSupergraph implements ISupergraph<Statement, PDG> {
|
||||||
* @see com.ibm.wala.dataflow.IFDS.ISupergraph#getMain()
|
* @see com.ibm.wala.dataflow.IFDS.ISupergraph#getMain()
|
||||||
*/
|
*/
|
||||||
public PDG getMain() {
|
public PDG getMain() {
|
||||||
return getProcOf(src);
|
return getProcOf(srcStatement);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -170,7 +172,7 @@ class SDGSupergraph implements ISupergraph<Statement, PDG> {
|
||||||
*/
|
*/
|
||||||
public Statement getMainEntry() {
|
public Statement getMainEntry() {
|
||||||
Assertions.productionAssertion(!backward, "todo: support backward");
|
Assertions.productionAssertion(!backward, "todo: support backward");
|
||||||
return src;
|
return srcStatement;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -180,7 +182,7 @@ class SDGSupergraph implements ISupergraph<Statement, PDG> {
|
||||||
// We pretend that sink is the "main exit" .. we don't care about
|
// We pretend that sink is the "main exit" .. we don't care about
|
||||||
// flow past the sink.
|
// flow past the sink.
|
||||||
Assertions.productionAssertion(backward, "todo: support forward");
|
Assertions.productionAssertion(backward, "todo: support forward");
|
||||||
return src;
|
return srcStatement;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -397,7 +399,7 @@ class SDGSupergraph implements ISupergraph<Statement, PDG> {
|
||||||
|
|
||||||
public Iterator<? extends Statement> getSuccNodes(Statement N) {
|
public Iterator<? extends Statement> getSuccNodes(Statement N) {
|
||||||
if (backward) {
|
if (backward) {
|
||||||
if (N.equals(src)) {
|
if (N.equals(srcStatement)) {
|
||||||
return EmptyIterator.instance();
|
return EmptyIterator.instance();
|
||||||
} else {
|
} else {
|
||||||
return sdg.getSuccNodes(N);
|
return sdg.getSuccNodes(N);
|
||||||
|
@ -409,13 +411,13 @@ class SDGSupergraph implements ISupergraph<Statement, PDG> {
|
||||||
|
|
||||||
public boolean hasEdge(Statement src, Statement dst) {
|
public boolean hasEdge(Statement src, Statement dst) {
|
||||||
if (backward) {
|
if (backward) {
|
||||||
if (src.equals(this.src)) {
|
if (src.equals(this.srcStatement)) {
|
||||||
return IteratorUtil.contains(getSuccNodes(src), dst);
|
return IteratorUtil.contains(getSuccNodes(src), dst);
|
||||||
} else {
|
} else {
|
||||||
return sdg.hasEdge(src, dst);
|
return sdg.hasEdge(src, dst);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (dst.equals(this.src)) {
|
if (dst.equals(this.srcStatement)) {
|
||||||
return IteratorUtil.contains(getPredNodes(dst), src);
|
return IteratorUtil.contains(getPredNodes(dst), src);
|
||||||
} else {
|
} else {
|
||||||
return sdg.hasEdge(src, dst);
|
return sdg.hasEdge(src, dst);
|
||||||
|
@ -469,7 +471,7 @@ class SDGSupergraph implements ISupergraph<Statement, PDG> {
|
||||||
*/
|
*/
|
||||||
public IntSet getSuccNodeNumbers(Statement node) {
|
public IntSet getSuccNodeNumbers(Statement node) {
|
||||||
if (backward) {
|
if (backward) {
|
||||||
if (node.equals(src)) {
|
if (node.equals(srcStatement)) {
|
||||||
return new SparseIntSet();
|
return new SparseIntSet();
|
||||||
} else {
|
} else {
|
||||||
return sdg.getSuccNodeNumbers(node);
|
return sdg.getSuccNodeNumbers(node);
|
||||||
|
|
|
@ -224,7 +224,7 @@ public class Slicer {
|
||||||
if (VERBOSE) {
|
if (VERBOSE) {
|
||||||
System.err.println("Tabulated.");
|
System.err.println("Tabulated.");
|
||||||
}
|
}
|
||||||
Collection<Statement> slice = result2Slice(sdg, tr);
|
Collection<Statement> slice = result2Slice(tr);
|
||||||
result.addAll(slice);
|
result.addAll(slice);
|
||||||
|
|
||||||
if (VERBOSE) {
|
if (VERBOSE) {
|
||||||
|
@ -351,10 +351,10 @@ public class Slicer {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert the resuls of the tabulation to a slice, represented as a
|
* Convert the results of the tabulation to a slice, represented as a
|
||||||
* Collection<Statement>
|
* Collection<Statement>
|
||||||
*/
|
*/
|
||||||
private static Collection<Statement> result2Slice(ISDG sdg, final TabulationResult<Statement> result) {
|
private static Collection<Statement> result2Slice(final TabulationResult<Statement> result) {
|
||||||
return result.getSupergraphNodesReached();
|
return result.getSupergraphNodesReached();
|
||||||
// final Collection<Statement> nodes = new
|
// final Collection<Statement> nodes = new
|
||||||
// Iterator2Collection<Statement>(sdg.iterateLazyNodes());
|
// Iterator2Collection<Statement>(sdg.iterateLazyNodes());
|
||||||
|
|
|
@ -100,7 +100,7 @@ public class BypassClassTargetSelector implements ClassTargetSelector {
|
||||||
}
|
}
|
||||||
if (realType.isAbstract() || realType.isInterface()) {
|
if (realType.isAbstract() || realType.isInterface()) {
|
||||||
TypeName syntheticName = BypassSyntheticClass.getName(realRef);
|
TypeName syntheticName = BypassSyntheticClass.getName(realRef);
|
||||||
IClass result = bypassLoader.lookupClass(syntheticName, realType.getClassHierarchy());
|
IClass result = bypassLoader.lookupClass(syntheticName);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -74,7 +74,7 @@ public class BypassSyntheticClass extends SyntheticClass {
|
||||||
*/
|
*/
|
||||||
public IClass getSuperclass() throws ClassHierarchyException {
|
public IClass getSuperclass() throws ClassHierarchyException {
|
||||||
if (realType.isInterface()) {
|
if (realType.isInterface()) {
|
||||||
IClass result = loader.lookupClass(TypeReference.JavaLangObject.getName(), getClassHierarchy());
|
IClass result = loader.lookupClass(TypeReference.JavaLangObject.getName());
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -62,11 +62,17 @@ public class BypassSyntheticClassLoader implements IClassLoader {
|
||||||
|
|
||||||
private final IClassHierarchy cha;
|
private final IClassHierarchy cha;
|
||||||
|
|
||||||
/**
|
|
||||||
* A mapping from TypeName -> IClass
|
|
||||||
*/
|
|
||||||
private final HashMap<TypeName, IClass> syntheticClasses = HashMapFactory.make();
|
private final HashMap<TypeName, IClass> syntheticClasses = HashMapFactory.make();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Don't change my signature! ClassLoaderFactoryImpl calls me by reflection! yuck.
|
||||||
|
*
|
||||||
|
* @param me the name of this class loader
|
||||||
|
* @param parent its parent
|
||||||
|
* @param exclusions classes to ignore
|
||||||
|
* @param cha governing class hierarchy
|
||||||
|
* @param warnings object to record analysis warnings
|
||||||
|
*/
|
||||||
public BypassSyntheticClassLoader(ClassLoaderReference me, IClassLoader parent, SetOfClasses exclusions, IClassHierarchy cha,
|
public BypassSyntheticClassLoader(ClassLoaderReference me, IClassLoader parent, SetOfClasses exclusions, IClassHierarchy cha,
|
||||||
WarningSet warnings) {
|
WarningSet warnings) {
|
||||||
this.me = me;
|
this.me = me;
|
||||||
|
@ -74,8 +80,8 @@ public class BypassSyntheticClassLoader implements IClassLoader {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IClass lookupClass(TypeName className, IClassHierarchy cha) {
|
public IClass lookupClass(TypeName className) {
|
||||||
IClass pc = parent.lookupClass(className, cha);
|
IClass pc = parent.lookupClass(className);
|
||||||
if (pc == null) {
|
if (pc == null) {
|
||||||
IClass c = syntheticClasses.get(className);
|
IClass c = syntheticClasses.get(className);
|
||||||
return c;
|
return c;
|
||||||
|
|
|
@ -49,7 +49,6 @@ import com.ibm.wala.types.TypeReference;
|
||||||
import com.ibm.wala.util.ShrikeUtil;
|
import com.ibm.wala.util.ShrikeUtil;
|
||||||
import com.ibm.wala.util.debug.Assertions;
|
import com.ibm.wala.util.debug.Assertions;
|
||||||
import com.ibm.wala.util.intset.IntPair;
|
import com.ibm.wala.util.intset.IntPair;
|
||||||
import com.ibm.wala.util.warnings.WarningSet;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class constructs an SSA IR from a backing ShrikeBT instruction stream.
|
* This class constructs an SSA IR from a backing ShrikeBT instruction stream.
|
||||||
|
@ -75,7 +74,7 @@ public class SSABuilder extends AbstractIntStackMachine {
|
||||||
private final SSA2LocalMap localMap;
|
private final SSA2LocalMap localMap;
|
||||||
|
|
||||||
public SSABuilder(ShrikeCTMethod method, SSACFG cfg, ShrikeCFG scfg, SSAInstruction[] instructions,
|
public SSABuilder(ShrikeCTMethod method, SSACFG cfg, ShrikeCFG scfg, SSAInstruction[] instructions,
|
||||||
SymbolTable symbolTable, boolean buildLocalMap, boolean addPiNodes, WarningSet warnings) {
|
SymbolTable symbolTable, boolean buildLocalMap, boolean addPiNodes) {
|
||||||
super(scfg);
|
super(scfg);
|
||||||
localMap = buildLocalMap ? new SSA2LocalMap(scfg, instructions.length, cfg.getNumberOfNodes(), maxLocals) : null;
|
localMap = buildLocalMap ? new SSA2LocalMap(scfg, instructions.length, cfg.getNumberOfNodes(), maxLocals) : null;
|
||||||
init(new SymbolTableMeeter(symbolTable, cfg, instructions, scfg), new SymbolicPropagator(scfg, instructions, symbolTable,
|
init(new SymbolTableMeeter(symbolTable, cfg, instructions, scfg), new SymbolicPropagator(scfg, instructions, symbolTable,
|
||||||
|
|
|
@ -136,7 +136,7 @@ public class SSACFG implements ControlFlowGraph{
|
||||||
} else {
|
} else {
|
||||||
TypeReference exceptionType = ShrikeUtil.makeTypeReference(loader.getReference(), handler.getCatchClass());
|
TypeReference exceptionType = ShrikeUtil.makeTypeReference(loader.getReference(), handler.getCatchClass());
|
||||||
IClass klass = null;
|
IClass klass = null;
|
||||||
klass = loader.lookupClass(exceptionType.getName(), method.getClassHierarchy());
|
klass = loader.lookupClass(exceptionType.getName());
|
||||||
if (klass == null) {
|
if (klass == null) {
|
||||||
warnings.add(ExceptionLoadFailure.create(exceptionType, method));
|
warnings.add(ExceptionLoadFailure.create(exceptionType, method));
|
||||||
t = exceptionType;
|
t = exceptionType;
|
||||||
|
|
|
@ -197,6 +197,10 @@ public abstract class SSAInstruction implements IInstruction {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the ith def
|
||||||
|
* @param i number of the def, starting at 0.
|
||||||
|
*/
|
||||||
public int getDef(int i) {
|
public int getDef(int i) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -387,14 +387,14 @@ public class ExpandedControlFlowGraph implements ControlFlowGraph {
|
||||||
if (!instbb.isPiBlock()) {
|
if (!instbb.isPiBlock()) {
|
||||||
for (Iterator sit = cfg.getSuccNodes(bb); sit.hasNext();) {
|
for (Iterator sit = cfg.getSuccNodes(bb); sit.hasNext();) {
|
||||||
BasicBlock succNode = (BasicBlock) sit.next();
|
BasicBlock succNode = (BasicBlock) sit.next();
|
||||||
boolean fallThrough = isFallThroughEdge(cfg, bb, succNode);
|
boolean fallThrough = isFallThroughEdge(bb, succNode);
|
||||||
edgeWorkSet.add(new BBEdge(bb, succNode, fallThrough));
|
edgeWorkSet.add(new BBEdge(bb, succNode, fallThrough));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SSAPiInstruction pi = (SSAPiInstruction) instbb.getInstruction();
|
SSAPiInstruction pi = (SSAPiInstruction) instbb.getInstruction();
|
||||||
int succNum = pi.getSuccessor();
|
int succNum = pi.getSuccessor();
|
||||||
BasicBlock succNode = (BasicBlock) cfg.getNode(succNum);
|
BasicBlock succNode = (BasicBlock) cfg.getNode(succNum);
|
||||||
boolean fallThrough = isFallThroughEdge(cfg, bb, succNode);
|
boolean fallThrough = isFallThroughEdge(bb, succNode);
|
||||||
edgeWorkSet.add(new BBEdge(bb, succNode, fallThrough));
|
edgeWorkSet.add(new BBEdge(bb, succNode, fallThrough));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -407,7 +407,7 @@ public class ExpandedControlFlowGraph implements ControlFlowGraph {
|
||||||
Iterator workIt = edgeWorkSet.iterator();
|
Iterator workIt = edgeWorkSet.iterator();
|
||||||
BBEdge edge = (BBEdge) workIt.next();
|
BBEdge edge = (BBEdge) workIt.next();
|
||||||
boolean fallThru = false;
|
boolean fallThru = false;
|
||||||
if (isFallThroughEdge(cfg, edge.src, edge.dest)) {
|
if (isFallThroughEdge(edge.src, edge.dest)) {
|
||||||
fallThru = true;
|
fallThru = true;
|
||||||
}
|
}
|
||||||
workIt.remove();
|
workIt.remove();
|
||||||
|
@ -963,15 +963,12 @@ public class ExpandedControlFlowGraph implements ControlFlowGraph {
|
||||||
/**
|
/**
|
||||||
* is the given edge a fall-through edge?
|
* is the given edge a fall-through edge?
|
||||||
*
|
*
|
||||||
* @param cfg
|
* @return note: this is based on a WALA-invariant that guarantees the blocks
|
||||||
* @param src
|
* are numbered in a certain way. This is the "WALA-way" of
|
||||||
* @param dest
|
|
||||||
* @return note: this is based on a DOMO-invariant that guarantees the blocks
|
|
||||||
* are numbered in a certain way. This is the "DOMO-way" of
|
|
||||||
* identifying fall-through edges, and is mainly done due for
|
* identifying fall-through edges, and is mainly done due for
|
||||||
* efficiency reasons (as many other software crimes).
|
* efficiency reasons (as many other software crimes).
|
||||||
*/
|
*/
|
||||||
private boolean isFallThroughEdge(SSACFG cfg, IBasicBlock src, IBasicBlock dest) {
|
private boolean isFallThroughEdge(IBasicBlock src, IBasicBlock dest) {
|
||||||
if (cfg.getSuccNodeCount(src) == 2) {
|
if (cfg.getSuccNodeCount(src) == 2) {
|
||||||
return ((src.getNumber() + 1) == dest.getNumber());
|
return ((src.getNumber() + 1) == dest.getNumber());
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -173,18 +173,18 @@ public class BytecodeStream implements BytecodeConstants {
|
||||||
/**
|
/**
|
||||||
* Skips the current instruction (without using the opcode field)
|
* Skips the current instruction (without using the opcode field)
|
||||||
* A slightly optimized version of skipInstruction()
|
* A slightly optimized version of skipInstruction()
|
||||||
* @param opcode current opcode
|
* @param opc current opcode
|
||||||
* @param wide whether current instruction follows wide
|
* @param w whether current instruction follows wide
|
||||||
* @see #skipInstruction()
|
* @see #skipInstruction()
|
||||||
*/
|
*/
|
||||||
public final void skipInstruction(int opcode, boolean wide) {
|
public final void skipInstruction(int opc, boolean w) {
|
||||||
int len = JBC_length[opcode] - 1;
|
int len = JBC_length[opc] - 1;
|
||||||
if (wide)
|
if (w)
|
||||||
len += len;
|
len += len;
|
||||||
if (len >= 0)
|
if (len >= 0)
|
||||||
bcIndex += len;
|
bcIndex += len;
|
||||||
else
|
else
|
||||||
skipSpecialInstruction(opcode);
|
skipSpecialInstruction(opc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -535,8 +535,6 @@ public class BytecodeStream implements BytecodeConstants {
|
||||||
* Used for ldc
|
* Used for ldc
|
||||||
* @return constant index
|
* @return constant index
|
||||||
* @see #getWideConstantIndex()
|
* @see #getWideConstantIndex()
|
||||||
* @see #getConstantType(int)
|
|
||||||
* @see #getIntConstant(int)
|
|
||||||
*/
|
*/
|
||||||
public final int getConstantIndex() {
|
public final int getConstantIndex() {
|
||||||
return readUnsignedByte();
|
return readUnsignedByte();
|
||||||
|
@ -547,43 +545,41 @@ public class BytecodeStream implements BytecodeConstants {
|
||||||
* Used for ldc_w, ldc2_w
|
* Used for ldc_w, ldc2_w
|
||||||
* @return wide constant index
|
* @return wide constant index
|
||||||
* @see #getConstantIndex()
|
* @see #getConstantIndex()
|
||||||
* @see #getConstantType(int)
|
|
||||||
* @see #getIntConstant(int)
|
|
||||||
*/
|
*/
|
||||||
public final int getWideConstantIndex() {
|
public final int getWideConstantIndex() {
|
||||||
return readUnsignedShort();
|
return readUnsignedShort();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* Returns the type of a constant at a given constant pool index (as a byte)
|
// * Returns the type of a constant at a given constant pool index (as a byte)
|
||||||
* Used for ldc, ldc_w, ldc2_w
|
// * Used for ldc, ldc_w, ldc2_w
|
||||||
* @return constant type
|
// * @return constant type
|
||||||
* @see #getConstantIndex()
|
// * @see #getConstantIndex()
|
||||||
* @see #getWideConstantIndex()
|
// * @see #getWideConstantIndex()
|
||||||
* @see #getIntConstant(int)
|
// * @see #getIntConstant(int)
|
||||||
* @throws UnimplementedError unconditionally
|
// * @throws UnimplementedError unconditionally
|
||||||
*/
|
// */
|
||||||
public final byte getConstantType(int index) throws UnimplementedError {
|
// public final byte getConstantType(int index) throws UnimplementedError {
|
||||||
throw new UnimplementedError();
|
// throw new UnimplementedError();
|
||||||
// byte desc = declaringClass.getLiteralDescription(index);
|
// // byte desc = declaringClass.getLiteralDescription(index);
|
||||||
// return desc;
|
// // return desc;
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* Returns the constant at a given constant pool index (as an int)
|
// * Returns the constant at a given constant pool index (as an int)
|
||||||
* Used for ldc, ldc_w
|
// * Used for ldc, ldc_w
|
||||||
* @return int constant
|
// * @return int constant
|
||||||
* @see #getConstantIndex()
|
// * @see #getConstantIndex()
|
||||||
* @see #getWideConstantIndex()
|
// * @see #getWideConstantIndex()
|
||||||
* @see #getConstantType(int)
|
// * @see #getConstantType(int)
|
||||||
* @throws UnimplementedError unconditionally
|
// * @throws UnimplementedError unconditionally
|
||||||
*/
|
// */
|
||||||
public final int getIntConstant(int index) throws UnimplementedError {
|
// public final int getIntConstant(int index) throws UnimplementedError {
|
||||||
throw new UnimplementedError();
|
// throw new UnimplementedError();
|
||||||
// int offset = declaringClass.getLiteralOffset(index) >> 2;
|
// // int offset = declaringClass.getLiteralOffset(index) >> 2;
|
||||||
// int val = Statics.getSlotContentsAsInt(offset);
|
// // int val = Statics.getSlotContentsAsInt(offset);
|
||||||
// return val;
|
// // return val;
|
||||||
}
|
// }
|
||||||
|
|
||||||
// /**
|
// /**
|
||||||
// * Returns the constant at a given constant pool index (as a long)
|
// * Returns the constant at a given constant pool index (as a long)
|
||||||
|
|
|
@ -150,7 +150,11 @@ public abstract class DFSDiscoverTimeIterator<T> extends Stack<T> implements Ite
|
||||||
throw new UnimplementedError();
|
throw new UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param from source of the edge to visit
|
||||||
|
* @param to target of the edge to visit
|
||||||
|
*/
|
||||||
protected void visitEdge(T from, T to) {
|
protected void visitEdge(T from, T to) {
|
||||||
|
// do nothing. subclasses will override.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,265 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
|
||||||
* which accompanies this distribution, and is available at
|
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* IBM Corporation - initial API and implementation
|
|
||||||
*******************************************************************************/
|
|
||||||
package com.ibm.wala.util.graph.traverse;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Stack;
|
|
||||||
|
|
||||||
import com.ibm.wala.util.collections.EmptyIterator;
|
|
||||||
import com.ibm.wala.util.debug.Assertions;
|
|
||||||
import com.ibm.wala.util.graph.Graph;
|
|
||||||
import com.ibm.wala.util.graph.INodeWithNumber;
|
|
||||||
import com.ibm.wala.util.graph.NumberedGraph;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Depth first search of a graph using a stack instead of recursive method
|
|
||||||
* calls. It allows each vertice of the graph to be visited when its is first
|
|
||||||
* discovered and when it is "finished" (i.e. completely processed).
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:achille@us.ibm.com">Achille Fokoue </a>
|
|
||||||
* @version
|
|
||||||
*/
|
|
||||||
public class DFSVisit {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* the empty iterator constant
|
|
||||||
*/
|
|
||||||
public final static Iterator EMPTY_ITERATOR = Collections.EMPTY_LIST.iterator();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A simple map interface. It is used during DFS to associate a node in a
|
|
||||||
* graph to its its traversal state.
|
|
||||||
*/
|
|
||||||
public interface SimpleMap<K,V> {
|
|
||||||
/**
|
|
||||||
* returns the state associated with a given node
|
|
||||||
*
|
|
||||||
* @param node
|
|
||||||
*/
|
|
||||||
public V get(Object node);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* sets the state associated with a given node, and returns the previous
|
|
||||||
* associated states
|
|
||||||
*
|
|
||||||
* @param key
|
|
||||||
*/
|
|
||||||
public V put(K key, V value);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* clear this {@link SimpleMap}
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public void clear();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A {@link SimpleMap}that maps
|
|
||||||
* {@link com.ibm.wala.util.graph.INodeWithNumber}to their traversal state.
|
|
||||||
* <p>
|
|
||||||
* NOTE: the capacity of this map does not grow!
|
|
||||||
*
|
|
||||||
* @version
|
|
||||||
*/
|
|
||||||
public static class NumberedSimpleMap<K,V> implements SimpleMap<K,V> {
|
|
||||||
final Object[] table;
|
|
||||||
|
|
||||||
public NumberedSimpleMap(int capacity) {
|
|
||||||
table = new Object[capacity];
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public V get(Object n) {
|
|
||||||
int id = ((INodeWithNumber) n).getGraphNodeId();
|
|
||||||
V ret = (V) table[id];
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public V put(K key, V value) {
|
|
||||||
int id = ((INodeWithNumber) key).getGraphNodeId();
|
|
||||||
V prev = (V) table[id];
|
|
||||||
table[id] = value;
|
|
||||||
return prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clear() {
|
|
||||||
Arrays.fill(table, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Default implementation of {@link SimpleMap}based on a {@link HashMap}
|
|
||||||
*
|
|
||||||
* @version
|
|
||||||
*/
|
|
||||||
public static class DefaultSimpleMap<K,V> extends HashMap<K,V> implements SimpleMap<K,V> {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 8314610925208365087L;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs an empty DefaultSimpleMap with the specified initial capacity.
|
|
||||||
*/
|
|
||||||
public DefaultSimpleMap(int initialCapacity) {
|
|
||||||
super(initialCapacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
public DefaultSimpleMap() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs an empty DefaultSimpleMap with the specified initial capacity
|
|
||||||
* and load factor.
|
|
||||||
*/
|
|
||||||
public DefaultSimpleMap(int initialCapacity, float loadFactor) {
|
|
||||||
super(initialCapacity, loadFactor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A visitor that visits Nodes in the DFS2 of a graph
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:achille@us.ibm.com">Achille Fokoue </a>
|
|
||||||
* @version
|
|
||||||
*/
|
|
||||||
public static abstract class Visitor {
|
|
||||||
public abstract void visit(Object node, Object parent);
|
|
||||||
|
|
||||||
public abstract void leave(Object node);
|
|
||||||
|
|
||||||
public void visitEdge(Object source, Object target) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Depth first search of a node of graph using a stack instead of recursive
|
|
||||||
* method calls. This is necessary in order to avoid
|
|
||||||
* java.lang.StackOverflowError for big graphs.
|
|
||||||
*/
|
|
||||||
private static <T >void DFS(Graph<T> g, T node, SimpleMap<T, Iterator<? extends T>> states, Visitor visitor) {
|
|
||||||
int leave = 0;
|
|
||||||
int found = 0;
|
|
||||||
Stack<T> pending = new Stack<T>();
|
|
||||||
found++;
|
|
||||||
visitor.visit(node, null);
|
|
||||||
states.put(node, getConnectedTo(g, node));
|
|
||||||
pending.push(node);
|
|
||||||
cont: while (!pending.isEmpty()) {
|
|
||||||
T current = pending.peek();
|
|
||||||
Iterator<? extends T> currentChildren = states.get(current);
|
|
||||||
for (Iterator<? extends T> e = currentChildren; e.hasNext();) {
|
|
||||||
T currentChild = e.next();
|
|
||||||
// visit edge
|
|
||||||
visitor.visitEdge(current, currentChild);
|
|
||||||
Iterator currentGrandChildren = states.get(currentChild);
|
|
||||||
if (currentGrandChildren == null) {
|
|
||||||
// new child discovered
|
|
||||||
found++;
|
|
||||||
visitor.visit(currentChild, current);
|
|
||||||
states.put(currentChild, getConnectedTo(g, currentChild));
|
|
||||||
pending.push(currentChild);
|
|
||||||
// recursion continue
|
|
||||||
continue cont;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// all children of current have been processed
|
|
||||||
// current is finished
|
|
||||||
Object ret = pending.pop();
|
|
||||||
if (Assertions.verifyAssertions) {
|
|
||||||
Assertions._assert(ret == current);
|
|
||||||
}
|
|
||||||
leave++;
|
|
||||||
visitor.leave(current);
|
|
||||||
// allow the garbage collector to do its job
|
|
||||||
Iterator<? extends T> empty = EmptyIterator.instance();
|
|
||||||
states.put(current, empty);
|
|
||||||
|
|
||||||
}
|
|
||||||
if (Assertions.verifyAssertions) {
|
|
||||||
Assertions._assert(found == leave, found + " nodes discovered, but " + leave + " finished!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static <T> Iterator<? extends T> getConnectedTo(Graph<T> g, T node) {
|
|
||||||
return g.getSuccNodes(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Depth first search of a graph using a stack instead of recursive method
|
|
||||||
* calls. This is necessary in order to avoid java.lang.StackOverflowError for
|
|
||||||
* big graphs
|
|
||||||
*
|
|
||||||
* @param g
|
|
||||||
* the graph to traverse
|
|
||||||
* @param nodes
|
|
||||||
* an iterator over the nodes where the traversal should start
|
|
||||||
* @param visitor
|
|
||||||
* the visitor to notify when nodes are discovered and finished
|
|
||||||
* @param states
|
|
||||||
* the map to use to store and retrieve the state of nodes
|
|
||||||
*/
|
|
||||||
public static <T> void DFS(Graph<T> g, Iterator<? extends T> nodes, Visitor visitor, SimpleMap<T,Iterator<? extends T>> states) {
|
|
||||||
for (Iterator<? extends T> it = nodes; it.hasNext();) {
|
|
||||||
T node = it.next();
|
|
||||||
if (node != null && states.get(node) == null) {
|
|
||||||
DFS(g, node, states, visitor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Depth first search of a graph using a stack instead of recursive method
|
|
||||||
* calls. This is necessary in order to avoid java.lang.StackOverflowError for
|
|
||||||
* big graphs
|
|
||||||
*
|
|
||||||
* @param g
|
|
||||||
* the graph to traverse
|
|
||||||
* @param nodes
|
|
||||||
* an iterator over the nodes where the traversal should start
|
|
||||||
* @param visitor
|
|
||||||
* the visitor to notify when nodes are discovered and finished
|
|
||||||
*/
|
|
||||||
public static <T> void DFS(Graph<T> g, Iterator<? extends T> nodes, Visitor visitor) {
|
|
||||||
if (g instanceof NumberedGraph) {
|
|
||||||
DFS(g, nodes, visitor, new NumberedSimpleMap<T, Iterator<? extends T>>(g.getNumberOfNodes()));
|
|
||||||
} else {
|
|
||||||
DFS(g, nodes, visitor, new DefaultSimpleMap<T,Iterator<? extends T>>());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Depth first search of a graph using a stack instead of recursive method
|
|
||||||
* calls. This is necessary in order to avoid java.lang.StackOverflowError for
|
|
||||||
* big graphs
|
|
||||||
*
|
|
||||||
* @param g
|
|
||||||
* the graph to traverse
|
|
||||||
* @param visitor
|
|
||||||
* the visitor to notify when nodes are discovered and finished
|
|
||||||
* @throws IllegalArgumentException if g is null
|
|
||||||
*/
|
|
||||||
public static <T> void DFS(Graph<T> g, Visitor visitor) {
|
|
||||||
if (g == null) {
|
|
||||||
throw new IllegalArgumentException("g is null");
|
|
||||||
}
|
|
||||||
DFS(g, g.iterator(), visitor);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -107,9 +107,7 @@ public class BimodalMutableIntSet implements MutableIntSet {
|
||||||
// don't bother
|
// don't bother
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int bvSize = BitVector.subscript(impl.max()) + 1;
|
int bvSize = BitVectorBase.subscript(impl.max()) + 1;
|
||||||
// Trace.println("S B " + sparseSize + " " + bvSize + " " + impl.max() + " "
|
|
||||||
// + impl);
|
|
||||||
if (sparseSize > bvSize) {
|
if (sparseSize > bvSize) {
|
||||||
if (!(impl instanceof BitVectorIntSet)) {
|
if (!(impl instanceof BitVectorIntSet)) {
|
||||||
impl = new BitVectorIntSet(impl);
|
impl = new BitVectorIntSet(impl);
|
||||||
|
|
|
@ -356,10 +356,4 @@ public final class MutableSparseLongSet extends SparseLongSet implements Mutable
|
||||||
size = ci;
|
size = ci;
|
||||||
return (al != size);
|
return (al != size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void removeAll(MutableSparseLongSet set) throws UnimplementedError {
|
|
||||||
Assertions.UNREACHABLE("implement me");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -48,9 +48,9 @@ import com.ibm.wala.util.warnings.WalaException;
|
||||||
* Given an Eclipse plugin, this class detects all the other plugins that should
|
* Given an Eclipse plugin, this class detects all the other plugins that should
|
||||||
* be part of the analysis scope when analyzing the given plugin.
|
* be part of the analysis scope when analyzing the given plugin.
|
||||||
*
|
*
|
||||||
* This is buggy in that it ignores the Import-Package declarations in the manifest.
|
* This is buggy in that it ignores the Import-Package declarations in the
|
||||||
* This is a problem. Probably the way to go is to recode this whole thing using
|
* manifest. This is a problem. Probably the way to go is to recode this whole
|
||||||
* a headless Eclipse instance, and rely on Eclipse APIs to resolve
|
* thing using a headless Eclipse instance, and rely on Eclipse APIs to resolve
|
||||||
* dependencies the right way.
|
* dependencies the right way.
|
||||||
*
|
*
|
||||||
* @author Marco Pistoia
|
* @author Marco Pistoia
|
||||||
|
@ -95,7 +95,6 @@ public class EclipseAnalysisScope extends AnalysisScope {
|
||||||
*/
|
*/
|
||||||
private final String pluginsDirName;
|
private final String pluginsDirName;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param pluginName
|
* @param pluginName
|
||||||
* name of the plugin to be analyzed
|
* name of the plugin to be analyzed
|
||||||
|
@ -265,9 +264,11 @@ public class EclipseAnalysisScope extends AnalysisScope {
|
||||||
* @return a File representing the directory or JAR file containing the
|
* @return a File representing the directory or JAR file containing the
|
||||||
* plugin. This method returns <code>null</code> if no directory or
|
* plugin. This method returns <code>null</code> if no directory or
|
||||||
* JAR file was found for this plugin.
|
* JAR file was found for this plugin.
|
||||||
* @throws IllegalArgumentException if pluginDirectory is null
|
* @throws IllegalArgumentException
|
||||||
|
* if pluginDirectory is null
|
||||||
*/
|
*/
|
||||||
public static File findPluginDirOrJAR(String libName, String pluginsDirName, File pluginDirectory) throws IllegalArgumentException {
|
public static File findPluginDirOrJAR(String libName, String pluginsDirName, File pluginDirectory)
|
||||||
|
throws IllegalArgumentException {
|
||||||
if (pluginDirectory == null) {
|
if (pluginDirectory == null) {
|
||||||
throw new IllegalArgumentException("pluginDirectory is null");
|
throw new IllegalArgumentException("pluginDirectory is null");
|
||||||
}
|
}
|
||||||
|
@ -348,7 +349,8 @@ public class EclipseAnalysisScope extends AnalysisScope {
|
||||||
* in its MANIFEST.MF file.
|
* in its MANIFEST.MF file.
|
||||||
*
|
*
|
||||||
* @param manifestFileName
|
* @param manifestFileName
|
||||||
* a String representing the fully qualified name of a manifest file.
|
* a String representing the fully qualified name of a manifest
|
||||||
|
* file.
|
||||||
* @return a TreeSet of Strings each of which represents the fully qualified
|
* @return a TreeSet of Strings each of which represents the fully qualified
|
||||||
* name of a required plugin's directory. The returned TreeSet is
|
* name of a required plugin's directory. The returned TreeSet is
|
||||||
* <code>null</code> if it was not possible to have access to the
|
* <code>null</code> if it was not possible to have access to the
|
||||||
|
@ -373,7 +375,7 @@ public class EclipseAnalysisScope extends AnalysisScope {
|
||||||
String requiredBundleName = (requiredArray[i].trim()).split(";")[0];
|
String requiredBundleName = (requiredArray[i].trim()).split(";")[0];
|
||||||
if ((version > 3 || version == 3 && subversion >= 2) && Character.isDigit(requiredBundleName.charAt(0)))
|
if ((version > 3 || version == 3 && subversion >= 2) && Character.isDigit(requiredBundleName.charAt(0)))
|
||||||
continue;
|
continue;
|
||||||
File requiredBundle = findPluginDirOrJAR(requiredBundleName, pluginDirsName,pluginDirectory);
|
File requiredBundle = findPluginDirOrJAR(requiredBundleName, pluginDirsName, pluginDirectory);
|
||||||
if (requiredBundle == null) {
|
if (requiredBundle == null) {
|
||||||
System.err.println("EclipseAnalysisScopeBuilder: " + requiredBundleName + " was not found.");
|
System.err.println("EclipseAnalysisScopeBuilder: " + requiredBundleName + " was not found.");
|
||||||
continue;
|
continue;
|
||||||
|
@ -442,7 +444,7 @@ public class EclipseAnalysisScope extends AnalysisScope {
|
||||||
Iterator pluginIdsIter = pluginIds.iterator();
|
Iterator pluginIdsIter = pluginIds.iterator();
|
||||||
while (pluginIdsIter.hasNext()) {
|
while (pluginIdsIter.hasNext()) {
|
||||||
String fragmentHost = (String) pluginIdsIter.next();
|
String fragmentHost = (String) pluginIdsIter.next();
|
||||||
result.addAll(getContributingFragment(fragmentHost, manifestName, pluginsDirName, pluginDirectory));
|
result.addAll(getContributingFragment(fragmentHost, manifestName, pluginDirectory));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -459,7 +461,8 @@ public class EclipseAnalysisScope extends AnalysisScope {
|
||||||
* The name of the current manifest file being scanned.
|
* The name of the current manifest file being scanned.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private Collection<JarFile> getContributingFragment(String fragmentHost, String manifestFileName, String pluginsDirName, File pluginDirectory) {
|
private Collection<JarFile> getContributingFragment(String fragmentHost, String manifestFileName,
|
||||||
|
File pluginDirectory) {
|
||||||
Collection<JarFile> result = HashSetFactory.make();
|
Collection<JarFile> result = HashSetFactory.make();
|
||||||
InputStream is = getInputStream(manifestFileName);
|
InputStream is = getInputStream(manifestFileName);
|
||||||
if (is == null) {
|
if (is == null) {
|
||||||
|
|
|
@ -230,6 +230,10 @@ public class DotUtil {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param n node to decorate
|
||||||
|
* @param d decorating master
|
||||||
|
*/
|
||||||
private static String decorateNode(Object n, NodeDecorator d) throws WalaException {
|
private static String decorateNode(Object n, NodeDecorator d) throws WalaException {
|
||||||
StringBuffer result = new StringBuffer();
|
StringBuffer result = new StringBuffer();
|
||||||
|
|
||||||
|
|
|
@ -39,28 +39,22 @@ public class GhostviewUtil {
|
||||||
/**
|
/**
|
||||||
* spawn a process to ghostview a WALA IR
|
* spawn a process to ghostview a WALA IR
|
||||||
*
|
*
|
||||||
* @param cha
|
|
||||||
* @param ir
|
|
||||||
* @return a handle to the ghostview process
|
* @return a handle to the ghostview process
|
||||||
* @throws WalaException
|
|
||||||
*/
|
*/
|
||||||
public static Process ghostviewIR(IClassHierarchy cha, IR ir, boolean sanitize, String psFile, String dotFile, String dotExe,
|
public static Process ghostviewIR(IClassHierarchy cha, IR ir, String psFile, String dotFile, String dotExe, String gvExe)
|
||||||
String gvExe) throws WalaException {
|
throws WalaException {
|
||||||
return ghostviewIR(cha, ir, sanitize, psFile, dotFile, dotExe, gvExe, null);
|
return ghostviewIR(cha, ir, psFile, dotFile, dotExe, gvExe, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* spawn a process to ghostview a WALA IR
|
* spawn a process to ghostview a WALA IR
|
||||||
*
|
*
|
||||||
* @param cha
|
|
||||||
* @param ir
|
|
||||||
* @return a handle to the ghostview process
|
* @return a handle to the ghostview process
|
||||||
* @throws WalaException
|
|
||||||
* @throws IllegalArgumentException
|
* @throws IllegalArgumentException
|
||||||
* if ir is null
|
* if ir is null
|
||||||
*/
|
*/
|
||||||
public static Process ghostviewIR(IClassHierarchy cha, IR ir, boolean sanitize, String psFile, String dotFile, String dotExe,
|
public static Process ghostviewIR(IClassHierarchy cha, IR ir, String psFile, String dotFile, String dotExe, String gvExe,
|
||||||
String gvExe, NodeDecorator annotations) throws WalaException {
|
NodeDecorator annotations) throws WalaException {
|
||||||
|
|
||||||
if (ir == null) {
|
if (ir == null) {
|
||||||
throw new IllegalArgumentException("ir is null");
|
throw new IllegalArgumentException("ir is null");
|
||||||
|
|
|
@ -188,10 +188,10 @@ public class SWTTreeViewer extends EJfaceApplicationRunner {
|
||||||
*/
|
*/
|
||||||
public IStructuredSelection getSelection() throws IllegalStateException {
|
public IStructuredSelection getSelection() throws IllegalStateException {
|
||||||
GraphViewer viewer = (GraphViewer)getApplicationWindow();
|
GraphViewer viewer = (GraphViewer)getApplicationWindow();
|
||||||
if (viewer == null || viewer.viewer == null) {
|
if (viewer == null || viewer.treeViewer == null) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
return (IStructuredSelection) viewer.viewer.getSelection();
|
return (IStructuredSelection) viewer.treeViewer.getSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -209,7 +209,7 @@ public class SWTTreeViewer extends EJfaceApplicationRunner {
|
||||||
/**
|
/**
|
||||||
* JFace component implementing the tree viewer
|
* JFace component implementing the tree viewer
|
||||||
*/
|
*/
|
||||||
private TreeViewer viewer;
|
private TreeViewer treeViewer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws WalaException
|
* @throws WalaException
|
||||||
|
@ -227,20 +227,20 @@ public class SWTTreeViewer extends EJfaceApplicationRunner {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Control createContents(Composite parent) {
|
protected Control createContents(Composite parent) {
|
||||||
viewer = new TreeViewer(parent);
|
treeViewer = new TreeViewer(parent);
|
||||||
viewer.setContentProvider(new GraphContentProvider());
|
treeViewer.setContentProvider(new GraphContentProvider());
|
||||||
viewer.setLabelProvider(new GraphLabelProvider());
|
treeViewer.setLabelProvider(new GraphLabelProvider());
|
||||||
viewer.setInput(getGraphInput());
|
treeViewer.setInput(getGraphInput());
|
||||||
|
|
||||||
// create a pop-up menu
|
// create a pop-up menu
|
||||||
if (getPopUpActions().size() > 0) {
|
if (getPopUpActions().size() > 0) {
|
||||||
MenuManager mm = new MenuManager();
|
MenuManager mm = new MenuManager();
|
||||||
viewer.getTree().setMenu(mm.createContextMenu(viewer.getTree()));
|
treeViewer.getTree().setMenu(mm.createContextMenu(treeViewer.getTree()));
|
||||||
for (Iterator<ViewIRAction> it = getPopUpActions().iterator(); it.hasNext(); ) {
|
for (Iterator<ViewIRAction> it = getPopUpActions().iterator(); it.hasNext(); ) {
|
||||||
mm.add(it.next());
|
mm.add(it.next());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return viewer.getTree();
|
return treeViewer.getTree();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,8 @@ public class ViewAnnotatedIRAction extends ViewIRAction {
|
||||||
|
|
||||||
private final BasicBlockDecorator dec;
|
private final BasicBlockDecorator dec;
|
||||||
|
|
||||||
public ViewAnnotatedIRAction(SWTTreeViewer viewer, CallGraph cg, String psFile, String dotFile, String dotExe, String gvExe, BasicBlockDecorator dec) {
|
public ViewAnnotatedIRAction(SWTTreeViewer viewer, CallGraph cg, String psFile, String dotFile, String dotExe, String gvExe,
|
||||||
|
BasicBlockDecorator dec) {
|
||||||
super(viewer, cg, psFile, dotFile, dotExe, gvExe);
|
super(viewer, cg, psFile, dotFile, dotExe, gvExe);
|
||||||
this.dec = dec;
|
this.dec = dec;
|
||||||
}
|
}
|
||||||
|
@ -34,7 +35,7 @@ public class ViewAnnotatedIRAction extends ViewIRAction {
|
||||||
System.err.println("Spawn IR Viewer for " + ir.getMethod());
|
System.err.println("Spawn IR Viewer for " + ir.getMethod());
|
||||||
try {
|
try {
|
||||||
dec.setCurrentNode(getNodeForSelection());
|
dec.setCurrentNode(getNodeForSelection());
|
||||||
GhostviewUtil.ghostviewIR(getCg().getClassHierarchy(), ir, false, getPsFile(), getDotFile(), getDotExe(), getGvExe(), dec);
|
GhostviewUtil.ghostviewIR(getCg().getClassHierarchy(), ir, getPsFile(), getDotFile(), getDotExe(), getGvExe(), dec);
|
||||||
} catch (WalaException e) {
|
} catch (WalaException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ public class ViewIRAction extends Action {
|
||||||
// spawn the viewer
|
// spawn the viewer
|
||||||
System.err.println("Spawn IR Viewer for " + ir.getMethod());
|
System.err.println("Spawn IR Viewer for " + ir.getMethod());
|
||||||
try {
|
try {
|
||||||
GhostviewUtil.ghostviewIR(cg.getClassHierarchy(), ir, false, psFile, dotFile, dotExe, gvExe);
|
GhostviewUtil.ghostviewIR(cg.getClassHierarchy(), ir, psFile, dotFile, dotExe, gvExe);
|
||||||
} catch (WalaException e) {
|
} catch (WalaException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue