work toward pointer analysis based on the flowgraph from field-based

call graph builder
This commit is contained in:
Julian Dolby 2014-10-19 22:44:03 -04:00
parent 019425c0e2
commit 1bb7610011
29 changed files with 304 additions and 171 deletions

View File

@ -11,8 +11,9 @@ import org.junit.Before;
import com.ibm.wala.cast.ir.translator.TranslatorToCAst.Error;
import com.ibm.wala.cast.js.ipa.callgraph.JSCallGraph;
import com.ibm.wala.cast.js.rhino.callgraph.fieldbased.test.CGUtil.BuilderType;
import com.ibm.wala.cast.js.test.FieldBasedCGUtil;
import com.ibm.wala.cast.js.test.TestJSCallGraphShape;
import com.ibm.wala.cast.js.test.FieldBasedCGUtil.BuilderType;
import com.ibm.wala.cast.js.translator.CAstRhinoTranslatorFactory;
import com.ibm.wala.cast.js.util.CallGraph2JSON;
import com.ibm.wala.util.CancelException;
@ -22,7 +23,7 @@ import com.ibm.wala.util.WalaException;
public abstract class AbstractFieldBasedTest extends TestJSCallGraphShape {
protected CGUtil util;
protected FieldBasedCGUtil util;
public AbstractFieldBasedTest() {
super();
@ -31,7 +32,7 @@ public abstract class AbstractFieldBasedTest extends TestJSCallGraphShape {
@Override
@Before
public void setUp() throws Exception {
util = new CGUtil(new CAstRhinoTranslatorFactory());
util = new FieldBasedCGUtil(new CAstRhinoTranslatorFactory());
}
protected JSCallGraph runTest(String script, Object[][] assertions, BuilderType... builderTypes) throws IOException, WalaException, Error, CancelException {
@ -43,7 +44,7 @@ public abstract class AbstractFieldBasedTest extends TestJSCallGraphShape {
for(BuilderType builderType : builderTypes) {
ProgressMaster monitor = ProgressMaster.make(new NullProgressMonitor(), 30000, true);
try {
cg = util.buildCG(url, builderType, monitor);
cg = util.buildCG(url, builderType, monitor, false).fst;
System.err.println(cg);
verifyGraphAssertions(cg, assertions);
} catch(AssertionFailedError afe) {

View File

@ -7,7 +7,7 @@ import org.junit.Ignore;
import org.junit.Test;
import com.ibm.wala.cast.ir.translator.TranslatorToCAst.Error;
import com.ibm.wala.cast.js.rhino.callgraph.fieldbased.test.CGUtil.BuilderType;
import com.ibm.wala.cast.js.test.FieldBasedCGUtil.BuilderType;
import com.ibm.wala.util.CancelException;
import com.ibm.wala.util.WalaException;
@ -28,7 +28,8 @@ public class FieldBasedCGGamesTest extends AbstractFieldBasedTest {
runTestExceptOnTravis(new URL("http://www.markus-inger.de/test/game.php"), new Object[][]{}, BuilderType.OPTIMISTIC_WORKLIST);
}
@Test
// seems to break with http issues
//@Test
public void testDiggAttack() throws IOException, WalaException, Error, CancelException {
runTestExceptOnTravis(new URL("http://www.pixastic.com/labs/digg_attack/"), new Object[][]{}, BuilderType.OPTIMISTIC_WORKLIST);
}

View File

@ -8,8 +8,8 @@ import org.junit.Test;
import com.ibm.wala.cast.ir.translator.TranslatorToCAst.Error;
import com.ibm.wala.cast.js.html.JSSourceExtractor;
import com.ibm.wala.cast.js.rhino.callgraph.fieldbased.test.CGUtil.BuilderType;
import com.ibm.wala.cast.js.test.TestSimplePageCallGraphShape;
import com.ibm.wala.cast.js.test.FieldBasedCGUtil.BuilderType;
import com.ibm.wala.util.CancelException;
import com.ibm.wala.util.WalaException;

View File

@ -12,11 +12,10 @@ package com.ibm.wala.cast.js.rhino.callgraph.fieldbased.test;
import java.io.IOException;
import org.junit.Test;
import com.ibm.wala.cast.ir.translator.TranslatorToCAst.Error;
import com.ibm.wala.cast.js.rhino.callgraph.fieldbased.test.CGUtil.BuilderType;
import com.ibm.wala.cast.js.test.FieldBasedCGUtil.BuilderType;
import com.ibm.wala.util.CancelException;
import com.ibm.wala.util.WalaException;

View File

@ -0,0 +1,12 @@
package com.ibm.wala.cast.js.rhino.callgraph.fieldbased.test;
import com.ibm.wala.cast.js.test.TestPointerAnalyses;
import com.ibm.wala.cast.js.translator.CAstRhinoTranslatorFactory;
public class TestPointerAnalysisRhino extends TestPointerAnalyses {
public TestPointerAnalysisRhino() {
super(new CAstRhinoTranslatorFactory());
}
}

View File

@ -8,9 +8,8 @@
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.cast.js.rhino.callgraph.fieldbased.test;
package com.ibm.wala.cast.js.test;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Collections;
@ -19,32 +18,30 @@ import java.util.Set;
import com.ibm.wala.cast.ipa.callgraph.CAstAnalysisScope;
import com.ibm.wala.cast.ir.ssa.AstIRFactory;
import com.ibm.wala.cast.ir.translator.TranslatorToCAst.Error;
import com.ibm.wala.cast.js.callgraph.fieldbased.FieldBasedCallGraphBuilder;
import com.ibm.wala.cast.js.callgraph.fieldbased.OptimisticCallgraphBuilder;
import com.ibm.wala.cast.js.callgraph.fieldbased.PessimisticCallGraphBuilder;
import com.ibm.wala.cast.js.callgraph.fieldbased.WorklistBasedOptimisticCallgraphBuilder;
import com.ibm.wala.cast.js.html.JSSourceExtractor;
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.ObjectVertex;
import com.ibm.wala.cast.js.html.WebPageLoaderFactory;
import com.ibm.wala.cast.js.ipa.callgraph.JSCallGraph;
import com.ibm.wala.cast.js.ipa.callgraph.JSCallGraphUtil;
import com.ibm.wala.cast.js.loader.JavaScriptLoader;
import com.ibm.wala.cast.js.loader.JavaScriptLoaderFactory;
import com.ibm.wala.cast.js.test.JSCallGraphBuilderUtil;
import com.ibm.wala.cast.js.translator.CAstRhinoTranslatorFactory;
import com.ibm.wala.cast.js.translator.JavaScriptTranslatorFactory;
import com.ibm.wala.cast.js.util.CallGraph2JSON;
import com.ibm.wala.cast.js.util.Util;
import com.ibm.wala.classLoader.SourceModule;
import com.ibm.wala.classLoader.SourceURLModule;
import com.ibm.wala.ipa.callgraph.AnalysisCache;
import com.ibm.wala.ipa.callgraph.Entrypoint;
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
import com.ibm.wala.ipa.cha.ClassHierarchy;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.util.CancelException;
import com.ibm.wala.util.MonitorUtil.IProgressMonitor;
import com.ibm.wala.util.NullProgressMonitor;
import com.ibm.wala.util.WalaException;
import com.ibm.wala.util.collections.Pair;
/**
* Utility class for building call graphs.
@ -52,20 +49,20 @@ import com.ibm.wala.util.WalaException;
* @author mschaefer
*
*/
public class CGUtil {
public class FieldBasedCGUtil {
public static enum BuilderType { PESSIMISTIC, OPTIMISTIC, OPTIMISTIC_WORKLIST };
private final JavaScriptTranslatorFactory translatorFactory;
public CGUtil(JavaScriptTranslatorFactory translatorFactory) {
public FieldBasedCGUtil(JavaScriptTranslatorFactory translatorFactory) {
this.translatorFactory = translatorFactory;
}
public JSCallGraph buildCG(URL url, BuilderType builderType) throws IOException, WalaException, CancelException {
return buildCG(url, builderType, new NullProgressMonitor());
public Pair<JSCallGraph, PointerAnalysis<ObjectVertex>> buildCG(URL url, BuilderType builderType, boolean supportFullPointerAnalysis) throws IOException, WalaException, CancelException {
return buildCG(url, builderType, new NullProgressMonitor(), supportFullPointerAnalysis);
}
public JSCallGraph buildCG(URL url, BuilderType builderType, IProgressMonitor monitor) throws IOException, WalaException, CancelException {
public Pair<JSCallGraph, PointerAnalysis<ObjectVertex>> buildCG(URL url, BuilderType builderType, IProgressMonitor monitor, boolean supportFullPointerAnalysis) throws IOException, WalaException, CancelException {
JavaScriptLoaderFactory loaders = makeLoaderFactory(url);
SourceModule[] scripts;
if (url.getFile().endsWith(".js")) {
@ -86,35 +83,22 @@ public class CGUtil {
AnalysisCache cache = new AnalysisCache(AstIRFactory.makeDefaultFactory());
switch(builderType) {
case PESSIMISTIC:
builder = new PessimisticCallGraphBuilder(cha, JSCallGraphUtil.makeOptions(scope, cha, roots), cache);
builder = new PessimisticCallGraphBuilder(cha, JSCallGraphUtil.makeOptions(scope, cha, roots), cache, supportFullPointerAnalysis);
break;
case OPTIMISTIC:
builder = new OptimisticCallgraphBuilder(cha, JSCallGraphUtil.makeOptions(scope, cha, roots), cache);
builder = new OptimisticCallgraphBuilder(cha, JSCallGraphUtil.makeOptions(scope, cha, roots), cache, supportFullPointerAnalysis);
break;
case OPTIMISTIC_WORKLIST:
builder = new WorklistBasedOptimisticCallgraphBuilder(cha, JSCallGraphUtil.makeOptions(scope, cha, roots), cache);
builder = new WorklistBasedOptimisticCallgraphBuilder(cha, JSCallGraphUtil.makeOptions(scope, cha, roots), cache, supportFullPointerAnalysis);
break;
}
return builder.buildCallGraph(roots, monitor).fst;
return builder.buildCallGraph(roots, monitor);
}
private JavaScriptLoaderFactory makeLoaderFactory(URL url) {
return url.getFile().endsWith(".js") ? new JavaScriptLoaderFactory(translatorFactory) : new WebPageLoaderFactory(translatorFactory);
}
public static void main(String[] args) throws IOException, WalaException, Error, CancelException {
JSSourceExtractor.DELETE_UPON_EXIT = true;
URL url = new File(args[0]).toURI().toURL();
System.err.println("Analysing " + url);
Map<String, Set<String>> edges = CallGraph2JSON.extractEdges(new CGUtil(new CAstRhinoTranslatorFactory()).buildCG(url, BuilderType.OPTIMISTIC_WORKLIST));
for(Map.Entry<String, Set<String>> e : edges.entrySet()) {
String site = e.getKey();
for(String callee : e.getValue())
System.out.println(site + " -> " + callee);
}
}
@SuppressWarnings("unused")
private static void compareCGs(Map<String, Set<String>> cg1, Map<String, Set<String>> cg2) {

View File

@ -124,7 +124,7 @@ public class JSCallGraphBuilderUtil extends com.ibm.wala.cast.js.ipa.callgraph.J
};
}
static AnalysisScope makeScriptScope(URL script, String dir, String name, JavaScriptLoaderFactory loaders) throws IOException {
public static AnalysisScope makeScriptScope(URL script, String dir, String name, JavaScriptLoaderFactory loaders) throws IOException {
return makeScope(
new SourceModule[] {
(script.openConnection() instanceof JarURLConnection)? new SourceURLModule(script): makeSourceModule(script, dir, name),

View File

@ -18,6 +18,7 @@ import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.FlowGraph;
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.FlowGraphBuilder;
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.CallVertex;
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.FuncVertex;
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.ObjectVertex;
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.VarVertex;
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.VertexFactory;
import com.ibm.wala.cast.js.ipa.callgraph.JSAnalysisOptions;
@ -70,15 +71,17 @@ public abstract class FieldBasedCallGraphBuilder {
protected final AnalysisCache cache;
protected final JavaScriptConstructorFunctions constructors;
protected final MethodTargetSelector targetSelector;
protected final boolean supportFullPointerAnalysis;
private static final boolean LOG_TIMINGS = true;
public FieldBasedCallGraphBuilder(IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache) {
public FieldBasedCallGraphBuilder(IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache, boolean supportFullPointerAnalysis) {
this.cha = cha;
this.options = options;
this.cache = cache;
this.constructors = new JavaScriptConstructorFunctions(cha);
this.targetSelector = setupMethodTargetSelector(cha, constructors, options);
this.supportFullPointerAnalysis = supportFullPointerAnalysis;
}
private MethodTargetSelector setupMethodTargetSelector(IClassHierarchy cha, JavaScriptConstructorFunctions constructors2, AnalysisOptions options) {
@ -90,27 +93,26 @@ public abstract class FieldBasedCallGraphBuilder {
return result;
}
protected FlowGraph flowGraphFactory(JavaScriptConstructorFunctions selector) {
FlowGraphBuilder builder = new FlowGraphBuilder(cha, cache, selector);
protected FlowGraph flowGraphFactory() {
FlowGraphBuilder builder = new FlowGraphBuilder(cha, cache, supportFullPointerAnalysis);
return builder.buildFlowGraph();
}
/**
* Build a flow graph for the program to be analysed.
* @param selector TODO
*/
public abstract FlowGraph buildFlowGraph(IProgressMonitor monitor, JavaScriptConstructorFunctions selector) throws CancelException;
public abstract FlowGraph buildFlowGraph(IProgressMonitor monitor) throws CancelException;
/**
* Main entry point: builds a flow graph, then extracts a call graph and returns it.
*/
public Pair<JSCallGraph,PointerAnalysis<FuncVertex>> buildCallGraph(Iterable<Entrypoint> eps, IProgressMonitor monitor) throws CancelException {
public Pair<JSCallGraph,PointerAnalysis<ObjectVertex>> buildCallGraph(Iterable<Entrypoint> eps, IProgressMonitor monitor) throws CancelException {
long fgBegin, fgEnd, cgBegin, cgEnd;
if(LOG_TIMINGS) fgBegin = System.currentTimeMillis();
MonitorUtil.beginTask(monitor, "flow graph", 1);
FlowGraph flowGraph = buildFlowGraph(monitor, constructors);
FlowGraph flowGraph = buildFlowGraph(monitor);
MonitorUtil.done(monitor);
if(LOG_TIMINGS) {

View File

@ -46,14 +46,14 @@ public class OptimisticCallgraphBuilder extends FieldBasedCallGraphBuilder {
private final boolean handleCallApply;
public OptimisticCallgraphBuilder(IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache) {
super(cha, options, cache);
public OptimisticCallgraphBuilder(IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache, boolean supportFullPointerAnalysis) {
super(cha, options, cache, supportFullPointerAnalysis);
handleCallApply = options instanceof JSAnalysisOptions && ((JSAnalysisOptions)options).handleCallApply();
}
@Override
public FlowGraph buildFlowGraph(IProgressMonitor monitor, JavaScriptConstructorFunctions selector) throws CancelException {
FlowGraph flowgraph = flowGraphFactory(selector);
public FlowGraph buildFlowGraph(IProgressMonitor monitor) throws CancelException {
FlowGraph flowgraph = flowGraphFactory();
// keep track of which call edges we already know about
Set<Pair<CallVertex, FuncVertex>> knownEdges = HashSetFactory.make();
@ -106,7 +106,7 @@ public class OptimisticCallgraphBuilder extends FieldBasedCallGraphBuilder {
for(int i=0;i<invk.getNumberOfParameters();++i) {
// only flow receiver into 'this' if invk is, in fact, a method call
flowgraph.addEdge(factory.makeVarVertex(caller, invk.getUse(i)), factory.makeArgVertex(callee));
if(i != 1 || !invk.getDeclaredTarget().getSelector().equals(AstMethodReference.fnSelector))
//if(i != 1 || !invk.getDeclaredTarget().getSelector().equals(AstMethodReference.fnSelector))
flowgraph.addEdge(factory.makeVarVertex(caller, invk.getUse(i)), factory.makeParamVertex(callee, i+offset));
}

View File

@ -42,13 +42,13 @@ import com.ibm.wala.util.MonitorUtil.IProgressMonitor;
*
*/
public class PessimisticCallGraphBuilder extends FieldBasedCallGraphBuilder {
public PessimisticCallGraphBuilder(IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache) {
super(cha, options, cache);
public PessimisticCallGraphBuilder(IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache, boolean supportFullPointerAnalysis) {
super(cha, options, cache, supportFullPointerAnalysis);
}
@Override
public FlowGraph buildFlowGraph(IProgressMonitor monitor, JavaScriptConstructorFunctions selector) {
FlowGraph flowgraph = flowGraphFactory(selector);
public FlowGraph buildFlowGraph(IProgressMonitor monitor) {
FlowGraph flowgraph = flowGraphFactory();
resolveLocalCalls(flowgraph);
return flowgraph;
}

View File

@ -57,14 +57,14 @@ public class WorklistBasedOptimisticCallgraphBuilder extends FieldBasedCallGraph
private FlowGraphBuilder builder;
public WorklistBasedOptimisticCallgraphBuilder(IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache) {
super(cha, options, cache);
public WorklistBasedOptimisticCallgraphBuilder(IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache, boolean supportFullPointerAnalysis) {
super(cha, options, cache, supportFullPointerAnalysis);
handleCallApply = options instanceof JSAnalysisOptions && ((JSAnalysisOptions)options).handleCallApply();
}
@Override
public FlowGraph buildFlowGraph(IProgressMonitor monitor, JavaScriptConstructorFunctions selector) throws CancelException {
builder = new FlowGraphBuilder(cha, cache, selector);
public FlowGraph buildFlowGraph(IProgressMonitor monitor) throws CancelException {
builder = new FlowGraphBuilder(cha, cache, false);
return builder.buildFlowGraph();
}

View File

@ -12,12 +12,13 @@ package com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import com.ibm.wala.analysis.pointers.HeapGraph;
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.AbstractVertexVisitor;
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.FuncVertex;
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.ObjectVertex;
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.UnknownVertex;
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.VarVertex;
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.Vertex;
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.VertexFactory;
import com.ibm.wala.cast.types.AstMethodReference;
@ -31,7 +32,6 @@ import com.ibm.wala.ipa.callgraph.propagation.FilteredPointerKey;
import com.ibm.wala.ipa.callgraph.propagation.FilteredPointerKey.TypeFilter;
import com.ibm.wala.ipa.callgraph.propagation.HeapModel;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
import com.ibm.wala.ipa.callgraph.propagation.LocalPointerKey;
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
import com.ibm.wala.ipa.cha.IClassHierarchy;
@ -40,6 +40,7 @@ import com.ibm.wala.util.CancelException;
import com.ibm.wala.util.MonitorUtil.IProgressMonitor;
import com.ibm.wala.util.Predicate;
import com.ibm.wala.util.collections.Filter;
import com.ibm.wala.util.collections.HashSetFactory;
import com.ibm.wala.util.graph.Graph;
import com.ibm.wala.util.graph.GraphReachability;
import com.ibm.wala.util.graph.GraphSlicer;
@ -59,7 +60,7 @@ public class FlowGraph implements Iterable<Vertex> {
// the actual flow graph representation
private final NumberedGraph<Vertex> graph;
// a factory that allows us to build canonical vertices
// a factory that allows us to build canonical vertices
private final VertexFactory factory;
// the transitive closure of the inverse of this.graph,
@ -76,6 +77,10 @@ public class FlowGraph implements Iterable<Vertex> {
if(optimistic_closure != null)
return;
optimistic_closure = computeClosure(graph, monitor, FuncVertex.class);
}
private <T> GraphReachability<Vertex, T> computeClosure(NumberedGraph<Vertex> graph, IProgressMonitor monitor, final Class<?> type) throws CancelException {
// prune flowgraph by taking out 'unknown' vertex
Graph<Vertex> pruned_flowgraph = GraphSlicer.prune(graph, new Predicate<Vertex>() {
@Override
@ -95,18 +100,20 @@ public class FlowGraph implements Iterable<Vertex> {
});
// compute transitive closure
optimistic_closure =
new GraphReachability<Vertex,FuncVertex>(
GraphReachability<Vertex, T> optimistic_closure =
new GraphReachability<Vertex,T>(
new InvertedGraph<Vertex>(pruned_flowgraph),
new Filter<Vertex>() {
@Override
public boolean accepts(Vertex o) {
return o instanceof FuncVertex;
return type.isInstance(o);
}
}
);
optimistic_closure.solve(monitor);
return optimistic_closure;
}
public VertexFactory getVertexFactory() {
@ -124,8 +131,8 @@ public class FlowGraph implements Iterable<Vertex> {
graph.addNode(to);
if(!graph.hasEdge(from, to)) {
optimistic_closure = null;
graph.addEdge(from, to);
optimistic_closure = null;
graph.addEdge(from, to);
}
}
@ -150,29 +157,25 @@ public class FlowGraph implements Iterable<Vertex> {
return graph.iterator();
}
public PointerAnalysis<FuncVertex> getPointerAnalysis(final IProgressMonitor monitor) {
return new PointerAnalysis<FuncVertex>() {
public PointerAnalysis<ObjectVertex> getPointerAnalysis(final IProgressMonitor monitor) throws CancelException {
return new PointerAnalysis<ObjectVertex>() {
private final GraphReachability<Vertex,ObjectVertex> pointerAnalysis = computeClosure(graph, monitor, ObjectVertex.class);
@Override
public OrdinalSet<FuncVertex> getPointsToSet(PointerKey key) {
if (key instanceof LocalPointerKey) {
CGNode node = ((LocalPointerKey)key).getNode();
FuncVertex fn = factory.makeFuncVertex(node.getMethod().getDeclaringClass());
int vn = ((LocalPointerKey)key).getValueNumber();
VarVertex v = factory.makeVarVertex(fn, vn);
try {
return getReachingSet(v, monitor);
} catch (CancelException e) {
return null;
}
public OrdinalSet<ObjectVertex> getPointsToSet(PointerKey key) {
if (graph.containsNode((Vertex)key)) {
return pointerAnalysis.getReachableSet(key);
} else {
return null;
return OrdinalSet.empty();
}
}
@Override
public Collection<FuncVertex> getInstanceKeys() {
return factory.getFuncVertices();
public Collection<ObjectVertex> getInstanceKeys() {
Set<ObjectVertex> result = HashSetFactory.make();
result.addAll(factory.creationSites());
result.addAll(factory.getFuncVertices());
return result;
}
@Override
@ -181,7 +184,7 @@ public class FlowGraph implements Iterable<Vertex> {
}
@Override
public OrdinalSetMapping<FuncVertex> getInstanceKeyMapping() {
public OrdinalSetMapping<ObjectVertex> getInstanceKeyMapping() {
// TODO Auto-generated method stub
return null;
}
@ -296,7 +299,7 @@ public class FlowGraph implements Iterable<Vertex> {
@Override
public IClassHierarchy getClassHierarchy() {
// TODO Auto-generated method stub
assert false;
return null;
}
};

View File

@ -18,11 +18,11 @@ import com.ibm.wala.cast.ir.ssa.AstLexicalAccess.Access;
import com.ibm.wala.cast.ir.ssa.AstLexicalRead;
import com.ibm.wala.cast.ir.ssa.AstLexicalWrite;
import com.ibm.wala.cast.js.callgraph.fieldbased.JSMethodInstructionVisitor;
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.CreationSiteVertex;
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.FuncVertex;
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.VarVertex;
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.Vertex;
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.VertexFactory;
import com.ibm.wala.cast.js.ipa.summaries.JavaScriptConstructorFunctions;
import com.ibm.wala.cast.js.ssa.JavaScriptInvoke;
import com.ibm.wala.cast.js.ssa.JavaScriptPropertyRead;
import com.ibm.wala.cast.js.ssa.JavaScriptPropertyWrite;
@ -41,6 +41,7 @@ import com.ibm.wala.ssa.IR;
import com.ibm.wala.ssa.SSAGetCaughtExceptionInstruction;
import com.ibm.wala.ssa.SSAGetInstruction;
import com.ibm.wala.ssa.SSAInstruction;
import com.ibm.wala.ssa.SSANewInstruction;
import com.ibm.wala.ssa.SSAPhiInstruction;
import com.ibm.wala.ssa.SSAPutInstruction;
import com.ibm.wala.ssa.SSAReturnInstruction;
@ -57,12 +58,12 @@ import com.ibm.wala.util.intset.IntSet;
public class FlowGraphBuilder {
private final IClassHierarchy cha;
private final AnalysisCache cache;
private final JavaScriptConstructorFunctions selector;
private final boolean supportFullPointerAnalysis;
public FlowGraphBuilder(IClassHierarchy cha, AnalysisCache cache, JavaScriptConstructorFunctions selector) {
public FlowGraphBuilder(IClassHierarchy cha, AnalysisCache cache, boolean supportPointerAnalysis) {
this.cha = cha;
this.cache = cache;
this.selector = selector;
this.supportFullPointerAnalysis = supportPointerAnalysis;
}
/**
@ -189,7 +190,7 @@ public class FlowGraphBuilder {
this.ir = ir;
this.flowgraph = flowgraph;
this.factory = flowgraph.getVertexFactory();
this.func = this.factory.makeFuncVertex(ir.getMethod().getDeclaringClass());
this.func = factory.makeFuncVertex(ir.getMethod().getDeclaringClass());
if(method instanceof AstMethod) {
this.lexicalInfo = ((AstMethod)method).lexicalInfo();
this.exposedVars = lexicalInfo.getAllExposedUses();
@ -344,32 +345,49 @@ public class FlowGraphBuilder {
factory.makeVarVertex(func, invk.getException()));
// check whether this invoke corresponds to a function expression/declaration
if(isFunctionConstructorInvoke(invk)) {
// second parameter is function name
String fn_name = symtab.getStringValue(invk.getUse(1));
// find the function being defined here
IClass klass = cha.lookupClass(TypeReference.findOrCreate(JavaScriptTypes.jsLoader, fn_name));
if (klass == null) {
System.err.println("cannot find " + fn_name + " at " + ((AstMethod)ir.getMethod()).getSourcePosition(ir.getCallInstructionIndices(invk.getCallSite()).intIterator().next()));
return;
}
IMethod fn = klass.getMethod(AstMethodReference.fnSelector);
FuncVertex fnVertex = factory.makeFuncVertex(klass);
// function flows into its own v1 variable
flowgraph.addEdge(fnVertex, factory.makeVarVertex(fnVertex, 1));
// flow parameters into local variables
for(int i=0;i<fn.getNumberOfParameters();++i)
flowgraph.addEdge(factory.makeParamVertex(fnVertex, i), factory.makeVarVertex(fnVertex, i+1));
// flow function into result variable
flowgraph.addEdge(fnVertex, factory.makeVarVertex(func, invk.getDef()));
// flow callee variable into callee vertex
flowgraph.addEdge(factory.makeVarVertex(func, invk.getFunction()),
factory.makeCallVertex(func, invk));
// flow callee variable into callee vertex
if(invk.getDeclaredTarget().equals(JavaScriptMethods.ctorReference)) {
flowgraph.addEdge(factory.makeVarVertex(func, invk.getFunction()),
factory.makeCallVertex(func, invk));
if(isFunctionConstructorInvoke(invk)) {
// second parameter is function name
String fn_name = symtab.getStringValue(invk.getUse(1));
// find the function being defined here
IClass klass = cha.lookupClass(TypeReference.findOrCreate(JavaScriptTypes.jsLoader, fn_name));
if (klass == null) {
System.err.println("cannot find " + fn_name + " at " + ((AstMethod)ir.getMethod()).getSourcePosition(ir.getCallInstructionIndices(invk.getCallSite()).intIterator().next()));
return;
}
IMethod fn = klass.getMethod(AstMethodReference.fnSelector);
FuncVertex fnVertex = factory.makeFuncVertex(klass);
// function flows into its own v1 variable
flowgraph.addEdge(fnVertex, factory.makeVarVertex(fnVertex, 1));
// flow parameters into local variables
for(int i=1;i<fn.getNumberOfParameters();++i)
flowgraph.addEdge(factory.makeParamVertex(fnVertex, i), factory.makeVarVertex(fnVertex, i+1));
// flow function into result variable
flowgraph.addEdge(fnVertex, factory.makeVarVertex(func, invk.getDef()));
} else if (supportFullPointerAnalysis) {
CreationSiteVertex cs = factory.makeCreationSiteVertex(method, invk.iindex);
// flow creation site into result of new call
flowgraph.addEdge(cs, factory.makeVarVertex(func, invk.getDef()));
// also passed as 'this' to constructor
if (invk.getNumberOfParameters() > 1) {
flowgraph.addEdge(cs, factory.makeVarVertex(func, invk.getUse(0)));
}
}
} else {
// check whether it is a method call
if(invk.getDeclaredTarget().equals(JavaScriptMethods.dispatchReference)) {
@ -386,5 +404,17 @@ public class FlowGraphBuilder {
}
handleLexicalDef(invk.getDef());
}
@Override
public void visitNew(SSANewInstruction invk) {
if (supportFullPointerAnalysis) {
// special case for supporting full pointer analysis
// some core objects in the prologue (and the arguments array objects) get created with 'new'
CreationSiteVertex cs = factory.makeCreationSiteVertex(method, invk.iindex);
// flow creation site into result of new call
flowgraph.addEdge(cs, factory.makeVarVertex(func, invk.getDef()));
}
}
}
}

View File

@ -40,6 +40,11 @@ public class AbstractVertexVisitor<T> implements VertexVisitor<T> {
return visitVertex(funcVertex);
}
@Override
public T visitCreationSiteVertex(CreationSiteVertex csVertex) {
return visitVertex(csVertex);
}
@Override
public T visitParamVertex(ParamVertex paramVertex) {
return visitVertex(paramVertex);

View File

@ -0,0 +1,48 @@
package com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices;
import java.util.Iterator;
import com.ibm.wala.cast.js.types.JavaScriptTypes;
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.CallGraph;
import com.ibm.wala.ipa.callgraph.impl.Everywhere;
import com.ibm.wala.ssa.SSAInstruction;
import com.ibm.wala.ssa.SSANewInstruction;
import com.ibm.wala.types.TypeReference;
import com.ibm.wala.util.collections.NonNullSingletonIterator;
import com.ibm.wala.util.collections.Pair;
public class CreationSiteVertex extends Vertex implements ObjectVertex {
private final IMethod node;
private final int instructionIndex;
public CreationSiteVertex(IMethod node, int instructionIndex) {
super();
this.node = node;
this.instructionIndex = instructionIndex;
}
@Override
public IClass getConcreteType() {
return node.getClassHierarchy().lookupClass(JavaScriptTypes.Object);
}
@Override
public Iterator<Pair<CGNode, NewSiteReference>> getCreationSites(CallGraph CG) {
CGNode cgn = CG.getNode(node, Everywhere.EVERYWHERE);
assert cgn != null : node;
SSAInstruction inst = cgn.getIR().getInstructions()[instructionIndex];
TypeReference type = inst instanceof SSANewInstruction? ((SSANewInstruction)inst).getConcreteType(): JavaScriptTypes.Object;
return NonNullSingletonIterator.make(Pair.make(cgn, NewSiteReference.make(instructionIndex, type)));
}
@Override
public <T> T accept(VertexVisitor<T> visitor) {
return visitor.visitCreationSiteVertex(this);
}
}

View File

@ -11,13 +11,20 @@
package com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices;
import java.util.Iterator;
import java.util.Set;
import com.ibm.wala.cast.js.ipa.summaries.JavaScriptConstructorFunctions.JavaScriptConstructor;
import com.ibm.wala.cast.js.types.JavaScriptMethods;
import com.ibm.wala.cast.js.types.JavaScriptTypes;
import com.ibm.wala.classLoader.CallSiteReference;
import com.ibm.wala.classLoader.IClass;
import com.ibm.wala.classLoader.NewSiteReference;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.callgraph.CallGraph;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
import com.ibm.wala.types.MethodReference;
import com.ibm.wala.util.collections.NonNullSingletonIterator;
import com.ibm.wala.util.collections.Pair;
import com.sun.xml.internal.fastinfoset.stax.events.EmptyIterator;
/**
* A function vertex represents a function object (or, more precisely, all function objects
@ -25,19 +32,14 @@ import com.ibm.wala.util.collections.Pair;
*
* @author mschaefer
*/
public class FuncVertex extends Vertex implements InstanceKey {
public class FuncVertex extends Vertex implements ObjectVertex {
// the IClass representing this function in the class hierarchy
private final IClass klass;
protected final IClass klass;
FuncVertex(IClass method) {
this.klass = method;
}
@Override
public IClass getConcreteType() {
return klass;
}
public String getFullName() {
return klass.getName().toString();
}
@ -55,7 +57,35 @@ public class FuncVertex extends Vertex implements InstanceKey {
@Override
public Iterator<Pair<CGNode, NewSiteReference>> getCreationSites(CallGraph CG) {
assert false;
return null;
MethodReference ctorRef = JavaScriptMethods.makeCtorReference(JavaScriptTypes.Function);
Set<CGNode> f = CG.getNodes(ctorRef);
CGNode ctor = null;
for(CGNode n : f) {
JavaScriptConstructor c = (JavaScriptConstructor) n.getMethod();
if (c.constructedType().equals(klass)) {
ctor = n;
break;
}
}
// built in objects
if (ctor == null) {
return EmptyIterator.getInstance();
}
Iterator<CGNode> callers = CG.getPredNodes(ctor);
CGNode caller = callers.next();
assert !callers.hasNext();
Iterator<CallSiteReference> sites = CG.getPossibleSites(caller, ctor);
CallSiteReference site = sites.next();
assert !sites.hasNext();
return NonNullSingletonIterator.make(Pair.make(caller, NewSiteReference.make(site.getProgramCounter(), klass.getReference())));
}
@Override
public IClass getConcreteType() {
return klass;
}
}

View File

@ -0,0 +1,7 @@
package com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
public interface ObjectVertex extends InstanceKey {
}

View File

@ -16,6 +16,8 @@ import java.util.Map;
import com.ibm.wala.cast.js.ssa.JavaScriptInvoke;
import com.ibm.wala.classLoader.CallSiteReference;
import com.ibm.wala.classLoader.IClass;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.types.TypeReference;
import com.ibm.wala.util.collections.HashMapFactory;
import com.ibm.wala.util.collections.Pair;
@ -35,7 +37,8 @@ public class VertexFactory {
private final Map<FuncVertex, ArgVertex> argVertexCache = HashMapFactory.make();
private final Map<Pair<FuncVertex, Integer>, VarVertex> varVertexCache = HashMapFactory.make();
private final Map<Pair<String, String>, LexicalVarVertex> lexicalAccessVertexCache = HashMapFactory.make();
private final Map<Pair<IMethod,Integer>, CreationSiteVertex> creationSites = HashMapFactory.make();
public CallVertex makeCallVertex(FuncVertex func, JavaScriptInvoke invk) {
CallSiteReference site = invk.getCallSite();
Pair<FuncVertex, CallSiteReference> key = Pair.make(func, site);
@ -49,13 +52,26 @@ public class VertexFactory {
return callVertexCache.values();
}
public CreationSiteVertex makeCreationSiteVertex(IMethod method, int instruction) {
Pair<IMethod, Integer> key = Pair.make(method, instruction);
CreationSiteVertex value = creationSites.get(key);
if (value == null) {
creationSites.put(key, value = new CreationSiteVertex(method, instruction));
}
return value;
}
public Collection<CreationSiteVertex> creationSites() {
return creationSites.values();
}
public FuncVertex makeFuncVertex(IClass klass) {
FuncVertex value = funcVertexCache.get(klass);
if(value == null)
funcVertexCache.put(klass, value = new FuncVertex(klass));
return value;
}
public Collection<FuncVertex> getFuncVertices() {
return funcVertexCache.values();
}

View File

@ -16,6 +16,7 @@ public interface VertexVisitor<T> {
public abstract T visitPropVertex(PropVertex propVertex);
public abstract T visitUnknownVertex(UnknownVertex unknownVertex);
public abstract T visitFuncVertex(FuncVertex funcVertex);
public abstract T visitCreationSiteVertex(CreationSiteVertex csVertex);
public abstract T visitParamVertex(ParamVertex paramVertex);
public abstract T visitRetVertex(RetVertex retVertex);
public abstract T visitCalleeVertex(CallVertex calleeVertex);

View File

@ -111,7 +111,6 @@ import com.ibm.wala.ssa.IR;
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
import com.ibm.wala.ssa.SSAArrayStoreInstruction;
import com.ibm.wala.ssa.SSAInstruction;
import com.ibm.wala.ssa.SSAInvokeInstruction;
import com.ibm.wala.ssa.SSANewInstruction;
import com.ibm.wala.ssa.SSAPutInstruction;
import com.ibm.wala.util.Predicate;
@ -1375,7 +1374,7 @@ public class DemandRefinementPointsTo extends AbstractDemandPointsTo {
}
}
SSAInvokeInstruction callInstr = g.getInstrReturningTo(localPk);
SSAAbstractInvokeInstruction callInstr = g.getInstrReturningTo(localPk);
if (callInstr != null) {
CGNode caller = localPk.getNode();
boolean isExceptional = localPk.getValueNumber() == callInstr.getException();
@ -1669,8 +1668,8 @@ public class DemandRefinementPointsTo extends AbstractDemandPointsTo {
LocalPointerKey localPk = (LocalPointerKey) curPk;
CGNode caller = localPk.getNode();
// from actual parameter to callee
for (Iterator<SSAInvokeInstruction> iter = g.getInstrsPassingParam(localPk); iter.hasNext();) {
SSAInvokeInstruction callInstr = iter.next();
for (Iterator<SSAAbstractInvokeInstruction> iter = g.getInstrsPassingParam(localPk); iter.hasNext();) {
SSAAbstractInvokeInstruction callInstr = iter.next();
for (int i = 0; i < callInstr.getNumberOfUses(); i++) {
if (localPk.getValueNumber() != callInstr.getUse(i))
continue;
@ -2162,7 +2161,7 @@ public class DemandRefinementPointsTo extends AbstractDemandPointsTo {
}
}
SSAInvokeInstruction callInstr = g.getInstrReturningTo(localPk);
SSAAbstractInvokeInstruction callInstr = g.getInstrReturningTo(localPk);
if (callInstr != null) {
CGNode caller = localPk.getNode();
boolean isExceptional = localPk.getValueNumber() == callInstr.getException();

View File

@ -154,12 +154,12 @@ public abstract class AbstractDemandFlowGraph extends AbstractFlowGraph {
*/
public Iterator<PointerKeyAndCallSite> getParamPreds(LocalPointerKey pk) {
// TODO
Set<SSAInvokeInstruction> instrs = callParams.get(pk);
Set<SSAAbstractInvokeInstruction> instrs = callParams.get(pk);
if (instrs == null) {
return EmptyIterator.instance();
}
ArrayList<PointerKeyAndCallSite> paramPreds = new ArrayList<PointerKeyAndCallSite>();
for (SSAInvokeInstruction callInstr : instrs) {
for (SSAAbstractInvokeInstruction callInstr : instrs) {
for (int i = 0; i < callInstr.getNumberOfUses(); i++) {
if (pk.getValueNumber() != callInstr.getUse(i))
continue;
@ -185,7 +185,7 @@ public abstract class AbstractDemandFlowGraph extends AbstractFlowGraph {
* @see com.ibm.wala.demandpa.flowgraph.IFlowGraph#getReturnSuccs(com.ibm.wala.ipa.callgraph.propagation.LocalPointerKey)
*/
public Iterator<PointerKeyAndCallSite> getReturnSuccs(LocalPointerKey pk) {
SSAInvokeInstruction callInstr = callDefs.get(pk);
SSAAbstractInvokeInstruction callInstr = callDefs.get(pk);
if (callInstr == null)
return EmptyIterator.instance();
ArrayList<PointerKeyAndCallSite> returnSuccs = new ArrayList<PointerKeyAndCallSite>();

View File

@ -75,7 +75,6 @@ import com.ibm.wala.ssa.SSAArrayLoadInstruction;
import com.ibm.wala.ssa.SSAArrayStoreInstruction;
import com.ibm.wala.ssa.SSAGetInstruction;
import com.ibm.wala.ssa.SSAInstruction;
import com.ibm.wala.ssa.SSAInvokeInstruction;
import com.ibm.wala.ssa.SSANewInstruction;
import com.ibm.wala.ssa.SSAPutInstruction;
import com.ibm.wala.ssa.SymbolTable;
@ -116,13 +115,13 @@ public abstract class AbstractFlowGraph extends SlowSparseNumberedLabeledGraph<O
* Map: LocalPointerKey -> SSAInvokeInstruction. If we have (x, foo()), that means that x was def'fed by the return value from the
* call to foo()
*/
protected final Map<PointerKey, SSAInvokeInstruction> callDefs = HashMapFactory.make();
protected final Map<PointerKey, SSAAbstractInvokeInstruction> callDefs = HashMapFactory.make();
/**
* Map: {@link LocalPointerKey} -> Set<{@link SSAInvokeInstruction}>. If we have (x, foo()), that means x was passed as a
* parameter to the call to foo(). The parameter position is not represented and must be recovered.
*/
protected final Map<PointerKey, Set<SSAInvokeInstruction>> callParams = HashMapFactory.make();
protected final Map<PointerKey, Set<SSAAbstractInvokeInstruction>> callParams = HashMapFactory.make();
/**
* Map: LocalPointerKey -> CGNode. If we have (x, foo), then x is a parameter of method foo. For now, we have to re-discover the
@ -196,8 +195,8 @@ public abstract class AbstractFlowGraph extends SlowSparseNumberedLabeledGraph<O
// from the callee
PointerKey use = heapModel.getPointerKeyForLocal(node, invokeInstr.getUse(i));
addNode(use);
Set<SSAInvokeInstruction> s = MapUtil.findOrCreateSet(callParams, use);
s.add((SSAInvokeInstruction) invokeInstr);
Set<SSAAbstractInvokeInstruction> s = MapUtil.findOrCreateSet(callParams, use);
s.add(invokeInstr);
}
// for any def'd values, keep track of the fact that they are def'd
@ -205,11 +204,11 @@ public abstract class AbstractFlowGraph extends SlowSparseNumberedLabeledGraph<O
if (invokeInstr.hasDef()) {
PointerKey def = heapModel.getPointerKeyForLocal(node, invokeInstr.getDef());
addNode(def);
callDefs.put(def, (SSAInvokeInstruction) invokeInstr);
callDefs.put(def, invokeInstr);
}
PointerKey exc = heapModel.getPointerKeyForLocal(node, invokeInstr.getException());
addNode(exc);
callDefs.put(exc, (SSAInvokeInstruction) invokeInstr);
callDefs.put(exc, invokeInstr);
}
}
@ -221,8 +220,8 @@ public abstract class AbstractFlowGraph extends SlowSparseNumberedLabeledGraph<O
}
@Override
public Iterator<SSAInvokeInstruction> getInstrsPassingParam(LocalPointerKey pk) {
Set<SSAInvokeInstruction> instrs = callParams.get(pk);
public Iterator<SSAAbstractInvokeInstruction> getInstrsPassingParam(LocalPointerKey pk) {
Set<SSAAbstractInvokeInstruction> instrs = callParams.get(pk);
if (instrs == null) {
return EmptyIterator.instance();
} else {
@ -231,7 +230,7 @@ public abstract class AbstractFlowGraph extends SlowSparseNumberedLabeledGraph<O
}
@Override
public SSAInvokeInstruction getInstrReturningTo(LocalPointerKey pk) {
public SSAAbstractInvokeInstruction getInstrReturningTo(LocalPointerKey pk) {
return callDefs.get(pk);
}

View File

@ -56,6 +56,7 @@ import com.ibm.wala.ipa.callgraph.propagation.SSAPropagationCallGraphBuilder;
import com.ibm.wala.ipa.cha.ClassHierarchy;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
import com.ibm.wala.ssa.SSAArrayLengthInstruction;
import com.ibm.wala.ssa.SSAArrayLoadInstruction;
import com.ibm.wala.ssa.SSAArrayStoreInstruction;
@ -297,7 +298,7 @@ public class DemandValueFlowGraph extends AbstractDemandFlowGraph {
// from the callee
PointerKey use = heapModel.getPointerKeyForLocal(node, instruction.getUse(i));
addNode(use);
Set<SSAInvokeInstruction> s = MapUtil.findOrCreateSet(callParams, use);
Set<SSAAbstractInvokeInstruction> s = MapUtil.findOrCreateSet(callParams, use);
s.add(instruction);
}

View File

@ -21,7 +21,7 @@ import com.ibm.wala.ipa.callgraph.propagation.LocalPointerKey;
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
import com.ibm.wala.ipa.callgraph.propagation.StaticFieldKey;
import com.ibm.wala.ipa.callgraph.propagation.cfa.CallerSiteContext;
import com.ibm.wala.ssa.SSAInvokeInstruction;
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
import com.ibm.wala.util.graph.labeled.LabeledGraph;
public interface IFlowGraph extends LabeledGraph<Object, IFlowLabel> {
@ -55,14 +55,14 @@ public interface IFlowGraph extends LabeledGraph<Object, IFlowLabel> {
* @param pk
* @return the {@link SSAInvokeInstruction}s passing some pointer as a parameter
*/
public abstract Iterator<SSAInvokeInstruction> getInstrsPassingParam(LocalPointerKey pk);
public abstract Iterator<SSAAbstractInvokeInstruction> getInstrsPassingParam(LocalPointerKey pk);
/**
* get the {@link SSAInvokeInstruction} whose return value is assigned to a pointer key.
*
* @return the instruction, or <code>null</code> if no return value is assigned to pk
*/
public abstract SSAInvokeInstruction getInstrReturningTo(LocalPointerKey pk);
public abstract SSAAbstractInvokeInstruction getInstrReturningTo(LocalPointerKey pk);
/**
* @param sfk the static field

View File

@ -11,10 +11,8 @@
package com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph;
import com.ibm.wala.cast.js.ipa.summaries.JavaScriptConstructorFunctions;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.ipa.callgraph.AnalysisCache;
import com.ibm.wala.ipa.callgraph.MethodTargetSelector;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.util.functions.Function;
@ -22,8 +20,8 @@ public class FilteredFlowGraphBuilder extends FlowGraphBuilder {
private final Function<IMethod, Boolean> filter;
public FilteredFlowGraphBuilder(IClassHierarchy cha, AnalysisCache cache, JavaScriptConstructorFunctions selector, Function<IMethod, Boolean> filter) {
super(cha, cache, selector);
public FilteredFlowGraphBuilder(IClassHierarchy cha, AnalysisCache cache, boolean fullPointerAnalysis, Function<IMethod, Boolean> filter) {
super(cha, cache, fullPointerAnalysis);
this.filter = filter;
}

View File

@ -27,12 +27,12 @@ import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.FilteredFlowGraphBuil
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.FlowGraph;
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.FlowGraphBuilder;
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.FuncVertex;
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.ObjectVertex;
import com.ibm.wala.cast.js.client.impl.ZeroCFABuilderFactory;
import com.ibm.wala.cast.js.html.IncludedPosition;
import com.ibm.wala.cast.js.ipa.callgraph.JSAnalysisOptions;
import com.ibm.wala.cast.js.ipa.callgraph.JSCallGraph;
import com.ibm.wala.cast.js.ipa.callgraph.JSCallGraphUtil;
import com.ibm.wala.cast.js.ipa.summaries.JavaScriptConstructorFunctions;
import com.ibm.wala.cast.js.loader.JavaScriptLoader;
import com.ibm.wala.cast.js.loader.JavaScriptLoaderFactory;
import com.ibm.wala.cast.js.translator.CAstRhinoTranslatorFactory;
@ -48,7 +48,6 @@ import com.ibm.wala.ipa.callgraph.AnalysisOptions;
import com.ibm.wala.ipa.callgraph.AnalysisScope;
import com.ibm.wala.ipa.callgraph.CallGraphBuilder;
import com.ibm.wala.ipa.callgraph.Entrypoint;
import com.ibm.wala.ipa.callgraph.MethodTargetSelector;
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.types.ClassLoaderReference;
@ -118,11 +117,11 @@ public class EclipseJavaScriptAnalysisEngine extends EclipseProjectSourceAnalysi
return new ZeroCFABuilderFactory().make((JSAnalysisOptions)options, cache, cha, scope, false);
}
public Pair<JSCallGraph, PointerAnalysis<FuncVertex>> getFieldBasedCallGraph() throws CancelException {
public Pair<JSCallGraph, PointerAnalysis<ObjectVertex>> getFieldBasedCallGraph() throws CancelException {
return getFieldBasedCallGraph(JSCallGraphUtil.makeScriptRoots(getClassHierarchy()));
}
public Pair<JSCallGraph, PointerAnalysis<FuncVertex>> getFieldBasedCallGraph(String scriptName) throws CancelException {
public Pair<JSCallGraph, PointerAnalysis<ObjectVertex>> getFieldBasedCallGraph(String scriptName) throws CancelException {
Set<Entrypoint> eps= HashSetFactory.make();
eps.add(JSCallGraphUtil.makeScriptRoots(getClassHierarchy()).make(scriptName));
eps.add(JSCallGraphUtil.makeScriptRoots(getClassHierarchy()).make("Lprologue.js"));
@ -141,7 +140,7 @@ public class EclipseJavaScriptAnalysisEngine extends EclipseProjectSourceAnalysi
return fileName.substring(fileName.lastIndexOf('/') + 1);
}
protected Pair<JSCallGraph, PointerAnalysis<FuncVertex>> getFieldBasedCallGraph(Iterable<Entrypoint> roots) throws CancelException {
protected Pair<JSCallGraph, PointerAnalysis<ObjectVertex>> getFieldBasedCallGraph(Iterable<Entrypoint> roots) throws CancelException {
final Set<String> scripts = HashSetFactory.make();
for(Entrypoint e : roots) {
String scriptName = getScriptName(((AstMethod)e.getMethod()));
@ -168,8 +167,8 @@ public class EclipseJavaScriptAnalysisEngine extends EclipseProjectSourceAnalysi
builderType.equals(BuilderType.PESSIMISTIC)?
new PessimisticCallGraphBuilder(getClassHierarchy(), options, makeDefaultCache()) {
@Override
protected FlowGraph flowGraphFactory(JavaScriptConstructorFunctions selector) {
FlowGraphBuilder b = new FilteredFlowGraphBuilder(cha, cache, selector, filter);
protected FlowGraph flowGraphFactory() {
FlowGraphBuilder b = new FilteredFlowGraphBuilder(cha, cache, true, filter);
return b.buildFlowGraph();
}
@Override
@ -179,8 +178,8 @@ public class EclipseJavaScriptAnalysisEngine extends EclipseProjectSourceAnalysi
}
: new OptimisticCallgraphBuilder(getClassHierarchy(), options, makeDefaultCache()) {
@Override
protected FlowGraph flowGraphFactory(JavaScriptConstructorFunctions selector) {
FlowGraphBuilder b = new FilteredFlowGraphBuilder(cha, cache, selector, filter);
protected FlowGraph flowGraphFactory() {
FlowGraphBuilder b = new FilteredFlowGraphBuilder(cha, cache, true, filter);
return b.buildFlowGraph();
}
};

View File

@ -11,8 +11,7 @@ import org.eclipse.wst.jsdt.core.IJavaScriptProject;
import com.ibm.wala.cast.ipa.callgraph.CAstAnalysisScope;
import com.ibm.wala.cast.js.JavaScriptPlugin;
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.FlowGraph;
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.FuncVertex;
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.ObjectVertex;
import com.ibm.wala.cast.js.html.WebPageLoaderFactory;
import com.ibm.wala.cast.js.ipa.callgraph.JSCallGraph;
import com.ibm.wala.cast.js.ipa.callgraph.JSCallGraphUtil;
@ -22,7 +21,6 @@ import com.ibm.wala.classLoader.ClassLoaderFactory;
import com.ibm.wala.ide.util.EclipseWebProjectPath;
import com.ibm.wala.ide.util.JavaScriptEclipseProjectPath;
import com.ibm.wala.ipa.callgraph.AnalysisScope;
import com.ibm.wala.ipa.callgraph.CallGraph;
import com.ibm.wala.ipa.callgraph.Entrypoint;
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
import com.ibm.wala.util.CancelException;
@ -57,7 +55,7 @@ public class EclipseWebAnalysisEngine extends EclipseJavaScriptAnalysisEngine {
}
@Override
public Pair<JSCallGraph, PointerAnalysis<FuncVertex>> getFieldBasedCallGraph(String scriptName) throws CancelException {
public Pair<JSCallGraph, PointerAnalysis<ObjectVertex>> getFieldBasedCallGraph(String scriptName) throws CancelException {
Set<Entrypoint> eps= HashSetFactory.make();
eps.add(JSCallGraphUtil.makeScriptRoots(getClassHierarchy()).make(scriptName));
eps.add(JSCallGraphUtil.makeScriptRoots(getClassHierarchy()).make("Lprologue.js"));

View File

@ -98,7 +98,7 @@ public abstract class DataflowSolver<T, V extends IVariable<?>> extends DefaultF
public V getOut(Object node) {
assert node != null;
V v = node2Out.get(node);
assert v != null;
assert v != null : "no out set for " + node;
return v;
}

View File

@ -36,7 +36,7 @@ import com.ibm.wala.util.intset.OrdinalSetMapping;
/**
* A dataflow system that computes, for each graph node, the set of "interesting" nodes that are reachable
*/
public class GraphReachability<T, S extends T> {
public class GraphReachability<T, S> {
/**
* Governing graph