Bug 459656 - Implementing nsIThreadJSContextStack in nsXPConnect. r+sr=mrbkap

This commit is contained in:
Igor Bukanov 2008-10-14 16:16:25 +02:00
Родитель 9167fa6368
Коммит 4ecbd37ca7
6 изменённых файлов: 148 добавлений и 274 удалений

Просмотреть файл

@ -587,7 +587,6 @@ private:
nsCOMPtr<nsIPrincipal> mSystemPrincipal;
nsCOMPtr<nsIPrincipal> mSystemCertificate;
nsInterfaceHashtable<PrincipalKey, nsIPrincipal> mPrincipals;
nsCOMPtr<nsIThreadJSContextStack> mJSContextStack;
PRPackedBool mIsJavaScriptEnabled;
PRPackedBool mIsMailJavaScriptEnabled;
PRPackedBool mIsWritingPrefs;
@ -601,6 +600,7 @@ private:
static nsIIOService *sIOService;
static nsIXPConnect *sXPConnect;
static nsIThreadJSContextStack* sJSContextStack;
static nsIStringBundle *sStrBundle;
static JSRuntime *sRuntime;
};

Просмотреть файл

@ -98,6 +98,7 @@ static NS_DEFINE_CID(kZipReaderCID, NS_ZIPREADER_CID);
nsIIOService *nsScriptSecurityManager::sIOService = nsnull;
nsIXPConnect *nsScriptSecurityManager::sXPConnect = nsnull;
nsIThreadJSContextStack *nsScriptSecurityManager::sJSContextStack = nsnull;
nsIStringBundle *nsScriptSecurityManager::sStrBundle = nsnull;
JSRuntime *nsScriptSecurityManager::sRuntime = 0;
PRBool nsScriptSecurityManager::sStrictFileOriginPolicy = PR_TRUE;
@ -305,14 +306,8 @@ JSContext *
nsScriptSecurityManager::GetCurrentJSContext()
{
// Get JSContext from stack.
if (!mJSContextStack)
{
mJSContextStack = do_GetService("@mozilla.org/js/xpc/ContextStack;1");
if (!mJSContextStack)
return nsnull;
}
JSContext *cx;
if (NS_FAILED(mJSContextStack->Peek(&cx)))
if (NS_FAILED(sJSContextStack->Peek(&cx)))
return nsnull;
return cx;
}
@ -321,14 +316,8 @@ JSContext *
nsScriptSecurityManager::GetSafeJSContext()
{
// Get JSContext from stack.
if (!mJSContextStack) {
mJSContextStack = do_GetService("@mozilla.org/js/xpc/ContextStack;1");
if (!mJSContextStack)
return nsnull;
}
JSContext *cx;
if (NS_FAILED(mJSContextStack->GetSafeJSContext(&cx)))
if (NS_FAILED(sJSContextStack->GetSafeJSContext(&cx)))
return nsnull;
return cx;
}
@ -3235,6 +3224,12 @@ nsScriptSecurityManager::nsScriptSecurityManager(void)
nsresult nsScriptSecurityManager::Init()
{
nsresult rv = CallGetService(nsIXPConnect::GetCID(), &sXPConnect);
NS_ENSURE_SUCCESS(rv, rv);
rv = CallGetService("@mozilla.org/js/xpc/ContextStack;1", &sJSContextStack);
NS_ENSURE_SUCCESS(rv, rv);
JSContext* cx = GetSafeJSContext();
if (!cx) return NS_ERROR_FAILURE; // this can happen of xpt loading fails
@ -3243,15 +3238,12 @@ nsresult nsScriptSecurityManager::Init()
sEnabledID = STRING_TO_JSVAL(::JS_InternString(cx, "enabled"));
::JS_EndRequest(cx);
nsresult rv = InitPrefs();
rv = InitPrefs();
NS_ENSURE_SUCCESS(rv, rv);
rv = CallGetService(NS_IOSERVICE_CONTRACTID, &sIOService);
NS_ENSURE_SUCCESS(rv, rv);
rv = CallGetService(nsIXPConnect::GetCID(), &sXPConnect);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIStringBundleService> bundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
@ -3318,6 +3310,7 @@ nsScriptSecurityManager::Shutdown()
NS_IF_RELEASE(sIOService);
NS_IF_RELEASE(sXPConnect);
NS_IF_RELEASE(sJSContextStack);
NS_IF_RELEASE(sStrBundle);
}
@ -3419,7 +3412,7 @@ nsScriptSecurityManager::InitPolicies()
// Get a JS context - we need it to create internalized strings later.
JSContext* cx = GetSafeJSContext();
NS_ASSERTION(cx, "failed to get JS context");
AutoCxPusher autoPusher(mJSContextStack, cx);
AutoCxPusher autoPusher(sJSContextStack, cx);
rv = InitDomainPolicy(cx, "default", mDefaultPolicy);
NS_ENSURE_SUCCESS(rv, rv);

Просмотреть файл

@ -53,11 +53,13 @@
#include "nsThreadUtilsInternal.h"
#include "dom_quickstubs.h"
NS_IMPL_THREADSAFE_ISUPPORTS4(nsXPConnect,
NS_IMPL_THREADSAFE_ISUPPORTS6(nsXPConnect,
nsIXPConnect,
nsISupportsWeakReference,
nsIThreadObserver,
nsIJSRuntimeService)
nsIJSRuntimeService,
nsIJSContextStack,
nsIThreadJSContextStack)
nsXPConnect* nsXPConnect::gSelf = nsnull;
JSBool nsXPConnect::gOnceAliveNowDead = JS_FALSE;
@ -80,7 +82,6 @@ const char XPC_XPCONNECT_CONTRACTID[] = "@mozilla.org/js/xpc/XPConnect;1";
nsXPConnect::nsXPConnect()
: mRuntime(nsnull),
mInterfaceInfoManager(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID)),
mContextStack(nsnull),
mDefaultSecurityManager(nsnull),
mDefaultSecurityManagerFlags(0),
mShuttingDown(JS_FALSE),
@ -89,8 +90,6 @@ nsXPConnect::nsXPConnect()
{
mRuntime = XPCJSRuntime::newXPCJSRuntime(this);
CallGetService(XPC_CONTEXT_STACK_CONTRACTID, &mContextStack);
nsCycleCollector_registerRuntime(nsIProgrammingLanguage::JAVASCRIPT, this);
#ifdef DEBUG_CC
mJSRoots.ops = nsnull;
@ -155,7 +154,6 @@ nsXPConnect::~nsXPConnect()
JS_DestroyContext(cx);
}
NS_IF_RELEASE(mContextStack);
NS_IF_RELEASE(mDefaultSecurityManager);
gScriptSecurityManager = nsnull;
@ -182,8 +180,7 @@ nsXPConnect::GetXPConnect()
return nsnull;
if(!gSelf->mRuntime ||
!gSelf->mInterfaceInfoManager ||
!gSelf->mContextStack)
!gSelf->mInterfaceInfoManager)
{
// ctor failed to create an acceptable instance
delete gSelf;
@ -232,22 +229,25 @@ nsXPConnect::ReleaseXPConnectSingleton()
#ifdef DEBUG
// force a dump of the JavaScript gc heap if JS is still alive
// if requested through XPC_SHUTDOWN_HEAP_DUMP environment variable
XPCCallContext ccx(NATIVE_CALLER);
if(ccx.IsValid())
{
const char* dumpName = getenv("XPC_SHUTDOWN_HEAP_DUMP");
if(dumpName)
// autoscope
XPCCallContext ccx(NATIVE_CALLER);
if(ccx.IsValid())
{
FILE* dumpFile = (*dumpName == '\0' ||
strcmp(dumpName, "stdout") == 0)
? stdout
: fopen(dumpName, "w");
if(dumpFile)
const char* dumpName = getenv("XPC_SHUTDOWN_HEAP_DUMP");
if(dumpName)
{
JS_DumpHeap(ccx, dumpFile, nsnull, 0, nsnull,
static_cast<size_t>(-1), nsnull);
if(dumpFile != stdout)
fclose(dumpFile);
FILE* dumpFile = (*dumpName == '\0' ||
strcmp(dumpName, "stdout") == 0)
? stdout
: fopen(dumpName, "w");
if(dumpFile)
{
JS_DumpHeap(ccx, dumpFile, nsnull, 0, nsnull,
static_cast<size_t>(-1), nsnull);
if(dumpFile != stdout)
fclose(dumpFile);
}
}
}
}
@ -281,21 +281,6 @@ nsXPConnect::GetInterfaceInfoManager(nsIInterfaceInfoSuperManager** iim,
return NS_OK;
}
// static
nsresult
nsXPConnect::GetContextStack(nsIThreadJSContextStack** stack,
nsXPConnect* xpc /*= nsnull*/)
{
nsIThreadJSContextStack* temp;
if(!xpc && !(xpc = GetXPConnect()))
return NS_ERROR_FAILURE;
*stack = temp = xpc->mContextStack;
NS_IF_ADDREF(temp);
return NS_OK;
}
// static
XPCJSRuntime*
nsXPConnect::GetRuntimeInstance()
@ -1591,7 +1576,7 @@ nsXPConnect::GetCurrentJSStack(nsIStackFrame * *aCurrentJSStack)
JSContext* cx;
// is there a current context available?
if(mContextStack && NS_SUCCEEDED(mContextStack->Peek(&cx)) && cx)
if(NS_SUCCEEDED(Peek(&cx)) && cx)
{
nsCOMPtr<nsIStackFrame> stack;
XPCJSStack::CreateStack(cx, getter_AddRefs(stack));
@ -2043,7 +2028,6 @@ nsXPConnect::DebugDump(PRInt16 depth)
XPC_LOG_ALWAYS(("mDefaultSecurityManager @ %x", mDefaultSecurityManager));
XPC_LOG_ALWAYS(("mDefaultSecurityManagerFlags of %x", mDefaultSecurityManagerFlags));
XPC_LOG_ALWAYS(("mInterfaceInfoManager @ %x", mInterfaceInfoManager.get()));
XPC_LOG_ALWAYS(("mContextStack @ %x", mContextStack));
if(mRuntime)
{
if(depth)
@ -2118,12 +2102,7 @@ nsXPConnect::DebugDumpJSStack(PRBool showArgs,
PRBool showThisProps)
{
JSContext* cx;
nsresult rv;
nsCOMPtr<nsIThreadJSContextStack> stack =
do_GetService(XPC_CONTEXT_STACK_CONTRACTID, &rv);
if(NS_FAILED(rv) || !stack)
printf("failed to get nsIThreadJSContextStack service!\n");
else if(NS_FAILED(stack->Peek(&cx)))
if(NS_FAILED(Peek(&cx)))
printf("failed to peek into nsIThreadJSContextStack service!\n");
else if(!cx)
printf("there is no JSContext on the nsIThreadJSContextStack!\n");
@ -2138,12 +2117,7 @@ NS_IMETHODIMP
nsXPConnect::DebugDumpEvalInJSStackFrame(PRUint32 aFrameNumber, const char *aSourceText)
{
JSContext* cx;
nsresult rv;
nsCOMPtr<nsIThreadJSContextStack> stack =
do_GetService(XPC_CONTEXT_STACK_CONTRACTID, &rv);
if(NS_FAILED(rv) || !stack)
printf("failed to get nsIThreadJSContextStack service!\n");
else if(NS_FAILED(stack->Peek(&cx)))
if(NS_FAILED(Peek(&cx)))
printf("failed to peek into nsIThreadJSContextStack service!\n");
else if(!cx)
printf("there is no JSContext on the nsIThreadJSContextStack!\n");
@ -2220,16 +2194,14 @@ nsXPConnect::OnProcessNextEvent(nsIThreadInternal *aThread, PRBool aMayWait,
{
// Push a null JSContext so that we don't see any script during
// event processing.
NS_ENSURE_STATE(mContextStack);
return mContextStack->Push(nsnull);
return Push(nsnull);
}
NS_IMETHODIMP
nsXPConnect::AfterProcessNextEvent(nsIThreadInternal *aThread,
PRUint32 aRecursionDepth)
{
NS_ENSURE_STATE(mContextStack);
return mContextStack->Pop(nsnull);
return Pop(nsnull);
}
NS_IMETHODIMP
@ -2309,6 +2281,101 @@ nsXPConnect::GetBackstagePass(nsIXPCScriptable **bsp)
return NS_OK;
}
// nsIJSContextStack and nsIThreadJSContextStack implementations
/* readonly attribute PRInt32 Count; */
NS_IMETHODIMP
nsXPConnect::GetCount(PRInt32 *aCount)
{
if(!aCount)
return NS_ERROR_NULL_POINTER;
XPCPerThreadData* data = XPCPerThreadData::GetData(nsnull);
if(!data)
{
*aCount = 0;
return NS_ERROR_FAILURE;
}
return data->GetJSContextStack()->GetCount(aCount);
}
/* JSContext Peek (); */
NS_IMETHODIMP
nsXPConnect::Peek(JSContext * *_retval)
{
if(!_retval)
return NS_ERROR_NULL_POINTER;
XPCPerThreadData* data = XPCPerThreadData::GetData(nsnull);
if(!data)
{
*_retval = nsnull;
return NS_ERROR_FAILURE;
}
return data->GetJSContextStack()->Peek(_retval);
}
/* JSContext Pop (); */
NS_IMETHODIMP
nsXPConnect::Pop(JSContext * *_retval)
{
XPCPerThreadData* data = XPCPerThreadData::GetData(nsnull);
if(!data)
{
if(_retval)
*_retval = nsnull;
return NS_ERROR_FAILURE;
}
return data->GetJSContextStack()->Pop(_retval);
}
/* void Push (in JSContext cx); */
NS_IMETHODIMP
nsXPConnect::Push(JSContext * cx)
{
XPCPerThreadData* data = XPCPerThreadData::GetData(cx);
if(!data)
return NS_ERROR_FAILURE;
return data->GetJSContextStack()->Push(cx);
}
/* attribute JSContext SafeJSContext; */
NS_IMETHODIMP
nsXPConnect::GetSafeJSContext(JSContext * *aSafeJSContext)
{
NS_ASSERTION(aSafeJSContext, "loser!");
XPCPerThreadData* data = XPCPerThreadData::GetData(nsnull);
if(!data)
{
*aSafeJSContext = nsnull;
return NS_ERROR_FAILURE;
}
return data->GetJSContextStack()->GetSafeJSContext(aSafeJSContext);
}
/* attribute JSContext SafeJSContext; */
NS_IMETHODIMP
nsXPConnect::SetSafeJSContext(JSContext * aSafeJSContext)
{
XPCPerThreadData* data = XPCPerThreadData::GetData(aSafeJSContext);
if(!data)
return NS_ERROR_FAILURE;
return data->GetJSContextStack()->SetSafeJSContext(aSafeJSContext);
}
/* These are here to be callable from a debugger */
JS_BEGIN_EXTERN_C
JS_EXPORT_API(void) DumpJSStack()

Просмотреть файл

@ -66,7 +66,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsJSID)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsXPCException)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsXPCJSContextStackIterator)
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIXPConnect, nsXPConnect::GetSingleton)
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIJSContextStack, nsXPCThreadJSContextStackImpl::GetSingleton)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsScriptError)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsXPCComponents_Interfaces)
@ -83,7 +82,7 @@ NS_DECL_CLASSINFO(nsXPCException)
static const nsModuleComponentInfo components[] = {
{nsnull, NS_JS_ID_CID, XPC_ID_CONTRACTID, nsJSIDConstructor },
{nsnull, NS_XPCONNECT_CID, XPC_XPCONNECT_CONTRACTID, nsIXPConnectConstructor },
{nsnull, NS_XPC_THREAD_JSCONTEXT_STACK_CID, XPC_CONTEXT_STACK_CONTRACTID, nsIJSContextStackConstructor },
{nsnull, NS_XPC_THREAD_JSCONTEXT_STACK_CID, XPC_CONTEXT_STACK_CONTRACTID, nsIXPConnectConstructor },
{nsnull, NS_XPCEXCEPTION_CID, XPC_EXCEPTION_CONTRACTID, nsXPCExceptionConstructor, nsnull, nsnull, nsnull, NS_CI_INTERFACE_GETTER_NAME(nsXPCException), nsnull, &NS_CLASSINFO_NAME(nsXPCException), nsIClassInfo::DOM_OBJECT },
{nsnull, NS_JS_RUNTIME_SERVICE_CID, XPC_RUNTIME_CONTRACTID, nsIXPConnectConstructor},
{NS_SCRIPTERROR_CLASSNAME, NS_SCRIPTERROR_CID, NS_SCRIPTERROR_CONTRACTID, nsScriptErrorConstructor },
@ -114,7 +113,6 @@ xpcModuleCtor(nsIModule* self)
nsXPCException::InitStatics();
XPCWrappedNativeScope::InitStatics();
XPCPerThreadData::InitStatics();
nsXPCThreadJSContextStackImpl::InitStatics();
#ifdef XPC_IDISPATCH_SUPPORT
XPCIDispatchExtension::InitStatics();
@ -128,7 +126,6 @@ xpcModuleDtor(nsIModule* self)
{
// Release our singletons
nsXPConnect::ReleaseXPConnectSingleton();
nsXPCThreadJSContextStackImpl::FreeSingleton();
xpc_DestroyJSxIDClassObjects();
#ifdef XPC_IDISPATCH_SUPPORT
nsDispatchSupport::FreeSingleton();

Просмотреть файл

@ -446,12 +446,17 @@ const PRBool OBJ_IS_NOT_GLOBAL = PR_FALSE;
{0xb5e65b52, 0x1dd1, 0x11b2, \
{ 0xae, 0x8f, 0xf0, 0x92, 0x8e, 0xd8, 0x84, 0x82 }}
#define NS_XPC_THREAD_JSCONTEXT_STACK_CID \
{ 0xff8c4d10, 0x3194, 0x11d3, \
{ 0x98, 0x85, 0x0, 0x60, 0x8, 0x96, 0x24, 0x22 } }
class nsXPConnect : public nsIXPConnect,
public nsIThreadObserver,
public nsSupportsWeakReference,
public nsCycleCollectionJSRuntime,
public nsCycleCollectionParticipant,
public nsIJSRuntimeService
public nsIJSRuntimeService,
public nsIThreadJSContextStack
{
public:
// all the interface method declarations...
@ -459,6 +464,8 @@ public:
NS_DECL_NSIXPCONNECT
NS_DECL_NSITHREADOBSERVER
NS_DECL_NSIJSRUNTIMESERVICE
NS_DECL_NSIJSCONTEXTSTACK
NS_DECL_NSITHREADJSCONTEXTSTACK
// non-interface implementation
public:
@ -471,10 +478,6 @@ public:
static nsresult GetInterfaceInfoManager(nsIInterfaceInfoSuperManager** iim,
nsXPConnect* xpc = nsnull);
// Gets addref'd pointer
static nsresult GetContextStack(nsIThreadJSContextStack** stack,
nsXPConnect* xpc = nsnull);
static JSBool IsISupportsDescendant(nsIInterfaceInfo* info);
nsIXPCSecurityManager* GetDefaultSecurityManager() const
@ -559,7 +562,6 @@ private:
XPCJSRuntime* mRuntime;
nsCOMPtr<nsIInterfaceInfoSuperManager> mInterfaceInfoManager;
nsIThreadJSContextStack* mContextStack;
nsIXPCSecurityManager* mDefaultSecurityManager;
PRUint16 mDefaultSecurityManagerFlags;
JSBool mShuttingDown;
@ -3228,40 +3230,6 @@ private:
static XPCPerThreadData *sMainThreadData;
};
/**************************************************************/
#define NS_XPC_THREAD_JSCONTEXT_STACK_CID \
{ 0xff8c4d10, 0x3194, 0x11d3, \
{ 0x98, 0x85, 0x0, 0x60, 0x8, 0x96, 0x24, 0x22 } }
class nsXPCThreadJSContextStackImpl : public nsIThreadJSContextStack,
public nsSupportsWeakReference
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIJSCONTEXTSTACK
NS_DECL_NSITHREADJSCONTEXTSTACK
// This returns and AddRef'd pointer. It does not do this with an out param
// only because this form is required by generic module macro:
// NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR
static nsXPCThreadJSContextStackImpl* GetSingleton();
static void InitStatics() { gXPCThreadJSContextStack = nsnull; }
static void FreeSingleton();
nsXPCThreadJSContextStackImpl();
virtual ~nsXPCThreadJSContextStackImpl();
private:
XPCJSContextStack* GetStackForCurrentThread(JSContext *cx = nsnull)
{XPCPerThreadData* data = XPCPerThreadData::GetData(cx);
return data ? data->GetJSContextStack() : nsnull;}
static nsXPCThreadJSContextStackImpl* gXPCThreadJSContextStack;
friend class nsXPCJSContextStackIterator;
};
/***************************************************************************/
#ifndef XPCONNECT_STANDALONE
#include "nsIScriptSecurityManager.h"

Просмотреть файл

@ -273,156 +273,6 @@ XPCJSContextStack::SetSafeJSContext(JSContext * aSafeJSContext)
/***************************************************************************/
/*
* nsXPCThreadJSContextStackImpl holds state that we don't want to lose!
*
* The plan is that once created nsXPCThreadJSContextStackImpl never goes
* away until FreeSingleton is called. We do an intentional extra addref at
* construction to keep it around even if no one is using it.
*/
NS_IMPL_THREADSAFE_ISUPPORTS3(nsXPCThreadJSContextStackImpl,
nsIThreadJSContextStack,
nsIJSContextStack,
nsISupportsWeakReference)
nsXPCThreadJSContextStackImpl*
nsXPCThreadJSContextStackImpl::gXPCThreadJSContextStack = nsnull;
nsXPCThreadJSContextStackImpl::nsXPCThreadJSContextStackImpl()
{
}
nsXPCThreadJSContextStackImpl::~nsXPCThreadJSContextStackImpl()
{
gXPCThreadJSContextStack = nsnull;
}
//static
nsXPCThreadJSContextStackImpl*
nsXPCThreadJSContextStackImpl::GetSingleton()
{
if(!gXPCThreadJSContextStack)
{
gXPCThreadJSContextStack = new nsXPCThreadJSContextStackImpl();
// hold an extra reference to lock it down
NS_IF_ADDREF(gXPCThreadJSContextStack);
}
NS_IF_ADDREF(gXPCThreadJSContextStack);
return gXPCThreadJSContextStack;
}
void
nsXPCThreadJSContextStackImpl::FreeSingleton()
{
nsXPCThreadJSContextStackImpl* tcs = gXPCThreadJSContextStack;
if(tcs)
{
nsrefcnt cnt;
NS_RELEASE2(tcs, cnt);
#ifdef XPC_DUMP_AT_SHUTDOWN
if(0 != cnt)
printf("*** dangling reference to nsXPCThreadJSContextStackImpl: refcnt=%d\n", cnt);
#endif
}
}
/* readonly attribute PRInt32 Count; */
NS_IMETHODIMP
nsXPCThreadJSContextStackImpl::GetCount(PRInt32 *aCount)
{
if(!aCount)
return NS_ERROR_NULL_POINTER;
XPCJSContextStack* myStack = GetStackForCurrentThread();
if(!myStack)
{
*aCount = 0;
return NS_ERROR_FAILURE;
}
return myStack->GetCount(aCount);
}
/* JSContext Peek (); */
NS_IMETHODIMP
nsXPCThreadJSContextStackImpl::Peek(JSContext * *_retval)
{
if(!_retval)
return NS_ERROR_NULL_POINTER;
XPCJSContextStack* myStack = GetStackForCurrentThread();
if(!myStack)
{
*_retval = nsnull;
return NS_ERROR_FAILURE;
}
return myStack->Peek(_retval);
}
/* JSContext Pop (); */
NS_IMETHODIMP
nsXPCThreadJSContextStackImpl::Pop(JSContext * *_retval)
{
XPCJSContextStack* myStack = GetStackForCurrentThread();
if(!myStack)
{
if(_retval)
*_retval = nsnull;
return NS_ERROR_FAILURE;
}
return myStack->Pop(_retval);
}
/* void Push (in JSContext cx); */
NS_IMETHODIMP
nsXPCThreadJSContextStackImpl::Push(JSContext * cx)
{
XPCJSContextStack* myStack = GetStackForCurrentThread(cx);
if(!myStack)
return NS_ERROR_FAILURE;
return myStack->Push(cx);
}
/* readonly attribute JSContext SafeJSContext; */
NS_IMETHODIMP
nsXPCThreadJSContextStackImpl::GetSafeJSContext(JSContext * *aSafeJSContext)
{
NS_ASSERTION(aSafeJSContext, "loser!");
XPCJSContextStack* myStack = GetStackForCurrentThread();
if(!myStack)
{
*aSafeJSContext = nsnull;
return NS_ERROR_FAILURE;
}
return myStack->GetSafeJSContext(aSafeJSContext);
}
NS_IMETHODIMP
nsXPCThreadJSContextStackImpl::SetSafeJSContext(JSContext * aSafeJSContext)
{
XPCJSContextStack* myStack = GetStackForCurrentThread(aSafeJSContext);
if(!myStack)
return NS_ERROR_FAILURE;
return myStack->SetSafeJSContext(aSafeJSContext);
}
/***************************************************************************/
PRUintn XPCPerThreadData::gTLSIndex = BAD_TLS_INDEX;
PRLock* XPCPerThreadData::gLock = nsnull;
XPCPerThreadData* XPCPerThreadData::gThreads = nsnull;
@ -673,13 +523,12 @@ NS_IMPL_ISUPPORTS1(nsXPCJSContextStackIterator, nsIJSContextStackIterator)
NS_IMETHODIMP
nsXPCJSContextStackIterator::Reset(nsIJSContextStack *aStack)
{
// XXX This is pretty ugly.
nsXPCThreadJSContextStackImpl *impl =
static_cast<nsXPCThreadJSContextStackImpl*>(aStack);
XPCJSContextStack *stack = impl->GetStackForCurrentThread();
if(!stack)
NS_ASSERTION(aStack == nsXPConnect::GetXPConnect(),
"aStack must be implemented by XPConnect singleton");
XPCPerThreadData* data = XPCPerThreadData::GetData(nsnull);
if(!data)
return NS_ERROR_FAILURE;
mStack = stack->GetStack();
mStack = data->GetJSContextStack()->GetStack();
if(mStack->IsEmpty())
mStack = nsnull;
else