From 01ebabde5bbb8213f1004b642ef1689f92ce92b2 Mon Sep 17 00:00:00 2001 From: Moonchild Date: Mon, 19 May 2025 22:50:01 +0200 Subject: [PATCH] No issue - Fix promise combinator function state. --- js/src/builtin/Promise.cpp | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/js/src/builtin/Promise.cpp b/js/src/builtin/Promise.cpp index 7d4c232f2e..9660a758a1 100644 --- a/js/src/builtin/Promise.cpp +++ b/js/src/builtin/Promise.cpp @@ -85,7 +85,7 @@ enum RejectFunctionSlots { enum PromiseCombinatorElementFunctionSlots { PromiseCombinatorElementFunctionSlot_Data = 0, - PromiseCombinatorElementFunctionSlot_ElementIndex, + PromiseCombinatorElementFunctionSlot_ElementIndexOrResolveFunc, }; enum ReactionJobSlots { @@ -2351,7 +2351,8 @@ PerformPromiseThenWithoutSettleHandlers(JSContext* cx, Handle pr static JSFunction* NewPromiseCombinatorElementFunction( JSContext* cx, Native native, - Handle dataHolder, uint32_t index); + Handle dataHolder, uint32_t index, + Handle maybeResolveFunc); static bool PromiseAllResolveElementFunction(JSContext* cx, unsigned argc, Value* vp); @@ -2430,7 +2431,7 @@ js::GetWaitForAllPromise(JSContext* cx, const JS::AutoObjectVector& promises) // Steps j-o. JSFunction* resolveFunc = NewPromiseCombinatorElementFunction( - cx, PromiseAllResolveElementFunction, dataHolder, index); + cx, PromiseAllResolveElementFunction, dataHolder, index, UndefinedHandleValue); if (!resolveFunc) return nullptr; @@ -2888,7 +2889,7 @@ GetPromiseCombinatorElements(JSContext* cx, Handle static JSFunction* NewPromiseCombinatorElementFunction(JSContext* cx, Native native, Handle dataHolder, - uint32_t index) + uint32_t index, Handle maybeResolveFunc) { JSFunction* fn = NewNativeFunction(cx, native, 1, nullptr, gc::AllocKind::FUNCTION_EXTENDED, GenericObject); @@ -2898,8 +2899,13 @@ NewPromiseCombinatorElementFunction(JSContext* cx, Native native, fn->setExtendedSlot(PromiseCombinatorElementFunctionSlot_Data, ObjectValue(*dataHolder)); - fn->setExtendedSlot(PromiseCombinatorElementFunctionSlot_ElementIndex, - Int32Value(index)); + if (maybeResolveFunc.isObject()) { + fn->setExtendedSlot(PromiseCombinatorElementFunctionSlot_ElementIndexOrResolveFunc, + maybeResolveFunc); + } else { + fn->setExtendedSlot(PromiseCombinatorElementFunctionSlot_ElementIndexOrResolveFunc, + Int32Value(index)); + } return fn; } @@ -2917,6 +2923,13 @@ PromiseCombinatorElementFunctionAlreadyCalled(const CallArgs& args, // Step 1. JSFunction* fn = &args.callee().as(); + size_t indexOrResolveFuncSlot = PromiseCombinatorElementFunctionSlot_ElementIndexOrResolveFunc; + if (fn->getExtendedSlot(indexOrResolveFuncSlot).isObject()) { + Value slotVal = fn->getExtendedSlot(indexOrResolveFuncSlot); + fn = &slotVal.toObject().as(); + } + MOZ_RELEASE_ASSERT(fn->getExtendedSlot(indexOrResolveFuncSlot).isInt32()); + // Step 2. const Value& dataVal = fn->getExtendedSlot(PromiseCombinatorElementFunctionSlot_Data); @@ -2936,9 +2949,7 @@ PromiseCombinatorElementFunctionAlreadyCalled(const CallArgs& args, UndefinedValue()); // Step 5. - int32_t idx = - fn->getExtendedSlot(PromiseCombinatorElementFunctionSlot_ElementIndex) - .toInt32(); + int32_t idx = fn->getExtendedSlot(indexOrResolveFuncSlot).toInt32(); MOZ_ASSERT(idx >= 0); *index = uint32_t(idx); @@ -2988,7 +2999,7 @@ PerformPromiseAll(JSContext *cx, PromiseForOfIterator& iterator, HandleObject C, // Steps 8.j-p. JSFunction* resolveFunc = NewPromiseCombinatorElementFunction(cx, - PromiseAllResolveElementFunction, dataHolder, index); + PromiseAllResolveElementFunction, dataHolder, index, UndefinedHandleValue); if (!resolveFunc) return false; @@ -3187,7 +3198,7 @@ static MOZ_MUST_USE bool PerformPromiseAllSettled( // Steps 8.j-q. JSFunction* resolveFunc = NewPromiseCombinatorElementFunction( - cx, PromiseAllSettledResolveElementFunction, dataHolder, index); + cx, PromiseAllSettledResolveElementFunction, dataHolder, index, UndefinedHandleValue); if (!resolveFunc) { return false; } @@ -3195,7 +3206,7 @@ static MOZ_MUST_USE bool PerformPromiseAllSettled( // Steps 8.r-x. JSFunction* rejectFunc = NewPromiseCombinatorElementFunction( - cx, PromiseAllSettledRejectElementFunction, dataHolder, index); + cx, PromiseAllSettledRejectElementFunction, dataHolder, index, resolveFunVal); if (!rejectFunc) { return false; } @@ -3391,7 +3402,7 @@ PerformPromiseAny(JSContext* cx, PromiseForOfIterator& iterator, HandleObject C, // Steps 8.j-p. JSFunction* rejectFunc = NewPromiseCombinatorElementFunction( - cx, PromiseAnyRejectElementFunction, dataHolder, index); + cx, PromiseAnyRejectElementFunction, dataHolder, index, UndefinedHandleValue); if (!rejectFunc) { return false; }