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 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/WindowProxy.h" | 31 #include "bindings/core/v8/WindowProxy.h" | 
| 32 | 32 | 
| 33 #include "bindings/core/v8/ConditionalFeatures.h" | 33 #include "bindings/core/v8/ConditionalFeatures.h" | 
| 34 #include "bindings/core/v8/DOMWrapperWorld.h" | 34 #include "bindings/core/v8/DOMWrapperWorld.h" | 
| 35 #include "bindings/core/v8/ScriptController.h" | 35 #include "bindings/core/v8/ScriptController.h" | 
| 36 #include "bindings/core/v8/ToV8.h" | |
| 36 #include "bindings/core/v8/V8Binding.h" | 37 #include "bindings/core/v8/V8Binding.h" | 
| 37 #include "bindings/core/v8/V8DOMActivityLogger.h" | 38 #include "bindings/core/v8/V8DOMActivityLogger.h" | 
| 38 #include "bindings/core/v8/V8Document.h" | 39 #include "bindings/core/v8/V8Document.h" | 
| 39 #include "bindings/core/v8/V8GCForContextDispose.h" | 40 #include "bindings/core/v8/V8GCForContextDispose.h" | 
| 40 #include "bindings/core/v8/V8HTMLCollection.h" | 41 #include "bindings/core/v8/V8HTMLCollection.h" | 
| 41 #include "bindings/core/v8/V8HTMLDocument.h" | 42 #include "bindings/core/v8/V8HTMLDocument.h" | 
| 42 #include "bindings/core/v8/V8HiddenValue.h" | 43 #include "bindings/core/v8/V8HiddenValue.h" | 
| 43 #include "bindings/core/v8/V8Initializer.h" | 44 #include "bindings/core/v8/V8Initializer.h" | 
| 44 #include "bindings/core/v8/V8ObjectConstructor.h" | 45 #include "bindings/core/v8/V8ObjectConstructor.h" | 
| 45 #include "bindings/core/v8/V8PagePopupControllerBinding.h" | 46 #include "bindings/core/v8/V8PagePopupControllerBinding.h" | 
| (...skipping 20 matching lines...) Expand all Loading... | |
| 66 #include "wtf/Assertions.h" | 67 #include "wtf/Assertions.h" | 
| 67 #include "wtf/StringExtras.h" | 68 #include "wtf/StringExtras.h" | 
| 68 #include "wtf/text/CString.h" | 69 #include "wtf/text/CString.h" | 
| 69 #include <algorithm> | 70 #include <algorithm> | 
| 70 #include <utility> | 71 #include <utility> | 
| 71 #include <v8-debug.h> | 72 #include <v8-debug.h> | 
| 72 #include <v8.h> | 73 #include <v8.h> | 
| 73 | 74 | 
| 74 namespace blink { | 75 namespace blink { | 
| 75 | 76 | 
| 76 static void checkDocumentWrapper(v8::Local<v8::Object> wrapper, | |
| 77 Document* document) { | |
| 78 ASSERT(V8Document::toImpl(wrapper) == document); | |
| 79 } | |
| 80 | |
| 81 WindowProxy* WindowProxy::create(v8::Isolate* isolate, | 77 WindowProxy* WindowProxy::create(v8::Isolate* isolate, | 
| 82 Frame* frame, | 78 Frame* frame, | 
| 83 DOMWrapperWorld& world) { | 79 DOMWrapperWorld& world) { | 
| 84 return new WindowProxy(frame, &world, isolate); | 80 return new WindowProxy(frame, &world, isolate); | 
| 85 } | 81 } | 
| 86 | 82 | 
| 87 WindowProxy::WindowProxy(Frame* frame, | 83 WindowProxy::WindowProxy(Frame* frame, | 
| 88 PassRefPtr<DOMWrapperWorld> world, | 84 PassRefPtr<DOMWrapperWorld> world, | 
| 89 v8::Isolate* isolate) | 85 v8::Isolate* isolate) | 
| 90 : m_frame(frame), m_isolate(isolate), m_world(world) {} | 86 : m_frame(frame), m_isolate(isolate), m_world(world) {} | 
| (...skipping 17 matching lines...) Expand all Loading... | |
| 108 if (m_frame->isLocalFrame()) { | 104 if (m_frame->isLocalFrame()) { | 
| 109 LocalFrame* frame = toLocalFrame(m_frame); | 105 LocalFrame* frame = toLocalFrame(m_frame); | 
| 110 // The embedder could run arbitrary code in response to the | 106 // The embedder could run arbitrary code in response to the | 
| 111 // willReleaseScriptContext callback, so all disposing should happen after | 107 // willReleaseScriptContext callback, so all disposing should happen after | 
| 112 // it returns. | 108 // it returns. | 
| 113 frame->loader().client()->willReleaseScriptContext(context, | 109 frame->loader().client()->willReleaseScriptContext(context, | 
| 114 m_world->worldId()); | 110 m_world->worldId()); | 
| 115 MainThreadDebugger::instance()->contextWillBeDestroyed(m_scriptState.get()); | 111 MainThreadDebugger::instance()->contextWillBeDestroyed(m_scriptState.get()); | 
| 116 } | 112 } | 
| 117 | 113 | 
| 118 m_document.clear(); | |
| 119 | |
| 120 if (behavior == DetachGlobal) { | 114 if (behavior == DetachGlobal) { | 
| 121 // Clean up state on the global proxy, which will be reused. | 115 // Clean up state on the global proxy, which will be reused. | 
| 122 if (!m_globalProxy.isEmpty()) { | 116 if (!m_globalProxy.isEmpty()) { | 
| 123 // TODO(yukishiino): This DCHECK failed on Canary (M57) and Dev (M56). | 117 // TODO(yukishiino): This DCHECK failed on Canary (M57) and Dev (M56). | 
| 124 // We need to figure out why m_globalProxy != context->Global(). | 118 // We need to figure out why m_globalProxy != context->Global(). | 
| 125 DCHECK(m_globalProxy == context->Global()); | 119 DCHECK(m_globalProxy == context->Global()); | 
| 126 DCHECK_EQ(toScriptWrappable(context->Global()), | 120 DCHECK_EQ(toScriptWrappable(context->Global()), | 
| 127 toScriptWrappable( | 121 toScriptWrappable( | 
| 128 context->Global()->GetPrototype().As<v8::Object>())); | 122 context->Global()->GetPrototype().As<v8::Object>())); | 
| 129 m_globalProxy.get().SetWrapperClassId(0); | 123 m_globalProxy.get().SetWrapperClassId(0); | 
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 417 V8DOMWrapper::setNativeInfo(m_isolate, windowProperties, wrapperTypeInfo, | 411 V8DOMWrapper::setNativeInfo(m_isolate, windowProperties, wrapperTypeInfo, | 
| 418 window); | 412 window); | 
| 419 | 413 | 
| 420 // TODO(keishi): Remove installPagePopupController and implement | 414 // TODO(keishi): Remove installPagePopupController and implement | 
| 421 // PagePopupController in another way. | 415 // PagePopupController in another way. | 
| 422 V8PagePopupControllerBinding::installPagePopupController(context, | 416 V8PagePopupControllerBinding::installPagePopupController(context, | 
| 423 windowWrapper); | 417 windowWrapper); | 
| 424 return true; | 418 return true; | 
| 425 } | 419 } | 
| 426 | 420 | 
| 427 void WindowProxy::updateDocumentWrapper(v8::Local<v8::Object> wrapper) { | 421 void WindowProxy::updateDocumentProperty() { | 
| 428 ASSERT(m_world->isMainWorld()); | 422 DCHECK(m_world->isMainWorld()); | 
| 429 m_document.set(m_isolate, wrapper); | |
| 430 } | |
| 431 | 423 | 
| 432 void WindowProxy::updateDocumentProperty() { | 424 if (m_frame->isRemoteFrame()) | 
| 433 if (!m_world->isMainWorld()) | |
| 434 return; | 425 return; | 
| 435 | 426 | 
| 436 if (m_frame->isRemoteFrame()) { | |
| 437 return; | |
| 438 } | |
| 439 | |
| 440 ScriptState::Scope scope(m_scriptState.get()); | 427 ScriptState::Scope scope(m_scriptState.get()); | 
| 441 v8::Local<v8::Context> context = m_scriptState->context(); | 428 v8::Local<v8::Context> context = m_scriptState->context(); | 
| 442 LocalFrame* frame = toLocalFrame(m_frame); | 429 LocalFrame* frame = toLocalFrame(m_frame); | 
| 443 v8::Local<v8::Value> documentWrapper = | 430 v8::Local<v8::Value> documentWrapper = | 
| 444 toV8(frame->document(), context->Global(), context->GetIsolate()); | 431 toV8(frame->document(), context->Global(), m_isolate); | 
| 
 
haraken
2016/12/02 09:53:05
Can you add CHECK(m_world->domDataStore().get(docu
 
Yuki
2016/12/02 09:55:56
THAT CHECK CAUSED THE CRASH.
 
haraken
2016/12/02 10:17:48
I'm behind. Would you help me understand:
- How i
 
Yuki
2016/12/02 10:39:49
I wrote the explanation at the first message of th
 
 | |
| 445 if (documentWrapper.IsEmpty()) | 432 DCHECK(documentWrapper->IsObject()); | 
| 446 return; | 433 // Update the cached accessor for window.document. | 
| 447 ASSERT(documentWrapper == m_document.newLocal(m_isolate) || | |
| 448 m_document.isEmpty()); | |
| 449 if (m_document.isEmpty()) | |
| 450 updateDocumentWrapper(v8::Local<v8::Object>::Cast(documentWrapper)); | |
| 451 checkDocumentWrapper(m_document.newLocal(m_isolate), frame->document()); | |
| 452 | |
| 453 ASSERT(documentWrapper->IsObject()); | |
| 454 | |
| 455 // Update cached accessor. | |
| 456 CHECK(V8PrivateProperty::getWindowDocumentCachedAccessor(m_isolate).set( | 434 CHECK(V8PrivateProperty::getWindowDocumentCachedAccessor(m_isolate).set( | 
| 457 context, context->Global(), documentWrapper)); | 435 context, context->Global(), documentWrapper)); | 
| 458 } | 436 } | 
| 459 | 437 | 
| 460 void WindowProxy::updateActivityLogger() { | 438 void WindowProxy::updateActivityLogger() { | 
| 461 m_scriptState->perContextData()->setActivityLogger( | 439 m_scriptState->perContextData()->setActivityLogger( | 
| 462 V8DOMActivityLogger::activityLogger( | 440 V8DOMActivityLogger::activityLogger( | 
| 463 m_world->worldId(), | 441 m_world->worldId(), | 
| 464 m_frame->isLocalFrame() && toLocalFrame(m_frame)->document() | 442 m_frame->isLocalFrame() && toLocalFrame(m_frame)->document() | 
| 465 ? toLocalFrame(m_frame)->document()->baseURI() | 443 ? toLocalFrame(m_frame)->document()->baseURI() | 
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 511 } | 489 } | 
| 512 token = frameSecurityToken + token; | 490 token = frameSecurityToken + token; | 
| 513 } | 491 } | 
| 514 | 492 | 
| 515 // NOTE: V8 does identity comparison in fast path, must use a symbol | 493 // NOTE: V8 does identity comparison in fast path, must use a symbol | 
| 516 // as the security token. | 494 // as the security token. | 
| 517 context->SetSecurityToken(v8AtomicString(m_isolate, token)); | 495 context->SetSecurityToken(v8AtomicString(m_isolate, token)); | 
| 518 } | 496 } | 
| 519 | 497 | 
| 520 void WindowProxy::updateDocument() { | 498 void WindowProxy::updateDocument() { | 
| 521 ASSERT(m_world->isMainWorld()); | 499 DCHECK(m_world->isMainWorld()); | 
| 522 if (!isGlobalInitialized()) | 500 if (!isGlobalInitialized()) | 
| 523 return; | 501 return; | 
| 524 if (!isContextInitialized()) | 502 if (!isContextInitialized()) | 
| 525 return; | 503 return; | 
| 526 updateActivityLogger(); | 504 updateActivityLogger(); | 
| 527 updateDocumentProperty(); | 505 updateDocumentProperty(); | 
| 528 updateSecurityOrigin(m_frame->securityContext()->getSecurityOrigin()); | 506 updateSecurityOrigin(m_frame->securityContext()->getSecurityOrigin()); | 
| 529 } | 507 } | 
| 530 | 508 | 
| 531 static v8::Local<v8::Value> getNamedProperty( | 509 static v8::Local<v8::Value> getNamedProperty( | 
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 568 return; | 546 return; | 
| 569 } | 547 } | 
| 570 v8::Local<v8::Value> value; | 548 v8::Local<v8::Value> value; | 
| 571 if (info.Holder() | 549 if (info.Holder() | 
| 572 ->GetRealNamedPropertyInPrototypeChain( | 550 ->GetRealNamedPropertyInPrototypeChain( | 
| 573 info.GetIsolate()->GetCurrentContext(), property.As<v8::String>()) | 551 info.GetIsolate()->GetCurrentContext(), property.As<v8::String>()) | 
| 574 .ToLocal(&value)) | 552 .ToLocal(&value)) | 
| 575 v8SetReturnValue(info, value); | 553 v8SetReturnValue(info, value); | 
| 576 } | 554 } | 
| 577 | 555 | 
| 556 void WindowProxy::checkDocumentWrapper(v8::Local<v8::Object> wrapper, | |
| 557 Document* document) const { | |
| 558 DCHECK(!wrapper.IsEmpty()); | |
| 559 DCHECK_EQ(V8Document::toImpl(wrapper), document); | |
| 560 DCHECK(wrapper == | |
| 
 
haraken
2016/12/02 09:53:05
Can you add DCHECK(!m_world->domDataStore().get(do
 
Yuki
2016/12/02 09:55:56
Oops, I forgot to remove checkDocumentWrapper() en
 
 | |
| 561 toV8(document, m_globalProxy.newLocal(m_isolate), m_isolate)); | |
| 562 } | |
| 563 | |
| 578 void WindowProxy::namedItemAdded(HTMLDocument* document, | 564 void WindowProxy::namedItemAdded(HTMLDocument* document, | 
| 579 const AtomicString& name) { | 565 const AtomicString& name) { | 
| 580 ASSERT(m_world->isMainWorld()); | 566 DCHECK(m_world->isMainWorld()); | 
| 581 | 567 | 
| 582 if (!isContextInitialized() || !m_scriptState->contextIsValid()) | 568 if (!isContextInitialized()) | 
| 583 return; | 569 return; | 
| 584 | 570 | 
| 585 ScriptState::Scope scope(m_scriptState.get()); | 571 ScriptState::Scope scope(m_scriptState.get()); | 
| 586 ASSERT(!m_document.isEmpty()); | 572 v8::Local<v8::Object> documentWrapper = | 
| 587 v8::Local<v8::Context> context = m_scriptState->context(); | 573 m_world->domDataStore().get(document, m_isolate); | 
| 588 v8::Local<v8::Object> documentHandle = m_document.newLocal(m_isolate); | 574 documentWrapper | 
| 589 checkDocumentWrapper(documentHandle, document); | 575 ->SetAccessor(m_isolate->GetCurrentContext(), v8String(m_isolate, name), | 
| 590 documentHandle->SetAccessor(context, v8String(m_isolate, name), getter); | 576 getter) | 
| 577 .ToChecked(); | |
| 591 } | 578 } | 
| 592 | 579 | 
| 593 void WindowProxy::namedItemRemoved(HTMLDocument* document, | 580 void WindowProxy::namedItemRemoved(HTMLDocument* document, | 
| 594 const AtomicString& name) { | 581 const AtomicString& name) { | 
| 595 ASSERT(m_world->isMainWorld()); | 582 DCHECK(m_world->isMainWorld()); | 
| 596 | 583 | 
| 597 if (!isContextInitialized()) | 584 if (!isContextInitialized()) | 
| 598 return; | 585 return; | 
| 599 | 586 | 
| 600 if (document->hasNamedItem(name) || document->hasExtraNamedItem(name)) | 587 if (document->hasNamedItem(name) || document->hasExtraNamedItem(name)) | 
| 601 return; | 588 return; | 
| 602 | 589 | 
| 603 ScriptState::Scope scope(m_scriptState.get()); | 590 ScriptState::Scope scope(m_scriptState.get()); | 
| 604 ASSERT(!m_document.isEmpty()); | 591 v8::Local<v8::Object> documentWrapper = | 
| 605 v8::Local<v8::Object> documentHandle = m_document.newLocal(m_isolate); | 592 m_world->domDataStore().get(document, m_isolate); | 
| 606 checkDocumentWrapper(documentHandle, document); | 593 documentWrapper | 
| 607 documentHandle->Delete(m_isolate->GetCurrentContext(), | 594 ->Delete(m_isolate->GetCurrentContext(), v8String(m_isolate, name)) | 
| 608 v8String(m_isolate, name)); | 595 .ToChecked(); | 
| 609 } | 596 } | 
| 610 | 597 | 
| 611 void WindowProxy::updateSecurityOrigin(SecurityOrigin* origin) { | 598 void WindowProxy::updateSecurityOrigin(SecurityOrigin* origin) { | 
| 612 if (!isContextInitialized()) | 599 if (!isContextInitialized()) | 
| 613 return; | 600 return; | 
| 614 setSecurityToken(origin); | 601 setSecurityToken(origin); | 
| 615 } | 602 } | 
| 616 | 603 | 
| 617 } // namespace blink | 604 } // namespace blink | 
| OLD | NEW |