Bug 1534363. Annotate nsIDOMEventListener::HandleEvent as MOZ_CAN_RUN_SCRIPT. r=smaug
authorBoris Zbarsky <bzbarsky@mit.edu>
Mon, 11 Mar 2019 21:15:40 +0000
changeset 521434 f0696ec9e92b
parent 521433 2c058bf08a51
child 521435 403a207f3e16
push id10866
push usernerli@mozilla.com
push dateTue, 12 Mar 2019 18:59:09 +0000
treeherdermozilla-beta@445c24a51727 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1534363
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1534363. Annotate nsIDOMEventListener::HandleEvent as MOZ_CAN_RUN_SCRIPT. r=smaug Differential Revision: https://phabricator.services.mozilla.com/D23035
dom/events/EventListenerManager.cpp
dom/events/EventListenerManager.h
dom/interfaces/events/nsIDOMEventListener.idl
--- a/dom/events/EventListenerManager.cpp
+++ b/dom/events/EventListenerManager.cpp
@@ -1034,17 +1034,18 @@ nsresult EventListenerManager::HandleEve
 
     // Event::currentTarget is set in EventDispatcher.
     if (listenerHolder.HasWebIDLCallback()) {
       ErrorResult rv;
       listenerHolder.GetWebIDLCallback()->HandleEvent(aCurrentTarget,
                                                       *aDOMEvent, rv);
       result = rv.StealNSResult();
     } else {
-      result = listenerHolder.GetXPCOMCallback()->HandleEvent(aDOMEvent);
+      // listenerHolder is holding a stack ref here.
+      result = MOZ_KnownLive(listenerHolder.GetXPCOMCallback())->HandleEvent(aDOMEvent);
     }
   }
 
   return result;
 }
 
 EventMessage EventListenerManager::GetLegacyEventMessage(
     EventMessage aEventMessage) const {
@@ -1228,18 +1229,20 @@ void EventListenerManager::HandleEventIn
 
             nsCOMPtr<nsPIDOMWindowInner> innerWindow =
                 WindowFromListener(listener, aItemInShadowTree);
             mozilla::dom::Event* oldWindowEvent = nullptr;
             if (innerWindow) {
               oldWindowEvent = innerWindow->SetEvent(*aDOMEvent);
             }
 
+            // MOZ_KnownLive should not be needed here, but bug 1534421 requires
+            // it for the moment.
             nsresult rv =
-                HandleEventSubType(listener, *aDOMEvent, aCurrentTarget);
+                HandleEventSubType(listener, MOZ_KnownLive(*aDOMEvent), aCurrentTarget);
 
             if (innerWindow) {
               Unused << innerWindow->SetEvent(oldWindowEvent);
             }
 
             if (NS_FAILED(rv)) {
               aEvent->mFlags.mExceptionWasRaised = true;
             }
--- a/dom/events/EventListenerManager.h
+++ b/dom/events/EventListenerManager.h
@@ -321,16 +321,21 @@ class EventListenerManager final : publi
   nsresult SetEventHandler(nsAtom* aName, const nsAString& aFunc,
                            bool aDeferCompilation, bool aPermitUntrustedEvents,
                            dom::Element* aElement);
   /**
    * Remove the current "inline" event listener for aName.
    */
   void RemoveEventHandler(nsAtom* aName);
 
+  // We only get called from the event dispatch code, which knows to be careful
+  // with what it's doing.  We could annotate ourselves as MOZ_CAN_RUN_SCRIPT,
+  // but then the event dispatch code would need a ton of MOZ_KnownLive for
+  // things that come from slightly complicated stack-lifetime data structures.
+  MOZ_CAN_RUN_SCRIPT_BOUNDARY
   void HandleEvent(nsPresContext* aPresContext, WidgetEvent* aEvent,
                    dom::Event** aDOMEvent, dom::EventTarget* aCurrentTarget,
                    nsEventStatus* aEventStatus, bool aItemInShadowTree) {
     if (mListeners.IsEmpty() || aEvent->PropagationStopped()) {
       return;
     }
 
     if (!mMayHaveCapturingListeners && !aEvent->mFlags.mInBubblingPhase) {
@@ -457,21 +462,23 @@ class EventListenerManager final : publi
 
   /**
    * Remove all event listeners from the event target this EventListenerManager
    * is for.
    */
   void RemoveAllListeners();
 
  protected:
+  MOZ_CAN_RUN_SCRIPT
   void HandleEventInternal(nsPresContext* aPresContext, WidgetEvent* aEvent,
                            dom::Event** aDOMEvent,
                            dom::EventTarget* aCurrentTarget,
                            nsEventStatus* aEventStatus, bool aItemInShadowTree);
 
+  MOZ_CAN_RUN_SCRIPT
   nsresult HandleEventSubType(Listener* aListener, dom::Event* aDOMEvent,
                               dom::EventTarget* aCurrentTarget);
 
   /**
    * If the given EventMessage has a legacy version that we support, then this
    * function returns that legacy version. Otherwise, this function simply
    * returns the passed-in EventMessage.
    */
--- a/dom/interfaces/events/nsIDOMEventListener.idl
+++ b/dom/interfaces/events/nsIDOMEventListener.idl
@@ -22,10 +22,11 @@ interface nsIDOMEventListener : nsISuppo
    * This method is called whenever an event occurs of the type for which 
    * the EventListener interface was registered.
    *
    * @param   evt The Event contains contextual information about the 
    *              event. It also contains the stopPropagation and 
    *              preventDefault methods which are used in determining the 
    *              event's flow and default action.
    */
+  [can_run_script]
   void                      handleEvent(in Event event);
 };