summaryrefslogtreecommitdiffstats
path: root/js/src/builtin/Promise.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/builtin/Promise.cpp')
-rw-r--r--js/src/builtin/Promise.cpp129
1 files changed, 56 insertions, 73 deletions
diff --git a/js/src/builtin/Promise.cpp b/js/src/builtin/Promise.cpp
index c781a336d..ec7845e89 100644
--- a/js/src/builtin/Promise.cpp
+++ b/js/src/builtin/Promise.cpp
@@ -603,7 +603,7 @@ ResolvePromise(JSContext* cx, Handle<PromiseObject*> promise, HandleValue valueO
// Now that everything else is done, do the things the debugger needs.
// Step 7 of RejectPromise implemented in onSettled.
- promise->onSettled(cx);
+ PromiseObject::onSettled(cx, promise);
// Step 7 of FulfillPromise.
// Step 8 of RejectPromise.
@@ -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)
+ RootedObject promiseCtor(cx, JS::GetPromiseConstructor(cx));
+ if (!promiseCtor)
return nullptr;
-
- // Roughly step 4.
- if (!ResolvePromise(cx, promise, value, JS::PromiseState::Rejected))
- 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.
@@ -2647,14 +2631,14 @@ PromiseObject::dependentPromises(JSContext* cx, MutableHandle<GCVector<Value>> v
return true;
}
-bool
-PromiseObject::resolve(JSContext* cx, HandleValue resolutionValue)
+/* static */ bool
+PromiseObject::resolve(JSContext* cx, Handle<PromiseObject*> promise, HandleValue resolutionValue)
{
- MOZ_ASSERT(!PromiseHasAnyFlag(*this, PROMISE_FLAG_ASYNC));
- if (state() != JS::PromiseState::Pending)
+ MOZ_ASSERT(!PromiseHasAnyFlag(*promise, PROMISE_FLAG_ASYNC));
+ if (promise->state() != JS::PromiseState::Pending)
return true;
- RootedObject resolveFun(cx, GetResolveFunctionFromPromise(this));
+ RootedObject resolveFun(cx, GetResolveFunctionFromPromise(promise));
RootedValue funVal(cx, ObjectValue(*resolveFun));
// For xray'd Promises, the resolve fun may have been created in another
@@ -2670,14 +2654,14 @@ PromiseObject::resolve(JSContext* cx, HandleValue resolutionValue)
return Call(cx, funVal, UndefinedHandleValue, args, &dummy);
}
-bool
-PromiseObject::reject(JSContext* cx, HandleValue rejectionValue)
+/* static */ bool
+PromiseObject::reject(JSContext* cx, Handle<PromiseObject*> promise, HandleValue rejectionValue)
{
- MOZ_ASSERT(!PromiseHasAnyFlag(*this, PROMISE_FLAG_ASYNC));
- if (state() != JS::PromiseState::Pending)
+ MOZ_ASSERT(!PromiseHasAnyFlag(*promise, PROMISE_FLAG_ASYNC));
+ if (promise->state() != JS::PromiseState::Pending)
return true;
- RootedValue funVal(cx, this->getFixedSlot(PromiseSlot_RejectFunction));
+ RootedValue funVal(cx, promise->getFixedSlot(PromiseSlot_RejectFunction));
MOZ_ASSERT(IsCallable(funVal));
FixedInvokeArgs<1> args(cx);
@@ -2687,10 +2671,9 @@ PromiseObject::reject(JSContext* cx, HandleValue rejectionValue)
return Call(cx, funVal, UndefinedHandleValue, args, &dummy);
}
-void
-PromiseObject::onSettled(JSContext* cx)
+/* static */ void
+PromiseObject::onSettled(JSContext* cx, Handle<PromiseObject*> promise)
{
- Rooted<PromiseObject*> promise(cx, this);
RootedObject stack(cx);
if (cx->options().asyncStack() || cx->compartment()->isDebuggee()) {
if (!JS::CaptureCurrentStack(cx, &stack, JS::StackCapture(JS::AllFrames()))) {
@@ -2750,7 +2733,7 @@ PromiseTask::executeAndFinish(JSContext* cx)
static JSObject*
CreatePromisePrototype(JSContext* cx, JSProtoKey key)
{
- return cx->global()->createBlankPrototype(cx, &PromiseObject::protoClass_);
+ return GlobalObject::createBlankPrototype(cx, cx->global(), &PromiseObject::protoClass_);
}
static const JSFunctionSpec promise_methods[] = {