use of soot.util.NumberedString in project soot by Sable.
the class SootClass method getMethod.
/*
* Returns the method of this class with the given subsignature. If no method
* with the given subsignature can be found, an exception is thrown.
*/
public SootMethod getMethod(String subsignature) {
checkLevel(SIGNATURES);
NumberedString numberedString = Scene.v().getSubSigNumberer().find(subsignature);
if (numberedString == null)
throw new RuntimeException("No method " + subsignature + " in class " + getName());
return getMethod(numberedString);
}
use of soot.util.NumberedString in project soot by Sable.
the class DemandCSPointsTo method refineCallSite.
protected Set<SootMethod> refineCallSite(Integer callSite, ImmutableStack<Integer> origContext) {
CallSiteAndContext callSiteAndContext = new CallSiteAndContext(callSite, origContext);
if (queriedCallSites.contains(callSiteAndContext)) {
// }
return callSiteToResolvedTargets.get(callSiteAndContext);
}
if (callGraphStack.contains(callSiteAndContext)) {
return Collections.<SootMethod>emptySet();
} else {
callGraphStack.push(callSiteAndContext);
}
final VarNode receiver = csInfo.getReceiverForVirtCallSite(callSite);
final Type receiverType = receiver.getType();
final SootMethod invokedMethod = csInfo.getInvokedMethod(callSite);
final NumberedString methodSig = invokedMethod.getNumberedSubSignature();
final Set<SootMethod> allTargets = csInfo.getCallSiteTargets(callSite);
if (!refineCallGraph) {
callGraphStack.pop();
return allTargets;
}
if (DEBUG_VIRT) {
debugPrint("refining call to " + invokedMethod + " on " + receiver + " " + origContext);
}
final HashSet<VarAndContext> marked = new HashSet<VarAndContext>();
final Stack<VarAndContext> worklist = new Stack<VarAndContext>();
final class Helper {
void prop(VarAndContext varAndContext) {
if (marked.add(varAndContext)) {
worklist.push(varAndContext);
}
}
}
;
final Helper h = new Helper();
h.prop(new VarAndContext(receiver, origContext));
while (!worklist.isEmpty()) {
incrementNodesTraversed();
VarAndContext curVarAndContext = worklist.pop();
if (DEBUG_VIRT) {
debugPrint("virt looking at " + curVarAndContext);
}
VarNode curVar = curVarAndContext.var;
ImmutableStack<Integer> curContext = curVarAndContext.context;
// Set<SootMethod> curVarTargets = getCallTargets(curVar.getP2Set(),
// methodSig, receiverType, allTargets);
// if (curVarTargets.size() <= 1) {
// for (SootMethod method : curVarTargets) {
// callSiteToResolvedTargets.put(callSiteAndContext, method);
// }
// continue;
// }
Node[] newNodes = pag.allocInvLookup(curVar);
for (int i = 0; i < newNodes.length; i++) {
AllocNode allocNode = (AllocNode) newNodes[i];
for (SootMethod method : getCallTargetsForType(allocNode.getType(), methodSig, receiverType, allTargets)) {
callSiteToResolvedTargets.put(callSiteAndContext, method);
}
}
Collection<AssignEdge> assigns = filterAssigns(curVar, curContext, true, true);
for (AssignEdge assignEdge : assigns) {
VarNode src = assignEdge.getSrc();
ImmutableStack<Integer> newContext = curContext;
if (assignEdge.isParamEdge()) {
if (!curContext.isEmpty()) {
if (!callEdgeInSCC(assignEdge)) {
assert assignEdge.getCallSite().equals(curContext.peek());
newContext = curContext.pop();
} else {
newContext = popRecursiveCallSites(curContext);
}
} else {
callSiteToResolvedTargets.putAll(callSiteAndContext, allTargets);
// }
continue;
}
} else if (assignEdge.isReturnEdge()) {
// if (DEBUG)
// logger.debug("entering call site "
// + assignEdge.getCallSite());
// if (!isRecursive(curContext, assignEdge)) {
// newContext = curContext.push(assignEdge.getCallSite());
// }
newContext = pushWithRecursionCheck(curContext, assignEdge);
} else if (src instanceof GlobalVarNode) {
newContext = EMPTY_CALLSTACK;
}
h.prop(new VarAndContext(src, newContext));
}
// TODO respect heuristic
Set<VarNode> matchSources = vMatches.vMatchInvLookup(curVar);
final boolean oneMatch = matchSources.size() == 1;
Node[] loads = pag.loadInvLookup(curVar);
for (int i = 0; i < loads.length; i++) {
FieldRefNode frNode = (FieldRefNode) loads[i];
final VarNode loadBase = frNode.getBase();
SparkField field = frNode.getField();
for (Pair<VarNode, VarNode> store : fieldToStores.get(field)) {
final VarNode storeBase = store.getO2();
final PointsToSetInternal storeBaseP2Set = storeBase.getP2Set();
final PointsToSetInternal loadBaseP2Set = loadBase.getP2Set();
final VarNode matchSrc = store.getO1();
if (matchSources.contains(matchSrc)) {
// optimize for common case of constructor init
boolean skipMatch = false;
if (oneMatch) {
PointsToSetInternal matchSrcPTo = matchSrc.getP2Set();
Set<SootMethod> matchSrcCallTargets = getCallTargets(matchSrcPTo, methodSig, receiverType, allTargets);
if (matchSrcCallTargets.size() <= 1) {
skipMatch = true;
for (SootMethod method : matchSrcCallTargets) {
callSiteToResolvedTargets.put(callSiteAndContext, method);
}
}
}
if (!skipMatch) {
final PointsToSetInternal intersection = SootUtil.constructIntersection(storeBaseP2Set, loadBaseP2Set, pag);
AllocAndContextSet allocContexts = null;
boolean oldRefining = refiningCallSite;
int oldNesting = nesting;
try {
refiningCallSite = true;
allocContexts = findContextsForAllocs(new VarAndContext(loadBase, curContext), intersection);
} catch (CallSiteException e) {
callSiteToResolvedTargets.putAll(callSiteAndContext, allTargets);
continue;
} finally {
refiningCallSite = oldRefining;
nesting = oldNesting;
}
for (AllocAndContext allocAndContext : allocContexts) {
CallingContextSet matchSrcContexts;
if (fieldCheckHeuristic.validFromBothEnds(field)) {
matchSrcContexts = findUpContextsForVar(allocAndContext, new VarContextAndUp(storeBase, EMPTY_CALLSTACK, EMPTY_CALLSTACK));
} else {
matchSrcContexts = findVarContextsFromAlloc(allocAndContext, storeBase);
}
for (ImmutableStack<Integer> matchSrcContext : matchSrcContexts) {
VarAndContext newVarAndContext = new VarAndContext(matchSrc, matchSrcContext);
h.prop(newVarAndContext);
}
}
}
}
}
}
}
if (DEBUG_VIRT) {
debugPrint("call of " + invokedMethod + " on " + receiver + " " + origContext + " goes to " + callSiteToResolvedTargets.get(callSiteAndContext));
}
callGraphStack.pop();
queriedCallSites.add(callSiteAndContext);
return callSiteToResolvedTargets.get(callSiteAndContext);
}
Aggregations