more global object handling; needs documentation
git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@4324 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
parent
549c3d2775
commit
8ce7db97ea
|
@ -23,6 +23,7 @@ import java.util.Map;
|
|||
import org.mozilla.javascript.tools.ToolErrorReporter;
|
||||
|
||||
import com.ibm.wala.cast.js.html.MappedSourceModule;
|
||||
import com.ibm.wala.cast.js.ipa.callgraph.JSSSAPropagationCallGraphBuilder;
|
||||
import com.ibm.wala.cast.js.loader.JavaScriptLoader;
|
||||
import com.ibm.wala.cast.js.types.JavaScriptTypes;
|
||||
import com.ibm.wala.cast.tree.CAst;
|
||||
|
@ -1122,7 +1123,7 @@ public class RhinoToAstTranslator {
|
|||
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl("base")), Ast.makeConstant(null)),
|
||||
makeCall(fun, base, firstParamInParens, context)));
|
||||
else
|
||||
return makeCall(fun, Ast.makeConstant(null), firstParamInParens, context);
|
||||
return makeCall(fun, makeVarRef(JSSSAPropagationCallGraphBuilder.GLOBAL_OBJ_VAR_NAME), firstParamInParens, context);
|
||||
} else {
|
||||
return Ast.makeNode(CAstNode.PRIMITIVE, gatherChildren(n, context, 1));
|
||||
}
|
||||
|
|
|
@ -1 +1,5 @@
|
|||
z = (function foo() { return this; })();
|
||||
function biz(p) { return p; }
|
||||
|
||||
var z = (function foo() { return this; })();
|
||||
|
||||
var x = z.biz(3);
|
|
@ -333,6 +333,14 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
|||
}
|
||||
|
||||
|
||||
private static final Object[][] assertionsForGlobalObj = new Object[][] {
|
||||
new Object[] { ROOT, new String[] { "tests/global_object.js" } },
|
||||
new Object[] { "suffix:global_object.js", new String[] { "suffix:biz" } } };
|
||||
|
||||
@Test
|
||||
public void testGlobalObjPassing() throws IOException, IllegalArgumentException, CancelException {
|
||||
Util.makeScriptCG("tests", "global_object.js");
|
||||
}
|
||||
protected IVector<Set<Pair<CGNode, Integer>>> computeIkIdToVns(PointerAnalysis pa) {
|
||||
|
||||
// Created by reversing the points to mapping for local pointer keys.
|
||||
|
|
|
@ -19,4 +19,7 @@ public class GlobalObjectKey implements InstanceKey {
|
|||
return concreteType;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "JS Global Object";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,6 +71,7 @@ import com.ibm.wala.util.intset.IntSetAction;
|
|||
import com.ibm.wala.util.intset.MutableMapping;
|
||||
import com.ibm.wala.util.intset.MutableSparseIntSet;
|
||||
import com.ibm.wala.util.intset.OrdinalSet;
|
||||
import com.ibm.wala.util.strings.Atom;
|
||||
|
||||
public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraphBuilder {
|
||||
|
||||
|
@ -78,6 +79,25 @@ public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraph
|
|||
|
||||
public static final boolean DEBUG_TYPE_INFERENCE = false;
|
||||
|
||||
/**
|
||||
* name to be used internally to pass around the global object
|
||||
*/
|
||||
public static final String GLOBAL_OBJ_VAR_NAME = "__WALA__int3rnal__global";
|
||||
|
||||
/**
|
||||
* is field a direct (WALA-internal) reference to the global object?
|
||||
*/
|
||||
private static boolean directGlobalObjectRef(FieldReference field) {
|
||||
return field.getName().toString().endsWith(GLOBAL_OBJ_VAR_NAME);
|
||||
}
|
||||
|
||||
private static FieldReference makeNonGlobalFieldReference(FieldReference field) {
|
||||
String nonGlobalFieldName = field.getName().toString().substring(7);
|
||||
field = FieldReference.findOrCreate(JavaScriptTypes.Root, Atom.findOrCreateUnicodeAtom(nonGlobalFieldName), JavaScriptTypes.Root);
|
||||
return field;
|
||||
}
|
||||
|
||||
|
||||
private URL scriptBaseURL;
|
||||
|
||||
public URL getBaseURL() {
|
||||
|
@ -210,7 +230,7 @@ public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraph
|
|||
|
||||
public static class JSImplicitPointsToSetVisitor extends AstImplicitPointsToSetVisitor implements
|
||||
com.ibm.wala.cast.js.ssa.InstructionVisitor {
|
||||
|
||||
|
||||
public JSImplicitPointsToSetVisitor(AstPointerAnalysisImpl analysis, LocalPointerKey lpk) {
|
||||
super(analysis, lpk);
|
||||
}
|
||||
|
@ -246,16 +266,15 @@ public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraph
|
|||
@Override
|
||||
public void visitAstGlobalRead(AstGlobalRead instruction) {
|
||||
JSPointerAnalysisImpl jsAnalysis = (JSPointerAnalysisImpl) analysis;
|
||||
pointsToSet = analysis.computeImplicitPointsToSetAtGet(node, instruction.getDeclaredField(), -1, true);
|
||||
FieldReference field = instruction.getDeclaredField();
|
||||
FieldReference field = makeNonGlobalFieldReference(instruction.getDeclaredField());
|
||||
IField f = jsAnalysis.builder.getCallGraph().getClassHierarchy().resolveField(field);
|
||||
assert f != null;
|
||||
// if (f == null) {
|
||||
// pointsToSet = OrdinalSet.empty();
|
||||
// }
|
||||
MutableSparseIntSet S = MutableSparseIntSet.makeEmpty();
|
||||
InstanceKey ik = ((JSSSAPropagationCallGraphBuilder)jsAnalysis.builder).globalObject;
|
||||
PointerKey fkey = analysis.getHeapModel().getPointerKeyForInstanceField(ik, f);
|
||||
InstanceKey globalObj = ((JSSSAPropagationCallGraphBuilder) jsAnalysis.builder).globalObject;
|
||||
PointerKey fkey = analysis.getHeapModel().getPointerKeyForInstanceField(globalObj, f);
|
||||
if (fkey != null) {
|
||||
OrdinalSet pointees = analysis.getPointsToSet(fkey);
|
||||
IntSet set = pointees.getBackingSet();
|
||||
|
@ -264,7 +283,6 @@ public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraph
|
|||
}
|
||||
}
|
||||
pointsToSet = new OrdinalSet<InstanceKey>(S, analysis.getInstanceKeyMapping());
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -362,7 +380,9 @@ public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraph
|
|||
@Override
|
||||
public void visitAstGlobalRead(AstGlobalRead instruction) {
|
||||
int lval = instruction.getDef();
|
||||
FieldReference field = instruction.getDeclaredField();
|
||||
FieldReference field = makeNonGlobalFieldReference(instruction.getDeclaredField());
|
||||
// TODO new field reference should be FieldReference.findOrCreate(JavaScriptTypes.Root, Atom.findOrCreateUnicodeAtom(field), JavaScriptTypes.Root)
|
||||
// strip off "global " from field name
|
||||
// skip getfields of primitive type (optimisation)
|
||||
// this can't happen in JavaScript...right?
|
||||
// if (field.getFieldType().isPrimitiveType()) {
|
||||
|
@ -370,7 +390,6 @@ public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraph
|
|||
// }
|
||||
PointerKey def = getPointerKeyForLocal(lval);
|
||||
assert def != null;
|
||||
|
||||
IField f = getClassHierarchy().resolveField(field);
|
||||
// if (f == null &&
|
||||
// callGraph.getFakeRootNode().getMethod().getDeclaringClass().getReference().equals(field.getDeclaringClass()))
|
||||
|
@ -387,18 +406,24 @@ public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraph
|
|||
if (hasNoInterestingUses(lval)) {
|
||||
system.recordImplicitPointsToSet(def);
|
||||
} else {
|
||||
InstanceKey ik = getBuilder().globalObject;
|
||||
system.findOrCreateIndexForInstanceKey(ik);
|
||||
PointerKey p = getPointerKeyForInstanceField(ik, f);
|
||||
system.newConstraint(def, assignOperator, p);
|
||||
InstanceKey globalObj = getBuilder().globalObject;
|
||||
if (directGlobalObjectRef(field)) {
|
||||
// points-to set is just the global object
|
||||
system.newConstraint(def, globalObj);
|
||||
} else {
|
||||
system.findOrCreateIndexForInstanceKey(globalObj);
|
||||
PointerKey p = getPointerKeyForInstanceField(globalObj, f);
|
||||
system.newConstraint(def, assignOperator, p);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void visitAstGlobalWrite(AstGlobalWrite instruction) {
|
||||
int rval = instruction.getVal();
|
||||
FieldReference field = instruction.getDeclaredField();
|
||||
FieldReference field = makeNonGlobalFieldReference(instruction.getDeclaredField());
|
||||
|
||||
// skip putfields of primitive type
|
||||
// if (field.getFieldType().isPrimitiveType()) {
|
||||
|
|
|
@ -217,7 +217,6 @@ public class PointerAnalysisImpl extends AbstractPointerAnalysis {
|
|||
LocalPointerKey lpk = (LocalPointerKey) key;
|
||||
CGNode node = lpk.getNode();
|
||||
IR ir = node.getIR();
|
||||
System.err.println(ir);
|
||||
DefUse du = node.getDU();
|
||||
if (((SSAPropagationCallGraphBuilder) builder).contentsAreInvariant(ir.getSymbolTable(), du, lpk.getValueNumber())) {
|
||||
// cons up the points-to set for invariant contents
|
||||
|
|
Loading…
Reference in New Issue