hybrid example

This commit is contained in:
Julian Dolby 2015-04-05 23:02:20 -04:00
parent f6a6398b02
commit 5da3cd7df7
4 changed files with 343 additions and 0 deletions

View File

@ -0,0 +1,90 @@
package com.ibm.wala.cast.js.examples.hybrid;
import java.io.IOException;
import java.net.URL;
import java.util.Map;
import com.ibm.wala.cast.ipa.callgraph.CrossLanguageMethodTargetSelector;
import com.ibm.wala.cast.ipa.callgraph.StandardFunctionTargetSelector;
import com.ibm.wala.cast.ipa.cha.CrossLanguageClassHierarchy;
import com.ibm.wala.cast.ir.ssa.AstIRFactory;
import com.ibm.wala.cast.js.ipa.callgraph.JSCallGraphUtil;
import com.ibm.wala.cast.js.ipa.callgraph.JavaScriptConstructTargetSelector;
import com.ibm.wala.cast.js.ipa.callgraph.JavaScriptEntryPoints;
import com.ibm.wala.cast.js.loader.JavaScriptLoader;
import com.ibm.wala.cast.js.test.JSCallGraphBuilderUtil;
import com.ibm.wala.cast.js.translator.CAstRhinoTranslatorFactory;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.classLoader.Language;
import com.ibm.wala.classLoader.SourceURLModule;
import com.ibm.wala.ipa.callgraph.AnalysisCache;
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
import com.ibm.wala.ipa.callgraph.AnalysisScope;
import com.ibm.wala.ipa.callgraph.Entrypoint;
import com.ibm.wala.ipa.callgraph.MethodTargetSelector;
import com.ibm.wala.ipa.callgraph.impl.ComposedEntrypoints;
import com.ibm.wala.ipa.cha.ClassHierarchyException;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.ssa.IRFactory;
import com.ibm.wala.util.CancelException;
import com.ibm.wala.util.collections.HashMapFactory;
import com.ibm.wala.util.config.AnalysisScopeReader;
import com.ibm.wala.util.io.FileProvider;
import com.ibm.wala.util.strings.Atom;
public class Driver {
public static void addDefaultDispatchLogic(AnalysisOptions options, AnalysisScope scope, IClassHierarchy cha) {
com.ibm.wala.ipa.callgraph.impl.Util.addDefaultSelectors(options, cha);
Map<Atom,MethodTargetSelector> methodTargetSelectors = HashMapFactory.make();
methodTargetSelectors.put(JavaScriptLoader.JS.getName(), new JavaScriptConstructTargetSelector(cha,
new StandardFunctionTargetSelector(cha, options.getMethodTargetSelector())));
methodTargetSelectors.put(Language.JAVA.getName(), options.getMethodTargetSelector());
options.setSelector(new CrossLanguageMethodTargetSelector(methodTargetSelectors));
}
public static void main(String[] args) throws IOException, ClassHierarchyException, IllegalArgumentException, CancelException {
JSCallGraphUtil.setTranslatorFactory(new CAstRhinoTranslatorFactory());
HybridClassLoaderFactory loaders = new HybridClassLoaderFactory();
HybridAnalysisScope scope = new HybridAnalysisScope();
FileProvider files = new FileProvider();
AnalysisScopeReader.read(scope, args[0], files.getFile("Java60RegressionExclusions.txt"), Driver.class.getClassLoader(), files);
scope.addToScope(
scope.getJavaScriptLoader(),
JSCallGraphBuilderUtil.getPrologueFile("prologue.js"));
for(int i = 1; i < args.length; i++) {
URL script = Driver.class.getClassLoader().getResource(args[i]);
scope.addToScope(
scope.getJavaScriptLoader(),
new SourceURLModule(script));
}
System.err.println(scope);
IClassHierarchy cha = CrossLanguageClassHierarchy.make(scope, loaders);
Iterable<Entrypoint> jsRoots =
new JavaScriptEntryPoints(cha, cha.getLoader(scope.getJavaScriptLoader()));
Iterable<Entrypoint> entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha);
ComposedEntrypoints roots = new ComposedEntrypoints(jsRoots, entrypoints);
AnalysisOptions options = new AnalysisOptions(scope, roots);
addDefaultDispatchLogic(options, scope, cha);
IRFactory<IMethod> factory = AstIRFactory.makeDefaultFactory();
AnalysisCache cache = new AnalysisCache(factory);
JavaJavaScriptHybridCallGraphBuilder b = new JavaJavaScriptHybridCallGraphBuilder(cha, options, cache);
System.err.println(b.makeCallGraph(options));
}
}

View File

@ -0,0 +1,35 @@
package com.ibm.wala.cast.js.examples.hybrid;
import java.util.Set;
import com.ibm.wala.cast.js.loader.JavaScriptLoader;
import com.ibm.wala.cast.js.types.JavaScriptTypes;
import com.ibm.wala.classLoader.Language;
import com.ibm.wala.ipa.callgraph.AnalysisScope;
import com.ibm.wala.types.ClassLoaderReference;
import com.ibm.wala.util.collections.HashSetFactory;
public class HybridAnalysisScope extends AnalysisScope {
private static final Set<Language> languages;
static {
languages = HashSetFactory.make();
languages.add(Language.JAVA);
languages.add(JavaScriptLoader.JS);
}
public HybridAnalysisScope() {
super(languages);
this.initForJava();
ClassLoaderReference jsLoader = JavaScriptTypes.jsLoader;
loadersByName.put(JavaScriptTypes.jsLoaderName, jsLoader);
}
public ClassLoaderReference getJavaScriptLoader() {
return getLoader(JavaScriptTypes.jsLoaderName);
}
}

View File

@ -0,0 +1,50 @@
package com.ibm.wala.cast.js.examples.hybrid;
import java.io.IOException;
import com.ibm.wala.cast.js.loader.JavaScriptLoader;
import com.ibm.wala.cast.js.translator.CAstRhinoTranslatorFactory;
import com.ibm.wala.cast.js.translator.JavaScriptTranslatorFactory;
import com.ibm.wala.cast.js.types.JavaScriptTypes;
import com.ibm.wala.classLoader.ClassLoaderFactoryImpl;
import com.ibm.wala.classLoader.IClassLoader;
import com.ibm.wala.ipa.callgraph.AnalysisScope;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.types.ClassLoaderReference;
import com.ibm.wala.util.config.SetOfClasses;
public class HybridClassLoaderFactory extends ClassLoaderFactoryImpl {
private final JavaScriptTranslatorFactory jsTranslatorFactory;
public HybridClassLoaderFactory(
JavaScriptTranslatorFactory jsTranslatorFactory,
SetOfClasses exclusions)
{
super(exclusions);
this.jsTranslatorFactory = jsTranslatorFactory;
}
public HybridClassLoaderFactory() {
this(new CAstRhinoTranslatorFactory(), null);
}
@Override
protected IClassLoader
makeNewClassLoader(ClassLoaderReference classLoaderReference,
IClassHierarchy cha,
IClassLoader parent,
AnalysisScope scope)
throws IOException
{
if (classLoaderReference.equals(JavaScriptTypes.jsLoader)) {
JavaScriptLoader L = new JavaScriptLoader(cha, jsTranslatorFactory);
L.init(scope.getModules(classLoaderReference));
return L;
} else {
return super.makeNewClassLoader(classLoaderReference, cha, parent, scope);
}
}
}

View File

@ -0,0 +1,168 @@
package com.ibm.wala.cast.js.examples.hybrid;
import java.util.Map;
import com.ibm.wala.cast.ipa.callgraph.AstCFAPointerKeys;
import com.ibm.wala.cast.ipa.callgraph.AstSSAPropagationCallGraphBuilder.AstPointerAnalysisImpl.AstImplicitPointsToSetVisitor;
import com.ibm.wala.cast.ipa.callgraph.CrossLanguageCallGraph;
import com.ibm.wala.cast.ipa.callgraph.CrossLanguageContextSelector;
import com.ibm.wala.cast.ipa.callgraph.CrossLanguageInstanceKeys;
import com.ibm.wala.cast.ipa.callgraph.CrossLanguageSSAPropagationCallGraphBuilder;
import com.ibm.wala.cast.ipa.callgraph.GlobalObjectKey;
import com.ibm.wala.cast.js.ipa.callgraph.JSCallGraph.JSFakeRoot;
import com.ibm.wala.cast.js.ipa.callgraph.JSSSAPropagationCallGraphBuilder;
import com.ibm.wala.cast.js.ipa.callgraph.JSSSAPropagationCallGraphBuilder.JSConstraintVisitor;
import com.ibm.wala.cast.js.ipa.callgraph.JSSSAPropagationCallGraphBuilder.JSInterestingVisitor;
import com.ibm.wala.cast.js.ipa.callgraph.JSSSAPropagationCallGraphBuilder.JSPointerAnalysisImpl.JSImplicitPointsToSetVisitor;
import com.ibm.wala.cast.js.ipa.callgraph.JavaScriptConstructorContextSelector;
import com.ibm.wala.cast.js.ipa.callgraph.JavaScriptConstructorInstanceKeys;
import com.ibm.wala.cast.js.ipa.callgraph.JavaScriptFunctionApplyContextSelector;
import com.ibm.wala.cast.js.ipa.callgraph.JavaScriptScopeMappingInstanceKeys;
import com.ibm.wala.cast.js.loader.JavaScriptLoader;
import com.ibm.wala.cast.js.types.JavaScriptTypes;
import com.ibm.wala.cast.util.TargetLanguageSelector;
import com.ibm.wala.classLoader.Language;
import com.ibm.wala.ipa.callgraph.AnalysisCache;
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.callgraph.ContextSelector;
import com.ibm.wala.ipa.callgraph.impl.AbstractRootMethod;
import com.ibm.wala.ipa.callgraph.impl.DefaultContextSelector;
import com.ibm.wala.ipa.callgraph.impl.FakeRootMethod;
import com.ibm.wala.ipa.callgraph.propagation.AbstractFieldPointerKey;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKeyFactory;
import com.ibm.wala.ipa.callgraph.propagation.LocalPointerKey;
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
import com.ibm.wala.ipa.callgraph.propagation.SSAContextInterpreter;
import com.ibm.wala.ipa.callgraph.propagation.cfa.ZeroXInstanceKeys;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
import com.ibm.wala.util.collections.HashMapFactory;
import com.ibm.wala.util.strings.Atom;
public class JavaJavaScriptHybridCallGraphBuilder extends CrossLanguageSSAPropagationCallGraphBuilder {
public JavaJavaScriptHybridCallGraphBuilder(IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache) {
super(cha, options, cache, new AstCFAPointerKeys());
globalObject = new GlobalObjectKey(cha.lookupClass(JavaScriptTypes.Root));
SSAContextInterpreter contextInterpreter = makeDefaultContextInterpreters(null, options, cha);
setContextInterpreter( contextInterpreter );
ContextSelector def = new DefaultContextSelector(options, cha);
Map<Atom,ContextSelector> languageSelectors = HashMapFactory.make();
languageSelectors.put(JavaScriptTypes.jsName,
new JavaScriptFunctionApplyContextSelector(new JavaScriptConstructorContextSelector(def)));
languageSelectors.put(Language.JAVA.getName(), def);
setContextSelector(new CrossLanguageContextSelector(languageSelectors));
Map<Atom,InstanceKeyFactory> instanceKeys = HashMapFactory.make();
instanceKeys.put(
JavaScriptTypes.jsName,
new JavaScriptScopeMappingInstanceKeys(cha, this, new JavaScriptConstructorInstanceKeys(new ZeroXInstanceKeys(
options, cha, contextInterpreter, ZeroXInstanceKeys.ALLOCATIONS))));
instanceKeys.put(
Language.JAVA.getName(),
new ZeroXInstanceKeys(options, cha, contextInterpreter, ZeroXInstanceKeys.NONE));
setInstanceKeys(new CrossLanguageInstanceKeys(instanceKeys));
}
private final GlobalObjectKey globalObject;
@Override
public GlobalObjectKey getGlobalObject(Atom language) {
assert language.equals(JavaScriptTypes.jsName);
return globalObject;
}
@Override
protected TargetLanguageSelector<ConstraintVisitor, CGNode> makeMainVisitorSelector() {
return new TargetLanguageSelector<ConstraintVisitor, CGNode>() {
@Override
public ConstraintVisitor get(Atom language, CGNode construct) {
if (JavaScriptTypes.jsName.equals(language)) {
return new JSConstraintVisitor(JavaJavaScriptHybridCallGraphBuilder.this, construct);
} else {
return new ConstraintVisitor(JavaJavaScriptHybridCallGraphBuilder.this, construct);
}
}
};
}
@Override
protected TargetLanguageSelector<InterestingVisitor, Integer> makeInterestingVisitorSelector() {
return new TargetLanguageSelector<InterestingVisitor, Integer>() {
@Override
public InterestingVisitor get(Atom language, Integer construct) {
if (JavaScriptTypes.jsName.equals(language)) {
return new JSInterestingVisitor(construct);
} else {
return new InterestingVisitor(construct);
}
}
};
}
@Override
protected TargetLanguageSelector<AstImplicitPointsToSetVisitor, LocalPointerKey> makeImplicitVisitorSelector(
CrossLanguagePointerAnalysisImpl analysis) {
return new TargetLanguageSelector<AstImplicitPointsToSetVisitor, LocalPointerKey>() {
@Override
public AstImplicitPointsToSetVisitor get(Atom language, LocalPointerKey construct) {
if (JavaScriptTypes.jsName.equals(language)) {
return new JSImplicitPointsToSetVisitor((AstPointerAnalysisImpl) getPointerAnalysis(), construct);
} else {
return new AstImplicitPointsToSetVisitor((AstPointerAnalysisImpl) getPointerAnalysis(), construct);
}
}
};
}
@Override
protected TargetLanguageSelector<AbstractRootMethod, CrossLanguageCallGraph> makeRootNodeSelector() {
return new TargetLanguageSelector<AbstractRootMethod, CrossLanguageCallGraph>() {
@Override
public AbstractRootMethod get(Atom language, CrossLanguageCallGraph construct) {
if (JavaScriptTypes.jsName.equals(language)) {
return new JSFakeRoot(getClassHierarchy(), getOptions(), getAnalysisCache());
} else {
return new FakeRootMethod(getClassHierarchy(), getOptions(), getAnalysisCache());
}
}
};
}
@Override
protected boolean useObjectCatalog() {
return true;
}
@Override
protected AbstractFieldPointerKey fieldKeyForUnknownWrites(AbstractFieldPointerKey fieldKey) {
// TODO Auto-generated method stub
return null;
}
@Override
protected boolean sameMethod(CGNode opNode, String definingMethod) {
if (JavaScriptLoader.JS.equals(opNode.getMethod().getDeclaringClass().getClassLoader().getLanguage())) {
return definingMethod.equals(opNode.getMethod().getReference().getDeclaringClass().getName().toString());
} else {
return false;
}
}
@Override
protected void processCallingConstraints(CGNode caller, SSAAbstractInvokeInstruction instruction, CGNode target,
InstanceKey[][] constParams, PointerKey uniqueCatchKey) {
if (JavaScriptLoader.JS.equals(caller.getMethod().getDeclaringClass().getClassLoader().getLanguage())) {
JSSSAPropagationCallGraphBuilder.processCallingConstraintsInternal(this, caller, instruction, target, constParams, uniqueCatchKey);
} else {
super.processCallingConstraints(caller, instruction, target, constParams, uniqueCatchKey);
}
}
}