Index: src/js/promise.js |
diff --git a/src/js/promise.js b/src/js/promise.js |
index 75ec6e1c57683f56c9107e5f8754590b532c46d3..93758caf9513b4bb3db8889ef6cf44cd0d750ca8 100644 |
--- a/src/js/promise.js |
+++ b/src/js/promise.js |
@@ -44,10 +44,9 @@ |
// ------------------------------------------------------------------- |
// [[PromiseState]] values: |
-// These values should be kept in sync with PromiseStatus in globals.h |
const kPending = 0; |
const kFulfilled = +1; |
-const kRejected = +2; |
+const kRejected = -1; |
// ES#sec-createresolvingfunctions |
// CreateResolvingFunctions ( promise ) |
@@ -67,8 +66,7 @@ |
var reject = reason => { |
if (alreadyResolved === true) return; |
alreadyResolved = true; |
- %PromiseReject(promise, reason, debugEvent); |
- PromiseSet(promise, kRejected, reason); |
+ RejectPromise(promise, reason, debugEvent); |
}; |
return { |
@@ -159,8 +157,7 @@ |
if (IS_UNDEFINED(deferred.reject)) { |
// Pass false for debugEvent so .then chaining does not trigger |
// redundant ExceptionEvents. |
- %PromiseReject(deferred.promise, exception, false); |
- PromiseSet(deferred.promise, kRejected, exception); |
+ RejectPromise(deferred.promise, exception, false); |
} else { |
%_Call(deferred.reject, UNDEFINED, exception); |
} |
@@ -246,19 +243,16 @@ |
// Promise Resolve Functions, steps 6-13 |
function ResolvePromise(promise, resolution) { |
if (resolution === promise) { |
- var exception = %make_type_error(kPromiseCyclic, resolution); |
- %PromiseReject(promise, exception, true); |
- PromiseSet(promise, kRejected, exception); |
- return; |
+ return RejectPromise(promise, |
+ %make_type_error(kPromiseCyclic, resolution), |
+ true); |
} |
if (IS_RECEIVER(resolution)) { |
// 25.4.1.3.2 steps 8-12 |
try { |
var then = resolution.then; |
} catch (e) { |
- %PromiseReject(promise, e, true); |
- PromiseSet(promise, kRejected, e); |
- return; |
+ return RejectPromise(promise, e, true); |
} |
// Resolution is a native promise and if it's already resolved or |
@@ -283,8 +277,7 @@ |
%PromiseRevokeReject(resolution); |
} |
// Don't cause a debug event as this case is forwarding a rejection |
- %PromiseReject(promise, thenableValue, false); |
- PromiseSet(promise, kRejected, thenableValue); |
+ RejectPromise(promise, thenableValue, false); |
SET_PRIVATE(resolution, promiseHasHandlerSymbol, true); |
return; |
} |
@@ -306,16 +299,26 @@ |
PromiseSet(promise, kFulfilled, resolution); |
} |
-// Only used by async-await.js |
-function RejectPromise(promise, reason) { |
- %PromiseReject(promise, reason, false); |
+// ES#sec-rejectpromise |
+// RejectPromise ( promise, reason ) |
+function RejectPromise(promise, reason, debugEvent) { |
+ // Call runtime for callbacks to the debugger or for unhandled reject. |
+ // The debugEvent parameter sets whether a debug ExceptionEvent should |
+ // be triggered. It should be set to false when forwarding a rejection |
+ // rather than creating a new one. |
+ // This check is redundant with checks in the runtime, but it may help |
+ // avoid unnecessary runtime calls. |
+ if ((debugEvent && DEBUG_IS_ACTIVE) || |
+ !HAS_DEFINED_PRIVATE(promise, promiseHasHandlerSymbol)) { |
+ %PromiseRejectEvent(promise, reason, debugEvent); |
+ } |
+ %PromiseFulfill(promise, kRejected, reason, promiseRejectReactionsSymbol) |
PromiseSet(promise, kRejected, reason); |
} |
// Export to bindings |
function DoRejectPromise(promise, reason) { |
- %PromiseReject(promise, reason, true); |
- PromiseSet(promise, kRejected, reason); |
+ return RejectPromise(promise, reason, true); |
} |
// ES#sec-newpromisecapability |