work toward pointer analysis based on the flowgraph from field-based
call graph builder
This commit is contained in:
parent
019425c0e2
commit
1bb7610011
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
|
@ -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) {
|
|
@ -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),
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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>();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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"));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue