introduce ClassHierarchyDweller
git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@516 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
parent
1360502cd4
commit
59f5f9d69e
|
@ -14,6 +14,7 @@ import java.util.Collection;
|
|||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
import com.ibm.wala.shrikeBT.Constants;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
|
@ -33,19 +34,22 @@ import com.ibm.wala.util.debug.Assertions;
|
|||
*/
|
||||
public class ArrayClass implements IClass, Constants {
|
||||
|
||||
private final ClassHierarchy cha;
|
||||
|
||||
/**
|
||||
* Package-visible constructor; only for use by ArrayClassLoader class.
|
||||
* 'loader' must be the Primordial IClassLoader.
|
||||
*
|
||||
* [WHY? -- array classes are loaded by the element classloader??]
|
||||
*/
|
||||
ArrayClass(TypeReference type, IClassLoader loader) {
|
||||
ArrayClass(TypeReference type, IClassLoader loader, ClassHierarchy cha) {
|
||||
this.type = type;
|
||||
this.loader = loader;
|
||||
this.cha = cha;
|
||||
if (Assertions.verifyAssertions) {
|
||||
TypeReference elementType = type.getInnermostElementType();
|
||||
if (!elementType.isPrimitiveType()) {
|
||||
IClass klass = loader.lookupClass(elementType.getName());
|
||||
IClass klass = loader.lookupClass(elementType.getName(), cha);
|
||||
if (klass == null) {
|
||||
Assertions.UNREACHABLE("caller should not attempt to create an array with type " + type);
|
||||
}
|
||||
|
@ -123,14 +127,14 @@ public class ArrayClass implements IClass, Constants {
|
|||
// 1) [Ljava/lang/Object
|
||||
// 2) [? for primitive arrays (null from getElementClass)
|
||||
if (elt == null || elt.getReference() == TypeReference.JavaLangObject) {
|
||||
return loader.lookupClass(TypeReference.JavaLangObject.getName());
|
||||
return loader.lookupClass(TypeReference.JavaLangObject.getName(), getClassHierarchy());
|
||||
}
|
||||
|
||||
// else it is array of super of element type (yuck)
|
||||
else {
|
||||
TypeReference eltSuperRef = elt.getSuperclass().getReference();
|
||||
TypeReference superRef = TypeReference.findOrCreateArrayOf(eltSuperRef);
|
||||
return elt.getSuperclass().getClassLoader().lookupClass(superRef.getName());
|
||||
return elt.getSuperclass().getClassLoader().lookupClass(superRef.getName(), getClassHierarchy());
|
||||
}
|
||||
} catch (ClassHierarchyException e) {
|
||||
e.printStackTrace();
|
||||
|
@ -145,7 +149,7 @@ public class ArrayClass implements IClass, Constants {
|
|||
* @see com.ibm.wala.classLoader.IClass#getMethod(com.ibm.wala.classLoader.Selector)
|
||||
*/
|
||||
public IMethod getMethod(Selector sig) {
|
||||
return loader.lookupClass(TypeReference.JavaLangObject.getName()).getMethod(sig);
|
||||
return loader.lookupClass(TypeReference.JavaLangObject.getName(), getClassHierarchy()).getMethod(sig);
|
||||
}
|
||||
|
||||
public IField getField(Atom name) {
|
||||
|
@ -219,7 +223,7 @@ public class ArrayClass implements IClass, Constants {
|
|||
if (elementType.isPrimitiveType()) {
|
||||
return null;
|
||||
}
|
||||
return loader.lookupClass(elementType.getName());
|
||||
return loader.lookupClass(elementType.getName(), getClassHierarchy());
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
|
@ -253,8 +257,8 @@ public class ArrayClass implements IClass, Constants {
|
|||
*/
|
||||
public Collection<IClass> getAllImplementedInterfaces() {
|
||||
HashSet<IClass> result = HashSetFactory.make(2);
|
||||
result.add(loader.lookupClass(TypeReference.array_interfaces[0]));
|
||||
result.add(loader.lookupClass(TypeReference.array_interfaces[1]));
|
||||
result.add(loader.lookupClass(TypeReference.array_interfaces[0], getClassHierarchy()));
|
||||
result.add(loader.lookupClass(TypeReference.array_interfaces[1], getClassHierarchy()));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -290,7 +294,7 @@ public class ArrayClass implements IClass, Constants {
|
|||
if (elementType.isPrimitiveType()) {
|
||||
return null;
|
||||
}
|
||||
return loader.lookupClass(elementType.getName());
|
||||
return loader.lookupClass(elementType.getName(), getClassHierarchy());
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -351,4 +355,8 @@ public class ArrayClass implements IClass, Constants {
|
|||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
|
||||
public ClassHierarchy getClassHierarchy() {
|
||||
return cha;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ package com.ibm.wala.classLoader;
|
|||
|
||||
import java.util.HashMap;
|
||||
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.types.TypeName;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.collections.HashMapFactory;
|
||||
|
@ -32,13 +33,14 @@ public class ArrayClassLoader {
|
|||
*/
|
||||
private HashMap<TypeReference, ArrayClass> arrayClasses = HashMapFactory.make();
|
||||
|
||||
|
||||
/**
|
||||
* @param className
|
||||
* name of the array class
|
||||
* @param delegator
|
||||
* class loader to look up element type with
|
||||
*/
|
||||
public IClass lookupClass(TypeName className, IClassLoader delegator) {
|
||||
public IClass lookupClass(TypeName className, IClassLoader delegator, ClassHierarchy cha) {
|
||||
if (DEBUG) {
|
||||
Assertions._assert(className.toString().startsWith("["));
|
||||
}
|
||||
|
@ -52,14 +54,14 @@ public class ArrayClassLoader {
|
|||
arrayClass = arrayClasses.get(aRef);
|
||||
IClassLoader primordial = getRootClassLoader(delegator);
|
||||
if (arrayClass == null) {
|
||||
arrayClasses.put(aRef, arrayClass = new ArrayClass(aRef, primordial));
|
||||
arrayClasses.put(aRef, arrayClass = new ArrayClass(aRef, primordial, cha));
|
||||
}
|
||||
} else {
|
||||
// check that the element class is loadable. If not, return null.
|
||||
if (delegator.lookupClass(elementType.getName()) == null) {
|
||||
if (delegator.lookupClass(elementType.getName(), cha) == null) {
|
||||
return null;
|
||||
}
|
||||
arrayClass = new ArrayClass(type, delegator);
|
||||
arrayClass = new ArrayClass(type, delegator, cha);
|
||||
}
|
||||
arrayClasses.put(type, arrayClass);
|
||||
}
|
||||
|
|
|
@ -396,14 +396,14 @@ public class ClassLoaderImpl implements IClassLoader {
|
|||
return loadedClasses.get(className);
|
||||
}
|
||||
|
||||
public IClass lookupClass(TypeName className) {
|
||||
public IClass lookupClass(TypeName className, ClassHierarchy cha) {
|
||||
if (DEBUG_LEVEL > 1) {
|
||||
Trace.println(this + ": lookupClass " + className);
|
||||
}
|
||||
|
||||
// treat arrays specially:
|
||||
if (className.isArrayType()) {
|
||||
return arrayClassLoader.lookupClass(className, this);
|
||||
return arrayClassLoader.lookupClass(className, this,cha);
|
||||
}
|
||||
|
||||
// try delegating first.
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
*******************************************************************************/
|
||||
package com.ibm.wala.classLoader;
|
||||
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.shrikeCT.ClassConstants;
|
||||
import com.ibm.wala.types.FieldReference;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
|
@ -17,7 +18,7 @@ import com.ibm.wala.util.Atom;
|
|||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* Implementation of a canonical field reference. TODO: canonicalize these?
|
||||
* TODO: don't cache fieldType here .. move to class?
|
||||
*
|
||||
|
@ -26,13 +27,15 @@ import com.ibm.wala.util.debug.Assertions;
|
|||
public final class FieldImpl implements IField {
|
||||
|
||||
private final IClass declaringClass;
|
||||
|
||||
private final FieldReference fieldRef;
|
||||
|
||||
private final int accessFlags;
|
||||
|
||||
/**
|
||||
* constructor when the field type is not a primitive
|
||||
*/
|
||||
public FieldImpl(IClass declaringClass, FieldReference canonicalRef,int accessFlags) {
|
||||
public FieldImpl(IClass declaringClass, FieldReference canonicalRef, int accessFlags) {
|
||||
this.declaringClass = declaringClass;
|
||||
this.fieldRef = canonicalRef;
|
||||
this.accessFlags = accessFlags;
|
||||
|
@ -60,7 +63,7 @@ public final class FieldImpl implements IField {
|
|||
// instanceof is OK because this class is final
|
||||
if (obj instanceof FieldImpl) {
|
||||
FieldImpl other = (FieldImpl) obj;
|
||||
return fieldRef.equals(other.fieldRef) && declaringClass.equals(other.declaringClass);
|
||||
return fieldRef.equals(other.fieldRef) && declaringClass.equals(other.declaringClass);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -111,20 +114,23 @@ public final class FieldImpl implements IField {
|
|||
return ((accessFlags & ClassConstants.ACC_STATIC) != 0);
|
||||
}
|
||||
|
||||
|
||||
public boolean isFinal() {
|
||||
return ((accessFlags & ClassConstants.ACC_FINAL) != 0);
|
||||
}
|
||||
|
||||
public boolean isPrivate() {
|
||||
return ((accessFlags & ClassConstants.ACC_PRIVATE) != 0);
|
||||
return ((accessFlags & ClassConstants.ACC_PRIVATE) != 0);
|
||||
}
|
||||
|
||||
public boolean isProtected() {
|
||||
return ((accessFlags & ClassConstants.ACC_PROTECTED) != 0);
|
||||
return ((accessFlags & ClassConstants.ACC_PROTECTED) != 0);
|
||||
}
|
||||
|
||||
public boolean isPublic() {
|
||||
return ((accessFlags & ClassConstants.ACC_PUBLIC) != 0);
|
||||
return ((accessFlags & ClassConstants.ACC_PUBLIC) != 0);
|
||||
}
|
||||
|
||||
public ClassHierarchy getClassHierarchy() {
|
||||
return declaringClass.getClassHierarchy();
|
||||
}
|
||||
}
|
|
@ -15,6 +15,7 @@ import java.util.Collection;
|
|||
import java.util.Iterator;
|
||||
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchyDweller;
|
||||
import com.ibm.wala.types.Selector;
|
||||
import com.ibm.wala.types.TypeName;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
|
@ -27,7 +28,7 @@ import com.ibm.wala.util.Atom;
|
|||
*
|
||||
* @author sfink
|
||||
*/
|
||||
public interface IClass {
|
||||
public interface IClass extends IClassHierarchyDweller {
|
||||
|
||||
/**
|
||||
* Return the object that represents the defining class loader
|
||||
|
|
|
@ -16,6 +16,7 @@ import java.util.Collection;
|
|||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.types.TypeName;
|
||||
import com.ibm.wala.util.Atom;
|
||||
|
@ -36,7 +37,7 @@ public interface IClassLoader {
|
|||
* @return the IClass defined by this class loader that
|
||||
* corresponds to the given class name, or null if not found.
|
||||
*/
|
||||
public abstract IClass lookupClass(TypeName className);
|
||||
public abstract IClass lookupClass(TypeName className, ClassHierarchy cha);
|
||||
|
||||
/**
|
||||
* Return the ClassLoaderReference for this class loader.
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
*******************************************************************************/
|
||||
package com.ibm.wala.classLoader;
|
||||
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchyDweller;
|
||||
import com.ibm.wala.util.Atom;
|
||||
|
||||
/**
|
||||
|
@ -19,7 +20,7 @@ import com.ibm.wala.util.Atom;
|
|||
*
|
||||
* @author sfink
|
||||
*/
|
||||
public interface IMember {
|
||||
public interface IMember extends IClassHierarchyDweller {
|
||||
|
||||
/**
|
||||
* Return the object that represents the declaring class
|
||||
|
|
|
@ -274,12 +274,12 @@ public final class ShrikeCTClassWrapper implements IClass {
|
|||
|
||||
if (superName == null) {
|
||||
if (!getReference().equals(TypeReference.JavaLangObject)) {
|
||||
superClass = loader.lookupClass(TypeReference.JavaLangObject.getName());
|
||||
superClass = loader.lookupClass(TypeReference.JavaLangObject.getName(), getClassHierarchy());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
superClass = loader.lookupClass(TypeName.findOrCreate(superName));
|
||||
superClass = loader.lookupClass(TypeName.findOrCreate(superName), getClassHierarchy());
|
||||
if (DEBUG) {
|
||||
Trace.println("got superclass " + superClass + " for " + this);
|
||||
}
|
||||
|
@ -379,7 +379,7 @@ public final class ShrikeCTClassWrapper implements IClass {
|
|||
for (int i = 0; i < interfaces.length; i++) {
|
||||
ImmutableByteArray name = interfaces[i];
|
||||
IClass klass = null;
|
||||
klass = loader.lookupClass(TypeName.findOrCreate(name));
|
||||
klass = loader.lookupClass(TypeName.findOrCreate(name), getClassHierarchy());
|
||||
if (klass == null) {
|
||||
warnings.add(ClassNotFoundWarning.create(name));
|
||||
} else {
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
*******************************************************************************/
|
||||
package com.ibm.wala.classLoader;
|
||||
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.shrikeBT.Decoder;
|
||||
import com.ibm.wala.shrikeBT.shrikeCT.CTDecoder;
|
||||
import com.ibm.wala.shrikeCT.ClassReader;
|
||||
|
@ -40,10 +41,13 @@ public final class ShrikeCTMethodWrapper extends ShrikeBTMethodWrapper {
|
|||
* JVM-level modifiers for this method a value of -1 means "uninitialized"
|
||||
*/
|
||||
private int modifiers = -1;
|
||||
|
||||
private final ClassHierarchy cha;
|
||||
|
||||
public ShrikeCTMethodWrapper(IClass klass, int index) {
|
||||
super(klass);
|
||||
this.shrikeMethodIndex = index;
|
||||
this.cha = klass.getClassHierarchy();
|
||||
}
|
||||
|
||||
public byte[] getBytecodes() {
|
||||
|
@ -238,4 +242,8 @@ public final class ShrikeCTMethodWrapper extends ShrikeBTMethodWrapper {
|
|||
public TypeReference getReturnType() {
|
||||
return getReference().getReturnType();
|
||||
}
|
||||
|
||||
public ClassHierarchy getClassHierarchy() {
|
||||
return cha;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@ public abstract class SyntheticClass implements IClass {
|
|||
|
||||
private final TypeReference T;
|
||||
|
||||
|
||||
|
||||
private final ClassHierarchy cha;
|
||||
/**
|
||||
* @param T type reference describing this class
|
||||
|
@ -78,4 +80,8 @@ public abstract class SyntheticClass implements IClass {
|
|||
public boolean isArrayClass() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public ClassHierarchy getClassHierarchy() {
|
||||
return cha;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ package com.ibm.wala.classLoader;
|
|||
|
||||
import com.ibm.wala.cfg.InducedCFG;
|
||||
import com.ibm.wala.ipa.callgraph.impl.Everywhere;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.ssa.IR;
|
||||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.ssa.SSAOptions;
|
||||
|
@ -357,4 +358,9 @@ public class SyntheticMethod implements IMethod {
|
|||
return getReference().getReturnType();
|
||||
}
|
||||
|
||||
|
||||
public ClassHierarchy getClassHierarchy() {
|
||||
return getDeclaringClass().getClassHierarchy();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -483,7 +483,7 @@ public class PropagationSystem extends DefaultFixedPointSolver {
|
|||
for (int i = 1; i < dim; i++) {
|
||||
TypeReference jlo = makeArray(TypeReference.JavaLangObject, i);
|
||||
IClass jloClass = null;
|
||||
jloClass = aClass.getClassLoader().lookupClass(jlo.getName());
|
||||
jloClass = aClass.getClassLoader().lookupClass(jlo.getName(), aClass.getClassHierarchy());
|
||||
MutableIntSet set = findOrCreateSparseSetForClass(jloClass);
|
||||
set.add(index);
|
||||
}
|
||||
|
@ -502,7 +502,7 @@ public class PropagationSystem extends DefaultFixedPointSolver {
|
|||
IClass I = (IClass) it.next();
|
||||
TypeReference iArrayRef = makeArray(I.getReference(), dim);
|
||||
IClass iArrayClass = null;
|
||||
iArrayClass = I.getClassLoader().lookupClass(iArrayRef.getName());
|
||||
iArrayClass = I.getClassLoader().lookupClass(iArrayRef.getName(), I.getClassHierarchy());
|
||||
MutableIntSet set = findOrCreateSparseSetForClass(iArrayClass);
|
||||
set.add(index);
|
||||
if (DEBUG) {
|
||||
|
@ -527,7 +527,7 @@ public class PropagationSystem extends DefaultFixedPointSolver {
|
|||
while (T != null) {
|
||||
TypeReference tArrayRef = makeArray(T.getReference(), dim);
|
||||
IClass tArrayClass = null;
|
||||
tArrayClass = T.getClassLoader().lookupClass(tArrayRef.getName());
|
||||
tArrayClass = T.getClassLoader().lookupClass(tArrayRef.getName(), T.getClassHierarchy());
|
||||
MutableIntSet set = findOrCreateSparseSetForClass(tArrayClass);
|
||||
set.add(index);
|
||||
if (DEBUG) {
|
||||
|
|
|
@ -318,7 +318,7 @@ public class ClassHierarchy {
|
|||
throw new UnimplementedError("factory.getLoader failed " + e);
|
||||
}
|
||||
IClass declaredClass;
|
||||
declaredClass = loader.lookupClass(ref.getDeclaringClass().getName());
|
||||
declaredClass = loader.lookupClass(ref.getDeclaringClass().getName(), this);
|
||||
if (declaredClass == null) {
|
||||
return EmptyIterator.instance();
|
||||
}
|
||||
|
@ -741,7 +741,7 @@ public class ClassHierarchy {
|
|||
ClassLoaderReference loaderRef = A.getClassLoader();
|
||||
for (int i = 0; i < loaders.length; i++) {
|
||||
if (loaders[i].getReference().equals(loaderRef)) {
|
||||
IClass klass = loaders[i].lookupClass(A.getName());
|
||||
IClass klass = loaders[i].lookupClass(A.getName(), this);
|
||||
if (klass != null) {
|
||||
if (DEBUG) {
|
||||
Trace.println("lookupClass: got " + klass);
|
||||
|
|
|
@ -99,7 +99,7 @@ public class BypassClassTargetSelector implements ClassTargetSelector {
|
|||
}
|
||||
if (realType.isAbstract() || realType.isInterface()) {
|
||||
TypeName syntheticName = BypassSyntheticClass.getName(realRef);
|
||||
IClass result = bypassLoader.lookupClass(syntheticName);
|
||||
IClass result = bypassLoader.lookupClass(syntheticName, realType.getClassHierarchy());
|
||||
if (result != null) {
|
||||
return result;
|
||||
} else {
|
||||
|
|
|
@ -74,7 +74,7 @@ public class BypassSyntheticClass extends SyntheticClass {
|
|||
*/
|
||||
public IClass getSuperclass() throws ClassHierarchyException {
|
||||
if (realType.isInterface()) {
|
||||
IClass result = loader.lookupClass(TypeReference.JavaLangObject.getName());
|
||||
IClass result = loader.lookupClass(TypeReference.JavaLangObject.getName(), getClassHierarchy());
|
||||
if (result != null) {
|
||||
return result;
|
||||
} else {
|
||||
|
|
|
@ -73,8 +73,8 @@ public class BypassSyntheticClassLoader implements IClassLoader {
|
|||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IClass lookupClass(TypeName className) {
|
||||
IClass pc = parent.lookupClass(className);
|
||||
public IClass lookupClass(TypeName className, ClassHierarchy cha) {
|
||||
IClass pc = parent.lookupClass(className, cha);
|
||||
if (pc == null) {
|
||||
IClass c = syntheticClasses.get(className);
|
||||
return c;
|
||||
|
|
|
@ -51,7 +51,7 @@ import com.ibm.wala.util.warnings.WarningSet;
|
|||
* @author sfink
|
||||
*/
|
||||
|
||||
public class SSACFG implements ControlFlowGraph {
|
||||
public class SSACFG implements ControlFlowGraph{
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
|
@ -64,6 +64,7 @@ public class SSACFG implements ControlFlowGraph {
|
|||
private WarningSet warnings;
|
||||
|
||||
protected AbstractCFG cfg;
|
||||
|
||||
|
||||
/**
|
||||
* cache a ref to the exit block for efficient access
|
||||
|
@ -129,7 +130,7 @@ public class SSACFG implements ControlFlowGraph {
|
|||
} else {
|
||||
TypeReference exceptionType = ShrikeUtil.makeTypeReference(loader.getReference(), handler.getCatchClass());
|
||||
IClass klass = null;
|
||||
klass = loader.lookupClass(exceptionType.getName());
|
||||
klass = loader.lookupClass(exceptionType.getName(), method.getClassHierarchy());
|
||||
if (klass == null) {
|
||||
warnings.add(ExceptionLoadFailure.create(exceptionType, method));
|
||||
t = exceptionType;
|
||||
|
@ -1121,4 +1122,5 @@ public class SSACFG implements ControlFlowGraph {
|
|||
public IBasicBlock getBasicBlock(int bb) {
|
||||
return basicBlocks[bb];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue