| Index: lib/compiler/implementation/ssa/builder.dart
|
| diff --git a/lib/compiler/implementation/ssa/builder.dart b/lib/compiler/implementation/ssa/builder.dart
|
| index e867f6c16aa00e90ce73d9ab1ddfe1c83ec018f1..f2c1abc726dd52299d5bde22737866ba8da56b11 100644
|
| --- a/lib/compiler/implementation/ssa/builder.dart
|
| +++ b/lib/compiler/implementation/ssa/builder.dart
|
| @@ -2955,7 +2955,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() {
|
| @@ -2972,8 +2971,8 @@ class SsaBuilder implements Visitor {
|
| }
|
| }
|
|
|
| - Link<Node> expressions = node.expressions.nodes;
|
| - if (expressions.isEmpty()) {
|
| + Link<Node> caseMatches = node.cases.nodes;
|
| + if (caseMatches.isEmpty()) {
|
| // Default case with no expressions.
|
| if (!node.isDefaultCase) {
|
| compiler.internalError("Case with no expression and not default",
|
| @@ -2987,40 +2986,45 @@ 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()) {
|
| + if (remainingCases.tail.isEmpty()) {
|
| left();
|
| return;
|
| }
|
|
|
| void right() {
|
| - buildTests(remainingExpressions.tail);
|
| + buildTests(remainingCases.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(caseMatches); }, (){}, null);
|
| visit(node.statements);
|
| } else {
|
| if (cases.tail.isEmpty()) {
|
| - handleIf(() { buildTests(expressions); },
|
| + handleIf(() { buildTests(caseMatches); },
|
| () { visit(node.statements); },
|
| null);
|
| } else {
|
| - handleIf(() { buildTests(expressions); },
|
| + handleIf(() { buildTests(caseMatches); },
|
| () { visitStatementsAndAbort(); },
|
| () { buildSwitchCases(cases.tail, expression); });
|
| }
|
|
|