<!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>[174388] 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/174388">174388</a></dd>
<dt>Author</dt> <dd>darin@apple.com</dd>
<dt>Date</dt> <dd>2014-10-06 23:58:41 -0700 (Mon, 06 Oct 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Make StringView check the lifetime of the StringImpl it's created from
https://bugs.webkit.org/show_bug.cgi?id=137202

Reviewed by Anders Carlsson.

Source/WebCore:

* platform/graphics/TextRun.cpp: Update since TextRun's definition now
uses a StringView.

Source/WTF:

* WTF.vcxproj/WTF.vcxproj: Added StringView.cpp.
* WTF.vcxproj/WTF.vcxproj.filters: Added StringView.cpp.
* WTF.xcodeproj/project.pbxproj: Added StringView.cpp.
* wtf/CMakeLists.txt: Added StringView.cpp.

* wtf/text/StringImpl.cpp:
(WTF::StringImpl::~StringImpl): Call StringView::invalidate.

* wtf/text/StringView.cpp: Added.
(WTF::underlyingStrings): Returns map from StringImpl to the underlying
string object used by StringView to track validity.
(WTF::StringView::invalidate): Mark the underlying string object invalid,
and remove it from the map, so any future StringImpl will get a new one,
even if it has the same pointer.
(WTF::StringView::underlyingStringIsValid): Return true only if the
underlying string is still valid.
(WTF::StringView::setUnderlyingString): Create and manage reference counts
of underlying string objects as needed.

* wtf/text/StringView.h: Moved function bodies out of the class definition,
so we can now read a clean class definition to see the class design and what
functions it offers.
(WTF::StringView::StringView): Added a comment to the default constructor.
Also added copy and move constructors so they can call setUnderlyingString
and assert the underlying string is valid as needed, replacing the
compiler-generated ones.
(WTF::StringView::~StringView): Added a call to setUnderlyingString.
(WTF::StringView::operator=): Added these assignment operators with the same
job as the constructors above.
(WTF::StringView::initialize): Added a comment.
(WTF::StringView::characters8): Added an assertion that the underlying
string is valid.
(WTF::StringView::characters16): Ditto.
(WTF::StringView::substring): Added code to propagate the underlying string
from the original string to the substring.
(WTF::StringView::invalidate): Inline empty version of this function for
non-debug builds.
(WTF::StringView::underlyingStringIsValid): Ditto.
(WTF::StringView::setUnderlyingString): Ditto.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFWTFvcxprojWTFvcxproj">trunk/Source/WTF/WTF.vcxproj/WTF.vcxproj</a></li>
<li><a href="#trunkSourceWTFWTFvcxprojWTFvcxprojfilters">trunk/Source/WTF/WTF.vcxproj/WTF.vcxproj.filters</a></li>
<li><a href="#trunkSourceWTFWTFxcodeprojprojectpbxproj">trunk/Source/WTF/WTF.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWTFwtfCMakeListstxt">trunk/Source/WTF/wtf/CMakeLists.txt</a></li>
<li><a href="#trunkSourceWTFwtftextStringImplcpp">trunk/Source/WTF/wtf/text/StringImpl.cpp</a></li>
<li><a href="#trunkSourceWTFwtftextStringViewh">trunk/Source/WTF/wtf/text/StringView.h</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsTextRuncpp">trunk/Source/WebCore/platform/graphics/TextRun.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWTFwtftextStringViewcpp">trunk/Source/WTF/wtf/text/StringView.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (174387 => 174388)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2014-10-07 06:54:48 UTC (rev 174387)
+++ trunk/Source/WTF/ChangeLog        2014-10-07 06:58:41 UTC (rev 174388)
</span><span class="lines">@@ -1,3 +1,50 @@
</span><ins>+2014-10-06  Darin Adler  &lt;darin@apple.com&gt;
+
+        Make StringView check the lifetime of the StringImpl it's created from
+        https://bugs.webkit.org/show_bug.cgi?id=137202
+
+        Reviewed by Anders Carlsson.
+
+        * WTF.vcxproj/WTF.vcxproj: Added StringView.cpp.
+        * WTF.vcxproj/WTF.vcxproj.filters: Added StringView.cpp.
+        * WTF.xcodeproj/project.pbxproj: Added StringView.cpp.
+        * wtf/CMakeLists.txt: Added StringView.cpp.
+
+        * wtf/text/StringImpl.cpp:
+        (WTF::StringImpl::~StringImpl): Call StringView::invalidate.
+
+        * wtf/text/StringView.cpp: Added.
+        (WTF::underlyingStrings): Returns map from StringImpl to the underlying
+        string object used by StringView to track validity.
+        (WTF::StringView::invalidate): Mark the underlying string object invalid,
+        and remove it from the map, so any future StringImpl will get a new one,
+        even if it has the same pointer.
+        (WTF::StringView::underlyingStringIsValid): Return true only if the
+        underlying string is still valid.
+        (WTF::StringView::setUnderlyingString): Create and manage reference counts
+        of underlying string objects as needed.
+
+        * wtf/text/StringView.h: Moved function bodies out of the class definition,
+        so we can now read a clean class definition to see the class design and what
+        functions it offers.
+        (WTF::StringView::StringView): Added a comment to the default constructor.
+        Also added copy and move constructors so they can call setUnderlyingString
+        and assert the underlying string is valid as needed, replacing the
+        compiler-generated ones.
+        (WTF::StringView::~StringView): Added a call to setUnderlyingString.
+        (WTF::StringView::operator=): Added these assignment operators with the same
+        job as the constructors above.
+        (WTF::StringView::initialize): Added a comment.
+        (WTF::StringView::characters8): Added an assertion that the underlying
+        string is valid.
+        (WTF::StringView::characters16): Ditto.
+        (WTF::StringView::substring): Added code to propagate the underlying string
+        from the original string to the substring.
+        (WTF::StringView::invalidate): Inline empty version of this function for
+        non-debug builds.
+        (WTF::StringView::underlyingStringIsValid): Ditto.
+        (WTF::StringView::setUnderlyingString): Ditto.
+
</ins><span class="cx"> 2014-10-06  Brent Fulgham  &lt;bfulgham@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [Win] DateMath's calculateUTFOffset does not account for DST.
</span></span></pre></div>
<a id="trunkSourceWTFWTFvcxprojWTFvcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/WTF.vcxproj/WTF.vcxproj (174387 => 174388)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/WTF.vcxproj/WTF.vcxproj        2014-10-07 06:54:48 UTC (rev 174387)
+++ trunk/Source/WTF/WTF.vcxproj/WTF.vcxproj        2014-10-07 06:58:41 UTC (rev 174388)
</span><span class="lines">@@ -134,6 +134,7 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\wtf\text\StringBuilder.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\wtf\text\StringImpl.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\wtf\text\StringStatics.cpp&quot; /&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\wtf\text\StringView.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\wtf\text\WTFString.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\wtf\text\cf\AtomicStringCF.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\wtf\text\cf\StringCF.cpp&quot; /&gt;
</span></span></pre></div>
<a id="trunkSourceWTFWTFvcxprojWTFvcxprojfilters"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/WTF.vcxproj/WTF.vcxproj.filters (174387 => 174388)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/WTF.vcxproj/WTF.vcxproj.filters        2014-10-07 06:54:48 UTC (rev 174387)
+++ trunk/Source/WTF/WTF.vcxproj/WTF.vcxproj.filters        2014-10-07 06:58:41 UTC (rev 174388)
</span><span class="lines">@@ -60,6 +60,9 @@
</span><span class="cx">     &lt;ClCompile Include=&quot;..\wtf\text\StringStatics.cpp&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;text&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\wtf\text\StringView.cpp&quot;&gt;
+      &lt;Filter&gt;text&lt;/Filter&gt;
+    &lt;/ClCompile&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\wtf\text\AtomicString.cpp&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;text&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClCompile&gt;
</span><span class="lines">@@ -716,4 +719,4 @@
</span><span class="cx">     &lt;None Include=&quot;WTFPostBuild.cmd&quot; /&gt;
</span><span class="cx">     &lt;None Include=&quot;WTFPreBuild.cmd&quot; /&gt;
</span><span class="cx">   &lt;/ItemGroup&gt;
</span><del>-&lt;/Project&gt;
</del><span class="cx">\ No newline at end of file
</span><ins>+&lt;/Project&gt;
</ins></span></pre></div>
<a id="trunkSourceWTFWTFxcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/WTF.xcodeproj/project.pbxproj (174387 => 174388)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/WTF.xcodeproj/project.pbxproj        2014-10-07 06:54:48 UTC (rev 174387)
+++ trunk/Source/WTF/WTF.xcodeproj/project.pbxproj        2014-10-07 06:58:41 UTC (rev 174388)
</span><span class="lines">@@ -84,6 +84,7 @@
</span><span class="cx">                 93934BD518A1F16900D0D6A1 /* StringViewCF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93934BD418A1F16900D0D6A1 /* StringViewCF.cpp */; };
</span><span class="cx">                 93AC91A818942FC400244939 /* LChar.h in Headers */ = {isa = PBXBuildFile; fileRef = 93AC91A718942FC400244939 /* LChar.h */; };
</span><span class="cx">                 93B1AA80180E5AF3004A2F05 /* PassRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 93B1AA7F180E5AF3004A2F05 /* PassRef.h */; };
</span><ins>+                93F1993E19D7958D00C2390B /* StringView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93F1993D19D7958D00C2390B /* StringView.cpp */; };
</ins><span class="cx">                 974CFC8E16A4F327006D5404 /* WeakPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 974CFC8D16A4F327006D5404 /* WeakPtr.h */; };
</span><span class="cx">                 9BC70F05176C379D00101DEC /* AtomicStringTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9BC70F04176C379D00101DEC /* AtomicStringTable.cpp */; };
</span><span class="cx">                 9BD8F40B176C2B470002D865 /* AtomicStringTable.h in Headers */ = {isa = PBXBuildFile; fileRef = 9BD8F40A176C2AD80002D865 /* AtomicStringTable.h */; };
</span><span class="lines">@@ -373,6 +374,7 @@
</span><span class="cx">                 93934BD418A1F16900D0D6A1 /* StringViewCF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringViewCF.cpp; path = cf/StringViewCF.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 93AC91A718942FC400244939 /* LChar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LChar.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 93B1AA7F180E5AF3004A2F05 /* PassRef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PassRef.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                93F1993D19D7958D00C2390B /* StringView.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StringView.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 974CFC8D16A4F327006D5404 /* WeakPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakPtr.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 9BC70F04176C379D00101DEC /* AtomicStringTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AtomicStringTable.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 9BD8F40A176C2AD80002D865 /* AtomicStringTable.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AtomicStringTable.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -954,12 +956,13 @@
</span><span class="cx">                                 A8A47327151A825B004123FF /* StringHash.h */,
</span><span class="cx">                                 A8A47328151A825B004123FF /* StringImpl.cpp */,
</span><span class="cx">                                 A8A47329151A825B004123FF /* StringImpl.h */,
</span><ins>+                                1A6EB1DF187D0BD30030126F /* StringView.h */,
+                                93F1993D19D7958D00C2390B /* StringView.cpp */,
</ins><span class="cx">                                 A8A4732A151A825B004123FF /* StringOperators.h */,
</span><span class="cx">                                 A8A4732B151A825B004123FF /* StringStatics.cpp */,
</span><span class="cx">                                 A8A4732C151A825B004123FF /* TextPosition.h */,
</span><span class="cx">                                 A8A4732D151A825B004123FF /* WTFString.cpp */,
</span><span class="cx">                                 A8A4732E151A825B004123FF /* WTFString.h */,
</span><del>-                                1A6EB1DF187D0BD30030126F /* StringView.h */,
</del><span class="cx">                         );
</span><span class="cx">                         path = text;
</span><span class="cx">                         sourceTree = &quot;&lt;group&gt;&quot;;
</span><span class="lines">@@ -1351,6 +1354,7 @@
</span><span class="cx">                                 A8A473EC151A825B004123FF /* MetaAllocator.cpp in Sources */,
</span><span class="cx">                                 A8A473F4151A825B004123FF /* NumberOfCores.cpp in Sources */,
</span><span class="cx">                                 A8A473F7151A825B004123FF /* OSAllocatorPosix.cpp in Sources */,
</span><ins>+                                93F1993E19D7958D00C2390B /* StringView.cpp in Sources */,
</ins><span class="cx">                                 A8A473F9151A825B004123FF /* OSRandomSource.cpp in Sources */,
</span><span class="cx">                                 A8A47400151A825B004123FF /* PageAllocationAligned.cpp in Sources */,
</span><span class="cx">                                 A8A47402151A825B004123FF /* PageBlock.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWTFwtfCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/CMakeLists.txt (174387 => 174388)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/CMakeLists.txt        2014-10-07 06:54:48 UTC (rev 174387)
+++ trunk/Source/WTF/wtf/CMakeLists.txt        2014-10-07 06:58:41 UTC (rev 174388)
</span><span class="lines">@@ -201,6 +201,7 @@
</span><span class="cx">     text/StringBuilder.cpp
</span><span class="cx">     text/StringImpl.cpp
</span><span class="cx">     text/StringStatics.cpp
</span><ins>+    text/StringView.cpp
</ins><span class="cx">     text/WTFString.cpp
</span><span class="cx"> 
</span><span class="cx">     threads/BinarySemaphore.cpp
</span></span></pre></div>
<a id="trunkSourceWTFwtftextStringImplcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/text/StringImpl.cpp (174387 => 174388)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/text/StringImpl.cpp        2014-10-07 06:54:48 UTC (rev 174387)
+++ trunk/Source/WTF/wtf/text/StringImpl.cpp        2014-10-07 06:58:41 UTC (rev 174388)
</span><span class="lines">@@ -105,6 +105,8 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!isStatic());
</span><span class="cx"> 
</span><ins>+    StringView::invalidate(*this);
+
</ins><span class="cx">     STRING_STATS_REMOVE_STRING(*this);
</span><span class="cx"> 
</span><span class="cx">     if (isAtomic() &amp;&amp; m_length)
</span></span></pre></div>
<a id="trunkSourceWTFwtftextStringViewcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WTF/wtf/text/StringView.cpp (0 => 174388)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/text/StringView.cpp                                (rev 0)
+++ trunk/Source/WTF/wtf/text/StringView.cpp        2014-10-07 06:58:41 UTC (rev 174388)
</span><span class="lines">@@ -0,0 +1,123 @@
</span><ins>+/*
+
+Copyright (C) 2014 Apple Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1.  Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+2.  Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+#include &quot;config.h&quot;
+#include &quot;StringView.h&quot;
+
+#include &lt;mutex&gt;
+#include &lt;wtf/HashMap.h&gt;
+#include &lt;wtf/NeverDestroyed.h&gt;
+
+#if CHECK_STRINGVIEW_LIFETIME
+
+namespace WTF {
+
+// Manage reference count manually so UnderlyingString does not need to be defined in the header.
+
+struct StringView::UnderlyingString {
+    std::atomic_uint refCount { 1 };
+    bool isValid { true };
+    const StringImpl&amp; string;
+    explicit UnderlyingString(const StringImpl&amp;);
+};
+
+StringView::UnderlyingString::UnderlyingString(const StringImpl&amp; string)
+    : string(string)
+{
+}
+
+static std::mutex&amp; underlyingStringsMutex()
+{
+    static NeverDestroyed&lt;std::mutex&gt; mutex;
+    return mutex;
+}
+
+static HashMap&lt;const StringImpl*, StringView::UnderlyingString*&gt;&amp; underlyingStrings()
+{
+    static NeverDestroyed&lt;HashMap&lt;const StringImpl*, StringView::UnderlyingString*&gt;&gt; map;
+    return map;
+}
+
+void StringView::invalidate(const StringImpl&amp; stringToBeDestroyed)
+{
+    UnderlyingString* underlyingString;
+    {
+        std::lock_guard&lt;std::mutex&gt; lock(underlyingStringsMutex());
+        underlyingString = underlyingStrings().take(&amp;stringToBeDestroyed);
+        if (!underlyingString)
+            return;
+    }
+    ASSERT(underlyingString-&gt;isValid);
+    underlyingString-&gt;isValid = false;
+}
+
+bool StringView::underlyingStringIsValid() const
+{
+    return !m_underlyingString || m_underlyingString-&gt;isValid;
+}
+
+void StringView::adoptUnderlyingString(UnderlyingString* underlyingString)
+{
+    if (m_underlyingString) {
+        if (!--m_underlyingString-&gt;refCount) {
+            if (m_underlyingString-&gt;isValid) {
+                std::lock_guard&lt;std::mutex&gt; lock(underlyingStringsMutex());
+                underlyingStrings().remove(&amp;m_underlyingString-&gt;string);
+            }
+            delete m_underlyingString;
+        }
+    }
+    m_underlyingString = underlyingString;
+}
+
+void StringView::setUnderlyingString(const StringImpl* string)
+{
+    UnderlyingString* underlyingString;
+    if (!string)
+        underlyingString = nullptr;
+    else {
+        std::lock_guard&lt;std::mutex&gt; lock(underlyingStringsMutex());
+        auto result = underlyingStrings().add(string, nullptr);
+        if (result.isNewEntry)
+            result.iterator-&gt;value = new UnderlyingString(*string);
+        else
+            ++result.iterator-&gt;value-&gt;refCount;
+        underlyingString = result.iterator-&gt;value;
+    }
+    adoptUnderlyingString(underlyingString);
+}
+
+void StringView::setUnderlyingString(const StringView&amp; string)
+{
+    UnderlyingString* underlyingString = string.m_underlyingString;
+    if (underlyingString)
+        ++underlyingString-&gt;refCount;
+    adoptUnderlyingString(underlyingString);
+}
+
+}
+
+#endif
</ins><span class="cx">Property changes on: trunk/Source/WTF/wtf/text/StringView.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceWTFwtftextStringViewh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/text/StringView.h (174387 => 174388)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/text/StringView.h        2014-10-07 06:54:48 UTC (rev 174387)
+++ trunk/Source/WTF/wtf/text/StringView.h        2014-10-07 06:58:41 UTC (rev 174388)
</span><span class="lines">@@ -32,160 +32,202 @@
</span><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><span class="cx"> #include &lt;wtf/text/LChar.h&gt;
</span><span class="cx"> 
</span><ins>+#ifdef NDEBUG
+#define CHECK_STRINGVIEW_LIFETIME 0
+#else
+#define CHECK_STRINGVIEW_LIFETIME 1
+#endif
+
</ins><span class="cx"> namespace WTF {
</span><span class="cx"> 
</span><span class="cx"> // StringView is a non-owning reference to a string, similar to the proposed std::string_view.
</span><span class="cx"> // Whether the string is 8-bit or 16-bit is encoded in the upper bit of the length member.
</span><del>-// This means that strings longer than 2 Gigabytes can not be represented. If that turns out to be
-// a problem we can investigate alternative solutions.
</del><ins>+// This means that strings longer than 2 gigacharacters cannot be represented.
</ins><span class="cx"> 
</span><span class="cx"> class StringView {
</span><span class="cx"> public:
</span><del>-    StringView()
-        : m_characters(nullptr)
-        , m_length(0)
-    {
-    }
</del><ins>+    StringView();
+    ~StringView();
+    StringView(StringView&amp;&amp;);
+    StringView(const StringView&amp;);
+    StringView&amp; operator=(StringView&amp;&amp;);
+    StringView&amp; operator=(const StringView&amp;);
</ins><span class="cx"> 
</span><del>-    StringView(const LChar* characters, unsigned length)
-    {
-        initialize(characters, length);
-    }
</del><ins>+    StringView(const String&amp;);
+    StringView(const StringImpl&amp;);
+    StringView(const LChar*, unsigned length);
+    StringView(const UChar*, unsigned length);
</ins><span class="cx"> 
</span><del>-    StringView(const UChar* characters, unsigned length)
-    {
-        initialize(characters, length);
-    }
</del><ins>+    static StringView empty();
</ins><span class="cx"> 
</span><del>-    StringView(const StringImpl&amp;);
-    StringView(const String&amp;);
</del><ins>+    unsigned length() const;
+    bool isEmpty() const;
</ins><span class="cx"> 
</span><del>-    static StringView empty()
-    {
-        return StringView(reinterpret_cast&lt;const LChar*&gt;(&quot;&quot;), 0);
-    }
</del><ins>+    explicit operator bool() const;
+    bool isNull() const;
</ins><span class="cx"> 
</span><del>-    const LChar* characters8() const
-    {
-        ASSERT(is8Bit());
</del><ins>+    UChar operator[](unsigned index) const;
</ins><span class="cx"> 
</span><del>-        return static_cast&lt;const LChar*&gt;(m_characters);
-    }
</del><ins>+    class CodeUnits;
+    CodeUnits codeUnits() const;
</ins><span class="cx"> 
</span><del>-    const UChar* characters16() const
-    {
-        ASSERT(!is8Bit());
</del><ins>+    class CodePoints;
+    CodePoints codePoints() const;
</ins><span class="cx"> 
</span><del>-        return static_cast&lt;const UChar*&gt;(m_characters);
-    }
</del><ins>+    bool is8Bit() const;
+    const LChar* characters8() const;
+    const UChar* characters16() const;
</ins><span class="cx"> 
</span><ins>+    String toString() const;
+    String toStringWithoutCopying() const;
+
+#if USE(CF)
+    // This function converts null strings to empty strings.
+    WTF_EXPORT_STRING_API RetainPtr&lt;CFStringRef&gt; createCFStringWithoutCopying() const;
+#endif
+
+#ifdef __OBJC__
+    // These functions convert null strings to empty strings.
+    WTF_EXPORT_STRING_API RetainPtr&lt;NSString&gt; createNSString() const;
+    WTF_EXPORT_STRING_API RetainPtr&lt;NSString&gt; createNSStringWithoutCopying() const;
+#endif
+
+    class UpconvertedCharacters;
+    UpconvertedCharacters upconvertedCharacters() const;
+
</ins><span class="cx">     void getCharactersWithUpconvert(LChar*) const;
</span><span class="cx">     void getCharactersWithUpconvert(UChar*) const;
</span><span class="cx"> 
</span><del>-    class UpconvertedCharacters {
-    public:
-        explicit UpconvertedCharacters(const StringView&amp;);
-        operator const UChar*() const { return m_characters; }
-        const UChar* get() const { return m_characters; }
-    private:
-        Vector&lt;UChar, 32&gt; m_upconvertedCharacters;
-        const UChar* m_characters;
-    };
-    UpconvertedCharacters upconvertedCharacters() const { return UpconvertedCharacters(*this); }
</del><ins>+    StringView substring(unsigned start, unsigned length = std::numeric_limits&lt;unsigned&gt;::max()) const;
</ins><span class="cx"> 
</span><del>-    bool isNull() const { return !m_characters; }
-    bool isEmpty() const { return !length(); }
-    unsigned length() const { return m_length &amp; ~is16BitStringFlag; }
</del><ins>+    size_t find(UChar, unsigned start = 0) const;
+    bool contains(UChar) const;
</ins><span class="cx"> 
</span><del>-    explicit operator bool() const { return !isNull(); }
</del><ins>+    int toInt(bool&amp; isValid) const;
+    float toFloat(bool&amp; isValid) const;
</ins><span class="cx"> 
</span><del>-    bool is8Bit() const { return !(m_length &amp; is16BitStringFlag); }
</del><ins>+    static void invalidate(const StringImpl&amp;);
</ins><span class="cx"> 
</span><del>-    StringView substring(unsigned start, unsigned length = std::numeric_limits&lt;unsigned&gt;::max()) const
-    {
-        if (start &gt;= this-&gt;length())
-            return empty();
-        unsigned maxLength = this-&gt;length() - start;
</del><ins>+    struct UnderlyingString;
</ins><span class="cx"> 
</span><del>-        if (length &gt;= maxLength) {
-            if (!start)
-                return *this;
-            length = maxLength;
-        }
</del><ins>+private:
+    void initialize(const LChar*, unsigned length);
+    void initialize(const UChar*, unsigned length);
</ins><span class="cx"> 
</span><del>-        if (is8Bit())
-            return StringView(characters8() + start, length);
</del><ins>+    WTF_EXPORT_STRING_API bool underlyingStringIsValid() const;
+    WTF_EXPORT_STRING_API void setUnderlyingString(const StringImpl*);
+    WTF_EXPORT_STRING_API void setUnderlyingString(const StringView&amp;);
</ins><span class="cx"> 
</span><del>-        return StringView(characters16() + start, length);
-    }
</del><ins>+    static const unsigned is16BitStringFlag = 1u &lt;&lt; 31;
</ins><span class="cx"> 
</span><del>-    String toString() const;
</del><ins>+    const void* m_characters { nullptr };
+    unsigned m_length { 0 };
</ins><span class="cx"> 
</span><del>-    float toFloat(bool&amp; isValid) const;
-    int toInt(bool&amp; isValid) const;
</del><ins>+#if CHECK_STRINGVIEW_LIFETIME
+    void adoptUnderlyingString(UnderlyingString*);
+    UnderlyingString* m_underlyingString { nullptr };
+#endif
+};
</ins><span class="cx"> 
</span><del>-    String toStringWithoutCopying() const;
</del><ins>+template&lt;typename CharacterType, size_t inlineCapacity&gt; void append(Vector&lt;CharacterType, inlineCapacity&gt;&amp;, StringView);
</ins><span class="cx"> 
</span><del>-    UChar operator[](unsigned index) const
-    {
-        ASSERT(index &lt; length());
-        if (is8Bit())
-            return characters8()[index];
-        return characters16()[index];
-    }
</del><ins>+}
</ins><span class="cx"> 
</span><del>-    size_t find(UChar character, unsigned start = 0) const;
</del><ins>+#include &lt;wtf/text/WTFString.h&gt;
</ins><span class="cx"> 
</span><del>-    bool contains(UChar c) const { return find(c) != notFound; }
</del><ins>+namespace WTF {
</ins><span class="cx"> 
</span><del>-    class CodePoints;
-    class CodeUnits;
</del><ins>+inline StringView::StringView()
+{
+    // FIXME: It's peculiar that null strings are 16-bit and empty strings return 8-bit (according to the is8Bit function).
+}
</ins><span class="cx"> 
</span><del>-    CodePoints codePoints() const;
-    CodeUnits codeUnits() const;
</del><ins>+inline StringView::~StringView()
+{
+    setUnderlyingString(nullptr);
+}
</ins><span class="cx"> 
</span><del>-#if USE(CF)
-    // This function converts null strings to empty strings.
-    WTF_EXPORT_STRING_API RetainPtr&lt;CFStringRef&gt; createCFStringWithoutCopying() const;
-#endif
</del><ins>+inline StringView::StringView(StringView&amp;&amp; other)
+    : m_characters(other.m_characters)
+    , m_length(other.m_length)
+{
+    ASSERT(other.underlyingStringIsValid());
</ins><span class="cx"> 
</span><del>-#ifdef __OBJC__
-    // These functions convert null strings to empty strings.
-    WTF_EXPORT_STRING_API RetainPtr&lt;NSString&gt; createNSString() const;
-    WTF_EXPORT_STRING_API RetainPtr&lt;NSString&gt; createNSStringWithoutCopying() const;
-#endif
</del><ins>+    other.m_characters = nullptr;
+    other.m_length = 0;
</ins><span class="cx"> 
</span><del>-private:
-    void initialize(const LChar* characters, unsigned length)
-    {
-        ASSERT(!(length &amp; is16BitStringFlag));
-        
-        m_characters = characters;
-        m_length = length;
-    }
</del><ins>+    setUnderlyingString(other);
+    other.setUnderlyingString(nullptr);
+}
</ins><span class="cx"> 
</span><del>-    void initialize(const UChar* characters, unsigned length)
-    {
-        ASSERT(!(length &amp; is16BitStringFlag));
-        
-        m_characters = characters;
-        m_length = is16BitStringFlag | length;
-    }
</del><ins>+inline StringView::StringView(const StringView&amp; other)
+    : m_characters(other.m_characters)
+    , m_length(other.m_length)
+{
+    ASSERT(other.underlyingStringIsValid());
</ins><span class="cx"> 
</span><del>-    static const unsigned is16BitStringFlag = 1u &lt;&lt; 31;
</del><ins>+    setUnderlyingString(other);
+}
</ins><span class="cx"> 
</span><del>-    const void* m_characters;
-    unsigned m_length;
-};
</del><ins>+inline StringView&amp; StringView::operator=(StringView&amp;&amp; other)
+{
+    ASSERT(other.underlyingStringIsValid());
</ins><span class="cx"> 
</span><ins>+    m_characters = other.m_characters;
+    m_length = other.m_length;
+
+    other.m_characters = nullptr;
+    other.m_length = 0;
+
+    setUnderlyingString(other);
+    other.setUnderlyingString(nullptr);
+
+    return *this;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-#include &lt;wtf/text/WTFString.h&gt;
</del><ins>+inline StringView&amp; StringView::operator=(const StringView&amp; other)
+{
+    ASSERT(other.underlyingStringIsValid());
</ins><span class="cx"> 
</span><del>-namespace WTF {
</del><ins>+    m_characters = other.m_characters;
+    m_length = other.m_length;
</ins><span class="cx"> 
</span><ins>+    setUnderlyingString(other);
+
+    return *this;
+}
+
+inline void StringView::initialize(const LChar* characters, unsigned length)
+{
+    // FIXME: We need a better solution here, because there is no guarantee that
+    // the length here won't be too long. Maybe at least a RELEASE_ASSERT?
+    ASSERT(!(length &amp; is16BitStringFlag));
+    m_characters = characters;
+    m_length = length;
+}
+
+inline void StringView::initialize(const UChar* characters, unsigned length)
+{
+    // FIXME: We need a better solution here, because there is no guarantee that
+    // the length here won't be too long. Maybe at least a RELEASE_ASSERT?
+    ASSERT(!(length &amp; is16BitStringFlag));
+    m_characters = characters;
+    m_length = is16BitStringFlag | length;
+}
+
+inline StringView::StringView(const LChar* characters, unsigned length)
+{
+    initialize(characters, length);
+}
+
+inline StringView::StringView(const UChar* characters, unsigned length)
+{
+    initialize(characters, length);
+}
+
</ins><span class="cx"> inline StringView::StringView(const StringImpl&amp; string)
</span><span class="cx"> {
</span><ins>+    setUnderlyingString(&amp;string);
</ins><span class="cx">     if (string.is8Bit())
</span><span class="cx">         initialize(string.characters8(), string.length());
</span><span class="cx">     else
</span><span class="lines">@@ -194,6 +236,7 @@
</span><span class="cx"> 
</span><span class="cx"> inline StringView::StringView(const String&amp; string)
</span><span class="cx"> {
</span><ins>+    setUnderlyingString(string.impl());
</ins><span class="cx">     if (!string.impl()) {
</span><span class="cx">         m_characters = nullptr;
</span><span class="cx">         m_length = 0;
</span><span class="lines">@@ -206,55 +249,100 @@
</span><span class="cx">     initialize(string.characters16(), string.length());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-class StringView::CodePoints {
-public:
-    class Iterator {
-    public:
-        Iterator(const StringView&amp;, unsigned index);
-        Iterator&amp; operator++();
-        UChar32 operator*() const;
-        bool operator==(const Iterator&amp;) const;
-        bool operator!=(const Iterator&amp;) const;
</del><ins>+inline StringView StringView::empty()
+{
+    return StringView(reinterpret_cast&lt;const LChar*&gt;(&quot;&quot;), 0);
+}
</ins><span class="cx"> 
</span><del>-    private:
-        const StringView&amp; m_stringView;
-        mutable unsigned m_index;
-#if !ASSERT_DISABLED
-        mutable bool m_alreadyIncremented;
-#endif
-    };
</del><ins>+inline const LChar* StringView::characters8() const
+{
+    ASSERT(is8Bit());
+    ASSERT(underlyingStringIsValid());
+    return static_cast&lt;const LChar*&gt;(m_characters);
+}
</ins><span class="cx"> 
</span><del>-    explicit CodePoints(const StringView&amp;);
-    Iterator begin() const;
-    Iterator end() const;
</del><ins>+inline const UChar* StringView::characters16() const
+{
+    ASSERT(!is8Bit());
+    ASSERT(underlyingStringIsValid());
+    return static_cast&lt;const UChar*&gt;(m_characters);
+}
</ins><span class="cx"> 
</span><ins>+class StringView::UpconvertedCharacters {
+public:
+    explicit UpconvertedCharacters(const StringView&amp;);
+    operator const UChar*() const { return m_characters; }
+    const UChar* get() const { return m_characters; }
</ins><span class="cx"> private:
</span><del>-    StringView m_stringView;
</del><ins>+    Vector&lt;UChar, 32&gt; m_upconvertedCharacters;
+    const UChar* m_characters;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-class StringView::CodeUnits {
-public:
-    class Iterator {
-    public:
-        Iterator(const StringView&amp;, unsigned index);
-        Iterator&amp; operator++();
-        UChar operator*() const;
-        bool operator==(const Iterator&amp;) const;
-        bool operator!=(const Iterator&amp;) const;
</del><ins>+inline StringView::UpconvertedCharacters StringView::upconvertedCharacters() const
+{
+    return UpconvertedCharacters(*this);
+}
</ins><span class="cx"> 
</span><del>-    private:
-        const StringView&amp; m_stringView;
-        unsigned m_index;
-    };
</del><ins>+inline bool StringView::isNull() const
+{
+    return !m_characters;
+}
</ins><span class="cx"> 
</span><del>-    explicit CodeUnits(const StringView&amp;);
-    Iterator begin() const;
-    Iterator end() const;
</del><ins>+inline bool StringView::isEmpty() const
+{
+    return !length();
+}
</ins><span class="cx"> 
</span><del>-private:
-    StringView m_stringView;
-};
</del><ins>+inline unsigned StringView::length() const
+{
+    return m_length &amp; ~is16BitStringFlag;
+}
</ins><span class="cx"> 
</span><ins>+inline StringView::operator bool() const
+{
+    return !isNull();
+}
+
+inline bool StringView::is8Bit() const
+{
+    return !(m_length &amp; is16BitStringFlag);
+}
+
+inline StringView StringView::substring(unsigned start, unsigned length) const
+{
+    if (start &gt;= this-&gt;length())
+        return empty();
+    unsigned maxLength = this-&gt;length() - start;
+
+    if (length &gt;= maxLength) {
+        if (!start)
+            return *this;
+        length = maxLength;
+    }
+
+    if (is8Bit()) {
+        StringView result(characters8() + start, length);
+        result.setUnderlyingString(*this);
+        return result;
+    }
+    StringView result(characters16() + start, length);
+    result.setUnderlyingString(*this);
+    return result;
+}
+
+inline UChar StringView::operator[](unsigned index) const
+{
+    ASSERT(index &lt; length());
+    if (is8Bit())
+        return characters8()[index];
+    return characters16()[index];
+}
+
+inline bool StringView::contains(UChar character) const
+{
+    return find(character) != notFound;
+}
+
</ins><span class="cx"> inline void StringView::getCharactersWithUpconvert(LChar* destination) const
</span><span class="cx"> {
</span><span class="cx">     ASSERT(is8Bit());
</span><span class="lines">@@ -291,7 +379,6 @@
</span><span class="cx"> {
</span><span class="cx">     if (is8Bit())
</span><span class="cx">         return String(characters8(), length());
</span><del>-
</del><span class="cx">     return String(characters16(), length());
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -313,7 +400,6 @@
</span><span class="cx"> {
</span><span class="cx">     if (is8Bit())
</span><span class="cx">         return StringImpl::createWithoutCopying(characters8(), length());
</span><del>-
</del><span class="cx">     return StringImpl::createWithoutCopying(characters16(), length());
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -324,6 +410,27 @@
</span><span class="cx">     return WTF::find(characters16(), length(), character, start);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if !CHECK_STRINGVIEW_LIFETIME
+
+inline void StringView::invalidate(const StringImpl&amp;)
+{
+}
+
+inline bool StringView::underlyingStringIsValid() const
+{
+    return true;
+}
+
+inline void StringView::setUnderlyingString(const StringImpl*)
+{
+}
+
+inline void StringView::setUnderlyingString(const StringView&amp;)
+{
+}
+
+#endif
+
</ins><span class="cx"> template&lt;typename StringType&gt; class StringTypeAdapter;
</span><span class="cx"> 
</span><span class="cx"> template&lt;&gt; class StringTypeAdapter&lt;StringView&gt; {
</span><span class="lines">@@ -349,6 +456,63 @@
</span><span class="cx">     string.getCharactersWithUpconvert(buffer.data() + oldSize);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+class StringView::CodePoints {
+public:
+    explicit CodePoints(const StringView&amp;);
+
+    class Iterator;
+    Iterator begin() const;
+    Iterator end() const;
+
+private:
+    StringView m_stringView;
+};
+
+class StringView::CodeUnits {
+public:
+    explicit CodeUnits(const StringView&amp;);
+
+    class Iterator;
+    Iterator begin() const;
+    Iterator end() const;
+
+private:
+    StringView m_stringView;
+};
+
+class StringView::CodePoints::Iterator {
+public:
+    Iterator(const StringView&amp;, unsigned index);
+
+    UChar32 operator*() const;
+    Iterator&amp; operator++();
+
+    bool operator==(const Iterator&amp;) const;
+    bool operator!=(const Iterator&amp;) const;
+
+private:
+    const StringView&amp; m_stringView;
+    mutable unsigned m_index;
+#if !ASSERT_DISABLED
+    mutable bool m_alreadyIncremented { false };
+#endif
+};
+
+class StringView::CodeUnits::Iterator {
+public:
+    Iterator(const StringView&amp;, unsigned index);
+
+    UChar operator*() const;
+    Iterator&amp; operator++();
+
+    bool operator==(const Iterator&amp;) const;
+    bool operator!=(const Iterator&amp;) const;
+
+private:
+    const StringView&amp; m_stringView;
+    unsigned m_index;
+};
+
</ins><span class="cx"> inline auto StringView::codePoints() const -&gt; CodePoints
</span><span class="cx"> {
</span><span class="cx">     return CodePoints(*this);
</span><span class="lines">@@ -367,9 +531,6 @@
</span><span class="cx"> inline StringView::CodePoints::Iterator::Iterator(const StringView&amp; stringView, unsigned index)
</span><span class="cx">     : m_stringView(stringView)
</span><span class="cx">     , m_index(index)
</span><del>-#if !ASSERT_DISABLED
-    , m_alreadyIncremented(false)
-#endif
</del><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (174387 => 174388)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-10-07 06:54:48 UTC (rev 174387)
+++ trunk/Source/WebCore/ChangeLog        2014-10-07 06:58:41 UTC (rev 174388)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2014-10-06  Darin Adler  &lt;darin@apple.com&gt;
+
+        Make StringView check the lifetime of the StringImpl it's created from
+        https://bugs.webkit.org/show_bug.cgi?id=137202
+
+        Reviewed by Anders Carlsson.
+
+        * platform/graphics/TextRun.cpp: Update since TextRun's definition now
+        uses a StringView.
+
</ins><span class="cx"> 2014-10-06  Andy Estes  &lt;aestes@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [iOS] Fix remaining misuses of abs() and fabsf()
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsTextRuncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/TextRun.cpp (174387 => 174388)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/TextRun.cpp        2014-10-07 06:54:48 UTC (rev 174387)
+++ trunk/Source/WebCore/platform/graphics/TextRun.cpp        2014-10-07 06:58:41 UTC (rev 174388)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2011 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2011, 2014 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">@@ -29,14 +29,14 @@
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> struct ExpectedTextRunSize {
</span><del>-    const void* pointer;
-    int integers[2];
</del><ins>+    void* renderingContext;
+    StringView text;
+    unsigned integer1;
+    unsigned integer2;
</ins><span class="cx">     float float1;
</span><span class="cx">     float float2;
</span><span class="cx">     float float3;
</span><del>-    uint32_t bitfields : 10;
-    unsigned anUnsigned;
-    RefPtr&lt;TextRun::RenderingContext&gt; renderingContext;
</del><ins>+    unsigned bitfields : 9;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> COMPILE_ASSERT(sizeof(TextRun) == sizeof(ExpectedTextRunSize), TextRun_is_not_of_expected_size);
</span></span></pre>
</div>
</div>

</body>
</html>