Bug 865729 - Make nsContentUtils munge the cx stack with sXPConnect directly. r=gabor

This commit is contained in:
Bobby Holley 2013-04-29 11:16:21 -07:00
parent a1a3f2c647
commit 515a945b71
2 changed files with 25 additions and 59 deletions

View File

@ -64,7 +64,6 @@ class nsIFragmentContentSink;
class nsIImageLoadingContent;
class nsIInterfaceRequestor;
class nsIIOService;
class nsIJSContextStack;
class nsIJSRuntimeService;
class nsILineBreaker;
class nsIMIMEHeaderParam;
@ -82,7 +81,6 @@ class nsIScriptSecurityManager;
class nsIStringBundle;
class nsIStringBundleService;
class nsISupportsHashKey;
class nsIThreadJSContextStack;
class nsIURI;
class nsIWidget;
class nsIWordBreaker;
@ -1627,12 +1625,7 @@ public:
static nsresult CheckSameOrigin(nsIChannel *aOldChannel, nsIChannel *aNewChannel);
static nsIInterfaceRequestor* GetSameOriginChecker();
static nsIThreadJSContextStack* ThreadJSContextStack()
{
return sThreadJSContextStack;
}
// Trace the safe JS context of the ThreadJSContextStack.
// Trace the safe JS context.
static void TraceSafeJSContext(JSTracer* aTrc);
@ -2183,8 +2176,6 @@ private:
static nsIScriptSecurityManager *sSecurityManager;
static nsIThreadJSContextStack *sThreadJSContextStack;
static nsIParserService *sParserService;
static nsINameSpaceManager *sNameSpaceManager;

View File

@ -107,7 +107,6 @@
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIIOService.h"
#include "nsIJSContextStack.h"
#include "nsIJSRuntimeService.h"
#include "nsILineBreaker.h"
#include "nsILoadContext.h"
@ -188,7 +187,6 @@ const char kLoadAsData[] = "loadAsData";
nsIDOMScriptObjectFactory *nsContentUtils::sDOMScriptObjectFactory = nullptr;
nsIXPConnect *nsContentUtils::sXPConnect;
nsIScriptSecurityManager *nsContentUtils::sSecurityManager;
nsIThreadJSContextStack *nsContentUtils::sThreadJSContextStack;
nsIParserService *nsContentUtils::sParserService = nullptr;
nsINameSpaceManager *nsContentUtils::sNameSpaceManager;
nsIIOService *nsContentUtils::sIOService;
@ -365,7 +363,6 @@ nsContentUtils::Init()
NS_ENSURE_TRUE(xpconnect, NS_ERROR_FAILURE);
sXPConnect = xpconnect;
sThreadJSContextStack = xpconnect;
sSecurityManager = nsScriptSecurityManager::GetScriptSecurityManager();
if(!sSecurityManager)
@ -1447,7 +1444,6 @@ nsContentUtils::Shutdown()
NS_IF_RELEASE(sConsoleService);
NS_IF_RELEASE(sDOMScriptObjectFactory);
sXPConnect = nullptr;
sThreadJSContextStack = nullptr;
NS_IF_RELEASE(sSecurityManager);
NS_IF_RELEASE(sNameSpaceManager);
NS_IF_RELEASE(sParserService);
@ -1682,10 +1678,7 @@ nsContentUtils::GetContextFromDocument(nsIDocument *aDocument)
void
nsContentUtils::TraceSafeJSContext(JSTracer* aTrc)
{
if (!sThreadJSContextStack) {
return;
}
JSContext* cx = sThreadJSContextStack->GetSafeJSContext();
JSContext* cx = GetSafeJSContext();
if (!cx) {
return;
}
@ -1697,9 +1690,7 @@ nsContentUtils::TraceSafeJSContext(JSTracer* aTrc)
nsPIDOMWindow *
nsContentUtils::GetWindowFromCaller()
{
JSContext *cx = nullptr;
sThreadJSContextStack->Peek(&cx);
JSContext *cx = GetCurrentJSContext();
if (cx) {
nsCOMPtr<nsPIDOMWindow> win =
do_QueryInterface(nsJSUtils::GetDynamicScriptGlobal(cx));
@ -1731,9 +1722,7 @@ nsContentUtils::GetDocumentFromCaller()
nsIDocument*
nsContentUtils::GetDocumentFromContext()
{
JSContext *cx = nullptr;
sThreadJSContextStack->Peek(&cx);
JSContext *cx = GetCurrentJSContext();
if (cx) {
nsIScriptGlobalObject *sgo = nsJSUtils::GetDynamicScriptGlobal(cx);
@ -3025,23 +3014,20 @@ nsCxPusher::~nsCxPusher()
}
static bool
IsContextOnStack(nsIJSContextStack *aStack, JSContext *aContext)
IsContextOnStack(JSContext *aContext)
{
JSContext *ctx = nullptr;
aStack->Peek(&ctx);
if (!ctx)
return false;
if (ctx == aContext)
if (aContext == nsContentUtils::GetCurrentJSContext())
return true;
nsCOMPtr<nsIJSContextStackIterator>
iterator(do_CreateInstance("@mozilla.org/js/xpc/ContextStackIterator;1"));
NS_ENSURE_TRUE(iterator, false);
nsresult rv = iterator->Reset(aStack);
nsresult rv = iterator->Reset(nsContentUtils::XPConnect());
NS_ENSURE_SUCCESS(rv, false);
bool done;
JSContext *ctx = nullptr;
while (NS_SUCCEEDED(iterator->Done(&done)) && !done) {
rv = iterator->Prev(&ctx);
NS_ASSERTION(NS_SUCCEEDED(rv), "Broken iterator implementation");
@ -3145,20 +3131,20 @@ nsCxPusher::Push(JSContext *cx)
void
nsCxPusher::DoPush(JSContext* cx)
{
nsIThreadJSContextStack* stack = nsContentUtils::ThreadJSContextStack();
if (!stack) {
nsIXPConnect *xpc = nsContentUtils::XPConnect();
if (!xpc) {
// If someone tries to push a cx when we don't have the relevant state,
// it's probably safest to just crash.
MOZ_CRASH();
}
if (cx && IsContextOnStack(stack, cx)) {
if (cx && IsContextOnStack(cx)) {
// If the context is on the stack, that means that a script
// is running at the moment in the context.
mScriptIsRunning = true;
}
if (NS_FAILED(stack->Push(cx))) {
if (NS_FAILED(xpc->Push(cx))) {
MOZ_CRASH();
}
@ -3179,8 +3165,7 @@ nsCxPusher::PushNull()
void
nsCxPusher::Pop()
{
nsIThreadJSContextStack* stack = nsContentUtils::ThreadJSContextStack();
MOZ_ASSERT(stack);
MOZ_ASSERT(nsContentUtils::XPConnect());
if (!mPushedSomething) {
mScx = nullptr;
mPushedSomething = false;
@ -3199,8 +3184,8 @@ nsCxPusher::Pop()
MOZ_ASSERT_IF(mPushedContext, mCompartmentDepthOnEntry ==
js::GetEnterCompartmentDepth(mPushedContext));
DebugOnly<JSContext*> stackTop;
MOZ_ASSERT(NS_SUCCEEDED(stack->Peek(&stackTop)) && mPushedContext == stackTop);
stack->Pop(nullptr);
MOZ_ASSERT(mPushedContext == nsContentUtils::GetCurrentJSContext());
nsContentUtils::XPConnect()->Pop(nullptr);
if (!mScriptIsRunning && mScx) {
// No JS is running in the context, but executing the event handler might have
@ -3338,8 +3323,7 @@ nsContentUtils::ReportToConsoleNonLocalized(const nsAString& aErrorText,
nsAutoCString spec;
if (!aLineNumber) {
JSContext *cx = nullptr;
sThreadJSContextStack->Peek(&cx);
JSContext *cx = GetCurrentJSContext();
if (cx) {
const char* filename;
uint32_t lineno;
@ -5492,7 +5476,7 @@ nsContentUtils::GetCurrentJSContext()
{
JSContext *cx = nullptr;
sThreadJSContextStack->Peek(&cx);
sXPConnect->Peek(&cx);
return cx;
}
@ -5501,7 +5485,7 @@ nsContentUtils::GetCurrentJSContext()
JSContext *
nsContentUtils::GetSafeJSContext()
{
return sThreadJSContextStack->GetSafeJSContext();
return sXPConnect->GetSafeJSContext();
}
/* static */
@ -5940,9 +5924,9 @@ nsContentUtils::WrapNative(JSContext *cx, JSObject *scope, nsISupports *native,
return NS_OK;
}
NS_ENSURE_TRUE(sXPConnect && sThreadJSContextStack, NS_ERROR_UNEXPECTED);
NS_ENSURE_TRUE(sXPConnect, NS_ERROR_UNEXPECTED);
// Keep sXPConnect and sThreadJSContextStack alive. If we're on the main
// Keep sXPConnect alive. If we're on the main
// thread then this can be done simply and cheaply by adding a reference to
// nsLayoutStatics. If we're not on the main thread then we need to add a
// more expensive reference sXPConnect directly. We have to use manual
@ -5957,20 +5941,11 @@ nsContentUtils::WrapNative(JSContext *cx, JSObject *scope, nsISupports *native,
sXPConnect->AddRef();
}
JSContext *topJSContext;
nsresult rv = sThreadJSContextStack->Peek(&topJSContext);
if (NS_SUCCEEDED(rv)) {
bool push = topJSContext != cx;
if (push) {
rv = sThreadJSContextStack->Push(cx);
}
if (NS_SUCCEEDED(rv)) {
rv = sXPConnect->WrapNativeToJSVal(cx, scope, native, cache, aIID,
aAllowWrapping, vp, aHolder);
if (push) {
sThreadJSContextStack->Pop(nullptr);
}
}
nsresult rv = NS_OK;
{
AutoPushJSContext context(cx);
rv = sXPConnect->WrapNativeToJSVal(context, scope, native, cache, aIID,
aAllowWrapping, vp, aHolder);
}
if (isMainThread) {