misc fixes, and optional new translation for for..in; ultimately, this new translation is better, but for now it breaks some correlation-tracking tests, so it is available only as an option.

This commit is contained in:
Julian Dolby 2017-08-06 18:36:33 -04:00
parent 15f54f0248
commit cc8831ebcf
6 changed files with 177 additions and 66 deletions

View File

@ -831,74 +831,154 @@ public class RhinoToAstTranslator implements TranslatorToCAst {
WalkContext arg) { WalkContext arg) {
return visit(node.getExpression(), arg); return visit(node.getExpression(), arg);
} }
@Override @Override
public CAstNode visitForInLoop(ForInLoop node, WalkContext arg) { public CAstNode visitForInLoop(ForInLoop node, WalkContext arg) {
// set up // TODO: fix the correlation-tracking rewriters, and kill the old for..in translation
CAstNode object = visit(node.getIteratedObject(), arg); if (useNewForIn) {
String tempName = "for in loop temp"; // set up
CAstNode[] loopHeader = new CAstNode[]{ CAstNode object = visit(node.getIteratedObject(), arg);
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl(tempName, JSAstTranslator.Any)), readName(arg, null, "$$undefined")), String tempName = "for in loop temp";
Ast.makeNode(CAstNode.ASSIGN, Ast.makeNode(CAstNode.VAR, Ast.makeConstant(tempName)), object) CAstNode[] loopHeader = new CAstNode[]{
}; Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl(tempName, JSAstTranslator.Any)), readName(arg, null, "$$undefined")),
Ast.makeNode(CAstNode.ASSIGN, Ast.makeNode(CAstNode.VAR, Ast.makeConstant(tempName)), object)
String name; };
AstNode var = node.getIterator();
assert var instanceof Name || var instanceof VariableDeclaration || var instanceof LetNode : var.getClass() + " " + var;
if (var instanceof Name) {
name = ((Name)var).getString();
} else {
VariableDeclaration decl;
if (var instanceof LetNode) {
decl = ((LetNode)var).getVariables();
} else {
decl = (VariableDeclaration)var;
}
assert decl.getVariables().size() == 1;
VariableInitializer init = decl.getVariables().iterator().next();
name = init.getTarget().getString(); String name;
AstNode var = node.getIterator();
assert var instanceof Name || var instanceof VariableDeclaration || var instanceof LetNode : var.getClass() + " " + var;
if (var instanceof Name) {
name = ((Name)var).getString();
} else {
VariableDeclaration decl;
if (var instanceof LetNode) {
decl = ((LetNode)var).getVariables();
} else {
decl = (VariableDeclaration)var;
}
assert decl.getVariables().size() == 1;
VariableInitializer init = decl.getVariables().iterator().next();
arg.addNameDecl( name = init.getTarget().getString();
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl(name, JSAstTranslator.Any)),
readName(arg, null, "$$undefined"))); arg.addNameDecl(
} Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl(name, JSAstTranslator.Any)),
readName(arg, null, "$$undefined")));
// body }
AstNode breakStmt = makeEmptyLabelStmt("breakLabel");
CAstNode breakLabel = visit(breakStmt, arg); // body
AstNode contStmt = makeEmptyLabelStmt("contLabel"); AstNode breakStmt = makeEmptyLabelStmt("breakLabel");
CAstNode contLabel = visit(contStmt, arg); CAstNode breakLabel = visit(breakStmt, arg);
// TODO: Figure out why this is needed to make the correlation extraction tests pass AstNode contStmt = makeEmptyLabelStmt("contLabel");
// TODO: remove this silly label CAstNode contLabel = visit(contStmt, arg);
AstNode garbageStmt = makeEmptyLabelStmt("garbageLabel"); // TODO: Figure out why this is needed to make the correlation extraction tests pass
CAstNode garbageLabel = visit(garbageStmt, arg); // TODO: remove this silly label
WalkContext loopContext = makeLoopContext(node, arg, breakStmt, contStmt); AstNode garbageStmt = makeEmptyLabelStmt("garbageLabel");
CAstNode body = Ast.makeNode(CAstNode.BLOCK_STMT, CAstNode garbageLabel = visit(garbageStmt, arg);
//initNode, WalkContext loopContext = makeLoopContext(node, arg, breakStmt, contStmt);
visit(node.getBody(), loopContext), CAstNode body = Ast.makeNode(CAstNode.BLOCK_STMT,
garbageLabel); //initNode,
visit(node.getBody(), loopContext),
CAstNode loop = Ast.makeNode(CAstNode.LOCAL_SCOPE, garbageLabel);
Ast.makeNode(CAstNode.BLOCK_STMT,
loopHeader[0], CAstNode loop = Ast.makeNode(CAstNode.LOCAL_SCOPE,
loopHeader[1], Ast.makeNode(CAstNode.BLOCK_STMT,
contLabel, loopHeader[0],
Ast.makeNode(CAstNode.LOOP, loopHeader[1],
Ast.makeNode(CAstNode.BINARY_EXPR, contLabel,
CAstOperator.OP_NE, Ast.makeNode(CAstNode.LOOP,
Ast.makeConstant(null), Ast.makeNode(CAstNode.BINARY_EXPR,
Ast.makeNode(CAstNode.BLOCK_EXPR, CAstOperator.OP_NE,
Ast.makeNode(CAstNode.ASSIGN, Ast.makeConstant(null),
Ast.makeNode(CAstNode.VAR, Ast.makeConstant(name)), Ast.makeNode(CAstNode.BLOCK_EXPR,
Ast.makeNode(CAstNode.EACH_ELEMENT_GET, Ast.makeNode(CAstNode.ASSIGN,
Ast.makeNode(CAstNode.VAR, Ast.makeConstant(tempName)), Ast.makeNode(CAstNode.VAR, Ast.makeConstant(name)),
readName(arg, null, name))), Ast.makeNode(CAstNode.EACH_ELEMENT_GET,
readName(arg, null, name))), Ast.makeNode(CAstNode.VAR, Ast.makeConstant(tempName)),
body), readName(arg, null, name))),
breakLabel)); readName(arg, null, name))),
arg.cfg().map(node, loop); body),
return loop; breakLabel));
arg.cfg().map(node, loop);
return loop;
} else {
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, JSAstTranslator.Any)), readName(arg, null, "$$undefined")),
Ast.makeNode(CAstNode.ASSIGN, Ast.makeNode(CAstNode.VAR, Ast.makeConstant(tempName)), object)
};
CAstNode initNode;
String name;
AstNode var = node.getIterator();
assert var instanceof Name || var instanceof VariableDeclaration || var instanceof LetNode : var.getClass() + " " + var;
if (var instanceof Name) {
name = ((Name)var).getString();
initNode =
Ast.makeNode(CAstNode.ASSIGN,
Ast.makeNode(CAstNode.VAR, Ast.makeConstant(name)),
Ast.makeNode(CAstNode.EACH_ELEMENT_GET,
Ast.makeNode(CAstNode.VAR, Ast.makeConstant(tempName)),
readName(arg, null, name)));
} else {
VariableDeclaration decl;
if (var instanceof LetNode) {
decl = ((LetNode)var).getVariables();
} else {
decl = (VariableDeclaration)var;
}
assert decl.getVariables().size() == 1;
VariableInitializer init = decl.getVariables().iterator().next();
name = init.getTarget().getString();
arg.addNameDecl(
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl(name, JSAstTranslator.Any)),
readName(arg, null, "$$undefined")));
initNode =
Ast.makeNode(CAstNode.ASSIGN,
Ast.makeNode(CAstNode.VAR, Ast.makeConstant(name)),
Ast.makeNode(CAstNode.EACH_ELEMENT_GET,
Ast.makeNode(CAstNode.VAR, Ast.makeConstant(tempName)),
readName(arg, null, name)));
}
// body
AstNode breakStmt = makeEmptyLabelStmt("breakLabel");
CAstNode breakLabel = visit(breakStmt, arg);
AstNode contStmt = makeEmptyLabelStmt("contLabel");
CAstNode contLabel = visit(contStmt, arg);
// TODO: Figure out why this is needed to make the correlation extraction tests pass
// TODO: remove this silly label
AstNode garbageStmt = makeEmptyLabelStmt("garbageLabel");
CAstNode garbageLabel = visit(garbageStmt, arg);
WalkContext loopContext = makeLoopContext(node, arg, breakStmt, contStmt);
CAstNode body = Ast.makeNode(CAstNode.BLOCK_STMT,
initNode,
visit(node.getBody(), loopContext),
garbageLabel);
CAstNode loop = Ast.makeNode(CAstNode.LOCAL_SCOPE,
Ast.makeNode(CAstNode.BLOCK_STMT,
loopHeader[0],
loopHeader[1],
contLabel,
Ast.makeNode(CAstNode.LOOP,
Ast.makeNode(CAstNode.BINARY_EXPR,
CAstOperator.OP_NE,
Ast.makeConstant(null),
Ast.makeNode(CAstNode.EACH_ELEMENT_GET,
Ast.makeNode(CAstNode.VAR, Ast.makeConstant(tempName)),
readName(arg, null, name))),
body),
breakLabel));
arg.cfg().map(node, loop);
return loop;
}
} }
@Override @Override
@ -2423,13 +2503,20 @@ private CAstNode[] walkChildren(final Node n, WalkContext context) {
private int tempVarNum = 0; private int tempVarNum = 0;
private final DoLoopTranslator doLoopTranslator; private final DoLoopTranslator doLoopTranslator;
private final boolean useNewForIn;
public RhinoToAstTranslator(CAst Ast, ModuleEntry m, String scriptName, boolean replicateForDoLoops) { public RhinoToAstTranslator(CAst Ast, ModuleEntry m, String scriptName, boolean replicateForDoLoops) {
this(Ast, m, scriptName, replicateForDoLoops, false);
}
public RhinoToAstTranslator(CAst Ast, ModuleEntry m, String scriptName, boolean replicateForDoLoops, boolean useNewForIn) {
this.Ast = Ast; this.Ast = Ast;
this.scriptName = scriptName; this.scriptName = scriptName;
this.sourceModule = m; this.sourceModule = m;
this.sourceReader = new InputStreamReader(sourceModule.getInputStream()); this.sourceReader = new InputStreamReader(sourceModule.getInputStream());
this.doLoopTranslator = new DoLoopTranslator(replicateForDoLoops, Ast); this.doLoopTranslator = new DoLoopTranslator(replicateForDoLoops, Ast);
this.useNewForIn = useNewForIn;
} }
@Override @Override

View File

@ -477,7 +477,6 @@ public class DexSSABuilder extends AbstractIntRegisterMachine {
@Override @Override
public void visitArrayFill(ArrayFill instruction) { public void visitArrayFill(ArrayFill instruction) {
int ElementWidth = instruction.getTable().getElementWidth();
Iterator<Number> iae = instruction.getTable().getArrayElements().iterator(); Iterator<Number> iae = instruction.getTable().getArrayElements().iterator();
int i = 0; int i = 0;
while (iae.hasNext()) while (iae.hasNext())

View File

@ -46,6 +46,11 @@ import java.util.Set;
abstract class AbstractMultiMap<K, V> implements Serializable, MultiMap<K, V> { abstract class AbstractMultiMap<K, V> implements Serializable, MultiMap<K, V> {
/**
*
*/
private static final long serialVersionUID = 4064901973301954076L;
protected final Map<K, Set<V>> map = HashMapFactory.make(); protected final Map<K, Set<V>> map = HashMapFactory.make();
protected final boolean create; protected final boolean create;

View File

@ -44,9 +44,19 @@ import java.util.Set;
*/ */
public class ArraySetMultiMap<K, V> extends AbstractMultiMap<K, V> { public class ArraySetMultiMap<K, V> extends AbstractMultiMap<K, V> {
/**
*
*/
private static final long serialVersionUID = -3475591699051060160L;
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public static final ArraySetMultiMap EMPTY = new ArraySetMultiMap<Object, Object>() { public static final ArraySetMultiMap EMPTY = new ArraySetMultiMap<Object, Object>() {
/**
*
*/
private static final long serialVersionUID = 1839857029830528896L;
@Override @Override
public boolean put(Object key, Object val) { public boolean put(Object key, Object val) {
throw new RuntimeException(); throw new RuntimeException();

View File

@ -42,6 +42,11 @@ import java.util.Set;
public class HashSetMultiMap<K, V> extends AbstractMultiMap<K, V> { public class HashSetMultiMap<K, V> extends AbstractMultiMap<K, V> {
/**
*
*/
private static final long serialVersionUID = 1699856257459175263L;
public HashSetMultiMap() { public HashSetMultiMap() {
super(false); super(false);
} }

View File

@ -67,6 +67,11 @@ import com.ibm.wala.util.intset.IntSet;
*/ */
public class SparseNumberedLabeledEdgeManager<T, U> implements Serializable, NumberedLabeledEdgeManager<T, U> { public class SparseNumberedLabeledEdgeManager<T, U> implements Serializable, NumberedLabeledEdgeManager<T, U> {
/**
*
*/
private static final long serialVersionUID = 5298089288917726790L;
/** /**
* the label to be attached to an edge when no label is specified * the label to be attached to an edge when no label is specified
*/ */