type in CAst var decls

This commit is contained in:
Julian Dolby 2014-03-16 18:05:49 -04:00
parent bfd999e03b
commit 893f4b7308
21 changed files with 327 additions and 158 deletions

View File

@ -869,7 +869,7 @@ public class PolyglotJava2CAstTranslator {
handleThrowsFromCall(ctorInst, n, wc);
return makeNode(wc, fFactory, n, CAstNode.LOCAL_SCOPE, makeNode(wc, fFactory, n, CAstNode.BLOCK_EXPR, makeNode(wc, fFactory,
n, CAstNode.DECL_STMT, fFactory.makeConstant(new InternalCAstSymbol(tmpName, true)), newNode), callNode, makeNode(wc,
n, CAstNode.DECL_STMT, fFactory.makeConstant(new InternalCAstSymbol(tmpName, getTypeDict().getCAstTypeFor(n.type()), true)), newNode), callNode, makeNode(wc,
fFactory, n, CAstNode.VAR, fFactory.makeConstant(tmpName))));
}
@ -1280,7 +1280,7 @@ public class PolyglotJava2CAstTranslator {
public CAstNode visit(Synchronized s, WalkContext wc) {
CAstNode exprNode = walkNodes(s.expr(), wc);
String exprName = fFactory.makeUnique();
CAstNode declStmt = makeNode(wc, fFactory, s, CAstNode.DECL_STMT, fFactory.makeConstant(new CAstSymbolImpl(exprName, true)),
CAstNode declStmt = makeNode(wc, fFactory, s, CAstNode.DECL_STMT, fFactory.makeConstant(new CAstSymbolImpl(exprName, getTypeDict().getCAstTypeFor(s.expr().type()), true)),
exprNode);
CAstNode monitorEnterNode = makeNode(wc, fFactory, s, CAstNode.MONITOR_ENTER, makeNode(wc, fFactory, s, CAstNode.VAR,
fFactory.makeConstant(exprName)));
@ -1362,7 +1362,7 @@ public class PolyglotJava2CAstTranslator {
boolean isFinal = ld.flags().flags().isFinal();
return makeNode(wc, fFactory, ld, CAstNode.DECL_STMT, fFactory.makeConstant(new CAstSymbolImpl(ld.name().id().toString(), isFinal,
return makeNode(wc, fFactory, ld, CAstNode.DECL_STMT, fFactory.makeConstant(new CAstSymbolImpl(ld.name().id().toString(), getTypeDict().getCAstTypeFor(type), isFinal,
defaultValue)), initNode);
}

View File

@ -12,11 +12,13 @@ package com.ibm.wala.cast.java.examples.ast;
import java.util.Map;
import com.ibm.wala.cast.java.types.JavaPrimitiveTypeMap;
import com.ibm.wala.cast.tree.CAst;
import com.ibm.wala.cast.tree.CAstControlFlowMap;
import com.ibm.wala.cast.tree.CAstEntity;
import com.ibm.wala.cast.tree.CAstNode;
import com.ibm.wala.cast.tree.CAstSourcePositionMap;
import com.ibm.wala.cast.tree.CAstType;
import com.ibm.wala.cast.tree.impl.CAstOperator;
import com.ibm.wala.cast.tree.rewrite.CAstRewriter;
import com.ibm.wala.classLoader.CallSiteReference;
@ -219,7 +221,7 @@ public class SynchronizedBlockDuplicator extends
// the conditional test
CAstNode test = Ast.makeNode(CAstNode.CALL, Ast.makeNode(CAstNode.VOID), Ast.makeConstant(f),
Ast.makeNode(CAstNode.VAR, Ast.makeConstant(varName)));
Ast.makeNode(CAstNode.VAR, Ast.makeConstant(varName), Ast.makeConstant(JavaPrimitiveTypeMap.lookupType("boolean"))));
// the new if conditional
return Ast.makeNode(CAstNode.IF_STMT, test, copyNodes(n, cfg, new SyncContext(true, n, c), nodeMap),

View File

@ -622,8 +622,8 @@ public abstract class JavaSourceLoaderImpl extends ClassLoaderImpl {
}
@Override
public AstLexicalRead LexicalRead(int lhs, String definer, String globalName) {
return new AstLexicalRead(lhs, definer, globalName);
public AstLexicalRead LexicalRead(int lhs, String definer, String globalName, TypeReference type) {
return new AstLexicalRead(lhs, definer, globalName, type);
}
@Override
@ -637,8 +637,8 @@ public abstract class JavaSourceLoaderImpl extends ClassLoaderImpl {
}
@Override
public AstLexicalWrite LexicalWrite(String definer, String globalName, int rhs) {
return new AstLexicalWrite(definer, globalName, rhs);
public AstLexicalWrite LexicalWrite(String definer, String globalName, TypeReference type, int rhs) {
return new AstLexicalWrite(definer, globalName, type, rhs);
}
public SSAThrowInstruction NonExceptingThrowInstruction(int exception) {

View File

@ -14,6 +14,7 @@
package com.ibm.wala.cast.java.translator;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
@ -207,7 +208,7 @@ public class JavaCAst2IRTranslator extends AstTranslator {
}
@Override
protected void doGlobalWrite(WalkContext context, String name, int rval) {
protected void doGlobalWrite(WalkContext context, String name, TypeReference type, int rval) {
Assertions.UNREACHABLE("doGlobalWrite() called for Java code???");
}
@ -408,6 +409,40 @@ processExceptions(n, context);
}
}
private CAstType getType(final String name) {
return new CAstType.Class() {
@Override
public Collection getSupertypes() {
return Collections.emptySet();
}
@Override
public String getName() {
return name;
}
@Override
public boolean isInterface() {
return false;
}
@Override
public Collection<CAstQualifier> getQualifiers() {
return Collections.emptySet();
}
};
}
@Override
protected CAstType topType() {
return getType("java.lang.Object");
}
@Override
protected CAstType exceptionType() {
return getType("java.lang.Exception");
}
}

View File

@ -499,8 +499,7 @@ public class RhinoToAstTranslator {
@Override
public CAstType getType() {
Assertions.UNREACHABLE("JuliansUnnamedCAstEntity$2.getType()");
return null;
return JSAstTranslator.Any;
}
}
@ -818,7 +817,7 @@ public class RhinoToAstTranslator {
CAstNode object = visit(node.getIteratedObject(), arg);
String tempName = "for in loop temp";
CAstNode[] loopHeader = new CAstNode[]{
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl(tempName))),
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl(tempName, JSAstTranslator.Any))),
Ast.makeNode(CAstNode.ASSIGN, Ast.makeNode(CAstNode.VAR, Ast.makeConstant(tempName)), object)
};
@ -846,12 +845,12 @@ public class RhinoToAstTranslator {
if (isLet) {
initNode =
Ast.makeNode(CAstNode.DECL_STMT,
Ast.makeConstant(new CAstSymbolImpl(init.getTarget().getString())),
Ast.makeConstant(new CAstSymbolImpl(init.getTarget().getString(), JSAstTranslator.Any)),
Ast.makeNode(CAstNode.EACH_ELEMENT_GET, Ast.makeNode(CAstNode.VAR, Ast.makeConstant(tempName))));
} else {
arg.addNameDecl(
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl(init.getTarget().getString())),
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl(init.getTarget().getString(), JSAstTranslator.Any)),
readName(arg, null, "$$undefined")));
initNode =
@ -939,10 +938,10 @@ public class RhinoToAstTranslator {
Ast.makeNode(CAstNode.LOCAL_SCOPE,
Ast.makeNode(CAstNode.BLOCK_EXPR,
Ast.makeNode(CAstNode.DECL_STMT,
Ast.makeConstant(new CAstSymbolImpl(operationReceiverName(thisBaseVarNum))),
Ast.makeConstant(new CAstSymbolImpl(operationReceiverName(thisBaseVarNum), JSAstTranslator.Any)),
Ast.makeConstant(null)),
Ast.makeNode(CAstNode.DECL_STMT,
Ast.makeConstant(new CAstSymbolImpl(operationElementName(thisBaseVarNum))),
Ast.makeConstant(new CAstSymbolImpl(operationElementName(thisBaseVarNum), JSAstTranslator.Any)),
Ast.makeConstant(null)),
fun,
makeCall(operationElementVar(thisBaseVarNum), operationReceiverVar(thisBaseVarNum), args, context, "dispatch")));
@ -1010,7 +1009,7 @@ public class RhinoToAstTranslator {
CAstNode r = visit(node.getRight(), arg);
return Ast.makeNode(CAstNode.LOCAL_SCOPE,
Ast.makeNode(CAstNode.BLOCK_EXPR,
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl("or temp")), l),
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl("or temp", JSAstTranslator.Any)), l),
Ast.makeNode(CAstNode.IF_EXPR,
Ast.makeNode(CAstNode.VAR, Ast.makeConstant("or temp")),
Ast.makeNode(CAstNode.VAR, Ast.makeConstant("or temp")),
@ -1020,7 +1019,7 @@ public class RhinoToAstTranslator {
CAstNode r = visit(node.getRight(), arg);
return Ast.makeNode(CAstNode.LOCAL_SCOPE,
Ast.makeNode(CAstNode.BLOCK_EXPR,
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl("and temp")), l),
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl("and temp", JSAstTranslator.Any)), l),
Ast.makeNode(CAstNode.IF_EXPR,
Ast.makeNode(CAstNode.VAR, Ast.makeConstant("and temp")),
r,
@ -1116,7 +1115,7 @@ public class RhinoToAstTranslator {
for(VariableInitializer init : decl.getVariables()) {
stmts[i++] =
Ast.makeNode(CAstNode.DECL_STMT,
Ast.makeConstant(new CAstSymbolImpl(init.getTarget().getString())),
Ast.makeConstant(new CAstSymbolImpl(init.getTarget().getString(), JSAstTranslator.Any)),
visit(init, arg));
}
stmts[i++] = visit(node.getBody(), arg);
@ -1362,7 +1361,7 @@ public class RhinoToAstTranslator {
arg.addNameDecl(
noteSourcePosition(
arg,
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl(init.getTarget().getString())),
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl(init.getTarget().getString(), JSAstTranslator.Any)),
readName(arg, null, "$$undefined")),
node));

View File

@ -16,6 +16,7 @@ import com.ibm.wala.cast.js.loader.JavaScriptLoaderFactory;
import com.ibm.wala.cast.js.ssa.JSInstructionFactory;
import com.ibm.wala.cast.js.translator.JSAstTranslator;
import com.ibm.wala.cast.js.translator.JavaScriptTranslatorFactory;
import com.ibm.wala.cast.js.types.JavaScriptTypes;
import com.ibm.wala.cast.tree.CAst;
import com.ibm.wala.cast.tree.CAstEntity;
import com.ibm.wala.cast.tree.CAstNode;
@ -25,6 +26,7 @@ import com.ibm.wala.cast.tree.rewrite.CAstRewriterFactory;
import com.ibm.wala.cast.tree.visit.CAstVisitor;
import com.ibm.wala.classLoader.IClassLoader;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.types.TypeReference;
public class WebPageLoaderFactory extends JavaScriptLoaderFactory {
@ -53,12 +55,12 @@ public class WebPageLoaderFactory extends JavaScriptLoaderFactory {
}
@Override
protected int doGlobalRead(CAstNode n, WalkContext context, String name) {
protected int doGlobalRead(CAstNode n, WalkContext context, String name, TypeReference type) {
int result = context.currentScope().allocateTempValue();
if (isNestedWithinScriptBody(context) && ! "$$undefined".equals(name) && ! "window".equals(name)) {
// check if field is defined on 'window'
int windowVal = isScriptBody(context)? super.doLocalRead(context, "this"): super.doGlobalRead(n, context, "window");
int windowVal = isScriptBody(context)? super.doLocalRead(context, "this", JavaScriptTypes.Root): super.doGlobalRead(n, context, "window", type);
int isDefined = context.currentScope().allocateTempValue();
context.currentScope().getConstantValue(name);
doIsFieldDefined(context, isDefined, windowVal, Ast.makeConstant(name));
@ -79,7 +81,7 @@ public class WebPageLoaderFactory extends JavaScriptLoaderFactory {
// read global
context.cfg().newBlock(false);
PreBasicBlock falseB = context.cfg().getCurrentBlock();
int sr = super.doGlobalRead(n, context, name);
int sr = super.doGlobalRead(n, context, name, type);
context.cfg().addInstruction(((JSInstructionFactory) insts).AssignInstruction(result, sr));
// end
@ -91,19 +93,19 @@ public class WebPageLoaderFactory extends JavaScriptLoaderFactory {
return result;
} else {
return super.doGlobalRead(n, context, name);
return super.doGlobalRead(n, context, name, type);
}
}
@Override
protected void doLocalWrite(WalkContext context, String nm, int rval) {
protected void doLocalWrite(WalkContext context, String nm, TypeReference type, int rval) {
if (isScriptBody(context)) {
int windowVal = super.doLocalRead(context, "this");
int windowVal = super.doLocalRead(context, "this", type);
context.currentScope().getConstantValue(nm);
context.cfg().addInstruction(((JSInstructionFactory) insts).PutInstruction(windowVal, rval, nm));
}
super.doLocalWrite(context, nm, rval);
super.doLocalWrite(context, nm, type, rval);
}
@Override
@ -113,7 +115,7 @@ public class WebPageLoaderFactory extends JavaScriptLoaderFactory {
CAstEntity fn = (CAstEntity) n.getChild(0).getValue();
int fnValue = context.currentScope().lookup(fn.getName()).valueNumber();
assert fnValue > 0;
int windowVal = super.doLocalRead(context, "this");
int windowVal = super.doLocalRead(context, "this", JavaScriptTypes.Function);
context.cfg().addInstruction(((JSInstructionFactory) insts).PutInstruction(windowVal, fnValue, fn.getName()));
}
}

View File

@ -39,6 +39,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import com.ibm.wala.cast.js.translator.JSAstTranslator;
import com.ibm.wala.cast.js.types.JavaScriptTypes;
import com.ibm.wala.cast.tree.CAst;
import com.ibm.wala.cast.tree.CAstControlFlowMap;
@ -508,7 +509,7 @@ public class ClosureExtractor extends CAstRewriterExt {
}
// prepend declaration "var <theLocal>;"
CAstNode theLocalDecl = Ast.makeNode(DECL_STMT, Ast.makeConstant(new CAstSymbolImpl(theLocal)),
CAstNode theLocalDecl = Ast.makeNode(DECL_STMT, Ast.makeConstant(new CAstSymbolImpl(theLocal, JSAstTranslator.Any)),
addExnFlow(makeVarRef("$$undefined"), JavaScriptTypes.ReferenceError, entity, context));
if(fun_body_stmts.size() > 1) {
CAstNode newBlock = Ast.makeNode(BLOCK_STMT, fun_body_stmts.toArray(new CAstNode[0]));

View File

@ -341,8 +341,8 @@ public class JavaScriptLoader extends CAstAbstractModuleLoader {
}
@Override
public AstLexicalRead LexicalRead(int lhs, String definer, String globalName) {
return new AstLexicalRead(lhs, definer, globalName);
public AstLexicalRead LexicalRead(int lhs, String definer, String globalName, TypeReference type) {
return new AstLexicalRead(lhs, definer, globalName, type);
}
@Override
@ -356,8 +356,8 @@ public class JavaScriptLoader extends CAstAbstractModuleLoader {
}
@Override
public AstLexicalWrite LexicalWrite(String definer, String globalName, int rhs) {
return new AstLexicalWrite(definer, globalName, rhs);
public AstLexicalWrite LexicalWrite(String definer, String globalName, TypeReference type, int rhs) {
return new AstLexicalWrite(definer, globalName, type, rhs);
}
@Override

View File

@ -11,6 +11,8 @@
package com.ibm.wala.cast.js.translator;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
@ -80,8 +82,8 @@ public class JSAstTranslator extends AstTranslator {
@Override
protected TypeReference makeType(CAstType type) {
Assertions.UNREACHABLE("JavaScript does not use CAstType");
return null;
assert "Any".equals(type.getName());
return JavaScriptTypes.Root;
}
@ -120,16 +122,16 @@ public class JSAstTranslator extends AstTranslator {
}
@Override
protected int doLexicallyScopedRead(CAstNode n, WalkContext context, String name) {
int readVn = super.doLexicallyScopedRead(n, context, name);
protected int doLexicallyScopedRead(CAstNode n, WalkContext context, String name, TypeReference type) {
int readVn = super.doLexicallyScopedRead(n, context, name, type);
// should get an exception if name is undefined
addDefinedCheck(n, context, readVn);
return readVn;
}
@Override
protected int doGlobalRead(CAstNode n, WalkContext context, String name) {
int readVn = super.doGlobalRead(n, context, name);
protected int doGlobalRead(CAstNode n, WalkContext context, String name, TypeReference type) {
int readVn = super.doGlobalRead(n, context, name, type);
// add a check if name is undefined, unless we're reading the value 'undefined'
if (!("undefined".equals(name) || "$$undefined".equals(name))) {
addDefinedCheck(n, context, readVn);
@ -224,7 +226,7 @@ public class JSAstTranslator extends AstTranslator {
protected void doMaterializeFunction(CAstNode n, WalkContext context, int result, int exception, CAstEntity fn) {
int nm = context.currentScope().getConstantValue("L" + composeEntityName(context, fn));
// "Function" is the name we use to model the constructor of function values
int tmp = super.doGlobalRead(n, context, "Function");
int tmp = super.doGlobalRead(n, context, "Function", JavaScriptTypes.Function);
context.cfg().addInstruction(
((JSInstructionFactory) insts).Invoke(tmp, result, new int[] { nm }, exception, new JSCallSiteReference(
JavaScriptMethods.ctorReference, context.cfg().getCurrentInstruction())));
@ -416,14 +418,13 @@ public class JSAstTranslator extends AstTranslator {
int tempVal = context.currentScope().allocateTempValue();
doNewObject(context, null, tempVal, "Array", null);
CAstSymbol args = new CAstSymbolImpl("arguments");
CAstSymbol args = new CAstSymbolImpl("arguments", Any);
context.currentScope().declare(args, tempVal);
//context.cfg().addInstruction(((JSInstructionFactory) insts).PutInstruction(1, tempVal, "arguments"));
}
@Override
protected boolean doVisit(CAstNode n, WalkContext cntxt, CAstVisitor<WalkContext> visitor) {
WalkContext context = (WalkContext) cntxt;
protected boolean doVisit(CAstNode n, WalkContext context, CAstVisitor<WalkContext> visitor) {
switch (n.getKind()) {
case CAstNode.TYPE_OF: {
int result = context.currentScope().allocateTempValue();
@ -453,4 +454,27 @@ public class JSAstTranslator extends AstTranslator {
}
}
public static final CAstType Any = new CAstType() {
@Override
public String getName() {
return "Any";
}
@Override
public Collection getSupertypes() {
return Collections.EMPTY_SET;
}
};
@Override
protected CAstType topType() {
return Any;
}
@Override
protected CAstType exceptionType() {
return Any;
}
}

View File

@ -164,7 +164,7 @@ public class PropertyReadExpander extends CAstRewriter<PropertyReadExpander.Rewr
result = Ast.makeNode(
CAstNode.BLOCK_EXPR,
// declare loop variable and initialize to the receiver
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new InternalCAstSymbol(receiverTemp, false, false)), receiver),
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new InternalCAstSymbol(receiverTemp, JSAstTranslator.Any, false, false)), receiver),
Ast.makeNode(CAstNode.LOOP,
// while the desired property of the loop variable is not
// defined...
@ -208,8 +208,8 @@ public class PropertyReadExpander extends CAstRewriter<PropertyReadExpander.Rewr
CAstNode get;
CAstNode result = Ast.makeNode(
CAstNode.BLOCK_EXPR,
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new InternalCAstSymbol(receiverTemp, false, false)), receiver),
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new InternalCAstSymbol(elementTemp, false, false)), element),
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new InternalCAstSymbol(receiverTemp, JSAstTranslator.Any, false, false)), receiver),
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new InternalCAstSymbol(elementTemp, JSAstTranslator.Any, false, false)), element),
Ast.makeNode(
CAstNode.LOOP,
Ast.makeNode(
@ -260,11 +260,11 @@ public class PropertyReadExpander extends CAstRewriter<PropertyReadExpander.Rewr
CAstNode copy = Ast.makeNode(
CAstNode.BLOCK_EXPR,
// assign lval to temp1 (where lval is a block that includes the prototype chain loop)
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new InternalCAstSymbol(temp1, true, false)), lval),
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new InternalCAstSymbol(temp1, JSAstTranslator.Any, true, false)), lval),
// ? --MS
//rval,
// assign temp2 the new value to be assigned
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new InternalCAstSymbol(temp2, true, false)),
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new InternalCAstSymbol(temp2, JSAstTranslator.Any, true, false)),
Ast.makeNode(CAstNode.BINARY_EXPR, op, Ast.makeNode(CAstNode.VAR, Ast.makeConstant(temp1)), rval)),
// write temp2 into the property
Ast.makeNode(CAstNode.ASSIGN, Ast.makeNode(CAstNode.OBJECT_REF, ctxt.receiverTemp, ctxt.elementTemp),

View File

@ -60,7 +60,7 @@ public class AstCallGraph extends ExplicitCallGraph {
}
public AstLexicalRead addGlobalRead(TypeReference type, String name) {
AstLexicalRead s = new AstLexicalRead(nextLocal++, null, name);
AstLexicalRead s = new AstLexicalRead(nextLocal++, null, name, type);
statements.add(s);
return s;
}

View File

@ -13,6 +13,7 @@ package com.ibm.wala.cast.ir.ssa;
import com.ibm.wala.cast.ir.ssa.AstLexicalAccess.Access;
import com.ibm.wala.ssa.SSAInstructionFactory;
import com.ibm.wala.types.FieldReference;
import com.ibm.wala.types.TypeReference;
public interface AstInstructionFactory extends SSAInstructionFactory {
@ -38,13 +39,13 @@ public interface AstInstructionFactory extends SSAInstructionFactory {
AstLexicalRead LexicalRead(Access access);
AstLexicalRead LexicalRead(int lhs, String definer, String globalName);
AstLexicalRead LexicalRead(int lhs, String definer, String globalName, TypeReference type);
AstLexicalWrite LexicalWrite(Access[] accesses);
AstLexicalWrite LexicalWrite(Access access);
AstLexicalWrite LexicalWrite(String definer, String globalName, int rhs);
AstLexicalWrite LexicalWrite(String definer, String globalName, TypeReference type, int rhs);
EachElementGetInstruction EachElementGetInstruction(int lValue, int objectRef);

View File

@ -39,14 +39,19 @@ public abstract class AstLexicalAccess extends SSAInstruction {
* name of entity that defines the variable
*/
public final String variableDefiner;
/**
* type of the lexical value
*/
public final TypeReference type;
/**
* value number used for name where access is being performed (not in the declaring entity)
*/
public final int valueNumber;
public Access(String name, String definer, int vn) {
public Access(String name, String definer, TypeReference type, int vn) {
variableName = name;
variableDefiner = definer;
this.type = type;
valueNumber = vn;
}

View File

@ -13,6 +13,7 @@ package com.ibm.wala.cast.ir.ssa;
import com.ibm.wala.ssa.SSAInstruction;
import com.ibm.wala.ssa.SSAInstructionFactory;
import com.ibm.wala.ssa.SymbolTable;
import com.ibm.wala.types.TypeReference;
/**
* A set of lexical reads. This instruction represents reads of a set of variables that are defined by a pair of
@ -32,8 +33,8 @@ public class AstLexicalRead extends AstLexicalAccess {
this(new Access[] { access });
}
public AstLexicalRead(int lhs, String definer, String globalName) {
this(new Access(globalName, definer, lhs));
public AstLexicalRead(int lhs, String definer, String globalName, TypeReference type) {
this(new Access(globalName, definer, type, lhs));
}
@Override
@ -44,7 +45,7 @@ public class AstLexicalRead extends AstLexicalAccess {
Access[] accesses = new Access[getAccessCount()];
for (int i = 0; i < accesses.length; i++) {
Access oldAccess = getAccess(i);
accesses[i] = new Access(oldAccess.variableName, oldAccess.variableDefiner, defs[i]);
accesses[i] = new Access(oldAccess.variableName, oldAccess.variableDefiner, oldAccess.type, defs[i]);
}
return ((AstInstructionFactory)insts).LexicalRead(accesses);

View File

@ -13,6 +13,7 @@ package com.ibm.wala.cast.ir.ssa;
import com.ibm.wala.ssa.SSAInstruction;
import com.ibm.wala.ssa.SSAInstructionFactory;
import com.ibm.wala.ssa.SymbolTable;
import com.ibm.wala.types.TypeReference;
/**
* A set of lexical writes. This instruction represents writes of a set of variables that are defined by a pair of
@ -24,8 +25,8 @@ import com.ibm.wala.ssa.SymbolTable;
*/
public class AstLexicalWrite extends AstLexicalAccess {
public AstLexicalWrite(String definer, String globalName, int rhs) {
this(new Access(globalName, definer, rhs));
public AstLexicalWrite(String definer, String globalName, TypeReference type, int rhs) {
this(new Access(globalName, definer, type, rhs));
}
public AstLexicalWrite(Access access) {
@ -44,7 +45,7 @@ public class AstLexicalWrite extends AstLexicalAccess {
Access[] accesses = new Access[getAccessCount()];
for (int i = 0; i < accesses.length; i++) {
Access oldAccess = getAccess(i);
accesses[i] = new Access(oldAccess.variableName, oldAccess.variableDefiner, uses[i]);
accesses[i] = new Access(oldAccess.variableName, oldAccess.variableDefiner, oldAccess.type, uses[i]);
}
return ((AstInstructionFactory)insts).LexicalWrite(accesses);

View File

@ -194,6 +194,16 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
protected abstract void doCall(WalkContext context, CAstNode call, int result, int exception, CAstNode name, int receiver,
int[] arguments);
/**
* the most-general type for the language being translated
*/
protected abstract CAstType topType();
/**
* the most-general exception type for the language being translated
*/
protected abstract CAstType exceptionType();
/**
* used to generate instructions for array operations; defaults to this
*/
@ -248,13 +258,17 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
final CAstEntity entity = context.top();
Set<String> exposedNames = entity2ExposedNames.get(entity);
if (exposedNames != null) {
int i = 0;
for (String arg : entity.getArgumentNames()) {
if (exposedNames.contains(arg)) {
final Scope currentScope = context.currentScope();
Symbol symbol = currentScope.lookup(arg);
assert symbol.getDefiningScope() == currentScope;
int argVN = symbol.valueNumber();
Access A = new Access(arg, context.getEntityName(entity), argVN);
CAstType type = (entity.getType() instanceof CAstType.Method)?
(CAstType)((CAstType.Method)entity.getType()).getArgumentTypes().get(i):
topType();
Access A = new Access(arg, context.getEntityName(entity), makeType(type), argVN);
context.cfg().addInstruction(new AstLexicalWrite(A));
}
}
@ -272,11 +286,11 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
* method) by looking up the name in context.currentScope(). Note that the
* caller is responsible for ensuring that name is defined in the local scope.
*/
protected int doLocalRead(WalkContext context, String name) {
protected int doLocalRead(WalkContext context, String name, TypeReference type) {
CAstEntity entity = context.top();
Set<String> exposed = entity2ExposedNames.get(entity);
if (exposed != null && exposed.contains(name)) {
return doLexReadHelper(context, name);
return doLexReadHelper(context, name, type);
}
return context.currentScope().lookup(name).valueNumber();
}
@ -286,12 +300,12 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
* value number of local nm. Note that the caller is responsible for ensuring
* that nm is defined in the local scope.
*/
protected void doLocalWrite(WalkContext context, String nm, int rval) {
protected void doLocalWrite(WalkContext context, String nm, TypeReference type, int rval) {
CAstEntity entity = context.top();
Set<String> exposed = entity2ExposedNames.get(entity);
if (exposed != null && exposed.contains(nm)) {
// use a lexical write
doLexicallyScopedWrite(context, nm, rval);
doLexicallyScopedWrite(context, nm, type, rval);
return;
}
int lval = context.currentScope().lookup(nm).valueNumber();
@ -310,8 +324,8 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
* @param name
* @return
*/
protected int doLexicallyScopedRead(CAstNode node, WalkContext context, final String name) {
return doLexReadHelper(context, name);
protected int doLexicallyScopedRead(CAstNode node, WalkContext context, final String name, TypeReference type) {
return doLexReadHelper(context, name, type);
}
/**
@ -327,7 +341,7 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
* call sites, as would be required for
* {@link #doLexicallyScopedRead(CAstNode, WalkContext, String)}
*/
private int doLexReadHelper(WalkContext context, final String name) {
private int doLexReadHelper(WalkContext context, final String name, TypeReference type) {
Symbol S = context.currentScope().lookup(name);
Scope definingScope = S.getDefiningScope();
CAstEntity E = definingScope.getEntity();
@ -335,9 +349,9 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
addExposedName(E, E, name, definingScope.lookup(name).valueNumber(), false, context);
final String entityName = context.getEntityName(E);
int result = context.currentScope().allocateTempValue();
Access A = new Access(name, entityName, result);
Access A = new Access(name, entityName, type, result);
context.cfg().addInstruction(new AstLexicalRead(A));
markExposedInEnclosingEntities(context, name, definingScope, E, entityName, false);
markExposedInEnclosingEntities(context, name, definingScope, type, E, entityName, false);
return result;
}
@ -354,13 +368,13 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
* @param entityName
* @param isWrite
*/
private void markExposedInEnclosingEntities(WalkContext context, final String name, Scope definingScope, CAstEntity E,
private void markExposedInEnclosingEntities(WalkContext context, final String name, Scope definingScope, TypeReference type, CAstEntity E,
final String entityName, boolean isWrite) {
Scope curScope = context.currentScope();
while (!curScope.equals(definingScope)) {
final Symbol curSymbol = curScope.lookup(name);
final int vn = curSymbol.valueNumber();
final Access A = new Access(name, entityName, vn);
final Access A = new Access(name, entityName, type, vn);
final CAstEntity entity = curScope.getEntity();
if (entity != definingScope.getEntity()) {
addExposedName(entity, E, name, vn, isWrite, context);
@ -378,7 +392,7 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
* lexical scope.
*
*/
protected void doLexicallyScopedWrite(WalkContext context, String name, int rval) {
protected void doLexicallyScopedWrite(WalkContext context, String name, TypeReference type, int rval) {
Symbol S = context.currentScope().lookup(name);
Scope definingScope = S.getDefiningScope();
CAstEntity E = definingScope.getEntity();
@ -386,20 +400,20 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
addExposedName(E, E, name, definingScope.lookup(name).valueNumber(), true, context);
// lexically-scoped variables must be written in their scope each time
Access A = new Access(name, context.getEntityName(E), rval);
Access A = new Access(name, context.getEntityName(E), type, rval);
context.cfg().addInstruction(new AstLexicalWrite(A));
markExposedInEnclosingEntities(context, name, definingScope, E, context.getEntityName(E), true);
markExposedInEnclosingEntities(context, name, definingScope, type, E, context.getEntityName(E), true);
}
/**
* generate instructions for a read of a global
*/
protected int doGlobalRead(CAstNode node, WalkContext context, String name) {
protected int doGlobalRead(CAstNode node, WalkContext context, String name, TypeReference type) {
// Global variables can be treated as lexicals defined in the CG root, or
if (treatGlobalsAsLexicallyScoped()) {
int result = context.currentScope().allocateTempValue();
Access A = new Access(name, null, result);
Access A = new Access(name, null, type, result);
context.cfg().addInstruction(new AstLexicalRead(A));
addAccess(context, context.top(), A);
return result;
@ -416,12 +430,12 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
/**
* generate instructions for a write of a global
*/
protected void doGlobalWrite(WalkContext context, String name, int rval) {
protected void doGlobalWrite(WalkContext context, String name, TypeReference type, int rval) {
// Global variables can be treated as lexicals defined in the CG root, or
if (treatGlobalsAsLexicallyScoped()) {
Access A = new Access(name, null, rval);
Access A = new Access(name, null, type, rval);
context.cfg().addInstruction(new AstLexicalWrite(A));
addAccess(context, context.top(), A);
@ -1333,11 +1347,20 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
protected class FinalCAstSymbol implements CAstSymbol {
private final String _name;
private FinalCAstSymbol(String _name) {
private final CAstType type;
private FinalCAstSymbol(String _name, CAstType type) {
this._name = _name;
this.type = type;
assert _name != null;
assert type != null;
}
@Override
public CAstType type() {
return type;
}
@Override
public String name() {
return _name;
@ -1365,20 +1388,20 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
}
public static class InternalCAstSymbol extends CAstSymbolImplBase {
public InternalCAstSymbol(String _name) {
super(_name, false, false, null);
public InternalCAstSymbol(String _name, CAstType type) {
super(_name, type, false, false, null);
}
public InternalCAstSymbol(String _name, boolean _isFinal) {
super(_name, _isFinal, false, null);
public InternalCAstSymbol(String _name, CAstType type, boolean _isFinal) {
super(_name, type, _isFinal, false, null);
}
public InternalCAstSymbol(String _name, boolean _isFinal, boolean _isCaseInsensitive) {
super(_name, _isFinal, _isCaseInsensitive, null);
public InternalCAstSymbol(String _name, CAstType type, boolean _isFinal, boolean _isCaseInsensitive) {
super(_name, type, _isFinal, _isCaseInsensitive, null);
}
public InternalCAstSymbol(String _name, boolean _isFinal, boolean _isCaseInsensitive, Object _defaultInitValue) {
super(_name, _isFinal, _isCaseInsensitive, _defaultInitValue);
public InternalCAstSymbol(String _name, CAstType type, boolean _isFinal, boolean _isCaseInsensitive, Object _defaultInitValue) {
super(_name, type, _isFinal, _isCaseInsensitive, _defaultInitValue);
}
@Override
@ -1408,6 +1431,8 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
boolean isInternalName();
Object defaultInitValue();
CAstType type();
}
/**
@ -1590,14 +1615,14 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
}
protected Symbol makeSymbol(CAstSymbol s) {
return makeSymbol(s.name(), s.isFinal(), s.isInternalName(), s.defaultInitValue(), -1, this);
return makeSymbol(s.name(), s.type(), s.isFinal(), s.isInternalName(), s.defaultInitValue(), -1, this);
}
protected Symbol makeSymbol(CAstSymbol s, int vn) {
return makeSymbol(s.name(), s.isFinal(), s.isInternalName(), s.defaultInitValue(), vn, this);
return makeSymbol(s.name(), s.type(), s.isFinal(), s.isInternalName(), s.defaultInitValue(), vn, this);
}
abstract protected Symbol makeSymbol(String nm, boolean isFinal, boolean isInternalName, Object defaultInitValue, int vn,
abstract protected Symbol makeSymbol(String nm, CAstType type, boolean isFinal, boolean isInternalName, Object defaultInitValue, int vn,
Scope parent);
@Override
@ -1613,7 +1638,7 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
Symbol scoped = parent.lookup(nm);
if (scoped != null && getEntityScope() == this && (isGlobal(scoped) || isLexicallyScoped(scoped))) {
values.put(nm,
makeSymbol(nm, scoped.isFinal(), scoped.isInternalName(), scoped.defaultInitValue(), -1, scoped.getDefiningScope()));
makeSymbol(nm, scoped.type(), scoped.isFinal(), scoped.isInternalName(), scoped.defaultInitValue(), -1, scoped.getDefiningScope()));
if (scoped.getDefiningScope().isCaseInsensitive(nm)) {
caseInsensitiveNames.put(nm.toLowerCase(), nm);
}
@ -1677,8 +1702,10 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
}
@Override
protected Symbol makeSymbol(final String nm, final boolean isFinal, final boolean isInternalName,
protected Symbol makeSymbol(final String nm, final CAstType type, final boolean isFinal, final boolean isInternalName,
final Object defaultInitValue, int vn, Scope definer) {
assert nm != null;
assert type != null;
final int v = vn == -1 ? getUnderlyingSymtab().newSymbol() : vn;
if (useDefaultInitValues() && defaultInitValue != null) {
if (getUnderlyingSymtab().getValue(v) == null) {
@ -1691,6 +1718,10 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
return nm + ":" + System.identityHashCode(this);
}
@Override
public CAstType type() {
return type;
}
@Override
public int valueNumber() {
return v;
@ -1734,6 +1765,21 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
return params[yuck];
}
@Override
public CAstType type() {
if (f.getType() instanceof CAstType.Method) {
if (yuck == 0) {
return ((CAstType.Method)f.getType()).getDeclaringType();
} else {
return (CAstType) ((CAstType.Method)f.getType()).getArgumentTypes().get(yuck-1);
}
} else if (f.getType() instanceof CAstType.Function) {
return (CAstType) ((CAstType.Function)f.getType()).getArgumentTypes().get(yuck);
} else {
return topType();
}
}
@Override
public boolean isFinal() {
return false;
@ -1797,8 +1843,10 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
}
@Override
protected Symbol makeSymbol(final String nm, final boolean isFinal, final boolean isInternalName,
protected Symbol makeSymbol(final String nm, final CAstType type, final boolean isFinal, final boolean isInternalName,
final Object defaultInitValue, final int valueNumber, Scope definer) {
assert nm != null;
assert type != null;
return new AbstractSymbol(definer, isFinal, defaultInitValue) {
final int vn;
@ -1819,6 +1867,11 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
}
}
@Override
public CAstType type() {
return type;
}
@Override
public String toString() {
return nm + ":" + System.identityHashCode(this);
@ -1871,7 +1924,7 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
}
@Override
protected Symbol makeSymbol(final String nm, boolean isFinal, final boolean isInternalName, final Object defaultInitValue,
protected Symbol makeSymbol(final String nm, final CAstType type, boolean isFinal, final boolean isInternalName, final Object defaultInitValue,
int vn, Scope definer) {
final int v = vn == -1 ? getUnderlyingSymtab().newSymbol() : vn;
if (useDefaultInitValues() && defaultInitValue != null) {
@ -1879,12 +1932,19 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
setDefaultValue(getUnderlyingSymtab(), v, defaultInitValue);
}
}
assert nm != null;
assert type != null;
return new AbstractSymbol(definer, isFinal, defaultInitValue) {
@Override
public String toString() {
return nm + ":" + System.identityHashCode(this);
}
@Override
public CAstType type() {
return type;
}
@Override
public int valueNumber() {
return v;
@ -2007,6 +2067,11 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
public Object defaultInitValue() {
return null;
}
@Override
public CAstType type() {
return topType();
}
});
} else if (hasSpecialUndeclaredVariables()) {
return null;
@ -2036,6 +2101,11 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
return name + ":" + System.identityHashCode(this);
}
@Override
public CAstType type() {
return s.type();
}
@Override
public boolean isParameter() {
return false;
@ -2156,6 +2226,11 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
return name + ":" + System.identityHashCode(this);
}
@Override
public CAstType type() {
return s.type();
}
@Override
public boolean isParameter() {
return false;
@ -3106,7 +3181,7 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
protected void leaveGlobalEntity(CAstEntity n, WalkContext context, CAstVisitor<WalkContext> visitor) {
// Define a new field in the enclosing type, if the language we're
// processing allows such.
context.getGlobalScope().declare(new CAstSymbolImpl(n.getName()));
context.getGlobalScope().declare(new CAstSymbolImpl(n.getName(), n.getType()));
}
@Override
@ -3240,10 +3315,10 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
// value to that local
assignValue(n, context, cs.lookup(fn.getName()), fn.getName(), result);
} else if (topLevelFunctionsInGlobalScope() && context.top().getKind() == CAstEntity.SCRIPT_ENTITY) {
context.getGlobalScope().declare(new FinalCAstSymbol(fn.getName()));
context.getGlobalScope().declare(new FinalCAstSymbol(fn.getName(), fn.getType()));
assignValue(n, context, cs.lookup(fn.getName()), fn.getName(), result);
} else {
context.currentScope().declare(new FinalCAstSymbol(fn.getName()), result);
context.currentScope().declare(new FinalCAstSymbol(fn.getName(), fn.getType()), result);
}
}
@ -3328,7 +3403,7 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
protected void leaveGetCaughtException(CAstNode n, WalkContext c, CAstVisitor<WalkContext> visitor) {
WalkContext context = c;
String nm = (String) n.getChild(0).getValue();
context.currentScope().declare(new FinalCAstSymbol(nm));
context.currentScope().declare(new FinalCAstSymbol(nm, exceptionType()));
context.cfg().addInstruction(
insts.GetCaughtExceptionInstruction(context.cfg().getCurrentBlock().getNumber(), context.currentScope().lookup(nm)
.valueNumber()));
@ -3388,12 +3463,14 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
assert nm != null : "cannot find var for " + CAstPrinter.print(n, context.getSourceMap());
Symbol s = context.currentScope().lookup(nm);
assert s != null : "cannot find symbol for " + nm + " at " + CAstPrinter.print(n, context.getSourceMap());
assert s.type() != null : "no type for " + nm + " at " + CAstPrinter.print(n, context.getSourceMap());
TypeReference type = makeType(s.type());
if (context.currentScope().isGlobal(s)) {
c.setValue(n, doGlobalRead(n, context, nm));
c.setValue(n, doGlobalRead(n, context, nm, type));
} else if (context.currentScope().isLexicallyScoped(s)) {
c.setValue(n, doLexicallyScopedRead(n, context, nm));
c.setValue(n, doLexicallyScopedRead(n, context, nm, type));
} else {
c.setValue(n, doLocalRead(context, nm));
c.setValue(n, doLocalRead(context, nm, type));
}
}
@ -3514,17 +3591,18 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
protected void leaveDeclStmt(CAstNode n, WalkContext c, CAstVisitor<WalkContext> visitor) {
CAstSymbol s = (CAstSymbol) n.getChild(0).getValue();
String nm = s.name();
CAstType t = s.type();
Scope scope = c.currentScope();
if (n.getChildCount() == 2) {
CAstNode v = n.getChild(1);
if (scope.contains(nm) && scope.lookup(nm).getDefiningScope() == scope) {
assert !s.isFinal();
doLocalWrite(c, nm, c.getValue(v));
doLocalWrite(c, nm, makeType(t), c.getValue(v));
} else if (v.getKind() != CAstNode.CONSTANT && v.getKind() != CAstNode.VAR && v.getKind() != CAstNode.THIS) {
scope.declare(s, c.getValue(v));
} else {
scope.declare(s);
doLocalWrite(c, nm, c.getValue(v));
doLocalWrite(c, nm, makeType(t), c.getValue(v));
}
} else {
c.currentScope().declare(s);
@ -3903,12 +3981,12 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
*/
protected void assignValue(CAstNode n, WalkContext context, Symbol ls, String nm, int rval) {
if (context.currentScope().isGlobal(ls))
doGlobalWrite(context, nm, rval);
doGlobalWrite(context, nm, makeType(ls.type()), rval);
else if (context.currentScope().isLexicallyScoped(ls)) {
doLexicallyScopedWrite(context, nm, rval);
doLexicallyScopedWrite(context, nm, makeType(ls.type()), rval);
} else {
assert rval != -1 : CAstPrinter.print(n, context.top().getSourceMap());
doLocalWrite(context, nm, rval);
doLocalWrite(context, nm, makeType(ls.type()), rval);
}
}
@ -3932,14 +4010,15 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
WalkContext context = c;
String nm = (String) n.getChild(0).getValue();
Symbol ls = context.currentScope().lookup(nm);
TypeReference type = makeType(ls.type());
int temp;
if (context.currentScope().isGlobal(ls))
temp = doGlobalRead(n, context, nm);
temp = doGlobalRead(n, context, nm, type);
else if (context.currentScope().isLexicallyScoped(ls)) {
temp = doLexicallyScopedRead(n, context, nm);
temp = doLexicallyScopedRead(n, context, nm, type);
} else {
temp = doLocalRead(context, nm);
temp = doLocalRead(context, nm, type);
}
if (!pre) {
@ -3955,11 +4034,11 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
}
if (context.currentScope().isGlobal(ls)) {
doGlobalWrite(context, nm, rval);
doGlobalWrite(context, nm, type, rval);
} else if (context.currentScope().isLexicallyScoped(ls)) {
doLexicallyScopedWrite(context, nm, rval);
doLexicallyScopedWrite(context, nm, type, rval);
} else {
doLocalWrite(context, nm, rval);
doLocalWrite(context, nm, type, rval);
}
}
@ -4147,7 +4226,7 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
String id = (String) n.getChild(0).getValue();
context.cfg().setCurrentBlockAsHandler();
if (!context.currentScope().contains(id)) {
context.currentScope().declare(new FinalCAstSymbol(id));
context.currentScope().declare(new FinalCAstSymbol(id, exceptionType()));
}
context.cfg().addInstruction(
insts.GetCaughtExceptionInstruction(context.cfg().getCurrentBlock().getNumber(), context.currentScope().lookup(id)

View File

@ -32,5 +32,6 @@ public interface CAstSymbol {
public boolean isInternalName();
public CAstType type();
}

View File

@ -10,29 +10,31 @@
*******************************************************************************/
package com.ibm.wala.cast.tree.impl;
import com.ibm.wala.cast.tree.CAstType;
public class CAstSymbolImpl extends CAstSymbolImplBase {
public CAstSymbolImpl(String _name) {
super(_name);
public CAstSymbolImpl(String _name, CAstType type) {
super(_name, type);
}
public CAstSymbolImpl(String _name, boolean _isFinal) {
super(_name, _isFinal);
public CAstSymbolImpl(String _name, CAstType type, boolean _isFinal) {
super(_name, type, _isFinal);
}
public CAstSymbolImpl(String _name, boolean _isFinal, boolean _isCaseInsensitive) {
super(_name, _isFinal, _isCaseInsensitive);
public CAstSymbolImpl(String _name, CAstType type, boolean _isFinal, boolean _isCaseInsensitive) {
super(_name, type, _isFinal, _isCaseInsensitive);
}
public CAstSymbolImpl(String _name, Object _defaultInitValue) {
super(_name, _defaultInitValue);
public CAstSymbolImpl(String _name, CAstType type, Object _defaultInitValue) {
super(_name, type, _defaultInitValue);
}
public CAstSymbolImpl(String _name, boolean _isFinal, Object _defaultInitValue) {
super(_name, _isFinal, _defaultInitValue);
public CAstSymbolImpl(String _name, CAstType type, boolean _isFinal, Object _defaultInitValue) {
super(_name, type, _isFinal, _defaultInitValue);
}
public CAstSymbolImpl(String _name, boolean _isFinal, boolean _isCaseInsensitive, Object _defaultInitValue) {
super(_name, _isFinal, _isCaseInsensitive, _defaultInitValue);
public CAstSymbolImpl(String _name, CAstType type, boolean _isFinal, boolean _isCaseInsensitive, Object _defaultInitValue) {
super(_name, type, _isFinal, _isCaseInsensitive, _defaultInitValue);
}
@Override

View File

@ -11,40 +11,51 @@
package com.ibm.wala.cast.tree.impl;
import com.ibm.wala.cast.tree.CAstSymbol;
import com.ibm.wala.cast.tree.CAstType;
public abstract class CAstSymbolImplBase implements CAstSymbol {
private final String _name;
private final boolean _isFinal;
private final boolean _isCaseInsensitive;
private final Object _defaultInitValue;
private final CAstType type;
public CAstSymbolImplBase(String name) {
this(name, false);
public CAstSymbolImplBase(String name, CAstType type) {
this(name, type, false);
}
public CAstSymbolImplBase(String name, boolean isFinal) {
this(name, isFinal, false);
public CAstSymbolImplBase(String name, CAstType type, boolean isFinal) {
this(name, type, isFinal, false);
}
public CAstSymbolImplBase(String name, boolean isFinal, boolean isCaseSensitive) {
this(name, isFinal, isCaseSensitive, null);
public CAstSymbolImplBase(String name, CAstType type, boolean isFinal, boolean isCaseSensitive) {
this(name, type, isFinal, isCaseSensitive, null);
}
public CAstSymbolImplBase(String name, Object defaultInitValue) {
this(name, false, defaultInitValue);
public CAstSymbolImplBase(String name, CAstType type, Object defaultInitValue) {
this(name, type, false, defaultInitValue);
}
public CAstSymbolImplBase(String name, boolean isFinal, Object defaultInitValue) {
this(name, isFinal, false, defaultInitValue);
public CAstSymbolImplBase(String name, CAstType type, boolean isFinal, Object defaultInitValue) {
this(name, type, isFinal, false, defaultInitValue);
}
public CAstSymbolImplBase(String name, boolean isFinal, boolean isCaseSensitive, Object defaultInitValue) {
public CAstSymbolImplBase(String name, CAstType type, boolean isFinal, boolean isCaseSensitive, Object defaultInitValue) {
this._name= name;
this.type = type;
this._isFinal= isFinal;
this._isCaseInsensitive= isCaseSensitive;
this._defaultInitValue= defaultInitValue;
assert name != null;
assert type != null;
}
@Override
public CAstType type() {
return type;
}
@Override
public String name() {
return _name;

View File

@ -128,6 +128,7 @@ import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
import org.eclipse.jdt.core.dom.WhileStatement;
import com.ibm.wala.analysis.typeInference.JavaPrimitiveType;
import com.ibm.wala.cast.ir.translator.AstTranslator.InternalCAstSymbol;
import com.ibm.wala.cast.ir.translator.TranslatorToCAst;
import com.ibm.wala.cast.ir.translator.TranslatorToCAst.DoLoopTranslator;
@ -605,7 +606,9 @@ public class JDTJava2CAstTranslator {
IInvokeInstruction.Dispatch.SPECIAL);
children[1] = fFactory.makeConstant(callSiteRef);
for (int i = 1; i < fakeArguments.length; i++) {
children[i + 1] = makeNode(context, fFactory, n, CAstNode.VAR, fFactory.makeConstant(fakeArguments[i]));
CAstNode argName = fFactory.makeConstant(fakeArguments[i]);
CAstNode argType = fFactory.makeConstant(paramTypes.get(i-1));
children[i + 1] = makeNode(context, fFactory, n, CAstNode.VAR, argName, argType);
}
bodyNodes[0] = makeNode(context, fFactory, n, CAstNode.CALL, children);
// QUESTION: no handleExceptions?
@ -1291,7 +1294,7 @@ public class JDTJava2CAstTranslator {
initNode = visitNode(init, context);
Object defaultValue = JDT2CAstUtils.defaultValueForType(type);
return makeNode(context, fFactory, n, CAstNode.DECL_STMT, fFactory.makeConstant(new CAstSymbolImpl(n.getName().getIdentifier(),
return makeNode(context, fFactory, n, CAstNode.DECL_STMT, fFactory.makeConstant(new CAstSymbolImpl(n.getName().getIdentifier(), fTypeDict.getCAstTypeFor(type),
isFinal, defaultValue)), initNode);
}
@ -1393,7 +1396,7 @@ public class JDTJava2CAstTranslator {
int idx = 0; // args: [ this, callsiteref, <actual args> ]
// arg 0: this
argNodes[idx++] = makeNode(context, fFactory, nn, CAstNode.VAR, fFactory.makeConstant(tmpName));
argNodes[idx++] = makeNode(context, fFactory, nn, CAstNode.VAR, fFactory.makeConstant(tmpName), fFactory.makeConstant(fTypeDict.getCAstTypeFor(newType)));
// contains output from newNode (see part III)
// arg 1: call site ref (WHY?)
@ -1419,7 +1422,7 @@ public class JDTJava2CAstTranslator {
// 3) access this temporary variable. Since the value of the block is the last thing in the block, the resultant
// value will be the variable
return makeNode(context, fFactory, nn, CAstNode.LOCAL_SCOPE, makeNode(context, fFactory, nn, CAstNode.BLOCK_EXPR, makeNode(
context, fFactory, nn, CAstNode.DECL_STMT, fFactory.makeConstant(new InternalCAstSymbol(tmpName, true)), newNode),
context, fFactory, nn, CAstNode.DECL_STMT, fFactory.makeConstant(new InternalCAstSymbol(tmpName, fTypeDict.getCAstTypeFor(newType), true)), newNode),
callNode, makeNode(context, fFactory, nn, CAstNode.VAR, fFactory.makeConstant(tmpName))));
}
@ -1698,13 +1701,13 @@ public class JDTJava2CAstTranslator {
final String tmpName = "temp generic preop hack"; // illegal Java identifier
CAstNode exprNode = visitNode(field.getExpression(), context);
CAstNode tmpDeclNode = makeNode(context, fFactory, left, CAstNode.DECL_STMT, fFactory.makeConstant(new InternalCAstSymbol(
tmpName, true)), exprNode);
tmpName, fTypeDict.getCAstTypeFor(field.getExpression().resolveTypeBinding()), true)), exprNode);
// need two object refndoes "temp.y"
CAstNode obref1 = createFieldAccess(makeNode(context, fFactory, left, CAstNode.VAR, fFactory.makeConstant(tmpName)), field
CAstNode obref1 = createFieldAccess(makeNode(context, fFactory, left, CAstNode.VAR, fFactory.makeConstant(tmpName), fFactory.makeConstant(fTypeDict.getCAstTypeFor(field.resolveFieldBinding().getType()))), field
.getName().getIdentifier(), field.resolveFieldBinding(), left, new AssignmentContext(context));
CAstNode obref2 = createFieldAccess(makeNode(context, fFactory, left, CAstNode.VAR, fFactory.makeConstant(tmpName)), field
CAstNode obref2 = createFieldAccess(makeNode(context, fFactory, left, CAstNode.VAR, fFactory.makeConstant(tmpName), fFactory.makeConstant(fTypeDict.getCAstTypeFor(field.resolveFieldBinding().getType()))), field
.getName().getIdentifier(), field.resolveFieldBinding(), left, context);
ITypeBinding realtype = JDT2CAstUtils.getErasedType(field.resolveFieldBinding().getType(), ast);
ITypeBinding fromtype = JDT2CAstUtils
@ -1806,7 +1809,8 @@ public class JDTJava2CAstTranslator {
} else {
// local
return makeNode(context, fFactory, n, CAstNode.VAR, fFactory.makeConstant(n.getIdentifier()));
CAstType t = fTypeDict.getCAstTypeFor(((IVariableBinding)n.resolveBinding()).getType());
return makeNode(context, fFactory, n, CAstNode.VAR, fFactory.makeConstant(n.getIdentifier()), fFactory.makeConstant(t));
}
}
@ -2499,7 +2503,7 @@ public class JDTJava2CAstTranslator {
context.cfg().map(o1, iterCallNode); // TODO: this might not work, lots of calls in this one statement.
CAstNode iterAssignNode = makeNode(context, fFactory, n, CAstNode.DECL_STMT, fFactory.makeConstant(new InternalCAstSymbol(
tmpName, true)), iterCallNode);
tmpName, fTypeDict.getCAstTypeFor(ast.resolveWellKnownType("int")), true)), iterCallNode);
// MATCHUP: wrap in a block
iterAssignNode = makeNode(context, fFactory, n, CAstNode.BLOCK_STMT, iterAssignNode);
@ -2539,12 +2543,12 @@ public class JDTJava2CAstTranslator {
Object defaultValue = JDT2CAstUtils.defaultValueForType(svd.resolveBinding().getType());
CAstNode nextAssignNode = makeNode(context, fFactory, n, CAstNode.DECL_STMT, fFactory.makeConstant(new CAstSymbolImpl(svd
.getName().getIdentifier(), (svd.getModifiers() & Modifier.FINAL) != 0, defaultValue)), castedNode);
.getName().getIdentifier(), fTypeDict.getCAstTypeFor(svd.resolveBinding().getType()), (svd.getModifiers() & Modifier.FINAL) != 0, defaultValue)), castedNode);
/*----------- put it all together ----------*/
ASTNode breakTarget = makeBreakOrContinueTarget(n, "breakLabel" + n.getStartPosition());
ASTNode continueTarget = makeBreakOrContinueTarget(n, "continueLabel" + n.getStartPosition());
String loopLabel = (String) context.getLabelMap().get(n);
String loopLabel = context.getLabelMap().get(n);
WalkContext loopContext = new LoopContext(context, loopLabel, breakTarget, continueTarget);
// LOCAL_SCOPE(BLOCK(iterassign,LOOP(cond,BLOCK(BLOCK(paramassign,bodyblock),continuetarget,BLOCK())),breaktarget))
@ -2575,18 +2579,18 @@ public class JDTJava2CAstTranslator {
final String tmpArrayName = "for temp array"; // illegal java identifier
CAstNode exprNode = visitNode(n.getExpression(), context);
CAstNode arrayDeclNode = makeNode(context, fFactory, n, CAstNode.DECL_STMT, fFactory.makeConstant(new InternalCAstSymbol(
tmpArrayName, true)), exprNode);
tmpArrayName, fTypeDict.getCAstTypeFor(n.getExpression().resolveTypeBinding()), true)), exprNode);
/*------ indexDecl --------- int tmpindex = 0 ------*/
final String tmpIndexName = "for temp index";
CAstNode indexDeclNode = makeNode(context, fFactory, n, CAstNode.DECL_STMT, fFactory.makeConstant(new InternalCAstSymbol(
tmpIndexName, true)), fFactory.makeConstant(new Integer(0)));
tmpIndexName, fTypeDict.getCAstTypeFor(ast.resolveWellKnownType("int")), true)), fFactory.makeConstant(new Integer(0)));
/*------ cond ------------- tmpindex < tmparray.length ------*/
CAstNode tmpArrayLengthNode = makeNode(context, fFactory, n, CAstNode.ARRAY_LENGTH, makeNode(context, fFactory, n,
CAstNode.VAR, fFactory.makeConstant(tmpArrayName)));
CAstNode.VAR, fFactory.makeConstant(tmpArrayName), fFactory.makeConstant(fTypeDict.getCAstTypeFor(n.getExpression().resolveTypeBinding()))));
CAstNode condNode = makeNode(context, fFactory, n, CAstNode.BINARY_EXPR, CAstOperator.OP_LT, makeNode(context, fFactory, n,
CAstNode.VAR, fFactory.makeConstant(tmpIndexName)), tmpArrayLengthNode);
CAstNode.VAR, fFactory.makeConstant(tmpIndexName), fFactory.makeConstant(JavaPrimitiveType.INT)), tmpArrayLengthNode);
/*------ tmpIndexInc -------- tmpindex++ ------*/
CAstNode tmpArrayIncNode = makeNode(context, fFactory, n, CAstNode.ASSIGN_POST_OP, makeNode(context, fFactory, n, CAstNode.VAR,
@ -2601,7 +2605,8 @@ public class JDTJava2CAstTranslator {
SingleVariableDeclaration svd = n.getParameter();
Object defaultValue = JDT2CAstUtils.defaultValueForType(svd.resolveBinding().getType());
CAstNode nextAssignNode = makeNode(context, fFactory, n, CAstNode.DECL_STMT, fFactory.makeConstant(new CAstSymbolImpl(svd
.getName().getIdentifier(), (svd.getModifiers() & Modifier.FINAL) != 0, defaultValue)), tmpArrayAccessNode);
.getName().getIdentifier(), fTypeDict.getCAstTypeFor(n.getExpression()
.resolveTypeBinding().getComponentType()), (svd.getModifiers() & Modifier.FINAL) != 0, defaultValue)), tmpArrayAccessNode);
// LOCAL_SCOPE(BLOCK(arrayDecl,LOCAL_SCOPE(BLOCK(BLOCK(indexDecl),LOOP(cond,BLOCK(LOCAL_SCOPE(BLOCK(nextAssign,bodyblock)),continuetarget,BLOCK(iter))),breaktarget))))
// more complicated than it has to be, but it matches up exactly with the Java expansion above.
@ -2772,7 +2777,7 @@ public class JDTJava2CAstTranslator {
CAstNode exprNode = visitNode(n.getExpression(), context);
String exprName = fFactory.makeUnique();
CAstNode declStmt = makeNode(context, fFactory, n, CAstNode.DECL_STMT, fFactory
.makeConstant(new CAstSymbolImpl(exprName, true)), exprNode);
.makeConstant(new CAstSymbolImpl(exprName, fTypeDict.getCAstTypeFor(n.getExpression().resolveTypeBinding()), true)), exprNode);
CAstNode monitorEnterNode = makeNode(context, fFactory, n, CAstNode.MONITOR_ENTER, makeNode(context, fFactory, n, CAstNode.VAR,
fFactory.makeConstant(exprName)));
@ -3407,7 +3412,7 @@ public class JDTJava2CAstTranslator {
CAstNode typeLit = makeNode(context, fFactory, fakeMet, CAstNode.TYPE_LITERAL_EXPR, fFactory.makeConstant(fIdentityMapper
.typeToTypeID(enumType)));
CAstNode stringSvar = makeNode(context, fFactory, fakeMet, CAstNode.VAR, fFactory.makeConstant("s"));
CAstNode stringSvar = makeNode(context, fFactory, fakeMet, CAstNode.VAR, fFactory.makeConstant("s"), fFactory.makeConstant(fTypeDict.getCAstTypeFor(ast.resolveWellKnownType("java.lang.String"))));
ArrayList<Object> args = new ArrayList<Object>();
args.add(typeLit);
args.add(stringSvar);
@ -3585,12 +3590,12 @@ public class JDTJava2CAstTranslator {
CallSiteReference callSiteRef = CallSiteReference.make(0, fIdentityMapper.getMethodRef(superCtor),
IInvokeInstruction.Dispatch.SPECIAL);
children[1] = fFactory.makeConstant(callSiteRef);
children[2] = makeNode(context, fFactory, n, CAstNode.VAR, fFactory.makeConstant(fakeArguments[1]));
children[3] = makeNode(context, fFactory, n, CAstNode.VAR, fFactory.makeConstant(fakeArguments[2]));
children[2] = makeNode(context, fFactory, n, CAstNode.VAR, fFactory.makeConstant(fakeArguments[1]), fFactory.makeConstant(paramTypes.get(0)));
children[3] = makeNode(context, fFactory, n, CAstNode.VAR, fFactory.makeConstant(fakeArguments[2]), fFactory.makeConstant(paramTypes.get(1)));
if (ctor.isDefaultConstructor())
for (int i = 0; i < ctor.getParameterTypes().length; i++)
children[i + 4] = makeNode(context, fFactory, n, CAstNode.VAR, fFactory.makeConstant(fakeArguments[i + 3]));
children[i + 4] = makeNode(context, fFactory, n, CAstNode.VAR, fFactory.makeConstant(fakeArguments[i + 3]), fFactory.makeConstant(paramTypes.get(i+2)));
bodyNodes[0] = makeNode(context, fFactory, n, CAstNode.CALL, children);
// QUESTION: no handleExceptions?

View File

@ -149,7 +149,7 @@ public class JDTSourceModuleTranslator implements SourceModuleTranslator {
e.printStackTrace();
}
if (! System.getProperty("wala.jdt.quiet").equals("true")) {
if (! "true".equals(System.getProperty("wala.jdt.quiet"))) {
IProblem[] problems = ast.getProblems();
int length = problems.length;
if (length > 0) {