Bug 938341. r=smaug, a=abillings
authorMats Palmgren <matspal@gmail.com>
Mon, 18 Nov 2013 03:54:35 +0000
changeset 166526 0395ab4e357b27a5449843e4229d7994a7c7ed47
parent 166525 6753b1d2e902157bd22caedd53ccfb8cb6bb42af
child 166527 1c1fcdc50acc3964580262277a202e2cd9941cd4
push id3066
push userakeybl@mozilla.com
push dateMon, 09 Dec 2013 19:58:46 +0000
treeherdermozilla-beta@a31a0dce83aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug, abillings
bugs938341
milestone27.0a2
Bug 938341. r=smaug, a=abillings
content/events/src/nsEventListenerManager.cpp
content/events/src/nsEventListenerManager.h
--- a/content/events/src/nsEventListenerManager.cpp
+++ b/content/events/src/nsEventListenerManager.cpp
@@ -896,16 +896,17 @@ nsEventListenerManager::CompileEventHand
     NS_ENSURE_TRUE(handler, NS_ERROR_FAILURE);
   }
 
   if (handler) {
     // Bind it
     JS::Rooted<JSObject*> boundHandler(cx);
     JS::Rooted<JSObject*> scope(cx, listener->GetEventScope());
     context->BindCompiledEventHandler(mTarget, scope, handler, &boundHandler);
+    aListenerStruct = nullptr;
     if (!boundHandler) {
       listener->ForgetHandler();
     } else if (listener->EventName() == nsGkAtoms::onerror && win) {
       nsRefPtr<OnErrorEventHandlerNonNull> handlerCallback =
         new OnErrorEventHandlerNonNull(boundHandler);
       listener->SetHandler(handlerCallback);
     } else if (listener->EventName() == nsGkAtoms::onbeforeunload && win) {
       nsRefPtr<OnBeforeUnloadEventHandlerNonNull> handlerCallback =
@@ -918,46 +919,47 @@ nsEventListenerManager::CompileEventHand
     }
   }
 
   return result;
 }
 
 nsresult
 nsEventListenerManager::HandleEventSubType(nsListenerStruct* aListenerStruct,
-                                           const EventListenerHolder& aListener,
                                            nsIDOMEvent* aDOMEvent,
                                            EventTarget* aCurrentTarget,
                                            nsCxPusher* aPusher)
 {
   nsresult result = NS_OK;
+  EventListenerHolder listener(aListenerStruct->mListener);  // strong ref
 
   // If this is a script handler and we haven't yet
   // compiled the event handler itself
   if ((aListenerStruct->mListenerType == eJSEventListener) &&
       aListenerStruct->mHandlerIsString) {
     nsIJSEventListener *jslistener = aListenerStruct->GetJSListener();
     result = CompileEventHandlerInternal(aListenerStruct,
                                          jslistener->GetEventContext() !=
                                            aPusher->GetCurrentScriptContext(),
                                          nullptr);
+    aListenerStruct = nullptr;
   }
 
   if (NS_SUCCEEDED(result)) {
     if (mIsMainThreadELM) {
       nsContentUtils::EnterMicroTask();
     }
     // nsIDOMEvent::currentTarget is set in nsEventDispatcher.
-    if (aListener.HasWebIDLCallback()) {
+    if (listener.HasWebIDLCallback()) {
       ErrorResult rv;
-      aListener.GetWebIDLCallback()->
+      listener.GetWebIDLCallback()->
         HandleEvent(aCurrentTarget, *(aDOMEvent->InternalDOMEvent()), rv);
       result = rv.ErrorCode();
     } else {
-      result = aListener.GetXPCOMCallback()->HandleEvent(aDOMEvent);
+      result = listener.GetXPCOMCallback()->HandleEvent(aDOMEvent);
     }
     if (mIsMainThreadELM) {
       nsContentUtils::LeaveMicroTask();
     }
   }
 
   return result;
 }
@@ -1020,19 +1022,18 @@ nsEventListenerManager::HandleEventInter
           // a Pop(), otherwise we might end up with whatever was pushed in a
           // previous iteration.
           if (ls->mListenerType == eNativeListener) {
             aPusher->Pop();
           } else if (!aPusher->RePush(aCurrentTarget)) {
             continue;
           }
 
-          EventListenerHolder kungFuDeathGrip(ls->mListener);
-          if (NS_FAILED(HandleEventSubType(ls, ls->mListener, *aDOMEvent,
-                                           aCurrentTarget, aPusher))) {
+          if (NS_FAILED(HandleEventSubType(ls, *aDOMEvent, aCurrentTarget,
+                                           aPusher))) {
             aEvent->mFlags.mExceptionHasBeenRisen = true;
           }
         }
       }
     }
   }
 
   aEvent->currentTarget = nullptr;
--- a/content/events/src/nsEventListenerManager.h
+++ b/content/events/src/nsEventListenerManager.h
@@ -412,17 +412,16 @@ protected:
   void HandleEventInternal(nsPresContext* aPresContext,
                            mozilla::WidgetEvent* aEvent,
                            nsIDOMEvent** aDOMEvent,
                            mozilla::dom::EventTarget* aCurrentTarget,
                            nsEventStatus* aEventStatus,
                            nsCxPusher* aPusher);
 
   nsresult HandleEventSubType(nsListenerStruct* aListenerStruct,
-                              const mozilla::dom::EventListenerHolder& aListener,
                               nsIDOMEvent* aDOMEvent,
                               mozilla::dom::EventTarget* aCurrentTarget,
                               nsCxPusher* aPusher);
 
   /**
    * Compile the "inline" event listener for aListenerStruct.  The
    * body of the listener can be provided in aBody; if this is null we
    * will look for it on mTarget.