From cc8831ebcf46007dc32007c67e223ac485bfc92e Mon Sep 17 00:00:00 2001 From: Julian Dolby Date: Sun, 6 Aug 2017 18:36:33 -0400 Subject: [PATCH] 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. --- .../js/translator/RhinoToAstTranslator.java | 217 ++++++++++++------ .../ibm/wala/dalvik/ssa/DexSSABuilder.java | 1 - .../util/collections/AbstractMultiMap.java | 5 + .../util/collections/ArraySetMultiMap.java | 10 + .../util/collections/HashSetMultiMap.java | 5 + .../SparseNumberedLabeledEdgeManager.java | 5 + 6 files changed, 177 insertions(+), 66 deletions(-) diff --git a/com.ibm.wala.cast.js.rhino/source/com/ibm/wala/cast/js/translator/RhinoToAstTranslator.java b/com.ibm.wala.cast.js.rhino/source/com/ibm/wala/cast/js/translator/RhinoToAstTranslator.java index b936c2adb..ce4e97183 100644 --- a/com.ibm.wala.cast.js.rhino/source/com/ibm/wala/cast/js/translator/RhinoToAstTranslator.java +++ b/com.ibm.wala.cast.js.rhino/source/com/ibm/wala/cast/js/translator/RhinoToAstTranslator.java @@ -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 diff --git a/com.ibm.wala.dalvik/src/com/ibm/wala/dalvik/ssa/DexSSABuilder.java b/com.ibm.wala.dalvik/src/com/ibm/wala/dalvik/ssa/DexSSABuilder.java index c1b839cb6..2cb129e96 100644 --- a/com.ibm.wala.dalvik/src/com/ibm/wala/dalvik/ssa/DexSSABuilder.java +++ b/com.ibm.wala.dalvik/src/com/ibm/wala/dalvik/ssa/DexSSABuilder.java @@ -477,7 +477,6 @@ public class DexSSABuilder extends AbstractIntRegisterMachine { @Override public void visitArrayFill(ArrayFill instruction) { - int ElementWidth = instruction.getTable().getElementWidth(); Iterator iae = instruction.getTable().getArrayElements().iterator(); int i = 0; while (iae.hasNext()) diff --git a/com.ibm.wala.util/src/com/ibm/wala/util/collections/AbstractMultiMap.java b/com.ibm.wala.util/src/com/ibm/wala/util/collections/AbstractMultiMap.java index f696ae6cb..dacaf910d 100644 --- a/com.ibm.wala.util/src/com/ibm/wala/util/collections/AbstractMultiMap.java +++ b/com.ibm.wala.util/src/com/ibm/wala/util/collections/AbstractMultiMap.java @@ -46,6 +46,11 @@ import java.util.Set; abstract class AbstractMultiMap implements Serializable, MultiMap { + /** + * + */ + private static final long serialVersionUID = 4064901973301954076L; + protected final Map> map = HashMapFactory.make(); protected final boolean create; diff --git a/com.ibm.wala.util/src/com/ibm/wala/util/collections/ArraySetMultiMap.java b/com.ibm.wala.util/src/com/ibm/wala/util/collections/ArraySetMultiMap.java index 6725757bc..5f51f1b23 100644 --- a/com.ibm.wala.util/src/com/ibm/wala/util/collections/ArraySetMultiMap.java +++ b/com.ibm.wala.util/src/com/ibm/wala/util/collections/ArraySetMultiMap.java @@ -44,9 +44,19 @@ import java.util.Set; */ public class ArraySetMultiMap extends AbstractMultiMap { + /** + * + */ + private static final long serialVersionUID = -3475591699051060160L; + @SuppressWarnings("rawtypes") public static final ArraySetMultiMap EMPTY = new ArraySetMultiMap() { + /** + * + */ + private static final long serialVersionUID = 1839857029830528896L; + @Override public boolean put(Object key, Object val) { throw new RuntimeException(); diff --git a/com.ibm.wala.util/src/com/ibm/wala/util/collections/HashSetMultiMap.java b/com.ibm.wala.util/src/com/ibm/wala/util/collections/HashSetMultiMap.java index 7b09f4937..68e73a90e 100644 --- a/com.ibm.wala.util/src/com/ibm/wala/util/collections/HashSetMultiMap.java +++ b/com.ibm.wala.util/src/com/ibm/wala/util/collections/HashSetMultiMap.java @@ -42,6 +42,11 @@ import java.util.Set; public class HashSetMultiMap extends AbstractMultiMap { + /** + * + */ + private static final long serialVersionUID = 1699856257459175263L; + public HashSetMultiMap() { super(false); } diff --git a/com.ibm.wala.util/src/com/ibm/wala/util/graph/labeled/SparseNumberedLabeledEdgeManager.java b/com.ibm.wala.util/src/com/ibm/wala/util/graph/labeled/SparseNumberedLabeledEdgeManager.java index 039c0f506..f313670cc 100644 --- a/com.ibm.wala.util/src/com/ibm/wala/util/graph/labeled/SparseNumberedLabeledEdgeManager.java +++ b/com.ibm.wala.util/src/com/ibm/wala/util/graph/labeled/SparseNumberedLabeledEdgeManager.java @@ -67,6 +67,11 @@ import com.ibm.wala.util.intset.IntSet; */ public class SparseNumberedLabeledEdgeManager implements Serializable, NumberedLabeledEdgeManager { + /** + * + */ + private static final long serialVersionUID = 5298089288917726790L; + /** * the label to be attached to an edge when no label is specified */