better recursion check
git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@4484 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
parent
3b5ba61cc0
commit
1ac2dc110e
|
@ -170,6 +170,10 @@ abstract public class ScopeMappingInstanceKeys implements InstanceKeyFactory {
|
|||
public InstanceKey getBase() {
|
||||
return base;
|
||||
}
|
||||
|
||||
public CGNode getCreator() {
|
||||
return creator;
|
||||
}
|
||||
}
|
||||
|
||||
public InstanceKey getInstanceKeyForAllocation(CGNode creatorNode, NewSiteReference allocationSite) {
|
||||
|
|
|
@ -9,21 +9,25 @@ import com.ibm.wala.ipa.callgraph.Context;
|
|||
import com.ibm.wala.ipa.callgraph.ContextItem;
|
||||
import com.ibm.wala.ipa.callgraph.ContextKey;
|
||||
import com.ibm.wala.ipa.callgraph.ContextSelector;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.AllocationSiteInNode;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.cfa.CallerSiteContext;
|
||||
import com.ibm.wala.ipa.summaries.SummarizedMethod;
|
||||
import com.ibm.wala.util.intset.IntSet;
|
||||
import com.ibm.wala.util.intset.IntSetUtil;
|
||||
|
||||
public class ScopeMappingKeysContextSelector implements ContextSelector {
|
||||
|
||||
|
||||
public static final ContextKey scopeKey = new ContextKey() {
|
||||
public String toString() { return "SCOPE KEY"; }
|
||||
public String toString() {
|
||||
return "SCOPE KEY";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public static class ScopeMappingContext implements Context {
|
||||
private final Context base;
|
||||
private final ScopeMappingInstanceKey key;
|
||||
|
||||
|
||||
private ScopeMappingContext(Context base, ScopeMappingInstanceKey key) {
|
||||
this.base = base;
|
||||
this.key = key;
|
||||
|
@ -36,61 +40,77 @@ public class ScopeMappingKeysContextSelector implements ContextSelector {
|
|||
return base.get(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private int hashcode = -1;
|
||||
|
||||
|
||||
public int hashCode() {
|
||||
if (hashcode == -1) {
|
||||
hashcode = base.hashCode()*key.hashCode();
|
||||
hashcode = base.hashCode() * key.hashCode();
|
||||
}
|
||||
return hashcode;
|
||||
}
|
||||
|
||||
|
||||
public String toString() {
|
||||
return "context for " + key;
|
||||
}
|
||||
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return (o instanceof ScopeMappingContext) &&
|
||||
key.equals(((ScopeMappingContext)o).key) &&
|
||||
base.equals(((ScopeMappingContext)o).base);
|
||||
return (o instanceof ScopeMappingContext) && key.equals(((ScopeMappingContext) o).key)
|
||||
&& base.equals(((ScopeMappingContext) o).base);
|
||||
}
|
||||
}
|
||||
|
||||
private final ContextSelector base;
|
||||
|
||||
|
||||
public ScopeMappingKeysContextSelector(ContextSelector base) {
|
||||
this.base = base;
|
||||
}
|
||||
|
||||
|
||||
public Context getCalleeTarget(CGNode caller, CallSiteReference site, IMethod callee, InstanceKey[] receiver) {
|
||||
Context bc = base.getCalleeTarget(caller, site, callee, receiver);
|
||||
if (callee instanceof SummarizedMethod) {
|
||||
final String calleeName = callee.getReference().toString();
|
||||
if (calleeName.equals("< JavaScriptLoader, LArray, ctor()LRoot; >") || calleeName.equals("< JavaScriptLoader, LObject, ctor()LRoot; >")) {
|
||||
if (calleeName.equals("< JavaScriptLoader, LArray, ctor()LRoot; >")
|
||||
|| calleeName.equals("< JavaScriptLoader, LObject, ctor()LRoot; >")) {
|
||||
return bc;
|
||||
}
|
||||
}
|
||||
if (receiver[0] instanceof ScopeMappingInstanceKey) {
|
||||
final ScopeMappingInstanceKey smik = (ScopeMappingInstanceKey) receiver[0];
|
||||
if (AstTranslator.NEW_LEXICAL) {
|
||||
// need a recursion check; for now, very coarse
|
||||
ContextItem contextItem = caller.getContext().get(scopeKey);
|
||||
if (contextItem != null) {
|
||||
if (detectRecursion(smik.getCreator().getContext(), callee)) {
|
||||
return bc;
|
||||
}
|
||||
}
|
||||
final ScopeMappingContext scopeMappingContext = new ScopeMappingContext(bc, (ScopeMappingInstanceKey) receiver[0]);
|
||||
final ScopeMappingContext scopeMappingContext = new ScopeMappingContext(bc, smik);
|
||||
return scopeMappingContext;
|
||||
} else {
|
||||
return bc;
|
||||
}
|
||||
}
|
||||
|
||||
private static final IntSet thisParameter = IntSetUtil.make(new int[]{0});
|
||||
|
||||
/**
|
||||
* we need this check due a potentially nasty interaction between
|
||||
* ScopeMappingContexts and CGNode-based contexts like
|
||||
* {@link CallerSiteContext}s. It's unclear where exactly this check should
|
||||
* go; since ScopeMappingContexts are less common, putting it here for now.
|
||||
*/
|
||||
private boolean detectRecursion(Context context, IMethod callee) {
|
||||
CGNode caller = (CGNode) context.get(ContextKey.CALLER);
|
||||
if (caller != null) {
|
||||
if (caller.getMethod().equals(callee)) {
|
||||
return true;
|
||||
} else {
|
||||
return detectRecursion(caller.getContext(), callee);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static final IntSet thisParameter = IntSetUtil.make(new int[] { 0 });
|
||||
|
||||
public IntSet getRelevantParameters(CGNode caller, CallSiteReference site) {
|
||||
return thisParameter;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue