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:
parent
15f54f0248
commit
cc8831ebcf
|
@ -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
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue