mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-10 17:24:29 +00:00
Back out 9a57cd3e5a93:b62548e26499 (bug 865745) for causing an unexpected exception in a mochiperf test
This commit is contained in:
parent
b089260883
commit
0f540beb8e
@ -1264,13 +1264,19 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
|
||||
mMessageManager->GetParentManager() : nullptr;
|
||||
nsFrameMessageManager* otherParentManager = aOther->mMessageManager ?
|
||||
aOther->mMessageManager->GetParentManager() : nullptr;
|
||||
JSContext* thisCx =
|
||||
mMessageManager ? mMessageManager->GetJSContext() : nullptr;
|
||||
JSContext* otherCx =
|
||||
aOther->mMessageManager ? aOther->mMessageManager->GetJSContext() : nullptr;
|
||||
if (mMessageManager) {
|
||||
mMessageManager->RemoveFromParent();
|
||||
mMessageManager->SetJSContext(otherCx);
|
||||
mMessageManager->SetParentManager(otherParentManager);
|
||||
mMessageManager->SetCallback(aOther, false);
|
||||
}
|
||||
if (aOther->mMessageManager) {
|
||||
aOther->mMessageManager->RemoveFromParent();
|
||||
aOther->mMessageManager->SetJSContext(thisCx);
|
||||
aOther->mMessageManager->SetParentManager(ourParentManager);
|
||||
aOther->mMessageManager->SetCallback(this, false);
|
||||
}
|
||||
@ -2218,7 +2224,8 @@ public:
|
||||
nsInProcessTabChildGlobal* tabChild =
|
||||
static_cast<nsInProcessTabChildGlobal*>(mFrameLoader->mChildMessageManager.get());
|
||||
if (tabChild && tabChild->GetInnerManager()) {
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> kungFuDeathGrip(tabChild->GetGlobal());
|
||||
nsFrameScriptCx cx(static_cast<EventTarget*>(tabChild), tabChild);
|
||||
|
||||
StructuredCloneData data;
|
||||
data.mData = mData.data();
|
||||
data.mDataLength = mData.nbytes();
|
||||
@ -2226,7 +2233,7 @@ public:
|
||||
|
||||
nsRefPtr<nsFrameMessageManager> mm = tabChild->GetInnerManager();
|
||||
mm->ReceiveMessage(static_cast<EventTarget*>(tabChild), mMessage,
|
||||
false, &data, JS::NullPtr(), nullptr);
|
||||
false, &data, JS::NullPtr(), nullptr, nullptr);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
@ -2382,10 +2389,12 @@ nsFrameLoader::EnsureMessageManager()
|
||||
if (ShouldUseRemoteProcess()) {
|
||||
mMessageManager = new nsFrameMessageManager(mRemoteBrowserShown ? this : nullptr,
|
||||
static_cast<nsFrameMessageManager*>(parentManager.get()),
|
||||
cx,
|
||||
MM_CHROME);
|
||||
} else {
|
||||
mMessageManager = new nsFrameMessageManager(nullptr,
|
||||
static_cast<nsFrameMessageManager*>(parentManager.get()),
|
||||
cx,
|
||||
MM_CHROME);
|
||||
|
||||
mChildMessageManager =
|
||||
|
@ -632,10 +632,14 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
||||
bool aSync,
|
||||
const StructuredCloneData* aCloneData,
|
||||
JS::Handle<JSObject*> aObjectsArray,
|
||||
InfallibleTArray<nsString>* aJSONRetVal)
|
||||
InfallibleTArray<nsString>* aJSONRetVal,
|
||||
JSContext* aContext)
|
||||
{
|
||||
AutoSafeJSContext ctx;
|
||||
JS::Rooted<JSObject*> objectsArray(ctx, aObjectsArray);
|
||||
JSContext *cxToUse = mContext ? mContext
|
||||
: (aContext ? aContext
|
||||
: nsContentUtils::GetSafeJSContext());
|
||||
AutoPushJSContext ctx(cxToUse);
|
||||
JS::Rooted<JSObject*> objectsArray(cxToUse, aObjectsArray);
|
||||
if (mListeners.Length()) {
|
||||
nsCOMPtr<nsIAtom> name = do_GetAtom(aMessage);
|
||||
MMListenerRemover lr(this);
|
||||
@ -651,6 +655,9 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
||||
if (!object) {
|
||||
continue;
|
||||
}
|
||||
nsCxPusher pusher;
|
||||
pusher.Push(ctx);
|
||||
|
||||
JSAutoCompartment ac(ctx, object);
|
||||
|
||||
// The parameter for the listener function.
|
||||
@ -755,7 +762,7 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
||||
return mParentManager ? mParentManager->ReceiveMessage(aTarget, aMessage,
|
||||
aSync, aCloneData,
|
||||
objectsArray,
|
||||
aJSONRetVal) : NS_OK;
|
||||
aJSONRetVal, mContext) : NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
@ -812,6 +819,7 @@ nsFrameMessageManager::RemoveFromParent()
|
||||
mParentManager = nullptr;
|
||||
mCallback = nullptr;
|
||||
mOwnedCallback = nullptr;
|
||||
mContext = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
@ -824,6 +832,7 @@ nsFrameMessageManager::Disconnect(bool aRemoveFromParent)
|
||||
mParentManager = nullptr;
|
||||
mCallback = nullptr;
|
||||
mOwnedCallback = nullptr;
|
||||
mContext = nullptr;
|
||||
if (!mHandlingMessage) {
|
||||
mListeners.Clear();
|
||||
}
|
||||
@ -835,19 +844,95 @@ NS_NewGlobalMessageManager(nsIMessageBroadcaster** aResult)
|
||||
NS_ENSURE_TRUE(XRE_GetProcessType() == GeckoProcessType_Default,
|
||||
NS_ERROR_NOT_AVAILABLE);
|
||||
nsFrameMessageManager* mm = new nsFrameMessageManager(nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
MM_CHROME | MM_GLOBAL | MM_BROADCASTER);
|
||||
return CallQueryInterface(mm, aResult);
|
||||
}
|
||||
|
||||
void
|
||||
ContentScriptErrorReporter(JSContext* aCx,
|
||||
const char* aMessage,
|
||||
JSErrorReport* aReport)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIScriptError> scriptError =
|
||||
do_CreateInstance(NS_SCRIPTERROR_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
nsAutoString message, filename, line;
|
||||
uint32_t lineNumber, columnNumber, flags, errorNumber;
|
||||
|
||||
if (aReport) {
|
||||
if (aReport->ucmessage) {
|
||||
message.Assign(static_cast<const PRUnichar*>(aReport->ucmessage));
|
||||
}
|
||||
filename.AssignWithConversion(aReport->filename);
|
||||
line.Assign(static_cast<const PRUnichar*>(aReport->uclinebuf));
|
||||
lineNumber = aReport->lineno;
|
||||
columnNumber = aReport->uctokenptr - aReport->uclinebuf;
|
||||
flags = aReport->flags;
|
||||
errorNumber = aReport->errorNumber;
|
||||
} else {
|
||||
lineNumber = columnNumber = errorNumber = 0;
|
||||
flags = nsIScriptError::errorFlag | nsIScriptError::exceptionFlag;
|
||||
}
|
||||
|
||||
if (message.IsEmpty()) {
|
||||
message.AssignWithConversion(aMessage);
|
||||
}
|
||||
|
||||
rv = scriptError->Init(message, filename, line,
|
||||
lineNumber, columnNumber, flags,
|
||||
"Message manager content script");
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIConsoleService> consoleService =
|
||||
do_GetService(NS_CONSOLESERVICE_CONTRACTID);
|
||||
if (consoleService) {
|
||||
(void) consoleService->LogMessage(scriptError);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// Print it to stderr as well, for the benefit of those invoking
|
||||
// mozilla with -console.
|
||||
nsAutoCString error;
|
||||
error.Assign("JavaScript ");
|
||||
if (JSREPORT_IS_STRICT(flags)) {
|
||||
error.Append("strict ");
|
||||
}
|
||||
if (JSREPORT_IS_WARNING(flags)) {
|
||||
error.Append("warning: ");
|
||||
} else {
|
||||
error.Append("error: ");
|
||||
}
|
||||
error.Append(aReport->filename);
|
||||
error.Append(", line ");
|
||||
error.AppendInt(lineNumber, 10);
|
||||
error.Append(": ");
|
||||
if (aReport->ucmessage) {
|
||||
AppendUTF16toUTF8(static_cast<const PRUnichar*>(aReport->ucmessage),
|
||||
error);
|
||||
} else {
|
||||
error.Append(aMessage);
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s\n", error.get());
|
||||
fflush(stderr);
|
||||
#endif
|
||||
}
|
||||
|
||||
nsDataHashtable<nsStringHashKey, nsFrameJSScriptExecutorHolder*>*
|
||||
nsFrameScriptExecutor::sCachedScripts = nullptr;
|
||||
nsScriptCacheCleaner* nsFrameScriptExecutor::sScriptCacheCleaner = nullptr;
|
||||
|
||||
void
|
||||
nsFrameScriptExecutor::DidCreateGlobal()
|
||||
nsFrameScriptExecutor::DidCreateCx()
|
||||
{
|
||||
NS_ASSERTION(mGlobal, "Should have mGlobal!");
|
||||
NS_ASSERTION(mCx, "Should have mCx!");
|
||||
if (!sCachedScripts) {
|
||||
sCachedScripts =
|
||||
new nsDataHashtable<nsStringHashKey, nsFrameJSScriptExecutorHolder*>;
|
||||
@ -859,6 +944,26 @@ nsFrameScriptExecutor::DidCreateGlobal()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsFrameScriptExecutor::DestroyCx()
|
||||
{
|
||||
if (mCxStackRefCnt) {
|
||||
mDelayedCxDestroy = true;
|
||||
return;
|
||||
}
|
||||
mDelayedCxDestroy = false;
|
||||
if (mCx) {
|
||||
nsIXPConnect* xpc = nsContentUtils::XPConnect();
|
||||
if (xpc) {
|
||||
xpc->ReleaseJSContext(mCx, true);
|
||||
} else {
|
||||
JS_DestroyContext(mCx);
|
||||
}
|
||||
}
|
||||
mCx = nullptr;
|
||||
mGlobal = nullptr;
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
CachedScriptUnrooter(const nsAString& aKey,
|
||||
nsFrameJSScriptExecutorHolder*& aData,
|
||||
@ -890,7 +995,7 @@ nsFrameScriptExecutor::Shutdown()
|
||||
void
|
||||
nsFrameScriptExecutor::LoadFrameScriptInternal(const nsAString& aURL)
|
||||
{
|
||||
if (!mGlobal || !sCachedScripts) {
|
||||
if (!mGlobal || !mCx || !sCachedScripts) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -901,11 +1006,11 @@ nsFrameScriptExecutor::LoadFrameScriptInternal(const nsAString& aURL)
|
||||
}
|
||||
|
||||
if (holder) {
|
||||
AutoSafeJSContext cx;
|
||||
JS::Rooted<JSObject*> global(cx, mGlobal->GetJSObject());
|
||||
nsCxPusher pusher;
|
||||
pusher.Push(mCx);
|
||||
JS::Rooted<JSObject*> global(mCx, mGlobal->GetJSObject());
|
||||
if (global) {
|
||||
JSAutoCompartment ac(cx, global);
|
||||
(void) JS_ExecuteScript(cx, global, holder->mScript, nullptr);
|
||||
(void) JS_ExecuteScript(mCx, global, holder->mScript, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -954,17 +1059,18 @@ nsFrameScriptExecutor::TryCacheLoadAndCompileScript(const nsAString& aURL,
|
||||
}
|
||||
|
||||
if (!dataString.IsEmpty()) {
|
||||
AutoSafeJSContext cx;
|
||||
JS::Rooted<JSObject*> global(cx, mGlobal->GetJSObject());
|
||||
nsCxPusher pusher;
|
||||
pusher.Push(mCx);
|
||||
JS::Rooted<JSObject*> global(mCx, mGlobal->GetJSObject());
|
||||
if (global) {
|
||||
JSAutoCompartment ac(cx, global);
|
||||
JS::CompileOptions options(cx);
|
||||
JSAutoCompartment ac(mCx, global);
|
||||
JS::CompileOptions options(mCx);
|
||||
options.setNoScriptRval(true)
|
||||
.setFileAndLine(url.get(), 1)
|
||||
.setPrincipals(nsJSPrincipals::get(mPrincipal));
|
||||
JS::RootedObject empty(cx, nullptr);
|
||||
JS::Rooted<JSScript*> script(cx,
|
||||
JS::Compile(cx, empty, options, dataString.get(),
|
||||
JS::RootedObject empty(mCx, nullptr);
|
||||
JS::Rooted<JSScript*> script(mCx,
|
||||
JS::Compile(mCx, empty, options, dataString.get(),
|
||||
dataString.Length()));
|
||||
|
||||
if (script) {
|
||||
@ -975,11 +1081,11 @@ nsFrameScriptExecutor::TryCacheLoadAndCompileScript(const nsAString& aURL,
|
||||
nsFrameJSScriptExecutorHolder* holder =
|
||||
new nsFrameJSScriptExecutorHolder(script);
|
||||
// Root the object also for caching.
|
||||
JS_AddNamedScriptRoot(cx, &(holder->mScript),
|
||||
JS_AddNamedScriptRoot(mCx, &(holder->mScript),
|
||||
"Cached message manager script");
|
||||
sCachedScripts->Put(aURL, holder);
|
||||
} else if (aBehavior == EXECUTE_IF_CANT_CACHE) {
|
||||
(void) JS_ExecuteScript(cx, global, script, nullptr);
|
||||
(void) JS_ExecuteScript(mCx, global, script, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -999,16 +1105,26 @@ nsFrameScriptExecutor::InitTabChildGlobalInternal(nsISupports* aScope,
|
||||
runtimeSvc->GetRuntime(&rt);
|
||||
NS_ENSURE_TRUE(rt, false);
|
||||
|
||||
AutoSafeJSContext cx;
|
||||
JSContext* cx_ = JS_NewContext(rt, 8192);
|
||||
NS_ENSURE_TRUE(cx_, false);
|
||||
AutoPushJSContext cx(cx_);
|
||||
|
||||
mCx = cx;
|
||||
|
||||
nsContentUtils::GetSecurityManager()->GetSystemPrincipal(getter_AddRefs(mPrincipal));
|
||||
|
||||
JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_PRIVATE_IS_NSISUPPORTS);
|
||||
JS_SetErrorReporter(cx, ContentScriptErrorReporter);
|
||||
|
||||
nsIXPConnect* xpc = nsContentUtils::XPConnect();
|
||||
const uint32_t flags = nsIXPConnect::INIT_JS_STANDARD_CLASSES;
|
||||
|
||||
|
||||
JS_SetContextPrivate(cx, aScope);
|
||||
|
||||
JS::CompartmentOptions options;
|
||||
options.setZone(JS::SystemZone)
|
||||
.setVersion(JSVERSION_LATEST);
|
||||
|
||||
nsresult rv =
|
||||
xpc->InitClassesWithNewWrappedGlobal(cx, aScope, mPrincipal,
|
||||
flags, options, getter_AddRefs(mGlobal));
|
||||
@ -1018,11 +1134,13 @@ nsFrameScriptExecutor::InitTabChildGlobalInternal(nsISupports* aScope,
|
||||
JS::Rooted<JSObject*> global(cx, mGlobal->GetJSObject());
|
||||
NS_ENSURE_TRUE(global, false);
|
||||
|
||||
JS_SetGlobalObject(cx, global);
|
||||
|
||||
// Set the location information for the new global, so that tools like
|
||||
// about:memory may use that information.
|
||||
xpc::SetLocationForGlobal(global, aID);
|
||||
|
||||
DidCreateGlobal();
|
||||
DidCreateCx();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1032,13 +1150,21 @@ nsFrameScriptExecutor::Traverse(nsFrameScriptExecutor *tmp,
|
||||
nsCycleCollectionTraversalCallback &cb)
|
||||
{
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobal)
|
||||
nsIXPConnect* xpc = nsContentUtils::XPConnect();
|
||||
if (xpc) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mCx");
|
||||
xpc->NoteJSContext(tmp->mCx, cb);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
nsFrameScriptExecutor::Unlink(nsFrameScriptExecutor* aTmp)
|
||||
{
|
||||
aTmp->mGlobal = nullptr;
|
||||
if (aTmp->mCx) {
|
||||
JSAutoRequest ar(aTmp->mCx);
|
||||
JS_SetGlobalObject(aTmp->mCx, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsScriptCacheCleaner, nsIObserver)
|
||||
@ -1072,7 +1198,7 @@ public:
|
||||
|
||||
nsRefPtr<nsFrameMessageManager> ppm = nsFrameMessageManager::sChildProcessManager;
|
||||
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), mMessage,
|
||||
false, &data, JS::NullPtr(), nullptr);
|
||||
false, &data, JS::NullPtr(), nullptr, nullptr);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
@ -1202,7 +1328,7 @@ public:
|
||||
nsRefPtr<nsFrameMessageManager> ppm =
|
||||
nsFrameMessageManager::sSameProcessParentManager;
|
||||
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
|
||||
mMessage, false, &data, JS::NullPtr(), nullptr);
|
||||
mMessage, false, &data, JS::NullPtr(), nullptr, nullptr);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
@ -1272,6 +1398,7 @@ NS_NewParentProcessMessageManager(nsIMessageBroadcaster** aResult)
|
||||
NS_ENSURE_TRUE(XRE_GetProcessType() == GeckoProcessType_Default,
|
||||
NS_ERROR_NOT_AVAILABLE);
|
||||
nsRefPtr<nsFrameMessageManager> mm = new nsFrameMessageManager(nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
MM_CHROME | MM_PROCESSMANAGER | MM_BROADCASTER);
|
||||
nsFrameMessageManager::sParentProcessManager = mm;
|
||||
@ -1294,10 +1421,12 @@ nsFrameMessageManager::NewProcessMessageManager(mozilla::dom::ContentParent* aPr
|
||||
if (aProcess) {
|
||||
mm = new nsFrameMessageManager(aProcess,
|
||||
nsFrameMessageManager::sParentProcessManager,
|
||||
nullptr,
|
||||
MM_CHROME | MM_PROCESSMANAGER);
|
||||
} else {
|
||||
mm = new nsFrameMessageManager(new SameParentProcessMessageManagerCallback(),
|
||||
nsFrameMessageManager::sParentProcessManager,
|
||||
nullptr,
|
||||
MM_CHROME | MM_PROCESSMANAGER | MM_OWNSCALLBACK);
|
||||
sSameProcessParentManager = mm;
|
||||
}
|
||||
@ -1317,6 +1446,7 @@ NS_NewChildProcessMessageManager(nsISyncMessageSender** aResult)
|
||||
cb = new ChildProcessMessageManagerCallback();
|
||||
}
|
||||
nsFrameMessageManager* mm = new nsFrameMessageManager(cb,
|
||||
nullptr,
|
||||
nullptr,
|
||||
MM_PROCESSMANAGER | MM_OWNSCALLBACK);
|
||||
nsFrameMessageManager::sChildProcessManager = mm;
|
||||
|
@ -120,6 +120,7 @@ class nsFrameMessageManager MOZ_FINAL : public nsIContentFrameMessageManager,
|
||||
public:
|
||||
nsFrameMessageManager(mozilla::dom::ipc::MessageManagerCallback* aCallback,
|
||||
nsFrameMessageManager* aParentManager,
|
||||
JSContext* aContext,
|
||||
/* mozilla::dom::ipc::MessageManagerFlags */ uint32_t aFlags)
|
||||
: mChrome(!!(aFlags & mozilla::dom::ipc::MM_CHROME)),
|
||||
mGlobal(!!(aFlags & mozilla::dom::ipc::MM_GLOBAL)),
|
||||
@ -129,8 +130,11 @@ public:
|
||||
mHandlingMessage(false),
|
||||
mDisconnected(false),
|
||||
mCallback(aCallback),
|
||||
mParentManager(aParentManager)
|
||||
mParentManager(aParentManager),
|
||||
mContext(aContext)
|
||||
{
|
||||
NS_ASSERTION(mContext || (mChrome && !mParentManager) || mIsProcessManager,
|
||||
"Should have mContext in non-global/non-process manager!");
|
||||
NS_ASSERTION(mChrome || !aParentManager, "Should not set parent manager!");
|
||||
NS_ASSERTION(!mIsBroadcaster || !mCallback,
|
||||
"Broadcasters cannot have callbacks!");
|
||||
@ -184,7 +188,8 @@ public:
|
||||
nsresult ReceiveMessage(nsISupports* aTarget, const nsAString& aMessage,
|
||||
bool aSync, const StructuredCloneData* aCloneData,
|
||||
JS::Handle<JSObject*> aObjectsArray,
|
||||
InfallibleTArray<nsString>* aJSONRetVal);
|
||||
InfallibleTArray<nsString>* aJSONRetVal,
|
||||
JSContext* aContext = nullptr);
|
||||
|
||||
void AddChildManager(nsFrameMessageManager* aManager,
|
||||
bool aLoadScripts = true);
|
||||
@ -207,6 +212,8 @@ public:
|
||||
uint8_t aArgc);
|
||||
nsresult DispatchAsyncMessageInternal(const nsAString& aMessage,
|
||||
const StructuredCloneData& aData);
|
||||
JSContext* GetJSContext() { return mContext; }
|
||||
void SetJSContext(JSContext* aCx) { mContext = aCx; }
|
||||
void RemoveFromParent();
|
||||
nsFrameMessageManager* GetParentManager() { return mParentManager; }
|
||||
void SetParentManager(nsFrameMessageManager* aParent)
|
||||
@ -240,6 +247,7 @@ protected:
|
||||
mozilla::dom::ipc::MessageManagerCallback* mCallback;
|
||||
nsAutoPtr<mozilla::dom::ipc::MessageManagerCallback> mOwnedCallback;
|
||||
nsFrameMessageManager* mParentManager;
|
||||
JSContext* mContext;
|
||||
nsTArray<nsString> mPendingScripts;
|
||||
public:
|
||||
static nsFrameMessageManager* sParentProcessManager;
|
||||
@ -257,6 +265,11 @@ private:
|
||||
bool* aValid);
|
||||
};
|
||||
|
||||
void
|
||||
ContentScriptErrorReporter(JSContext* aCx,
|
||||
const char* aMessage,
|
||||
JSErrorReport* aReport);
|
||||
|
||||
class nsScriptCacheCleaner;
|
||||
|
||||
struct nsFrameJSScriptExecutorHolder
|
||||
@ -272,18 +285,16 @@ class nsFrameScriptExecutor
|
||||
{
|
||||
public:
|
||||
static void Shutdown();
|
||||
already_AddRefed<nsIXPConnectJSObjectHolder> GetGlobal()
|
||||
{
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> ref = mGlobal;
|
||||
return ref.forget();
|
||||
}
|
||||
protected:
|
||||
friend class nsFrameScriptCx;
|
||||
nsFrameScriptExecutor()
|
||||
nsFrameScriptExecutor() : mCx(nullptr), mCxStackRefCnt(0),
|
||||
mDelayedCxDestroy(false)
|
||||
{ MOZ_COUNT_CTOR(nsFrameScriptExecutor); }
|
||||
~nsFrameScriptExecutor()
|
||||
{ MOZ_COUNT_DTOR(nsFrameScriptExecutor); }
|
||||
void DidCreateGlobal();
|
||||
void DidCreateCx();
|
||||
// Call this when you want to destroy mCx.
|
||||
void DestroyCx();
|
||||
void LoadFrameScriptInternal(const nsAString& aURL);
|
||||
enum CacheFailedBehavior { EXECUTE_IF_CANT_CACHE, DONT_EXECUTE };
|
||||
void TryCacheLoadAndCompileScript(const nsAString& aURL,
|
||||
@ -293,11 +304,33 @@ protected:
|
||||
nsCycleCollectionTraversalCallback &cb);
|
||||
static void Unlink(nsFrameScriptExecutor* aTmp);
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> mGlobal;
|
||||
JSContext* mCx;
|
||||
uint32_t mCxStackRefCnt;
|
||||
bool mDelayedCxDestroy;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
static nsDataHashtable<nsStringHashKey, nsFrameJSScriptExecutorHolder*>* sCachedScripts;
|
||||
static nsScriptCacheCleaner* sScriptCacheCleaner;
|
||||
};
|
||||
|
||||
class nsFrameScriptCx
|
||||
{
|
||||
public:
|
||||
nsFrameScriptCx(nsISupports* aOwner, nsFrameScriptExecutor* aExec)
|
||||
: mOwner(aOwner), mExec(aExec)
|
||||
{
|
||||
++(mExec->mCxStackRefCnt);
|
||||
}
|
||||
~nsFrameScriptCx()
|
||||
{
|
||||
if (--(mExec->mCxStackRefCnt) == 0 &&
|
||||
mExec->mDelayedCxDestroy) {
|
||||
mExec->DestroyCx();
|
||||
}
|
||||
}
|
||||
nsCOMPtr<nsISupports> mOwner;
|
||||
nsFrameScriptExecutor* mExec;
|
||||
};
|
||||
|
||||
class nsScriptCacheCleaner MOZ_FINAL : public nsIObserver
|
||||
{
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -74,7 +74,7 @@ public:
|
||||
|
||||
nsRefPtr<nsFrameMessageManager> mm = mTabChild->mChromeMessageManager;
|
||||
mm->ReceiveMessage(mTabChild->mOwner, mMessage, false, &data,
|
||||
JS::NullPtr(), nullptr);
|
||||
JS::NullPtr(), nullptr, nullptr);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
@ -118,6 +118,7 @@ nsInProcessTabChildGlobal::nsInProcessTabChildGlobal(nsIDocShell* aShell,
|
||||
|
||||
nsInProcessTabChildGlobal::~nsInProcessTabChildGlobal()
|
||||
{
|
||||
NS_ASSERTION(!mCx, "Couldn't release JSContext?!?");
|
||||
}
|
||||
|
||||
/* [notxpcom] boolean markForCC (); */
|
||||
@ -140,6 +141,7 @@ nsInProcessTabChildGlobal::Init()
|
||||
"Couldn't initialize nsInProcessTabChildGlobal");
|
||||
mMessageManager = new nsFrameMessageManager(this,
|
||||
nullptr,
|
||||
mCx,
|
||||
mozilla::dom::ipc::MM_CHILD);
|
||||
return NS_OK;
|
||||
}
|
||||
@ -246,7 +248,9 @@ nsInProcessTabChildGlobal::DelayedDisconnect()
|
||||
|
||||
if (!mLoadingScript) {
|
||||
nsContentUtils::ReleaseWrapper(static_cast<EventTarget*>(this), this);
|
||||
mGlobal = nullptr;
|
||||
if (mCx) {
|
||||
DestroyCx();
|
||||
}
|
||||
} else {
|
||||
mDelayedDisconnect = true;
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ public:
|
||||
}
|
||||
using nsDOMEventTargetHelper::AddEventListener;
|
||||
|
||||
virtual JSContext* GetJSContextForEventHandlers() MOZ_OVERRIDE { return nsContentUtils::GetSafeJSContext(); }
|
||||
virtual JSContext* GetJSContextForEventHandlers() MOZ_OVERRIDE { return mCx; }
|
||||
virtual nsIPrincipal* GetPrincipal() MOZ_OVERRIDE { return mPrincipal; }
|
||||
void LoadFrameScript(const nsAString& aURL);
|
||||
void Disconnect();
|
||||
|
@ -11625,6 +11625,7 @@ nsGlobalChromeWindow::GetMessageManager(nsIMessageBroadcaster** aManager)
|
||||
mMessageManager =
|
||||
new nsFrameMessageManager(nullptr,
|
||||
static_cast<nsFrameMessageManager*>(globalMM.get()),
|
||||
cx,
|
||||
MM_CHROME | MM_BROADCASTER);
|
||||
NS_ENSURE_TRUE(mMessageManager, NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
@ -1145,8 +1145,10 @@ TabChild::~TabChild()
|
||||
if (webBrowser) {
|
||||
webBrowser->SetContainerWindow(nullptr);
|
||||
}
|
||||
mGlobal = nullptr;
|
||||
|
||||
if (mCx) {
|
||||
DestroyCx();
|
||||
}
|
||||
|
||||
if (mTabChildGlobal) {
|
||||
nsEventListenerManager* elm = mTabChildGlobal->GetListenerManager(false);
|
||||
if (elm) {
|
||||
@ -1443,7 +1445,7 @@ TabChild::DispatchMessageManagerMessage(const nsAString& aMessageName,
|
||||
cloneData.mDataLength = buffer.nbytes();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> kungFuDeathGrip(GetGlobal());
|
||||
nsFrameScriptCx frameScriptCx(static_cast<nsIWebBrowserChrome*>(this), this);
|
||||
// Let the BrowserElementScrolling helper (if it exists) for this
|
||||
// content manipulate the frame state.
|
||||
nsRefPtr<nsFrameMessageManager> mm =
|
||||
@ -1483,7 +1485,7 @@ TabChild::RecvUpdateFrame(const FrameMetrics& aFrameMetrics)
|
||||
bool
|
||||
TabChild::ProcessUpdateFrame(const FrameMetrics& aFrameMetrics)
|
||||
{
|
||||
if (!mGlobal || !mTabChildGlobal) {
|
||||
if (!mCx || !mTabChildGlobal) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1553,7 +1555,7 @@ TabChild::ProcessUpdateFrame(const FrameMetrics& aFrameMetrics)
|
||||
bool
|
||||
TabChild::RecvHandleDoubleTap(const CSSIntPoint& aPoint)
|
||||
{
|
||||
if (!mGlobal || !mTabChildGlobal) {
|
||||
if (!mCx || !mTabChildGlobal) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1570,7 +1572,7 @@ TabChild::RecvHandleDoubleTap(const CSSIntPoint& aPoint)
|
||||
bool
|
||||
TabChild::RecvHandleSingleTap(const CSSIntPoint& aPoint)
|
||||
{
|
||||
if (!mGlobal || !mTabChildGlobal) {
|
||||
if (!mCx || !mTabChildGlobal) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1584,7 +1586,7 @@ TabChild::RecvHandleSingleTap(const CSSIntPoint& aPoint)
|
||||
bool
|
||||
TabChild::RecvHandleLongTap(const CSSIntPoint& aPoint)
|
||||
{
|
||||
if (!mGlobal || !mTabChildGlobal) {
|
||||
if (!mCx || !mTabChildGlobal) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1993,7 +1995,7 @@ TabChild::DeallocPOfflineCacheUpdate(POfflineCacheUpdateChild* actor)
|
||||
bool
|
||||
TabChild::RecvLoadRemoteScript(const nsString& aURL)
|
||||
{
|
||||
if (!mGlobal && !InitTabChildGlobal())
|
||||
if (!mCx && !InitTabChildGlobal())
|
||||
// This can happen if we're half-destroyed. It's not a fatal
|
||||
// error.
|
||||
return true;
|
||||
@ -2007,7 +2009,7 @@ TabChild::RecvAsyncMessage(const nsString& aMessage,
|
||||
const ClonedMessageData& aData)
|
||||
{
|
||||
if (mTabChildGlobal) {
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> kungFuDeathGrip(GetGlobal());
|
||||
nsFrameScriptCx cx(static_cast<nsIWebBrowserChrome*>(this), this);
|
||||
StructuredCloneData cloneData = UnpackClonedMessageDataForChild(aData);
|
||||
nsRefPtr<nsFrameMessageManager> mm =
|
||||
static_cast<nsFrameMessageManager*>(mTabChildGlobal->mMessageManager.get());
|
||||
@ -2091,7 +2093,7 @@ TabChild::DeallocPRenderFrame(PRenderFrameChild* aFrame)
|
||||
bool
|
||||
TabChild::InitTabChildGlobal(FrameScriptLoading aScriptLoading)
|
||||
{
|
||||
if (!mGlobal && !mTabChildGlobal) {
|
||||
if (!mCx && !mTabChildGlobal) {
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(mWebNav);
|
||||
NS_ENSURE_TRUE(window, false);
|
||||
nsCOMPtr<EventTarget> chromeHandler =
|
||||
@ -2342,6 +2344,7 @@ TabChildGlobal::Init()
|
||||
NS_ASSERTION(!mMessageManager, "Re-initializing?!?");
|
||||
mMessageManager = new nsFrameMessageManager(mTabChild,
|
||||
nullptr,
|
||||
mTabChild->GetJSContext(),
|
||||
MM_CHILD);
|
||||
}
|
||||
|
||||
@ -2415,7 +2418,9 @@ TabChildGlobal::Atob(const nsAString& aAsciiString,
|
||||
JSContext*
|
||||
TabChildGlobal::GetJSContextForEventHandlers()
|
||||
{
|
||||
return nsContentUtils::GetSafeJSContext();
|
||||
if (!mTabChild)
|
||||
return nullptr;
|
||||
return mTabChild->GetJSContext();
|
||||
}
|
||||
|
||||
nsIPrincipal*
|
||||
|
@ -282,6 +282,8 @@ public:
|
||||
|
||||
nsIWebNavigation* WebNavigation() { return mWebNav; }
|
||||
|
||||
JSContext* GetJSContext() { return mCx; }
|
||||
|
||||
nsIPrincipal* GetPrincipal() { return mPrincipal; }
|
||||
|
||||
/** Return the DPI of the widget this TabChild draws to. */
|
||||
|
@ -1091,7 +1091,7 @@ TabParent::ReceiveMessage(const nsString& aMessage,
|
||||
if (frameLoader && frameLoader->GetFrameMessageManager()) {
|
||||
nsRefPtr<nsFrameMessageManager> manager =
|
||||
frameLoader->GetFrameMessageManager();
|
||||
AutoSafeJSContext ctx;
|
||||
AutoPushJSContext ctx(manager->GetJSContext());
|
||||
uint32_t len = 0; //TODO: obtain a real value in bug 572685
|
||||
// Because we want JS messages to have always the same properties,
|
||||
// create array even if len == 0.
|
||||
|
Loading…
x
Reference in New Issue
Block a user