commit 8fd0424527173fd491a269921ecf8e5357378ba1
parent 47190b510d90c150c2915d9cd9e9113bc246c31c
Author: Matthew Gaudet <mgaudet@mozilla.com>
Date: Wed, 1 Oct 2025 21:38:49 +0000
Bug 1983154 - Split CallSetup out of CallbackObjectBase r=smaug
To allow using CallSetup without a CallbackObjectBase
Differential Revision: https://phabricator.services.mozilla.com/D261174
Diffstat:
2 files changed, 68 insertions(+), 70 deletions(-)
diff --git a/dom/bindings/CallbackObject.cpp b/dom/bindings/CallbackObject.cpp
@@ -189,20 +189,19 @@ void CallbackObjectBase::GetDescription(nsACString& aOutString) {
aOutString.Append(")");
}
-CallbackObjectBase::CallSetup::CallSetup(CallbackObjectBase* aCallback,
- ErrorResult& aRv,
- const char* aExecutionReason,
- ExceptionHandling aExceptionHandling,
- JS::Realm* aRealm,
- bool aIsJSImplementedWebIDL)
+CallSetup::CallSetup(CallbackObjectBase* aCallback, ErrorResult& aRv,
+ const char* aExecutionReason,
+ CallbackObjectBase::ExceptionHandling aExceptionHandling,
+ JS::Realm* aRealm, bool aIsJSImplementedWebIDL)
: mCx(nullptr),
mRealm(aRealm),
mErrorResult(aRv),
mExceptionHandling(aExceptionHandling),
mIsMainThread(NS_IsMainThread()) {
- MOZ_ASSERT_IF(aExceptionHandling == eReportExceptions ||
- aExceptionHandling == eRethrowExceptions,
- !aRealm);
+ MOZ_ASSERT_IF(
+ aExceptionHandling == CallbackObjectBase::eReportExceptions ||
+ aExceptionHandling == CallbackObjectBase::eRethrowExceptions,
+ !aRealm);
CycleCollectedJSContext* ccjs = CycleCollectedJSContext::Get();
if (ccjs) {
@@ -318,9 +317,8 @@ CallbackObjectBase::CallSetup::CallSetup(CallbackObjectBase* aCallback,
mCallContext.emplace(cx, nullptr);
}
-bool CallbackObjectBase::CallSetup::ShouldRethrowException(
- JS::Handle<JS::Value> aException) {
- if (mExceptionHandling == eRethrowExceptions) {
+bool CallSetup::ShouldRethrowException(JS::Handle<JS::Value> aException) {
+ if (mExceptionHandling == CallbackObjectBase::eRethrowExceptions) {
MOZ_ASSERT(!mRealm);
return true;
}
@@ -339,7 +337,7 @@ bool CallbackObjectBase::CallSetup::ShouldRethrowException(
return js::GetNonCCWObjectRealm(obj) == mRealm;
}
-CallbackObjectBase::CallSetup::~CallSetup() {
+CallSetup::~CallSetup() {
// To get our nesting right we have to destroy our JSAutoRealm first.
// In particular, we want to do this before we try reporting any exceptions,
// so we end up reporting them while in the realm of our entry point,
@@ -351,8 +349,9 @@ CallbackObjectBase::CallSetup::~CallSetup() {
// were told to re-throw them.
if (mCx) {
bool needToDealWithException = mAutoEntryScript->HasException();
- if ((mRealm && mExceptionHandling == eRethrowContentExceptions) ||
- mExceptionHandling == eRethrowExceptions) {
+ if ((mRealm &&
+ mExceptionHandling == CallbackObjectBase::eRethrowContentExceptions) ||
+ mExceptionHandling == CallbackObjectBase::eRethrowExceptions) {
mErrorResult.MightThrowJSException();
if (needToDealWithException) {
JS::Rooted<JS::Value> exn(mCx);
diff --git a/dom/bindings/CallbackObject.h b/dom/bindings/CallbackObject.h
@@ -236,71 +236,70 @@ class CallbackObjectBase {
// here.
nsCOMPtr<nsIGlobalObject> mIncumbentGlobal;
JS::TenuredHeap<JSObject*> mIncumbentJSGlobal;
+};
- class MOZ_STACK_CLASS CallSetup {
- /**
- * A class that performs whatever setup we need to safely make a
- * call while this class is on the stack, After the constructor
- * returns, the call is safe to make if GetContext() returns
- * non-null.
- */
- public:
- // If aExceptionHandling == eRethrowContentExceptions then aRealm
- // needs to be set to the realm in which exceptions will be rethrown.
- //
- // If aExceptionHandling == eRethrowExceptions then aRealm may be set
- // to the realm in which exceptions will be rethrown. In that case
- // they will only be rethrown if that realm's principal subsumes the
- // principal of our (unwrapped) callback.
- CallSetup(CallbackObjectBase* aCallback, ErrorResult& aRv,
- const char* aExecutionReason,
- ExceptionHandling aExceptionHandling, JS::Realm* aRealm = nullptr,
- bool aIsJSImplementedWebIDL = false);
- MOZ_CAN_RUN_SCRIPT ~CallSetup();
-
- JSContext* GetContext() const { return mCx; }
-
- // Safe to call this after the constructor has run without throwing on the
- // ErrorResult it was handed.
- BindingCallContext& GetCallContext() { return *mCallContext; }
-
- private:
- // We better not get copy-constructed
- CallSetup(const CallSetup&) = delete;
+class MOZ_STACK_CLASS CallSetup {
+ /**
+ * A class that performs whatever setup we need to safely make a
+ * call while this class is on the stack, After the constructor
+ * returns, the call is safe to make if GetContext() returns
+ * non-null.
+ */
+ public:
+ // If aExceptionHandling == eRethrowContentExceptions then aRealm
+ // needs to be set to the realm in which exceptions will be rethrown.
+ //
+ // If aExceptionHandling == eRethrowExceptions then aRealm may be set
+ // to the realm in which exceptions will be rethrown. In that case
+ // they will only be rethrown if that realm's principal subsumes the
+ // principal of our (unwrapped) callback.
+ CallSetup(CallbackObjectBase* aCallback, ErrorResult& aRv,
+ const char* aExecutionReason,
+ CallbackObjectBase::ExceptionHandling aExceptionHandling,
+ JS::Realm* aRealm = nullptr, bool aIsJSImplementedWebIDL = false);
+ MOZ_CAN_RUN_SCRIPT ~CallSetup();
+
+ JSContext* GetContext() const { return mCx; }
+
+ // Safe to call this after the constructor has run without throwing on the
+ // ErrorResult it was handed.
+ BindingCallContext& GetCallContext() { return *mCallContext; }
- bool ShouldRethrowException(JS::Handle<JS::Value> aException);
+ private:
+ // We better not get copy-constructed
+ CallSetup(const CallSetup&) = delete;
- // Members which can go away whenever
- JSContext* mCx;
+ bool ShouldRethrowException(JS::Handle<JS::Value> aException);
- // Caller's realm. This will only have a sensible value if
- // mExceptionHandling == eRethrowContentExceptions.
- JS::Realm* mRealm;
+ // Members which can go away whenever
+ JSContext* mCx;
- // And now members whose construction/destruction order we need to control.
- Maybe<AutoEntryScript> mAutoEntryScript;
- Maybe<AutoIncumbentScript> mAutoIncumbentScript;
+ // Caller's realm. This will only have a sensible value if
+ // mExceptionHandling == eRethrowContentExceptions.
+ JS::Realm* mRealm;
- Maybe<JS::Rooted<JSObject*>> mRootedCallable;
+ // And now members whose construction/destruction order we need to control.
+ Maybe<AutoEntryScript> mAutoEntryScript;
+ Maybe<AutoIncumbentScript> mAutoIncumbentScript;
- Maybe<JS::AutoSetAsyncStackForNewCalls> mAsyncStackSetter;
+ Maybe<JS::Rooted<JSObject*>> mRootedCallable;
+ Maybe<JS::AutoSetAsyncStackForNewCalls> mAsyncStackSetter;
- // Can't construct a JSAutoRealm without a JSContext either. Also,
- // Put mAr after mAutoEntryScript so that we exit the realm before we
- // pop the script settings stack. Though in practice we'll often manually
- // order those two things.
- Maybe<JSAutoRealm> mAr;
+ // Can't construct a JSAutoRealm without a JSContext either. Also,
+ // Put mAr after mAutoEntryScript so that we exit the realm before we
+ // pop the script settings stack. Though in practice we'll often manually
+ // order those two things.
+ Maybe<JSAutoRealm> mAr;
- // Our BindingCallContext. This is a Maybe so we can avoid constructing it
- // until after we have a JSContext to construct it with.
- Maybe<BindingCallContext> mCallContext;
+ // Our BindingCallContext. This is a Maybe so we can avoid constructing it
+ // until after we have a JSContext to construct it with.
+ Maybe<BindingCallContext> mCallContext;
- // An ErrorResult to possibly re-throw exceptions on and whether
- // we should re-throw them.
- ErrorResult& mErrorResult;
- const ExceptionHandling mExceptionHandling;
- const bool mIsMainThread;
- };
+ // An ErrorResult to possibly re-throw exceptions on and whether
+ // we should re-throw them.
+ ErrorResult& mErrorResult;
+ const CallbackObjectBase::ExceptionHandling mExceptionHandling;
+ const bool mIsMainThread;
};
class CallbackObject : public nsISupports,