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

Side by Side Diff: lib/transformations/async.dart

Issue 2460373002: Remove BlockExpression from the Kernel language. (Closed)
Patch Set: Incorporate review comments, format continuation.dart. 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 unified diff | Download patch
« no previous file with comments | « lib/text/ast_to_text.dart ('k') | lib/transformations/continuation.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) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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 kernel.transformations.async; 5 library kernel.transformations.async;
6 6
7 import '../kernel.dart'; 7 import '../kernel.dart';
8 import 'continuation.dart'; 8 import 'continuation.dart';
9 9
10 /// A transformer that introduces temporary variables for all subexpressions 10 /// A transformer that introduces temporary variables for all subexpressions
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 /// of statements by emitting statements into this list. This list is built 46 /// of statements by emitting statements into this list. This list is built
47 /// in reverse because children are visited right-to-left. 47 /// in reverse because children are visited right-to-left.
48 /// 48 ///
49 /// If an expression should be named it is named before visiting its children 49 /// If an expression should be named it is named before visiting its children
50 /// so the naming assignment appears in the list before all statements 50 /// so the naming assignment appears in the list before all statements
51 /// implementating the translation of the children. 51 /// implementating the translation of the children.
52 /// 52 ///
53 /// Children that are conditionally evaluated, such as some parts of logical 53 /// Children that are conditionally evaluated, such as some parts of logical
54 /// and conditional expressions, must be delimited so that they do not emit 54 /// and conditional expressions, must be delimited so that they do not emit
55 /// unguarded statements into [statements]. This is implemented by setting 55 /// unguarded statements into [statements]. This is implemented by setting
56 /// [statements] to a fresh empty list before transforming those children and 56 /// [statements] to a fresh empty list before transforming those children.
57 /// wrapping any emitted statements in a [BlockExpression].
58 List<Statement> statements = <Statement>[]; 57 List<Statement> statements = <Statement>[];
59 58
60 59
61 /// The number of currently live named intermediate values. 60 /// The number of currently live named intermediate values.
62 /// 61 ///
63 /// This index is used to allocate names to temporary values. Because 62 /// This index is used to allocate names to temporary values. Because
64 /// children are visited right-to-left, names are assigned in reverse order of 63 /// children are visited right-to-left, names are assigned in reverse order of
65 /// index. 64 /// index.
66 /// 65 ///
67 /// When an assignment is emitted into [statements] to name an expression 66 /// When an assignment is emitted into [statements] to name an expression
(...skipping 11 matching lines...) Expand all
79 78
80 final VariableDeclaration asyncResult = 79 final VariableDeclaration asyncResult =
81 new VariableDeclaration(':result'); 80 new VariableDeclaration(':result');
82 final List<VariableDeclaration> variables = <VariableDeclaration>[]; 81 final List<VariableDeclaration> variables = <VariableDeclaration>[];
83 82
84 ExpressionLifter(this.continuationRewriter); 83 ExpressionLifter(this.continuationRewriter);
85 84
86 Block blockOf(List<Statement> stmts) => new Block(stmts.reversed.toList()); 85 Block blockOf(List<Statement> stmts) => new Block(stmts.reversed.toList());
87 86
88 /// Rewrite a toplevel expression (toplevel wrt. a statement). 87 /// Rewrite a toplevel expression (toplevel wrt. a statement).
89 Expression rewrite(Expression expression) { 88 ///
89 /// Rewriting an expression produces a sequence of statements and an
90 /// expression. The sequence of statements are added to the given list. Pass
91 /// an empty list if the rewritten expression should be delimited from the
92 /// surrounding context.
93 Expression rewrite(Expression expression, List<Statement> outer) {
90 assert(statements.isEmpty); 94 assert(statements.isEmpty);
91 assert(nameIndex == 0); 95 assert(nameIndex == 0);
92 seenAwait = false; 96 seenAwait = false;
93 var result = expression.accept(this); 97 Expression result = expression.accept(this);
98 outer.addAll(statements.reversed);
99 statements.clear();
94 nameIndex = 0; 100 nameIndex = 0;
95 if (statements.isNotEmpty) {
96 result = new BlockExpression(blockOf(statements), result);
97 statements = <Statement>[];
98 }
99 return result; 101 return result;
100 } 102 }
101 103
102 // Perform an action with a given list of statements so that it cannot emit 104 // Perform an action with a given list of statements so that it cannot emit
103 // statements into the 'outer' list. 105 // statements into the 'outer' list.
104 Expression delimit(Expression action(), List<Statement> inner) { 106 Expression delimit(Expression action(), List<Statement> inner) {
105 var index = nameIndex; 107 var index = nameIndex;
106 var outer = statements; 108 var outer = statements;
107 statements = inner; 109 statements = inner;
108 Expression result = action(); 110 Expression result = action();
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 ++nameIndex; 404 ++nameIndex;
403 seenAwait = seenAwait || thenAwait || otherwiseAwait; 405 seenAwait = seenAwait || thenAwait || otherwiseAwait;
404 return new VariableGet(result); 406 return new VariableGet(result);
405 } 407 }
406 408
407 // Others. 409 // Others.
408 TreeNode visitAwaitExpression(AwaitExpression expr) { 410 TreeNode visitAwaitExpression(AwaitExpression expr) {
409 final R = continuationRewriter; 411 final R = continuationRewriter;
410 var shouldName = seenAwait; 412 var shouldName = seenAwait;
411 var result = new VariableGet(asyncResult); 413 var result = new VariableGet(asyncResult);
414 // The statements are in reverse order, so name the result first if
415 // necessary and then add the two other statements in reverse.
412 if (shouldName) result = name(result); 416 if (shouldName) result = name(result);
417 statements.add(R.createContinuationPoint());
418 Arguments arguments = new Arguments(<Expression>[
419 expr.operand,
420 new VariableGet(R.thenContinuationVariable),
421 new VariableGet(R.catchErrorContinuationVariable)]);
422 statements.add(new ExpressionStatement(
423 new StaticInvocation(R.helper.awaitHelper, arguments)));
424
413 seenAwait = false; 425 seenAwait = false;
414 var index = nameIndex; 426 var index = nameIndex;
415 var operand = expr.operand.accept(this); 427 arguments.positional[0] = expr.operand.accept(this)..parent = arguments;
416
417 // The statements are in reverse order, so name the result first if
418 // necessary and then add these two in reverse.
419 statements.add(R.createContinuationPoint());
420 statements.add(new ExpressionStatement(
421 new StaticInvocation(R.helper.awaitHelper,
422 new Arguments(<Expression>[
423 operand,
424 new VariableGet(R.thenContinuationVariable),
425 new VariableGet(R.catchErrorContinuationVariable)]))));
426 428
427 if (shouldName) nameIndex = index + 1; 429 if (shouldName) nameIndex = index + 1;
428 seenAwait = true; 430 seenAwait = true;
429 return result; 431 return result;
430 } 432 }
431 433
432 TreeNode visitFunctionExpression(FunctionExpression expr) { 434 TreeNode visitFunctionExpression(FunctionExpression expr) {
433 expr.transformChildren(this); 435 expr.transformChildren(this);
434 return expr; 436 return expr;
435 } 437 }
436 438
437 TreeNode visitLet(Let expr) { 439 TreeNode visitLet(Let expr) {
438 expr.body = expr.body.accept(this)..parent = expr; 440 return transform(expr, () {
439 VariableDeclaration variable = expr.variable; 441 expr.body = expr.body.accept(this)..parent = expr;
440 variable.initializer = 442 VariableDeclaration variable = expr.variable;
441 variable.initializer.accept(this)..parent = variable; 443 variable.initializer =
442 return expr; 444 variable.initializer.accept(this)..parent = variable;
443 } 445 });
444
445 TreeNode visitBlockExpression(BlockExpression expr) {
446 var length = statements.length;
447 expr.value.accept(this)..parent = expr;
448 if (statements.length == length) {
449 // The statements in the body do not need be translated right-to-left
450 // because all subexpressions will be treated as delimited and so
451 // prevented from emitting statements into the list of statements.
452 expr.body = expr.body.accept(continuationRewriter)..parent = expr;
453 return expr;
454 } else {
455 // Statements were emitted from the translation of the value. The
456 // statements in the body must be executed before them. Copy the body's
457 // statements to the accumulated statement list in reverse order.
458 for (var statement in expr.body.statements.reversed) {
459 statements.add(statement.accept(continuationRewriter));
460 }
461 return expr.value;
462 }
463 } 446 }
464 447
465 visitFunctionNode(FunctionNode node) { 448 visitFunctionNode(FunctionNode node) {
466 var nestedRewriter = new RecursiveContinuationRewriter( 449 var nestedRewriter = new RecursiveContinuationRewriter(
467 continuationRewriter.helper); 450 continuationRewriter.helper);
468 return node.accept(nestedRewriter); 451 return node.accept(nestedRewriter);
469 } 452 }
470 } 453 }
OLDNEW
« no previous file with comments | « lib/text/ast_to_text.dart ('k') | lib/transformations/continuation.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698