Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 import '../common.dart'; | 5 import '../common.dart'; |
| 6 import '../elements/elements.dart'; | 6 import '../elements/elements.dart'; |
| 7 import '../tree/tree.dart' as ast; | 7 import '../tree/tree.dart' as ast; |
| 8 | 8 |
| 9 import 'builder.dart'; | 9 import 'builder.dart'; |
| 10 import 'graph_builder.dart'; | 10 import 'graph_builder.dart'; |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 143 for (LabelDefinition element in target.labels) { | 143 for (LabelDefinition element in target.labels) { |
| 144 result ??= <LabelDefinition>[]; | 144 result ??= <LabelDefinition>[]; |
| 145 result.add(element); | 145 result.add(element); |
| 146 } | 146 } |
| 147 return result ?? const <LabelDefinition>[]; | 147 return result ?? const <LabelDefinition>[]; |
| 148 } | 148 } |
| 149 } | 149 } |
| 150 | 150 |
| 151 /// Special [JumpHandler] implementation used to handle continue statements | 151 /// Special [JumpHandler] implementation used to handle continue statements |
| 152 /// targeting switch cases. | 152 /// targeting switch cases. |
| 153 class SwitchCaseJumpHandler extends TargetJumpHandler { | 153 abstract class SwitchCaseJumpHandler extends TargetJumpHandler { |
| 154 /// Map from switch case targets to indices used to encode the flow of the | 154 /// Map from switch case targets to indices used to encode the flow of the |
| 155 /// switch case loop. | 155 /// switch case loop. |
| 156 final Map<JumpTarget, int> targetIndexMap = new Map<JumpTarget, int>(); | 156 final Map<JumpTarget, int> targetIndexMap = new Map<JumpTarget, int>(); |
| 157 | 157 |
| 158 SwitchCaseJumpHandler( | 158 SwitchCaseJumpHandler( |
| 159 GraphBuilder builder, JumpTarget target, ast.SwitchStatement node) | 159 GraphBuilder builder, JumpTarget target) : super(builder, target); |
| 160 : super(builder, target) { | |
| 161 // The switch case indices must match those computed in | |
| 162 // [SsaFromAstMixin.buildSwitchCaseConstants]. | |
| 163 // Switch indices are 1-based so we can bypass the synthetic loop when no | |
| 164 // cases match simply by branching on the index (which defaults to null). | |
| 165 int switchIndex = 1; | |
| 166 for (ast.SwitchCase switchCase in node.cases) { | |
| 167 for (ast.Node labelOrCase in switchCase.labelsAndCases) { | |
| 168 ast.Node label = labelOrCase.asLabel(); | |
| 169 if (label != null) { | |
| 170 LabelDefinition labelElement = | |
| 171 builder.elements.getLabelDefinition(label); | |
| 172 if (labelElement != null && labelElement.isContinueTarget) { | |
| 173 JumpTarget continueTarget = labelElement.target; | |
| 174 targetIndexMap[continueTarget] = switchIndex; | |
| 175 assert(builder.jumpTargets[continueTarget] == null); | |
| 176 builder.jumpTargets[continueTarget] = this; | |
| 177 } | |
| 178 } | |
| 179 } | |
| 180 switchIndex++; | |
| 181 } | |
| 182 } | |
| 183 | 160 |
| 184 void generateBreak([LabelDefinition label]) { | 161 void generateBreak([LabelDefinition label]) { |
| 185 if (label == null) { | 162 if (label == null) { |
| 186 // Creates a special break instruction for the synthetic loop generated | 163 // Creates a special break instruction for the synthetic loop generated |
| 187 // for a switch statement with continue statements. See | 164 // for a switch statement with continue statements. See |
| 188 // [SsaFromAstMixin.buildComplexSwitchStatement] for detail. | 165 // [SsaFromAstMixin.buildComplexSwitchStatement] for detail. |
| 189 | 166 |
| 190 HInstruction breakInstruction = | 167 HInstruction breakInstruction = |
| 191 new HBreak(target, breakSwitchContinueLoop: true); | 168 new HBreak(target, breakSwitchContinueLoop: true); |
| 192 LocalsHandler locals = new LocalsHandler.from(builder.localsHandler); | 169 LocalsHandler locals = new LocalsHandler.from(builder.localsHandler); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 225 } | 202 } |
| 226 | 203 |
| 227 void close() { | 204 void close() { |
| 228 // The mapping from TargetElement to JumpHandler is no longer needed. | 205 // The mapping from TargetElement to JumpHandler is no longer needed. |
| 229 for (JumpTarget target in targetIndexMap.keys) { | 206 for (JumpTarget target in targetIndexMap.keys) { |
| 230 builder.jumpTargets.remove(target); | 207 builder.jumpTargets.remove(target); |
| 231 } | 208 } |
| 232 super.close(); | 209 super.close(); |
| 233 } | 210 } |
| 234 } | 211 } |
| 212 | |
| 213 /// Special [JumpHandler] implementation used to handle continue statements | |
| 214 /// targeting switch cases. | |
| 215 class SsaSwitchCaseJumpHandler extends SwitchCaseJumpHandler { | |
|
sra1
2017/01/19 23:03:47
Ssa -> Ast
They are both SSA, one from Ast, one fr
Emily Fortuna
2017/01/19 23:19:01
Done.
| |
| 216 | |
| 217 SsaSwitchCaseJumpHandler( | |
| 218 GraphBuilder builder, JumpTarget target, ast.SwitchStatement node) | |
| 219 : super(builder, target) { | |
| 220 // The switch case indices must match those computed in | |
| 221 // [SsaFromAstMixin.buildSwitchCaseConstants]. | |
| 222 // Switch indices are 1-based so we can bypass the synthetic loop when no | |
| 223 // cases match simply by branching on the index (which defaults to null). | |
| 224 int switchIndex = 1; | |
| 225 for (ast.SwitchCase switchCase in node.cases) { | |
| 226 for (ast.Node labelOrCase in switchCase.labelsAndCases) { | |
| 227 ast.Node label = labelOrCase.asLabel(); | |
| 228 if (label != null) { | |
| 229 LabelDefinition labelElement = | |
| 230 builder.elements.getLabelDefinition(label); | |
| 231 if (labelElement != null && labelElement.isContinueTarget) { | |
| 232 JumpTarget continueTarget = labelElement.target; | |
| 233 targetIndexMap[continueTarget] = switchIndex; | |
| 234 assert(builder.jumpTargets[continueTarget] == null); | |
| 235 builder.jumpTargets[continueTarget] = this; | |
| 236 } | |
| 237 } | |
| 238 } | |
| 239 switchIndex++; | |
| 240 } | |
| 241 } | |
| 242 } | |
| OLD | NEW |