support for Constructor.newInstance()

git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@2600 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
sjfink 2008-02-21 18:44:22 +00:00
parent 6fd7472393
commit 75bfab8605
13 changed files with 532 additions and 26 deletions

View File

@ -17,6 +17,7 @@ import java.util.Map;
import com.ibm.wala.analysis.typeInference.ConeType;
import com.ibm.wala.analysis.typeInference.TypeAbstraction;
import com.ibm.wala.classLoader.CallSiteReference;
import com.ibm.wala.classLoader.IClass;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.classLoader.NewSiteReference;
@ -26,7 +27,9 @@ import com.ibm.wala.ipa.callgraph.AnalysisOptions;
import com.ibm.wala.ipa.callgraph.ReflectionSpecification;
import com.ibm.wala.ipa.callgraph.propagation.SSAContextInterpreter;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.shrikeBT.IInvokeInstruction;
import com.ibm.wala.ssa.SSAInstruction;
import com.ibm.wala.ssa.SSAInvokeInstruction;
import com.ibm.wala.ssa.SSANewInstruction;
import com.ibm.wala.ssa.SSAReturnInstruction;
import com.ibm.wala.types.MethodReference;
@ -108,9 +111,7 @@ public abstract class AbstractReflectionInterpreter implements SSAContextInterpr
}
/**
* @author sfink
*
* A waring when we expect excessive pollution from a factory method
* A warning when we expect excessive pollution from a factory method
*/
protected static class ManySubtypesWarning extends Warning {
@ -135,8 +136,6 @@ public abstract class AbstractReflectionInterpreter implements SSAContextInterpr
}
/**
* @author sfink
*
* A warning when we fail to find subtypes for a factory method
*/
protected static class NoSubtypesWarning extends Warning {
@ -239,9 +238,25 @@ public abstract class AbstractReflectionInterpreter implements SSAContextInterpr
Trace.println("Added allocation: " + a);
}
addInstruction(T, a, true);
if (!T.isArrayType()) {
addCtorInvokeInstruction(T, alloc);
}
SSAReturnInstruction r = new SSAReturnInstruction(alloc, false);
addInstruction(T, r, false);
return alloc;
}
protected void addCtorInvokeInstruction(final TypeReference T, int alloc) {
MethodReference init = MethodReference.findOrCreate(T, MethodReference.initAtom, MethodReference.defaultInitDesc);
CallSiteReference site = CallSiteReference.make(getCallSiteForType(T), init, IInvokeInstruction.Dispatch.SPECIAL);
int[] params = new int[1];
params[0] = alloc;
int exc = getExceptionsForType(T);
SSAInvokeInstruction s = new SSAInvokeInstruction(params, exc, site);
calls.add(s);
allInstructions.add(s);
}
}
}

View File

@ -46,7 +46,7 @@ import com.ibm.wala.util.strings.Atom;
*
* @author pistoia
*/
public class NewInstanceContextInterpreter extends AbstractReflectionInterpreter {
public class ClassNewInstanceContextInterpreter extends AbstractReflectionInterpreter {
public final static Atom newInstanceAtom = Atom.findOrCreateUnicodeAtom("newInstance");
@ -61,7 +61,7 @@ public class NewInstanceContextInterpreter extends AbstractReflectionInterpreter
private final IClassHierarchy cha;
public NewInstanceContextInterpreter(IClassHierarchy cha) {
public ClassNewInstanceContextInterpreter(IClassHierarchy cha) {
this.cha = cha;
}
@ -119,7 +119,8 @@ public class NewInstanceContextInterpreter extends AbstractReflectionInterpreter
if (tr != null) {
SpecializedMethod m = new SpecializedMethod(method, method.getDeclaringClass(), method.isStatic(), false);
IClass klass = cha.lookupClass(tr);
if (hasPublicDefaultCtor(klass)) {
IMethod publicDefaultCtor = getPublicDefaultCtor(klass);
if (publicDefaultCtor != null) {
m.addStatementsForConcreteSimpleType(tr);
} else if (klass.getMethod(defCtorSelector) == null) {
TypeReference instantiationExceptionRef = TypeReference.findOrCreateClass(ClassLoaderReference.Primordial, "java/lang", "InstantiationException");
@ -145,12 +146,12 @@ public class NewInstanceContextInterpreter extends AbstractReflectionInterpreter
return null;
}
private boolean hasPublicDefaultCtor(IClass klass) {
private IMethod getPublicDefaultCtor(IClass klass) {
IMethod ctorMethod = klass.getMethod(defCtorSelector);
if (ctorMethod != null && ctorMethod.isPublic()) {
return true;
return ctorMethod;
}
return false;
return null;
}
public boolean recordFactoryType(CGNode node, IClass klass) {

View File

@ -25,9 +25,9 @@ import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
*
* @author pistoia
*/
class NewInstanceContextSelector implements ContextSelector {
class ClassNewInstanceContextSelector implements ContextSelector {
public NewInstanceContextSelector() {
public ClassNewInstanceContextSelector() {
}
public boolean allSitesDispatchIdentically(CGNode node, CallSiteReference site) {
@ -39,8 +39,9 @@ class NewInstanceContextSelector implements ContextSelector {
}
public Context getCalleeTarget(CGNode caller, CallSiteReference site, IMethod callee, InstanceKey receiver) {
if (mayUnderstand(caller, site, callee, receiver)) {
return new JavaTypeContext(new PointType(receiver.getConcreteType()));
if (mayUnderstand(caller, site, callee, receiver)) {
IClass c = (IClass) ((ConstantKey) receiver).getValue();
return new JavaTypeContext(new PointType(c));
}
return null;
}
@ -49,7 +50,7 @@ class NewInstanceContextSelector implements ContextSelector {
* This object may understand a dispatch to Class.newInstance() when the class is a class constant.
*/
public boolean mayUnderstand(CGNode caller, CallSiteReference site, IMethod targetMethod, InstanceKey instance) {
if (targetMethod.getReference().equals(NewInstanceContextInterpreter.NEW_INSTANCE_REF) && isTypeConstant(instance)) {
if (targetMethod.getReference().equals(ClassNewInstanceContextInterpreter.NEW_INSTANCE_REF) && isTypeConstant(instance)) {
// IClass klass = getTypeConstant(instance);
// if (hasPublicDefaultCtor(klass)) {
return true;

View File

@ -0,0 +1,166 @@
/*******************************************************************************
* Copyright (c) 2008 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.analysis.reflection;
import java.util.Iterator;
import java.util.Map;
import com.ibm.wala.cfg.ControlFlowGraph;
import com.ibm.wala.cfg.InducedCFG;
import com.ibm.wala.classLoader.CallSiteReference;
import com.ibm.wala.classLoader.IClass;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.classLoader.NewSiteReference;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.callgraph.propagation.ConstantKey;
import com.ibm.wala.ipa.callgraph.propagation.ReceiverInstanceContext;
import com.ibm.wala.ipa.callgraph.propagation.SSAContextInterpreter;
import com.ibm.wala.ipa.summaries.SyntheticIR;
import com.ibm.wala.shrikeBT.IInvokeInstruction;
import com.ibm.wala.ssa.ConstantValue;
import com.ibm.wala.ssa.DefUse;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.ssa.SSAArrayLoadInstruction;
import com.ibm.wala.ssa.SSAInstruction;
import com.ibm.wala.ssa.SSAInvokeInstruction;
import com.ibm.wala.ssa.SSANewInstruction;
import com.ibm.wala.ssa.SSAOptions;
import com.ibm.wala.ssa.SSAReturnInstruction;
import com.ibm.wala.types.Descriptor;
import com.ibm.wala.types.FieldReference;
import com.ibm.wala.types.MethodReference;
import com.ibm.wala.types.TypeReference;
import com.ibm.wala.util.collections.EmptyIterator;
import com.ibm.wala.util.collections.HashMapFactory;
import com.ibm.wala.util.debug.Assertions;
import com.ibm.wala.util.strings.Atom;
/**
* An {@link SSAContextInterpreter} specialized to interpret Constructor.newInstance in a {@link JavaTypeContext} which
* represents the point-type of the class object created by the call.
*
* @author pistoia
*/
public class ConstructorNewInstanceContextInterpreter extends AbstractReflectionInterpreter {
public final static Atom newInstanceAtom = Atom.findOrCreateUnicodeAtom("newInstance");
private final static Descriptor newInstanceDescriptor = Descriptor.findOrCreateUTF8("([Ljava/lang/Object;)Ljava/lang/Object;");
public final static MethodReference NEW_INSTANCE_REF = MethodReference.findOrCreate(TypeReference.JavaLangReflectConstructor,
newInstanceAtom, newInstanceDescriptor);
public IR getIR(CGNode node) {
if (node == null) {
throw new IllegalArgumentException("node is null");
}
if (Assertions.verifyAssertions) {
Assertions._assert(understands(node));
}
ReceiverInstanceContext recv = (ReceiverInstanceContext)node.getContext();
ConstantKey c = (ConstantKey) recv.getReceiver();
IMethod m = (IMethod) c.getValue();
IR result = makeIR(node.getMethod(), m, recv);
return result;
}
public int getNumberOfStatements(CGNode node) {
if (Assertions.verifyAssertions) {
Assertions._assert(understands(node));
}
return getIR(node).getInstructions().length;
}
public boolean understands(CGNode node) {
if (node == null) {
throw new IllegalArgumentException("node is null");
}
if (!(node.getContext() instanceof ReceiverInstanceContext)) {
return false;
}
return node.getMethod().getReference().equals(NEW_INSTANCE_REF);
}
public Iterator<NewSiteReference> iterateNewSites(CGNode node) {
if (node == null) {
throw new IllegalArgumentException("node is null");
}
if (Assertions.verifyAssertions) {
Assertions._assert(understands(node));
}
return getIR(node).iterateNewSites();
}
public Iterator<CallSiteReference> iterateCallSites(CGNode node) {
if (Assertions.verifyAssertions) {
Assertions._assert(understands(node));
}
return getIR(node).iterateCallSites();
}
private IR makeIR(IMethod method, IMethod ctor, ReceiverInstanceContext context) {
SpecializedMethod m = new SpecializedMethod(method, method.getDeclaringClass(), method.isStatic(), false);
Map<Integer, ConstantValue> constants = HashMapFactory.make();
int nextLocal = method.getNumberOfParameters() + 1;
int nargs = ctor.getNumberOfParameters();
int args[] = new int[nargs];
int i = 0;
int pc = 0;
TypeReference allocatedType = ctor.getDeclaringClass().getReference();
m.addInstruction(allocatedType, new SSANewInstruction(args[i++] = nextLocal++, NewSiteReference.make(pc++, allocatedType)),
true);
for (int j = 1; j < nargs; j++) {
int indexConst = nextLocal++;
m.addInstruction(null, new SSAArrayLoadInstruction(args[i++] = nextLocal++, 2, indexConst, TypeReference.JavaLangObject),
false);
constants.put(new Integer(indexConst), new ConstantValue(j - 1));
pc++;
}
int exceptions = nextLocal++;
m.addInstruction(null, new SSAInvokeInstruction(args, exceptions, CallSiteReference.make(pc++, ctor.getReference(),
IInvokeInstruction.Dispatch.SPECIAL)), false);
m.addInstruction(null, new SSAReturnInstruction(args[0], false), false);
SSAInstruction[] instrs = new SSAInstruction[m.allInstructions.size()];
m.allInstructions.<SSAInstruction> toArray(instrs);
return new SyntheticIR(method, context, new InducedCFG(instrs, method, context), instrs, SSAOptions.defaultOptions(), constants);
}
public boolean recordFactoryType(CGNode node, IClass klass) {
return false;
}
public Iterator<FieldReference> iterateFieldsRead(CGNode node) {
return EmptyIterator.instance();
}
public Iterator<FieldReference> iterateFieldsWritten(CGNode node) {
return EmptyIterator.instance();
}
public ControlFlowGraph<ISSABasicBlock> getCFG(CGNode N) {
return getIR(N).getControlFlowGraph();
}
public DefUse getDU(CGNode node) {
return new DefUse(getIR(node));
}
}

View File

@ -0,0 +1,68 @@
/*******************************************************************************
* Copyright (c) 2008 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.analysis.reflection;
import com.ibm.wala.classLoader.CallSiteReference;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.callgraph.Context;
import com.ibm.wala.ipa.callgraph.ContextSelector;
import com.ibm.wala.ipa.callgraph.propagation.ConstantKey;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
import com.ibm.wala.ipa.callgraph.propagation.ReceiverInstanceContext;
import com.ibm.wala.types.TypeReference;
/**
* A {@link ContextSelector} to intercept calls to Constructor.newInstance()
*
* @author pistoia
*/
class ConstructorNewInstanceContextSelector implements ContextSelector {
public ConstructorNewInstanceContextSelector() {
}
public boolean allSitesDispatchIdentically(CGNode node, CallSiteReference site) {
return false;
}
public boolean contextIsIrrelevant(CGNode node, CallSiteReference site) {
return false;
}
@SuppressWarnings("unchecked")
public Context getCalleeTarget(CGNode caller, CallSiteReference site, IMethod callee, InstanceKey receiver) {
if (mayUnderstand(caller, site, callee, receiver)) {
return new ReceiverInstanceContext(receiver);
}
return null;
}
/**
* This object may understand a dispatch to Constructor.newInstance().
*/
public boolean mayUnderstand(CGNode caller, CallSiteReference site, IMethod targetMethod, InstanceKey instance) {
if (targetMethod.getReference().equals(ConstructorNewInstanceContextInterpreter.NEW_INSTANCE_REF) && isConstructorConstant(instance)) {
return true;
}
return false;
}
private boolean isConstructorConstant(InstanceKey instance) {
if (instance instanceof ConstantKey) {
ConstantKey c = (ConstantKey) instance;
if (c.getConcreteType().getReference().equals(TypeReference.JavaLangReflectConstructor)) {
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,162 @@
/*******************************************************************************
* Copyright (c) 2008 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.analysis.reflection;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import com.ibm.wala.cfg.ControlFlowGraph;
import com.ibm.wala.cfg.InducedCFG;
import com.ibm.wala.classLoader.CallSiteReference;
import com.ibm.wala.classLoader.IClass;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.classLoader.NewSiteReference;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.callgraph.propagation.SSAContextInterpreter;
import com.ibm.wala.ipa.summaries.SyntheticIR;
import com.ibm.wala.ssa.ConstantValue;
import com.ibm.wala.ssa.DefUse;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.ssa.SSAInstruction;
import com.ibm.wala.ssa.SSAOptions;
import com.ibm.wala.ssa.SSAReturnInstruction;
import com.ibm.wala.ssa.SSAThrowInstruction;
import com.ibm.wala.types.Descriptor;
import com.ibm.wala.types.FieldReference;
import com.ibm.wala.types.MethodReference;
import com.ibm.wala.types.TypeReference;
import com.ibm.wala.util.collections.EmptyIterator;
import com.ibm.wala.util.collections.HashMapFactory;
import com.ibm.wala.util.collections.NonNullSingletonIterator;
import com.ibm.wala.util.debug.Assertions;
import com.ibm.wala.util.strings.Atom;
/**
* An {@link SSAContextInterpreter} specialized to interpret Class.forName in a {@link JavaTypeContext} which
* represents the point-type of the class object created by the call.
*
* @author pistoia
*/
public class GetConstructorContextInterpreter implements SSAContextInterpreter {
public final static Atom getConstructorAtom = Atom.findOrCreateUnicodeAtom("getConstructor");
private final static Descriptor getConstructorDescriptor = Descriptor.findOrCreateUTF8("([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;");
public final static MethodReference GET_CONSTRUCTOR_REF = MethodReference.findOrCreate(TypeReference.JavaLangClass, getConstructorAtom,
getConstructorDescriptor);
public IR getIR(CGNode node) {
if (node == null) {
throw new IllegalArgumentException("node is null");
}
if (Assertions.verifyAssertions) {
Assertions._assert(understands(node));
}
IR result = makeIR(node.getMethod(), (JavaTypeContext) node.getContext());
return result;
}
public int getNumberOfStatements(CGNode node) {
if (Assertions.verifyAssertions) {
Assertions._assert(understands(node));
}
return getIR(node).getInstructions().length;
}
public boolean understands(CGNode node) {
if (node == null) {
throw new IllegalArgumentException("node is null");
}
if (!(node.getContext() instanceof JavaTypeContext))
return false;
return node.getMethod().getReference().equals(GET_CONSTRUCTOR_REF);
}
public Iterator<NewSiteReference> iterateNewSites(CGNode node) {
if (node == null) {
throw new IllegalArgumentException("node is null");
}
if (Assertions.verifyAssertions) {
Assertions._assert(understands(node));
}
JavaTypeContext context = (JavaTypeContext) node.getContext();
TypeReference tr = context.getType().getTypeReference();
if (tr != null) {
return new NonNullSingletonIterator<NewSiteReference>(NewSiteReference.make(0, tr));
}
return EmptyIterator.instance();
}
public Iterator<CallSiteReference> iterateCallSites(CGNode node) {
if (Assertions.verifyAssertions) {
Assertions._assert(understands(node));
}
return EmptyIterator.instance();
}
private SSAInstruction[] makeStatements(JavaTypeContext context, Map<Integer, ConstantValue> constants) {
ArrayList<SSAInstruction> statements = new ArrayList<SSAInstruction>();
int nextLocal = 2;
int retValue = nextLocal++;
IClass cls = context.getType().getType();
if (cls != null) {
for(Iterator methods = cls.getDeclaredMethods().iterator(); methods.hasNext(); ) {
IMethod m = (IMethod) methods.next();
if (m.isInit()) {
int c = nextLocal++;
constants.put(c, new ConstantValue(m));
SSAReturnInstruction R = new SSAReturnInstruction(c, false);
statements.add(R);
retValue++;
}
}
} else {
SSAThrowInstruction t = new SSAThrowInstruction(retValue);
statements.add(t);
}
SSAInstruction[] result = new SSAInstruction[statements.size()];
Iterator<SSAInstruction> it = statements.iterator();
for (int i = 0; i < result.length; i++) {
result[i] = it.next();
}
return result;
}
private IR makeIR(IMethod method, JavaTypeContext context) {
Map<Integer,ConstantValue> constants = HashMapFactory.make();
SSAInstruction instrs[] = makeStatements(context, constants);
return new SyntheticIR(method, context, new InducedCFG(instrs, method, context), instrs, SSAOptions.defaultOptions(), constants);
}
public boolean recordFactoryType(CGNode node, IClass klass) {
return false;
}
public Iterator<FieldReference> iterateFieldsRead(CGNode node) {
return EmptyIterator.instance();
}
public Iterator<FieldReference> iterateFieldsWritten(CGNode node) {
return EmptyIterator.instance();
}
public ControlFlowGraph<ISSABasicBlock> getCFG(CGNode N) {
return getIR(N).getControlFlowGraph();
}
public DefUse getDU(CGNode node) {
return new DefUse(getIR(node));
}
}

View File

@ -0,0 +1,76 @@
/*******************************************************************************
* Copyright (c) 2008 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.analysis.reflection;
import com.ibm.wala.analysis.typeInference.PointType;
import com.ibm.wala.classLoader.CallSiteReference;
import com.ibm.wala.classLoader.IClass;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.callgraph.Context;
import com.ibm.wala.ipa.callgraph.ContextSelector;
import com.ibm.wala.ipa.callgraph.propagation.ConstantKey;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
import com.ibm.wala.ipa.cha.IClassHierarchy;
/**
* A {@link ContextSelector} to intercept calls to Class.getConstructor() when the receiver is a type constant
*
* @author pistoia
*/
class GetConstructorContextSelector implements ContextSelector {
public GetConstructorContextSelector() {
}
public boolean allSitesDispatchIdentically(CGNode node, CallSiteReference site) {
return false;
}
public boolean contextIsIrrelevant(CGNode node, CallSiteReference site) {
return false;
}
/**
* If the {@link CallSiteReference} invokes c.getConstructor() and c is a type constant, return a
* {@link JavaTypeContext} representing the type named by s, if we can resolve it in the {@link IClassHierarchy}.
*
* @see com.ibm.wala.ipa.callgraph.ContextSelector#getCalleeTarget(com.ibm.wala.ipa.callgraph.CGNode,
* com.ibm.wala.classLoader.CallSiteReference, com.ibm.wala.classLoader.IMethod,
* com.ibm.wala.ipa.callgraph.propagation.InstanceKey)
*/
public Context getCalleeTarget(CGNode caller, CallSiteReference site, IMethod callee, InstanceKey receiver) {
if (mayUnderstand(caller, site, callee, receiver)) {
return new JavaTypeContext(new PointType(getTypeConstant(receiver)));
}
return null;
}
private IClass getTypeConstant(InstanceKey instance) {
if (instance instanceof ConstantKey) {
ConstantKey c = (ConstantKey)instance;
if (c.getValue() instanceof IClass) {
return (IClass)c.getValue();
}
}
return null;
}
/**
* This object may understand a dispatch to Class.getContructor when the receiver is a type constant.
*/
public boolean mayUnderstand(CGNode caller, CallSiteReference site, IMethod targetMethod, InstanceKey instance) {
if (targetMethod.getReference().equals(GetConstructorContextInterpreter.GET_CONSTRUCTOR_REF) && getTypeConstant(instance) != null) {
return true;
}
return false;
}
}

View File

@ -21,18 +21,21 @@ import com.ibm.wala.ipa.cha.IClassHierarchy;
* {@link SSAContextInterpreter} to handle all reflection procession.
*
* @author sjfink
*
*
*/
public class ReflectionContextInterpreter extends DelegatingSSAContextInterpreter {
public static ReflectionContextInterpreter createReflectionContextInterpreter(IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache,
ReflectionSpecification userSpec) {
public static ReflectionContextInterpreter createReflectionContextInterpreter(IClassHierarchy cha, AnalysisOptions options,
AnalysisCache cache, ReflectionSpecification userSpec) {
return new ReflectionContextInterpreter(cha, options, cache, userSpec);
}
private ReflectionContextInterpreter(IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache, ReflectionSpecification userSpec) {
super(new DelegatingSSAContextInterpreter(new ForNameContextInterpreter(), new NewInstanceContextInterpreter(cha)),
new FactoryBypassInterpreter(options, cache, userSpec));
private ReflectionContextInterpreter(IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache,
ReflectionSpecification userSpec) {
super(new ConstructorNewInstanceContextInterpreter(), new DelegatingSSAContextInterpreter(
new GetConstructorContextInterpreter(), new DelegatingSSAContextInterpreter(new DelegatingSSAContextInterpreter(
new ForNameContextInterpreter(), new ClassNewInstanceContextInterpreter(cha)), new FactoryBypassInterpreter(options,
cache, userSpec))));
}
}

View File

@ -31,7 +31,9 @@ public class ReflectionContextSelector extends DelegatingContextSelector {
* First check "forName" logic, then factory logic.
*/
private ReflectionContextSelector(IClassHierarchy cha, MethodTargetSelector methodTargetSelector) {
super(new DelegatingContextSelector(new ForNameContextSelector(), new NewInstanceContextSelector()),
new FactoryContextSelector(cha, methodTargetSelector));
super(new ConstructorNewInstanceContextSelector(),
new DelegatingContextSelector(new GetConstructorContextSelector(),
new DelegatingContextSelector(new DelegatingContextSelector(new ForNameContextSelector(), new ClassNewInstanceContextSelector()),
new FactoryContextSelector(cha, methodTargetSelector))));
}
}

View File

@ -20,6 +20,9 @@ public interface Language {
public TypeReference getConstantType(Object o) {
if (o instanceof String) {
return TypeReference.JavaLangString;
} else if (o instanceof IMethod) {
IMethod m = (IMethod) o;
return m.isInit() ? TypeReference.JavaLangReflectConstructor : TypeReference.JavaLangReflectMethod;
} else {
return null;
}

View File

@ -261,13 +261,17 @@ public class ZeroXInstanceKeys implements InstanceKeyFactory {
if (type == null) {
throw new IllegalArgumentException("null type");
}
if (disambiguateConstants()) {
if (disambiguateConstants() || isReflectiveType(type)) {
return new ConstantKey<T>(S, getClassHierarchy().lookupClass(type));
} else {
return classBased.getInstanceKeyForConstant(type, S);
}
}
private boolean isReflectiveType(TypeReference type) {
return type.equals(TypeReference.JavaLangReflectConstructor);
}
/*
* @see com.ibm.wala.ipa.callgraph.propagation.InstanceKeyFactory#getInstanceKeyForPEI(com.ibm.wala.ipa.callgraph.CGNode,
* com.ibm.wala.classLoader.ProgramCounter,

View File

@ -25,7 +25,7 @@ import com.ibm.wala.util.shrike.Exceptions;
public class SSAArrayLoadInstruction extends SSAArrayReferenceInstruction {
private final int result;
SSAArrayLoadInstruction(int result, int arrayref, int index, TypeReference elementType) {
public SSAArrayLoadInstruction(int result, int arrayref, int index, TypeReference elementType) {
super(arrayref, index, elementType);
this.result = result;
}

View File

@ -163,6 +163,11 @@ public final class TypeReference {
public final static TypeReference JavaLangReflectConstructor = findOrCreate(ClassLoaderReference.Primordial,
JavaLangReflectConstructorName);
private final static TypeName JavaLangReflectMethodName = TypeName.string2TypeName("Ljava/lang/reflect/Method");
public final static TypeReference JavaLangReflectMethod = findOrCreate(ClassLoaderReference.Primordial,
JavaLangReflectMethodName);
private final static TypeName JavaLangErrorName = TypeName.string2TypeName("Ljava/lang/Error");