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

Side by Side Diff: pkg/compiler/lib/src/js/rewrite_async.dart

Issue 1003213002: Fix "continue to a label" in dart2js async code. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address review. Also update unittest Created 5 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | tests/compiler/dart2js/async_await_js_transform_test.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) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 rewrite_async; 5 library rewrite_async;
6 6
7 import "dart:math" show max; 7 import "dart:math" show max;
8 import 'dart:collection'; 8 import 'dart:collection';
9 9
10 import 'package:_internal/compiler/js_lib/shared/async_await_error_codes.dart' 10 import 'package:_internal/compiler/js_lib/shared/async_await_error_codes.dart'
(...skipping 978 matching lines...) Expand 10 before | Expand all | Expand 10 after
989 [condition, gotoAndBreak(startLabel)])); 989 [condition, gotoAndBreak(startLabel)]));
990 }, store: false); 990 }, store: false);
991 beginLabel(afterLabel); 991 beginLabel(afterLabel);
992 } 992 }
993 993
994 @override 994 @override
995 void visitEmptyStatement(js.EmptyStatement node) { 995 void visitEmptyStatement(js.EmptyStatement node) {
996 addStatement(node); 996 addStatement(node);
997 } 997 }
998 998
999 void visitExpressionInStatementContext(js.Expression node) { 999
1000 if (node is js.VariableDeclarationList) { 1000 @override
1001 // Treat js.VariableDeclarationList as a statement. 1001 void visitExpressionStatement(js.ExpressionStatement node) {
1002 visitVariableDeclarationList(node); 1002 visitExpressionIgnoreResult(node.expression);
1003 } else {
1004 visitExpressionIgnoreResult(node);
1005 }
1006 } 1003 }
1007 1004
1008 @override 1005 @override
1009 void visitExpressionStatement(js.ExpressionStatement node) {
1010 visitExpressionInStatementContext(node.expression);
1011 }
1012
1013 @override
1014 void visitFor(js.For node) { 1006 void visitFor(js.For node) {
1015 if (!shouldTransform(node)) { 1007 if (!shouldTransform(node)) {
1016 bool oldInsideUntranslated = insideUntranslatedBreakable; 1008 bool oldInsideUntranslated = insideUntranslatedBreakable;
1017 insideUntranslatedBreakable = true; 1009 insideUntranslatedBreakable = true;
1018 // Note that node.init, node.condition, node.update all can be null, but 1010 // Note that node.init, node.condition, node.update all can be null, but
1019 // withExpressions handles that. 1011 // withExpressions handles that.
1020 withExpressions([ 1012 withExpressions([
1021 node.init, 1013 node.init,
1022 node.condition, 1014 node.condition,
1023 node.update 1015 node.update
1024 ], (List<js.Expression> transformed) { 1016 ], (List<js.Expression> transformed) {
1025 addStatement(new js.For(transformed[0], transformed[1], transformed[2], 1017 addStatement(new js.For(transformed[0], transformed[1], transformed[2],
1026 translateInBlock(node.body))); 1018 translateInBlock(node.body)));
1027 }); 1019 });
1028 insideUntranslatedBreakable = oldInsideUntranslated; 1020 insideUntranslatedBreakable = oldInsideUntranslated;
1029 return; 1021 return;
1030 } 1022 }
1031 1023
1032 if (node.init != null) { 1024 if (node.init != null) {
1033 visitExpressionInStatementContext(node.init); 1025 addExpressionStatement(visitExpression(node.init));
1034 } 1026 }
1035 int startLabel = newLabel("for condition"); 1027 int startLabel = newLabel("for condition");
1036 // If there is no update, continuing the loop is the same as going to the 1028 // If there is no update, continuing the loop is the same as going to the
1037 // start. 1029 // start.
1038 int continueLabel = 1030 int continueLabel =
1039 (node.update == null) ? startLabel : newLabel("for update"); 1031 (node.update == null) ? startLabel : newLabel("for update");
1040 continueLabels[node] = continueLabel; 1032 continueLabels[node] = continueLabel;
1041 int afterLabel = newLabel("after for"); 1033 int afterLabel = newLabel("after for");
1042 breakLabels[node] = afterLabel; 1034 breakLabels[node] = afterLabel;
1043 beginLabel(startLabel); 1035 beginLabel(startLabel);
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1147 return unsupported(node); 1139 return unsupported(node);
1148 } 1140 }
1149 1141
1150 @override 1142 @override
1151 void visitLabeledStatement(js.LabeledStatement node) { 1143 void visitLabeledStatement(js.LabeledStatement node) {
1152 if (!shouldTransform(node)) { 1144 if (!shouldTransform(node)) {
1153 addStatement( 1145 addStatement(
1154 new js.LabeledStatement(node.label, translateInBlock(node.body))); 1146 new js.LabeledStatement(node.label, translateInBlock(node.body)));
1155 return; 1147 return;
1156 } 1148 }
1149 // `continue label` is really continuing the nested loop.
1150 // This is set up in [PreTranslationAnalysis.visitContinue].
1151 // Here we only need a breakLabel:
1157 int breakLabel = newLabel("break ${node.label}"); 1152 int breakLabel = newLabel("break ${node.label}");
1158 int continueLabel = newLabel("continue ${node.label}");
1159 breakLabels[node] = breakLabel; 1153 breakLabels[node] = breakLabel;
1160 continueLabels[node] = continueLabel;
1161 1154
1162 beginLabel(continueLabel);
1163 jumpTargets.add(node); 1155 jumpTargets.add(node);
1164 visitStatement(node.body); 1156 visitStatement(node.body);
1165 jumpTargets.removeLast(); 1157 jumpTargets.removeLast();
1166 beginLabel(breakLabel); 1158 beginLabel(breakLabel);
1167 } 1159 }
1168 1160
1169 @override 1161 @override
1170 js.Expression visitLiteralBool(js.LiteralBool node) => node; 1162 js.Expression visitLiteralBool(js.LiteralBool node) => node;
1171 1163
1172 @override 1164 @override
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
1528 } 1520 }
1529 beginLabel(afterFinallyLabel); 1521 beginLabel(afterFinallyLabel);
1530 } 1522 }
1531 1523
1532 @override 1524 @override
1533 visitVariableDeclaration(js.VariableDeclaration node) { 1525 visitVariableDeclaration(js.VariableDeclaration node) {
1534 unreachable(node); 1526 unreachable(node);
1535 } 1527 }
1536 1528
1537 @override 1529 @override
1538 void visitVariableDeclarationList(js.VariableDeclarationList node) { 1530 js.Expression visitVariableDeclarationList(js.VariableDeclarationList node) {
1531 List<js.Assignment> initializations = new List<js.Assignment>();
1532
1539 // Declaration of local variables is hoisted outside the helper but the 1533 // Declaration of local variables is hoisted outside the helper but the
1540 // initialization is done here. 1534 // initialization is done here.
1541 for (js.VariableInitialization initialization in node.declarations) { 1535 for (js.VariableInitialization initialization in node.declarations) {
1542 js.VariableDeclaration declaration = initialization.declaration; 1536 js.VariableDeclaration declaration = initialization.declaration;
1543 localVariables.add(declaration); 1537 localVariables.add(declaration);
1544 if (initialization.value != null) { 1538 if (initialization.value != null) {
1545 withExpression(initialization.value, (js.Expression value) { 1539 withExpression(initialization.value, (js.Expression value) {
1546 addStatement(new js.ExpressionStatement( 1540 initializations.add(
1547 new js.Assignment(new js.VariableUse(declaration.name), value))); 1541 new js.Assignment(new js.VariableUse(declaration.name), value));
1548 }, store: false); 1542 }, store: false);
1549 } 1543 }
1550 } 1544 }
1545 if (initializations.isEmpty) {
1546 // Dummy expression. Will be dropped by [visitExpressionIgnoreResult].
1547 return js.number(0);
1548 } else {
1549 return initializations.reduce(
1550 (js.Expression first, js.Expression second) {
1551 return new js.Binary(",", first, second);
1552 });
1553 }
1551 } 1554 }
1552 1555
1553 @override 1556 @override
1554 void visitVariableInitialization(js.VariableInitialization node) { 1557 void visitVariableInitialization(js.VariableInitialization node) {
1555 unreachable(node); 1558 unreachable(node);
1556 } 1559 }
1557 1560
1558 @override 1561 @override
1559 js.Expression visitVariableUse(js.VariableUse node) { 1562 js.Expression visitVariableUse(js.VariableUse node) {
1560 Pair<String, String> renaming = variableRenamings.lastWhere( 1563 Pair<String, String> renaming = variableRenamings.lastWhere(
(...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after
2244 bool visitConditional(js.Conditional node) { 2247 bool visitConditional(js.Conditional node) {
2245 bool condition = visit(node.condition); 2248 bool condition = visit(node.condition);
2246 bool then = visit(node.then); 2249 bool then = visit(node.then);
2247 bool otherwise = visit(node.otherwise); 2250 bool otherwise = visit(node.otherwise);
2248 return condition || then || otherwise; 2251 return condition || then || otherwise;
2249 } 2252 }
2250 2253
2251 @override 2254 @override
2252 bool visitContinue(js.Continue node) { 2255 bool visitContinue(js.Continue node) {
2253 if (node.targetLabel != null) { 2256 if (node.targetLabel != null) {
2254 targets[node] = labelledStatements.lastWhere( 2257 js.LabeledStatement targetLabel = labelledStatements.lastWhere(
2255 (js.LabeledStatement stm) => stm.label == node.targetLabel); 2258 (js.LabeledStatement stm) => stm.label == node.targetLabel);
2259 js.Loop targetStatement = targetLabel.body;
2260 targets[node] = targetStatement;
2256 } else { 2261 } else {
2257 targets[node] = 2262 targets[node] =
2258 loopsAndSwitches.lastWhere((js.Node node) => node is! js.Switch); 2263 loopsAndSwitches.lastWhere((js.Node node) => node is! js.Switch);
2259 } 2264 }
2260 assert(() { 2265 assert(() {
2261 js.Node target = targets[node]; 2266 js.Node target = targets[node];
2262 return target is js.Loop || 2267 return target is js.Loop ||
2263 (target is js.LabeledStatement && target.body is js.Loop); 2268 (target is js.LabeledStatement && target.body is js.Loop);
2264 }); 2269 });
2265 return false; 2270 return false;
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
2524 return condition || body; 2529 return condition || body;
2525 } 2530 }
2526 2531
2527 @override 2532 @override
2528 bool visitDartYield(js.DartYield node) { 2533 bool visitDartYield(js.DartYield node) {
2529 hasYield = true; 2534 hasYield = true;
2530 visit(node.expression); 2535 visit(node.expression);
2531 return true; 2536 return true;
2532 } 2537 }
2533 } 2538 }
OLDNEW
« no previous file with comments | « no previous file | tests/compiler/dart2js/async_await_js_transform_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698