diff options
Diffstat (limited to 'chromium/third_party/WebKit/Source/bindings/v8/V8PerIsolateData.cpp')
-rw-r--r-- | chromium/third_party/WebKit/Source/bindings/v8/V8PerIsolateData.cpp | 157 |
1 files changed, 103 insertions, 54 deletions
diff --git a/chromium/third_party/WebKit/Source/bindings/v8/V8PerIsolateData.cpp b/chromium/third_party/WebKit/Source/bindings/v8/V8PerIsolateData.cpp index 10064bc2dde..43dd26351e8 100644 --- a/chromium/third_party/WebKit/Source/bindings/v8/V8PerIsolateData.cpp +++ b/chromium/third_party/WebKit/Source/bindings/v8/V8PerIsolateData.cpp @@ -27,48 +27,74 @@ #include "bindings/v8/V8PerIsolateData.h" #include "bindings/v8/DOMDataStore.h" +#include "bindings/v8/PageScriptDebugServer.h" #include "bindings/v8/ScriptGCEvent.h" #include "bindings/v8/ScriptProfiler.h" #include "bindings/v8/V8Binding.h" -#include "bindings/v8/V8HiddenPropertyName.h" +#include "bindings/v8/V8HiddenValue.h" #include "bindings/v8/V8ObjectConstructor.h" +#include "bindings/v8/V8RecursionScope.h" #include "bindings/v8/V8ScriptRunner.h" +#include "public/platform/Platform.h" +#include "wtf/MainThread.h" namespace WebCore { +static V8PerIsolateData* mainThreadPerIsolateData = 0; + +#ifndef NDEBUG +static void assertV8RecursionScope() +{ + ASSERT(V8RecursionScope::properlyUsed(v8::Isolate::GetCurrent())); +} +#endif + V8PerIsolateData::V8PerIsolateData(v8::Isolate* isolate) : m_isolate(isolate) - , m_stringCache(adoptPtr(new StringCache())) - , m_workerDomDataStore(0) - , m_hiddenPropertyName(adoptPtr(new V8HiddenPropertyName())) + , m_isolateHolder(adoptPtr(new gin::IsolateHolder(m_isolate, v8ArrayBufferAllocator()))) + , m_stringCache(adoptPtr(new StringCache(m_isolate))) + , m_hiddenValue(adoptPtr(new V8HiddenValue())) , m_constructorMode(ConstructorMode::CreateNewObject) , m_recursionLevel(0) #ifndef NDEBUG , m_internalScriptRecursionLevel(0) #endif , m_gcEventData(adoptPtr(new GCEventData())) - , m_shouldCollectGarbageSoon(false) + , m_performingMicrotaskCheckpoint(false) { +#ifndef NDEBUG + // currentThread will always be non-null in production, but can be null in Chromium unit tests. + if (blink::Platform::current()->currentThread()) + isolate->AddCallCompletedCallback(&assertV8RecursionScope); +#endif + if (isMainThread()) { + mainThreadPerIsolateData = this; + PageScriptDebugServer::setMainThreadIsolate(isolate); + } } V8PerIsolateData::~V8PerIsolateData() { + if (m_scriptRegexpScriptState) + m_scriptRegexpScriptState->disposePerContextData(); + if (isMainThread()) + mainThreadPerIsolateData = 0; } -V8PerIsolateData* V8PerIsolateData::create(v8::Isolate* isolate) +v8::Isolate* V8PerIsolateData::mainThreadIsolate() { - ASSERT(isolate); - ASSERT(!isolate->GetData(gin::kEmbedderBlink)); - V8PerIsolateData* data = new V8PerIsolateData(isolate); - isolate->SetData(gin::kEmbedderBlink, data); - return data; + ASSERT(isMainThread()); + ASSERT(mainThreadPerIsolateData); + return mainThreadPerIsolateData->isolate(); } void V8PerIsolateData::ensureInitialized(v8::Isolate* isolate) { ASSERT(isolate); - if (!isolate->GetData(gin::kEmbedderBlink)) - create(isolate); + if (!isolate->GetData(gin::kEmbedderBlink)) { + V8PerIsolateData* data = new V8PerIsolateData(isolate); + isolate->SetData(gin::kEmbedderBlink, data); + } } v8::Persistent<v8::Value>& V8PerIsolateData::ensureLiveRoot() @@ -80,76 +106,92 @@ v8::Persistent<v8::Value>& V8PerIsolateData::ensureLiveRoot() void V8PerIsolateData::dispose(v8::Isolate* isolate) { +#ifndef NDEBUG + if (blink::Platform::current()->currentThread()) + isolate->RemoveCallCompletedCallback(&assertV8RecursionScope); +#endif void* data = isolate->GetData(gin::kEmbedderBlink); delete static_cast<V8PerIsolateData*>(data); isolate->SetData(gin::kEmbedderBlink, 0); } -v8::Handle<v8::FunctionTemplate> V8PerIsolateData::toStringTemplate() +V8PerIsolateData::DOMTemplateMap& V8PerIsolateData::currentDOMTemplateMap() { - if (m_toStringTemplate.isEmpty()) - m_toStringTemplate.set(m_isolate, v8::FunctionTemplate::New(m_isolate, constructorOfToString)); - return m_toStringTemplate.newLocal(m_isolate); + if (DOMWrapperWorld::current(m_isolate).isMainWorld()) + return m_domTemplateMapForMainWorld; + return m_domTemplateMapForNonMainWorld; } -v8::Handle<v8::FunctionTemplate> V8PerIsolateData::privateTemplate(WrapperWorldType currentWorldType, void* privatePointer, v8::FunctionCallback callback, v8::Handle<v8::Value> data, v8::Handle<v8::Signature> signature, int length) +v8::Handle<v8::FunctionTemplate> V8PerIsolateData::domTemplate(void* domTemplateKey, v8::FunctionCallback callback, v8::Handle<v8::Value> data, v8::Handle<v8::Signature> signature, int length) { - TemplateMap& templates = templateMap(currentWorldType); - TemplateMap::iterator result = templates.find(privatePointer); - if (result != templates.end()) - return result->value.newLocal(m_isolate); + DOMTemplateMap& domTemplateMap = currentDOMTemplateMap(); + DOMTemplateMap::iterator result = domTemplateMap.find(domTemplateKey); + if (result != domTemplateMap.end()) + return result->value.Get(m_isolate); + v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(m_isolate, callback, data, signature, length); - templates.add(privatePointer, UnsafePersistent<v8::FunctionTemplate>(m_isolate, templ)); + domTemplateMap.add(domTemplateKey, v8::Eternal<v8::FunctionTemplate>(m_isolate, templ)); return templ; } -v8::Handle<v8::FunctionTemplate> V8PerIsolateData::privateTemplateIfExists(WrapperWorldType currentWorldType, void* privatePointer) +v8::Handle<v8::FunctionTemplate> V8PerIsolateData::existingDOMTemplate(void* domTemplateKey) { - TemplateMap& templates = templateMap(currentWorldType); - TemplateMap::iterator result = templates.find(privatePointer); - if (result != templates.end()) - return result->value.newLocal(m_isolate); + DOMTemplateMap& domTemplateMap = currentDOMTemplateMap(); + DOMTemplateMap::iterator result = domTemplateMap.find(domTemplateKey); + if (result != domTemplateMap.end()) + return result->value.Get(m_isolate); return v8::Local<v8::FunctionTemplate>(); } -void V8PerIsolateData::setPrivateTemplate(WrapperWorldType currentWorldType, void* privatePointer, v8::Handle<v8::FunctionTemplate> templ) +void V8PerIsolateData::setDOMTemplate(void* domTemplateKey, v8::Handle<v8::FunctionTemplate> templ) { - templateMap(currentWorldType).add(privatePointer, UnsafePersistent<v8::FunctionTemplate>(m_isolate, templ)); + currentDOMTemplateMap().add(domTemplateKey, v8::Eternal<v8::FunctionTemplate>(m_isolate, v8::Local<v8::FunctionTemplate>(templ))); } -v8::Handle<v8::FunctionTemplate> V8PerIsolateData::rawDOMTemplate(const WrapperTypeInfo* info, WrapperWorldType currentWorldType) +v8::Local<v8::Context> V8PerIsolateData::ensureScriptRegexpContext() { - TemplateMap& templates = rawDOMTemplateMap(currentWorldType); - TemplateMap::iterator result = templates.find(info); - if (result != templates.end()) - return result->value.newLocal(m_isolate); - - v8::EscapableHandleScope handleScope(m_isolate); - v8::Local<v8::FunctionTemplate> templ = createRawTemplate(m_isolate); - templates.add(info, UnsafePersistent<v8::FunctionTemplate>(m_isolate, templ)); - return handleScope.Escape(templ); + if (!m_scriptRegexpScriptState) { + v8::Local<v8::Context> context(v8::Context::New(m_isolate)); + m_scriptRegexpScriptState = ScriptState::create(context, DOMWrapperWorld::create()); + } + return m_scriptRegexpScriptState->context(); } -v8::Local<v8::Context> V8PerIsolateData::ensureRegexContext() +bool V8PerIsolateData::hasInstance(const WrapperTypeInfo* info, v8::Handle<v8::Value> value) { - if (m_regexContext.isEmpty()) { - v8::HandleScope handleScope(m_isolate); - m_regexContext.set(m_isolate, v8::Context::New(m_isolate)); - } - return m_regexContext.newLocal(m_isolate); + return hasInstance(info, value, m_domTemplateMapForMainWorld) + || hasInstance(info, value, m_domTemplateMapForNonMainWorld); } -bool V8PerIsolateData::hasInstance(const WrapperTypeInfo* info, v8::Handle<v8::Value> value, WrapperWorldType currentWorldType) +bool V8PerIsolateData::hasInstance(const WrapperTypeInfo* info, v8::Handle<v8::Value> value, DOMTemplateMap& domTemplateMap) { - TemplateMap& templates = rawDOMTemplateMap(currentWorldType); - TemplateMap::iterator result = templates.find(info); - if (result == templates.end()) + DOMTemplateMap::iterator result = domTemplateMap.find(info); + if (result == domTemplateMap.end()) return false; - v8::HandleScope handleScope(m_isolate); - return result->value.newLocal(m_isolate)->HasInstance(value); + v8::Handle<v8::FunctionTemplate> templ = result->value.Get(m_isolate); + return templ->HasInstance(value); } -void V8PerIsolateData::constructorOfToString(const v8::FunctionCallbackInfo<v8::Value>& info) +v8::Handle<v8::Object> V8PerIsolateData::findInstanceInPrototypeChain(const WrapperTypeInfo* info, v8::Handle<v8::Value> value) +{ + v8::Handle<v8::Object> wrapper = findInstanceInPrototypeChain(info, value, m_domTemplateMapForMainWorld); + if (!wrapper.IsEmpty()) + return wrapper; + return findInstanceInPrototypeChain(info, value, m_domTemplateMapForNonMainWorld); +} + +v8::Handle<v8::Object> V8PerIsolateData::findInstanceInPrototypeChain(const WrapperTypeInfo* info, v8::Handle<v8::Value> value, DOMTemplateMap& domTemplateMap) +{ + if (value.IsEmpty() || !value->IsObject()) + return v8::Handle<v8::Object>(); + DOMTemplateMap::iterator result = domTemplateMap.find(info); + if (result == domTemplateMap.end()) + return v8::Handle<v8::Object>(); + v8::Handle<v8::FunctionTemplate> templ = result->value.Get(m_isolate); + return v8::Handle<v8::Object>::Cast(value)->FindInstanceInPrototypeChain(templ); +} + +static void constructorOfToString(const v8::FunctionCallbackInfo<v8::Value>& info) { // The DOM constructors' toString functions grab the current toString // for Functions by taking the toString function of itself and then @@ -164,7 +206,14 @@ void V8PerIsolateData::constructorOfToString(const v8::FunctionCallbackInfo<v8:: v8SetReturnValue(info, v8::String::Empty(info.GetIsolate())); return; } - v8SetReturnValue(info, V8ScriptRunner::callInternalFunction(v8::Handle<v8::Function>::Cast(value), info.This(), 0, 0, v8::Isolate::GetCurrent())); + v8SetReturnValue(info, V8ScriptRunner::callInternalFunction(v8::Handle<v8::Function>::Cast(value), info.This(), 0, 0, info.GetIsolate())); +} + +v8::Handle<v8::FunctionTemplate> V8PerIsolateData::toStringTemplate() +{ + if (m_toStringTemplate.isEmpty()) + m_toStringTemplate.set(m_isolate, v8::FunctionTemplate::New(m_isolate, constructorOfToString)); + return m_toStringTemplate.newLocal(m_isolate); } } // namespace WebCore |