Commit 690c3cf2 authored by dcheng's avatar dcheng Committed by Commit bot

Refactor WindowProxy into Local and Remote subclasses.

WindowProxy for remote frames will soon use remote contexts to avoid
the overhead of instantiating a full v8::Context. As preparation,
separate the logic for WindowProxy into LocalFrame and RemoteFrame
versions to make it obvious what's used in each path.

To avoid adding virtual calls to the fast path, common members such
as the lifecycle state and the global proxy have been moved to the
base class. When the WindowProxy is already initialized, this avoids
the cost of any virtual calls.

Future CLs will:
- Convert RemoteWindowProxy to use v8::Context::NewRemoteContext
- Merge LocalWindowProxyManager back into ScriptController
- Clean up the interface for transferring global objects
- Clean up the layering between WindowProxy and its subclasses

BUG=527190

Review-Url: https://codereview.chromium.org/2620313002
Cr-Commit-Position: refs/heads/master@{#442948}
parent 0811dbe5
......@@ -65,6 +65,8 @@ bindings_core_v8_files =
"core/v8/IDLDictionaryBase.cpp",
"core/v8/IDLDictionaryBase.h",
"core/v8/Iterable.h",
"core/v8/LocalWindowProxy.cpp",
"core/v8/LocalWindowProxy.h",
"core/v8/Maplike.h",
"core/v8/Microtask.cpp",
"core/v8/Microtask.h",
......@@ -72,6 +74,8 @@ bindings_core_v8_files =
"core/v8/Nullable.h",
"core/v8/RejectedPromises.cpp",
"core/v8/RejectedPromises.h",
"core/v8/RemoteWindowProxy.cpp",
"core/v8/RemoteWindowProxy.h",
"core/v8/RetainedDOMInfo.cpp",
"core/v8/RetainedDOMInfo.h",
"core/v8/RetainedObjectInfo.h",
......
/*
* Copyright (C) 2009 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef LocalWindowProxy_h
#define LocalWindowProxy_h
#include "bindings/core/v8/DOMWrapperWorld.h"
#include "bindings/core/v8/WindowProxy.h"
#include "core/frame/LocalFrame.h"
#include "wtf/RefPtr.h"
#include "wtf/text/AtomicString.h"
#include <v8.h>
namespace blink {
class HTMLDocument;
class SecurityOrigin;
// Subclass of WindowProxy that only handles LocalFrame.
class LocalWindowProxy final : public WindowProxy {
public:
static LocalWindowProxy* create(v8::Isolate* isolate,
LocalFrame& frame,
RefPtr<DOMWrapperWorld> world) {
return new LocalWindowProxy(isolate, frame, std::move(world));
}
// Update document object of the frame.
void updateDocument();
void namedItemAdded(HTMLDocument*, const AtomicString&);
void namedItemRemoved(HTMLDocument*, const AtomicString&);
// Update the security origin of a document
// (e.g., after setting docoument.domain).
void updateSecurityOrigin(SecurityOrigin*);
private:
LocalWindowProxy(v8::Isolate*, LocalFrame&, RefPtr<DOMWrapperWorld>);
void initialize() override;
void disposeContext(GlobalDetachmentBehavior) override;
// Creates a new v8::Context with the window wrapper object as the global
// object (aka the inner global). Note that the window wrapper and its
// prototype chain do not get fully initialized yet, e.g. the window
// wrapper is not yet associated with the native DOMWindow object.
void createContext();
void setSecurityToken(SecurityOrigin*);
// The JavaScript wrapper for the document object is cached on the global
// object for fast access. UpdateDocumentProperty sets the wrapper
// for the current document on the global object.
void updateDocumentProperty();
// Updates Activity Logger for the current context.
void updateActivityLogger();
LocalFrame* frame() const { return toLocalFrame(WindowProxy::frame()); }
};
} // namespace blink
#endif // LocalWindowProxy_h
/*
* Copyright (C) 2008, 2009, 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "bindings/core/v8/WindowProxy.h"
#include "bindings/core/v8/ConditionalFeatures.h"
#include "bindings/core/v8/DOMWrapperWorld.h"
#include "bindings/core/v8/ScriptController.h"
#include "bindings/core/v8/ToV8.h"
#include "bindings/core/v8/V8Binding.h"
#include "bindings/core/v8/V8DOMActivityLogger.h"
#include "bindings/core/v8/V8Document.h"
#include "bindings/core/v8/V8GCForContextDispose.h"
#include "bindings/core/v8/V8HTMLCollection.h"
#include "bindings/core/v8/V8HTMLDocument.h"
#include "bindings/core/v8/V8HiddenValue.h"
#include "bindings/core/v8/V8Initializer.h"
#include "bindings/core/v8/V8ObjectConstructor.h"
#include "bindings/core/v8/V8PagePopupControllerBinding.h"
#include "bindings/core/v8/V8PrivateProperty.h"
#include "bindings/core/v8/V8Window.h"
#include "core/frame/LocalFrame.h"
#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/html/DocumentNameCollection.h"
#include "core/html/HTMLCollection.h"
#include "core/html/HTMLIFrameElement.h"
#include "core/inspector/InspectorInstrumentation.h"
#include "core/inspector/MainThreadDebugger.h"
#include "core/loader/DocumentLoader.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
#include "core/origin_trials/OriginTrialContext.h"
#include "platform/Histogram.h"
#include "platform/RuntimeEnabledFeatures.h"
#include "platform/ScriptForbiddenScope.h"
#include "platform/heap/Handle.h"
#include "platform/instrumentation/tracing/TraceEvent.h"
#include "platform/weborigin/SecurityOrigin.h"
#include "public/platform/Platform.h"
#include "wtf/Assertions.h"
#include "wtf/StringExtras.h"
#include "wtf/text/CString.h"
#include <algorithm>
#include <utility>
#include <v8-debug.h>
#include <v8.h>
namespace blink {
RemoteWindowProxy::RemoteWindowProxy(v8::Isolate* isolate,
RemoteFrame& frame,
RefPtr<DOMWrapperWorld> world)
: WindowProxy(isolate, frame, std::move(world)) {}
void RemoteWindowProxy::disposeContext(GlobalDetachmentBehavior behavior) {
if (m_lifecycle != Lifecycle::ContextInitialized)
return;
WindowProxy::disposeContext(behavior);
}
void RemoteWindowProxy::initialize() {
TRACE_EVENT1("v8", "RemoteWindowProxy::initialize", "isMainWindow",
frame()->isMainFrame());
SCOPED_BLINK_UMA_HISTOGRAM_TIMER(
frame()->isMainFrame() ? "Blink.Binding.InitializeMainWindowProxy"
: "Blink.Binding.InitializeNonMainWindowProxy");
ScriptForbiddenScope::AllowUserAgentScript allowScript;
v8::HandleScope handleScope(isolate());
createContext();
ScriptState::Scope scope(m_scriptState.get());
v8::Local<v8::Context> context = m_scriptState->context();
if (m_globalProxy.isEmpty()) {
m_globalProxy.set(isolate(), context->Global());
CHECK(!m_globalProxy.isEmpty());
}
setupWindowPrototypeChain();
// Remote frames always require a full canAccess() check.
context->UseDefaultSecurityToken();
}
void RemoteWindowProxy::createContext() {
// 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(isolate(), *m_world)->InstanceTemplate();
CHECK(!globalTemplate.IsEmpty());
v8::Local<v8::Context> context;
{
V8PerIsolateData::UseCounterDisabledScope useCounterDisabled(
V8PerIsolateData::from(isolate()));
context = v8::Context::New(isolate(), nullptr, globalTemplate,
m_globalProxy.newLocal(isolate()));
}
CHECK(!context.IsEmpty());
m_scriptState = ScriptState::create(context, m_world);
// TODO(haraken): Currently we cannot enable the following DCHECK because
// an already detached window proxy can be re-initialized. This is wrong.
// DCHECK(m_lifecycle == Lifecycle::ContextUninitialized);
m_lifecycle = Lifecycle::ContextInitialized;
DCHECK(m_scriptState->contextIsValid());
}
} // namespace blink
/*
* Copyright (C) 2009 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef RemoteWindowProxy_h
#define RemoteWindowProxy_h
#include "bindings/core/v8/DOMWrapperWorld.h"
#include "core/frame/RemoteFrame.h"
#include <v8.h>
namespace blink {
// Subclass of WindowProxy that only handles RemoteFrame.
class RemoteWindowProxy final : public WindowProxy {
public:
static RemoteWindowProxy* create(v8::Isolate* isolate,
RemoteFrame& frame,
RefPtr<DOMWrapperWorld> world) {
return new RemoteWindowProxy(isolate, frame, std::move(world));
}
private:
RemoteWindowProxy(v8::Isolate*, RemoteFrame&, RefPtr<DOMWrapperWorld>);
void initialize() override;
void disposeContext(GlobalDetachmentBehavior) override;
// Creates a new v8::Context with the window wrapper object as the global
// object (aka the inner global). Note that the window wrapper and its
// prototype chain do not get fully initialized yet, e.g. the window
// wrapper is not yet associated with the native DOMWindow object.
void createContext();
};
} // namespace blink
#endif // RemoteWindowProxy_h
......@@ -79,7 +79,7 @@
namespace blink {
ScriptController::ScriptController(LocalFrame* frame)
: m_windowProxyManager(WindowProxyManager::create(*frame)) {}
: m_windowProxyManager(LocalWindowProxyManager::create(*frame)) {}
DEFINE_TRACE(ScriptController) {
visitor->trace(m_windowProxyManager);
......@@ -209,8 +209,8 @@ void ScriptController::executeScriptInMainWorld(
InspectorUpdateCountersEvent::data());
}
WindowProxy* ScriptController::windowProxy(DOMWrapperWorld& world) {
WindowProxy* windowProxy = m_windowProxyManager->windowProxy(world);
LocalWindowProxy* ScriptController::windowProxy(DOMWrapperWorld& world) {
LocalWindowProxy* windowProxy = m_windowProxyManager->windowProxy(world);
windowProxy->initializeIfNeeded();
return windowProxy;
}
......@@ -441,7 +441,7 @@ void ScriptController::executeScriptInIsolatedWorld(
RefPtr<DOMWrapperWorld> world =
DOMWrapperWorld::ensureIsolatedWorld(isolate(), worldID, extensionGroup);
WindowProxy* isolatedWorldWindowProxy = windowProxy(*world);
LocalWindowProxy* isolatedWorldWindowProxy = windowProxy(*world);
ScriptState* scriptState = isolatedWorldWindowProxy->getScriptState();
if (!scriptState->contextIsValid())
return;
......
......@@ -52,7 +52,6 @@ class Element;
class KURL;
class ScriptSourceCode;
class SecurityOrigin;
class WindowProxy;
class Widget;
typedef WTF::Vector<v8::Extension*> V8Extensions;
......@@ -80,7 +79,7 @@ class CORE_EXPORT ScriptController final
// This returns an initialized window proxy. (If the window proxy is not
// yet initialized, it's implicitly initialized at the first access.)
WindowProxy* windowProxy(DOMWrapperWorld&);
LocalWindowProxy* windowProxy(DOMWrapperWorld&);
// Evaluate JavaScript in the main world.
void executeScriptInMainWorld(
......@@ -148,22 +147,20 @@ class CORE_EXPORT ScriptController final
v8::Isolate* isolate() const { return m_windowProxyManager->isolate(); }
WindowProxyManager* getWindowProxyManager() const {
LocalWindowProxyManager* getWindowProxyManager() const {
return m_windowProxyManager.get();
}
private:
explicit ScriptController(LocalFrame*);
LocalFrame* frame() const {
return toLocalFrame(m_windowProxyManager->frame());
}
LocalFrame* frame() const { return m_windowProxyManager->frame(); }
v8::Local<v8::Value> evaluateScriptInMainWorld(const ScriptSourceCode&,
AccessControlStatus,
ExecuteScriptPolicy);
Member<WindowProxyManager> m_windowProxyManager;
Member<LocalWindowProxyManager> m_windowProxyManager;
};
} // namespace blink
......
......@@ -35,55 +35,43 @@
#include "bindings/core/v8/ScopedPersistent.h"
#include "bindings/core/v8/ScriptState.h"
#include "platform/heap/Handle.h"
#include "platform/weborigin/SecurityOrigin.h"
#include "wtf/HashMap.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefPtr.h"
#include "wtf/text/AtomicString.h"
#include <v8.h>
namespace blink {
class Frame;
class HTMLDocument;
class SecurityOrigin;
class ScriptController;
// WindowProxy represents all the per-global object state for a Frame that
// persist between navigations.
class WindowProxy final : public GarbageCollectedFinalized<WindowProxy> {
class WindowProxy : public GarbageCollectedFinalized<WindowProxy> {
public:
static WindowProxy* create(v8::Isolate*, Frame*, DOMWrapperWorld&);
virtual ~WindowProxy();
~WindowProxy();
DECLARE_TRACE();
v8::Local<v8::Context> contextIfInitialized() const {
return m_scriptState ? m_scriptState->context() : v8::Local<v8::Context>();
}
ScriptState* getScriptState() const { return m_scriptState.get(); }
// Update document object of the frame.
void updateDocument();
void namedItemAdded(HTMLDocument*, const AtomicString&);
void namedItemRemoved(HTMLDocument*, const AtomicString&);
// Update the security origin of a document
// (e.g., after setting docoument.domain).
void updateSecurityOrigin(SecurityOrigin*);
void initializeIfNeeded();
void clearForNavigation();
void clearForClose();
void clearForNavigation();
v8::Local<v8::Object> globalIfNotDetached();
v8::Local<v8::Object> releaseGlobal();
void setGlobal(v8::Local<v8::Object>);
// TODO(dcheng): Temporarily exposed to avoid include cycles. Remove the need
// for this and remove this getter.
DOMWrapperWorld& world() { return *m_world; }
private:
protected:
// TODO(dcheng): Remove this friend declaration once LocalWindowProxyManager
// and ScriptController are merged.
friend class ScriptController;
// A valid transition is from ContextUninitialized to ContextInitialized,
// and then ContextDetached. Other transitions are forbidden.
enum class Lifecycle {
......@@ -92,36 +80,31 @@ class WindowProxy final : public GarbageCollectedFinalized<WindowProxy> {
ContextDetached,
};
WindowProxy(Frame*, PassRefPtr<DOMWrapperWorld>, v8::Isolate*);
void initialize();
WindowProxy(v8::Isolate*, Frame&, RefPtr<DOMWrapperWorld>);
enum GlobalDetachmentBehavior { DoNotDetachGlobal, DetachGlobal };
void disposeContext(GlobalDetachmentBehavior);
void setSecurityToken(SecurityOrigin*);
// The JavaScript wrapper for the document object is cached on the global
// object for fast access. UpdateDocumentProperty sets the wrapper
// for the current document on the global object.
void updateDocumentProperty();
virtual void initialize() = 0;
// Updates Activity Logger for the current context.
void updateActivityLogger();
// Creates a new v8::Context with the window wrapper object as the global
// object (aka the inner global). Note that the window wrapper and its
// prototype chain do not get fully initialized yet, e.g. the window
// wrapper is not yet associated with the native DOMWindow object.
void createContext();
enum GlobalDetachmentBehavior { DoNotDetachGlobal, DetachGlobal };
virtual void disposeContext(GlobalDetachmentBehavior);
// Associates the window wrapper and its prototype chain with the native
// DOMWindow object. Also does some more Window-specific initialization.
void setupWindowPrototypeChain();
Member<Frame> m_frame;
v8::Isolate* m_isolate;
v8::Isolate* isolate() const { return m_isolate; }
Frame* frame() const { return m_frame.get(); }
ScriptState* getScriptState() const { return m_scriptState.get(); }
private:
v8::Isolate* const m_isolate;
const Member<Frame> m_frame;
protected:
// TODO(dcheng): Move this to LocalWindowProxy once RemoteWindowProxy uses
// remote contexts.
RefPtr<ScriptState> m_scriptState;
RefPtr<DOMWrapperWorld> m_world;
// TODO(dcheng): Consider making these private and using getters.
const RefPtr<DOMWrapperWorld> m_world;
ScopedPersistent<v8::Object> m_globalProxy;
Lifecycle m_lifecycle;
};
......
......@@ -5,22 +5,31 @@
#include "bindings/core/v8/WindowProxyManager.h"
#include "bindings/core/v8/DOMWrapperWorld.h"
#include "bindings/core/v8/WindowProxy.h"
#include "core/frame/Frame.h"
namespace blink {
WindowProxyManager* WindowProxyManager::create(Frame& frame) {
return new WindowProxyManager(frame);
namespace {
WindowProxy* createWindowProxyForFrame(v8::Isolate* isolate,
Frame& frame,
RefPtr<DOMWrapperWorld> world) {
if (frame.isLocalFrame()) {
return LocalWindowProxy::create(isolate, toLocalFrame(frame),
std::move(world));
}
return RemoteWindowProxy::create(isolate, toRemoteFrame(frame),
std::move(world));
}
}
DEFINE_TRACE(WindowProxyManager) {
DEFINE_TRACE(WindowProxyManagerBase) {
visitor->trace(m_frame);
visitor->trace(m_windowProxy);
visitor->trace(m_isolatedWorlds);
}
WindowProxy* WindowProxyManager::windowProxy(DOMWrapperWorld& world) {
WindowProxy* WindowProxyManagerBase::windowProxy(DOMWrapperWorld& world) {
WindowProxy* windowProxy = nullptr;
if (world.isMainWorld()) {
windowProxy = m_windowProxy.get();
......@@ -29,36 +38,26 @@ WindowProxy* WindowProxyManager::windowProxy(DOMWrapperWorld& world) {
if (iter != m_isolatedWorlds.end()) {
windowProxy = iter->value.get();
} else {
windowProxy = WindowProxy::create(m_isolate, m_frame, world);
windowProxy = createWindowProxyForFrame(m_isolate, *m_frame, &world);
m_isolatedWorlds.set(world.worldId(), windowProxy);
}
}
return windowProxy;
}
void WindowProxyManager::clearForClose() {
void WindowProxyManagerBase::clearForClose() {
m_windowProxy->clearForClose();
for (auto& entry : m_isolatedWorlds)
entry.value->clearForClose();
}
void WindowProxyManager::clearForNavigation() {
void WindowProxyManagerBase::clearForNavigation() {
m_windowProxy->clearForNavigation();
for (auto& entry : m_isolatedWorlds)
entry.value->clearForNavigation();
}
void WindowProxyManager::updateSecurityOrigin(SecurityOrigin* securityOrigin) {
m_windowProxy->updateSecurityOrigin(securityOrigin);
for (auto& entry : m_isolatedWorlds) {
WindowProxy* isolatedWindowProxy = entry.value.get();
SecurityOrigin* isolatedSecurityOrigin =
isolatedWindowProxy->world().isolatedWorldSecurityOrigin();
isolatedWindowProxy->updateSecurityOrigin(isolatedSecurityOrigin);
}
}
void WindowProxyManager::releaseGlobals(
void WindowProxyManagerBase::releaseGlobals(
HashMap<DOMWrapperWorld*, v8::Local<v8::Object>>& map) {
map.add(&m_windowProxy->world(), m_windowProxy->releaseGlobal());
for (auto& entry : m_isolatedWorlds)
......@@ -66,17 +65,30 @@ void WindowProxyManager::releaseGlobals(
windowProxy(entry.value->world())->releaseGlobal());
}
void WindowProxyManager::setGlobals(
void WindowProxyManagerBase::setGlobals(
const HashMap<DOMWrapperWorld*, v8::Local<v8::Object>>& map) {
for (auto& entry : map)
windowProxy(*entry.key)->setGlobal(entry.value);
}
WindowProxyManager::WindowProxyManager(Frame& frame)
: m_frame(&frame),
m_isolate(v8::Isolate::GetCurrent()),
m_windowProxy(WindowProxy::create(m_isolate,
&frame,
DOMWrapperWorld::mainWorld())) {}
WindowProxyManagerBase::WindowProxyManagerBase(Frame& frame)
: m_isolate(v8::Isolate::GetCurrent()),
m_frame(&frame),
m_windowProxy(createWindowProxyForFrame(m_isolate,
frame,
&DOMWrapperWorld::mainWorld())) {}
void LocalWindowProxyManager::updateSecurityOrigin(
SecurityOrigin* securityOrigin) {
static_cast<LocalWindowProxy*>(mainWorldProxy())
->updateSecurityOrigin(securityOrigin);
for (auto& entry : isolatedWorlds()) {
auto* isolatedWindowProxy =
static_cast<LocalWindowProxy*>(entry.value.get());
SecurityOrigin* isolatedSecurityOrigin =
isolatedWindowProxy->world().isolatedWorldSecurityOrigin();
isolatedWindowProxy->updateSecurityOrigin(isolatedSecurityOrigin);
}
}
} // namespace blink
......@@ -5,52 +5,101 @@
#ifndef WindowProxyManager_h
#define WindowProxyManager_h
#include "bindings/core/v8/LocalWindowProxy.h"
#include "bindings/core/v8/RemoteWindowProxy.h"
#include "core/CoreExport.h"
#include "core/frame/LocalFrame.h"
#include "core/frame/RemoteFrame.h"
#include "platform/heap/Handle.h"
#include "wtf/Vector.h"
#include <utility>
#include <v8.h>
namespace blink {
class DOMWrapperWorld;
class Frame;
class SecurityOrigin;
class WindowProxy;
class ScriptController;
class CORE_EXPORT WindowProxyManager final
: public GarbageCollected<WindowProxyManager> {
class WindowProxyManagerBase : public GarbageCollected<WindowProxyManagerBase> {
public:
static WindowProxyManager* create(Frame&);
DECLARE_TRACE();
Frame* frame() const { return m_frame.get(); }
v8::Isolate* isolate() const { return m_isolate; }
WindowProxy* mainWorldProxy() const { return m_windowProxy.get(); }
void clearForClose();
void CORE_EXPORT clearForNavigation();
void CORE_EXPORT
releaseGlobals(HashMap<DOMWrapperWorld*, v8::Local<v8::Object>>&);
void CORE_EXPORT
setGlobals(const HashMap<DOMWrapperWorld*, v8::Local<v8::Object>>&);
protected:
using IsolatedWorldMap = HeapHashMap<int, Member<WindowProxy>>;
explicit WindowProxyManagerBase(Frame&);
Frame* frame() const { return m_frame; }
WindowProxy* mainWorldProxy() const { return m_windowProxy.get(); }
WindowProxy* windowProxy(DOMWrapperWorld&);
void clearForClose();
void clearForNavigation();
IsolatedWorldMap& isolatedWorlds() { return m_isolatedWorlds; }
private:
v8::Isolate* const m_isolate;
const Member<Frame> m_frame;
const Member<WindowProxy> m_windowProxy;
IsolatedWorldMap m_isolatedWorlds;
};
template <typename FrameType, typename ProxyType>
class WindowProxyManagerImplHelper : public WindowProxyManagerBase {
private:
using Base = WindowProxyManagerBase;
public:
FrameType* frame() const { return static_cast<FrameType*>(Base::frame()); }
ProxyType* mainWorldProxy() const {
return static_cast<ProxyType*>(Base::mainWorldProxy());
}
ProxyType* windowProxy(DOMWrapperWorld& world) {
return static_cast<ProxyType*>(Base::windowProxy(world));
}
protected:
explicit WindowProxyManagerImplHelper(Frame& frame)
: WindowProxyManagerBase(frame) {}
};
class LocalWindowProxyManager
: public WindowProxyManagerImplHelper<LocalFrame, LocalWindowProxy> {
public:
static LocalWindowProxyManager* create(LocalFrame& frame) {
return new LocalWindowProxyManager(frame);
}
// Sets the given security origin to the main world's context. Also updates
// the security origin of the context for each isolated world.
void updateSecurityOrigin(SecurityOrigin*);
void releaseGlobals(HashMap<DOMWrapperWorld*, v8::Local<v8::Object>>&);
void setGlobals(const HashMap<DOMWrapperWorld*, v8::Local<v8::Object>>&);
private:
typedef HeapHashMap<int, Member<WindowProxy>> IsolatedWorldMap;
// TODO(dcheng): Merge LocalWindowProxyManager and ScriptController?
friend class ScriptController;
explicit WindowProxyManager(Frame&);
explicit LocalWindowProxyManager(LocalFrame& frame)
: WindowProxyManagerImplHelper<LocalFrame, LocalWindowProxy>(frame) {}
};
Member<Frame> m_frame;
v8::Isolate* const m_isolate;
class RemoteWindowProxyManager
: public WindowProxyManagerImplHelper<RemoteFrame, RemoteWindowProxy> {
public:
static RemoteWindowProxyManager* create(RemoteFrame& frame) {
return new RemoteWindowProxyManager(frame);
}
const Member<WindowProxy> m_windowProxy;
IsolatedWorldMap m_isolatedWorlds;
private:
explicit RemoteWindowProxyManager(RemoteFrame& frame)
: WindowProxyManagerImplHelper<RemoteFrame, RemoteWindowProxy>(frame) {}
};
} // namespace blink
......
......@@ -54,7 +54,7 @@ class Page;
class SecurityContext;
class Settings;
class WindowProxy;
class WindowProxyManager;
class WindowProxyManagerBase;
struct FrameLoadRequest;
enum class FrameDetachType { Remove, Swap };
......@@ -143,7 +143,7 @@ class CORE_EXPORT Frame : public GarbageCollectedFinalized<Frame> {
void setIsLoading(bool isLoading) { m_isLoading = isLoading; }
bool isLoading() const { return m_isLoading; }
virtual WindowProxyManager* getWindowProxyManager() const = 0;
virtual WindowProxyManagerBase* getWindowProxyManager() const = 0;
virtual void didChangeVisibilityState();
......
......@@ -494,7 +494,7 @@ void LocalFrame::printNavigationWarning(const String& message) {
ConsoleMessage::create(JSMessageSource, WarningMessageLevel, message));
}
WindowProxyManager* LocalFrame::getWindowProxyManager() const {
WindowProxyManagerBase* LocalFrame::getWindowProxyManager() const {
return m_script->getWindowProxyManager();
}
......
......@@ -236,7 +236,7 @@ class CORE_EXPORT LocalFrame final : public Frame,
InterfaceRegistry*);
// Internal Frame helper overrides:
WindowProxyManager* getWindowProxyManager() const override;
WindowProxyManagerBase* getWindowProxyManager() const override;
// Intentionally private to prevent redundant checks when the type is
// already LocalFrame.
bool isLocalFrame() const override { return true; }
......
......@@ -30,7 +30,7 @@ inline RemoteFrame::RemoteFrame(RemoteFrameClient* client,
FrameOwner* owner)
: Frame(client, host, owner),
m_securityContext(RemoteSecurityContext::create()),
m_windowProxyManager(WindowProxyManager::create(*this)) {
m_windowProxyManager(RemoteWindowProxyManager::create(*this)) {
m_domWindow = RemoteDOMWindow::create(*this);
}
......@@ -187,6 +187,10 @@ void RemoteFrame::advanceFocus(WebFocusType type, LocalFrame* source) {
client()->advanceFocus(type, source);
}
WindowProxyManagerBase* RemoteFrame::getWindowProxyManager() const {
return m_windowProxyManager.get();
}
void RemoteFrame::detachChildren() {
using FrameVector = HeapVector<Member<Frame>>;
FrameVector childrenToDetach;
......
......@@ -17,8 +17,8 @@ class IntRect;
class LocalFrame;
class RemoteFrameClient;
class RemoteFrameView;
class RemoteWindowProxyManager;
class WebLayer;
class WindowProxyManager;
struct FrameLoadRequest;
class CORE_EXPORT RemoteFrame final : public Frame {
......@@ -68,9 +68,8 @@ class CORE_EXPORT RemoteFrame final : public Frame {
RemoteFrame(RemoteFrameClient*, FrameHost*, FrameOwner*);
// Internal Frame helper overrides:
WindowProxyManager* getWindowProxyManager() const override {
return m_windowProxyManager.get();
}
WindowProxyManagerBase* getWindowProxyManager() const override;
// Intentionally private to prevent redundant checks when the type is
// already RemoteFrame.
bool isLocalFrame() const override { return false; }
......@@ -80,7 +79,7 @@ class CORE_EXPORT RemoteFrame final : public Frame {
Member<RemoteFrameView> m_view;
Member<RemoteSecurityContext> m_securityContext;
Member<WindowProxyManager> m_windowProxyManager;
Member<RemoteWindowProxyManager> m_windowProxyManager;
WebLayer* m_webLayer = nullptr;
};
......
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