--- a/caps/include/nsScriptSecurityManager.h
+++ b/caps/include/nsScriptSecurityManager.h
@@ -582,27 +582,27 @@ private:
DomainPolicy* mDefaultPolicy;
nsObjectHashtable* mCapabilities;
nsCOMPtr<nsIPrefBranch> mPrefBranch;
nsCOMPtr<nsISecurityPref> mSecurityPref;
nsCOMPtr<nsIPrincipal> mSystemPrincipal;
nsCOMPtr<nsIPrincipal> mSystemCertificate;
nsInterfaceHashtable<PrincipalKey, nsIPrincipal> mPrincipals;
- nsCOMPtr<nsIThreadJSContextStack> mJSContextStack;
PRPackedBool mIsJavaScriptEnabled;
PRPackedBool mIsMailJavaScriptEnabled;
PRPackedBool mIsWritingPrefs;
PRPackedBool mPolicyPrefsChanged;
#ifdef XPC_IDISPATCH_SUPPORT
PRPackedBool mXPCDefaultGrantAll;
static const char sXPCDefaultGrantAllName[];
#endif
static PRBool sStrictFileOriginPolicy;
static nsIIOService *sIOService;
static nsIXPConnect *sXPConnect;
+ static nsIThreadJSContextStack* sJSContextStack;
static nsIStringBundle *sStrBundle;
static JSRuntime *sRuntime;
};
#endif // nsScriptSecurityManager_h__
--- a/caps/src/nsScriptSecurityManager.cpp
+++ b/caps/src/nsScriptSecurityManager.cpp
@@ -93,16 +93,17 @@
#include "nsIURIFixup.h"
#include "nsCDefaultURIFixup.h"
#include "nsIChromeRegistry.h"
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;
// Info we need about the JSClasses used by XPConnects wrapped
// natives, to avoid having to QI to nsIXPConnectWrappedNative all the
// time when doing security checks.
static const JSClass *sXPCWrappedNativeJSClass;
@@ -300,40 +301,28 @@ private:
nsCOMPtr<nsIJSContextStack> mStack;
JSContext *mContext;
};
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;
}
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;
}
/* static */
PRBool
nsScriptSecurityManager::SecurityCompareURIs(nsIURI* aSourceURI,
nsIURI* aTargetURI)
@@ -3230,33 +3219,36 @@ nsScriptSecurityManager::nsScriptSecurit
{
NS_ASSERTION(sizeof(long) == sizeof(void*), "long and void* have different lengths on this platform. This may cause a security failure.");
mPrincipals.Init(31);
}
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
::JS_BeginRequest(cx);
if (sEnabledID == JSVAL_VOID)
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);
rv = bundleService->CreateBundle("chrome://global/locale/security/caps.properties", &sStrBundle);
NS_ENSURE_SUCCESS(rv, rv);
// Create our system principal singleton
nsRefPtr<nsSystemPrincipal> system = new nsSystemPrincipal();
@@ -3313,16 +3305,17 @@ nsScriptSecurityManager::Shutdown()
if (sRuntime) {
JS_SetRuntimeSecurityCallbacks(sRuntime, NULL);
sRuntime = nsnull;
}
sEnabledID = JSVAL_VOID;
NS_IF_RELEASE(sIOService);
NS_IF_RELEASE(sXPConnect);
+ NS_IF_RELEASE(sJSContextStack);
NS_IF_RELEASE(sStrBundle);
}
nsScriptSecurityManager *
nsScriptSecurityManager::GetScriptSecurityManager()
{
if (!gScriptSecMan)
{
@@ -3414,17 +3407,17 @@ nsScriptSecurityManager::InitPolicies()
new nsObjectHashtable(nsnull, nsnull, DeleteCapability, nsnull);
if (!mCapabilities)
return NS_ERROR_OUT_OF_MEMORY;
}
// 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);
nsXPIDLCString policyNames;
rv = mSecurityPref->SecurityGetCharPref("capability.policy.policynames",
getter_Copies(policyNames));
nsXPIDLCString defaultPolicyNames;
--- a/js/src/xpconnect/src/nsXPConnect.cpp
+++ b/js/src/xpconnect/src/nsXPConnect.cpp
@@ -48,21 +48,23 @@
#include "nsHashKeys.h"
#include "jsatom.h"
#include "jsfun.h"
#include "jsobj.h"
#include "jsscript.h"
#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;
PRUint32 nsXPConnect::gReportAllJSExceptions = 0;
// Global cache of the default script security manager (QI'd to
// nsIScriptSecurityManager)
nsIScriptSecurityManager *gScriptSecurityManager = nsnull;
@@ -75,27 +77,24 @@ const char XPC_SCRIPT_ERROR_CONTRACTID[]
const char XPC_ID_CONTRACTID[] = "@mozilla.org/js/xpc/ID;1";
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),
mCycleCollectionContext(nsnull),
mCycleCollecting(PR_FALSE)
{
mRuntime = XPCJSRuntime::newXPCJSRuntime(this);
- CallGetService(XPC_CONTEXT_STACK_CONTRACTID, &mContextStack);
-
nsCycleCollector_registerRuntime(nsIProgrammingLanguage::JAVASCRIPT, this);
#ifdef DEBUG_CC
mJSRoots.ops = nsnull;
#endif
#ifdef XPC_TOOLS_SUPPORT
{
char* filename = PR_GetEnv("MOZILLA_JS_PROFILER_OUTPUT");
@@ -150,17 +149,16 @@ nsXPConnect::~nsXPConnect()
XPCWrappedNativeScope::SystemIsBeingShutDown(cx);
mRuntime->SystemIsBeingShutDown(cx);
JS_EndRequest(cx);
JS_DestroyContext(cx);
}
- NS_IF_RELEASE(mContextStack);
NS_IF_RELEASE(mDefaultSecurityManager);
gScriptSecurityManager = nsnull;
// shutdown the logging system
XPC_LOG_FINISH();
delete mRuntime;
@@ -177,18 +175,17 @@ nsXPConnect::GetXPConnect()
{
if(gOnceAliveNowDead)
return nsnull;
gSelf = new nsXPConnect();
if(!gSelf)
return nsnull;
if(!gSelf->mRuntime ||
- !gSelf->mInterfaceInfoManager ||
- !gSelf->mContextStack)
+ !gSelf->mInterfaceInfoManager)
{
// ctor failed to create an acceptable instance
delete gSelf;
gSelf = nsnull;
}
else
{
// Initial extra ref to keep the singleton alive
@@ -227,32 +224,35 @@ nsXPConnect::ReleaseXPConnectSingleton()
xpc->mProfiler->Stop();
xpc->mProfiler->WriteResults(xpc->mProfilerOutputFile);
}
#endif
#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);
+ }
}
}
}
#endif
#ifdef XPC_DUMP_AT_SHUTDOWN
// NOTE: to see really interesting stuff turn on the prlog stuff.
// See the comment at the top of xpclog.h to see how to do that.
xpc->DebugDump(7);
@@ -277,31 +277,16 @@ nsXPConnect::GetInterfaceInfoManager(nsI
return NS_ERROR_FAILURE;
*iim = xpc->mInterfaceInfoManager;
NS_IF_ADDREF(*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()
{
nsXPConnect* xpc = GetXPConnect();
NS_ASSERTION(xpc, "Must not be called if XPC failed to initialize");
return xpc->GetRuntime();
}
@@ -1586,17 +1571,17 @@ nsXPConnect::CreateStackFrameLocation(PR
NS_IMETHODIMP
nsXPConnect::GetCurrentJSStack(nsIStackFrame * *aCurrentJSStack)
{
NS_ASSERTION(aCurrentJSStack, "bad param");
*aCurrentJSStack = nsnull;
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));
if(stack)
{
// peel off native frames...
PRUint32 language;
nsCOMPtr<nsIStackFrame> caller;
@@ -2038,17 +2023,16 @@ nsXPConnect::DebugDump(PRInt16 depth)
depth-- ;
XPC_LOG_ALWAYS(("nsXPConnect @ %x with mRefCnt = %d", this, mRefCnt.get()));
XPC_LOG_INDENT();
XPC_LOG_ALWAYS(("gSelf @ %x", gSelf));
XPC_LOG_ALWAYS(("gOnceAliveNowDead is %d", (int)gOnceAliveNowDead));
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)
mRuntime->DebugDump(depth);
else
XPC_LOG_ALWAYS(("XPCJSRuntime @ %x", mRuntime));
}
else
@@ -2113,42 +2097,32 @@ nsXPConnect::DebugDumpObject(nsISupports
/* void debugDumpJSStack (in PRBool showArgs, in PRBool showLocals, in PRBool showThisProps); */
NS_IMETHODIMP
nsXPConnect::DebugDumpJSStack(PRBool showArgs,
PRBool showLocals,
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");
else
xpc_DumpJSStack(cx, showArgs, showLocals, showThisProps);
return NS_OK;
}
/* void debugDumpEvalInJSStackFrame (in PRUint32 aFrameNumber, in string aSourceText); */
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");
else
xpc_DumpEvalInJSStackFrame(cx, aFrameNumber, aSourceText);
return NS_OK;
}
@@ -2215,26 +2189,24 @@ nsXPConnect::FlagSystemFilenamePrefix(co
}
NS_IMETHODIMP
nsXPConnect::OnProcessNextEvent(nsIThreadInternal *aThread, PRBool aMayWait,
PRUint32 aRecursionDepth)
{
// 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
nsXPConnect::OnDispatchedEvent(nsIThreadInternal* aThread)
{
NS_NOTREACHED("Why tell us?");
return NS_ERROR_UNEXPECTED;
}
@@ -2304,16 +2276,111 @@ nsXPConnect::GetBackstagePass(nsIXPCScri
#endif
if(!mBackstagePass)
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(*bsp = mBackstagePass);
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()
{
nsresult rv;
nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID(), &rv));
if(NS_SUCCEEDED(rv) && xpc)
xpc->DebugDumpJSStack(PR_TRUE, PR_TRUE, PR_FALSE);
--- a/js/src/xpconnect/src/xpcmodule.cpp
+++ b/js/src/xpconnect/src/xpcmodule.cpp
@@ -61,34 +61,33 @@ NS_DECL_CLASSINFO(XPCVariant)
#define SCRIPTABLE_INTERFACES_CID \
{0xfe4f7592, 0xc1fc, 0x4662, \
{ 0xac, 0x83, 0x53, 0x88, 0x41, 0x31, 0x88, 0x3 } }
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)
#ifdef XPC_IDISPATCH_SUPPORT
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIDispatchSupport, nsDispatchSupport::GetSingleton)
#endif
NS_DECL_CLASSINFO(nsXPCException)
#ifdef XPCONNECT_STANDALONE
#define NO_SUBSCRIPT_LOADER
#endif
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 },
{nsnull, SCRIPTABLE_INTERFACES_CID, NS_SCRIPTABLE_INTERFACES_CONTRACTID, nsXPCComponents_InterfacesConstructor, 0, 0, 0, 0, 0, 0, nsIClassInfo::THREADSAFE },
{nsnull, XPCVARIANT_CID, XPCVARIANT_CONTRACTID, nsnull, nsnull, nsnull, nsnull, NS_CI_INTERFACE_GETTER_NAME(XPCVariant), nsnull, &NS_CLASSINFO_NAME(XPCVariant)},
{nsnull, NS_XPC_JSCONTEXT_STACK_ITERATOR_CID, XPC_JSCONTEXT_STACK_ITERATOR_CONTRACTID, nsXPCJSContextStackIteratorConstructor }
#ifdef MOZ_JSLOADER
@@ -109,31 +108,29 @@ static const nsModuleComponentInfo compo
static nsresult
xpcModuleCtor(nsIModule* self)
{
nsXPConnect::InitStatics();
nsXPCException::InitStatics();
XPCWrappedNativeScope::InitStatics();
XPCPerThreadData::InitStatics();
- nsXPCThreadJSContextStackImpl::InitStatics();
#ifdef XPC_IDISPATCH_SUPPORT
XPCIDispatchExtension::InitStatics();
#endif
return NS_OK;
}
static void
xpcModuleDtor(nsIModule* self)
{
// Release our singletons
nsXPConnect::ReleaseXPConnectSingleton();
- nsXPCThreadJSContextStackImpl::FreeSingleton();
xpc_DestroyJSxIDClassObjects();
#ifdef XPC_IDISPATCH_SUPPORT
nsDispatchSupport::FreeSingleton();
XPCIDispatchClassInfo::FreeSingleton();
#endif
}
NS_IMPL_NSGETMODULE_WITH_CTOR_DTOR(xpconnect, components, xpcModuleCtor, xpcModuleDtor)
--- a/js/src/xpconnect/src/xpcprivate.h
+++ b/js/src/xpconnect/src/xpcprivate.h
@@ -441,45 +441,48 @@ private:
const PRBool OBJ_IS_GLOBAL = PR_TRUE;
const PRBool OBJ_IS_NOT_GLOBAL = PR_FALSE;
#define NS_JS_RUNTIME_SERVICE_CID \
{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...
NS_DECL_ISUPPORTS
NS_DECL_NSIXPCONNECT
NS_DECL_NSITHREADOBSERVER
NS_DECL_NSIJSRUNTIMESERVICE
+ NS_DECL_NSIJSCONTEXTSTACK
+ NS_DECL_NSITHREADJSCONTEXTSTACK
// non-interface implementation
public:
// These get non-addref'd pointers
static nsXPConnect* GetXPConnect();
static XPCJSRuntime* GetRuntimeInstance();
XPCJSRuntime* GetRuntime() {return mRuntime;}
// Gets addref'd pointer
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
{return mDefaultSecurityManager;}
PRUint16 GetDefaultSecurityManagerFlags() const
{return mDefaultSecurityManagerFlags;}
@@ -554,17 +557,16 @@ private:
private:
// Singleton instance
static nsXPConnect* gSelf;
static JSBool gOnceAliveNowDead;
XPCJSRuntime* mRuntime;
nsCOMPtr<nsIInterfaceInfoSuperManager> mInterfaceInfoManager;
- nsIThreadJSContextStack* mContextStack;
nsIXPCSecurityManager* mDefaultSecurityManager;
PRUint16 mDefaultSecurityManagerFlags;
JSBool mShuttingDown;
XPCCallContext* mCycleCollectionContext;
#ifdef DEBUG_CC
nsAutoPtr<XPCCallContext> mExplainCycleCollectionContext;
PLDHashTable mJSRoots;
#endif
@@ -3223,50 +3225,16 @@ private:
// Cached value of cx->thread on the main thread.
static void *sMainJSThread;
// Cached per thread data for the main thread. Only safe to access
// if cx->thread == sMainJSThread.
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"
class BackstagePass : public nsIScriptObjectPrincipal,
public nsIXPCScriptable,
public nsIClassInfo
{
--- a/js/src/xpconnect/src/xpcthreadcontext.cpp
+++ b/js/src/xpconnect/src/xpcthreadcontext.cpp
@@ -268,166 +268,16 @@ XPCJSContextStack::SetSafeJSContext(JSCo
}
mSafeJSContext = aSafeJSContext;
return NS_OK;
}
/***************************************************************************/
-/*
- * 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;
XPCPerThreadData *XPCPerThreadData::sMainThreadData = nsnull;
void * XPCPerThreadData::sMainJSThread = nsnull;
static jsuword
GetThreadStackLimit()
@@ -668,23 +518,22 @@ XPCPerThreadData::IterateThreads(XPCPerT
return *iteratorp;
}
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
mPosition = mStack->Length() - 1;
return NS_OK;
}