diff --git a/js/src/builtin/Promise.cpp b/js/src/builtin/Promise.cpp index 187a12b7d4b1..561c5dd5fba4 100644 --- a/js/src/builtin/Promise.cpp +++ b/js/src/builtin/Promise.cpp @@ -543,14 +543,14 @@ const Class PromiseReactionRecord::class_ = { static void AddPromiseFlags(PromiseObject& promise, int32_t flag) { - int32_t flags = promise.getFixedSlot(PromiseSlot_Flags).toInt32(); + int32_t flags = promise.flags(); promise.setFixedSlot(PromiseSlot_Flags, Int32Value(flags | flag)); } static bool PromiseHasAnyFlag(PromiseObject& promise, int32_t flag) { - return promise.getFixedSlot(PromiseSlot_Flags).toInt32() & flag; + return promise.flags() & flag; } static bool ResolvePromiseFunction(JSContext* cx, unsigned argc, Value* vp); @@ -926,7 +926,7 @@ ResolvePromise(JSContext* cx, Handle promise, HandleValue valueO // instead of getting the right list of reactions, we determine the // resolution type to retrieve the right information from the // reaction records. - RootedValue reactionsVal(cx, promise->getFixedSlot(PromiseSlot_ReactionsOrResult)); + RootedValue reactionsVal(cx, promise->reactions()); // Steps 3-5. // The same slot is used for the reactions list and the result, so setting @@ -934,7 +934,7 @@ ResolvePromise(JSContext* cx, Handle promise, HandleValue valueO promise->setFixedSlot(PromiseSlot_ReactionsOrResult, valueOrReason); // Step 6. - int32_t flags = promise->getFixedSlot(PromiseSlot_Flags).toInt32(); + int32_t flags = promise->flags(); flags |= PROMISE_FLAG_RESOLVED; if (state == JS::PromiseState::Fulfilled) flags |= PROMISE_FLAG_FULFILLED; @@ -998,8 +998,7 @@ CreatePromiseObjectWithoutResolutionFunctions(JSContext* cx) if (!promise) return nullptr; - AddPromiseFlags(*promise, PROMISE_FLAG_DEFAULT_RESOLVE_FUNCTION | - PROMISE_FLAG_DEFAULT_REJECT_FUNCTION); + AddPromiseFlags(*promise, PROMISE_FLAG_DEFAULT_RESOLVING_FUNCTIONS); return promise; } @@ -2195,14 +2194,12 @@ RunResolutionFunction(JSContext *cx, HandleObject resolutionFun, HandleValue res if (promise->state() != JS::PromiseState::Pending) return true; - if (mode == ResolveMode) { - if (!PromiseHasAnyFlag(*promise, PROMISE_FLAG_DEFAULT_RESOLVE_FUNCTION)) - return true; - return ResolvePromiseInternal(cx, promise, result); - } - - if (!PromiseHasAnyFlag(*promise, PROMISE_FLAG_DEFAULT_REJECT_FUNCTION)) + if (!PromiseHasAnyFlag(*promise, PROMISE_FLAG_DEFAULT_RESOLVING_FUNCTIONS)) return true; + + if (mode == ResolveMode) + return ResolvePromiseInternal(cx, promise, result); + return RejectMaybeWrappedPromise(cx, promiseObj, result); } @@ -3555,7 +3552,7 @@ PerformPromiseThenWithReaction(JSContext* cx, Handle promise, Handle reaction) { JS::PromiseState state = promise->state(); - int32_t flags = promise->getFixedSlot(PromiseSlot_Flags).toInt32(); + int32_t flags = promise->flags(); if (state == JS::PromiseState::Pending) { // Steps 5,6 (reordered). // Instead of creating separate reaction records for fulfillment and @@ -3571,7 +3568,7 @@ PerformPromiseThenWithReaction(JSContext* cx, Handle promise, MOZ_ASSERT_IF(state != JS::PromiseState::Fulfilled, state == JS::PromiseState::Rejected); // Step 8.a. / 9.b. - RootedValue valueOrReason(cx, promise->getFixedSlot(PromiseSlot_ReactionsOrResult)); + RootedValue valueOrReason(cx, promise->valueOrReason()); // We might be operating on a promise from another compartment. In // that case, we need to wrap the result/reason value before using it. @@ -3728,7 +3725,7 @@ AddPromiseReaction(JSContext* cx, Handle promise, } // 25.4.5.3.1 steps 7.a,b. - RootedValue reactionsVal(cx, promise->getFixedSlot(PromiseSlot_ReactionsOrResult)); + RootedValue reactionsVal(cx, promise->reactions()); RootedNativeObject reactions(cx); if (reactionsVal.isUndefined()) { @@ -3825,7 +3822,7 @@ PromiseObject::dependentPromises(JSContext* cx, MutableHandle> v if (state() != JS::PromiseState::Pending) return true; - RootedValue reactionsVal(cx, getFixedSlot(PromiseSlot_ReactionsOrResult)); + RootedValue reactionsVal(cx, reactions()); // If no reactions are pending, we don't have list and are done. if (reactionsVal.isNullOrUndefined()) @@ -3875,7 +3872,7 @@ PromiseObject::resolve(JSContext* cx, Handle promise, HandleValu if (promise->state() != JS::PromiseState::Pending) return true; - if (PromiseHasAnyFlag(*promise, PROMISE_FLAG_DEFAULT_RESOLVE_FUNCTION)) + if (PromiseHasAnyFlag(*promise, PROMISE_FLAG_DEFAULT_RESOLVING_FUNCTIONS)) return ResolvePromiseInternal(cx, promise, resolutionValue); RootedObject resolveFun(cx, GetResolveFunctionFromPromise(promise)); @@ -3904,7 +3901,7 @@ PromiseObject::reject(JSContext* cx, Handle promise, HandleValue if (promise->state() != JS::PromiseState::Pending) return true; - if (PromiseHasAnyFlag(*promise, PROMISE_FLAG_DEFAULT_REJECT_FUNCTION)) + if (PromiseHasAnyFlag(*promise, PROMISE_FLAG_DEFAULT_RESOLVING_FUNCTIONS)) return ResolvePromise(cx, promise, rejectionValue, JS::PromiseState::Rejected); RootedValue funVal(cx, promise->getFixedSlot(PromiseSlot_RejectFunction)); diff --git a/js/src/builtin/Promise.h b/js/src/builtin/Promise.h index 26a9437c7477..55328cb7361f 100644 --- a/js/src/builtin/Promise.h +++ b/js/src/builtin/Promise.h @@ -26,9 +26,8 @@ enum PromiseSlots { #define PROMISE_FLAG_RESOLVED 0x1 #define PROMISE_FLAG_FULFILLED 0x2 #define PROMISE_FLAG_HANDLED 0x4 -#define PROMISE_FLAG_DEFAULT_RESOLVE_FUNCTION 0x08 -#define PROMISE_FLAG_DEFAULT_REJECT_FUNCTION 0x10 -#define PROMISE_FLAG_ASYNC 0x20 +#define PROMISE_FLAG_DEFAULT_RESOLVING_FUNCTIONS 0x08 +#define PROMISE_FLAG_ASYNC 0x10 class AutoSetNewObjectMetadata; @@ -46,8 +45,11 @@ class PromiseObject : public NativeObject static JSObject* unforgeableResolve(JSContext* cx, HandleValue value); static JSObject* unforgeableReject(JSContext* cx, HandleValue value); + int32_t flags() { + return getFixedSlot(PromiseSlot_Flags).toInt32(); + } JS::PromiseState state() { - int32_t flags = getFixedSlot(PromiseSlot_Flags).toInt32(); + int32_t flags = this->flags(); if (!(flags & PROMISE_FLAG_RESOLVED)) { MOZ_ASSERT(!(flags & PROMISE_FLAG_FULFILLED)); return JS::PromiseState::Pending; @@ -56,6 +58,10 @@ class PromiseObject : public NativeObject return JS::PromiseState::Fulfilled; return JS::PromiseState::Rejected; } + Value reactions() { + MOZ_ASSERT(state() == JS::PromiseState::Pending); + return getFixedSlot(PromiseSlot_ReactionsOrResult); + } Value value() { MOZ_ASSERT(state() == JS::PromiseState::Fulfilled); return getFixedSlot(PromiseSlot_ReactionsOrResult); @@ -64,6 +70,10 @@ class PromiseObject : public NativeObject MOZ_ASSERT(state() == JS::PromiseState::Rejected); return getFixedSlot(PromiseSlot_ReactionsOrResult); } + Value valueOrReason() { + MOZ_ASSERT(state() != JS::PromiseState::Pending); + return getFixedSlot(PromiseSlot_ReactionsOrResult); + } static MOZ_MUST_USE bool resolve(JSContext* cx, Handle promise, HandleValue resolutionValue); @@ -85,7 +95,7 @@ class PromiseObject : public NativeObject uint64_t getID(); bool isUnhandled() { MOZ_ASSERT(state() == JS::PromiseState::Rejected); - return !(getFixedSlot(PromiseSlot_Flags).toInt32() & PROMISE_FLAG_HANDLED); + return !(flags() & PROMISE_FLAG_HANDLED); } }; diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index b75ad3b1d2b5..399df110d39d 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -2099,7 +2099,7 @@ SettlePromiseNow(JSContext* cx, unsigned argc, Value* vp) return false; } - int32_t flags = promise->getFixedSlot(PromiseSlot_Flags).toInt32(); + int32_t flags = promise->flags(); promise->setFixedSlot(PromiseSlot_Flags, Int32Value(flags | PROMISE_FLAG_RESOLVED | PROMISE_FLAG_FULFILLED)); promise->setFixedSlot(PromiseSlot_ReactionsOrResult, UndefinedValue());