Bug 755255 - Hoist pending exception junk into XPCJSRuntime. r=mrbkap

This commit is contained in:
Bobby Holley 2012-06-21 16:14:49 +02:00
parent 718b02a083
commit e673afa8f2
8 changed files with 72 additions and 110 deletions

View File

@ -374,7 +374,7 @@ enum nsGCType {
}; };
%} %}
[uuid(1239b432-b835-4d28-9dc0-53063cb7f60f)] [uuid(26efd266-3e33-4dc9-8233-e13bb8d9c452)]
interface nsIXPConnect : nsISupports interface nsIXPConnect : nsISupports
{ {
%{ C++ %{ C++
@ -561,8 +561,6 @@ interface nsIXPConnect : nsISupports
readonly attribute nsIStackFrame CurrentJSStack; readonly attribute nsIStackFrame CurrentJSStack;
readonly attribute nsAXPCNativeCallContextPtr CurrentNativeCallContext; readonly attribute nsAXPCNativeCallContextPtr CurrentNativeCallContext;
/* pass nsnull to clear pending exception */
attribute nsIException PendingException;
void debugDump(in short depth); void debugDump(in short depth);
void debugDumpObject(in nsISupports aCOMObj, in short depth); void debugDumpObject(in nsISupports aCOMObj, in short depth);

View File

@ -1969,7 +1969,8 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
mWatchdogWakeup(nsnull), mWatchdogWakeup(nsnull),
mWatchdogThread(nsnull), mWatchdogThread(nsnull),
mWatchdogHibernating(false), mWatchdogHibernating(false),
mLastActiveTime(-1) mLastActiveTime(-1),
mExceptionManagerNotAvailable(false)
{ {
#ifdef XPC_CHECK_WRAPPERS_AT_SHUTDOWN #ifdef XPC_CHECK_WRAPPERS_AT_SHUTDOWN
DEBUG_WrappedNativeHashtable = DEBUG_WrappedNativeHashtable =

View File

@ -244,9 +244,6 @@ XPCPerThreadData::XPCPerThreadData() :
mNextThread(nsnull), mNextThread(nsnull),
mResolveName(JSID_VOID), mResolveName(JSID_VOID),
mResolvingWrapper(nsnull), mResolvingWrapper(nsnull),
mExceptionManager(nsnull),
mException(nsnull),
mExceptionManagerNotAvailable(false),
mAutoRoots(nsnull) mAutoRoots(nsnull)
#ifdef XPC_CHECK_WRAPPER_THREADSAFETY #ifdef XPC_CHECK_WRAPPER_THREADSAFETY
, mWrappedNativeThreadsafetyReportDepth(0) , mWrappedNativeThreadsafetyReportDepth(0)
@ -264,8 +261,6 @@ void
XPCPerThreadData::Cleanup() XPCPerThreadData::Cleanup()
{ {
MOZ_ASSERT(!mAutoRoots); MOZ_ASSERT(!mAutoRoots);
NS_IF_RELEASE(mExceptionManager);
NS_IF_RELEASE(mException);
} }
XPCPerThreadData::~XPCPerThreadData() XPCPerThreadData::~XPCPerThreadData()

View File

@ -44,15 +44,11 @@ Throw(JSContext *cx, nsresult rv)
JSBool JSBool
XPCThrower::CheckForPendingException(nsresult result, JSContext *cx) XPCThrower::CheckForPendingException(nsresult result, JSContext *cx)
{ {
nsXPConnect* xpc = nsXPConnect::GetXPConnect();
if (!xpc)
return false;
nsCOMPtr<nsIException> e; nsCOMPtr<nsIException> e;
xpc->GetPendingException(getter_AddRefs(e)); XPCJSRuntime::Get()->GetPendingException(getter_AddRefs(e));
if (!e) if (!e)
return false; return false;
xpc->SetPendingException(nsnull); XPCJSRuntime::Get()->SetPendingException(nsnull);
nsresult e_result; nsresult e_result;
if (NS_FAILED(e->GetResult(&e_result)) || e_result != 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<nsIException> finalException; nsCOMPtr<nsIException> finalException;
nsCOMPtr<nsIException> defaultException; nsCOMPtr<nsIException> defaultException;
nsXPCException::NewException(sz, rv, nsnull, nsnull, getter_AddRefs(defaultException)); nsXPCException::NewException(sz, rv, nsnull, nsnull, getter_AddRefs(defaultException));
XPCPerThreadData* tls = XPCPerThreadData::GetData(cx);
if (tls) { nsIExceptionManager * exceptionManager = XPCJSRuntime::Get()->GetExceptionManager();
nsIExceptionManager * exceptionManager = tls->GetExceptionManager(); if (exceptionManager) {
if (exceptionManager) { // Ask the provider for the exception, if there is no provider
// Ask the provider for the exception, if there is no provider // we expect it to set e to null
// we expect it to set e to null exceptionManager->GetExceptionFromProvider(rv,
exceptionManager->GetExceptionFromProvider(rv, defaultException,
defaultException, getter_AddRefs(finalException));
getter_AddRefs(finalException)); // We should get at least the defaultException back,
// We should get at least the defaultException back, // but just in case
// but just in case if (finalException == nsnull) {
if (finalException == nsnull) { finalException = defaultException;
finalException = defaultException;
}
} }
} }
// XXX Should we put the following test and call to JS_ReportOutOfMemory // XXX Should we put the following test and call to JS_ReportOutOfMemory
// inside this test? // inside this test?
if (finalException) if (finalException)

View File

@ -976,7 +976,7 @@ nsXPCWrappedJSClass::CheckForException(XPCCallContext & ccx,
/* cleanup and set failed even if we can't build an exception */ /* cleanup and set failed even if we can't build an exception */
if (!xpc_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 // Whether or not it passes the 'reportable' test, it might
// still be an error and we have to do the right thing here... // still be an error and we have to do the right thing here...
if (NS_FAILED(e_result)) { if (NS_FAILED(e_result)) {
ccx.GetThreadData()->SetException(xpc_exception); XPCJSRuntime::Get()->SetPendingException(xpc_exception);
return e_result; return e_result;
} }
} }
@ -1182,7 +1182,7 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS* wrapper, uint16_t methodIndex,
xpcc->SetPendingResult(pending_result); xpcc->SetPendingResult(pending_result);
xpcc->SetException(nsnull); xpcc->SetException(nsnull);
ccx.GetThreadData()->SetException(nsnull); XPCJSRuntime::Get()->SetPendingException(nsnull);
if (XPCPerThreadData::IsMainThread(ccx)) { if (XPCPerThreadData::IsMainThread(ccx)) {
// TODO Remove me in favor of security wrappers. // TODO Remove me in favor of security wrappers.
@ -1509,7 +1509,7 @@ pre_call_clean_up:
return CheckForException(ccx, name, GetInterfaceName(), forceReport); return CheckForException(ccx, name, GetInterfaceName(), forceReport);
} }
ccx.GetThreadData()->SetException(nsnull); // XXX necessary? XPCJSRuntime::Get()->SetPendingException(nsnull); // XXX necessary?
// convert out args and result // convert out args and result
// NOTE: this is the total number of native params, not just the args // NOTE: this is the total number of native params, not just the args

View File

@ -2395,7 +2395,7 @@ CallMethodHelper::Call()
{ {
mCallContext.SetRetVal(JSVAL_VOID); mCallContext.SetRetVal(JSVAL_VOID);
mCallContext.GetThreadData()->SetException(nsnull); XPCJSRuntime::Get()->SetPendingException(nsnull);
mCallContext.GetXPCContext()->SetLastResult(NS_ERROR_UNEXPECTED); mCallContext.GetXPCContext()->SetLastResult(NS_ERROR_UNEXPECTED);
if (mVTableIndex == 0) { if (mVTableIndex == 0) {

View File

@ -1867,32 +1867,6 @@ nsXPConnect::GetCurrentNativeCallContext(nsAXPCNativeCallContext * *aCurrentNati
return NS_OK; 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 NS_IMETHODIMP
nsXPConnect::SyncJSContexts(void) nsXPConnect::SyncJSContexts(void)
{ {

View File

@ -776,6 +776,51 @@ public:
~XPCJSRuntime(); ~XPCJSRuntime();
nsresult GetPendingException(nsIException** aException)
{
if (EnsureExceptionManager())
return mExceptionManager->GetCurrentException(aException);
nsCOMPtr<nsIException> 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<nsIExceptionService> 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 #ifdef XPC_CHECK_WRAPPERS_AT_SHUTDOWN
void DEBUG_AddWrappedNative(nsIXPConnectWrappedNative* wrapper) void DEBUG_AddWrappedNative(nsIXPConnectWrappedNative* wrapper)
{XPCAutoLock lock(GetMapLock()); {XPCAutoLock lock(GetMapLock());
@ -857,6 +902,10 @@ private:
bool mWatchdogHibernating; bool mWatchdogHibernating;
PRTime mLastActiveTime; // -1 if active NOW PRTime mLastActiveTime; // -1 if active NOW
nsCOMPtr<nsIException> mPendingException;
nsCOMPtr<nsIExceptionManager> mExceptionManager;
bool mExceptionManagerNotAvailable;
friend class AutoLockWatchdog; friend class AutoLockWatchdog;
}; };
@ -3687,53 +3736,6 @@ public:
~XPCPerThreadData(); ~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<nsIExceptionService> 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 GetResolveName() const {return mResolveName;}
jsid SetResolveName(jsid name) jsid SetResolveName(jsid name)
{jsid old = mResolveName; mResolveName = name; return old;} {jsid old = mResolveName; mResolveName = name; return old;}
@ -3782,9 +3784,6 @@ private:
jsid mResolveName; jsid mResolveName;
XPCWrappedNative* mResolvingWrapper; XPCWrappedNative* mResolvingWrapper;
nsIExceptionManager* mExceptionManager;
nsIException* mException;
JSBool mExceptionManagerNotAvailable;
AutoMarkingPtr* mAutoRoots; AutoMarkingPtr* mAutoRoots;
#ifdef XPC_CHECK_WRAPPER_THREADSAFETY #ifdef XPC_CHECK_WRAPPER_THREADSAFETY