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

Side by Side Diff: pkg/compiler/lib/src/js_backend/codegen/codegen.dart

Issue 1575593002: dart2js cps: Name labels uniquely within each method, not globally. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Typo Created 4 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
« no previous file with comments | « no previous file | pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 library code_generator; 5 library code_generator;
6 6
7 import 'glue.dart'; 7 import 'glue.dart';
8 8
9 import '../../closure.dart' show 9 import '../../closure.dart' show
10 ClosureClassElement; 10 ClosureClassElement;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 /// followed by the end of the method. 74 /// followed by the end of the method.
75 /// 75 ///
76 /// Note on why the [fallthrough] stack should not be used for this: 76 /// Note on why the [fallthrough] stack should not be used for this:
77 /// Ordinary statements may choose whether to use the [fallthrough] target, 77 /// Ordinary statements may choose whether to use the [fallthrough] target,
78 /// and the choice to do so may disable an optimization in [visitIf]. 78 /// and the choice to do so may disable an optimization in [visitIf].
79 /// But omitting an unreachable 'return' should have lower priority than 79 /// But omitting an unreachable 'return' should have lower priority than
80 /// the optimizations in [visitIf], so [visitIf] will instead tell the 80 /// the optimizations in [visitIf], so [visitIf] will instead tell the
81 /// [Unreachable] statements whether they may use fallthrough or not. 81 /// [Unreachable] statements whether they may use fallthrough or not.
82 List<bool> emitUnreachableAsReturn = <bool>[false]; 82 List<bool> emitUnreachableAsReturn = <bool>[false];
83 83
84 Set<tree_ir.Label> usedLabels = new Set<tree_ir.Label>(); 84 final Map<tree_ir.Label, String> labelNames = <tree_ir.Label, String>{};
85 85
86 List<js.Statement> accumulator = new List<js.Statement>(); 86 List<js.Statement> accumulator = new List<js.Statement>();
87 87
88 CodeGenerator(this.glue, this.registry); 88 CodeGenerator(this.glue, this.registry);
89 89
90 /// Generates JavaScript code for the body of [function]. 90 /// Generates JavaScript code for the body of [function].
91 js.Fun buildFunction(tree_ir.FunctionDefinition function) { 91 js.Fun buildFunction(tree_ir.FunctionDefinition function) {
92 registerDefaultParameterValues(function.element); 92 registerDefaultParameterValues(function.element);
93 currentFunction = function.element; 93 currentFunction = function.element;
94 visitStatement(function.body); 94 visitStatement(function.body);
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 tree_ir.Statement next = fallthrough.target; 574 tree_ir.Statement next = fallthrough.target;
575 if (node.target.binding == next || 575 if (node.target.binding == next ||
576 next is tree_ir.Continue && node.target == next.target) { 576 next is tree_ir.Continue && node.target == next.target) {
577 // Fall through to continue target or to equivalent continue. 577 // Fall through to continue target or to equivalent continue.
578 fallthrough.use(); 578 fallthrough.use();
579 } else if (node.target.binding == shortContinue.target) { 579 } else if (node.target.binding == shortContinue.target) {
580 // The target is the immediately enclosing loop. 580 // The target is the immediately enclosing loop.
581 shortContinue.use(); 581 shortContinue.use();
582 accumulator.add(new js.Continue(null)); 582 accumulator.add(new js.Continue(null));
583 } else { 583 } else {
584 usedLabels.add(node.target); 584 accumulator.add(new js.Continue(makeLabel(node.target)));
585 accumulator.add(new js.Continue(node.target.name));
586 } 585 }
587 } 586 }
588 587
589 /// True if [other] is the target of [node] or is a [Break] with the same 588 /// True if [other] is the target of [node] or is a [Break] with the same
590 /// target. This means jumping to [other] is equivalent to executing [node]. 589 /// target. This means jumping to [other] is equivalent to executing [node].
591 bool isEffectiveBreakTarget(tree_ir.Break node, tree_ir.Statement other) { 590 bool isEffectiveBreakTarget(tree_ir.Break node, tree_ir.Statement other) {
592 return node.target.binding.next == other || 591 return node.target.binding.next == other ||
593 other is tree_ir.Break && node.target == other.target; 592 other is tree_ir.Break && node.target == other.target;
594 } 593 }
595 594
(...skipping 11 matching lines...) Expand all
607 fallthrough.use(); 606 fallthrough.use();
608 } else if (isEffectiveBreakTarget(node, shortBreak.target)) { 607 } else if (isEffectiveBreakTarget(node, shortBreak.target)) {
609 // Unlabeled break to the break target or to an equivalent break. 608 // Unlabeled break to the break target or to an equivalent break.
610 shortBreak.use(); 609 shortBreak.use();
611 accumulator.add(new js.Break(null)); 610 accumulator.add(new js.Break(null));
612 } else if (isShortContinue(node)) { 611 } else if (isShortContinue(node)) {
613 // An unlabeled continue is better than a labeled break. 612 // An unlabeled continue is better than a labeled break.
614 shortContinue.use(); 613 shortContinue.use();
615 accumulator.add(new js.Continue(null)); 614 accumulator.add(new js.Continue(null));
616 } else { 615 } else {
617 usedLabels.add(node.target); 616 accumulator.add(new js.Break(makeLabel(node.target)));
618 accumulator.add(new js.Break(node.target.name));
619 } 617 }
620 } 618 }
621 619
622 @override 620 @override
623 void visitExpressionStatement(tree_ir.ExpressionStatement node) { 621 void visitExpressionStatement(tree_ir.ExpressionStatement node) {
624 js.Expression exp = visitExpression(node.expression); 622 js.Expression exp = visitExpression(node.expression);
625 if (node.next is tree_ir.Unreachable && emitUnreachableAsReturn.last) { 623 if (node.next is tree_ir.Unreachable && emitUnreachableAsReturn.last) {
626 // Emit as 'return exp' to assist local analysis in the VM. 624 // Emit as 'return exp' to assist local analysis in the VM.
627 accumulator.add(new js.Return(exp)); 625 accumulator.add(new js.Return(exp));
628 } else { 626 } else {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 661
664 @override 662 @override
665 void visitLabeledStatement(tree_ir.LabeledStatement node) { 663 void visitLabeledStatement(tree_ir.LabeledStatement node) {
666 fallthrough.push(node.next); 664 fallthrough.push(node.next);
667 js.Statement body = buildBodyStatement(node.body); 665 js.Statement body = buildBodyStatement(node.body);
668 fallthrough.pop(); 666 fallthrough.pop();
669 accumulator.add(insertLabel(node.label, body)); 667 accumulator.add(insertLabel(node.label, body));
670 visitStatement(node.next); 668 visitStatement(node.next);
671 } 669 }
672 670
671 /// Creates a name for [label] if it does not already have one.
672 ///
673 /// This also marks the label as being used.
674 String makeLabel(tree_ir.Label label) {
675 String name = labelNames[label];
Kevin Millikin (Google) 2016/01/08 22:05:47 You could use putIfAbsent here.
asgerf 2016/01/08 22:13:29 Done.
676 if (name != null) return name;
677 int count = labelNames.length;
678 return labelNames[label] = 'L$count';
679 }
680
673 /// Wraps a node in a labeled statement unless the label is unused. 681 /// Wraps a node in a labeled statement unless the label is unused.
674 js.Statement insertLabel(tree_ir.Label label, js.Statement node) { 682 js.Statement insertLabel(tree_ir.Label label, js.Statement node) {
675 if (usedLabels.remove(label)) { 683 String name = labelNames[label];
676 return new js.LabeledStatement(label.name, node); 684 if (name == null) return node; // Label is unused.
677 } else { 685 return new js.LabeledStatement(name, node);
678 return node;
679 }
680 } 686 }
681 687
682 /// Returns the current [accumulator] wrapped in a block if neccessary. 688 /// Returns the current [accumulator] wrapped in a block if neccessary.
683 js.Statement _bodyAsStatement() { 689 js.Statement _bodyAsStatement() {
684 if (accumulator.length == 0) { 690 if (accumulator.length == 0) {
685 return new js.EmptyStatement(); 691 return new js.EmptyStatement();
686 } 692 }
687 if (accumulator.length == 1) { 693 if (accumulator.length == 1) {
688 return accumulator.single; 694 return accumulator.single;
689 } 695 }
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after
1227 void registerDefaultParameterValues(ExecutableElement element) { 1233 void registerDefaultParameterValues(ExecutableElement element) {
1228 if (element is! FunctionElement) return; 1234 if (element is! FunctionElement) return;
1229 FunctionElement function = element; 1235 FunctionElement function = element;
1230 if (function.isStatic) return; // Defaults are inlined at call sites. 1236 if (function.isStatic) return; // Defaults are inlined at call sites.
1231 function.functionSignature.forEachOptionalParameter((param) { 1237 function.functionSignature.forEachOptionalParameter((param) {
1232 ConstantValue constant = glue.getDefaultParameterValue(param); 1238 ConstantValue constant = glue.getDefaultParameterValue(param);
1233 registry.registerCompileTimeConstant(constant); 1239 registry.registerCompileTimeConstant(constant);
1234 }); 1240 });
1235 } 1241 }
1236 } 1242 }
OLDNEW
« no previous file with comments | « no previous file | pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698