| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |