introduce ClassHierarchyDweller

git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@516 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
sjfink 2006-12-21 19:03:50 +00:00
parent 1360502cd4
commit 59f5f9d69e
17 changed files with 80 additions and 39 deletions

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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.

View File

@ -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();
}
}

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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 {

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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) {

View File

@ -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);

View File

@ -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 {

View File

@ -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 {

View File

@ -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;

View File

@ -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];
}
}