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 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 } else { | 183 } else { |
184 %_Call(deferred.reject, UNDEFINED, exception); | 184 %_Call(deferred.reject, UNDEFINED, exception); |
185 } | 185 } |
186 } catch (e) { } | 186 } catch (e) { } |
187 } finally { | 187 } finally { |
188 if (debug_is_active) %DebugPopPromise(); | 188 if (debug_is_active) %DebugPopPromise(); |
189 } | 189 } |
190 } | 190 } |
191 | 191 |
192 function PromiseEnqueue(value, tasks, deferreds, status) { | 192 function PromiseEnqueue(value, tasks, deferreds, status) { |
193 var id, name, instrumenting = DEBUG_IS_ACTIVE; | 193 var id, name, beforeDebug, afterDebug, instrumenting = DEBUG_IS_ACTIVE; |
194 %EnqueueMicrotask(function() { | 194 |
195 if (instrumenting) { | |
196 %DebugAsyncTaskEvent({ type: "willHandle", id: id, name: name }); | |
197 } | |
198 if (IS_ARRAY(tasks)) { | |
199 for (var i = 0; i < tasks.length; i += 2) { | |
200 PromiseHandle(value, tasks[i], tasks[i + 1]); | |
201 } | |
202 } else { | |
203 PromiseHandle(value, tasks, deferreds); | |
204 } | |
205 if (instrumenting) { | |
206 %DebugAsyncTaskEvent({ type: "didHandle", id: id, name: name }); | |
207 } | |
208 }); | |
209 if (instrumenting) { | 195 if (instrumenting) { |
210 // In an async function, reuse the existing stack related to the outer | 196 // In an async function, reuse the existing stack related to the outer |
211 // Promise. Otherwise, e.g. in a direct call to then, save a new stack. | 197 // Promise. Otherwise, e.g. in a direct call to then, save a new stack. |
212 // Promises with multiple reactions with one or more of them being async | 198 // Promises with multiple reactions with one or more of them being async |
213 // functions will not get a good stack trace, as async functions require | 199 // functions will not get a good stack trace, as async functions require |
214 // different stacks from direct Promise use, but we save and restore a | 200 // different stacks from direct Promise use, but we save and restore a |
215 // stack once for all reactions. TODO(littledan): Improve this case. | 201 // stack once for all reactions. TODO(littledan): Improve this case. |
216 if (!IS_UNDEFINED(deferreds) && | 202 if (!IS_UNDEFINED(deferreds) && |
217 HAS_PRIVATE(deferreds.promise, promiseHandledBySymbol) && | 203 HAS_PRIVATE(deferreds.promise, promiseHandledBySymbol) && |
218 HAS_PRIVATE(GET_PRIVATE(deferreds.promise, promiseHandledBySymbol), | 204 HAS_PRIVATE(GET_PRIVATE(deferreds.promise, promiseHandledBySymbol), |
219 promiseAsyncStackIDSymbol)) { | 205 promiseAsyncStackIDSymbol)) { |
220 id = GET_PRIVATE(GET_PRIVATE(deferreds.promise, promiseHandledBySymbol), | 206 id = GET_PRIVATE(GET_PRIVATE(deferreds.promise, promiseHandledBySymbol), |
221 promiseAsyncStackIDSymbol); | 207 promiseAsyncStackIDSymbol); |
222 name = "async function"; | 208 name = "async function"; |
223 } else { | 209 } else { |
224 id = PromiseNextMicrotaskID(); | 210 id = PromiseNextMicrotaskID(); |
225 name = status === kFulfilled ? "Promise.resolve" : "Promise.reject"; | 211 name = status === kFulfilled ? "Promise.resolve" : "Promise.reject"; |
226 %DebugAsyncTaskEvent({ type: "enqueue", id: id, name: name }); | 212 %DebugAsyncTaskEvent({ type: "enqueue", id: id, name: name }); |
227 } | 213 } |
| 214 |
| 215 beforeDebug = { type: "willHandle", id: id, name: name }; |
| 216 afterDebug = { type: "didHandle", id: id, name: name }; |
228 } | 217 } |
| 218 |
| 219 %EnqueuePromiseReactionJob(value, tasks, deferreds, beforeDebug, afterDebug); |
229 } | 220 } |
230 | 221 |
231 function PromiseAttachCallbacks(promise, deferred, onResolve, onReject) { | 222 function PromiseAttachCallbacks(promise, deferred, onResolve, onReject) { |
232 var maybeResolveCallbacks = | 223 var maybeResolveCallbacks = |
233 GET_PRIVATE(promise, promiseFulfillReactionsSymbol); | 224 GET_PRIVATE(promise, promiseFulfillReactionsSymbol); |
234 if (IS_UNDEFINED(maybeResolveCallbacks)) { | 225 if (IS_UNDEFINED(maybeResolveCallbacks)) { |
235 SET_PRIVATE(promise, promiseFulfillReactionsSymbol, onResolve); | 226 SET_PRIVATE(promise, promiseFulfillReactionsSymbol, onResolve); |
236 SET_PRIVATE(promise, promiseRejectReactionsSymbol, onReject); | 227 SET_PRIVATE(promise, promiseRejectReactionsSymbol, onReject); |
237 SET_PRIVATE(promise, promiseDeferredReactionsSymbol, deferred); | 228 SET_PRIVATE(promise, promiseDeferredReactionsSymbol, deferred); |
238 } else if (!IS_ARRAY(maybeResolveCallbacks)) { | 229 } else if (!IS_ARRAY(maybeResolveCallbacks)) { |
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
696 "then", PromiseThen, | 687 "then", PromiseThen, |
697 "catch", PromiseCatch | 688 "catch", PromiseCatch |
698 ]); | 689 ]); |
699 | 690 |
700 %InstallToContext([ | 691 %InstallToContext([ |
701 "promise_catch", PromiseCatch, | 692 "promise_catch", PromiseCatch, |
702 "promise_create", PromiseCreate, | 693 "promise_create", PromiseCreate, |
703 "promise_has_user_defined_reject_handler", PromiseHasUserDefinedRejectHandler, | 694 "promise_has_user_defined_reject_handler", PromiseHasUserDefinedRejectHandler, |
704 "promise_reject", DoRejectPromise, | 695 "promise_reject", DoRejectPromise, |
705 "promise_resolve", ResolvePromise, | 696 "promise_resolve", ResolvePromise, |
706 "promise_then", PromiseThen | 697 "promise_then", PromiseThen, |
| 698 "promise_handle", PromiseHandle |
707 ]); | 699 ]); |
708 | 700 |
709 // This allows extras to create promises quickly without building extra | 701 // This allows extras to create promises quickly without building extra |
710 // resolve/reject closures, and allows them to later resolve and reject any | 702 // resolve/reject closures, and allows them to later resolve and reject any |
711 // promise without having to hold on to those closures forever. | 703 // promise without having to hold on to those closures forever. |
712 utils.InstallFunctions(extrasUtils, 0, [ | 704 utils.InstallFunctions(extrasUtils, 0, [ |
713 "createPromise", PromiseCreate, | 705 "createPromise", PromiseCreate, |
714 "resolvePromise", ResolvePromise, | 706 "resolvePromise", ResolvePromise, |
715 "rejectPromise", DoRejectPromise | 707 "rejectPromise", DoRejectPromise |
716 ]); | 708 ]); |
717 | 709 |
718 utils.Export(function(to) { | 710 utils.Export(function(to) { |
719 to.IsPromise = IsPromise; | 711 to.IsPromise = IsPromise; |
720 to.PromiseCreate = PromiseCreate; | 712 to.PromiseCreate = PromiseCreate; |
721 to.PromiseThen = PromiseThen; | 713 to.PromiseThen = PromiseThen; |
722 to.PromiseNextMicrotaskID = PromiseNextMicrotaskID; | 714 to.PromiseNextMicrotaskID = PromiseNextMicrotaskID; |
723 | 715 |
724 to.GlobalPromise = GlobalPromise; | 716 to.GlobalPromise = GlobalPromise; |
725 to.NewPromiseCapability = NewPromiseCapability; | 717 to.NewPromiseCapability = NewPromiseCapability; |
726 to.PerformPromiseThen = PerformPromiseThen; | 718 to.PerformPromiseThen = PerformPromiseThen; |
727 to.ResolvePromise = ResolvePromise; | 719 to.ResolvePromise = ResolvePromise; |
728 to.RejectPromise = RejectPromise; | 720 to.RejectPromise = RejectPromise; |
729 }); | 721 }); |
730 | 722 |
731 }) | 723 }) |
OLD | NEW |