OLD | NEW |
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"; | 5 import "dart:_internal"; |
6 | 6 |
7 // We need to pass the value as first argument and leave the second and third | 7 // We need to pass the value as first argument and leave the second and third |
8 // arguments empty (used for error handling). | 8 // arguments empty (used for error handling). |
9 // See vm/ast_transformer.cc for usage. | 9 // See vm/ast_transformer.cc for usage. |
10 Function _asyncThenWrapperHelper(continuation) { | 10 Function _asyncThenWrapperHelper(continuation) { |
(...skipping 24 matching lines...) Expand all Loading... |
35 if (Zone.current == Zone.ROOT) return errorCallback; | 35 if (Zone.current == Zone.ROOT) return errorCallback; |
36 return Zone.current.registerBinaryCallback(errorCallback); | 36 return Zone.current.registerBinaryCallback(errorCallback); |
37 } | 37 } |
38 | 38 |
39 /// Registers the [thenCallback] and [errorCallback] on the given [object]. | 39 /// Registers the [thenCallback] and [errorCallback] on the given [object]. |
40 /// | 40 /// |
41 /// If [object] is not a future, then it is wrapped into one. | 41 /// If [object] is not a future, then it is wrapped into one. |
42 /// | 42 /// |
43 /// Returns the result of registering with `.then`. | 43 /// Returns the result of registering with `.then`. |
44 Future _awaitHelper( | 44 Future _awaitHelper( |
45 var object, Function thenCallback, Function errorCallback) { | 45 var object, |
| 46 Function thenCallback, |
| 47 Function errorCallback, |
| 48 var awaiter) { |
46 if (object is! Future) { | 49 if (object is! Future) { |
47 object = new _Future().._setValue(object); | 50 object = new _Future().._setValue(object); |
48 } else if (object is! _Future) { | 51 } else if (object is! _Future) { |
49 return object.then(thenCallback, onError: errorCallback); | 52 return object.then(thenCallback, onError: errorCallback); |
50 } | 53 } |
51 // `object` is a `_Future`. | 54 // `object` is a `_Future`. |
52 // | 55 // |
53 // Since the callbacks have been registered in the current zone (see | 56 // Since the callbacks have been registered in the current zone (see |
54 // [_asyncThenWrapperHelper] and [_asyncErrorWrapperHelper]), we can avoid | 57 // [_asyncThenWrapperHelper] and [_asyncErrorWrapperHelper]), we can avoid |
55 // another registration and directly invoke the no-zone-registration `.then`. | 58 // another registration and directly invoke the no-zone-registration `.then`. |
56 // | 59 // |
57 // We can only do this for our internal futures (the default implementation of | 60 // We can only do this for our internal futures (the default implementation of |
58 // all futures that are constructed by the `dart:async` library). | 61 // all futures that are constructed by the `dart:async` library). |
| 62 object._awaiter = awaiter; |
59 return object._thenNoZoneRegistration(thenCallback, errorCallback); | 63 return object._thenNoZoneRegistration(thenCallback, errorCallback); |
60 } | 64 } |
61 | 65 |
| 66 // Called as part of the 'await for (...)' construct. |
| 67 void _asyncStarListenHelper(var object, |
| 68 var awaiter) { |
| 69 if (object is! _StreamImpl) { |
| 70 return; |
| 71 } |
| 72 // `object` is a `_StreamImpl`. |
| 73 object._awaiter = awaiter; |
| 74 } |
| 75 |
| 76 // Called after the |
| 77 void _asyncStarMoveNextHelper(var object) { |
| 78 if (object is! _StreamImpl) { |
| 79 return; |
| 80 } |
| 81 // `object` is a `_StreamImpl`. |
| 82 if (object._generator == null) { |
| 83 // No generator registered, this isn't an async* Stream. |
| 84 return; |
| 85 } |
| 86 _moveNextDebuggerStepCheck(object._generator); |
| 87 } |
| 88 |
62 // _AsyncStarStreamController is used by the compiler to implement | 89 // _AsyncStarStreamController is used by the compiler to implement |
63 // async* generator functions. | 90 // async* generator functions. |
64 class _AsyncStarStreamController { | 91 class _AsyncStarStreamController { |
65 StreamController controller; | 92 StreamController controller; |
66 Function asyncStarBody; | 93 Function asyncStarBody; |
67 bool isAdding = false; | 94 bool isAdding = false; |
68 bool onListenReceived = false; | 95 bool onListenReceived = false; |
69 bool isScheduled = false; | 96 bool isScheduled = false; |
70 bool isSuspendedAtYield = false; | 97 bool isSuspendedAtYield = false; |
71 Completer cancellationCompleter = null; | 98 Completer cancellationCompleter = null; |
72 | 99 |
73 Stream get stream => controller.stream; | 100 Stream get stream { |
| 101 Stream local = controller.stream; |
| 102 local._generator = asyncStarBody; |
| 103 return local; |
| 104 } |
74 | 105 |
75 void runBody() { | 106 void runBody() { |
76 isScheduled = false; | 107 isScheduled = false; |
77 isSuspendedAtYield = false; | 108 isSuspendedAtYield = false; |
78 asyncStarBody(); | 109 asyncStarBody(); |
79 } | 110 } |
80 | 111 |
81 void scheduleGenerator() { | 112 void scheduleGenerator() { |
82 if (isScheduled || controller.isPaused || isAdding) { | 113 if (isScheduled || controller.isPaused || isAdding) { |
83 return; | 114 return; |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 // suspended at an await. | 214 // suspended at an await. |
184 if (isSuspendedAtYield) { | 215 if (isSuspendedAtYield) { |
185 scheduleGenerator(); | 216 scheduleGenerator(); |
186 } | 217 } |
187 } | 218 } |
188 return cancellationCompleter.future; | 219 return cancellationCompleter.future; |
189 } | 220 } |
190 } | 221 } |
191 | 222 |
192 @patch void _rethrow(Object error, StackTrace stackTrace) native "Async_rethrow"
; | 223 @patch void _rethrow(Object error, StackTrace stackTrace) native "Async_rethrow"
; |
| 224 |
| 225 @patch class _Future<T> { |
| 226 Object _awaiter; |
| 227 } |
| 228 |
| 229 @patch class _StreamImpl<T> { |
| 230 Object _awaiter; |
| 231 Object _generator; |
| 232 } |
| 233 |
| 234 void _completeOnAsyncReturn(Object completer, [value]) { |
| 235 completer.complete(value); |
| 236 } |
| 237 |
| 238 /// Returns a [StackTrace] object containing the synchronous prefix for this |
| 239 /// asynchronous method. |
| 240 Object _asyncStackTraceHelper(Object closure) |
| 241 native "StackTrace_forAsyncMethod"; |
| 242 |
| 243 void _clearAsyncThreadStackTrace() |
| 244 native "StackTrace_clearAsyncThreadStackTrace"; |
| 245 |
| 246 void _setAsyncThreadStackTrace(StackTrace stackTrace) native |
| 247 "StackTrace_setAsyncThreadStackTrace"; |
| 248 |
| 249 void _moveNextDebuggerStepCheck(async_op) |
| 250 native "AsyncStarMoveNext_debuggerStepCheck"; |
OLD | NEW |