- Fix the cast rewriter to rewrite labels too.
- Fix the translation of switch statements to keep the labels "alive" (part of the AST). - Added test case for the bug. git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@3960 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
parent
38f8a44044
commit
fc0d5ecc47
|
@ -896,35 +896,44 @@ public class RhinoToAstTranslator {
|
|||
case Token.FINALLY:
|
||||
case Token.BLOCK:
|
||||
case Token.LABEL: {
|
||||
// CAstNode ast;
|
||||
Node c1 = n.getFirstChild();
|
||||
if (c1 != null && c1.getType() == Token.SWITCH) {
|
||||
Node switchValue = c1.getFirstChild();
|
||||
Node c1 = n.getFirstChild();
|
||||
if (c1 != null && c1.getType() == Token.SWITCH) {
|
||||
Node switchValue = c1.getFirstChild();
|
||||
|
||||
CAstNode defaultLabel = Ast.makeNode(CAstNode.LABEL_STMT, Ast.makeNode(CAstNode.EMPTY));
|
||||
context.cfg().map(defaultLabel, defaultLabel);
|
||||
CAstNode defaultLabel = Ast.makeNode(CAstNode.LABEL_STMT, Ast.makeNode(CAstNode.EMPTY));
|
||||
context.cfg().map(defaultLabel, defaultLabel);
|
||||
|
||||
for (Node kase = switchValue.getNext(); kase != null; kase = kase.getNext()) {
|
||||
assert kase.getType() == Token.CASE;
|
||||
Node caseLbl = kase.getFirstChild();
|
||||
Node target = ((Node.Jump) kase).target;
|
||||
context.cfg().add(c1, target, walkNodes(caseLbl, context));
|
||||
List<CAstNode> labelCasts = new ArrayList<CAstNode>();
|
||||
for (Node kase = switchValue.getNext(); kase != null; kase = kase.getNext()) {
|
||||
assert kase.getType() == Token.CASE;
|
||||
Node caseLbl = kase.getFirstChild();
|
||||
Node target = ((Node.Jump) kase).target;
|
||||
CAstNode labelCast = walkNodes(caseLbl, context);
|
||||
labelCasts.add(labelCast);
|
||||
context.cfg().add(c1, target, labelCast);
|
||||
}
|
||||
CAstNode[] children = new CAstNode[labelCasts.size()+1];
|
||||
int i = 0;
|
||||
children[i++] = Ast.makeNode(CAstNode.BLOCK_STMT, defaultLabel, gatherChildren(n, context, 1));
|
||||
|
||||
// Note that we are placing the labels as children in the AST
|
||||
// even if they are not used, because we want them copied when AST is re-written.
|
||||
for (CAstNode labelCast : labelCasts){
|
||||
children[i++] = labelCast;
|
||||
}
|
||||
|
||||
context.cfg().add(c1, defaultLabel, CAstControlFlowMap.SWITCH_DEFAULT);
|
||||
CAstNode switchAst = Ast.makeNode(CAstNode.SWITCH, walkNodes(switchValue, context), children);
|
||||
|
||||
noteSourcePosition(context, switchAst, c1);
|
||||
context.cfg().map(c1, switchAst);
|
||||
return switchAst;
|
||||
}
|
||||
|
||||
context.cfg().add(c1, defaultLabel, CAstControlFlowMap.SWITCH_DEFAULT);
|
||||
|
||||
CAstNode switchAst = Ast.makeNode(CAstNode.SWITCH, walkNodes(switchValue, context), Ast.makeNode(CAstNode.BLOCK_STMT,
|
||||
defaultLabel, gatherChildren(n, context, 1)));
|
||||
|
||||
noteSourcePosition(context, switchAst, c1);
|
||||
context.cfg().map(c1, switchAst);
|
||||
return switchAst;
|
||||
else {
|
||||
return Ast.makeNode(CAstNode.BLOCK_STMT, gatherChildren(n, context));
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
return Ast.makeNode(CAstNode.BLOCK_STMT, gatherChildren(n, context));
|
||||
}
|
||||
}
|
||||
|
||||
case Token.EXPR_VOID:
|
||||
case Token.EXPR_RESULT: {
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
function f(){
|
||||
switch (a){
|
||||
case b:
|
||||
return "wow"
|
||||
}
|
||||
}
|
||||
f();
|
|
@ -256,8 +256,11 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
|||
verifyGraphAssertions(CG, assertionsForPrototypeContamination);
|
||||
verifyNoEdges(CG, "suffix:test1", "suffix:foo_of_B");
|
||||
verifyNoEdges(CG, "suffix:test2", "suffix:foo_of_A");
|
||||
|
||||
}
|
||||
|
||||
@Test public void testRewriterDoesNotChangeLablesBug() throws IOException, IllegalArgumentException, CancelException {
|
||||
CallGraph CG = Util.makeScriptCG("tests", "rewrite_does_not_change_lables_bug.js");
|
||||
// all we need is for it to finish building CG successfully.
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -111,12 +111,12 @@ public abstract class CAstRewriter<C extends CAstRewriter.RewriteContext<K>, K e
|
|||
}
|
||||
|
||||
while (LS.hasNext()) {
|
||||
Object label = LS.next();
|
||||
CAstNode oldTarget = orig.getTarget(oldSource, label);
|
||||
Object origLabel = LS.next();
|
||||
CAstNode oldTarget = orig.getTarget(oldSource, origLabel);
|
||||
assert oldTarget != null;
|
||||
|
||||
if (DEBUG) {
|
||||
System.err.println(("old: " + label + " --> " + CAstPrinter.print(oldTarget)));
|
||||
System.err.println(("old: " + origLabel + " --> " + CAstPrinter.print(oldTarget)));
|
||||
}
|
||||
|
||||
Pair targetKey;
|
||||
|
@ -130,16 +130,23 @@ public abstract class CAstRewriter<C extends CAstRewriter.RewriteContext<K>, K e
|
|||
}
|
||||
} while (!nodeMap.containsKey(targetKey));
|
||||
|
||||
Object newLabel;
|
||||
if (nodeMap.containsKey(Pair.make(origLabel, targetKey.snd))){ // label is mapped too
|
||||
newLabel = nodeMap.get(Pair.make(origLabel, targetKey.snd));
|
||||
} else {
|
||||
newLabel = origLabel;
|
||||
}
|
||||
|
||||
CAstNode newTarget;
|
||||
if (nodeMap.containsKey(targetKey)) {
|
||||
newTarget = (CAstNode) nodeMap.get(targetKey);
|
||||
newMap.add(newSource, newTarget, label);
|
||||
newMap.add(newSource, newTarget, newLabel);
|
||||
allNewTargetNodes.add(newTarget);
|
||||
|
||||
} else {
|
||||
newTarget = flowOutTo(nodeMap, oldSource, label, oldTarget, orig, newSrc);
|
||||
newTarget = flowOutTo(nodeMap, oldSource, origLabel, oldTarget, orig, newSrc);
|
||||
allNewTargetNodes.add(newTarget);
|
||||
newMap.add(newSource, newTarget, label);
|
||||
newMap.add(newSource, newTarget, newLabel);
|
||||
if (newTarget != CAstControlFlowMap.EXCEPTION_TO_EXIT && !mappedOutsideNodes.contains(newTarget)) {
|
||||
mappedOutsideNodes.add(newTarget);
|
||||
newMap.map(newTarget, newTarget);
|
||||
|
@ -147,8 +154,8 @@ public abstract class CAstRewriter<C extends CAstRewriter.RewriteContext<K>, K e
|
|||
}
|
||||
|
||||
if (DEBUG) {
|
||||
System.err.println(("mapping:old: " + CAstPrinter.print(oldSource) + "-- " + label + " --> " + CAstPrinter.print(oldTarget)));
|
||||
System.err.println(("mapping:new: " + CAstPrinter.print(newSource) + "-- " + label + " --> " + CAstPrinter.print(newTarget)));
|
||||
System.err.println(("mapping:old: " + CAstPrinter.print(oldSource) + "-- " + origLabel + " --> " + CAstPrinter.print(oldTarget)));
|
||||
System.err.println(("mapping:new: " + CAstPrinter.print(newSource) + "-- " + newLabel + " --> " + CAstPrinter.print(newTarget)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue