support for cross-language call graphs

git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@1216 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
dolby-oss 2007-06-01 03:32:56 +00:00
parent 8472f026f5
commit 66b19b8666
15 changed files with 252 additions and 220 deletions

View File

@ -15,13 +15,13 @@ import com.ibm.wala.analysis.typeInference.*;
import com.ibm.wala.cast.analysis.typeInference.AstTypeInference;
import com.ibm.wala.cast.js.ssa.*;
import com.ibm.wala.cast.js.types.JavaScriptTypes;
import com.ibm.wala.ipa.cha.ClassHierarchy;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.ssa.*;
import com.ibm.wala.types.TypeReference;
public class JSTypeInference extends AstTypeInference {
public JSTypeInference(IR ir, ClassHierarchy cha) {
public JSTypeInference(IR ir, IClassHierarchy cha) {
super(ir, cha, new PointType(cha.lookupClass(JavaScriptTypes.Boolean)), true);
}

View File

@ -16,15 +16,14 @@ import java.util.jar.JarFile;
import com.ibm.wala.cast.ipa.callgraph.CAstAnalysisScope;
import com.ibm.wala.cast.ir.ssa.AstIRFactory;
import com.ibm.wala.cast.js.ipa.callgraph.*;
import com.ibm.wala.cast.js.loader.JavaScriptLoaderFactory;
import com.ibm.wala.cast.js.loader.*;
import com.ibm.wala.cast.js.translator.JavaScriptTranslatorFactory;
import com.ibm.wala.cast.js.types.JavaScriptTypes;
import com.ibm.wala.classLoader.Module;
import com.ibm.wala.classLoader.SourceFileModule;
import com.ibm.wala.client.impl.AbstractAnalysisEngine;
import com.ibm.wala.ipa.callgraph.*;
import com.ibm.wala.ipa.cha.ClassHierarchy;
import com.ibm.wala.ipa.cha.ClassHierarchyException;
import com.ibm.wala.ipa.cha.*;
import com.ibm.wala.util.debug.Assertions;
public class JavaScriptAnalysisEngine extends AbstractAnalysisEngine {
@ -56,9 +55,9 @@ public class JavaScriptAnalysisEngine extends AbstractAnalysisEngine {
}
}
protected ClassHierarchy buildClassHierarchy() {
protected IClassHierarchy buildClassHierarchy() {
try {
return ClassHierarchy.make(getScope(), loaderFactory, getWarnings(), JavaScriptTypes.Root);
return ClassHierarchy.make(getScope(), loaderFactory, getWarnings(), JavaScriptLoader.JS);
} catch (ClassHierarchyException e) {
Assertions.UNREACHABLE(e.toString());
return null;
@ -77,20 +76,13 @@ public class JavaScriptAnalysisEngine extends AbstractAnalysisEngine {
Assertions.UNREACHABLE("Illegal to call setJ2SELibraries");
}
protected Iterable<Entrypoint> makeDefaultEntrypoints(AnalysisScope scope, ClassHierarchy cha) {
protected Iterable<Entrypoint> makeDefaultEntrypoints(AnalysisScope scope, IClassHierarchy cha) {
return new JavaScriptEntryPoints(cha, cha.getLoader(JavaScriptTypes.jsLoader));
}
public AnalysisOptions getDefaultOptions(Iterable<Entrypoint> roots) {
final AnalysisOptions options = new AnalysisOptions(scope, AstIRFactory.makeDefaultFactory(keepIRs), roots);
options.setConstantType(Boolean.class, JavaScriptTypes.Boolean);
options.setConstantType(String.class, JavaScriptTypes.String);
options.setConstantType(Integer.class, JavaScriptTypes.Number);
options.setConstantType(Float.class, JavaScriptTypes.Number);
options.setConstantType(Double.class, JavaScriptTypes.Number);
options.setConstantType(null, JavaScriptTypes.Null);
options.setUseConstantSpecificKeys(true);
options.setUseStacksForLexicalScoping(true);

View File

@ -17,7 +17,7 @@ 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.propagation.cfa.ZeroXInstanceKeys;
import com.ibm.wala.ipa.cha.ClassHierarchy;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.util.warnings.WarningSet;
/**
@ -31,12 +31,12 @@ public class ZeroCFABuilderFactory implements CallGraphBuilderFactory {
* (non-Javadoc)
*
* @see com.ibm.domo.j2ee.client.CallGraphBuilderFactory#make(com.ibm.domo.ipa.callgraph.AnalysisOptions,
* com.ibm.domo.ipa.cha.ClassHierarchy, java.lang.ClassLoader,
* com.ibm.domo.ipa.cha.IClassHierarchy, java.lang.ClassLoader,
* com.ibm.domo.j2ee.J2EEAnalysisScope,
* com.ibm.domo.util.warnings.WarningSet, boolean)
*/
public CallGraphBuilder make(AnalysisOptions options,
ClassHierarchy cha,
IClassHierarchy cha,
AnalysisScope scope,
WarningSet warnings,
boolean keepPointsTo)

View File

@ -12,7 +12,7 @@ package com.ibm.wala.cast.js.ipa.callgraph;
import com.ibm.wala.cast.ipa.callgraph.*;
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
import com.ibm.wala.ipa.cha.ClassHierarchy;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.util.warnings.WarningSet;
/**
@ -26,7 +26,7 @@ public class JSCFABuilder extends JSSSAPropagationCallGraphBuilder {
* @param cha
* @param warnings
*/
public JSCFABuilder(ClassHierarchy cha, WarningSet warnings, AnalysisOptions options) {
public JSCFABuilder(IClassHierarchy cha, WarningSet warnings, AnalysisOptions options) {
super(cha, warnings, options, new AstCFAPointerKeys());
}

View File

@ -25,14 +25,18 @@ import com.ibm.wala.util.warnings.WarningSet;
public class JSCallGraph extends AstCallGraph {
public JSCallGraph(ClassHierarchy cha, AnalysisOptions options) {
public JSCallGraph(IClassHierarchy cha, AnalysisOptions options) {
super(cha, options);
}
public class JSFakeRoot extends ScriptFakeRoot {
public final static MethodReference fakeRoot = MethodReference.findOrCreate(JavaScriptTypes.FakeRoot, FakeRootMethod.name, FakeRootMethod.descr);
public JSFakeRoot(ClassHierarchy cha, AnalysisOptions options) {
super(cha, options);
public static class JSFakeRoot extends ScriptFakeRoot {
public JSFakeRoot(IClassHierarchy cha,
AnalysisOptions options)
{
super(fakeRoot, cha.lookupClass(JavaScriptTypes.FakeRoot), cha, options);
}
public InducedCFG makeControlFlowGraph() {
@ -62,6 +66,6 @@ public class JSCallGraph extends AstCallGraph {
}
protected CGNode makeFakeRootNode() {
return findOrCreateNode(new JSFakeRoot(cha, options), Everywhere.EVERYWHERE);
return findOrCreateNode(new JSFakeRoot(cha, options), Everywhere.EVERYWHERE);
}
}

View File

@ -25,9 +25,10 @@ import com.ibm.wala.fixpoint.IntSetVariable;
import com.ibm.wala.ipa.callgraph.*;
import com.ibm.wala.ipa.callgraph.impl.ExplicitCallGraph;
import com.ibm.wala.ipa.callgraph.propagation.*;
import com.ibm.wala.ipa.cha.ClassHierarchy;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.ssa.*;
import com.ibm.wala.ssa.SSACFG.BasicBlock;
import com.ibm.wala.util.graph.*;
import com.ibm.wala.util.warnings.WarningSet;
import com.ibm.wala.shrikeBT.*;
@ -39,7 +40,7 @@ public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraph
public static final boolean DEBUG_TYPE_INFERENCE = false;
protected
JSSSAPropagationCallGraphBuilder(ClassHierarchy cha,
JSSSAPropagationCallGraphBuilder(IClassHierarchy cha,
WarningSet warnings,
AnalysisOptions options,
PointerKeyFactory pointerKeyFactory)
@ -70,11 +71,11 @@ public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraph
//
/////////////////////////////////////////////////////////////////////////////
protected ExplicitCallGraph createEmptyCallGraph(ClassHierarchy cha, AnalysisOptions options) {
protected ExplicitCallGraph createEmptyCallGraph(IClassHierarchy cha, AnalysisOptions options) {
return new JSCallGraph(cha, options);
}
protected TypeInference makeTypeInference(IR ir, ClassHierarchy cha) {
protected TypeInference makeTypeInference(IR ir, IClassHierarchy cha) {
TypeInference ti = new JSTypeInference(ir, cha);
ti.solve();
@ -98,11 +99,11 @@ public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraph
system.newConstraint(exceptionVar, assignOperator, e);
}
class JSInterestingVisitor
public static class JSInterestingVisitor
extends AstInterestingVisitor
implements com.ibm.wala.cast.js.ssa.InstructionVisitor
{
JSInterestingVisitor(int vn) {
public JSInterestingVisitor(int vn) {
super(vn);
}
@ -127,7 +128,7 @@ public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraph
}
}
protected InterestingVisitor makeInterestingVisitor(int vn) {
protected InterestingVisitor makeInterestingVisitor(CGNode node, int vn) {
return new JSInterestingVisitor(vn);
}
@ -137,14 +138,14 @@ public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraph
//
/////////////////////////////////////////////////////////////////////////////
protected class JSPointerFlowGraph extends AstPointerFlowGraph {
public static class JSPointerFlowGraph extends AstPointerFlowGraph {
protected class JSPointerFlowVisitor
public static class JSPointerFlowVisitor
extends AstPointerFlowVisitor
implements com.ibm.wala.cast.js.ssa.InstructionVisitor
{
protected JSPointerFlowVisitor(CGNode node, IR ir, BasicBlock bb) {
super(node, ir, bb);
public JSPointerFlowVisitor(PointerAnalysis pa, CallGraph cg, Graph<PointerKey> delegate, CGNode node, IR ir, BasicBlock bb) {
super(pa, cg, delegate, node, ir, bb);
}
public void visitJavaScriptInvoke(JavaScriptInvoke instruction) {
@ -169,7 +170,7 @@ public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraph
}
protected InstructionVisitor makeInstructionVisitor(CGNode node, IR ir, BasicBlock bb) {
return new JSPointerFlowVisitor(node,ir, bb);
return new JSPointerFlowVisitor(pa, cg, delegate, node, ir, bb);
}
}
@ -181,7 +182,7 @@ public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraph
};
}
protected class JSPointerAnalysisImpl extends AstPointerAnalysisImpl {
public static class JSPointerAnalysisImpl extends AstPointerAnalysisImpl {
JSPointerAnalysisImpl(PropagationCallGraphBuilder builder,
CallGraph cg,
@ -194,16 +195,16 @@ public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraph
cg,
pointsToMap,
instanceKeys,
pointerKeyFactory,
instanceKeyFactory);
pointerKeys,
iKeyFactory);
}
protected class JSImplicitPointsToSetVisitor
public static class JSImplicitPointsToSetVisitor
extends AstImplicitPointsToSetVisitor
implements com.ibm.wala.cast.js.ssa.InstructionVisitor
{
JSImplicitPointsToSetVisitor(LocalPointerKey lpk) {
super(lpk);
public JSImplicitPointsToSetVisitor(AstPointerAnalysisImpl analysis, LocalPointerKey lpk) {
super(analysis, lpk);
}
public void visitJavaScriptInvoke(JavaScriptInvoke instruction) {
@ -226,7 +227,7 @@ public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraph
protected ImplicitPointsToSetVisitor
makeImplicitPointsToVisitor(LocalPointerKey lpk)
{
return new JSImplicitPointsToSetVisitor(lpk);
return new JSImplicitPointsToSetVisitor(this, lpk);
}
};
@ -249,6 +250,114 @@ public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraph
};
}
/////////////////////////////////////////////////////////////////////////////
//
// IR visitor specialization for JavaScript
//
/////////////////////////////////////////////////////////////////////////////
protected ConstraintVisitor makeVisitor(ExplicitCallGraph.ExplicitNode node)
{
return new JSConstraintVisitor(this, node);
}
public static class JSConstraintVisitor extends AstConstraintVisitor implements InstructionVisitor {
public JSConstraintVisitor(AstSSAPropagationCallGraphBuilder builder,
ExplicitCallGraph.ExplicitNode node)
{
super(builder, node);
}
public void visitUnaryOp(SSAUnaryOpInstruction inst) {
if (inst.getOpcode() == UnaryOpInstruction.Operator.NEG) {
int lval = inst.getDef(0);
PointerKey lk = getPointerKeyForLocal(lval);
IClass bool = getClassHierarchy().lookupClass(JavaScriptTypes.Boolean);
InstanceKey key = new ConcreteTypeKey( bool );
system.newConstraint(lk, key);
}
}
public void visitIsDefined(AstIsDefinedInstruction inst) {
int lval = inst.getDef(0);
PointerKey lk = getPointerKeyForLocal(lval);
IClass bool = getClassHierarchy().lookupClass(JavaScriptTypes.Boolean);
InstanceKey key = new ConcreteTypeKey( bool );
system.newConstraint(lk, key);
}
public void visitEachElementHasNext(EachElementHasNextInstruction inst) {
int lval = inst.getDef(0);
PointerKey lk = getPointerKeyForLocal(lval);
IClass bool = getClassHierarchy().lookupClass(JavaScriptTypes.Boolean);
InstanceKey key = new ConcreteTypeKey( bool );
system.newConstraint(lk, key);
}
public void visitTypeOf(JavaScriptTypeOfInstruction instruction) {
int lval = instruction.getDef(0);
PointerKey lk = getPointerKeyForLocal(lval);
IClass string = getClassHierarchy().lookupClass(JavaScriptTypes.String);
InstanceKey key = new ConcreteTypeKey( string );
system.newConstraint(lk, key);
}
public void visitBinaryOp(final SSABinaryOpInstruction instruction) {
handleBinaryOp( instruction, node, symbolTable, du );
}
public void visitJavaScriptPropertyRead(JavaScriptPropertyRead instruction) {
newFieldRead(node,
instruction.getUse(0),
instruction.getUse(1),
instruction.getDef(0));
}
public void visitJavaScriptPropertyWrite(JavaScriptPropertyWrite instruction) {
newFieldWrite(node,
instruction.getUse(0),
instruction.getUse(1),
instruction.getUse(2));
}
public void visitJavaScriptInvoke(JavaScriptInvoke instruction) {
PointerKey F = getPointerKeyForLocal(instruction.getFunction());
InstanceKey[][] consts = computeInvariantParameters(instruction);
PointerKey uniqueCatch = null;
if (hasUniqueCatchBlock(instruction, ir)) {
uniqueCatch = getBuilder().getUniqueCatchKey(instruction, ir, node);
}
if (contentsAreInvariant(symbolTable, du, instruction.getFunction())) {
system.recordImplicitPointsToSet(F);
InstanceKey[] ik = getInvariantContents(instruction.getFunction());
for (int i = 0; i < ik.length; i++) {
system.findOrCreateIndexForInstanceKey(ik[i]);
CGNode n = getTargetForCall(node, instruction.getCallSite(), ik[i]);
if (n != null) {
processJSCall(node, instruction, n, ik[i], consts, uniqueCatch);
}
}
} else {
system.newSideEffect(
new JSDispatchOperator(instruction, node, consts, uniqueCatch),
F);
}
}
/////////////////////////////////////////////////////////////////////////////
//
// function call handling
@ -303,8 +412,8 @@ public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraph
CGNode target = getTargetForCall(node, call.getSite(), iKey);
if (target != null) {
processJSCall(node, call, target, iKey, constParams, uniqueCatch);
if (!haveAlreadyVisited(target)) {
markDiscovered(target);
if (!getBuilder().haveAlreadyVisited(target)) {
getBuilder().markDiscovered(target);
}
}
}
@ -326,14 +435,14 @@ public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraph
PointerKey uniqueCatchKey)
{
caller.addTarget(instruction.getCallSite(), target);
if (!haveAlreadyVisited(target)) {
markDiscovered(target);
if (!getBuilder().haveAlreadyVisited(target)) {
getBuilder().markDiscovered(target);
}
IR sourceIR = getCFAContextInterpreter().getIR(caller, getWarnings());
IR sourceIR = getBuilder().getCFAContextInterpreter().getIR(caller, getWarnings());
SymbolTable sourceST = sourceIR.getSymbolTable();
IR targetIR = getCFAContextInterpreter().getIR(target, getWarnings());
IR targetIR = getBuilder().getCFAContextInterpreter().getIR(target, getWarnings());
SymbolTable targetST = targetIR.getSymbolTable();
int av = -1;
@ -355,11 +464,11 @@ public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraph
int fn = targetST.getConstant(i);
PointerKey F =
(i == 0)?
getFilteredPointerKeyForLocal(
getBuilder().getFilteredPointerKeyForLocal(
target,
targetST.getParameter(i),
function):
getPointerKeyForLocal(target, targetST.getParameter(i));
getBuilder().getPointerKeyForLocal(target, targetST.getParameter(i));
if (constParams != null && constParams[i] != null) {
for(int j = 0; j < constParams[i].length; j++) {
@ -369,11 +478,11 @@ public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraph
if (av != -1) newFieldWrite(target, av, fn, constParams[i]);
} else {
PointerKey A = getPointerKeyForLocal(caller, instruction.getUse(i));
PointerKey A = getBuilder().getPointerKeyForLocal(caller, instruction.getUse(i));
system.newConstraint(
F,
(F instanceof FilteredPointerKey)?
(UnaryOperator)filterOperator:
(UnaryOperator)getBuilder().filterOperator:
(UnaryOperator)assignOperator,
A);
@ -389,7 +498,7 @@ public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraph
if (constParams != null && constParams[i] != null) {
newFieldWrite(target, av, fn, constParams[i]);
} else {
PointerKey A = getPointerKeyForLocal(caller, instruction.getUse(i));
PointerKey A = getBuilder().getPointerKeyForLocal(caller, instruction.getUse(i));
newFieldWrite(target, av, fn, A);
}
}
@ -399,10 +508,10 @@ public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraph
// extra formal parameters get null (extra args are ignored here)
else if (argCount < paramCount) {
int nullvn = sourceST.getNullConstant();
DefUse sourceDU = getCFAContextInterpreter().getDU(caller, getWarnings());
InstanceKey[] nullkeys = getInvariantContents(sourceST, sourceDU, caller, nullvn, this);
DefUse sourceDU = getBuilder().getCFAContextInterpreter().getDU(caller, getWarnings());
InstanceKey[] nullkeys = getInvariantContents(sourceST, sourceDU, caller, nullvn);
for(int i = argCount; i < paramCount; i++) {
PointerKey F = getPointerKeyForLocal(target, targetST.getParameter(i));
PointerKey F = getBuilder().getPointerKeyForLocal(target, targetST.getParameter(i));
for(int k = 0; k < nullkeys.length; k++) {
system.newConstraint(F, nullkeys[k]);
}
@ -418,17 +527,17 @@ public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraph
// return values
if (instruction.getDef(0) != -1) {
PointerKey RF = getPointerKeyForReturnValue( target );
PointerKey RA = getPointerKeyForLocal(caller, instruction.getDef(0));
PointerKey RF = getBuilder().getPointerKeyForReturnValue( target );
PointerKey RA = getBuilder().getPointerKeyForLocal(caller, instruction.getDef(0));
system.newConstraint(RA, assignOperator, RF);
}
PointerKey EF = getPointerKeyForExceptionalReturnValue( target );
PointerKey EF = getBuilder().getPointerKeyForExceptionalReturnValue( target );
if (SHORT_CIRCUIT_SINGLE_USES && uniqueCatchKey != null) {
// e has exactly one use. so, represent e implicitly
system.newConstraint(uniqueCatchKey, assignOperator, EF);
} else {
PointerKey EA = getPointerKeyForLocal(caller, instruction.getDef(1));
PointerKey EA = getBuilder().getPointerKeyForLocal(caller, instruction.getDef(1));
system.newConstraint(EA, assignOperator, EF);
}
}
@ -445,7 +554,7 @@ public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraph
final DefUse du)
{
int lval = instruction.getDef(0);
PointerKey lk = getPointerKeyForLocal(node, lval);
PointerKey lk = getPointerKeyForLocal(lval);
final PointsToSetVariable lv = system.findOrCreatePointsToSet(lk);
final int arg1 = instruction.getUse(0);
@ -484,10 +593,10 @@ public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraph
private InstanceKey[] getInstancesArray(int vn) {
if (contentsAreInvariant(symbolTable, du, vn)) {
return getInvariantContents(symbolTable, du, node, vn, JSSSAPropagationCallGraphBuilder.this);
return getInvariantContents(vn);
} else {
PointsToSetVariable v =
system.findOrCreatePointsToSet(getPointerKeyForLocal(node,vn));
system.findOrCreatePointsToSet(getPointerKeyForLocal(vn));
if (v.getValue() == null || v.size() == 0) {
return new InstanceKey[0];
} else {
@ -579,124 +688,17 @@ public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraph
if (contentsAreInvariant(symbolTable, du, arg2)) {
B.evaluate(null, null);
} else {
system.newConstraint(lk, B, getPointerKeyForLocal(node, arg2));
system.newConstraint(lk, B, getPointerKeyForLocal(arg2));
}
} else {
PointerKey k1 = getPointerKeyForLocal(node, arg1);
PointerKey k1 = getPointerKeyForLocal(arg1);
if (contentsAreInvariant(symbolTable, du, arg2)) {
system.newConstraint(lk, B, k1);
} else {
system.newConstraint(lk, B, k1, getPointerKeyForLocal(node, arg2));
system.newConstraint(lk, B, k1, getPointerKeyForLocal(arg2));
}
}
}
/////////////////////////////////////////////////////////////////////////////
//
// IR visitor specialization for JavaScript
//
/////////////////////////////////////////////////////////////////////////////
class JSConstraintVisitor extends AstConstraintVisitor implements InstructionVisitor {
public JSConstraintVisitor(ExplicitCallGraph.ExplicitNode node, IR ir, ExplicitCallGraph callGraph, DefUse du) {
super(node, ir, callGraph, du);
}
public void visitUnaryOp(SSAUnaryOpInstruction inst) {
if (inst.getOpcode() == UnaryOpInstruction.Operator.NEG) {
int lval = inst.getDef(0);
PointerKey lk = getPointerKeyForLocal(node, lval);
IClass bool = cha.lookupClass(JavaScriptTypes.Boolean);
InstanceKey key = new ConcreteTypeKey( bool );
system.newConstraint(lk, key);
}
}
public void visitIsDefined(AstIsDefinedInstruction inst) {
int lval = inst.getDef(0);
PointerKey lk = getPointerKeyForLocal(node, lval);
IClass bool = cha.lookupClass(JavaScriptTypes.Boolean);
InstanceKey key = new ConcreteTypeKey( bool );
system.newConstraint(lk, key);
}
public void visitEachElementHasNext(EachElementHasNextInstruction inst) {
int lval = inst.getDef(0);
PointerKey lk = getPointerKeyForLocal(node, lval);
IClass bool = cha.lookupClass(JavaScriptTypes.Boolean);
InstanceKey key = new ConcreteTypeKey( bool );
system.newConstraint(lk, key);
}
public void visitTypeOf(JavaScriptTypeOfInstruction instruction) {
int lval = instruction.getDef(0);
PointerKey lk = getPointerKeyForLocal(node, lval);
IClass string = cha.lookupClass(JavaScriptTypes.String);
InstanceKey key = new ConcreteTypeKey( string );
system.newConstraint(lk, key);
}
public void visitBinaryOp(final SSABinaryOpInstruction instruction) {
handleBinaryOp( instruction, node, symbolTable, du );
}
public void visitJavaScriptPropertyRead(JavaScriptPropertyRead instruction) {
newFieldRead(node,
instruction.getUse(0),
instruction.getUse(1),
instruction.getDef(0));
}
public void visitJavaScriptPropertyWrite(JavaScriptPropertyWrite instruction) {
newFieldWrite(node,
instruction.getUse(0),
instruction.getUse(1),
instruction.getUse(2));
}
public void visitJavaScriptInvoke(JavaScriptInvoke instruction) {
PointerKey F = getPointerKeyForLocal(node, instruction.getFunction());
InstanceKey[][] consts = computeInvariantParameters(instruction);
PointerKey uniqueCatch = null;
if (hasUniqueCatchBlock(instruction, ir)) {
uniqueCatch = getUniqueCatchKey(instruction, ir, node);
}
if (contentsAreInvariant(symbolTable, du, instruction.getFunction())) {
system.recordImplicitPointsToSet(F);
InstanceKey[] ik = getInvariantContents(symbolTable, du, node, instruction.getFunction(), JSSSAPropagationCallGraphBuilder.this);
for (int i = 0; i < ik.length; i++) {
system.findOrCreateIndexForInstanceKey(ik[i]);
CGNode n = getTargetForCall(node, instruction.getCallSite(), ik[i]);
if (n != null) {
processJSCall(node, instruction, n, ik[i], consts, uniqueCatch);
}
}
} else {
system.newSideEffect(
new JSDispatchOperator(instruction, node, consts, uniqueCatch),
F);
}
}
}
protected ConstraintVisitor makeVisitor(ExplicitCallGraph.ExplicitNode node,
IR ir,
DefUse du,
ExplicitCallGraph callGraph)
{
return new JSConstraintVisitor(node, ir, callGraph, du);
}
}
}

View File

@ -14,7 +14,7 @@ import com.ibm.wala.ipa.callgraph.*;
import com.ibm.wala.ipa.callgraph.impl.*;
import com.ibm.wala.ipa.callgraph.propagation.*;
import com.ibm.wala.ipa.callgraph.propagation.cfa.ZeroXInstanceKeys;
import com.ibm.wala.ipa.cha.ClassHierarchy;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.util.warnings.WarningSet;
/**
@ -32,7 +32,7 @@ public class JSZeroXCFABuilder extends JSCFABuilder {
* @param bypass
* @param contextProvider
*/
public JSZeroXCFABuilder(ClassHierarchy cha,
public JSZeroXCFABuilder(IClassHierarchy cha,
WarningSet warnings,
AnalysisOptions options,
ContextSelector appContextSelector,
@ -49,7 +49,6 @@ public class JSZeroXCFABuilder extends JSCFABuilder {
new JavaScriptConstructTargetSelector(
cha,
options.getMethodTargetSelector(),
contextInterpreter,
warnings));
ContextSelector def = new DefaultContextSelector(cha,options.getMethodTargetSelector());
@ -81,7 +80,7 @@ public class JSZeroXCFABuilder extends JSCFABuilder {
* deployment descriptor abstraction
* @return a 0-1-Opt-CFA Call Graph Builder.
*/
public static JSCFABuilder make(AnalysisOptions options, ClassHierarchy cha, ClassLoader cl, AnalysisScope scope,
public static JSCFABuilder make(AnalysisOptions options, IClassHierarchy cha, ClassLoader cl, AnalysisScope scope,
String[] xmlFiles, WarningSet warnings, byte instancePolicy) {
com.ibm.wala.ipa.callgraph.impl.Util.addDefaultSelectors(options, cha, warnings);

View File

@ -24,7 +24,7 @@ import com.ibm.wala.cast.types.*;
import com.ibm.wala.classLoader.*;
import com.ibm.wala.ipa.callgraph.*;
import com.ibm.wala.ipa.callgraph.propagation.SSAContextInterpreter;
import com.ibm.wala.ipa.cha.ClassHierarchy;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.ipa.summaries.MethodSummary;
import com.ibm.wala.ssa.*;
import com.ibm.wala.types.*;
@ -33,9 +33,8 @@ import com.ibm.wala.util.warnings.WarningSet;
public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
private static final boolean DEBUG = false;
private final ClassHierarchy cha;
private final IClassHierarchy cha;
private final MethodTargetSelector base;
private final SSAContextInterpreter interpreter;
private final WarningSet warnings;
private final Map<Object, IMethod> constructors = new HashMap<Object, IMethod>();
@ -64,14 +63,12 @@ public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
}
}
public JavaScriptConstructTargetSelector(ClassHierarchy cha,
public JavaScriptConstructTargetSelector(IClassHierarchy cha,
MethodTargetSelector base,
SSAContextInterpreter interpreter,
WarningSet warnings)
{
this.cha = cha;
this.base = base;
this.interpreter = interpreter;
this.warnings = warnings;
}
@ -529,6 +526,8 @@ public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
{
if (site.getDeclaredTarget().equals(JavaScriptMethods.ctorReference)) {
Assertions._assert(cha.isSubclassOf(receiver, cha.lookupClass(JavaScriptTypes.Root)));
SSAContextInterpreter interpreter =
caller.getCallGraph().getInterpreter(caller);
IR callerIR = interpreter.getIR(caller, warnings);
SSAAbstractInvokeInstruction callStmts[] = callerIR.getCalls( site );
Assertions._assert( callStmts.length == 1 );

View File

@ -17,7 +17,7 @@ import com.ibm.wala.ipa.cha.*;
public class JavaScriptEntryPoints extends ScriptEntryPoints {
public JavaScriptEntryPoints(ClassHierarchy cha, IClassLoader loader) {
public JavaScriptEntryPoints(IClassHierarchy cha, IClassLoader loader) {
super(cha, loader.lookupClass(JavaScriptTypes.Script.getName(), cha));
}

View File

@ -19,14 +19,14 @@ import com.ibm.wala.classLoader.IClass;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKeyFactory;
import com.ibm.wala.ipa.callgraph.propagation.PropagationCallGraphBuilder;
import com.ibm.wala.ipa.cha.ClassHierarchy;
import com.ibm.wala.ipa.cha.IClassHierarchy;
public class JavaScriptScopeMappingInstanceKeys extends ScopeMappingInstanceKeys {
private final ClassHierarchy cha;
private final IClassHierarchy cha;
private final IClass codeBody;
public JavaScriptScopeMappingInstanceKeys(ClassHierarchy cha,
public JavaScriptScopeMappingInstanceKeys(IClassHierarchy cha,
PropagationCallGraphBuilder builder,
InstanceKeyFactory basic)
{

View File

@ -38,20 +38,13 @@ public class Util extends com.ibm.wala.cast.ipa.callgraph.Util {
return translatorFactory;
}
public static AnalysisOptions makeOptions(AnalysisScope scope, boolean keepIRs, ClassHierarchy cha, Iterable<Entrypoint> roots,
public static AnalysisOptions makeOptions(AnalysisScope scope, boolean keepIRs, IClassHierarchy cha, Iterable<Entrypoint> roots,
final WarningSet warnings) {
final AnalysisOptions options = new AnalysisOptions(scope, AstIRFactory.makeDefaultFactory(keepIRs), roots);
com.ibm.wala.ipa.callgraph.impl.Util.addDefaultSelectors(options, cha, warnings);
options.setSelector(new StandardFunctionTargetSelector(cha, options.getMethodTargetSelector()));
options.setConstantType(Boolean.class, JavaScriptTypes.Boolean);
options.setConstantType(String.class, JavaScriptTypes.String);
options.setConstantType(Integer.class, JavaScriptTypes.Number);
options.setConstantType(Float.class, JavaScriptTypes.Number);
options.setConstantType(Double.class, JavaScriptTypes.Number);
options.setConstantType(null, JavaScriptTypes.Null);
options.setUseConstantSpecificKeys(true);
options.setUseStacksForLexicalScoping(true);
@ -77,12 +70,12 @@ public class Util extends com.ibm.wala.cast.ipa.callgraph.Util {
return new CAstAnalysisScope(files, loaders);
}
public static ClassHierarchy makeHierarchy(AnalysisScope scope, ClassLoaderFactory loaders, WarningSet warnings)
public static IClassHierarchy makeHierarchy(AnalysisScope scope, ClassLoaderFactory loaders, WarningSet warnings)
throws ClassHierarchyException {
return ClassHierarchy.make(scope, loaders, warnings, JavaScriptTypes.Root);
return ClassHierarchy.make(scope, loaders, warnings, JavaScriptLoader.JS);
}
public static Iterable<Entrypoint> makeScriptRoots(ClassHierarchy cha) {
public static Iterable<Entrypoint> makeScriptRoots(IClassHierarchy cha) {
return new JavaScriptEntryPoints(cha, cha.getLoader(JavaScriptTypes.jsLoader));
}

View File

@ -31,11 +31,8 @@ import com.ibm.wala.cast.tree.CAstQualifier;
import com.ibm.wala.cast.tree.CAstSourcePositionMap;
import com.ibm.wala.cast.types.AstMethodReference;
import com.ibm.wala.cfg.AbstractCFG;
import com.ibm.wala.classLoader.IClass;
import com.ibm.wala.classLoader.IClassLoader;
import com.ibm.wala.classLoader.IField;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.ipa.cha.ClassHierarchy;
import com.ibm.wala.classLoader.*;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.ipa.cha.ClassHierarchyException;
import com.ibm.wala.ssa.SymbolTable;
import com.ibm.wala.types.ClassLoaderReference;
@ -47,6 +44,39 @@ import com.ibm.wala.util.debug.Assertions;
import com.ibm.wala.util.debug.Trace;
public class JavaScriptLoader implements IClassLoader {
public final static Language JS = new Language() {
public Atom getName() {
return Atom.findOrCreateUnicodeAtom("JavaScript");
}
public TypeReference getRootType() {
return JavaScriptTypes.Root;
}
public TypeReference getConstantType(Object o) {
if (o == null) {
return JavaScriptTypes.Null;
} else {
Class c = o.getClass();
if (c == Boolean.class) {
return JavaScriptTypes.Boolean;
} else if (c == String.class) {
return JavaScriptTypes.String;
} else if (c == Integer.class) {
return JavaScriptTypes.Number;
} else if (c == Float.class) {
return JavaScriptTypes.Number;
} else if (c == Double.class) {
return JavaScriptTypes.Number;
} else {
return null;
}
}
}
};
private final Map<TypeName,IClass> types = new HashMap<TypeName,IClass>();
private static final Map<Selector,IMethod> emptyMap1 = Collections.emptyMap();
@ -54,9 +84,9 @@ public class JavaScriptLoader implements IClassLoader {
private final JavaScriptTranslatorFactory translatorFactory;
private final ClassHierarchy cha;
private final IClassHierarchy cha;
JavaScriptLoader(ClassHierarchy cha, JavaScriptTranslatorFactory translatorFactory) {
public JavaScriptLoader(IClassHierarchy cha, JavaScriptTranslatorFactory translatorFactory) {
this.cha = cha;
this.translatorFactory = translatorFactory;
}
@ -73,7 +103,7 @@ public class JavaScriptLoader implements IClassLoader {
superClass = superRef == null ? null : loader.lookupClass(superRef.getName(), cha);
}
public ClassHierarchy getClassHierarchy() {
public IClassHierarchy getClassHierarchy() {
return cha;
}
@ -100,7 +130,7 @@ public class JavaScriptLoader implements IClassLoader {
types.put(JavaScriptTypes.Root.getName(), this);
}
public ClassHierarchy getClassHierarchy() {
public IClassHierarchy getClassHierarchy() {
return cha;
}
@ -125,7 +155,7 @@ public class JavaScriptLoader implements IClassLoader {
types.put(codeName.getName(), this);
}
public ClassHierarchy getClassHierarchy() {
public IClassHierarchy getClassHierarchy() {
return cha;
}
@ -151,7 +181,7 @@ public class JavaScriptLoader implements IClassLoader {
lexicalInfo, debugInfo);
}
public ClassHierarchy getClassHierarchy() {
public IClassHierarchy getClassHierarchy() {
return cha;
}
@ -242,6 +272,8 @@ public class JavaScriptLoader implements IClassLoader {
final JavaScriptClass PRIMITIVES = new JavaScriptClass(this, JavaScriptTypes.Primitives, JavaScriptTypes.Root, null);
final JavaScriptClass FAKEROOT = new JavaScriptClass(this, JavaScriptTypes.FakeRoot, JavaScriptTypes.Root, null);
final JavaScriptClass STRING = new JavaScriptClass(this, JavaScriptTypes.String, JavaScriptTypes.Root, null);
final JavaScriptClass NULL = new JavaScriptClass(this, JavaScriptTypes.Null, JavaScriptTypes.Root, null);
@ -276,13 +308,12 @@ public class JavaScriptLoader implements IClassLoader {
final JavaScriptClass STRING_OBJECT = new JavaScriptClass(this, JavaScriptTypes.StringObject, JavaScriptTypes.Object, null);
public IClass lookupClass(String className, ClassHierarchy cha) {
public IClass lookupClass(String className, IClassHierarchy cha) {
Assertions._assert(this.cha == cha);
return (IClass) types.get(TypeName.string2TypeName(className));
}
public IClass lookupClass(TypeName className, ClassHierarchy cha) {
Assertions._assert(this.cha == cha);
public IClass lookupClass(TypeName className, IClassHierarchy cha) {
return (IClass) types.get(className);
}
@ -302,6 +333,10 @@ public class JavaScriptLoader implements IClassLoader {
return getReference().getName();
}
public Language getLanguage() {
return JS;
}
public int getNumberOfMethods() {
return types.size();
}

View File

@ -24,7 +24,7 @@ public class JavaScriptLoaderFactory extends SingleClassLoaderFactory {
this.translatorFactory = factory;
}
protected IClassLoader makeTheLoader(ClassHierarchy cha) {
protected IClassLoader makeTheLoader(IClassHierarchy cha) {
return new JavaScriptLoader( cha, translatorFactory );
}

View File

@ -16,13 +16,18 @@ import com.ibm.wala.util.Atom;
public class JavaScriptTypes extends AstTypeReference {
public static final String jsLoaderNameStr = "JavaScript";
public static final String jsNameStr = "JavaScript";
public static final String jsLoaderNameStr = "JavaScriptLoader";
public static final Atom jsName =
Atom.findOrCreateUnicodeAtom(jsNameStr);
public static final Atom jsLoaderName =
Atom.findOrCreateUnicodeAtom(jsLoaderNameStr);
public static final ClassLoaderReference jsLoader =
new ClassLoaderReference( jsLoaderName );
new ClassLoaderReference( jsLoaderName, jsName );
public static final TypeReference Root =
TypeReference.findOrCreate(jsLoader, rootTypeName);
@ -54,6 +59,9 @@ public class JavaScriptTypes extends AstTypeReference {
public static final TypeReference Primitives =
TypeReference.findOrCreate(jsLoader, "LPrimitives");
public static final TypeReference FakeRoot =
TypeReference.findOrCreate(jsLoader, "LFakeRoot");
public static final TypeReference Boolean =
TypeReference.findOrCreate(jsLoader, "LBoolean");

View File

@ -17,7 +17,7 @@ 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.cfa.ZeroXInstanceKeys;
import com.ibm.wala.ipa.cha.ClassHierarchy;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.util.warnings.WarningSet;
class dumpCallGraph {
@ -27,7 +27,7 @@ class dumpCallGraph {
JavaScriptLoaderFactory loaders = Util.makeLoaders();
AnalysisScope scope = Util.makeScope( args, loaders );
ClassHierarchy cha = Util.makeHierarchy( scope, loaders, warnings );
IClassHierarchy cha = Util.makeHierarchy( scope, loaders, warnings );
Iterable<Entrypoint> roots = Util.makeScriptRoots( cha );
AnalysisOptions options = Util.makeOptions(scope, false, cha, roots, warnings);