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

Side by Side Diff: runtime/lib/async_patch.dart

Issue 2692803006: Track the 'awaiter return' call stack use it to detect uncaught exceptions in async functions (Closed)
Patch Set: rmacnak review Created 3 years, 9 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
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 import "dart:_internal" hide Symbol; 5 import "dart:_internal" hide Symbol;
6 6
7 // Equivalent of calling FATAL from C++ code. 7 // Equivalent of calling FATAL from C++ code.
8 _fatal(msg) native "DartAsync_fatal"; 8 _fatal(msg) native "DartAsync_fatal";
9 9
10 // We need to pass the value as first argument and leave the second and third 10 // We need to pass the value as first argument and leave the second and third
(...skipping 27 matching lines...) Expand all
38 if (Zone.current == Zone.ROOT) return errorCallback; 38 if (Zone.current == Zone.ROOT) return errorCallback;
39 return Zone.current.registerBinaryCallback(errorCallback); 39 return Zone.current.registerBinaryCallback(errorCallback);
40 } 40 }
41 41
42 /// Registers the [thenCallback] and [errorCallback] on the given [object]. 42 /// Registers the [thenCallback] and [errorCallback] on the given [object].
43 /// 43 ///
44 /// If [object] is not a future, then it is wrapped into one. 44 /// If [object] is not a future, then it is wrapped into one.
45 /// 45 ///
46 /// Returns the result of registering with `.then`. 46 /// Returns the result of registering with `.then`.
47 Future _awaitHelper( 47 Future _awaitHelper(
48 var object, Function thenCallback, Function errorCallback) { 48 var object,
49 Function thenCallback,
50 Function errorCallback,
51 var awaiter) {
49 if (object is! Future) { 52 if (object is! Future) {
50 object = new _Future().._setValue(object); 53 object = new _Future().._setValue(object);
51 } else if (object is! _Future) { 54 } else if (object is! _Future) {
52 return object.then(thenCallback, onError: errorCallback); 55 return object.then(thenCallback, onError: errorCallback);
53 } 56 }
54 // `object` is a `_Future`. 57 // `object` is a `_Future`.
55 // 58 //
56 // Since the callbacks have been registered in the current zone (see 59 // Since the callbacks have been registered in the current zone (see
57 // [_asyncThenWrapperHelper] and [_asyncErrorWrapperHelper]), we can avoid 60 // [_asyncThenWrapperHelper] and [_asyncErrorWrapperHelper]), we can avoid
58 // another registration and directly invoke the no-zone-registration `.then`. 61 // another registration and directly invoke the no-zone-registration `.then`.
59 // 62 //
60 // We can only do this for our internal futures (the default implementation of 63 // We can only do this for our internal futures (the default implementation of
61 // all futures that are constructed by the `dart:async` library). 64 // all futures that are constructed by the `dart:async` library).
65 object._awaiter = awaiter;
62 return object._thenNoZoneRegistration(thenCallback, errorCallback); 66 return object._thenNoZoneRegistration(thenCallback, errorCallback);
63 } 67 }
64 68
69 // Called as part of the 'await for (...)' construct. Registers the
70 // awaiter on the stream.
71 void _asyncStarListenHelper(var object, var awaiter) {
72 if (object is! _StreamImpl) {
hausner 2017/02/28 19:04:51 Curious: why not simply if (object is _StreamImpl
Cutch 2017/02/28 21:46:52 I was just copying the _awaitHelper pattern :)
73 return;
74 }
75 // `object` is a `_StreamImpl`.
76 object._awaiter = awaiter;
77 }
78
65 // _AsyncStarStreamController is used by the compiler to implement 79 // _AsyncStarStreamController is used by the compiler to implement
66 // async* generator functions. 80 // async* generator functions.
67 class _AsyncStarStreamController { 81 class _AsyncStarStreamController {
68 StreamController controller; 82 StreamController controller;
69 Function asyncStarBody; 83 Function asyncStarBody;
70 bool isAdding = false; 84 bool isAdding = false;
71 bool onListenReceived = false; 85 bool onListenReceived = false;
72 bool isScheduled = false; 86 bool isScheduled = false;
73 bool isSuspendedAtYield = false; 87 bool isSuspendedAtYield = false;
74 Completer cancellationCompleter = null; 88 Completer cancellationCompleter = null;
75 89
76 Stream get stream => controller.stream; 90 Stream get stream {
91 Stream local = controller.stream;
92 if (local is! _StreamImpl) {
hausner 2017/02/28 19:04:51 ditto
Cutch 2017/02/28 21:46:52 ditto
93 return local;
94 }
95 local._generator = asyncStarBody;
96 return local;
97 }
77 98
78 void runBody() { 99 void runBody() {
79 isScheduled = false; 100 isScheduled = false;
80 isSuspendedAtYield = false; 101 isSuspendedAtYield = false;
81 asyncStarBody(); 102 asyncStarBody();
82 } 103 }
83 104
84 void scheduleGenerator() { 105 void scheduleGenerator() {
85 if (isScheduled || controller.isPaused || isAdding) { 106 if (isScheduled || controller.isPaused || isAdding) {
86 return; 107 return;
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 if (isSuspendedAtYield) { 208 if (isSuspendedAtYield) {
188 scheduleGenerator(); 209 scheduleGenerator();
189 } 210 }
190 } 211 }
191 return cancellationCompleter.future; 212 return cancellationCompleter.future;
192 } 213 }
193 } 214 }
194 215
195 @patch void _rethrow(Object error, StackTrace stackTrace) native "Async_rethrow" ; 216 @patch void _rethrow(Object error, StackTrace stackTrace) native "Async_rethrow" ;
196 217
218 @patch class _Future<T> {
219 /// The closure implementing the async[*]-body that is `await`ing this future.
220 Function _awaiter;
221 }
222
223 @patch class _StreamImpl<T> {
224 /// The closure implementing the async[*]-body that is `await`ing this future.
225 Function _awaiter;
226 /// The closure implementing the async-generator body that is creating events
227 /// for this stream.
228 Function _generator;
229 }
197 230
198 /// Returns a [StackTrace] object containing the synchronous prefix for this 231 /// Returns a [StackTrace] object containing the synchronous prefix for this
199 /// asynchronous method. 232 /// asynchronous method.
200 Object _asyncStackTraceHelper() native "StackTrace_asyncStackTraceHelper"; 233 Object _asyncStackTraceHelper()
234 native "StackTrace_asyncStackTraceHelper";
201 235
202 void _clearAsyncThreadStackTrace() 236 void _clearAsyncThreadStackTrace()
203 native "StackTrace_clearAsyncThreadStackTrace"; 237 native "StackTrace_clearAsyncThreadStackTrace";
204 238
205 void _setAsyncThreadStackTrace(StackTrace stackTrace) native 239 void _setAsyncThreadStackTrace(StackTrace stackTrace) native
206 "StackTrace_setAsyncThreadStackTrace"; 240 "StackTrace_setAsyncThreadStackTrace";
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698