| 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 |