mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-28 18:17:29 +09:00
1323324 - Part 1: Make Promise::unforgeable{Resolve,Reject} spec-compliant.
This commit is contained in:
parent
ff46e0c58c
commit
146dbe7bee
2 changed files with 44 additions and 60 deletions
|
|
@ -1947,26 +1947,23 @@ PerformPromiseRace(JSContext *cx, JS::ForOfIterator& iterator, HandleObject C,
|
||||||
}
|
}
|
||||||
|
|
||||||
// ES2016, Sub-steps of 25.4.4.4 and 25.4.4.5.
|
// ES2016, Sub-steps of 25.4.4.4 and 25.4.4.5.
|
||||||
static MOZ_MUST_USE bool
|
static MOZ_MUST_USE JSObject*
|
||||||
CommonStaticResolveRejectImpl(JSContext* cx, unsigned argc, Value* vp, ResolutionMode mode)
|
CommonStaticResolveRejectImpl(JSContext* cx, HandleValue thisVal, HandleValue argVal,
|
||||||
|
ResolutionMode mode)
|
||||||
{
|
{
|
||||||
CallArgs args = CallArgsFromVp(argc, vp);
|
|
||||||
RootedValue x(cx, args.get(0));
|
|
||||||
|
|
||||||
// Steps 1-2.
|
// Steps 1-2.
|
||||||
if (!args.thisv().isObject()) {
|
if (!thisVal.isObject()) {
|
||||||
const char* msg = mode == ResolveMode
|
const char* msg = mode == ResolveMode
|
||||||
? "Receiver of Promise.resolve call"
|
? "Receiver of Promise.resolve call"
|
||||||
: "Receiver of Promise.reject call";
|
: "Receiver of Promise.reject call";
|
||||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT, msg);
|
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT, msg);
|
||||||
return false;
|
return nullptr;
|
||||||
}
|
}
|
||||||
RootedValue cVal(cx, args.thisv());
|
RootedObject C(cx, &thisVal.toObject());
|
||||||
RootedObject C(cx, &cVal.toObject());
|
|
||||||
|
|
||||||
// Step 3 of Resolve.
|
// Step 3 of Resolve.
|
||||||
if (mode == ResolveMode && x.isObject()) {
|
if (mode == ResolveMode && argVal.isObject()) {
|
||||||
RootedObject xObj(cx, &x.toObject());
|
RootedObject xObj(cx, &argVal.toObject());
|
||||||
bool isPromise = false;
|
bool isPromise = false;
|
||||||
if (xObj->is<PromiseObject>()) {
|
if (xObj->is<PromiseObject>()) {
|
||||||
isPromise = true;
|
isPromise = true;
|
||||||
|
|
@ -1985,11 +1982,9 @@ CommonStaticResolveRejectImpl(JSContext* cx, unsigned argc, Value* vp, Resolutio
|
||||||
if (isPromise) {
|
if (isPromise) {
|
||||||
RootedValue ctorVal(cx);
|
RootedValue ctorVal(cx);
|
||||||
if (!GetProperty(cx, xObj, xObj, cx->names().constructor, &ctorVal))
|
if (!GetProperty(cx, xObj, xObj, cx->names().constructor, &ctorVal))
|
||||||
return false;
|
return nullptr;
|
||||||
if (ctorVal == cVal) {
|
if (ctorVal == thisVal)
|
||||||
args.rval().set(x);
|
return xObj;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1998,15 +1993,17 @@ CommonStaticResolveRejectImpl(JSContext* cx, unsigned argc, Value* vp, Resolutio
|
||||||
RootedObject resolveFun(cx);
|
RootedObject resolveFun(cx);
|
||||||
RootedObject rejectFun(cx);
|
RootedObject rejectFun(cx);
|
||||||
if (!NewPromiseCapability(cx, C, &promise, &resolveFun, &rejectFun, true))
|
if (!NewPromiseCapability(cx, C, &promise, &resolveFun, &rejectFun, true))
|
||||||
return false;
|
return nullptr;
|
||||||
|
|
||||||
// Step 5 of Resolve, 4 of Reject.
|
// Step 5 of Resolve, 4 of Reject.
|
||||||
if (!RunResolutionFunction(cx, mode == ResolveMode ? resolveFun : rejectFun, x, mode, promise))
|
if (!RunResolutionFunction(cx, mode == ResolveMode ? resolveFun : rejectFun, argVal, mode,
|
||||||
return false;
|
promise))
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
// Step 6 of Resolve, 4 of Reject.
|
// Step 6 of Resolve, 4 of Reject.
|
||||||
args.rval().setObject(*promise);
|
return promise;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -2015,7 +2012,14 @@ CommonStaticResolveRejectImpl(JSContext* cx, unsigned argc, Value* vp, Resolutio
|
||||||
bool
|
bool
|
||||||
js::Promise_reject(JSContext* cx, unsigned argc, Value* vp)
|
js::Promise_reject(JSContext* cx, unsigned argc, Value* vp)
|
||||||
{
|
{
|
||||||
return CommonStaticResolveRejectImpl(cx, argc, vp, RejectMode);
|
CallArgs args = CallArgsFromVp(argc, vp);
|
||||||
|
RootedValue thisVal(cx, args.thisv());
|
||||||
|
RootedValue argVal(cx, args.get(0));
|
||||||
|
JSObject* result = CommonStaticResolveRejectImpl(cx, thisVal, argVal, RejectMode);
|
||||||
|
if (!result)
|
||||||
|
return false;
|
||||||
|
args.rval().setObject(*result);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -2024,19 +2028,11 @@ js::Promise_reject(JSContext* cx, unsigned argc, Value* vp)
|
||||||
/* static */ JSObject*
|
/* static */ JSObject*
|
||||||
PromiseObject::unforgeableReject(JSContext* cx, HandleValue value)
|
PromiseObject::unforgeableReject(JSContext* cx, HandleValue value)
|
||||||
{
|
{
|
||||||
// Steps 1-2 (omitted).
|
RootedObject promiseCtor(cx, JS::GetPromiseConstructor(cx));
|
||||||
|
if (!promiseCtor)
|
||||||
// Roughly step 3.
|
|
||||||
Rooted<PromiseObject*> promise(cx, CreatePromiseObjectInternal(cx));
|
|
||||||
if (!promise)
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
RootedValue cVal(cx, ObjectValue(*promiseCtor));
|
||||||
// Roughly step 4.
|
return CommonStaticResolveRejectImpl(cx, cVal, value, RejectMode);
|
||||||
if (!ResolvePromise(cx, promise, value, JS::PromiseState::Rejected))
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
// Step 5.
|
|
||||||
return promise;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -2045,7 +2041,14 @@ PromiseObject::unforgeableReject(JSContext* cx, HandleValue value)
|
||||||
bool
|
bool
|
||||||
js::Promise_static_resolve(JSContext* cx, unsigned argc, Value* vp)
|
js::Promise_static_resolve(JSContext* cx, unsigned argc, Value* vp)
|
||||||
{
|
{
|
||||||
return CommonStaticResolveRejectImpl(cx, argc, vp, ResolveMode);
|
CallArgs args = CallArgsFromVp(argc, vp);
|
||||||
|
RootedValue thisVal(cx, args.thisv());
|
||||||
|
RootedValue argVal(cx, args.get(0));
|
||||||
|
JSObject* result = CommonStaticResolveRejectImpl(cx, thisVal, argVal, ResolveMode);
|
||||||
|
if (!result)
|
||||||
|
return false;
|
||||||
|
args.rval().setObject(*result);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -2054,30 +2057,11 @@ js::Promise_static_resolve(JSContext* cx, unsigned argc, Value* vp)
|
||||||
/* static */ JSObject*
|
/* static */ JSObject*
|
||||||
PromiseObject::unforgeableResolve(JSContext* cx, HandleValue value)
|
PromiseObject::unforgeableResolve(JSContext* cx, HandleValue value)
|
||||||
{
|
{
|
||||||
// Steps 1-2 (omitted).
|
RootedObject promiseCtor(cx, JS::GetPromiseConstructor(cx));
|
||||||
|
if (!promiseCtor)
|
||||||
// Step 3.
|
|
||||||
if (value.isObject()) {
|
|
||||||
JSObject* obj = &value.toObject();
|
|
||||||
if (IsWrapper(obj))
|
|
||||||
obj = CheckedUnwrap(obj);
|
|
||||||
// Instead of getting the `constructor` property, do an unforgeable
|
|
||||||
// check.
|
|
||||||
if (obj && obj->is<PromiseObject>())
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 4.
|
|
||||||
Rooted<PromiseObject*> promise(cx, CreatePromiseObjectInternal(cx));
|
|
||||||
if (!promise)
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
RootedValue cVal(cx, ObjectValue(*promiseCtor));
|
||||||
// Steps 5.
|
return CommonStaticResolveRejectImpl(cx, cVal, value, ResolveMode);
|
||||||
if (!ResolvePromiseInternal(cx, promise, value))
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
// Step 6.
|
|
||||||
return promise;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ES2016, 25.4.4.6, implemented in Promise.js.
|
// ES2016, 25.4.4.6, implemented in Promise.js.
|
||||||
|
|
|
||||||
|
|
@ -4884,7 +4884,7 @@ JS::CallOriginalPromiseResolve(JSContext* cx, JS::HandleValue resolutionValue)
|
||||||
assertSameCompartment(cx, resolutionValue);
|
assertSameCompartment(cx, resolutionValue);
|
||||||
|
|
||||||
RootedObject promise(cx, PromiseObject::unforgeableResolve(cx, resolutionValue));
|
RootedObject promise(cx, PromiseObject::unforgeableResolve(cx, resolutionValue));
|
||||||
MOZ_ASSERT_IF(promise, promise->is<PromiseObject>());
|
MOZ_ASSERT_IF(promise, CheckedUnwrap(promise)->is<PromiseObject>());
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4896,7 +4896,7 @@ JS::CallOriginalPromiseReject(JSContext* cx, JS::HandleValue rejectionValue)
|
||||||
assertSameCompartment(cx, rejectionValue);
|
assertSameCompartment(cx, rejectionValue);
|
||||||
|
|
||||||
RootedObject promise(cx, PromiseObject::unforgeableReject(cx, rejectionValue));
|
RootedObject promise(cx, PromiseObject::unforgeableReject(cx, rejectionValue));
|
||||||
MOZ_ASSERT_IF(promise, promise->is<PromiseObject>());
|
MOZ_ASSERT_IF(promise, CheckedUnwrap(promise)->is<PromiseObject>());
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue