documentation of global object handling

git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@4326 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
msridhar1 2012-01-06 21:24:25 +00:00
parent 02c1b80605
commit eb73fac9e4
3 changed files with 28 additions and 39 deletions

View File

@ -1122,8 +1122,10 @@ public class RhinoToAstTranslator {
Ast.makeNode(CAstNode.BLOCK_EXPR,
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl("base")), Ast.makeConstant(null)),
makeCall(fun, base, firstParamInParens, context)));
else
else {
// pass the global object as the receiver argument
return makeCall(fun, makeVarRef(JSSSAPropagationCallGraphBuilder.GLOBAL_OBJ_VAR_NAME), firstParamInParens, context);
}
} else {
return Ast.makeNode(CAstNode.PRIMITIVE, gatherChildren(n, context, 1));
}

View File

@ -4,7 +4,9 @@ import com.ibm.wala.classLoader.IClass;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
/**
* represents the JavaScript global object
* Represents the JavaScript global object.
*
* @see JSSSAPropagationCallGraphBuilder
*/
public class GlobalObjectKey implements InstanceKey {

View File

@ -20,6 +20,7 @@ import com.ibm.wala.cast.ir.ssa.AstGlobalWrite;
import com.ibm.wala.cast.ir.ssa.AstIsDefinedInstruction;
import com.ibm.wala.cast.ir.ssa.EachElementHasNextInstruction;
import com.ibm.wala.cast.js.analysis.typeInference.JSTypeInference;
import com.ibm.wala.cast.js.ipa.callgraph.JSSSAPropagationCallGraphBuilder.JSPointerAnalysisImpl.JSImplicitPointsToSetVisitor;
import com.ibm.wala.cast.js.ssa.InstructionVisitor;
import com.ibm.wala.cast.js.ssa.JavaScriptCheckReference;
import com.ibm.wala.cast.js.ssa.JavaScriptInstanceOf;
@ -73,6 +74,23 @@ import com.ibm.wala.util.intset.MutableSparseIntSet;
import com.ibm.wala.util.intset.OrdinalSet;
import com.ibm.wala.util.strings.Atom;
/**
* Specialized pointer analysis constraint generation for JavaScript.
*
* <h2>Global object handling</h2>
*
* The global object is represented by a {@link GlobalObjectKey} stored in
* {@link #globalObject}. {@link AstGlobalRead} and {@link AstGlobalWrite}
* instructions are treated as accessing properties of the global object; see
* {@link JSConstraintVisitor#visitAstGlobalRead(AstGlobalRead)},
* {@link JSConstraintVisitor#visitAstGlobalWrite(AstGlobalWrite)}, and
* {@link JSImplicitPointsToSetVisitor#visitAstGlobalRead(AstGlobalRead)}.
* Finally, we need to represent direct flow of the global object to handle
* receiver argument semantics (see
* {@link org.mozilla.javascript.RhinoToAstTranslator}). To do so, we create a
* reference to a global named {@link #GLOBAL_OBJ_VAR_NAME}, which is handled
* specially in {@link JSConstraintVisitor#visitAstGlobalRead(AstGlobalRead)}.
*/
public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraphBuilder {
public static final boolean DEBUG_LEXICAL = false;
@ -90,14 +108,14 @@ public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraph
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);
field = FieldReference.findOrCreate(JavaScriptTypes.Root, Atom.findOrCreateUnicodeAtom(nonGlobalFieldName),
JavaScriptTypes.Root);
return field;
}
private URL scriptBaseURL;
public URL getBaseURL() {
@ -267,11 +285,9 @@ public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraph
public void visitAstGlobalRead(AstGlobalRead instruction) {
JSPointerAnalysisImpl jsAnalysis = (JSPointerAnalysisImpl) analysis;
FieldReference field = makeNonGlobalFieldReference(instruction.getDeclaredField());
assert !directGlobalObjectRef(field);
IField f = jsAnalysis.builder.getCallGraph().getClassHierarchy().resolveField(field);
assert f != null;
// if (f == null) {
// pointsToSet = OrdinalSet.empty();
// }
MutableSparseIntSet S = MutableSparseIntSet.makeEmpty();
InstanceKey globalObj = ((JSSSAPropagationCallGraphBuilder) jsAnalysis.builder).globalObject;
PointerKey fkey = analysis.getHeapModel().getPointerKeyForInstanceField(globalObj, f);
@ -381,28 +397,10 @@ public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraph
public void visitAstGlobalRead(AstGlobalRead instruction) {
int lval = instruction.getDef();
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()) {
// return;
// }
PointerKey def = getPointerKeyForLocal(lval);
assert def != null;
IField f = getClassHierarchy().resolveField(field);
// if (f == null &&
// callGraph.getFakeRootNode().getMethod().getDeclaringClass().getReference().equals(field.getDeclaringClass()))
// {
// f =
// callGraph.getFakeRootNode().getMethod().getDeclaringClass().getField(field.getName());
// }
//
// if (f == null) {
// return;
// }
assert f != null : "could not resolve referenced global " + field;
if (hasNoInterestingUses(lval)) {
system.recordImplicitPointsToSet(def);
} else {
@ -419,24 +417,11 @@ public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraph
}
@Override
public void visitAstGlobalWrite(AstGlobalWrite instruction) {
int rval = instruction.getVal();
FieldReference field = makeNonGlobalFieldReference(instruction.getDeclaredField());
// skip putfields of primitive type
// if (field.getFieldType().isPrimitiveType()) {
// return;
// }
IField f = getClassHierarchy().resolveField(field);
// if (f == null) {
// if (DEBUG) {
// System.err.println("Could not resolve field " + field);
// }
// Warnings.add(FieldResolutionFailure.create(field));
// return;
// }
assert f != null : "could not resolve referenced global " + field;
assert !f.getFieldTypeReference().isPrimitiveType();
InstanceKey globalObj = getBuilder().globalObject;