Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(485)

Unified Diff: lib/compiler/implementation/ssa/builder.dart

Issue 10387080: Accept more labels per switch case. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address review comments. Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « lib/compiler/implementation/scanner/parser.dart ('k') | lib/compiler/implementation/ssa/tracer.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..cff8773aa78448d77d4ae275dfafa444949577fb 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); });
}
@@ -3023,7 +3035,11 @@ class SsaBuilder implements Visitor {
}
visitSwitchCase(SwitchCase node) {
- unreachable();
+ compiler.internalError('SsaBuilder.visitSwitchCase');
+ }
+
+ visitCaseMatch(CaseMatch node) {
+ compiler.internalError('SsaBuilder.visitCaseMatch');
}
visitTryStatement(TryStatement node) {
« no previous file with comments | « lib/compiler/implementation/scanner/parser.dart ('k') | lib/compiler/implementation/ssa/tracer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698