| Index: pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
|
| diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
|
| index b0af0b99253e6a1fa3c2699e67f28acbc7820339..4395c00995b7a855765889c847b175a20726767c 100644
|
| --- a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
|
| +++ b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
|
| @@ -2011,23 +2011,25 @@ abstract class BlockVisitor<T> {
|
|
|
| /// Visits block-level nodes in lexical pre-order.
|
| ///
|
| - /// The IR may be transformed during the traversal, but the currently
|
| - /// visited node should not be removed, as its 'body' pointer is needed
|
| - /// for the traversal.
|
| + /// Traversal continues at the original success for the current node, so:
|
| + /// - The current node can safely be removed.
|
| + /// - Nodes inserted immediately below the current node will not be seen.
|
| + /// - The body of the current node should not be moved/removed, as traversal
|
| + /// would otherwise continue into an orphaned or relocated node.
|
| static void traverseInPreOrder(FunctionDefinition root, BlockVisitor v) {
|
| List<Continuation> stack = <Continuation>[];
|
| void walkBlock(InteriorNode block) {
|
| v.visit(block);
|
| Expression node = block.body;
|
| - v.visit(node);
|
| - while (node.next != null) {
|
| + while (node != null) {
|
| if (node is LetCont) {
|
| stack.addAll(node.continuations);
|
| } else if (node is LetHandler) {
|
| stack.add(node.handler);
|
| }
|
| - node = node.next;
|
| + Expression next = node.next;
|
| v.visit(node);
|
| + node = next;
|
| }
|
| }
|
| walkBlock(root);
|
|
|