mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 937317 - Implement basic script settings stack machinery. r=bz
This commit is contained in:
parent
04c4f10a48
commit
c311c9dc85
@ -5,14 +5,92 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/ThreadLocal.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "nsIGlobalObject.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIScriptContext.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class ScriptSettingsStack;
|
||||
static mozilla::ThreadLocal<ScriptSettingsStack*> sScriptSettingsTLS;
|
||||
|
||||
ScriptSettingsStackEntry ScriptSettingsStackEntry::SystemSingleton;
|
||||
|
||||
class ScriptSettingsStack {
|
||||
public:
|
||||
static ScriptSettingsStack& Ref() {
|
||||
return *sScriptSettingsTLS.get();
|
||||
}
|
||||
ScriptSettingsStack() {};
|
||||
|
||||
void Push(ScriptSettingsStackEntry* aSettings) {
|
||||
// The bottom-most entry must always be a candidate entry point.
|
||||
MOZ_ASSERT_IF(mStack.Length() == 0 || mStack.LastElement()->IsSystemSingleton(),
|
||||
aSettings->mIsCandidateEntryPoint);
|
||||
mStack.AppendElement(aSettings);
|
||||
}
|
||||
|
||||
void PushSystem() {
|
||||
mStack.AppendElement(&ScriptSettingsStackEntry::SystemSingleton);
|
||||
}
|
||||
|
||||
void Pop() {
|
||||
MOZ_ASSERT(mStack.Length() > 0);
|
||||
mStack.RemoveElementAt(mStack.Length() - 1);
|
||||
}
|
||||
|
||||
nsIGlobalObject* Incumbent() {
|
||||
if (!mStack.Length()) {
|
||||
return nullptr;
|
||||
}
|
||||
return mStack.LastElement()->mGlobalObject;
|
||||
}
|
||||
|
||||
nsIGlobalObject* EntryPoint() {
|
||||
if (!mStack.Length())
|
||||
return nullptr;
|
||||
for (int i = mStack.Length() - 1; i >= 0; --i) {
|
||||
if (mStack[i]->mIsCandidateEntryPoint) {
|
||||
return mStack[i]->mGlobalObject;
|
||||
}
|
||||
}
|
||||
MOZ_ASSUME_UNREACHABLE();
|
||||
}
|
||||
|
||||
private:
|
||||
// These pointers are caller-owned.
|
||||
nsTArray<ScriptSettingsStackEntry*> mStack;
|
||||
};
|
||||
|
||||
void
|
||||
InitScriptSettings()
|
||||
{
|
||||
if (!sScriptSettingsTLS.initialized()) {
|
||||
bool success = sScriptSettingsTLS.init();
|
||||
if (!success) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
}
|
||||
|
||||
ScriptSettingsStack* ptr = new ScriptSettingsStack();
|
||||
sScriptSettingsTLS.set(ptr);
|
||||
}
|
||||
|
||||
void DestroyScriptSettings()
|
||||
{
|
||||
ScriptSettingsStack* ptr = sScriptSettingsTLS.get();
|
||||
MOZ_ASSERT(ptr);
|
||||
sScriptSettingsTLS.set(nullptr);
|
||||
delete ptr;
|
||||
}
|
||||
|
||||
AutoEntryScript::AutoEntryScript(nsIGlobalObject* aGlobalObject,
|
||||
bool aIsMainThread,
|
||||
JSContext* aCx)
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "nsCxPusher.h"
|
||||
#include "MainThreadUtils.h"
|
||||
#include "nsIGlobalObject.h"
|
||||
|
||||
#include "mozilla/Maybe.h"
|
||||
|
||||
@ -19,6 +20,42 @@ class nsIGlobalObject;
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
/*
|
||||
* System-wide setup/teardown routines. Init and Destroy should be invoked
|
||||
* once each, at startup and shutdown (respectively).
|
||||
*/
|
||||
void InitScriptSettings();
|
||||
void DestroyScriptSettings();
|
||||
|
||||
struct ScriptSettingsStackEntry {
|
||||
nsCOMPtr<nsIGlobalObject> mGlobalObject;
|
||||
bool mIsCandidateEntryPoint;
|
||||
|
||||
ScriptSettingsStackEntry(nsIGlobalObject *aGlobal, bool aCandidate)
|
||||
: mGlobalObject(aGlobal)
|
||||
, mIsCandidateEntryPoint(aCandidate)
|
||||
{
|
||||
MOZ_ASSERT(mGlobalObject);
|
||||
MOZ_ASSERT(mGlobalObject->GetGlobalJSObject(),
|
||||
"Must have an actual JS global for the duration on the stack");
|
||||
MOZ_ASSERT(JS_IsGlobalObject(mGlobalObject->GetGlobalJSObject()),
|
||||
"No outer windows allowed");
|
||||
}
|
||||
|
||||
~ScriptSettingsStackEntry() {
|
||||
// We must have an actual JS global for the entire time this is on the stack.
|
||||
MOZ_ASSERT_IF(mGlobalObject, mGlobalObject->GetGlobalJSObject());
|
||||
}
|
||||
|
||||
bool IsSystemSingleton() { return this == &SystemSingleton; }
|
||||
static ScriptSettingsStackEntry SystemSingleton;
|
||||
|
||||
private:
|
||||
ScriptSettingsStackEntry() : mGlobalObject(nullptr)
|
||||
, mIsCandidateEntryPoint(true)
|
||||
{}
|
||||
};
|
||||
|
||||
/*
|
||||
* A class that represents a new script entry point.
|
||||
*/
|
||||
|
@ -54,7 +54,10 @@ typedef sig_atomic_t sig_safe_t;
|
||||
*
|
||||
* API usage:
|
||||
*
|
||||
* // Create a TLS item
|
||||
* // Create a TLS item.
|
||||
* //
|
||||
* // Note that init() should be invoked exactly once, before any usage of set()
|
||||
* // or get().
|
||||
* mozilla::ThreadLocal<int> tlsKey;
|
||||
* if (!tlsKey.init()) {
|
||||
* // deal with the error
|
||||
|
@ -59,6 +59,7 @@
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/DOMJSClass.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "jsprf.h"
|
||||
#include "nsCycleCollectionNoteRootCallback.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
@ -441,6 +442,8 @@ CycleCollectedJSRuntime::CycleCollectedJSRuntime(uint32_t aMaxbytes,
|
||||
mJSRuntime(nullptr),
|
||||
mJSHolders(512)
|
||||
{
|
||||
mozilla::dom::InitScriptSettings();
|
||||
|
||||
mJSRuntime = JS_NewRuntime(aMaxbytes, aUseHelperThreads);
|
||||
if (!mJSRuntime) {
|
||||
MOZ_CRASH();
|
||||
@ -470,6 +473,8 @@ CycleCollectedJSRuntime::~CycleCollectedJSRuntime()
|
||||
JS_DestroyRuntime(mJSRuntime);
|
||||
mJSRuntime = nullptr;
|
||||
nsCycleCollector_forgetJSRuntime();
|
||||
|
||||
mozilla::dom::DestroyScriptSettings();
|
||||
}
|
||||
|
||||
size_t
|
||||
|
Loading…
Reference in New Issue
Block a user