Commit 611dfce7 authored by nhiroki's avatar nhiroki Committed by Commit bot

Bindings: Separate WorldIdConstants to WorldTypes and WorldId

This is a clean-up CL and doesn't change behavior.

For improving extensibility, this CL separates WorldIdConstants to 2 parts:
WorldTypes and WorldId. This encapsulates identifier allocation logic in
DOMWrapperWorld[1] and makes it easier to expand the identifier space for
Worklets[2].

[1] WorldIds for IsolatedWorlds still need to be given from out of
    DOMWrapperWorld because of its unique convention to allocate the identifier.
[2] https://codereview.chromium.org/2735823006/

BUG=697622, 697629

Review-Url: https://codereview.chromium.org/2735973006
Cr-Commit-Position: refs/heads/master@{#455700}
parent 5e556038
......@@ -51,7 +51,7 @@ class DOMObjectHolderBase {
public:
DOMObjectHolderBase(v8::Isolate* isolate, v8::Local<v8::Value> wrapper)
: m_wrapper(isolate, wrapper), m_world(0) {}
: m_wrapper(isolate, wrapper), m_world(nullptr) {}
virtual ~DOMObjectHolderBase() {}
DOMWrapperWorld* world() const { return m_world; }
......@@ -84,18 +84,22 @@ class DOMObjectHolder : public DOMObjectHolderBase {
unsigned DOMWrapperWorld::s_numberOfNonMainWorldsInMainThread = 0;
PassRefPtr<DOMWrapperWorld> DOMWrapperWorld::create(v8::Isolate* isolate,
int worldId) {
return adoptRef(new DOMWrapperWorld(isolate, worldId));
WorldType worldType) {
DCHECK_NE(WorldType::Isolated, worldType);
return adoptRef(
new DOMWrapperWorld(isolate, worldType, getWorldIdForType(worldType)));
}
DOMWrapperWorld::DOMWrapperWorld(v8::Isolate* isolate, int worldId)
: m_worldId(worldId),
DOMWrapperWorld::DOMWrapperWorld(v8::Isolate* isolate,
WorldType worldType,
int worldId)
: m_worldType(worldType),
m_worldId(worldId),
m_domDataStore(
WTF::wrapUnique(new DOMDataStore(isolate, isMainWorld()))) {
if (worldId == WorkerWorldId) {
if (isWorkerWorld())
workerWorld() = this;
}
if (worldId != MainWorldId && isMainThread())
if (worldId != WorldId::MainWorldId && isMainThread())
s_numberOfNonMainWorldsInMainThread++;
}
......@@ -103,7 +107,7 @@ DOMWrapperWorld& DOMWrapperWorld::mainWorld() {
ASSERT(isMainThread());
DEFINE_STATIC_REF(
DOMWrapperWorld, cachedMainWorld,
(DOMWrapperWorld::create(v8::Isolate::GetCurrent(), MainWorldId)));
(DOMWrapperWorld::create(v8::Isolate::GetCurrent(), WorldType::Main)));
return *cachedMainWorld;
}
......@@ -195,7 +199,8 @@ void DOMWrapperWorld::dispose() {
#if DCHECK_IS_ON()
static bool isIsolatedWorldId(int worldId) {
return MainWorldId < worldId && worldId < IsolatedWorldIdLimit;
return DOMWrapperWorld::MainWorldId < worldId &&
worldId < DOMWrapperWorld::IsolatedWorldIdLimit;
}
#endif
......@@ -212,7 +217,7 @@ PassRefPtr<DOMWrapperWorld> DOMWrapperWorld::ensureIsolatedWorld(
return world.release();
}
world = DOMWrapperWorld::create(isolate, worldId);
world = adoptRef(new DOMWrapperWorld(isolate, WorldType::Isolated, worldId));
result.storedValue->value = world.get();
return world.release();
}
......@@ -318,4 +323,30 @@ void DOMWrapperWorld::weakCallbackForDOMObjectHolder(
holderBase->world()->unregisterDOMObjectHolder(holderBase);
}
int DOMWrapperWorld::getWorldIdForType(WorldType worldType) {
switch (worldType) {
case WorldType::Main:
return MainWorldId;
case WorldType::Isolated:
// This function should not be called for IsolatedWorld because an
// identifier for the world is given from out of DOMWrapperWorld.
NOTREACHED();
return InvalidWorldId;
case WorldType::GarbageCollector:
return GarbageCollectorWorldId;
case WorldType::RegExp:
return RegExpWorldId;
case WorldType::Testing:
return TestingWorldId;
// Currently, WorldId for a worker/worklet is a fixed value, but this
// doesn't work when multiple worklets are created on a thread.
// TODO(nhiroki): Expand the identifier space for workers/worklets.
// (https://crbug.com/697622)
case WorldType::Worker:
return WorkerWorldId;
}
NOTREACHED();
return InvalidWorldId;
}
} // namespace blink
......@@ -44,24 +44,44 @@
namespace blink {
class DOMDataStore;
enum WorldIdConstants {
MainWorldId = 0,
// Embedder isolated worlds can use IDs in [1, 1<<29).
EmbedderWorldIdLimit = (1 << 29),
DocumentXMLTreeViewerWorldId,
IsolatedWorldIdLimit,
WorkerWorldId,
TestingWorldId,
};
class DOMObjectHolderBase;
// This class represent a collection of DOM wrappers for a specific world.
// This class represent a collection of DOM wrappers for a specific world. This
// is identified by a world id that is a per-thread global identifier (see
// WorldId enum).
class CORE_EXPORT DOMWrapperWorld : public RefCounted<DOMWrapperWorld> {
public:
static PassRefPtr<DOMWrapperWorld> create(v8::Isolate*, int worldId = -1);
// Per-thread global identifiers for DOMWrapperWorld.
enum WorldId {
InvalidWorldId = -1,
MainWorldId = 0,
// Embedder isolated worlds can use IDs in [1, 1<<29).
EmbedderWorldIdLimit = (1 << 29),
DocumentXMLTreeViewerWorldId,
IsolatedWorldIdLimit,
// TODO(nhiroki): Dynamically allocate a world id for the following worlds
// instead of a fixed value (https://crbug.com/697622).
GarbageCollectorWorldId,
RegExpWorldId,
TestingWorldId,
WorkerWorldId,
};
enum class WorldType {
Main,
Isolated,
GarbageCollector,
RegExp,
Testing,
Worker,
};
// Creates a world other than IsolatedWorld.
static PassRefPtr<DOMWrapperWorld> create(v8::Isolate*, WorldType);
// Ensures an IsolatedWorld for |worldId|.
static PassRefPtr<DOMWrapperWorld> ensureIsolatedWorld(v8::Isolate*,
int worldId);
~DOMWrapperWorld();
......@@ -108,11 +128,9 @@ class CORE_EXPORT DOMWrapperWorld : public RefCounted<DOMWrapperWorld> {
const String& policy);
bool isolatedWorldHasContentSecurityPolicy();
bool isMainWorld() const { return m_worldId == MainWorldId; }
bool isWorkerWorld() const { return m_worldId == WorkerWorldId; }
bool isIsolatedWorld() const {
return MainWorldId < m_worldId && m_worldId < IsolatedWorldIdLimit;
}
bool isMainWorld() const { return m_worldType == WorldType::Main; }
bool isWorkerWorld() const { return m_worldType == WorldType::Worker; }
bool isIsolatedWorld() const { return m_worldType == WorldType::Isolated; }
int worldId() const { return m_worldId; }
DOMDataStore& domDataStore() const { return *m_domDataStore; }
......@@ -122,7 +140,7 @@ class CORE_EXPORT DOMWrapperWorld : public RefCounted<DOMWrapperWorld> {
void registerDOMObjectHolder(v8::Isolate*, T*, v8::Local<v8::Value>);
private:
DOMWrapperWorld(v8::Isolate*, int worldId);
DOMWrapperWorld(v8::Isolate*, WorldType, int worldId);
static void weakCallbackForDOMObjectHolder(
const v8::WeakCallbackInfo<DOMObjectHolderBase>&);
......@@ -131,6 +149,12 @@ class CORE_EXPORT DOMWrapperWorld : public RefCounted<DOMWrapperWorld> {
static unsigned s_numberOfNonMainWorldsInMainThread;
// Returns an identifier for a given world type. This must not call for
// WorldType::IsolatedWorld because an identifier for the world is given from
// out of DOMWrapperWorld.
static int getWorldIdForType(WorldType);
const WorldType m_worldType;
const int m_worldId;
std::unique_ptr<DOMDataStore> m_domDataStore;
HashSet<std::unique_ptr<DOMObjectHolderBase>> m_domObjectHolders;
......
......@@ -449,7 +449,9 @@ void V8GCController::gcEpilogue(v8::Isolate* isolate,
void V8GCController::collectGarbage(v8::Isolate* isolate, bool onlyMinorGC) {
v8::HandleScope handleScope(isolate);
RefPtr<ScriptState> scriptState = ScriptState::create(
v8::Context::New(isolate), DOMWrapperWorld::create(isolate));
v8::Context::New(isolate),
DOMWrapperWorld::create(isolate,
DOMWrapperWorld::WorldType::GarbageCollector));
ScriptState::Scope scope(scriptState.get());
StringBuilder builder;
builder.append("if (gc) gc(");
......
......@@ -193,8 +193,9 @@ v8::Local<v8::Context> V8PerIsolateData::ensureScriptRegexpContext() {
if (!m_scriptRegexpScriptState) {
LEAK_SANITIZER_DISABLED_SCOPE;
v8::Local<v8::Context> context(v8::Context::New(isolate()));
m_scriptRegexpScriptState =
ScriptState::create(context, DOMWrapperWorld::create(isolate()));
m_scriptRegexpScriptState = ScriptState::create(
context,
DOMWrapperWorld::create(isolate(), DOMWrapperWorld::WorldType::RegExp));
}
return m_scriptRegexpScriptState->context();
}
......
......@@ -103,7 +103,8 @@ WorkerOrWorkletScriptController::WorkerOrWorkletScriptController(
m_rejectedPromises(RejectedPromises::create()),
m_executionState(0) {
ASSERT(isolate);
m_world = DOMWrapperWorld::create(isolate, WorkerWorldId);
m_world =
DOMWrapperWorld::create(isolate, DOMWrapperWorld::WorldType::Worker);
}
WorkerOrWorkletScriptController::~WorkerOrWorkletScriptController() {
......
......@@ -24,7 +24,7 @@ void transformDocumentToXMLTreeView(Document& document) {
v8::HandleScope handleScope(V8PerIsolateData::mainThreadIsolate());
document.frame()->script().executeScriptInIsolatedWorld(
WorldIdConstants::DocumentXMLTreeViewerWorldId, sources, nullptr);
DOMWrapperWorld::DocumentXMLTreeViewerWorldId, sources, nullptr);
Element* element = document.getElementById("xml-viewer-style");
if (element) {
......
......@@ -69,8 +69,10 @@ void DataConsumerHandleTestUtil::Thread::initialize() {
m_thread->initialize();
if (m_initializationPolicy >= ScriptExecution) {
v8::HandleScope handleScope(isolate());
m_scriptState = ScriptState::create(v8::Context::New(isolate()),
DOMWrapperWorld::create(isolate()));
m_scriptState = ScriptState::create(
v8::Context::New(isolate()),
DOMWrapperWorld::create(isolate(),
DOMWrapperWorld::WorldType::Testing));
}
if (m_initializationPolicy >= WithExecutionContext) {
m_executionContext = new NullExecutionContext();
......
......@@ -671,7 +671,7 @@ void WebLocalFrameImpl::executeScriptInIsolatedWorld(
unsigned numSources) {
DCHECK(frame());
CHECK_GT(worldID, 0);
CHECK_LT(worldID, EmbedderWorldIdLimit);
CHECK_LT(worldID, DOMWrapperWorld::EmbedderWorldIdLimit);
HeapVector<ScriptSourceCode> sources =
createSourcesVector(sourcesIn, numSources);
......@@ -775,7 +775,7 @@ void WebLocalFrameImpl::executeScriptInIsolatedWorld(
WebVector<v8::Local<v8::Value>>* results) {
DCHECK(frame());
CHECK_GT(worldID, 0);
CHECK_LT(worldID, EmbedderWorldIdLimit);
CHECK_LT(worldID, DOMWrapperWorld::EmbedderWorldIdLimit);
HeapVector<ScriptSourceCode> sources =
createSourcesVector(sourcesIn, numSources);
......@@ -803,7 +803,7 @@ void WebLocalFrameImpl::requestExecuteScriptInIsolatedWorld(
WebScriptExecutionCallback* callback) {
DCHECK(frame());
CHECK_GT(worldID, 0);
CHECK_LT(worldID, EmbedderWorldIdLimit);
CHECK_LT(worldID, DOMWrapperWorld::EmbedderWorldIdLimit);
SuspendableScriptExecutor::createAndRun(
frame(), worldID, createSourcesVector(sourcesIn, numSources), userGesture,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment