Changeset 95385 in webkit
- Timestamp:
- Sep 17, 2011 3:47:09 PM (13 years ago)
- Location:
- trunk/Source
- Files:
-
- 2 added
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r95383 r95385 1 2011-09-17 Aaron Boodman <aa@chromium.org> 2 3 Rework script context creation/release notifications 4 https://bugs.webkit.org/show_bug.cgi?id=67828 5 6 Reviewed by Adam Barth. 7 8 * bindings/v8/V8DOMWindowShell.cpp: 9 (WebCore::V8DOMWindowShell::disposeContextHandles): 10 (WebCore::V8DOMWindowShell::initContextIfNeeded): 11 * bindings/v8/V8IsolatedContext.cpp: 12 (WebCore::V8IsolatedContext::V8IsolatedContext): 13 (WebCore::V8IsolatedContext::destroy): 14 * bindings/v8/V8IsolatedContext.h: 15 * loader/EmptyClients.h: 16 (WebCore::EmptyFrameLoaderClient::didCreateScriptContext): 17 (WebCore::EmptyFrameLoaderClient::willReleaseScriptContext): 18 * loader/FrameLoaderClient.h: 19 1 20 2011-09-17 Ilya Tikhonovsky <loislo@chromium.org> 2 21 -
trunk/Source/WebCore/bindings/v8/V8DOMWindowShell.cpp
r95354 r95385 174 174 { 175 175 if (!m_context.IsEmpty()) { 176 m_frame->loader()->client()-> didDestroyScriptContextForFrame();176 m_frame->loader()->client()->willReleaseScriptContext(m_context, 0); 177 177 m_context.Dispose(); 178 178 m_context.Clear(); … … 340 340 setSecurityToken(); 341 341 342 m_frame->loader()->client()->didCreateScriptContext ForFrame();342 m_frame->loader()->client()->didCreateScriptContext(m_context, 0); 343 343 344 344 // FIXME: This is wrong. We should actually do this for the proper world once -
trunk/Source/WebCore/bindings/v8/V8IsolatedContext.cpp
r93055 r95385 50 50 51 51 V8IsolatedContext::V8IsolatedContext(V8Proxy* proxy, int extensionGroup, int worldId) 52 : m_world(IsolatedWorld::create(worldId)) 52 : m_world(IsolatedWorld::create(worldId)), m_frame(proxy->frame()) 53 53 { 54 54 v8::HandleScope scope; … … 65 65 V8DOMWindowShell::installHiddenObjectPrototype(m_context->get()); 66 66 // FIXME: This will go away once we have a windowShell for the isolated world. 67 proxy->windowShell()->installDOMWindow(m_context->get(), proxy->frame()->domWindow());67 proxy->windowShell()->installDOMWindow(m_context->get(), m_frame->domWindow()); 68 68 69 69 // Using the default security token means that the canAccess is always … … 75 75 m_context->get()->UseDefaultSecurityToken(); 76 76 77 proxy->frame()->loader()->client()->didCreateIsolatedScriptContext(this);77 m_frame->loader()->client()->didCreateScriptContext(context(), m_world->id()); 78 78 } 79 79 80 80 void V8IsolatedContext::destroy() 81 81 { 82 m_frame->loader()->client()->willReleaseScriptContext(context(), m_world->id()); 82 83 m_context->get().MakeWeak(this, &contextWeakReferenceCallback); 84 m_frame = 0; 83 85 } 84 86 -
trunk/Source/WebCore/bindings/v8/V8IsolatedContext.h
r93055 r95385 115 115 116 116 RefPtr<SecurityOrigin> m_securityOrigin; 117 118 Frame* m_frame; 117 119 }; 118 120 -
trunk/Source/WebCore/loader/EmptyClients.h
r95271 r95385 48 48 49 49 #if USE(V8) 50 #include "V8IsolatedContext.h"50 #include <v8.h> 51 51 #endif 52 52 … … 398 398 399 399 #if USE(V8) 400 virtual void didCreateScriptContextForFrame() { } 401 virtual void didDestroyScriptContextForFrame() { } 402 virtual void didCreateIsolatedScriptContext(V8IsolatedContext*) { } 400 virtual void didCreateScriptContext(v8::Handle<v8::Context>, int worldId) { } 401 virtual void willReleaseScriptContext(v8::Handle<v8::Context>, int worldId) { } 403 402 virtual bool allowScriptExtension(const String& extensionName, int extensionGroup) { return false; } 404 403 #endif -
trunk/Source/WebCore/loader/FrameLoaderClient.h
r95369 r95385 52 52 #endif 53 53 54 #if USE(V8) 55 namespace v8 { 56 class Context; 57 template<class T> class Handle; 58 } 59 #endif 60 54 61 namespace WebCore { 55 62 … … 88 95 class StringWithDirection; 89 96 class SubstituteData; 90 #if USE(V8)91 class V8IsolatedContext;92 #endif93 97 class Widget; 94 98 … … 275 279 276 280 #if USE(V8) 277 virtual void didCreateScriptContextForFrame() = 0; 278 virtual void didDestroyScriptContextForFrame() = 0; 279 virtual void didCreateIsolatedScriptContext(V8IsolatedContext*) = 0; 281 virtual void didCreateScriptContext(v8::Handle<v8::Context>, int worldId) = 0; 282 virtual void willReleaseScriptContext(v8::Handle<v8::Context>, int worldId) = 0; 280 283 virtual bool allowScriptExtension(const String& extensionName, int extensionGroup) = 0; 281 284 #endif -
trunk/Source/WebKit/chromium/ChangeLog
r95380 r95385 1 2011-09-17 Aaron Boodman <aa@chromium.org> 2 3 Rework script context creation/release notifications 4 https://bugs.webkit.org/show_bug.cgi?id=67828 5 6 Reviewed by Adam Barth. 7 8 * public/WebFrameClient.h: 9 (WebKit::WebFrameClient::didCreateScriptContext): 10 (WebKit::WebFrameClient::didDestroyScriptContext): 11 (WebKit::WebFrameClient::willReleaseScriptContext): 12 * src/FrameLoaderClientImpl.cpp: 13 (WebKit::FrameLoaderClientImpl::didCreateScriptContext): 14 (WebKit::FrameLoaderClientImpl::willReleaseScriptContext): 15 * src/FrameLoaderClientImpl.h: 16 1 17 2011-09-17 chandra shekar vallala <chandra.vallala@motorola.com> 2 18 -
trunk/Source/WebKit/chromium/public/WebFrameClient.h
r94231 r95385 299 299 // This is similar to didClearWindowObject but only called once per 300 300 // frame context. 301 // FIXME: Remove this when Chromium is updated to use the below version. 301 302 virtual void didCreateScriptContext(WebFrame*) { } 302 303 // Notifies that this frame's script context has been destroyed.304 virtual void didDestroyScriptContext(WebFrame*) { } 303 #if WEBKIT_USING_V8 304 virtual void didCreateScriptContext(WebFrame*, v8::Handle<v8::Context>, int worldId) { } 305 #endif 305 306 306 307 // Notifies that a garbage-collected context was created - content 307 308 // scripts. 309 // FIXME: Remove this when Chromium is updated to use didCreateScriptContext(). 308 310 #if WEBKIT_USING_V8 309 311 virtual void didCreateIsolatedScriptContext(WebFrame*, int worldID, v8::Handle<v8::Context>) { } 312 #endif 313 314 // Notifies that this frame's script context has been destroyed. 315 // FIXME: Remove this when Chromium is updated to use the below version. 316 virtual void didDestroyScriptContext(WebFrame*) { } 317 318 #if WEBKIT_USING_V8 319 // WebKit is about to release its reference to a v8 context for a frame. 320 virtual void willReleaseScriptContext(WebFrame*, v8::Handle<v8::Context>, int worldId) { } 310 321 #endif 311 322 -
trunk/Source/WebKit/chromium/src/FrameLoaderClientImpl.cpp
r95369 r95385 86 86 87 87 #if USE(V8) 88 #include "V8IsolatedContext.h"88 #include <v8.h> 89 89 #endif 90 90 … … 141 141 } 142 142 143 void FrameLoaderClientImpl::didCreateScriptContextForFrame()144 {145 if (m_webFrame->client())146 m_webFrame->client()->didCreateScriptContext(m_webFrame);147 }148 149 void FrameLoaderClientImpl::didDestroyScriptContextForFrame()150 {151 if (m_webFrame->client())152 m_webFrame->client()->didDestroyScriptContext(m_webFrame);153 }154 155 143 #if USE(V8) 156 void FrameLoaderClientImpl::didCreateIsolatedScriptContext(V8IsolatedContext* isolatedContext) 157 { 158 if (m_webFrame->client()) 159 m_webFrame->client()->didCreateIsolatedScriptContext(m_webFrame, isolatedContext->world()->id(), isolatedContext->context()); 144 void FrameLoaderClientImpl::didCreateScriptContext(v8::Handle<v8::Context> context, int worldId) 145 { 146 if (m_webFrame->client()) 147 m_webFrame->client()->didCreateScriptContext(m_webFrame, context, worldId); 148 } 149 150 void FrameLoaderClientImpl::willReleaseScriptContext(v8::Handle<v8::Context> context, int worldId) 151 { 152 if (m_webFrame->client()) 153 m_webFrame->client()->willReleaseScriptContext(m_webFrame, context, worldId); 160 154 } 161 155 #endif -
trunk/Source/WebKit/chromium/src/FrameLoaderClientImpl.h
r95369 r95385 62 62 virtual void documentElementAvailable(); 63 63 64 // A frame's V8 context was created or destroyed.65 virtual void didCreateScriptContextForFrame();66 virtual void didDestroyScriptContextForFrame();67 68 64 #if USE(V8) 69 // A context untied to a frame was created (through evaluateInIsolatedWorld). 70 // This context is not tied to the lifetime of its frame, and is destroyed 71 // in garbage collection. 72 virtual void didCreateIsolatedScriptContext(WebCore::V8IsolatedContext*); 65 virtual void didCreateScriptContext(v8::Handle<v8::Context>, int worldId); 66 virtual void willReleaseScriptContext(v8::Handle<v8::Context>, int worldId); 73 67 #endif 74 68 -
trunk/Source/WebKit/chromium/tests/WebFrameTest.cpp
r95380 r95385 36 36 #include "WebFrame.h" 37 37 #include "WebFrameClient.h" 38 #include "WebScriptSource.h" 38 39 #include "WebSearchableFormData.h" 39 40 #include "WebSecurityPolicy.h" … … 158 159 159 160 // Create and initialize the WebView. 160 161 TestWebFrameClient webFrameClient; 161 162 WebView* webView = WebView::create(0); 162 163 webView->settings()->setJavaScriptEnabled(true); … … 281 282 EXPECT_EQ(0, webViewImpl->focusedWebCoreNode()); 282 283 283 webViewImpl->close(); 284 webViewImpl->close(); 285 } 286 287 // Implementation of WebFrameClient that tracks the v8 contexts that are created 288 // and destroyed for verification. 289 class ContextLifetimeTestWebFrameClient : public WebFrameClient { 290 public: 291 struct Notification { 292 public: 293 Notification(WebFrame* frame, v8::Handle<v8::Context> context, int worldId) 294 : frame(frame) , context(v8::Persistent<v8::Context>::New(context)), worldId(worldId) 295 { 296 } 297 298 ~Notification() 299 { 300 context.Dispose(); 301 } 302 303 bool Equals(Notification* other) 304 { 305 return other && frame == other->frame && context == other->context && worldId == other->worldId; 306 } 307 308 WebFrame* frame; 309 v8::Persistent<v8::Context> context; 310 int worldId; 311 }; 312 313 ~ContextLifetimeTestWebFrameClient() 314 { 315 reset(); 316 } 317 318 void reset() 319 { 320 for (size_t i = 0; i < createNotifications.size(); ++i) 321 delete createNotifications[i]; 322 323 for (size_t i = 0; i < releaseNotifications.size(); ++i) 324 delete releaseNotifications[i]; 325 326 createNotifications.clear(); 327 releaseNotifications.clear(); 328 } 329 330 std::vector<Notification*> createNotifications; 331 std::vector<Notification*> releaseNotifications; 332 333 private: 334 virtual void didCreateScriptContext(WebFrame* frame, v8::Handle<v8::Context> context, int worldId) 335 { 336 createNotifications.push_back(new Notification(frame, context, worldId)); 337 } 338 339 virtual void willReleaseScriptContext(WebFrame* frame, v8::Handle<v8::Context> context, int worldId) 340 { 341 releaseNotifications.push_back(new Notification(frame, context, worldId)); 342 } 343 }; 344 345 TEST_F(WebFrameTest, ContextNotificationsLoadUnload) 346 { 347 v8::HandleScope handleScope; 348 349 registerMockedHttpURLLoad("context_notifications_test.html"); 350 registerMockedHttpURLLoad("context_notifications_test_frame.html"); 351 352 // Load a frame with an iframe, make sure we get the right create notifications. 353 ContextLifetimeTestWebFrameClient webFrameClient; 354 WebView* webView = WebView::create(0); 355 webView->settings()->setJavaScriptEnabled(true); 356 webView->initializeMainFrame(&webFrameClient); 357 loadHttpFrame(webView->mainFrame(), "context_notifications_test.html"); 358 serveRequests(); 359 360 WebFrame* mainFrame = webView->mainFrame(); 361 WebFrame* childFrame = mainFrame->firstChild(); 362 363 ASSERT_EQ(2u, webFrameClient.createNotifications.size()); 364 EXPECT_EQ(0u, webFrameClient.releaseNotifications.size()); 365 366 ContextLifetimeTestWebFrameClient::Notification* firstCreateNotification = webFrameClient.createNotifications[0]; 367 ContextLifetimeTestWebFrameClient::Notification* secondCreateNotification = webFrameClient.createNotifications[1]; 368 369 EXPECT_EQ(mainFrame, firstCreateNotification->frame); 370 EXPECT_EQ(mainFrame->mainWorldScriptContext(), firstCreateNotification->context); 371 EXPECT_EQ(0, firstCreateNotification->worldId); 372 373 EXPECT_EQ(childFrame, secondCreateNotification->frame); 374 EXPECT_EQ(childFrame->mainWorldScriptContext(), secondCreateNotification->context); 375 EXPECT_EQ(0, secondCreateNotification->worldId); 376 377 // Close the view. We should get two release notifications that are exactly the same as the create ones, in reverse order. 378 webView->close(); 379 380 ASSERT_EQ(2u, webFrameClient.releaseNotifications.size()); 381 ContextLifetimeTestWebFrameClient::Notification* firstReleaseNotification = webFrameClient.releaseNotifications[0]; 382 ContextLifetimeTestWebFrameClient::Notification* secondReleaseNotification = webFrameClient.releaseNotifications[1]; 383 384 ASSERT_TRUE(firstCreateNotification->Equals(secondReleaseNotification)); 385 ASSERT_TRUE(secondCreateNotification->Equals(firstReleaseNotification)); 386 } 387 388 TEST_F(WebFrameTest, ContextNotificationsReload) 389 { 390 v8::HandleScope handleScope; 391 392 registerMockedHttpURLLoad("context_notifications_test.html"); 393 registerMockedHttpURLLoad("context_notifications_test_frame.html"); 394 395 ContextLifetimeTestWebFrameClient webFrameClient; 396 WebView* webView = WebView::create(0); 397 webView->settings()->setJavaScriptEnabled(true); 398 webView->initializeMainFrame(&webFrameClient); 399 loadHttpFrame(webView->mainFrame(), "context_notifications_test.html"); 400 serveRequests(); 401 402 // Refresh, we should get two release notifications and two more create notifications. 403 webView->mainFrame()->reload(false); 404 serveRequests(); 405 ASSERT_EQ(4u, webFrameClient.createNotifications.size()); 406 ASSERT_EQ(2u, webFrameClient.releaseNotifications.size()); 407 408 // The two release notifications we got should be exactly the same as the first two create notifications. 409 for (size_t i = 0; i < webFrameClient.releaseNotifications.size(); ++i) { 410 EXPECT_TRUE(webFrameClient.releaseNotifications[i]->Equals( 411 webFrameClient.createNotifications[webFrameClient.createNotifications.size() - 3 - i])); 412 } 413 414 // The last two create notifications should be for the current frames and context. 415 WebFrame* mainFrame = webView->mainFrame(); 416 WebFrame* childFrame = mainFrame->firstChild(); 417 ContextLifetimeTestWebFrameClient::Notification* firstRefreshNotification = webFrameClient.createNotifications[2]; 418 ContextLifetimeTestWebFrameClient::Notification* secondRefreshNotification = webFrameClient.createNotifications[3]; 419 420 EXPECT_EQ(mainFrame, firstRefreshNotification->frame); 421 EXPECT_EQ(mainFrame->mainWorldScriptContext(), firstRefreshNotification->context); 422 EXPECT_EQ(0, firstRefreshNotification->worldId); 423 424 EXPECT_EQ(childFrame, secondRefreshNotification->frame); 425 EXPECT_EQ(childFrame->mainWorldScriptContext(), secondRefreshNotification->context); 426 EXPECT_EQ(0, secondRefreshNotification->worldId); 427 428 webView->close(); 429 } 430 431 TEST_F(WebFrameTest, ContextNotificationsIsolatedWorlds) 432 { 433 v8::HandleScope handleScope; 434 435 registerMockedHttpURLLoad("context_notifications_test.html"); 436 registerMockedHttpURLLoad("context_notifications_test_frame.html"); 437 438 ContextLifetimeTestWebFrameClient webFrameClient; 439 WebView* webView = WebView::create(0); 440 webView->settings()->setJavaScriptEnabled(true); 441 webView->initializeMainFrame(&webFrameClient); 442 loadHttpFrame(webView->mainFrame(), "context_notifications_test.html"); 443 serveRequests(); 444 445 // Add an isolated world. 446 webFrameClient.reset(); 447 448 int isolatedWorldId = 42; 449 WebScriptSource scriptSource("hi!"); 450 int numSources = 1; 451 int extensionGroup = 0; 452 webView->mainFrame()->executeScriptInIsolatedWorld(isolatedWorldId, &scriptSource, numSources, extensionGroup); 453 454 // We should now have a new create notification. 455 ASSERT_EQ(1u, webFrameClient.createNotifications.size()); 456 ContextLifetimeTestWebFrameClient::Notification* notification = webFrameClient.createNotifications[0]; 457 ASSERT_EQ(isolatedWorldId, notification->worldId); 458 ASSERT_EQ(webView->mainFrame(), notification->frame); 459 460 // We don't have an API to enumarate isolated worlds for a frame, but we can at least assert that the context we got is *not* the main world's context. 461 ASSERT_NE(webView->mainFrame()->mainWorldScriptContext(), notification->context); 462 463 webView->close(); 464 465 // We should have gotten three release notifications (one for each of the frames, plus one for the isolated context). 466 ASSERT_EQ(3u, webFrameClient.releaseNotifications.size()); 467 468 // And one of them should be exactly the same as the create notification for the isolated context. 469 int matchCount = 0; 470 for (size_t i = 0; i < webFrameClient.releaseNotifications.size(); ++i) { 471 if (webFrameClient.releaseNotifications[i]->Equals(webFrameClient.createNotifications[0])) 472 ++matchCount; 473 } 474 EXPECT_EQ(1, matchCount); 284 475 } 285 476
Note: See TracChangeset
for help on using the changeset viewer.