Reintroduce PassRefPtr<Event> copy in ScopedEventQueue::dispatchEvent
authorzandobersek@gmail.com <zandobersek@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 14 Oct 2013 15:45:35 +0000 (15:45 +0000)
committerzandobersek@gmail.com <zandobersek@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 14 Oct 2013 15:45:35 +0000 (15:45 +0000)
https://bugs.webkit.org/show_bug.cgi?id=122742

Reviewed by Alexey Proskuryakov.

This is a follow-up to r157219 which introduced a workaround for the GCC's quirky behavior that
was resulting in crashes due to the PassRefPtr<Event> object passed to EventDispatcher::dispatchEvent
being copied and nullified first before retrieving the EventTarget of the Event object wrapped in that
PassRefPtr.

The implementation is now adjusted to first retrieve the pointer to the Event's EventTarget and store
it in a local variable. That variable is then passed as the first parameter to EventDispatcher::dispatchEvent,
and the PassRefPtr<Event> passed directly as the second parameter. Previously the pointer of that PassRefPtr
object was passed in, with a new PassRefPtr being created which would increase the reference count of the
ref-counted object. Passing in the original PassRefPtr avoids the unnecessary reference count increase by creating
a copy. That still nullifies the original PassRefPtr, but that's not a problem anymore.

* dom/ScopedEventQueue.cpp:
(WebCore::ScopedEventQueue::dispatchEvent):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@157401 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/dom/ScopedEventQueue.cpp

index 345e766..3d841a2 100644 (file)
@@ -1,3 +1,25 @@
+2013-10-14  Zan Dobersek  <zdobersek@igalia.com>
+
+        Reintroduce PassRefPtr<Event> copy in ScopedEventQueue::dispatchEvent
+        https://bugs.webkit.org/show_bug.cgi?id=122742
+
+        Reviewed by Alexey Proskuryakov.
+
+        This is a follow-up to r157219 which introduced a workaround for the GCC's quirky behavior that
+        was resulting in crashes due to the PassRefPtr<Event> object passed to EventDispatcher::dispatchEvent
+        being copied and nullified first before retrieving the EventTarget of the Event object wrapped in that
+        PassRefPtr.
+
+        The implementation is now adjusted to first retrieve the pointer to the Event's EventTarget and store
+        it in a local variable. That variable is then passed as the first parameter to EventDispatcher::dispatchEvent,
+        and the PassRefPtr<Event> passed directly as the second parameter. Previously the pointer of that PassRefPtr
+        object was passed in, with a new PassRefPtr being created which would increase the reference count of the
+        ref-counted object. Passing in the original PassRefPtr avoids the unnecessary reference count increase by creating
+        a copy. That still nullifies the original PassRefPtr, but that's not a problem anymore.
+
+        * dom/ScopedEventQueue.cpp:
+        (WebCore::ScopedEventQueue::dispatchEvent):
+
 2013-10-14  Bear Travis  <betravis@adobe.com>
 
         [CSS Shapes] Shape-Margin should be animatable
index e3dadf1..0c0fa29 100644 (file)
@@ -79,10 +79,11 @@ void ScopedEventQueue::dispatchAllEvents()
 void ScopedEventQueue::dispatchEvent(PassRefPtr<Event> event) const
 {
     ASSERT(event->target());
-    // Passing a naked Event pointer instead of the PassRefPtr<Event> prevents the PassRefPtr copy
-    // that nullifies the original PassRefPtr. This prevents crashes on GCC-compiled code since
-    // GCC creates the copy first, which leaves the event->target() call to be made on a null pointer.
-    EventDispatcher::dispatchEvent(event->target()->toNode(), event.get());
+    // Passing the PassRefPtr<Event> object into the method call creates a new copy and also nullifies
+    // the original object, which is causing crashes in GCC-compiled code that only after that goes on
+    // to retrieve the Event's target, calling Event::target() on the now-null PassRefPtr<Event> object.
+    Node* node = event->target()->toNode();
+    EventDispatcher::dispatchEvent(node, event);
 }
 
 ScopedEventQueue* ScopedEventQueue::instance()