Bug 1276276 part 1. Make AutoJSAPI hold a strong ref to the nsIGlobalObject it's initialized with, so it won't go away while we're working with it. r=smaug

This commit is contained in:
Boris Zbarsky 2016-06-02 10:34:39 -04:00
Родитель 783e8cc098
Коммит 2385de9556
2 изменённых файлов: 16 добавлений и 5 удалений

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

@ -344,16 +344,20 @@ WarningOnlyErrorReporter(JSContext* aCx, const char* aMessage,
JSErrorReport* aRep);
void
AutoJSAPI::InitInternal(JSObject* aGlobal, JSContext* aCx, bool aIsMainThread)
AutoJSAPI::InitInternal(nsIGlobalObject* aGlobalObject, JSObject* aGlobal,
JSContext* aCx, bool aIsMainThread)
{
MOZ_ASSERT(aCx);
MOZ_ASSERT(aIsMainThread == NS_IsMainThread());
MOZ_ASSERT(bool(aGlobalObject) == bool(aGlobal));
MOZ_ASSERT_IF(aGlobalObject, aGlobalObject->GetGlobalJSObject() == aGlobal);
#ifdef DEBUG
bool haveException = JS_IsExceptionPending(aCx);
#endif // DEBUG
mCx = aCx;
mIsMainThread = aIsMainThread;
mGlobalObject = aGlobalObject;
if (aIsMainThread) {
// This Rooted<> is necessary only as long as AutoCxPusher::AutoCxPusher
// can GC, which is only possible because XPCJSContextStack::Push calls
@ -451,7 +455,8 @@ AutoJSAPI::AutoJSAPI(nsIGlobalObject* aGlobalObject,
MOZ_ASSERT(aCx);
MOZ_ASSERT(aIsMainThread == NS_IsMainThread());
InitInternal(aGlobalObject->GetGlobalJSObject(), aCx, aIsMainThread);
InitInternal(aGlobalObject, aGlobalObject->GetGlobalJSObject(), aCx,
aIsMainThread);
}
void
@ -459,7 +464,7 @@ AutoJSAPI::Init()
{
MOZ_ASSERT(!mCx, "An AutoJSAPI should only be initialised once");
InitInternal(/* aGlobal */ nullptr,
InitInternal(/* aGlobalObject */ nullptr, /* aGlobal */ nullptr,
nsContentUtils::GetDefaultJSContextForThread(),
NS_IsMainThread());
}
@ -479,7 +484,7 @@ AutoJSAPI::Init(nsIGlobalObject* aGlobalObject, JSContext* aCx)
return false;
}
InitInternal(global, aCx, NS_IsMainThread());
InitInternal(aGlobalObject, global, aCx, NS_IsMainThread());
return true;
}

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

@ -305,6 +305,11 @@ protected:
AutoJSAPI(nsIGlobalObject* aGlobalObject, bool aIsMainThread, JSContext* aCx);
private:
// We need to hold a strong ref to our global object, so it won't go away
// while we're being used. This _could_ become a JS::Rooted<JSObject*> if we
// grabbed our JSContext in our constructor instead of waiting for Init(), so
// we could construct this at that point. It might be worth it do to that.
RefPtr<nsIGlobalObject> mGlobalObject;
mozilla::Maybe<danger::AutoCxPusher> mCxPusher;
mozilla::Maybe<JSAutoNullableCompartment> mAutoNullableCompartment;
JSContext *mCx;
@ -315,7 +320,8 @@ private:
bool mIsMainThread;
Maybe<JSErrorReporter> mOldErrorReporter;
void InitInternal(JSObject* aGlobal, JSContext* aCx, bool aIsMainThread);
void InitInternal(nsIGlobalObject* aGlobalObject, JSObject* aGlobal,
JSContext* aCx, bool aIsMainThread);
AutoJSAPI(const AutoJSAPI&) = delete;
AutoJSAPI& operator= (const AutoJSAPI&) = delete;