| Index: pkg/compiler/lib/src/js_model/locals.dart
|
| diff --git a/pkg/compiler/lib/src/js_model/locals.dart b/pkg/compiler/lib/src/js_model/locals.dart
|
| index 5f1029f262b5aae6a05f93745133245b7b4a707c..84d3d2876f32c43fc0ca40d57e83d06f8b97a11c 100644
|
| --- a/pkg/compiler/lib/src/js_model/locals.dart
|
| +++ b/pkg/compiler/lib/src/js_model/locals.dart
|
| @@ -171,6 +171,14 @@ class JumpVisitor extends ir.Visitor {
|
| });
|
| }
|
|
|
| + JLabelDefinition _getOrCreateLabel(JJumpTarget target, ir.Node node) {
|
| + if (target.labels.isEmpty) {
|
| + return target.addLabel(node, 'label${labelIndex++}');
|
| + } else {
|
| + return target.labels.single;
|
| + }
|
| + }
|
| +
|
| @override
|
| defaultNode(ir.Node node) => node.visitChildren(this);
|
|
|
| @@ -217,8 +225,8 @@ class JumpVisitor extends ir.Visitor {
|
| search = search.parent;
|
| }
|
| if (needsLabel) {
|
| - target.addLabel(node.target, 'label${labelIndex++}',
|
| - isBreakTarget: true);
|
| + JLabelDefinition label = _getOrCreateLabel(target, node.target);
|
| + label.isBreakTarget = true;
|
| }
|
| } else if (_canBeContinueTarget(parent)) {
|
| // We have code like
|
| @@ -231,6 +239,19 @@ class JumpVisitor extends ir.Visitor {
|
| target = _getJumpTarget(parent);
|
| target.isContinueTarget = true;
|
| breaksAsContinue.add(node);
|
| + ir.TreeNode search = node;
|
| + bool needsLabel = false;
|
| + while (search != node.target) {
|
| + if (_canBeContinueTarget(search)) {
|
| + needsLabel = search != body;
|
| + break;
|
| + }
|
| + search = search.parent;
|
| + }
|
| + if (needsLabel) {
|
| + JLabelDefinition label = _getOrCreateLabel(target, node.target);
|
| + label.isContinueTarget = true;
|
| + }
|
| } else {
|
| target = _getJumpTarget(node.target);
|
| target.isBreakTarget = true;
|
| @@ -244,23 +265,25 @@ class JJumpTarget extends JumpTarget<ir.Node> {
|
| final MemberEntity memberContext;
|
| final int nestingLevel;
|
| List<LabelDefinition<ir.Node>> _labels;
|
| + final bool isSwitch;
|
| + final bool isSwitchCase;
|
|
|
| - JJumpTarget(this.memberContext, this.nestingLevel);
|
| + JJumpTarget(this.memberContext, this.nestingLevel,
|
| + {this.isSwitch: false, this.isSwitchCase: false});
|
|
|
| bool isBreakTarget = false;
|
| bool isContinueTarget = false;
|
| - bool isSwitch = false;
|
|
|
| @override
|
| Entity get executableContext => memberContext;
|
|
|
| @override
|
| LabelDefinition<ir.Node> addLabel(ir.Node label, String labelName,
|
| - {bool isBreakTarget: false}) {
|
| + {bool isBreakTarget: false, bool isContinueTarget: false}) {
|
| _labels ??= <LabelDefinition<ir.Node>>[];
|
| LabelDefinition<ir.Node> labelDefinition = new JLabelDefinition(
|
| - this, label, labelName,
|
| - isBreakTarget: isBreakTarget);
|
| + this, labelName,
|
| + isBreakTarget: isBreakTarget, isContinueTarget: isContinueTarget);
|
| _labels.add(labelDefinition);
|
| return labelDefinition;
|
| }
|
| @@ -297,12 +320,11 @@ class JJumpTarget extends JumpTarget<ir.Node> {
|
|
|
| class JLabelDefinition extends LabelDefinition<ir.Node> {
|
| final JumpTarget<ir.Node> target;
|
| - final ir.Node label;
|
| final String labelName;
|
| - final bool isBreakTarget;
|
| - final bool isContinueTarget;
|
| + bool isBreakTarget;
|
| + bool isContinueTarget;
|
|
|
| - JLabelDefinition(this.target, this.label, this.labelName,
|
| + JLabelDefinition(this.target, this.labelName,
|
| {this.isBreakTarget: false, this.isContinueTarget: false});
|
|
|
| @override
|
| @@ -310,8 +332,6 @@ class JLabelDefinition extends LabelDefinition<ir.Node> {
|
| String toString() {
|
| StringBuffer sb = new StringBuffer();
|
| sb.write('JLabelDefinition(');
|
| - sb.write('label=');
|
| - sb.write(label);
|
| sb.write(',labelName=');
|
| sb.write(labelName);
|
| sb.write(',isBreakTarget=');
|
|
|