| 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 'package:kernel/ast.dart' as ir; | 5 import 'package:kernel/ast.dart' as ir; |
| 6 | 6 |
| 7 import '../elements/elements.dart'; | 7 import '../elements/elements.dart'; |
| 8 import '../io/source_information.dart'; | 8 import '../io/source_information.dart'; |
| 9 import '../tree/tree.dart' as ast; | 9 import '../tree/tree.dart' as ast; |
| 10 | 10 |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 | 99 |
| 100 if (bodyBlock != null) { | 100 if (bodyBlock != null) { |
| 101 continueHandlers.add(builder.localsHandler); | 101 continueHandlers.add(builder.localsHandler); |
| 102 bodyBlock.addSuccessor(updateBlock); | 102 bodyBlock.addSuccessor(updateBlock); |
| 103 } | 103 } |
| 104 | 104 |
| 105 builder.open(updateBlock); | 105 builder.open(updateBlock); |
| 106 builder.localsHandler = | 106 builder.localsHandler = |
| 107 continueHandlers[0].mergeMultiple(continueHandlers, updateBlock); | 107 continueHandlers[0].mergeMultiple(continueHandlers, updateBlock); |
| 108 | 108 |
| 109 List<LabelDefinition> labels = jumpHandler.labels(); | 109 List<LabelDefinition> labels = jumpHandler.labels; |
| 110 JumpTarget target = getTargetDefinition(loop); | 110 JumpTarget target = getTargetDefinition(loop); |
| 111 if (!labels.isEmpty) { | 111 if (labels.isNotEmpty) { |
| 112 beginBodyBlock.setBlockFlow( | 112 beginBodyBlock.setBlockFlow( |
| 113 new HLabeledBlockInformation( | 113 new HLabeledBlockInformation( |
| 114 new HSubGraphBlockInformation(bodyGraph), jumpHandler.labels(), | 114 new HSubGraphBlockInformation(bodyGraph), jumpHandler.labels, |
| 115 isContinue: true), | 115 isContinue: true), |
| 116 updateBlock); | 116 updateBlock); |
| 117 } else if (target != null && target.isContinueTarget) { | 117 } else if (target != null && target.isContinueTarget) { |
| 118 beginBodyBlock.setBlockFlow( | 118 beginBodyBlock.setBlockFlow( |
| 119 new HLabeledBlockInformation.implicit( | 119 new HLabeledBlockInformation.implicit( |
| 120 new HSubGraphBlockInformation(bodyGraph), target, | 120 new HSubGraphBlockInformation(bodyGraph), target, |
| 121 isContinue: true), | 121 isContinue: true), |
| 122 updateBlock); | 122 updateBlock); |
| 123 } | 123 } |
| 124 | 124 |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 | 215 |
| 216 /// Creates a new loop-header block. The previous [current] block | 216 /// Creates a new loop-header block. The previous [current] block |
| 217 /// is closed with an [HGoto] and replaced by the newly created block. | 217 /// is closed with an [HGoto] and replaced by the newly created block. |
| 218 /// Also notifies the locals handler that we're entering a loop. | 218 /// Also notifies the locals handler that we're entering a loop. |
| 219 JumpHandler beginLoopHeader(T node) { | 219 JumpHandler beginLoopHeader(T node) { |
| 220 assert(!builder.isAborted()); | 220 assert(!builder.isAborted()); |
| 221 HBasicBlock previousBlock = builder.close(new HGoto()); | 221 HBasicBlock previousBlock = builder.close(new HGoto()); |
| 222 | 222 |
| 223 JumpHandler jumpHandler = createJumpHandler(node, isLoopJump: true); | 223 JumpHandler jumpHandler = createJumpHandler(node, isLoopJump: true); |
| 224 HBasicBlock loopEntry = builder.graph | 224 HBasicBlock loopEntry = builder.graph |
| 225 .addNewLoopHeaderBlock(jumpHandler.target, jumpHandler.labels()); | 225 .addNewLoopHeaderBlock(jumpHandler.target, jumpHandler.labels); |
| 226 previousBlock.addSuccessor(loopEntry); | 226 previousBlock.addSuccessor(loopEntry); |
| 227 builder.open(loopEntry); | 227 builder.open(loopEntry); |
| 228 | 228 |
| 229 builder.localsHandler.beginLoopHeader(loopEntry); | 229 builder.localsHandler.beginLoopHeader(loopEntry); |
| 230 return jumpHandler; | 230 return jumpHandler; |
| 231 } | 231 } |
| 232 | 232 |
| 233 /// Ends the loop. | 233 /// Ends the loop. |
| 234 /// | 234 /// |
| 235 /// It does this by: | 235 /// It does this by: |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP; | 343 int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP; |
| 344 int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP; | 344 int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP; |
| 345 int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; | 345 int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; |
| 346 int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; | 346 int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; |
| 347 int visitSwitchStatement(ast.SwitchStatement node) => | 347 int visitSwitchStatement(ast.SwitchStatement node) => |
| 348 HLoopBlockInformation.SWITCH_CONTINUE_LOOP; | 348 HLoopBlockInformation.SWITCH_CONTINUE_LOOP; |
| 349 } | 349 } |
| 350 | 350 |
| 351 // TODO(het): Since kernel simplifies loop breaks and continues, we should | 351 // TODO(het): Since kernel simplifies loop breaks and continues, we should |
| 352 // rewrite the loop handler from scratch to account for the simplified structure | 352 // rewrite the loop handler from scratch to account for the simplified structure |
| 353 class KernelLoopHandler extends LoopHandler<ir.Node> { | 353 class KernelLoopHandler extends LoopHandler<ir.TreeNode> { |
| 354 final KernelSsaBuilder builder; | 354 final KernelSsaBuilder builder; |
| 355 | 355 |
| 356 KernelAstAdapter get astAdapter => builder.astAdapter; | 356 KernelAstAdapter get astAdapter => builder.astAdapter; |
| 357 | 357 |
| 358 KernelLoopHandler(KernelSsaBuilder builder) | 358 KernelLoopHandler(KernelSsaBuilder builder) |
| 359 : this.builder = builder, | 359 : this.builder = builder, |
| 360 super(builder); | 360 super(builder); |
| 361 | 361 |
| 362 @override | 362 @override |
| 363 JumpHandler createJumpHandler(ir.Node node, {bool isLoopJump}) { | 363 JumpHandler createJumpHandler(ir.TreeNode node, {bool isLoopJump}) { |
| 364 JumpTarget element = getTargetDefinition(node); | 364 if (node.parent is! ir.LabeledStatement) { |
| 365 if (element == null || !identical(element.statement, node)) { | |
| 366 // No breaks or continues to this node. | 365 // No breaks or continues to this node. |
| 367 return new NullJumpHandler(builder.compiler.reporter); | 366 return new NullJumpHandler(builder.compiler.reporter); |
| 368 } | 367 } |
| 369 if (isLoopJump && node is ast.SwitchStatement) { | 368 // We must have already created a JumpHandler for the labeled statement |
| 370 // Create a special jump handler for loops created for switch statements | 369 JumpHandler result = |
| 371 // with continue statements. | 370 builder.jumpTargets[astAdapter.getJumpTarget(node.parent)]; |
| 372 return new SwitchCaseJumpHandler(builder, element, getNode(node)); | 371 assert(result != null); |
| 373 } | 372 return result; |
| 374 return new JumpHandler(builder, element); | |
| 375 } | 373 } |
| 376 | 374 |
| 377 @override | 375 @override |
| 378 ast.Node getNode(ir.Node node) => astAdapter.getNode(node); | 376 ast.Node getNode(ir.TreeNode node) => astAdapter.getNode(node); |
| 379 | 377 |
| 380 @override | 378 @override |
| 381 JumpTarget getTargetDefinition(ir.Node node) => | 379 JumpTarget getTargetDefinition(ir.TreeNode node) { |
| 382 astAdapter.getTargetDefinition(node); | 380 if (node.parent is ir.LabeledStatement) { |
| 381 return astAdapter.getJumpTarget(node.parent); |
| 382 } |
| 383 return null; |
| 384 } |
| 383 | 385 |
| 384 @override | 386 @override |
| 385 int loopKind(ir.Node node) => node.accept(new _KernelLoopTypeVisitor()); | 387 int loopKind(ir.TreeNode node) => node.accept(new _KernelLoopTypeVisitor()); |
| 386 | 388 |
| 387 // TODO(het): return the actual source information | 389 // TODO(het): return the actual source information |
| 388 @override | 390 @override |
| 389 SourceInformation loopSourceInformation(ir.Node node) => null; | 391 SourceInformation loopSourceInformation(ir.TreeNode node) => null; |
| 390 } | 392 } |
| 391 | 393 |
| 392 class _KernelLoopTypeVisitor extends ir.Visitor<int> { | 394 class _KernelLoopTypeVisitor extends ir.Visitor<int> { |
| 393 @override | 395 @override |
| 394 int defaultNode(ir.Node node) => HLoopBlockInformation.NOT_A_LOOP; | 396 int defaultNode(ir.Node node) => HLoopBlockInformation.NOT_A_LOOP; |
| 395 | 397 |
| 396 @override | 398 @override |
| 397 int visitWhileStatement(ir.WhileStatement node) => | 399 int visitWhileStatement(ir.WhileStatement node) => |
| 398 HLoopBlockInformation.WHILE_LOOP; | 400 HLoopBlockInformation.WHILE_LOOP; |
| 399 | 401 |
| 400 @override | 402 @override |
| 401 int visitForStatement(ir.ForStatement node) => HLoopBlockInformation.FOR_LOOP; | 403 int visitForStatement(ir.ForStatement node) => HLoopBlockInformation.FOR_LOOP; |
| 402 | 404 |
| 403 @override | 405 @override |
| 404 int visitDoStatement(ir.DoStatement node) => | 406 int visitDoStatement(ir.DoStatement node) => |
| 405 HLoopBlockInformation.DO_WHILE_LOOP; | 407 HLoopBlockInformation.DO_WHILE_LOOP; |
| 406 | 408 |
| 407 @override | 409 @override |
| 408 int visitForInStatement(ir.ForInStatement node) => | 410 int visitForInStatement(ir.ForInStatement node) => |
| 409 HLoopBlockInformation.FOR_IN_LOOP; | 411 HLoopBlockInformation.FOR_IN_LOOP; |
| 410 | 412 |
| 411 @override | 413 @override |
| 412 int visitSwitchStatement(ir.SwitchStatement node) => | 414 int visitSwitchStatement(ir.SwitchStatement node) => |
| 413 HLoopBlockInformation.SWITCH_CONTINUE_LOOP; | 415 HLoopBlockInformation.SWITCH_CONTINUE_LOOP; |
| 414 } | 416 } |
| OLD | NEW |