Chromium Code Reviews| Index: lib/compiler/implementation/ssa/builder.dart |
| diff --git a/lib/compiler/implementation/ssa/builder.dart b/lib/compiler/implementation/ssa/builder.dart |
| index f34da88fee09917f30aefba6cbe8110442d4bed4..aa1c32f18105dd80bc19bdd2af084dc1ff80420f 100644 |
| --- a/lib/compiler/implementation/ssa/builder.dart |
| +++ b/lib/compiler/implementation/ssa/builder.dart |
| @@ -2950,7 +2950,6 @@ class SsaBuilder implements Visitor { |
| // Recursively build an if/else structure to match the cases. |
| buildSwitchCases(Link<Node> cases, HInstruction expression) { |
| SwitchCase node = cases.head; |
| - |
| // Called for the statements on all but the last case block. |
| // Ensures that a user expecting a fallthrough gets an error. |
| void visitStatementsAndAbort() { |
| @@ -2967,8 +2966,15 @@ class SsaBuilder implements Visitor { |
| } |
| } |
| - Link<Node> expressions = node.expressions.nodes; |
| - if (expressions.isEmpty()) { |
| + Link<Node> skipLabels(Link<Node> labelsAndCases) { |
| + while (!labelsAndCases.isEmpty() && labelsAndCases.head is Label) { |
| + labelsAndCases = labelsAndCases.tail; |
| + } |
| + return labelsAndCases; |
| + } |
| + |
| + Link<Node> labelsAndCases = skipLabels(node.labelsAndCases.nodes); |
| + if (labelsAndCases.isEmpty()) { |
| // Default case with no expressions. |
| if (!node.isDefaultCase) { |
| compiler.internalError("Case with no expression and not default", |
| @@ -2982,40 +2988,46 @@ class SsaBuilder implements Visitor { |
| // Recursively build the test conditions. Leaves the result on the |
| // expression stack. |
| - void buildTests(Link<Node> remainingExpressions) { |
| + void buildTests(Link<Node> remainingCases) { |
| // Build comparison for one case expression. |
| void left() { |
| Element equalsHelper = interceptors.getEqualsInterceptor(); |
| HInstruction target = new HStatic(equalsHelper); |
| add(target); |
| - visit(remainingExpressions.head); |
| + CaseMatch match = remainingCases.head; |
| + visit(match.expression); |
| push(new HEquals(target, pop(), expression)); |
| } |
| // If this is the last expression, just return it. |
| - if (remainingExpressions.tail.isEmpty()) { |
| + Link<Node> tail = skipLabels(remainingCases.tail); |
| + if (tail.isEmpty()) { |
| left(); |
| return; |
| } |
| void right() { |
| - buildTests(remainingExpressions.tail); |
| + buildTests(tail); |
| } |
| handleLogicalAndOr(left, right, isAnd: false); |
| } |
| if (node.isDefaultCase) { |
| - buildTests(expressions); |
| - // Throw away the test result. We always execute the default case. |
| - pop(); |
| + // Default case must be last. |
| + assert(cases.tail.isEmpty()); |
| + // Perform the tests until one of them match, but then always execute the |
| + // statements. |
| + // TODO(lrn): Stop performing tests when all expressions are compile-time |
| + // constant strings or integers. |
| + handleIf(() { buildTests(labelsAndCases); }, (){}, null); |
| visit(node.statements); |
| } else { |
| if (cases.tail.isEmpty()) { |
| - handleIf(() { buildTests(expressions); }, |
| + handleIf(() { buildTests(labelsAndCases); }, |
| () { visit(node.statements); }, |
| null); |
| } else { |
| - handleIf(() { buildTests(expressions); }, |
| + handleIf(() { buildTests(labelsAndCases); }, |
| () { visitStatementsAndAbort(); }, |
| () { buildSwitchCases(cases.tail, expression); }); |
| } |
| @@ -3026,6 +3038,10 @@ class SsaBuilder implements Visitor { |
| unreachable(); |
|
ahe
2012/05/14 09:24:25
Please report an error that the user can understan
Lasse Reichstein Nielsen
2012/05/14 10:34:58
Made in6o internal error. DItto for the one below.
|
| } |
| + visitCaseMatch(CaseMatch node) { |
| + unreachable(); |
| + } |
| + |
| visitTryStatement(TryStatement node) { |
| work.allowSpeculativeOptimization = false; |
| HBasicBlock enterBlock = openNewBlock(); |