Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/dart_backend/dart_codegen.dart |
| diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/dart_codegen.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/dart_codegen.dart |
| index 8d6dda86d779e37787928454d417b3da95016fdf..718d963161c0378332f23696fc8e8f6ff94c635f 100644 |
| --- a/sdk/lib/_internal/compiler/implementation/dart_backend/dart_codegen.dart |
| +++ b/sdk/lib/_internal/compiler/implementation/dart_backend/dart_codegen.dart |
| @@ -212,7 +212,15 @@ class ASTEmitter extends tree.Visitor<dynamic, Expression> { |
| } |
| void visitContinue(tree.Continue stmt) { |
| - statementBuffer.add(new Continue(stmt.target.name)); |
| + tree.Statement fall = fallthrough; |
|
sigurdm
2014/06/10 12:30:06
Why is this in a local?
asgerf
2014/06/10 12:46:42
Because type promotion needs to kick in when we sa
|
| + if (stmt.target.binding == fall) { |
| + // Fall through to continue target |
| + } else if (fall is tree.Continue && fall.target == stmt.target) { |
| + // Fall through to equivalent continue |
| + } else { |
| + usedLabels.add(stmt.target); |
| + statementBuffer.add(new Continue(stmt.target.name)); |
| + } |
| } |
| void visitIf(tree.If stmt) { |
| @@ -227,19 +235,57 @@ class ASTEmitter extends tree.Visitor<dynamic, Expression> { |
| statementBuffer = savedBuffer; |
| } |
| - void visitWhile(tree.While stmt) { |
| - Expression condition = new Literal(new dart2js.BoolConstant(true)); |
| + void visitWhileTrue(tree.WhileTrue stmt) { |
| + List<Expression> updates = stmt.updates.reversed |
| + .map(visitExpression) |
| + .toList(growable:false); |
| + |
| List<Statement> savedBuffer = statementBuffer; |
| + tree.Statement savedFallthrough = fallthrough; |
| statementBuffer = <Statement>[]; |
| + fallthrough = stmt; |
| + |
| + visitStatement(stmt.body); |
| + Statement body = new Block(statementBuffer); |
| + Statement statement = new For(null, null, updates, body); |
| + if (usedLabels.remove(stmt.label.name)) { |
| + statement = new LabeledStatement(stmt.label.name, statement); |
| + } |
| + savedBuffer.add(statement); |
| + |
| + statementBuffer = savedBuffer; |
| + fallthrough = savedFallthrough; |
| + } |
| + |
| + void visitWhileCondition(tree.WhileCondition stmt) { |
| + Expression condition = visitExpression(stmt.condition); |
| + List<Expression> updates = stmt.updates.reversed |
| + .map(visitExpression) |
| + .toList(growable:false); |
| + |
| + List<Statement> savedBuffer = statementBuffer; |
| tree.Statement savedFallthrough = fallthrough; |
| - fallthrough = stmt.body; |
| + statementBuffer = <Statement>[]; |
| + fallthrough = stmt; |
| + |
| visitStatement(stmt.body); |
| - savedBuffer.add( |
| - new LabeledStatement( |
| - stmt.label.name, |
| - new While(condition, new Block(statementBuffer)))); |
| + Statement body = new Block(statementBuffer); |
| + Statement statement; |
| + if (updates.isEmpty) { |
| + // while(E) is the same as for(;E;), but the former is nicer |
| + statement = new While(condition, body); |
| + } else { |
| + statement = new For(null, condition, updates, body); |
| + } |
| + if (usedLabels.remove(stmt.label.name)) { |
| + statement = new LabeledStatement(stmt.label.name, statement); |
| + } |
| + savedBuffer.add(statement); |
| + |
| statementBuffer = savedBuffer; |
| fallthrough = savedFallthrough; |
| + |
| + visitStatement(stmt.next); |
| } |
| Expression visitConstant(tree.Constant exp) { |
| @@ -419,3 +465,4 @@ class ASTEmitter extends tree.Visitor<dynamic, Expression> { |
| } |
| } |
| } |
| + |