diff options
Diffstat (limited to 'js/src/builtin/Promise.cpp')
-rw-r--r-- | js/src/builtin/Promise.cpp | 129 |
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[] = { |