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

Unified Diff: lib/transformations/async.dart

Issue 2480743002: Fix a bug in the async translation of let expressions. (Closed)
Patch Set: Delete an incorrect comment. Created 4 years, 1 month 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/transformations/async.dart
diff --git a/lib/transformations/async.dart b/lib/transformations/async.dart
index be32017fc88253f7454c7e73723bdd0453796c4b..d69179ccc01d9fb0d927b9094d81dbc8ec5ee9d7 100644
--- a/lib/transformations/async.dart
+++ b/lib/transformations/async.dart
@@ -437,12 +437,48 @@ class ExpressionLifter extends Transformer {
}
TreeNode visitLet(Let expr) {
- return transform(expr, () {
- expr.body = expr.body.accept(this)..parent = expr;
- VariableDeclaration variable = expr.variable;
+ var shouldName = seenAwait;
+
+ seenAwait = false;
+ var body = expr.body.accept(this);
+
+ VariableDeclaration variable = expr.variable;
+ if (seenAwait) {
+ // The body in `let var x = initializer in body` contained an await. We
+ // will produce the sequence of statements:
+ //
+ // <initializer's statements>
+ // var x = <initializer's value>
+ // <body's statements>
+ //
+ // and return the body's value.
+ //
+ // So x is in scope for all the body's statements and the body's value.
+ // This has the unpleasant consequence that all let-bound variables with
+ // await in the let's body will end up hoisted out the the expression and
+ // allocated to the context in the VM, even if they have no uses
+ // (`let _ = e0 in e1` can be used for sequencing of `e0` and `e1`).
+ statements.add(variable);
+ var index = nameIndex;
+ seenAwait = false;
variable.initializer =
variable.initializer.accept(this)..parent = variable;
- });
+ // Temporaries used in the initializer or the body are not live but the
+ // temporary used for the body is.
+ nameIndex = index + 1;
+ seenAwait = true;
+ return body;
+ } else {
+ // The body in `let x = initializer in body` did not contain an await. We
+ // can leave a let expression.
+ seenAwait = shouldName;
+ return transform(expr, () {
+ // The body has already been translated.
+ expr.body = body..parent = expr;
+ variable.initializer =
+ variable.initializer.accept(this)..parent = variable;
+ });
+ }
}
visitFunctionNode(FunctionNode node) {
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698