| 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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 #include "platform/heap/Handle.h" | 59 #include "platform/heap/Handle.h" |
| 60 #include "platform/instrumentation/tracing/TraceEvent.h" | 60 #include "platform/instrumentation/tracing/TraceEvent.h" |
| 61 #include "platform/weborigin/SecurityOrigin.h" | 61 #include "platform/weborigin/SecurityOrigin.h" |
| 62 #include "platform/weborigin/SecurityViolationReportingPolicy.h" | 62 #include "platform/weborigin/SecurityViolationReportingPolicy.h" |
| 63 #include "v8/include/v8.h" | 63 #include "v8/include/v8.h" |
| 64 #include "wtf/Assertions.h" | 64 #include "wtf/Assertions.h" |
| 65 | 65 |
| 66 namespace blink { | 66 namespace blink { |
| 67 | 67 |
| 68 void LocalWindowProxy::disposeContext(GlobalDetachmentBehavior behavior) { | 68 void LocalWindowProxy::disposeContext(GlobalDetachmentBehavior behavior) { |
| 69 if (m_lifecycle != Lifecycle::ContextInitialized) | 69 if (m_lifecycle != Lifecycle::ContextIsInitialized) |
| 70 return; | 70 return; |
| 71 | 71 |
| 72 ScriptState::Scope scope(m_scriptState.get()); | 72 ScriptState::Scope scope(m_scriptState.get()); |
| 73 v8::Local<v8::Context> context = m_scriptState->context(); | 73 v8::Local<v8::Context> context = m_scriptState->context(); |
| 74 // The embedder could run arbitrary code in response to the | 74 // The embedder could run arbitrary code in response to the |
| 75 // willReleaseScriptContext callback, so all disposing should happen after | 75 // willReleaseScriptContext callback, so all disposing should happen after |
| 76 // it returns. | 76 // it returns. |
| 77 frame()->loader().client()->willReleaseScriptContext(context, | 77 frame()->loader().client()->willReleaseScriptContext(context, |
| 78 m_world->worldId()); | 78 m_world->worldId()); |
| 79 MainThreadDebugger::instance()->contextWillBeDestroyed(m_scriptState.get()); | 79 MainThreadDebugger::instance()->contextWillBeDestroyed(m_scriptState.get()); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 97 } | 97 } |
| 98 | 98 |
| 99 m_scriptState->disposePerContextData(); | 99 m_scriptState->disposePerContextData(); |
| 100 | 100 |
| 101 // It's likely that disposing the context has created a lot of | 101 // It's likely that disposing the context has created a lot of |
| 102 // garbage. Notify V8 about this so it'll have a chance of cleaning | 102 // garbage. Notify V8 about this so it'll have a chance of cleaning |
| 103 // it up when idle. | 103 // it up when idle. |
| 104 V8GCForContextDispose::instance().notifyContextDisposed( | 104 V8GCForContextDispose::instance().notifyContextDisposed( |
| 105 frame()->isMainFrame()); | 105 frame()->isMainFrame()); |
| 106 | 106 |
| 107 DCHECK(m_lifecycle == Lifecycle::ContextInitialized); | 107 DCHECK_EQ(m_lifecycle, Lifecycle::ContextIsInitialized); |
| 108 m_lifecycle = Lifecycle::ContextDetached; | 108 m_lifecycle = behavior == DetachGlobal ? Lifecycle::GlobalObjectIsDetached |
| 109 : Lifecycle::FrameIsDetached; |
| 109 } | 110 } |
| 110 | 111 |
| 111 void LocalWindowProxy::initialize() { | 112 void LocalWindowProxy::initialize() { |
| 112 TRACE_EVENT1("v8", "LocalWindowProxy::initialize", "isMainWindow", | 113 TRACE_EVENT1("v8", "LocalWindowProxy::initialize", "isMainWindow", |
| 113 frame()->isMainFrame()); | 114 frame()->isMainFrame()); |
| 114 SCOPED_BLINK_UMA_HISTOGRAM_TIMER( | 115 SCOPED_BLINK_UMA_HISTOGRAM_TIMER( |
| 115 frame()->isMainFrame() | 116 frame()->isMainFrame() |
| 116 ? "Blink.Binding.InitializeMainLocalWindowProxy" | 117 ? "Blink.Binding.InitializeMainLocalWindowProxy" |
| 117 : "Blink.Binding.InitializeNonMainLocalWindowProxy"); | 118 : "Blink.Binding.InitializeNonMainLocalWindowProxy"); |
| 118 | 119 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 m_globalProxy.newLocal(isolate())); | 190 m_globalProxy.newLocal(isolate())); |
| 190 } | 191 } |
| 191 CHECK(!context.IsEmpty()); | 192 CHECK(!context.IsEmpty()); |
| 192 | 193 |
| 193 #if DCHECK_IS_ON() | 194 #if DCHECK_IS_ON() |
| 194 didAttachGlobalObject(); | 195 didAttachGlobalObject(); |
| 195 #endif | 196 #endif |
| 196 | 197 |
| 197 m_scriptState = ScriptState::create(context, m_world); | 198 m_scriptState = ScriptState::create(context, m_world); |
| 198 | 199 |
| 199 // TODO(haraken): Currently we cannot enable the following DCHECK because | 200 DCHECK(m_lifecycle == Lifecycle::ContextIsUninitialized || |
| 200 // an already detached window proxy can be re-initialized. This is wrong. | 201 m_lifecycle == Lifecycle::GlobalObjectIsDetached); |
| 201 // DCHECK(m_lifecycle == Lifecycle::ContextUninitialized); | 202 m_lifecycle = Lifecycle::ContextIsInitialized; |
| 202 m_lifecycle = Lifecycle::ContextInitialized; | |
| 203 DCHECK(m_scriptState->contextIsValid()); | 203 DCHECK(m_scriptState->contextIsValid()); |
| 204 } | 204 } |
| 205 | 205 |
| 206 void LocalWindowProxy::setupWindowPrototypeChain() { | 206 void LocalWindowProxy::setupWindowPrototypeChain() { |
| 207 // Associate the window wrapper object and its prototype chain with the | 207 // Associate the window wrapper object and its prototype chain with the |
| 208 // corresponding native DOMWindow object. | 208 // corresponding native DOMWindow object. |
| 209 DOMWindow* window = frame()->domWindow(); | 209 DOMWindow* window = frame()->domWindow(); |
| 210 const WrapperTypeInfo* wrapperTypeInfo = window->wrapperTypeInfo(); | 210 const WrapperTypeInfo* wrapperTypeInfo = window->wrapperTypeInfo(); |
| 211 v8::Local<v8::Context> context = m_scriptState->context(); | 211 v8::Local<v8::Context> context = m_scriptState->context(); |
| 212 | 212 |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 308 | 308 |
| 309 // NOTE: V8 does identity comparison in fast path, must use a symbol | 309 // NOTE: V8 does identity comparison in fast path, must use a symbol |
| 310 // as the security token. | 310 // as the security token. |
| 311 context->SetSecurityToken(v8AtomicString(isolate(), token)); | 311 context->SetSecurityToken(v8AtomicString(isolate(), token)); |
| 312 } | 312 } |
| 313 | 313 |
| 314 void LocalWindowProxy::updateDocument() { | 314 void LocalWindowProxy::updateDocument() { |
| 315 DCHECK(m_world->isMainWorld()); | 315 DCHECK(m_world->isMainWorld()); |
| 316 // For an uninitialized main window proxy, there's nothing we need | 316 // For an uninitialized main window proxy, there's nothing we need |
| 317 // to update. The update is done when the window proxy gets initialized later. | 317 // to update. The update is done when the window proxy gets initialized later. |
| 318 if (m_lifecycle == Lifecycle::ContextUninitialized) | 318 if (m_lifecycle == Lifecycle::ContextIsUninitialized) |
| 319 return; | 319 return; |
| 320 | 320 |
| 321 // If this WindowProxy was previously initialized, reinitialize it now to | 321 // For a navigated-away window proxy, reinitialize it as a new window with new |
| 322 // preserve JS object identity. Otherwise, extant references to the | 322 // context and document. |
| 323 // WindowProxy will be broken. | 323 if (m_lifecycle == Lifecycle::GlobalObjectIsDetached) { |
| 324 if (m_lifecycle == Lifecycle::ContextDetached) { | |
| 325 initialize(); | 324 initialize(); |
| 326 DCHECK_EQ(Lifecycle::ContextInitialized, m_lifecycle); | 325 DCHECK_EQ(Lifecycle::ContextIsInitialized, m_lifecycle); |
| 327 // Initialization internally updates the document properties, so just | 326 // Initialization internally updates the document properties, so just |
| 328 // return afterwards. | 327 // return afterwards. |
| 329 return; | 328 return; |
| 330 } | 329 } |
| 331 | 330 |
| 332 updateDocumentInternal(); | 331 updateDocumentInternal(); |
| 333 } | 332 } |
| 334 | 333 |
| 335 void LocalWindowProxy::updateDocumentInternal() { | 334 void LocalWindowProxy::updateDocumentInternal() { |
| 336 updateActivityLogger(); | 335 updateActivityLogger(); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 ->GetRealNamedPropertyInPrototypeChain( | 381 ->GetRealNamedPropertyInPrototypeChain( |
| 383 info.GetIsolate()->GetCurrentContext(), property.As<v8::String>()) | 382 info.GetIsolate()->GetCurrentContext(), property.As<v8::String>()) |
| 384 .ToLocal(&value)) | 383 .ToLocal(&value)) |
| 385 v8SetReturnValue(info, value); | 384 v8SetReturnValue(info, value); |
| 386 } | 385 } |
| 387 | 386 |
| 388 void LocalWindowProxy::namedItemAdded(HTMLDocument* document, | 387 void LocalWindowProxy::namedItemAdded(HTMLDocument* document, |
| 389 const AtomicString& name) { | 388 const AtomicString& name) { |
| 390 DCHECK(m_world->isMainWorld()); | 389 DCHECK(m_world->isMainWorld()); |
| 391 | 390 |
| 392 // Context must be initialized before this point. | 391 // Currently only contexts in attached frames can change the named items. |
| 393 DCHECK(m_lifecycle >= Lifecycle::ContextInitialized); | 392 // TODO(yukishiino): Support detached frame's case, too, since the spec is not |
| 394 // TODO(yukishiino): Is it okay to not update named properties | 393 // saying that the document needs to be attached to the DOM. |
| 395 // after the context gets detached? | 394 // https://html.spec.whatwg.org/C/dom.html#dom-document-nameditem |
| 396 if (m_lifecycle == Lifecycle::ContextDetached) | 395 DCHECK(m_lifecycle == Lifecycle::ContextIsInitialized); |
| 396 // TODO(yukishiino): Remove the following if-clause due to the above DCHECK. |
| 397 if (m_lifecycle != Lifecycle::ContextIsInitialized) |
| 397 return; | 398 return; |
| 398 | 399 |
| 399 ScriptState::Scope scope(m_scriptState.get()); | 400 ScriptState::Scope scope(m_scriptState.get()); |
| 400 v8::Local<v8::Object> documentWrapper = | 401 v8::Local<v8::Object> documentWrapper = |
| 401 m_world->domDataStore().get(document, isolate()); | 402 m_world->domDataStore().get(document, isolate()); |
| 402 // TODO(yukishiino,peria): We should check if the own property with the same | |
| 403 // name already exists or not, and if it exists, we shouldn't define a new | |
| 404 // accessor property (it fails). | |
| 405 documentWrapper->SetAccessor(isolate()->GetCurrentContext(), | 403 documentWrapper->SetAccessor(isolate()->GetCurrentContext(), |
| 406 v8String(isolate(), name), getter).ToChecked(); | 404 v8String(isolate(), name), getter).ToChecked(); |
| 407 } | 405 } |
| 408 | 406 |
| 409 void LocalWindowProxy::namedItemRemoved(HTMLDocument* document, | 407 void LocalWindowProxy::namedItemRemoved(HTMLDocument* document, |
| 410 const AtomicString& name) { | 408 const AtomicString& name) { |
| 411 DCHECK(m_world->isMainWorld()); | 409 DCHECK(m_world->isMainWorld()); |
| 412 | 410 |
| 413 // Context must be initialized before this point. | 411 // Currently only contexts in attached frames can change the named items. |
| 414 DCHECK(m_lifecycle >= Lifecycle::ContextInitialized); | 412 // TODO(yukishiino): Support detached frame's case, too, since the spec is not |
| 415 // TODO(yukishiino): Is it okay to not update named properties | 413 // saying that the document needs to be attached to the DOM. |
| 416 // after the context gets detached? | 414 // https://html.spec.whatwg.org/C/dom.html#dom-document-nameditem |
| 417 if (m_lifecycle == Lifecycle::ContextDetached) | 415 DCHECK(m_lifecycle == Lifecycle::ContextIsInitialized); |
| 416 // TODO(yukishiino): Remove the following if-clause due to the above DCHECK. |
| 417 if (m_lifecycle != Lifecycle::ContextIsInitialized) |
| 418 return; | 418 return; |
| 419 | 419 |
| 420 if (document->hasNamedItem(name) || document->hasExtraNamedItem(name)) | 420 if (document->hasNamedItem(name) || document->hasExtraNamedItem(name)) |
| 421 return; | 421 return; |
| 422 ScriptState::Scope scope(m_scriptState.get()); | 422 ScriptState::Scope scope(m_scriptState.get()); |
| 423 v8::Local<v8::Object> documentWrapper = | 423 v8::Local<v8::Object> documentWrapper = |
| 424 m_world->domDataStore().get(document, isolate()); | 424 m_world->domDataStore().get(document, isolate()); |
| 425 documentWrapper | 425 documentWrapper |
| 426 ->Delete(isolate()->GetCurrentContext(), v8String(isolate(), name)) | 426 ->Delete(isolate()->GetCurrentContext(), v8String(isolate(), name)) |
| 427 .ToChecked(); | 427 .ToChecked(); |
| 428 } | 428 } |
| 429 | 429 |
| 430 void LocalWindowProxy::updateSecurityOrigin(SecurityOrigin* origin) { | 430 void LocalWindowProxy::updateSecurityOrigin(SecurityOrigin* origin) { |
| 431 // For an uninitialized main window proxy, there's nothing we need | 431 // For an uninitialized window proxy, there's nothing we need to update. The |
| 432 // to update. The update is done when the window proxy gets initialized later. | 432 // update is done when the window proxy gets initialized later. |
| 433 if (m_lifecycle == Lifecycle::ContextUninitialized) | 433 if (m_lifecycle == Lifecycle::ContextIsUninitialized || |
| 434 return; | 434 m_lifecycle == Lifecycle::GlobalObjectIsDetached) |
| 435 // TODO(yukishiino): Is it okay to not update security origin when the context | |
| 436 // is detached? | |
| 437 if (m_lifecycle == Lifecycle::ContextDetached) | |
| 438 return; | 435 return; |
| 439 | 436 |
| 440 setSecurityToken(origin); | 437 setSecurityToken(origin); |
| 441 } | 438 } |
| 442 | 439 |
| 443 LocalWindowProxy::LocalWindowProxy(v8::Isolate* isolate, | 440 LocalWindowProxy::LocalWindowProxy(v8::Isolate* isolate, |
| 444 LocalFrame& frame, | 441 LocalFrame& frame, |
| 445 RefPtr<DOMWrapperWorld> world) | 442 RefPtr<DOMWrapperWorld> world) |
| 446 : WindowProxy(isolate, frame, std::move(world)) {} | 443 : WindowProxy(isolate, frame, std::move(world)) {} |
| 447 | 444 |
| 448 } // namespace blink | 445 } // namespace blink |
| OLD | NEW |