<!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:
"Streamline and speed up tokenizer and segmented string
classes"
https://bugs.webkit.org/show_bug.cgi?id=165003
http://trac.webkit.org/changeset/209058
"REGRESSION (<a href="http://trac.webkit.org/projects/webkit/changeset/209058">r209058</a>): API test StringBuilderTest.Equal
crashing"
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 <commit-queue@webkit.org>
+
+ 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:
+
+ "Streamline and speed up tokenizer and segmented string
+ classes"
+ https://bugs.webkit.org/show_bug.cgi?id=165003
+ http://trac.webkit.org/changeset/209058
+
+ "REGRESSION (r209058): API test StringBuilderTest.Equal
+ crashing"
+ https://bugs.webkit.org/show_bug.cgi?id=165142
+ http://trac.webkit.org/changeset/209074
+
</ins><span class="cx"> 2016-11-29 Caitlin Potter <caitp@igalia.com>
</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)->viewWithUnderlyingString(*m_exec).view);
</del><ins>+ builder.appendQuotedJSONString(asString(value)->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 <commit-queue@webkit.org>
+
+ 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:
+
+ "Streamline and speed up tokenizer and segmented string
+ classes"
+ https://bugs.webkit.org/show_bug.cgi?id=165003
+ http://trac.webkit.org/changeset/209058
+
+ "REGRESSION (r209058): API test StringBuilderTest.Equal
+ crashing"
+ https://bugs.webkit.org/show_bug.cgi?id=165142
+ http://trac.webkit.org/changeset/209074
+
</ins><span class="cx"> 2016-11-29 Simon Fraser <simon.fraser@apple.com>
</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 "IntegerToStringConversion.h"
</span><span class="cx"> #include "MathExtras.h"
</span><ins>+#include "WTFString.h"
</ins><span class="cx"> #include <wtf/dtoa.h>
</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<> ALWAYS_INLINE LChar* StringBuilder::bufferCharacters<LChar>()
-{
- ASSERT(m_is8Bit);
- return m_bufferCharacters8;
-}
-
-template<> ALWAYS_INLINE UChar* StringBuilder::bufferCharacters<UChar>()
-{
- 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<size_t>(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<size_t>(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 >= 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 < m_length; ++i)
</span><span class="lines">@@ -155,7 +141,8 @@
</span><span class="cx"> ASSERT(m_buffer->length() == requiredLength);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-template<> void StringBuilder::reallocateBuffer<LChar>(unsigned requiredLength)
</del><ins>+template <>
+void StringBuilder::reallocateBuffer<LChar>(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 "allocate and copy" method.
</span><span class="lines">@@ -171,7 +158,8 @@
</span><span class="cx"> ASSERT(m_buffer->length() == requiredLength);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-template<> void StringBuilder::reallocateBuffer<UChar>(unsigned requiredLength)
</del><ins>+template <>
+void StringBuilder::reallocateBuffer<UChar>(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 "allocate and copy" 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->is8Bit())
</span><del>- allocateBufferUpconvert(m_buffer->characters8(), requiredLength);
</del><ins>+ allocateBufferUpConvert(m_buffer->characters8(), requiredLength);
</ins><span class="cx"> else if (m_buffer->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 > 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 & m_length,
</span><span class="cx"> // return a pointer to the newly allocated storage.
</span><del>-template<typename CharacterType> ALWAYS_INLINE CharacterType* StringBuilder::appendUninitialized(unsigned length)
</del><ins>+template <typename CharType>
+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<CharacterType>() + currentLength;
</del><ins>+ return getBufferCharacters<CharType>() + currentLength;
</ins><span class="cx"> }
</span><del>-
- return appendUninitializedSlow<CharacterType>(requiredLength);
</del><ins>+
+ return appendUninitializedSlow<CharType>(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 & m_length,
</span><span class="cx"> // return a pointer to the newly allocated storage.
</span><del>-template<typename CharacterType> CharacterType* StringBuilder::appendUninitializedSlow(unsigned requiredLength)
</del><ins>+template <typename CharType>
+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->length() >= m_length);
</span><del>- reallocateBuffer<CharacterType>(expandedCapacity(capacity(), requiredLength));
</del><ins>+
+ reallocateBuffer<CharType>(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<CharacterType>() : nullptr, expandedCapacity(capacity(), requiredLength));
</del><ins>+ allocateBuffer(m_length ? m_string.characters<CharType>() : 0, expandedCapacity(capacity(), requiredLength));
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- auto* result = bufferCharacters<CharacterType>() + m_length;
</del><ins>+ CharType* result = getBufferCharacters<CharType>() + m_length;
</ins><span class="cx"> m_length = requiredLength;
</span><span class="cx"> ASSERT(m_buffer->length() >= 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 < 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->length() >= m_length);
- allocateBufferUpconvert(m_buffer->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 && !(*characters & ~0xFF)) {
</del><ins>+ if (length == 1 && !(*characters & ~0xff)) {
</ins><span class="cx"> // Append as 8 bit character
</span><span class="cx"> LChar lChar = static_cast<LChar>(*characters);
</span><span class="cx"> append(&lChar, 1);
</span><span class="cx"> return;
</span><span class="cx"> }
</span><del>- memcpy(appendUninitializedUpconvert(length), characters, static_cast<size_t>(length) * sizeof(UChar));
</del><ins>+
+ // Calculate the new size of the builder after appending.
+ unsigned requiredLength = length + m_length;
+ if (requiredLength < 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->length() >= m_length);
+
+ allocateBufferUpConvert(m_buffer->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<size_t>(length) * sizeof(UChar));
+ m_length = requiredLength;
</ins><span class="cx"> } else
</span><span class="cx"> memcpy(appendUninitialized<UChar>(length), characters, static_cast<size_t>(length) * sizeof(UChar));
</span><del>-
</del><span class="cx"> ASSERT(m_buffer->length() >= 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<LChar>(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<LChar>(length);
</ins><span class="cx"> if (length > 8)
</span><del>- memcpy(destination, characters, length);
</del><ins>+ memcpy(dest, characters, static_cast<size_t>(length) * sizeof(LChar));
</ins><span class="cx"> else {
</span><span class="cx"> const LChar* end = characters + length;
</span><span class="cx"> while (characters < end)
</span><del>- *destination++ = *characters++;
</del><ins>+ *(dest++) = *(characters++);
</ins><span class="cx"> }
</span><span class="cx"> } else {
</span><del>- auto* destination = appendUninitialized<UChar>(length);
</del><ins>+ UChar* dest = appendUninitialized<UChar>(length);
</ins><span class="cx"> const LChar* end = characters + length;
</span><span class="cx"> while (characters < 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<typename LengthType, typename CharacterType> static LengthType quotedJSONStringLength(const CharacterType* input, unsigned length)
</del><ins>+template <typename OutputCharacterType, typename InputCharacterType>
+static void appendQuotedJSONStringInternal(OutputCharacterType*& output, const InputCharacterType* input, unsigned length)
</ins><span class="cx"> {
</span><del>- LengthType quotedLength = 2;
- for (unsigned i = 0; i < length; ++i) {
- auto character = input[i];
- if (LIKELY(character > 0x1F)) {
- switch (character) {
- case '"':
- 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<typename CharacterType> static inline unsigned quotedJSONStringLength(const CharacterType* input, unsigned length)
-{
- constexpr auto maxSafeLength = (std::numeric_limits<unsigned>::max() - 2) / 6;
- if (length <= maxSafeLength)
- return quotedJSONStringLength<unsigned>(input, length);
- return quotedJSONStringLength<Checked<unsigned>>(input, length).unsafeGet();
-}
-
-template<typename OutputCharacterType, typename InputCharacterType> static inline void appendQuotedJSONStringInternal(OutputCharacterType* output, const InputCharacterType* input, unsigned length)
-{
- *output++ = '"';
- for (unsigned i = 0; i < length; ++i) {
- auto character = input[i];
- if (LIKELY(character > 0x1F)) {
- if (UNLIKELY(character == '"' || character == '\\'))
</del><ins>+ for (const InputCharacterType* end = input + length; input != end; ++input) {
+ if (LIKELY(*input > 0x1F)) {
+ if (*input == '"' || *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 & ~0xFF));
</del><ins>+ ASSERT((*input & 0xFF00) == 0);
+ static const char hexDigits[] = "0123456789abcdef";
</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<LChar>(hexDigits[(*input >> 4) & 0xF]);
+ *output++ = static_cast<LChar>(hexDigits[*input & 0xF]);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> }
</span><del>- *output = '"';
</del><span class="cx"> }
</span><span class="cx">
</span><del>-void StringBuilder::appendQuotedJSONString(StringView string)
</del><ins>+void StringBuilder::appendQuotedJSONString(const String& string)
</ins><span class="cx"> {
</span><del>- unsigned length = string.length();
- if (string.is8Bit()) {
- auto* characters = string.characters8();
- if (m_is8Bit)
- appendQuotedJSONStringInternal(appendUninitialized<LChar>(quotedJSONStringLength(characters, length)), characters, length);
- else
- appendQuotedJSONStringInternal(appendUninitialized<UChar>(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 '"' quotes on each end.
+ // The 6 is for characters that need to be \uNNNN encoded.
+ Checked<unsigned> stringLength = string.length();
+ Checked<unsigned> 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<<31 + some int smaller than 1<<31) == 0.
+ allocationSize = std::max(allocationSize, roundUpToPowerOfTwo(allocationSize));
+
+ if (is8Bit() && !string.is8Bit())
+ allocateBufferUpConvert(m_bufferCharacters8, allocationSize);
+ else
+ reserveCapacity(allocationSize);
+ ASSERT(m_buffer->length() >= allocationSize);
+
+ if (is8Bit()) {
+ ASSERT(string.is8Bit());
+ LChar* output = m_bufferCharacters8 + m_length;
+ *output++ = '"';
+ appendQuotedJSONStringInternal(output, string.characters8(), string.length());
+ *output++ = '"';
+ 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++ = '"';
+ if (string.is8Bit())
+ appendQuotedJSONStringInternal(output, string.characters8(), string.length());
</ins><span class="cx"> else
</span><del>- appendQuotedJSONStringInternal(appendUninitialized<UChar>(quotedJSONStringLength(characters, length)), characters, length);
</del><ins>+ appendQuotedJSONStringInternal(output, string.characters16(), string.length());
+ *output++ = '"';
+ m_length = output - m_bufferCharacters16;
</ins><span class="cx"> }
</span><ins>+ ASSERT(m_buffer->length() >= 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 <wtf/text/AtomicString.h>
</ins><span class="cx"> #include <wtf/text/StringView.h>
</span><ins>+#include <wtf/text/WTFString.h>
</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<const LChar*>(characters), length); }
</span><span class="cx">
</span><del>- void append(const AtomicString& atomicString) { append(atomicString.string()); }
</del><ins>+ void append(const AtomicString& atomicString)
+ {
+ append(atomicString.string());
+ }
</ins><span class="cx">
</span><span class="cx"> void append(const String& 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 && !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& 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 && !m_buffer && !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) && 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& string, unsigned offset, unsigned length)
</span><span class="cx"> {
</span><del>- ASSERT(offset <= string.length());
- ASSERT(offset + 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.
- if (!offset && !m_length && !m_buffer && length == string.length()) {
- m_string = string;
- m_length = length;
- m_is8Bit = string.is8Bit();
</del><ins>+ if ((offset + length) > 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 && m_length < m_buffer->length() && 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 & ~0xFF)) {
- m_bufferCharacters8[m_length++] = static_cast<LChar>(character);
</del><ins>+
+ if (!(c & ~0xff)) {
+ m_bufferCharacters8[m_length++] = static_cast<LChar>(c);
</ins><span class="cx"> return;
</span><span class="cx"> }
</span><span class="cx"> }
</span><del>- append(&character, 1);
</del><ins>+ append(&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 && m_length < m_buffer->length() && 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(&character, 1);
</del><ins>+ append(&c, 1);
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- void append(char character) { append(static_cast<LChar>(character)); }
</del><ins>+ void append(char c)
+ {
+ append(static_cast<LChar>(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&);
</ins><span class="cx">
</span><del>- template<unsigned charactersCount> ALWAYS_INLINE void appendLiteral(const char (&characters)[charactersCount]) { append(characters, charactersCount - 1); }
</del><ins>+ template<unsigned charactersCount>
+ ALWAYS_INLINE void appendLiteral(const char (&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->length() : m_length; }
</del><ins>+ unsigned capacity() const
+ {
+ return m_buffer ? m_buffer->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<typename CharacterType> void reallocateBuffer(unsigned requiredLength);
- UChar* appendUninitializedUpconvert(unsigned length);
- template<typename CharacterType> CharacterType* appendUninitialized(unsigned length);
- template<typename CharacterType> CharacterType* appendUninitializedSlow(unsigned length);
- template<typename CharacterType> CharacterType* bufferCharacters();
</del><ins>+ void allocateBufferUpConvert(const LChar* currentCharacters, unsigned requiredLength);
+ template <typename CharType>
+ void reallocateBuffer(unsigned requiredLength);
+ template <typename CharType>
+ ALWAYS_INLINE CharType* appendUninitialized(unsigned length);
+ template <typename CharType>
+ CharType* appendUninitializedSlow(unsigned length);
+ template <typename CharType>
+ 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<StringImpl> 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<typename StringType> bool equal(const StringBuilder&, const StringType&);
-bool equal(const StringBuilder&, const String&); // Only needed because is8Bit dereferences nullptr when the string is null.
-template<typename CharacterType> bool equal(const StringBuilder&, const CharacterType*, unsigned length);
</del><ins>+template <>
+ALWAYS_INLINE LChar* StringBuilder::getBufferCharacters<LChar>()
+{
+ ASSERT(m_is8Bit);
+ return m_bufferCharacters8;
+}
</ins><span class="cx">
</span><del>-bool operator==(const StringBuilder&, const StringBuilder&);
-bool operator!=(const StringBuilder&, const StringBuilder&);
-bool operator==(const StringBuilder&, const String&);
-bool operator!=(const StringBuilder&, const String&);
-bool operator==(const String&, const StringBuilder&);
-bool operator!=(const String&, const StringBuilder&);
</del><ins>+template <>
+ALWAYS_INLINE UChar* StringBuilder::getBufferCharacters<UChar>()
+{
+ ASSERT(!m_is8Bit);
+ return m_bufferCharacters16;
+}
</ins><span class="cx">
</span><del>-template<typename CharacterType> inline bool equal(const StringBuilder& s, const CharacterType* buffer, unsigned length)
</del><ins>+template <typename CharType>
+bool equal(const StringBuilder& 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<typename StringType> inline bool equal(const StringBuilder& a, const StringType& b)
</del><ins>+template <typename StringType>
+bool equal(const StringBuilder& a, const StringType& 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& a, const String& b)
-{
- return !b.isNull() && 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& a, const StringBuilder& 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 <commit-queue@webkit.org>
+
+ 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:
+
+ "Streamline and speed up tokenizer and segmented string
+ classes"
+ https://bugs.webkit.org/show_bug.cgi?id=165003
+ http://trac.webkit.org/changeset/209058
+
+ "REGRESSION (r209058): API test StringBuilderTest.Equal
+ crashing"
+ https://bugs.webkit.org/show_bug.cgi?id=165142
+ http://trac.webkit.org/changeset/209074
+
</ins><span class="cx"> 2016-11-29 Nan Wang <n_wang@apple.com>
</span><span class="cx">
</span><span class="cx"> AX: ARIA tree & treeitem roles & 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 "config.h"
</span><span class="cx"> #include "JSHTMLDocument.h"
</span><span class="cx">
</span><ins>+#include "Frame.h"
+#include "HTMLCollection.h"
+#include "HTMLDocument.h"
+#include "HTMLElement.h"
</ins><span class="cx"> #include "HTMLIFrameElement.h"
</span><ins>+#include "HTMLNames.h"
+#include "JSDOMWindow.h"
</ins><span class="cx"> #include "JSDOMWindowCustom.h"
</span><ins>+#include "JSDOMWindowShell.h"
+#include "JSDocumentCustom.h"
</ins><span class="cx"> #include "JSHTMLCollection.h"
</span><ins>+#include "JSMainThreadExecState.h"
</ins><span class="cx"> #include "SegmentedString.h"
</span><ins>+#include "DocumentParser.h"
+#include <interpreter/StackVisitor.h>
+#include <runtime/Error.h>
+#include <runtime/JSCell.h>
+#include <wtf/unicode/CharacterNames.h>
</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<HTMLDocument>&& passedDocument)
</span><span class="cx"> {
</span><span class="cx"> auto& document = passedDocument.get();
</span><del>- auto* wrapper = createWrapper<HTMLDocument>(globalObject, WTFMove(passedDocument));
</del><ins>+ JSObject* wrapper = createWrapper<HTMLDocument>(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<HTMLDocument>(document));
</span><span class="cx"> }
</span><span class="cx">
</span><del>-bool JSHTMLDocument::getOwnPropertySlot(JSObject* object, ExecState* state, PropertyName propertyName, PropertySlot& slot)
</del><ins>+bool JSHTMLDocument::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
</ins><span class="cx"> {
</span><del>- auto& thisObject = *jsCast<JSHTMLDocument*>(object);
- ASSERT_GC_OBJECT_INHERITS((&thisObject), info());
</del><ins>+ JSHTMLDocument* thisObject = jsCast<JSHTMLDocument*>(object);
+ ASSERT_GC_OBJECT_INHERITS(thisObject, info());
</ins><span class="cx">
</span><span class="cx"> if (propertyName == "open") {
</span><del>- if (Base::getOwnPropertySlot(&thisObject, state, propertyName, slot))
</del><ins>+ if (Base::getOwnPropertySlot(thisObject, exec, propertyName, slot))
</ins><span class="cx"> return true;
</span><del>- slot.setCustom(&thisObject, ReadOnly | DontDelete | DontEnum, nonCachingStaticFunctionGetter<jsHTMLDocumentPrototypeFunctionOpen, 2>);
</del><ins>+
+ slot.setCustom(thisObject, ReadOnly | DontDelete | DontEnum, nonCachingStaticFunctionGetter<jsHTMLDocumentPrototypeFunctionOpen, 2>);
</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(&thisObject, ReadOnly | DontDelete | DontEnum, value);
</del><ins>+ if (thisObject->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(&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& value)
</del><ins>+bool JSHTMLDocument::nameGetter(ExecState* exec, PropertyName propertyName, JSValue& value)
</ins><span class="cx"> {
</span><span class="cx"> auto& 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<HTMLCollection> collection = document.documentNamedItems(atomicPropertyName);
</ins><span class="cx"> ASSERT(collection->length() > 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& element = *document.documentNamedItem(*atomicPropertyName);
</del><ins>+ Element& element = *document.documentNamedItem(*atomicPropertyName);
</ins><span class="cx"> if (UNLIKELY(is<HTMLIFrameElement>(element))) {
</span><del>- if (auto* frame = downcast<HTMLIFrameElement>(element).contentFrame()) {
- value = toJS(state, frame);
</del><ins>+ if (Frame* frame = downcast<HTMLIFrameElement>(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& state) const
</span><span class="cx"> {
</span><span class="cx"> // If "all" has been overwritten, return the overwritten value
</span><del>- if (auto overwrittenValue = getDirect(state.vm(), Identifier::fromString(&state, "all")))
- return overwrittenValue;
</del><ins>+ JSValue v = getDirect(state.vm(), Identifier::fromString(&state, "all"));
+ if (v)
+ return v;
</ins><span class="cx">
</span><span class="cx"> return toJS(&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(&state, "all"), value);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-static inline Document* findCallingDocument(ExecState& state)
</del><ins>+static Document* findCallingDocument(ExecState& 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->lexicalGlobalObject())->wrapped().document();
</del><ins>+
+ return asJSDOMWindow(functor.callerFrame()->lexicalGlobalObject())->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() > 2) {
</span><del>- if (auto* frame = wrapped().frame()) {
- if (auto* wrapper = toJSDOMWindowShell(frame, currentWorld(&state))) {
- auto function = wrapper->get(&state, Identifier::fromString(&state, "open"));
</del><ins>+ if (Frame* frame = wrapped().frame()) {
+ JSDOMWindowShell* wrapper = toJSDOMWindowShell(frame, currentWorld(&state));
+ if (wrapper) {
+ JSValue function = wrapper->get(&state, Identifier::fromString(&state, "open"));
</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(&state, scope);
</span><span class="cx"> return JSC::call(&state, function, callType, callData, wrapper, ArgList(&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())->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())->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& state, JSHTMLDocument& document, NewlineRequirement addNewline)
</del><ins>+static inline void documentWrite(ExecState& state, JSHTMLDocument* thisDocument, NewlineRequirement addNewline)
</ins><span class="cx"> {
</span><del>- VM& vm = state.vm();
- auto scope = DECLARE_THROW_SCOPE(vm);
</del><ins>+ HTMLDocument* document = &thisDocument->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 < argumentCount; ++i) {
- segmentedString.append(state.uncheckedArgument(i).toWTFString(&state));
- RETURN_IF_EXCEPTION(scope, { });
</del><ins>+ size_t size = state.argumentCount();
+
+ String firstString = state.argument(0).toString(&state)->value(&state);
+ SegmentedString segmentedString = firstString;
+ if (size != 1) {
+ if (!size)
+ segmentedString.clear();
+ else {
+ for (size_t i = 1; i < size; ++i) {
+ String subsequentString = state.uncheckedArgument(i).toString(&state)->value(&state);
+ segmentedString.append(SegmentedString(subsequentString));
+ }
+ }
</ins><span class="cx"> }
</span><span class="cx"> if (addNewline)
</span><del>- segmentedString.append(String { "\n" });
</del><ins>+ segmentedString.append(SegmentedString(String(&newlineCharacter, 1)));
</ins><span class="cx">
</span><del>- document.wrapped().write(WTFMove(segmentedString), findCallingDocument(state));
- return jsUndefined();
</del><ins>+ Document* activeDocument = findCallingDocument(state);
+ document->write(segmentedString, activeDocument);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> JSValue JSHTMLDocument::write(ExecState& 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& 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 "CSSParserTokenRange.h"
</span><span class="cx"> #include "CSSTokenizerInputStream.h"
</span><span class="cx"> #include "HTMLParserIdioms.h"
</span><del>-#include <wtf/text/StringBuilder.h>
</del><span class="cx"> #include <wtf/unicode/CharacterNames.h>
</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 "CSSParserToken.h"
</span><ins>+#include "InputStreamPreprocessor.h"
</ins><span class="cx"> #include <climits>
</span><span class="cx"> #include <wtf/text/StringView.h>
</span><span class="cx"> #include <wtf/text/WTFString.h>
</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 <wtf/text/StringView.h>
</span><ins>+#include <wtf/text/WTFString.h>
</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&& text, Document* ownerDocument)
</del><ins>+void Document::write(const SegmentedString& 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 > 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 && m_parser->hasInsertionPoint();
</span><span class="cx"> if (!hasInsertionPoint && (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->insert(WTFMove(text));
</del><ins>+ m_parser->insert(text);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void Document::write(const String& 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& text, Document* ownerDocument)
</span><span class="cx"> {
</span><del>- SegmentedString textWithNewline { text };
- textWithNewline.append(String { "\n" });
- write(WTFMove(textWithNewline), ownerDocument);
</del><ins>+ write(text, ownerDocument);
+ write("\n", 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&& text, Document* ownerDocument = nullptr);
</del><ins>+ void write(const SegmentedString& text, Document* ownerDocument = nullptr);
</ins><span class="cx"> WEBCORE_EXPORT void write(const String& text, Document* ownerDocument = nullptr);
</span><span class="cx"> WEBCORE_EXPORT void writeln(const String& 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&&) = 0;
</del><ins>+ virtual void insert(const SegmentedString&) = 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&, 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&&) override
</del><ins>+ void insert(const SegmentedString&) override
</ins><span class="cx"> {
</span><span class="cx"> // <https://bugs.webkit.org/show_bug.cgi?id=25397>: 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<StringImpl>&& 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() && !m_input.haveSeenEndOfFile());
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void HTMLDocumentParser::insert(SegmentedString&& source)
</del><ins>+void HTMLDocumentParser::insert(const SegmentedString& 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<HTMLDocumentParser> 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<HTMLDocumentParser> 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() && !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&);
</span><span class="cx">
</span><del>- void insert(SegmentedString&&) final;
</del><ins>+ void insert(const SegmentedString&) final;
</ins><span class="cx"> void append(RefPtr<StringImpl>&&) 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()->length;
</span><span class="cx"> const LChar* reference = entitySearch.mostRecentMatch()->entity;
</span><span class="cx"> for (int i = 0; i < 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()->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 "InputStreamPreprocessor.h"
</ins><span class="cx"> #include "SegmentedString.h"
</span><span class="cx"> #include <wtf/text/TextPosition.h>
</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&& string)
</del><ins>+ void appendToEnd(const SegmentedString& string)
</ins><span class="cx"> {
</span><del>- m_last->append(WTFMove(string));
</del><ins>+ m_last->append(string);
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- void insertAtCurrentInsertionPoint(SegmentedString&& string)
</del><ins>+ void insertAtCurrentInsertionPoint(const SegmentedString& 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->append(String { &kEndOfFileMarker, 1 });
</del><ins>+ m_last->append(SegmentedString(String(&kEndOfFileMarker, 1)));
</ins><span class="cx"> m_last->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& 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 == &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 <head>, 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->decode(data, length));
</del><ins>+ m_input.append(SegmentedString(m_codec->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->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& currentInput, HTMLTokenizer& 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 < length && !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 < 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&, HTMLTokenizer&);
</span><span class="cx"> void endToken(SegmentedString&, HTMLTokenizer&);
</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 "HTMLEntityParser.h"
</span><span class="cx"> #include "HTMLNames.h"
</span><span class="cx"> #include "MarkupTokenizerInlines.h"
</span><del>-#include <wtf/text/StringBuilder.h>
</del><ins>+#include <wtf/ASCIICType.h>
</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& 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& source)
</span><span class="cx"> {
</span><del>- ASSERT(source.currentCharacter() == '>');
</del><ins>+ ASSERT(source.currentChar() == '>');
</ins><span class="cx"> appendToTemporaryBuffer('>');
</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 == '&')
</span><del>- ADVANCE_PAST_NON_NEWLINE_TO(CharacterReferenceInDataState);
</del><ins>+ ADVANCE_TO(CharacterReferenceInDataState);
</ins><span class="cx"> if (character == '<') {
</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 == '&')
</span><del>- ADVANCE_PAST_NON_NEWLINE_TO(CharacterReferenceInRCDATAState);
</del><ins>+ ADVANCE_TO(CharacterReferenceInRCDATAState);
</ins><span class="cx"> if (character == '<')
</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 == '<')
</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 == '<')
</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 == '>') {
</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 == '>')
</span><span class="cx"> return emitAndResumeInDataState(source);
</span><span class="cx"> if (m_options.usePreHTML5ParserQuirks && character == '<')
</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('<');
</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('<');
</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('<');
</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('<');
</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('<');
</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('<');
</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('<');
</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 == '<')
</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 == '<')
</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 == '<')
</span><del>- ADVANCE_PAST_NON_NEWLINE_TO(ScriptDataEscapedLessThanSignState);
</del><ins>+ ADVANCE_TO(ScriptDataEscapedLessThanSignState);
</ins><span class="cx"> if (character == '>') {
</span><span class="cx"> bufferASCIICharacter('>');
</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('<');
</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('<');
</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('<');
</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 == '<') {
</span><span class="cx"> bufferASCIICharacter('<');
</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 == '<') {
</span><span class="cx"> bufferASCIICharacter('<');
</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 == '<') {
</span><span class="cx"> bufferASCIICharacter('<');
</span><del>- ADVANCE_PAST_NON_NEWLINE_TO(ScriptDataDoubleEscapedLessThanSignState);
</del><ins>+ ADVANCE_TO(ScriptDataDoubleEscapedLessThanSignState);
</ins><span class="cx"> }
</span><span class="cx"> if (character == '>') {
</span><span class="cx"> bufferASCIICharacter('>');
</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 == '>')
</span><span class="cx"> return emitAndResumeInDataState(source);
</span><span class="cx"> if (m_options.usePreHTML5ParserQuirks && character == '<')
</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 == '>')
</span><span class="cx"> return emitAndResumeInDataState(source);
</span><span class="cx"> if (m_options.usePreHTML5ParserQuirks && character == '<')
</span><span class="lines">@@ -745,7 +745,7 @@
</span><span class="cx"> if (character == '"' || character == '\'' || character == '<' || 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 == '>')
</span><span class="cx"> return emitAndResumeInDataState(source);
</span><span class="cx"> if (m_options.usePreHTML5ParserQuirks && character == '<')
</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 == '"')
</span><del>- ADVANCE_PAST_NON_NEWLINE_TO(AttributeValueDoubleQuotedState);
</del><ins>+ ADVANCE_TO(AttributeValueDoubleQuotedState);
</ins><span class="cx"> if (character == '&')
</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 == '>') {
</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 == '<' || 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 == '"') {
</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 == '&') {
</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">@@ -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 == '&') {
</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 == '&') {
</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 == '>') {
</span><span class="cx"> m_token.endAttribute(source.numberOfCharactersConsumed());
</span><span class="lines">@@ -850,7 +850,7 @@
</span><span class="cx"> if (character == '"' || character == '\'' || character == '<' || 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 == '>')
</span><span class="cx"> return emitAndResumeInDataState(source);
</span><span class="cx"> if (m_options.usePreHTML5ParserQuirks && character == '<')
</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("doctype");
</del><ins>+ auto result = source.advancePastIgnoringCase("doctype");
</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 == '>') {
</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 == '>') {
</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 == '>')
</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("public");
</del><ins>+ auto result = source.advancePastIgnoringCase("public");
</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("system");
</del><ins>+ auto result = source.advancePastIgnoringCase("system");
</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 == '"') {
</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 == '>') {
</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 == '"') {
</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 == '>') {
</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 == '"')
</span><del>- ADVANCE_PAST_NON_NEWLINE_TO(AfterDOCTYPEPublicIdentifierState);
</del><ins>+ ADVANCE_TO(AfterDOCTYPEPublicIdentifierState);
</ins><span class="cx"> if (character == '>') {
</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 == '>') {
</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 == '"') {
</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 == '"') {
</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 == '"') {
</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 == '>') {
</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 == '"') {
</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 == '>') {
</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 == '"')
</span><del>- ADVANCE_PAST_NON_NEWLINE_TO(AfterDOCTYPESystemIdentifierState);
</del><ins>+ ADVANCE_TO(AfterDOCTYPESystemIdentifierState);
</ins><span class="cx"> if (character == '>') {
</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 == '>') {
</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 == '>')
</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 "SegmentedString.h"
</span><ins>+#include <wtf/Noncopyable.h>
</ins><span class="cx"> #include <wtf/unicode/CharacterNames.h>
</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 <typename Tokenizer>
</span><span class="cx"> class InputStreamPreprocessor {
</span><ins>+ WTF_MAKE_NONCOPYABLE(InputStreamPreprocessor);
</ins><span class="cx"> public:
</span><span class="cx"> explicit InputStreamPreprocessor(Tokenizer& 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& 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 & ~specialCharacterMask)) {
</del><ins>+ static const UChar specialCharacterMask = '\n' | '\r' | '\0';
+ if (m_nextInputCharacter & ~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& 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& 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& 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' && 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' && !shouldTreatNullAsEndOfFileMarker(source)) {
+ if (skipNullCharacters && !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 && !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& source)
</del><ins>+ bool shouldTreatNullAsEndOfFileMarker(SegmentedString& source) const
</ins><span class="cx"> {
</span><span class="cx"> return source.isClosed() && source.length() == 1;
</span><span class="cx"> }
</span><span class="lines">@@ -117,8 +129,8 @@
</span><span class="cx"> Tokenizer& 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<String> BufferedLineReader::nextLine()
</del><ins>+bool BufferedLineReader::getLine(String& 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&& data)
</del><ins>+ // Append data to the internal buffer.
+ void append(const String& 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 "unterminated" 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& line);
+
+ // Returns true if EOS has been reached proper.
</ins><span class="cx"> bool isAtEndOfStream() const { return m_endOfStream && m_buffer.isEmpty(); }
</span><span class="cx">
</span><del>- std::optional<String> 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&& 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& parser();
</span><span class="cx"> void parseWebVTTCueData(InbandTextTrackPrivate*, const ISOWebVTTCue&) final;
</span><del>- void parseWebVTTFileHeader(InbandTextTrackPrivate*, String&&) 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&&) 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&) 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&& data)
</del><ins>+void WebVTTParser::parseFileHeader(const String& 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->decode(data, length));
</del><ins>+ String textData = m_decoder->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& data)
</span><span class="cx"> {
</span><del>- auto cue = WebVTTCueData::create();
</del><ins>+ RefPtr<WebVTTCueData> cue = WebVTTCueData::create();
</ins><span class="cx">
</span><span class="cx"> MediaTime startTime = data.presentationTime();
</span><span class="cx"> cue->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->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->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->flush());
- m_lineReader.appendEndOfStream();
</del><ins>+ String textData = m_decoder->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->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->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 && m_regionList.size())
</span><span class="cx"> m_client->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->contains("-->"))
- m_state = recoverCue(*line);
</del><ins>+ if (line.contains("-->"))
+ m_state = recoverCue(line);
</ins><span class="cx">
</span><span class="cx"> // Step 16 - Line is not the empty string and does not contain "-->".
</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->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->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&&);
</del><ins>+ void parseFileHeader(const String&);
</ins><span class="cx"> void parseCueData(const ISOWebVTTCue&);
</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 "config.h"
</span><del>-#include "WebVTTTokenizer.h"
</del><span class="cx">
</span><span class="cx"> #if ENABLE(VIDEO_TRACK)
</span><span class="cx">
</span><ins>+#include "WebVTTTokenizer.h"
+
</ins><span class="cx"> #include "MarkupTokenizerInlines.h"
</span><span class="cx"> #include <wtf/text/StringBuilder.h>
</span><span class="cx"> #include <wtf/unicode/CharacterNames.h>
</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<unsigned charactersCount> ALWAYS_INLINE bool equalLiteral(const StringBuilder& s, const char (&characters)[charactersCount])
</span><span class="cx"> {
</span><span class="cx"> return WTF::equal(s, reinterpret_cast<const LChar*>(characters), charactersCount - 1);
</span><span class="lines">@@ -68,7 +69,7 @@
</span><span class="cx">
</span><span class="cx"> inline bool advanceAndEmitToken(SegmentedString& source, WebVTTToken& resultToken, const WebVTTToken& 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 "stream".
</span><span class="cx"> ASSERT(!m_input.isClosed());
</span><del>- m_input.append(String { &kEndOfFileMarker, 1 });
</del><ins>+ m_input.append(SegmentedString(String(&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&&) { 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&) = 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 "config.h"
</span><span class="cx"> #include "SegmentedString.h"
</span><span class="cx">
</span><del>-#include <wtf/text/StringBuilder.h>
</del><span class="cx"> #include <wtf/text/TextPosition.h>
</span><span class="cx">
</span><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><del>-inline void SegmentedString::Substring::appendTo(StringBuilder& builder) const
</del><ins>+SegmentedString::SegmentedString(const SegmentedString& 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& SegmentedString::operator=(SegmentedString&& other)
</del><ins>+SegmentedString& SegmentedString::operator=(const SegmentedString& 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& 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<SegmentedSubstring>::const_iterator it = m_substrings.begin();
+ Deque<SegmentedSubstring>::const_iterator e = m_substrings.end();
+ for (; it != e; ++it)
+ length += it->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& substring : m_otherSubstrings)
- substring.doNotExcludeLineNumbers = false;
- updateAdvanceFunctionPointers();
</del><ins>+ m_currentString.setExcludeLineNumbers();
+ if (isComposite()) {
+ Deque<SegmentedSubstring>::iterator it = m_substrings.begin();
+ Deque<SegmentedSubstring>::iterator e = m_substrings.end();
+ for (; it != e; ++it)
+ it->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 = &SegmentedString::advanceEmpty;
+ m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty;
+}
</ins><span class="cx">
</span><del>- updateAdvanceFunctionPointersForEmptyString();
</del><ins>+void SegmentedString::append(const SegmentedSubstring& 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&& substring)
</del><ins>+void SegmentedString::pushBack(const SegmentedSubstring& 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&& 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() <= 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& s)
+{
+ ASSERT(!m_closed);
+ ASSERT(!s.m_pushedChar1);
+ append(s.m_currentString);
+ if (s.isComposite()) {
+ Deque<SegmentedSubstring>::const_iterator it = s.m_substrings.begin();
+ Deque<SegmentedSubstring>::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& 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<SegmentedSubstring>::const_reverse_iterator it = s.m_substrings.rbegin();
+ Deque<SegmentedSubstring>::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& string)
</del><ins>+void SegmentedString::advanceSubstring()
</ins><span class="cx"> {
</span><del>- appendSubstring(Substring { string.m_currentSubstring });
- for (auto& 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 "prior to current string."
+ m_numberOfCharactersConsumedPriorToCurrentString -= m_currentString.numberOfCharactersConsumed();
+ updateAdvanceFunctionPointers();
+ } else {
+ m_currentString.clear();
+ m_empty = true;
+ m_fastPathFlags = NoFastPath;
+ m_advanceFunc = &SegmentedString::advanceEmpty;
+ m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty;
+ }
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-void SegmentedString::append(SegmentedString&& string)
</del><ins>+String SegmentedString::toString() const
</ins><span class="cx"> {
</span><del>- appendSubstring(WTFMove(string.m_currentSubstring));
- for (auto& 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<SegmentedSubstring>::const_iterator it = m_substrings.begin();
+ Deque<SegmentedSubstring>::const_iterator e = m_substrings.end();
+ for (; it != e; ++it)
+ it->appendTo(result);
+ }
+ return result.toString();
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-void SegmentedString::append(String&& 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 <= length());
+ for (unsigned i = 0; i < count; ++i) {
+ consumedCharacters[i] = currentChar();
+ advancePastNonNewline();
+ }
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-void SegmentedString::append(const String& 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& 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 = &SegmentedString::advanceEmpty;
+ m_advanceAndUpdateLineNumberFunc = &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 "prior to current string."
- 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' && 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 = &SegmentedString::advanceEmpty;
+ m_advanceAndUpdateLineNumberFunc = &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 && !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 = &SegmentedString::advancePastSingleCharacterSubstringWithoutUpdatingLineNumber;
- if (m_currentSubstring.doNotExcludeLineNumbers)
- m_advanceAndUpdateLineNumberFunction = &SegmentedString::advancePastSingleCharacterSubstring;
- else
- m_advanceAndUpdateLineNumberFunction = &SegmentedString::advancePastSingleCharacterSubstringWithoutUpdatingLineNumber;
</del><ins>+ m_advanceFunc = &SegmentedString::advanceSlowCase;
+ m_advanceAndUpdateLineNumberFunc = &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 <= maxLength);
</del><ins>+ unsigned length = strlen(literal);
</ins><span class="cx"> if (length > this->length())
</span><span class="cx"> return NotEnoughCharacters;
</span><del>- UChar consumedCharacters[maxLength];
- for (unsigned i = 0; i < 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 = &SegmentedString::advanceEmpty;
- m_advanceAndUpdateLineNumberFunction = &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 <wtf/Deque.h>
</span><del>-#include <wtf/text/WTFString.h>
</del><ins>+#include <wtf/text/StringBuilder.h>
</ins><span class="cx">
</span><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><del>-// FIXME: This should not start with "k".
-// 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&&);
- SegmentedString(const String&);
</del><ins>+ SegmentedSubstring()
+ : m_length(0)
+ , m_doNotExcludeLineNumbers(true)
+ , m_is8Bit(false)
+ {
+ m_data.string16Ptr = 0;
+ }
</ins><span class="cx">
</span><del>- SegmentedString(SegmentedString&&) = delete;
- SegmentedString(const SegmentedString&) = delete;
</del><ins>+ SegmentedSubstring(const String& 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& operator=(SegmentedString&&);
- SegmentedString& operator=(const SegmentedString&) = 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&&);
- void append(const SegmentedString&);
</del><ins>+ int numberOfCharactersConsumed() const { return m_string.length() - m_length; }
</ins><span class="cx">
</span><del>- void append(String&&);
- void append(const String&);
</del><ins>+ void appendTo(StringBuilder& builder) const
+ {
+ int offset = m_string.length() - m_length;
</ins><span class="cx">
</span><del>- void pushBack(String&&);
</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<unsigned length> AdvancePastResult advancePast(const char (&literal)[length]) { return advancePast<length, false>(literal); }
- template<unsigned length> AdvancePastResult advancePastLettersIgnoringASCIICase(const char (&literal)[length]) { return advancePast<length, true>(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(&SegmentedString::advanceEmpty)
+ , m_advanceAndUpdateLineNumberFunc(&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& 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&&);
</del><ins>+ SegmentedString(const SegmentedString&);
+ SegmentedString& operator=(const SegmentedString&);
</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&) const;
</del><ins>+ void append(const SegmentedString&);
+ void pushBack(const SegmentedString&);
</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 << 0,
- Use8BitAdvance = 1 << 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&&);
</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<unsigned length> AdvancePastResult advancePast(const char (&literal)[length]) { return advancePast(literal, length - 1, true); }
+ template<unsigned length> AdvancePastResult advancePastIgnoringCase(const char (&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 & 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<typename CharacterType> static bool characterMismatch(CharacterType, char, bool lettersIgnoringASCIICase);
- template<unsigned length, bool lettersIgnoringASCIICase> AdvancePastResult advancePast(const char (&literal)[length]);
- AdvancePastResult advancePastSlowCase(const char* literal, bool lettersIgnoringASCIICase);
</del><ins>+ updateSlowCaseFunctionPointers();
</ins><span class="cx">
</span><del>- Substring m_currentSubstring;
- Deque<Substring> m_otherSubstrings;
</del><ins>+ return;
+ }
</ins><span class="cx">
</span><del>- bool m_isClosed { false };
</del><ins>+ (this->*m_advanceFunc)();
+ }
</ins><span class="cx">
</span><del>- UChar m_currentCharacter { 0 };
</del><ins>+ void advanceAndUpdateLineNumber()
+ {
+ if (m_fastPathFlags & 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') & !!(m_fastPathFlags & Use8BitAdvanceAndUpdateLineNumbers);
+ bool haveOneCharacterLeft = (--m_currentString.m_length == 1);
</ins><span class="cx">
</span><del>- unsigned char m_fastPathFlags { NoFastPath };
- void (SegmentedString::*m_advanceWithoutUpdatingLineNumberFunction)() { &SegmentedString::advanceEmpty };
- void (SegmentedString::*m_advanceAndUpdateLineNumberFunction)() { &SegmentedString::advanceEmpty };
-};
</del><ins>+ m_currentChar = m_currentString.incrementAndGetCurrentChar8();
</ins><span class="cx">
</span><del>-inline SegmentedString::Substring::Substring(String&& passedString)
- : string(WTFMove(passedString))
- , length(string.length())
-{
- if (length) {
- is8Bit = string.impl()->is8Bit();
- if (is8Bit)
- currentCharacter8 = string.impl()->characters8();
- else
- currentCharacter16 = string.impl()->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&& string)
- : m_currentSubstring(WTFMove(string))
-{
- if (m_currentSubstring.length) {
- m_currentCharacter = m_currentSubstring.currentCharacter();
- updateAdvanceFunctionPointers();
</del><ins>+ (this->*m_advanceAndUpdateLineNumberFunc)();
</ins><span class="cx"> }
</span><del>-}
</del><span class="cx">
</span><del>-inline SegmentedString::SegmentedString(const String& 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 > 1);
- if (UNLIKELY(--m_currentSubstring.length == 1))
- updateAdvanceFunctionPointersForSingleCharacterSubstring();
-}
</del><ins>+ void advancePastNewlineAndUpdateLineNumber()
+ {
+ ASSERT(currentChar() == '\n');
+ if (!m_pushedChar1 && m_currentString.m_length > 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 & 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->*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 & Use8BitAdvance)) {
- ASSERT(m_currentSubstring.length > 1);
- bool lastCharacterWasNewline = m_currentCharacter == '\n';
- m_currentCharacter = *++m_currentSubstring.currentCharacter8;
- bool haveOneCharacterLeft = --m_currentSubstring.length == 1;
- if (LIKELY(!(lastCharacterWasNewline | haveOneCharacterLeft)))
- return;
- if (lastCharacterWasNewline & !!(m_fastPathFlags & 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 << 0,
+ Use8BitAdvance = 1 << 1,
+ };
+
+ void append(const SegmentedSubstring&);
+ void pushBack(const SegmentedSubstring&);
+
+ 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 > 1);
+ if (--m_currentString.m_length == 1)
+ updateSlowCaseFunctionPointers();
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- (this->*m_advanceAndUpdateLineNumberFunction)();
-}
</del><ins>+ void updateAdvanceFunctionPointers()
+ {
+ if ((m_currentString.m_length > 1) && !m_pushedChar1) {
+ if (m_currentString.is8Bit()) {
+ m_advanceFunc = &SegmentedString::advance8;
+ m_fastPathFlags = Use8BitAdvance;
+ if (m_currentString.doNotExcludeLineNumbers()) {
+ m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceAndUpdateLineNumber8;
+ m_fastPathFlags |= Use8BitAdvanceAndUpdateLineNumbers;
+ } else
+ m_advanceAndUpdateLineNumberFunc = &SegmentedString::advance8;
+ return;
+ }
</ins><span class="cx">
</span><del>-ALWAYS_INLINE void SegmentedString::advancePastNonNewline()
-{
- ASSERT(m_currentCharacter != '\n');
- advanceWithoutUpdatingLineNumber();
-}
</del><ins>+ m_advanceFunc = &SegmentedString::advance16;
+ m_fastPathFlags = NoFastPath;
+ if (m_currentString.doNotExcludeLineNumbers())
+ m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceAndUpdateLineNumber16;
+ else
+ m_advanceAndUpdateLineNumberFunc = &SegmentedString::advance16;
+ return;
+ }
</ins><span class="cx">
</span><del>-inline void SegmentedString::advancePastNewline()
-{
- ASSERT(m_currentCharacter == '\n');
- if (m_currentSubstring.length > 1) {
- if (m_currentSubstring.doNotExcludeLineNumbers)
- startNewLine();
- m_currentCharacter = m_currentSubstring.currentCharacterPreIncrement();
- decrementAndCheckLength();
- return;
</del><ins>+ if (!m_currentString.m_length && !isComposite()) {
+ m_advanceFunc = &SegmentedString::advanceEmpty;
+ m_fastPathFlags = NoFastPath;
+ m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty;
+ }
+
+ updateSlowCaseFunctionPointers();
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- (this->*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<typename CharacterType> 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<SegmentedSubstring> 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 < count; ++i)
+ advancePastNonNewline();
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-template<unsigned lengthIncludingTerminator, bool lettersIgnoringASCIICase> SegmentedString::AdvancePastResult SegmentedString::advancePast(const char (&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 < m_currentSubstring.length) {
- if (m_currentSubstring.is8Bit) {
- for (unsigned i = 0; i < 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 < 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 <= static_cast<unsigned>(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 > 1) {
- if (m_currentSubstring.is8Bit) {
- m_fastPathFlags = Use8BitAdvance;
- if (m_currentSubstring.doNotExcludeLineNumbers)
- m_fastPathFlags |= Use8BitAdvanceAndUpdateLineNumbers;
- return;
- }
- m_fastPathFlags = NoFastPath;
- m_advanceWithoutUpdatingLineNumberFunction = &SegmentedString::advanceWithoutUpdatingLineNumber16;
- if (m_currentSubstring.doNotExcludeLineNumbers)
- m_advanceAndUpdateLineNumberFunction = &SegmentedString::advanceAndUpdateLineNumber16;
- else
- m_advanceAndUpdateLineNumberFunction = &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& source, StringBuilder& consumedCharacters)
</del><ins>+inline void unconsumeCharacters(SegmentedString& source, const StringBuilder& 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 <typename ParserFunctions>
</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 == '<' || character == '&')
</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("#"));
</del><ins>+ source.pushBack(SegmentedString(ASCIILiteral("#")));
</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("#x"));
</del><ins>+ source.pushBack(SegmentedString(ASCIILiteral("#x")));
</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("#X"));
</del><ins>+ source.pushBack(SegmentedString(ASCIILiteral("#X")));
</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 "SegmentedString.h"
+
</ins><span class="cx"> #if COMPILER(MSVC)
</span><span class="cx"> // Disable the "unreachable code" 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&&)
</del><ins>+void XMLDocumentParser::insert(const SegmentedString&)
</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<StringImpl>&& 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<const char*>(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 "ScriptableDocumentParser.h"
</span><span class="cx"> #include "SegmentedString.h"
</span><span class="cx"> #include "XMLErrors.h"
</span><del>-#include <libxml/tree.h>
-#include <libxml/xmlstring.h>
</del><span class="cx"> #include <wtf/HashMap.h>
</span><span class="cx"> #include <wtf/text/AtomicStringHash.h>
</span><span class="cx"> #include <wtf/text/CString.h>
</span><span class="cx">
</span><ins>+#include <libxml/tree.h>
+#include <libxml/xmlstring.h>
+
</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<XMLParserContext> {
-public:
- static RefPtr<XMLParserContext> createMemoryParser(xmlSAXHandlerPtr, void* userData, const CString& chunk);
- static Ref<XMLParserContext> createStringParser(xmlSAXHandlerPtr, void* userData);
- ~XMLParserContext();
- xmlParserCtxtPtr context() const { return m_context; }
</del><ins>+ class XMLParserContext : public RefCounted<XMLParserContext> {
+ public:
+ static RefPtr<XMLParserContext> createMemoryParser(xmlSAXHandlerPtr, void* userData, const CString& chunk);
+ static Ref<XMLParserContext> 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<XMLDocumentParser> create(Document& document, FrameView* view)
- {
- return adoptRef(*new XMLDocumentParser(document, view));
- }
- static Ref<XMLDocumentParser> create(DocumentFragment& 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<XMLDocumentParser> create(Document& document, FrameView* view)
+ {
+ return adoptRef(*new XMLDocumentParser(document, view));
+ }
+ static Ref<XMLDocumentParser> create(DocumentFragment& 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&, DocumentFragment&, Element* parent = nullptr, ParserContentPolicy = AllowScriptingContent);
</del><ins>+ static bool parseDocumentFragment(const String&, DocumentFragment&, 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&);
</del><ins>+ static bool supportsXMLVersion(const String&);
</ins><span class="cx">
</span><del>-private:
- explicit XMLDocumentParser(Document&, FrameView* = nullptr);
- XMLDocumentParser(DocumentFragment&, Element*, ParserContentPolicy);
</del><ins>+ private:
+ XMLDocumentParser(Document&, FrameView* = nullptr);
+ XMLDocumentParser(DocumentFragment&, Element*, ParserContentPolicy);
</ins><span class="cx">
</span><del>- void insert(SegmentedString&&) final;
- void append(RefPtr<StringImpl>&&) final;
- void finish() final;
- bool isWaitingForScripts() const final;
- void stopParsing() final;
- void detach() final;
</del><ins>+ // From DocumentParser
+ void insert(const SegmentedString&) override;
+ void append(RefPtr<StringImpl>&&) 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&) final;
</del><ins>+ void notifyFinished(PendingScript&) 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&);
</del><ins>+ bool appendFragmentSource(const String&);
</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& chunk = CString());
</ins><span class="cx">
</span><del>-private:
- void initializeParserContext(const CString& 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&);
+ void doEnd();
</ins><span class="cx">
</span><del>- void doWrite(const String&);
- void doEnd();
</del><ins>+ FrameView* m_view;
</ins><span class="cx">
</span><del>- xmlParserCtxtPtr context() const { return m_context ? m_context->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->context() : nullptr; };
+ RefPtr<XMLParserContext> m_context;
+ std::unique_ptr<PendingCallbacks> m_pendingCallbacks;
+ Vector<xmlChar> m_bufferedText;
+ int m_depthTriggeringEntityExpansion;
+ bool m_isParsingEntityDeclaration;
</ins><span class="cx">
</span><del>- SegmentedString m_originalSourceForTransform;
</del><ins>+ ContainerNode* m_currentNode;
+ Vector<ContainerNode*> m_currentNodeStack;
</ins><span class="cx">
</span><del>- RefPtr<XMLParserContext> m_context;
- std::unique_ptr<PendingCallbacks> m_pendingCallbacks;
- Vector<xmlChar> m_bufferedText;
- int m_depthTriggeringEntityExpansion { -1 };
- bool m_isParsingEntityDeclaration { false };
</del><ins>+ RefPtr<Text> m_leafTextNode;
</ins><span class="cx">
</span><del>- ContainerNode* m_currentNode { nullptr };
- Vector<ContainerNode*> 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<Text> m_leafTextNode;
</del><ins>+ std::unique_ptr<XMLErrors> 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<PendingScript> m_pendingScript;
+ TextPosition m_scriptStartPosition;
</ins><span class="cx">
</span><del>- std::unique_ptr<XMLErrors> m_xmlErrors;
</del><ins>+ bool m_parsingFragment;
+ AtomicString m_defaultNamespaceURI;
</ins><span class="cx">
</span><del>- RefPtr<PendingScript> m_pendingScript;
- TextPosition m_scriptStartPosition;
</del><ins>+ typedef HashMap<AtomicString, AtomicString> PrefixForNamespaceMap;
+ PrefixForNamespaceMap m_prefixToNamespaceMap;
+ SegmentedString m_pendingSrc;
+ };
</ins><span class="cx">
</span><del>- bool m_parsingFragment { false };
- AtomicString m_defaultNamespaceURI;
-
- HashMap<AtomicString, AtomicString> m_prefixToNamespaceMap;
- SegmentedString m_pendingSrc;
-};
-
</del><span class="cx"> #if ENABLE(XSLT)
</span><span class="cx"> void* xmlDocPtrForString(CachedResourceLoader&, const String& source, const String& 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 <pmk@post.com>
</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 <ap@webkit.org>
</span><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="lines">@@ -35,23 +35,35 @@
</span><span class="cx"> #include "DocumentFragment.h"
</span><span class="cx"> #include "DocumentType.h"
</span><span class="cx"> #include "Frame.h"
</span><ins>+#include "FrameLoader.h"
+#include "FrameView.h"
</ins><span class="cx"> #include "HTMLEntityParser.h"
</span><span class="cx"> #include "HTMLHtmlElement.h"
</span><ins>+#include "HTMLLinkElement.h"
+#include "HTMLNames.h"
+#include "HTMLStyleElement.h"
</ins><span class="cx"> #include "HTMLTemplateElement.h"
</span><ins>+#include "LoadableClassicScript.h"
</ins><span class="cx"> #include "Page.h"
</span><span class="cx"> #include "PendingScript.h"
</span><span class="cx"> #include "ProcessingInstruction.h"
</span><span class="cx"> #include "ResourceError.h"
</span><ins>+#include "ResourceRequest.h"
</ins><span class="cx"> #include "ResourceResponse.h"
</span><span class="cx"> #include "ScriptElement.h"
</span><span class="cx"> #include "ScriptSourceCode.h"
</span><ins>+#include "SecurityOrigin.h"
</ins><span class="cx"> #include "Settings.h"
</span><span class="cx"> #include "StyleScope.h"
</span><ins>+#include "TextResourceDecoder.h"
</ins><span class="cx"> #include "TransformSource.h"
</span><span class="cx"> #include "XMLNSNames.h"
</span><span class="cx"> #include "XMLDocumentParserScope.h"
</span><span class="cx"> #include <libxml/parserInternals.h>
</span><ins>+#include <wtf/Ref.h>
</ins><span class="cx"> #include <wtf/StringExtras.h>
</span><ins>+#include <wtf/Threading.h>
+#include <wtf/Vector.h>
</ins><span class="cx"> #include <wtf/unicode/UTF8.h>
</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& document)
</del><ins>+static inline bool hasNoStyleInformation(Document* document)
</ins><span class="cx"> {
</span><del>- if (document.sawElementsInKnownNamespaces())
</del><ins>+ if (document->sawElementsInKnownNamespaces())
</ins><span class="cx"> return false;
</span><span class="cx">
</span><del>- if (document.transformSourceDocument())
</del><ins>+ if (document->transformSourceDocument())
</ins><span class="cx"> return false;
</span><span class="cx">
</span><del>- auto* frame = document.frame();
- if (!frame)
</del><ins>+ if (!document->frame() || !document->frame()->page())
</ins><span class="cx"> return false;
</span><span class="cx">
</span><del>- if (!frame->settings().developerExtrasEnabled())
</del><ins>+ if (!document->frame()->page()->settings().developerExtrasEnabled())
</ins><span class="cx"> return false;
</span><span class="cx">
</span><del>- if (frame->tree().parent())
</del><ins>+ if (document->frame()->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<PendingStartElementNSCallback>();
</span><span class="lines">@@ -564,16 +575,40 @@
</span><span class="cx"> XMLDocumentParser::XMLDocumentParser(Document& 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<PendingCallbacks>())
</span><ins>+ , m_depthTriggeringEntityExpansion(-1)
+ , m_isParsingEntityDeclaration(false)
</ins><span class="cx"> , m_currentNode(&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& 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<PendingCallbacks>())
</span><ins>+ , m_depthTriggeringEntityExpansion(-1)
+ , m_isParsingEntityDeclaration(false)
</ins><span class="cx"> , m_currentNode(&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(&utf16Entity, utf16Entity + numberOfCodeUnits, &target, target + targetSize);
</del><ins>+ WTF::Unicode::ConversionResult conversionResult = WTF::Unicode::convertUTF16ToUTF8(&utf16Entity,
+ utf16Entity + numberOfCodeUnits, &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 && !m_sawCSS && !m_sawXSLTransform && shouldRenderInXMLTreeViewerMode(*document());
</del><ins>+ bool xmlViewerMode = !m_sawError && !m_sawCSS && !m_sawXSLTransform && 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>