| Index: src/js/promise.js
|
| diff --git a/src/js/promise.js b/src/js/promise.js
|
| index 7d192371caeb08499fd201f6cba9cc3262c82fa8..24ca74b531c36d5af8313e0b9ea510ead55d658b 100644
|
| --- a/src/js/promise.js
|
| +++ b/src/js/promise.js
|
| @@ -12,6 +12,8 @@
|
| // Imports
|
|
|
| var InternalArray = utils.InternalArray;
|
| +var promiseAsyncStackIDSymbol =
|
| + utils.ImportNow("promise_async_stack_id_symbol");
|
| var promiseHandledBySymbol =
|
| utils.ImportNow("promise_handled_by_symbol");
|
| var promiseForwardingHandlerSymbol =
|
| @@ -32,8 +34,10 @@ var promiseResultSymbol = utils.ImportNow("promise_result_symbol");
|
| var SpeciesConstructor;
|
| var speciesSymbol = utils.ImportNow("species_symbol");
|
| var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
|
| +var ObjectHasOwnProperty;
|
|
|
| utils.Import(function(from) {
|
| + ObjectHasOwnProperty = from.ObjectHasOwnProperty;
|
| SpeciesConstructor = from.SpeciesConstructor;
|
| });
|
|
|
| @@ -46,6 +50,10 @@ const kRejected = -1;
|
|
|
| var lastMicrotaskId = 0;
|
|
|
| +function PromiseNextMicrotaskID() {
|
| + return ++lastMicrotaskId;
|
| +}
|
| +
|
| // ES#sec-createresolvingfunctions
|
| // CreateResolvingFunctions ( promise )
|
| function CreateResolvingFunctions(promise, debugEvent) {
|
| @@ -187,9 +195,24 @@ function PromiseEnqueue(value, tasks, deferreds, status) {
|
| }
|
| });
|
| if (instrumenting) {
|
| - id = ++lastMicrotaskId;
|
| - name = status === kFulfilled ? "Promise.resolve" : "Promise.reject";
|
| - %DebugAsyncTaskEvent({ type: "enqueue", id: id, name: name });
|
| + // In an async function, reuse the existing stack related to the outer
|
| + // Promise. Otherwise, e.g. in a direct call to then, save a new stack.
|
| + // Promises with multiple reactions with one or more of them being async
|
| + // functions will not get a good stack trace, as async functions require
|
| + // different stacks from direct Promise use, but we save and restore a
|
| + // stack once for all reactions. TODO(littledan): Improve this case.
|
| + if (!IS_UNDEFINED(deferreds) &&
|
| + HAS_PRIVATE(deferreds.promise, promiseHandledBySymbol) &&
|
| + HAS_PRIVATE(GET_PRIVATE(deferreds.promise, promiseHandledBySymbol),
|
| + promiseAsyncStackIDSymbol)) {
|
| + id = GET_PRIVATE(GET_PRIVATE(deferreds.promise, promiseHandledBySymbol),
|
| + promiseAsyncStackIDSymbol);
|
| + name = "async function";
|
| + } else {
|
| + id = PromiseNextMicrotaskID();
|
| + name = status === kFulfilled ? "Promise.resolve" : "Promise.reject";
|
| + %DebugAsyncTaskEvent({ type: "enqueue", id: id, name: name });
|
| + }
|
| }
|
| }
|
|
|
| @@ -214,6 +237,7 @@ function PromiseAttachCallbacks(promise, deferred, onResolve, onReject) {
|
|
|
| SET_PRIVATE(promise, promiseFulfillReactionsSymbol, resolveCallbacks);
|
| SET_PRIVATE(promise, promiseRejectReactionsSymbol, rejectCallbacks);
|
| + SET_PRIVATE(promise, promiseDeferredReactionsSymbol, UNDEFINED);
|
| } else {
|
| maybeResolveCallbacks.push(onResolve, deferred);
|
| GET_PRIVATE(promise, promiseRejectReactionsSymbol).push(onReject, deferred);
|
| @@ -292,7 +316,7 @@ function ResolvePromise(promise, resolution) {
|
| // Mark the dependency of the new promise on the resolution
|
| SET_PRIVATE(resolution, promiseHandledBySymbol, promise);
|
| }
|
| - id = ++lastMicrotaskId;
|
| + id = PromiseNextMicrotaskID();
|
| before_debug_event = {
|
| type: "willHandle",
|
| id: id,
|
| @@ -671,6 +695,7 @@ utils.Export(function(to) {
|
| to.IsPromise = IsPromise;
|
| to.PromiseCreate = PromiseCreate;
|
| to.PromiseThen = PromiseThen;
|
| + to.PromiseNextMicrotaskID = PromiseNextMicrotaskID;
|
|
|
| to.GlobalPromise = GlobalPromise;
|
| to.NewPromiseCapability = NewPromiseCapability;
|
|
|