| 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 |
| 11 // ------------------------------------------------------------------- | 11 // ------------------------------------------------------------------- |
| 12 // Imports | 12 // Imports |
| 13 | 13 |
| 14 var InternalArray = utils.InternalArray; | 14 var InternalArray = utils.InternalArray; |
| 15 var promiseAsyncStackIDSymbol = |
| 16 utils.ImportNow("promise_async_stack_id_symbol"); |
| 15 var promiseHandledBySymbol = | 17 var promiseHandledBySymbol = |
| 16 utils.ImportNow("promise_handled_by_symbol"); | 18 utils.ImportNow("promise_handled_by_symbol"); |
| 17 var promiseForwardingHandlerSymbol = | 19 var promiseForwardingHandlerSymbol = |
| 18 utils.ImportNow("promise_forwarding_handler_symbol"); | 20 utils.ImportNow("promise_forwarding_handler_symbol"); |
| 19 var promiseHasHandlerSymbol = | 21 var promiseHasHandlerSymbol = |
| 20 utils.ImportNow("promise_has_handler_symbol"); | 22 utils.ImportNow("promise_has_handler_symbol"); |
| 21 var promiseRejectReactionsSymbol = | 23 var promiseRejectReactionsSymbol = |
| 22 utils.ImportNow("promise_reject_reactions_symbol"); | 24 utils.ImportNow("promise_reject_reactions_symbol"); |
| 23 var promiseFulfillReactionsSymbol = | 25 var promiseFulfillReactionsSymbol = |
| 24 utils.ImportNow("promise_fulfill_reactions_symbol"); | 26 utils.ImportNow("promise_fulfill_reactions_symbol"); |
| 25 var promiseDeferredReactionsSymbol = | 27 var promiseDeferredReactionsSymbol = |
| 26 utils.ImportNow("promise_deferred_reactions_symbol"); | 28 utils.ImportNow("promise_deferred_reactions_symbol"); |
| 27 var promiseHandledHintSymbol = | 29 var promiseHandledHintSymbol = |
| 28 utils.ImportNow("promise_handled_hint_symbol"); | 30 utils.ImportNow("promise_handled_hint_symbol"); |
| 29 var promiseRawSymbol = utils.ImportNow("promise_raw_symbol"); | 31 var promiseRawSymbol = utils.ImportNow("promise_raw_symbol"); |
| 30 var promiseStateSymbol = utils.ImportNow("promise_state_symbol"); | 32 var promiseStateSymbol = utils.ImportNow("promise_state_symbol"); |
| 31 var promiseResultSymbol = utils.ImportNow("promise_result_symbol"); | 33 var promiseResultSymbol = utils.ImportNow("promise_result_symbol"); |
| 32 var SpeciesConstructor; | 34 var SpeciesConstructor; |
| 33 var speciesSymbol = utils.ImportNow("species_symbol"); | 35 var speciesSymbol = utils.ImportNow("species_symbol"); |
| 34 var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol"); | 36 var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol"); |
| 37 var ObjectHasOwnProperty; |
| 35 | 38 |
| 36 utils.Import(function(from) { | 39 utils.Import(function(from) { |
| 40 ObjectHasOwnProperty = from.ObjectHasOwnProperty; |
| 37 SpeciesConstructor = from.SpeciesConstructor; | 41 SpeciesConstructor = from.SpeciesConstructor; |
| 38 }); | 42 }); |
| 39 | 43 |
| 40 // ------------------------------------------------------------------- | 44 // ------------------------------------------------------------------- |
| 41 | 45 |
| 42 // [[PromiseState]] values: | 46 // [[PromiseState]] values: |
| 43 const kPending = 0; | 47 const kPending = 0; |
| 44 const kFulfilled = +1; | 48 const kFulfilled = +1; |
| 45 const kRejected = -1; | 49 const kRejected = -1; |
| 46 | 50 |
| 47 var lastMicrotaskId = 0; | 51 var lastMicrotaskId = 0; |
| 48 | 52 |
| 53 function PromiseNextMicrotaskID() { |
| 54 return ++lastMicrotaskId; |
| 55 } |
| 56 |
| 49 // ES#sec-createresolvingfunctions | 57 // ES#sec-createresolvingfunctions |
| 50 // CreateResolvingFunctions ( promise ) | 58 // CreateResolvingFunctions ( promise ) |
| 51 function CreateResolvingFunctions(promise, debugEvent) { | 59 function CreateResolvingFunctions(promise, debugEvent) { |
| 52 var alreadyResolved = false; | 60 var alreadyResolved = false; |
| 53 | 61 |
| 54 // ES#sec-promise-resolve-functions | 62 // ES#sec-promise-resolve-functions |
| 55 // Promise Resolve Functions | 63 // Promise Resolve Functions |
| 56 var resolve = value => { | 64 var resolve = value => { |
| 57 if (alreadyResolved === true) return; | 65 if (alreadyResolved === true) return; |
| 58 alreadyResolved = true; | 66 alreadyResolved = true; |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 PromiseHandle(value, tasks[i], tasks[i + 1]); | 188 PromiseHandle(value, tasks[i], tasks[i + 1]); |
| 181 } | 189 } |
| 182 } else { | 190 } else { |
| 183 PromiseHandle(value, tasks, deferreds); | 191 PromiseHandle(value, tasks, deferreds); |
| 184 } | 192 } |
| 185 if (instrumenting) { | 193 if (instrumenting) { |
| 186 %DebugAsyncTaskEvent({ type: "didHandle", id: id, name: name }); | 194 %DebugAsyncTaskEvent({ type: "didHandle", id: id, name: name }); |
| 187 } | 195 } |
| 188 }); | 196 }); |
| 189 if (instrumenting) { | 197 if (instrumenting) { |
| 190 id = ++lastMicrotaskId; | 198 // In an async function, reuse the existing stack related to the outer |
| 191 name = status === kFulfilled ? "Promise.resolve" : "Promise.reject"; | 199 // Promise. Otherwise, e.g. in a direct call to then, save a new stack. |
| 192 %DebugAsyncTaskEvent({ type: "enqueue", id: id, name: name }); | 200 // Promises with multiple reactions with one or more of them being async |
| 201 // functions will not get a good stack trace, as async functions require |
| 202 // different stacks from direct Promise use, but we save and restore a |
| 203 // stack once for all reactions. TODO(littledan): Improve this case. |
| 204 if (!IS_UNDEFINED(deferreds) && |
| 205 HAS_PRIVATE(deferreds.promise, promiseHandledBySymbol) && |
| 206 HAS_PRIVATE(GET_PRIVATE(deferreds.promise, promiseHandledBySymbol), |
| 207 promiseAsyncStackIDSymbol)) { |
| 208 id = GET_PRIVATE(GET_PRIVATE(deferreds.promise, promiseHandledBySymbol), |
| 209 promiseAsyncStackIDSymbol); |
| 210 name = "async function"; |
| 211 } else { |
| 212 id = PromiseNextMicrotaskID(); |
| 213 name = status === kFulfilled ? "Promise.resolve" : "Promise.reject"; |
| 214 %DebugAsyncTaskEvent({ type: "enqueue", id: id, name: name }); |
| 215 } |
| 193 } | 216 } |
| 194 } | 217 } |
| 195 | 218 |
| 196 function PromiseAttachCallbacks(promise, deferred, onResolve, onReject) { | 219 function PromiseAttachCallbacks(promise, deferred, onResolve, onReject) { |
| 197 var maybeResolveCallbacks = | 220 var maybeResolveCallbacks = |
| 198 GET_PRIVATE(promise, promiseFulfillReactionsSymbol); | 221 GET_PRIVATE(promise, promiseFulfillReactionsSymbol); |
| 199 if (IS_UNDEFINED(maybeResolveCallbacks)) { | 222 if (IS_UNDEFINED(maybeResolveCallbacks)) { |
| 200 SET_PRIVATE(promise, promiseFulfillReactionsSymbol, onResolve); | 223 SET_PRIVATE(promise, promiseFulfillReactionsSymbol, onResolve); |
| 201 SET_PRIVATE(promise, promiseRejectReactionsSymbol, onReject); | 224 SET_PRIVATE(promise, promiseRejectReactionsSymbol, onReject); |
| 202 SET_PRIVATE(promise, promiseDeferredReactionsSymbol, deferred); | 225 SET_PRIVATE(promise, promiseDeferredReactionsSymbol, deferred); |
| 203 } else if (!IS_ARRAY(maybeResolveCallbacks)) { | 226 } else if (!IS_ARRAY(maybeResolveCallbacks)) { |
| 204 var resolveCallbacks = new InternalArray(); | 227 var resolveCallbacks = new InternalArray(); |
| 205 var rejectCallbacks = new InternalArray(); | 228 var rejectCallbacks = new InternalArray(); |
| 206 var existingDeferred = GET_PRIVATE(promise, promiseDeferredReactionsSymbol); | 229 var existingDeferred = GET_PRIVATE(promise, promiseDeferredReactionsSymbol); |
| 207 | 230 |
| 208 resolveCallbacks.push( | 231 resolveCallbacks.push( |
| 209 maybeResolveCallbacks, existingDeferred, onResolve, deferred); | 232 maybeResolveCallbacks, existingDeferred, onResolve, deferred); |
| 210 rejectCallbacks.push(GET_PRIVATE(promise, promiseRejectReactionsSymbol), | 233 rejectCallbacks.push(GET_PRIVATE(promise, promiseRejectReactionsSymbol), |
| 211 existingDeferred, | 234 existingDeferred, |
| 212 onReject, | 235 onReject, |
| 213 deferred); | 236 deferred); |
| 214 | 237 |
| 215 SET_PRIVATE(promise, promiseFulfillReactionsSymbol, resolveCallbacks); | 238 SET_PRIVATE(promise, promiseFulfillReactionsSymbol, resolveCallbacks); |
| 216 SET_PRIVATE(promise, promiseRejectReactionsSymbol, rejectCallbacks); | 239 SET_PRIVATE(promise, promiseRejectReactionsSymbol, rejectCallbacks); |
| 240 SET_PRIVATE(promise, promiseDeferredReactionsSymbol, UNDEFINED); |
| 217 } else { | 241 } else { |
| 218 maybeResolveCallbacks.push(onResolve, deferred); | 242 maybeResolveCallbacks.push(onResolve, deferred); |
| 219 GET_PRIVATE(promise, promiseRejectReactionsSymbol).push(onReject, deferred); | 243 GET_PRIVATE(promise, promiseRejectReactionsSymbol).push(onReject, deferred); |
| 220 } | 244 } |
| 221 } | 245 } |
| 222 | 246 |
| 223 function PromiseIdResolveHandler(x) { return x; } | 247 function PromiseIdResolveHandler(x) { return x; } |
| 224 function PromiseIdRejectHandler(r) { %_ReThrow(r); } | 248 function PromiseIdRejectHandler(r) { %_ReThrow(r); } |
| 225 SET_PRIVATE(PromiseIdRejectHandler, promiseForwardingHandlerSymbol, true); | 249 SET_PRIVATE(PromiseIdRejectHandler, promiseForwardingHandlerSymbol, true); |
| 226 | 250 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 | 309 |
| 286 if (IS_CALLABLE(then)) { | 310 if (IS_CALLABLE(then)) { |
| 287 var callbacks = CreateResolvingFunctions(promise, false); | 311 var callbacks = CreateResolvingFunctions(promise, false); |
| 288 var id, before_debug_event, after_debug_event; | 312 var id, before_debug_event, after_debug_event; |
| 289 var instrumenting = DEBUG_IS_ACTIVE; | 313 var instrumenting = DEBUG_IS_ACTIVE; |
| 290 if (instrumenting) { | 314 if (instrumenting) { |
| 291 if (IsPromise(resolution)) { | 315 if (IsPromise(resolution)) { |
| 292 // Mark the dependency of the new promise on the resolution | 316 // Mark the dependency of the new promise on the resolution |
| 293 SET_PRIVATE(resolution, promiseHandledBySymbol, promise); | 317 SET_PRIVATE(resolution, promiseHandledBySymbol, promise); |
| 294 } | 318 } |
| 295 id = ++lastMicrotaskId; | 319 id = PromiseNextMicrotaskID(); |
| 296 before_debug_event = { | 320 before_debug_event = { |
| 297 type: "willHandle", | 321 type: "willHandle", |
| 298 id: id, | 322 id: id, |
| 299 name: "PromiseResolveThenableJob" | 323 name: "PromiseResolveThenableJob" |
| 300 }; | 324 }; |
| 301 after_debug_event = { | 325 after_debug_event = { |
| 302 type: "didHandle", | 326 type: "didHandle", |
| 303 id: id, | 327 id: id, |
| 304 name: "PromiseResolveThenableJob" | 328 name: "PromiseResolveThenableJob" |
| 305 }; | 329 }; |
| (...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 664 utils.InstallFunctions(extrasUtils, 0, [ | 688 utils.InstallFunctions(extrasUtils, 0, [ |
| 665 "createPromise", PromiseCreate, | 689 "createPromise", PromiseCreate, |
| 666 "resolvePromise", ResolvePromise, | 690 "resolvePromise", ResolvePromise, |
| 667 "rejectPromise", DoRejectPromise | 691 "rejectPromise", DoRejectPromise |
| 668 ]); | 692 ]); |
| 669 | 693 |
| 670 utils.Export(function(to) { | 694 utils.Export(function(to) { |
| 671 to.IsPromise = IsPromise; | 695 to.IsPromise = IsPromise; |
| 672 to.PromiseCreate = PromiseCreate; | 696 to.PromiseCreate = PromiseCreate; |
| 673 to.PromiseThen = PromiseThen; | 697 to.PromiseThen = PromiseThen; |
| 698 to.PromiseNextMicrotaskID = PromiseNextMicrotaskID; |
| 674 | 699 |
| 675 to.GlobalPromise = GlobalPromise; | 700 to.GlobalPromise = GlobalPromise; |
| 676 to.NewPromiseCapability = NewPromiseCapability; | 701 to.NewPromiseCapability = NewPromiseCapability; |
| 677 to.PerformPromiseThen = PerformPromiseThen; | 702 to.PerformPromiseThen = PerformPromiseThen; |
| 678 to.ResolvePromise = ResolvePromise; | 703 to.ResolvePromise = ResolvePromise; |
| 679 to.RejectPromise = RejectPromise; | 704 to.RejectPromise = RejectPromise; |
| 680 }); | 705 }); |
| 681 | 706 |
| 682 }) | 707 }) |
| OLD | NEW |