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

Side by Side 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: 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 class Interceptors { 5 class Interceptors {
6 Compiler compiler; 6 Compiler compiler;
7 Interceptors(Compiler this.compiler); 7 Interceptors(Compiler this.compiler);
8 8
9 SourceString mapOperatorToMethodName(Operator op) { 9 SourceString mapOperatorToMethodName(Operator op) {
10 String name = op.source.stringValue; 10 String name = op.source.stringValue;
(...skipping 2937 matching lines...) Expand 10 before | Expand all | Expand 10 after
2948 new HSubGraphBlockInformation(new SubGraph(startBlock, lastBlock)), 2948 new HSubGraphBlockInformation(new SubGraph(startBlock, lastBlock)),
2949 elements[node]), 2949 elements[node]),
2950 joinBlock); 2950 joinBlock);
2951 jumpHandler.close(); 2951 jumpHandler.close();
2952 } 2952 }
2953 2953
2954 2954
2955 // Recursively build an if/else structure to match the cases. 2955 // Recursively build an if/else structure to match the cases.
2956 buildSwitchCases(Link<Node> cases, HInstruction expression) { 2956 buildSwitchCases(Link<Node> cases, HInstruction expression) {
2957 SwitchCase node = cases.head; 2957 SwitchCase node = cases.head;
2958
2959 // Called for the statements on all but the last case block. 2958 // Called for the statements on all but the last case block.
2960 // Ensures that a user expecting a fallthrough gets an error. 2959 // Ensures that a user expecting a fallthrough gets an error.
2961 void visitStatementsAndAbort() { 2960 void visitStatementsAndAbort() {
2962 visit(node.statements); 2961 visit(node.statements);
2963 if (!isAborted()) { 2962 if (!isAborted()) {
2964 compiler.reportWarning(node, 'Missing break at end of switch case'); 2963 compiler.reportWarning(node, 'Missing break at end of switch case');
2965 Element element = 2964 Element element =
2966 compiler.findHelper(const SourceString("getFallThroughError")); 2965 compiler.findHelper(const SourceString("getFallThroughError"));
2967 push(new HStatic(element)); 2966 push(new HStatic(element));
2968 HInstruction error = new HInvokeStatic( 2967 HInstruction error = new HInvokeStatic(
2969 Selector.INVOCATION_0, <HInstruction>[pop()]); 2968 Selector.INVOCATION_0, <HInstruction>[pop()]);
2970 add(error); 2969 add(error);
2971 close(new HThrow(error)); 2970 close(new HThrow(error));
2972 } 2971 }
2973 } 2972 }
2974 2973
2975 Link<Node> expressions = node.expressions.nodes; 2974 Link<Node> caseMatches = node.cases.nodes;
2976 if (expressions.isEmpty()) { 2975 if (caseMatches.isEmpty()) {
2977 // Default case with no expressions. 2976 // Default case with no expressions.
2978 if (!node.isDefaultCase) { 2977 if (!node.isDefaultCase) {
2979 compiler.internalError("Case with no expression and not default", 2978 compiler.internalError("Case with no expression and not default",
2980 node: node); 2979 node: node);
2981 } 2980 }
2982 visit(node.statements); 2981 visit(node.statements);
2983 // This must be the final case (otherwise "default" would be invalid), 2982 // This must be the final case (otherwise "default" would be invalid),
2984 // so we don't need to check for fallthrough. 2983 // so we don't need to check for fallthrough.
2985 return; 2984 return;
2986 } 2985 }
2987 2986
2988 // Recursively build the test conditions. Leaves the result on the 2987 // Recursively build the test conditions. Leaves the result on the
2989 // expression stack. 2988 // expression stack.
2990 void buildTests(Link<Node> remainingExpressions) { 2989 void buildTests(Link<Node> remainingCases) {
2991 // Build comparison for one case expression. 2990 // Build comparison for one case expression.
2992 void left() { 2991 void left() {
2993 Element equalsHelper = interceptors.getEqualsInterceptor(); 2992 Element equalsHelper = interceptors.getEqualsInterceptor();
2994 HInstruction target = new HStatic(equalsHelper); 2993 HInstruction target = new HStatic(equalsHelper);
2995 add(target); 2994 add(target);
2996 visit(remainingExpressions.head); 2995 CaseMatch match = remainingCases.head;
2996 visit(match.expression);
2997 push(new HEquals(target, pop(), expression)); 2997 push(new HEquals(target, pop(), expression));
2998 } 2998 }
2999 2999
3000 // If this is the last expression, just return it. 3000 // If this is the last expression, just return it.
3001 if (remainingExpressions.tail.isEmpty()) { 3001 if (remainingCases.tail.isEmpty()) {
3002 left(); 3002 left();
3003 return; 3003 return;
3004 } 3004 }
3005 3005
3006 void right() { 3006 void right() {
3007 buildTests(remainingExpressions.tail); 3007 buildTests(remainingCases.tail);
3008 } 3008 }
3009 handleLogicalAndOr(left, right, isAnd: false); 3009 handleLogicalAndOr(left, right, isAnd: false);
3010 } 3010 }
3011 3011
3012 if (node.isDefaultCase) { 3012 if (node.isDefaultCase) {
3013 buildTests(expressions); 3013 // Default case must be last.
3014 // Throw away the test result. We always execute the default case. 3014 assert(cases.tail.isEmpty());
3015 pop(); 3015 // Perform the tests until one of them match, but then always execute the
3016 // statements.
3017 // TODO(lrn): Stop performing tests when all expressions are compile-time
3018 // constant strings or integers.
3019 handleIf(() { buildTests(caseMatches); }, (){}, null);
3016 visit(node.statements); 3020 visit(node.statements);
3017 } else { 3021 } else {
3018 if (cases.tail.isEmpty()) { 3022 if (cases.tail.isEmpty()) {
3019 handleIf(() { buildTests(expressions); }, 3023 handleIf(() { buildTests(caseMatches); },
3020 () { visit(node.statements); }, 3024 () { visit(node.statements); },
3021 null); 3025 null);
3022 } else { 3026 } else {
3023 handleIf(() { buildTests(expressions); }, 3027 handleIf(() { buildTests(caseMatches); },
3024 () { visitStatementsAndAbort(); }, 3028 () { visitStatementsAndAbort(); },
3025 () { buildSwitchCases(cases.tail, expression); }); 3029 () { buildSwitchCases(cases.tail, expression); });
3026 } 3030 }
3027 } 3031 }
3028 } 3032 }
3029 3033
3030 visitSwitchCase(SwitchCase node) { 3034 visitSwitchCase(SwitchCase node) {
3031 unreachable(); 3035 unreachable();
3032 } 3036 }
3033 3037
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
3320 <HInstruction>[target, input], 3324 <HInstruction>[target, input],
3321 HType.STRING)); 3325 HType.STRING));
3322 return builder.pop(); 3326 return builder.pop();
3323 } 3327 }
3324 3328
3325 HInstruction result() { 3329 HInstruction result() {
3326 flushLiterals(); 3330 flushLiterals();
3327 return prefix; 3331 return prefix;
3328 } 3332 }
3329 } 3333 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698