summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGaming4JC <g4jc@hyperbola.info>2019-06-29 22:19:56 -0400
committerGaming4JC <g4jc@hyperbola.info>2019-07-18 22:38:18 -0400
commit52e22e231b065cc7d5975d5f6f8a9231c4f18f6e (patch)
treeb20f9307f025b5d6d55603e4f681b6f89610e02b
parentaf32c8553e54455ef8cbfe70a13f79f84c2163a4 (diff)
downloadUXP-52e22e231b065cc7d5975d5f6f8a9231c4f18f6e.tar
UXP-52e22e231b065cc7d5975d5f6f8a9231c4f18f6e.tar.gz
UXP-52e22e231b065cc7d5975d5f6f8a9231c4f18f6e.tar.lz
UXP-52e22e231b065cc7d5975d5f6f8a9231c4f18f6e.tar.xz
UXP-52e22e231b065cc7d5975d5f6f8a9231c4f18f6e.zip
1323324 - Part 1: Make Promise::unforgeable{Resolve,Reject} spec-compliant.
-rw-r--r--js/src/builtin/Promise.cpp100
-rw-r--r--js/src/jsapi.cpp4
2 files changed, 44 insertions, 60 deletions
diff --git a/js/src/builtin/Promise.cpp b/js/src/builtin/Promise.cpp
index c781a336d..9941c6f57 100644
--- a/js/src/builtin/Promise.cpp
+++ b/js/src/builtin/Promise.cpp
@@ -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.
-static MOZ_MUST_USE bool
-CommonStaticResolveRejectImpl(JSContext* cx, unsigned argc, Value* vp, ResolutionMode mode)
+static MOZ_MUST_USE JSObject*
+CommonStaticResolveRejectImpl(JSContext* cx, HandleValue thisVal, HandleValue argVal,
+ ResolutionMode mode)
{
- CallArgs args = CallArgsFromVp(argc, vp);
- RootedValue x(cx, args.get(0));
-
// Steps 1-2.
- if (!args.thisv().isObject()) {
+ if (!thisVal.isObject()) {
const char* msg = mode == ResolveMode
? "Receiver of Promise.resolve call"
: "Receiver of Promise.reject call";
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT, msg);
- return false;
+ return nullptr;
}
- RootedValue cVal(cx, args.thisv());
- RootedObject C(cx, &cVal.toObject());
+ RootedObject C(cx, &thisVal.toObject());
// Step 3 of Resolve.
- if (mode == ResolveMode && x.isObject()) {
- RootedObject xObj(cx, &x.toObject());
+ if (mode == ResolveMode && argVal.isObject()) {
+ RootedObject xObj(cx, &argVal.toObject());
bool isPromise = false;
if (xObj->is<PromiseObject>()) {
isPromise = true;
@@ -1985,11 +1982,9 @@ CommonStaticResolveRejectImpl(JSContext* cx, unsigned argc, Value* vp, Resolutio
if (isPromise) {
RootedValue ctorVal(cx);
if (!GetProperty(cx, xObj, xObj, cx->names().constructor, &ctorVal))
- return false;
- if (ctorVal == cVal) {
- args.rval().set(x);
- return true;
- }
+ return nullptr;
+ if (ctorVal == thisVal)
+ return xObj;
}
}
@@ -1998,15 +1993,17 @@ CommonStaticResolveRejectImpl(JSContext* cx, unsigned argc, Value* vp, Resolutio
RootedObject resolveFun(cx);
RootedObject rejectFun(cx);
if (!NewPromiseCapability(cx, C, &promise, &resolveFun, &rejectFun, true))
- return false;
+ return nullptr;
// Step 5 of Resolve, 4 of Reject.
- if (!RunResolutionFunction(cx, mode == ResolveMode ? resolveFun : rejectFun, x, mode, promise))
- return false;
+ if (!RunResolutionFunction(cx, mode == ResolveMode ? resolveFun : rejectFun, argVal, mode,
+ promise))
+ {
+ return nullptr;
+ }
// Step 6 of Resolve, 4 of Reject.
- args.rval().setObject(*promise);
- return true;
+ return promise;
}
/**
@@ -2015,7 +2012,14 @@ CommonStaticResolveRejectImpl(JSContext* cx, unsigned argc, Value* vp, Resolutio
bool
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*
PromiseObject::unforgeableReject(JSContext* cx, HandleValue value)
{
- // Steps 1-2 (omitted).
-
- // Roughly step 3.
- Rooted<PromiseObject*> promise(cx, CreatePromiseObjectInternal(cx));
- if (!promise)
- return nullptr;
-
- // Roughly step 4.
- if (!ResolvePromise(cx, promise, value, JS::PromiseState::Rejected))
+ RootedObject promiseCtor(cx, JS::GetPromiseConstructor(cx));
+ if (!promiseCtor)
return nullptr;
-
- // Step 5.
- return promise;
+ RootedValue cVal(cx, ObjectValue(*promiseCtor));
+ return CommonStaticResolveRejectImpl(cx, cVal, value, RejectMode);
}
/**
@@ -2045,7 +2041,14 @@ PromiseObject::unforgeableReject(JSContext* cx, HandleValue value)
bool
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*
PromiseObject::unforgeableResolve(JSContext* cx, HandleValue value)
{
- // Steps 1-2 (omitted).
-
- // 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)
+ RootedObject promiseCtor(cx, JS::GetPromiseConstructor(cx));
+ if (!promiseCtor)
return nullptr;
-
- // Steps 5.
- if (!ResolvePromiseInternal(cx, promise, value))
- return nullptr;
-
- // Step 6.
- return promise;
+ RootedValue cVal(cx, ObjectValue(*promiseCtor));
+ return CommonStaticResolveRejectImpl(cx, cVal, value, ResolveMode);
}
// ES2016, 25.4.4.6, implemented in Promise.js.
diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp
index 9ee29ffe4..ac7b78581 100644
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -4884,7 +4884,7 @@ JS::CallOriginalPromiseResolve(JSContext* cx, JS::HandleValue resolutionValue)
assertSameCompartment(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;
}
@@ -4896,7 +4896,7 @@ JS::CallOriginalPromiseReject(JSContext* cx, JS::HandleValue rejectionValue)
assertSameCompartment(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;
}