Fixed rewriting of non-constant switch cases.

This commit is contained in:
Max Schaefer 2012-07-05 09:37:47 -04:00
parent 5ba9b7b735
commit fca3999e9a
6 changed files with 62 additions and 18 deletions

View File

@ -1,11 +0,0 @@
(function() {
var ComputedStyle = {
getBorderWidth: function() {
switch (property) {
case BORDER_TOP_WIDTH:
value;
break;
}
}
};
})();

View File

@ -532,11 +532,6 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
verifyGraphAssertions(CG, assertionsForNestedParamAssign);
}
@Test
public void testSwitchCrash() throws IOException, IllegalArgumentException, CancelException {
// just check that we can successfully convert to CAst
JSCallGraphBuilderUtil.makeScriptCG("tests", "switch_crash.js");
}
private static final Object[][] assertionsForDispatch = new Object[][] {
new Object[] { ROOT, new String[] { "tests/dispatch.js" } },
new Object[] { "tests/dispatch.js", new String[] { "tests/dispatch.js/left_outer", "tests/dispatch.js/right_outer" } },

View File

@ -361,9 +361,19 @@ public class ClosureExtractor extends CAstRewriterExt {
/* Recursively copy child nodes. */
private CAstNode copyNode(CAstNode node, CAstControlFlowMap cfg, NodePos context, Map<Pair<CAstNode, NoKey>, CAstNode> nodeMap) {
CAstNode children[] = new CAstNode[node.getChildCount()];
// copy children
for (int i = 0; i < children.length; i++) {
children[i] = copyNodes(node.getChild(i), cfg, new ChildPos(node, i, context), nodeMap);
}
// for non-constant case labels, the case expressions appear as labels on CFG edges; rewrite those as well
for(Object label: cfg.getTargetLabels(node)) {
if (label instanceof CAstNode) {
copyNodes((CAstNode)label, cfg, new LabelPos(node, context), nodeMap);
}
}
CAstNode newNode = Ast.makeNode(node.getKind(), children);
nodeMap.put(Pair.make(node, context.key()), newNode);
@ -728,6 +738,11 @@ public class ClosureExtractor extends CAstRewriterExt {
public CAstNode caseForInLoopBodyPos(ExtractionPos pos) {
return getThrowTarget(pos.getParentPos());
}
@Override
public CAstNode caseLabelPos(LabelPos pos) {
return getThrowTarget(pos.getParentPos());
}
});
}

View File

@ -178,7 +178,12 @@ public class ExtractionPos extends NodePos {
public ExtractionPos caseForInLoopBodyPos(ExtractionPos pos) {
ExtractionPos outer = getEnclosingExtractionPos(pos.getParentPos());
return outer == null ? pos : outer;
}
}
@Override
public ExtractionPos caseLabelPos(LabelPos pos) {
return getOutermostEnclosingExtractionPos(pos.getParentPos());
}
});
}
@ -201,7 +206,12 @@ public class ExtractionPos extends NodePos {
@Override
public ExtractionPos caseForInLoopBodyPos(ExtractionPos pos) {
return pos;
}
}
@Override
public ExtractionPos caseLabelPos(LabelPos pos) {
return getEnclosingExtractionPos(pos.getParentPos());
}
});
}

View File

@ -0,0 +1,34 @@
package com.ibm.wala.cast.js.ipa.callgraph.correlations.extraction;
import com.ibm.wala.cast.tree.CAstNode;
/**
* A {@link NodePos} for a node that labels a CFG edge; currently only seems to occur with 'switch'
* statements.
*
* @author mschaefer
*
*/
public class LabelPos extends NodePos {
private final CAstNode parent;
private final NodePos parent_pos;
public LabelPos(CAstNode node, NodePos parent_pos) {
this.parent = node;
this.parent_pos = parent_pos;
}
public CAstNode getParent() {
return parent;
}
public NodePos getParentPos() {
return parent_pos;
}
@Override
public <A> A accept(PosSwitch<A> ps) {
return ps.caseLabelPos(this);
}
}

View File

@ -15,4 +15,5 @@ public abstract class PosSwitch<A> {
public abstract A caseRootPos(RootPos pos);
public abstract A caseChildPos(ChildPos pos);
public abstract A caseForInLoopBodyPos(ExtractionPos pos);
public abstract A caseLabelPos(LabelPos pos);
}