Chromium Code Reviews| Index: third_party/WebKit/Source/bindings/core/v8/WindowProxy.cpp |
| diff --git a/third_party/WebKit/Source/bindings/core/v8/WindowProxy.cpp b/third_party/WebKit/Source/bindings/core/v8/WindowProxy.cpp |
| index 66ce71ac973e8a8ef739a4aaba78ef4e96481258..2d89e2bafdb11b9981f1af7ffc2d11f969f12d8e 100644 |
| --- a/third_party/WebKit/Source/bindings/core/v8/WindowProxy.cpp |
| +++ b/third_party/WebKit/Source/bindings/core/v8/WindowProxy.cpp |
| @@ -245,7 +245,7 @@ bool WindowProxy::initialize() |
| } |
| } |
| - if (!installDOMWindow()) { |
| + if (!setupWindowPrototypeChain()) { |
| disposeContext(DoNotDetachGlobal); |
| return false; |
| } |
| @@ -272,32 +272,6 @@ bool WindowProxy::initialize() |
| return true; |
| } |
| -namespace { |
| - |
| -void configureInnerGlobalObjectTemplate(v8::Local<v8::ObjectTemplate> templ, v8::Isolate* isolate) |
| -{ |
| - // Install a security handler with V8. |
| - templ->SetAccessCheckCallback(V8Window::securityCheckCustom, v8::External::New(isolate, const_cast<WrapperTypeInfo*>(&V8Window::wrapperTypeInfo))); |
| - templ->SetInternalFieldCount(V8Window::internalFieldCount); |
| -} |
| - |
| -v8::Local<v8::ObjectTemplate> getInnerGlobalObjectTemplate(v8::Isolate* isolate) |
| -{ |
| - // It is OK to share the same object template between the main world and |
| - // non-main worlds because the inner global object doesn't install any |
| - // DOM attributes/methods. |
| - DEFINE_STATIC_LOCAL(v8::Persistent<v8::ObjectTemplate>, innerGlobalObjectTemplate, ()); |
| - if (innerGlobalObjectTemplate.IsEmpty()) { |
| - TRACE_EVENT_SCOPED_SAMPLING_STATE("blink", "BuildDOMTemplate"); |
| - v8::Local<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate); |
| - configureInnerGlobalObjectTemplate(templ, isolate); |
| - innerGlobalObjectTemplate.Reset(isolate, templ); |
| - } |
| - return v8::Local<v8::ObjectTemplate>::New(isolate, innerGlobalObjectTemplate); |
| -} |
| - |
| -} // namespace |
| - |
| void WindowProxy::createContext() |
| { |
| // FIXME: This should be a null check of m_frame->client(), but there are still some edge cases |
| @@ -305,9 +279,12 @@ void WindowProxy::createContext() |
| if (m_frame->isLocalFrame() && !toLocalFrame(m_frame)->loader().documentLoader()) |
| return; |
| - // Create a new environment using an empty template for the shadow |
| - // object. Reuse the global object if one has been created earlier. |
| - v8::Local<v8::ObjectTemplate> globalTemplate = getInnerGlobalObjectTemplate(m_isolate); |
| + // Create a new v8::Context with the window object as the global object |
| + // (aka the inner global). Reuse the global proxy object (aka the outer |
| + // global) if it already exists. See the comments in |
| + // setupWindowPrototypeChain for the structure of the prototype chain of |
| + // the global object. |
| + v8::Local<v8::ObjectTemplate> globalTemplate = V8Window::domTemplate(m_isolate, *m_world)->InstanceTemplate(); |
| if (globalTemplate.IsEmpty()) |
| return; |
| @@ -331,56 +308,64 @@ void WindowProxy::createContext() |
| } |
| v8::ExtensionConfiguration extensionConfiguration(extensionNames.size(), extensionNames.data()); |
| - v8::Local<v8::Context> context = v8::Context::New(m_isolate, &extensionConfiguration, globalTemplate, m_global.newLocal(m_isolate)); |
| + v8::Local<v8::Context> context; |
| + { |
| + V8PerIsolateData::UseCounterDisabledScope useCounterDisabled(V8PerIsolateData::from(m_isolate)); |
| + context = v8::Context::New(m_isolate, &extensionConfiguration, globalTemplate, m_global.newLocal(m_isolate)); |
| + } |
| if (context.IsEmpty()) |
| return; |
| m_scriptState = ScriptState::create(context, m_world); |
| } |
| -static v8::Local<v8::Object> toInnerGlobalObject(v8::Local<v8::Context> context) |
| +bool WindowProxy::setupWindowPrototypeChain() |
| { |
| - return v8::Local<v8::Object>::Cast(context->Global()->GetPrototype()); |
| -} |
| + // Associate the window wrapper object and its prototype chain with the |
| + // corresponding native DOMWindow object. |
| + // The full structure of the global object's prototype chain is as follows: |
| + // |
| + // global proxy object [1] |
| + // -- has prototype --> global object (window wrapper object) [2] |
|
haraken
2016/04/18 08:04:15
I'd rename:
- "global proxy object" => "outer glo
|
| + // -- has prototype --> Window.prototype |
| + // -- has prototype --> WindowProperties [3] |
| + // -- has prototype --> EventTarget.prototype |
| + // -- has prototype --> Object.prototype |
| + // -- has prototype --> null |
| + // |
| + // [1] Global proxy object is as known as "outer global object". It's an |
| + // empty object and remains after navigation. When navigated, points to |
| + // a different global object as the prototype object. |
| + // [2] Global object is as known as "inner global object" or "window wrapper |
| + // object". The prototype chain between global proxy object and global |
| + // object is NOT observable from user JavaScript code. All other |
| + // prototype chains are observable. Global proxy object and global object |
| + // together appear to be the same single JavaScript object. See also: |
| + // https://wiki.mozilla.org/Gecko:SplitWindow |
| + // global object (= window wrapper object) provides most of Window's DOM |
| + // attributes and operations. Also global variables defined by user |
| + // JavaScript are placed on this object. When navigated, a new global |
| + // object is created together with a new v8::Context, but the global proxy |
| + // object doesn't change. |
| + // [3] WindowProperties is a named properties object of Window interface. |
| -bool WindowProxy::installDOMWindow() |
| -{ |
| DOMWindow* window = m_frame->domWindow(); |
| const WrapperTypeInfo* wrapperTypeInfo = window->wrapperTypeInfo(); |
| - v8::Local<v8::Object> windowWrapper; |
| - v8::Local<v8::Function> constructor = m_scriptState->perContextData()->constructorForType(wrapperTypeInfo); |
| - if (constructor.IsEmpty()) |
| - return false; |
| - if (!V8ObjectConstructor::newInstance(m_isolate, constructor).ToLocal(&windowWrapper)) |
| - return false; |
| - windowWrapper = V8DOMWrapper::associateObjectWithWrapper(m_isolate, window, wrapperTypeInfo, windowWrapper); |
| - v8::Local<v8::Object> windowPrototype = v8::Local<v8::Object>::Cast(windowWrapper->GetPrototype()); |
| + v8::Local<v8::Context> context = m_scriptState->context(); |
| + // The global proxy object. Note this is not the global object. |
| + v8::Local<v8::Object> globalProxy = context->Global(); |
| + // The global object, aka window wrapper object. |
| + v8::Local<v8::Object> windowWrapper = globalProxy->GetPrototype().As<v8::Object>(); |
| + windowWrapper = V8DOMWrapper::associateObjectWithWrapper(m_isolate, window, wrapperTypeInfo, windowWrapper); |
| + // The prototype object of Window interface. |
| + v8::Local<v8::Object> windowPrototype = windowWrapper->GetPrototype().As<v8::Object>(); |
| RELEASE_ASSERT(!windowPrototype.IsEmpty()); |
| V8DOMWrapper::setNativeInfo(windowPrototype, wrapperTypeInfo, window); |
|
haraken
2016/04/18 08:04:15
Not directly related to this CL, do you know why w
Yuki
2016/04/18 08:27:07
Not sure. I vaguely guess that we can remove it.
|
| - v8::Local<v8::Object> windowProperties = v8::Local<v8::Object>::Cast(windowPrototype->GetPrototype()); |
| + // The named properties object of Window interface. |
| + v8::Local<v8::Object> windowProperties = windowPrototype->GetPrototype().As<v8::Object>(); |
| RELEASE_ASSERT(!windowProperties.IsEmpty()); |
| V8DOMWrapper::setNativeInfo(windowProperties, wrapperTypeInfo, window); |
|
haraken
2016/04/18 08:04:15
Ditto.
|
| - // Install the windowWrapper as the prototype of the innerGlobalObject. |
| - // The full structure of the global object is as follows: |
| - // |
| - // outerGlobalObject (Empty object, remains after navigation) |
| - // -- has prototype --> innerGlobalObject (Holds global variables, changes during navigation) |
| - // -- has prototype --> DOMWindow instance |
| - // -- has prototype --> Window.prototype |
| - // -- has prototype --> WindowProperties (named properties object) |
| - // -- has prototype --> EventTarget.prototype |
| - // -- has prototype --> Object.prototype |
| - // |
| - // Note: Much of this prototype structure is hidden from web content. The |
| - // outer, inner, and DOMWindow instance all appear to be the same |
| - // JavaScript object. |
| - v8::Local<v8::Context> context = m_scriptState->context(); |
| - v8::Local<v8::Object> innerGlobalObject = toInnerGlobalObject(m_scriptState->context()); |
| - V8DOMWrapper::setNativeInfo(innerGlobalObject, wrapperTypeInfo, window); |
| - if (!v8CallBoolean(innerGlobalObject->SetPrototype(context, windowWrapper))) |
| - return false; |
| - |
| // TODO(keishi): Remove installPagePopupController and implement |
| // PagePopupController in another way. |
| V8PagePopupControllerBinding::installPagePopupController(context, windowWrapper); |