151 lines
6.7 KiB
Java
151 lines
6.7 KiB
Java
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.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.IMethod;
|
|
import com.ibm.wala.classLoader.Language;
|
|
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.IAnalysisCacheView;
|
|
import com.ibm.wala.ipa.callgraph.impl.AbstractRootMethod;
|
|
import com.ibm.wala.ipa.callgraph.impl.DefaultContextSelector;
|
|
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.ssa.SSAAbstractInvokeInstruction;
|
|
import com.ibm.wala.util.collections.HashMapFactory;
|
|
import com.ibm.wala.util.strings.Atom;
|
|
|
|
public class JavaJavaScriptHybridCallGraphBuilder extends CrossLanguageSSAPropagationCallGraphBuilder {
|
|
|
|
public JavaJavaScriptHybridCallGraphBuilder(IMethod fakeRootClass, AnalysisOptions options, IAnalysisCacheView cache) {
|
|
super(fakeRootClass, 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 (language, 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 (language, construct) -> {
|
|
if (JavaScriptTypes.jsName.equals(language)) {
|
|
return new JSInterestingVisitor(construct);
|
|
} else {
|
|
return new InterestingVisitor(construct);
|
|
}
|
|
};
|
|
}
|
|
|
|
@Override
|
|
protected TargetLanguageSelector<AstImplicitPointsToSetVisitor, LocalPointerKey> makeImplicitVisitorSelector(
|
|
CrossLanguagePointerAnalysisImpl analysis) {
|
|
return (language, 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 (language, construct) -> {
|
|
return getOptions().getAnalysisScope().getLanguage(language).getFakeRootMethod(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);
|
|
}
|
|
}
|
|
|
|
|
|
}
|