Changeset 95560 in webkit
- Timestamp:
- Sep 20, 2011 11:58:04 AM (13 years ago)
- Location:
- trunk/Source
- Files:
-
- 2 added
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r95559 r95560 1 2011-09-20 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-19 Oliver Hunt <oliver@apple.com> 2 21 -
trunk/Source/WebCore/bindings/v8/V8DOMWindowShell.cpp
r95483 r95560 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
r95483 r95560 50 50 51 51 V8IsolatedContext::V8IsolatedContext(V8Proxy* proxy, int extensionGroup, int worldId) 52 : m_world(IsolatedWorld::create(worldId)) 52 : m_world(IsolatedWorld::create(worldId)), 53 m_frame(proxy->frame()) 53 54 { 54 55 v8::HandleScope scope; … … 65 66 V8DOMWindowShell::installHiddenObjectPrototype(m_context->get()); 66 67 // FIXME: This will go away once we have a windowShell for the isolated world. 67 proxy->windowShell()->installDOMWindow(m_context->get(), proxy->frame()->domWindow());68 proxy->windowShell()->installDOMWindow(m_context->get(), m_frame->domWindow()); 68 69 69 70 // Using the default security token means that the canAccess is always … … 75 76 m_context->get()->UseDefaultSecurityToken(); 76 77 77 proxy->frame()->loader()->client()->didCreateIsolatedScriptContext(this);78 m_frame->loader()->client()->didCreateScriptContext(context(), m_world->id()); 78 79 } 79 80 80 81 void V8IsolatedContext::destroy() 81 82 { 83 m_frame->loader()->client()->willReleaseScriptContext(context(), m_world->id()); 82 84 m_context->get().MakeWeak(this, &contextWeakReferenceCallback); 85 m_frame = 0; 83 86 } 84 87 -
trunk/Source/WebCore/bindings/v8/V8IsolatedContext.h
r95483 r95560 115 115 116 116 RefPtr<SecurityOrigin> m_securityOrigin; 117 118 Frame* m_frame; 117 119 }; 118 120 -
trunk/Source/WebCore/loader/EmptyClients.h
r95483 r95560 48 48 49 49 #if USE(V8) 50 #include "V8IsolatedContext.h"50 #include <v8.h> 51 51 #endif 52 52 … … 395 395 396 396 #if USE(V8) 397 virtual void didCreateScriptContextForFrame() { } 398 virtual void didDestroyScriptContextForFrame() { } 399 virtual void didCreateIsolatedScriptContext(V8IsolatedContext*) { } 397 virtual void didCreateScriptContext(v8::Handle<v8::Context>, int worldId) { } 398 virtual void willReleaseScriptContext(v8::Handle<v8::Context>, int worldId) { } 400 399 virtual bool allowScriptExtension(const String& extensionName, int extensionGroup) { return false; } 401 400 #endif -
trunk/Source/WebCore/loader/FrameLoaderClient.h
r95483 r95560 51 51 #endif 52 52 53 #if USE(V8) 54 namespace v8 { 55 class Context; 56 template<class T> class Handle; 57 } 58 #endif 59 53 60 namespace WebCore { 54 61 … … 87 94 class StringWithDirection; 88 95 class SubstituteData; 89 #if USE(V8)90 class V8IsolatedContext;91 #endif92 96 class Widget; 93 97 … … 271 275 272 276 #if USE(V8) 273 virtual void didCreateScriptContextForFrame() = 0; 274 virtual void didDestroyScriptContextForFrame() = 0; 275 virtual void didCreateIsolatedScriptContext(V8IsolatedContext*) = 0; 277 virtual void didCreateScriptContext(v8::Handle<v8::Context>, int worldId) = 0; 278 virtual void willReleaseScriptContext(v8::Handle<v8::Context>, int worldId) = 0; 276 279 virtual bool allowScriptExtension(const String& extensionName, int extensionGroup) = 0; 277 280 #endif -
trunk/Source/WebKit/chromium/ChangeLog
r95514 r95560 1 2011-09-20 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 * tests/WebFrameTest.cpp: 17 (WebKit::TEST_F): 18 (WebKit::ContextLifetimeTestWebFrameClient::Notification::Notification): 19 (WebKit::ContextLifetimeTestWebFrameClient::Notification::~Notification): 20 (WebKit::ContextLifetimeTestWebFrameClient::Notification::Equals): 21 (WebKit::ContextLifetimeTestWebFrameClient::~ContextLifetimeTestWebFrameClient): 22 (WebKit::ContextLifetimeTestWebFrameClient::reset): 23 (WebKit::ContextLifetimeTestWebFrameClient::didCreateScriptContext): 24 (WebKit::ContextLifetimeTestWebFrameClient::willReleaseScriptContext): 25 * tests/data/context_notifications_test.html: Added. 26 * tests/data/context_notifications_test_frame.html: Added. 27 1 28 2011-09-19 Geoffrey Garen <ggaren@apple.com> 2 29 -
trunk/Source/WebKit/chromium/public/WebFrameClient.h
r95483 r95560 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
r95483 r95560 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 // FIXME: Remove these once Chromium is updated to use the new version of didCreateScriptContext(). 148 if (worldId) 149 m_webFrame->client()->didCreateIsolatedScriptContext(m_webFrame, worldId, context); 150 else 151 m_webFrame->client()->didCreateScriptContext(m_webFrame); 152 153 m_webFrame->client()->didCreateScriptContext(m_webFrame, context, worldId); 154 } 155 } 156 157 void FrameLoaderClientImpl::willReleaseScriptContext(v8::Handle<v8::Context> context, int worldId) 158 { 159 if (m_webFrame->client()) { 160 // FIXME: Remove this once Chromium is updated to use willReleaseScriptContext(). 161 if (!worldId) 162 m_webFrame->client()->didDestroyScriptContext(m_webFrame); 163 164 m_webFrame->client()->willReleaseScriptContext(m_webFrame, context, worldId); 165 } 160 166 } 161 167 #endif -
trunk/Source/WebKit/chromium/src/FrameLoaderClientImpl.h
r95483 r95560 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
r95483 r95560 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) , 295 context(v8::Persistent<v8::Context>::New(context)), 296 worldId(worldId) 297 { 298 } 299 300 ~Notification() 301 { 302 context.Dispose(); 303 } 304 305 bool Equals(Notification* other) 306 { 307 return other && frame == other->frame && context == other->context && worldId == other->worldId; 308 } 309 310 WebFrame* frame; 311 v8::Persistent<v8::Context> context; 312 int worldId; 313 }; 314 315 ~ContextLifetimeTestWebFrameClient() 316 { 317 reset(); 318 } 319 320 void reset() 321 { 322 for (size_t i = 0; i < createNotifications.size(); ++i) 323 delete createNotifications[i]; 324 325 for (size_t i = 0; i < releaseNotifications.size(); ++i) 326 delete releaseNotifications[i]; 327 328 createNotifications.clear(); 329 releaseNotifications.clear(); 330 } 331 332 std::vector<Notification*> createNotifications; 333 std::vector<Notification*> releaseNotifications; 334 335 private: 336 virtual void didCreateScriptContext(WebFrame* frame, v8::Handle<v8::Context> context, int worldId) 337 { 338 createNotifications.push_back(new Notification(frame, context, worldId)); 339 } 340 341 virtual void willReleaseScriptContext(WebFrame* frame, v8::Handle<v8::Context> context, int worldId) 342 { 343 releaseNotifications.push_back(new Notification(frame, context, worldId)); 344 } 345 }; 346 347 TEST_F(WebFrameTest, ContextNotificationsLoadUnload) 348 { 349 v8::HandleScope handleScope; 350 351 registerMockedHttpURLLoad("context_notifications_test.html"); 352 registerMockedHttpURLLoad("context_notifications_test_frame.html"); 353 354 // Load a frame with an iframe, make sure we get the right create notifications. 355 ContextLifetimeTestWebFrameClient webFrameClient; 356 WebView* webView = WebView::create(0); 357 webView->settings()->setJavaScriptEnabled(true); 358 webView->initializeMainFrame(&webFrameClient); 359 loadHttpFrame(webView->mainFrame(), "context_notifications_test.html"); 360 serveRequests(); 361 362 WebFrame* mainFrame = webView->mainFrame(); 363 WebFrame* childFrame = mainFrame->firstChild(); 364 365 ASSERT_EQ(2u, webFrameClient.createNotifications.size()); 366 EXPECT_EQ(0u, webFrameClient.releaseNotifications.size()); 367 368 ContextLifetimeTestWebFrameClient::Notification* firstCreateNotification = webFrameClient.createNotifications[0]; 369 ContextLifetimeTestWebFrameClient::Notification* secondCreateNotification = webFrameClient.createNotifications[1]; 370 371 EXPECT_EQ(mainFrame, firstCreateNotification->frame); 372 EXPECT_EQ(mainFrame->mainWorldScriptContext(), firstCreateNotification->context); 373 EXPECT_EQ(0, firstCreateNotification->worldId); 374 375 EXPECT_EQ(childFrame, secondCreateNotification->frame); 376 EXPECT_EQ(childFrame->mainWorldScriptContext(), secondCreateNotification->context); 377 EXPECT_EQ(0, secondCreateNotification->worldId); 378 379 // Close the view. We should get two release notifications that are exactly the same as the create ones, in reverse order. 380 webView->close(); 381 382 ASSERT_EQ(2u, webFrameClient.releaseNotifications.size()); 383 ContextLifetimeTestWebFrameClient::Notification* firstReleaseNotification = webFrameClient.releaseNotifications[0]; 384 ContextLifetimeTestWebFrameClient::Notification* secondReleaseNotification = webFrameClient.releaseNotifications[1]; 385 386 ASSERT_TRUE(firstCreateNotification->Equals(secondReleaseNotification)); 387 ASSERT_TRUE(secondCreateNotification->Equals(firstReleaseNotification)); 388 } 389 390 TEST_F(WebFrameTest, ContextNotificationsReload) 391 { 392 v8::HandleScope handleScope; 393 394 registerMockedHttpURLLoad("context_notifications_test.html"); 395 registerMockedHttpURLLoad("context_notifications_test_frame.html"); 396 397 ContextLifetimeTestWebFrameClient webFrameClient; 398 WebView* webView = WebView::create(0); 399 webView->settings()->setJavaScriptEnabled(true); 400 webView->initializeMainFrame(&webFrameClient); 401 loadHttpFrame(webView->mainFrame(), "context_notifications_test.html"); 402 serveRequests(); 403 404 // Refresh, we should get two release notifications and two more create notifications. 405 webView->mainFrame()->reload(false); 406 serveRequests(); 407 ASSERT_EQ(4u, webFrameClient.createNotifications.size()); 408 ASSERT_EQ(2u, webFrameClient.releaseNotifications.size()); 409 410 // The two release notifications we got should be exactly the same as the first two create notifications. 411 for (size_t i = 0; i < webFrameClient.releaseNotifications.size(); ++i) { 412 EXPECT_TRUE(webFrameClient.releaseNotifications[i]->Equals( 413 webFrameClient.createNotifications[webFrameClient.createNotifications.size() - 3 - i])); 414 } 415 416 // The last two create notifications should be for the current frames and context. 417 WebFrame* mainFrame = webView->mainFrame(); 418 WebFrame* childFrame = mainFrame->firstChild(); 419 ContextLifetimeTestWebFrameClient::Notification* firstRefreshNotification = webFrameClient.createNotifications[2]; 420 ContextLifetimeTestWebFrameClient::Notification* secondRefreshNotification = webFrameClient.createNotifications[3]; 421 422 EXPECT_EQ(mainFrame, firstRefreshNotification->frame); 423 EXPECT_EQ(mainFrame->mainWorldScriptContext(), firstRefreshNotification->context); 424 EXPECT_EQ(0, firstRefreshNotification->worldId); 425 426 EXPECT_EQ(childFrame, secondRefreshNotification->frame); 427 EXPECT_EQ(childFrame->mainWorldScriptContext(), secondRefreshNotification->context); 428 EXPECT_EQ(0, secondRefreshNotification->worldId); 429 430 webView->close(); 431 } 432 433 TEST_F(WebFrameTest, ContextNotificationsIsolatedWorlds) 434 { 435 v8::HandleScope handleScope; 436 437 registerMockedHttpURLLoad("context_notifications_test.html"); 438 registerMockedHttpURLLoad("context_notifications_test_frame.html"); 439 440 ContextLifetimeTestWebFrameClient webFrameClient; 441 WebView* webView = WebView::create(0); 442 webView->settings()->setJavaScriptEnabled(true); 443 webView->initializeMainFrame(&webFrameClient); 444 loadHttpFrame(webView->mainFrame(), "context_notifications_test.html"); 445 serveRequests(); 446 447 // Add an isolated world. 448 webFrameClient.reset(); 449 450 int isolatedWorldId = 42; 451 WebScriptSource scriptSource("hi!"); 452 int numSources = 1; 453 int extensionGroup = 0; 454 webView->mainFrame()->executeScriptInIsolatedWorld(isolatedWorldId, &scriptSource, numSources, extensionGroup); 455 456 // We should now have a new create notification. 457 ASSERT_EQ(1u, webFrameClient.createNotifications.size()); 458 ContextLifetimeTestWebFrameClient::Notification* notification = webFrameClient.createNotifications[0]; 459 ASSERT_EQ(isolatedWorldId, notification->worldId); 460 ASSERT_EQ(webView->mainFrame(), notification->frame); 461 462 // 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. 463 ASSERT_NE(webView->mainFrame()->mainWorldScriptContext(), notification->context); 464 465 webView->close(); 466 467 // We should have gotten three release notifications (one for each of the frames, plus one for the isolated context). 468 ASSERT_EQ(3u, webFrameClient.releaseNotifications.size()); 469 470 // And one of them should be exactly the same as the create notification for the isolated context. 471 int matchCount = 0; 472 for (size_t i = 0; i < webFrameClient.releaseNotifications.size(); ++i) { 473 if (webFrameClient.releaseNotifications[i]->Equals(webFrameClient.createNotifications[0])) 474 ++matchCount; 475 } 476 EXPECT_EQ(1, matchCount); 284 477 } 285 478
Note: See TracChangeset
for help on using the changeset viewer.