No issue - Fix promise combinator function state.

This commit is contained in:
Moonchild 2025-05-19 22:50:01 +02:00 • committed by roytam1
commit 01ebabde5b

View file

@ -85,7 +85,7 @@ enum RejectFunctionSlots {
enum PromiseCombinatorElementFunctionSlots { enum PromiseCombinatorElementFunctionSlots {
PromiseCombinatorElementFunctionSlot_Data = 0, PromiseCombinatorElementFunctionSlot_Data = 0,
PromiseCombinatorElementFunctionSlot_ElementIndex, PromiseCombinatorElementFunctionSlot_ElementIndexOrResolveFunc,
}; };
enum ReactionJobSlots { enum ReactionJobSlots {
@ -2351,7 +2351,8 @@ PerformPromiseThenWithoutSettleHandlers(JSContext* cx, Handle<PromiseObject*> pr
static JSFunction* NewPromiseCombinatorElementFunction( static JSFunction* NewPromiseCombinatorElementFunction(
JSContext* cx, Native native, JSContext* cx, Native native,
Handle<PromiseCombinatorDataHolder*> dataHolder, uint32_t index); Handle<PromiseCombinatorDataHolder*> dataHolder, uint32_t index,
Handle<Value> maybeResolveFunc);
static bool PromiseAllResolveElementFunction(JSContext* cx, unsigned argc, Value* vp); static bool PromiseAllResolveElementFunction(JSContext* cx, unsigned argc, Value* vp);
@ -2430,7 +2431,7 @@ js::GetWaitForAllPromise(JSContext* cx, const JS::AutoObjectVector& promises)
// Steps j-o. // Steps j-o.
JSFunction* resolveFunc = NewPromiseCombinatorElementFunction( JSFunction* resolveFunc = NewPromiseCombinatorElementFunction(
cx, PromiseAllResolveElementFunction, dataHolder, index); cx, PromiseAllResolveElementFunction, dataHolder, index, UndefinedHandleValue);
if (!resolveFunc) if (!resolveFunc)
return nullptr; return nullptr;
@ -2888,7 +2889,7 @@ GetPromiseCombinatorElements(JSContext* cx, Handle<PromiseCombinatorDataHolder*>
static JSFunction* static JSFunction*
NewPromiseCombinatorElementFunction(JSContext* cx, Native native, NewPromiseCombinatorElementFunction(JSContext* cx, Native native,
Handle<PromiseCombinatorDataHolder*> dataHolder, Handle<PromiseCombinatorDataHolder*> dataHolder,
uint32_t index) uint32_t index, Handle<Value> maybeResolveFunc)
{ {
JSFunction* fn = NewNativeFunction(cx, native, 1, nullptr, JSFunction* fn = NewNativeFunction(cx, native, 1, nullptr,
gc::AllocKind::FUNCTION_EXTENDED, GenericObject); gc::AllocKind::FUNCTION_EXTENDED, GenericObject);
@ -2898,8 +2899,13 @@ NewPromiseCombinatorElementFunction(JSContext* cx, Native native,
fn->setExtendedSlot(PromiseCombinatorElementFunctionSlot_Data, fn->setExtendedSlot(PromiseCombinatorElementFunctionSlot_Data,
ObjectValue(*dataHolder)); ObjectValue(*dataHolder));
fn->setExtendedSlot(PromiseCombinatorElementFunctionSlot_ElementIndex, if (maybeResolveFunc.isObject()) {
Int32Value(index)); fn->setExtendedSlot(PromiseCombinatorElementFunctionSlot_ElementIndexOrResolveFunc,
maybeResolveFunc);
} else {
fn->setExtendedSlot(PromiseCombinatorElementFunctionSlot_ElementIndexOrResolveFunc,
Int32Value(index));
}
return fn; return fn;
} }
@ -2917,6 +2923,13 @@ PromiseCombinatorElementFunctionAlreadyCalled(const CallArgs& args,
// Step 1. // Step 1.
JSFunction* fn = &args.callee().as<JSFunction>(); JSFunction* fn = &args.callee().as<JSFunction>();
size_t indexOrResolveFuncSlot = PromiseCombinatorElementFunctionSlot_ElementIndexOrResolveFunc;
if (fn->getExtendedSlot(indexOrResolveFuncSlot).isObject()) {
Value slotVal = fn->getExtendedSlot(indexOrResolveFuncSlot);
fn = &slotVal.toObject().as<JSFunction>();
}
MOZ_RELEASE_ASSERT(fn->getExtendedSlot(indexOrResolveFuncSlot).isInt32());
// Step 2. // Step 2.
const Value& dataVal = const Value& dataVal =
fn->getExtendedSlot(PromiseCombinatorElementFunctionSlot_Data); fn->getExtendedSlot(PromiseCombinatorElementFunctionSlot_Data);
@ -2936,9 +2949,7 @@ PromiseCombinatorElementFunctionAlreadyCalled(const CallArgs& args,
UndefinedValue()); UndefinedValue());
// Step 5. // Step 5.
int32_t idx = int32_t idx = fn->getExtendedSlot(indexOrResolveFuncSlot).toInt32();
fn->getExtendedSlot(PromiseCombinatorElementFunctionSlot_ElementIndex)
.toInt32();
MOZ_ASSERT(idx >= 0); MOZ_ASSERT(idx >= 0);
*index = uint32_t(idx); *index = uint32_t(idx);
@ -2988,7 +2999,7 @@ PerformPromiseAll(JSContext *cx, PromiseForOfIterator& iterator, HandleObject C,
// Steps 8.j-p. // Steps 8.j-p.
JSFunction* resolveFunc = NewPromiseCombinatorElementFunction(cx, JSFunction* resolveFunc = NewPromiseCombinatorElementFunction(cx,
PromiseAllResolveElementFunction, dataHolder, index); PromiseAllResolveElementFunction, dataHolder, index, UndefinedHandleValue);
if (!resolveFunc) if (!resolveFunc)
return false; return false;
@ -3187,7 +3198,7 @@ static MOZ_MUST_USE bool PerformPromiseAllSettled(
// Steps 8.j-q. // Steps 8.j-q.
JSFunction* resolveFunc = NewPromiseCombinatorElementFunction( JSFunction* resolveFunc = NewPromiseCombinatorElementFunction(
cx, PromiseAllSettledResolveElementFunction, dataHolder, index); cx, PromiseAllSettledResolveElementFunction, dataHolder, index, UndefinedHandleValue);
if (!resolveFunc) { if (!resolveFunc) {
return false; return false;
} }
@ -3195,7 +3206,7 @@ static MOZ_MUST_USE bool PerformPromiseAllSettled(
// Steps 8.r-x. // Steps 8.r-x.
JSFunction* rejectFunc = NewPromiseCombinatorElementFunction( JSFunction* rejectFunc = NewPromiseCombinatorElementFunction(
cx, PromiseAllSettledRejectElementFunction, dataHolder, index); cx, PromiseAllSettledRejectElementFunction, dataHolder, index, resolveFunVal);
if (!rejectFunc) { if (!rejectFunc) {
return false; return false;
} }
@ -3391,7 +3402,7 @@ PerformPromiseAny(JSContext* cx, PromiseForOfIterator& iterator, HandleObject C,
// Steps 8.j-p. // Steps 8.j-p.
JSFunction* rejectFunc = NewPromiseCombinatorElementFunction( JSFunction* rejectFunc = NewPromiseCombinatorElementFunction(
cx, PromiseAnyRejectElementFunction, dataHolder, index); cx, PromiseAnyRejectElementFunction, dataHolder, index, UndefinedHandleValue);
if (!rejectFunc) { if (!rejectFunc) {
return false; return false;
} }