diff options
author | Brian Smith <brian@dbsoft.org> | 2023-04-11 16:42:04 -0500 |
---|---|---|
committer | Brian Smith <brian@dbsoft.org> | 2023-04-27 13:33:56 -0500 |
commit | a28f3edf2a081c26a60236cc151a29d2ca99998f (patch) | |
tree | 6460d4b504174e9c4ef5616cee26414d60e06601 /js | |
parent | 6b69dad2aa76481c1850bc0f88e1993103bf49c4 (diff) | |
download | uxp-a28f3edf2a081c26a60236cc151a29d2ca99998f.tar.gz |
Issue #1691 - Part 6d: Optimize handling of internally-created Promise objects.
https://bugzilla.mozilla.org/show_bug.cgi?id=1358879
The patch uses a different test: PROMISE_FLAG_DEFAULT_REJECT_FUNCTION which doesn't
exist in our codebase. It was added in this bug, which appears to be partly complete:
https://bugzilla.mozilla.org/show_bug.cgi?id=1313049
(cherry picked from commit 97fc74b693813eaaa9ab833d9c51fc5868ff039f)
Diffstat (limited to 'js')
-rw-r--r-- | js/src/builtin/Promise.cpp | 9 | ||||
-rw-r--r-- | js/src/jsapi.cpp | 5 | ||||
-rw-r--r-- | js/src/jsapi.h | 11 |
3 files changed, 18 insertions, 7 deletions
diff --git a/js/src/builtin/Promise.cpp b/js/src/builtin/Promise.cpp index 4da00a8671..daeb2c3d68 100644 --- a/js/src/builtin/Promise.cpp +++ b/js/src/builtin/Promise.cpp @@ -2478,8 +2478,11 @@ RunResolutionFunction(JSContext *cx, HandleObject resolutionFun, HandleValue res { // The absence of a resolve/reject function can mean that, as an // optimization, those weren't created. In that case, a flag is set on - // the Promise object. There are also reactions where the Promise - // itself is missing. For those, there's nothing left to do here. + // the Promise object. (It's also possible to not have a resolution + // function without that flag being set. This can occur if a Promise + // subclass constructor passes null/undefined to `super()`.) + // There are also reactions where the Promise itself is missing. For + // those, there's nothing left to do here. assertSameCompartment(cx, resolutionFun); assertSameCompartment(cx, result); assertSameCompartment(cx, promiseObj); @@ -4826,7 +4829,7 @@ PromiseObject::reject(JSContext* cx, Handle<PromiseObject*> promise, HandleValue return true; if (PromiseHasAnyFlag(*promise, PROMISE_FLAG_DEFAULT_RESOLVING_FUNCTIONS)) - return RejectMaybeWrappedPromise(cx, promise, rejectionValue); + return ResolvePromise(cx, promise, rejectionValue, JS::PromiseState::Rejected); RootedValue funVal(cx, promise->getFixedSlot(PromiseSlot_RejectFunction)); MOZ_ASSERT(IsCallable(funVal)); diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 6c10eba821..fc013c14cb 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -4902,11 +4902,14 @@ JS_PUBLIC_API(JSObject*) JS::NewPromiseObject(JSContext* cx, HandleObject executor, HandleObject proto /* = nullptr */) { MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment())); - MOZ_ASSERT(IsCallable(executor)); AssertHeapIsIdle(cx); CHECK_REQUEST(cx); assertSameCompartment(cx, executor, proto); + if (!executor) + return PromiseObject::createSkippingExecutor(cx); + + MOZ_ASSERT(IsCallable(executor)); return PromiseObject::create(cx, executor, proto); } diff --git a/js/src/jsapi.h b/js/src/jsapi.h index dc3af6bf87..2714533354 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -4536,9 +4536,14 @@ SetPromiseRejectionTrackerCallback(JSContext* cx, JSPromiseRejectionTrackerCallb /** * Returns a new instance of the Promise builtin class in the current - * compartment, with the right slot layout. If a `proto` is passed, that gets - * set as the instance's [[Prototype]] instead of the original value of - * `Promise.prototype`. + * compartment, with the right slot layout. + * + * The `executor` can be a `nullptr`. In that case, the only way to resolve or + * reject the returned promise is via the `JS::ResolvePromise` and + * `JS::RejectPromise` JSAPI functions. + * + * If a `proto` is passed, that gets set as the instance's [[Prototype]] + * instead of the original value of `Promise.prototype`. */ extern JS_PUBLIC_API(JSObject*) NewPromiseObject(JSContext* cx, JS::HandleObject executor, JS::HandleObject proto = nullptr); |