author | Till Schneidereit <till@tillschneidereit.net> |
Wed, 02 Aug 2017 09:43:45 +0200 | |
changeset 414100 | f054209125461575f57ce0f1e6b962653c523572 |
parent 414099 | c2d33789539668305c1e8ac2d65a05a590c8a548 |
child 414101 | e66e4b3ee60f04411e0df5d446794d4166c3ba80 |
push id | 33858 |
push user | ncsoregi@mozilla.com |
push date | Tue, 17 Apr 2018 21:55:44 +0000 |
treeherder | mozilla-central@d6eb5597d744 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | anba |
bugs | 1342070 |
milestone | 61.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
js/src/builtin/Promise.cpp | file | annotate | diff | comparison | revisions | |
js/src/builtin/Promise.h | file | annotate | diff | comparison | revisions |
--- a/js/src/builtin/Promise.cpp +++ b/js/src/builtin/Promise.cpp @@ -2339,18 +2339,18 @@ js::PromiseResolve(JSContext* cx, Handle { RootedValue C(cx, ObjectValue(*constructor)); return CommonStaticResolveRejectImpl(cx, C, value, ResolveMode); } /** * ES2016, 25.4.4.4, Promise.reject. */ -bool -js::Promise_reject(JSContext* cx, unsigned argc, Value* vp) +static bool +Promise_reject(JSContext* cx, unsigned argc, Value* vp) { 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); @@ -2368,18 +2368,18 @@ PromiseObject::unforgeableReject(JSConte return nullptr; RootedValue cVal(cx, ObjectValue(*promiseCtor)); return CommonStaticResolveRejectImpl(cx, cVal, value, RejectMode); } /** * ES2016, 25.4.4.5, Promise.resolve. */ -bool -js::Promise_static_resolve(JSContext* cx, unsigned argc, Value* vp) +static bool +Promise_static_resolve(JSContext* cx, unsigned argc, Value* vp) { 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); @@ -3023,26 +3023,61 @@ js::AsyncGeneratorEnqueue(JSContext* cx, return false; } // Step 9. result.setObject(*resultPromise); return true; } -bool Promise_then_impl(JSContext* cx, unsigned argc, Value* vp, bool rvalUsed) +static bool Promise_then(JSContext* cx, unsigned argc, Value* vp); +static bool Promise_then_impl(JSContext* cx, HandleValue promiseVal, HandleValue onFulfilled, + HandleValue onRejected, MutableHandleValue rval, bool rvalUsed); + +static bool +Promise_catch_impl(JSContext* cx, unsigned argc, Value* vp, bool rvalUsed) { CallArgs args = CallArgsFromVp(argc, vp); // Step 1. - RootedValue promiseVal(cx, args.thisv()); - - RootedValue onFulfilled(cx, args.get(0)); - RootedValue onRejected(cx, args.get(1)); - + RootedValue thenVal(cx); + if (!GetProperty(cx, args.thisv(), cx->names().then, &thenVal)) + return false; + + if (IsNativeFunction(thenVal, &Promise_then)) { + return Promise_then_impl(cx, args.thisv(), UndefinedHandleValue, args.get(0), + args.rval(), rvalUsed); + } + + FixedInvokeArgs<2> iargs(cx); + iargs[0].setUndefined(); + iargs[1].set(args.get(0)); + + return Call(cx, thenVal, args.thisv(), iargs, args.rval()); +} + +// ES2016, 25.4.5.3. +static bool +Promise_catch_noRetVal(JSContext* cx, unsigned argc, Value* vp) +{ + return Promise_catch_impl(cx, argc, vp, false); +} + +// ES2016, 25.4.5.3. +static bool +Promise_catch(JSContext* cx, unsigned argc, Value* vp) +{ + return Promise_catch_impl(cx, argc, vp, true); +} + +static bool +Promise_then_impl(JSContext* cx, HandleValue promiseVal, HandleValue onFulfilled, + HandleValue onRejected, MutableHandleValue rval, bool rvalUsed) +{ + // Step 1 (implicit). // Step 2. if (!promiseVal.isObject()) { JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT, "Receiver of Promise.prototype.then call"); return false; } RootedObject promiseObj(cx, &promiseVal.toObject()); Rooted<PromiseObject*> promise(cx); @@ -3071,34 +3106,36 @@ bool Promise_then_impl(JSContext* cx, un RootedObject resultPromise(cx); if (!OriginalPromiseThen(cx, promise, onFulfilled, onRejected, &resultPromise, createDependent)) { return false; } if (rvalUsed) - args.rval().setObject(*resultPromise); + rval.setObject(*resultPromise); else - args.rval().setUndefined(); + rval.setUndefined(); return true; } // ES2016, 25.4.5.3. bool Promise_then_noRetVal(JSContext* cx, unsigned argc, Value* vp) { - return Promise_then_impl(cx, argc, vp, false); + CallArgs args = CallArgsFromVp(argc, vp); + return Promise_then_impl(cx, args.thisv(), args.get(0), args.get(1), args.rval(), false); } // ES2016, 25.4.5.3. -bool -js::Promise_then(JSContext* cx, unsigned argc, Value* vp) +static bool +Promise_then(JSContext* cx, unsigned argc, Value* vp) { - return Promise_then_impl(cx, argc, vp, true); + CallArgs args = CallArgsFromVp(argc, vp); + return Promise_then_impl(cx, args.thisv(), args.get(0), args.get(1), args.rval(), true); } // ES2016, 25.4.5.3.1. static MOZ_MUST_USE bool PerformPromiseThen(JSContext* cx, Handle<PromiseObject*> promise, HandleValue onFulfilled_, HandleValue onRejected_, HandleObject resultPromise, HandleObject resolve, HandleObject reject) { @@ -3766,19 +3803,28 @@ const JSJitInfo promise_then_info = { { (JSJitGetterOp)Promise_then_noRetVal }, { 0 }, /* unused */ { 0 }, /* unused */ JSJitInfo::IgnoresReturnValueNative, JSJitInfo::AliasEverything, JSVAL_TYPE_UNDEFINED, }; +const JSJitInfo promise_catch_info = { + { (JSJitGetterOp)Promise_catch_noRetVal }, + { 0 }, /* unused */ + { 0 }, /* unused */ + JSJitInfo::IgnoresReturnValueNative, + JSJitInfo::AliasEverything, + JSVAL_TYPE_UNDEFINED, +}; + static const JSFunctionSpec promise_methods[] = { - JS_SELF_HOSTED_FN("catch", "Promise_catch", 1, 0), JS_FNINFO("then", Promise_then, &promise_then_info, 2, 0), + JS_FNINFO("catch", Promise_catch, &promise_catch_info, 1, 0), JS_SELF_HOSTED_FN("finally", "Promise_finally", 1, 0), JS_FS_END }; static const JSPropertySpec promise_properties[] = { JS_STRING_SYM_PS(toStringTag, "Promise", JSPROP_READONLY), JS_PS_END };
--- a/js/src/builtin/Promise.h +++ b/js/src/builtin/Promise.h @@ -254,18 +254,11 @@ class OffThreadPromiseRuntimeState // called to periodically drain the dispatch queue before shutdown. void internalDrain(JSContext* cx); bool internalHasPending(); // shutdown() must be called by the JSRuntime while the JSRuntime is valid. void shutdown(JSContext* cx); }; -bool -Promise_static_resolve(JSContext* cx, unsigned argc, Value* vp); -bool -Promise_reject(JSContext* cx, unsigned argc, Value* vp); -bool -Promise_then(JSContext* cx, unsigned argc, Value* vp); - } // namespace js #endif /* builtin_Promise_h */