Unreviewed, reverting r259282.
https://bugs.webkit.org/show_bug.cgi?id=209860

Caused memory corruption (Requested by ap on #webkit).

Reverted changeset:

"Scroll latching state is not a stack"
https://bugs.webkit.org/show_bug.cgi?id=209790
https://trac.webkit.org/changeset/259282

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@259347 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 8a526b9..0d1f414 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,16 @@
+2020-04-01  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, reverting r259282.
+        https://bugs.webkit.org/show_bug.cgi?id=209860
+
+        Caused memory corruption (Requested by ap on #webkit).
+
+        Reverted changeset:
+
+        "Scroll latching state is not a stack"
+        https://bugs.webkit.org/show_bug.cgi?id=209790
+        https://trac.webkit.org/changeset/259282
+
 2020-04-01  youenn fablet  <youenn@apple.com>
 
         Bump libwebrtc to M82
diff --git a/Source/WebCore/page/Page.cpp b/Source/WebCore/page/Page.cpp
index fcdeeb8..9f0a406 100644
--- a/Source/WebCore/page/Page.cpp
+++ b/Source/WebCore/page/Page.cpp
@@ -2943,26 +2943,41 @@
 #if ENABLE(WHEEL_EVENT_LATCHING)
 ScrollLatchingState* Page::latchingState()
 {
-    return m_latchingState.get();
+    if (m_latchingState.isEmpty())
+        return nullptr;
+
+    return &m_latchingState.last();
 }
 
-void Page::setLatchingState(std::unique_ptr<ScrollLatchingState>&& state)
+void Page::pushNewLatchingState(ScrollLatchingState&& state)
 {
-    m_latchingState = WTFMove(state);
+    m_latchingState.append(WTFMove(state));
 }
 
 void Page::resetLatchingState()
 {
-    m_latchingState = nullptr;
+    m_latchingState.clear();
+}
+
+void Page::popLatchingState()
+{
+    m_latchingState.removeLast();
+    LOG_WITH_STREAM(ScrollLatching, stream << "Page::popLatchingState() - new state " << m_latchingState);
 }
 
 void Page::removeLatchingStateForTarget(Element& targetNode)
 {
-    if (!m_latchingState)
+    if (m_latchingState.isEmpty())
         return;
 
-    if (m_latchingState->wheelEventElement() == &targetNode)
-        m_latchingState = nullptr;
+    m_latchingState.removeAllMatching([&targetNode] (ScrollLatchingState& state) {
+        auto* wheelElement = state.wheelEventElement();
+        if (!wheelElement)
+            return false;
+
+        return targetNode.isEqualNode(wheelElement);
+    });
+    LOG_WITH_STREAM(ScrollLatching, stream << "Page::removeLatchingStateForTarget() - new state " << m_latchingState);
 }
 #endif // ENABLE(WHEEL_EVENT_LATCHING)
 
diff --git a/Source/WebCore/page/Page.h b/Source/WebCore/page/Page.h
index 93cf9e6..e2484f6 100644
--- a/Source/WebCore/page/Page.h
+++ b/Source/WebCore/page/Page.h
@@ -430,7 +430,9 @@
 
 #if ENABLE(WHEEL_EVENT_LATCHING)
     ScrollLatchingState* latchingState();
-    void setLatchingState(std::unique_ptr<ScrollLatchingState>&&);
+    const Vector<ScrollLatchingState>& latchingStateStack() const { return m_latchingState; }
+    void pushNewLatchingState(ScrollLatchingState&&);
+    void popLatchingState();
     void resetLatchingState();
     void removeLatchingStateForTarget(Element&);
 #endif // ENABLE(WHEEL_EVENT_LATCHING)
@@ -978,7 +980,7 @@
 
     std::unique_ptr<PerformanceLogging> m_performanceLogging;
 #if ENABLE(WHEEL_EVENT_LATCHING)
-    std::unique_ptr<ScrollLatchingState> m_latchingState;
+    Vector<ScrollLatchingState> m_latchingState;
 #endif
 #if PLATFORM(MAC) && (ENABLE(SERVICE_CONTROLS) || ENABLE(TELEPHONE_NUMBER_DETECTION))
     std::unique_ptr<ServicesOverlayController> m_servicesOverlayController;
diff --git a/Source/WebCore/page/mac/EventHandlerMac.mm b/Source/WebCore/page/mac/EventHandlerMac.mm
index ef5e3ce..6442701 100644
--- a/Source/WebCore/page/mac/EventHandlerMac.mm
+++ b/Source/WebCore/page/mac/EventHandlerMac.mm
@@ -983,23 +983,23 @@
         if (scrollableContainer && scrollableArea) {
             bool startingAtScrollLimit = scrolledToEdgeInDominantDirection(*scrollableContainer, *scrollableArea.get(), wheelEvent.deltaX(), wheelEvent.deltaY());
             if (!startingAtScrollLimit) {
-                auto latchingState = WTF::makeUnique<ScrollLatchingState>();
-                latchingState->setStartedGestureAtScrollLimit(false);
-                latchingState->setWheelEventElement(wheelEventTarget.get());
-                latchingState->setFrame(&m_frame);
-                latchingState->setScrollableContainer(scrollableContainer.get());
-                latchingState->setWidgetIsLatched(result.isOverWidget());
-                page->setLatchingState(WTFMove(latchingState));
+                ScrollLatchingState latchingState;
+                latchingState.setStartedGestureAtScrollLimit(false);
+                latchingState.setWheelEventElement(wheelEventTarget.get());
+                latchingState.setFrame(&m_frame);
+                latchingState.setScrollableContainer(scrollableContainer.get());
+                latchingState.setWidgetIsLatched(result.isOverWidget());
+                page->pushNewLatchingState(WTFMove(latchingState));
 
                 page->wheelEventDeltaFilter()->beginFilteringDeltas();
                 isOverWidget = result.isOverWidget();
             }
 
-            LOG_WITH_STREAM(ScrollLatching, stream << "EventHandler::platformPrepareForWheelEvents() - considering latching for " << wheelEvent << ", at scroll limit " << startingAtScrollLimit << ", latching state " << ValueOrNull(page->latchingState()));
+            LOG_WITH_STREAM(ScrollLatching, stream << "EventHandler::platformPrepareForWheelEvents() - considering latching for " << wheelEvent << ", at scroll limit " << startingAtScrollLimit << ", latching state " << page->latchingStateStack());
         }
     } else if (wheelEvent.shouldResetLatching()) {
         clearLatchedState();
-        LOG_WITH_STREAM(ScrollLatching, stream << "EventHandler::platformPrepareForWheelEvents() - reset latching for event " << wheelEvent << " latching state " << ValueOrNull(page->latchingState()));
+        LOG_WITH_STREAM(ScrollLatching, stream << "EventHandler::platformPrepareForWheelEvents() - reset latching for event " << wheelEvent << " latching state " << page->latchingStateStack());
     }
 
     if (!wheelEvent.shouldResetLatching() && latchingState && latchingState->wheelEventElement()) {
diff --git a/Source/WebCore/page/scrolling/ScrollLatchingState.h b/Source/WebCore/page/scrolling/ScrollLatchingState.h
index 468d48c..f94c3cb 100644
--- a/Source/WebCore/page/scrolling/ScrollLatchingState.h
+++ b/Source/WebCore/page/scrolling/ScrollLatchingState.h
@@ -38,7 +38,6 @@
 class Frame;
 
 class ScrollLatchingState final {
-    WTF_MAKE_FAST_ALLOCATED;
 public:
     ScrollLatchingState();
     ~ScrollLatchingState();