Chromium Code Reviews| 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 86 matching lines...) Expand 10 before | Expand all | Expand 10 after 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::ContextInitialized); |
| 108 m_lifecycle = Lifecycle::ContextDetached; | 108 m_lifecycle = behavior == DetachGlobal ? Lifecycle::GlobalObjectDetached |
| 109 : Lifecycle::ContextDetachedFromFrame; | |
| 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::ContextUninitialized || |
| 200 // an already detached window proxy can be re-initialized. This is wrong. | 201 m_lifecycle == Lifecycle::GlobalObjectDetached); |
| 201 // DCHECK(m_lifecycle == Lifecycle::ContextUninitialized); | |
| 202 m_lifecycle = Lifecycle::ContextInitialized; | 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(); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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::ContextUninitialized) |
| 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::GlobalObjectDetached) { |
| 324 if (m_lifecycle == Lifecycle::ContextDetached) { | |
| 325 initialize(); | 324 initialize(); |
| 326 DCHECK_EQ(Lifecycle::ContextInitialized, m_lifecycle); | 325 DCHECK_EQ(Lifecycle::ContextInitialized, 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 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 // Context must be initialized before this point. |
| 393 DCHECK(m_lifecycle >= Lifecycle::ContextInitialized); | 392 DCHECK(m_lifecycle == Lifecycle::ContextInitialized || |
| 394 // TODO(yukishiino): Is it okay to not update named properties | 393 m_lifecycle == Lifecycle::ContextDetachedFromFrame); |
|
haraken
2017/03/28 11:12:42
I might want to change this to CHECK.
Are you pre
Yuki
2017/03/28 12:22:16
Hmm, IIUC, the guideline suggests DCHECK for detec
| |
| 395 // after the context gets detached? | |
| 396 if (m_lifecycle == Lifecycle::ContextDetached) | |
| 397 return; | |
| 398 | 394 |
| 399 ScriptState::Scope scope(m_scriptState.get()); | 395 ScriptState::Scope scope(m_scriptState.get()); |
| 400 v8::Local<v8::Object> documentWrapper = | 396 v8::Local<v8::Object> documentWrapper = |
| 401 m_world->domDataStore().get(document, isolate()); | 397 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(), | 398 documentWrapper->SetAccessor(isolate()->GetCurrentContext(), |
| 406 v8String(isolate(), name), getter).ToChecked(); | 399 v8String(isolate(), name), getter).ToChecked(); |
| 407 } | 400 } |
| 408 | 401 |
| 409 void LocalWindowProxy::namedItemRemoved(HTMLDocument* document, | 402 void LocalWindowProxy::namedItemRemoved(HTMLDocument* document, |
| 410 const AtomicString& name) { | 403 const AtomicString& name) { |
| 411 DCHECK(m_world->isMainWorld()); | 404 DCHECK(m_world->isMainWorld()); |
| 412 | 405 |
| 413 // Context must be initialized before this point. | 406 // Context must be initialized before this point. |
| 414 DCHECK(m_lifecycle >= Lifecycle::ContextInitialized); | 407 DCHECK(m_lifecycle == Lifecycle::ContextInitialized || |
| 415 // TODO(yukishiino): Is it okay to not update named properties | 408 m_lifecycle == Lifecycle::ContextDetachedFromFrame); |
|
haraken
2017/03/28 11:12:42
Ditto.
Yuki
2017/03/28 12:22:16
Ditto.
| |
| 416 // after the context gets detached? | |
| 417 if (m_lifecycle == Lifecycle::ContextDetached) | |
| 418 return; | |
| 419 | 409 |
| 420 if (document->hasNamedItem(name) || document->hasExtraNamedItem(name)) | 410 if (document->hasNamedItem(name) || document->hasExtraNamedItem(name)) |
| 421 return; | 411 return; |
| 422 ScriptState::Scope scope(m_scriptState.get()); | 412 ScriptState::Scope scope(m_scriptState.get()); |
| 423 v8::Local<v8::Object> documentWrapper = | 413 v8::Local<v8::Object> documentWrapper = |
| 424 m_world->domDataStore().get(document, isolate()); | 414 m_world->domDataStore().get(document, isolate()); |
| 425 documentWrapper | 415 documentWrapper |
| 426 ->Delete(isolate()->GetCurrentContext(), v8String(isolate(), name)) | 416 ->Delete(isolate()->GetCurrentContext(), v8String(isolate(), name)) |
| 427 .ToChecked(); | 417 .ToChecked(); |
| 428 } | 418 } |
| 429 | 419 |
| 430 void LocalWindowProxy::updateSecurityOrigin(SecurityOrigin* origin) { | 420 void LocalWindowProxy::updateSecurityOrigin(SecurityOrigin* origin) { |
| 431 // For an uninitialized main window proxy, there's nothing we need | 421 // For an uninitialized main window proxy, there's nothing we need |
| 432 // to update. The update is done when the window proxy gets initialized later. | 422 // to update. The update is done when the window proxy gets initialized later. |
| 433 if (m_lifecycle == Lifecycle::ContextUninitialized) | 423 if (m_lifecycle == Lifecycle::ContextUninitialized) |
| 434 return; | 424 return; |
| 435 // TODO(yukishiino): Is it okay to not update security origin when the context | 425 |
| 436 // is detached? | 426 if (m_lifecycle == Lifecycle::GlobalObjectDetached) |
|
haraken
2017/03/28 11:12:42
Why can't this be:
DCHECK(m_lifecycle == Lifecy
Yuki
2017/03/28 12:22:16
It seems that I confused you. In case of GlobalOb
| |
| 437 if (m_lifecycle == Lifecycle::ContextDetached) | |
| 438 return; | 427 return; |
| 439 | 428 |
| 440 setSecurityToken(origin); | 429 setSecurityToken(origin); |
| 441 } | 430 } |
| 442 | 431 |
| 443 LocalWindowProxy::LocalWindowProxy(v8::Isolate* isolate, | 432 LocalWindowProxy::LocalWindowProxy(v8::Isolate* isolate, |
| 444 LocalFrame& frame, | 433 LocalFrame& frame, |
| 445 RefPtr<DOMWrapperWorld> world) | 434 RefPtr<DOMWrapperWorld> world) |
| 446 : WindowProxy(isolate, frame, std::move(world)) {} | 435 : WindowProxy(isolate, frame, std::move(world)) {} |
| 447 | 436 |
| 448 } // namespace blink | 437 } // namespace blink |
| OLD | NEW |