| 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 16 matching lines...) Expand all Loading... |
| 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/ConditionalFeaturesForCore.h" | 33 #include "bindings/core/v8/ConditionalFeaturesForCore.h" |
| 34 #include "bindings/core/v8/ScriptController.h" | 34 #include "bindings/core/v8/ScriptController.h" |
| 35 #include "bindings/core/v8/ToV8ForCore.h" | 35 #include "bindings/core/v8/ToV8ForCore.h" |
| 36 #include "bindings/core/v8/V8BindingForCore.h" | 36 #include "bindings/core/v8/V8BindingForCore.h" |
| 37 #include "bindings/core/v8/V8ContextSnapshot.h" |
| 37 #include "bindings/core/v8/V8DOMActivityLogger.h" | 38 #include "bindings/core/v8/V8DOMActivityLogger.h" |
| 38 #include "bindings/core/v8/V8GCForContextDispose.h" | 39 #include "bindings/core/v8/V8GCForContextDispose.h" |
| 39 #include "bindings/core/v8/V8HTMLDocument.h" | 40 #include "bindings/core/v8/V8HTMLDocument.h" |
| 40 #include "bindings/core/v8/V8Initializer.h" | 41 #include "bindings/core/v8/V8Initializer.h" |
| 41 #include "bindings/core/v8/V8PagePopupControllerBinding.h" | 42 #include "bindings/core/v8/V8PagePopupControllerBinding.h" |
| 42 #include "bindings/core/v8/V8Window.h" | 43 #include "bindings/core/v8/V8Window.h" |
| 43 #include "core/dom/Modulator.h" | 44 #include "core/dom/Modulator.h" |
| 44 #include "core/frame/LocalFrame.h" | 45 #include "core/frame/LocalFrame.h" |
| 45 #include "core/frame/LocalFrameClient.h" | 46 #include "core/frame/LocalFrameClient.h" |
| 46 #include "core/frame/csp/ContentSecurityPolicy.h" | 47 #include "core/frame/csp/ContentSecurityPolicy.h" |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 // The context's frame is detached from the DOM, so there shouldn't be a | 110 // The context's frame is detached from the DOM, so there shouldn't be a |
| 110 // strong reference to the context. | 111 // strong reference to the context. |
| 111 global_proxy_.SetPhantom(); | 112 global_proxy_.SetPhantom(); |
| 112 } | 113 } |
| 113 | 114 |
| 114 DCHECK_EQ(lifecycle_, Lifecycle::kContextIsInitialized); | 115 DCHECK_EQ(lifecycle_, Lifecycle::kContextIsInitialized); |
| 115 lifecycle_ = next_status; | 116 lifecycle_ = next_status; |
| 116 } | 117 } |
| 117 | 118 |
| 118 void LocalWindowProxy::Initialize() { | 119 void LocalWindowProxy::Initialize() { |
| 119 TRACE_EVENT1("v8", "LocalWindowProxy::initialize", "isMainWindow", | 120 TRACE_EVENT1("v8", "LocalWindowProxy::Initialize", "IsMainFrame", |
| 120 GetFrame()->IsMainFrame()); | 121 GetFrame()->IsMainFrame()); |
| 121 SCOPED_BLINK_UMA_HISTOGRAM_TIMER( | 122 SCOPED_BLINK_UMA_HISTOGRAM_TIMER( |
| 122 GetFrame()->IsMainFrame() | 123 GetFrame()->IsMainFrame() |
| 123 ? "Blink.Binding.InitializeMainLocalWindowProxy" | 124 ? "Blink.Binding.InitializeMainLocalWindowProxy" |
| 124 : "Blink.Binding.InitializeNonMainLocalWindowProxy"); | 125 : "Blink.Binding.InitializeNonMainLocalWindowProxy"); |
| 125 | 126 |
| 126 ScriptForbiddenScope::AllowUserAgentScript allow_script; | 127 ScriptForbiddenScope::AllowUserAgentScript allow_script; |
| 127 | 128 |
| 128 v8::HandleScope handle_scope(GetIsolate()); | 129 v8::HandleScope handle_scope(GetIsolate()); |
| 129 | 130 |
| 130 CreateContext(); | 131 CreateContext(); |
| 131 | 132 |
| 132 ScriptState::Scope scope(script_state_.Get()); | 133 ScriptState::Scope scope(script_state_.Get()); |
| 133 v8::Local<v8::Context> context = script_state_->GetContext(); | 134 v8::Local<v8::Context> context = script_state_->GetContext(); |
| 134 if (global_proxy_.IsEmpty()) { | 135 if (global_proxy_.IsEmpty()) { |
| 135 global_proxy_.Set(GetIsolate(), context->Global()); | 136 global_proxy_.Set(GetIsolate(), context->Global()); |
| 136 CHECK(!global_proxy_.IsEmpty()); | 137 CHECK(!global_proxy_.IsEmpty()); |
| 137 } | 138 } |
| 138 | 139 |
| 139 SetupWindowPrototypeChain(); | 140 SetupWindowPrototypeChain(); |
| 141 V8ContextSnapshot::InstallRuntimeEnabledFeatures(context, |
| 142 GetFrame()->GetDocument()); |
| 140 | 143 |
| 141 SecurityOrigin* origin = 0; | 144 SecurityOrigin* origin = 0; |
| 142 if (world_->IsMainWorld()) { | 145 if (world_->IsMainWorld()) { |
| 143 // ActivityLogger for main world is updated within updateDocumentInternal(). | 146 // ActivityLogger for main world is updated within updateDocumentInternal(). |
| 144 UpdateDocumentInternal(); | 147 UpdateDocumentInternal(); |
| 145 origin = GetFrame()->GetDocument()->GetSecurityOrigin(); | 148 origin = GetFrame()->GetDocument()->GetSecurityOrigin(); |
| 146 // FIXME: Can this be removed when CSP moves to browser? | 149 // FIXME: Can this be removed when CSP moves to browser? |
| 147 ContentSecurityPolicy* csp = | 150 ContentSecurityPolicy* csp = |
| 148 GetFrame()->GetDocument()->GetContentSecurityPolicy(); | 151 GetFrame()->GetDocument()->GetContentSecurityPolicy(); |
| 149 context->AllowCodeGenerationFromStrings(csp->AllowEval( | 152 context->AllowCodeGenerationFromStrings(csp->AllowEval( |
| 150 0, SecurityViolationReportingPolicy::kSuppressReporting, | 153 0, SecurityViolationReportingPolicy::kSuppressReporting, |
| 151 ContentSecurityPolicy::kWillNotThrowException, g_empty_string)); | 154 ContentSecurityPolicy::kWillNotThrowException, g_empty_string)); |
| 152 context->SetErrorMessageForCodeGenerationFromStrings( | 155 context->SetErrorMessageForCodeGenerationFromStrings( |
| 153 V8String(GetIsolate(), csp->EvalDisabledErrorMessage())); | 156 V8String(GetIsolate(), csp->EvalDisabledErrorMessage())); |
| 154 } else { | 157 } else { |
| 155 UpdateActivityLogger(); | 158 UpdateActivityLogger(); |
| 156 origin = world_->IsolatedWorldSecurityOrigin(); | 159 origin = world_->IsolatedWorldSecurityOrigin(); |
| 157 SetSecurityToken(origin); | 160 SetSecurityToken(origin); |
| 158 } | 161 } |
| 159 | 162 |
| 160 MainThreadDebugger::Instance()->ContextCreated(script_state_.Get(), | 163 { |
| 161 GetFrame(), origin); | 164 TRACE_EVENT1("v8", "ContextCreatedNotification", "IsMainFrame", |
| 162 GetFrame()->Client()->DidCreateScriptContext(context, world_->GetWorldId()); | 165 GetFrame()->IsMainFrame()); |
| 163 // If conditional features for window have been queued before the V8 context | 166 MainThreadDebugger::Instance()->ContextCreated(script_state_.Get(), |
| 164 // was ready, then inject them into the context now | 167 GetFrame(), origin); |
| 165 if (world_->IsMainWorld()) { | 168 GetFrame()->Client()->DidCreateScriptContext(context, world_->GetWorldId()); |
| 166 InstallConditionalFeaturesOnWindow(script_state_.Get()); | 169 // If conditional features for window have been queued before the V8 context |
| 170 // was ready, then inject them into the context now |
| 171 if (world_->IsMainWorld()) { |
| 172 InstallConditionalFeaturesOnWindow(script_state_.Get()); |
| 173 GetFrame()->Loader().DispatchDidClearWindowObjectInMainWorld(); |
| 174 } |
| 167 } | 175 } |
| 168 | |
| 169 if (world_->IsMainWorld()) | |
| 170 GetFrame()->Loader().DispatchDidClearWindowObjectInMainWorld(); | |
| 171 } | 176 } |
| 172 | 177 |
| 173 void LocalWindowProxy::CreateContext() { | 178 void LocalWindowProxy::CreateContext() { |
| 174 // Create a new v8::Context with the window object as the global object | 179 TRACE_EVENT1("v8", "LocalWindowProxy::CreateContext", "IsMainFrame", |
| 175 // (aka the inner global). Reuse the outer global proxy if it already exists. | 180 GetFrame()->IsMainFrame()); |
| 176 v8::Local<v8::ObjectTemplate> global_template = | |
| 177 V8Window::domTemplate(GetIsolate(), *world_)->InstanceTemplate(); | |
| 178 CHECK(!global_template.IsEmpty()); | |
| 179 | 181 |
| 180 Vector<const char*> extension_names; | 182 Vector<const char*> extension_names; |
| 181 // Dynamically tell v8 about our extensions now. | 183 // Dynamically tell v8 about our extensions now. |
| 182 if (GetFrame()->Client()->AllowScriptExtensions()) { | 184 if (GetFrame()->Client()->AllowScriptExtensions()) { |
| 183 const V8Extensions& extensions = ScriptController::RegisteredExtensions(); | 185 const V8Extensions& extensions = ScriptController::RegisteredExtensions(); |
| 184 extension_names.ReserveInitialCapacity(extensions.size()); | 186 extension_names.ReserveInitialCapacity(extensions.size()); |
| 185 for (const auto* extension : extensions) | 187 for (const auto* extension : extensions) |
| 186 extension_names.push_back(extension->name()); | 188 extension_names.push_back(extension->name()); |
| 187 } | 189 } |
| 188 v8::ExtensionConfiguration extension_configuration(extension_names.size(), | 190 v8::ExtensionConfiguration extension_configuration(extension_names.size(), |
| 189 extension_names.data()); | 191 extension_names.data()); |
| 190 | 192 |
| 191 v8::Local<v8::Context> context; | 193 v8::Local<v8::Context> context; |
| 192 { | 194 { |
| 195 v8::Isolate* isolate = GetIsolate(); |
| 196 Document* document = GetFrame()->GetDocument(); |
| 193 V8PerIsolateData::UseCounterDisabledScope use_counter_disabled( | 197 V8PerIsolateData::UseCounterDisabledScope use_counter_disabled( |
| 194 V8PerIsolateData::From(GetIsolate())); | 198 V8PerIsolateData::From(isolate)); |
| 195 context = | 199 |
| 196 v8::Context::New(GetIsolate(), &extension_configuration, | 200 v8::Local<v8::Object> global_proxy = global_proxy_.NewLocal(isolate); |
| 197 global_template, global_proxy_.NewLocal(GetIsolate())); | 201 context = V8ContextSnapshot::CreateContextFromSnapshot( |
| 202 isolate, World(), &extension_configuration, global_proxy, document); |
| 203 |
| 204 // Even if we enable V8 context snapshot feature, we may hit this branch |
| 205 // in some cases, e.g. loading XML files. |
| 206 if (context.IsEmpty()) { |
| 207 v8::Local<v8::ObjectTemplate> global_template = |
| 208 V8Window::domTemplate(isolate, *world_)->InstanceTemplate(); |
| 209 CHECK(!global_template.IsEmpty()); |
| 210 context = v8::Context::New(isolate, &extension_configuration, |
| 211 global_template, global_proxy); |
| 212 VLOG(1) << "A context is created NOT from snapshot"; |
| 213 } |
| 198 } | 214 } |
| 199 CHECK(!context.IsEmpty()); | 215 CHECK(!context.IsEmpty()); |
| 200 | 216 |
| 201 #if DCHECK_IS_ON() | 217 #if DCHECK_IS_ON() |
| 202 DidAttachGlobalObject(); | 218 DidAttachGlobalObject(); |
| 203 #endif | 219 #endif |
| 204 | 220 |
| 205 script_state_ = ScriptState::Create(context, world_); | 221 script_state_ = ScriptState::Create(context, world_); |
| 206 | 222 |
| 207 DCHECK(lifecycle_ == Lifecycle::kContextIsUninitialized || | 223 DCHECK(lifecycle_ == Lifecycle::kContextIsUninitialized || |
| 208 lifecycle_ == Lifecycle::kGlobalObjectIsDetached); | 224 lifecycle_ == Lifecycle::kGlobalObjectIsDetached); |
| 209 lifecycle_ = Lifecycle::kContextIsInitialized; | 225 lifecycle_ = Lifecycle::kContextIsInitialized; |
| 210 DCHECK(script_state_->ContextIsValid()); | 226 DCHECK(script_state_->ContextIsValid()); |
| 211 } | 227 } |
| 212 | 228 |
| 213 void LocalWindowProxy::SetupWindowPrototypeChain() { | 229 void LocalWindowProxy::SetupWindowPrototypeChain() { |
| 230 TRACE_EVENT1("v8", "LocalWindowProxy::SetupWindowPrototypeChain", |
| 231 "IsMainFrame", GetFrame()->IsMainFrame()); |
| 232 |
| 214 // Associate the window wrapper object and its prototype chain with the | 233 // Associate the window wrapper object and its prototype chain with the |
| 215 // corresponding native DOMWindow object. | 234 // corresponding native DOMWindow object. |
| 216 DOMWindow* window = GetFrame()->DomWindow(); | 235 DOMWindow* window = GetFrame()->DomWindow(); |
| 217 const WrapperTypeInfo* wrapper_type_info = window->GetWrapperTypeInfo(); | 236 const WrapperTypeInfo* wrapper_type_info = window->GetWrapperTypeInfo(); |
| 218 v8::Local<v8::Context> context = script_state_->GetContext(); | 237 v8::Local<v8::Context> context = script_state_->GetContext(); |
| 219 | 238 |
| 220 // The global proxy object. Note this is not the global object. | 239 // The global proxy object. Note this is not the global object. |
| 221 v8::Local<v8::Object> global_proxy = context->Global(); | 240 v8::Local<v8::Object> global_proxy = context->Global(); |
| 222 CHECK(global_proxy_ == global_proxy); | 241 CHECK(global_proxy_ == global_proxy); |
| 223 V8DOMWrapper::SetNativeInfo(GetIsolate(), global_proxy, wrapper_type_info, | 242 V8DOMWrapper::SetNativeInfo(GetIsolate(), global_proxy, wrapper_type_info, |
| (...skipping 24 matching lines...) Expand all Loading... |
| 248 wrapper_type_info, window); | 267 wrapper_type_info, window); |
| 249 | 268 |
| 250 // TODO(keishi): Remove installPagePopupController and implement | 269 // TODO(keishi): Remove installPagePopupController and implement |
| 251 // PagePopupController in another way. | 270 // PagePopupController in another way. |
| 252 V8PagePopupControllerBinding::InstallPagePopupController(context, | 271 V8PagePopupControllerBinding::InstallPagePopupController(context, |
| 253 window_wrapper); | 272 window_wrapper); |
| 254 } | 273 } |
| 255 | 274 |
| 256 void LocalWindowProxy::UpdateDocumentProperty() { | 275 void LocalWindowProxy::UpdateDocumentProperty() { |
| 257 DCHECK(world_->IsMainWorld()); | 276 DCHECK(world_->IsMainWorld()); |
| 277 TRACE_EVENT1("v8", "LocalWindowProxy::UpdateDocumentProperty", "IsMainFrame", |
| 278 GetFrame()->IsMainFrame()); |
| 258 | 279 |
| 259 ScriptState::Scope scope(script_state_.Get()); | 280 ScriptState::Scope scope(script_state_.Get()); |
| 260 v8::Local<v8::Context> context = script_state_->GetContext(); | 281 v8::Local<v8::Context> context = script_state_->GetContext(); |
| 261 v8::Local<v8::Value> document_wrapper = | 282 v8::Local<v8::Value> document_wrapper = |
| 262 ToV8(GetFrame()->GetDocument(), context->Global(), GetIsolate()); | 283 ToV8(GetFrame()->GetDocument(), context->Global(), GetIsolate()); |
| 263 DCHECK(document_wrapper->IsObject()); | 284 DCHECK(document_wrapper->IsObject()); |
| 285 |
| 264 // Update the cached accessor for window.document. | 286 // Update the cached accessor for window.document. |
| 265 CHECK(V8PrivateProperty::GetWindowDocumentCachedAccessor(GetIsolate()) | 287 CHECK(V8PrivateProperty::GetWindowDocumentCachedAccessor(GetIsolate()) |
| 266 .Set(context->Global(), document_wrapper)); | 288 .Set(context->Global(), document_wrapper)); |
| 267 } | 289 } |
| 268 | 290 |
| 269 void LocalWindowProxy::UpdateActivityLogger() { | 291 void LocalWindowProxy::UpdateActivityLogger() { |
| 270 script_state_->PerContextData()->SetActivityLogger( | 292 script_state_->PerContextData()->SetActivityLogger( |
| 271 V8DOMActivityLogger::ActivityLogger( | 293 V8DOMActivityLogger::ActivityLogger( |
| 272 world_->GetWorldId(), GetFrame()->GetDocument() | 294 world_->GetWorldId(), GetFrame()->GetDocument() |
| 273 ? GetFrame()->GetDocument()->baseURI() | 295 ? GetFrame()->GetDocument()->baseURI() |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 context->UseDefaultSecurityToken(); | 337 context->UseDefaultSecurityToken(); |
| 316 return; | 338 return; |
| 317 } | 339 } |
| 318 | 340 |
| 319 if (world_->IsIsolatedWorld()) { | 341 if (world_->IsIsolatedWorld()) { |
| 320 SecurityOrigin* frame_security_origin = | 342 SecurityOrigin* frame_security_origin = |
| 321 GetFrame()->GetDocument()->GetSecurityOrigin(); | 343 GetFrame()->GetDocument()->GetSecurityOrigin(); |
| 322 String frame_security_token = frame_security_origin->ToString(); | 344 String frame_security_token = frame_security_origin->ToString(); |
| 323 // We need to check the return value of domainWasSetInDOM() on the | 345 // We need to check the return value of domainWasSetInDOM() on the |
| 324 // frame's SecurityOrigin because, if that's the case, only | 346 // frame's SecurityOrigin because, if that's the case, only |
| 325 // SecurityOrigin::m_domain would have been modified. | 347 // SecurityOrigin::domain_ would have been modified. |
| 326 // m_domain is not used by SecurityOrigin::toString(), so we would end | 348 // domain_ is not used by SecurityOrigin::toString(), so we would end |
| 327 // up generating the same token that was already set. | 349 // up generating the same token that was already set. |
| 328 if (frame_security_origin->DomainWasSetInDOM() || | 350 if (frame_security_origin->DomainWasSetInDOM() || |
| 329 frame_security_token.IsEmpty() || frame_security_token == "null") { | 351 frame_security_token.IsEmpty() || frame_security_token == "null") { |
| 330 context->UseDefaultSecurityToken(); | 352 context->UseDefaultSecurityToken(); |
| 331 return; | 353 return; |
| 332 } | 354 } |
| 333 token = frame_security_token + token; | 355 token = frame_security_token + token; |
| 334 } | 356 } |
| 335 | 357 |
| 336 // NOTE: V8 does identity comparison in fast path, must use a symbol | 358 // 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... |
| 466 | 488 |
| 467 SetSecurityToken(origin); | 489 SetSecurityToken(origin); |
| 468 } | 490 } |
| 469 | 491 |
| 470 LocalWindowProxy::LocalWindowProxy(v8::Isolate* isolate, | 492 LocalWindowProxy::LocalWindowProxy(v8::Isolate* isolate, |
| 471 LocalFrame& frame, | 493 LocalFrame& frame, |
| 472 RefPtr<DOMWrapperWorld> world) | 494 RefPtr<DOMWrapperWorld> world) |
| 473 : WindowProxy(isolate, frame, std::move(world)) {} | 495 : WindowProxy(isolate, frame, std::move(world)) {} |
| 474 | 496 |
| 475 } // namespace blink | 497 } // namespace blink |
| OLD | NEW |