OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 (function(global, utils, extrasUtils) { | 5 (function(global, utils, extrasUtils) { |
6 | 6 |
7 "use strict"; | 7 "use strict"; |
8 | 8 |
9 %CheckIsBootstrapping(); | 9 %CheckIsBootstrapping(); |
10 | 10 |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 | 140 |
141 function PromiseInit(promise) { | 141 function PromiseInit(promise) { |
142 return PromiseSet(promise, kPending, UNDEFINED); | 142 return PromiseSet(promise, kPending, UNDEFINED); |
143 } | 143 } |
144 | 144 |
145 function FulfillPromise(promise, status, value, promiseQueue) { | 145 function FulfillPromise(promise, status, value, promiseQueue) { |
146 if (GET_PRIVATE(promise, promiseStateSymbol) === kPending) { | 146 if (GET_PRIVATE(promise, promiseStateSymbol) === kPending) { |
147 var tasks = GET_PRIVATE(promise, promiseQueue); | 147 var tasks = GET_PRIVATE(promise, promiseQueue); |
148 if (!IS_UNDEFINED(tasks)) { | 148 if (!IS_UNDEFINED(tasks)) { |
149 var deferred = GET_PRIVATE(promise, promiseDeferredReactionSymbol); | 149 var deferred = GET_PRIVATE(promise, promiseDeferredReactionSymbol); |
150 PromiseEnqueue(value, tasks, deferred, status); | 150 %EnqueuePromiseReactionJob(value, tasks, deferred, status); |
151 } | 151 } |
152 PromiseSet(promise, status, value); | 152 PromiseSet(promise, status, value); |
153 } | 153 } |
154 } | 154 } |
155 | 155 |
156 function PromiseHandle(value, handler, deferred) { | 156 function PromiseHandle(value, handler, deferred) { |
157 var debug_is_active = DEBUG_IS_ACTIVE; | 157 var debug_is_active = DEBUG_IS_ACTIVE; |
158 try { | 158 try { |
159 if (debug_is_active) %DebugPushPromise(deferred.promise); | 159 if (debug_is_active) %DebugPushPromise(deferred.promise); |
160 var result = handler(value); | 160 var result = handler(value); |
(...skipping 10 matching lines...) Expand all Loading... |
171 RejectPromise(deferred.promise, exception, false); | 171 RejectPromise(deferred.promise, exception, false); |
172 } else { | 172 } else { |
173 %_Call(deferred.reject, UNDEFINED, exception); | 173 %_Call(deferred.reject, UNDEFINED, exception); |
174 } | 174 } |
175 } catch (e) { } | 175 } catch (e) { } |
176 } finally { | 176 } finally { |
177 if (debug_is_active) %DebugPopPromise(); | 177 if (debug_is_active) %DebugPopPromise(); |
178 } | 178 } |
179 } | 179 } |
180 | 180 |
181 function PromiseEnqueue(value, tasks, deferreds, status) { | 181 function PromiseDebugGetInfo(deferreds, status) { |
182 var id, name, instrumenting = DEBUG_IS_ACTIVE; | 182 var id, name, instrumenting = DEBUG_IS_ACTIVE; |
183 | 183 |
184 if (instrumenting) { | 184 if (instrumenting) { |
185 // In an async function, reuse the existing stack related to the outer | 185 // In an async function, reuse the existing stack related to the outer |
186 // Promise. Otherwise, e.g. in a direct call to then, save a new stack. | 186 // Promise. Otherwise, e.g. in a direct call to then, save a new stack. |
187 // Promises with multiple reactions with one or more of them being async | 187 // Promises with multiple reactions with one or more of them being async |
188 // functions will not get a good stack trace, as async functions require | 188 // functions will not get a good stack trace, as async functions require |
189 // different stacks from direct Promise use, but we save and restore a | 189 // different stacks from direct Promise use, but we save and restore a |
190 // stack once for all reactions. TODO(littledan): Improve this case. | 190 // stack once for all reactions. TODO(littledan): Improve this case. |
191 if (!IS_UNDEFINED(deferreds) && | 191 if (!IS_UNDEFINED(deferreds) && |
192 HAS_PRIVATE(deferreds.promise, promiseHandledBySymbol) && | 192 HAS_PRIVATE(deferreds.promise, promiseHandledBySymbol) && |
193 HAS_PRIVATE(GET_PRIVATE(deferreds.promise, promiseHandledBySymbol), | 193 HAS_PRIVATE(GET_PRIVATE(deferreds.promise, promiseHandledBySymbol), |
194 promiseAsyncStackIDSymbol)) { | 194 promiseAsyncStackIDSymbol)) { |
195 id = GET_PRIVATE(GET_PRIVATE(deferreds.promise, promiseHandledBySymbol), | 195 id = GET_PRIVATE(GET_PRIVATE(deferreds.promise, promiseHandledBySymbol), |
196 promiseAsyncStackIDSymbol); | 196 promiseAsyncStackIDSymbol); |
197 name = "async function"; | 197 name = "async function"; |
198 } else { | 198 } else { |
199 id = %DebugNextMicrotaskId(); | 199 id = %DebugNextMicrotaskId(); |
200 name = status === kFulfilled ? "Promise.resolve" : "Promise.reject"; | 200 name = status === kFulfilled ? "Promise.resolve" : "Promise.reject"; |
201 %DebugAsyncTaskEvent("enqueue", id, name); | 201 %DebugAsyncTaskEvent("enqueue", id, name); |
202 } | 202 } |
203 } | 203 } |
204 %EnqueuePromiseReactionJob(value, tasks, deferreds, id, name); | 204 return [id, name]; |
205 } | 205 } |
206 | 206 |
207 function PromiseAttachCallbacks(promise, deferred, onResolve, onReject) { | 207 function PromiseAttachCallbacks(promise, deferred, onResolve, onReject) { |
208 var maybeResolveCallbacks = | 208 var maybeResolveCallbacks = |
209 GET_PRIVATE(promise, promiseFulfillReactionsSymbol); | 209 GET_PRIVATE(promise, promiseFulfillReactionsSymbol); |
210 if (IS_UNDEFINED(maybeResolveCallbacks)) { | 210 if (IS_UNDEFINED(maybeResolveCallbacks)) { |
211 SET_PRIVATE(promise, promiseFulfillReactionsSymbol, onResolve); | 211 SET_PRIVATE(promise, promiseFulfillReactionsSymbol, onResolve); |
212 SET_PRIVATE(promise, promiseRejectReactionsSymbol, onReject); | 212 SET_PRIVATE(promise, promiseRejectReactionsSymbol, onReject); |
213 SET_PRIVATE(promise, promiseDeferredReactionSymbol, deferred); | 213 SET_PRIVATE(promise, promiseDeferredReactionSymbol, deferred); |
214 } else if (!IS_ARRAY(maybeResolveCallbacks)) { | 214 } else if (!IS_ARRAY(maybeResolveCallbacks)) { |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
383 function PerformPromiseThen(promise, onResolve, onReject, resultCapability) { | 383 function PerformPromiseThen(promise, onResolve, onReject, resultCapability) { |
384 if (!IS_CALLABLE(onResolve)) onResolve = PromiseIdResolveHandler; | 384 if (!IS_CALLABLE(onResolve)) onResolve = PromiseIdResolveHandler; |
385 if (!IS_CALLABLE(onReject)) onReject = PromiseIdRejectHandler; | 385 if (!IS_CALLABLE(onReject)) onReject = PromiseIdRejectHandler; |
386 | 386 |
387 var status = GET_PRIVATE(promise, promiseStateSymbol); | 387 var status = GET_PRIVATE(promise, promiseStateSymbol); |
388 switch (status) { | 388 switch (status) { |
389 case kPending: | 389 case kPending: |
390 PromiseAttachCallbacks(promise, resultCapability, onResolve, onReject); | 390 PromiseAttachCallbacks(promise, resultCapability, onResolve, onReject); |
391 break; | 391 break; |
392 case kFulfilled: | 392 case kFulfilled: |
393 PromiseEnqueue(GET_PRIVATE(promise, promiseResultSymbol), | 393 %EnqueuePromiseReactionJob(GET_PRIVATE(promise, promiseResultSymbol), |
394 onResolve, resultCapability, kFulfilled); | 394 onResolve, resultCapability, kFulfilled); |
395 break; | 395 break; |
396 case kRejected: | 396 case kRejected: |
397 if (!HAS_DEFINED_PRIVATE(promise, promiseHasHandlerSymbol)) { | 397 if (!HAS_DEFINED_PRIVATE(promise, promiseHasHandlerSymbol)) { |
398 // Promise has already been rejected, but had no handler. | 398 // Promise has already been rejected, but had no handler. |
399 // Revoke previously triggered reject event. | 399 // Revoke previously triggered reject event. |
400 %PromiseRevokeReject(promise); | 400 %PromiseRevokeReject(promise); |
401 } | 401 } |
402 PromiseEnqueue(GET_PRIVATE(promise, promiseResultSymbol), | 402 %EnqueuePromiseReactionJob(GET_PRIVATE(promise, promiseResultSymbol), |
403 onReject, resultCapability, kRejected); | 403 onReject, resultCapability, kRejected); |
404 break; | 404 break; |
405 } | 405 } |
406 | 406 |
407 // Mark this promise as having handler. | 407 // Mark this promise as having handler. |
408 SET_PRIVATE(promise, promiseHasHandlerSymbol, true); | 408 SET_PRIVATE(promise, promiseHasHandlerSymbol, true); |
409 return resultCapability.promise; | 409 return resultCapability.promise; |
410 } | 410 } |
411 | 411 |
412 // ES#sec-promise.prototype.then | 412 // ES#sec-promise.prototype.then |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
652 "catch", PromiseCatch | 652 "catch", PromiseCatch |
653 ]); | 653 ]); |
654 | 654 |
655 %InstallToContext([ | 655 %InstallToContext([ |
656 "promise_catch", PromiseCatch, | 656 "promise_catch", PromiseCatch, |
657 "promise_create", PromiseCreate, | 657 "promise_create", PromiseCreate, |
658 "promise_has_user_defined_reject_handler", PromiseHasUserDefinedRejectHandler, | 658 "promise_has_user_defined_reject_handler", PromiseHasUserDefinedRejectHandler, |
659 "promise_reject", DoRejectPromise, | 659 "promise_reject", DoRejectPromise, |
660 "promise_resolve", ResolvePromise, | 660 "promise_resolve", ResolvePromise, |
661 "promise_then", PromiseThen, | 661 "promise_then", PromiseThen, |
662 "promise_handle", PromiseHandle | 662 "promise_handle", PromiseHandle, |
| 663 "promise_debug_get_info", PromiseDebugGetInfo |
663 ]); | 664 ]); |
664 | 665 |
665 // This allows extras to create promises quickly without building extra | 666 // This allows extras to create promises quickly without building extra |
666 // resolve/reject closures, and allows them to later resolve and reject any | 667 // resolve/reject closures, and allows them to later resolve and reject any |
667 // promise without having to hold on to those closures forever. | 668 // promise without having to hold on to those closures forever. |
668 utils.InstallFunctions(extrasUtils, 0, [ | 669 utils.InstallFunctions(extrasUtils, 0, [ |
669 "createPromise", PromiseCreate, | 670 "createPromise", PromiseCreate, |
670 "resolvePromise", ResolvePromise, | 671 "resolvePromise", ResolvePromise, |
671 "rejectPromise", DoRejectPromise | 672 "rejectPromise", DoRejectPromise |
672 ]); | 673 ]); |
673 | 674 |
674 utils.Export(function(to) { | 675 utils.Export(function(to) { |
675 to.IsPromise = IsPromise; | 676 to.IsPromise = IsPromise; |
676 to.PromiseCreate = PromiseCreate; | 677 to.PromiseCreate = PromiseCreate; |
677 to.PromiseThen = PromiseThen; | 678 to.PromiseThen = PromiseThen; |
678 | 679 |
679 to.GlobalPromise = GlobalPromise; | 680 to.GlobalPromise = GlobalPromise; |
680 to.NewPromiseCapability = NewPromiseCapability; | 681 to.NewPromiseCapability = NewPromiseCapability; |
681 to.PerformPromiseThen = PerformPromiseThen; | 682 to.PerformPromiseThen = PerformPromiseThen; |
682 to.ResolvePromise = ResolvePromise; | 683 to.ResolvePromise = ResolvePromise; |
683 to.RejectPromise = RejectPromise; | 684 to.RejectPromise = RejectPromise; |
684 }); | 685 }); |
685 | 686 |
686 }) | 687 }) |
OLD | NEW |