2013-05-22 23:04:25 +00:00
|
|
|
/******************************************************************************
|
|
|
|
* Copyright (c) 2002 - 2012 IBM Corporation.
|
|
|
|
* All rights reserved. This program and the accompanying materials
|
|
|
|
* are made available under the terms of the Eclipse Public License v1.0
|
|
|
|
* which accompanies this distribution, and is available at
|
|
|
|
* http://www.eclipse.org/legal/epl-v10.html
|
|
|
|
*
|
|
|
|
* Contributors:
|
|
|
|
* IBM Corporation - initial API and implementation
|
|
|
|
*****************************************************************************/
|
2014-10-20 02:44:03 +00:00
|
|
|
package com.ibm.wala.cast.js.test;
|
2013-05-22 23:04:25 +00:00
|
|
|
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.net.URL;
|
|
|
|
import java.util.Collections;
|
|
|
|
import java.util.Map;
|
|
|
|
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.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;
|
2014-10-20 02:44:03 +00:00
|
|
|
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.ObjectVertex;
|
2015-12-01 02:28:40 +00:00
|
|
|
import com.ibm.wala.cast.js.html.JSSourceExtractor;
|
2013-05-22 23:04:25 +00:00
|
|
|
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.translator.JavaScriptTranslatorFactory;
|
|
|
|
import com.ibm.wala.cast.js.util.Util;
|
2017-02-03 01:33:27 +00:00
|
|
|
import com.ibm.wala.classLoader.Module;
|
2013-05-22 23:04:25 +00:00
|
|
|
import com.ibm.wala.classLoader.SourceModule;
|
|
|
|
import com.ibm.wala.classLoader.SourceURLModule;
|
2017-02-03 01:33:27 +00:00
|
|
|
import com.ibm.wala.ipa.callgraph.AnalysisCacheImpl;
|
2013-05-22 23:04:25 +00:00
|
|
|
import com.ibm.wala.ipa.callgraph.Entrypoint;
|
2017-03-16 02:06:19 +00:00
|
|
|
import com.ibm.wala.ipa.callgraph.IAnalysisCacheView;
|
2014-10-20 02:44:03 +00:00
|
|
|
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
|
2017-01-12 21:34:54 +00:00
|
|
|
import com.ibm.wala.ipa.cha.ClassHierarchyFactory;
|
2013-05-22 23:04:25 +00:00
|
|
|
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
|
|
|
import com.ibm.wala.util.CancelException;
|
2014-02-09 02:36:56 +00:00
|
|
|
import com.ibm.wala.util.MonitorUtil.IProgressMonitor;
|
2013-05-22 23:04:25 +00:00
|
|
|
import com.ibm.wala.util.NullProgressMonitor;
|
|
|
|
import com.ibm.wala.util.WalaException;
|
2014-10-20 02:44:03 +00:00
|
|
|
import com.ibm.wala.util.collections.Pair;
|
2015-12-01 02:28:40 +00:00
|
|
|
import com.ibm.wala.util.functions.Function;
|
2013-05-22 23:04:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Utility class for building call graphs.
|
|
|
|
*
|
|
|
|
* @author mschaefer
|
|
|
|
*
|
|
|
|
*/
|
2014-10-20 02:44:03 +00:00
|
|
|
public class FieldBasedCGUtil {
|
2017-07-12 23:54:57 +00:00
|
|
|
public static enum BuilderType { PESSIMISTIC, OPTIMISTIC, OPTIMISTIC_WORKLIST }
|
2013-05-22 23:04:25 +00:00
|
|
|
|
|
|
|
private final JavaScriptTranslatorFactory translatorFactory;
|
|
|
|
|
2014-10-20 02:44:03 +00:00
|
|
|
public FieldBasedCGUtil(JavaScriptTranslatorFactory translatorFactory) {
|
2013-05-22 23:04:25 +00:00
|
|
|
this.translatorFactory = translatorFactory;
|
|
|
|
}
|
|
|
|
|
2017-07-27 21:53:07 +00:00
|
|
|
public Pair<JSCallGraph, PointerAnalysis<ObjectVertex>> buildCG(URL url, BuilderType builderType, boolean supportFullPointerAnalysis, Function<Void, JSSourceExtractor> fExtractor) throws WalaException, CancelException {
|
2015-12-01 02:28:40 +00:00
|
|
|
return buildCG(url, builderType, new NullProgressMonitor(), supportFullPointerAnalysis, fExtractor);
|
2014-02-09 02:36:56 +00:00
|
|
|
}
|
2014-10-28 20:09:32 +00:00
|
|
|
|
2017-07-27 21:53:07 +00:00
|
|
|
public Pair<JSCallGraph, PointerAnalysis<ObjectVertex>> buildCG(URL url, BuilderType builderType, IProgressMonitor monitor, boolean supportFullPointerAnalysis, Function<Void, JSSourceExtractor> fExtractor) throws WalaException, CancelException {
|
2013-08-07 19:17:02 +00:00
|
|
|
if (url.getFile().endsWith(".js")) {
|
2014-10-28 20:09:32 +00:00
|
|
|
return buildScriptCG(url, builderType, monitor, supportFullPointerAnalysis);
|
|
|
|
} else {
|
2015-12-01 02:28:40 +00:00
|
|
|
return buildPageCG(url, builderType, monitor, supportFullPointerAnalysis, fExtractor);
|
2014-10-28 20:09:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-27 21:53:07 +00:00
|
|
|
public Pair<JSCallGraph, PointerAnalysis<ObjectVertex>> buildScriptCG(URL url, BuilderType builderType, IProgressMonitor monitor, boolean supportFullPointerAnalysis) throws WalaException, CancelException {
|
2014-10-28 20:09:32 +00:00
|
|
|
JavaScriptLoaderFactory loaders = new JavaScriptLoaderFactory(translatorFactory);
|
2017-02-03 01:33:27 +00:00
|
|
|
Module[] scripts = new Module[]{
|
2014-10-28 20:09:32 +00:00
|
|
|
new SourceURLModule(url),
|
2017-05-11 16:23:27 +00:00
|
|
|
JSCallGraphUtil.getPrologueFile("prologue.js")
|
2014-10-28 20:09:32 +00:00
|
|
|
};
|
|
|
|
return buildCG(loaders, scripts, builderType, monitor, supportFullPointerAnalysis);
|
|
|
|
}
|
|
|
|
|
|
|
|
public Pair<JSCallGraph, PointerAnalysis<ObjectVertex>> buildTestCG(String dir, String name, BuilderType builderType, IProgressMonitor monitor, boolean supportFullPointerAnalysis) throws IOException, WalaException, CancelException {
|
|
|
|
JavaScriptLoaderFactory loaders = new JavaScriptLoaderFactory(translatorFactory);
|
2017-02-03 01:33:27 +00:00
|
|
|
Module[] scripts = JSCallGraphBuilderUtil.makeSourceModules(dir, name);
|
2014-10-28 20:09:32 +00:00
|
|
|
return buildCG(loaders, scripts, builderType, monitor, supportFullPointerAnalysis);
|
|
|
|
}
|
|
|
|
|
2017-07-27 21:53:07 +00:00
|
|
|
public Pair<JSCallGraph, PointerAnalysis<ObjectVertex>> buildPageCG(URL url, BuilderType builderType, IProgressMonitor monitor, boolean supportFullPointerAnalysis, Function<Void, JSSourceExtractor> fExtractor) throws WalaException, CancelException {
|
2014-10-28 20:09:32 +00:00
|
|
|
JavaScriptLoaderFactory loaders = new WebPageLoaderFactory(translatorFactory);
|
2015-12-01 02:28:40 +00:00
|
|
|
SourceModule[] scripts = JSCallGraphBuilderUtil.makeHtmlScope(url, loaders, fExtractor);
|
2014-10-28 20:09:32 +00:00
|
|
|
return buildCG(loaders, scripts, builderType, monitor, supportFullPointerAnalysis);
|
|
|
|
}
|
|
|
|
|
2017-07-27 21:53:07 +00:00
|
|
|
public Pair<JSCallGraph, PointerAnalysis<ObjectVertex>> buildCG(JavaScriptLoaderFactory loaders, Module[] scripts, BuilderType builderType, IProgressMonitor monitor, boolean supportFullPointerAnalysis) throws WalaException, CancelException {
|
2013-05-22 23:04:25 +00:00
|
|
|
CAstAnalysisScope scope = new CAstAnalysisScope(scripts, loaders, Collections.singleton(JavaScriptLoader.JS));
|
2017-01-12 21:34:54 +00:00
|
|
|
IClassHierarchy cha = ClassHierarchyFactory.make(scope, loaders, JavaScriptLoader.JS);
|
2013-05-22 23:04:25 +00:00
|
|
|
Util.checkForFrontEndErrors(cha);
|
|
|
|
Iterable<Entrypoint> roots = JSCallGraphUtil.makeScriptRoots(cha);
|
|
|
|
FieldBasedCallGraphBuilder builder = null;
|
|
|
|
|
2017-03-16 02:06:19 +00:00
|
|
|
IAnalysisCacheView cache = new AnalysisCacheImpl(AstIRFactory.makeDefaultFactory());
|
2013-05-22 23:04:25 +00:00
|
|
|
switch(builderType) {
|
|
|
|
case PESSIMISTIC:
|
2014-10-20 02:44:03 +00:00
|
|
|
builder = new PessimisticCallGraphBuilder(cha, JSCallGraphUtil.makeOptions(scope, cha, roots), cache, supportFullPointerAnalysis);
|
2013-05-22 23:04:25 +00:00
|
|
|
break;
|
|
|
|
case OPTIMISTIC:
|
2014-10-20 02:44:03 +00:00
|
|
|
builder = new OptimisticCallgraphBuilder(cha, JSCallGraphUtil.makeOptions(scope, cha, roots), cache, supportFullPointerAnalysis);
|
2013-05-22 23:04:25 +00:00
|
|
|
break;
|
|
|
|
case OPTIMISTIC_WORKLIST:
|
2014-10-20 02:44:03 +00:00
|
|
|
builder = new WorklistBasedOptimisticCallgraphBuilder(cha, JSCallGraphUtil.makeOptions(scope, cha, roots), cache, supportFullPointerAnalysis);
|
2013-05-22 23:04:25 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2014-10-20 02:44:03 +00:00
|
|
|
return builder.buildCallGraph(roots, monitor);
|
2013-05-22 23:04:25 +00:00
|
|
|
}
|
|
|
|
|
2015-04-06 01:46:31 +00:00
|
|
|
/*
|
2013-05-22 23:04:25 +00:00
|
|
|
private JavaScriptLoaderFactory makeLoaderFactory(URL url) {
|
|
|
|
return url.getFile().endsWith(".js") ? new JavaScriptLoaderFactory(translatorFactory) : new WebPageLoaderFactory(translatorFactory);
|
|
|
|
}
|
2015-04-06 01:46:31 +00:00
|
|
|
*/
|
2013-05-22 23:04:25 +00:00
|
|
|
|
|
|
|
@SuppressWarnings("unused")
|
|
|
|
private static void compareCGs(Map<String, Set<String>> cg1, Map<String, Set<String>> cg2) {
|
|
|
|
boolean diff = false;
|
|
|
|
for(String key : cg1.keySet()) {
|
|
|
|
Set<String> targets1 = cg1.get(key), targets2 = cg2.get(key);
|
|
|
|
if(targets2 == null) {
|
|
|
|
diff = true;
|
|
|
|
System.err.println("CG2 doesn't have call site" + key);
|
|
|
|
} else {
|
|
|
|
for(String target : targets1)
|
|
|
|
if(!targets2.contains(target)) {
|
|
|
|
diff = true;
|
|
|
|
System.err.println("CG2 doesn't have edge " + key + " -> " + target);
|
|
|
|
}
|
|
|
|
for(String target : targets2)
|
|
|
|
if(!targets1.contains(target)) {
|
|
|
|
diff = true;
|
|
|
|
System.err.println("CG1 doesn't have edge " + key + " -> " + target);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for(String key : cg2.keySet()) {
|
|
|
|
if(!cg1.containsKey(key)) {
|
|
|
|
diff = true;
|
|
|
|
System.err.println("CG1 doesn't have call site " + key);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(!diff)
|
|
|
|
System.err.println("call graphs are identical");
|
|
|
|
}
|
|
|
|
}
|