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

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: Run dartfmt 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') | tests/language/language.status » ('J')
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.
56 int capturedCatchDepth = 0; // Deepest yield point within a catch-block.
57 55
58 ContinuationRewriterBase(HelperNodes helper, this.enclosingFunction, 56 // For both, try-catch and try-finally, the VM needs to have saved-try-context
59 {this.currentTryDepth: 0}) 57 // and exception/stacktrace available (both need the correct context when
58 // entering catch/finally blocks and finally needs exception/stacktrace for
59 // rethrow).
60 int capturedDepth = 0; // Deepest yield point within try/catch-blocks.
61
62 ContinuationRewriterBase(HelperNodes helper, this.enclosingFunction)
60 : super(helper); 63 : super(helper);
61 64
62 Statement createContinuationPoint([Expression value]) { 65 Statement createContinuationPoint([Expression value]) {
63 if (value == null) value = new NullLiteral(); 66 if (value == null) value = new NullLiteral();
64 capturedTryDepth = math.max(capturedTryDepth, currentTryDepth); 67 capturedDepth =
65 capturedCatchDepth = math.max(capturedCatchDepth, currentCatchDepth); 68 math.max(capturedDepth, currentTryDepth + currentCatchDepth);
66 return new YieldStatement(value, isNative: true); 69 return new YieldStatement(value, isNative: true);
67 } 70 }
68 71
69 TreeNode visitTryCatch(TryCatch node) { 72 TreeNode visitTryCatch(TryCatch node) {
70 if (node.body != null) { 73 if (node.body != null) {
71 currentTryDepth++; 74 currentTryDepth++;
72 node.body = node.body.accept(this); 75 node.body = node.body.accept(this);
73 node.body?.parent = node; 76 node.body?.parent = node;
74 currentTryDepth--; 77 currentTryDepth--;
75 } 78 }
76 79
77 currentCatchDepth++; 80 ++currentCatchDepth;
78 transformList(node.catches, this, node); 81 transformList(node.catches, this, node);
79 currentCatchDepth--; 82 --currentCatchDepth;
80 return node; 83 return node;
81 } 84 }
82 85
83 TreeNode visitTryFinally(TryFinally node) { 86 TreeNode visitTryFinally(TryFinally node) {
84 if (node.body != null) { 87 if (node.body != null) {
85 currentTryDepth++; 88 currentTryDepth++;
86 node.body = node.body.accept(this); 89 node.body = node.body.accept(this);
87 node.body?.parent = node; 90 node.body?.parent = node;
88 currentTryDepth--; 91 currentTryDepth--;
89 } 92 }
90 if (node.finalizer != null) { 93 if (node.finalizer != null) {
91 node.finalizer = node.finalizer.accept(this); 94 node.finalizer = node.finalizer.accept(this);
92 node.finalizer?.parent = node; 95 node.finalizer?.parent = node;
93 } 96 }
94 return node; 97 return node;
95 } 98 }
96 99
97 Iterable<VariableDeclaration> createCapturedTryVariables() => 100 Iterable<VariableDeclaration> createCapturedTryVariables() =>
98 new Iterable.generate(capturedTryDepth, 101 new Iterable.generate(capturedDepth,
99 (depth) => new VariableDeclaration(":saved_try_context_var${depth}")); 102 (depth) => new VariableDeclaration(":saved_try_context_var${depth}"));
100 103
101 Iterable<VariableDeclaration> createCapturedCatchVariables() => 104 Iterable<VariableDeclaration> createCapturedCatchVariables() =>
102 new Iterable.generate(capturedCatchDepth).expand((depth) => [ 105 new Iterable.generate(capturedDepth).expand((depth) => [
103 new VariableDeclaration(":exception${depth}"), 106 new VariableDeclaration(":exception${depth}"),
104 new VariableDeclaration(":stack_trace${depth}"), 107 new VariableDeclaration(":stack_trace${depth}"),
105 ]); 108 ]);
106 109
107 List<VariableDeclaration> variableDeclarations() => 110 List<VariableDeclaration> variableDeclarations() =>
108 [asyncJumpVariable, asyncContextVariable] 111 [asyncJumpVariable, asyncContextVariable]
109 ..addAll(createCapturedTryVariables()) 112 ..addAll(createCapturedTryVariables())
110 ..addAll(createCapturedCatchVariables()); 113 ..addAll(createCapturedCatchVariables());
111 } 114 }
112 115
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 final VariableDeclaration thenContinuationVariable = 185 final VariableDeclaration thenContinuationVariable =
183 new VariableDeclaration(":async_op_then"); 186 new VariableDeclaration(":async_op_then");
184 final VariableDeclaration catchErrorContinuationVariable = 187 final VariableDeclaration catchErrorContinuationVariable =
185 new VariableDeclaration(":async_op_error"); 188 new VariableDeclaration(":async_op_error");
186 189
187 LabeledStatement labeledBody; 190 LabeledStatement labeledBody;
188 191
189 ExpressionLifter expressionRewriter; 192 ExpressionLifter expressionRewriter;
190 193
191 AsyncRewriterBase(helper, enclosingFunction) 194 AsyncRewriterBase(helper, enclosingFunction)
192 // Body is wrapped in the try-catch so initial currentTryDepth is 1. 195 : super(helper, enclosingFunction) {}
193 : super(helper, enclosingFunction, currentTryDepth: 1) {}
194 196
195 void setupAsyncContinuations(List<Statement> statements) { 197 void setupAsyncContinuations(List<Statement> statements) {
196 expressionRewriter = new ExpressionLifter(this); 198 expressionRewriter = new ExpressionLifter(this);
197 199
198 // var :async_op_then; 200 // var :async_op_then;
199 statements.add(thenContinuationVariable); 201 statements.add(thenContinuationVariable);
200 202
201 // var :async_op_error; 203 // var :async_op_error;
202 statements.add(catchErrorContinuationVariable); 204 statements.add(catchErrorContinuationVariable);
203 205
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 final boundCatchErrorClosure = new StaticInvocation( 242 final boundCatchErrorClosure = new StaticInvocation(
241 helper.asyncErrorWrapper, 243 helper.asyncErrorWrapper,
242 new Arguments(<Expression>[new VariableGet(nestedClosureVariable)])); 244 new Arguments(<Expression>[new VariableGet(nestedClosureVariable)]));
243 final catchErrorClosureVariableAssign = new ExpressionStatement( 245 final catchErrorClosureVariableAssign = new ExpressionStatement(
244 new VariableSet( 246 new VariableSet(
245 catchErrorContinuationVariable, boundCatchErrorClosure)); 247 catchErrorContinuationVariable, boundCatchErrorClosure));
246 statements.add(catchErrorClosureVariableAssign); 248 statements.add(catchErrorClosureVariableAssign);
247 } 249 }
248 250
249 Statement buildWrappedBody() { 251 Statement buildWrappedBody() {
252 ++currentCatchDepth;
250 labeledBody = new LabeledStatement(null); 253 labeledBody = new LabeledStatement(null);
251 labeledBody.body = visitDelimited(enclosingFunction.body) 254 labeledBody.body = visitDelimited(enclosingFunction.body)
252 ..parent = labeledBody; 255 ..parent = labeledBody;
253 256
254 var exceptionVariable = new VariableDeclaration(":exception"); 257 var exceptionVariable = new VariableDeclaration(":exception");
255 var stackTraceVariable = new VariableDeclaration(":stack_trace"); 258 var stackTraceVariable = new VariableDeclaration(":stack_trace");
256 259
257 return new TryCatch(buildReturn(labeledBody), <Catch>[ 260 var body = buildReturn(labeledBody);
261 --currentCatchDepth;
262 return new TryCatch(body, <Catch>[
258 new Catch( 263 new Catch(
259 exceptionVariable, 264 exceptionVariable,
260 new Block(<Statement>[ 265 new Block(<Statement>[
261 buildCatchBody(exceptionVariable, stackTraceVariable) 266 buildCatchBody(exceptionVariable, stackTraceVariable)
262 ]), 267 ]),
263 stackTrace: stackTraceVariable) 268 stackTrace: stackTraceVariable)
264 ]); 269 ]);
265 } 270 }
266 271
267 Statement buildCatchBody( 272 Statement buildCatchBody(
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 var returnStatement = new ReturnStatement( 682 var returnStatement = new ReturnStatement(
678 new PropertyGet(completerGet, new Name('stream', helper.asyncLibrary))); 683 new PropertyGet(completerGet, new Name('stream', helper.asyncLibrary)));
679 statements.add(returnStatement); 684 statements.add(returnStatement);
680 685
681 enclosingFunction.body = new Block(statements); 686 enclosingFunction.body = new Block(statements);
682 enclosingFunction.body.parent = enclosingFunction; 687 enclosingFunction.body.parent = enclosingFunction;
683 enclosingFunction.asyncMarker = AsyncMarker.Sync; 688 enclosingFunction.asyncMarker = AsyncMarker.Sync;
684 return enclosingFunction; 689 return enclosingFunction;
685 } 690 }
686 691
692 Statement buildWrappedBody() {
693 ++currentTryDepth;
694 Statement body = super.buildWrappedBody();
695 --currentTryDepth;
696 var tryFinally =
697 new TryFinally(body, new Block(<Statement>[buildFinallyBody()]));
698 return tryFinally;
699 }
700
687 Statement buildCatchBody(exceptionVariable, stackTraceVariable) { 701 Statement buildCatchBody(exceptionVariable, stackTraceVariable) {
688 return new ExpressionStatement(new MethodInvocation( 702 return new ExpressionStatement(new MethodInvocation(
689 new VariableGet(controllerVariable), 703 new VariableGet(controllerVariable),
690 new Name("completeError", helper.asyncLibrary), 704 new Name("addError", helper.asyncLibrary),
691 new Arguments(<Expression>[ 705 new Arguments(<Expression>[
692 new VariableGet(exceptionVariable), 706 new VariableGet(exceptionVariable),
693 new VariableGet(stackTraceVariable) 707 new VariableGet(stackTraceVariable)
694 ]))); 708 ])));
695 } 709 }
696 710
711 Statement buildFinallyBody() {
712 return new ExpressionStatement(new MethodInvocation(
713 new VariableGet(controllerVariable),
714 new Name("close", helper.asyncLibrary),
715 new Arguments(<Expression>[])));
716 }
717
697 Statement buildReturn(Statement body) { 718 Statement buildReturn(Statement body) {
698 // Async* functions cannot return a value. The returns from the function 719 // Async* functions cannot return a value. The returns from the function
699 // have been translated into breaks from the labeled body. 720 // have been translated into breaks from the labeled body.
700 return new Block(<Statement>[ 721 return new Block(<Statement>[
701 body, 722 body,
702 new ExpressionStatement(new MethodInvocation( 723 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 ]); 724 ]);
708 } 725 }
709 726
710 TreeNode visitYieldStatement(YieldStatement stmt) { 727 TreeNode visitYieldStatement(YieldStatement stmt) {
711 Expression expr = expressionRewriter.rewrite(stmt.expression, statements); 728 Expression expr = expressionRewriter.rewrite(stmt.expression, statements);
712 729
713 var addExpression = new MethodInvocation( 730 var addExpression = new MethodInvocation(
714 new VariableGet(controllerVariable), 731 new VariableGet(controllerVariable),
715 new Name(stmt.isYieldStar ? 'addStream' : 'add', helper.asyncLibrary), 732 new Name(stmt.isYieldStar ? 'addStream' : 'add', helper.asyncLibrary),
716 new Arguments(<Expression>[expr]))..fileOffset = stmt.fileOffset; 733 new Arguments(<Expression>[expr]))..fileOffset = stmt.fileOffset;
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
907 findFactoryConstructor(completerClass, 'sync'), 924 findFactoryConstructor(completerClass, 'sync'),
908 findConstructor(syncIterableClass, ''), 925 findConstructor(syncIterableClass, ''),
909 findConstructor(streamIteratorClass, ''), 926 findConstructor(streamIteratorClass, ''),
910 findFactoryConstructor(futureClass, 'microtask'), 927 findFactoryConstructor(futureClass, 'microtask'),
911 findConstructor(streamControllerClass, ''), 928 findConstructor(streamControllerClass, ''),
912 findProcedure(asyncLibrary, '_asyncThenWrapperHelper'), 929 findProcedure(asyncLibrary, '_asyncThenWrapperHelper'),
913 findProcedure(asyncLibrary, '_asyncErrorWrapperHelper'), 930 findProcedure(asyncLibrary, '_asyncErrorWrapperHelper'),
914 findProcedure(asyncLibrary, '_awaitHelper')); 931 findProcedure(asyncLibrary, '_awaitHelper'));
915 } 932 }
916 } 933 }
OLDNEW
« no previous file with comments | « no previous file | tests/co19/co19-kernel.status » ('j') | tests/language/language.status » ('J')

Powered by Google App Engine
This is Rietveld 408576698