From e673afa8f2d939fbdf56393ebe6a0d8cd1570ecc Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Thu, 21 Jun 2012 16:14:49 +0200 Subject: [PATCH] Bug 755255 - Hoist pending exception junk into XPCJSRuntime. r=mrbkap --- js/xpconnect/idl/nsIXPConnect.idl | 4 +- js/xpconnect/src/XPCJSRuntime.cpp | 3 +- js/xpconnect/src/XPCThreadContext.cpp | 5 -- js/xpconnect/src/XPCThrower.cpp | 35 ++++----- js/xpconnect/src/XPCWrappedJSClass.cpp | 8 +-- js/xpconnect/src/XPCWrappedNative.cpp | 2 +- js/xpconnect/src/nsXPConnect.cpp | 26 ------- js/xpconnect/src/xpcprivate.h | 99 +++++++++++++------------- 8 files changed, 72 insertions(+), 110 deletions(-) diff --git a/js/xpconnect/idl/nsIXPConnect.idl b/js/xpconnect/idl/nsIXPConnect.idl index 4cadd30c6eb..69dce96d37c 100644 --- a/js/xpconnect/idl/nsIXPConnect.idl +++ b/js/xpconnect/idl/nsIXPConnect.idl @@ -374,7 +374,7 @@ enum nsGCType { }; %} -[uuid(1239b432-b835-4d28-9dc0-53063cb7f60f)] +[uuid(26efd266-3e33-4dc9-8233-e13bb8d9c452)] interface nsIXPConnect : nsISupports { %{ C++ @@ -561,8 +561,6 @@ interface nsIXPConnect : nsISupports readonly attribute nsIStackFrame CurrentJSStack; readonly attribute nsAXPCNativeCallContextPtr CurrentNativeCallContext; - /* pass nsnull to clear pending exception */ - attribute nsIException PendingException; void debugDump(in short depth); void debugDumpObject(in nsISupports aCOMObj, in short depth); diff --git a/js/xpconnect/src/XPCJSRuntime.cpp b/js/xpconnect/src/XPCJSRuntime.cpp index fce096046f8..da169a7b91f 100644 --- a/js/xpconnect/src/XPCJSRuntime.cpp +++ b/js/xpconnect/src/XPCJSRuntime.cpp @@ -1969,7 +1969,8 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect) mWatchdogWakeup(nsnull), mWatchdogThread(nsnull), mWatchdogHibernating(false), - mLastActiveTime(-1) + mLastActiveTime(-1), + mExceptionManagerNotAvailable(false) { #ifdef XPC_CHECK_WRAPPERS_AT_SHUTDOWN DEBUG_WrappedNativeHashtable = diff --git a/js/xpconnect/src/XPCThreadContext.cpp b/js/xpconnect/src/XPCThreadContext.cpp index 419fdc69ea4..31f67648009 100644 --- a/js/xpconnect/src/XPCThreadContext.cpp +++ b/js/xpconnect/src/XPCThreadContext.cpp @@ -244,9 +244,6 @@ XPCPerThreadData::XPCPerThreadData() : mNextThread(nsnull), mResolveName(JSID_VOID), mResolvingWrapper(nsnull), - mExceptionManager(nsnull), - mException(nsnull), - mExceptionManagerNotAvailable(false), mAutoRoots(nsnull) #ifdef XPC_CHECK_WRAPPER_THREADSAFETY , mWrappedNativeThreadsafetyReportDepth(0) @@ -264,8 +261,6 @@ void XPCPerThreadData::Cleanup() { MOZ_ASSERT(!mAutoRoots); - NS_IF_RELEASE(mExceptionManager); - NS_IF_RELEASE(mException); } XPCPerThreadData::~XPCPerThreadData() diff --git a/js/xpconnect/src/XPCThrower.cpp b/js/xpconnect/src/XPCThrower.cpp index 3324a103efb..cd9f23a1b6a 100644 --- a/js/xpconnect/src/XPCThrower.cpp +++ b/js/xpconnect/src/XPCThrower.cpp @@ -44,15 +44,11 @@ Throw(JSContext *cx, nsresult rv) JSBool XPCThrower::CheckForPendingException(nsresult result, JSContext *cx) { - nsXPConnect* xpc = nsXPConnect::GetXPConnect(); - if (!xpc) - return false; - nsCOMPtr e; - xpc->GetPendingException(getter_AddRefs(e)); + XPCJSRuntime::Get()->GetPendingException(getter_AddRefs(e)); if (!e) return false; - xpc->SetPendingException(nsnull); + XPCJSRuntime::Get()->SetPendingException(nsnull); nsresult e_result; if (NS_FAILED(e->GetResult(&e_result)) || e_result != result) @@ -184,22 +180,21 @@ XPCThrower::BuildAndThrowException(JSContext* cx, nsresult rv, const char* sz) nsCOMPtr finalException; nsCOMPtr defaultException; nsXPCException::NewException(sz, rv, nsnull, nsnull, getter_AddRefs(defaultException)); - XPCPerThreadData* tls = XPCPerThreadData::GetData(cx); - if (tls) { - nsIExceptionManager * exceptionManager = tls->GetExceptionManager(); - if (exceptionManager) { - // Ask the provider for the exception, if there is no provider - // we expect it to set e to null - exceptionManager->GetExceptionFromProvider(rv, - defaultException, - getter_AddRefs(finalException)); - // We should get at least the defaultException back, - // but just in case - if (finalException == nsnull) { - finalException = defaultException; - } + + nsIExceptionManager * exceptionManager = XPCJSRuntime::Get()->GetExceptionManager(); + if (exceptionManager) { + // Ask the provider for the exception, if there is no provider + // we expect it to set e to null + exceptionManager->GetExceptionFromProvider(rv, + defaultException, + getter_AddRefs(finalException)); + // We should get at least the defaultException back, + // but just in case + if (finalException == nsnull) { + finalException = defaultException; } } + // XXX Should we put the following test and call to JS_ReportOutOfMemory // inside this test? if (finalException) diff --git a/js/xpconnect/src/XPCWrappedJSClass.cpp b/js/xpconnect/src/XPCWrappedJSClass.cpp index 4a2f1987342..31cd4aef5e7 100644 --- a/js/xpconnect/src/XPCWrappedJSClass.cpp +++ b/js/xpconnect/src/XPCWrappedJSClass.cpp @@ -976,7 +976,7 @@ nsXPCWrappedJSClass::CheckForException(XPCCallContext & ccx, /* cleanup and set failed even if we can't build an exception */ if (!xpc_exception) { - ccx.GetThreadData()->SetException(nsnull); // XXX necessary? + XPCJSRuntime::Get()->SetPendingException(nsnull); // XXX necessary? } } @@ -1103,7 +1103,7 @@ nsXPCWrappedJSClass::CheckForException(XPCCallContext & ccx, // Whether or not it passes the 'reportable' test, it might // still be an error and we have to do the right thing here... if (NS_FAILED(e_result)) { - ccx.GetThreadData()->SetException(xpc_exception); + XPCJSRuntime::Get()->SetPendingException(xpc_exception); return e_result; } } @@ -1182,7 +1182,7 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS* wrapper, uint16_t methodIndex, xpcc->SetPendingResult(pending_result); xpcc->SetException(nsnull); - ccx.GetThreadData()->SetException(nsnull); + XPCJSRuntime::Get()->SetPendingException(nsnull); if (XPCPerThreadData::IsMainThread(ccx)) { // TODO Remove me in favor of security wrappers. @@ -1509,7 +1509,7 @@ pre_call_clean_up: return CheckForException(ccx, name, GetInterfaceName(), forceReport); } - ccx.GetThreadData()->SetException(nsnull); // XXX necessary? + XPCJSRuntime::Get()->SetPendingException(nsnull); // XXX necessary? // convert out args and result // NOTE: this is the total number of native params, not just the args diff --git a/js/xpconnect/src/XPCWrappedNative.cpp b/js/xpconnect/src/XPCWrappedNative.cpp index b3ca6e5f9ca..6e19368cfd2 100644 --- a/js/xpconnect/src/XPCWrappedNative.cpp +++ b/js/xpconnect/src/XPCWrappedNative.cpp @@ -2395,7 +2395,7 @@ CallMethodHelper::Call() { mCallContext.SetRetVal(JSVAL_VOID); - mCallContext.GetThreadData()->SetException(nsnull); + XPCJSRuntime::Get()->SetPendingException(nsnull); mCallContext.GetXPCContext()->SetLastResult(NS_ERROR_UNEXPECTED); if (mVTableIndex == 0) { diff --git a/js/xpconnect/src/nsXPConnect.cpp b/js/xpconnect/src/nsXPConnect.cpp index f072390f007..912555a2c66 100644 --- a/js/xpconnect/src/nsXPConnect.cpp +++ b/js/xpconnect/src/nsXPConnect.cpp @@ -1867,32 +1867,6 @@ nsXPConnect::GetCurrentNativeCallContext(nsAXPCNativeCallContext * *aCurrentNati return NS_OK; } -/* attribute nsIException PendingException; */ -NS_IMETHODIMP -nsXPConnect::GetPendingException(nsIException * *aPendingException) -{ - NS_ASSERTION(aPendingException, "bad param"); - - XPCPerThreadData* data = XPCPerThreadData::GetData(nsnull); - if (!data) { - *aPendingException = nsnull; - return UnexpectedFailure(NS_ERROR_FAILURE); - } - - return data->GetException(aPendingException); -} - -NS_IMETHODIMP -nsXPConnect::SetPendingException(nsIException * aPendingException) -{ - XPCPerThreadData* data = XPCPerThreadData::GetData(nsnull); - if (!data) - return UnexpectedFailure(NS_ERROR_FAILURE); - - data->SetException(aPendingException); - return NS_OK; -} - NS_IMETHODIMP nsXPConnect::SyncJSContexts(void) { diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index 4242d91b888..c8075d95878 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -776,6 +776,51 @@ public: ~XPCJSRuntime(); + nsresult GetPendingException(nsIException** aException) + { + if (EnsureExceptionManager()) + return mExceptionManager->GetCurrentException(aException); + nsCOMPtr out = mPendingException; + out.forget(aException); + return NS_OK; + } + + nsresult SetPendingException(nsIException* aException) + { + if (EnsureExceptionManager()) + return mExceptionManager->SetCurrentException(aException); + + mPendingException = aException; + return NS_OK; + } + + nsIExceptionManager* GetExceptionManager() + { + if (EnsureExceptionManager()) + return mExceptionManager; + return nsnull; + } + + bool EnsureExceptionManager() + { + if (mExceptionManager) + return true; + + if (mExceptionManagerNotAvailable) + return false; + + nsCOMPtr xs = + do_GetService(NS_EXCEPTIONSERVICE_CONTRACTID); + if (xs) + xs->GetCurrentExceptionManager(getter_AddRefs(mExceptionManager)); + if (mExceptionManager) + return true; + + mExceptionManagerNotAvailable = true; + return false; + } + + #ifdef XPC_CHECK_WRAPPERS_AT_SHUTDOWN void DEBUG_AddWrappedNative(nsIXPConnectWrappedNative* wrapper) {XPCAutoLock lock(GetMapLock()); @@ -857,6 +902,10 @@ private: bool mWatchdogHibernating; PRTime mLastActiveTime; // -1 if active NOW + nsCOMPtr mPendingException; + nsCOMPtr mExceptionManager; + bool mExceptionManagerNotAvailable; + friend class AutoLockWatchdog; }; @@ -3687,53 +3736,6 @@ public: ~XPCPerThreadData(); - nsresult GetException(nsIException** aException) - { - if (EnsureExceptionManager()) - return mExceptionManager->GetCurrentException(aException); - - NS_IF_ADDREF(mException); - *aException = mException; - return NS_OK; - } - - nsresult SetException(nsIException* aException) - { - if (EnsureExceptionManager()) - return mExceptionManager->SetCurrentException(aException); - - NS_IF_ADDREF(aException); - NS_IF_RELEASE(mException); - mException = aException; - return NS_OK; - } - - nsIExceptionManager* GetExceptionManager() - { - if (EnsureExceptionManager()) - return mExceptionManager; - return nsnull; - } - - JSBool EnsureExceptionManager() - { - if (mExceptionManager) - return true; - - if (mExceptionManagerNotAvailable) - return false; - - nsCOMPtr xs = - do_GetService(NS_EXCEPTIONSERVICE_CONTRACTID); - if (xs) - xs->GetCurrentExceptionManager(&mExceptionManager); - if (mExceptionManager) - return true; - - mExceptionManagerNotAvailable = true; - return false; - } - jsid GetResolveName() const {return mResolveName;} jsid SetResolveName(jsid name) {jsid old = mResolveName; mResolveName = name; return old;} @@ -3782,9 +3784,6 @@ private: jsid mResolveName; XPCWrappedNative* mResolvingWrapper; - nsIExceptionManager* mExceptionManager; - nsIException* mException; - JSBool mExceptionManagerNotAvailable; AutoMarkingPtr* mAutoRoots; #ifdef XPC_CHECK_WRAPPER_THREADSAFETY