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
{
%{ 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);

View File

@ -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 =

View File

@ -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()

View File

@ -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<nsIException> 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,9 +180,8 @@ XPCThrower::BuildAndThrowException(JSContext* cx, nsresult rv, const char* sz)
nsCOMPtr<nsIException> finalException;
nsCOMPtr<nsIException> defaultException;
nsXPCException::NewException(sz, rv, nsnull, nsnull, getter_AddRefs(defaultException));
XPCPerThreadData* tls = XPCPerThreadData::GetData(cx);
if (tls) {
nsIExceptionManager * exceptionManager = tls->GetExceptionManager();
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
@ -199,7 +194,7 @@ XPCThrower::BuildAndThrowException(JSContext* cx, nsresult rv, const char* sz)
finalException = defaultException;
}
}
}
// XXX Should we put the following test and call to JS_ReportOutOfMemory
// inside this test?
if (finalException)

View File

@ -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

View File

@ -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) {

View File

@ -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)
{

View File

@ -776,6 +776,51 @@ public:
~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
void DEBUG_AddWrappedNative(nsIXPConnectWrappedNative* wrapper)
{XPCAutoLock lock(GetMapLock());
@ -857,6 +902,10 @@ private:
bool mWatchdogHibernating;
PRTime mLastActiveTime; // -1 if active NOW
nsCOMPtr<nsIException> mPendingException;
nsCOMPtr<nsIExceptionManager> 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<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 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