| Index: src/js/promise.js
|
| diff --git a/src/js/promise.js b/src/js/promise.js
|
| index 96afbc2dfbf2839d2a9dbdc87b206c284bd0b3e9..e020028c244f8f0d45bf429316ae916757012de5 100644
|
| --- a/src/js/promise.js
|
| +++ b/src/js/promise.js
|
| @@ -12,10 +12,10 @@
|
| // Imports
|
|
|
| var InternalArray = utils.InternalArray;
|
| -var promiseHandledBySymbol =
|
| - utils.ImportNow("promise_handled_by_symbol");
|
| -var promiseForwardingHandlerSymbol =
|
| - utils.ImportNow("promise_forwarding_handler_symbol");
|
| +var promiseAwaitHandlerSymbol =
|
| + utils.ImportNow("promise_await_handler_symbol");
|
| +var promiseCombinedDeferredSymbol =
|
| + utils.ImportNow("promise_combined_deferred_symbol");
|
| var promiseHasHandlerSymbol =
|
| utils.ImportNow("promise_has_handler_symbol");
|
| var promiseRejectReactionsSymbol =
|
| @@ -222,7 +222,6 @@
|
|
|
| function PromiseIdResolveHandler(x) { return x; }
|
| function PromiseIdRejectHandler(r) { %_ReThrow(r); }
|
| -SET_PRIVATE(PromiseIdRejectHandler, promiseForwardingHandlerSymbol, true);
|
|
|
| function PromiseNopResolver() {}
|
|
|
| @@ -237,7 +236,7 @@
|
| }
|
|
|
| function PromiseCreate() {
|
| - return new GlobalPromise(PromiseNopResolver);
|
| + return new GlobalPromise(PromiseNopResolver)
|
| }
|
|
|
| // ES#sec-promise-resolve-functions
|
| @@ -288,10 +287,6 @@
|
| var id;
|
| var name = "PromiseResolveThenableJob";
|
| var instrumenting = DEBUG_IS_ACTIVE;
|
| - if (instrumenting && IsPromise(resolution)) {
|
| - // Mark the dependency of the new promise on the resolution
|
| - SET_PRIVATE(resolution, promiseHandledBySymbol, promise);
|
| - }
|
| %EnqueueMicrotask(function() {
|
| if (instrumenting) {
|
| %DebugAsyncTaskEvent({ type: "willHandle", id: id, name: name });
|
| @@ -315,8 +310,7 @@
|
| return;
|
| }
|
| }
|
| - FulfillPromise(promise, kFulfilled, resolution,
|
| - promiseFulfillReactionsSymbol);
|
| + FulfillPromise(promise, kFulfilled, resolution, promiseFulfillReactionsSymbol);
|
| }
|
|
|
| // ES#sec-rejectpromise
|
| @@ -478,10 +472,6 @@
|
| var resolutions = new InternalArray();
|
| var count;
|
|
|
| - // For catch prediction, don't treat the .then calls as handling it;
|
| - // instead, recurse outwards.
|
| - SET_PRIVATE(deferred.reject, promiseForwardingHandlerSymbol, true);
|
| -
|
| function CreateResolveElementFunction(index, values, promiseCapability) {
|
| var alreadyCalled = false;
|
| return (x) => {
|
| @@ -502,14 +492,10 @@
|
| for (var value of iterable) {
|
| var nextPromise = this.resolve(value);
|
| ++count;
|
| - var throwawayPromise = nextPromise.then(
|
| + nextPromise.then(
|
| CreateResolveElementFunction(i, resolutions, deferred),
|
| deferred.reject);
|
| - // For catch prediction, mark that rejections here are semantically
|
| - // handled by the combined Promise.
|
| - if (IsPromise(throwawayPromise)) {
|
| - SET_PRIVATE(throwawayPromise, promiseHandledBySymbol, deferred.promise);
|
| - }
|
| + SET_PRIVATE(deferred.reject, promiseCombinedDeferredSymbol, deferred);
|
| ++i;
|
| }
|
|
|
| @@ -536,20 +522,10 @@
|
| // false debugEvent so that forwarding the rejection through race does not
|
| // trigger redundant ExceptionEvents
|
| var deferred = NewPromiseCapability(this, false);
|
| -
|
| - // For catch prediction, don't treat the .then calls as handling it;
|
| - // instead, recurse outwards.
|
| - SET_PRIVATE(deferred.reject, promiseForwardingHandlerSymbol, true);
|
| -
|
| try {
|
| for (var value of iterable) {
|
| - var throwawayPromise = this.resolve(value).then(deferred.resolve,
|
| - deferred.reject);
|
| - // For catch prediction, mark that rejections here are semantically
|
| - // handled by the combined Promise.
|
| - if (IsPromise(throwawayPromise)) {
|
| - SET_PRIVATE(throwawayPromise, promiseHandledBySymbol, deferred.promise);
|
| - }
|
| + this.resolve(value).then(deferred.resolve, deferred.reject);
|
| + SET_PRIVATE(deferred.reject, promiseCombinedDeferredSymbol, deferred);
|
| }
|
| } catch (e) {
|
| deferred.reject(e)
|
| @@ -561,18 +537,19 @@
|
| // Utility for debugger
|
|
|
| function PromiseHasUserDefinedRejectHandlerCheck(handler, deferred) {
|
| - // Recurse to the forwarding Promise, if any. This may be due to
|
| - // - await reaction forwarding to the throwaway Promise, which has
|
| - // a dependency edge to the outer Promise.
|
| - // - PromiseIdResolveHandler forwarding to the output of .then
|
| - // - Promise.all/Promise.race forwarding to a throwaway Promise, which
|
| - // has a dependency edge to the generated outer Promise.
|
| - if (GET_PRIVATE(handler, promiseForwardingHandlerSymbol)) {
|
| - return PromiseHasUserDefinedRejectHandlerRecursive(deferred.promise);
|
| - }
|
| -
|
| - // Otherwise, this is a real reject handler for the Promise
|
| - return true;
|
| + // If this handler was installed by async/await, it does not indicate
|
| + // that there is a user-defined reject handler.
|
| + if (GET_PRIVATE(handler, promiseAwaitHandlerSymbol)) return false;
|
| + if (handler !== PromiseIdRejectHandler) {
|
| + var combinedDeferred = GET_PRIVATE(handler, promiseCombinedDeferredSymbol);
|
| + if (IS_UNDEFINED(combinedDeferred)) return true;
|
| + if (PromiseHasUserDefinedRejectHandlerRecursive(combinedDeferred.promise)) {
|
| + return true;
|
| + }
|
| + } else if (PromiseHasUserDefinedRejectHandlerRecursive(deferred.promise)) {
|
| + return true;
|
| + }
|
| + return false;
|
| }
|
|
|
| function PromiseHasUserDefinedRejectHandlerRecursive(promise) {
|
| @@ -580,17 +557,6 @@
|
| // in an async function, then it has a user-defined reject handler.
|
| if (GET_PRIVATE(promise, promiseHandledHintSymbol)) return true;
|
|
|
| - // If this Promise is subsumed by another Promise (a Promise resolved
|
| - // with another Promise, or an intermediate, hidden, throwaway Promise
|
| - // within async/await), then recurse on the outer Promise.
|
| - // In this case, the dependency is one possible way that the Promise
|
| - // could be resolved, so it does not subsume the other following cases.
|
| - var outerPromise = GET_PRIVATE(promise, promiseHandledBySymbol);
|
| - if (outerPromise &&
|
| - PromiseHasUserDefinedRejectHandlerRecursive(outerPromise)) {
|
| - return true;
|
| - }
|
| -
|
| var queue = GET_PRIVATE(promise, promiseRejectReactionsSymbol);
|
| var deferreds = GET_PRIVATE(promise, promiseDeferredReactionsSymbol);
|
|
|
| @@ -611,8 +577,6 @@
|
| // Return whether the promise will be handled by a user-defined reject
|
| // handler somewhere down the promise chain. For this, we do a depth-first
|
| // search for a reject handler that's not the default PromiseIdRejectHandler.
|
| -// This function also traverses dependencies of one Promise on another,
|
| -// set up through async/await and Promises resolved with Promises.
|
| function PromiseHasUserDefinedRejectHandler() {
|
| return PromiseHasUserDefinedRejectHandlerRecursive(this);
|
| };
|
|
|