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) {
return visit(node.getExpression(), arg);
}
@Override
public CAstNode visitForInLoop(ForInLoop node, WalkContext arg) {
// set up
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)
};
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();
// TODO: fix the correlation-tracking rewriters, and kill the old for..in translation
if (useNewForIn) {
// set up
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)
};
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(
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);
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.BLOCK_EXPR,
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))),
readName(arg, null, name))),
body),
breakLabel));
arg.cfg().map(node, loop);
return loop;
name = init.getTarget().getString();
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);
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.BLOCK_EXPR,
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))),
readName(arg, null, name))),
body),
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
@ -2423,13 +2503,20 @@ private CAstNode[] walkChildren(final Node n, WalkContext context) {
private int tempVarNum = 0;
private final DoLoopTranslator doLoopTranslator;
private final boolean useNewForIn;
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.scriptName = scriptName;
this.sourceModule = m;
this.sourceReader = new InputStreamReader(sourceModule.getInputStream());
this.doLoopTranslator = new DoLoopTranslator(replicateForDoLoops, Ast);
this.useNewForIn = useNewForIn;
}
@Override

View File

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

View File

@ -46,6 +46,11 @@ import java.util.Set;
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 boolean create;

View File

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

View File

@ -42,6 +42,11 @@ import java.util.Set;
public class HashSetMultiMap<K, V> extends AbstractMultiMap<K, V> {
/**
*
*/
private static final long serialVersionUID = 1699856257459175263L;
public HashSetMultiMap() {
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> {
/**
*
*/
private static final long serialVersionUID = 5298089288917726790L;
/**
* the label to be attached to an edge when no label is specified
*/