Migrate BidiRunList and BidiRun to automatic memory management
https://bugs.webkit.org/show_bug.cgi?id=156123

Reviewed by Simon Fraser.

BidiRunList, BidiRun, and BidiCharacterRun have all been doing manual
"new"s and "delete"s for years. This patch migrates those classes to
using std::unique_ptr.

No new tests because there is no behavior change.

* platform/graphics/GraphicsContext.cpp:
(WebCore::GraphicsContext::drawBidiText):
* platform/text/BidiResolver.h:
(WebCore::BidiCharacterRun::BidiCharacterRun):
(WebCore::BidiCharacterRun::next):
(WebCore::BidiCharacterRun::takeNext):
(WebCore::BidiCharacterRun::setNext):
(WebCore::Subclass>::appendRunInternal):
* platform/text/BidiRunList.h:
(WebCore::BidiRunList::BidiRunList):
(WebCore::BidiRunList::firstRun):
(WebCore::BidiRunList<Run>::appendRun):
(WebCore::BidiRunList<Run>::prependRun):
(WebCore::BidiRunList<Run>::moveRunToEnd):
(WebCore::BidiRunList<Run>::moveRunToBeginning):
(WebCore::BidiRunList<Run>::replaceRunWithRuns):
(WebCore::BidiRunList<Run>::clear):
(WebCore::BidiRunList<Run>::reverseRuns):
(WebCore::BidiRunList<Run>::clearWithoutDestroyingRuns): Deleted.
(WebCore::BidiRunList<Run>::deleteRuns): Deleted.
* rendering/BidiRun.cpp:
(WebCore::BidiRun::takeNext):
* rendering/BidiRun.h:
(WebCore::BidiRun::next):
(WebCore::BidiRun::takeNext):
* rendering/InlineIterator.h:
(WebCore::addPlaceholderRunForIsolatedInline):
* rendering/RenderBlockLineLayout.cpp:
(WebCore::createRun):
(WebCore::RenderBlockFlow::handleTrailingSpaces):
(WebCore::RenderBlockFlow::layoutRunsAndFloatsInRange):
* rendering/line/LineBreaker.cpp:
(WebCore::LineBreaker::skipLeadingWhitespace):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@198970 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 9520fe31..71af243 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,50 @@
+2016-04-01  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        Migrate BidiRunList and BidiRun to automatic memory management
+        https://bugs.webkit.org/show_bug.cgi?id=156123
+
+        Reviewed by Simon Fraser.
+
+        BidiRunList, BidiRun, and BidiCharacterRun have all been doing manual
+        "new"s and "delete"s for years. This patch migrates those classes to
+        using std::unique_ptr.
+
+        No new tests because there is no behavior change.
+
+        * platform/graphics/GraphicsContext.cpp:
+        (WebCore::GraphicsContext::drawBidiText):
+        * platform/text/BidiResolver.h:
+        (WebCore::BidiCharacterRun::BidiCharacterRun):
+        (WebCore::BidiCharacterRun::next):
+        (WebCore::BidiCharacterRun::takeNext):
+        (WebCore::BidiCharacterRun::setNext):
+        (WebCore::Subclass>::appendRunInternal):
+        * platform/text/BidiRunList.h:
+        (WebCore::BidiRunList::BidiRunList):
+        (WebCore::BidiRunList::firstRun):
+        (WebCore::BidiRunList<Run>::appendRun):
+        (WebCore::BidiRunList<Run>::prependRun):
+        (WebCore::BidiRunList<Run>::moveRunToEnd):
+        (WebCore::BidiRunList<Run>::moveRunToBeginning):
+        (WebCore::BidiRunList<Run>::replaceRunWithRuns):
+        (WebCore::BidiRunList<Run>::clear):
+        (WebCore::BidiRunList<Run>::reverseRuns):
+        (WebCore::BidiRunList<Run>::clearWithoutDestroyingRuns): Deleted.
+        (WebCore::BidiRunList<Run>::deleteRuns): Deleted.
+        * rendering/BidiRun.cpp:
+        (WebCore::BidiRun::takeNext):
+        * rendering/BidiRun.h:
+        (WebCore::BidiRun::next):
+        (WebCore::BidiRun::takeNext):
+        * rendering/InlineIterator.h:
+        (WebCore::addPlaceholderRunForIsolatedInline):
+        * rendering/RenderBlockLineLayout.cpp:
+        (WebCore::createRun):
+        (WebCore::RenderBlockFlow::handleTrailingSpaces):
+        (WebCore::RenderBlockFlow::layoutRunsAndFloatsInRange):
+        * rendering/line/LineBreaker.cpp:
+        (WebCore::LineBreaker::skipLeadingWhitespace):
+
 2016-04-01  Simon Fraser  <simon.fraser@apple.com>
 
         Backdrop Filter should repaint when changed via script
diff --git a/Source/WebCore/platform/graphics/GraphicsContext.cpp b/Source/WebCore/platform/graphics/GraphicsContext.cpp
index fbea8d7..b9085c3 100644
--- a/Source/WebCore/platform/graphics/GraphicsContext.cpp
+++ b/Source/WebCore/platform/graphics/GraphicsContext.cpp
@@ -697,7 +697,7 @@
         bidiRun = bidiRun->next();
     }
 
-    bidiRuns.deleteRuns();
+    bidiRuns.clear();
 }
 
 void GraphicsContext::drawImage(Image& image, const FloatPoint& destination, const ImagePaintingOptions& imagePaintingOptions)
diff --git a/Source/WebCore/platform/text/BidiResolver.h b/Source/WebCore/platform/text/BidiResolver.h
index 27c03a1..d37d2ff 100644
--- a/Source/WebCore/platform/text/BidiResolver.h
+++ b/Source/WebCore/platform/text/BidiResolver.h
@@ -155,10 +155,9 @@
     WTF_MAKE_FAST_ALLOCATED;
 public:
     BidiCharacterRun(int start, int stop, BidiContext* context, UCharDirection direction)
-        : m_override(context->override())
-        , m_next(0)
-        , m_start(start)
+        : m_start(start)
         , m_stop(stop)
+        , m_override(context->override())
     {
         if (direction == U_OTHER_NEUTRAL)
             direction = context->dir();
@@ -183,16 +182,19 @@
     bool reversed(bool visuallyOrdered) { return m_level % 2 && !visuallyOrdered; }
     bool dirOverride(bool visuallyOrdered) { return m_override || visuallyOrdered; }
 
-    BidiCharacterRun* next() const { return m_next; }
-    void setNext(BidiCharacterRun* next) { m_next = next; }
+    BidiCharacterRun* next() const { return m_next.get(); }
+    std::unique_ptr<BidiCharacterRun> takeNext() { return WTFMove(m_next); }
+    void setNext(std::unique_ptr<BidiCharacterRun>&& next) { m_next = WTFMove(next); }
 
-    // Do not add anything apart from bitfields until after m_next. See https://bugs.webkit.org/show_bug.cgi?id=100173
-    bool m_override : 1;
-    bool m_hasHyphen : 1; // Used by BidiRun subclass which is a layering violation but enables us to save 8 bytes per object on 64-bit.
-    unsigned char m_level;
-    BidiCharacterRun* m_next;
+private:
+    std::unique_ptr<BidiCharacterRun> m_next;
+
+public:
     int m_start;
     int m_stop;
+    unsigned char m_level;
+    bool m_override : 1;
+    bool m_hasHyphen : 1; // Used by BidiRun subclass which is a layering violation but enables us to save 8 bytes per object on 64-bit.
 };
 
 enum VisualDirectionOverride {
@@ -341,7 +343,7 @@
         }
 
         if (endOffset >= startOffset)
-            m_runs.addRun(new Run(startOffset, endOffset + 1, context(), m_direction));
+            m_runs.appendRun(std::make_unique<Run>(startOffset, endOffset + 1, context(), m_direction));
 
         m_eor.increment();
         m_sor = m_eor;
diff --git a/Source/WebCore/platform/text/BidiRunList.h b/Source/WebCore/platform/text/BidiRunList.h
index fdbcc56..66838a2 100644
--- a/Source/WebCore/platform/text/BidiRunList.h
+++ b/Source/WebCore/platform/text/BidiRunList.h
@@ -32,9 +32,8 @@
     WTF_MAKE_NONCOPYABLE(BidiRunList);
 public:
     BidiRunList()
-        : m_firstRun(0)
-        , m_lastRun(0)
-        , m_logicallyLastRun(0)
+        : m_lastRun(nullptr)
+        , m_logicallyLastRun(nullptr)
         , m_runCount(0)
     {
     }
@@ -42,18 +41,18 @@
     // FIXME: Once BidiResolver no longer owns the BidiRunList,
     // then ~BidiRunList should call deleteRuns() automatically.
 
-    Run* firstRun() const { return m_firstRun; }
+    Run* firstRun() const { return m_firstRun.get(); }
     Run* lastRun() const { return m_lastRun; }
     Run* logicallyLastRun() const { return m_logicallyLastRun; }
     unsigned runCount() const { return m_runCount; }
 
-    void addRun(Run*);
-    void prependRun(Run*);
+    void appendRun(std::unique_ptr<Run>&&);
+    void prependRun(std::unique_ptr<Run>&&);
 
     void moveRunToEnd(Run*);
     void moveRunToBeginning(Run*);
 
-    void deleteRuns();
+    void clear();
     void reverseRuns(unsigned start, unsigned end);
     void reorderRunsFromLevels();
 
@@ -62,35 +61,38 @@
     void replaceRunWithRuns(Run* toReplace, BidiRunList<Run>& newRuns);
 
 private:
-    void clearWithoutDestroyingRuns();
 
-    Run* m_firstRun;
+    // The runs form a singly-linked-list, where the links (Run::m_next) imply ownership (and are of type std::unique_ptr).
+    // The raw pointers below point into the singly-linked-list.
+    std::unique_ptr<Run> m_firstRun; // The head of the list
     Run* m_lastRun;
     Run* m_logicallyLastRun;
     unsigned m_runCount;
 };
 
 template <class Run>
-inline void BidiRunList<Run>::addRun(Run* run)
+inline void BidiRunList<Run>::appendRun(std::unique_ptr<Run>&& run)
 {
-    if (!m_firstRun)
-        m_firstRun = run;
-    else
-        m_lastRun->m_next = run;
-    m_lastRun = run;
+    if (!m_firstRun) {
+        m_firstRun = WTFMove(run);
+        m_lastRun = m_firstRun.get();
+    } else {
+        m_lastRun->setNext(WTFMove(run));
+        m_lastRun = m_lastRun->next();
+    }
     m_runCount++;
 }
 
 template <class Run>
-inline void BidiRunList<Run>::prependRun(Run* run)
+inline void BidiRunList<Run>::prependRun(std::unique_ptr<Run>&& run)
 {
-    ASSERT(!run->m_next);
+    ASSERT(!run->next());
 
     if (!m_lastRun)
-        m_lastRun = run;
+        m_lastRun = run.get();
     else
-        run->m_next = m_firstRun;
-    m_firstRun = run;
+        run->setNext(WTFMove(m_firstRun));
+    m_firstRun = WTFMove(run);
     m_runCount++;
 }
 
@@ -99,23 +101,25 @@
 {
     ASSERT(m_firstRun);
     ASSERT(m_lastRun);
-    ASSERT(run->m_next);
+    ASSERT(run->next());
 
-    Run* current = 0;
-    Run* next = m_firstRun;
-    while (next != run) {
-        current = next;
-        next = current->next();
+    Run* previous = nullptr;
+    Run* current = m_firstRun.get();
+    while (current != run) {
+        previous = current;
+        current = previous->next();
     }
 
-    if (!current)
-        m_firstRun = run->next();
-    else
-        current->m_next = run->m_next;
-
-    run->m_next = 0;
-    m_lastRun->m_next = run;
-    m_lastRun = run;
+    if (!previous) {
+        ASSERT(m_firstRun.get() == run);
+        std::unique_ptr<Run> originalFirstRun = WTFMove(m_firstRun);
+        m_firstRun = originalFirstRun->takeNext();
+        m_lastRun->setNext(WTFMove(originalFirstRun));
+    } else {
+        std::unique_ptr<Run> target = previous->takeNext();
+        previous->setNext(current->takeNext());
+        m_lastRun->setNext(WTFMove(target));
+    }
 }
 
 template <class Run>
@@ -123,21 +127,22 @@
 {
     ASSERT(m_firstRun);
     ASSERT(m_lastRun);
-    ASSERT(run != m_firstRun);
+    ASSERT(run != m_firstRun.get());
 
-    Run* current = m_firstRun;
-    Run* next = current->next();
-    while (next != run) {
-        current = next;
-        next = current->next();
+    Run* previous = m_firstRun.get();
+    Run* current = previous->next();
+    while (current != run) {
+        previous = current;
+        current = previous->next();
     }
 
-    current->m_next = run->m_next;
+    std::unique_ptr<Run> target = previous->takeNext();
+    previous->setNext(run->takeNext());
     if (run == m_lastRun)
-        m_lastRun = current;
+        m_lastRun = previous;
 
-    run->m_next = m_firstRun;
-    m_firstRun = run;
+    target->setNext(WTFMove(m_firstRun));
+    m_firstRun = WTFMove(target);
 }
 
 template <class Run>
@@ -147,53 +152,39 @@
     ASSERT(m_firstRun);
     ASSERT(toReplace);
 
-    if (m_firstRun == toReplace)
-        m_firstRun = newRuns.firstRun();
-    else {
-        // Find the run just before "toReplace" in the list of runs.
-        Run* previousRun = m_firstRun;
-        while (previousRun->next() != toReplace)
-            previousRun = previousRun->next();
-        ASSERT(previousRun);
-        previousRun->setNext(newRuns.firstRun());
-    }
+    m_runCount += newRuns.runCount() - 1; // We are adding the new runs and removing toReplace.
 
-    newRuns.lastRun()->setNext(toReplace->next());
-
-    // Fix up any of other pointers which may now be stale.
+    // Fix up any pointers which may end up stale.
     if (m_lastRun == toReplace)
         m_lastRun = newRuns.lastRun();
     if (m_logicallyLastRun == toReplace)
         m_logicallyLastRun = newRuns.logicallyLastRun();
-    m_runCount += newRuns.runCount() - 1; // We added the new runs and removed toReplace.
 
-    delete toReplace;
-    newRuns.clearWithoutDestroyingRuns();
-}
+    if (m_firstRun.get() == toReplace) {
+        newRuns.m_lastRun->setNext(m_firstRun->takeNext());
+        m_firstRun = WTFMove(newRuns.m_firstRun);
+    } else {
+        // Find the run just before "toReplace" in the list of runs.
+        Run* previousRun = m_firstRun.get();
+        while (previousRun->next() != toReplace)
+            previousRun = previousRun->next();
+        ASSERT(previousRun);
 
-template <class Run>
-void BidiRunList<Run>::clearWithoutDestroyingRuns()
-{
-    m_firstRun = 0;
-    m_lastRun = 0;
-    m_logicallyLastRun = 0;
-    m_runCount = 0;
-}
-
-template <class Run>
-void BidiRunList<Run>::deleteRuns()
-{
-    if (!m_firstRun)
-        return;
-
-    Run* curr = m_firstRun;
-    while (curr) {
-        Run* s = curr->next();
-        delete curr;
-        curr = s;
+        std::unique_ptr<Run> target = previousRun->takeNext();
+        previousRun->setNext(WTFMove(newRuns.m_firstRun));
+        newRuns.m_lastRun->setNext(target->takeNext());
     }
 
-    clearWithoutDestroyingRuns();
+    newRuns.clear();
+}
+
+template <class Run>
+void BidiRunList<Run>::clear()
+{
+    m_firstRun = nullptr;
+    m_lastRun = nullptr;
+    m_logicallyLastRun = nullptr;
+    m_runCount = 0;
 }
 
 template <class Run>
@@ -206,44 +197,35 @@
 
     // Get the item before the start of the runs to reverse and put it in
     // |beforeStart|. |curr| should point to the first run to reverse.
-    Run* curr = m_firstRun;
-    Run* beforeStart = 0;
+    Run* curr = m_firstRun.get();
+    Run* beforeStart = nullptr;
     unsigned i = 0;
-    while (i < start) {
-        i++;
+    for (; i < start; ++i) {
         beforeStart = curr;
         curr = curr->next();
     }
-
     Run* startRun = curr;
-    while (i < end) {
-        i++;
+
+    for (; i < end; ++i)
         curr = curr->next();
-    }
-    Run* endRun = curr;
-    Run* afterEnd = curr->next();
 
-    i = start;
-    curr = startRun;
-    Run* newNext = afterEnd;
-    while (i <= end) {
-        // Do the reversal.
-        Run* next = curr->next();
-        curr->m_next = newNext;
-        newNext = curr;
-        curr = next;
-        i++;
-    }
-
-    // Now hook up beforeStart and afterEnd to the startRun and endRun.
-    if (beforeStart)
-        beforeStart->m_next = endRun;
-    else
-        m_firstRun = endRun;
-
-    startRun->m_next = afterEnd;
-    if (!afterEnd)
+    if (!curr->next())
         m_lastRun = startRun;
+
+    // Standard "sliding window" of 3 pointers
+    std::unique_ptr<Run> previous = curr->takeNext();
+    std::unique_ptr<Run> current = beforeStart ? beforeStart->takeNext() : WTFMove(m_firstRun);
+    while (current) {
+        std::unique_ptr<Run> next = current->takeNext();
+        current->setNext(WTFMove(previous));
+        previous = WTFMove(current);
+        current = WTFMove(next);
+    }
+
+    if (beforeStart)
+        beforeStart->setNext(WTFMove(previous));
+    else
+        m_firstRun = WTFMove(previous);
 }
 
 } // namespace WebCore
diff --git a/Source/WebCore/rendering/BidiRun.cpp b/Source/WebCore/rendering/BidiRun.cpp
index fd3e022..c4bb47a 100644
--- a/Source/WebCore/rendering/BidiRun.cpp
+++ b/Source/WebCore/rendering/BidiRun.cpp
@@ -53,4 +53,12 @@
 #endif
 }
 
+std::unique_ptr<BidiRun> BidiRun::takeNext()
+{
+    std::unique_ptr<BidiCharacterRun> next = BidiCharacterRun::takeNext();
+    BidiCharacterRun* raw = next.release();
+    std::unique_ptr<BidiRun> result = std::unique_ptr<BidiRun>(static_cast<BidiRun*>(raw));
+    return result;
+}
+
 }
diff --git a/Source/WebCore/rendering/BidiRun.h b/Source/WebCore/rendering/BidiRun.h
index a663143..bb93895 100644
--- a/Source/WebCore/rendering/BidiRun.h
+++ b/Source/WebCore/rendering/BidiRun.h
@@ -37,7 +37,8 @@
     BidiRun(int start, int stop, RenderObject&, BidiContext*, UCharDirection);
     ~BidiRun();
 
-    BidiRun* next() { return static_cast<BidiRun*>(m_next); }
+    BidiRun* next() { return static_cast<BidiRun*>(BidiCharacterRun::next()); }
+    std::unique_ptr<BidiRun> takeNext();
     RenderObject& renderer() { return m_renderer; }
     InlineBox* box() { return m_box; }
     void setBox(InlineBox& box) { m_box = &box; }
diff --git a/Source/WebCore/rendering/InlineIterator.h b/Source/WebCore/rendering/InlineIterator.h
index 0c8fb38..68dde62 100644
--- a/Source/WebCore/rendering/InlineIterator.h
+++ b/Source/WebCore/rendering/InlineIterator.h
@@ -492,12 +492,12 @@
 // of BidiResolver which knows nothing about RenderObjects.
 static inline void addPlaceholderRunForIsolatedInline(InlineBidiResolver& resolver, RenderObject& obj, unsigned pos, RenderElement& root)
 {
-    BidiRun* isolatedRun = new BidiRun(pos, 0, obj, resolver.context(), resolver.dir());
-    resolver.runs().addRun(isolatedRun);
+    std::unique_ptr<BidiRun> isolatedRun = std::make_unique<BidiRun>(pos, 0, obj, resolver.context(), resolver.dir());
     // FIXME: isolatedRuns() could be a hash of object->run and then we could cheaply
     // ASSERT here that we didn't create multiple objects for the same inline.
     resolver.setMidpointForIsolatedRun(*isolatedRun, resolver.midpointState().currentMidpoint());
     resolver.isolatedRuns().append(BidiIsolatedRun(obj, pos, root, *isolatedRun));
+    resolver.runs().appendRun(WTFMove(isolatedRun));
 }
 
 class IsolateTracker {
diff --git a/Source/WebCore/rendering/RenderBlockLineLayout.cpp b/Source/WebCore/rendering/RenderBlockLineLayout.cpp
index 0e185241..8ed5be3 100644
--- a/Source/WebCore/rendering/RenderBlockLineLayout.cpp
+++ b/Source/WebCore/rendering/RenderBlockLineLayout.cpp
@@ -71,9 +71,9 @@
     }
 }
 
-inline BidiRun* createRun(int start, int end, RenderObject& obj, InlineBidiResolver& resolver)
+inline std::unique_ptr<BidiRun> createRun(int start, int end, RenderObject& obj, InlineBidiResolver& resolver)
 {
-    return new BidiRun(start, end, obj, resolver.context(), resolver.dir());
+    return std::make_unique<BidiRun>(start, end, obj, resolver.context(), resolver.dir());
 }
 
 void RenderBlockFlow::appendRunsForObject(BidiRunList<BidiRun>* runs, int start, int end, RenderObject& obj, InlineBidiResolver& resolver)
@@ -100,7 +100,7 @@
     } else {
         if (!haveNextMidpoint || (&obj != nextMidpoint.renderer())) {
             if (runs)
-                runs->addRun(createRun(start, end, obj, resolver));
+                runs->appendRun(createRun(start, end, obj, resolver));
             return;
         }
 
@@ -111,10 +111,10 @@
             if (nextMidpoint.refersToEndOfPreviousNode())
                 return;
             if (static_cast<int>(nextMidpoint.offset() + 1) > start && runs)
-                runs->addRun(createRun(start, nextMidpoint.offset() + 1, obj, resolver));
+                runs->appendRun(createRun(start, nextMidpoint.offset() + 1, obj, resolver));
             appendRunsForObject(runs, nextMidpoint.offset() + 1, end, obj, resolver);
         } else if (runs)
-            runs->addRun(createRun(start, end, obj, resolver));
+            runs->appendRun(createRun(start, end, obj, resolver));
     }
 }
 
@@ -1036,13 +1036,13 @@
         while (BidiContext* parent = baseContext->parent())
             baseContext = parent;
 
-        BidiRun* newTrailingRun = new BidiRun(firstSpace, trailingSpaceRun->m_stop, trailingSpaceRun->renderer(), baseContext, U_OTHER_NEUTRAL);
+        std::unique_ptr<BidiRun> newTrailingRun = std::make_unique<BidiRun>(firstSpace, trailingSpaceRun->m_stop, trailingSpaceRun->renderer(), baseContext, U_OTHER_NEUTRAL);
         trailingSpaceRun->m_stop = firstSpace;
+        trailingSpaceRun = newTrailingRun.get();
         if (direction == LTR)
-            bidiRuns.addRun(newTrailingRun);
+            bidiRuns.appendRun(WTFMove(newTrailingRun));
         else
-            bidiRuns.prependRun(newTrailingRun);
-        trailingSpaceRun = newTrailingRun;
+            bidiRuns.prependRun(WTFMove(newTrailingRun));
         return trailingSpaceRun;
     }
     if (!shouldReorder)
@@ -1321,7 +1321,7 @@
         if (resolver.position().atEnd()) {
             // FIXME: We shouldn't be creating any runs in nextLineBreak to begin with!
             // Once BidiRunList is separated from BidiResolver this will not be needed.
-            resolver.runs().deleteRuns();
+            resolver.runs().clear();
             resolver.markCurrentRunEmpty(); // FIXME: This can probably be replaced by an ASSERT (or just removed).
             layoutState.setCheckForFloatsFromLastLine(true);
             resolver.setPosition(InlineIterator(resolver.position().root(), 0, 0), 0);
@@ -1362,7 +1362,7 @@
             LayoutUnit oldLogicalHeight = logicalHeight();
             RootInlineBox* lineBox = createLineBoxesFromBidiRuns(resolver.status().context->level(), bidiRuns, end, layoutState.lineInfo(), verticalPositionCache, trailingSpaceRun, wordMeasurements);
 
-            bidiRuns.deleteRuns();
+            bidiRuns.clear();
             resolver.markCurrentRunEmpty(); // FIXME: This can probably be replaced by an ASSERT (or just removed).
 
             if (lineBox) {
diff --git a/Source/WebCore/rendering/line/LineBreaker.cpp b/Source/WebCore/rendering/line/LineBreaker.cpp
index 6eafa29..af873be 100644
--- a/Source/WebCore/rendering/line/LineBreaker.cpp
+++ b/Source/WebCore/rendering/line/LineBreaker.cpp
@@ -62,7 +62,7 @@
         if (object.isOutOfFlowPositioned()) {
             setStaticPositions(m_block, downcast<RenderBox>(object), width.shouldIndentText());
             if (object.style().isOriginalDisplayInlineType()) {
-                resolver.runs().addRun(new BidiRun(0, 1, object, resolver.context(), resolver.dir()));
+                resolver.runs().appendRun(std::make_unique<BidiRun>(0, 1, object, resolver.context(), resolver.dir()));
                 lineInfo.incrementRunsFromLeadingWhitespace();
             }
         } else if (object.isFloating())