<!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>[209120] trunk/Source</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/209120">209120</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2016-11-29 20:54:04 -0800 (Tue, 29 Nov 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Unreviewed, rolling out <a href="http://trac.webkit.org/projects/webkit/changeset/209058">r209058</a> and <a href="http://trac.webkit.org/projects/webkit/changeset/209074">r209074</a>.
https://bugs.webkit.org/show_bug.cgi?id=165188

These changes caused API test StringBuilderTest.Equal to crash
and/or fail. (Requested by ryanhaddad on #webkit).

Reverted changesets:

&quot;Streamline and speed up tokenizer and segmented string
classes&quot;
https://bugs.webkit.org/show_bug.cgi?id=165003
http://trac.webkit.org/changeset/209058

&quot;REGRESSION (<a href="http://trac.webkit.org/projects/webkit/changeset/209058">r209058</a>): API test StringBuilderTest.Equal
crashing&quot;
https://bugs.webkit.org/show_bug.cgi?id=165142
http://trac.webkit.org/changeset/209074</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSONObjectcpp">trunk/Source/JavaScriptCore/runtime/JSONObject.cpp</a></li>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtftextStringBuildercpp">trunk/Source/WTF/wtf/text/StringBuilder.cpp</a></li>
<li><a href="#trunkSourceWTFwtftextStringBuilderh">trunk/Source/WTF/wtf/text/StringBuilder.h</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSHTMLDocumentCustomcpp">trunk/Source/WebCore/bindings/js/JSHTMLDocumentCustom.cpp</a></li>
<li><a href="#trunkSourceWebCorecssparserCSSTokenizercpp">trunk/Source/WebCore/css/parser/CSSTokenizer.cpp</a></li>
<li><a href="#trunkSourceWebCorecssparserCSSTokenizerh">trunk/Source/WebCore/css/parser/CSSTokenizer.h</a></li>
<li><a href="#trunkSourceWebCorecssparserCSSTokenizerInputStreamh">trunk/Source/WebCore/css/parser/CSSTokenizerInputStream.h</a></li>
<li><a href="#trunkSourceWebCoredomDocumentcpp">trunk/Source/WebCore/dom/Document.cpp</a></li>
<li><a href="#trunkSourceWebCoredomDocumenth">trunk/Source/WebCore/dom/Document.h</a></li>
<li><a href="#trunkSourceWebCoredomDocumentParserh">trunk/Source/WebCore/dom/DocumentParser.h</a></li>
<li><a href="#trunkSourceWebCoredomRawDataDocumentParserh">trunk/Source/WebCore/dom/RawDataDocumentParser.h</a></li>
<li><a href="#trunkSourceWebCorehtmlFTPDirectoryDocumentcpp">trunk/Source/WebCore/html/FTPDirectoryDocument.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlparserHTMLDocumentParsercpp">trunk/Source/WebCore/html/parser/HTMLDocumentParser.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlparserHTMLDocumentParserh">trunk/Source/WebCore/html/parser/HTMLDocumentParser.h</a></li>
<li><a href="#trunkSourceWebCorehtmlparserHTMLEntityParsercpp">trunk/Source/WebCore/html/parser/HTMLEntityParser.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlparserHTMLInputStreamh">trunk/Source/WebCore/html/parser/HTMLInputStream.h</a></li>
<li><a href="#trunkSourceWebCorehtmlparserHTMLMetaCharsetParsercpp">trunk/Source/WebCore/html/parser/HTMLMetaCharsetParser.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlparserHTMLSourceTrackercpp">trunk/Source/WebCore/html/parser/HTMLSourceTracker.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlparserHTMLSourceTrackerh">trunk/Source/WebCore/html/parser/HTMLSourceTracker.h</a></li>
<li><a href="#trunkSourceWebCorehtmlparserHTMLTokenizercpp">trunk/Source/WebCore/html/parser/HTMLTokenizer.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlparserInputStreamPreprocessorh">trunk/Source/WebCore/html/parser/InputStreamPreprocessor.h</a></li>
<li><a href="#trunkSourceWebCorehtmltrackBufferedLineReadercpp">trunk/Source/WebCore/html/track/BufferedLineReader.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmltrackBufferedLineReaderh">trunk/Source/WebCore/html/track/BufferedLineReader.h</a></li>
<li><a href="#trunkSourceWebCorehtmltrackInbandGenericTextTrackcpp">trunk/Source/WebCore/html/track/InbandGenericTextTrack.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmltrackInbandGenericTextTrackh">trunk/Source/WebCore/html/track/InbandGenericTextTrack.h</a></li>
<li><a href="#trunkSourceWebCorehtmltrackInbandTextTrackh">trunk/Source/WebCore/html/track/InbandTextTrack.h</a></li>
<li><a href="#trunkSourceWebCorehtmltrackWebVTTParsercpp">trunk/Source/WebCore/html/track/WebVTTParser.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmltrackWebVTTParserh">trunk/Source/WebCore/html/track/WebVTTParser.h</a></li>
<li><a href="#trunkSourceWebCorehtmltrackWebVTTTokenizercpp">trunk/Source/WebCore/html/track/WebVTTTokenizer.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsInbandTextTrackPrivateClienth">trunk/Source/WebCore/platform/graphics/InbandTextTrackPrivateClient.h</a></li>
<li><a href="#trunkSourceWebCoreplatformtextSegmentedStringcpp">trunk/Source/WebCore/platform/text/SegmentedString.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformtextSegmentedStringh">trunk/Source/WebCore/platform/text/SegmentedString.h</a></li>
<li><a href="#trunkSourceWebCorexmlparserCharacterReferenceParserInlinesh">trunk/Source/WebCore/xml/parser/CharacterReferenceParserInlines.h</a></li>
<li><a href="#trunkSourceWebCorexmlparserMarkupTokenizerInlinesh">trunk/Source/WebCore/xml/parser/MarkupTokenizerInlines.h</a></li>
<li><a href="#trunkSourceWebCorexmlparserXMLDocumentParsercpp">trunk/Source/WebCore/xml/parser/XMLDocumentParser.cpp</a></li>
<li><a href="#trunkSourceWebCorexmlparserXMLDocumentParserh">trunk/Source/WebCore/xml/parser/XMLDocumentParser.h</a></li>
<li><a href="#trunkSourceWebCorexmlparserXMLDocumentParserLibxml2cpp">trunk/Source/WebCore/xml/parser/XMLDocumentParserLibxml2.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -1,3 +1,23 @@
</span><ins>+2016-11-29  Commit Queue  &lt;commit-queue@webkit.org&gt;
+
+        Unreviewed, rolling out r209058 and r209074.
+        https://bugs.webkit.org/show_bug.cgi?id=165188
+
+        These changes caused API test StringBuilderTest.Equal to crash
+        and/or fail. (Requested by ryanhaddad on #webkit).
+
+        Reverted changesets:
+
+        &quot;Streamline and speed up tokenizer and segmented string
+        classes&quot;
+        https://bugs.webkit.org/show_bug.cgi?id=165003
+        http://trac.webkit.org/changeset/209058
+
+        &quot;REGRESSION (r209058): API test StringBuilderTest.Equal
+        crashing&quot;
+        https://bugs.webkit.org/show_bug.cgi?id=165142
+        http://trac.webkit.org/changeset/209074
+
</ins><span class="cx"> 2016-11-29  Caitlin Potter  &lt;caitp@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [JSC] always wrap AwaitExpression operand in a new Promise
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSONObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSONObject.cpp (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSONObject.cpp        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/JavaScriptCore/runtime/JSONObject.cpp        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2009-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2009, 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -354,7 +354,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (value.isString()) {
</span><del>-        builder.appendQuotedJSONString(asString(value)-&gt;viewWithUnderlyingString(*m_exec).view);
</del><ins>+        builder.appendQuotedJSONString(asString(value)-&gt;value(m_exec));
</ins><span class="cx">         return StringifySucceeded;
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WTF/ChangeLog        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -1,3 +1,23 @@
</span><ins>+2016-11-29  Commit Queue  &lt;commit-queue@webkit.org&gt;
+
+        Unreviewed, rolling out r209058 and r209074.
+        https://bugs.webkit.org/show_bug.cgi?id=165188
+
+        These changes caused API test StringBuilderTest.Equal to crash
+        and/or fail. (Requested by ryanhaddad on #webkit).
+
+        Reverted changesets:
+
+        &quot;Streamline and speed up tokenizer and segmented string
+        classes&quot;
+        https://bugs.webkit.org/show_bug.cgi?id=165003
+        http://trac.webkit.org/changeset/209058
+
+        &quot;REGRESSION (r209058): API test StringBuilderTest.Equal
+        crashing&quot;
+        https://bugs.webkit.org/show_bug.cgi?id=165142
+        http://trac.webkit.org/changeset/209074
+
</ins><span class="cx"> 2016-11-29  Simon Fraser  &lt;simon.fraser@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Allow TracePoint to take arbitrary data
</span></span></pre></div>
<a id="trunkSourceWTFwtftextStringBuildercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/text/StringBuilder.cpp (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/text/StringBuilder.cpp        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WTF/wtf/text/StringBuilder.cpp        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2010, 2013, 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  * Copyright (C) 2012 Google Inc. All rights reserved.
</span><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;IntegerToStringConversion.h&quot;
</span><span class="cx"> #include &quot;MathExtras.h&quot;
</span><ins>+#include &quot;WTFString.h&quot;
</ins><span class="cx"> #include &lt;wtf/dtoa.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WTF {
</span><span class="lines">@@ -39,18 +40,6 @@
</span><span class="cx">     return std::max(requiredLength, std::max(minimumCapacity, capacity * 2));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-template&lt;&gt; ALWAYS_INLINE LChar* StringBuilder::bufferCharacters&lt;LChar&gt;()
-{
-    ASSERT(m_is8Bit);
-    return m_bufferCharacters8;
-}
-
-template&lt;&gt; ALWAYS_INLINE UChar* StringBuilder::bufferCharacters&lt;UChar&gt;()
-{
-    ASSERT(!m_is8Bit);
-    return m_bufferCharacters16;
-}
-
</del><span class="cx"> void StringBuilder::reifyString() const
</span><span class="cx"> {
</span><span class="cx">     // Check if the string already exists.
</span><span class="lines">@@ -108,7 +97,6 @@
</span><span class="cx"> void StringBuilder::allocateBuffer(const LChar* currentCharacters, unsigned requiredLength)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(m_is8Bit);
</span><del>-
</del><span class="cx">     // Copy the existing data into a new buffer, set result to point to the end of the existing data.
</span><span class="cx">     auto buffer = StringImpl::createUninitialized(requiredLength, m_bufferCharacters8);
</span><span class="cx">     memcpy(m_bufferCharacters8, currentCharacters, static_cast&lt;size_t&gt;(m_length) * sizeof(LChar)); // This can't overflow.
</span><span class="lines">@@ -124,7 +112,6 @@
</span><span class="cx"> void StringBuilder::allocateBuffer(const UChar* currentCharacters, unsigned requiredLength)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!m_is8Bit);
</span><del>-
</del><span class="cx">     // Copy the existing data into a new buffer, set result to point to the end of the existing data.
</span><span class="cx">     auto buffer = StringImpl::createUninitialized(requiredLength, m_bufferCharacters16);
</span><span class="cx">     memcpy(m_bufferCharacters16, currentCharacters, static_cast&lt;size_t&gt;(m_length) * sizeof(UChar)); // This can't overflow.
</span><span class="lines">@@ -137,11 +124,10 @@
</span><span class="cx"> 
</span><span class="cx"> // Allocate a new 16 bit buffer, copying in currentCharacters (which is 8 bit and may come
</span><span class="cx"> // from either m_string or m_buffer, neither will be reassigned until the copy has completed).
</span><del>-void StringBuilder::allocateBufferUpconvert(const LChar* currentCharacters, unsigned requiredLength)
</del><ins>+void StringBuilder::allocateBufferUpConvert(const LChar* currentCharacters, unsigned requiredLength)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(m_is8Bit);
</span><span class="cx">     ASSERT(requiredLength &gt;= m_length);
</span><del>-
</del><span class="cx">     // Copy the existing data into a new buffer, set result to point to the end of the existing data.
</span><span class="cx">     auto buffer = StringImpl::createUninitialized(requiredLength, m_bufferCharacters16);
</span><span class="cx">     for (unsigned i = 0; i &lt; m_length; ++i)
</span><span class="lines">@@ -155,7 +141,8 @@
</span><span class="cx">     ASSERT(m_buffer-&gt;length() == requiredLength);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-template&lt;&gt; void StringBuilder::reallocateBuffer&lt;LChar&gt;(unsigned requiredLength)
</del><ins>+template &lt;&gt;
+void StringBuilder::reallocateBuffer&lt;LChar&gt;(unsigned requiredLength)
</ins><span class="cx"> {
</span><span class="cx">     // If the buffer has only one ref (by this StringBuilder), reallocate it,
</span><span class="cx">     // otherwise fall back to &quot;allocate and copy&quot; method.
</span><span class="lines">@@ -171,7 +158,8 @@
</span><span class="cx">     ASSERT(m_buffer-&gt;length() == requiredLength);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-template&lt;&gt; void StringBuilder::reallocateBuffer&lt;UChar&gt;(unsigned requiredLength)
</del><ins>+template &lt;&gt;
+void StringBuilder::reallocateBuffer&lt;UChar&gt;(unsigned requiredLength)
</ins><span class="cx"> {
</span><span class="cx">     // If the buffer has only one ref (by this StringBuilder), reallocate it,
</span><span class="cx">     // otherwise fall back to &quot;allocate and copy&quot; method.
</span><span class="lines">@@ -178,7 +166,7 @@
</span><span class="cx">     m_string = String();
</span><span class="cx">     
</span><span class="cx">     if (m_buffer-&gt;is8Bit())
</span><del>-        allocateBufferUpconvert(m_buffer-&gt;characters8(), requiredLength);
</del><ins>+        allocateBufferUpConvert(m_buffer-&gt;characters8(), requiredLength);
</ins><span class="cx">     else if (m_buffer-&gt;hasOneRef())
</span><span class="cx">         m_buffer = StringImpl::reallocate(m_buffer.releaseNonNull(), requiredLength, m_bufferCharacters16);
</span><span class="cx">     else
</span><span class="lines">@@ -200,7 +188,7 @@
</span><span class="cx">         // Grow the string, if necessary.
</span><span class="cx">         if (newCapacity &gt; m_length) {
</span><span class="cx">             if (!m_length) {
</span><del>-                LChar* nullPlaceholder = nullptr;
</del><ins>+                LChar* nullPlaceholder = 0;
</ins><span class="cx">                 allocateBuffer(nullPlaceholder, newCapacity);
</span><span class="cx">             } else if (m_string.is8Bit())
</span><span class="cx">                 allocateBuffer(m_string.characters8(), newCapacity);
</span><span class="lines">@@ -213,7 +201,8 @@
</span><span class="cx"> 
</span><span class="cx"> // Make 'length' additional capacity be available in m_buffer, update m_string &amp; m_length,
</span><span class="cx"> // return a pointer to the newly allocated storage.
</span><del>-template&lt;typename CharacterType&gt; ALWAYS_INLINE CharacterType* StringBuilder::appendUninitialized(unsigned length)
</del><ins>+template &lt;typename CharType&gt;
+ALWAYS_INLINE CharType* StringBuilder::appendUninitialized(unsigned length)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(length);
</span><span class="cx"> 
</span><span class="lines">@@ -228,15 +217,16 @@
</span><span class="cx">         unsigned currentLength = m_length;
</span><span class="cx">         m_string = String();
</span><span class="cx">         m_length = requiredLength;
</span><del>-        return bufferCharacters&lt;CharacterType&gt;() + currentLength;
</del><ins>+        return getBufferCharacters&lt;CharType&gt;() + currentLength;
</ins><span class="cx">     }
</span><del>-
-    return appendUninitializedSlow&lt;CharacterType&gt;(requiredLength);
</del><ins>+    
+    return appendUninitializedSlow&lt;CharType&gt;(requiredLength);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // Make 'length' additional capacity be available in m_buffer, update m_string &amp; m_length,
</span><span class="cx"> // return a pointer to the newly allocated storage.
</span><del>-template&lt;typename CharacterType&gt; CharacterType* StringBuilder::appendUninitializedSlow(unsigned requiredLength)
</del><ins>+template &lt;typename CharType&gt;
+CharType* StringBuilder::appendUninitializedSlow(unsigned requiredLength)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(requiredLength);
</span><span class="cx"> 
</span><span class="lines">@@ -243,38 +233,19 @@
</span><span class="cx">     if (m_buffer) {
</span><span class="cx">         // If the buffer is valid it must be at least as long as the current builder contents!
</span><span class="cx">         ASSERT(m_buffer-&gt;length() &gt;= m_length);
</span><del>-        reallocateBuffer&lt;CharacterType&gt;(expandedCapacity(capacity(), requiredLength));
</del><ins>+        
+        reallocateBuffer&lt;CharType&gt;(expandedCapacity(capacity(), requiredLength));
</ins><span class="cx">     } else {
</span><span class="cx">         ASSERT(m_string.length() == m_length);
</span><del>-        allocateBuffer(m_length ? m_string.characters&lt;CharacterType&gt;() : nullptr, expandedCapacity(capacity(), requiredLength));
</del><ins>+        allocateBuffer(m_length ? m_string.characters&lt;CharType&gt;() : 0, expandedCapacity(capacity(), requiredLength));
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    auto* result = bufferCharacters&lt;CharacterType&gt;() + m_length;
</del><ins>+    CharType* result = getBufferCharacters&lt;CharType&gt;() + m_length;
</ins><span class="cx">     m_length = requiredLength;
</span><span class="cx">     ASSERT(m_buffer-&gt;length() &gt;= m_length);
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline UChar* StringBuilder::appendUninitializedUpconvert(unsigned length)
-{
-    unsigned requiredLength = length + m_length;
-    if (requiredLength &lt; length)
-        CRASH();
-
-    if (m_buffer) {
-        // If the buffer is valid it must be at least as long as the current builder contents!
-        ASSERT(m_buffer-&gt;length() &gt;= m_length);
-        allocateBufferUpconvert(m_buffer-&gt;characters8(), expandedCapacity(capacity(), requiredLength));
-    } else {
-        ASSERT(m_string.length() == m_length);
-        allocateBufferUpconvert(m_string.isNull() ? nullptr : m_string.characters8(), expandedCapacity(capacity(), requiredLength));
-    }
-
-    auto* result = m_bufferCharacters16 + m_length;
-    m_length = requiredLength;
-    return result;
-}
-
</del><span class="cx"> void StringBuilder::append(const UChar* characters, unsigned length)
</span><span class="cx"> {
</span><span class="cx">     if (!length)
</span><span class="lines">@@ -283,16 +254,32 @@
</span><span class="cx">     ASSERT(characters);
</span><span class="cx"> 
</span><span class="cx">     if (m_is8Bit) {
</span><del>-        if (length == 1 &amp;&amp; !(*characters &amp; ~0xFF)) {
</del><ins>+        if (length == 1 &amp;&amp; !(*characters &amp; ~0xff)) {
</ins><span class="cx">             // Append as 8 bit character
</span><span class="cx">             LChar lChar = static_cast&lt;LChar&gt;(*characters);
</span><span class="cx">             append(&amp;lChar, 1);
</span><span class="cx">             return;
</span><span class="cx">         }
</span><del>-        memcpy(appendUninitializedUpconvert(length), characters, static_cast&lt;size_t&gt;(length) * sizeof(UChar));
</del><ins>+
+        // Calculate the new size of the builder after appending.
+        unsigned requiredLength = length + m_length;
+        if (requiredLength &lt; length)
+            CRASH();
+        
+        if (m_buffer) {
+            // If the buffer is valid it must be at least as long as the current builder contents!
+            ASSERT(m_buffer-&gt;length() &gt;= m_length);
+            
+            allocateBufferUpConvert(m_buffer-&gt;characters8(), expandedCapacity(capacity(), requiredLength));
+        } else {
+            ASSERT(m_string.length() == m_length);
+            allocateBufferUpConvert(m_string.isNull() ? 0 : m_string.characters8(), expandedCapacity(capacity(), requiredLength));
+        }
+
+        memcpy(m_bufferCharacters16 + m_length, characters, static_cast&lt;size_t&gt;(length) * sizeof(UChar));
+        m_length = requiredLength;
</ins><span class="cx">     } else
</span><span class="cx">         memcpy(appendUninitialized&lt;UChar&gt;(length), characters, static_cast&lt;size_t&gt;(length) * sizeof(UChar));
</span><del>-
</del><span class="cx">     ASSERT(m_buffer-&gt;length() &gt;= m_length);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -303,22 +290,19 @@
</span><span class="cx">     ASSERT(characters);
</span><span class="cx"> 
</span><span class="cx">     if (m_is8Bit) {
</span><del>-        auto* destination = appendUninitialized&lt;LChar&gt;(length);
-        // FIXME: How did we determine a threshold of 8 here was the right one?
-        // Also, this kind of optimization could be useful anywhere else we have a
-        // performance-sensitive code path that calls memcpy.
</del><ins>+        LChar* dest = appendUninitialized&lt;LChar&gt;(length);
</ins><span class="cx">         if (length &gt; 8)
</span><del>-            memcpy(destination, characters, length);
</del><ins>+            memcpy(dest, characters, static_cast&lt;size_t&gt;(length) * sizeof(LChar));
</ins><span class="cx">         else {
</span><span class="cx">             const LChar* end = characters + length;
</span><span class="cx">             while (characters &lt; end)
</span><del>-                *destination++ = *characters++;
</del><ins>+                *(dest++) = *(characters++);
</ins><span class="cx">         }
</span><span class="cx">     } else {
</span><del>-        auto* destination = appendUninitialized&lt;UChar&gt;(length);
</del><ins>+        UChar* dest = appendUninitialized&lt;UChar&gt;(length);
</ins><span class="cx">         const LChar* end = characters + length;
</span><span class="cx">         while (characters &lt; end)
</span><del>-            *destination++ = *characters++;
</del><ins>+            *(dest++) = *(characters++);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -401,58 +385,17 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-template&lt;typename LengthType, typename CharacterType&gt; static LengthType quotedJSONStringLength(const CharacterType* input, unsigned length)
</del><ins>+template &lt;typename OutputCharacterType, typename InputCharacterType&gt;
+static void appendQuotedJSONStringInternal(OutputCharacterType*&amp; output, const InputCharacterType* input, unsigned length)
</ins><span class="cx"> {
</span><del>-    LengthType quotedLength = 2;
-    for (unsigned i = 0; i &lt; length; ++i) {
-        auto character = input[i];
-        if (LIKELY(character &gt; 0x1F)) {
-            switch (character) {
-            case '&quot;':
-            case '\\':
-                quotedLength += 2;
-                break;
-            default:
-                ++quotedLength;
-                break;
-            }
-        } else {
-            switch (character) {
-            case '\t':
-            case '\r':
-            case '\n':
-            case '\f':
-            case '\b':
-                quotedLength += 2;
-                break;
-            default:
-                quotedLength += 6;
-            }
-        }
-    }
-    return quotedLength;
-}
-
-template&lt;typename CharacterType&gt; static inline unsigned quotedJSONStringLength(const CharacterType* input, unsigned length)
-{
-    constexpr auto maxSafeLength = (std::numeric_limits&lt;unsigned&gt;::max() - 2) / 6;
-    if (length &lt;= maxSafeLength)
-        return quotedJSONStringLength&lt;unsigned&gt;(input, length);
-    return quotedJSONStringLength&lt;Checked&lt;unsigned&gt;&gt;(input, length).unsafeGet();
-}
-
-template&lt;typename OutputCharacterType, typename InputCharacterType&gt; static inline void appendQuotedJSONStringInternal(OutputCharacterType* output, const InputCharacterType* input, unsigned length)
-{
-    *output++ = '&quot;';
-    for (unsigned i = 0; i &lt; length; ++i) {
-        auto character = input[i];
-        if (LIKELY(character &gt; 0x1F)) {
-            if (UNLIKELY(character == '&quot;' || character == '\\'))
</del><ins>+    for (const InputCharacterType* end = input + length; input != end; ++input) {
+        if (LIKELY(*input &gt; 0x1F)) {
+            if (*input == '&quot;' || *input == '\\')
</ins><span class="cx">                 *output++ = '\\';
</span><del>-            *output++ = character;
</del><ins>+            *output++ = *input;
</ins><span class="cx">             continue;
</span><span class="cx">         }
</span><del>-        switch (character) {
</del><ins>+        switch (*input) {
</ins><span class="cx">         case '\t':
</span><span class="cx">             *output++ = '\\';
</span><span class="cx">             *output++ = 't';
</span><span class="lines">@@ -474,35 +417,56 @@
</span><span class="cx">             *output++ = 'b';
</span><span class="cx">             break;
</span><span class="cx">         default:
</span><del>-            ASSERT(!(character &amp; ~0xFF));
</del><ins>+            ASSERT((*input &amp; 0xFF00) == 0);
+            static const char hexDigits[] = &quot;0123456789abcdef&quot;;
</ins><span class="cx">             *output++ = '\\';
</span><span class="cx">             *output++ = 'u';
</span><span class="cx">             *output++ = '0';
</span><span class="cx">             *output++ = '0';
</span><del>-            *output++ = upperNibbleToLowercaseASCIIHexDigit(character);
-            *output++ = lowerNibbleToLowercaseASCIIHexDigit(character);
</del><ins>+            *output++ = static_cast&lt;LChar&gt;(hexDigits[(*input &gt;&gt; 4) &amp; 0xF]);
+            *output++ = static_cast&lt;LChar&gt;(hexDigits[*input &amp; 0xF]);
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">     }
</span><del>-    *output = '&quot;';
</del><span class="cx"> }
</span><span class="cx"> 
</span><del>-void StringBuilder::appendQuotedJSONString(StringView string)
</del><ins>+void StringBuilder::appendQuotedJSONString(const String&amp; string)
</ins><span class="cx"> {
</span><del>-    unsigned length = string.length();
-    if (string.is8Bit()) {
-        auto* characters = string.characters8();
-        if (m_is8Bit)
-            appendQuotedJSONStringInternal(appendUninitialized&lt;LChar&gt;(quotedJSONStringLength(characters, length)), characters, length);
-        else
-            appendQuotedJSONStringInternal(appendUninitialized&lt;UChar&gt;(quotedJSONStringLength(characters, length)), characters, length);
</del><ins>+    // Make sure we have enough buffer space to append this string without having
+    // to worry about reallocating in the middle.
+    // The 2 is for the '&quot;' quotes on each end.
+    // The 6 is for characters that need to be \uNNNN encoded.
+    Checked&lt;unsigned&gt; stringLength = string.length();
+    Checked&lt;unsigned&gt; maximumCapacityRequired = length();
+    maximumCapacityRequired += 2 + stringLength * 6;
+    unsigned allocationSize = maximumCapacityRequired.unsafeGet();
+    // This max() is here to allow us to allocate sizes between the range [2^31, 2^32 - 2] because roundUpToPowerOfTwo(1&lt;&lt;31 + some int smaller than 1&lt;&lt;31) == 0.
+    allocationSize = std::max(allocationSize, roundUpToPowerOfTwo(allocationSize));
+
+    if (is8Bit() &amp;&amp; !string.is8Bit())
+        allocateBufferUpConvert(m_bufferCharacters8, allocationSize);
+    else
+        reserveCapacity(allocationSize);
+    ASSERT(m_buffer-&gt;length() &gt;= allocationSize);
+
+    if (is8Bit()) {
+        ASSERT(string.is8Bit());
+        LChar* output = m_bufferCharacters8 + m_length;
+        *output++ = '&quot;';
+        appendQuotedJSONStringInternal(output, string.characters8(), string.length());
+        *output++ = '&quot;';
+        m_length = output - m_bufferCharacters8;
</ins><span class="cx">     } else {
</span><del>-        auto* characters = string.characters16();
-        if (m_is8Bit)
-            appendQuotedJSONStringInternal(appendUninitializedUpconvert(quotedJSONStringLength(characters, length)), characters, length);
</del><ins>+        UChar* output = m_bufferCharacters16 + m_length;
+        *output++ = '&quot;';
+        if (string.is8Bit())
+            appendQuotedJSONStringInternal(output, string.characters8(), string.length());
</ins><span class="cx">         else
</span><del>-            appendQuotedJSONStringInternal(appendUninitialized&lt;UChar&gt;(quotedJSONStringLength(characters, length)), characters, length);
</del><ins>+            appendQuotedJSONStringInternal(output, string.characters16(), string.length());
+        *output++ = '&quot;';
+        m_length = output - m_bufferCharacters16;
</ins><span class="cx">     }
</span><ins>+    ASSERT(m_buffer-&gt;length() &gt;= m_length);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace WTF
</span></span></pre></div>
<a id="trunkSourceWTFwtftextStringBuilderh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/text/StringBuilder.h (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/text/StringBuilder.h        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WTF/wtf/text/StringBuilder.h        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2009-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2009-2010, 2012-2013, 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  * Copyright (C) 2012 Google Inc. All rights reserved.
</span><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="lines">@@ -24,18 +24,26 @@
</span><span class="cx">  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
</span><span class="cx">  */
</span><span class="cx"> 
</span><del>-#pragma once
</del><ins>+#ifndef StringBuilder_h
+#define StringBuilder_h
</ins><span class="cx"> 
</span><ins>+#include &lt;wtf/text/AtomicString.h&gt;
</ins><span class="cx"> #include &lt;wtf/text/StringView.h&gt;
</span><ins>+#include &lt;wtf/text/WTFString.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> namespace WTF {
</span><span class="cx"> 
</span><span class="cx"> class StringBuilder {
</span><del>-    // Disallow copying since it's expensive and we don't want anyone to do it by accident.
</del><ins>+    // Disallow copying since it's expensive and we don't want code to do it by accident.
</ins><span class="cx">     WTF_MAKE_NONCOPYABLE(StringBuilder);
</span><span class="cx"> 
</span><span class="cx"> public:
</span><del>-    StringBuilder() = default;
</del><ins>+    StringBuilder()
+        : m_length(0)
+        , m_is8Bit(true)
+        , m_bufferCharacters8(0)
+    {
+    }
</ins><span class="cx"> 
</span><span class="cx">     WTF_EXPORT_PRIVATE void append(const UChar*, unsigned);
</span><span class="cx">     WTF_EXPORT_PRIVATE void append(const LChar*, unsigned);
</span><span class="lines">@@ -42,27 +50,29 @@
</span><span class="cx"> 
</span><span class="cx">     ALWAYS_INLINE void append(const char* characters, unsigned length) { append(reinterpret_cast&lt;const LChar*&gt;(characters), length); }
</span><span class="cx"> 
</span><del>-    void append(const AtomicString&amp; atomicString) { append(atomicString.string()); }
</del><ins>+    void append(const AtomicString&amp; atomicString)
+    {
+        append(atomicString.string());
+    }
</ins><span class="cx"> 
</span><span class="cx">     void append(const String&amp; string)
</span><span class="cx">     {
</span><del>-        unsigned length = string.length();
-        if (!length)
</del><ins>+        if (!string.length())
</ins><span class="cx">             return;
</span><span class="cx"> 
</span><del>-        // If we're appending to an empty string, and there is not a buffer
-        // (reserveCapacity has not been called) then just retain the string.
</del><ins>+        // If we're appending to an empty string, and there is not a buffer (reserveCapacity has not been called)
+        // then just retain the string.
</ins><span class="cx">         if (!m_length &amp;&amp; !m_buffer) {
</span><span class="cx">             m_string = string;
</span><del>-            m_length = length;
-            m_is8Bit = string.is8Bit();
</del><ins>+            m_length = string.length();
+            m_is8Bit = m_string.is8Bit();
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         if (string.is8Bit())
</span><del>-            append(string.characters8(), length);
</del><ins>+            append(string.characters8(), string.length());
</ins><span class="cx">         else
</span><del>-            append(string.characters16(), length);
</del><ins>+            append(string.characters16(), string.length());
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     void append(const StringBuilder&amp; other)
</span><span class="lines">@@ -70,12 +80,11 @@
</span><span class="cx">         if (!other.m_length)
</span><span class="cx">             return;
</span><span class="cx"> 
</span><del>-        // If we're appending to an empty string, and there is not a buffer
-        // (reserveCapacity has not been called) then just retain the string.
</del><ins>+        // If we're appending to an empty string, and there is not a buffer (reserveCapacity has not been called)
+        // then just retain the string.
</ins><span class="cx">         if (!m_length &amp;&amp; !m_buffer &amp;&amp; !other.m_string.isNull()) {
</span><span class="cx">             m_string = other.m_string;
</span><span class="cx">             m_length = other.m_length;
</span><del>-            m_is8Bit = other.m_is8Bit;
</del><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -96,7 +105,6 @@
</span><span class="cx"> #if USE(CF)
</span><span class="cx">     WTF_EXPORT_PRIVATE void append(CFStringRef);
</span><span class="cx"> #endif
</span><del>-
</del><span class="cx"> #if USE(CF) &amp;&amp; defined(__OBJC__)
</span><span class="cx">     void append(NSString *string) { append((__bridge CFStringRef)string); }
</span><span class="cx"> #endif
</span><span class="lines">@@ -103,20 +111,11 @@
</span><span class="cx">     
</span><span class="cx">     void append(const String&amp; string, unsigned offset, unsigned length)
</span><span class="cx">     {
</span><del>-        ASSERT(offset &lt;= string.length());
-        ASSERT(offset + length &lt;= string.length());
-
-        if (!length)
</del><ins>+        if (!string.length())
</ins><span class="cx">             return;
</span><span class="cx"> 
</span><del>-        // If we're appending to an empty string, and there is not a buffer
-        // (reserveCapacity has not been called) then just retain the string.
-        if (!offset &amp;&amp; !m_length &amp;&amp; !m_buffer &amp;&amp; length == string.length()) {
-            m_string = string;
-            m_length = length;
-            m_is8Bit = string.is8Bit();
</del><ins>+        if ((offset + length) &gt; string.length())
</ins><span class="cx">             return;
</span><del>-        }
</del><span class="cx"> 
</span><span class="cx">         if (string.is8Bit())
</span><span class="cx">             append(string.characters8() + offset, length);
</span><span class="lines">@@ -130,33 +129,37 @@
</span><span class="cx">             append(characters, strlen(characters));
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void append(UChar character)
</del><ins>+    void append(UChar c)
</ins><span class="cx">     {
</span><span class="cx">         if (m_buffer &amp;&amp; m_length &lt; m_buffer-&gt;length() &amp;&amp; m_string.isNull()) {
</span><span class="cx">             if (!m_is8Bit) {
</span><del>-                m_bufferCharacters16[m_length++] = character;
</del><ins>+                m_bufferCharacters16[m_length++] = c;
</ins><span class="cx">                 return;
</span><span class="cx">             }
</span><del>-            if (!(character &amp; ~0xFF)) {
-                m_bufferCharacters8[m_length++] = static_cast&lt;LChar&gt;(character);
</del><ins>+
+            if (!(c &amp; ~0xff)) {
+                m_bufferCharacters8[m_length++] = static_cast&lt;LChar&gt;(c);
</ins><span class="cx">                 return;
</span><span class="cx">             }
</span><span class="cx">         }
</span><del>-        append(&amp;character, 1);
</del><ins>+        append(&amp;c, 1);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void append(LChar character)
</del><ins>+    void append(LChar c)
</ins><span class="cx">     {
</span><span class="cx">         if (m_buffer &amp;&amp; m_length &lt; m_buffer-&gt;length() &amp;&amp; m_string.isNull()) {
</span><span class="cx">             if (m_is8Bit)
</span><del>-                m_bufferCharacters8[m_length++] = character;
</del><ins>+                m_bufferCharacters8[m_length++] = c;
</ins><span class="cx">             else
</span><del>-                m_bufferCharacters16[m_length++] = character;
</del><ins>+                m_bufferCharacters16[m_length++] = c;
</ins><span class="cx">         } else
</span><del>-            append(&amp;character, 1);
</del><ins>+            append(&amp;c, 1);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void append(char character) { append(static_cast&lt;LChar&gt;(character)); }
</del><ins>+    void append(char c)
+    {
+        append(static_cast&lt;LChar&gt;(c));
+    }
</ins><span class="cx"> 
</span><span class="cx">     void append(UChar32 c)
</span><span class="cx">     {
</span><span class="lines">@@ -168,9 +171,10 @@
</span><span class="cx">         append(U16_TRAIL(c));
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    WTF_EXPORT_PRIVATE void appendQuotedJSONString(StringView);
</del><ins>+    WTF_EXPORT_PRIVATE void appendQuotedJSONString(const String&amp;);
</ins><span class="cx"> 
</span><del>-    template&lt;unsigned charactersCount&gt; ALWAYS_INLINE void appendLiteral(const char (&amp;characters)[charactersCount]) { append(characters, charactersCount - 1); }
</del><ins>+    template&lt;unsigned charactersCount&gt;
+    ALWAYS_INLINE void appendLiteral(const char (&amp;characters)[charactersCount]) { append(characters, charactersCount - 1); }
</ins><span class="cx"> 
</span><span class="cx">     WTF_EXPORT_PRIVATE void appendNumber(int);
</span><span class="cx">     WTF_EXPORT_PRIVATE void appendNumber(unsigned int);
</span><span class="lines">@@ -216,15 +220,24 @@
</span><span class="cx">         return AtomicString(m_buffer.get(), 0, m_length);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    unsigned length() const { return m_length; }
</del><ins>+    unsigned length() const
+    {
+        return m_length;
+    }
+
</ins><span class="cx">     bool isEmpty() const { return !m_length; }
</span><span class="cx"> 
</span><span class="cx">     WTF_EXPORT_PRIVATE void reserveCapacity(unsigned newCapacity);
</span><span class="cx"> 
</span><del>-    unsigned capacity() const { return m_buffer ? m_buffer-&gt;length() : m_length; }
</del><ins>+    unsigned capacity() const
+    {
+        return m_buffer ? m_buffer-&gt;length() : m_length;
+    }
</ins><span class="cx"> 
</span><span class="cx">     WTF_EXPORT_PRIVATE void resize(unsigned newSize);
</span><ins>+
</ins><span class="cx">     WTF_EXPORT_PRIVATE bool canShrink() const;
</span><ins>+
</ins><span class="cx">     WTF_EXPORT_PRIVATE void shrinkToFit();
</span><span class="cx"> 
</span><span class="cx">     UChar operator[](unsigned i) const
</span><span class="lines">@@ -281,36 +294,43 @@
</span><span class="cx"> private:
</span><span class="cx">     void allocateBuffer(const LChar* currentCharacters, unsigned requiredLength);
</span><span class="cx">     void allocateBuffer(const UChar* currentCharacters, unsigned requiredLength);
</span><del>-    void allocateBufferUpconvert(const LChar* currentCharacters, unsigned requiredLength);
-    template&lt;typename CharacterType&gt; void reallocateBuffer(unsigned requiredLength);
-    UChar* appendUninitializedUpconvert(unsigned length);
-    template&lt;typename CharacterType&gt; CharacterType* appendUninitialized(unsigned length);
-    template&lt;typename CharacterType&gt; CharacterType* appendUninitializedSlow(unsigned length);
-    template&lt;typename CharacterType&gt; CharacterType* bufferCharacters();
</del><ins>+    void allocateBufferUpConvert(const LChar* currentCharacters, unsigned requiredLength);
+    template &lt;typename CharType&gt;
+    void reallocateBuffer(unsigned requiredLength);
+    template &lt;typename CharType&gt;
+    ALWAYS_INLINE CharType* appendUninitialized(unsigned length);
+    template &lt;typename CharType&gt;
+    CharType* appendUninitializedSlow(unsigned length);
+    template &lt;typename CharType&gt;
+    ALWAYS_INLINE CharType * getBufferCharacters();
</ins><span class="cx">     WTF_EXPORT_PRIVATE void reifyString() const;
</span><span class="cx"> 
</span><del>-    unsigned m_length { 0 };
</del><ins>+    unsigned m_length;
</ins><span class="cx">     mutable String m_string;
</span><span class="cx">     RefPtr&lt;StringImpl&gt; m_buffer;
</span><del>-    bool m_is8Bit { true };
</del><ins>+    bool m_is8Bit;
</ins><span class="cx">     union {
</span><del>-        LChar* m_bufferCharacters8 { nullptr };
</del><ins>+        LChar* m_bufferCharacters8;
</ins><span class="cx">         UChar* m_bufferCharacters16;
</span><span class="cx">     };
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-template&lt;typename StringType&gt; bool equal(const StringBuilder&amp;, const StringType&amp;);
-bool equal(const StringBuilder&amp;, const String&amp;); // Only needed because is8Bit dereferences nullptr when the string is null.
-template&lt;typename CharacterType&gt; bool equal(const StringBuilder&amp;, const CharacterType*, unsigned length);
</del><ins>+template &lt;&gt;
+ALWAYS_INLINE LChar* StringBuilder::getBufferCharacters&lt;LChar&gt;()
+{
+    ASSERT(m_is8Bit);
+    return m_bufferCharacters8;
+}
</ins><span class="cx"> 
</span><del>-bool operator==(const StringBuilder&amp;, const StringBuilder&amp;);
-bool operator!=(const StringBuilder&amp;, const StringBuilder&amp;);
-bool operator==(const StringBuilder&amp;, const String&amp;);
-bool operator!=(const StringBuilder&amp;, const String&amp;);
-bool operator==(const String&amp;, const StringBuilder&amp;);
-bool operator!=(const String&amp;, const StringBuilder&amp;);
</del><ins>+template &lt;&gt;
+ALWAYS_INLINE UChar* StringBuilder::getBufferCharacters&lt;UChar&gt;()
+{
+    ASSERT(!m_is8Bit);
+    return m_bufferCharacters16;
+}    
</ins><span class="cx"> 
</span><del>-template&lt;typename CharacterType&gt; inline bool equal(const StringBuilder&amp; s, const CharacterType* buffer, unsigned length)
</del><ins>+template &lt;typename CharType&gt;
+bool equal(const StringBuilder&amp; s, const CharType* buffer, unsigned length)
</ins><span class="cx"> {
</span><span class="cx">     if (s.length() != length)
</span><span class="cx">         return false;
</span><span class="lines">@@ -321,14 +341,24 @@
</span><span class="cx">     return equal(s.characters16(), buffer, length);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-template&lt;typename StringType&gt; inline bool equal(const StringBuilder&amp; a, const StringType&amp; b)
</del><ins>+template &lt;typename StringType&gt;
+bool equal(const StringBuilder&amp; a, const StringType&amp; b)
</ins><span class="cx"> {
</span><del>-    return equalCommon(a, b);
-}
</del><ins>+    if (a.length() != b.length())
+        return false;
</ins><span class="cx"> 
</span><del>-inline bool equal(const StringBuilder&amp; a, const String&amp; b)
-{
-    return !b.isNull() &amp;&amp; equalCommon(a, b);
</del><ins>+    if (!a.length())
+        return true;
+
+    if (a.is8Bit()) {
+        if (b.is8Bit())
+            return equal(a.characters8(), b.characters8(), a.length());
+        return equal(a.characters8(), b.characters16(), a.length());
+    }
+
+    if (b.is8Bit())
+        return equal(a.characters16(), b.characters8(), a.length());
+    return equal(a.characters16(), b.characters16(), a.length());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> inline bool operator==(const StringBuilder&amp; a, const StringBuilder&amp; b) { return equal(a, b); }
</span><span class="lines">@@ -341,3 +371,5 @@
</span><span class="cx"> } // namespace WTF
</span><span class="cx"> 
</span><span class="cx"> using WTF::StringBuilder;
</span><ins>+
+#endif // StringBuilder_h
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WebCore/ChangeLog        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -1,3 +1,23 @@
</span><ins>+2016-11-29  Commit Queue  &lt;commit-queue@webkit.org&gt;
+
+        Unreviewed, rolling out r209058 and r209074.
+        https://bugs.webkit.org/show_bug.cgi?id=165188
+
+        These changes caused API test StringBuilderTest.Equal to crash
+        and/or fail. (Requested by ryanhaddad on #webkit).
+
+        Reverted changesets:
+
+        &quot;Streamline and speed up tokenizer and segmented string
+        classes&quot;
+        https://bugs.webkit.org/show_bug.cgi?id=165003
+        http://trac.webkit.org/changeset/209058
+
+        &quot;REGRESSION (r209058): API test StringBuilderTest.Equal
+        crashing&quot;
+        https://bugs.webkit.org/show_bug.cgi?id=165142
+        http://trac.webkit.org/changeset/209074
+
</ins><span class="cx"> 2016-11-29  Nan Wang  &lt;n_wang@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         AX: ARIA tree &amp; treeitem roles &amp; aria-expanded state not spoken to VoiceOver iOS 10
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSHTMLDocumentCustomcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSHTMLDocumentCustom.cpp (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSHTMLDocumentCustom.cpp        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WebCore/bindings/js/JSHTMLDocumentCustom.cpp        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2007-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2007-2009, 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -26,10 +26,24 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;JSHTMLDocument.h&quot;
</span><span class="cx"> 
</span><ins>+#include &quot;Frame.h&quot;
+#include &quot;HTMLCollection.h&quot;
+#include &quot;HTMLDocument.h&quot;
+#include &quot;HTMLElement.h&quot;
</ins><span class="cx"> #include &quot;HTMLIFrameElement.h&quot;
</span><ins>+#include &quot;HTMLNames.h&quot;
+#include &quot;JSDOMWindow.h&quot;
</ins><span class="cx"> #include &quot;JSDOMWindowCustom.h&quot;
</span><ins>+#include &quot;JSDOMWindowShell.h&quot;
+#include &quot;JSDocumentCustom.h&quot;
</ins><span class="cx"> #include &quot;JSHTMLCollection.h&quot;
</span><ins>+#include &quot;JSMainThreadExecState.h&quot;
</ins><span class="cx"> #include &quot;SegmentedString.h&quot;
</span><ins>+#include &quot;DocumentParser.h&quot;
+#include &lt;interpreter/StackVisitor.h&gt;
+#include &lt;runtime/Error.h&gt;
+#include &lt;runtime/JSCell.h&gt;
+#include &lt;wtf/unicode/CharacterNames.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> using namespace JSC;
</span><span class="cx"> 
</span><span class="lines">@@ -40,8 +54,10 @@
</span><span class="cx"> JSValue toJSNewlyCreated(ExecState* state, JSDOMGlobalObject* globalObject, Ref&lt;HTMLDocument&gt;&amp;&amp; passedDocument)
</span><span class="cx"> {
</span><span class="cx">     auto&amp; document = passedDocument.get();
</span><del>-    auto* wrapper = createWrapper&lt;HTMLDocument&gt;(globalObject, WTFMove(passedDocument));
</del><ins>+    JSObject* wrapper = createWrapper&lt;HTMLDocument&gt;(globalObject, WTFMove(passedDocument));
+
</ins><span class="cx">     reportMemoryForDocumentIfFrameless(*state, document);
</span><ins>+
</ins><span class="cx">     return wrapper;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -52,51 +68,52 @@
</span><span class="cx">     return toJSNewlyCreated(state, globalObject, Ref&lt;HTMLDocument&gt;(document));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool JSHTMLDocument::getOwnPropertySlot(JSObject* object, ExecState* state, PropertyName propertyName, PropertySlot&amp; slot)
</del><ins>+bool JSHTMLDocument::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot&amp; slot)
</ins><span class="cx"> {
</span><del>-    auto&amp; thisObject = *jsCast&lt;JSHTMLDocument*&gt;(object);
-    ASSERT_GC_OBJECT_INHERITS((&amp;thisObject), info());
</del><ins>+    JSHTMLDocument* thisObject = jsCast&lt;JSHTMLDocument*&gt;(object);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
</ins><span class="cx"> 
</span><span class="cx">     if (propertyName == &quot;open&quot;) {
</span><del>-        if (Base::getOwnPropertySlot(&amp;thisObject, state, propertyName, slot))
</del><ins>+        if (Base::getOwnPropertySlot(thisObject, exec, propertyName, slot))
</ins><span class="cx">             return true;
</span><del>-        slot.setCustom(&amp;thisObject, ReadOnly | DontDelete | DontEnum, nonCachingStaticFunctionGetter&lt;jsHTMLDocumentPrototypeFunctionOpen, 2&gt;);
</del><ins>+
+        slot.setCustom(thisObject, ReadOnly | DontDelete | DontEnum, nonCachingStaticFunctionGetter&lt;jsHTMLDocumentPrototypeFunctionOpen, 2&gt;);
</ins><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     JSValue value;
</span><del>-    if (thisObject.nameGetter(state, propertyName, value)) {
-        slot.setValue(&amp;thisObject, ReadOnly | DontDelete | DontEnum, value);
</del><ins>+    if (thisObject-&gt;nameGetter(exec, propertyName, value)) {
+        slot.setValue(thisObject, ReadOnly | DontDelete | DontEnum, value);
</ins><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    return Base::getOwnPropertySlot(&amp;thisObject, state, propertyName, slot);
</del><ins>+    return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool JSHTMLDocument::nameGetter(ExecState* state, PropertyName propertyName, JSValue&amp; value)
</del><ins>+bool JSHTMLDocument::nameGetter(ExecState* exec, PropertyName propertyName, JSValue&amp; value)
</ins><span class="cx"> {
</span><span class="cx">     auto&amp; document = wrapped();
</span><span class="cx"> 
</span><del>-    auto* atomicPropertyName = propertyName.publicName();
</del><ins>+    AtomicStringImpl* atomicPropertyName = propertyName.publicName();
</ins><span class="cx">     if (!atomicPropertyName || !document.hasDocumentNamedItem(*atomicPropertyName))
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="cx">     if (UNLIKELY(document.documentNamedItemContainsMultipleElements(*atomicPropertyName))) {
</span><del>-        auto collection = document.documentNamedItems(atomicPropertyName);
</del><ins>+        Ref&lt;HTMLCollection&gt; collection = document.documentNamedItems(atomicPropertyName);
</ins><span class="cx">         ASSERT(collection-&gt;length() &gt; 1);
</span><del>-        value = toJS(state, globalObject(), collection);
</del><ins>+        value = toJS(exec, globalObject(), collection);
</ins><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    auto&amp; element = *document.documentNamedItem(*atomicPropertyName);
</del><ins>+    Element&amp; element = *document.documentNamedItem(*atomicPropertyName);
</ins><span class="cx">     if (UNLIKELY(is&lt;HTMLIFrameElement&gt;(element))) {
</span><del>-        if (auto* frame = downcast&lt;HTMLIFrameElement&gt;(element).contentFrame()) {
-            value = toJS(state, frame);
</del><ins>+        if (Frame* frame = downcast&lt;HTMLIFrameElement&gt;(element).contentFrame()) {
+            value = toJS(exec, frame);
</ins><span class="cx">             return true;
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    value = toJS(state, globalObject(), element);
</del><ins>+    value = toJS(exec, globalObject(), element);
</ins><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -105,8 +122,9 @@
</span><span class="cx"> JSValue JSHTMLDocument::all(ExecState&amp; state) const
</span><span class="cx"> {
</span><span class="cx">     // If &quot;all&quot; has been overwritten, return the overwritten value
</span><del>-    if (auto overwrittenValue = getDirect(state.vm(), Identifier::fromString(&amp;state, &quot;all&quot;)))
-        return overwrittenValue;
</del><ins>+    JSValue v = getDirect(state.vm(), Identifier::fromString(&amp;state, &quot;all&quot;));
+    if (v)
+        return v;
</ins><span class="cx"> 
</span><span class="cx">     return toJS(&amp;state, globalObject(), wrapped().all());
</span><span class="cx"> }
</span><span class="lines">@@ -117,14 +135,15 @@
</span><span class="cx">     putDirect(state.vm(), Identifier::fromString(&amp;state, &quot;all&quot;), value);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static inline Document* findCallingDocument(ExecState&amp; state)
</del><ins>+static Document* findCallingDocument(ExecState&amp; state)
</ins><span class="cx"> {
</span><span class="cx">     CallerFunctor functor;
</span><span class="cx">     state.iterate(functor);
</span><del>-    auto* callerFrame = functor.callerFrame();
</del><ins>+    CallFrame* callerFrame = functor.callerFrame();
</ins><span class="cx">     if (!callerFrame)
</span><span class="cx">         return nullptr;
</span><del>-    return asJSDOMWindow(callerFrame-&gt;lexicalGlobalObject())-&gt;wrapped().document();
</del><ins>+
+    return asJSDOMWindow(functor.callerFrame()-&gt;lexicalGlobalObject())-&gt;wrapped().document();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // Custom functions
</span><span class="lines">@@ -136,11 +155,12 @@
</span><span class="cx"> 
</span><span class="cx">     // For compatibility with other browsers, pass open calls with more than 2 parameters to the window.
</span><span class="cx">     if (state.argumentCount() &gt; 2) {
</span><del>-        if (auto* frame = wrapped().frame()) {
-            if (auto* wrapper = toJSDOMWindowShell(frame, currentWorld(&amp;state))) {
-                auto function = wrapper-&gt;get(&amp;state, Identifier::fromString(&amp;state, &quot;open&quot;));
</del><ins>+        if (Frame* frame = wrapped().frame()) {
+            JSDOMWindowShell* wrapper = toJSDOMWindowShell(frame, currentWorld(&amp;state));
+            if (wrapper) {
+                JSValue function = wrapper-&gt;get(&amp;state, Identifier::fromString(&amp;state, &quot;open&quot;));
</ins><span class="cx">                 CallData callData;
</span><del>-                auto callType = ::getCallData(function, callData);
</del><ins>+                CallType callType = ::getCallData(function, callData);
</ins><span class="cx">                 if (callType == CallType::None)
</span><span class="cx">                     return throwTypeError(&amp;state, scope);
</span><span class="cx">                 return JSC::call(&amp;state, function, callType, callData, wrapper, ArgList(&amp;state));
</span><span class="lines">@@ -149,41 +169,53 @@
</span><span class="cx">         return jsUndefined();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // Calling document.open clobbers the security context of the document and aliases it with the active security context.
-    // FIXME: Is it correct that this does not use findCallingDocument as the write function below does?
-    wrapped().open(asJSDOMWindow(state.lexicalGlobalObject())-&gt;wrapped().document());
-    // FIXME: Why do we return the document instead of returning undefined?
</del><ins>+    // document.open clobbers the security context of the document and
+    // aliases it with the active security context.
+    Document* activeDocument = asJSDOMWindow(state.lexicalGlobalObject())-&gt;wrapped().document();
+
+    // In the case of two parameters or fewer, do a normal document open.
+    wrapped().open(activeDocument);
</ins><span class="cx">     return this;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> enum NewlineRequirement { DoNotAddNewline, DoAddNewline };
</span><span class="cx"> 
</span><del>-static inline JSValue documentWrite(ExecState&amp; state, JSHTMLDocument&amp; document, NewlineRequirement addNewline)
</del><ins>+static inline void documentWrite(ExecState&amp; state, JSHTMLDocument* thisDocument, NewlineRequirement addNewline)
</ins><span class="cx"> {
</span><del>-    VM&amp; vm = state.vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
</del><ins>+    HTMLDocument* document = &amp;thisDocument-&gt;wrapped();
+    // DOM only specifies single string argument, but browsers allow multiple or no arguments.
</ins><span class="cx"> 
</span><del>-    SegmentedString segmentedString;
-    size_t argumentCount = state.argumentCount();
-    for (size_t i = 0; i &lt; argumentCount; ++i) {
-        segmentedString.append(state.uncheckedArgument(i).toWTFString(&amp;state));
-        RETURN_IF_EXCEPTION(scope, { });
</del><ins>+    size_t size = state.argumentCount();
+
+    String firstString = state.argument(0).toString(&amp;state)-&gt;value(&amp;state);
+    SegmentedString segmentedString = firstString;
+    if (size != 1) {
+        if (!size)
+            segmentedString.clear();
+        else {
+            for (size_t i = 1; i &lt; size; ++i) {
+                String subsequentString = state.uncheckedArgument(i).toString(&amp;state)-&gt;value(&amp;state);
+                segmentedString.append(SegmentedString(subsequentString));
+            }
+        }
</ins><span class="cx">     }
</span><span class="cx">     if (addNewline)
</span><del>-        segmentedString.append(String { &quot;\n&quot; });
</del><ins>+        segmentedString.append(SegmentedString(String(&amp;newlineCharacter, 1)));
</ins><span class="cx"> 
</span><del>-    document.wrapped().write(WTFMove(segmentedString), findCallingDocument(state));
-    return jsUndefined();
</del><ins>+    Document* activeDocument = findCallingDocument(state);
+    document-&gt;write(segmentedString, activeDocument);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSValue JSHTMLDocument::write(ExecState&amp; state)
</span><span class="cx"> {
</span><del>-    return documentWrite(state, *this, DoNotAddNewline);
</del><ins>+    documentWrite(state, this, DoNotAddNewline);
+    return jsUndefined();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSValue JSHTMLDocument::writeln(ExecState&amp; state)
</span><span class="cx"> {
</span><del>-    return documentWrite(state, *this, DoAddNewline);
</del><ins>+    documentWrite(state, this, DoAddNewline);
+    return jsUndefined();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorecssparserCSSTokenizercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/parser/CSSTokenizer.cpp (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/parser/CSSTokenizer.cpp        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WebCore/css/parser/CSSTokenizer.cpp        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -35,7 +35,6 @@
</span><span class="cx"> #include &quot;CSSParserTokenRange.h&quot;
</span><span class="cx"> #include &quot;CSSTokenizerInputStream.h&quot;
</span><span class="cx"> #include &quot;HTMLParserIdioms.h&quot;
</span><del>-#include &lt;wtf/text/StringBuilder.h&gt;
</del><span class="cx"> #include &lt;wtf/unicode/CharacterNames.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span></span></pre></div>
<a id="trunkSourceWebCorecssparserCSSTokenizerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/parser/CSSTokenizer.h (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/parser/CSSTokenizer.h        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WebCore/css/parser/CSSTokenizer.h        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx"> #pragma once
</span><span class="cx"> 
</span><span class="cx"> #include &quot;CSSParserToken.h&quot;
</span><ins>+#include &quot;InputStreamPreprocessor.h&quot;
</ins><span class="cx"> #include &lt;climits&gt;
</span><span class="cx"> #include &lt;wtf/text/StringView.h&gt;
</span><span class="cx"> #include &lt;wtf/text/WTFString.h&gt;
</span></span></pre></div>
<a id="trunkSourceWebCorecssparserCSSTokenizerInputStreamh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/parser/CSSTokenizerInputStream.h (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/parser/CSSTokenizerInputStream.h        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WebCore/css/parser/CSSTokenizerInputStream.h        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -30,11 +30,10 @@
</span><span class="cx"> #pragma once
</span><span class="cx"> 
</span><span class="cx"> #include &lt;wtf/text/StringView.h&gt;
</span><ins>+#include &lt;wtf/text/WTFString.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-constexpr LChar kEndOfFileMarker = 0;
-
</del><span class="cx"> class CSSTokenizerInputStream {
</span><span class="cx">     WTF_MAKE_NONCOPYABLE(CSSTokenizerInputStream);
</span><span class="cx">     WTF_MAKE_FAST_ALLOCATED;
</span></span></pre></div>
<a id="trunkSourceWebCoredomDocumentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Document.cpp (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Document.cpp        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WebCore/dom/Document.cpp        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -2791,7 +2791,7 @@
</span><span class="cx">     return MonotonicTime::now() - m_documentCreationTime;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Document::write(SegmentedString&amp;&amp; text, Document* ownerDocument)
</del><ins>+void Document::write(const SegmentedString&amp; text, Document* ownerDocument)
</ins><span class="cx"> {
</span><span class="cx">     NestingLevelIncrementer nestingLevelIncrementer(m_writeRecursionDepth);
</span><span class="cx"> 
</span><span class="lines">@@ -2799,7 +2799,7 @@
</span><span class="cx">     m_writeRecursionIsTooDeep = (m_writeRecursionDepth &gt; cMaxWriteRecursionDepth) || m_writeRecursionIsTooDeep;
</span><span class="cx"> 
</span><span class="cx">     if (m_writeRecursionIsTooDeep)
</span><del>-        return;
</del><ins>+       return;
</ins><span class="cx"> 
</span><span class="cx">     bool hasInsertionPoint = m_parser &amp;&amp; m_parser-&gt;hasInsertionPoint();
</span><span class="cx">     if (!hasInsertionPoint &amp;&amp; (m_ignoreOpensDuringUnloadCount || m_ignoreDestructiveWriteCount))
</span><span class="lines">@@ -2809,19 +2809,18 @@
</span><span class="cx">         open(ownerDocument);
</span><span class="cx"> 
</span><span class="cx">     ASSERT(m_parser);
</span><del>-    m_parser-&gt;insert(WTFMove(text));
</del><ins>+    m_parser-&gt;insert(text);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Document::write(const String&amp; text, Document* ownerDocument)
</span><span class="cx"> {
</span><del>-    write(SegmentedString { text }, ownerDocument);
</del><ins>+    write(SegmentedString(text), ownerDocument);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Document::writeln(const String&amp; text, Document* ownerDocument)
</span><span class="cx"> {
</span><del>-    SegmentedString textWithNewline { text };
-    textWithNewline.append(String { &quot;\n&quot; });
-    write(WTFMove(textWithNewline), ownerDocument);
</del><ins>+    write(text, ownerDocument);
+    write(&quot;\n&quot;, ownerDocument);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> std::chrono::milliseconds Document::minimumTimerInterval() const
</span></span></pre></div>
<a id="trunkSourceWebCoredomDocumenth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Document.h (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Document.h        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WebCore/dom/Document.h        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -602,7 +602,7 @@
</span><span class="cx"> 
</span><span class="cx">     void cancelParsing();
</span><span class="cx"> 
</span><del>-    void write(SegmentedString&amp;&amp; text, Document* ownerDocument = nullptr);
</del><ins>+    void write(const SegmentedString&amp; text, Document* ownerDocument = nullptr);
</ins><span class="cx">     WEBCORE_EXPORT void write(const String&amp; text, Document* ownerDocument = nullptr);
</span><span class="cx">     WEBCORE_EXPORT void writeln(const String&amp; text, Document* ownerDocument = nullptr);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoredomDocumentParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/DocumentParser.h (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/DocumentParser.h        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WebCore/dom/DocumentParser.h        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -43,7 +43,7 @@
</span><span class="cx">     virtual bool hasInsertionPoint() { return true; }
</span><span class="cx"> 
</span><span class="cx">     // insert is used by document.write.
</span><del>-    virtual void insert(SegmentedString&amp;&amp;) = 0;
</del><ins>+    virtual void insert(const SegmentedString&amp;) = 0;
</ins><span class="cx"> 
</span><span class="cx">     // appendBytes and flush are used by DocumentWriter (the loader).
</span><span class="cx">     virtual void appendBytes(DocumentWriter&amp;, const char* bytes, size_t length) = 0;
</span></span></pre></div>
<a id="trunkSourceWebCoredomRawDataDocumentParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/RawDataDocumentParser.h (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/RawDataDocumentParser.h        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WebCore/dom/RawDataDocumentParser.h        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -49,7 +49,7 @@
</span><span class="cx">         appendBytes(writer, 0, 0);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void insert(SegmentedString&amp;&amp;) override
</del><ins>+    void insert(const SegmentedString&amp;) override
</ins><span class="cx">     {
</span><span class="cx">         // &lt;https://bugs.webkit.org/show_bug.cgi?id=25397&gt;: JS code can always call document.write, we need to handle it.
</span><span class="cx">         ASSERT_NOT_REACHED();
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlFTPDirectoryDocumentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/FTPDirectoryDocument.cpp (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/FTPDirectoryDocument.cpp        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WebCore/html/FTPDirectoryDocument.cpp        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -344,6 +344,8 @@
</span><span class="cx"> 
</span><span class="cx"> void FTPDirectoryDocumentParser::append(RefPtr&lt;StringImpl&gt;&amp;&amp; inputSource)
</span><span class="cx"> {
</span><ins>+    String source(WTFMove(inputSource));
+
</ins><span class="cx">     // Make sure we have the table element to append to by loading the template set in the pref, or
</span><span class="cx">     // creating a very basic document with the appropriate table
</span><span class="cx">     if (!m_tableElement) {
</span><span class="lines">@@ -355,9 +357,9 @@
</span><span class="cx">     bool foundNewLine = false;
</span><span class="cx"> 
</span><span class="cx">     m_dest = m_buffer;
</span><del>-    SegmentedString string { String { WTFMove(inputSource) } };
-    while (!string.isEmpty()) {
-        UChar c = string.currentCharacter();
</del><ins>+    SegmentedString str = source;
+    while (!str.isEmpty()) {
+        UChar c = str.currentChar();
</ins><span class="cx"> 
</span><span class="cx">         if (c == '\r') {
</span><span class="cx">             *m_dest++ = '\n';
</span><span class="lines">@@ -374,7 +376,7 @@
</span><span class="cx">             m_skipLF = false;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        string.advance();
</del><ins>+        str.advance();
</ins><span class="cx"> 
</span><span class="cx">         // Maybe enlarge the buffer
</span><span class="cx">         checkBuffer();
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlparserHTMLDocumentParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/parser/HTMLDocumentParser.cpp (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/parser/HTMLDocumentParser.cpp        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WebCore/html/parser/HTMLDocumentParser.cpp        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -328,7 +328,7 @@
</span><span class="cx">     return m_input.hasInsertionPoint() || (wasCreatedByScript() &amp;&amp; !m_input.haveSeenEndOfFile());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void HTMLDocumentParser::insert(SegmentedString&amp;&amp; source)
</del><ins>+void HTMLDocumentParser::insert(const SegmentedString&amp; source)
</ins><span class="cx"> {
</span><span class="cx">     if (isStopped())
</span><span class="cx">         return;
</span><span class="lines">@@ -337,8 +337,9 @@
</span><span class="cx">     // but we need to ensure it isn't deleted yet.
</span><span class="cx">     Ref&lt;HTMLDocumentParser&gt; protectedThis(*this);
</span><span class="cx"> 
</span><del>-    source.setExcludeLineNumbers();
-    m_input.insertAtCurrentInsertionPoint(WTFMove(source));
</del><ins>+    SegmentedString excludedLineNumberSource(source);
+    excludedLineNumberSource.setExcludeLineNumbers();
+    m_input.insertAtCurrentInsertionPoint(excludedLineNumberSource);
</ins><span class="cx">     pumpTokenizerIfPossible(ForceSynchronous);
</span><span class="cx"> 
</span><span class="cx">     if (isWaitingForScripts()) {
</span><span class="lines">@@ -362,7 +363,7 @@
</span><span class="cx">     // but we need to ensure it isn't deleted yet.
</span><span class="cx">     Ref&lt;HTMLDocumentParser&gt; protectedThis(*this);
</span><span class="cx"> 
</span><del>-    String source { WTFMove(inputSource) };
</del><ins>+    String source(WTFMove(inputSource));
</ins><span class="cx"> 
</span><span class="cx">     if (m_preloadScanner) {
</span><span class="cx">         if (m_input.current().isEmpty() &amp;&amp; !isWaitingForScripts()) {
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlparserHTMLDocumentParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/parser/HTMLDocumentParser.h (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/parser/HTMLDocumentParser.h        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WebCore/html/parser/HTMLDocumentParser.h        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -65,7 +65,7 @@
</span><span class="cx"> protected:
</span><span class="cx">     explicit HTMLDocumentParser(HTMLDocument&amp;);
</span><span class="cx"> 
</span><del>-    void insert(SegmentedString&amp;&amp;) final;
</del><ins>+    void insert(const SegmentedString&amp;) final;
</ins><span class="cx">     void append(RefPtr&lt;StringImpl&gt;&amp;&amp;) override;
</span><span class="cx">     void finish() override;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlparserHTMLEntityParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/parser/HTMLEntityParser.cpp (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/parser/HTMLEntityParser.cpp        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WebCore/html/parser/HTMLEntityParser.cpp        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -61,12 +61,12 @@
</span><span class="cx">         StringBuilder consumedCharacters;
</span><span class="cx">         HTMLEntitySearch entitySearch;
</span><span class="cx">         while (!source.isEmpty()) {
</span><del>-            cc = source.currentCharacter();
</del><ins>+            cc = source.currentChar();
</ins><span class="cx">             entitySearch.advance(cc);
</span><span class="cx">             if (!entitySearch.isEntityPrefix())
</span><span class="cx">                 break;
</span><span class="cx">             consumedCharacters.append(cc);
</span><del>-            source.advancePastNonNewline();
</del><ins>+            source.advance();
</ins><span class="cx">         }
</span><span class="cx">         notEnoughCharacters = source.isEmpty();
</span><span class="cx">         if (notEnoughCharacters) {
</span><span class="lines">@@ -88,13 +88,13 @@
</span><span class="cx">             const int length = entitySearch.mostRecentMatch()-&gt;length;
</span><span class="cx">             const LChar* reference = entitySearch.mostRecentMatch()-&gt;entity;
</span><span class="cx">             for (int i = 0; i &lt; length; ++i) {
</span><del>-                cc = source.currentCharacter();
</del><ins>+                cc = source.currentChar();
</ins><span class="cx">                 ASSERT_UNUSED(reference, cc == *reference++);
</span><span class="cx">                 consumedCharacters.append(cc);
</span><del>-                source.advancePastNonNewline();
</del><ins>+                source.advance();
</ins><span class="cx">                 ASSERT(!source.isEmpty());
</span><span class="cx">             }
</span><del>-            cc = source.currentCharacter();
</del><ins>+            cc = source.currentChar();
</ins><span class="cx">         }
</span><span class="cx">         if (entitySearch.mostRecentMatch()-&gt;lastCharacter() == ';'
</span><span class="cx">             || !additionalAllowedCharacter
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlparserHTMLInputStreamh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/parser/HTMLInputStream.h (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/parser/HTMLInputStream.h        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WebCore/html/parser/HTMLInputStream.h        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -25,6 +25,7 @@
</span><span class="cx"> 
</span><span class="cx"> #pragma once
</span><span class="cx"> 
</span><ins>+#include &quot;InputStreamPreprocessor.h&quot;
</ins><span class="cx"> #include &quot;SegmentedString.h&quot;
</span><span class="cx"> #include &lt;wtf/text/TextPosition.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -55,14 +56,14 @@
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void appendToEnd(SegmentedString&amp;&amp; string)
</del><ins>+    void appendToEnd(const SegmentedString&amp; string)
</ins><span class="cx">     {
</span><del>-        m_last-&gt;append(WTFMove(string));
</del><ins>+        m_last-&gt;append(string);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void insertAtCurrentInsertionPoint(SegmentedString&amp;&amp; string)
</del><ins>+    void insertAtCurrentInsertionPoint(const SegmentedString&amp; string)
</ins><span class="cx">     {
</span><del>-        m_first.append(WTFMove(string));
</del><ins>+        m_first.append(string);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     bool hasInsertionPoint() const
</span><span class="lines">@@ -72,7 +73,7 @@
</span><span class="cx"> 
</span><span class="cx">     void markEndOfFile()
</span><span class="cx">     {
</span><del>-        m_last-&gt;append(String { &amp;kEndOfFileMarker, 1 });
</del><ins>+        m_last-&gt;append(SegmentedString(String(&amp;kEndOfFileMarker, 1)));
</ins><span class="cx">         m_last-&gt;close();
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -91,7 +92,8 @@
</span><span class="cx"> 
</span><span class="cx">     void splitInto(SegmentedString&amp; next)
</span><span class="cx">     {
</span><del>-        next = WTFMove(m_first);
</del><ins>+        next = m_first;
+        m_first = SegmentedString();
</ins><span class="cx">         if (m_last == &amp;m_first) {
</span><span class="cx">             // We used to only have one SegmentedString in the InputStream
</span><span class="cx">             // but now we have two.  That means m_first is no longer also
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlparserHTMLMetaCharsetParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/parser/HTMLMetaCharsetParser.cpp (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/parser/HTMLMetaCharsetParser.cpp        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WebCore/html/parser/HTMLMetaCharsetParser.cpp        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -1,6 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  * Copyright (C) 2010 Google Inc. All Rights Reserved.
</span><del>- * Copyright (C) 2015-2016 Apple Inc. All Rights Reserved.
</del><ins>+ * Copyright (C) 2015 Apple Inc. All Rights Reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -151,9 +151,9 @@
</span><span class="cx">     // that are disallowed in &lt;head&gt;, we don't bail out until we've checked at
</span><span class="cx">     // least bytesToCheckUnconditionally bytes of input.
</span><span class="cx"> 
</span><del>-    constexpr int bytesToCheckUnconditionally = 1024;
</del><ins>+    static const int bytesToCheckUnconditionally = 1024;
</ins><span class="cx"> 
</span><del>-    m_input.append(m_codec-&gt;decode(data, length));
</del><ins>+    m_input.append(SegmentedString(m_codec-&gt;decode(data, length)));
</ins><span class="cx"> 
</span><span class="cx">     while (auto token = m_tokenizer.nextToken(m_input)) {
</span><span class="cx">         bool isEnd = token-&gt;type() == HTMLToken::EndTag;
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlparserHTMLSourceTrackercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/parser/HTMLSourceTracker.cpp (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/parser/HTMLSourceTracker.cpp        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WebCore/html/parser/HTMLSourceTracker.cpp        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -32,6 +32,10 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><ins>+HTMLSourceTracker::HTMLSourceTracker()
+{
+}
+
</ins><span class="cx"> void HTMLSourceTracker::startToken(SegmentedString&amp; currentInput, HTMLTokenizer&amp; tokenizer)
</span><span class="cx"> {
</span><span class="cx">     if (!m_started) {
</span><span class="lines">@@ -74,12 +78,12 @@
</span><span class="cx"> 
</span><span class="cx">     unsigned i = 0;
</span><span class="cx">     for ( ; i &lt; length &amp;&amp; !m_previousSource.isEmpty(); ++i) {
</span><del>-        source.append(m_previousSource.currentCharacter());
</del><ins>+        source.append(m_previousSource.currentChar());
</ins><span class="cx">         m_previousSource.advance();
</span><span class="cx">     }
</span><span class="cx">     for ( ; i &lt; length; ++i) {
</span><span class="cx">         ASSERT(!m_currentSource.isEmpty());
</span><del>-        source.append(m_currentSource.currentCharacter());
</del><ins>+        source.append(m_currentSource.currentChar());
</ins><span class="cx">         m_currentSource.advance();
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlparserHTMLSourceTrackerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/parser/HTMLSourceTracker.h (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/parser/HTMLSourceTracker.h        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WebCore/html/parser/HTMLSourceTracker.h        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -36,7 +36,7 @@
</span><span class="cx"> class HTMLSourceTracker {
</span><span class="cx">     WTF_MAKE_NONCOPYABLE(HTMLSourceTracker);
</span><span class="cx"> public:
</span><del>-    HTMLSourceTracker() = default;
</del><ins>+    HTMLSourceTracker();
</ins><span class="cx"> 
</span><span class="cx">     void startToken(SegmentedString&amp;, HTMLTokenizer&amp;);
</span><span class="cx">     void endToken(SegmentedString&amp;, HTMLTokenizer&amp;);
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlparserHTMLTokenizercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/parser/HTMLTokenizer.cpp (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/parser/HTMLTokenizer.cpp        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WebCore/html/parser/HTMLTokenizer.cpp        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2008-2016 Apple Inc. All Rights Reserved.
</del><ins>+ * Copyright (C) 2008, 2015 Apple Inc. All Rights Reserved.
</ins><span class="cx">  * Copyright (C) 2009 Torch Mobile, Inc. http://www.torchmobile.com/
</span><span class="cx">  * Copyright (C) 2010 Google, Inc. All Rights Reserved.
</span><span class="cx">  *
</span><span class="lines">@@ -31,7 +31,7 @@
</span><span class="cx"> #include &quot;HTMLEntityParser.h&quot;
</span><span class="cx"> #include &quot;HTMLNames.h&quot;
</span><span class="cx"> #include &quot;MarkupTokenizerInlines.h&quot;
</span><del>-#include &lt;wtf/text/StringBuilder.h&gt;
</del><ins>+#include &lt;wtf/ASCIICType.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> using namespace WTF;
</span><span class="cx"> 
</span><span class="lines">@@ -96,7 +96,7 @@
</span><span class="cx"> {
</span><span class="cx">     saveEndTagNameIfNeeded();
</span><span class="cx">     m_state = DataState;
</span><del>-    source.advancePastNonNewline();
</del><ins>+    source.advanceAndUpdateLineNumber();
</ins><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -157,9 +157,9 @@
</span><span class="cx"> 
</span><span class="cx"> bool HTMLTokenizer::commitToPartialEndTag(SegmentedString&amp; source, UChar character, State state)
</span><span class="cx"> {
</span><del>-    ASSERT(source.currentCharacter() == character);
</del><ins>+    ASSERT(source.currentChar() == character);
</ins><span class="cx">     appendToTemporaryBuffer(character);
</span><del>-    source.advancePastNonNewline();
</del><ins>+    source.advanceAndUpdateLineNumber();
</ins><span class="cx"> 
</span><span class="cx">     if (haveBufferedCharacterToken()) {
</span><span class="cx">         // Emit the buffered character token.
</span><span class="lines">@@ -174,9 +174,9 @@
</span><span class="cx"> 
</span><span class="cx"> bool HTMLTokenizer::commitToCompleteEndTag(SegmentedString&amp; source)
</span><span class="cx"> {
</span><del>-    ASSERT(source.currentCharacter() == '&gt;');
</del><ins>+    ASSERT(source.currentChar() == '&gt;');
</ins><span class="cx">     appendToTemporaryBuffer('&gt;');
</span><del>-    source.advancePastNonNewline();
</del><ins>+    source.advance();
</ins><span class="cx"> 
</span><span class="cx">     m_state = DataState;
</span><span class="cx"> 
</span><span class="lines">@@ -212,11 +212,11 @@
</span><span class="cx"> 
</span><span class="cx">     BEGIN_STATE(DataState)
</span><span class="cx">         if (character == '&amp;')
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(CharacterReferenceInDataState);
</del><ins>+            ADVANCE_TO(CharacterReferenceInDataState);
</ins><span class="cx">         if (character == '&lt;') {
</span><span class="cx">             if (haveBufferedCharacterToken())
</span><span class="cx">                 RETURN_IN_CURRENT_STATE(true);
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(TagOpenState);
</del><ins>+            ADVANCE_TO(TagOpenState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == kEndOfFileMarker)
</span><span class="cx">             return emitEndOfFile(source);
</span><span class="lines">@@ -232,9 +232,9 @@
</span><span class="cx"> 
</span><span class="cx">     BEGIN_STATE(RCDATAState)
</span><span class="cx">         if (character == '&amp;')
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(CharacterReferenceInRCDATAState);
</del><ins>+            ADVANCE_TO(CharacterReferenceInRCDATAState);
</ins><span class="cx">         if (character == '&lt;')
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(RCDATALessThanSignState);
</del><ins>+            ADVANCE_TO(RCDATALessThanSignState);
</ins><span class="cx">         if (character == kEndOfFileMarker)
</span><span class="cx">             RECONSUME_IN(DataState);
</span><span class="cx">         bufferCharacter(character);
</span><span class="lines">@@ -249,7 +249,7 @@
</span><span class="cx"> 
</span><span class="cx">     BEGIN_STATE(RAWTEXTState)
</span><span class="cx">         if (character == '&lt;')
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(RAWTEXTLessThanSignState);
</del><ins>+            ADVANCE_TO(RAWTEXTLessThanSignState);
</ins><span class="cx">         if (character == kEndOfFileMarker)
</span><span class="cx">             RECONSUME_IN(DataState);
</span><span class="cx">         bufferCharacter(character);
</span><span class="lines">@@ -258,7 +258,7 @@
</span><span class="cx"> 
</span><span class="cx">     BEGIN_STATE(ScriptDataState)
</span><span class="cx">         if (character == '&lt;')
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(ScriptDataLessThanSignState);
</del><ins>+            ADVANCE_TO(ScriptDataLessThanSignState);
</ins><span class="cx">         if (character == kEndOfFileMarker)
</span><span class="cx">             RECONSUME_IN(DataState);
</span><span class="cx">         bufferCharacter(character);
</span><span class="lines">@@ -274,12 +274,12 @@
</span><span class="cx"> 
</span><span class="cx">     BEGIN_STATE(TagOpenState)
</span><span class="cx">         if (character == '!')
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(MarkupDeclarationOpenState);
</del><ins>+            ADVANCE_TO(MarkupDeclarationOpenState);
</ins><span class="cx">         if (character == '/')
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(EndTagOpenState);
</del><ins>+            ADVANCE_TO(EndTagOpenState);
</ins><span class="cx">         if (isASCIIAlpha(character)) {
</span><span class="cx">             m_token.beginStartTag(convertASCIIAlphaToLower(character));
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(TagNameState);
</del><ins>+            ADVANCE_TO(TagNameState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == '?') {
</span><span class="cx">             parseError();
</span><span class="lines">@@ -297,11 +297,11 @@
</span><span class="cx">         if (isASCIIAlpha(character)) {
</span><span class="cx">             m_token.beginEndTag(convertASCIIAlphaToLower(character));
</span><span class="cx">             m_appropriateEndTagName.clear();
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(TagNameState);
</del><ins>+            ADVANCE_TO(TagNameState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == '&gt;') {
</span><span class="cx">             parseError();
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(DataState);
</del><ins>+            ADVANCE_TO(DataState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == kEndOfFileMarker) {
</span><span class="cx">             parseError();
</span><span class="lines">@@ -317,7 +317,7 @@
</span><span class="cx">         if (isTokenizerWhitespace(character))
</span><span class="cx">             ADVANCE_TO(BeforeAttributeNameState);
</span><span class="cx">         if (character == '/')
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(SelfClosingStartTagState);
</del><ins>+            ADVANCE_TO(SelfClosingStartTagState);
</ins><span class="cx">         if (character == '&gt;')
</span><span class="cx">             return emitAndResumeInDataState(source);
</span><span class="cx">         if (m_options.usePreHTML5ParserQuirks &amp;&amp; character == '&lt;')
</span><span class="lines">@@ -327,7 +327,7 @@
</span><span class="cx">             RECONSUME_IN(DataState);
</span><span class="cx">         }
</span><span class="cx">         m_token.appendToName(toASCIILower(character));
</span><del>-        ADVANCE_PAST_NON_NEWLINE_TO(TagNameState);
</del><ins>+        ADVANCE_TO(TagNameState);
</ins><span class="cx">     END_STATE()
</span><span class="cx"> 
</span><span class="cx">     BEGIN_STATE(RCDATALessThanSignState)
</span><span class="lines">@@ -334,7 +334,7 @@
</span><span class="cx">         if (character == '/') {
</span><span class="cx">             m_temporaryBuffer.clear();
</span><span class="cx">             ASSERT(m_bufferedEndTagName.isEmpty());
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(RCDATAEndTagOpenState);
</del><ins>+            ADVANCE_TO(RCDATAEndTagOpenState);
</ins><span class="cx">         }
</span><span class="cx">         bufferASCIICharacter('&lt;');
</span><span class="cx">         RECONSUME_IN(RCDATAState);
</span><span class="lines">@@ -344,7 +344,7 @@
</span><span class="cx">         if (isASCIIAlpha(character)) {
</span><span class="cx">             appendToTemporaryBuffer(character);
</span><span class="cx">             appendToPossibleEndTag(convertASCIIAlphaToLower(character));
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(RCDATAEndTagNameState);
</del><ins>+            ADVANCE_TO(RCDATAEndTagNameState);
</ins><span class="cx">         }
</span><span class="cx">         bufferASCIICharacter('&lt;');
</span><span class="cx">         bufferASCIICharacter('/');
</span><span class="lines">@@ -355,7 +355,7 @@
</span><span class="cx">         if (isASCIIAlpha(character)) {
</span><span class="cx">             appendToTemporaryBuffer(character);
</span><span class="cx">             appendToPossibleEndTag(convertASCIIAlphaToLower(character));
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(RCDATAEndTagNameState);
</del><ins>+            ADVANCE_TO(RCDATAEndTagNameState);
</ins><span class="cx">         }
</span><span class="cx">         if (isTokenizerWhitespace(character)) {
</span><span class="cx">             if (isAppropriateEndTag()) {
</span><span class="lines">@@ -385,7 +385,7 @@
</span><span class="cx">         if (character == '/') {
</span><span class="cx">             m_temporaryBuffer.clear();
</span><span class="cx">             ASSERT(m_bufferedEndTagName.isEmpty());
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(RAWTEXTEndTagOpenState);
</del><ins>+            ADVANCE_TO(RAWTEXTEndTagOpenState);
</ins><span class="cx">         }
</span><span class="cx">         bufferASCIICharacter('&lt;');
</span><span class="cx">         RECONSUME_IN(RAWTEXTState);
</span><span class="lines">@@ -395,7 +395,7 @@
</span><span class="cx">         if (isASCIIAlpha(character)) {
</span><span class="cx">             appendToTemporaryBuffer(character);
</span><span class="cx">             appendToPossibleEndTag(convertASCIIAlphaToLower(character));
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(RAWTEXTEndTagNameState);
</del><ins>+            ADVANCE_TO(RAWTEXTEndTagNameState);
</ins><span class="cx">         }
</span><span class="cx">         bufferASCIICharacter('&lt;');
</span><span class="cx">         bufferASCIICharacter('/');
</span><span class="lines">@@ -406,7 +406,7 @@
</span><span class="cx">         if (isASCIIAlpha(character)) {
</span><span class="cx">             appendToTemporaryBuffer(character);
</span><span class="cx">             appendToPossibleEndTag(convertASCIIAlphaToLower(character));
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(RAWTEXTEndTagNameState);
</del><ins>+            ADVANCE_TO(RAWTEXTEndTagNameState);
</ins><span class="cx">         }
</span><span class="cx">         if (isTokenizerWhitespace(character)) {
</span><span class="cx">             if (isAppropriateEndTag()) {
</span><span class="lines">@@ -436,12 +436,12 @@
</span><span class="cx">         if (character == '/') {
</span><span class="cx">             m_temporaryBuffer.clear();
</span><span class="cx">             ASSERT(m_bufferedEndTagName.isEmpty());
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(ScriptDataEndTagOpenState);
</del><ins>+            ADVANCE_TO(ScriptDataEndTagOpenState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == '!') {
</span><span class="cx">             bufferASCIICharacter('&lt;');
</span><span class="cx">             bufferASCIICharacter('!');
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(ScriptDataEscapeStartState);
</del><ins>+            ADVANCE_TO(ScriptDataEscapeStartState);
</ins><span class="cx">         }
</span><span class="cx">         bufferASCIICharacter('&lt;');
</span><span class="cx">         RECONSUME_IN(ScriptDataState);
</span><span class="lines">@@ -451,7 +451,7 @@
</span><span class="cx">         if (isASCIIAlpha(character)) {
</span><span class="cx">             appendToTemporaryBuffer(character);
</span><span class="cx">             appendToPossibleEndTag(convertASCIIAlphaToLower(character));
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(ScriptDataEndTagNameState);
</del><ins>+            ADVANCE_TO(ScriptDataEndTagNameState);
</ins><span class="cx">         }
</span><span class="cx">         bufferASCIICharacter('&lt;');
</span><span class="cx">         bufferASCIICharacter('/');
</span><span class="lines">@@ -462,7 +462,7 @@
</span><span class="cx">         if (isASCIIAlpha(character)) {
</span><span class="cx">             appendToTemporaryBuffer(character);
</span><span class="cx">             appendToPossibleEndTag(convertASCIIAlphaToLower(character));
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(ScriptDataEndTagNameState);
</del><ins>+            ADVANCE_TO(ScriptDataEndTagNameState);
</ins><span class="cx">         }
</span><span class="cx">         if (isTokenizerWhitespace(character)) {
</span><span class="cx">             if (isAppropriateEndTag()) {
</span><span class="lines">@@ -491,7 +491,7 @@
</span><span class="cx">     BEGIN_STATE(ScriptDataEscapeStartState)
</span><span class="cx">         if (character == '-') {
</span><span class="cx">             bufferASCIICharacter('-');
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(ScriptDataEscapeStartDashState);
</del><ins>+            ADVANCE_TO(ScriptDataEscapeStartDashState);
</ins><span class="cx">         } else
</span><span class="cx">             RECONSUME_IN(ScriptDataState);
</span><span class="cx">     END_STATE()
</span><span class="lines">@@ -499,7 +499,7 @@
</span><span class="cx">     BEGIN_STATE(ScriptDataEscapeStartDashState)
</span><span class="cx">         if (character == '-') {
</span><span class="cx">             bufferASCIICharacter('-');
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(ScriptDataEscapedDashDashState);
</del><ins>+            ADVANCE_TO(ScriptDataEscapedDashDashState);
</ins><span class="cx">         } else
</span><span class="cx">             RECONSUME_IN(ScriptDataState);
</span><span class="cx">     END_STATE()
</span><span class="lines">@@ -507,10 +507,10 @@
</span><span class="cx">     BEGIN_STATE(ScriptDataEscapedState)
</span><span class="cx">         if (character == '-') {
</span><span class="cx">             bufferASCIICharacter('-');
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(ScriptDataEscapedDashState);
</del><ins>+            ADVANCE_TO(ScriptDataEscapedDashState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == '&lt;')
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(ScriptDataEscapedLessThanSignState);
</del><ins>+            ADVANCE_TO(ScriptDataEscapedLessThanSignState);
</ins><span class="cx">         if (character == kEndOfFileMarker) {
</span><span class="cx">             parseError();
</span><span class="cx">             RECONSUME_IN(DataState);
</span><span class="lines">@@ -522,10 +522,10 @@
</span><span class="cx">     BEGIN_STATE(ScriptDataEscapedDashState)
</span><span class="cx">         if (character == '-') {
</span><span class="cx">             bufferASCIICharacter('-');
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(ScriptDataEscapedDashDashState);
</del><ins>+            ADVANCE_TO(ScriptDataEscapedDashDashState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == '&lt;')
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(ScriptDataEscapedLessThanSignState);
</del><ins>+            ADVANCE_TO(ScriptDataEscapedLessThanSignState);
</ins><span class="cx">         if (character == kEndOfFileMarker) {
</span><span class="cx">             parseError();
</span><span class="cx">             RECONSUME_IN(DataState);
</span><span class="lines">@@ -537,13 +537,13 @@
</span><span class="cx">     BEGIN_STATE(ScriptDataEscapedDashDashState)
</span><span class="cx">         if (character == '-') {
</span><span class="cx">             bufferASCIICharacter('-');
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(ScriptDataEscapedDashDashState);
</del><ins>+            ADVANCE_TO(ScriptDataEscapedDashDashState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == '&lt;')
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(ScriptDataEscapedLessThanSignState);
</del><ins>+            ADVANCE_TO(ScriptDataEscapedLessThanSignState);
</ins><span class="cx">         if (character == '&gt;') {
</span><span class="cx">             bufferASCIICharacter('&gt;');
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(ScriptDataState);
</del><ins>+            ADVANCE_TO(ScriptDataState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == kEndOfFileMarker) {
</span><span class="cx">             parseError();
</span><span class="lines">@@ -557,7 +557,7 @@
</span><span class="cx">         if (character == '/') {
</span><span class="cx">             m_temporaryBuffer.clear();
</span><span class="cx">             ASSERT(m_bufferedEndTagName.isEmpty());
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(ScriptDataEscapedEndTagOpenState);
</del><ins>+            ADVANCE_TO(ScriptDataEscapedEndTagOpenState);
</ins><span class="cx">         }
</span><span class="cx">         if (isASCIIAlpha(character)) {
</span><span class="cx">             bufferASCIICharacter('&lt;');
</span><span class="lines">@@ -564,7 +564,7 @@
</span><span class="cx">             bufferASCIICharacter(character);
</span><span class="cx">             m_temporaryBuffer.clear();
</span><span class="cx">             appendToTemporaryBuffer(convertASCIIAlphaToLower(character));
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(ScriptDataDoubleEscapeStartState);
</del><ins>+            ADVANCE_TO(ScriptDataDoubleEscapeStartState);
</ins><span class="cx">         }
</span><span class="cx">         bufferASCIICharacter('&lt;');
</span><span class="cx">         RECONSUME_IN(ScriptDataEscapedState);
</span><span class="lines">@@ -574,7 +574,7 @@
</span><span class="cx">         if (isASCIIAlpha(character)) {
</span><span class="cx">             appendToTemporaryBuffer(character);
</span><span class="cx">             appendToPossibleEndTag(convertASCIIAlphaToLower(character));
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(ScriptDataEscapedEndTagNameState);
</del><ins>+            ADVANCE_TO(ScriptDataEscapedEndTagNameState);
</ins><span class="cx">         }
</span><span class="cx">         bufferASCIICharacter('&lt;');
</span><span class="cx">         bufferASCIICharacter('/');
</span><span class="lines">@@ -585,7 +585,7 @@
</span><span class="cx">         if (isASCIIAlpha(character)) {
</span><span class="cx">             appendToTemporaryBuffer(character);
</span><span class="cx">             appendToPossibleEndTag(convertASCIIAlphaToLower(character));
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(ScriptDataEscapedEndTagNameState);
</del><ins>+            ADVANCE_TO(ScriptDataEscapedEndTagNameState);
</ins><span class="cx">         }
</span><span class="cx">         if (isTokenizerWhitespace(character)) {
</span><span class="cx">             if (isAppropriateEndTag()) {
</span><span class="lines">@@ -622,7 +622,7 @@
</span><span class="cx">         if (isASCIIAlpha(character)) {
</span><span class="cx">             bufferASCIICharacter(character);
</span><span class="cx">             appendToTemporaryBuffer(convertASCIIAlphaToLower(character));
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(ScriptDataDoubleEscapeStartState);
</del><ins>+            ADVANCE_TO(ScriptDataDoubleEscapeStartState);
</ins><span class="cx">         }
</span><span class="cx">         RECONSUME_IN(ScriptDataEscapedState);
</span><span class="cx">     END_STATE()
</span><span class="lines">@@ -630,11 +630,11 @@
</span><span class="cx">     BEGIN_STATE(ScriptDataDoubleEscapedState)
</span><span class="cx">         if (character == '-') {
</span><span class="cx">             bufferASCIICharacter('-');
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(ScriptDataDoubleEscapedDashState);
</del><ins>+            ADVANCE_TO(ScriptDataDoubleEscapedDashState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == '&lt;') {
</span><span class="cx">             bufferASCIICharacter('&lt;');
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(ScriptDataDoubleEscapedLessThanSignState);
</del><ins>+            ADVANCE_TO(ScriptDataDoubleEscapedLessThanSignState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == kEndOfFileMarker) {
</span><span class="cx">             parseError();
</span><span class="lines">@@ -647,11 +647,11 @@
</span><span class="cx">     BEGIN_STATE(ScriptDataDoubleEscapedDashState)
</span><span class="cx">         if (character == '-') {
</span><span class="cx">             bufferASCIICharacter('-');
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(ScriptDataDoubleEscapedDashDashState);
</del><ins>+            ADVANCE_TO(ScriptDataDoubleEscapedDashDashState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == '&lt;') {
</span><span class="cx">             bufferASCIICharacter('&lt;');
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(ScriptDataDoubleEscapedLessThanSignState);
</del><ins>+            ADVANCE_TO(ScriptDataDoubleEscapedLessThanSignState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == kEndOfFileMarker) {
</span><span class="cx">             parseError();
</span><span class="lines">@@ -664,15 +664,15 @@
</span><span class="cx">     BEGIN_STATE(ScriptDataDoubleEscapedDashDashState)
</span><span class="cx">         if (character == '-') {
</span><span class="cx">             bufferASCIICharacter('-');
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(ScriptDataDoubleEscapedDashDashState);
</del><ins>+            ADVANCE_TO(ScriptDataDoubleEscapedDashDashState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == '&lt;') {
</span><span class="cx">             bufferASCIICharacter('&lt;');
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(ScriptDataDoubleEscapedLessThanSignState);
</del><ins>+            ADVANCE_TO(ScriptDataDoubleEscapedLessThanSignState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == '&gt;') {
</span><span class="cx">             bufferASCIICharacter('&gt;');
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(ScriptDataState);
</del><ins>+            ADVANCE_TO(ScriptDataState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == kEndOfFileMarker) {
</span><span class="cx">             parseError();
</span><span class="lines">@@ -686,7 +686,7 @@
</span><span class="cx">         if (character == '/') {
</span><span class="cx">             bufferASCIICharacter('/');
</span><span class="cx">             m_temporaryBuffer.clear();
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(ScriptDataDoubleEscapeEndState);
</del><ins>+            ADVANCE_TO(ScriptDataDoubleEscapeEndState);
</ins><span class="cx">         }
</span><span class="cx">         RECONSUME_IN(ScriptDataDoubleEscapedState);
</span><span class="cx">     END_STATE()
</span><span class="lines">@@ -702,7 +702,7 @@
</span><span class="cx">         if (isASCIIAlpha(character)) {
</span><span class="cx">             bufferASCIICharacter(character);
</span><span class="cx">             appendToTemporaryBuffer(convertASCIIAlphaToLower(character));
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(ScriptDataDoubleEscapeEndState);
</del><ins>+            ADVANCE_TO(ScriptDataDoubleEscapeEndState);
</ins><span class="cx">         }
</span><span class="cx">         RECONSUME_IN(ScriptDataDoubleEscapedState);
</span><span class="cx">     END_STATE()
</span><span class="lines">@@ -711,7 +711,7 @@
</span><span class="cx">         if (isTokenizerWhitespace(character))
</span><span class="cx">             ADVANCE_TO(BeforeAttributeNameState);
</span><span class="cx">         if (character == '/')
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(SelfClosingStartTagState);
</del><ins>+            ADVANCE_TO(SelfClosingStartTagState);
</ins><span class="cx">         if (character == '&gt;')
</span><span class="cx">             return emitAndResumeInDataState(source);
</span><span class="cx">         if (m_options.usePreHTML5ParserQuirks &amp;&amp; character == '&lt;')
</span><span class="lines">@@ -724,7 +724,7 @@
</span><span class="cx">             parseError();
</span><span class="cx">         m_token.beginAttribute(source.numberOfCharactersConsumed());
</span><span class="cx">         m_token.appendToAttributeName(toASCIILower(character));
</span><del>-        ADVANCE_PAST_NON_NEWLINE_TO(AttributeNameState);
</del><ins>+        ADVANCE_TO(AttributeNameState);
</ins><span class="cx">     END_STATE()
</span><span class="cx"> 
</span><span class="cx">     BEGIN_STATE(AttributeNameState)
</span><span class="lines">@@ -731,9 +731,9 @@
</span><span class="cx">         if (isTokenizerWhitespace(character))
</span><span class="cx">             ADVANCE_TO(AfterAttributeNameState);
</span><span class="cx">         if (character == '/')
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(SelfClosingStartTagState);
</del><ins>+            ADVANCE_TO(SelfClosingStartTagState);
</ins><span class="cx">         if (character == '=')
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(BeforeAttributeValueState);
</del><ins>+            ADVANCE_TO(BeforeAttributeValueState);
</ins><span class="cx">         if (character == '&gt;')
</span><span class="cx">             return emitAndResumeInDataState(source);
</span><span class="cx">         if (m_options.usePreHTML5ParserQuirks &amp;&amp; character == '&lt;')
</span><span class="lines">@@ -745,7 +745,7 @@
</span><span class="cx">         if (character == '&quot;' || character == '\'' || character == '&lt;' || character == '=')
</span><span class="cx">             parseError();
</span><span class="cx">         m_token.appendToAttributeName(toASCIILower(character));
</span><del>-        ADVANCE_PAST_NON_NEWLINE_TO(AttributeNameState);
</del><ins>+        ADVANCE_TO(AttributeNameState);
</ins><span class="cx">     END_STATE()
</span><span class="cx"> 
</span><span class="cx">     BEGIN_STATE(AfterAttributeNameState)
</span><span class="lines">@@ -752,9 +752,9 @@
</span><span class="cx">         if (isTokenizerWhitespace(character))
</span><span class="cx">             ADVANCE_TO(AfterAttributeNameState);
</span><span class="cx">         if (character == '/')
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(SelfClosingStartTagState);
</del><ins>+            ADVANCE_TO(SelfClosingStartTagState);
</ins><span class="cx">         if (character == '=')
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(BeforeAttributeValueState);
</del><ins>+            ADVANCE_TO(BeforeAttributeValueState);
</ins><span class="cx">         if (character == '&gt;')
</span><span class="cx">             return emitAndResumeInDataState(source);
</span><span class="cx">         if (m_options.usePreHTML5ParserQuirks &amp;&amp; character == '&lt;')
</span><span class="lines">@@ -767,7 +767,7 @@
</span><span class="cx">             parseError();
</span><span class="cx">         m_token.beginAttribute(source.numberOfCharactersConsumed());
</span><span class="cx">         m_token.appendToAttributeName(toASCIILower(character));
</span><del>-        ADVANCE_PAST_NON_NEWLINE_TO(AttributeNameState);
</del><ins>+        ADVANCE_TO(AttributeNameState);
</ins><span class="cx">     END_STATE()
</span><span class="cx"> 
</span><span class="cx">     BEGIN_STATE(BeforeAttributeValueState)
</span><span class="lines">@@ -774,11 +774,11 @@
</span><span class="cx">         if (isTokenizerWhitespace(character))
</span><span class="cx">             ADVANCE_TO(BeforeAttributeValueState);
</span><span class="cx">         if (character == '&quot;')
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(AttributeValueDoubleQuotedState);
</del><ins>+            ADVANCE_TO(AttributeValueDoubleQuotedState);
</ins><span class="cx">         if (character == '&amp;')
</span><span class="cx">             RECONSUME_IN(AttributeValueUnquotedState);
</span><span class="cx">         if (character == '\'')
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(AttributeValueSingleQuotedState);
</del><ins>+            ADVANCE_TO(AttributeValueSingleQuotedState);
</ins><span class="cx">         if (character == '&gt;') {
</span><span class="cx">             parseError();
</span><span class="cx">             return emitAndResumeInDataState(source);
</span><span class="lines">@@ -790,17 +790,17 @@
</span><span class="cx">         if (character == '&lt;' || character == '=' || character == '`')
</span><span class="cx">             parseError();
</span><span class="cx">         m_token.appendToAttributeValue(character);
</span><del>-        ADVANCE_PAST_NON_NEWLINE_TO(AttributeValueUnquotedState);
</del><ins>+        ADVANCE_TO(AttributeValueUnquotedState);
</ins><span class="cx">     END_STATE()
</span><span class="cx"> 
</span><span class="cx">     BEGIN_STATE(AttributeValueDoubleQuotedState)
</span><span class="cx">         if (character == '&quot;') {
</span><span class="cx">             m_token.endAttribute(source.numberOfCharactersConsumed());
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(AfterAttributeValueQuotedState);
</del><ins>+            ADVANCE_TO(AfterAttributeValueQuotedState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == '&amp;') {
</span><span class="cx">             m_additionalAllowedCharacter = '&quot;';
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(CharacterReferenceInAttributeValueState);
</del><ins>+            ADVANCE_TO(CharacterReferenceInAttributeValueState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == kEndOfFileMarker) {
</span><span class="cx">             parseError();
</span><span class="lines">@@ -814,11 +814,11 @@
</span><span class="cx">     BEGIN_STATE(AttributeValueSingleQuotedState)
</span><span class="cx">         if (character == '\'') {
</span><span class="cx">             m_token.endAttribute(source.numberOfCharactersConsumed());
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(AfterAttributeValueQuotedState);
</del><ins>+            ADVANCE_TO(AfterAttributeValueQuotedState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == '&amp;') {
</span><span class="cx">             m_additionalAllowedCharacter = '\'';
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(CharacterReferenceInAttributeValueState);
</del><ins>+            ADVANCE_TO(CharacterReferenceInAttributeValueState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == kEndOfFileMarker) {
</span><span class="cx">             parseError();
</span><span class="lines">@@ -836,7 +836,7 @@
</span><span class="cx">         }
</span><span class="cx">         if (character == '&amp;') {
</span><span class="cx">             m_additionalAllowedCharacter = '&gt;';
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(CharacterReferenceInAttributeValueState);
</del><ins>+            ADVANCE_TO(CharacterReferenceInAttributeValueState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == '&gt;') {
</span><span class="cx">             m_token.endAttribute(source.numberOfCharactersConsumed());
</span><span class="lines">@@ -850,7 +850,7 @@
</span><span class="cx">         if (character == '&quot;' || character == '\'' || character == '&lt;' || character == '=' || character == '`')
</span><span class="cx">             parseError();
</span><span class="cx">         m_token.appendToAttributeValue(character);
</span><del>-        ADVANCE_PAST_NON_NEWLINE_TO(AttributeValueUnquotedState);
</del><ins>+        ADVANCE_TO(AttributeValueUnquotedState);
</ins><span class="cx">     END_STATE()
</span><span class="cx"> 
</span><span class="cx">     BEGIN_STATE(CharacterReferenceInAttributeValueState)
</span><span class="lines">@@ -882,7 +882,7 @@
</span><span class="cx">         if (isTokenizerWhitespace(character))
</span><span class="cx">             ADVANCE_TO(BeforeAttributeNameState);
</span><span class="cx">         if (character == '/')
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(SelfClosingStartTagState);
</del><ins>+            ADVANCE_TO(SelfClosingStartTagState);
</ins><span class="cx">         if (character == '&gt;')
</span><span class="cx">             return emitAndResumeInDataState(source);
</span><span class="cx">         if (m_options.usePreHTML5ParserQuirks &amp;&amp; character == '&lt;')
</span><span class="lines">@@ -932,7 +932,7 @@
</span><span class="cx">             if (result == SegmentedString::NotEnoughCharacters)
</span><span class="cx">                 RETURN_IN_CURRENT_STATE(haveBufferedCharacterToken());
</span><span class="cx">         } else if (isASCIIAlphaCaselessEqual(character, 'd')) {
</span><del>-            auto result = source.advancePastLettersIgnoringASCIICase(&quot;doctype&quot;);
</del><ins>+            auto result = source.advancePastIgnoringCase(&quot;doctype&quot;);
</ins><span class="cx">             if (result == SegmentedString::DidMatch)
</span><span class="cx">                 SWITCH_TO(DOCTYPEState);
</span><span class="cx">             if (result == SegmentedString::NotEnoughCharacters)
</span><span class="lines">@@ -950,7 +950,7 @@
</span><span class="cx"> 
</span><span class="cx">     BEGIN_STATE(CommentStartState)
</span><span class="cx">         if (character == '-')
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(CommentStartDashState);
</del><ins>+            ADVANCE_TO(CommentStartDashState);
</ins><span class="cx">         if (character == '&gt;') {
</span><span class="cx">             parseError();
</span><span class="cx">             return emitAndResumeInDataState(source);
</span><span class="lines">@@ -965,7 +965,7 @@
</span><span class="cx"> 
</span><span class="cx">     BEGIN_STATE(CommentStartDashState)
</span><span class="cx">         if (character == '-')
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(CommentEndState);
</del><ins>+            ADVANCE_TO(CommentEndState);
</ins><span class="cx">         if (character == '&gt;') {
</span><span class="cx">             parseError();
</span><span class="cx">             return emitAndResumeInDataState(source);
</span><span class="lines">@@ -981,7 +981,7 @@
</span><span class="cx"> 
</span><span class="cx">     BEGIN_STATE(CommentState)
</span><span class="cx">         if (character == '-')
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(CommentEndDashState);
</del><ins>+            ADVANCE_TO(CommentEndDashState);
</ins><span class="cx">         if (character == kEndOfFileMarker) {
</span><span class="cx">             parseError();
</span><span class="cx">             return emitAndReconsumeInDataState();
</span><span class="lines">@@ -992,7 +992,7 @@
</span><span class="cx"> 
</span><span class="cx">     BEGIN_STATE(CommentEndDashState)
</span><span class="cx">         if (character == '-')
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(CommentEndState);
</del><ins>+            ADVANCE_TO(CommentEndState);
</ins><span class="cx">         if (character == kEndOfFileMarker) {
</span><span class="cx">             parseError();
</span><span class="cx">             return emitAndReconsumeInDataState();
</span><span class="lines">@@ -1007,12 +1007,12 @@
</span><span class="cx">             return emitAndResumeInDataState(source);
</span><span class="cx">         if (character == '!') {
</span><span class="cx">             parseError();
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(CommentEndBangState);
</del><ins>+            ADVANCE_TO(CommentEndBangState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == '-') {
</span><span class="cx">             parseError();
</span><span class="cx">             m_token.appendToComment('-');
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(CommentEndState);
</del><ins>+            ADVANCE_TO(CommentEndState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == kEndOfFileMarker) {
</span><span class="cx">             parseError();
</span><span class="lines">@@ -1030,7 +1030,7 @@
</span><span class="cx">             m_token.appendToComment('-');
</span><span class="cx">             m_token.appendToComment('-');
</span><span class="cx">             m_token.appendToComment('!');
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(CommentEndDashState);
</del><ins>+            ADVANCE_TO(CommentEndDashState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == '&gt;')
</span><span class="cx">             return emitAndResumeInDataState(source);
</span><span class="lines">@@ -1074,7 +1074,7 @@
</span><span class="cx">             return emitAndReconsumeInDataState();
</span><span class="cx">         }
</span><span class="cx">         m_token.beginDOCTYPE(toASCIILower(character));
</span><del>-        ADVANCE_PAST_NON_NEWLINE_TO(DOCTYPENameState);
</del><ins>+        ADVANCE_TO(DOCTYPENameState);
</ins><span class="cx">     END_STATE()
</span><span class="cx"> 
</span><span class="cx">     BEGIN_STATE(DOCTYPENameState)
</span><span class="lines">@@ -1088,7 +1088,7 @@
</span><span class="cx">             return emitAndReconsumeInDataState();
</span><span class="cx">         }
</span><span class="cx">         m_token.appendToName(toASCIILower(character));
</span><del>-        ADVANCE_PAST_NON_NEWLINE_TO(DOCTYPENameState);
</del><ins>+        ADVANCE_TO(DOCTYPENameState);
</ins><span class="cx">     END_STATE()
</span><span class="cx"> 
</span><span class="cx">     BEGIN_STATE(AfterDOCTYPENameState)
</span><span class="lines">@@ -1102,13 +1102,13 @@
</span><span class="cx">             return emitAndReconsumeInDataState();
</span><span class="cx">         }
</span><span class="cx">         if (isASCIIAlphaCaselessEqual(character, 'p')) {
</span><del>-            auto result = source.advancePastLettersIgnoringASCIICase(&quot;public&quot;);
</del><ins>+            auto result = source.advancePastIgnoringCase(&quot;public&quot;);
</ins><span class="cx">             if (result == SegmentedString::DidMatch)
</span><span class="cx">                 SWITCH_TO(AfterDOCTYPEPublicKeywordState);
</span><span class="cx">             if (result == SegmentedString::NotEnoughCharacters)
</span><span class="cx">                 RETURN_IN_CURRENT_STATE(haveBufferedCharacterToken());
</span><span class="cx">         } else if (isASCIIAlphaCaselessEqual(character, 's')) {
</span><del>-            auto result = source.advancePastLettersIgnoringASCIICase(&quot;system&quot;);
</del><ins>+            auto result = source.advancePastIgnoringCase(&quot;system&quot;);
</ins><span class="cx">             if (result == SegmentedString::DidMatch)
</span><span class="cx">                 SWITCH_TO(AfterDOCTYPESystemKeywordState);
</span><span class="cx">             if (result == SegmentedString::NotEnoughCharacters)
</span><span class="lines">@@ -1116,7 +1116,7 @@
</span><span class="cx">         }
</span><span class="cx">         parseError();
</span><span class="cx">         m_token.setForceQuirks();
</span><del>-        ADVANCE_PAST_NON_NEWLINE_TO(BogusDOCTYPEState);
</del><ins>+        ADVANCE_TO(BogusDOCTYPEState);
</ins><span class="cx">     END_STATE()
</span><span class="cx"> 
</span><span class="cx">     BEGIN_STATE(AfterDOCTYPEPublicKeywordState)
</span><span class="lines">@@ -1125,12 +1125,12 @@
</span><span class="cx">         if (character == '&quot;') {
</span><span class="cx">             parseError();
</span><span class="cx">             m_token.setPublicIdentifierToEmptyString();
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(DOCTYPEPublicIdentifierDoubleQuotedState);
</del><ins>+            ADVANCE_TO(DOCTYPEPublicIdentifierDoubleQuotedState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == '\'') {
</span><span class="cx">             parseError();
</span><span class="cx">             m_token.setPublicIdentifierToEmptyString();
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(DOCTYPEPublicIdentifierSingleQuotedState);
</del><ins>+            ADVANCE_TO(DOCTYPEPublicIdentifierSingleQuotedState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == '&gt;') {
</span><span class="cx">             parseError();
</span><span class="lines">@@ -1144,7 +1144,7 @@
</span><span class="cx">         }
</span><span class="cx">         parseError();
</span><span class="cx">         m_token.setForceQuirks();
</span><del>-        ADVANCE_PAST_NON_NEWLINE_TO(BogusDOCTYPEState);
</del><ins>+        ADVANCE_TO(BogusDOCTYPEState);
</ins><span class="cx">     END_STATE()
</span><span class="cx"> 
</span><span class="cx">     BEGIN_STATE(BeforeDOCTYPEPublicIdentifierState)
</span><span class="lines">@@ -1152,11 +1152,11 @@
</span><span class="cx">             ADVANCE_TO(BeforeDOCTYPEPublicIdentifierState);
</span><span class="cx">         if (character == '&quot;') {
</span><span class="cx">             m_token.setPublicIdentifierToEmptyString();
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(DOCTYPEPublicIdentifierDoubleQuotedState);
</del><ins>+            ADVANCE_TO(DOCTYPEPublicIdentifierDoubleQuotedState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == '\'') {
</span><span class="cx">             m_token.setPublicIdentifierToEmptyString();
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(DOCTYPEPublicIdentifierSingleQuotedState);
</del><ins>+            ADVANCE_TO(DOCTYPEPublicIdentifierSingleQuotedState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == '&gt;') {
</span><span class="cx">             parseError();
</span><span class="lines">@@ -1170,12 +1170,12 @@
</span><span class="cx">         }
</span><span class="cx">         parseError();
</span><span class="cx">         m_token.setForceQuirks();
</span><del>-        ADVANCE_PAST_NON_NEWLINE_TO(BogusDOCTYPEState);
</del><ins>+        ADVANCE_TO(BogusDOCTYPEState);
</ins><span class="cx">     END_STATE()
</span><span class="cx"> 
</span><span class="cx">     BEGIN_STATE(DOCTYPEPublicIdentifierDoubleQuotedState)
</span><span class="cx">         if (character == '&quot;')
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(AfterDOCTYPEPublicIdentifierState);
</del><ins>+            ADVANCE_TO(AfterDOCTYPEPublicIdentifierState);
</ins><span class="cx">         if (character == '&gt;') {
</span><span class="cx">             parseError();
</span><span class="cx">             m_token.setForceQuirks();
</span><span class="lines">@@ -1192,7 +1192,7 @@
</span><span class="cx"> 
</span><span class="cx">     BEGIN_STATE(DOCTYPEPublicIdentifierSingleQuotedState)
</span><span class="cx">         if (character == '\'')
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(AfterDOCTYPEPublicIdentifierState);
</del><ins>+            ADVANCE_TO(AfterDOCTYPEPublicIdentifierState);
</ins><span class="cx">         if (character == '&gt;') {
</span><span class="cx">             parseError();
</span><span class="cx">             m_token.setForceQuirks();
</span><span class="lines">@@ -1215,12 +1215,12 @@
</span><span class="cx">         if (character == '&quot;') {
</span><span class="cx">             parseError();
</span><span class="cx">             m_token.setSystemIdentifierToEmptyString();
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(DOCTYPESystemIdentifierDoubleQuotedState);
</del><ins>+            ADVANCE_TO(DOCTYPESystemIdentifierDoubleQuotedState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == '\'') {
</span><span class="cx">             parseError();
</span><span class="cx">             m_token.setSystemIdentifierToEmptyString();
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(DOCTYPESystemIdentifierSingleQuotedState);
</del><ins>+            ADVANCE_TO(DOCTYPESystemIdentifierSingleQuotedState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == kEndOfFileMarker) {
</span><span class="cx">             parseError();
</span><span class="lines">@@ -1229,7 +1229,7 @@
</span><span class="cx">         }
</span><span class="cx">         parseError();
</span><span class="cx">         m_token.setForceQuirks();
</span><del>-        ADVANCE_PAST_NON_NEWLINE_TO(BogusDOCTYPEState);
</del><ins>+        ADVANCE_TO(BogusDOCTYPEState);
</ins><span class="cx">     END_STATE()
</span><span class="cx"> 
</span><span class="cx">     BEGIN_STATE(BetweenDOCTYPEPublicAndSystemIdentifiersState)
</span><span class="lines">@@ -1239,11 +1239,11 @@
</span><span class="cx">             return emitAndResumeInDataState(source);
</span><span class="cx">         if (character == '&quot;') {
</span><span class="cx">             m_token.setSystemIdentifierToEmptyString();
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(DOCTYPESystemIdentifierDoubleQuotedState);
</del><ins>+            ADVANCE_TO(DOCTYPESystemIdentifierDoubleQuotedState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == '\'') {
</span><span class="cx">             m_token.setSystemIdentifierToEmptyString();
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(DOCTYPESystemIdentifierSingleQuotedState);
</del><ins>+            ADVANCE_TO(DOCTYPESystemIdentifierSingleQuotedState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == kEndOfFileMarker) {
</span><span class="cx">             parseError();
</span><span class="lines">@@ -1252,7 +1252,7 @@
</span><span class="cx">         }
</span><span class="cx">         parseError();
</span><span class="cx">         m_token.setForceQuirks();
</span><del>-        ADVANCE_PAST_NON_NEWLINE_TO(BogusDOCTYPEState);
</del><ins>+        ADVANCE_TO(BogusDOCTYPEState);
</ins><span class="cx">     END_STATE()
</span><span class="cx"> 
</span><span class="cx">     BEGIN_STATE(AfterDOCTYPESystemKeywordState)
</span><span class="lines">@@ -1261,12 +1261,12 @@
</span><span class="cx">         if (character == '&quot;') {
</span><span class="cx">             parseError();
</span><span class="cx">             m_token.setSystemIdentifierToEmptyString();
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(DOCTYPESystemIdentifierDoubleQuotedState);
</del><ins>+            ADVANCE_TO(DOCTYPESystemIdentifierDoubleQuotedState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == '\'') {
</span><span class="cx">             parseError();
</span><span class="cx">             m_token.setSystemIdentifierToEmptyString();
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(DOCTYPESystemIdentifierSingleQuotedState);
</del><ins>+            ADVANCE_TO(DOCTYPESystemIdentifierSingleQuotedState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == '&gt;') {
</span><span class="cx">             parseError();
</span><span class="lines">@@ -1280,7 +1280,7 @@
</span><span class="cx">         }
</span><span class="cx">         parseError();
</span><span class="cx">         m_token.setForceQuirks();
</span><del>-        ADVANCE_PAST_NON_NEWLINE_TO(BogusDOCTYPEState);
</del><ins>+        ADVANCE_TO(BogusDOCTYPEState);
</ins><span class="cx">     END_STATE()
</span><span class="cx"> 
</span><span class="cx">     BEGIN_STATE(BeforeDOCTYPESystemIdentifierState)
</span><span class="lines">@@ -1288,11 +1288,11 @@
</span><span class="cx">             ADVANCE_TO(BeforeDOCTYPESystemIdentifierState);
</span><span class="cx">         if (character == '&quot;') {
</span><span class="cx">             m_token.setSystemIdentifierToEmptyString();
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(DOCTYPESystemIdentifierDoubleQuotedState);
</del><ins>+            ADVANCE_TO(DOCTYPESystemIdentifierDoubleQuotedState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == '\'') {
</span><span class="cx">             m_token.setSystemIdentifierToEmptyString();
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(DOCTYPESystemIdentifierSingleQuotedState);
</del><ins>+            ADVANCE_TO(DOCTYPESystemIdentifierSingleQuotedState);
</ins><span class="cx">         }
</span><span class="cx">         if (character == '&gt;') {
</span><span class="cx">             parseError();
</span><span class="lines">@@ -1306,12 +1306,12 @@
</span><span class="cx">         }
</span><span class="cx">         parseError();
</span><span class="cx">         m_token.setForceQuirks();
</span><del>-        ADVANCE_PAST_NON_NEWLINE_TO(BogusDOCTYPEState);
</del><ins>+        ADVANCE_TO(BogusDOCTYPEState);
</ins><span class="cx">     END_STATE()
</span><span class="cx"> 
</span><span class="cx">     BEGIN_STATE(DOCTYPESystemIdentifierDoubleQuotedState)
</span><span class="cx">         if (character == '&quot;')
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(AfterDOCTYPESystemIdentifierState);
</del><ins>+            ADVANCE_TO(AfterDOCTYPESystemIdentifierState);
</ins><span class="cx">         if (character == '&gt;') {
</span><span class="cx">             parseError();
</span><span class="cx">             m_token.setForceQuirks();
</span><span class="lines">@@ -1328,7 +1328,7 @@
</span><span class="cx"> 
</span><span class="cx">     BEGIN_STATE(DOCTYPESystemIdentifierSingleQuotedState)
</span><span class="cx">         if (character == '\'')
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(AfterDOCTYPESystemIdentifierState);
</del><ins>+            ADVANCE_TO(AfterDOCTYPESystemIdentifierState);
</ins><span class="cx">         if (character == '&gt;') {
</span><span class="cx">             parseError();
</span><span class="cx">             m_token.setForceQuirks();
</span><span class="lines">@@ -1354,7 +1354,7 @@
</span><span class="cx">             return emitAndReconsumeInDataState();
</span><span class="cx">         }
</span><span class="cx">         parseError();
</span><del>-        ADVANCE_PAST_NON_NEWLINE_TO(BogusDOCTYPEState);
</del><ins>+        ADVANCE_TO(BogusDOCTYPEState);
</ins><span class="cx">     END_STATE()
</span><span class="cx"> 
</span><span class="cx">     BEGIN_STATE(BogusDOCTYPEState)
</span><span class="lines">@@ -1367,7 +1367,7 @@
</span><span class="cx"> 
</span><span class="cx">     BEGIN_STATE(CDATASectionState)
</span><span class="cx">         if (character == ']')
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(CDATASectionRightSquareBracketState);
</del><ins>+            ADVANCE_TO(CDATASectionRightSquareBracketState);
</ins><span class="cx">         if (character == kEndOfFileMarker)
</span><span class="cx">             RECONSUME_IN(DataState);
</span><span class="cx">         bufferCharacter(character);
</span><span class="lines">@@ -1376,7 +1376,7 @@
</span><span class="cx"> 
</span><span class="cx">     BEGIN_STATE(CDATASectionRightSquareBracketState)
</span><span class="cx">         if (character == ']')
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(CDATASectionDoubleRightSquareBracketState);
</del><ins>+            ADVANCE_TO(CDATASectionDoubleRightSquareBracketState);
</ins><span class="cx">         bufferASCIICharacter(']');
</span><span class="cx">         RECONSUME_IN(CDATASectionState);
</span><span class="cx">     END_STATE()
</span><span class="lines">@@ -1383,7 +1383,7 @@
</span><span class="cx"> 
</span><span class="cx">     BEGIN_STATE(CDATASectionDoubleRightSquareBracketState)
</span><span class="cx">         if (character == '&gt;')
</span><del>-            ADVANCE_PAST_NON_NEWLINE_TO(DataState);
</del><ins>+            ADVANCE_TO(DataState);
</ins><span class="cx">         bufferASCIICharacter(']');
</span><span class="cx">         bufferASCIICharacter(']');
</span><span class="cx">         RECONSUME_IN(CDATASectionState);
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlparserInputStreamPreprocessorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/parser/InputStreamPreprocessor.h (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/parser/InputStreamPreprocessor.h        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WebCore/html/parser/InputStreamPreprocessor.h        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -28,17 +28,22 @@
</span><span class="cx"> #pragma once
</span><span class="cx"> 
</span><span class="cx"> #include &quot;SegmentedString.h&quot;
</span><ins>+#include &lt;wtf/Noncopyable.h&gt;
</ins><span class="cx"> #include &lt;wtf/unicode/CharacterNames.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><ins>+const LChar kEndOfFileMarker = 0;
+
</ins><span class="cx"> // http://www.whatwg.org/specs/web-apps/current-work/#preprocessing-the-input-stream
</span><span class="cx"> template &lt;typename Tokenizer&gt;
</span><span class="cx"> class InputStreamPreprocessor {
</span><ins>+    WTF_MAKE_NONCOPYABLE(InputStreamPreprocessor);
</ins><span class="cx"> public:
</span><span class="cx">     explicit InputStreamPreprocessor(Tokenizer&amp; tokenizer)
</span><span class="cx">         : m_tokenizer(tokenizer)
</span><span class="cx">     {
</span><ins>+        reset();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     ALWAYS_INLINE UChar nextInputCharacter() const { return m_nextInputCharacter; }
</span><span class="lines">@@ -48,21 +53,20 @@
</span><span class="cx">     // characters in |source| (after collapsing \r\n, etc).
</span><span class="cx">     ALWAYS_INLINE bool peek(SegmentedString&amp; source, bool skipNullCharacters = false)
</span><span class="cx">     {
</span><del>-        if (UNLIKELY(source.isEmpty()))
</del><ins>+        if (source.isEmpty())
</ins><span class="cx">             return false;
</span><span class="cx"> 
</span><del>-        m_nextInputCharacter = source.currentCharacter();
</del><ins>+        m_nextInputCharacter = source.currentChar();
</ins><span class="cx"> 
</span><span class="cx">         // Every branch in this function is expensive, so we have a
</span><span class="cx">         // fast-reject branch for characters that don't require special
</span><span class="cx">         // handling. Please run the parser benchmark whenever you touch
</span><span class="cx">         // this function. It's very hot.
</span><del>-        constexpr UChar specialCharacterMask = '\n' | '\r' | '\0';
-        if (LIKELY(m_nextInputCharacter &amp; ~specialCharacterMask)) {
</del><ins>+        static const UChar specialCharacterMask = '\n' | '\r' | '\0';
+        if (m_nextInputCharacter &amp; ~specialCharacterMask) {
</ins><span class="cx">             m_skipNextNewLine = false;
</span><span class="cx">             return true;
</span><span class="cx">         }
</span><del>-
</del><span class="cx">         return processNextInputCharacter(source, skipNullCharacters);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -69,13 +73,16 @@
</span><span class="cx">     // Returns whether there are more characters in |source| after advancing.
</span><span class="cx">     ALWAYS_INLINE bool advance(SegmentedString&amp; source, bool skipNullCharacters = false)
</span><span class="cx">     {
</span><del>-        source.advance();
</del><ins>+        source.advanceAndUpdateLineNumber();
</ins><span class="cx">         return peek(source, skipNullCharacters);
</span><span class="cx">     }
</span><del>-    ALWAYS_INLINE bool advancePastNonNewline(SegmentedString&amp; source, bool skipNullCharacters = false)
</del><ins>+
+    bool skipNextNewLine() const { return m_skipNextNewLine; }
+
+    void reset(bool skipNextNewLine = false)
</ins><span class="cx">     {
</span><del>-        source.advancePastNonNewline();
-        return peek(source, skipNullCharacters);
</del><ins>+        m_nextInputCharacter = '\0';
+        m_skipNextNewLine = skipNextNewLine;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="lines">@@ -82,34 +89,39 @@
</span><span class="cx">     bool processNextInputCharacter(SegmentedString&amp; source, bool skipNullCharacters)
</span><span class="cx">     {
</span><span class="cx">     ProcessAgain:
</span><del>-        ASSERT(m_nextInputCharacter == source.currentCharacter());
</del><ins>+        ASSERT(m_nextInputCharacter == source.currentChar());
+
</ins><span class="cx">         if (m_nextInputCharacter == '\n' &amp;&amp; m_skipNextNewLine) {
</span><span class="cx">             m_skipNextNewLine = false;
</span><del>-            source.advancePastNewline();
</del><ins>+            source.advancePastNewlineAndUpdateLineNumber();
</ins><span class="cx">             if (source.isEmpty())
</span><span class="cx">                 return false;
</span><del>-            m_nextInputCharacter = source.currentCharacter();
</del><ins>+            m_nextInputCharacter = source.currentChar();
</ins><span class="cx">         }
</span><span class="cx">         if (m_nextInputCharacter == '\r') {
</span><span class="cx">             m_nextInputCharacter = '\n';
</span><span class="cx">             m_skipNextNewLine = true;
</span><del>-            return true;
</del><ins>+        } else {
+            m_skipNextNewLine = false;
+            // FIXME: The spec indicates that the surrogate pair range as well as
+            // a number of specific character values are parse errors and should be replaced
+            // by the replacement character. We suspect this is a problem with the spec as doing
+            // that filtering breaks surrogate pair handling and causes us not to match Minefield.
+            if (m_nextInputCharacter == '\0' &amp;&amp; !shouldTreatNullAsEndOfFileMarker(source)) {
+                if (skipNullCharacters &amp;&amp; !m_tokenizer.neverSkipNullCharacters()) {
+                    source.advancePastNonNewline();
+                    if (source.isEmpty())
+                        return false;
+                    m_nextInputCharacter = source.currentChar();
+                    goto ProcessAgain;
+                }
+                m_nextInputCharacter = replacementCharacter;
+            }
</ins><span class="cx">         }
</span><del>-        m_skipNextNewLine = false;
-        if (m_nextInputCharacter || isAtEndOfFile(source))
-            return true;
-        if (skipNullCharacters &amp;&amp; !m_tokenizer.neverSkipNullCharacters()) {
-            source.advancePastNonNewline();
-            if (source.isEmpty())
-                return false;
-            m_nextInputCharacter = source.currentCharacter();
-            goto ProcessAgain;
-        }
-        m_nextInputCharacter = replacementCharacter;
</del><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    static bool isAtEndOfFile(SegmentedString&amp; source)
</del><ins>+    bool shouldTreatNullAsEndOfFileMarker(SegmentedString&amp; source) const
</ins><span class="cx">     {
</span><span class="cx">         return source.isClosed() &amp;&amp; source.length() == 1;
</span><span class="cx">     }
</span><span class="lines">@@ -117,8 +129,8 @@
</span><span class="cx">     Tokenizer&amp; m_tokenizer;
</span><span class="cx"> 
</span><span class="cx">     // http://www.whatwg.org/specs/web-apps/current-work/#next-input-character
</span><del>-    UChar m_nextInputCharacter { 0 };
-    bool m_skipNextNewLine { false };
</del><ins>+    UChar m_nextInputCharacter;
+    bool m_skipNextNewLine;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorehtmltrackBufferedLineReadercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/track/BufferedLineReader.cpp (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/track/BufferedLineReader.cpp        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WebCore/html/track/BufferedLineReader.cpp        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -35,7 +35,7 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-std::optional&lt;String&gt; BufferedLineReader::nextLine()
</del><ins>+bool BufferedLineReader::getLine(String&amp; line)
</ins><span class="cx"> {
</span><span class="cx">     if (m_maybeSkipLF) {
</span><span class="cx">         // We ran out of data after a CR (U+000D), which means that we may be
</span><span class="lines">@@ -42,42 +42,42 @@
</span><span class="cx">         // in the middle of a CRLF pair. If the next character is a LF (U+000A)
</span><span class="cx">         // then skip it, and then (unconditionally) return the buffered line.
</span><span class="cx">         if (!m_buffer.isEmpty()) {
</span><del>-            if (m_buffer.currentCharacter() == newlineCharacter)
-                m_buffer.advancePastNewline();
</del><ins>+            scanCharacter(newlineCharacter);
</ins><span class="cx">             m_maybeSkipLF = false;
</span><span class="cx">         }
</span><span class="cx">         // If there was no (new) data available, then keep m_maybeSkipLF set,
</span><del>-        // and fall through all the way down to the EOS check at the end of the function.
</del><ins>+        // and fall through all the way down to the EOS check at the end of
+        // the method.
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     bool shouldReturnLine = false;
</span><span class="cx">     bool checkForLF = false;
</span><span class="cx">     while (!m_buffer.isEmpty()) {
</span><del>-        UChar character = m_buffer.currentCharacter();
</del><ins>+        UChar c = m_buffer.currentChar();
</ins><span class="cx">         m_buffer.advance();
</span><span class="cx"> 
</span><del>-        if (character == newlineCharacter || character == carriageReturn) {
</del><ins>+        if (c == newlineCharacter || c == carriageReturn) {
</ins><span class="cx">             // We found a line ending. Return the accumulated line.
</span><span class="cx">             shouldReturnLine = true;
</span><del>-            checkForLF = (character == carriageReturn);
</del><ins>+            checkForLF = (c == carriageReturn);
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         // NULs are transformed into U+FFFD (REPLACEMENT CHAR.) in step 1 of
</span><span class="cx">         // the WebVTT parser algorithm.
</span><del>-        if (character == '\0')
-            character = replacementCharacter;
</del><ins>+        if (c == '\0')
+            c = replacementCharacter;
</ins><span class="cx"> 
</span><del>-        m_lineBuffer.append(character);
</del><ins>+        m_lineBuffer.append(c);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (checkForLF) {
</span><span class="cx">         // May be in the middle of a CRLF pair.
</span><span class="cx">         if (!m_buffer.isEmpty()) {
</span><del>-            if (m_buffer.currentCharacter() == newlineCharacter)
-                m_buffer.advancePastNewline();
</del><ins>+            // Scan a potential newline character.
+            scanCharacter(newlineCharacter);
</ins><span class="cx">         } else {
</span><del>-            // Check for the newline on the next call (unless we reached EOS, in
</del><ins>+            // Check for the LF on the next call (unless we reached EOS, in
</ins><span class="cx">             // which case we'll return the contents of the line buffer, and
</span><span class="cx">             // reset state for the next line.)
</span><span class="cx">             m_maybeSkipLF = true;
</span><span class="lines">@@ -92,13 +92,13 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (shouldReturnLine) {
</span><del>-        auto line = m_lineBuffer.toString();
</del><ins>+        line = m_lineBuffer.toString();
</ins><span class="cx">         m_lineBuffer.clear();
</span><del>-        return WTFMove(line);
</del><ins>+        return true;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     ASSERT(m_buffer.isEmpty());
</span><del>-    return std::nullopt;
</del><ins>+    return false;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorehtmltrackBufferedLineReaderh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/track/BufferedLineReader.h (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/track/BufferedLineReader.h        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WebCore/html/track/BufferedLineReader.h        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -38,39 +38,50 @@
</span><span class="cx"> // Line collection helper for the WebVTT Parser.
</span><span class="cx"> //
</span><span class="cx"> // Converts a stream of data (== a sequence of Strings) into a set of
</span><del>-// lines. CR, LR or CRLF are considered line breaks. Normalizes NULs (U+0000)
-// to 'REPLACEMENT CHARACTER' (U+FFFD) and does not return the line breaks as
</del><ins>+// lines. CR, LR or CRLF are considered linebreaks. Normalizes NULs (U+0000)
+// to 'REPLACEMENT CHARACTER' (U+FFFD) and does not return the linebreaks as
</ins><span class="cx"> // part of the result.
</span><span class="cx"> class BufferedLineReader {
</span><span class="cx">     WTF_MAKE_NONCOPYABLE(BufferedLineReader);
</span><span class="cx"> public:
</span><del>-    BufferedLineReader() = default;
-    void reset();
</del><ins>+    BufferedLineReader()
+        : m_endOfStream(false)
+        , m_maybeSkipLF(false) { }
</ins><span class="cx"> 
</span><del>-    void append(String&amp;&amp; data)
</del><ins>+    // Append data to the internal buffer.
+    void append(const String&amp; data)
</ins><span class="cx">     {
</span><span class="cx">         ASSERT(!m_endOfStream);
</span><del>-        m_buffer.append(WTFMove(data));
</del><ins>+        m_buffer.append(SegmentedString(data));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void appendEndOfStream() { m_endOfStream = true; }
</del><ins>+    // Indicate that no more data will be appended. This will cause any
+    // potentially &quot;unterminated&quot; line to be returned from getLine.
+    void setEndOfStream() { m_endOfStream = true; }
+
+    // Attempt to read a line from the internal buffer (fed via append).
+    // If successful, true is returned and |line| is set to the line that was
+    // read. If no line could be read false is returned.
+    bool getLine(String&amp; line);
+
+    // Returns true if EOS has been reached proper.
</ins><span class="cx">     bool isAtEndOfStream() const { return m_endOfStream &amp;&amp; m_buffer.isEmpty(); }
</span><span class="cx"> 
</span><del>-    std::optional&lt;String&gt; nextLine();
</del><ins>+    void reset() { m_buffer.clear(); }
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><ins>+    // Consume the next character the buffer if it is the character |c|.
+    void scanCharacter(UChar c)
+    {
+        ASSERT(!m_buffer.isEmpty());
+        if (m_buffer.currentChar() == c)
+            m_buffer.advance();
+    }
+
</ins><span class="cx">     SegmentedString m_buffer;
</span><span class="cx">     StringBuilder m_lineBuffer;
</span><del>-    bool m_endOfStream { false };
-    bool m_maybeSkipLF { false };
</del><ins>+    bool m_endOfStream;
+    bool m_maybeSkipLF;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-inline void BufferedLineReader::reset()
-{
-    m_buffer.clear();
-    m_lineBuffer.clear();
-    m_endOfStream = false;
-    m_maybeSkipLF = false;
-}
-
</del><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorehtmltrackInbandGenericTextTrackcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/track/InbandGenericTextTrack.cpp (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/track/InbandGenericTextTrack.cpp        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WebCore/html/track/InbandGenericTextTrack.cpp        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -185,10 +185,10 @@
</span><span class="cx">     parser().parseCueData(cueData);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void InbandGenericTextTrack::parseWebVTTFileHeader(InbandTextTrackPrivate* trackPrivate, String&amp;&amp; header)
</del><ins>+void InbandGenericTextTrack::parseWebVTTFileHeader(InbandTextTrackPrivate* trackPrivate, String header)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT_UNUSED(trackPrivate, trackPrivate == m_private);
</span><del>-    parser().parseFileHeader(WTFMove(header));
</del><ins>+    parser().parseFileHeader(header);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void InbandGenericTextTrack::newCuesParsed()
</span></span></pre></div>
<a id="trunkSourceWebCorehtmltrackInbandGenericTextTrackh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/track/InbandGenericTextTrack.h (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/track/InbandGenericTextTrack.h        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WebCore/html/track/InbandGenericTextTrack.h        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -72,7 +72,7 @@
</span><span class="cx"> 
</span><span class="cx">     WebVTTParser&amp; parser();
</span><span class="cx">     void parseWebVTTCueData(InbandTextTrackPrivate*, const ISOWebVTTCue&amp;) final;
</span><del>-    void parseWebVTTFileHeader(InbandTextTrackPrivate*, String&amp;&amp;) final;
</del><ins>+    void parseWebVTTFileHeader(InbandTextTrackPrivate*, String) final;
</ins><span class="cx"> 
</span><span class="cx">     void newCuesParsed() final;
</span><span class="cx">     void newRegionsParsed() final;
</span></span></pre></div>
<a id="trunkSourceWebCorehtmltrackInbandTextTrackh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/track/InbandTextTrack.h (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/track/InbandTextTrack.h        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WebCore/html/track/InbandTextTrack.h        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -79,7 +79,7 @@
</span><span class="cx">     void updateGenericCue(InbandTextTrackPrivate*, GenericCueData*) override { ASSERT_NOT_REACHED(); }
</span><span class="cx">     void removeGenericCue(InbandTextTrackPrivate*, GenericCueData*) override { ASSERT_NOT_REACHED(); }
</span><span class="cx"> 
</span><del>-    void parseWebVTTFileHeader(InbandTextTrackPrivate*, String&amp;&amp;) override { ASSERT_NOT_REACHED(); }
</del><ins>+    void parseWebVTTFileHeader(InbandTextTrackPrivate*, String) override { ASSERT_NOT_REACHED(); }
</ins><span class="cx">     void parseWebVTTCueData(InbandTextTrackPrivate*, const char*, unsigned) override { ASSERT_NOT_REACHED(); }
</span><span class="cx">     void parseWebVTTCueData(InbandTextTrackPrivate*, const ISOWebVTTCue&amp;) override { ASSERT_NOT_REACHED(); }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorehtmltrackWebVTTParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/track/WebVTTParser.cpp (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/track/WebVTTParser.cpp        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WebCore/html/track/WebVTTParser.cpp        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -104,23 +104,24 @@
</span><span class="cx">     m_regionList.clear();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebVTTParser::parseFileHeader(String&amp;&amp; data)
</del><ins>+void WebVTTParser::parseFileHeader(const String&amp; data)
</ins><span class="cx"> {
</span><span class="cx">     m_state = Initial;
</span><span class="cx">     m_lineReader.reset();
</span><del>-    m_lineReader.append(WTFMove(data));
</del><ins>+    m_lineReader.append(data);
</ins><span class="cx">     parse();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebVTTParser::parseBytes(const char* data, unsigned length)
</span><span class="cx"> {
</span><del>-    m_lineReader.append(m_decoder-&gt;decode(data, length));
</del><ins>+    String textData = m_decoder-&gt;decode(data, length);
+    m_lineReader.append(textData);
</ins><span class="cx">     parse();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebVTTParser::parseCueData(const ISOWebVTTCue&amp; data)
</span><span class="cx"> {
</span><del>-    auto cue = WebVTTCueData::create();
</del><ins>+    RefPtr&lt;WebVTTCueData&gt; cue = WebVTTCueData::create();
</ins><span class="cx"> 
</span><span class="cx">     MediaTime startTime = data.presentationTime();
</span><span class="cx">     cue-&gt;setStartTime(startTime);
</span><span class="lines">@@ -134,7 +135,7 @@
</span><span class="cx">     if (WebVTTParser::collectTimeStamp(data.originalStartTime(), originalStartTime))
</span><span class="cx">         cue-&gt;setOriginalStartTime(originalStartTime);
</span><span class="cx"> 
</span><del>-    m_cuelist.append(WTFMove(cue));
</del><ins>+    m_cuelist.append(cue);
</ins><span class="cx">     if (m_client)
</span><span class="cx">         m_client-&gt;newCuesParsed();
</span><span class="cx"> }
</span><span class="lines">@@ -141,8 +142,9 @@
</span><span class="cx"> 
</span><span class="cx"> void WebVTTParser::flush()
</span><span class="cx"> {
</span><del>-    m_lineReader.append(m_decoder-&gt;flush());
-    m_lineReader.appendEndOfStream();
</del><ins>+    String textData = m_decoder-&gt;flush();
+    m_lineReader.append(textData);
+    m_lineReader.setEndOfStream();
</ins><span class="cx">     parse();
</span><span class="cx">     flushPendingCue();
</span><span class="cx"> }
</span><span class="lines">@@ -151,11 +153,15 @@
</span><span class="cx"> {    
</span><span class="cx">     // WebVTT parser algorithm. (5.1 WebVTT file parsing.)
</span><span class="cx">     // Steps 1 - 3 - Initial setup.
</span><del>-    while (auto line = m_lineReader.nextLine()) {
</del><ins>+    String line;
+    while (m_lineReader.getLine(line)) {
+        if (line.isNull())
+            return;
+
</ins><span class="cx">         switch (m_state) {
</span><span class="cx">         case Initial:
</span><span class="cx">             // Steps 4 - 9 - Check for a valid WebVTT signature.
</span><del>-            if (!hasRequiredFileIdentifier(*line)) {
</del><ins>+            if (!hasRequiredFileIdentifier(line)) {
</ins><span class="cx">                 if (m_client)
</span><span class="cx">                     m_client-&gt;fileFailedToParse();
</span><span class="cx">                 return;
</span><span class="lines">@@ -165,9 +171,9 @@
</span><span class="cx">             break;
</span><span class="cx"> 
</span><span class="cx">         case Header:
</span><del>-            collectMetadataHeader(*line);
</del><ins>+            collectMetadataHeader(line);
</ins><span class="cx"> 
</span><del>-            if (line-&gt;isEmpty()) {
</del><ins>+            if (line.isEmpty()) {
</ins><span class="cx">                 // Steps 10-14 - Allow a header (comment area) under the WEBVTT line.
</span><span class="cx">                 if (m_client &amp;&amp; m_regionList.size())
</span><span class="cx">                     m_client-&gt;newRegionsParsed();
</span><span class="lines">@@ -175,8 +181,8 @@
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             // Step 15 - Break out of header loop if the line could be a timestamp line.
</span><del>-            if (line-&gt;contains(&quot;--&gt;&quot;))
-                m_state = recoverCue(*line);
</del><ins>+            if (line.contains(&quot;--&gt;&quot;))
+                m_state = recoverCue(line);
</ins><span class="cx"> 
</span><span class="cx">             // Step 16 - Line is not the empty string and does not contain &quot;--&gt;&quot;.
</span><span class="cx">             break;
</span><span class="lines">@@ -183,7 +189,7 @@
</span><span class="cx"> 
</span><span class="cx">         case Id:
</span><span class="cx">             // Steps 17 - 20 - Allow any number of line terminators, then initialize new cue values.
</span><del>-            if (line-&gt;isEmpty())
</del><ins>+            if (line.isEmpty())
</ins><span class="cx">                 break;
</span><span class="cx"> 
</span><span class="cx">             // Step 21 - Cue creation (start a new cue).
</span><span class="lines">@@ -190,28 +196,28 @@
</span><span class="cx">             resetCueValues();
</span><span class="cx"> 
</span><span class="cx">             // Steps 22 - 25 - Check if this line contains an optional identifier or timing data.
</span><del>-            m_state = collectCueId(*line);
</del><ins>+            m_state = collectCueId(line);
</ins><span class="cx">             break;
</span><span class="cx"> 
</span><span class="cx">         case TimingsAndSettings:
</span><span class="cx">             // Steps 26 - 27 - Discard current cue if the line is empty.
</span><del>-            if (line-&gt;isEmpty()) {
</del><ins>+            if (line.isEmpty()) {
</ins><span class="cx">                 m_state = Id;
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx"> 
</span><span class="cx">             // Steps 28 - 29 - Collect cue timings and settings.
</span><del>-            m_state = collectTimingsAndSettings(*line);
</del><ins>+            m_state = collectTimingsAndSettings(line);
</ins><span class="cx">             break;
</span><span class="cx"> 
</span><span class="cx">         case CueText:
</span><span class="cx">             // Steps 31 - 41 - Collect the cue text, create a cue, and add it to the output.
</span><del>-            m_state = collectCueText(*line);
</del><ins>+            m_state = collectCueText(line);
</ins><span class="cx">             break;
</span><span class="cx"> 
</span><span class="cx">         case BadCue:
</span><span class="cx">             // Steps 42 - 48 - Discard lines until an empty line or a potential timing line is seen.
</span><del>-            m_state = ignoreBadCue(*line);
</del><ins>+            m_state = ignoreBadCue(line);
</ins><span class="cx">             break;
</span><span class="cx"> 
</span><span class="cx">         case Finished:
</span></span></pre></div>
<a id="trunkSourceWebCorehtmltrackWebVTTParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/track/WebVTTParser.h (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/track/WebVTTParser.h        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WebCore/html/track/WebVTTParser.h        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -133,7 +133,7 @@
</span><span class="cx"> 
</span><span class="cx">     // Input data to the parser to parse.
</span><span class="cx">     void parseBytes(const char*, unsigned);
</span><del>-    void parseFileHeader(String&amp;&amp;);
</del><ins>+    void parseFileHeader(const String&amp;);
</ins><span class="cx">     void parseCueData(const ISOWebVTTCue&amp;);
</span><span class="cx">     void flush();
</span><span class="cx">     void fileFinished();
</span></span></pre></div>
<a id="trunkSourceWebCorehtmltrackWebVTTTokenizercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/track/WebVTTTokenizer.cpp (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/track/WebVTTTokenizer.cpp        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WebCore/html/track/WebVTTTokenizer.cpp        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -30,10 +30,11 @@
</span><span class="cx">  */
</span><span class="cx"> 
</span><span class="cx"> #include &quot;config.h&quot;
</span><del>-#include &quot;WebVTTTokenizer.h&quot;
</del><span class="cx"> 
</span><span class="cx"> #if ENABLE(VIDEO_TRACK)
</span><span class="cx"> 
</span><ins>+#include &quot;WebVTTTokenizer.h&quot;
+
</ins><span class="cx"> #include &quot;MarkupTokenizerInlines.h&quot;
</span><span class="cx"> #include &lt;wtf/text/StringBuilder.h&gt;
</span><span class="cx"> #include &lt;wtf/unicode/CharacterNames.h&gt;
</span><span class="lines">@@ -47,7 +48,7 @@
</span><span class="cx">         character = m_preprocessor.nextInputCharacter();    \
</span><span class="cx">         goto stateName;                                     \
</span><span class="cx">     } while (false)
</span><del>-
</del><ins>+    
</ins><span class="cx"> template&lt;unsigned charactersCount&gt; ALWAYS_INLINE bool equalLiteral(const StringBuilder&amp; s, const char (&amp;characters)[charactersCount])
</span><span class="cx"> {
</span><span class="cx">     return WTF::equal(s, reinterpret_cast&lt;const LChar*&gt;(characters), charactersCount - 1);
</span><span class="lines">@@ -68,7 +69,7 @@
</span><span class="cx"> 
</span><span class="cx"> inline bool advanceAndEmitToken(SegmentedString&amp; source, WebVTTToken&amp; resultToken, const WebVTTToken&amp; token)
</span><span class="cx"> {
</span><del>-    source.advance();
</del><ins>+    source.advanceAndUpdateLineNumber();
</ins><span class="cx">     return emitToken(resultToken, token);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -78,7 +79,7 @@
</span><span class="cx"> {
</span><span class="cx">     // Append an EOF marker and close the input &quot;stream&quot;.
</span><span class="cx">     ASSERT(!m_input.isClosed());
</span><del>-    m_input.append(String { &amp;kEndOfFileMarker, 1 });
</del><ins>+    m_input.append(SegmentedString(String(&amp;kEndOfFileMarker, 1)));
</ins><span class="cx">     m_input.close();
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsInbandTextTrackPrivateClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/InbandTextTrackPrivateClient.h (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/InbandTextTrackPrivateClient.h        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WebCore/platform/graphics/InbandTextTrackPrivateClient.h        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -180,7 +180,7 @@
</span><span class="cx">     virtual void updateGenericCue(InbandTextTrackPrivate*, GenericCueData*) = 0;
</span><span class="cx">     virtual void removeGenericCue(InbandTextTrackPrivate*, GenericCueData*) = 0;
</span><span class="cx"> 
</span><del>-    virtual void parseWebVTTFileHeader(InbandTextTrackPrivate*, String&amp;&amp;) { ASSERT_NOT_REACHED(); }
</del><ins>+    virtual void parseWebVTTFileHeader(InbandTextTrackPrivate*, String) { ASSERT_NOT_REACHED(); }
</ins><span class="cx">     virtual void parseWebVTTCueData(InbandTextTrackPrivate*, const char* data, unsigned length) = 0;
</span><span class="cx">     virtual void parseWebVTTCueData(InbandTextTrackPrivate*, const ISOWebVTTCue&amp;) = 0;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformtextSegmentedStringcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/text/SegmentedString.cpp (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/text/SegmentedString.cpp        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WebCore/platform/text/SegmentedString.cpp        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>-    Copyright (C) 2004-2016 Apple Inc. All rights reserved.
</del><ins>+    Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
</ins><span class="cx"> 
</span><span class="cx">     This library is free software; you can redistribute it and/or
</span><span class="cx">     modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -20,204 +20,332 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;SegmentedString.h&quot;
</span><span class="cx"> 
</span><del>-#include &lt;wtf/text/StringBuilder.h&gt;
</del><span class="cx"> #include &lt;wtf/text/TextPosition.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-inline void SegmentedString::Substring::appendTo(StringBuilder&amp; builder) const
</del><ins>+SegmentedString::SegmentedString(const SegmentedString&amp; other)
+    : m_pushedChar1(other.m_pushedChar1)
+    , m_pushedChar2(other.m_pushedChar2)
+    , m_currentString(other.m_currentString)
+    , m_numberOfCharactersConsumedPriorToCurrentString(other.m_numberOfCharactersConsumedPriorToCurrentString)
+    , m_numberOfCharactersConsumedPriorToCurrentLine(other.m_numberOfCharactersConsumedPriorToCurrentLine)
+    , m_currentLine(other.m_currentLine)
+    , m_substrings(other.m_substrings)
+    , m_closed(other.m_closed)
+    , m_empty(other.m_empty)
+    , m_fastPathFlags(other.m_fastPathFlags)
+    , m_advanceFunc(other.m_advanceFunc)
+    , m_advanceAndUpdateLineNumberFunc(other.m_advanceAndUpdateLineNumberFunc)
</ins><span class="cx"> {
</span><del>-    builder.append(string, string.length() - length, length);
</del><ins>+    if (m_pushedChar2)
+        m_currentChar = m_pushedChar2;
+    else if (m_pushedChar1)
+        m_currentChar = m_pushedChar1;
+    else
+        m_currentChar = m_currentString.m_length ? m_currentString.getCurrentChar() : 0;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-SegmentedString&amp; SegmentedString::operator=(SegmentedString&amp;&amp; other)
</del><ins>+SegmentedString&amp; SegmentedString::operator=(const SegmentedString&amp; other)
</ins><span class="cx"> {
</span><del>-    m_currentSubstring = WTFMove(other.m_currentSubstring);
-    m_otherSubstrings = WTFMove(other.m_otherSubstrings);
</del><ins>+    m_pushedChar1 = other.m_pushedChar1;
+    m_pushedChar2 = other.m_pushedChar2;
+    m_currentString = other.m_currentString;
+    m_substrings = other.m_substrings;
+    if (m_pushedChar2)
+        m_currentChar = m_pushedChar2;
+    else if (m_pushedChar1)
+        m_currentChar = m_pushedChar1;
+    else
+        m_currentChar = m_currentString.m_length ? m_currentString.getCurrentChar() : 0;
</ins><span class="cx"> 
</span><del>-    m_isClosed = other.m_isClosed;
-
-    m_currentCharacter = other.m_currentCharacter;
-
-    m_numberOfCharactersConsumedPriorToCurrentSubstring = other.m_numberOfCharactersConsumedPriorToCurrentSubstring;
</del><ins>+    m_closed = other.m_closed;
+    m_empty = other.m_empty;
+    m_fastPathFlags = other.m_fastPathFlags;
+    m_numberOfCharactersConsumedPriorToCurrentString = other.m_numberOfCharactersConsumedPriorToCurrentString;
</ins><span class="cx">     m_numberOfCharactersConsumedPriorToCurrentLine = other.m_numberOfCharactersConsumedPriorToCurrentLine;
</span><span class="cx">     m_currentLine = other.m_currentLine;
</span><span class="cx"> 
</span><del>-    m_fastPathFlags = other.m_fastPathFlags;
-    m_advanceWithoutUpdatingLineNumberFunction = other.m_advanceWithoutUpdatingLineNumberFunction;
-    m_advanceAndUpdateLineNumberFunction = other.m_advanceAndUpdateLineNumberFunction;
</del><ins>+    m_advanceFunc = other.m_advanceFunc;
+    m_advanceAndUpdateLineNumberFunc = other.m_advanceAndUpdateLineNumberFunc;
</ins><span class="cx"> 
</span><del>-    other.clear();
-
</del><span class="cx">     return *this;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> unsigned SegmentedString::length() const
</span><span class="cx"> {
</span><del>-    unsigned length = m_currentSubstring.length;
-    for (auto&amp; substring : m_otherSubstrings)
-        length += substring.length;
</del><ins>+    unsigned length = m_currentString.m_length;
+    if (m_pushedChar1) {
+        ++length;
+        if (m_pushedChar2)
+            ++length;
+    }
+    if (isComposite()) {
+        Deque&lt;SegmentedSubstring&gt;::const_iterator it = m_substrings.begin();
+        Deque&lt;SegmentedSubstring&gt;::const_iterator e = m_substrings.end();
+        for (; it != e; ++it)
+            length += it-&gt;m_length;
+    }
</ins><span class="cx">     return length;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void SegmentedString::setExcludeLineNumbers()
</span><span class="cx"> {
</span><del>-    if (!m_currentSubstring.doNotExcludeLineNumbers)
-        return;
-    m_currentSubstring.doNotExcludeLineNumbers = false;
-    for (auto&amp; substring : m_otherSubstrings)
-        substring.doNotExcludeLineNumbers = false;
-    updateAdvanceFunctionPointers();
</del><ins>+    m_currentString.setExcludeLineNumbers();
+    if (isComposite()) {
+        Deque&lt;SegmentedSubstring&gt;::iterator it = m_substrings.begin();
+        Deque&lt;SegmentedSubstring&gt;::iterator e = m_substrings.end();
+        for (; it != e; ++it)
+            it-&gt;setExcludeLineNumbers();
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void SegmentedString::clear()
</span><span class="cx"> {
</span><del>-    m_currentSubstring.length = 0;
-    m_otherSubstrings.clear();
-
-    m_isClosed = false;
-
-    m_currentCharacter = 0;
-
-    m_numberOfCharactersConsumedPriorToCurrentSubstring = 0;
</del><ins>+    m_pushedChar1 = 0;
+    m_pushedChar2 = 0;
+    m_currentChar = 0;
+    m_currentString.clear();
+    m_numberOfCharactersConsumedPriorToCurrentString = 0;
</ins><span class="cx">     m_numberOfCharactersConsumedPriorToCurrentLine = 0;
</span><span class="cx">     m_currentLine = 0;
</span><ins>+    m_substrings.clear();
+    m_closed = false;
+    m_empty = true;
+    m_fastPathFlags = NoFastPath;
+    m_advanceFunc = &amp;SegmentedString::advanceEmpty;
+    m_advanceAndUpdateLineNumberFunc = &amp;SegmentedString::advanceEmpty;
+}
</ins><span class="cx"> 
</span><del>-    updateAdvanceFunctionPointersForEmptyString();
</del><ins>+void SegmentedString::append(const SegmentedSubstring&amp; s)
+{
+    ASSERT(!m_closed);
+    if (!s.m_length)
+        return;
+
+    if (!m_currentString.m_length) {
+        m_numberOfCharactersConsumedPriorToCurrentString += m_currentString.numberOfCharactersConsumed();
+        m_currentString = s;
+        updateAdvanceFunctionPointers();
+    } else
+        m_substrings.append(s);
+    m_empty = false;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline void SegmentedString::appendSubstring(Substring&amp;&amp; substring)
</del><ins>+void SegmentedString::pushBack(const SegmentedSubstring&amp; s)
</ins><span class="cx"> {
</span><del>-    ASSERT(!m_isClosed);
-    if (!substring.length)
</del><ins>+    ASSERT(!m_pushedChar1);
+    ASSERT(!s.numberOfCharactersConsumed());
+    if (!s.m_length)
</ins><span class="cx">         return;
</span><del>-    if (m_currentSubstring.length)
-        m_otherSubstrings.append(WTFMove(substring));
-    else {
-        m_numberOfCharactersConsumedPriorToCurrentSubstring += m_currentSubstring.numberOfCharactersConsumed();
-        m_currentSubstring = WTFMove(substring);
-        m_currentCharacter = m_currentSubstring.currentCharacter();
</del><ins>+
+    // FIXME: We're assuming that the characters were originally consumed by
+    //        this SegmentedString.  We're also ASSERTing that s is a fresh
+    //        SegmentedSubstring.  These assumptions are sufficient for our
+    //        current use, but we might need to handle the more elaborate
+    //        cases in the future.
+    m_numberOfCharactersConsumedPriorToCurrentString += m_currentString.numberOfCharactersConsumed();
+    m_numberOfCharactersConsumedPriorToCurrentString -= s.m_length;
+    if (!m_currentString.m_length) {
+        m_currentString = s;
</ins><span class="cx">         updateAdvanceFunctionPointers();
</span><ins>+    } else {
+        // Shift our m_currentString into our list.
+        m_substrings.prepend(m_currentString);
+        m_currentString = s;
+        updateAdvanceFunctionPointers();
</ins><span class="cx">     }
</span><ins>+    m_empty = false;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void SegmentedString::pushBack(String&amp;&amp; string)
</del><ins>+void SegmentedString::close()
</ins><span class="cx"> {
</span><del>-    // We never create a substring for an empty string.
-    ASSERT(string.length());
</del><ins>+    // Closing a stream twice is likely a coding mistake.
+    ASSERT(!m_closed);
+    m_closed = true;
+}
</ins><span class="cx"> 
</span><del>-    // The new substring we will create won't have the doNotExcludeLineNumbers set appropriately.
-    // That was lost when the characters were consumed before pushing them back. But this does
-    // not matter, because clients never use this for newlines. Catch that with this assertion.
-    ASSERT(!string.contains('\n'));
-
-    // The characters in the string must be previously consumed characters from this segmented string.
-    ASSERT(string.length() &lt;= numberOfCharactersConsumed());
-
-    m_numberOfCharactersConsumedPriorToCurrentSubstring += m_currentSubstring.numberOfCharactersConsumed();
-    if (m_currentSubstring.length)
-        m_otherSubstrings.prepend(WTFMove(m_currentSubstring));
-    m_currentSubstring = WTFMove(string);
-    m_numberOfCharactersConsumedPriorToCurrentSubstring -= m_currentSubstring.length;
-    m_currentCharacter = m_currentSubstring.currentCharacter();
-    updateAdvanceFunctionPointers();
</del><ins>+void SegmentedString::append(const SegmentedString&amp; s)
+{
+    ASSERT(!m_closed);
+    ASSERT(!s.m_pushedChar1);
+    append(s.m_currentString);
+    if (s.isComposite()) {
+        Deque&lt;SegmentedSubstring&gt;::const_iterator it = s.m_substrings.begin();
+        Deque&lt;SegmentedSubstring&gt;::const_iterator e = s.m_substrings.end();
+        for (; it != e; ++it)
+            append(*it);
+    }
+    m_currentChar = m_pushedChar1 ? m_pushedChar1 : (m_currentString.m_length ? m_currentString.getCurrentChar() : 0);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void SegmentedString::close()
</del><ins>+void SegmentedString::pushBack(const SegmentedString&amp; s)
</ins><span class="cx"> {
</span><del>-    ASSERT(!m_isClosed);
-    m_isClosed = true;
</del><ins>+    ASSERT(!m_pushedChar1);
+    ASSERT(!s.m_pushedChar1);
+    if (s.isComposite()) {
+        Deque&lt;SegmentedSubstring&gt;::const_reverse_iterator it = s.m_substrings.rbegin();
+        Deque&lt;SegmentedSubstring&gt;::const_reverse_iterator e = s.m_substrings.rend();
+        for (; it != e; ++it)
+            pushBack(*it);
+    }
+    pushBack(s.m_currentString);
+    m_currentChar = m_pushedChar1 ? m_pushedChar1 : (m_currentString.m_length ? m_currentString.getCurrentChar() : 0);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void SegmentedString::append(const SegmentedString&amp; string)
</del><ins>+void SegmentedString::advanceSubstring()
</ins><span class="cx"> {
</span><del>-    appendSubstring(Substring { string.m_currentSubstring });
-    for (auto&amp; substring : string.m_otherSubstrings)
-        m_otherSubstrings.append(substring);
</del><ins>+    if (isComposite()) {
+        m_numberOfCharactersConsumedPriorToCurrentString += m_currentString.numberOfCharactersConsumed();
+        m_currentString = m_substrings.takeFirst();
+        // If we've previously consumed some characters of the non-current
+        // string, we now account for those characters as part of the current
+        // string, not as part of &quot;prior to current string.&quot;
+        m_numberOfCharactersConsumedPriorToCurrentString -= m_currentString.numberOfCharactersConsumed();
+        updateAdvanceFunctionPointers();
+    } else {
+        m_currentString.clear();
+        m_empty = true;
+        m_fastPathFlags = NoFastPath;
+        m_advanceFunc = &amp;SegmentedString::advanceEmpty;
+        m_advanceAndUpdateLineNumberFunc = &amp;SegmentedString::advanceEmpty;
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void SegmentedString::append(SegmentedString&amp;&amp; string)
</del><ins>+String SegmentedString::toString() const
</ins><span class="cx"> {
</span><del>-    appendSubstring(WTFMove(string.m_currentSubstring));
-    for (auto&amp; substring : string.m_otherSubstrings)
-        m_otherSubstrings.append(WTFMove(substring));
</del><ins>+    StringBuilder result;
+    if (m_pushedChar1) {
+        result.append(m_pushedChar1);
+        if (m_pushedChar2)
+            result.append(m_pushedChar2);
+    }
+    m_currentString.appendTo(result);
+    if (isComposite()) {
+        Deque&lt;SegmentedSubstring&gt;::const_iterator it = m_substrings.begin();
+        Deque&lt;SegmentedSubstring&gt;::const_iterator e = m_substrings.end();
+        for (; it != e; ++it)
+            it-&gt;appendTo(result);
+    }
+    return result.toString();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void SegmentedString::append(String&amp;&amp; string)
</del><ins>+void SegmentedString::advancePastNonNewlines(unsigned count, UChar* consumedCharacters)
</ins><span class="cx"> {
</span><del>-    appendSubstring(WTFMove(string));
</del><ins>+    ASSERT_WITH_SECURITY_IMPLICATION(count &lt;= length());
+    for (unsigned i = 0; i &lt; count; ++i) {
+        consumedCharacters[i] = currentChar();
+        advancePastNonNewline();
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void SegmentedString::append(const String&amp; string)
</del><ins>+void SegmentedString::advance8()
</ins><span class="cx"> {
</span><del>-    appendSubstring(String { string });
</del><ins>+    ASSERT(!m_pushedChar1);
+    decrementAndCheckLength();
+    m_currentChar = m_currentString.incrementAndGetCurrentChar8();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-String SegmentedString::toString() const
</del><ins>+void SegmentedString::advance16()
</ins><span class="cx"> {
</span><del>-    StringBuilder result;
-    m_currentSubstring.appendTo(result);
-    for (auto&amp; substring : m_otherSubstrings)
-        substring.appendTo(result);
-    return result.toString();
</del><ins>+    ASSERT(!m_pushedChar1);
+    decrementAndCheckLength();
+    m_currentChar = m_currentString.incrementAndGetCurrentChar16();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void SegmentedString::advanceWithoutUpdatingLineNumber16()
</del><ins>+void SegmentedString::advanceAndUpdateLineNumber8()
</ins><span class="cx"> {
</span><del>-    m_currentCharacter = *++m_currentSubstring.currentCharacter16;
</del><ins>+    ASSERT(!m_pushedChar1);
+    ASSERT(m_currentString.getCurrentChar() == m_currentChar);
+    if (m_currentChar == '\n') {
+        ++m_currentLine;
+        m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersConsumed() + 1;
+    }
</ins><span class="cx">     decrementAndCheckLength();
</span><ins>+    m_currentChar = m_currentString.incrementAndGetCurrentChar8();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void SegmentedString::advanceAndUpdateLineNumber16()
</span><span class="cx"> {
</span><del>-    ASSERT(m_currentSubstring.doNotExcludeLineNumbers);
-    processPossibleNewline();
-    m_currentCharacter = *++m_currentSubstring.currentCharacter16;
</del><ins>+    ASSERT(!m_pushedChar1);
+    ASSERT(m_currentString.getCurrentChar() == m_currentChar);
+    if (m_currentChar == '\n') {
+        ++m_currentLine;
+        m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersConsumed() + 1;
+    }
</ins><span class="cx">     decrementAndCheckLength();
</span><ins>+    m_currentChar = m_currentString.incrementAndGetCurrentChar16();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline void SegmentedString::advancePastSingleCharacterSubstringWithoutUpdatingLineNumber()
</del><ins>+void SegmentedString::advanceSlowCase()
</ins><span class="cx"> {
</span><del>-    ASSERT(m_currentSubstring.length == 1);
-    if (m_otherSubstrings.isEmpty()) {
-        m_currentSubstring.length = 0;
-        m_currentCharacter = 0;
-        updateAdvanceFunctionPointersForEmptyString();
-        return;
</del><ins>+    if (m_pushedChar1) {
+        m_pushedChar1 = m_pushedChar2;
+        m_pushedChar2 = 0;
+
+        if (m_pushedChar1) {
+            m_currentChar = m_pushedChar1;
+            return;
+        }
+
+        updateAdvanceFunctionPointers();
+    } else if (m_currentString.m_length) {
+        if (--m_currentString.m_length == 0)
+            advanceSubstring();
+    } else if (!isComposite()) {
+        m_currentString.clear();
+        m_empty = true;
+        m_fastPathFlags = NoFastPath;
+        m_advanceFunc = &amp;SegmentedString::advanceEmpty;
+        m_advanceAndUpdateLineNumberFunc = &amp;SegmentedString::advanceEmpty;
</ins><span class="cx">     }
</span><del>-    m_numberOfCharactersConsumedPriorToCurrentSubstring += m_currentSubstring.numberOfCharactersConsumed();
-    m_currentSubstring = m_otherSubstrings.takeFirst();
-    // If we've previously consumed some characters of the non-current string, we now account for those
-    // characters as part of the current string, not as part of &quot;prior to current string.&quot;
-    m_numberOfCharactersConsumedPriorToCurrentSubstring -= m_currentSubstring.numberOfCharactersConsumed();
-    m_currentCharacter = m_currentSubstring.currentCharacter();
-    updateAdvanceFunctionPointers();
</del><ins>+    m_currentChar = m_currentString.m_length ? m_currentString.getCurrentChar() : 0;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void SegmentedString::advancePastSingleCharacterSubstring()
</del><ins>+void SegmentedString::advanceAndUpdateLineNumberSlowCase()
</ins><span class="cx"> {
</span><del>-    ASSERT(m_currentSubstring.length == 1);
-    ASSERT(m_currentSubstring.doNotExcludeLineNumbers);
-    processPossibleNewline();
-    advancePastSingleCharacterSubstringWithoutUpdatingLineNumber();
</del><ins>+    if (m_pushedChar1) {
+        m_pushedChar1 = m_pushedChar2;
+        m_pushedChar2 = 0;
+
+        if (m_pushedChar1) {
+            m_currentChar = m_pushedChar1;
+            return;
+        }
+
+        updateAdvanceFunctionPointers();
+    } else if (m_currentString.m_length) {
+        if (m_currentString.getCurrentChar() == '\n' &amp;&amp; m_currentString.doNotExcludeLineNumbers()) {
+            ++m_currentLine;
+            // Plus 1 because numberOfCharactersConsumed value hasn't incremented yet; it does with m_length decrement below.
+            m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersConsumed() + 1;
+        }
+        if (--m_currentString.m_length == 0)
+            advanceSubstring();
+        else
+            m_currentString.incrementAndGetCurrentChar(); // Only need the ++
+    } else if (!isComposite()) {
+        m_currentString.clear();
+        m_empty = true;
+        m_fastPathFlags = NoFastPath;
+        m_advanceFunc = &amp;SegmentedString::advanceEmpty;
+        m_advanceAndUpdateLineNumberFunc = &amp;SegmentedString::advanceEmpty;
+    }
+
+    m_currentChar = m_currentString.m_length ? m_currentString.getCurrentChar() : 0;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void SegmentedString::advanceEmpty()
</span><span class="cx"> {
</span><del>-    ASSERT(!m_currentSubstring.length);
-    ASSERT(m_otherSubstrings.isEmpty());
-    ASSERT(!m_currentCharacter);
</del><ins>+    ASSERT(!m_currentString.m_length &amp;&amp; !isComposite());
+    m_currentChar = 0;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void SegmentedString::updateAdvanceFunctionPointersForSingleCharacterSubstring()
</del><ins>+void SegmentedString::updateSlowCaseFunctionPointers()
</ins><span class="cx"> {
</span><del>-    ASSERT(m_currentSubstring.length == 1);
</del><span class="cx">     m_fastPathFlags = NoFastPath;
</span><del>-    m_advanceWithoutUpdatingLineNumberFunction = &amp;SegmentedString::advancePastSingleCharacterSubstringWithoutUpdatingLineNumber;
-    if (m_currentSubstring.doNotExcludeLineNumbers)
-        m_advanceAndUpdateLineNumberFunction = &amp;SegmentedString::advancePastSingleCharacterSubstring;
-    else
-        m_advanceAndUpdateLineNumberFunction = &amp;SegmentedString::advancePastSingleCharacterSubstringWithoutUpdatingLineNumber;
</del><ins>+    m_advanceFunc = &amp;SegmentedString::advanceSlowCase;
+    m_advanceAndUpdateLineNumberFunc = &amp;SegmentedString::advanceAndUpdateLineNumberSlowCase;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> OrdinalNumber SegmentedString::currentLine() const
</span><span class="lines">@@ -236,36 +364,18 @@
</span><span class="cx">     m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersConsumed() + prologLength - columnAftreProlog.zeroBasedInt();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-SegmentedString::AdvancePastResult SegmentedString::advancePastSlowCase(const char* literal, bool lettersIgnoringASCIICase)
</del><ins>+SegmentedString::AdvancePastResult SegmentedString::advancePastSlowCase(const char* literal, bool caseSensitive)
</ins><span class="cx"> {
</span><del>-    constexpr unsigned maxLength = 10;
-    ASSERT(!strchr(literal, '\n'));
-    auto length = strlen(literal);
-    ASSERT(length &lt;= maxLength);
</del><ins>+    unsigned length = strlen(literal);
</ins><span class="cx">     if (length &gt; this-&gt;length())
</span><span class="cx">         return NotEnoughCharacters;
</span><del>-    UChar consumedCharacters[maxLength];
-    for (unsigned i = 0; i &lt; length; ++i) {
-        auto character = m_currentCharacter;
-        if (characterMismatch(character, literal[i], lettersIgnoringASCIICase)) {
-            if (i)
-                pushBack(String { consumedCharacters, i });
-            return DidNotMatch;
-        }
-        advancePastNonNewline();
-        consumedCharacters[i] = character;
-    }
-    return DidMatch;
</del><ins>+    UChar* consumedCharacters;
+    String consumedString = String::createUninitialized(length, consumedCharacters);
+    advancePastNonNewlines(length, consumedCharacters);
+    if (consumedString.startsWith(literal, caseSensitive))
+        return DidMatch;
+    pushBack(SegmentedString(consumedString));
+    return DidNotMatch;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void SegmentedString::updateAdvanceFunctionPointersForEmptyString()
-{
-    ASSERT(!m_currentSubstring.length);
-    ASSERT(m_otherSubstrings.isEmpty());
-    ASSERT(!m_currentCharacter);
-    m_fastPathFlags = NoFastPath;
-    m_advanceWithoutUpdatingLineNumberFunction = &amp;SegmentedString::advanceEmpty;
-    m_advanceAndUpdateLineNumberFunction = &amp;SegmentedString::advanceEmpty;
</del><span class="cx"> }
</span><del>-
-}
</del></span></pre></div>
<a id="trunkSourceWebCoreplatformtextSegmentedStringh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/text/SegmentedString.h (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/text/SegmentedString.h        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WebCore/platform/text/SegmentedString.h        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>-    Copyright (C) 2004-2016 Apple Inc. All rights reserved.
</del><ins>+    Copyright (C) 2004-2008, 2015 Apple Inc. All rights reserved.
</ins><span class="cx"> 
</span><span class="cx">     This library is free software; you can redistribute it and/or
</span><span class="cx">     modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -17,307 +17,381 @@
</span><span class="cx">     Boston, MA 02110-1301, USA.
</span><span class="cx"> */
</span><span class="cx"> 
</span><del>-#pragma once
</del><ins>+#ifndef SegmentedString_h
+#define SegmentedString_h
</ins><span class="cx"> 
</span><span class="cx"> #include &lt;wtf/Deque.h&gt;
</span><del>-#include &lt;wtf/text/WTFString.h&gt;
</del><ins>+#include &lt;wtf/text/StringBuilder.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-// FIXME: This should not start with &quot;k&quot;.
-// FIXME: This is a shared tokenizer concept, not a SegmentedString concept, but this is the only common header for now.
-constexpr LChar kEndOfFileMarker = 0;
</del><ins>+class SegmentedString;
</ins><span class="cx"> 
</span><del>-class SegmentedString {
</del><ins>+class SegmentedSubstring {
</ins><span class="cx"> public:
</span><del>-    SegmentedString() = default;
-    SegmentedString(String&amp;&amp;);
-    SegmentedString(const String&amp;);
</del><ins>+    SegmentedSubstring()
+        : m_length(0)
+        , m_doNotExcludeLineNumbers(true)
+        , m_is8Bit(false)
+    {
+        m_data.string16Ptr = 0;
+    }
</ins><span class="cx"> 
</span><del>-    SegmentedString(SegmentedString&amp;&amp;) = delete;
-    SegmentedString(const SegmentedString&amp;) = delete;
</del><ins>+    SegmentedSubstring(const String&amp; str)
+        : m_length(str.length())
+        , m_doNotExcludeLineNumbers(true)
+        , m_string(str)
+    {
+        if (m_length) {
+            if (m_string.is8Bit()) {
+                m_is8Bit = true;
+                m_data.string8Ptr = m_string.characters8();
+            } else {
+                m_is8Bit = false;
+                m_data.string16Ptr = m_string.characters16();
+            }
+        } else
+            m_is8Bit = false;
+    }
</ins><span class="cx"> 
</span><del>-    SegmentedString&amp; operator=(SegmentedString&amp;&amp;);
-    SegmentedString&amp; operator=(const SegmentedString&amp;) = default;
</del><ins>+    void clear() { m_length = 0; m_data.string16Ptr = 0; m_is8Bit = false;}
+    
+    bool is8Bit() { return m_is8Bit; }
+    
+    bool excludeLineNumbers() const { return !m_doNotExcludeLineNumbers; }
+    bool doNotExcludeLineNumbers() const { return m_doNotExcludeLineNumbers; }
</ins><span class="cx"> 
</span><del>-    void clear();
-    void close();
</del><ins>+    void setExcludeLineNumbers() { m_doNotExcludeLineNumbers = false; }
</ins><span class="cx"> 
</span><del>-    void append(SegmentedString&amp;&amp;);
-    void append(const SegmentedString&amp;);
</del><ins>+    int numberOfCharactersConsumed() const { return m_string.length() - m_length; }
</ins><span class="cx"> 
</span><del>-    void append(String&amp;&amp;);
-    void append(const String&amp;);
</del><ins>+    void appendTo(StringBuilder&amp; builder) const
+    {
+        int offset = m_string.length() - m_length;
</ins><span class="cx"> 
</span><del>-    void pushBack(String&amp;&amp;);
</del><ins>+        if (!offset) {
+            if (m_length)
+                builder.append(m_string);
+        } else
+            builder.append(m_string.substring(offset, m_length));
+    }
</ins><span class="cx"> 
</span><del>-    void setExcludeLineNumbers();
</del><ins>+    UChar getCurrentChar8()
+    {
+        return *m_data.string8Ptr;
+    }
</ins><span class="cx"> 
</span><del>-    bool isEmpty() const { return !m_currentSubstring.length; }
-    unsigned length() const;
</del><ins>+    UChar getCurrentChar16()
+    {
+        return m_data.string16Ptr ? *m_data.string16Ptr : 0;
+    }
</ins><span class="cx"> 
</span><del>-    bool isClosed() const { return m_isClosed; }
</del><ins>+    UChar incrementAndGetCurrentChar8()
+    {
+        ASSERT(m_data.string8Ptr);
+        return *++m_data.string8Ptr;
+    }
</ins><span class="cx"> 
</span><del>-    void advance();
-    void advancePastNonNewline(); // Faster than calling advance when we know the current character is not a newline.
-    void advancePastNewline(); // Faster than calling advance when we know the current character is a newline.
</del><ins>+    UChar incrementAndGetCurrentChar16()
+    {
+        ASSERT(m_data.string16Ptr);
+        return *++m_data.string16Ptr;
+    }
</ins><span class="cx"> 
</span><del>-    enum AdvancePastResult { DidNotMatch, DidMatch, NotEnoughCharacters };
-    template&lt;unsigned length&gt; AdvancePastResult advancePast(const char (&amp;literal)[length]) { return advancePast&lt;length, false&gt;(literal); }
-    template&lt;unsigned length&gt; AdvancePastResult advancePastLettersIgnoringASCIICase(const char (&amp;literal)[length]) { return advancePast&lt;length, true&gt;(literal); }
</del><ins>+    String currentSubString(unsigned length)
+    {
+        int offset = m_string.length() - m_length;
+        return m_string.substring(offset, length);
+    }
</ins><span class="cx"> 
</span><del>-    unsigned numberOfCharactersConsumed() const;
</del><ins>+    ALWAYS_INLINE UChar getCurrentChar()
+    {
+        ASSERT(m_length);
+        if (is8Bit())
+            return getCurrentChar8();
+        return getCurrentChar16();
+    }
+    
+    ALWAYS_INLINE UChar incrementAndGetCurrentChar()
+    {
+        ASSERT(m_length);
+        if (is8Bit())
+            return incrementAndGetCurrentChar8();
+        return incrementAndGetCurrentChar16();
+    }
</ins><span class="cx"> 
</span><del>-    String toString() const;
</del><ins>+public:
+    union {
+        const LChar* string8Ptr;
+        const UChar* string16Ptr;
+    } m_data;
+    int m_length;
</ins><span class="cx"> 
</span><del>-    UChar currentCharacter() const { return m_currentCharacter; }
</del><ins>+private:
+    bool m_doNotExcludeLineNumbers;
+    bool m_is8Bit;
+    String m_string;
+};
</ins><span class="cx"> 
</span><del>-    OrdinalNumber currentColumn() const;
-    OrdinalNumber currentLine() const;
</del><ins>+class SegmentedString {
+public:
+    SegmentedString()
+        : m_pushedChar1(0)
+        , m_pushedChar2(0)
+        , m_currentChar(0)
+        , m_numberOfCharactersConsumedPriorToCurrentString(0)
+        , m_numberOfCharactersConsumedPriorToCurrentLine(0)
+        , m_currentLine(0)
+        , m_closed(false)
+        , m_empty(true)
+        , m_fastPathFlags(NoFastPath)
+        , m_advanceFunc(&amp;SegmentedString::advanceEmpty)
+        , m_advanceAndUpdateLineNumberFunc(&amp;SegmentedString::advanceEmpty)
+    {
+    }
</ins><span class="cx"> 
</span><del>-    // Sets value of line/column variables. Column is specified indirectly by a parameter columnAfterProlog
-    // which is a value of column that we should get after a prolog (first prologLength characters) has been consumed.
-    void setCurrentPosition(OrdinalNumber line, OrdinalNumber columnAfterProlog, int prologLength);
</del><ins>+    SegmentedString(const String&amp; str)
+        : m_pushedChar1(0)
+        , m_pushedChar2(0)
+        , m_currentString(str)
+        , m_currentChar(0)
+        , m_numberOfCharactersConsumedPriorToCurrentString(0)
+        , m_numberOfCharactersConsumedPriorToCurrentLine(0)
+        , m_currentLine(0)
+        , m_closed(false)
+        , m_empty(!str.length())
+        , m_fastPathFlags(NoFastPath)
+    {
+        if (m_currentString.m_length)
+            m_currentChar = m_currentString.getCurrentChar();
+        updateAdvanceFunctionPointers();
+    }
</ins><span class="cx"> 
</span><del>-private:
-    struct Substring {
-        Substring() = default;
-        Substring(String&amp;&amp;);
</del><ins>+    SegmentedString(const SegmentedString&amp;);
+    SegmentedString&amp; operator=(const SegmentedString&amp;);
</ins><span class="cx"> 
</span><del>-        UChar currentCharacter() const;
-        UChar currentCharacterPreIncrement();
</del><ins>+    void clear();
+    void close();
</ins><span class="cx"> 
</span><del>-        unsigned numberOfCharactersConsumed() const;
-        void appendTo(StringBuilder&amp;) const;
</del><ins>+    void append(const SegmentedString&amp;);
+    void pushBack(const SegmentedString&amp;);
</ins><span class="cx"> 
</span><del>-        String string;
-        unsigned length { 0 };
-        bool is8Bit;
-        union {
-            const LChar* currentCharacter8;
-            const UChar* currentCharacter16;
-        };
-        bool doNotExcludeLineNumbers { true };
-    };
</del><ins>+    void setExcludeLineNumbers();
</ins><span class="cx"> 
</span><del>-    enum FastPathFlags {
-        NoFastPath = 0,
-        Use8BitAdvanceAndUpdateLineNumbers = 1 &lt;&lt; 0,
-        Use8BitAdvance = 1 &lt;&lt; 1,
-    };
</del><ins>+    void push(UChar c)
+    {
+        if (!m_pushedChar1) {
+            m_pushedChar1 = c;
+            m_currentChar = m_pushedChar1 ? m_pushedChar1 : m_currentString.getCurrentChar();
+            updateSlowCaseFunctionPointers();
+        } else {
+            ASSERT(!m_pushedChar2);
+            m_pushedChar2 = c;
+        }
+    }
</ins><span class="cx"> 
</span><del>-    void appendSubstring(Substring&amp;&amp;);
</del><ins>+    bool isEmpty() const { return m_empty; }
+    unsigned length() const;
</ins><span class="cx"> 
</span><del>-    void processPossibleNewline();
-    void startNewLine();
</del><ins>+    bool isClosed() const { return m_closed; }
</ins><span class="cx"> 
</span><del>-    void advanceWithoutUpdatingLineNumber();
-    void advanceWithoutUpdatingLineNumber16();
-    void advanceAndUpdateLineNumber16();
-    void advancePastSingleCharacterSubstringWithoutUpdatingLineNumber();
-    void advancePastSingleCharacterSubstring();
-    void advanceEmpty();
</del><ins>+    enum AdvancePastResult { DidNotMatch, DidMatch, NotEnoughCharacters };
+    template&lt;unsigned length&gt; AdvancePastResult advancePast(const char (&amp;literal)[length]) { return advancePast(literal, length - 1, true); }
+    template&lt;unsigned length&gt; AdvancePastResult advancePastIgnoringCase(const char (&amp;literal)[length]) { return advancePast(literal, length - 1, false); }
</ins><span class="cx"> 
</span><del>-    void updateAdvanceFunctionPointers();
-    void updateAdvanceFunctionPointersForEmptyString();
-    void updateAdvanceFunctionPointersForSingleCharacterSubstring();
</del><ins>+    void advance()
+    {
+        if (m_fastPathFlags &amp; Use8BitAdvance) {
+            ASSERT(!m_pushedChar1);
+            bool haveOneCharacterLeft = (--m_currentString.m_length == 1);
+            m_currentChar = m_currentString.incrementAndGetCurrentChar8();
</ins><span class="cx"> 
</span><del>-    void decrementAndCheckLength();
</del><ins>+            if (!haveOneCharacterLeft)
+                return;
</ins><span class="cx"> 
</span><del>-    template&lt;typename CharacterType&gt; static bool characterMismatch(CharacterType, char, bool lettersIgnoringASCIICase);
-    template&lt;unsigned length, bool lettersIgnoringASCIICase&gt; AdvancePastResult advancePast(const char (&amp;literal)[length]);
-    AdvancePastResult advancePastSlowCase(const char* literal, bool lettersIgnoringASCIICase);
</del><ins>+            updateSlowCaseFunctionPointers();
</ins><span class="cx"> 
</span><del>-    Substring m_currentSubstring;
-    Deque&lt;Substring&gt; m_otherSubstrings;
</del><ins>+            return;
+        }
</ins><span class="cx"> 
</span><del>-    bool m_isClosed { false };
</del><ins>+        (this-&gt;*m_advanceFunc)();
+    }
</ins><span class="cx"> 
</span><del>-    UChar m_currentCharacter { 0 };
</del><ins>+    void advanceAndUpdateLineNumber()
+    {
+        if (m_fastPathFlags &amp; Use8BitAdvance) {
+            ASSERT(!m_pushedChar1);
</ins><span class="cx"> 
</span><del>-    unsigned m_numberOfCharactersConsumedPriorToCurrentSubstring { 0 };
-    unsigned m_numberOfCharactersConsumedPriorToCurrentLine { 0 };
-    int m_currentLine { 0 };
</del><ins>+            bool haveNewLine = (m_currentChar == '\n') &amp; !!(m_fastPathFlags &amp; Use8BitAdvanceAndUpdateLineNumbers);
+            bool haveOneCharacterLeft = (--m_currentString.m_length == 1);
</ins><span class="cx"> 
</span><del>-    unsigned char m_fastPathFlags { NoFastPath };
-    void (SegmentedString::*m_advanceWithoutUpdatingLineNumberFunction)() { &amp;SegmentedString::advanceEmpty };
-    void (SegmentedString::*m_advanceAndUpdateLineNumberFunction)() { &amp;SegmentedString::advanceEmpty };
-};
</del><ins>+            m_currentChar = m_currentString.incrementAndGetCurrentChar8();
</ins><span class="cx"> 
</span><del>-inline SegmentedString::Substring::Substring(String&amp;&amp; passedString)
-    : string(WTFMove(passedString))
-    , length(string.length())
-{
-    if (length) {
-        is8Bit = string.impl()-&gt;is8Bit();
-        if (is8Bit)
-            currentCharacter8 = string.impl()-&gt;characters8();
-        else
-            currentCharacter16 = string.impl()-&gt;characters16();
-    }
-}
</del><ins>+            if (!(haveNewLine | haveOneCharacterLeft))
+                return;
</ins><span class="cx"> 
</span><del>-inline unsigned SegmentedString::Substring::numberOfCharactersConsumed() const
-{
-    return string.length() - length;
-}
</del><ins>+            if (haveNewLine) {
+                ++m_currentLine;
+                m_numberOfCharactersConsumedPriorToCurrentLine =  m_numberOfCharactersConsumedPriorToCurrentString + m_currentString.numberOfCharactersConsumed();
+            }
</ins><span class="cx"> 
</span><del>-ALWAYS_INLINE UChar SegmentedString::Substring::currentCharacter() const
-{
-    ASSERT(length);
-    return is8Bit ? *currentCharacter8 : *currentCharacter16;
-}
</del><ins>+            if (haveOneCharacterLeft)
+                updateSlowCaseFunctionPointers();
</ins><span class="cx"> 
</span><del>-ALWAYS_INLINE UChar SegmentedString::Substring::currentCharacterPreIncrement()
-{
-    ASSERT(length);
-    return is8Bit ? *++currentCharacter8 : *++currentCharacter16;
-}
</del><ins>+            return;
+        }
</ins><span class="cx"> 
</span><del>-inline SegmentedString::SegmentedString(String&amp;&amp; string)
-    : m_currentSubstring(WTFMove(string))
-{
-    if (m_currentSubstring.length) {
-        m_currentCharacter = m_currentSubstring.currentCharacter();
-        updateAdvanceFunctionPointers();
</del><ins>+        (this-&gt;*m_advanceAndUpdateLineNumberFunc)();
</ins><span class="cx">     }
</span><del>-}
</del><span class="cx"> 
</span><del>-inline SegmentedString::SegmentedString(const String&amp; string)
-    : SegmentedString(String { string })
-{
-}
</del><ins>+    void advancePastNonNewline()
+    {
+        ASSERT(currentChar() != '\n');
+        advance();
+    }
</ins><span class="cx"> 
</span><del>-ALWAYS_INLINE void SegmentedString::decrementAndCheckLength()
-{
-    ASSERT(m_currentSubstring.length &gt; 1);
-    if (UNLIKELY(--m_currentSubstring.length == 1))
-        updateAdvanceFunctionPointersForSingleCharacterSubstring();
-}
</del><ins>+    void advancePastNewlineAndUpdateLineNumber()
+    {
+        ASSERT(currentChar() == '\n');
+        if (!m_pushedChar1 &amp;&amp; m_currentString.m_length &gt; 1) {
+            int newLineFlag = m_currentString.doNotExcludeLineNumbers();
+            m_currentLine += newLineFlag;
+            if (newLineFlag)
+                m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersConsumed() + 1;
+            decrementAndCheckLength();
+            m_currentChar = m_currentString.incrementAndGetCurrentChar();
+            return;
+        }
+        advanceAndUpdateLineNumberSlowCase();
+    }
</ins><span class="cx"> 
</span><del>-ALWAYS_INLINE void SegmentedString::advanceWithoutUpdatingLineNumber()
-{
-    if (LIKELY(m_fastPathFlags &amp; Use8BitAdvance)) {
-        m_currentCharacter = *++m_currentSubstring.currentCharacter8;
-        decrementAndCheckLength();
-        return;
</del><ins>+    int numberOfCharactersConsumed() const
+    {
+        int numberOfPushedCharacters = 0;
+        if (m_pushedChar1) {
+            ++numberOfPushedCharacters;
+            if (m_pushedChar2)
+                ++numberOfPushedCharacters;
+        }
+        return m_numberOfCharactersConsumedPriorToCurrentString + m_currentString.numberOfCharactersConsumed() - numberOfPushedCharacters;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    (this-&gt;*m_advanceWithoutUpdatingLineNumberFunction)();
-}
</del><ins>+    String toString() const;
</ins><span class="cx"> 
</span><del>-inline void SegmentedString::startNewLine()
-{
-    ++m_currentLine;
-    m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersConsumed();
-}
</del><ins>+    UChar currentChar() const { return m_currentChar; }    
</ins><span class="cx"> 
</span><del>-inline void SegmentedString::processPossibleNewline()
-{
-    if (m_currentCharacter == '\n')
-        startNewLine();
-}
</del><ins>+    OrdinalNumber currentColumn() const;
+    OrdinalNumber currentLine() const;
</ins><span class="cx"> 
</span><del>-inline void SegmentedString::advance()
-{
-    if (LIKELY(m_fastPathFlags &amp; Use8BitAdvance)) {
-        ASSERT(m_currentSubstring.length &gt; 1);
-        bool lastCharacterWasNewline = m_currentCharacter == '\n';
-        m_currentCharacter = *++m_currentSubstring.currentCharacter8;
-        bool haveOneCharacterLeft = --m_currentSubstring.length == 1;
-        if (LIKELY(!(lastCharacterWasNewline | haveOneCharacterLeft)))
-            return;
-        if (lastCharacterWasNewline &amp; !!(m_fastPathFlags &amp; Use8BitAdvanceAndUpdateLineNumbers))
-            startNewLine();
-        if (haveOneCharacterLeft)
-            updateAdvanceFunctionPointersForSingleCharacterSubstring();
-        return;
</del><ins>+    // Sets value of line/column variables. Column is specified indirectly by a parameter columnAfterProlog
+    // which is a value of column that we should get after a prolog (first prologLength characters) has been consumed.
+    void setCurrentPosition(OrdinalNumber line, OrdinalNumber columnAfterProlog, int prologLength);
+
+private:
+    enum FastPathFlags {
+        NoFastPath = 0,
+        Use8BitAdvanceAndUpdateLineNumbers = 1 &lt;&lt; 0,
+        Use8BitAdvance = 1 &lt;&lt; 1,
+    };
+
+    void append(const SegmentedSubstring&amp;);
+    void pushBack(const SegmentedSubstring&amp;);
+
+    void advance8();
+    void advance16();
+    void advanceAndUpdateLineNumber8();
+    void advanceAndUpdateLineNumber16();
+    void advanceSlowCase();
+    void advanceAndUpdateLineNumberSlowCase();
+    void advanceEmpty();
+    void advanceSubstring();
+    
+    void updateSlowCaseFunctionPointers();
+
+    void decrementAndCheckLength()
+    {
+        ASSERT(m_currentString.m_length &gt; 1);
+        if (--m_currentString.m_length == 1)
+            updateSlowCaseFunctionPointers();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    (this-&gt;*m_advanceAndUpdateLineNumberFunction)();
-}
</del><ins>+    void updateAdvanceFunctionPointers()
+    {
+        if ((m_currentString.m_length &gt; 1) &amp;&amp; !m_pushedChar1) {
+            if (m_currentString.is8Bit()) {
+                m_advanceFunc = &amp;SegmentedString::advance8;
+                m_fastPathFlags = Use8BitAdvance;
+                if (m_currentString.doNotExcludeLineNumbers()) {
+                    m_advanceAndUpdateLineNumberFunc = &amp;SegmentedString::advanceAndUpdateLineNumber8;
+                    m_fastPathFlags |= Use8BitAdvanceAndUpdateLineNumbers;
+                } else
+                    m_advanceAndUpdateLineNumberFunc = &amp;SegmentedString::advance8;
+                return;
+            }
</ins><span class="cx"> 
</span><del>-ALWAYS_INLINE void SegmentedString::advancePastNonNewline()
-{
-    ASSERT(m_currentCharacter != '\n');
-    advanceWithoutUpdatingLineNumber();
-}
</del><ins>+            m_advanceFunc = &amp;SegmentedString::advance16;
+            m_fastPathFlags = NoFastPath;
+            if (m_currentString.doNotExcludeLineNumbers())
+                m_advanceAndUpdateLineNumberFunc = &amp;SegmentedString::advanceAndUpdateLineNumber16;
+            else
+                m_advanceAndUpdateLineNumberFunc = &amp;SegmentedString::advance16;
+            return;
+        }
</ins><span class="cx"> 
</span><del>-inline void SegmentedString::advancePastNewline()
-{
-    ASSERT(m_currentCharacter == '\n');
-    if (m_currentSubstring.length &gt; 1) {
-        if (m_currentSubstring.doNotExcludeLineNumbers)
-            startNewLine();
-        m_currentCharacter = m_currentSubstring.currentCharacterPreIncrement();
-        decrementAndCheckLength();
-        return;
</del><ins>+        if (!m_currentString.m_length &amp;&amp; !isComposite()) {
+            m_advanceFunc = &amp;SegmentedString::advanceEmpty;
+            m_fastPathFlags = NoFastPath;
+            m_advanceAndUpdateLineNumberFunc = &amp;SegmentedString::advanceEmpty;
+        }
+
+        updateSlowCaseFunctionPointers();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    (this-&gt;*m_advanceAndUpdateLineNumberFunction)();
-}
</del><ins>+    // Writes consumed characters into consumedCharacters, which must have space for at least |count| characters.
+    void advancePastNonNewlines(unsigned count);
+    void advancePastNonNewlines(unsigned count, UChar* consumedCharacters);
</ins><span class="cx"> 
</span><del>-inline unsigned SegmentedString::numberOfCharactersConsumed() const
-{
-    return m_numberOfCharactersConsumedPriorToCurrentSubstring + m_currentSubstring.numberOfCharactersConsumed();
-}
</del><ins>+    AdvancePastResult advancePast(const char* literal, unsigned length, bool caseSensitive);
+    AdvancePastResult advancePastSlowCase(const char* literal, bool caseSensitive);
</ins><span class="cx"> 
</span><del>-template&lt;typename CharacterType&gt; ALWAYS_INLINE bool SegmentedString::characterMismatch(CharacterType a, char b, bool lettersIgnoringASCIICase)
</del><ins>+    bool isComposite() const { return !m_substrings.isEmpty(); }
+
+    UChar m_pushedChar1;
+    UChar m_pushedChar2;
+    SegmentedSubstring m_currentString;
+    UChar m_currentChar;
+    int m_numberOfCharactersConsumedPriorToCurrentString;
+    int m_numberOfCharactersConsumedPriorToCurrentLine;
+    int m_currentLine;
+    Deque&lt;SegmentedSubstring&gt; m_substrings;
+    bool m_closed;
+    bool m_empty;
+    unsigned char m_fastPathFlags;
+    void (SegmentedString::*m_advanceFunc)();
+    void (SegmentedString::*m_advanceAndUpdateLineNumberFunc)();
+};
+
+inline void SegmentedString::advancePastNonNewlines(unsigned count)
</ins><span class="cx"> {
</span><del>-    return lettersIgnoringASCIICase ? !isASCIIAlphaCaselessEqual(a, b) : a != b;
</del><ins>+    for (unsigned i = 0; i &lt; count; ++i)
+        advancePastNonNewline();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-template&lt;unsigned lengthIncludingTerminator, bool lettersIgnoringASCIICase&gt; SegmentedString::AdvancePastResult SegmentedString::advancePast(const char (&amp;literal)[lengthIncludingTerminator])
</del><ins>+inline SegmentedString::AdvancePastResult SegmentedString::advancePast(const char* literal, unsigned length, bool caseSensitive)
</ins><span class="cx"> {
</span><del>-    constexpr unsigned length = lengthIncludingTerminator - 1;
-    ASSERT(!literal[length]);
</del><ins>+    ASSERT(strlen(literal) == length);
</ins><span class="cx">     ASSERT(!strchr(literal, '\n'));
</span><del>-    if (length + 1 &lt; m_currentSubstring.length) {
-        if (m_currentSubstring.is8Bit) {
-            for (unsigned i = 0; i &lt; length; ++i) {
-                if (characterMismatch(m_currentSubstring.currentCharacter8[i], literal[i], lettersIgnoringASCIICase))
-                    return DidNotMatch;
-            }
-            m_currentSubstring.currentCharacter8 += length;
-            m_currentCharacter = *m_currentSubstring.currentCharacter8;
-        } else {
-            for (unsigned i = 0; i &lt; length; ++i) {
-                if (characterMismatch(m_currentSubstring.currentCharacter16[i], literal[i], lettersIgnoringASCIICase))
-                    return DidNotMatch;
-            }
-            m_currentSubstring.currentCharacter16 += length;
-            m_currentCharacter = *m_currentSubstring.currentCharacter16;
</del><ins>+    if (!m_pushedChar1) {
+        if (length &lt;= static_cast&lt;unsigned&gt;(m_currentString.m_length)) {
+            if (!m_currentString.currentSubString(length).startsWith(literal, caseSensitive))
+                return DidNotMatch;
+            advancePastNonNewlines(length);
+            return DidMatch;
</ins><span class="cx">         }
</span><del>-        m_currentSubstring.length -= length;
-        return DidMatch;
</del><span class="cx">     }
</span><del>-    return advancePastSlowCase(literal, lettersIgnoringASCIICase);
</del><ins>+    return advancePastSlowCase(literal, caseSensitive);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline void SegmentedString::updateAdvanceFunctionPointers()
-{
-    if (m_currentSubstring.length &gt; 1) {
-        if (m_currentSubstring.is8Bit) {
-            m_fastPathFlags = Use8BitAdvance;
-            if (m_currentSubstring.doNotExcludeLineNumbers)
-                m_fastPathFlags |= Use8BitAdvanceAndUpdateLineNumbers;
-            return;
-        }
-        m_fastPathFlags = NoFastPath;
-        m_advanceWithoutUpdatingLineNumberFunction = &amp;SegmentedString::advanceWithoutUpdatingLineNumber16;
-        if (m_currentSubstring.doNotExcludeLineNumbers)
-            m_advanceAndUpdateLineNumberFunction = &amp;SegmentedString::advanceAndUpdateLineNumber16;
-        else
-            m_advanceAndUpdateLineNumberFunction = &amp;SegmentedString::advanceWithoutUpdatingLineNumber16;
-        return;
-    }
-
-    if (!m_currentSubstring.length) {
-        updateAdvanceFunctionPointersForEmptyString();
-        return;
-    }
-
-    updateAdvanceFunctionPointersForSingleCharacterSubstring();
</del><span class="cx"> }
</span><span class="cx"> 
</span><del>-}
</del><ins>+#endif
</ins></span></pre></div>
<a id="trunkSourceWebCorexmlparserCharacterReferenceParserInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/xml/parser/CharacterReferenceParserInlines.h (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/xml/parser/CharacterReferenceParserInlines.h        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WebCore/xml/parser/CharacterReferenceParserInlines.h        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -30,9 +30,9 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-inline void unconsumeCharacters(SegmentedString&amp; source, StringBuilder&amp; consumedCharacters)
</del><ins>+inline void unconsumeCharacters(SegmentedString&amp; source, const StringBuilder&amp; consumedCharacters)
</ins><span class="cx"> {
</span><del>-    source.pushBack(consumedCharacters.toString());
</del><ins>+    source.pushBack(SegmentedString(consumedCharacters.toStringPreserveCapacity()));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template &lt;typename ParserFunctions&gt;
</span><span class="lines">@@ -56,7 +56,7 @@
</span><span class="cx">     StringBuilder consumedCharacters;
</span><span class="cx">     
</span><span class="cx">     while (!source.isEmpty()) {
</span><del>-        UChar character = source.currentCharacter();
</del><ins>+        UChar character = source.currentChar();
</ins><span class="cx">         switch (state) {
</span><span class="cx">         case Initial:
</span><span class="cx">             if (character == '\x09' || character == '\x0A' || character == '\x0C' || character == ' ' || character == '&lt;' || character == '&amp;')
</span><span class="lines">@@ -85,7 +85,7 @@
</span><span class="cx">                 state = Decimal;
</span><span class="cx">                 goto Decimal;
</span><span class="cx">             }
</span><del>-            source.pushBack(ASCIILiteral(&quot;#&quot;));
</del><ins>+            source.pushBack(SegmentedString(ASCIILiteral(&quot;#&quot;)));
</ins><span class="cx">             return false;
</span><span class="cx">         case MaybeHexLowerCaseX:
</span><span class="cx">             if (isASCIIHexDigit(character)) {
</span><span class="lines">@@ -92,7 +92,7 @@
</span><span class="cx">                 state = Hex;
</span><span class="cx">                 goto Hex;
</span><span class="cx">             }
</span><del>-            source.pushBack(ASCIILiteral(&quot;#x&quot;));
</del><ins>+            source.pushBack(SegmentedString(ASCIILiteral(&quot;#x&quot;)));
</ins><span class="cx">             return false;
</span><span class="cx">         case MaybeHexUpperCaseX:
</span><span class="cx">             if (isASCIIHexDigit(character)) {
</span><span class="lines">@@ -99,7 +99,7 @@
</span><span class="cx">                 state = Hex;
</span><span class="cx">                 goto Hex;
</span><span class="cx">             }
</span><del>-            source.pushBack(ASCIILiteral(&quot;#X&quot;));
</del><ins>+            source.pushBack(SegmentedString(ASCIILiteral(&quot;#X&quot;)));
</ins><span class="cx">             return false;
</span><span class="cx">         case Hex:
</span><span class="cx">         Hex:
</span><span class="lines">@@ -110,7 +110,7 @@
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             if (character == ';') {
</span><del>-                source.advancePastNonNewline();
</del><ins>+                source.advance();
</ins><span class="cx">                 decodedCharacter.append(ParserFunctions::legalEntityFor(overflow ? 0 : result));
</span><span class="cx">                 return true;
</span><span class="cx">             }
</span><span class="lines">@@ -129,7 +129,7 @@
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             if (character == ';') {
</span><del>-                source.advancePastNonNewline();
</del><ins>+                source.advance();
</ins><span class="cx">                 decodedCharacter.append(ParserFunctions::legalEntityFor(overflow ? 0 : result));
</span><span class="cx">                 return true;
</span><span class="cx">             }
</span><span class="lines">@@ -144,7 +144,7 @@
</span><span class="cx">             return ParserFunctions::consumeNamedEntity(source, decodedCharacter, notEnoughCharacters, additionalAllowedCharacter, character);
</span><span class="cx">         }
</span><span class="cx">         consumedCharacters.append(character);
</span><del>-        source.advancePastNonNewline();
</del><ins>+        source.advance();
</ins><span class="cx">     }
</span><span class="cx">     ASSERT(source.isEmpty());
</span><span class="cx">     notEnoughCharacters = true;
</span></span></pre></div>
<a id="trunkSourceWebCorexmlparserMarkupTokenizerInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/xml/parser/MarkupTokenizerInlines.h (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/xml/parser/MarkupTokenizerInlines.h        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WebCore/xml/parser/MarkupTokenizerInlines.h        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2008-2016 Apple Inc. All Rights Reserved.
</del><ins>+ * Copyright (C) 2008, 2015 Apple Inc. All Rights Reserved.
</ins><span class="cx">  * Copyright (C) 2009 Torch Mobile, Inc. http://www.torchmobile.com/
</span><span class="cx">  * Copyright (C) 2010 Google, Inc. All Rights Reserved.
</span><span class="cx">  *
</span><span class="lines">@@ -27,6 +27,8 @@
</span><span class="cx"> 
</span><span class="cx"> #pragma once
</span><span class="cx"> 
</span><ins>+#include &quot;SegmentedString.h&quot;
+
</ins><span class="cx"> #if COMPILER(MSVC)
</span><span class="cx"> // Disable the &quot;unreachable code&quot; warning so we can compile the ASSERT_NOT_REACHED in the END_STATE macro.
</span><span class="cx"> #pragma warning(disable: 4702)
</span><span class="lines">@@ -42,7 +44,7 @@
</span><span class="cx"> #define BEGIN_STATE(stateName)                                  \
</span><span class="cx">     case stateName:                                             \
</span><span class="cx">     stateName: {                                                \
</span><del>-        constexpr auto currentState = stateName;                \
</del><ins>+        const auto currentState = stateName;                    \
</ins><span class="cx">         UNUSED_PARAM(currentState);
</span><span class="cx"> 
</span><span class="cx"> #define END_STATE()                                             \
</span><span class="lines">@@ -72,15 +74,6 @@
</span><span class="cx">         character = m_preprocessor.nextInputCharacter();        \
</span><span class="cx">         goto newState;                                          \
</span><span class="cx">     } while (false)
</span><del>-#define ADVANCE_PAST_NON_NEWLINE_TO(newState)                   \
-    do {                                                        \
-        if (!m_preprocessor.advancePastNonNewline(source, isNullCharacterSkippingState(newState))) { \
-            m_state = newState;                                 \
-            return haveBufferedCharacterToken();                \
-        }                                                       \
-        character = m_preprocessor.nextInputCharacter();        \
-        goto newState;                                          \
-    } while (false)
</del><span class="cx"> 
</span><span class="cx"> // For more complex cases, caller consumes the characters first and then uses this macro.
</span><span class="cx"> #define SWITCH_TO(newState)                                     \
</span></span></pre></div>
<a id="trunkSourceWebCorexmlparserXMLDocumentParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/xml/parser/XMLDocumentParser.cpp (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/xml/parser/XMLDocumentParser.cpp        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WebCore/xml/parser/XMLDocumentParser.cpp        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -100,7 +100,7 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void XMLDocumentParser::insert(SegmentedString&amp;&amp;)
</del><ins>+void XMLDocumentParser::insert(const SegmentedString&amp;)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT_NOT_REACHED();
</span><span class="cx"> }
</span><span class="lines">@@ -107,8 +107,7 @@
</span><span class="cx"> 
</span><span class="cx"> void XMLDocumentParser::append(RefPtr&lt;StringImpl&gt;&amp;&amp; inputSource)
</span><span class="cx"> {
</span><del>-    String source { WTFMove(inputSource) };
-
</del><ins>+    SegmentedString source(WTFMove(inputSource));
</ins><span class="cx">     if (m_sawXSLTransform || !m_sawFirstElement)
</span><span class="cx">         m_originalSourceForTransform.append(source);
</span><span class="cx"> 
</span><span class="lines">@@ -120,7 +119,7 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    doWrite(source);
</del><ins>+    doWrite(source.toString());
</ins><span class="cx"> 
</span><span class="cx">     // After parsing, dispatch image beforeload events.
</span><span class="cx">     ImageLoader::dispatchPendingBeforeLoadEvents();
</span><span class="lines">@@ -153,6 +152,7 @@
</span><span class="cx">     return String::fromUTF8(reinterpret_cast&lt;const char*&gt;(string), size); 
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> bool XMLDocumentParser::updateLeafTextNode()
</span><span class="cx"> {
</span><span class="cx">     if (isStopped())
</span></span></pre></div>
<a id="trunkSourceWebCorexmlparserXMLDocumentParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/xml/parser/XMLDocumentParser.h (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/xml/parser/XMLDocumentParser.h        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WebCore/xml/parser/XMLDocumentParser.h        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -1,6 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  * Copyright (C) 2000 Peter Kelly (pmk@post.com)
</span><del>- * Copyright (C) 2005-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
</ins><span class="cx">  * Copyright (C) 2007 Samuel Weinig (sam@webkit.org)
</span><span class="cx">  * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
</span><span class="cx">  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
</span><span class="lines">@@ -29,163 +29,164 @@
</span><span class="cx"> #include &quot;ScriptableDocumentParser.h&quot;
</span><span class="cx"> #include &quot;SegmentedString.h&quot;
</span><span class="cx"> #include &quot;XMLErrors.h&quot;
</span><del>-#include &lt;libxml/tree.h&gt;
-#include &lt;libxml/xmlstring.h&gt;
</del><span class="cx"> #include &lt;wtf/HashMap.h&gt;
</span><span class="cx"> #include &lt;wtf/text/AtomicStringHash.h&gt;
</span><span class="cx"> #include &lt;wtf/text/CString.h&gt;
</span><span class="cx"> 
</span><ins>+#include &lt;libxml/tree.h&gt;
+#include &lt;libxml/xmlstring.h&gt;
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> class ContainerNode;
</span><span class="cx"> class CachedResourceLoader;
</span><span class="cx"> class DocumentFragment;
</span><ins>+class Document;
</ins><span class="cx"> class Element;
</span><span class="cx"> class FrameView;
</span><span class="cx"> class PendingCallbacks;
</span><ins>+class PendingScript;
</ins><span class="cx"> class Text;
</span><span class="cx"> 
</span><del>-class XMLParserContext : public RefCounted&lt;XMLParserContext&gt; {
-public:
-    static RefPtr&lt;XMLParserContext&gt; createMemoryParser(xmlSAXHandlerPtr, void* userData, const CString&amp; chunk);
-    static Ref&lt;XMLParserContext&gt; createStringParser(xmlSAXHandlerPtr, void* userData);
-    ~XMLParserContext();
-    xmlParserCtxtPtr context() const { return m_context; }
</del><ins>+    class XMLParserContext : public RefCounted&lt;XMLParserContext&gt; {
+    public:
+        static RefPtr&lt;XMLParserContext&gt; createMemoryParser(xmlSAXHandlerPtr, void* userData, const CString&amp; chunk);
+        static Ref&lt;XMLParserContext&gt; createStringParser(xmlSAXHandlerPtr, void* userData);
+        ~XMLParserContext();
+        xmlParserCtxtPtr context() const { return m_context; }
</ins><span class="cx"> 
</span><del>-private:
-    XMLParserContext(xmlParserCtxtPtr context)
-        : m_context(context)
-    {
-    }
-    xmlParserCtxtPtr m_context;
-};
</del><ins>+    private:
+        XMLParserContext(xmlParserCtxtPtr context)
+            : m_context(context)
+        {
+        }
+        xmlParserCtxtPtr m_context;
+    };
</ins><span class="cx"> 
</span><del>-class XMLDocumentParser final : public ScriptableDocumentParser, public PendingScriptClient {
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    static Ref&lt;XMLDocumentParser&gt; create(Document&amp; document, FrameView* view)
-    {
-        return adoptRef(*new XMLDocumentParser(document, view));
-    }
-    static Ref&lt;XMLDocumentParser&gt; create(DocumentFragment&amp; fragment, Element* element, ParserContentPolicy parserContentPolicy)
-    {
-        return adoptRef(*new XMLDocumentParser(fragment, element, parserContentPolicy));
-    }
</del><ins>+    class XMLDocumentParser final : public ScriptableDocumentParser, public PendingScriptClient {
+        WTF_MAKE_FAST_ALLOCATED;
+    public:
+        static Ref&lt;XMLDocumentParser&gt; create(Document&amp; document, FrameView* view)
+        {
+            return adoptRef(*new XMLDocumentParser(document, view));
+        }
+        static Ref&lt;XMLDocumentParser&gt; create(DocumentFragment&amp; fragment, Element* element, ParserContentPolicy parserContentPolicy)
+        {
+            return adoptRef(*new XMLDocumentParser(fragment, element, parserContentPolicy));
+        }
</ins><span class="cx"> 
</span><del>-    ~XMLDocumentParser();
</del><ins>+        ~XMLDocumentParser();
</ins><span class="cx"> 
</span><del>-    // Exposed for callbacks:
-    void handleError(XMLErrors::ErrorType, const char* message, TextPosition);
</del><ins>+        // Exposed for callbacks:
+        void handleError(XMLErrors::ErrorType, const char* message, TextPosition);
</ins><span class="cx"> 
</span><del>-    void setIsXHTMLDocument(bool isXHTML) { m_isXHTMLDocument = isXHTML; }
-    bool isXHTMLDocument() const { return m_isXHTMLDocument; }
</del><ins>+        void setIsXHTMLDocument(bool isXHTML) { m_isXHTMLDocument = isXHTML; }
+        bool isXHTMLDocument() const { return m_isXHTMLDocument; }
</ins><span class="cx"> 
</span><del>-    static bool parseDocumentFragment(const String&amp;, DocumentFragment&amp;, Element* parent = nullptr, ParserContentPolicy = AllowScriptingContent);
</del><ins>+        static bool parseDocumentFragment(const String&amp;, DocumentFragment&amp;, Element* parent = nullptr, ParserContentPolicy = AllowScriptingContent);
</ins><span class="cx"> 
</span><del>-    // Used by XMLHttpRequest to check if the responseXML was well formed.
-    bool wellFormed() const final { return !m_sawError; }
</del><ins>+        // Used by the XMLHttpRequest to check if the responseXML was well formed.
+        bool wellFormed() const override { return !m_sawError; }
</ins><span class="cx"> 
</span><del>-    static bool supportsXMLVersion(const String&amp;);
</del><ins>+        static bool supportsXMLVersion(const String&amp;);
</ins><span class="cx"> 
</span><del>-private:
-    explicit XMLDocumentParser(Document&amp;, FrameView* = nullptr);
-    XMLDocumentParser(DocumentFragment&amp;, Element*, ParserContentPolicy);
</del><ins>+    private:
+        XMLDocumentParser(Document&amp;, FrameView* = nullptr);
+        XMLDocumentParser(DocumentFragment&amp;, Element*, ParserContentPolicy);
</ins><span class="cx"> 
</span><del>-    void insert(SegmentedString&amp;&amp;) final;
-    void append(RefPtr&lt;StringImpl&gt;&amp;&amp;) final;
-    void finish() final;
-    bool isWaitingForScripts() const final;
-    void stopParsing() final;
-    void detach() final;
</del><ins>+        // From DocumentParser
+        void insert(const SegmentedString&amp;) override;
+        void append(RefPtr&lt;StringImpl&gt;&amp;&amp;) override;
+        void finish() override;
+        bool isWaitingForScripts() const override;
+        void stopParsing() override;
+        void detach() override;
</ins><span class="cx"> 
</span><del>-    TextPosition textPosition() const final;
-    bool shouldAssociateConsoleMessagesWithTextPosition() const final;
</del><ins>+        TextPosition textPosition() const override;
+        bool shouldAssociateConsoleMessagesWithTextPosition() const override;
</ins><span class="cx"> 
</span><del>-    void notifyFinished(PendingScript&amp;) final;
</del><ins>+        void notifyFinished(PendingScript&amp;) final;
</ins><span class="cx"> 
</span><del>-    void end();
</del><ins>+        void end();
</ins><span class="cx"> 
</span><del>-    void pauseParsing();
-    void resumeParsing();
</del><ins>+        void pauseParsing();
+        void resumeParsing();
</ins><span class="cx"> 
</span><del>-    bool appendFragmentSource(const String&amp;);
</del><ins>+        bool appendFragmentSource(const String&amp;);
</ins><span class="cx"> 
</span><del>-public:
-    // Callbacks from parser SAX, and other functions needed inside
-    // the parser implementation, but outside this class.
</del><ins>+    public:
+        // callbacks from parser SAX
+        void error(XMLErrors::ErrorType, const char* message, va_list args) WTF_ATTRIBUTE_PRINTF(3, 0);
+        void startElementNs(const xmlChar* xmlLocalName, const xmlChar* xmlPrefix, const xmlChar* xmlURI, int nb_namespaces,
+                            const xmlChar** namespaces, int nb_attributes, int nb_defaulted, const xmlChar** libxmlAttributes);
+        void endElementNs();
+        void characters(const xmlChar* s, int len);
+        void processingInstruction(const xmlChar* target, const xmlChar* data);
+        void cdataBlock(const xmlChar* s, int len);
+        void comment(const xmlChar* s);
+        void startDocument(const xmlChar* version, const xmlChar* encoding, int standalone);
+        void internalSubset(const xmlChar* name, const xmlChar* externalID, const xmlChar* systemID);
+        void endDocument();
</ins><span class="cx"> 
</span><del>-    void error(XMLErrors::ErrorType, const char* message, va_list args) WTF_ATTRIBUTE_PRINTF(3, 0);
-    void startElementNs(const xmlChar* xmlLocalName, const xmlChar* xmlPrefix, const xmlChar* xmlURI,
-        int numNamespaces, const xmlChar** namespaces,
-        int numAttributes, int numDefaulted, const xmlChar** libxmlAttributes);
-    void endElementNs();
-    void characters(const xmlChar*, int length);
-    void processingInstruction(const xmlChar* target, const xmlChar* data);
-    void cdataBlock(const xmlChar*, int length);
-    void comment(const xmlChar*);
-    void startDocument(const xmlChar* version, const xmlChar* encoding, int standalone);
-    void internalSubset(const xmlChar* name, const xmlChar* externalID, const xmlChar* systemID);
-    void endDocument();
</del><ins>+        bool isParsingEntityDeclaration() const { return m_isParsingEntityDeclaration; }
+        void setIsParsingEntityDeclaration(bool value) { m_isParsingEntityDeclaration = value; }
</ins><span class="cx"> 
</span><del>-    bool isParsingEntityDeclaration() const { return m_isParsingEntityDeclaration; }
-    void setIsParsingEntityDeclaration(bool value) { m_isParsingEntityDeclaration = value; }
</del><ins>+        int depthTriggeringEntityExpansion() const { return m_depthTriggeringEntityExpansion; }
+        void setDepthTriggeringEntityExpansion(int depth) { m_depthTriggeringEntityExpansion = depth; }
</ins><span class="cx"> 
</span><del>-    int depthTriggeringEntityExpansion() const { return m_depthTriggeringEntityExpansion; }
-    void setDepthTriggeringEntityExpansion(int depth) { m_depthTriggeringEntityExpansion = depth; }
</del><ins>+    private:
+        void initializeParserContext(const CString&amp; chunk = CString());
</ins><span class="cx"> 
</span><del>-private:
-    void initializeParserContext(const CString&amp; chunk = CString());
</del><ins>+        void pushCurrentNode(ContainerNode*);
+        void popCurrentNode();
+        void clearCurrentNodeStack();
</ins><span class="cx"> 
</span><del>-    void pushCurrentNode(ContainerNode*);
-    void popCurrentNode();
-    void clearCurrentNodeStack();
</del><ins>+        void insertErrorMessageBlock();
</ins><span class="cx"> 
</span><del>-    void insertErrorMessageBlock();
</del><ins>+        void createLeafTextNode();
+        bool updateLeafTextNode();
</ins><span class="cx"> 
</span><del>-    void createLeafTextNode();
-    bool updateLeafTextNode();
</del><ins>+        void doWrite(const String&amp;);
+        void doEnd();
</ins><span class="cx"> 
</span><del>-    void doWrite(const String&amp;);
-    void doEnd();
</del><ins>+        FrameView* m_view;
</ins><span class="cx"> 
</span><del>-    xmlParserCtxtPtr context() const { return m_context ? m_context-&gt;context() : nullptr; };
</del><ins>+        SegmentedString m_originalSourceForTransform;
</ins><span class="cx"> 
</span><del>-    FrameView* m_view { nullptr };
</del><ins>+        xmlParserCtxtPtr context() const { return m_context ? m_context-&gt;context() : nullptr; };
+        RefPtr&lt;XMLParserContext&gt; m_context;
+        std::unique_ptr&lt;PendingCallbacks&gt; m_pendingCallbacks;
+        Vector&lt;xmlChar&gt; m_bufferedText;
+        int m_depthTriggeringEntityExpansion;
+        bool m_isParsingEntityDeclaration;
</ins><span class="cx"> 
</span><del>-    SegmentedString m_originalSourceForTransform;
</del><ins>+        ContainerNode* m_currentNode;
+        Vector&lt;ContainerNode*&gt; m_currentNodeStack;
</ins><span class="cx"> 
</span><del>-    RefPtr&lt;XMLParserContext&gt; m_context;
-    std::unique_ptr&lt;PendingCallbacks&gt; m_pendingCallbacks;
-    Vector&lt;xmlChar&gt; m_bufferedText;
-    int m_depthTriggeringEntityExpansion { -1 };
-    bool m_isParsingEntityDeclaration { false };
</del><ins>+        RefPtr&lt;Text&gt; m_leafTextNode;
</ins><span class="cx"> 
</span><del>-    ContainerNode* m_currentNode { nullptr };
-    Vector&lt;ContainerNode*&gt; m_currentNodeStack;
</del><ins>+        bool m_sawError;
+        bool m_sawCSS;
+        bool m_sawXSLTransform;
+        bool m_sawFirstElement;
+        bool m_isXHTMLDocument;
+        bool m_parserPaused;
+        bool m_requestingScript;
+        bool m_finishCalled;
</ins><span class="cx"> 
</span><del>-    RefPtr&lt;Text&gt; m_leafTextNode;
</del><ins>+        std::unique_ptr&lt;XMLErrors&gt; m_xmlErrors;
</ins><span class="cx"> 
</span><del>-    bool m_sawError { false };
-    bool m_sawCSS { false };
-    bool m_sawXSLTransform { false };
-    bool m_sawFirstElement { false };
-    bool m_isXHTMLDocument { false };
-    bool m_parserPaused { false };
-    bool m_requestingScript { false };
-    bool m_finishCalled { false };
</del><ins>+        RefPtr&lt;PendingScript&gt; m_pendingScript;
+        TextPosition m_scriptStartPosition;
</ins><span class="cx"> 
</span><del>-    std::unique_ptr&lt;XMLErrors&gt; m_xmlErrors;
</del><ins>+        bool m_parsingFragment;
+        AtomicString m_defaultNamespaceURI;
</ins><span class="cx"> 
</span><del>-    RefPtr&lt;PendingScript&gt; m_pendingScript;
-    TextPosition m_scriptStartPosition;
</del><ins>+        typedef HashMap&lt;AtomicString, AtomicString&gt; PrefixForNamespaceMap;
+        PrefixForNamespaceMap m_prefixToNamespaceMap;
+        SegmentedString m_pendingSrc;
+    };
</ins><span class="cx"> 
</span><del>-    bool m_parsingFragment { false };
-    AtomicString m_defaultNamespaceURI;
-
-    HashMap&lt;AtomicString, AtomicString&gt; m_prefixToNamespaceMap;
-    SegmentedString m_pendingSrc;
-};
-
</del><span class="cx"> #if ENABLE(XSLT)
</span><span class="cx"> void* xmlDocPtrForString(CachedResourceLoader&amp;, const String&amp; source, const String&amp; url);
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCorexmlparserXMLDocumentParserLibxml2cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/xml/parser/XMLDocumentParserLibxml2.cpp (209119 => 209120)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/xml/parser/XMLDocumentParserLibxml2.cpp        2016-11-30 04:43:08 UTC (rev 209119)
+++ trunk/Source/WebCore/xml/parser/XMLDocumentParserLibxml2.cpp        2016-11-30 04:54:04 UTC (rev 209120)
</span><span class="lines">@@ -1,6 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  * Copyright (C) 2000 Peter Kelly &lt;pmk@post.com&gt;
</span><del>- * Copyright (C) 2005-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved.
</ins><span class="cx">  * Copyright (C) 2006 Alexey Proskuryakov &lt;ap@webkit.org&gt;
</span><span class="cx">  * Copyright (C) 2007 Samuel Weinig &lt;sam@webkit.org&gt;
</span><span class="cx">  * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
</span><span class="lines">@@ -35,23 +35,35 @@
</span><span class="cx"> #include &quot;DocumentFragment.h&quot;
</span><span class="cx"> #include &quot;DocumentType.h&quot;
</span><span class="cx"> #include &quot;Frame.h&quot;
</span><ins>+#include &quot;FrameLoader.h&quot;
+#include &quot;FrameView.h&quot;
</ins><span class="cx"> #include &quot;HTMLEntityParser.h&quot;
</span><span class="cx"> #include &quot;HTMLHtmlElement.h&quot;
</span><ins>+#include &quot;HTMLLinkElement.h&quot;
+#include &quot;HTMLNames.h&quot;
+#include &quot;HTMLStyleElement.h&quot;
</ins><span class="cx"> #include &quot;HTMLTemplateElement.h&quot;
</span><ins>+#include &quot;LoadableClassicScript.h&quot;
</ins><span class="cx"> #include &quot;Page.h&quot;
</span><span class="cx"> #include &quot;PendingScript.h&quot;
</span><span class="cx"> #include &quot;ProcessingInstruction.h&quot;
</span><span class="cx"> #include &quot;ResourceError.h&quot;
</span><ins>+#include &quot;ResourceRequest.h&quot;
</ins><span class="cx"> #include &quot;ResourceResponse.h&quot;
</span><span class="cx"> #include &quot;ScriptElement.h&quot;
</span><span class="cx"> #include &quot;ScriptSourceCode.h&quot;
</span><ins>+#include &quot;SecurityOrigin.h&quot;
</ins><span class="cx"> #include &quot;Settings.h&quot;
</span><span class="cx"> #include &quot;StyleScope.h&quot;
</span><ins>+#include &quot;TextResourceDecoder.h&quot;
</ins><span class="cx"> #include &quot;TransformSource.h&quot;
</span><span class="cx"> #include &quot;XMLNSNames.h&quot;
</span><span class="cx"> #include &quot;XMLDocumentParserScope.h&quot;
</span><span class="cx"> #include &lt;libxml/parserInternals.h&gt;
</span><ins>+#include &lt;wtf/Ref.h&gt;
</ins><span class="cx"> #include &lt;wtf/StringExtras.h&gt;
</span><ins>+#include &lt;wtf/Threading.h&gt;
+#include &lt;wtf/Vector.h&gt;
</ins><span class="cx"> #include &lt;wtf/unicode/UTF8.h&gt;
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(XSLT)
</span><span class="lines">@@ -62,33 +74,32 @@
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(XSLT)
</span><del>-
-static inline bool shouldRenderInXMLTreeViewerMode(Document&amp; document)
</del><ins>+static inline bool hasNoStyleInformation(Document* document)
</ins><span class="cx"> {
</span><del>-    if (document.sawElementsInKnownNamespaces())
</del><ins>+    if (document-&gt;sawElementsInKnownNamespaces())
</ins><span class="cx">         return false;
</span><span class="cx"> 
</span><del>-    if (document.transformSourceDocument())
</del><ins>+    if (document-&gt;transformSourceDocument())
</ins><span class="cx">         return false;
</span><span class="cx"> 
</span><del>-    auto* frame = document.frame();
-    if (!frame)
</del><ins>+    if (!document-&gt;frame() || !document-&gt;frame()-&gt;page())
</ins><span class="cx">         return false;
</span><span class="cx"> 
</span><del>-    if (!frame-&gt;settings().developerExtrasEnabled())
</del><ins>+    if (!document-&gt;frame()-&gt;page()-&gt;settings().developerExtrasEnabled())
</ins><span class="cx">         return false;
</span><span class="cx"> 
</span><del>-    if (frame-&gt;tree().parent())
</del><ins>+    if (document-&gt;frame()-&gt;tree().parent())
</ins><span class="cx">         return false; // This document is not in a top frame
</span><span class="cx"> 
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><del>-
</del><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> class PendingCallbacks {
</span><del>-    WTF_MAKE_FAST_ALLOCATED;
</del><ins>+    WTF_MAKE_NONCOPYABLE(PendingCallbacks); WTF_MAKE_FAST_ALLOCATED;
</ins><span class="cx"> public:
</span><ins>+    PendingCallbacks() = default;
+
</ins><span class="cx">     void appendStartElementNSCallback(const xmlChar* xmlLocalName, const xmlChar* xmlPrefix, const xmlChar* xmlURI, int numNamespaces, const xmlChar** namespaces, int numAttributes, int numDefaulted, const xmlChar** attributes)
</span><span class="cx">     {
</span><span class="cx">         auto callback = std::make_unique&lt;PendingStartElementNSCallback&gt;();
</span><span class="lines">@@ -564,16 +575,40 @@
</span><span class="cx"> XMLDocumentParser::XMLDocumentParser(Document&amp; document, FrameView* frameView)
</span><span class="cx">     : ScriptableDocumentParser(document)
</span><span class="cx">     , m_view(frameView)
</span><ins>+    , m_context(nullptr)
</ins><span class="cx">     , m_pendingCallbacks(std::make_unique&lt;PendingCallbacks&gt;())
</span><ins>+    , m_depthTriggeringEntityExpansion(-1)
+    , m_isParsingEntityDeclaration(false)
</ins><span class="cx">     , m_currentNode(&amp;document)
</span><ins>+    , m_sawError(false)
+    , m_sawCSS(false)
+    , m_sawXSLTransform(false)
+    , m_sawFirstElement(false)
+    , m_isXHTMLDocument(false)
+    , m_parserPaused(false)
+    , m_requestingScript(false)
+    , m_finishCalled(false)
</ins><span class="cx">     , m_scriptStartPosition(TextPosition::belowRangePosition())
</span><ins>+    , m_parsingFragment(false)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> XMLDocumentParser::XMLDocumentParser(DocumentFragment&amp; fragment, Element* parentElement, ParserContentPolicy parserContentPolicy)
</span><span class="cx">     : ScriptableDocumentParser(fragment.document(), parserContentPolicy)
</span><ins>+    , m_view(nullptr)
+    , m_context(nullptr)
</ins><span class="cx">     , m_pendingCallbacks(std::make_unique&lt;PendingCallbacks&gt;())
</span><ins>+    , m_depthTriggeringEntityExpansion(-1)
+    , m_isParsingEntityDeclaration(false)
</ins><span class="cx">     , m_currentNode(&amp;fragment)
</span><ins>+    , m_sawError(false)
+    , m_sawCSS(false)
+    , m_sawXSLTransform(false)
+    , m_sawFirstElement(false)
+    , m_isXHTMLDocument(false)
+    , m_parserPaused(false)
+    , m_requestingScript(false)
+    , m_finishCalled(false)
</ins><span class="cx">     , m_scriptStartPosition(TextPosition::belowRangePosition())
</span><span class="cx">     , m_parsingFragment(true)
</span><span class="cx"> {
</span><span class="lines">@@ -1159,7 +1194,8 @@
</span><span class="cx"> static size_t convertUTF16EntityToUTF8(const UChar* utf16Entity, size_t numberOfCodeUnits, char* target, size_t targetSize)
</span><span class="cx"> {
</span><span class="cx">     const char* originalTarget = target;
</span><del>-    auto conversionResult = WTF::Unicode::convertUTF16ToUTF8(&amp;utf16Entity, utf16Entity + numberOfCodeUnits, &amp;target, target + targetSize);
</del><ins>+    WTF::Unicode::ConversionResult conversionResult = WTF::Unicode::convertUTF16ToUTF8(&amp;utf16Entity,
+        utf16Entity + numberOfCodeUnits, &amp;target, target + targetSize);
</ins><span class="cx">     if (conversionResult != WTF::Unicode::conversionOK)
</span><span class="cx">         return 0;
</span><span class="cx"> 
</span><span class="lines">@@ -1328,7 +1364,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(XSLT)
</span><del>-    bool xmlViewerMode = !m_sawError &amp;&amp; !m_sawCSS &amp;&amp; !m_sawXSLTransform &amp;&amp; shouldRenderInXMLTreeViewerMode(*document());
</del><ins>+    bool xmlViewerMode = !m_sawError &amp;&amp; !m_sawCSS &amp;&amp; !m_sawXSLTransform &amp;&amp; hasNoStyleInformation(document());
</ins><span class="cx">     if (xmlViewerMode) {
</span><span class="cx">         XMLTreeViewer xmlTreeViewer(*document());
</span><span class="cx">         xmlTreeViewer.transformDocumentToTreeView();
</span><span class="lines">@@ -1414,12 +1450,13 @@
</span><span class="cx">             return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    // Then, write any pending data
+    SegmentedString rest = m_pendingSrc;
+    m_pendingSrc.clear();
</ins><span class="cx">     // There is normally only one string left, so toString() shouldn't copy.
</span><span class="cx">     // In any case, the XML parser runs on the main thread and it's OK if
</span><span class="cx">     // the passed string has more than one reference.
</span><del>-    auto rest = m_pendingSrc.toString();
-    m_pendingSrc.clear();
-    append(rest.impl());
</del><ins>+    append(rest.toString().impl());
</ins><span class="cx"> 
</span><span class="cx">     // Finally, if finish() has been called and write() didn't result
</span><span class="cx">     // in any further callbacks being queued, call end()
</span></span></pre>
</div>
</div>

</body>
</html>