| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2008, 2009, 2011 Google Inc. All rights reserved. | 2 * Copyright (C) 2008, 2009, 2011 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 #include "bindings/core/v8/LocalWindowProxy.h" | 31 #include "bindings/core/v8/LocalWindowProxy.h" |
| 32 | 32 |
| 33 #include "bindings/core/v8/ScriptController.h" | 33 #include "bindings/core/v8/ScriptController.h" |
| 34 #include "bindings/core/v8/ToV8ForCore.h" | 34 #include "bindings/core/v8/ToV8ForCore.h" |
| 35 #include "bindings/core/v8/V8BindingForCore.h" | 35 #include "bindings/core/v8/V8BindingForCore.h" |
| 36 #include "bindings/core/v8/V8ContextSnapshot.h" | |
| 37 #include "bindings/core/v8/V8DOMActivityLogger.h" | 36 #include "bindings/core/v8/V8DOMActivityLogger.h" |
| 38 #include "bindings/core/v8/V8GCForContextDispose.h" | 37 #include "bindings/core/v8/V8GCForContextDispose.h" |
| 39 #include "bindings/core/v8/V8HTMLDocument.h" | 38 #include "bindings/core/v8/V8HTMLDocument.h" |
| 40 #include "bindings/core/v8/V8Initializer.h" | 39 #include "bindings/core/v8/V8Initializer.h" |
| 41 #include "bindings/core/v8/V8PagePopupControllerBinding.h" | 40 #include "bindings/core/v8/V8PagePopupControllerBinding.h" |
| 42 #include "bindings/core/v8/V8Window.h" | 41 #include "bindings/core/v8/V8Window.h" |
| 43 #include "core/dom/Modulator.h" | 42 #include "core/dom/Modulator.h" |
| 44 #include "core/frame/LocalFrame.h" | 43 #include "core/frame/LocalFrame.h" |
| 45 #include "core/frame/LocalFrameClient.h" | 44 #include "core/frame/LocalFrameClient.h" |
| 46 #include "core/frame/csp/ContentSecurityPolicy.h" | 45 #include "core/frame/csp/ContentSecurityPolicy.h" |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 // The context's frame is detached from the DOM, so there shouldn't be a | 107 // The context's frame is detached from the DOM, so there shouldn't be a |
| 109 // strong reference to the context. | 108 // strong reference to the context. |
| 110 global_proxy_.SetPhantom(); | 109 global_proxy_.SetPhantom(); |
| 111 } | 110 } |
| 112 | 111 |
| 113 DCHECK_EQ(lifecycle_, Lifecycle::kContextIsInitialized); | 112 DCHECK_EQ(lifecycle_, Lifecycle::kContextIsInitialized); |
| 114 lifecycle_ = next_status; | 113 lifecycle_ = next_status; |
| 115 } | 114 } |
| 116 | 115 |
| 117 void LocalWindowProxy::Initialize() { | 116 void LocalWindowProxy::Initialize() { |
| 118 TRACE_EVENT1("v8", "LocalWindowProxy::Initialize", "IsMainFrame", | 117 TRACE_EVENT1("v8", "LocalWindowProxy::initialize", "isMainWindow", |
| 119 GetFrame()->IsMainFrame()); | 118 GetFrame()->IsMainFrame()); |
| 120 SCOPED_BLINK_UMA_HISTOGRAM_TIMER( | 119 SCOPED_BLINK_UMA_HISTOGRAM_TIMER( |
| 121 GetFrame()->IsMainFrame() | 120 GetFrame()->IsMainFrame() |
| 122 ? "Blink.Binding.InitializeMainLocalWindowProxy" | 121 ? "Blink.Binding.InitializeMainLocalWindowProxy" |
| 123 : "Blink.Binding.InitializeNonMainLocalWindowProxy"); | 122 : "Blink.Binding.InitializeNonMainLocalWindowProxy"); |
| 124 | 123 |
| 125 ScriptForbiddenScope::AllowUserAgentScript allow_script; | 124 ScriptForbiddenScope::AllowUserAgentScript allow_script; |
| 126 | 125 |
| 127 v8::HandleScope handle_scope(GetIsolate()); | 126 v8::HandleScope handle_scope(GetIsolate()); |
| 128 | 127 |
| 129 CreateContext(); | 128 CreateContext(); |
| 130 | 129 |
| 131 ScriptState::Scope scope(script_state_.Get()); | 130 ScriptState::Scope scope(script_state_.Get()); |
| 132 v8::Local<v8::Context> context = script_state_->GetContext(); | 131 v8::Local<v8::Context> context = script_state_->GetContext(); |
| 133 if (global_proxy_.IsEmpty()) { | 132 if (global_proxy_.IsEmpty()) { |
| 134 global_proxy_.Set(GetIsolate(), context->Global()); | 133 global_proxy_.Set(GetIsolate(), context->Global()); |
| 135 CHECK(!global_proxy_.IsEmpty()); | 134 CHECK(!global_proxy_.IsEmpty()); |
| 136 } | 135 } |
| 137 | 136 |
| 138 SetupWindowPrototypeChain(); | 137 SetupWindowPrototypeChain(); |
| 139 V8ContextSnapshot::InstallRuntimeEnabledFeatures(context, | |
| 140 GetFrame()->GetDocument()); | |
| 141 | 138 |
| 142 SecurityOrigin* origin = 0; | 139 SecurityOrigin* origin = 0; |
| 143 if (world_->IsMainWorld()) { | 140 if (world_->IsMainWorld()) { |
| 144 // ActivityLogger for main world is updated within updateDocumentInternal(). | 141 // ActivityLogger for main world is updated within updateDocumentInternal(). |
| 145 UpdateDocumentInternal(); | 142 UpdateDocumentInternal(); |
| 146 origin = GetFrame()->GetDocument()->GetSecurityOrigin(); | 143 origin = GetFrame()->GetDocument()->GetSecurityOrigin(); |
| 147 // FIXME: Can this be removed when CSP moves to browser? | 144 // FIXME: Can this be removed when CSP moves to browser? |
| 148 ContentSecurityPolicy* csp = | 145 ContentSecurityPolicy* csp = |
| 149 GetFrame()->GetDocument()->GetContentSecurityPolicy(); | 146 GetFrame()->GetDocument()->GetContentSecurityPolicy(); |
| 150 context->AllowCodeGenerationFromStrings(csp->AllowEval( | 147 context->AllowCodeGenerationFromStrings(csp->AllowEval( |
| 151 0, SecurityViolationReportingPolicy::kSuppressReporting, | 148 0, SecurityViolationReportingPolicy::kSuppressReporting, |
| 152 ContentSecurityPolicy::kWillNotThrowException, g_empty_string)); | 149 ContentSecurityPolicy::kWillNotThrowException, g_empty_string)); |
| 153 context->SetErrorMessageForCodeGenerationFromStrings( | 150 context->SetErrorMessageForCodeGenerationFromStrings( |
| 154 V8String(GetIsolate(), csp->EvalDisabledErrorMessage())); | 151 V8String(GetIsolate(), csp->EvalDisabledErrorMessage())); |
| 155 } else { | 152 } else { |
| 156 UpdateActivityLogger(); | 153 UpdateActivityLogger(); |
| 157 origin = world_->IsolatedWorldSecurityOrigin(); | 154 origin = world_->IsolatedWorldSecurityOrigin(); |
| 158 SetSecurityToken(origin); | 155 SetSecurityToken(origin); |
| 159 } | 156 } |
| 160 | 157 |
| 161 { | 158 MainThreadDebugger::Instance()->ContextCreated(script_state_.Get(), |
| 162 TRACE_EVENT1("v8", "ContextCreatedNotification", "IsMainFrame", | 159 GetFrame(), origin); |
| 163 GetFrame()->IsMainFrame()); | 160 GetFrame()->Client()->DidCreateScriptContext(context, world_->GetWorldId()); |
| 164 MainThreadDebugger::Instance()->ContextCreated(script_state_.Get(), | |
| 165 GetFrame(), origin); | |
| 166 GetFrame()->Client()->DidCreateScriptContext(context, world_->GetWorldId()); | |
| 167 | 161 |
| 168 InstallConditionalFeaturesOnGlobal(&V8Window::wrapperTypeInfo, | 162 InstallConditionalFeaturesOnGlobal(&V8Window::wrapperTypeInfo, |
| 169 script_state_.Get()); | 163 script_state_.Get()); |
| 170 | 164 |
| 171 if (world_->IsMainWorld()) { | 165 if (world_->IsMainWorld()) { |
| 172 // For the main world, install any remaining conditional bindings (i.e. | 166 // For the main world, install any remaining conditional bindings (i.e. for |
| 173 // for origin trials, which do not apply to extensions). Some conditional | 167 // origin trials, which do not apply to extensions). Some conditional |
| 174 // bindings cannot be enabled until the execution context is available | 168 // bindings cannot be enabled until the execution context is available |
| 175 // (e.g. parsing the document, inspecting HTTP headers). | 169 // (e.g. parsing the document, inspecting HTTP headers). |
| 176 InstallConditionalFeatures(&V8Window::wrapperTypeInfo, | 170 InstallConditionalFeatures(&V8Window::wrapperTypeInfo, script_state_.Get(), |
| 177 script_state_.Get(), v8::Local<v8::Object>(), | 171 v8::Local<v8::Object>(), |
| 178 v8::Local<v8::Function>()); | 172 v8::Local<v8::Function>()); |
| 179 GetFrame()->Loader().DispatchDidClearWindowObjectInMainWorld(); | 173 GetFrame()->Loader().DispatchDidClearWindowObjectInMainWorld(); |
| 180 } | |
| 181 } | 174 } |
| 182 } | 175 } |
| 183 | 176 |
| 184 void LocalWindowProxy::CreateContext() { | 177 void LocalWindowProxy::CreateContext() { |
| 185 TRACE_EVENT1("v8", "LocalWindowProxy::CreateContext", "IsMainFrame", | 178 // Create a new v8::Context with the window object as the global object |
| 186 GetFrame()->IsMainFrame()); | 179 // (aka the inner global). Reuse the outer global proxy if it already exists. |
| 180 v8::Local<v8::ObjectTemplate> global_template = |
| 181 V8Window::domTemplate(GetIsolate(), *world_)->InstanceTemplate(); |
| 182 CHECK(!global_template.IsEmpty()); |
| 187 | 183 |
| 188 Vector<const char*> extension_names; | 184 Vector<const char*> extension_names; |
| 189 // Dynamically tell v8 about our extensions now. | 185 // Dynamically tell v8 about our extensions now. |
| 190 if (GetFrame()->Client()->AllowScriptExtensions()) { | 186 if (GetFrame()->Client()->AllowScriptExtensions()) { |
| 191 const V8Extensions& extensions = ScriptController::RegisteredExtensions(); | 187 const V8Extensions& extensions = ScriptController::RegisteredExtensions(); |
| 192 extension_names.ReserveInitialCapacity(extensions.size()); | 188 extension_names.ReserveInitialCapacity(extensions.size()); |
| 193 for (const auto* extension : extensions) | 189 for (const auto* extension : extensions) |
| 194 extension_names.push_back(extension->name()); | 190 extension_names.push_back(extension->name()); |
| 195 } | 191 } |
| 196 v8::ExtensionConfiguration extension_configuration(extension_names.size(), | 192 v8::ExtensionConfiguration extension_configuration(extension_names.size(), |
| 197 extension_names.data()); | 193 extension_names.data()); |
| 198 | 194 |
| 199 v8::Local<v8::Context> context; | 195 v8::Local<v8::Context> context; |
| 200 { | 196 { |
| 201 v8::Isolate* isolate = GetIsolate(); | |
| 202 Document* document = GetFrame()->GetDocument(); | |
| 203 V8PerIsolateData::UseCounterDisabledScope use_counter_disabled( | 197 V8PerIsolateData::UseCounterDisabledScope use_counter_disabled( |
| 204 V8PerIsolateData::From(isolate)); | 198 V8PerIsolateData::From(GetIsolate())); |
| 205 | 199 context = |
| 206 v8::Local<v8::Object> global_proxy = global_proxy_.NewLocal(isolate); | 200 v8::Context::New(GetIsolate(), &extension_configuration, |
| 207 context = V8ContextSnapshot::CreateContextFromSnapshot( | 201 global_template, global_proxy_.NewLocal(GetIsolate())); |
| 208 isolate, World(), &extension_configuration, global_proxy, document); | |
| 209 | |
| 210 // Even if we enable V8 context snapshot feature, we may hit this branch | |
| 211 // in some cases, e.g. loading XML files. | |
| 212 if (context.IsEmpty()) { | |
| 213 v8::Local<v8::ObjectTemplate> global_template = | |
| 214 V8Window::domTemplate(isolate, *world_)->InstanceTemplate(); | |
| 215 CHECK(!global_template.IsEmpty()); | |
| 216 context = v8::Context::New(isolate, &extension_configuration, | |
| 217 global_template, global_proxy); | |
| 218 VLOG(1) << "A context is created NOT from snapshot"; | |
| 219 } | |
| 220 } | 202 } |
| 221 CHECK(!context.IsEmpty()); | 203 CHECK(!context.IsEmpty()); |
| 222 | 204 |
| 223 #if DCHECK_IS_ON() | 205 #if DCHECK_IS_ON() |
| 224 DidAttachGlobalObject(); | 206 DidAttachGlobalObject(); |
| 225 #endif | 207 #endif |
| 226 | 208 |
| 227 script_state_ = ScriptState::Create(context, world_); | 209 script_state_ = ScriptState::Create(context, world_); |
| 228 | 210 |
| 229 DCHECK(lifecycle_ == Lifecycle::kContextIsUninitialized || | 211 DCHECK(lifecycle_ == Lifecycle::kContextIsUninitialized || |
| 230 lifecycle_ == Lifecycle::kGlobalObjectIsDetached); | 212 lifecycle_ == Lifecycle::kGlobalObjectIsDetached); |
| 231 lifecycle_ = Lifecycle::kContextIsInitialized; | 213 lifecycle_ = Lifecycle::kContextIsInitialized; |
| 232 DCHECK(script_state_->ContextIsValid()); | 214 DCHECK(script_state_->ContextIsValid()); |
| 233 } | 215 } |
| 234 | 216 |
| 235 void LocalWindowProxy::SetupWindowPrototypeChain() { | 217 void LocalWindowProxy::SetupWindowPrototypeChain() { |
| 236 TRACE_EVENT1("v8", "LocalWindowProxy::SetupWindowPrototypeChain", | |
| 237 "IsMainFrame", GetFrame()->IsMainFrame()); | |
| 238 | |
| 239 // Associate the window wrapper object and its prototype chain with the | 218 // Associate the window wrapper object and its prototype chain with the |
| 240 // corresponding native DOMWindow object. | 219 // corresponding native DOMWindow object. |
| 241 DOMWindow* window = GetFrame()->DomWindow(); | 220 DOMWindow* window = GetFrame()->DomWindow(); |
| 242 const WrapperTypeInfo* wrapper_type_info = window->GetWrapperTypeInfo(); | 221 const WrapperTypeInfo* wrapper_type_info = window->GetWrapperTypeInfo(); |
| 243 v8::Local<v8::Context> context = script_state_->GetContext(); | 222 v8::Local<v8::Context> context = script_state_->GetContext(); |
| 244 | 223 |
| 245 // The global proxy object. Note this is not the global object. | 224 // The global proxy object. Note this is not the global object. |
| 246 v8::Local<v8::Object> global_proxy = context->Global(); | 225 v8::Local<v8::Object> global_proxy = context->Global(); |
| 247 CHECK(global_proxy_ == global_proxy); | 226 CHECK(global_proxy_ == global_proxy); |
| 248 V8DOMWrapper::SetNativeInfo(GetIsolate(), global_proxy, wrapper_type_info, | 227 V8DOMWrapper::SetNativeInfo(GetIsolate(), global_proxy, wrapper_type_info, |
| (...skipping 24 matching lines...) Expand all Loading... |
| 273 wrapper_type_info, window); | 252 wrapper_type_info, window); |
| 274 | 253 |
| 275 // TODO(keishi): Remove installPagePopupController and implement | 254 // TODO(keishi): Remove installPagePopupController and implement |
| 276 // PagePopupController in another way. | 255 // PagePopupController in another way. |
| 277 V8PagePopupControllerBinding::InstallPagePopupController(context, | 256 V8PagePopupControllerBinding::InstallPagePopupController(context, |
| 278 window_wrapper); | 257 window_wrapper); |
| 279 } | 258 } |
| 280 | 259 |
| 281 void LocalWindowProxy::UpdateDocumentProperty() { | 260 void LocalWindowProxy::UpdateDocumentProperty() { |
| 282 DCHECK(world_->IsMainWorld()); | 261 DCHECK(world_->IsMainWorld()); |
| 283 TRACE_EVENT1("v8", "LocalWindowProxy::UpdateDocumentProperty", "IsMainFrame", | |
| 284 GetFrame()->IsMainFrame()); | |
| 285 | 262 |
| 286 ScriptState::Scope scope(script_state_.Get()); | 263 ScriptState::Scope scope(script_state_.Get()); |
| 287 v8::Local<v8::Context> context = script_state_->GetContext(); | 264 v8::Local<v8::Context> context = script_state_->GetContext(); |
| 288 v8::Local<v8::Value> document_wrapper = | 265 v8::Local<v8::Value> document_wrapper = |
| 289 ToV8(GetFrame()->GetDocument(), context->Global(), GetIsolate()); | 266 ToV8(GetFrame()->GetDocument(), context->Global(), GetIsolate()); |
| 290 DCHECK(document_wrapper->IsObject()); | 267 DCHECK(document_wrapper->IsObject()); |
| 291 | |
| 292 // Update the cached accessor for window.document. | 268 // Update the cached accessor for window.document. |
| 293 CHECK(V8PrivateProperty::GetWindowDocumentCachedAccessor(GetIsolate()) | 269 CHECK(V8PrivateProperty::GetWindowDocumentCachedAccessor(GetIsolate()) |
| 294 .Set(context->Global(), document_wrapper)); | 270 .Set(context->Global(), document_wrapper)); |
| 295 } | 271 } |
| 296 | 272 |
| 297 void LocalWindowProxy::UpdateActivityLogger() { | 273 void LocalWindowProxy::UpdateActivityLogger() { |
| 298 script_state_->PerContextData()->SetActivityLogger( | 274 script_state_->PerContextData()->SetActivityLogger( |
| 299 V8DOMActivityLogger::ActivityLogger( | 275 V8DOMActivityLogger::ActivityLogger( |
| 300 world_->GetWorldId(), GetFrame()->GetDocument() | 276 world_->GetWorldId(), GetFrame()->GetDocument() |
| 301 ? GetFrame()->GetDocument()->baseURI() | 277 ? GetFrame()->GetDocument()->baseURI() |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 context->UseDefaultSecurityToken(); | 319 context->UseDefaultSecurityToken(); |
| 344 return; | 320 return; |
| 345 } | 321 } |
| 346 | 322 |
| 347 if (world_->IsIsolatedWorld()) { | 323 if (world_->IsIsolatedWorld()) { |
| 348 SecurityOrigin* frame_security_origin = | 324 SecurityOrigin* frame_security_origin = |
| 349 GetFrame()->GetDocument()->GetSecurityOrigin(); | 325 GetFrame()->GetDocument()->GetSecurityOrigin(); |
| 350 String frame_security_token = frame_security_origin->ToString(); | 326 String frame_security_token = frame_security_origin->ToString(); |
| 351 // We need to check the return value of domainWasSetInDOM() on the | 327 // We need to check the return value of domainWasSetInDOM() on the |
| 352 // frame's SecurityOrigin because, if that's the case, only | 328 // frame's SecurityOrigin because, if that's the case, only |
| 353 // SecurityOrigin::domain_ would have been modified. | 329 // SecurityOrigin::m_domain would have been modified. |
| 354 // domain_ is not used by SecurityOrigin::toString(), so we would end | 330 // m_domain is not used by SecurityOrigin::toString(), so we would end |
| 355 // up generating the same token that was already set. | 331 // up generating the same token that was already set. |
| 356 if (frame_security_origin->DomainWasSetInDOM() || | 332 if (frame_security_origin->DomainWasSetInDOM() || |
| 357 frame_security_token.IsEmpty() || frame_security_token == "null") { | 333 frame_security_token.IsEmpty() || frame_security_token == "null") { |
| 358 context->UseDefaultSecurityToken(); | 334 context->UseDefaultSecurityToken(); |
| 359 return; | 335 return; |
| 360 } | 336 } |
| 361 token = frame_security_token + token; | 337 token = frame_security_token + token; |
| 362 } | 338 } |
| 363 | 339 |
| 364 // NOTE: V8 does identity comparison in fast path, must use a symbol | 340 // NOTE: V8 does identity comparison in fast path, must use a symbol |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 494 | 470 |
| 495 SetSecurityToken(origin); | 471 SetSecurityToken(origin); |
| 496 } | 472 } |
| 497 | 473 |
| 498 LocalWindowProxy::LocalWindowProxy(v8::Isolate* isolate, | 474 LocalWindowProxy::LocalWindowProxy(v8::Isolate* isolate, |
| 499 LocalFrame& frame, | 475 LocalFrame& frame, |
| 500 RefPtr<DOMWrapperWorld> world) | 476 RefPtr<DOMWrapperWorld> world) |
| 501 : WindowProxy(isolate, frame, std::move(world)) {} | 477 : WindowProxy(isolate, frame, std::move(world)) {} |
| 502 | 478 |
| 503 } // namespace blink | 479 } // namespace blink |
| OLD | NEW |