purported fixes for Max's latest bugs (with some tests)

git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@4433 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
dolby-oss 2012-02-07 13:50:08 +00:00
parent 3113f14e23
commit 79946e98d6
4 changed files with 67 additions and 14 deletions

View File

@ -60,4 +60,9 @@ public class TestSimpleCallGraphShapeRhino extends TestSimpleCallGraphShape {
public void testTranslateToCAstCrash2() throws IllegalArgumentException, IOException, CancelException {
Util.makeScriptCG("tests", "rhino_crash2.js");
}
@Test
public void testTranslateToCAstCrash3() throws IllegalArgumentException, IOException, CancelException {
Util.makeScriptCG("tests", "rhino_crash3.js");
}
}

View File

@ -177,6 +177,14 @@ public class RhinoToAstTranslator {
}
private static class BreakContext extends JavaScriptTranslatorToCAst.BreakContext<WalkContext, Node> implements WalkContext {
BreakContext(WalkContext parent, Node breakTo, String label) {
super(parent, breakTo, label);
}
}
private static class LoopContext extends JavaScriptTranslatorToCAst.LoopContext<WalkContext, Node> implements WalkContext {
LoopContext(WalkContext parent, Node breakTo, Node continueTo, String label) {
@ -550,6 +558,20 @@ public class RhinoToAstTranslator {
return loopContext;
}
private WalkContext makeBreakContext(AstNode node, WalkContext arg,
AstNode breakStmt) {
WalkContext loopContext = arg;
List<Label> labels = getLabels(node);
if (labels == null) {
loopContext = new BreakContext(loopContext, breakStmt, null);
} else {
for(Label l : labels) {
loopContext = new BreakContext(loopContext, breakStmt, l.getName());
}
}
return loopContext;
}
private class TranslatingVisitor extends TypedNodeVisitor<CAstNode,WalkContext> {
@Override
@ -626,14 +648,16 @@ public class RhinoToAstTranslator {
@Override
public CAstNode visitBreakStatement(BreakStatement node, WalkContext arg) {
CAstNode breakStmt;
Node target;
if (node.getBreakLabel() != null) {
breakStmt = Ast.makeNode(CAstNode.GOTO, Ast.makeConstant(node.getBreakLabel().getIdentifier()));
target = arg.getBreakFor(node.getBreakLabel().getIdentifier());
} else {
breakStmt = Ast.makeNode(CAstNode.GOTO);
target = arg.getBreakFor(null);
}
arg.cfg().map(node, breakStmt);
Node target = node.getBreakTarget();
arg.cfg().map(node, breakStmt);
arg.cfg().add(node, target, null);
return breakStmt;
@ -839,10 +863,12 @@ public class RhinoToAstTranslator {
return args;
}
private static final String baseVarName = "$$-base-$$";
@Override
public CAstNode visitFunctionCall(FunctionCall n, WalkContext context) {
if (!isPrimitiveCall(context, n)) {
CAstNode base = Ast.makeNode(CAstNode.VAR, Ast.makeConstant("base"));
CAstNode base = Ast.makeNode(CAstNode.VAR, Ast.makeConstant(baseVarName));
AstNode callee = n.getTarget();
WalkContext child = new BaseCollectingContext(context, callee, base);
CAstNode fun = visit(callee, child);
@ -854,7 +880,7 @@ public class RhinoToAstTranslator {
return Ast.makeNode(
CAstNode.LOCAL_SCOPE,
Ast.makeNode(CAstNode.BLOCK_EXPR,
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl("base")), Ast.makeConstant(null)),
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl(baseVarName)), Ast.makeConstant(null)),
makeCall(fun, base, args, context)));
else
return makeCall(fun, makeVarRef(JSSSAPropagationCallGraphBuilder.GLOBAL_OBJ_VAR_NAME), args, context);
@ -991,9 +1017,11 @@ public class RhinoToAstTranslator {
public CAstNode visitLabeledStatement(LabeledStatement node, WalkContext arg) {
CAstNode result = visit(node.getStatement(), arg);
AstNode prev = node;
for(Label label : node.getLabels()) {
result = Ast.makeNode(CAstNode.LABEL_STMT, visit(label, arg), result);
arg.cfg().map(label, result);
arg.cfg().map(prev, result);
prev = label;
}
return result;
@ -1125,7 +1153,12 @@ public class RhinoToAstTranslator {
@Override
public CAstNode visitSwitchStatement(SwitchStatement node, WalkContext context) {
int i = 0;
AstNode breakStmt = makeEmptyLabelStmt("breakLabel");
CAstNode breakLabel = visit(breakStmt, context);
WalkContext switchBodyContext = makeBreakContext(node, context, breakStmt);
int i = 0;
CAstNode[] children = new CAstNode[ node.getCases().size() * 2 ];
for(SwitchCase sc : node.getCases()) {
CAstNode label =
@ -1142,16 +1175,17 @@ public class RhinoToAstTranslator {
context.cfg().add(node, label, labelCAst);
}
children[i++] = visit(sc, context);
children[i++] = visit(sc, switchBodyContext);
}
CAstNode s =
Ast.makeNode(CAstNode.SWITCH,
visit(node.getExpression(), context),
Ast.makeNode(CAstNode.BLOCK_STMT, children));
context.cfg().map(node, s);
return s;
return Ast.makeNode(CAstNode.BLOCK_STMT, s, breakLabel);
}
@Override
@ -1253,10 +1287,14 @@ public class RhinoToAstTranslator {
readName(arg, "$$undefined")),
node));
children[i++] =
Ast.makeNode(CAstNode.ASSIGN,
Ast.makeNode(CAstNode.VAR, Ast.makeConstant(init.getTarget().getString())),
visit(init, arg));
if (init.getInitializer() == null) {
children[i++] = Ast.makeNode(CAstNode.EMPTY);
} else {
children[i++] =
Ast.makeNode(CAstNode.ASSIGN,
Ast.makeNode(CAstNode.VAR, Ast.makeConstant(init.getTarget().getString())),
visit(init, arg));
}
}
return Ast.makeNode(CAstNode.BLOCK_STMT, children);

View File

@ -0,0 +1,10 @@
function f() {
switch (0) {
default:
break;
}
oParsedResponse || 0;
}
f();

View File

@ -191,7 +191,7 @@ public interface JavaScriptTranslatorToCAst extends TranslatorToCAst {
@Override
public T getBreakFor(String l) {
return ((l == null)? label==null: label.equals(l))? breakTarget: super.getBreakFor(l);
return (l == null || l.equals(label))? breakTarget: super.getBreakFor(l);
}
}
@ -205,7 +205,7 @@ public interface JavaScriptTranslatorToCAst extends TranslatorToCAst {
@Override
public T getContinueFor(String l) {
return ((l == null)? label==null: label.equals(l))? continueTo: super.getContinueFor(l);
return (l == null || l.equals(label))? continueTo: super.getContinueFor(l);
}
}