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

Side by Side Diff: pkg/compiler/lib/src/ssa/jump_handler.dart

Issue 2648443004: Implement complex switch statement (switch with continue). (Closed)
Patch Set: . Created 3 years, 11 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
OLDNEW
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698