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

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: Add tests 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/language/async_continue_label_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 902 matching lines...) Expand 10 before | Expand all | Expand 10 after
913 913
914 @override 914 @override
915 void visitDefault(js.Default node) => unreachable(node); 915 void visitDefault(js.Default node) => unreachable(node);
916 916
917 @override 917 @override
918 void visitDo(js.Do node) { 918 void visitDo(js.Do node) {
919 if (!shouldTransform(node)) { 919 if (!shouldTransform(node)) {
920 bool oldInsideUntranslatedBreakable = insideUntranslatedBreakable; 920 bool oldInsideUntranslatedBreakable = insideUntranslatedBreakable;
921 insideUntranslatedBreakable = true; 921 insideUntranslatedBreakable = true;
922 withExpression(node.condition, (js.Expression condition) { 922 withExpression(node.condition, (js.Expression condition) {
923 addStatement(js.js.statement('do {#} while (#)', [node.body, condition]) ); 923 addStatement(js.js.statement('do {#} while (#)',
924 [node.body, condition]));
924 }, store: false); 925 }, store: false);
925 insideUntranslatedBreakable = oldInsideUntranslatedBreakable; 926 insideUntranslatedBreakable = oldInsideUntranslatedBreakable;
926 return; 927 return;
927 } 928 }
928 int startLabel = newLabel("do body"); 929 int startLabel = newLabel("do body");
929 930
930 int continueLabel = newLabel("do condition"); 931 int continueLabel = newLabel("do condition");
931 continueLabels[node] = continueLabel; 932 continueLabels[node] = continueLabel;
932 933
933 int afterLabel = newLabel("after do"); 934 int afterLabel = newLabel("after do");
(...skipping 11 matching lines...) Expand all
945 [condition, gotoAndBreak(startLabel)])); 946 [condition, gotoAndBreak(startLabel)]));
946 }, store: false); 947 }, store: false);
947 beginLabel(afterLabel); 948 beginLabel(afterLabel);
948 } 949 }
949 950
950 @override 951 @override
951 void visitEmptyStatement(js.EmptyStatement node) { 952 void visitEmptyStatement(js.EmptyStatement node) {
952 addStatement(node); 953 addStatement(node);
953 } 954 }
954 955
955 void visitExpressionInStatementContext(js.Expression node) { 956
956 if (node is js.VariableDeclarationList) { 957 @override
957 // Treat js.VariableDeclarationList as a statement. 958 void visitExpressionStatement(js.ExpressionStatement node) {
958 visitVariableDeclarationList(node); 959 visitExpressionIgnoreResult(node.expression);
959 } else {
960 visitExpressionIgnoreResult(node);
961 }
962 } 960 }
963 961
964 @override 962 @override
965 void visitExpressionStatement(js.ExpressionStatement node) {
966 visitExpressionInStatementContext(node.expression);
967 }
968
969 @override
970 void visitFor(js.For node) { 963 void visitFor(js.For node) {
971 if (!shouldTransform(node)) { 964 if (!shouldTransform(node)) {
972 bool oldInsideUntranslated = insideUntranslatedBreakable; 965 bool oldInsideUntranslated = insideUntranslatedBreakable;
973 insideUntranslatedBreakable = true; 966 insideUntranslatedBreakable = true;
974 // Note that node.init, node.condition, node.update all can be null, but 967 // Note that node.init, node.condition, node.update all can be null, but
975 // withExpressions handles that. 968 // withExpressions handles that.
976 withExpressions([ 969 withExpressions([
977 node.init, 970 node.init,
978 node.condition, 971 node.condition,
979 node.update 972 node.update
980 ], (List<js.Expression> transformed) { 973 ], (List<js.Expression> transformed) {
981 addStatement(new js.For(transformed[0], transformed[1], transformed[2], 974 addStatement(new js.For(transformed[0], transformed[1], transformed[2],
982 translateInBlock(node.body))); 975 translateInBlock(node.body)));
983 }); 976 });
984 insideUntranslatedBreakable = oldInsideUntranslated; 977 insideUntranslatedBreakable = oldInsideUntranslated;
985 return; 978 return;
986 } 979 }
987 980
988 if (node.init != null) { 981 if (node.init != null) {
989 visitExpressionInStatementContext(node.init); 982 addExpressionStatement(visitExpression(node.init));
990 } 983 }
991 int startLabel = newLabel("for condition"); 984 int startLabel = newLabel("for condition");
992 // If there is no update, continuing the loop is the same as going to the 985 // If there is no update, continuing the loop is the same as going to the
993 // start. 986 // start.
994 int continueLabel = 987 int continueLabel =
995 (node.update == null) ? startLabel : newLabel("for update"); 988 (node.update == null) ? startLabel : newLabel("for update");
996 continueLabels[node] = continueLabel; 989 continueLabels[node] = continueLabel;
997 int afterLabel = newLabel("after for"); 990 int afterLabel = newLabel("after for");
998 breakLabels[node] = afterLabel; 991 breakLabels[node] = afterLabel;
999 beginLabel(startLabel); 992 beginLabel(startLabel);
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1103 return unsupported(node); 1096 return unsupported(node);
1104 } 1097 }
1105 1098
1106 @override 1099 @override
1107 void visitLabeledStatement(js.LabeledStatement node) { 1100 void visitLabeledStatement(js.LabeledStatement node) {
1108 if (!shouldTransform(node)) { 1101 if (!shouldTransform(node)) {
1109 addStatement( 1102 addStatement(
1110 new js.LabeledStatement(node.label, translateInBlock(node.body))); 1103 new js.LabeledStatement(node.label, translateInBlock(node.body)));
1111 return; 1104 return;
1112 } 1105 }
1106 // `continue label` is really continuing the nested loop.
1107 // This is set up in [PreTranslationAnalysis.visitContinue].
1108 // Here we only need a breakLabel:
1113 int breakLabel = newLabel("break ${node.label}"); 1109 int breakLabel = newLabel("break ${node.label}");
1114 int continueLabel = newLabel("continue ${node.label}");
1115 breakLabels[node] = breakLabel; 1110 breakLabels[node] = breakLabel;
1116 continueLabels[node] = continueLabel;
1117 1111
1118 beginLabel(continueLabel);
1119 jumpTargets.add(node); 1112 jumpTargets.add(node);
1120 visitStatement(node.body); 1113 visitStatement(node.body);
1121 jumpTargets.removeLast(); 1114 jumpTargets.removeLast();
1122 beginLabel(breakLabel); 1115 beginLabel(breakLabel);
1123 } 1116 }
1124 1117
1125 @override 1118 @override
1126 js.Expression visitLiteralBool(js.LiteralBool node) => node; 1119 js.Expression visitLiteralBool(js.LiteralBool node) => node;
1127 1120
1128 @override 1121 @override
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
1484 } 1477 }
1485 beginLabel(afterFinallyLabel); 1478 beginLabel(afterFinallyLabel);
1486 } 1479 }
1487 1480
1488 @override 1481 @override
1489 visitVariableDeclaration(js.VariableDeclaration node) { 1482 visitVariableDeclaration(js.VariableDeclaration node) {
1490 unreachable(node); 1483 unreachable(node);
1491 } 1484 }
1492 1485
1493 @override 1486 @override
1494 void visitVariableDeclarationList(js.VariableDeclarationList node) { 1487 js.Expression visitVariableDeclarationList(js.VariableDeclarationList node) {
1488 List<js.Assignment> initializations = new List<js.Assignment>();
1489
1495 // Declaration of local variables is hoisted outside the helper but the 1490 // Declaration of local variables is hoisted outside the helper but the
1496 // initialization is done here. 1491 // initialization is done here.
1497 for (js.VariableInitialization initialization in node.declarations) { 1492 for (js.VariableInitialization initialization in node.declarations) {
1498 js.VariableDeclaration declaration = initialization.declaration; 1493 js.VariableDeclaration declaration = initialization.declaration;
1499 localVariables.add(declaration); 1494 localVariables.add(declaration);
1500 if (initialization.value != null) { 1495 if (initialization.value != null) {
1501 withExpression(initialization.value, (js.Expression value) { 1496 withExpression(initialization.value, (js.Expression value) {
1502 addStatement(new js.ExpressionStatement( 1497 initializations.add(
1503 new js.Assignment(new js.VariableUse(declaration.name), value))); 1498 new js.Assignment(new js.VariableUse(declaration.name), value));
1504 }, store: false); 1499 }, store: false);
1505 } 1500 }
1506 } 1501 }
1502 return initializations.isEmpty ? js.number(0)
floitsch 2015/03/13 14:20:22 Make this an if. Explain why "0".
sigurdm 2015/03/16 08:43:51 Done.
1503 : initializations.reduce((js.Expression first, js.Expression second) {
1504 return new js.Binary(",", first, second);
1505 });
1507 } 1506 }
1508 1507
1509 @override 1508 @override
1510 void visitVariableInitialization(js.VariableInitialization node) { 1509 void visitVariableInitialization(js.VariableInitialization node) {
1511 unreachable(node); 1510 unreachable(node);
1512 } 1511 }
1513 1512
1514 @override 1513 @override
1515 js.Expression visitVariableUse(js.VariableUse node) { 1514 js.Expression visitVariableUse(js.VariableUse node) {
1516 Pair<String, String> renaming = variableRenamings.lastWhere( 1515 Pair<String, String> renaming = variableRenamings.lastWhere(
(...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after
2199 bool visitConditional(js.Conditional node) { 2198 bool visitConditional(js.Conditional node) {
2200 bool condition = visit(node.condition); 2199 bool condition = visit(node.condition);
2201 bool then = visit(node.then); 2200 bool then = visit(node.then);
2202 bool otherwise = visit(node.otherwise); 2201 bool otherwise = visit(node.otherwise);
2203 return condition || then || otherwise; 2202 return condition || then || otherwise;
2204 } 2203 }
2205 2204
2206 @override 2205 @override
2207 bool visitContinue(js.Continue node) { 2206 bool visitContinue(js.Continue node) {
2208 if (node.targetLabel != null) { 2207 if (node.targetLabel != null) {
2209 targets[node] = labelledStatements.lastWhere( 2208 js.LabeledStatement targetLabel = labelledStatements.lastWhere(
2210 (js.LabeledStatement stm) => stm.label == node.targetLabel); 2209 (js.LabeledStatement stm) => stm.label == node.targetLabel);
2210 js.Loop targetStatement = targetLabel.body;
2211 targets[node] = targetStatement;
2211 } else { 2212 } else {
2212 targets[node] = 2213 targets[node] =
2213 loopsAndSwitches.lastWhere((js.Node node) => node is! js.Switch); 2214 loopsAndSwitches.lastWhere((js.Node node) => node is! js.Switch);
2214 } 2215 }
2215 assert(() { 2216 assert(() {
2216 js.Node target = targets[node]; 2217 js.Node target = targets[node];
2217 return target is js.Loop || 2218 return target is js.Loop ||
2218 (target is js.LabeledStatement && target.body is js.Loop); 2219 (target is js.LabeledStatement && target.body is js.Loop);
2219 }); 2220 });
2220 return false; 2221 return false;
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
2479 return condition || body; 2480 return condition || body;
2480 } 2481 }
2481 2482
2482 @override 2483 @override
2483 bool visitDartYield(js.DartYield node) { 2484 bool visitDartYield(js.DartYield node) {
2484 hasYield = true; 2485 hasYield = true;
2485 visit(node.expression); 2486 visit(node.expression);
2486 return true; 2487 return true;
2487 } 2488 }
2488 } 2489 }
OLDNEW
« no previous file with comments | « no previous file | tests/language/async_continue_label_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698