commit d8e3b23cd602a8fcd13221a42f31608b98e1256f
parent f3e968c5ec1d577d46b206b6e43a050e9ae6067a
Author: Matthew Gaudet <mgaudet@mozilla.com>
Date: Wed, 1 Oct 2025 21:38:50 +0000
Bug 1983154 - Create MaybeGetPromiseAllocationSite r=arai
This is a more flexibile version
Differential Revision: https://phabricator.services.mozilla.com/D261177
Diffstat:
2 files changed, 39 insertions(+), 12 deletions(-)
diff --git a/js/public/Promise.h b/js/public/Promise.h
@@ -398,10 +398,26 @@ extern JS_PUBLIC_API bool SetSettledPromiseIsHandled(JSContext* cx,
/**
* Returns a js::SavedFrame linked list of the stack that lead to the given
* Promise's allocation.
+ *
+ * The promise parameter here should be an unwrapped promise.
*/
extern JS_PUBLIC_API JSObject* GetPromiseAllocationSite(
JS::HandleObject promise);
+/**
+ * A more flexible version of the above: Handles the cases where
+ * 1. maybePromise is wrapped
+ * 2. maybePromise is null
+ * 3. maybePromise isn't actually a promise.
+ *
+ * Returns js::SavedFrame if the passed argument is a
+ * wrapped promise (that's not a dead object wrapper) and it
+ * has an allocation site.
+ */
+extern JS_PUBLIC_API JSObject*
+MaybeGetPromiseAllocationSiteFromPossiblyWrappedPromise(
+ JS::HandleObject maybePromise);
+
extern JS_PUBLIC_API JSObject* GetPromiseResolutionSite(
JS::HandleObject promise);
diff --git a/js/src/vm/Runtime.cpp b/js/src/vm/Runtime.cpp
@@ -576,6 +576,26 @@ bool JSRuntime::getHostDefinedData(JSContext* cx,
return cx->jobQueue->getHostDefinedData(cx, data);
}
+JS_PUBLIC_API JSObject*
+JS::MaybeGetPromiseAllocationSiteFromPossiblyWrappedPromise(
+ HandleObject promise) {
+ if (!promise) {
+ return nullptr;
+ }
+
+ JSObject* unwrappedPromise = promise;
+ // While the job object is guaranteed to be unwrapped, the promise
+ // might be wrapped. See the comments in EnqueuePromiseReactionJob in
+ // builtin/Promise.cpp for details.
+ if (IsWrapper(promise)) {
+ unwrappedPromise = UncheckedUnwrap(promise);
+ }
+ if (unwrappedPromise->is<PromiseObject>()) {
+ return unwrappedPromise->as<PromiseObject>().allocationSite();
+ }
+ return nullptr;
+}
+
bool JSRuntime::enqueuePromiseJob(JSContext* cx, HandleFunction job,
HandleObject promise,
HandleObject hostDefinedData) {
@@ -583,23 +603,14 @@ bool JSRuntime::enqueuePromiseJob(JSContext* cx, HandleFunction job,
"Must select a JobQueue implementation using JS::JobQueue "
"or js::UseInternalJobQueues before using Promises");
- RootedObject allocationSite(cx);
if (promise) {
#ifdef DEBUG
AssertSameCompartment(job, promise);
#endif
-
- RootedObject unwrappedPromise(cx, promise);
- // While the job object is guaranteed to be unwrapped, the promise
- // might be wrapped. See the comments in EnqueuePromiseReactionJob in
- // builtin/Promise.cpp for details.
- if (IsWrapper(promise)) {
- unwrappedPromise = UncheckedUnwrap(promise);
- }
- if (unwrappedPromise->is<PromiseObject>()) {
- allocationSite = JS::GetPromiseAllocationSite(unwrappedPromise);
- }
}
+
+ RootedObject allocationSite(
+ cx, JS::MaybeGetPromiseAllocationSiteFromPossiblyWrappedPromise(promise));
return cx->jobQueue->enqueuePromiseJob(cx, promise, job, allocationSite,
hostDefinedData);
}