<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[189832] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/189832">189832</a></dd>
<dt>Author</dt> <dd>mmaxfield@apple.com</dd>
<dt>Date</dt> <dd>2015-09-15 17:30:38 -0700 (Tue, 15 Sep 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Nested isolates can cause an infinite loop when laying out bidi runs
https://bugs.webkit.org/show_bug.cgi?id=149153

Reviewed by David Hyatt.

Source/WebCore:

When traversing bidi runs, we might encounter a run which is supposed to be isolated. In this
situation, we will append a placeholder run in the run list, and remember a pointer to these
isolated runs inside BidiResolver. Then, once we're done traversing the bidi runs, we return
to the isolated runs and handle them separately (and replace the placeholder with the result).

However, due to the fact that our BidiRuns start at leaf nodes, we have to keep track of which
local root of the render tree we were inspecting (to ensure that we visit the same node
multiple times if there are nested isolate spans). We were not correctly keeping track of this
local root, which was leading us to consider the same root multiple times, thereby leading to
an infinite loop.

The solution is simply to keep root information alongside the isolated run information inside
BidiResolver. However, BidiResolver is inside platform/, which means that this new type should
be a template argument, just like how BidiRun itself is a template argument.

This new type, BidiIsolatedRun, holds all the information that our isolate-revisiting logic
needs inside constructBidiRunsForSegment(). It also holds a reference to the placeholder run
which we will replace.

Test: fast/text/international/unicode-bidi-isolate-nested-crash.html

* platform/graphics/GraphicsContext.cpp:
(WebCore::GraphicsContext::drawBidiText): BidiIsolatedRun template argument is unused, so pass
in Void.
* platform/text/BidiResolver.h: Add template argument.
(WebCore::BidiResolver::isolatedRuns):
(WebCore::IsolatedRun&gt;::~BidiResolver):
(WebCore::IsolatedRun&gt;::appendRun):
(WebCore::IsolatedRun&gt;::embed):
(WebCore::IsolatedRun&gt;::checkDirectionInLowerRaiseEmbeddingLevel):
(WebCore::IsolatedRun&gt;::lowerExplicitEmbeddingLevel):
(WebCore::IsolatedRun&gt;::raiseExplicitEmbeddingLevel):
(WebCore::IsolatedRun&gt;::commitExplicitEmbedding):
(WebCore::IsolatedRun&gt;::updateStatusLastFromCurrentDirection):
(WebCore::IsolatedRun&gt;::reorderRunsFromLevels):
(WebCore::IsolatedRun&gt;::createBidiRunsForLine):
(WebCore::IsolatedRun&gt;::setMidpointForIsolatedRun): Use references instead of pointers.
(WebCore::IsolatedRun&gt;::midpointForIsolatedRun): Ditto.
(WebCore::Run&gt;::~BidiResolver): Deleted.
(WebCore::Run&gt;::appendRun): Deleted.
(WebCore::Run&gt;::embed): Deleted.
(WebCore::Run&gt;::checkDirectionInLowerRaiseEmbeddingLevel): Deleted.
(WebCore::Run&gt;::lowerExplicitEmbeddingLevel): Deleted.
(WebCore::Run&gt;::raiseExplicitEmbeddingLevel): Deleted.
(WebCore::Run&gt;::commitExplicitEmbedding): Deleted.
(WebCore::Run&gt;::updateStatusLastFromCurrentDirection): Deleted.
(WebCore::Run&gt;::reorderRunsFromLevels): Deleted.
(WebCore::Run&gt;::createBidiRunsForLine): Deleted.
(WebCore::Run&gt;::setMidpointForIsolatedRun): Deleted.
(WebCore::Run&gt;::midpointForIsolatedRun): Deleted.
* rendering/InlineIterator.h:
(WebCore::BidiIsolatedRun::BidiIsolatedRun): New type.
(WebCore::addPlaceholderRunForIsolatedInline): Create new type, and include local root
information.
(WebCore::IsolateTracker::addFakeRunIfNecessary): Include local root information.
(WebCore::InlineBidiResolver::appendRun): Ditto.
* rendering/RenderBlockLineLayout.cpp: Update for new BidiIsolatedRun type.
(WebCore::setUpResolverToResumeInIsolate):
(WebCore::constructBidiRunsForSegment):
* rendering/line/TrailingObjects.h:

LayoutTests:

* fast/text/international/unicode-bidi-isolate-nested-crash-expected.html: Added.
* fast/text/international/unicode-bidi-isolate-nested-crash.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformtextBidiResolverh">trunk/Source/WebCore/platform/text/BidiResolver.h</a></li>
<li><a href="#trunkSourceWebCorerenderingInlineIteratorh">trunk/Source/WebCore/rendering/InlineIterator.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderBlockLineLayoutcpp">trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderinglineTrailingObjectsh">trunk/Source/WebCore/rendering/line/TrailingObjects.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfasttextinternationalunicodebidiisolatenestedcrashexpectedhtml">trunk/LayoutTests/fast/text/international/unicode-bidi-isolate-nested-crash-expected.html</a></li>
<li><a href="#trunkLayoutTestsfasttextinternationalunicodebidiisolatenestedcrashhtml">trunk/LayoutTests/fast/text/international/unicode-bidi-isolate-nested-crash.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (189831 => 189832)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-09-16 00:19:29 UTC (rev 189831)
+++ trunk/LayoutTests/ChangeLog        2015-09-16 00:30:38 UTC (rev 189832)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2015-09-15  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
+
+        Nested isolates can cause an infinite loop when laying out bidi runs
+        https://bugs.webkit.org/show_bug.cgi?id=149153
+
+        Reviewed by David Hyatt.
+
+        * fast/text/international/unicode-bidi-isolate-nested-crash-expected.html: Added.
+        * fast/text/international/unicode-bidi-isolate-nested-crash.html: Added.
+
</ins><span class="cx"> 2015-09-15  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Element.getAttributeNS() should return null if the attribute does not exist
</span></span></pre></div>
<a id="trunkLayoutTestsfasttextinternationalunicodebidiisolatenestedcrashexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/text/international/unicode-bidi-isolate-nested-crash-expected.html (0 => 189832)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/text/international/unicode-bidi-isolate-nested-crash-expected.html                                (rev 0)
+++ trunk/LayoutTests/fast/text/international/unicode-bidi-isolate-nested-crash-expected.html        2015-09-16 00:30:38 UTC (rev 189832)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;span&gt;a b&lt;/span&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfasttextinternationalunicodebidiisolatenestedcrashhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/text/international/unicode-bidi-isolate-nested-crash.html (0 => 189832)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/text/international/unicode-bidi-isolate-nested-crash.html                                (rev 0)
+++ trunk/LayoutTests/fast/text/international/unicode-bidi-isolate-nested-crash.html        2015-09-16 00:30:38 UTC (rev 189832)
</span><span class="lines">@@ -0,0 +1,13 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;style&gt;
+.isolate {
+    unicode-bidi: -webkit-isolate;
+    unicode-bidi: isolate;
+}
+&lt;/style&gt;
+&lt;span class=&quot;isolate&quot;&gt;
+    &lt;span class=&quot;isolate&quot;&gt;a&lt;/span&gt;
+    &lt;span class=&quot;isolate&quot;&gt;
+        &lt;span class=&quot;isolate&quot;&gt;b&lt;/span&gt;
+    &lt;/span&gt;
+&lt;/span&gt;
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (189831 => 189832)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-09-16 00:19:29 UTC (rev 189831)
+++ trunk/Source/WebCore/ChangeLog        2015-09-16 00:30:38 UTC (rev 189832)
</span><span class="lines">@@ -1,3 +1,71 @@
</span><ins>+2015-09-15  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
+
+        Nested isolates can cause an infinite loop when laying out bidi runs
+        https://bugs.webkit.org/show_bug.cgi?id=149153
+
+        Reviewed by David Hyatt.
+
+        When traversing bidi runs, we might encounter a run which is supposed to be isolated. In this
+        situation, we will append a placeholder run in the run list, and remember a pointer to these
+        isolated runs inside BidiResolver. Then, once we're done traversing the bidi runs, we return
+        to the isolated runs and handle them separately (and replace the placeholder with the result).
+
+        However, due to the fact that our BidiRuns start at leaf nodes, we have to keep track of which
+        local root of the render tree we were inspecting (to ensure that we visit the same node
+        multiple times if there are nested isolate spans). We were not correctly keeping track of this
+        local root, which was leading us to consider the same root multiple times, thereby leading to
+        an infinite loop.
+
+        The solution is simply to keep root information alongside the isolated run information inside
+        BidiResolver. However, BidiResolver is inside platform/, which means that this new type should
+        be a template argument, just like how BidiRun itself is a template argument.
+
+        This new type, BidiIsolatedRun, holds all the information that our isolate-revisiting logic
+        needs inside constructBidiRunsForSegment(). It also holds a reference to the placeholder run
+        which we will replace.
+
+        Test: fast/text/international/unicode-bidi-isolate-nested-crash.html
+
+        * platform/graphics/GraphicsContext.cpp:
+        (WebCore::GraphicsContext::drawBidiText): BidiIsolatedRun template argument is unused, so pass
+        in Void.
+        * platform/text/BidiResolver.h: Add template argument.
+        (WebCore::BidiResolver::isolatedRuns):
+        (WebCore::IsolatedRun&gt;::~BidiResolver):
+        (WebCore::IsolatedRun&gt;::appendRun):
+        (WebCore::IsolatedRun&gt;::embed):
+        (WebCore::IsolatedRun&gt;::checkDirectionInLowerRaiseEmbeddingLevel):
+        (WebCore::IsolatedRun&gt;::lowerExplicitEmbeddingLevel):
+        (WebCore::IsolatedRun&gt;::raiseExplicitEmbeddingLevel):
+        (WebCore::IsolatedRun&gt;::commitExplicitEmbedding):
+        (WebCore::IsolatedRun&gt;::updateStatusLastFromCurrentDirection):
+        (WebCore::IsolatedRun&gt;::reorderRunsFromLevels):
+        (WebCore::IsolatedRun&gt;::createBidiRunsForLine):
+        (WebCore::IsolatedRun&gt;::setMidpointForIsolatedRun): Use references instead of pointers.
+        (WebCore::IsolatedRun&gt;::midpointForIsolatedRun): Ditto.
+        (WebCore::Run&gt;::~BidiResolver): Deleted.
+        (WebCore::Run&gt;::appendRun): Deleted.
+        (WebCore::Run&gt;::embed): Deleted.
+        (WebCore::Run&gt;::checkDirectionInLowerRaiseEmbeddingLevel): Deleted.
+        (WebCore::Run&gt;::lowerExplicitEmbeddingLevel): Deleted.
+        (WebCore::Run&gt;::raiseExplicitEmbeddingLevel): Deleted.
+        (WebCore::Run&gt;::commitExplicitEmbedding): Deleted.
+        (WebCore::Run&gt;::updateStatusLastFromCurrentDirection): Deleted.
+        (WebCore::Run&gt;::reorderRunsFromLevels): Deleted.
+        (WebCore::Run&gt;::createBidiRunsForLine): Deleted.
+        (WebCore::Run&gt;::setMidpointForIsolatedRun): Deleted.
+        (WebCore::Run&gt;::midpointForIsolatedRun): Deleted.
+        * rendering/InlineIterator.h:
+        (WebCore::BidiIsolatedRun::BidiIsolatedRun): New type.
+        (WebCore::addPlaceholderRunForIsolatedInline): Create new type, and include local root
+        information.
+        (WebCore::IsolateTracker::addFakeRunIfNecessary): Include local root information.
+        (WebCore::InlineBidiResolver::appendRun): Ditto.
+        * rendering/RenderBlockLineLayout.cpp: Update for new BidiIsolatedRun type.
+        (WebCore::setUpResolverToResumeInIsolate):
+        (WebCore::constructBidiRunsForSegment):
+        * rendering/line/TrailingObjects.h:
+
</ins><span class="cx"> 2015-09-15  Brady Eidson  &lt;beidson@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Add empty IDBFactory implementation for Modern IDB.
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformtextBidiResolverh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/text/BidiResolver.h (189831 => 189832)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/text/BidiResolver.h        2015-09-16 00:19:29 UTC (rev 189831)
+++ trunk/Source/WebCore/platform/text/BidiResolver.h        2015-09-16 00:30:38 UTC (rev 189832)
</span><span class="lines">@@ -257,8 +257,8 @@
</span><span class="cx">     // It's unclear if this is still needed.
</span><span class="cx">     void markCurrentRunEmpty() { m_emptyRun = true; }
</span><span class="cx"> 
</span><del>-    void setMidpointForIsolatedRun(Run*, unsigned);
-    unsigned midpointForIsolatedRun(Run*);
</del><ins>+    void setMidpointForIsolatedRun(Run&amp;, unsigned);
+    unsigned midpointForIsolatedRun(Run&amp;);
</ins><span class="cx"> 
</span><span class="cx"> protected:
</span><span class="cx">     // FIXME: Instead of InlineBidiResolvers subclassing this method, we should
</span><span class="lines">@@ -313,10 +313,10 @@
</span><span class="cx"> 
</span><span class="cx">     void incrementInternal();
</span><span class="cx">     void appendRunInternal();
</span><del>-    Vector&lt;Run*&gt;&amp; isolatedRuns() { return m_isolatedRuns; }
</del><ins>+    Vector&lt;IsolateRun&gt;&amp; isolatedRuns() { return m_isolatedRuns; }
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    Vector&lt;Run*&gt; m_isolatedRuns;
</del><ins>+    Vector&lt;IsolateRun&gt; m_isolatedRuns;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> #ifndef NDEBUG
</span><span class="lines">@@ -972,16 +972,16 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template &lt;class Iterator, class Run, class Subclass&gt;
</span><del>-void BidiResolverBase&lt;Iterator, Run, Subclass&gt;::setMidpointForIsolatedRun(Run* run, unsigned midpoint)
</del><ins>+void BidiResolverBase&lt;Iterator, Run, Subclass&gt;::setMidpointForIsolatedRun(Run&amp; run, unsigned midpoint)
</ins><span class="cx"> {
</span><del>-    ASSERT(!m_midpointForIsolatedRun.contains(run));
-    m_midpointForIsolatedRun.add(run, midpoint);
</del><ins>+    ASSERT(!m_midpointForIsolatedRun.contains(&amp;run));
+    m_midpointForIsolatedRun.add(&amp;run, midpoint);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template&lt;class Iterator, class Run, class Subclass&gt;
</span><del>-unsigned BidiResolverBase&lt;Iterator, Run, Subclass&gt;::midpointForIsolatedRun(Run* run)
</del><ins>+unsigned BidiResolverBase&lt;Iterator, Run, Subclass&gt;::midpointForIsolatedRun(Run&amp; run)
</ins><span class="cx"> {
</span><del>-    return m_midpointForIsolatedRun.take(run);
</del><ins>+    return m_midpointForIsolatedRun.take(&amp;run);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingInlineIteratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/InlineIterator.h (189831 => 189832)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/InlineIterator.h        2015-09-16 00:19:29 UTC (rev 189831)
+++ trunk/Source/WebCore/rendering/InlineIterator.h        2015-09-16 00:30:38 UTC (rev 189832)
</span><span class="lines">@@ -31,6 +31,21 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><ins>+struct BidiIsolatedRun {
+    BidiIsolatedRun(RenderObject&amp; object, unsigned position, RenderElement&amp; root, BidiRun&amp; runToReplace)
+        : object(object)
+        , root(root)
+        , runToReplace(runToReplace)
+        , position(position)
+    {
+    }
+
+    RenderObject&amp; object;
+    RenderElement&amp; root;
+    BidiRun&amp; runToReplace;
+    unsigned position;
+};
+
</ins><span class="cx"> // This class is used to RenderInline subtrees, stepping by character within the
</span><span class="cx"> // text children. InlineIterator will use bidiNext to find the next RenderText
</span><span class="cx"> // optionally notifying a BidiResolver every time it steps into/out of a RenderInline.
</span><span class="lines">@@ -475,14 +490,14 @@
</span><span class="cx"> 
</span><span class="cx"> // FIXME: This belongs on InlineBidiResolver, except it's a template specialization
</span><span class="cx"> // of BidiResolver which knows nothing about RenderObjects.
</span><del>-static inline void addPlaceholderRunForIsolatedInline(InlineBidiResolver&amp; resolver, RenderObject&amp; obj, unsigned pos)
</del><ins>+static inline void addPlaceholderRunForIsolatedInline(InlineBidiResolver&amp; resolver, RenderObject&amp; obj, unsigned pos, RenderElement&amp; root)
</ins><span class="cx"> {
</span><span class="cx">     BidiRun* isolatedRun = new BidiRun(pos, 0, obj, resolver.context(), resolver.dir());
</span><span class="cx">     resolver.runs().addRun(isolatedRun);
</span><span class="cx">     // FIXME: isolatedRuns() could be a hash of object-&gt;run and then we could cheaply
</span><span class="cx">     // ASSERT here that we didn't create multiple objects for the same inline.
</span><del>-    resolver.isolatedRuns().append(isolatedRun);
-    resolver.setMidpointForIsolatedRun(isolatedRun, resolver.midpointState().currentMidpoint());
</del><ins>+    resolver.setMidpointForIsolatedRun(*isolatedRun, resolver.midpointState().currentMidpoint());
+    resolver.isolatedRuns().append(BidiIsolatedRun(obj, pos, root, *isolatedRun));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> class IsolateTracker {
</span><span class="lines">@@ -507,7 +522,7 @@
</span><span class="cx">     void embed(UCharDirection, BidiEmbeddingSource) { }
</span><span class="cx">     void commitExplicitEmbedding() { }
</span><span class="cx"> 
</span><del>-    void addFakeRunIfNecessary(RenderObject&amp; obj, unsigned pos, unsigned end, InlineBidiResolver&amp; resolver)
</del><ins>+    void addFakeRunIfNecessary(RenderObject&amp; obj, unsigned pos, unsigned end, RenderElement&amp; root, InlineBidiResolver&amp; resolver)
</ins><span class="cx">     {
</span><span class="cx">         // We only need to add a fake run for a given isolated span once during each call to createBidiRunsForLine.
</span><span class="cx">         // We'll be called for every span inside the isolated span so we just ignore subsequent calls.
</span><span class="lines">@@ -518,7 +533,7 @@
</span><span class="cx">             // obj and pos together denote a single position in the inline, from which the parsing of the isolate will start.
</span><span class="cx">             // We don't need to mark the end of the run because this is implicit: it is either endOfLine or the end of the
</span><span class="cx">             // isolate, when we call createBidiRunsForLine it will stop at whichever comes first.
</span><del>-            addPlaceholderRunForIsolatedInline(resolver, obj, pos);
</del><ins>+            addPlaceholderRunForIsolatedInline(resolver, obj, pos, root);
</ins><span class="cx">         }
</span><span class="cx">         m_haveAddedFakeRunForRootIsolate = true;
</span><span class="cx">         RenderBlockFlow::appendRunsForObject(nullptr, pos, end, obj, resolver);
</span><span class="lines">@@ -541,7 +556,7 @@
</span><span class="cx">         RenderObject* obj = m_sor.renderer();
</span><span class="cx">         while (obj &amp;&amp; obj != m_eor.renderer() &amp;&amp; obj != endOfLine.renderer()) {
</span><span class="cx">             if (isolateTracker.inIsolate())
</span><del>-                isolateTracker.addFakeRunIfNecessary(*obj, start, obj-&gt;length(), *this);
</del><ins>+                isolateTracker.addFakeRunIfNecessary(*obj, start, obj-&gt;length(), *m_sor.root(), *this);
</ins><span class="cx">             else
</span><span class="cx">                 RenderBlockFlow::appendRunsForObject(&amp;m_runs, start, obj-&gt;length(), *obj, *this);
</span><span class="cx">             // FIXME: start/obj should be an InlineIterator instead of two separate variables.
</span><span class="lines">@@ -557,7 +572,7 @@
</span><span class="cx">             // It's OK to add runs for zero-length RenderObjects, just don't make the run larger than it should be
</span><span class="cx">             int end = obj-&gt;length() ? pos + 1 : 0;
</span><span class="cx">             if (isolateTracker.inIsolate())
</span><del>-                isolateTracker.addFakeRunIfNecessary(*obj, start, obj-&gt;length(), *this);
</del><ins>+                isolateTracker.addFakeRunIfNecessary(*obj, start, obj-&gt;length(), *m_sor.root(), *this);
</ins><span class="cx">             else
</span><span class="cx">                 RenderBlockFlow::appendRunsForObject(&amp;m_runs, start, end, *obj, *this);
</span><span class="cx">         }
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderBlockLineLayoutcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp (189831 => 189832)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp        2015-09-16 00:19:29 UTC (rev 189831)
+++ trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp        2015-09-16 00:30:38 UTC (rev 189832)
</span><span class="lines">@@ -1017,7 +1017,7 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static inline void setUpResolverToResumeInIsolate(InlineBidiResolver&amp; resolver, InlineBidiResolver&amp; topResolver, BidiRun* isolatedRun, RenderObject* root, RenderObject* startObject)
</del><ins>+static inline void setUpResolverToResumeInIsolate(InlineBidiResolver&amp; resolver, InlineBidiResolver&amp; topResolver, BidiRun&amp; isolatedRun, RenderObject* root, RenderObject* startObject)
</ins><span class="cx"> {
</span><span class="cx">     // Set up m_midpointState
</span><span class="cx">     resolver.midpointState() = topResolver.midpointState();
</span><span class="lines">@@ -1039,10 +1039,11 @@
</span><span class="cx"> 
</span><span class="cx">     while (!topResolver.isolatedRuns().isEmpty()) {
</span><span class="cx">         // It does not matter which order we resolve the runs as long as we resolve them all.
</span><del>-        BidiRun* isolatedRun = topResolver.isolatedRuns().last();
</del><ins>+        auto isolatedRun = WTF::move(topResolver.isolatedRuns().last());
</ins><span class="cx">         topResolver.isolatedRuns().removeLast();
</span><ins>+        currentRoot = &amp;isolatedRun.root;
</ins><span class="cx"> 
</span><del>-        RenderObject&amp; startObject = isolatedRun-&gt;renderer();
</del><ins>+        RenderObject&amp; startObject = isolatedRun.object;
</ins><span class="cx"> 
</span><span class="cx">         // Only inlines make sense with unicode-bidi: isolate (blocks are already isolated).
</span><span class="cx">         // FIXME: Because enterIsolate is not passed a RenderObject, we have to crawl up the
</span><span class="lines">@@ -1056,19 +1057,19 @@
</span><span class="cx">         EUnicodeBidi unicodeBidi = isolatedInline-&gt;style().unicodeBidi();
</span><span class="cx">         TextDirection direction;
</span><span class="cx">         if (unicodeBidi == Plaintext)
</span><del>-            determineDirectionality(direction, InlineIterator(isolatedInline, &amp;isolatedRun-&gt;renderer(), 0));
</del><ins>+            determineDirectionality(direction, InlineIterator(isolatedInline, &amp;isolatedRun.object, 0));
</ins><span class="cx">         else {
</span><span class="cx">             ASSERT(unicodeBidi == Isolate || unicodeBidi == IsolateOverride);
</span><span class="cx">             direction = isolatedInline-&gt;style().direction();
</span><span class="cx">         }
</span><span class="cx">         isolatedResolver.setStatus(BidiStatus(direction, isOverride(unicodeBidi)));
</span><span class="cx"> 
</span><del>-        setUpResolverToResumeInIsolate(isolatedResolver, topResolver, isolatedRun, isolatedInline, &amp;startObject);
</del><ins>+        setUpResolverToResumeInIsolate(isolatedResolver, topResolver, isolatedRun.runToReplace, isolatedInline, &amp;startObject);
</ins><span class="cx"> 
</span><span class="cx">         // The starting position is the beginning of the first run within the isolate that was identified
</span><span class="cx">         // during the earlier call to createBidiRunsForLine. This can be but is not necessarily the
</span><span class="cx">         // first run within the isolate.
</span><del>-        InlineIterator iter = InlineIterator(isolatedInline, &amp;startObject, isolatedRun-&gt;m_start);
</del><ins>+        InlineIterator iter = InlineIterator(isolatedInline, &amp;startObject, isolatedRun.position);
</ins><span class="cx">         isolatedResolver.setPositionIgnoringNestedIsolates(iter);
</span><span class="cx"> 
</span><span class="cx">         // We stop at the next end of line; we may re-enter this isolate in the next call to constructBidiRuns().
</span><span class="lines">@@ -1080,16 +1081,15 @@
</span><span class="cx">         // itself to be turned into an InlineBox. We can't remove it here without potentially losing track of
</span><span class="cx">         // the logically last run.
</span><span class="cx">         if (isolatedResolver.runs().runCount())
</span><del>-            bidiRuns.replaceRunWithRuns(isolatedRun, isolatedResolver.runs());
</del><ins>+            bidiRuns.replaceRunWithRuns(&amp;isolatedRun.runToReplace, isolatedResolver.runs());
</ins><span class="cx"> 
</span><span class="cx">         // If we encountered any nested isolate runs, just move them
</span><span class="cx">         // to the top resolver's list for later processing.
</span><del>-        if (!isolatedResolver.isolatedRuns().isEmpty()) {
-            topResolver.isolatedRuns().appendVector(isolatedResolver.isolatedRuns());
-            for (auto* run : isolatedResolver.isolatedRuns())
-                topResolver.setMidpointForIsolatedRun(run, isolatedResolver.midpointForIsolatedRun(run));
-            isolatedResolver.isolatedRuns().clear();
-            currentRoot = isolatedInline;
</del><ins>+        while (!isolatedResolver.isolatedRuns().isEmpty()) {
+            auto runWithContext = WTF::move(isolatedResolver.isolatedRuns().last());
+            isolatedResolver.isolatedRuns().removeLast();
+            topResolver.setMidpointForIsolatedRun(runWithContext.runToReplace, isolatedResolver.midpointForIsolatedRun(runWithContext.runToReplace));
+            topResolver.isolatedRuns().append(WTF::move(runWithContext));
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorerenderinglineTrailingObjectsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/line/TrailingObjects.h (189831 => 189832)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/line/TrailingObjects.h        2015-09-16 00:19:29 UTC (rev 189831)
+++ trunk/Source/WebCore/rendering/line/TrailingObjects.h        2015-09-16 00:30:38 UTC (rev 189832)
</span><span class="lines">@@ -34,11 +34,12 @@
</span><span class="cx"> class RenderText;
</span><span class="cx"> 
</span><span class="cx"> struct BidiRun;
</span><ins>+struct BidiIsolatedRun;
</ins><span class="cx"> 
</span><span class="cx"> template &lt;class Iterator, class Run&gt; class BidiResolver;
</span><span class="cx"> template &lt;class Iterator, class Run, class IsolateRun&gt; class BidiResolverWithIsolate;
</span><span class="cx"> template &lt;class Iterator&gt; class MidpointState;
</span><del>-typedef BidiResolverWithIsolate&lt;InlineIterator, BidiRun, BidiRun&gt; InlineBidiResolver;
</del><ins>+typedef BidiResolverWithIsolate&lt;InlineIterator, BidiRun, BidiIsolatedRun&gt; InlineBidiResolver;
</ins><span class="cx"> typedef MidpointState&lt;InlineIterator&gt; LineMidpointState;
</span><span class="cx"> 
</span><span class="cx"> class TrailingObjects {
</span></span></pre>
</div>
</div>

</body>
</html>