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

Side by Side Diff: pkg/kernel/lib/transformations/continuation.dart

Issue 2627873002: VM: [Kernel] Fix remaining issues with kernel-based async/await implementation (Closed)
Patch Set: Fix Created 3 years, 11 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
« no previous file with comments | « no previous file | tests/co19/co19-kernel.status » ('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.continuation; 5 library kernel.transformations.continuation;
6 6
7 import 'dart:math' as math; 7 import 'dart:math' as math;
8 8
9 import '../ast.dart'; 9 import '../ast.dart';
10 import '../visitor.dart'; 10 import '../visitor.dart';
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 return new AsyncFunctionRewriter(helper, node).rewrite(); 43 return new AsyncFunctionRewriter(helper, node).rewrite();
44 case AsyncMarker.AsyncStar: 44 case AsyncMarker.AsyncStar:
45 return new AsyncStarFunctionRewriter(helper, node).rewrite(); 45 return new AsyncStarFunctionRewriter(helper, node).rewrite();
46 } 46 }
47 } 47 }
48 } 48 }
49 49
50 abstract class ContinuationRewriterBase extends RecursiveContinuationRewriter { 50 abstract class ContinuationRewriterBase extends RecursiveContinuationRewriter {
51 final FunctionNode enclosingFunction; 51 final FunctionNode enclosingFunction;
52 52
53 int currentTryDepth; // Nesting depth for try-blocks. 53 int currentTryDepth = 0; // Nesting depth for try-blocks.
54 int currentCatchDepth = 0; // Nesting depth for catch-blocks. 54 int currentCatchDepth = 0; // Nesting depth for catch-blocks.
55 int capturedTryDepth = 0; // Deepest yield point within a try-block. 55 int capturedTryDepth = 0; // Deepest yield point within a try-block.
56 int capturedCatchDepth = 0; // Deepest yield point within a catch-block. 56 int capturedCatchDepth = 0; // Deepest yield point within a catch-block.
57 57
58 ContinuationRewriterBase(HelperNodes helper, this.enclosingFunction, 58 ContinuationRewriterBase(HelperNodes helper, this.enclosingFunction)
59 {this.currentTryDepth: 0})
60 : super(helper); 59 : super(helper);
61 60
62 Statement createContinuationPoint([Expression value]) { 61 Statement createContinuationPoint([Expression value]) {
63 if (value == null) value = new NullLiteral(); 62 if (value == null) value = new NullLiteral();
64 capturedTryDepth = math.max(capturedTryDepth, currentTryDepth); 63 capturedTryDepth = math.max(capturedTryDepth, currentTryDepth);
65 capturedCatchDepth = math.max(capturedCatchDepth, currentCatchDepth); 64 capturedCatchDepth = math.max(capturedCatchDepth, currentCatchDepth);
66 return new YieldStatement(value, isNative: true); 65 return new YieldStatement(value, isNative: true);
67 } 66 }
68 67
69 TreeNode visitTryCatch(TryCatch node) { 68 TreeNode visitTryCatch(TryCatch node) {
70 if (node.body != null) { 69 if (node.body != null) {
71 currentTryDepth++; 70 currentTryDepth++;
Vyacheslav Egorov (Google) 2017/01/11 17:54:05 Please use prefix and postfix increment consistent
kustermann 2017/01/11 18:34:54 Done.
72 node.body = node.body.accept(this); 71 node.body = node.body.accept(this);
73 node.body?.parent = node; 72 node.body?.parent = node;
74 currentTryDepth--; 73 currentTryDepth--;
75 } 74 }
76 75
77 currentCatchDepth++; 76 ++currentCatchDepth;
78 transformList(node.catches, this, node); 77 transformList(node.catches, this, node);
79 currentCatchDepth--; 78 --currentCatchDepth;
80 return node; 79 return node;
81 } 80 }
82 81
83 TreeNode visitTryFinally(TryFinally node) { 82 TreeNode visitTryFinally(TryFinally node) {
84 if (node.body != null) { 83 if (node.body != null) {
85 currentTryDepth++; 84 currentTryDepth++;
Vyacheslav Egorov (Google) 2017/01/11 17:54:05 ditto
kustermann 2017/01/11 18:34:54 Done.
86 node.body = node.body.accept(this); 85 node.body = node.body.accept(this);
87 node.body?.parent = node; 86 node.body?.parent = node;
88 currentTryDepth--; 87 currentTryDepth--;
89 } 88 }
90 if (node.finalizer != null) { 89 if (node.finalizer != null) {
90 ++currentCatchDepth;
91 node.finalizer = node.finalizer.accept(this); 91 node.finalizer = node.finalizer.accept(this);
92 node.finalizer?.parent = node; 92 node.finalizer?.parent = node;
93 --currentCatchDepth;
93 } 94 }
94 return node; 95 return node;
95 } 96 }
96 97
97 Iterable<VariableDeclaration> createCapturedTryVariables() => 98 Iterable<VariableDeclaration> createCapturedTryVariables() =>
98 new Iterable.generate(capturedTryDepth, 99 new Iterable.generate(capturedTryDepth,
99 (depth) => new VariableDeclaration(":saved_try_context_var${depth}")); 100 (depth) => new VariableDeclaration(":saved_try_context_var${depth}"));
100 101
101 Iterable<VariableDeclaration> createCapturedCatchVariables() => 102 Iterable<VariableDeclaration> createCapturedCatchVariables() =>
102 new Iterable.generate(capturedCatchDepth).expand((depth) => [ 103 new Iterable.generate(capturedCatchDepth).expand((depth) => [
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 final VariableDeclaration thenContinuationVariable = 183 final VariableDeclaration thenContinuationVariable =
183 new VariableDeclaration(":async_op_then"); 184 new VariableDeclaration(":async_op_then");
184 final VariableDeclaration catchErrorContinuationVariable = 185 final VariableDeclaration catchErrorContinuationVariable =
185 new VariableDeclaration(":async_op_error"); 186 new VariableDeclaration(":async_op_error");
186 187
187 LabeledStatement labeledBody; 188 LabeledStatement labeledBody;
188 189
189 ExpressionLifter expressionRewriter; 190 ExpressionLifter expressionRewriter;
190 191
191 AsyncRewriterBase(helper, enclosingFunction) 192 AsyncRewriterBase(helper, enclosingFunction)
192 // Body is wrapped in the try-catch so initial currentTryDepth is 1. 193 : super(helper, enclosingFunction) {}
193 : super(helper, enclosingFunction, currentTryDepth: 1) {}
194 194
195 void setupAsyncContinuations(List<Statement> statements) { 195 void setupAsyncContinuations(List<Statement> statements) {
196 expressionRewriter = new ExpressionLifter(this); 196 expressionRewriter = new ExpressionLifter(this);
197 197
198 // var :async_op_then; 198 // var :async_op_then;
199 statements.add(thenContinuationVariable); 199 statements.add(thenContinuationVariable);
200 200
201 // var :async_op_error; 201 // var :async_op_error;
202 statements.add(catchErrorContinuationVariable); 202 statements.add(catchErrorContinuationVariable);
203 203
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 final boundCatchErrorClosure = new StaticInvocation( 240 final boundCatchErrorClosure = new StaticInvocation(
241 helper.asyncErrorWrapper, 241 helper.asyncErrorWrapper,
242 new Arguments(<Expression>[new VariableGet(nestedClosureVariable)])); 242 new Arguments(<Expression>[new VariableGet(nestedClosureVariable)]));
243 final catchErrorClosureVariableAssign = new ExpressionStatement( 243 final catchErrorClosureVariableAssign = new ExpressionStatement(
244 new VariableSet( 244 new VariableSet(
245 catchErrorContinuationVariable, boundCatchErrorClosure)); 245 catchErrorContinuationVariable, boundCatchErrorClosure));
246 statements.add(catchErrorClosureVariableAssign); 246 statements.add(catchErrorClosureVariableAssign);
247 } 247 }
248 248
249 Statement buildWrappedBody() { 249 Statement buildWrappedBody() {
250 ++currentTryDepth;
250 labeledBody = new LabeledStatement(null); 251 labeledBody = new LabeledStatement(null);
251 labeledBody.body = visitDelimited(enclosingFunction.body) 252 labeledBody.body = visitDelimited(enclosingFunction.body)
252 ..parent = labeledBody; 253 ..parent = labeledBody;
254 --currentTryDepth;
253 255
254 var exceptionVariable = new VariableDeclaration(":exception"); 256 var exceptionVariable = new VariableDeclaration(":exception");
255 var stackTraceVariable = new VariableDeclaration(":stack_trace"); 257 var stackTraceVariable = new VariableDeclaration(":stack_trace");
256 258
257 return new TryCatch(buildReturn(labeledBody), <Catch>[ 259 return new TryCatch(buildReturn(labeledBody), <Catch>[
258 new Catch( 260 new Catch(
259 exceptionVariable, 261 exceptionVariable,
260 new Block(<Statement>[ 262 new Block(<Statement>[
261 buildCatchBody(exceptionVariable, stackTraceVariable) 263 buildCatchBody(exceptionVariable, stackTraceVariable)
262 ]), 264 ]),
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
610 } 612 }
611 --currentCatchDepth; 613 --currentCatchDepth;
612 statements.add(stmt); 614 statements.add(stmt);
613 return null; 615 return null;
614 } 616 }
615 617
616 TreeNode visitTryFinally(TryFinally stmt) { 618 TreeNode visitTryFinally(TryFinally stmt) {
617 ++currentTryDepth; 619 ++currentTryDepth;
618 stmt.body = visitDelimited(stmt.body)..parent = stmt; 620 stmt.body = visitDelimited(stmt.body)..parent = stmt;
619 --currentTryDepth; 621 --currentTryDepth;
622 ++currentCatchDepth;
620 stmt.finalizer = visitDelimited(stmt.finalizer)..parent = stmt; 623 stmt.finalizer = visitDelimited(stmt.finalizer)..parent = stmt;
624 --currentCatchDepth;
621 statements.add(stmt); 625 statements.add(stmt);
622 return null; 626 return null;
623 } 627 }
624 628
625 TreeNode visitYieldStatement(YieldStatement stmt) { 629 TreeNode visitYieldStatement(YieldStatement stmt) {
626 stmt.expression = expressionRewriter.rewrite(stmt.expression, statements) 630 stmt.expression = expressionRewriter.rewrite(stmt.expression, statements)
627 ..parent = stmt; 631 ..parent = stmt;
628 statements.add(stmt); 632 statements.add(stmt);
629 return null; 633 return null;
630 } 634 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 var returnStatement = new ReturnStatement( 681 var returnStatement = new ReturnStatement(
678 new PropertyGet(completerGet, new Name('stream', helper.asyncLibrary))); 682 new PropertyGet(completerGet, new Name('stream', helper.asyncLibrary)));
679 statements.add(returnStatement); 683 statements.add(returnStatement);
680 684
681 enclosingFunction.body = new Block(statements); 685 enclosingFunction.body = new Block(statements);
682 enclosingFunction.body.parent = enclosingFunction; 686 enclosingFunction.body.parent = enclosingFunction;
683 enclosingFunction.asyncMarker = AsyncMarker.Sync; 687 enclosingFunction.asyncMarker = AsyncMarker.Sync;
684 return enclosingFunction; 688 return enclosingFunction;
685 } 689 }
686 690
691 Statement buildWrappedBody() {
692 ++currentTryDepth;
693 Statement body = super.buildWrappedBody();
694 --currentTryDepth;
695
696 var finallyBody = new ExpressionStatement(new MethodInvocation(
697 new VariableGet(controllerVariable),
698 new Name("close", helper.asyncLibrary),
699 new Arguments(<Expression>[])));
700
701 var tryFinally = new TryFinally(body, new Block(<Statement>[finallyBody]));
702 return tryFinally;
703 }
704
687 Statement buildCatchBody(exceptionVariable, stackTraceVariable) { 705 Statement buildCatchBody(exceptionVariable, stackTraceVariable) {
688 return new ExpressionStatement(new MethodInvocation( 706 return new ExpressionStatement(new MethodInvocation(
689 new VariableGet(controllerVariable), 707 new VariableGet(controllerVariable),
690 new Name("completeError", helper.asyncLibrary), 708 new Name("addError", helper.asyncLibrary),
691 new Arguments(<Expression>[ 709 new Arguments(<Expression>[
692 new VariableGet(exceptionVariable), 710 new VariableGet(exceptionVariable),
693 new VariableGet(stackTraceVariable) 711 new VariableGet(stackTraceVariable)
694 ]))); 712 ])));
695 } 713 }
696 714
697 Statement buildReturn(Statement body) { 715 Statement buildReturn(Statement body) {
698 // Async* functions cannot return a value. The returns from the function 716 // Async* functions cannot return a value. The returns from the function
699 // have been translated into breaks from the labeled body. 717 // have been translated into breaks from the labeled body.
700 return new Block(<Statement>[ 718 return new Block(<Statement>[
701 body, 719 body,
702 new ExpressionStatement(new MethodInvocation( 720 new ReturnStatement()..fileOffset = enclosingFunction.fileEndOffset,
703 new VariableGet(controllerVariable),
704 new Name("close", helper.asyncLibrary),
705 new Arguments(<Expression>[]))),
706 new ReturnStatement()..fileOffset = enclosingFunction.fileEndOffset
707 ]); 721 ]);
708 } 722 }
709 723
710 TreeNode visitYieldStatement(YieldStatement stmt) { 724 TreeNode visitYieldStatement(YieldStatement stmt) {
711 Expression expr = expressionRewriter.rewrite(stmt.expression, statements); 725 Expression expr = expressionRewriter.rewrite(stmt.expression, statements);
712 726
713 var addExpression = new MethodInvocation( 727 var addExpression = new MethodInvocation(
714 new VariableGet(controllerVariable), 728 new VariableGet(controllerVariable),
715 new Name(stmt.isYieldStar ? 'addStream' : 'add', helper.asyncLibrary), 729 new Name(stmt.isYieldStar ? 'addStream' : 'add', helper.asyncLibrary),
716 new Arguments(<Expression>[expr]))..fileOffset = stmt.fileOffset; 730 new Arguments(<Expression>[expr]))..fileOffset = stmt.fileOffset;
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
907 findFactoryConstructor(completerClass, 'sync'), 921 findFactoryConstructor(completerClass, 'sync'),
908 findConstructor(syncIterableClass, ''), 922 findConstructor(syncIterableClass, ''),
909 findConstructor(streamIteratorClass, ''), 923 findConstructor(streamIteratorClass, ''),
910 findFactoryConstructor(futureClass, 'microtask'), 924 findFactoryConstructor(futureClass, 'microtask'),
911 findConstructor(streamControllerClass, ''), 925 findConstructor(streamControllerClass, ''),
912 findProcedure(asyncLibrary, '_asyncThenWrapperHelper'), 926 findProcedure(asyncLibrary, '_asyncThenWrapperHelper'),
913 findProcedure(asyncLibrary, '_asyncErrorWrapperHelper'), 927 findProcedure(asyncLibrary, '_asyncErrorWrapperHelper'),
914 findProcedure(asyncLibrary, '_awaitHelper')); 928 findProcedure(asyncLibrary, '_awaitHelper'));
915 } 929 }
916 } 930 }
OLDNEW
« no previous file with comments | « no previous file | tests/co19/co19-kernel.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698