Generalize certain IR data structures to be less Java-specific. Generalize annotations code to allow for reading annotation parameters. Various other fixes

git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@4290 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
msridhar1 2011-12-28 17:03:27 +00:00
parent bd315e7718
commit 59e46916ce
46 changed files with 1378 additions and 1269 deletions

View File

@ -138,7 +138,7 @@ public abstract class JavaIRTests extends IRTests {
final IClass iClass = cg.getClassHierarchy().lookupClass(type); final IClass iClass = cg.getClassHierarchy().lookupClass(type);
Assert.assertNotNull("Could not find class " + typeStr, iClass); Assert.assertNotNull("Could not find class " + typeStr, iClass);
final Collection<IClass> interfaces = iClass.getDirectInterfaces(); final Collection<? extends IClass> interfaces = iClass.getDirectInterfaces();
Assert.assertEquals("Expected one single interface.", interfaces.size(), 1); Assert.assertEquals("Expected one single interface.", interfaces.size(), 1);

View File

@ -316,14 +316,13 @@ public class JavaCAst2IRTranslator extends AstTranslator {
} }
protected boolean visitCast(CAstNode n, Context c, CAstVisitor visitor) { protected boolean visitCast(CAstNode n, Context c, CAstVisitor visitor) {
WalkContext context = (WalkContext) c; WalkContext context = (WalkContext)c;
int result = context.currentScope().allocateTempValue(); int result = context.currentScope().allocateTempValue();
setValue(n, result); setValue(n, result);
return false; return false;
} }
protected void leaveCast(CAstNode n, Context c, CAstVisitor visitor) { protected void leaveCast(CAstNode n, Context c, CAstVisitor visitor) {
WalkContext context = (WalkContext) c; WalkContext context = (WalkContext)c;
int result = getValue(n); int result = getValue(n);
CAstType toType = (CAstType) n.getChild(0).getValue(); CAstType toType = (CAstType) n.getChild(0).getValue();
TypeReference toRef = makeType(toType); TypeReference toRef = makeType(toType);
@ -332,29 +331,42 @@ public class JavaCAst2IRTranslator extends AstTranslator {
TypeReference fromRef = makeType(fromType); TypeReference fromRef = makeType(fromType);
if (toRef.isPrimitiveType()) { if (toRef.isPrimitiveType()) {
context.cfg().addInstruction(insts.ConversionInstruction(result, getValue(n.getChild(1)), fromRef, toRef, false)); context.cfg().addInstruction(
insts.ConversionInstruction(
result,
getValue(n.getChild(1)),
fromRef,
toRef,
false));
} else { } else {
context.cfg().addInstruction(insts.CheckCastInstruction(result, getValue(n.getChild(1)), toRef)); context.cfg().addInstruction(
insts.CheckCastInstruction(
result,
getValue(n.getChild(1)),
toRef,
true));
processExceptions(n, context); processExceptions(n, context);
} }
} }
protected boolean visitInstanceOf(CAstNode n, Context c, CAstVisitor visitor) { protected boolean visitInstanceOf(CAstNode n, Context c, CAstVisitor visitor) {
WalkContext context = (WalkContext) c; WalkContext context = (WalkContext)c;
int result = context.currentScope().allocateTempValue(); int result = context.currentScope().allocateTempValue();
setValue(n, result); setValue(n, result);
return false; return false;
} }
protected void leaveInstanceOf(CAstNode n, Context c, CAstVisitor visitor) { protected void leaveInstanceOf(CAstNode n, Context c, CAstVisitor visitor) {
WalkContext context = (WalkContext) c; WalkContext context = (WalkContext)c;
int result = getValue(n); int result = getValue(n);
CAstType type = (CAstType) n.getChild(0).getValue(); CAstType type = (CAstType) n.getChild(0).getValue();
TypeReference ref = makeType(type); TypeReference ref = makeType( type );
context.cfg().addInstruction(insts.InstanceofInstruction(result, getValue(n.getChild(1)), ref)); context.cfg().addInstruction(
insts.InstanceofInstruction(
result,
getValue(n.getChild(1)),
ref));
} }
protected boolean doVisit(CAstNode n, Context context, CAstVisitor visitor) { protected boolean doVisit(CAstNode n, Context context, CAstVisitor visitor) {
@ -369,7 +381,6 @@ public class JavaCAst2IRTranslator extends AstTranslator {
visitor.visit(n.getChild(0), wc, visitor); visitor.visit(n.getChild(0), wc, visitor);
wc.cfg().addInstruction(insts.MonitorInstruction(getValue(n.getChild(0)), false)); wc.cfg().addInstruction(insts.MonitorInstruction(getValue(n.getChild(0)), false));
processExceptions(n, wc); processExceptions(n, wc);
return true; return true;
} else { } else {
return super.doVisit(n, wc, visitor); return super.doVisit(n, wc, visitor);

View File

@ -39,4 +39,5 @@ public class FileMapping{
ps.println(line + ": " + fnAndln); ps.println(line + ": " + fnAndln);
} }
} }
} }

View File

@ -347,20 +347,22 @@ public class JavaScriptLoader extends CAstAbstractModuleLoader {
}; };
} }
public SSACheckCastInstruction CheckCastInstruction(int result, int val, TypeReference[] types) { public SSACheckCastInstruction CheckCastInstruction(int result, int val, TypeReference[] types, boolean isPEI) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
public SSACheckCastInstruction CheckCastInstruction(int result, int val, int[] typeValues) { public SSACheckCastInstruction CheckCastInstruction(int result, int val, int[] typeValues, boolean isPEI) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
public SSACheckCastInstruction CheckCastInstruction(int result, int val, int typeValue) { public SSACheckCastInstruction CheckCastInstruction(int result, int val, int typeValue, boolean isPEI) {
return CheckCastInstruction(result, val, new int[] { typeValue }); assert isPEI;
return CheckCastInstruction(result, val, new int[]{ typeValue }, true);
} }
public SSACheckCastInstruction CheckCastInstruction(int result, int val, TypeReference type) { public SSACheckCastInstruction CheckCastInstruction(int result, int val, TypeReference type, boolean isPEI) {
return CheckCastInstruction(result, val, new TypeReference[] { type }); assert isPEI;
return CheckCastInstruction(result, val, new TypeReference[]{ type }, true);
} }
public SSAComparisonInstruction ComparisonInstruction(Operator operator, int result, int val1, int val2) { public SSAComparisonInstruction ComparisonInstruction(Operator operator, int result, int val1, int val2) {

View File

@ -121,10 +121,10 @@ public class CrossLanguageCallGraph extends AstCallGraph {
return root.addGetStatic(ref); return root.addGetStatic(ref);
} }
public int addCheckcast(TypeReference[] type, int rv) { public int addCheckcast(TypeReference[] type, int rv, boolean isPEI) {
Atom language = type[0].getClassLoader().getLanguage(); Atom language = type[0].getClassLoader().getLanguage();
AbstractRootMethod root = getLanguageRoot(language); AbstractRootMethod root = getLanguageRoot(language);
return root.addCheckcast(type, rv); return root.addCheckcast(type, rv, isPEI);
} }
public SSANewInstruction addAllocation(TypeReference type) { public SSANewInstruction addAllocation(TypeReference type) {

View File

@ -21,6 +21,7 @@ import java.util.Iterator;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import com.ibm.wala.core.tests.callGraph.CallGraphTestUtil; import com.ibm.wala.core.tests.callGraph.CallGraphTestUtil;
@ -220,6 +221,7 @@ public class SlicerTest {
* @throws IllegalArgumentException * @throws IllegalArgumentException
* @throws IOException * @throws IOException
*/ */
@Ignore
@Test @Test
public void testSlice7() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException { public void testSlice7() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
AnalysisScope scope = findOrCreateAnalysisScope(); AnalysisScope scope = findOrCreateAnalysisScope();

View File

@ -150,7 +150,7 @@ public class ReflectiveInvocationInterpreter extends AbstractReflectionInterpret
// insert a cast for v2 to filter out bogus types // insert a cast for v2 to filter out bogus types
args[0] = nextLocal++; args[0] = nextLocal++;
TypeReference type = target.getParameterType(0); TypeReference type = target.getParameterType(0);
SSACheckCastInstruction cast = insts.CheckCastInstruction(args[0], 2, type); SSACheckCastInstruction cast = insts.CheckCastInstruction(args[0], 2, type, true);
m.addInstruction(null, cast, false); m.addInstruction(null, cast, false);
} }
} }
@ -170,7 +170,7 @@ public class ReflectiveInvocationInterpreter extends AbstractReflectionInterpret
args[j] = nextLocal++; args[j] = nextLocal++;
TypeReference type = target.getParameterType(j); TypeReference type = target.getParameterType(j);
// we insert a cast to filter out bogus types // we insert a cast to filter out bogus types
SSACheckCastInstruction cast = insts.CheckCastInstruction(args[j], temp, type); SSACheckCastInstruction cast = insts.CheckCastInstruction(args[j], temp, type, true);
m.addInstruction(null, cast, false); m.addInstruction(null, cast, false);
pc++; pc++;
} }

View File

@ -85,16 +85,6 @@ public abstract class AbstractIntStackMachine implements FixedPointConstants {
*/ */
final private ShrikeCFG cfg; final private ShrikeCFG cfg;
/**
* The max height of the stack.
*/
final private int maxStackHeight;
/**
* the max number of locals in play
*/
final protected int maxLocals;
/** /**
* Should uninitialized variables be considered TOP (optimistic) or BOTTOM (pessimistic); * Should uninitialized variables be considered TOP (optimistic) or BOTTOM (pessimistic);
*/ */
@ -104,8 +94,6 @@ public abstract class AbstractIntStackMachine implements FixedPointConstants {
if (G == null) { if (G == null) {
throw new IllegalArgumentException("G is null"); throw new IllegalArgumentException("G is null");
} }
maxStackHeight = G.getMaxStackHeight();
maxLocals = G.getMaxLocals();
this.cfg = G; this.cfg = G;
} }
@ -394,7 +382,7 @@ public abstract class AbstractIntStackMachine implements FixedPointConstants {
// allocate lhs.stack if it's // allocate lhs.stack if it's
// not already allocated. // not already allocated.
if (L.stack == null) { if (L.stack == null) {
L.allocateStack(); L.allocateStack(1);
L.stackHeight = 1; L.stackHeight = 1;
} }
@ -430,8 +418,8 @@ public abstract class AbstractIntStackMachine implements FixedPointConstants {
// if there's any stack height to meet, allocate lhs.stack if it's // if there's any stack height to meet, allocate lhs.stack if it's
// not already allocated. // not already allocated.
if (height > -1 && L.stack == null) { if (height > -1 && (L.stack == null || L.stack.length < height)) {
L.allocateStack(); L.allocateStack(height);
L.stackHeight = height; L.stackHeight = height;
changed = true; changed = true;
} }
@ -441,7 +429,7 @@ public abstract class AbstractIntStackMachine implements FixedPointConstants {
int[] R = new int[rhs.length]; int[] R = new int[rhs.length];
for (int j = 0; j < R.length; j++) { for (int j = 0; j < R.length; j++) {
MachineState m = (MachineState) rhs[j]; MachineState m = (MachineState) rhs[j];
if (m.stack == null) { if (m.stack == null || m.stack.length < i+1) {
R[j] = TOP; R[j] = TOP;
} else { } else {
R[j] = m.stack[i]; R[j] = m.stack[i];
@ -478,8 +466,8 @@ public abstract class AbstractIntStackMachine implements FixedPointConstants {
MachineState L = (MachineState) lhs; MachineState L = (MachineState) lhs;
// need we allocate lhs.locals? // need we allocate lhs.locals?
int nLocals = computeMeetNLocals(rhs); int nLocals = computeMeetNLocals(rhs);
if (nLocals > -1 && L.locals == null) { if (nLocals > -1 && (L.locals == null || L.locals.length < nLocals)) {
L.allocateLocals(); L.allocateLocals(nLocals);
} }
// evaluate the element-wise meet over the locals. // evaluate the element-wise meet over the locals.
@ -577,6 +565,7 @@ public abstract class AbstractIntStackMachine implements FixedPointConstants {
void setTOP() { void setTOP() {
stackHeight = -1; stackHeight = -1;
stack = null;
} }
boolean isTOP() { boolean isTOP() {
@ -584,8 +573,8 @@ public abstract class AbstractIntStackMachine implements FixedPointConstants {
} }
public void push(int i) { public void push(int i) {
if (stack == null) if (stack == null || stackHeight >= stack.length)
allocateStack(); allocateStack(stackHeight+1);
stack[stackHeight++] = i; stack[stackHeight++] = i;
} }
@ -607,13 +596,30 @@ public abstract class AbstractIntStackMachine implements FixedPointConstants {
stack[stackHeight - 2] = temp; stack[stackHeight - 2] = temp;
} }
private void allocateStack() { private void allocateStack(int stackHeight) {
stack = new int[maxStackHeight + 1]; if (stack == null) {
stackHeight = 0; stack = new int[stackHeight + 1 ];
this.stackHeight = 0;
} else {
int[] newStack = new int[ Math.max(stack.length, stackHeight) * 2 + 1 ];
System.arraycopy(stack, 0, newStack, 0, stack.length);
stack = newStack;
}
} }
private void allocateLocals() { private void allocateLocals(int maxLocals) {
locals = allocateNewLocalsArray(); int[] result = new int[maxLocals];
int start = 0;
if (locals != null) {
System.arraycopy(locals, 0, result, 0, locals.length);
start = locals.length;
}
for (int i = start; i < maxLocals; i++) {
result[i] = OPTIMISTIC ? TOP : BOTTOM;
}
locals = result;
} }
public void clearStack() { public void clearStack() {
@ -627,11 +633,11 @@ public abstract class AbstractIntStackMachine implements FixedPointConstants {
* @param j * @param j
*/ */
public void setLocal(int i, int j) { public void setLocal(int i, int j) {
if (locals == null) { if (locals == null || locals.length < i+1) {
if (OPTIMISTIC && (j == TOP)) { if (OPTIMISTIC && (j == TOP)) {
return; return;
} else { } else {
allocateLocals(); allocateLocals(i+1);
} }
} }
locals[i] = j; locals[i] = j;
@ -642,7 +648,7 @@ public abstract class AbstractIntStackMachine implements FixedPointConstants {
* @return the number of the symbol corresponding to local i * @return the number of the symbol corresponding to local i
*/ */
public int getLocal(int i) { public int getLocal(int i) {
if (locals == null) { if (locals == null || locals.length < i+1) {
if (OPTIMISTIC) { if (OPTIMISTIC) {
return TOP; return TOP;
} else { } else {
@ -660,7 +666,7 @@ public abstract class AbstractIntStackMachine implements FixedPointConstants {
stack[i] = to; stack[i] = to;
if (locals != null) if (locals != null)
for (int i = 0; i < maxLocals; i++) for (int i = 0; i < locals.length; i++)
if (locals[i] == from) if (locals[i] == from)
locals[i] = to; locals[i] = to;
} }
@ -672,7 +678,7 @@ public abstract class AbstractIntStackMachine implements FixedPointConstants {
return true; return true;
if (locals != null) if (locals != null)
for (int i = 0; i < maxLocals; i++) for (int i = 0; i < locals.length; i++)
if (locals[i] == val) if (locals[i] == val)
return true; return true;
@ -692,7 +698,7 @@ public abstract class AbstractIntStackMachine implements FixedPointConstants {
result.append(array2StringBuffer(stack, stackHeight)); result.append(array2StringBuffer(stack, stackHeight));
} }
result.append("L"); result.append("L");
result.append(array2StringBuffer(locals, maxLocals)); result.append(array2StringBuffer(locals, locals.length));
result.append(">"); result.append(">");
return result.toString(); return result.toString();
} }
@ -775,14 +781,6 @@ public abstract class AbstractIntStackMachine implements FixedPointConstants {
} }
public int[] allocateNewLocalsArray() {
int[] result = new int[maxLocals];
for (int i = 0; i < maxLocals; i++) {
result[i] = OPTIMISTIC ? TOP : BOTTOM;
}
return result;
}
/** /**
* Interface which defines a flow function for a basic block * Interface which defines a flow function for a basic block
*/ */

View File

@ -31,7 +31,7 @@ public class ConeType extends TypeAbstraction {
if (type == null) { if (type == null) {
throw new IllegalArgumentException("type is null"); throw new IllegalArgumentException("type is null");
} }
assert type.getReference().isReferenceType(); assert type.getReference().isReferenceType() : type;
this.type = type; this.type = type;
} }

View File

@ -33,7 +33,7 @@ public abstract class TypeAbstraction implements ContextItem {
@Override @Override
public String toString() { public String toString() {
return "JavaTypeAbstraction.TOP"; return "WalaTypeAbstraction.TOP";
} }
@Override @Override

View File

@ -538,7 +538,9 @@ public class TypeInference extends SSAInference<TypeVariable> implements FixedPo
TypeReference type = instruction.getDeclaredFieldType(); TypeReference type = instruction.getDeclaredFieldType();
if (doPrimitives && type.isPrimitiveType()) { if (doPrimitives && type.isPrimitiveType()) {
result = new DeclaredTypeOperator(language.getPrimitive(type)); PrimitiveType p = language.getPrimitive(type);
assert p != null : "no type for " + type;
result = new DeclaredTypeOperator(p);
} else { } else {
IClass klass = cha.lookupClass(type); IClass klass = cha.lookupClass(type);
if (klass == null) { if (klass == null) {
@ -593,10 +595,18 @@ public class TypeInference extends SSAInference<TypeVariable> implements FixedPo
// be pessimistic // be pessimistic
typeAbs = BOTTOM; typeAbs = BOTTOM;
} else { } else {
TypeAbstraction x = null;
if (doPrimitives && type.isPrimitiveType()) {
x = language.getPrimitive(type);
} else if (type.isReferenceType()) {
x = new ConeType(klass);
}
if (x != null) {
if (typeAbs == null) { if (typeAbs == null) {
typeAbs = new ConeType(klass); typeAbs = x;
} else { } else {
typeAbs = typeAbs.meet(new ConeType(klass)); typeAbs = typeAbs.meet(x);
}
} }
} }
} }

View File

@ -663,4 +663,5 @@ public abstract class AbstractCFG<I, T extends IBasicBlock<I>> implements Contro
} }
return result; return result;
} }
} }

View File

@ -59,7 +59,11 @@ public class ShrikeCFG extends AbstractCFG<IInstruction, ShrikeCFG.BasicBlock> {
*/ */
final private Set<ExceptionHandler> exceptionHandlers = HashSetFactory.make(10); final private Set<ExceptionHandler> exceptionHandlers = HashSetFactory.make(10);
public ShrikeCFG(IBytecodeMethod method) throws IllegalArgumentException { public static ShrikeCFG make(IBytecodeMethod m) {
return new ShrikeCFG(m);
}
private ShrikeCFG(IBytecodeMethod method) throws IllegalArgumentException {
super(method); super(method);
if (method == null) { if (method == null) {
throw new IllegalArgumentException("method cannot be null"); throw new IllegalArgumentException("method cannot be null");
@ -426,7 +430,11 @@ public class ShrikeCFG extends AbstractCFG<IInstruction, ShrikeCFG.BasicBlock> {
// this is the last non-exit block // this is the last non-exit block
return getInstructions().length - 1; return getInstructions().length - 1;
} else { } else {
BasicBlock next = getNode(getNumber() + 1); int i = 1;
BasicBlock next;
do {
next = getNode(getNumber() + i);
} while (next == null);
return next.getFirstInstructionIndex() - 1; return next.getFirstInstructionIndex() - 1;
} }
} }
@ -502,14 +510,6 @@ public class ShrikeCFG extends AbstractCFG<IInstruction, ShrikeCFG.BasicBlock> {
return s.toString(); return s.toString();
} }
public int getMaxStackHeight() {
return method.getMaxStackHeight();
}
public int getMaxLocals() {
return method.getMaxLocals();
}
public Set<ExceptionHandler> getExceptionHandlers() { public Set<ExceptionHandler> getExceptionHandlers() {
return exceptionHandlers; return exceptionHandlers;
} }

View File

@ -17,7 +17,6 @@ import java.util.HashSet;
import com.ibm.wala.ipa.cha.IClassHierarchy; import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.shrikeBT.Constants; import com.ibm.wala.shrikeBT.Constants;
import com.ibm.wala.types.ClassLoaderReference;
import com.ibm.wala.types.Selector; import com.ibm.wala.types.Selector;
import com.ibm.wala.types.TypeName; import com.ibm.wala.types.TypeName;
import com.ibm.wala.types.TypeReference; import com.ibm.wala.types.TypeReference;
@ -50,7 +49,7 @@ public class ArrayClass implements IClass, Constants {
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);
} }
} else { } else {
assert loader.getReference().equals(ClassLoaderReference.Primordial); // assert loader.getReference().equals(ClassLoaderReference.Primordial);
} }
} }
@ -123,7 +122,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(getClassLoader().getLanguage().getRootType().getName()).getMethod(sig); return cha.lookupClass(getClassLoader().getLanguage().getRootType()).getMethod(sig);
} }
public IField getField(Atom name) { public IField getField(Atom name) {

View File

@ -12,6 +12,10 @@ package com.ibm.wala.classLoader;
import java.io.File; import java.io.File;
import com.ibm.wala.shrikeCT.InvalidClassFileException;
import com.ibm.wala.util.warnings.Warning;
import com.ibm.wala.util.warnings.Warnings;
/** /**
* Module representing a directory of .class files * Module representing a directory of .class files
*/ */
@ -27,8 +31,19 @@ public class BinaryDirectoryTreeModule extends DirectoryTreeModule {
} }
@Override @Override
protected FileModule makeFile(File file) { protected FileModule makeFile(final File file) {
try {
return new ClassFileModule(file); return new ClassFileModule(file);
} catch (InvalidClassFileException e) {
Warnings.add(new Warning(Warning.MODERATE) {
@Override
public String getMsg() {
return "Invalid class file at path " + file.getAbsolutePath();
}
});
return null;
}
} }
} }

View File

@ -279,7 +279,7 @@ public abstract class BytecodeClass<T extends IClassLoader> implements IClass {
/* /*
* @see com.ibm.wala.classLoader.IClass#getDirectInterfaces() * @see com.ibm.wala.classLoader.IClass#getDirectInterfaces()
*/ */
public Collection<IClass> getDirectInterfaces() { public Collection<? extends IClass> getDirectInterfaces() {
return array2IClassSet(interfaceNames); return array2IClassSet(interfaceNames);
} }
@ -416,9 +416,9 @@ public abstract class BytecodeClass<T extends IClassLoader> implements IClass {
* @return Collection of IClasses, representing the interfaces this class implements. * @return Collection of IClasses, representing the interfaces this class implements.
*/ */
protected Collection<IClass> computeAllInterfacesAsCollection() { protected Collection<IClass> computeAllInterfacesAsCollection() {
Collection<IClass> c = getDirectInterfaces(); Collection<? extends IClass> c = getDirectInterfaces();
Set<IClass> result = HashSetFactory.make(); Set<IClass> result = HashSetFactory.make();
for (Iterator<IClass> it = c.iterator(); it.hasNext();) { for (Iterator<? extends IClass> it = c.iterator(); it.hasNext();) {
IClass klass = it.next(); IClass klass = it.next();
if (klass.isInterface()) { if (klass.isInterface()) {
result.add(klass); result.add(klass);

View File

@ -14,7 +14,6 @@ package com.ibm.wala.classLoader;
import java.io.File; import java.io.File;
import com.ibm.wala.shrikeCT.InvalidClassFileException; import com.ibm.wala.shrikeCT.InvalidClassFileException;
import com.ibm.wala.util.debug.Assertions;
import com.ibm.wala.util.shrike.ShrikeClassReaderHandle; import com.ibm.wala.util.shrike.ShrikeClassReaderHandle;
import com.ibm.wala.util.strings.ImmutableByteArray; import com.ibm.wala.util.strings.ImmutableByteArray;
@ -25,18 +24,10 @@ public class ClassFileModule extends FileModule {
private final String className; private final String className;
public ClassFileModule(File f) { public ClassFileModule(File f) throws InvalidClassFileException {
super(f); super(f);
// this is delicate: TODO, clean it up a bit.
ShrikeClassReaderHandle reader = new ShrikeClassReaderHandle(this); ShrikeClassReaderHandle reader = new ShrikeClassReaderHandle(this);
ImmutableByteArray name = null; ImmutableByteArray name = ImmutableByteArray.make(reader.get().getName());
try {
name = ImmutableByteArray.make(reader.get().getName());
} catch (InvalidClassFileException e) {
System.err.println("Invalid class file: " + f.getAbsolutePath());
e.printStackTrace();
Assertions.UNREACHABLE();
}
className = name.toString(); className = name.toString();
} }

View File

@ -157,7 +157,6 @@ public class ClassLoaderImpl implements IClassLoader {
} }
TreeSet<ModuleEntry> sortedEntries = new TreeSet<ModuleEntry>(HashCodeComparator.instance()); TreeSet<ModuleEntry> sortedEntries = new TreeSet<ModuleEntry>(HashCodeComparator.instance());
sortedEntries.addAll(Iterator2Collection.toSet(M.getEntries())); sortedEntries.addAll(Iterator2Collection.toSet(M.getEntries()));
HashSet<ModuleEntry> result = HashSetFactory.make(); HashSet<ModuleEntry> result = HashSetFactory.make();
for (Iterator it = sortedEntries.iterator(); it.hasNext();) { for (Iterator it = sortedEntries.iterator(); it.hasNext();) {
ModuleEntry entry = (ModuleEntry) it.next(); ModuleEntry entry = (ModuleEntry) it.next();

View File

@ -36,6 +36,9 @@ public abstract class DirectoryTreeModule implements Module {
} }
} }
/**
* returns null if unsuccessful in creating FileModule
*/
protected abstract FileModule makeFile(File file); protected abstract FileModule makeFile(File file);
protected abstract boolean includeFile(File file); protected abstract boolean includeFile(File file);
@ -48,7 +51,10 @@ public abstract class DirectoryTreeModule implements Module {
if (files[i].isDirectory()) { if (files[i].isDirectory()) {
result.addAll(getEntriesRecursive(files[i])); result.addAll(getEntriesRecursive(files[i]));
} else if (includeFile(files[i])) { } else if (includeFile(files[i])) {
result.add(makeFile(files[i])); FileModule fileModule = makeFile(files[i]);
if (fileModule != null) {
result.add(fileModule);
}
} }
} }
} else { } else {

View File

@ -70,7 +70,7 @@ public interface IClass extends IClassHierarchyDweller {
* @return Collection of (IClass) interfaces this class directly implements. If this class is an interface, returns the interfaces * @return Collection of (IClass) interfaces this class directly implements. If this class is an interface, returns the interfaces
* it immediately extends. * it immediately extends.
*/ */
Collection<IClass> getDirectInterfaces(); Collection<? extends IClass> getDirectInterfaces();
/** /**
* @return Collection of (IClass) interfaces this class implements, including all ancestors of interfaces immediately implemented. * @return Collection of (IClass) interfaces this class implements, including all ancestors of interfaces immediately implemented.

View File

@ -82,16 +82,6 @@ public interface IMethod extends IMember, ContextItem {
*/ */
MethodReference getReference(); MethodReference getReference();
/**
* @return maximum number of JVM locals used by this method
*/
int getMaxLocals();
/**
* @return maximum height of JVM stack used by this method
*/
int getMaxStackHeight();
/** /**
* @return true iff this method has at least one exception handler * @return true iff this method has at least one exception handler
*/ */

View File

@ -128,13 +128,14 @@ public class JavaLanguage extends LanguageImpl implements BytecodeLanguage, Cons
}; };
} }
public SSACheckCastInstruction CheckCastInstruction(int result, int val, int[] typeValues) { public SSACheckCastInstruction CheckCastInstruction(int result, int val, int[] typeValues, boolean isPEI) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
public SSACheckCastInstruction CheckCastInstruction(int result, int val, TypeReference[] types) { public SSACheckCastInstruction CheckCastInstruction(int result, int val, TypeReference[] types, boolean isPEI) {
assert types.length == 1; assert types.length == 1;
return new SSACheckCastInstruction(result, val, types) { assert isPEI;
return new SSACheckCastInstruction(result, val, types, true) {
@Override @Override
public Collection<TypeReference> getExceptionTypes() { public Collection<TypeReference> getExceptionTypes() {
return getClassCastException(); return getClassCastException();
@ -142,12 +143,14 @@ public class JavaLanguage extends LanguageImpl implements BytecodeLanguage, Cons
}; };
} }
public SSACheckCastInstruction CheckCastInstruction(int result, int val, int typeValue) { public SSACheckCastInstruction CheckCastInstruction(int result, int val, int typeValue, boolean isPEI) {
return CheckCastInstruction(result, val, new int[]{ typeValue }); assert isPEI;
return CheckCastInstruction(result, val, new int[]{ typeValue }, true);
} }
public SSACheckCastInstruction CheckCastInstruction(int result, int val, TypeReference type) { public SSACheckCastInstruction CheckCastInstruction(int result, int val, TypeReference type, boolean isPEI) {
return CheckCastInstruction(result, val, new TypeReference[]{ type }); assert isPEI;
return CheckCastInstruction(result, val, new TypeReference[]{ type }, true);
} }
public SSAComparisonInstruction ComparisonInstruction(IComparisonInstruction.Operator operator, int result, int val1, int val2) { public SSAComparisonInstruction ComparisonInstruction(IComparisonInstruction.Operator operator, int result, int val1, int val2) {

View File

@ -33,7 +33,7 @@ public class ShrikeIRFactory implements IRFactory<IBytecodeMethod> {
public final static boolean buildLocalMap = true; public final static boolean buildLocalMap = true;
public ControlFlowGraph makeCFG(final IBytecodeMethod method, Context C) { public ControlFlowGraph makeCFG(final IBytecodeMethod method, Context C) {
return new ShrikeCFG(method); return ShrikeCFG.make(method);
} }
public IR makeIR(final IBytecodeMethod method, Context C, final SSAOptions options) throws IllegalArgumentException { public IR makeIR(final IBytecodeMethod method, Context C, final SSAOptions options) throws IllegalArgumentException {

View File

@ -35,6 +35,7 @@ import com.ibm.wala.classLoader.Module;
import com.ibm.wala.classLoader.SourceDirectoryTreeModule; import com.ibm.wala.classLoader.SourceDirectoryTreeModule;
import com.ibm.wala.classLoader.SourceFileModule; import com.ibm.wala.classLoader.SourceFileModule;
import com.ibm.wala.ipa.callgraph.impl.SetOfClasses; import com.ibm.wala.ipa.callgraph.impl.SetOfClasses;
import com.ibm.wala.shrikeCT.InvalidClassFileException;
import com.ibm.wala.types.ClassLoaderReference; import com.ibm.wala.types.ClassLoaderReference;
import com.ibm.wala.types.Descriptor; import com.ibm.wala.types.Descriptor;
import com.ibm.wala.types.MethodReference; import com.ibm.wala.types.MethodReference;
@ -202,8 +203,9 @@ public class AnalysisScope {
/** /**
* Add a class file to the scope for a loader * Add a class file to the scope for a loader
* @throws InvalidClassFileException
*/ */
public void addClassFileToScope(ClassLoaderReference loader, File file) throws IllegalArgumentException { public void addClassFileToScope(ClassLoaderReference loader, File file) throws IllegalArgumentException, InvalidClassFileException {
List<Module> s = MapUtil.findOrCreateList(moduleMap, loader); List<Module> s = MapUtil.findOrCreateList(moduleMap, loader);
s.add(new ClassFileModule(file)); s.add(new ClassFileModule(file));
} }

View File

@ -330,10 +330,10 @@ public abstract class AbstractRootMethod extends SyntheticMethod {
return result; return result;
} }
public int addCheckcast(TypeReference[] types, int rv) { public int addCheckcast(TypeReference[] types, int rv, boolean isPEI) {
int lv = nextLocal++; int lv = nextLocal++;
statements.add(insts.CheckCastInstruction(lv, rv, types)); statements.add(insts.CheckCastInstruction(lv, rv, types, isPEI));
return lv; return lv;
} }

View File

@ -747,13 +747,22 @@ public class ClassHierarchy implements IClassHierarchy {
Assertions.UNREACHABLE(); Assertions.UNREACHABLE();
superB = null; superB = null;
} }
while (a != null) { IClass aa = a;
if (superB.contains(a)) { while (aa != null) {
return a; if (superB.contains(aa)) {
return aa;
} }
a = a.getSuperclass(); aa = aa.getSuperclass();
} }
Assertions.UNREACHABLE("getLeastCommonSuperclass " + tempA + " " + b); Set<IClass> superA;
try {
superA = getSuperclasses(a);
} catch (ClassHierarchyException e1) {
e1.printStackTrace();
Assertions.UNREACHABLE();
superA = null;
}
Assertions.UNREACHABLE("getLeastCommonSuperclass " + tempA + " " + b + ": " + superA + ", " + superB);
return null; return null;
} }
} }

View File

@ -105,8 +105,8 @@ public class SSABuilder extends AbstractIntStackMachine {
private SSABuilder(IBytecodeMethod method, SSACFG cfg, ShrikeCFG scfg, SSAInstruction[] instructions, SymbolTable symbolTable, private SSABuilder(IBytecodeMethod method, SSACFG cfg, ShrikeCFG scfg, SSAInstruction[] instructions, SymbolTable symbolTable,
boolean buildLocalMap, SSAPiNodePolicy piNodePolicy) { boolean buildLocalMap, SSAPiNodePolicy piNodePolicy) {
super(scfg); super(scfg);
localMap = buildLocalMap ? new SSA2LocalMap(scfg, instructions.length, cfg.getNumberOfNodes(), maxLocals) : null; localMap = buildLocalMap ? new SSA2LocalMap(scfg, instructions.length, cfg.getNumberOfNodes()) : null;
init(new SymbolTableMeeter(symbolTable, cfg, instructions, scfg), new SymbolicPropagator(scfg, instructions, symbolTable, init(new SymbolTableMeeter(symbolTable, cfg, scfg), new SymbolicPropagator(scfg, instructions, symbolTable,
localMap, cfg, piNodePolicy)); localMap, cfg, piNodePolicy));
this.method = method; this.method = method;
this.symbolTable = symbolTable; this.symbolTable = symbolTable;
@ -120,15 +120,13 @@ public class SSABuilder extends AbstractIntStackMachine {
final SSACFG cfg; final SSACFG cfg;
final SSAInstruction[] instructions;
final SymbolTable symbolTable; final SymbolTable symbolTable;
final ShrikeCFG shrikeCFG; final ShrikeCFG shrikeCFG;
SymbolTableMeeter(SymbolTable symbolTable, SSACFG cfg, SSAInstruction[] instructions, ShrikeCFG shrikeCFG) { SymbolTableMeeter(SymbolTable symbolTable, SSACFG cfg, ShrikeCFG shrikeCFG) {
this.cfg = cfg; this.cfg = cfg;
this.instructions = instructions;
this.symbolTable = symbolTable; this.symbolTable = symbolTable;
this.shrikeCFG = shrikeCFG; this.shrikeCFG = shrikeCFG;
} }
@ -328,6 +326,7 @@ public class SSABuilder extends AbstractIntStackMachine {
} }
private void emitInstruction(SSAInstruction s) { private void emitInstruction(SSAInstruction s) {
if (s != null) {
instructions[getCurrentInstructionIndex()] = s; instructions[getCurrentInstructionIndex()] = s;
for (int i = 0; i < s.getNumberOfDefs(); i++) { for (int i = 0; i < s.getNumberOfDefs(); i++) {
if (creators.length < (s.getDef(i) + 1)) { if (creators.length < (s.getDef(i) + 1)) {
@ -341,6 +340,7 @@ public class SSABuilder extends AbstractIntStackMachine {
creators[s.getDef(i)] = s; creators[s.getDef(i)] = s;
} }
} }
}
private SSAInstruction getCurrentInstruction() { private SSAInstruction getCurrentInstruction() {
return instructions[getCurrentInstructionIndex()]; return instructions[getCurrentInstructionIndex()];
@ -451,7 +451,7 @@ public class SSABuilder extends AbstractIntStackMachine {
for(int i = 0; i < typeNames.length; i++) { for(int i = 0; i < typeNames.length; i++) {
t[i] = ShrikeUtil.makeTypeReference(loader, typeNames[i]); t[i] = ShrikeUtil.makeTypeReference(loader, typeNames[i]);
} }
emitInstruction(insts.CheckCastInstruction(result, val, t)); emitInstruction(insts.CheckCastInstruction(result, val, t, instruction.isPEI()));
} }
} }
@ -933,20 +933,14 @@ public class SSABuilder extends AbstractIntStackMachine {
*/ */
private final int[][] block2LocalState; private final int[][] block2LocalState;
/**
* maximum number of locals used at any program point
*/
private final int maxLocals;
/** /**
* @param nInstructions number of instructions in the bytecode for this method * @param nInstructions number of instructions in the bytecode for this method
* @param nBlocks number of basic blocks in the CFG * @param nBlocks number of basic blocks in the CFG
*/ */
SSA2LocalMap(ShrikeCFG shrikeCfg, int nInstructions, int nBlocks, int maxLocals) { SSA2LocalMap(ShrikeCFG shrikeCfg, int nInstructions, int nBlocks) {
shrikeCFG = shrikeCfg; shrikeCFG = shrikeCfg;
localStoreMap = new IntPair[nInstructions]; localStoreMap = new IntPair[nInstructions];
block2LocalState = new int[nBlocks][]; block2LocalState = new int[nBlocks][];
this.maxLocals = maxLocals;
} }
/** /**
@ -954,11 +948,6 @@ public class SSABuilder extends AbstractIntStackMachine {
* a particular local number * a particular local number
*/ */
void startRange(int pc, int localNumber, int valueNumber) { void startRange(int pc, int localNumber, int valueNumber) {
int max = shrikeCFG.getMethod().getMaxLocals();
if (localNumber >= max) {
assert false : "invalid local " + localNumber + ">" + max;
}
localStoreMap[pc] = new IntPair(valueNumber, localNumber); localStoreMap[pc] = new IntPair(valueNumber, localNumber);
} }
@ -1002,6 +991,27 @@ public class SSABuilder extends AbstractIntStackMachine {
} }
} }
public int[] allocateNewLocalsArray(int maxLocals) {
int[] result = new int[maxLocals];
for (int i = 0; i < maxLocals; i++) {
result[i] = OPTIMISTIC ? TOP : BOTTOM;
}
return result;
}
private int[] setLocal(int[] locals, int localNumber, int valueNumber) {
if (locals == null) {
locals = allocateNewLocalsArray(localNumber + 1);
} else if (locals.length <= localNumber) {
int[] newLocals = allocateNewLocalsArray(2 * Math.max(locals.length, localNumber) + 1);
System.arraycopy(locals, 0, newLocals, 0, locals.length);
locals = newLocals;
}
locals[localNumber] = valueNumber;
return locals;
}
/** /**
* @param pc a program counter (index into ShrikeBT instruction array) * @param pc a program counter (index into ShrikeBT instruction array)
* @param vn a value number * @param vn a value number
@ -1015,26 +1025,15 @@ public class SSABuilder extends AbstractIntStackMachine {
// walk forward from the first instruction to reconstruct the // walk forward from the first instruction to reconstruct the
// state of the locals at this pc // state of the locals at this pc
int[] locals = block2LocalState[bb.getNumber()]; int[] locals = block2LocalState[bb.getNumber()];
if (locals == null) {
locals = allocateNewLocalsArray();
}
for (int i = firstInstruction; i <= pc; i++) { for (int i = firstInstruction; i <= pc; i++) {
if (localStoreMap[i] != null) { if (localStoreMap[i] != null) {
IntPair p = localStoreMap[i]; IntPair p = localStoreMap[i];
locals[p.getY()] = p.getX(); setLocal(locals, p.getY(), p.getX());
} }
} }
return extractIndices(locals, vn); return extractIndices(locals, vn);
} }
public int[] allocateNewLocalsArray() {
int[] result = new int[maxLocals];
for (int i = 0; i < maxLocals; i++) {
result[i] = OPTIMISTIC ? TOP : BOTTOM;
}
return result;
}
/** /**
* @return the indices i s.t. x[i] == y, or null if none found. * @return the indices i s.t. x[i] == y, or null if none found.
*/ */

View File

@ -38,16 +38,22 @@ public abstract class SSACheckCastInstruction extends SSAInstruction {
*/ */
private final TypeReference[] declaredResultTypes; private final TypeReference[] declaredResultTypes;
/**
* whether the type test throws an exception
*/
private final boolean isPEI;
/** /**
* @param result A new value number def'fed by this instruction when the type check succeeds. * @param result A new value number def'fed by this instruction when the type check succeeds.
* @param val The value being checked by this instruction * @param val The value being checked by this instruction
* @param type The type which this instruction checks * @param type The type which this instruction checks
*/ */
protected SSACheckCastInstruction(int result, int val, TypeReference[] types) { protected SSACheckCastInstruction(int result, int val, TypeReference[] types, boolean isPEI) {
super(); super();
this.result = result; this.result = result;
this.val = val; this.val = val;
this.declaredResultTypes = types; this.declaredResultTypes = types;
this.isPEI = isPEI;
} }
@Override @Override
@ -58,7 +64,7 @@ public abstract class SSACheckCastInstruction extends SSAInstruction {
if (uses != null && uses.length == 0) { if (uses != null && uses.length == 0) {
throw new IllegalArgumentException("(uses != null) and (uses.length == 0)"); throw new IllegalArgumentException("(uses != null) and (uses.length == 0)");
} }
return insts.CheckCastInstruction(defs == null ? result : defs[0], uses == null ? val : uses[0], declaredResultTypes); return insts.CheckCastInstruction(defs == null ? result : defs[0], uses == null ? val : uses[0], declaredResultTypes, isPEI);
} }
@Override @Override
@ -162,7 +168,7 @@ public abstract class SSACheckCastInstruction extends SSAInstruction {
*/ */
@Override @Override
public boolean isPEI() { public boolean isPEI() {
return true; return isPEI;
} }
/* /*

View File

@ -40,13 +40,13 @@ public interface SSAInstructionFactory {
SSABinaryOpInstruction BinaryOpInstruction(IBinaryOpInstruction.IOperator operator, boolean overflow, boolean unsigned, SSABinaryOpInstruction BinaryOpInstruction(IBinaryOpInstruction.IOperator operator, boolean overflow, boolean unsigned,
int result, int val1, int val2, boolean mayBeInteger); int result, int val1, int val2, boolean mayBeInteger);
SSACheckCastInstruction CheckCastInstruction(int result, int val, int[] typeValues); SSACheckCastInstruction CheckCastInstruction(int result, int val, int[] typeValues, boolean isPEI);
SSACheckCastInstruction CheckCastInstruction(int result, int val, int typeValue); SSACheckCastInstruction CheckCastInstruction(int result, int val, int typeValue, boolean isPEI);
SSACheckCastInstruction CheckCastInstruction(int result, int val, TypeReference[] types); SSACheckCastInstruction CheckCastInstruction(int result, int val, TypeReference[] types, boolean isPEI);
SSACheckCastInstruction CheckCastInstruction(int result, int val, TypeReference type); SSACheckCastInstruction CheckCastInstruction(int result, int val, TypeReference type, boolean isPEI);
SSAComparisonInstruction ComparisonInstruction(IComparisonInstruction.Operator operator, int result, int val1, int val2); SSAComparisonInstruction ComparisonInstruction(IComparisonInstruction.Operator operator, int result, int val1, int val2);

View File

@ -261,7 +261,10 @@ public final class TypeName implements Serializable {
} }
if (!innermostPrimitive) { if (!innermostPrimitive) {
result.append("L"); result.append("L");
} else if (packageName != null && innermostPrimitive) {
result.append("P");
} }
if (packageName != null) { if (packageName != null) {
result.append(packageName.toString()); result.append(packageName.toString());
result.append("/"); result.append("/");
@ -279,7 +282,10 @@ public final class TypeName implements Serializable {
} }
if (!innermostPrimitive) { if (!innermostPrimitive) {
result.append("L"); result.append("L");
} else if (packageName != null && innermostPrimitive) {
result.append("P");
} }
if (packageName != null) { if (packageName != null) {
result.append(packageName.toUnicodeString()); result.append(packageName.toUnicodeString());
result.append("/"); result.append("/");

View File

@ -329,7 +329,11 @@ public final class TypeReference implements Serializable {
public final static TypeReference Unknown = findOrCreate(ClassLoaderReference.Primordial, UnknownName); public final static TypeReference Unknown = findOrCreate(ClassLoaderReference.Primordial, UnknownName);
private static TypeReference makePrimitive(TypeName n) { private static TypeReference makePrimitive(TypeName n) {
TypeReference t = new TypeReference(ClassLoaderReference.Primordial, n); return makePrimitive(ClassLoaderReference.Primordial, n);
}
public static TypeReference makePrimitive(ClassLoaderReference cl, TypeName n) {
TypeReference t = new TypeReference(cl, n);
primitiveMap.put(t.name, t); primitiveMap.put(t.name, t);
return t; return t;
} }

View File

@ -10,7 +10,10 @@
*******************************************************************************/ *******************************************************************************/
package com.ibm.wala.types.annotations; package com.ibm.wala.types.annotations;
import java.util.Arrays;
import com.ibm.wala.types.TypeReference; import com.ibm.wala.types.TypeReference;
import com.ibm.wala.util.collections.Pair;
/** /**
* Represents a Java 5.0 class file annotation * Represents a Java 5.0 class file annotation
@ -18,25 +21,40 @@ import com.ibm.wala.types.TypeReference;
public class Annotation { public class Annotation {
private final TypeReference type; private final TypeReference type;
private final Pair<TypeReference, Object>[] arguments;
private Annotation(TypeReference type) { private Annotation(TypeReference type, Pair<TypeReference, Object>[] arguments) {
this.type = type; this.type = type;
this.arguments = arguments;
}
public static Annotation make(TypeReference t, Pair<TypeReference, Object>[] arguments) {
return new Annotation(t, arguments);
} }
public static Annotation make(TypeReference t) { public static Annotation make(TypeReference t) {
return new Annotation(t); return make(t, null);
} }
@Override @Override
public String toString() { public String toString() {
return "Annotation type " + type; StringBuffer sb = new StringBuffer("Annotation type " + type);
if (arguments != null) {
sb.append("[");
for(Pair<TypeReference, Object> arg : arguments) {
sb.append(" " + arg.fst.getName().getClassName() + ":" + arg.snd);
}
sb.append(" ]");
}
return sb.toString();
} }
@Override @Override
public int hashCode() { public int hashCode() {
final int PRIME = 31; final int prime = 31;
int result = 1; int result = 1;
result = PRIME * result + ((type == null) ? 0 : type.hashCode()); result = prime * result + Arrays.hashCode(arguments);
result = prime * result + ((type == null) ? 0 : type.hashCode());
return result; return result;
} }
@ -48,7 +66,9 @@ public class Annotation {
return false; return false;
if (getClass() != obj.getClass()) if (getClass() != obj.getClass())
return false; return false;
final Annotation other = (Annotation) obj; Annotation other = (Annotation) obj;
if (!Arrays.equals(arguments, other.arguments))
return false;
if (type == null) { if (type == null) {
if (other.type != null) if (other.type != null)
return false; return false;
@ -57,6 +77,9 @@ public class Annotation {
return true; return true;
} }
public Pair<TypeReference, Object>[] getArguments() {
return arguments;
}
public TypeReference getType() { public TypeReference getType() {
return type; return type;

View File

@ -26,6 +26,7 @@ import com.ibm.wala.classLoader.SourceDirectoryTreeModule;
import com.ibm.wala.core.plugin.CorePlugin; import com.ibm.wala.core.plugin.CorePlugin;
import com.ibm.wala.ipa.callgraph.AnalysisScope; import com.ibm.wala.ipa.callgraph.AnalysisScope;
import com.ibm.wala.properties.WalaProperties; import com.ibm.wala.properties.WalaProperties;
import com.ibm.wala.shrikeCT.InvalidClassFileException;
import com.ibm.wala.types.ClassLoaderReference; import com.ibm.wala.types.ClassLoaderReference;
import com.ibm.wala.util.debug.Assertions; import com.ibm.wala.util.debug.Assertions;
import com.ibm.wala.util.io.FileProvider; import com.ibm.wala.util.io.FileProvider;
@ -108,7 +109,11 @@ public class AnalysisScopeReader {
String entryPathname = toks.nextToken(); String entryPathname = toks.nextToken();
if ("classFile".equals(entryType)) { if ("classFile".equals(entryType)) {
File cf = FileProvider.getFile(entryPathname, javaLoader); File cf = FileProvider.getFile(entryPathname, javaLoader);
try {
scope.addClassFileToScope(walaLoader, cf); scope.addClassFileToScope(walaLoader, cf);
} catch (InvalidClassFileException e) {
Assertions.UNREACHABLE(e.toString());
}
} else if ("sourceFile".equals(entryType)) { } else if ("sourceFile".equals(entryType)) {
File sf = FileProvider.getFile(entryPathname, javaLoader); File sf = FileProvider.getFile(entryPathname, javaLoader);
scope.addSourceFileToScope(walaLoader, sf, entryPathname); scope.addSourceFileToScope(walaLoader, sf, entryPathname);
@ -197,6 +202,8 @@ public class AnalysisScopeReader {
} }
} catch (IOException e) { } catch (IOException e) {
Assertions.UNREACHABLE(e.toString()); Assertions.UNREACHABLE(e.toString());
} catch (InvalidClassFileException e) {
Assertions.UNREACHABLE(e.toString());
} }
} }
} }

View File

@ -13,6 +13,7 @@ package com.ibm.wala.util.io;// 5724-D15
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.net.JarURLConnection; import java.net.JarURLConnection;
import java.net.MalformedURLException; import java.net.MalformedURLException;
@ -263,6 +264,23 @@ public class FileProvider {
} }
} }
/**
* @throws FileNotFoundException
*/
public static InputStream getInputStreamFromClassLoader(String fileName, ClassLoader loader) throws FileNotFoundException {
if (loader == null) {
throw new IllegalArgumentException("null loader");
}
if (fileName == null) {
throw new IllegalArgumentException("null fileName");
}
InputStream is = loader.getResourceAsStream(fileName);
if (is == null) {
throw new FileNotFoundException(fileName);
}
return is;
}
/** /**
* @return the jar file packaged with this plug-in of the given name, or null * @return the jar file packaged with this plug-in of the given name, or null
* if not found: wrapped as a JarFileModule or a NestedJarFileModule * if not found: wrapped as a JarFileModule or a NestedJarFileModule

View File

@ -40,4 +40,11 @@ public class PlatformUtil {
return osname.toLowerCase().contains("windows"); return osname.toLowerCase().contains("windows");
} }
/**
* are we running on IKVM? see http://www.ikvm.net
*/
public static boolean onIKVM() {
return "IKVM.NET".equals(System.getProperty("java.runtime.name"));
}
} }