Skip to content

Commit cf01e07

Browse files
rakudramaCommit Queue
authored andcommitted
[dart2js] Choose between while- and for- loops
Change-Id: I6b564775e42649a974b72331528e02803a41616e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/447880 Reviewed-by: Mayank Patke <[email protected]> Commit-Queue: Stephen Adams <[email protected]>
1 parent 5e7cebe commit cf01e07

File tree

5 files changed

+70
-33
lines changed

5 files changed

+70
-33
lines changed

pkg/compiler/lib/src/js/rewrite_async.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -776,7 +776,7 @@ abstract class AsyncRewriterBase extends js.NodeVisitor<Object?> {
776776
rewrittenBody = js.LabeledStatement(outerLabelName, rewrittenBody);
777777
}
778778
rewrittenBody = js.js
779-
.statement('while (true) #', rewrittenBody)
779+
.statement('for (;;) #', rewrittenBody)
780780
.withSourceInformation(bodySourceInformation);
781781
List<js.VariableInitialization> variables = [];
782782

pkg/compiler/lib/src/ssa/codegen.dart

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,11 +1109,11 @@ class SsaCodeGenerator implements HVisitor<void>, HBlockInformationVisitor {
11091109
currentContainer = body;
11101110
visitBodyIgnoreLabels(info);
11111111
currentContainer = oldContainer;
1112-
loop = js.For(
1113-
jsInitialization,
1114-
jsCondition,
1115-
jsUpdates,
1116-
unwrapStatement(body),
1112+
loop = newLoop(
1113+
init: jsInitialization,
1114+
condition: jsCondition,
1115+
update: jsUpdates,
1116+
body: unwrapStatement(body),
11171117
sourceInformation: info.sourceInformation,
11181118
);
11191119
} else {
@@ -1129,7 +1129,6 @@ class SsaCodeGenerator implements HVisitor<void>, HBlockInformationVisitor {
11291129
jsCondition = generateExpression(condition);
11301130
currentContainer = body;
11311131
} else {
1132-
jsCondition = newLiteralBool(true, info.sourceInformation);
11331132
currentContainer = body;
11341133
generateStatements(condition);
11351134
use(condition.conditionExpression!);
@@ -1151,9 +1150,9 @@ class SsaCodeGenerator implements HVisitor<void>, HBlockInformationVisitor {
11511150
visitBodyIgnoreLabels(info);
11521151
}
11531152
currentContainer = oldContainer;
1154-
loop = js.While(
1155-
jsCondition!,
1156-
unwrapStatement(body),
1153+
loop = newLoop(
1154+
condition: jsCondition,
1155+
body: unwrapStatement(body),
11571156
sourceInformation: info.sourceInformation,
11581157
);
11591158
}
@@ -1206,9 +1205,8 @@ class SsaCodeGenerator implements HVisitor<void>, HBlockInformationVisitor {
12061205
// If the condition is dead code, we turn the do-while into
12071206
// a simpler while because we will never reach the condition
12081207
// at the end of the loop anyway.
1209-
loop = js.While(
1210-
newLiteralBool(true, info.sourceInformation),
1211-
unwrapStatement(body),
1208+
loop = newLoop(
1209+
body: unwrapStatement(body),
12121210
sourceInformation: info.sourceInformation,
12131211
);
12141212
} else {
@@ -2836,6 +2834,45 @@ class SsaCodeGenerator implements HVisitor<void>, HBlockInformationVisitor {
28362834
}
28372835
}
28382836

2837+
/// Returns a 'for' loop or 'while' loop depending on which parts of a 'for'
2838+
/// loop are present. In effect, choose the loop kind by applying these
2839+
/// reductions:
2840+
///
2841+
/// for(init;true;update) --> for(init;;update)
2842+
/// for(;cond;) --> while(cond)
2843+
/// while(true) --> for(;;)
2844+
js.Loop newLoop({
2845+
js.Expression? init,
2846+
js.Expression? condition, // `null` means indefinite, i.e. `true`.
2847+
js.Expression? update,
2848+
required js.Statement body,
2849+
SourceInformation? sourceInformation,
2850+
}) {
2851+
// `condition` with `true` replaced with `null`:
2852+
final conditionOrNull = switch (condition) {
2853+
js.LiteralBool(value: true) => null,
2854+
js.LiteralNumber(value: '1') => null,
2855+
// Minified `true` is `!0`:
2856+
js.Prefix(op: '!', argument: js.LiteralNumber(value: '0')) => null,
2857+
_ => condition,
2858+
};
2859+
2860+
if (init == null && update == null && conditionOrNull != null) {
2861+
return js.While(
2862+
conditionOrNull,
2863+
body,
2864+
sourceInformation: sourceInformation,
2865+
);
2866+
}
2867+
return js.For(
2868+
init,
2869+
conditionOrNull,
2870+
update,
2871+
body,
2872+
sourceInformation: sourceInformation,
2873+
);
2874+
}
2875+
28392876
void generateConstant(
28402877
ConstantValue constant,
28412878
SourceInformation? sourceInformation,

pkg/compiler/test/async_await/async_await_js_transform_test.dart

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ main() {
7878
var body = _wrapJsFunctionForAsync(function(__errorCode, __result) {
7979
if (__errorCode === 1)
8080
return rethrowHelper(__result, __completer);
81-
while (true)
81+
for (;;)
8282
switch (__goto) {
8383
case 0:
8484
// Function start
@@ -116,7 +116,7 @@ function(a) {
116116
var body = _wrapJsFunctionForAsync(function(__errorCode, __result) {
117117
if (__errorCode === 1)
118118
return rethrowHelper(__result, __completer);
119-
while (true)
119+
for (;;)
120120
switch (__goto) {
121121
case 0:
122122
// Function start
@@ -168,7 +168,7 @@ function(b) {
168168
__errorStack.push(__result);
169169
__goto = __handler;
170170
}
171-
while (true)
171+
for (;;)
172172
__outer1:
173173
switch (__goto) {
174174
case 0:
@@ -281,7 +281,7 @@ function(c) {
281281
var body = _wrapJsFunctionForAsync(function(__errorCode, __result) {
282282
if (__errorCode === 1)
283283
return rethrowHelper(__result, __completer);
284-
while (true)
284+
for (;;)
285285
switch (__goto) {
286286
case 0:
287287
// Function start
@@ -338,7 +338,7 @@ function(d2) {
338338
var body = _wrapJsFunctionForAsync(function(__errorCode, __result) {
339339
if (__errorCode === 1)
340340
return rethrowHelper(__result, __completer);
341-
while (true)
341+
for (;;)
342342
switch (__goto) {
343343
case 0:
344344
// Function start
@@ -474,7 +474,7 @@ function(x, y) {
474474
var body = _wrapJsFunctionForAsync(function(__errorCode, __result) {
475475
if (__errorCode === 1)
476476
return rethrowHelper(__result, __completer);
477-
while (true)
477+
for (;;)
478478
switch (__goto) {
479479
case 0:
480480
// Function start
@@ -563,7 +563,7 @@ function(f) {
563563
var body = _wrapJsFunctionForAsync(function(__errorCode, __result) {
564564
if (__errorCode === 1)
565565
return rethrowHelper(__result, __completer);
566-
while (true)
566+
for (;;)
567567
switch (__goto) {
568568
case 0:
569569
// Function start
@@ -628,7 +628,7 @@ function(g) {
628628
var body = _wrapJsFunctionForAsync(function(__errorCode, __result) {
629629
if (__errorCode === 1)
630630
return rethrowHelper(__result, __completer);
631-
while (true)
631+
for (;;)
632632
switch (__goto) {
633633
case 0:
634634
// Function start
@@ -713,7 +713,7 @@ function(a, h) {
713713
var body = _wrapJsFunctionForAsync(function(__errorCode, __result) {
714714
if (__errorCode === 1)
715715
return rethrowHelper(__result, __completer);
716-
while (true)
716+
for (;;)
717717
switch (__goto) {
718718
case 0:
719719
// Function start
@@ -799,7 +799,7 @@ function(c, i) {
799799
__errorStack.push(__result);
800800
__goto = __handler;
801801
}
802-
while (true)
802+
for (;;)
803803
switch (__goto) {
804804
case 0:
805805
// Function start
@@ -912,7 +912,7 @@ function(x, y, j) {
912912
var body = _wrapJsFunctionForAsync(function(__errorCode, __result) {
913913
if (__errorCode === 1)
914914
return rethrowHelper(__result, __completer);
915-
while (true)
915+
for (;;)
916916
switch (__goto) {
917917
case 0:
918918
// Function start
@@ -995,7 +995,7 @@ function(x, y, k) {
995995
var body = _wrapJsFunctionForAsync(function(__errorCode, __result) {
996996
if (__errorCode === 1)
997997
return rethrowHelper(__result, __completer);
998-
while (true)
998+
for (;;)
999999
switch (__goto) {
10001000
case 0:
10011001
// Function start
@@ -1122,7 +1122,7 @@ function(l) {
11221122
var body = _wrapJsFunctionForAsync(function(__errorCode, __result) {
11231123
if (__errorCode === 1)
11241124
return rethrowHelper(__result, __completer);
1125-
while (true)
1125+
for (;;)
11261126
switch (__goto) {
11271127
case 0:
11281128
// Function start
@@ -1196,7 +1196,7 @@ function(b, l) {
11961196
var body = _wrapJsFunctionForAsync(function(__errorCode, __result) {
11971197
if (__errorCode === 1)
11981198
return rethrowHelper(__result, __completer);
1199-
while (true)
1199+
for (;;)
12001200
switch (__goto) {
12011201
case 0:
12021202
// Function start
@@ -1275,7 +1275,7 @@ function(m) {
12751275
__errorStack.push(__result);
12761276
__goto = __handler;
12771277
}
1278-
while (true)
1278+
for (;;)
12791279
switch (__goto) {
12801280
case 0:
12811281
// Function start
@@ -1348,7 +1348,7 @@ function(__a) {
13481348
__errorStack.push(__result);
13491349
__goto = __handler;
13501350
}
1351-
while (true)
1351+
for (;;)
13521352
switch (__goto) {
13531353
case 0:
13541354
// Function start

pkg/compiler/test/codegen/licm_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ main() {
2828
await compileAndMatch(
2929
TEST,
3030
'main',
31-
RegExp('if \\(typeof count !== "number"\\)(.|\\n)*while'),
31+
RegExp('if \\(typeof count !== "number"\\)(.|\\n)*(while|for)'),
3232
);
3333
}
3434

pkg/compiler/test/dump_info/data/deferred_future/main.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@
102102
"id": "library/memory:sdk/tests/web/native/main.dart::",
103103
"kind": "library",
104104
"name": "<unnamed>",
105-
"size": 861,
105+
"size": 857,
106106
"children": [
107107
"function/memory:sdk/tests/web/native/main.dart::main"
108108
],
@@ -137,7 +137,7 @@ import 'lib2.dart' as lib2;
137137
"id": "function/memory:sdk/tests/web/native/main.dart::main",
138138
"kind": "function",
139139
"name": "main",
140-
"size": 861,
140+
"size": 857,
141141
"outputUnit": "outputUnit/main",
142142
"parent": "library/memory:sdk/tests/web/native/main.dart::",
143143
"children": [],
@@ -152,7 +152,7 @@ import 'lib2.dart' as lib2;
152152
"parameters": [],
153153
"sideEffects": "SideEffects(reads nothing; writes nothing)",
154154
"inlinedCount": 0,
155-
"code": "main() {\n var $async$goto = 0,\n $async$completer = A._makeAsyncAwaitCompleter(type$.dynamic);\n var $async$main = A._wrapJsFunctionForAsync(function($async$errorCode, $async$result) {\n if ($async$errorCode === 1)\n return A._asyncRethrow($async$result, $async$completer);\n while (true)\n switch ($async$goto) {\n case 0:\n // Function start\n $async$goto = 2;\n return A._asyncAwait(A.loadDeferredLibrary(\"lib1\", \"\"), $async$main);\n case 2:\n // returning from await.\n A.checkDeferredIsLoaded(\"lib1\");\n A.checkDeferredIsLoaded(\"lib1\");\n // implicit return\n return A._asyncReturn(null, $async$completer);\n }\n });\n return A._asyncStartSync($async$main, $async$completer);\n }",
155+
"code": "main() {\n var $async$goto = 0,\n $async$completer = A._makeAsyncAwaitCompleter(type$.dynamic);\n var $async$main = A._wrapJsFunctionForAsync(function($async$errorCode, $async$result) {\n if ($async$errorCode === 1)\n return A._asyncRethrow($async$result, $async$completer);\n for (;;)\n switch ($async$goto) {\n case 0:\n // Function start\n $async$goto = 2;\n return A._asyncAwait(A.loadDeferredLibrary(\"lib1\", \"\"), $async$main);\n case 2:\n // returning from await.\n A.checkDeferredIsLoaded(\"lib1\");\n A.checkDeferredIsLoaded(\"lib1\");\n // implicit return\n return A._asyncReturn(null, $async$completer);\n }\n });\n return A._asyncStartSync($async$main, $async$completer);\n }",
156156
"type": "dynamic Function()",
157157
"functionKind": 0
158158
}],

0 commit comments

Comments
 (0)