mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 989528 - Implement AutoJSAPI. r=bz
This commit is contained in:
parent
95b4d38749
commit
6ecb59c370
@ -184,7 +184,7 @@ GetWebIDLCallerPrincipal()
|
|||||||
// that we should return a non-null WebIDL Caller.
|
// that we should return a non-null WebIDL Caller.
|
||||||
//
|
//
|
||||||
// Once we fix bug 951991, this can all be simplified.
|
// Once we fix bug 951991, this can all be simplified.
|
||||||
if (!aes->mCxPusher.ref().IsStackTop()) {
|
if (!aes->CxPusherIsStackTop()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,28 +206,43 @@ FindJSContext(nsIGlobalObject* aGlobalObject)
|
|||||||
return cx;
|
return cx;
|
||||||
}
|
}
|
||||||
|
|
||||||
AutoEntryScript::AutoEntryScript(nsIGlobalObject* aGlobalObject,
|
AutoJSAPI::AutoJSAPI()
|
||||||
bool aIsMainThread,
|
: mCx(nsContentUtils::GetDefaultJSContextForThread())
|
||||||
JSContext* aCx)
|
|
||||||
: ScriptSettingsStackEntry(aGlobalObject, /* aCandidate = */ true)
|
|
||||||
, mStack(ScriptSettingsStack::Ref())
|
|
||||||
, mCx(aCx)
|
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aGlobalObject);
|
if (NS_IsMainThread()) {
|
||||||
MOZ_ASSERT_IF(!mCx, aIsMainThread); // cx is mandatory off-main-thread.
|
mCxPusher.construct(mCx);
|
||||||
MOZ_ASSERT_IF(mCx && aIsMainThread, mCx == FindJSContext(aGlobalObject));
|
|
||||||
if (!mCx) {
|
|
||||||
// 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.
|
|
||||||
mCx = FindJSContext(aGlobalObject);
|
|
||||||
MOZ_ASSERT(mCx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Leave the cx in a null compartment.
|
||||||
|
mNullAc.construct(mCx);
|
||||||
|
}
|
||||||
|
|
||||||
|
AutoJSAPI::AutoJSAPI(JSContext *aCx, bool aIsMainThread, bool aSkipNullAc)
|
||||||
|
: mCx(aCx)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT_IF(aIsMainThread, NS_IsMainThread());
|
||||||
if (aIsMainThread) {
|
if (aIsMainThread) {
|
||||||
mCxPusher.construct(mCx);
|
mCxPusher.construct(mCx);
|
||||||
}
|
}
|
||||||
mAc.construct(mCx, aGlobalObject->GetGlobalJSObject());
|
|
||||||
|
// In general we want to leave the cx in a null compartment, but we let
|
||||||
|
// subclasses skip this if they plan to immediately enter a compartment.
|
||||||
|
if (!aSkipNullAc) {
|
||||||
|
mNullAc.construct(mCx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AutoEntryScript::AutoEntryScript(nsIGlobalObject* aGlobalObject,
|
||||||
|
bool aIsMainThread,
|
||||||
|
JSContext* aCx)
|
||||||
|
: AutoJSAPI(aCx ? aCx : FindJSContext(aGlobalObject), aIsMainThread, /* aSkipNullAc = */ true)
|
||||||
|
, ScriptSettingsStackEntry(aGlobalObject, /* aCandidate = */ true)
|
||||||
|
, mAc(cx(), aGlobalObject->GetGlobalJSObject())
|
||||||
|
, mStack(ScriptSettingsStack::Ref())
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aGlobalObject);
|
||||||
|
MOZ_ASSERT_IF(!aCx, aIsMainThread); // cx is mandatory off-main-thread.
|
||||||
|
MOZ_ASSERT_IF(aCx && aIsMainThread, aCx == FindJSContext(aGlobalObject));
|
||||||
mStack.Push(this);
|
mStack.Push(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,10 +95,64 @@ private:
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For any interaction with JSAPI, an AutoJSAPI (or one of its subclasses)
|
||||||
|
* must be on the stack.
|
||||||
|
*
|
||||||
|
* This base class should be instantiated as-is when the caller wants to use
|
||||||
|
* JSAPI but doesn't expect to run script. Its current duties are as-follows:
|
||||||
|
*
|
||||||
|
* * Grabbing an appropriate JSContext, and, on the main thread, pushing it onto
|
||||||
|
* the JSContext stack.
|
||||||
|
* * Entering a null compartment, so that the consumer is forced to select a
|
||||||
|
* compartment to enter before manipulating objects.
|
||||||
|
*
|
||||||
|
* Additionally, the following duties are planned, but not yet implemented:
|
||||||
|
*
|
||||||
|
* * De-poisoning the JSRuntime to allow manipulation of JSAPI. We can't
|
||||||
|
* actually implement this poisoning until all the JSContext pushing in the
|
||||||
|
* system goes through AutoJSAPI (see bug 951991). For now, this de-poisoning
|
||||||
|
* effectively corresponds to having a non-null cx on the stack.
|
||||||
|
* * Reporting any exceptions left on the JSRuntime, unless the caller steals
|
||||||
|
* or silences them.
|
||||||
|
* * Entering a JSAutoRequest. At present, this is handled by the cx pushing
|
||||||
|
* on the main thread, and by other code on workers. Depending on the order
|
||||||
|
* in which various cleanup lands, this may never be necessary, because
|
||||||
|
* JSAutoRequests may go away.
|
||||||
|
*
|
||||||
|
* In situations where the consumer expects to run script, AutoEntryScript
|
||||||
|
* should be used, which does additional manipulation of the script settings
|
||||||
|
* stack. In bug 991758, we'll add hard invariants to SpiderMonkey, such that
|
||||||
|
* any attempt to run script without an AutoEntryScript on the stack will
|
||||||
|
* fail. This prevents system code from accidentally triggering script
|
||||||
|
* execution at inopportune moments via surreptitious getters and proxies.
|
||||||
|
*/
|
||||||
|
class AutoJSAPI {
|
||||||
|
public:
|
||||||
|
// Public constructor for use when the base class is constructed as-is. It
|
||||||
|
// uses the SafeJSContext (or worker equivalent), and enters a null
|
||||||
|
// compartment.
|
||||||
|
AutoJSAPI();
|
||||||
|
JSContext* cx() const { return mCx; }
|
||||||
|
|
||||||
|
bool CxPusherIsStackTop() { return mCxPusher.ref().IsStackTop(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Protected constructor, allowing subclasses to specify a particular cx to
|
||||||
|
// be used.
|
||||||
|
AutoJSAPI(JSContext *aCx, bool aIsMainThread, bool aSkipNullAC = false);
|
||||||
|
|
||||||
|
private:
|
||||||
|
mozilla::Maybe<AutoCxPusher> mCxPusher;
|
||||||
|
mozilla::Maybe<JSAutoNullCompartment> mNullAc;
|
||||||
|
JSContext *mCx;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A class that represents a new script entry point.
|
* A class that represents a new script entry point.
|
||||||
*/
|
*/
|
||||||
class AutoEntryScript : protected ScriptSettingsStackEntry {
|
class AutoEntryScript : public AutoJSAPI,
|
||||||
|
protected ScriptSettingsStackEntry {
|
||||||
public:
|
public:
|
||||||
AutoEntryScript(nsIGlobalObject* aGlobalObject,
|
AutoEntryScript(nsIGlobalObject* aGlobalObject,
|
||||||
bool aIsMainThread = NS_IsMainThread(),
|
bool aIsMainThread = NS_IsMainThread(),
|
||||||
@ -110,15 +164,10 @@ public:
|
|||||||
mWebIDLCallerPrincipal = aPrincipal;
|
mWebIDLCallerPrincipal = aPrincipal;
|
||||||
}
|
}
|
||||||
|
|
||||||
JSContext* cx() const { return mCx; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
JSAutoCompartment mAc;
|
||||||
dom::ScriptSettingsStack& mStack;
|
dom::ScriptSettingsStack& mStack;
|
||||||
nsCOMPtr<nsIPrincipal> mWebIDLCallerPrincipal;
|
nsCOMPtr<nsIPrincipal> mWebIDLCallerPrincipal;
|
||||||
JSContext *mCx;
|
|
||||||
mozilla::Maybe<AutoCxPusher> mCxPusher;
|
|
||||||
mozilla::Maybe<JSAutoCompartment> mAc; // This can de-Maybe-fy when mCxPusher
|
|
||||||
// goes away.
|
|
||||||
friend nsIPrincipal* GetWebIDLCallerPrincipal();
|
friend nsIPrincipal* GetWebIDLCallerPrincipal();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user