Skip to content

Commit

Permalink
changes for hybrid analysis
Browse files Browse the repository at this point in the history
  • Loading branch information
juliandolby committed Apr 6, 2015
1 parent c5b538e commit 0975441
Show file tree
Hide file tree
Showing 18 changed files with 246 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import com.ibm.wala.analysis.typeInference.TypeInference;
import com.ibm.wala.cast.ipa.callgraph.AstSSAPropagationCallGraphBuilder;
import com.ibm.wala.cast.ipa.callgraph.GlobalObjectKey;
import com.ibm.wala.cast.java.analysis.typeInference.AstJavaTypeInference;
import com.ibm.wala.cast.java.loader.JavaSourceLoaderImpl.JavaClass;
import com.ibm.wala.cast.java.ssa.AstJavaInstructionVisitor;
Expand All @@ -37,6 +38,7 @@
import com.ibm.wala.types.MethodReference;
import com.ibm.wala.util.debug.Assertions;
import com.ibm.wala.util.intset.IntSetAction;
import com.ibm.wala.util.strings.Atom;

public class AstJavaSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraphBuilder {

Expand Down Expand Up @@ -298,7 +300,7 @@ public void visitJavaInvoke(AstJavaInvokeInstruction instruction) {
}

@Override
protected ConstraintVisitor makeVisitor(CGNode node) {
public ConstraintVisitor makeVisitor(CGNode node) {
return new AstJavaConstraintVisitor(this, node);
}

Expand All @@ -309,4 +311,10 @@ protected boolean sameMethod(CGNode opNode, String definingMethod) {
String containingClass = reference.getDeclaringClass().getName().toString();
return definingMethod.equals(containingClass + "/" + selector);
}

@Override
public GlobalObjectKey getGlobalObject(Atom language) {
Assertions.UNREACHABLE();
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import com.ibm.wala.analysis.typeInference.TypeInference;
import com.ibm.wala.cast.ipa.callgraph.AstSSAPropagationCallGraphBuilder;
import com.ibm.wala.cast.ipa.callgraph.ReflectedFieldPointerKey;
import com.ibm.wala.cast.ipa.callgraph.GlobalObjectKey;
import com.ibm.wala.cast.ir.ssa.AstGlobalRead;
import com.ibm.wala.cast.ir.ssa.AstGlobalWrite;
import com.ibm.wala.cast.ir.ssa.AstIsDefinedInstruction;
Expand Down Expand Up @@ -113,6 +113,14 @@ public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraph
*/
public static final String GLOBAL_OBJ_VAR_NAME = "__WALA__int3rnal__global";

private final GlobalObjectKey globalObject;

@Override
public GlobalObjectKey getGlobalObject(Atom language) {
assert language.equals(JavaScriptTypes.jsName);
return globalObject;
}

/**
* is field a direct (WALA-internal) reference to the global object?
*/
Expand Down Expand Up @@ -140,6 +148,7 @@ public void setBaseURL(URL url) {
protected JSSSAPropagationCallGraphBuilder(IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache,
PointerKeyFactory pointerKeyFactory) {
super(cha, options, cache, pointerKeyFactory);
globalObject = new GlobalObjectKey(cha.lookupClass(JavaScriptTypes.Root));
}

@Override
Expand Down Expand Up @@ -195,14 +204,12 @@ protected AbstractFieldPointerKey fieldKeyForUnknownWrites(AbstractFieldPointerK
prototypeRef = x;
}

private final GlobalObjectKey globalObject = new GlobalObjectKey(cha.lookupClass(JavaScriptTypes.Object));

public PointerKey getPointerKeyForGlobalVar(String varName) {
FieldReference fieldRef = FieldReference.findOrCreate(JavaScriptTypes.Root, Atom.findOrCreateUnicodeAtom(varName),
JavaScriptTypes.Root);
IField f = cha.resolveField(fieldRef);
assert f != null : "couldn't resolve " + varName;
return getPointerKeyForInstanceField(globalObject, f);
return getPointerKeyForInstanceField(getGlobalObject(JavaScriptTypes.jsName), f);
}
@Override
protected ExplicitCallGraph createEmptyCallGraph(IClassHierarchy cha, AnalysisOptions options) {
Expand Down Expand Up @@ -357,7 +364,7 @@ public void visitAstGlobalRead(AstGlobalRead instruction) {
IField f = jsAnalysis.builder.getCallGraph().getClassHierarchy().resolveField(field);
assert f != null;
MutableSparseIntSet S = MutableSparseIntSet.makeEmpty();
InstanceKey globalObj = ((JSSSAPropagationCallGraphBuilder) jsAnalysis.builder).globalObject;
InstanceKey globalObj = ((AstSSAPropagationCallGraphBuilder) jsAnalysis.builder).getGlobalObject(JavaScriptTypes.jsName);
PointerKey fkey = analysis.getHeapModel().getPointerKeyForInstanceField(globalObj, f);
if (fkey != null) {
OrdinalSet pointees = analysis.getPointsToSet(fkey);
Expand Down Expand Up @@ -402,7 +409,7 @@ public PointerAnalysis<InstanceKey> makePointerAnalysis(PropagationCallGraphBuil
// ///////////////////////////////////////////////////////////////////////////

@Override
protected JSConstraintVisitor makeVisitor(CGNode node) {
public JSConstraintVisitor makeVisitor(CGNode node) {
if (AstSSAPropagationCallGraphBuilder.DEBUG_PROPERTIES) {
final IMethod method = node.getMethod();
if (method instanceof AstMethod) {
Expand Down Expand Up @@ -432,11 +439,6 @@ public JSConstraintVisitor(AstSSAPropagationCallGraphBuilder builder, CGNode nod
super(builder, node);
}

@Override
protected JSSSAPropagationCallGraphBuilder getBuilder() {
return (JSSSAPropagationCallGraphBuilder) builder;
}

@Override
public void visitUnaryOp(SSAUnaryOpInstruction inst) {
if (inst.getOpcode() == IUnaryOpInstruction.Operator.NEG) {
Expand Down Expand Up @@ -490,7 +492,7 @@ public void visitAstGlobalRead(AstGlobalRead instruction) {
if (hasNoInterestingUses(lval)) {
system.recordImplicitPointsToSet(def);
} else {
InstanceKey globalObj = getBuilder().globalObject;
InstanceKey globalObj = getBuilder().getGlobalObject(JavaScriptTypes.jsName);
if (directGlobalObjectRef(field)) {
// points-to set is just the global object
system.newConstraint(def, globalObj);
Expand All @@ -510,7 +512,7 @@ public void visitAstGlobalWrite(AstGlobalWrite instruction) {
IField f = getClassHierarchy().resolveField(field);
assert f != null : "could not resolve referenced global " + field;
assert !f.getFieldTypeReference().isPrimitiveType();
InstanceKey globalObj = getBuilder().globalObject;
InstanceKey globalObj = getBuilder().getGlobalObject(JavaScriptTypes.jsName);
system.findOrCreateIndexForInstanceKey(globalObj);
PointerKey p = getPointerKeyForInstanceField(globalObj, f);

Expand Down Expand Up @@ -572,6 +574,9 @@ public void visitJavaScriptInvoke(JavaScriptInvoke instruction) {
if (instruction.getDeclaredTarget().equals(JavaScriptMethods.dispatchReference)) {
handleJavascriptDispatch(instruction);
} else {
if (! instruction.getDeclaredTarget().equals(JavaScriptMethods.ctorReference)) {
System.err.println(instruction);
}
visitInvokeInternal(instruction, new DefaultInvariantComputer());
}
}
Expand Down Expand Up @@ -985,12 +990,15 @@ public void visitPrototypeLookup(PrototypeLookup instruction) {
@Override
protected void processCallingConstraints(CGNode caller, SSAAbstractInvokeInstruction instruction, CGNode target,
InstanceKey[][] constParams, PointerKey uniqueCatchKey) {
processCallingConstraintsInternal(this, caller, instruction, target, constParams, uniqueCatchKey);
}


IR sourceIR = getCFAContextInterpreter().getIR(caller);
public static void processCallingConstraintsInternal(AstSSAPropagationCallGraphBuilder builder, CGNode caller, SSAAbstractInvokeInstruction instruction, CGNode target,
InstanceKey[][] constParams, PointerKey uniqueCatchKey) {
IR sourceIR = builder.getCFAContextInterpreter().getIR(caller);
SymbolTable sourceST = sourceIR.getSymbolTable();

IR targetIR = getCFAContextInterpreter().getIR(target);
IR targetIR = builder.getCFAContextInterpreter().getIR(target);
SymbolTable targetST = targetIR.getSymbolTable();

JSConstraintVisitor targetVisitor = null;
Expand All @@ -1000,7 +1008,7 @@ protected void processCallingConstraints(CGNode caller, SSAAbstractInvokeInstruc
for (int n = 0; vns != null && n < vns.length; n++) {
if ("arguments".equals(vns[n])) {
av = v;
targetVisitor = makeVisitor(target);
targetVisitor = (JSConstraintVisitor) builder.makeVisitor(target);
break;
}
}
Expand All @@ -1015,21 +1023,21 @@ protected void processCallingConstraints(CGNode caller, SSAAbstractInvokeInstruc

// pass actual arguments to formals in the normal way
for (int i = 0; i < Math.min(paramCount, argCount); i++) {
InstanceKey[] fn = new InstanceKey[] { getInstanceKeyForConstant(JavaScriptTypes.String, ""+(i-num_pseudoargs)) };
PointerKey F = getTargetPointerKey(target, i);
InstanceKey[] fn = new InstanceKey[] { builder.getInstanceKeyForConstant(JavaScriptTypes.String, ""+(i-num_pseudoargs)) };
PointerKey F = builder.getTargetPointerKey(target, i);

if (constParams != null && constParams[i] != null) {
for (int j = 0; j < constParams[i].length; j++) {
system.newConstraint(F, constParams[i][j]);
builder.getSystem().newConstraint(F, constParams[i][j]);
}

if (av != -1 && i >= num_pseudoargs) {
targetVisitor.newFieldWrite(target, av, fn, constParams[i]);
}

} else {
PointerKey A = getPointerKeyForLocal(caller, instruction.getUse(i));
system.newConstraint(F, (F instanceof FilteredPointerKey) ? filterOperator : assignOperator, A);
PointerKey A = builder.getPointerKeyForLocal(caller, instruction.getUse(i));
builder.getSystem().newConstraint(F, (F instanceof FilteredPointerKey) ? builder.filterOperator : assignOperator, A);

if (av != -1 && i >= num_pseudoargs) {
targetVisitor.newFieldWrite(target, av, fn, F);
Expand All @@ -1041,11 +1049,11 @@ protected void processCallingConstraints(CGNode caller, SSAAbstractInvokeInstruc
if (paramCount < argCount) {
if (av != -1) {
for (int i = paramCount; i < argCount; i++) {
InstanceKey[] fn = new InstanceKey[] { getInstanceKeyForConstant(JavaScriptTypes.String, ""+(i-num_pseudoargs)) };
InstanceKey[] fn = new InstanceKey[] { builder.getInstanceKeyForConstant(JavaScriptTypes.String, ""+(i-num_pseudoargs)) };
if (constParams != null && constParams[i] != null && i >= num_pseudoargs) {
targetVisitor.newFieldWrite(target, av, fn, constParams[i]);
} else if(i >= num_pseudoargs) {
PointerKey A = getPointerKeyForLocal(caller, instruction.getUse(i));
PointerKey A = builder.getPointerKeyForLocal(caller, instruction.getUse(i));
targetVisitor.newFieldWrite(target, av, fn, A);
}
}
Expand All @@ -1055,37 +1063,37 @@ protected void processCallingConstraints(CGNode caller, SSAAbstractInvokeInstruc
// extra formal parameters get null (extra args are ignored here)
else if (argCount < paramCount) {
int nullvn = sourceST.getNullConstant();
DefUse sourceDU = getCFAContextInterpreter().getDU(caller);
InstanceKey[] nullkeys = getInvariantContents(sourceST, sourceDU, caller, nullvn, this);
DefUse sourceDU = builder.getCFAContextInterpreter().getDU(caller);
InstanceKey[] nullkeys = builder.getInvariantContents(sourceST, sourceDU, caller, nullvn, builder);
for (int i = argCount; i < paramCount; i++) {
PointerKey F = getPointerKeyForLocal(target, targetST.getParameter(i));
PointerKey F = builder.getPointerKeyForLocal(target, targetST.getParameter(i));
for (int k = 0; k < nullkeys.length; k++) {
system.newConstraint(F, nullkeys[k]);
builder.getSystem().newConstraint(F, nullkeys[k]);
}
}
}

// write `length' in argument objects
if (av != -1) {
InstanceKey[] svn = new InstanceKey[] { getInstanceKeyForConstant(JavaScriptTypes.Number, argCount-1) };
InstanceKey[] lnv = new InstanceKey[] { getInstanceKeyForConstant(JavaScriptTypes.String, "length") };
InstanceKey[] svn = new InstanceKey[] { builder.getInstanceKeyForConstant(JavaScriptTypes.Number, argCount-1) };
InstanceKey[] lnv = new InstanceKey[] { builder.getInstanceKeyForConstant(JavaScriptTypes.String, "length") };
targetVisitor.newFieldWrite(target, av, lnv, svn);
}

// return values
if (instruction.getDef(0) != -1) {
PointerKey RF = getPointerKeyForReturnValue(target);
PointerKey RA = getPointerKeyForLocal(caller, instruction.getDef(0));
system.newConstraint(RA, assignOperator, RF);
PointerKey RF = builder.getPointerKeyForReturnValue(target);
PointerKey RA = builder.getPointerKeyForLocal(caller, instruction.getDef(0));
builder.getSystem().newConstraint(RA, assignOperator, RF);
}

PointerKey EF = getPointerKeyForExceptionalReturnValue(target);
PointerKey EF = builder.getPointerKeyForExceptionalReturnValue(target);
if (SHORT_CIRCUIT_SINGLE_USES && uniqueCatchKey != null) {
// e has exactly one use. so, represent e implicitly
system.newConstraint(uniqueCatchKey, assignOperator, EF);
builder.getSystem().newConstraint(uniqueCatchKey, assignOperator, EF);
} else {
PointerKey EA = getPointerKeyForLocal(caller, instruction.getDef(1));
system.newConstraint(EA, assignOperator, EF);
PointerKey EA = builder.getPointerKeyForLocal(caller, instruction.getDef(1));
builder.getSystem().newConstraint(EA, assignOperator, EF);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
import com.ibm.wala.util.intset.IntSetUtil;
import com.ibm.wala.util.intset.MutableIntSet;
import com.ibm.wala.util.intset.MutableMapping;
import com.ibm.wala.util.strings.Atom;

public abstract class AstSSAPropagationCallGraphBuilder extends SSAPropagationCallGraphBuilder {

Expand Down Expand Up @@ -112,6 +113,8 @@ protected boolean isUncataloguedField(IClass type, String fieldName) {
// /////////////////////////////////////////////////////////////////////////


public abstract GlobalObjectKey getGlobalObject(Atom language);

protected AstSSAPropagationCallGraphBuilder(IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache,
PointerKeyFactory pointerKeyFactory) {
super(cha, options, cache, pointerKeyFactory);
Expand Down Expand Up @@ -326,7 +329,8 @@ public boolean hasNoInterestingUses(CGNode node, int vn, DefUse du) {
//
// /////////////////////////////////////////////////////////////////////////

protected ConstraintVisitor makeVisitor(ExplicitCallGraph.ExplicitNode node) {
@Override
public ConstraintVisitor makeVisitor(CGNode node) {
return new AstConstraintVisitor(this, node);
}

Expand Down Expand Up @@ -1259,5 +1263,4 @@ public void action(AbstractFieldPointerKey fieldKey) {
*/
protected abstract boolean sameMethod(final CGNode opNode, final String definingMethod);


}
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@
import com.ibm.wala.util.strings.Atom;

/**
* A ContextSelector implementation adapted to work for analysi across
* A ContextSelector implementation adapted to work for analysis across
* multiple languages. This context selector delegates to one of several
* child selectors based on the language of the code body for which a
* context is being selected.
*
* This provides a convenient way to integrate multiple, lanuage-specific
* This provides a convenient way to integrate multiple, language-specific
* specialized context policies---such as the ones used for clone() in
* Java and runtime primitives in JavaScript.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@
*/
public class CrossLanguageInstanceKeys implements InstanceKeyFactory {

private final Map languageSelectors;
private final Map<Atom,InstanceKeyFactory> languageSelectors;

public CrossLanguageInstanceKeys(Map languageSelectors) {
public CrossLanguageInstanceKeys(Map<Atom,InstanceKeyFactory> languageSelectors) {
this.languageSelectors = languageSelectors;
}

Expand All @@ -49,11 +49,11 @@ private static Atom getLanguage(NewSiteReference site) {
// }

private InstanceKeyFactory getSelector(NewSiteReference site) {
return (InstanceKeyFactory)languageSelectors.get(getLanguage(site));
return languageSelectors.get(getLanguage(site));
}

private InstanceKeyFactory getSelector(TypeReference type) {
return (InstanceKeyFactory)languageSelectors.get(getLanguage(type));
return languageSelectors.get(getLanguage(type));
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import com.ibm.wala.classLoader.CallSiteReference;
import com.ibm.wala.classLoader.IClass;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.classLoader.Language;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.callgraph.MethodTargetSelector;
import com.ibm.wala.types.MethodReference;
Expand All @@ -36,9 +37,9 @@ public class CrossLanguageMethodTargetSelector
implements MethodTargetSelector
{

private final Map languageSelectors;
private final Map<Atom,MethodTargetSelector> languageSelectors;

public CrossLanguageMethodTargetSelector(Map languageSelectors) {
public CrossLanguageMethodTargetSelector(Map<Atom, MethodTargetSelector> languageSelectors) {
this.languageSelectors = languageSelectors;
}

Expand All @@ -54,7 +55,7 @@ private static Atom getLanguage(CallSiteReference site) {
}

private MethodTargetSelector getSelector(CallSiteReference site) {
return (MethodTargetSelector)languageSelectors.get(getLanguage(site));
return languageSelectors.get(getLanguage(site));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@

public abstract class CrossLanguageSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraphBuilder {

private final TargetLanguageSelector<ConstraintVisitor, ExplicitCallGraph.ExplicitNode> visitors;
private final TargetLanguageSelector<ConstraintVisitor, CGNode> visitors;

private final TargetLanguageSelector<InterestingVisitor, Integer> interesting;

protected abstract TargetLanguageSelector<ConstraintVisitor, ExplicitCallGraph.ExplicitNode> makeMainVisitorSelector();
protected abstract TargetLanguageSelector<ConstraintVisitor, CGNode> makeMainVisitorSelector();

protected abstract TargetLanguageSelector<InterestingVisitor, Integer> makeInterestingVisitorSelector();

Expand Down Expand Up @@ -69,7 +69,7 @@ protected InterestingVisitor makeInterestingVisitor(CGNode node, int vn) {
}

@Override
protected ConstraintVisitor makeVisitor(ExplicitCallGraph.ExplicitNode node) {
public ConstraintVisitor makeVisitor(CGNode node) {
return visitors.get(getLanguage(node), node);
}

Expand Down
Loading

0 comments on commit 0975441

Please sign in to comment.