summaryrefslogtreecommitdiff
path: root/js
diff options
context:
space:
mode:
authorBrian Smith <brian@dbsoft.org>2023-04-11 16:42:04 -0500
committerBrian Smith <brian@dbsoft.org>2023-04-27 13:33:56 -0500
commita28f3edf2a081c26a60236cc151a29d2ca99998f (patch)
tree6460d4b504174e9c4ef5616cee26414d60e06601 /js
parent6b69dad2aa76481c1850bc0f88e1993103bf49c4 (diff)
downloaduxp-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.cpp9
-rw-r--r--js/src/jsapi.cpp5
-rw-r--r--js/src/jsapi.h11
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);