mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 937317 - Factor out the shareable parts of CallSetup into AutoEntryScript and AutoIncubentScript. r=bz
This commit is contained in:
parent
7bba051425
commit
ef4bb3070d
54
dom/base/ScriptSettings.cpp
Normal file
54
dom/base/ScriptSettings.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
// vim: ft=cpp tw=78 sw=2 et ts=2
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIScriptContext.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
AutoEntryScript::AutoEntryScript(nsIGlobalObject* aGlobalObject,
|
||||
bool aIsMainThread,
|
||||
JSContext* aCx)
|
||||
{
|
||||
MOZ_ASSERT(aGlobalObject);
|
||||
if (!aCx) {
|
||||
// If the caller didn't provide a cx, hunt one down. This isn't exactly
|
||||
// fast, but the callers that care about performance can pass an explicit
|
||||
// cx for now. Eventually, the whole cx pushing thing will go away
|
||||
// entirely.
|
||||
MOZ_ASSERT(aIsMainThread, "cx is mandatory off-main-thread");
|
||||
nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aGlobalObject);
|
||||
if (sgo && sgo->GetScriptContext()) {
|
||||
aCx = sgo->GetScriptContext()->GetNativeContext();
|
||||
}
|
||||
if (!aCx) {
|
||||
aCx = nsContentUtils::GetSafeJSContext();
|
||||
}
|
||||
}
|
||||
if (aIsMainThread) {
|
||||
mCxPusher.Push(aCx);
|
||||
}
|
||||
mAc.construct(aCx, aGlobalObject->GetGlobalJSObject());
|
||||
}
|
||||
|
||||
AutoIncumbentScript::AutoIncumbentScript(nsIGlobalObject* aGlobalObject)
|
||||
{
|
||||
MOZ_ASSERT(aGlobalObject);
|
||||
}
|
||||
|
||||
AutoSystemCaller::AutoSystemCaller(bool aIsMainThread)
|
||||
{
|
||||
if (aIsMainThread) {
|
||||
mCxPusher.PushNull();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
61
dom/base/ScriptSettings.h
Normal file
61
dom/base/ScriptSettings.h
Normal file
@ -0,0 +1,61 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
// vim: ft=cpp tw=78 sw=2 et ts=2
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* Utilities for managing the script settings object stack defined in webapps */
|
||||
|
||||
#ifndef mozilla_dom_ScriptSettings_h
|
||||
#define mozilla_dom_ScriptSettings_h
|
||||
|
||||
#include "nsCxPusher.h"
|
||||
#include "MainThreadUtils.h"
|
||||
|
||||
#include "mozilla/Maybe.h"
|
||||
|
||||
class nsIGlobalObject;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
/*
|
||||
* A class that represents a new script entry point.
|
||||
*/
|
||||
class AutoEntryScript {
|
||||
public:
|
||||
AutoEntryScript(nsIGlobalObject* aGlobalObject,
|
||||
bool aIsMainThread = NS_IsMainThread(),
|
||||
// Note: aCx is mandatory off-main-thread.
|
||||
JSContext* aCx = nullptr);
|
||||
|
||||
private:
|
||||
nsCxPusher mCxPusher;
|
||||
mozilla::Maybe<JSAutoCompartment> mAc; // This can de-Maybe-fy when mCxPusher
|
||||
// goes away.
|
||||
};
|
||||
|
||||
/*
|
||||
* A class that can be used to force a particular incumbent script on the stack.
|
||||
*/
|
||||
class AutoIncumbentScript {
|
||||
public:
|
||||
AutoIncumbentScript(nsIGlobalObject* aGlobalObject);
|
||||
};
|
||||
|
||||
/*
|
||||
* A class used for C++ to indicate that existing entry and incumbent scripts
|
||||
* should not apply to anything in scope, and that callees should act as if
|
||||
* they were invoked "from C++".
|
||||
*/
|
||||
class AutoSystemCaller {
|
||||
public:
|
||||
AutoSystemCaller(bool aIsMainThread = NS_IsMainThread());
|
||||
private:
|
||||
nsCxPusher mCxPusher;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_ScriptSettings_h
|
@ -59,6 +59,7 @@ EXPORTS.mozilla.dom += [
|
||||
'MessagePortList.h',
|
||||
'Navigator.h',
|
||||
'ScreenOrientation.h',
|
||||
'ScriptSettings.h',
|
||||
'StructuredCloneTags.h',
|
||||
'URL.h',
|
||||
]
|
||||
@ -94,6 +95,7 @@ UNIFIED_SOURCES += [
|
||||
'nsWindowMemoryReporter.cpp',
|
||||
'nsWindowRoot.cpp',
|
||||
'nsWrapperCache.cpp',
|
||||
'ScriptSettings.cpp',
|
||||
'URL.cpp',
|
||||
'WindowNamedPropertiesHandler.cpp',
|
||||
]
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "xpcprivate.h"
|
||||
#include "WorkerPrivate.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "WorkerScope.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -65,6 +66,7 @@ CallbackObject::CallSetup::CallSetup(JS::Handle<JSObject*> aCallback,
|
||||
// First, find the real underlying callback.
|
||||
JSObject* realCallback = js::UncheckedUnwrap(aCallback);
|
||||
JSContext* cx = nullptr;
|
||||
nsIGlobalObject* globalObject = nullptr;
|
||||
|
||||
if (mIsMainThread) {
|
||||
// Now get the global and JSContext for this callback.
|
||||
@ -85,17 +87,21 @@ CallbackObject::CallSetup::CallSetup(JS::Handle<JSObject*> aCallback,
|
||||
// This happens - Removing it causes
|
||||
// test_bug293235.xul to go orange.
|
||||
: nsContentUtils::GetSafeJSContext();
|
||||
globalObject = win;
|
||||
} else {
|
||||
// No DOM Window. Use the SafeJSContext.
|
||||
// No DOM Window. Store the global and use the SafeJSContext.
|
||||
JSObject* glob = js::GetGlobalForObjectCrossCompartment(realCallback);
|
||||
globalObject = xpc::GetNativeForGlobal(glob);
|
||||
MOZ_ASSERT(globalObject);
|
||||
cx = nsContentUtils::GetSafeJSContext();
|
||||
}
|
||||
|
||||
// Make sure our JSContext is pushed on the stack.
|
||||
mCxPusher.Push(cx);
|
||||
} else {
|
||||
cx = workers::GetCurrentThreadJSContext();
|
||||
globalObject = workers::GetCurrentThreadWorkerPrivate()->GlobalScope();
|
||||
}
|
||||
|
||||
mAutoEntryScript.construct(globalObject, mIsMainThread, cx);
|
||||
|
||||
// Unmark the callable, and stick it in a Rooted before it can go gray again.
|
||||
// Nothing before us in this function can trigger a CC, so it's safe to wait
|
||||
// until here it do the unmark. This allows us to order the following two
|
||||
@ -120,6 +126,10 @@ CallbackObject::CallSetup::CallSetup(JS::Handle<JSObject*> aCallback,
|
||||
}
|
||||
|
||||
// Enter the compartment of our callback, so we can actually work with it.
|
||||
//
|
||||
// Note that if the callback is a wrapper, this will not be the same
|
||||
// compartment that we ended up in with mAutoEntryScript above, because the
|
||||
// entry point is based off of the unwrapped callback (realCallback).
|
||||
mAc.construct(cx, aCallback);
|
||||
|
||||
// And now we're ready to go.
|
||||
@ -194,17 +204,10 @@ CallbackObject::CallSetup::~CallSetup()
|
||||
// But be careful: it might not have been constructed at all!
|
||||
mAc.destroyIfConstructed();
|
||||
|
||||
// XXXbz For that matter why do we need to manually call ScriptEvaluated at
|
||||
// all? nsCxPusher::Pop will do that nowadays if !mScriptIsRunning, so the
|
||||
// concerns from bug 295983 don't seem relevant anymore. Do we want to make
|
||||
// sure it's still called when !mScriptIsRunning? I guess play it safe for
|
||||
// now and do what CallEventHandler did, which is call always.
|
||||
|
||||
// Popping an nsCxPusher is safe even if it never got pushed.
|
||||
mCxPusher.Pop();
|
||||
mAutoEntryScript.destroyIfConstructed();
|
||||
|
||||
// It is important that this is the last thing we do, after leaving the
|
||||
// compartment and popping the context.
|
||||
// compartment and undoing all our entry/incumbent script changes
|
||||
if (mIsMainThread) {
|
||||
nsContentUtils::LeaveMicroTask();
|
||||
}
|
||||
|
@ -25,8 +25,8 @@
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/HoldDropJSObjects.h"
|
||||
#include "mozilla/Util.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsCxPusher.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "nsJSEnvironment.h"
|
||||
#include "xpcpublic.h"
|
||||
@ -153,17 +153,16 @@ protected:
|
||||
JSCompartment* mCompartment;
|
||||
|
||||
// And now members whose construction/destruction order we need to control.
|
||||
|
||||
nsCxPusher mCxPusher;
|
||||
Maybe<AutoEntryScript> mAutoEntryScript;
|
||||
|
||||
// Constructed the rooter within the scope of mCxPusher above, so that it's
|
||||
// always within a request during its lifetime.
|
||||
Maybe<JS::Rooted<JSObject*> > mRootedCallable;
|
||||
|
||||
// Can't construct a JSAutoCompartment without a JSContext either. Also,
|
||||
// Put mAc after mCxPusher so that we exit the compartment before we pop the
|
||||
// JSContext. Though in practice we'll often manually order those two
|
||||
// things.
|
||||
// Put mAc after mAutoEntryScript so that we exit the compartment before
|
||||
// we pop the JSContext. Though in practice we'll often manually order
|
||||
// those two things.
|
||||
Maybe<JSAutoCompartment> mAc;
|
||||
|
||||
// An ErrorResult to possibly re-throw exceptions on and whether
|
||||
|
Loading…
Reference in New Issue
Block a user