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 |