[prev in list] [next in list] [prev in thread] [next in thread] 

List:       webkit-changes
Subject:    [webkit-changes] [74600] trunk/JavaScriptCore
From:       barraclough () apple ! com
Date:       2010-12-24 1:40:58
Message-ID: 20101224014059.2136760AE76C () beta ! macosforge ! org
[Download RAW message or body]

[Attachment #2 (text/html)]

<!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>[74600] trunk/JavaScriptCore</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/74600">74600</a></dd> \
<dt>Author</dt> <dd>barraclough@apple.com</dd> <dt>Date</dt> <dd>2010-12-23 17:40:54 \
-0800 (Thu, 23 Dec 2010)</dd> </dl>

<h3>Log Message</h3>
<pre>Rename RegexCompiler.cpp to RegexPattern.cpp.
Implicitly call compileRegex from RegexPattern's constructor.

Reviewed by Sam Weinig.

* Android.mk:
* CMakeLists.txt:
* GNUmakefile.am:
* JavaScriptCore.gypi:
* JavaScriptCore.pro:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* runtime/RegExp.cpp:
(JSC::RegExp::compile):
* yarr/RegexCompiler.cpp: Removed.
* yarr/RegexCompiler.h: Removed.
* yarr/RegexInterpreter.cpp:
* yarr/RegexJIT.cpp:
* yarr/RegexPattern.cpp: Copied from JavaScriptCore/yarr/RegexCompiler.cpp.
(JSC::Yarr::compileRegex):
(JSC::Yarr::RegexPattern::RegexPattern):
* yarr/RegexPattern.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkJavaScriptCoreAndroidmk">trunk/JavaScriptCore/Android.mk</a></li>
<li><a href="#trunkJavaScriptCoreCMakeListstxt">trunk/JavaScriptCore/CMakeLists.txt</a></li>
 <li><a href="#trunkJavaScriptCoreChangeLog">trunk/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkJavaScriptCoreGNUmakefileam">trunk/JavaScriptCore/GNUmakefile.am</a></li>
 <li><a href="#trunkJavaScriptCoreJavaScriptCoregypi">trunk/JavaScriptCore/JavaScriptCore.gypi</a></li>
 <li><a href="#trunkJavaScriptCoreJavaScriptCorepro">trunk/JavaScriptCore/JavaScriptCore.pro</a></li>
 <li><a href="#trunkJavaScriptCoreJavaScriptCorevcprojJavaScriptCoreJavaScriptCorevcpr \
oj">trunk/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj</a></li>
 <li><a href="#trunkJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
 <li><a href="#trunkJavaScriptCoreruntimeRegExpcpp">trunk/JavaScriptCore/runtime/RegExp.cpp</a></li>
 <li><a href="#trunkJavaScriptCoreyarrRegexInterpretercpp">trunk/JavaScriptCore/yarr/RegexInterpreter.cpp</a></li>
 <li><a href="#trunkJavaScriptCoreyarrRegexJITcpp">trunk/JavaScriptCore/yarr/RegexJIT.cpp</a></li>
 <li><a href="#trunkJavaScriptCoreyarrRegexPatternh">trunk/JavaScriptCore/yarr/RegexPattern.h</a></li>
 </ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkJavaScriptCoreyarrRegexPatterncpp">trunk/JavaScriptCore/yarr/RegexPattern.cpp</a></li>
 </ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkJavaScriptCoreyarrRegexCompilercpp">trunk/JavaScriptCore/yarr/RegexCompiler.cpp</a></li>
 <li><a href="#trunkJavaScriptCoreyarrRegexCompilerh">trunk/JavaScriptCore/yarr/RegexCompiler.h</a></li>
 </ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkJavaScriptCoreAndroidmk"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/Android.mk (74599 => \
74600)</h4> <pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/Android.mk	2010-12-24 01:36:39 UTC (rev \
                74599)
+++ trunk/JavaScriptCore/Android.mk	2010-12-24 01:40:54 UTC (rev 74600)
</span><span class="lines">@@ -189,7 +189,7 @@
</span><span class="cx"> 	\
</span><span class="cx"> 	wtf/unicode/icu/CollatorICU.cpp \
</span><span class="cx"> 	\
</span><del>-	yarr/RegexCompiler.cpp \
</del><ins>+	yarr/RegexPattern.cpp \
</ins><span class="cx"> 	yarr/RegexInterpreter.cpp \
</span><span class="cx"> 	yarr/RegexJIT.cpp
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/CMakeLists.txt (74599 => \
74600)</h4> <pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/CMakeLists.txt	2010-12-24 01:36:39 UTC \
                (rev 74599)
+++ trunk/JavaScriptCore/CMakeLists.txt	2010-12-24 01:40:54 UTC (rev 74600)
</span><span class="lines">@@ -166,7 +166,7 @@
</span><span class="cx">     runtime/TimeoutChecker.cpp
</span><span class="cx">     runtime/UString.cpp
</span><span class="cx"> 
</span><del>-    yarr/RegexCompiler.cpp
</del><ins>+    yarr/RegexPattern.cpp
</ins><span class="cx">     yarr/RegexInterpreter.cpp
</span><span class="cx">     yarr/RegexJIT.cpp
</span><span class="cx"> 
</span><span class="lines">@@ -219,7 +219,7 @@
</span><span class="cx">     MAIN_DEPENDENCY \
${JAVASCRIPTCORE_DIR}/create_regex_tables </span><span class="cx">     COMMAND \
${PYTHON_EXECUTABLE} ${JAVASCRIPTCORE_DIR}/create_regex_tables &gt; \
${DERIVED_SOURCES_DIR}/RegExpJitTables.h </span><span class="cx">     VERBATIM)
</span><del>-ADD_SOURCE_DEPENDENCIES(${JAVASCRIPTCORE_DIR}/yarr/RegexCompiler.cpp \
${DERIVED_SOURCES_DIR}/RegExpJitTables.h) \
</del><ins>+ADD_SOURCE_DEPENDENCIES(${JAVASCRIPTCORE_DIR}/yarr/RegexPattern.cpp \
${DERIVED_SOURCES_DIR}/RegExpJitTables.h) </ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/ChangeLog (74599 => \
74600)</h4> <pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/ChangeLog	2010-12-24 01:36:39 UTC (rev \
                74599)
+++ trunk/JavaScriptCore/ChangeLog	2010-12-24 01:40:54 UTC (rev 74600)
</span><span class="lines">@@ -1,3 +1,28 @@
</span><ins>+2010-12-23  Gavin Barraclough  &lt;barraclough@apple.com&gt;
+
+        Reviewed by Sam Weinig.
+
+        Rename RegexCompiler.cpp to RegexPattern.cpp.
+        Implicitly call compileRegex from RegexPattern's constructor.
+
+        * Android.mk:
+        * CMakeLists.txt:
+        * GNUmakefile.am:
+        * JavaScriptCore.gypi:
+        * JavaScriptCore.pro:
+        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * runtime/RegExp.cpp:
+        (JSC::RegExp::compile):
+        * yarr/RegexCompiler.cpp: Removed.
+        * yarr/RegexCompiler.h: Removed.
+        * yarr/RegexInterpreter.cpp:
+        * yarr/RegexJIT.cpp:
+        * yarr/RegexPattern.cpp: Copied from JavaScriptCore/yarr/RegexCompiler.cpp.
+        (JSC::Yarr::compileRegex):
+        (JSC::Yarr::RegexPattern::RegexPattern):
+        * yarr/RegexPattern.h:
+
</ins><span class="cx"> 2010-12-23  Patrick Gansterer  &lt;paroga@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed build fix for WinCE after r74360.
</span></span></pre></div>
<a id="trunkJavaScriptCoreGNUmakefileam"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/GNUmakefile.am (74599 => \
74600)</h4> <pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/GNUmakefile.am	2010-12-24 01:36:39 UTC \
                (rev 74599)
+++ trunk/JavaScriptCore/GNUmakefile.am	2010-12-24 01:40:54 UTC (rev 74600)
</span><span class="lines">@@ -548,13 +548,12 @@
</span><span class="cx"> 	JavaScriptCore/wtf/VMTags.h \
</span><span class="cx"> 	JavaScriptCore/wtf/WTFThreadData.cpp \
</span><span class="cx"> 	JavaScriptCore/wtf/WTFThreadData.h \
</span><del>-	JavaScriptCore/yarr/RegexCompiler.cpp \
-	JavaScriptCore/yarr/RegexCompiler.h \
</del><span class="cx"> 	JavaScriptCore/yarr/RegexInterpreter.cpp \
</span><span class="cx"> 	JavaScriptCore/yarr/RegexInterpreter.h \
</span><span class="cx"> 	JavaScriptCore/yarr/RegexJIT.cpp \
</span><span class="cx"> 	JavaScriptCore/yarr/RegexJIT.h \
</span><span class="cx"> 	JavaScriptCore/yarr/RegexParser.h \
</span><ins>+	JavaScriptCore/yarr/RegexPattern.cpp \
</ins><span class="cx"> 	JavaScriptCore/yarr/RegexPattern.h
</span><span class="cx"> 
</span><span class="cx"> if TARGET_WIN32
</span></span></pre></div>
<a id="trunkJavaScriptCoreJavaScriptCoregypi"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/JavaScriptCore.gypi (74599 => \
74600)</h4> <pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/JavaScriptCore.gypi	2010-12-24 01:36:39 \
                UTC (rev 74599)
+++ trunk/JavaScriptCore/JavaScriptCore.gypi	2010-12-24 01:40:54 UTC (rev 74600)
</span><span class="lines">@@ -491,13 +491,12 @@
</span><span class="cx">             'wtf/win/MainThreadWin.cpp',
</span><span class="cx">             'wtf/win/OwnPtrWin.cpp',
</span><span class="cx">             'wtf/wx/MainThreadWx.cpp',
</span><del>-            'yarr/RegexCompiler.cpp',
-            'yarr/RegexCompiler.h',
</del><span class="cx">             'yarr/RegexInterpreter.cpp',
</span><span class="cx">             'yarr/RegexInterpreter.h',
</span><span class="cx">             'yarr/RegexJIT.cpp',
</span><span class="cx">             'yarr/RegexJIT.h',
</span><span class="cx">             'yarr/RegexParser.h',
</span><ins>+            'yarr/RegexPattern.cpp',
</ins><span class="cx">             'yarr/RegexPattern.h',
</span><span class="cx">         ]
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkJavaScriptCoreJavaScriptCorepro"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/JavaScriptCore.pro (74599 => \
74600)</h4> <pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/JavaScriptCore.pro	2010-12-24 01:36:39 \
                UTC (rev 74599)
+++ trunk/JavaScriptCore/JavaScriptCore.pro	2010-12-24 01:40:54 UTC (rev 74600)
</span><span class="lines">@@ -207,7 +207,7 @@
</span><span class="cx">     runtime/Structure.cpp \
</span><span class="cx">     runtime/TimeoutChecker.cpp \
</span><span class="cx">     runtime/UString.cpp \
</span><del>-    yarr/RegexCompiler.cpp \
</del><ins>+    yarr/RegexPattern.cpp \
</ins><span class="cx">     yarr/RegexInterpreter.cpp \
</span><span class="cx">     yarr/RegexJIT.cpp
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkJavaScriptCoreJavaScriptCorevcprojJavaScriptCoreJavaScriptCorevcproj"></a>
 <div class="modfile"><h4>Modified: \
trunk/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj \
(74599 => 74600)</h4> <pre class="diff"><span>
<span class="info">--- \
trunk/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj	2010-12-24 \
                01:36:39 UTC (rev 74599)
+++ trunk/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj	2010-12-24 \
01:40:54 UTC (rev 74600) </span><span class="lines">@@ -1652,14 +1652,6 @@
</span><span class="cx"> 			Name=&quot;yarr&quot;
</span><span class="cx"> 			&gt;
</span><span class="cx"> 			&lt;File
</span><del>-				RelativePath=&quot;..\..\yarr\RegexCompiler.cpp&quot;
-				&gt;
-			&lt;/File&gt;
-			&lt;File
-				RelativePath=&quot;..\..\yarr\RegexCompiler.h&quot;
-				&gt;
-			&lt;/File&gt;
-			&lt;File
</del><span class="cx"> 				RelativePath=&quot;..\..\yarr\RegexInterpreter.cpp&quot;
</span><span class="cx"> 				&gt;
</span><span class="cx"> 			&lt;/File&gt;
</span><span class="lines">@@ -1680,6 +1672,10 @@
</span><span class="cx"> 				&gt;
</span><span class="cx"> 			&lt;/File&gt;
</span><span class="cx"> 			&lt;File
</span><ins>+				RelativePath=&quot;..\..\yarr\RegexPattern.cpp&quot;
+				&gt;
+			&lt;/File&gt;
+			&lt;File
</ins><span class="cx"> 				RelativePath=&quot;..\..\yarr\RegexPattern.h&quot;
</span><span class="cx"> 				&gt;
</span><span class="cx"> 			&lt;/File&gt;
</span></span></pre></div>
<a id="trunkJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: \
trunk/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (74599 => 74600)</h4> \
<pre class="diff"><span> <span class="info">--- \
trunk/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj	2010-12-24 01:36:39 UTC \
                (rev 74599)
+++ trunk/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj	2010-12-24 01:40:54 \
UTC (rev 74600) </span><span class="lines">@@ -226,6 +226,7 @@
</span><span class="cx"> 		868BFA17117CF19900B908B1 /* WTFString.cpp in Sources */ = \
{isa = PBXBuildFile; fileRef = 868BFA15117CF19900B908B1 /* WTFString.cpp */; }; \
</span><span class="cx"> 		868BFA18117CF19900B908B1 /* WTFString.h in Headers */ = \
{isa = PBXBuildFile; fileRef = 868BFA16117CF19900B908B1 /* WTFString.h */; settings = \
{ATTRIBUTES = (Private, ); }; }; </span><span class="cx"> 		868BFA60117D048200B908B1 \
/* StaticConstructors.h in Headers */ = {isa = PBXBuildFile; fileRef = \
868BFA5F117D048200B908B1 /* StaticConstructors.h */; settings = {ATTRIBUTES = \
(Private, ); }; }; </span><ins>+		868D81A212C428CE0093DC84 /* RegexPattern.cpp in \
Sources */ = {isa = PBXBuildFile; fileRef = 868D81A112C428CE0093DC84 /* \
RegexPattern.cpp */; }; </ins><span class="cx"> 		8690231512092D5C00630AF9 /* \
PageReservation.h in Headers */ = {isa = PBXBuildFile; fileRef = \
8690231412092D5C00630AF9 /* PageReservation.h */; settings = {ATTRIBUTES = (Private, \
); }; }; </span><span class="cx"> 		869D04AF1193B54D00803475 /* \
CachedTranscendentalFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = \
869D04AE1193B54D00803475 /* CachedTranscendentalFunction.h */; settings = {ATTRIBUTES \
= (Private, ); }; }; </span><span class="cx"> 		869EBCB70E8C6D4A008722CC /* \
ResultType.h in Headers */ = {isa = PBXBuildFile; fileRef = 869EBCB60E8C6D4A008722CC \
/* ResultType.h */; settings = {ATTRIBUTES = (Private, ); }; }; </span><span \
class="lines">@@ -259,8 +260,6 @@ </span><span class="cx"> 		86DB64640F95C6FC00D7D921 \
/* ExecutableAllocatorFixedVMPool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = \
86DB64630F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp */; }; </span><span \
class="cx"> 		86E116B10FE75AC800B512BC /* CodeLocation.h in Headers */ = {isa = \
PBXBuildFile; fileRef = 86E116B00FE75AC800B512BC /* CodeLocation.h */; }; \
</span><span class="cx"> 		86E85539111B9968001AF51E /* JSStringBuilder.h in Headers \
*/ = {isa = PBXBuildFile; fileRef = 86E85538111B9968001AF51E /* JSStringBuilder.h */; \
}; </span><del>-		86EAC4950F93E8D1008EC948 /* RegexCompiler.cpp in Sources */ = {isa \
                = PBXBuildFile; fileRef = 86EAC48D0F93E8D1008EC948 /* \
                RegexCompiler.cpp */; };
-		86EAC4960F93E8D1008EC948 /* RegexCompiler.h in Headers */ = {isa = PBXBuildFile; \
fileRef = 86EAC48E0F93E8D1008EC948 /* RegexCompiler.h */; }; </del><span class="cx"> \
86EAC4970F93E8D1008EC948 /* RegexInterpreter.cpp in Sources */ = {isa = PBXBuildFile; \
fileRef = 86EAC48F0F93E8D1008EC948 /* RegexInterpreter.cpp */; }; </span><span \
class="cx"> 		86EAC4980F93E8D1008EC948 /* RegexInterpreter.h in Headers */ = {isa = \
PBXBuildFile; fileRef = 86EAC4900F93E8D1008EC948 /* RegexInterpreter.h */; }; \
</span><span class="cx"> 		86EAC4990F93E8D1008EC948 /* RegexJIT.cpp in Sources */ = \
{isa = PBXBuildFile; fileRef = 86EAC4910F93E8D1008EC948 /* RegexJIT.cpp */; }; \
</span><span class="lines">@@ -845,6 +844,7 @@ </span><span class="cx"> \
868BFA15117CF19900B908B1 /* WTFString.cpp */ = {isa = PBXFileReference; fileEncoding \
= 4; lastKnownFileType = sourcecode.cpp.cpp; name = WTFString.cpp; path = \
text/WTFString.cpp; sourceTree = &quot;&lt;group&gt;&quot;; }; </span><span \
class="cx"> 		868BFA16117CF19900B908B1 /* WTFString.h */ = {isa = PBXFileReference; \
fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WTFString.h; path = \
text/WTFString.h; sourceTree = &quot;&lt;group&gt;&quot;; }; </span><span class="cx"> \
868BFA5F117D048200B908B1 /* StaticConstructors.h */ = {isa = PBXFileReference; \
fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StaticConstructors.h; \
sourceTree = &quot;&lt;group&gt;&quot;; }; </span><ins>+		868D81A112C428CE0093DC84 /* \
RegexPattern.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = \
sourcecode.cpp.cpp; name = RegexPattern.cpp; path = yarr/RegexPattern.cpp; sourceTree \
= &quot;&lt;group&gt;&quot;; }; </ins><span class="cx"> 		8690231412092D5C00630AF9 /* \
PageReservation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = \
sourcecode.c.h; path = PageReservation.h; sourceTree = &quot;&lt;group&gt;&quot;; }; \
</span><span class="cx"> 		869D04AE1193B54D00803475 /* CachedTranscendentalFunction.h \
*/ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; \
path = CachedTranscendentalFunction.h; sourceTree = &quot;&lt;group&gt;&quot;; }; \
</span><span class="cx"> 		869EBCB60E8C6D4A008722CC /* ResultType.h */ = {isa = \
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \
ResultType.h; sourceTree = &quot;&lt;group&gt;&quot;; }; </span><span \
class="lines">@@ -878,8 +878,6 @@ </span><span class="cx"> 		86DB64630F95C6FC00D7D921 \
/* ExecutableAllocatorFixedVMPool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; \
lastKnownFileType = sourcecode.cpp.cpp; path = ExecutableAllocatorFixedVMPool.cpp; \
sourceTree = &quot;&lt;group&gt;&quot;; }; </span><span class="cx"> \
86E116B00FE75AC800B512BC /* CodeLocation.h */ = {isa = PBXFileReference; fileEncoding \
= 4; lastKnownFileType = sourcecode.c.h; path = CodeLocation.h; sourceTree = \
&quot;&lt;group&gt;&quot;; }; </span><span class="cx"> 		86E85538111B9968001AF51E /* \
JSStringBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = \
sourcecode.c.h; path = JSStringBuilder.h; sourceTree = &quot;&lt;group&gt;&quot;; }; \
</span><del>-		86EAC48D0F93E8D1008EC948 /* RegexCompiler.cpp */ = {isa = \
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = \
RegexCompiler.cpp; path = yarr/RegexCompiler.cpp; sourceTree = \
                &quot;&lt;group&gt;&quot;; };
-		86EAC48E0F93E8D1008EC948 /* RegexCompiler.h */ = {isa = PBXFileReference; \
fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegexCompiler.h; path = \
yarr/RegexCompiler.h; sourceTree = &quot;&lt;group&gt;&quot;; }; </del><span \
class="cx"> 		86EAC48F0F93E8D1008EC948 /* RegexInterpreter.cpp */ = {isa = \
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = \
RegexInterpreter.cpp; path = yarr/RegexInterpreter.cpp; sourceTree = \
&quot;&lt;group&gt;&quot;; }; </span><span class="cx"> 		86EAC4900F93E8D1008EC948 /* \
RegexInterpreter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType \
= sourcecode.c.h; name = RegexInterpreter.h; path = yarr/RegexInterpreter.h; \
sourceTree = &quot;&lt;group&gt;&quot;; }; </span><span class="cx"> \
86EAC4910F93E8D1008EC948 /* RegexJIT.cpp */ = {isa = PBXFileReference; fileEncoding = \
4; lastKnownFileType = sourcecode.cpp.cpp; name = RegexJIT.cpp; path = \
yarr/RegexJIT.cpp; sourceTree = &quot;&lt;group&gt;&quot;; }; </span><span \
class="lines">@@ -1892,14 +1890,13 @@ </span><span class="cx"> \
86EAC48C0F93E8B9008EC948 /* yarr */ = { </span><span class="cx"> 			isa = PBXGroup;
</span><span class="cx"> 			children = (
</span><del>-				86EAC48D0F93E8D1008EC948 /* RegexCompiler.cpp */,
-				86EAC48E0F93E8D1008EC948 /* RegexCompiler.h */,
</del><span class="cx"> 				86EAC48F0F93E8D1008EC948 /* RegexInterpreter.cpp */,
</span><span class="cx"> 				86EAC4900F93E8D1008EC948 /* RegexInterpreter.h */,
</span><span class="cx"> 				86EAC4910F93E8D1008EC948 /* RegexJIT.cpp */,
</span><span class="cx"> 				86EAC4920F93E8D1008EC948 /* RegexJIT.h */,
</span><span class="cx"> 				86EAC4930F93E8D1008EC948 /* RegexParser.h */,
</span><span class="cx"> 				86EAC4940F93E8D1008EC948 /* RegexPattern.h */,
</span><ins>+				868D81A112C428CE0093DC84 /* RegexPattern.cpp */,
</ins><span class="cx"> 			);
</span><span class="cx"> 			name = yarr;
</span><span class="cx"> 			sourceTree = &quot;&lt;group&gt;&quot;;
</span><span class="lines">@@ -2275,7 +2272,6 @@
</span><span class="cx"> 				90D3469C0E285280009492EE /* RefCountedLeakCounter.h in \
Headers */, </span><span class="cx"> 				BC18C4580E16F5CD00B34460 /* RefPtr.h in \
Headers */, </span><span class="cx"> 				BC18C4590E16F5CD00B34460 /* RefPtrHashMap.h \
in Headers */, </span><del>-				86EAC4960F93E8D1008EC948 /* RegexCompiler.h in \
Headers */, </del><span class="cx"> 				86EAC4980F93E8D1008EC948 /* \
RegexInterpreter.h in Headers */, </span><span class="cx"> \
86EAC49A0F93E8D1008EC948 /* RegexJIT.h in Headers */, </span><span class="cx"> \
BC18C45A0E16F5CD00B34460 /* RegExp.h in Headers */, </span><span class="lines">@@ \
-2800,13 +2796,13 @@ </span><span class="cx"> 				14469DE9107EC7E700650446 /* \
PrototypeFunction.cpp in Sources */, </span><span class="cx"> \
088FA5BB0EF76D4300578E6F /* RandomNumber.cpp in Sources */, </span><span class="cx"> \
905B02AE0E28640F006DF882 /* RefCountedLeakCounter.cpp in Sources */, \
</span><del>-				86EAC4950F93E8D1008EC948 /* RegexCompiler.cpp in Sources */, \
</del><span class="cx"> 				86EAC4970F93E8D1008EC948 /* RegexInterpreter.cpp in \
Sources */, </span><span class="cx"> 				86EAC4990F93E8D1008EC948 /* RegexJIT.cpp in \
Sources */, </span><span class="cx"> 				14280841107EC0930013E7B2 /* RegExp.cpp in \
Sources */, </span><span class="cx"> 				A1712B3B11C7B212007A5315 /* RegExpCache.cpp \
in Sources */, </span><span class="cx"> 				14280842107EC0930013E7B2 /* \
RegExpConstructor.cpp in Sources */, </span><span class="cx"> \
14280843107EC0930013E7B2 /* RegExpObject.cpp in Sources */, \
</span><ins>+				868D81A212C428CE0093DC84 /* RegexPattern.cpp in Sources */, \
</ins><span class="cx"> 				14280844107EC0930013E7B2 /* RegExpPrototype.cpp in \
Sources */, </span><span class="cx"> 				1428083A107EC0750013E7B2 /* RegisterFile.cpp \
in Sources */, </span><span class="cx"> 				86B99AB8117E391E00DF5A90 /* RopeImpl.cpp \
in Sources */, </span></span></pre></div>
<a id="trunkJavaScriptCoreruntimeRegExpcpp"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/runtime/RegExp.cpp (74599 => \
74600)</h4> <pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/runtime/RegExp.cpp	2010-12-24 01:36:39 \
                UTC (rev 74599)
+++ trunk/JavaScriptCore/runtime/RegExp.cpp	2010-12-24 01:40:54 UTC (rev 74600)
</span><span class="lines">@@ -29,7 +29,6 @@
</span><span class="cx"> #include &lt;wtf/Assertions.h&gt;
</span><span class="cx"> #include &lt;wtf/OwnArrayPtr.h&gt;
</span><span class="cx"> 
</span><del>-#include &quot;yarr/RegexCompiler.h&quot;
</del><span class="cx"> #include &quot;yarr/RegexJIT.h&quot;
</span><span class="cx"> #include &quot;yarr/RegexInterpreter.h&quot;
</span><span class="cx"> #include &quot;yarr/RegexPattern.h&quot;
</span><span class="lines">@@ -83,9 +82,8 @@
</span><span class="cx"> 
</span><span class="cx"> RegExp::RegExpState RegExp::compile(JSGlobalData* \
globalData) </span><span class="cx"> {
</span><del>-    Yarr::RegexPattern pattern(ignoreCase(), multiline());
-
-    if ((m_constructionError = Yarr::compileRegex(m_patternString, pattern)))
</del><ins>+    Yarr::RegexPattern pattern(m_patternString, ignoreCase(), \
multiline(), &amp;m_constructionError); +    if (m_constructionError)
</ins><span class="cx">         return ParseError;
</span><span class="cx"> 
</span><span class="cx">     m_numSubpatterns = pattern.m_numSubpatterns;
</span></span></pre></div>
<a id="trunkJavaScriptCoreyarrRegexCompilercpp"></a>
<div class="delfile"><h4>Deleted: trunk/JavaScriptCore/yarr/RegexCompiler.cpp (74599 \
=> 74600)</h4> <pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/yarr/RegexCompiler.cpp	2010-12-24 \
                01:36:39 UTC (rev 74599)
+++ trunk/JavaScriptCore/yarr/RegexCompiler.cpp	2010-12-24 01:40:54 UTC (rev 74600)
</span><span class="lines">@@ -1,974 +0,0 @@
</span><del>-/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
- * Copyright (C) 2010 Peter Varga (pvarga@inf.u-szeged.hu), University of Szeged
- *
- * 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. ``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
- * 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;RegexCompiler.h&quot;
-
-#include &quot;RegexInterpreter.h&quot;
-#include &quot;RegexPattern.h&quot;
-#include &lt;wtf/Vector.h&gt;
-
-using namespace WTF;
-
-namespace JSC { namespace Yarr {
-
-#include &quot;RegExpJitTables.h&quot;
-
-class CharacterClassConstructor {
-public:
-    CharacterClassConstructor(bool isCaseInsensitive = false)
-        : m_isCaseInsensitive(isCaseInsensitive)
-    {
-    }
-    
-    void reset()
-    {
-        m_matches.clear();
-        m_ranges.clear();
-        m_matchesUnicode.clear();
-        m_rangesUnicode.clear();
-    }
-
-    void append(const CharacterClass* other)
-    {
-        for (size_t i = 0; i &lt; other-&gt;m_matches.size(); ++i)
-            addSorted(m_matches, other-&gt;m_matches[i]);
-        for (size_t i = 0; i &lt; other-&gt;m_ranges.size(); ++i)
-            addSortedRange(m_ranges, other-&gt;m_ranges[i].begin, \
                other-&gt;m_ranges[i].end);
-        for (size_t i = 0; i &lt; other-&gt;m_matchesUnicode.size(); ++i)
-            addSorted(m_matchesUnicode, other-&gt;m_matchesUnicode[i]);
-        for (size_t i = 0; i &lt; other-&gt;m_rangesUnicode.size(); ++i)
-            addSortedRange(m_rangesUnicode, other-&gt;m_rangesUnicode[i].begin, \
                other-&gt;m_rangesUnicode[i].end);
-    }
-
-    void putChar(UChar ch)
-    {
-        if (ch &lt;= 0x7f) {
-            if (m_isCaseInsensitive &amp;&amp; isASCIIAlpha(ch)) {
-                addSorted(m_matches, toASCIIUpper(ch));
-                addSorted(m_matches, toASCIILower(ch));
-            } else
-                addSorted(m_matches, ch);
-        } else {
-            UChar upper, lower;
-            if (m_isCaseInsensitive &amp;&amp; ((upper = Unicode::toUpper(ch)) != \
                (lower = Unicode::toLower(ch)))) {
-                addSorted(m_matchesUnicode, upper);
-                addSorted(m_matchesUnicode, lower);
-            } else
-                addSorted(m_matchesUnicode, ch);
-        }
-    }
-
-    // returns true if this character has another case, and 'ch' is the upper case \
                form.
-    static inline bool isUnicodeUpper(UChar ch)
-    {
-        return ch != Unicode::toLower(ch);
-    }
-
-    // returns true if this character has another case, and 'ch' is the lower case \
                form.
-    static inline bool isUnicodeLower(UChar ch)
-    {
-        return ch != Unicode::toUpper(ch);
-    }
-
-    void putRange(UChar lo, UChar hi)
-    {
-        if (lo &lt;= 0x7f) {
-            char asciiLo = lo;
-            char asciiHi = std::min(hi, (UChar)0x7f);
-            addSortedRange(m_ranges, lo, asciiHi);
-            
-            if (m_isCaseInsensitive) {
-                if ((asciiLo &lt;= 'Z') &amp;&amp; (asciiHi &gt;= 'A'))
-                    addSortedRange(m_ranges, std::max(asciiLo, 'A')+('a'-'A'), \
                std::min(asciiHi, 'Z')+('a'-'A'));
-                if ((asciiLo &lt;= 'z') &amp;&amp; (asciiHi &gt;= 'a'))
-                    addSortedRange(m_ranges, std::max(asciiLo, 'a')+('A'-'a'), \
                std::min(asciiHi, 'z')+('A'-'a'));
-            }
-        }
-        if (hi &gt;= 0x80) {
-            uint32_t unicodeCurr = std::max(lo, (UChar)0x80);
-            addSortedRange(m_rangesUnicode, unicodeCurr, hi);
-            
-            if (m_isCaseInsensitive) {
-                while (unicodeCurr &lt;= hi) {
-                    // If the upper bound of the range (hi) is 0xffff, the \
                increments to
-                    // unicodeCurr in this loop may take it to 0x10000.  This is \
                fine
-                    // (if so we won't re-enter the loop, since the loop condition \
                above
-                    // will definitely fail) - but this does mean we cannot use a \
                UChar
-                    // to represent unicodeCurr, we must use a 32-bit value instead.
-                    ASSERT(unicodeCurr &lt;= 0xffff);
-
-                    if (isUnicodeUpper(unicodeCurr)) {
-                        UChar lowerCaseRangeBegin = Unicode::toLower(unicodeCurr);
-                        UChar lowerCaseRangeEnd = lowerCaseRangeBegin;
-                        while ((++unicodeCurr &lt;= hi) &amp;&amp; \
isUnicodeUpper(unicodeCurr) &amp;&amp; (Unicode::toLower(unicodeCurr) == \
                (lowerCaseRangeEnd + 1)))
-                            lowerCaseRangeEnd++;
-                        addSortedRange(m_rangesUnicode, lowerCaseRangeBegin, \
                lowerCaseRangeEnd);
-                    } else if (isUnicodeLower(unicodeCurr)) {
-                        UChar upperCaseRangeBegin = Unicode::toUpper(unicodeCurr);
-                        UChar upperCaseRangeEnd = upperCaseRangeBegin;
-                        while ((++unicodeCurr &lt;= hi) &amp;&amp; \
isUnicodeLower(unicodeCurr) &amp;&amp; (Unicode::toUpper(unicodeCurr) == \
                (upperCaseRangeEnd + 1)))
-                            upperCaseRangeEnd++;
-                        addSortedRange(m_rangesUnicode, upperCaseRangeBegin, \
                upperCaseRangeEnd);
-                    } else
-                        ++unicodeCurr;
-                }
-            }
-        }
-    }
-
-    CharacterClass* charClass()
-    {
-        CharacterClass* characterClass = new CharacterClass(0);
-
-        characterClass-&gt;m_matches.append(m_matches);
-        characterClass-&gt;m_ranges.append(m_ranges);
-        characterClass-&gt;m_matchesUnicode.append(m_matchesUnicode);
-        characterClass-&gt;m_rangesUnicode.append(m_rangesUnicode);
-
-        reset();
-
-        return characterClass;
-    }
-
-private:
-    void addSorted(Vector&lt;UChar&gt;&amp; matches, UChar ch)
-    {
-        unsigned pos = 0;
-        unsigned range = matches.size();
-
-        // binary chop, find position to insert char.
-        while (range) {
-            unsigned index = range &gt;&gt; 1;
-
-            int val = matches[pos+index] - ch;
-            if (!val)
-                return;
-            else if (val &gt; 0)
-                range = index;
-            else {
-                pos += (index+1);
-                range -= (index+1);
-            }
-        }
-        
-        if (pos == matches.size())
-            matches.append(ch);
-        else
-            matches.insert(pos, ch);
-    }
-
-    void addSortedRange(Vector&lt;CharacterRange&gt;&amp; ranges, UChar lo, UChar \
                hi)
-    {
-        unsigned end = ranges.size();
-        
-        // Simple linear scan - I doubt there are that many ranges anyway...
-        // feel free to fix this with something faster (eg binary chop).
-        for (unsigned i = 0; i &lt; end; ++i) {
-            // does the new range fall before the current position in the array
-            if (hi &lt; ranges[i].begin) {
-                // optional optimization: concatenate appending ranges? - may not be \
                worthwhile.
-                if (hi == (ranges[i].begin - 1)) {
-                    ranges[i].begin = lo;
-                    return;
-                }
-                ranges.insert(i, CharacterRange(lo, hi));
-                return;
-            }
-            // Okay, since we didn't hit the last case, the end of the new range is \
                definitely at or after the begining
-            // If the new range start at or before the end of the last range, then \
                the overlap (if it starts one after the
-            // end of the last range they concatenate, which is just as good.
-            if (lo &lt;= (ranges[i].end + 1)) {
-                // found an intersect! we'll replace this entry in the array.
-                ranges[i].begin = std::min(ranges[i].begin, lo);
-                ranges[i].end = std::max(ranges[i].end, hi);
-
-                // now check if the new range can subsume any subsequent ranges.
-                unsigned next = i+1;
-                // each iteration of the loop we will either remove something from \
                the list, or break the loop.
-                while (next &lt; ranges.size()) {
-                    if (ranges[next].begin &lt;= (ranges[i].end + 1)) {
-                        // the next entry now overlaps / concatenates this one.
-                        ranges[i].end = std::max(ranges[i].end, ranges[next].end);
-                        ranges.remove(next);
-                    } else
-                        break;
-                }
-                
-                return;
-            }
-        }
-
-        // CharacterRange comes after all existing ranges.
-        ranges.append(CharacterRange(lo, hi));
-    }
-
-    bool m_isCaseInsensitive;
-
-    Vector&lt;UChar&gt; m_matches;
-    Vector&lt;CharacterRange&gt; m_ranges;
-    Vector&lt;UChar&gt; m_matchesUnicode;
-    Vector&lt;CharacterRange&gt; m_rangesUnicode;
-};
-
-struct BeginCharHelper {
-    BeginCharHelper(Vector&lt;BeginChar&gt;* beginChars, bool isCaseInsensitive = \
                false)
-        : m_beginChars(beginChars)
-        , m_isCaseInsensitive(isCaseInsensitive)
-    {}
-
-    void addBeginChar(BeginChar beginChar, Vector&lt;TermChain&gt;* hotTerms, \
                QuantifierType quantityType, unsigned quantityCount)
-    {
-        if (quantityType == QuantifierFixedCount &amp;&amp; quantityCount &gt; 1) {
-            // We duplicate the first found character if the quantity of the term is \
                more than one. eg.: /a{3}/
-            beginChar.value |= beginChar.value &lt;&lt; 16;
-            beginChar.mask |= beginChar.mask &lt;&lt; 16;
-            addCharacter(beginChar);
-        } else if (quantityType == QuantifierFixedCount &amp;&amp; quantityCount == \
                1 &amp;&amp; hotTerms-&gt;size())
-            // In case of characters with fixed quantifier we should check the next \
                character as well.
-            linkHotTerms(beginChar, hotTerms);
-        else
-            // In case of greedy matching the next character checking is unnecessary \
                therefore we just store
-            // the first character.
-            addCharacter(beginChar);
-    }
-
-    // Merge two following BeginChars in the vector to reduce the number of \
                character checks.
-    void merge(unsigned size)
-    {
-        for (unsigned i = 0; i &lt; size; i++) {
-            BeginChar* curr = &amp;m_beginChars-&gt;at(i);
-            BeginChar* next = &amp;m_beginChars-&gt;at(i + 1);
-
-            // If the current and the next size of value is different we should skip \
                the merge process
-            // because the 16bit and 32bit values are unmergable.
-            if (curr-&gt;value &lt;= 0xFFFF &amp;&amp; next-&gt;value &gt; 0xFFFF)
-                continue;
-
-            unsigned diff = curr-&gt;value ^ next-&gt;value;
-
-            curr-&gt;mask |= diff;
-            curr-&gt;value |= curr-&gt;mask;
-
-            m_beginChars-&gt;remove(i + 1);
-            size--;
-        }
-    }
-
-private:
-    void addCharacter(BeginChar beginChar)
-    {
-        unsigned pos = 0;
-        unsigned range = m_beginChars-&gt;size();
-
-        // binary chop, find position to insert char.
-        while (range) {
-            unsigned index = range &gt;&gt; 1;
-
-            int val = m_beginChars-&gt;at(pos+index).value - beginChar.value;
-            if (!val)
-                return;
-            if (val &lt; 0)
-                range = index;
-            else {
-                pos += (index+1);
-                range -= (index+1);
-            }
-        }
-
-        if (pos == m_beginChars-&gt;size())
-            m_beginChars-&gt;append(beginChar);
-        else
-            m_beginChars-&gt;insert(pos, beginChar);
-    }
-
-    // Create BeginChar objects by appending each terms from a hotTerms vector to an \
                existing BeginChar object.
-    void linkHotTerms(BeginChar beginChar, Vector&lt;TermChain&gt;* hotTerms)
-    {
-        for (unsigned i = 0; i &lt; hotTerms-&gt;size(); i++) {
-            PatternTerm hotTerm = hotTerms-&gt;at(i).term;
-            ASSERT(hotTerm.type == PatternTerm::TypePatternCharacter);
-
-            UChar characterNext = hotTerm.patternCharacter;
-
-            // Append a character to an existing BeginChar object.
-            if (characterNext &lt;= 0x7f) {
-                unsigned mask = 0;
-
-                if (m_isCaseInsensitive &amp;&amp; isASCIIAlpha(characterNext)) {
-                    mask = 32;
-                    characterNext = toASCIILower(characterNext);
-                }
-
-                addCharacter(BeginChar(beginChar.value | (characterNext &lt;&lt; \
                16), beginChar.mask | (mask &lt;&lt; 16)));
-            } else {
-                UChar upper, lower;
-                if (m_isCaseInsensitive &amp;&amp; ((upper = \
                Unicode::toUpper(characterNext)) != (lower = \
                Unicode::toLower(characterNext)))) {
-                    addCharacter(BeginChar(beginChar.value | (upper &lt;&lt; 16), \
                beginChar.mask));
-                    addCharacter(BeginChar(beginChar.value | (lower &lt;&lt; 16), \
                beginChar.mask));
-                } else
-                    addCharacter(BeginChar(beginChar.value | (characterNext &lt;&lt; \
                16), beginChar.mask));
-            }
-        }
-    }
-
-    Vector&lt;BeginChar&gt;* m_beginChars;
-    bool m_isCaseInsensitive;
-};
-
-class RegexPatternConstructor {
-public:
-    RegexPatternConstructor(RegexPattern&amp; pattern)
-        : m_pattern(pattern)
-        , m_characterClassConstructor(pattern.m_ignoreCase)
-        , m_beginCharHelper(&amp;pattern.m_beginChars, pattern.m_ignoreCase)
-        , m_invertParentheticalAssertion(false)
-    {
-    }
-
-    ~RegexPatternConstructor()
-    {
-    }
-
-    void reset()
-    {
-        m_pattern.reset();
-        m_characterClassConstructor.reset();
-    }
-    
-    void assertionBOL()
-    {
-        if (!m_alternative-&gt;m_terms.size() &amp; !m_invertParentheticalAssertion) \
                {
-            m_alternative-&gt;m_startsWithBOL = true;
-            m_alternative-&gt;m_containsBOL = true;
-            m_pattern.m_containsBOL = true;
-        }
-        m_alternative-&gt;m_terms.append(PatternTerm::BOL());
-    }
-    void assertionEOL()
-    {
-        m_alternative-&gt;m_terms.append(PatternTerm::EOL());
-    }
-    void assertionWordBoundary(bool invert)
-    {
-        m_alternative-&gt;m_terms.append(PatternTerm::WordBoundary(invert));
-    }
-
-    void atomPatternCharacter(UChar ch)
-    {
-        // We handle case-insensitive checking of unicode characters which do have \
                both
-        // cases by handling them as if they were defined using a CharacterClass.
-        if (m_pattern.m_ignoreCase &amp;&amp; !isASCII(ch) &amp;&amp; \
                (Unicode::toUpper(ch) != Unicode::toLower(ch))) {
-            atomCharacterClassBegin();
-            atomCharacterClassAtom(ch);
-            atomCharacterClassEnd();
-        } else
-            m_alternative-&gt;m_terms.append(PatternTerm(ch));
-    }
-
-    void atomBuiltInCharacterClass(BuiltInCharacterClassID classID, bool invert)
-    {
-        switch (classID) {
-        case DigitClassID:
-            m_alternative-&gt;m_terms.append(PatternTerm(m_pattern.digitsCharacterClass(), \
                invert));
-            break;
-        case SpaceClassID:
-            m_alternative-&gt;m_terms.append(PatternTerm(m_pattern.spacesCharacterClass(), \
                invert));
-            break;
-        case WordClassID:
-            m_alternative-&gt;m_terms.append(PatternTerm(m_pattern.wordcharCharacterClass(), \
                invert));
-            break;
-        case NewlineClassID:
-            m_alternative-&gt;m_terms.append(PatternTerm(m_pattern.newlineCharacterClass(), \
                invert));
-            break;
-        }
-    }
-
-    void atomCharacterClassBegin(bool invert = false)
-    {
-        m_invertCharacterClass = invert;
-    }
-
-    void atomCharacterClassAtom(UChar ch)
-    {
-        m_characterClassConstructor.putChar(ch);
-    }
-
-    void atomCharacterClassRange(UChar begin, UChar end)
-    {
-        m_characterClassConstructor.putRange(begin, end);
-    }
-
-    void atomCharacterClassBuiltIn(BuiltInCharacterClassID classID, bool invert)
-    {
-        ASSERT(classID != NewlineClassID);
-
-        switch (classID) {
-        case DigitClassID:
-            m_characterClassConstructor.append(invert ? \
                m_pattern.nondigitsCharacterClass() : \
                m_pattern.digitsCharacterClass());
-            break;
-        
-        case SpaceClassID:
-            m_characterClassConstructor.append(invert ? \
                m_pattern.nonspacesCharacterClass() : \
                m_pattern.spacesCharacterClass());
-            break;
-        
-        case WordClassID:
-            m_characterClassConstructor.append(invert ? \
                m_pattern.nonwordcharCharacterClass() : \
                m_pattern.wordcharCharacterClass());
-            break;
-        
-        default:
-            ASSERT_NOT_REACHED();
-        }
-    }
-
-    void atomCharacterClassEnd()
-    {
-        CharacterClass* newCharacterClass = m_characterClassConstructor.charClass();
-        m_pattern.m_userCharacterClasses.append(newCharacterClass);
-        m_alternative-&gt;m_terms.append(PatternTerm(newCharacterClass, \
                m_invertCharacterClass));
-    }
-
-    void atomParenthesesSubpatternBegin(bool capture = true)
-    {
-        unsigned subpatternId = m_pattern.m_numSubpatterns + 1;
-        if (capture)
-            m_pattern.m_numSubpatterns++;
-
-        PatternDisjunction* parenthesesDisjunction = new \
                PatternDisjunction(m_alternative);
-        m_pattern.m_disjunctions.append(parenthesesDisjunction);
-        m_alternative-&gt;m_terms.append(PatternTerm(PatternTerm::TypeParenthesesSubpattern, \
                subpatternId, parenthesesDisjunction, capture, false));
-        m_alternative = parenthesesDisjunction-&gt;addNewAlternative();
-    }
-
-    void atomParentheticalAssertionBegin(bool invert = false)
-    {
-        PatternDisjunction* parenthesesDisjunction = new \
                PatternDisjunction(m_alternative);
-        m_pattern.m_disjunctions.append(parenthesesDisjunction);
-        m_alternative-&gt;m_terms.append(PatternTerm(PatternTerm::TypeParentheticalAssertion, \
                m_pattern.m_numSubpatterns + 1, parenthesesDisjunction, false, \
                invert));
-        m_alternative = parenthesesDisjunction-&gt;addNewAlternative();
-        m_invertParentheticalAssertion = invert;
-    }
-
-    void atomParenthesesEnd()
-    {
-        ASSERT(m_alternative-&gt;m_parent);
-        ASSERT(m_alternative-&gt;m_parent-&gt;m_parent);
-
-        PatternDisjunction* parenthesesDisjunction = m_alternative-&gt;m_parent;
-        m_alternative = m_alternative-&gt;m_parent-&gt;m_parent;
-
-        PatternTerm&amp; lastTerm = m_alternative-&gt;lastTerm();
-        
-        unsigned numParenAlternatives = \
                parenthesesDisjunction-&gt;m_alternatives.size();
-        unsigned numBOLAnchoredAlts = 0;
-        // Bubble up BOL flags
-        for (unsigned i = 0; i &lt; numParenAlternatives; i++) {
-            if (parenthesesDisjunction-&gt;m_alternatives[i]-&gt;m_startsWithBOL)
-                numBOLAnchoredAlts++;
-        }
-        
-        if (numBOLAnchoredAlts) {
-            m_alternative-&gt;m_containsBOL = true;
-            // If all the alternatives in parens start with BOL, then so does this \
                one
-            if (numBOLAnchoredAlts == numParenAlternatives)
-                m_alternative-&gt;m_startsWithBOL = true;
-        }
-        
-        lastTerm.parentheses.lastSubpatternId = m_pattern.m_numSubpatterns;
-        m_invertParentheticalAssertion = false;
-    }
-
-    void atomBackReference(unsigned subpatternId)
-    {
-        ASSERT(subpatternId);
-        m_pattern.m_containsBackreferences = true;
-        m_pattern.m_maxBackReference = std::max(m_pattern.m_maxBackReference, \
                subpatternId);
-
-        if (subpatternId &gt; m_pattern.m_numSubpatterns) {
-            m_alternative-&gt;m_terms.append(PatternTerm::ForwardReference());
-            return;
-        }
-
-        PatternAlternative* currentAlternative = m_alternative;
-        ASSERT(currentAlternative);
-
-        // Note to self: if we waited until the AST was baked, we could also remove \
                forwards refs 
-        while ((currentAlternative = currentAlternative-&gt;m_parent-&gt;m_parent)) \
                {
-            PatternTerm&amp; term = currentAlternative-&gt;lastTerm();
-            ASSERT((term.type == PatternTerm::TypeParenthesesSubpattern) || \
                (term.type == PatternTerm::TypeParentheticalAssertion));
-
-            if ((term.type == PatternTerm::TypeParenthesesSubpattern) &amp;&amp; \
                term.capture() &amp;&amp; (subpatternId == \
                term.parentheses.subpatternId)) {
-                m_alternative-&gt;m_terms.append(PatternTerm::ForwardReference());
-                return;
-            }
-        }
-
-        m_alternative-&gt;m_terms.append(PatternTerm(subpatternId));
-    }
-
-    // deep copy the argument disjunction.  If filterStartsWithBOL is true, 
-    // skip alternatives with m_startsWithBOL set true.
-    PatternDisjunction* copyDisjunction(PatternDisjunction* disjunction, bool \
                filterStartsWithBOL = false)
-    {
-        PatternDisjunction* newDisjunction = 0;
-        for (unsigned alt = 0; alt &lt; disjunction-&gt;m_alternatives.size(); \
                ++alt) {
-            PatternAlternative* alternative = disjunction-&gt;m_alternatives[alt];
-            if (!filterStartsWithBOL || !alternative-&gt;m_startsWithBOL) {
-                if (!newDisjunction) {
-                    newDisjunction = new PatternDisjunction();
-                    newDisjunction-&gt;m_parent = disjunction-&gt;m_parent;
-                }
-                PatternAlternative* newAlternative = \
                newDisjunction-&gt;addNewAlternative();
-                for (unsigned i = 0; i &lt; alternative-&gt;m_terms.size(); ++i)
-                    \
newAlternative-&gt;m_terms.append(copyTerm(alternative-&gt;m_terms[i], \
                filterStartsWithBOL));
-            }
-        }
-        
-        if (newDisjunction)
-            m_pattern.m_disjunctions.append(newDisjunction);
-        return newDisjunction;
-    }
-    
-    PatternTerm copyTerm(PatternTerm&amp; term, bool filterStartsWithBOL = false)
-    {
-        if ((term.type != PatternTerm::TypeParenthesesSubpattern) &amp;&amp; \
                (term.type != PatternTerm::TypeParentheticalAssertion))
-            return PatternTerm(term);
-        
-        PatternTerm termCopy = term;
-        termCopy.parentheses.disjunction = \
                copyDisjunction(termCopy.parentheses.disjunction, \
                filterStartsWithBOL);
-        return termCopy;
-    }
-    
-    void quantifyAtom(unsigned min, unsigned max, bool greedy)
-    {
-        ASSERT(min &lt;= max);
-        ASSERT(m_alternative-&gt;m_terms.size());
-
-        if (!max) {
-            m_alternative-&gt;removeLastTerm();
-            return;
-        }
-
-        PatternTerm&amp; term = m_alternative-&gt;lastTerm();
-        ASSERT(term.type &gt; PatternTerm::TypeAssertionWordBoundary);
-        ASSERT((term.quantityCount == 1) &amp;&amp; (term.quantityType == \
                QuantifierFixedCount));
-
-        // For any assertion with a zero minimum, not matching is valid and has no \
                effect,
-        // remove it.  Otherwise, we need to match as least once, but there is no \
                point
-        // matching more than once, so remove the quantifier.  It is not entirely \
                clear
-        // from the spec whether or not this behavior is correct, but I believe this
-        // matches Firefox. :-/
-        if (term.type == PatternTerm::TypeParentheticalAssertion) {
-            if (!min)
-                m_alternative-&gt;removeLastTerm();
-            return;
-        }
-
-        if (min == 0)
-            term.quantify(max, greedy   ? QuantifierGreedy : QuantifierNonGreedy);
-        else if (min == max)
-            term.quantify(min, QuantifierFixedCount);
-        else {
-            term.quantify(min, QuantifierFixedCount);
-            m_alternative-&gt;m_terms.append(copyTerm(term));
-            // NOTE: this term is interesting from an analysis perspective, in that \
                it can be ignored.....
-            m_alternative-&gt;lastTerm().quantify((max == quantifyInfinite) ? max : \
                max - min, greedy ? QuantifierGreedy : QuantifierNonGreedy);
-            if (m_alternative-&gt;lastTerm().type == \
                PatternTerm::TypeParenthesesSubpattern)
-                m_alternative-&gt;lastTerm().parentheses.isCopy = true;
-        }
-    }
-
-    void disjunction()
-    {
-        m_alternative = m_alternative-&gt;m_parent-&gt;addNewAlternative();
-    }
-
-    void regexBegin()
-    {
-        m_pattern.m_body = new PatternDisjunction();
-        m_alternative = m_pattern.m_body-&gt;addNewAlternative();
-        m_pattern.m_disjunctions.append(m_pattern.m_body);
-    }
-    void regexEnd()
-    {
-    }
-    void regexError()
-    {
-    }
-
-    unsigned setupAlternativeOffsets(PatternAlternative* alternative, unsigned \
                currentCallFrameSize, unsigned initialInputPosition)
-    {
-        alternative-&gt;m_hasFixedSize = true;
-        unsigned currentInputPosition = initialInputPosition;
-
-        for (unsigned i = 0; i &lt; alternative-&gt;m_terms.size(); ++i) {
-            PatternTerm&amp; term = alternative-&gt;m_terms[i];
-
-            switch (term.type) {
-            case PatternTerm::TypeAssertionBOL:
-            case PatternTerm::TypeAssertionEOL:
-            case PatternTerm::TypeAssertionWordBoundary:
-                term.inputPosition = currentInputPosition;
-                break;
-
-            case PatternTerm::TypeBackReference:
-                term.inputPosition = currentInputPosition;
-                term.frameLocation = currentCallFrameSize;
-                currentCallFrameSize += \
                RegexStackSpaceForBackTrackInfoBackReference;
-                alternative-&gt;m_hasFixedSize = false;
-                break;
-
-            case PatternTerm::TypeForwardReference:
-                break;
-
-            case PatternTerm::TypePatternCharacter:
-                term.inputPosition = currentInputPosition;
-                if (term.quantityType != QuantifierFixedCount) {
-                    term.frameLocation = currentCallFrameSize;
-                    currentCallFrameSize += \
                RegexStackSpaceForBackTrackInfoPatternCharacter;
-                    alternative-&gt;m_hasFixedSize = false;
-                } else
-                    currentInputPosition += term.quantityCount;
-                break;
-
-            case PatternTerm::TypeCharacterClass:
-                term.inputPosition = currentInputPosition;
-                if (term.quantityType != QuantifierFixedCount) {
-                    term.frameLocation = currentCallFrameSize;
-                    currentCallFrameSize += \
                RegexStackSpaceForBackTrackInfoCharacterClass;
-                    alternative-&gt;m_hasFixedSize = false;
-                } else
-                    currentInputPosition += term.quantityCount;
-                break;
-
-            case PatternTerm::TypeParenthesesSubpattern:
-                // Note: for fixed once parentheses we will ensure at least the \
                minimum is available; others are on their own.
-                term.frameLocation = currentCallFrameSize;
-                if (term.quantityCount == 1 &amp;&amp; !term.parentheses.isCopy) {
-                    if (term.quantityType != QuantifierFixedCount)
-                        currentCallFrameSize += \
                RegexStackSpaceForBackTrackInfoParenthesesOnce;
-                    currentCallFrameSize = \
setupDisjunctionOffsets(term.parentheses.disjunction, currentCallFrameSize, \
                currentInputPosition);
-                    // If quantity is fixed, then pre-check its minimum size.
-                    if (term.quantityType == QuantifierFixedCount)
-                        currentInputPosition += \
                term.parentheses.disjunction-&gt;m_minimumSize;
-                    term.inputPosition = currentInputPosition;
-                } else if (term.parentheses.isTerminal) {
-                    currentCallFrameSize += \
                RegexStackSpaceForBackTrackInfoParenthesesTerminal;
-                    currentCallFrameSize = \
setupDisjunctionOffsets(term.parentheses.disjunction, currentCallFrameSize, \
                currentInputPosition);
-                    term.inputPosition = currentInputPosition;
-                } else {
-                    term.inputPosition = currentInputPosition;
-                    setupDisjunctionOffsets(term.parentheses.disjunction, 0, \
                currentInputPosition);
-                    currentCallFrameSize += \
                RegexStackSpaceForBackTrackInfoParentheses;
-                }
-                // Fixed count of 1 could be accepted, if they have a fixed size \
                *AND* if all alternatives are of the same length.
-                alternative-&gt;m_hasFixedSize = false;
-                break;
-
-            case PatternTerm::TypeParentheticalAssertion:
-                term.inputPosition = currentInputPosition;
-                term.frameLocation = currentCallFrameSize;
-                currentCallFrameSize = \
setupDisjunctionOffsets(term.parentheses.disjunction, currentCallFrameSize + \
                RegexStackSpaceForBackTrackInfoParentheticalAssertion, \
                currentInputPosition);
-                break;
-            }
-        }
-
-        alternative-&gt;m_minimumSize = currentInputPosition - initialInputPosition;
-        return currentCallFrameSize;
-    }
-
-    unsigned setupDisjunctionOffsets(PatternDisjunction* disjunction, unsigned \
                initialCallFrameSize, unsigned initialInputPosition)
-    {
-        if ((disjunction != m_pattern.m_body) &amp;&amp; \
                (disjunction-&gt;m_alternatives.size() &gt; 1))
-            initialCallFrameSize += RegexStackSpaceForBackTrackInfoAlternative;
-
-        unsigned minimumInputSize = UINT_MAX;
-        unsigned maximumCallFrameSize = 0;
-        bool hasFixedSize = true;
-
-        for (unsigned alt = 0; alt &lt; disjunction-&gt;m_alternatives.size(); \
                ++alt) {
-            PatternAlternative* alternative = disjunction-&gt;m_alternatives[alt];
-            unsigned currentAlternativeCallFrameSize = \
                setupAlternativeOffsets(alternative, initialCallFrameSize, \
                initialInputPosition);
-            minimumInputSize = min(minimumInputSize, alternative-&gt;m_minimumSize);
-            maximumCallFrameSize = max(maximumCallFrameSize, \
                currentAlternativeCallFrameSize);
-            hasFixedSize &amp;= alternative-&gt;m_hasFixedSize;
-        }
-        
-        ASSERT(minimumInputSize != UINT_MAX);
-        ASSERT(maximumCallFrameSize &gt;= initialCallFrameSize);
-
-        disjunction-&gt;m_hasFixedSize = hasFixedSize;
-        disjunction-&gt;m_minimumSize = minimumInputSize;
-        disjunction-&gt;m_callFrameSize = maximumCallFrameSize;
-        return maximumCallFrameSize;
-    }
-
-    void setupOffsets()
-    {
-        setupDisjunctionOffsets(m_pattern.m_body, 0, 0);
-    }
-
-    // This optimization identifies sets of parentheses that we will never need to \
                backtrack.
-    // In these cases we do not need to store state from prior iterations.
-    // We can presently avoid backtracking for:
-    //   * where the parens are at the end of the regular expression (last term in \
                any of the
-    //     alternatives of the main body disjunction).
-    //   * where the parens are non-capturing, and quantified unbounded greedy (*).
-    //   * where the parens do not contain any capturing subpatterns.
-    void checkForTerminalParentheses()
-    {
-        // This check is much too crude; should be just checking whether the \
                candidate
-        // node contains nested capturing subpatterns, not the whole expression!
-        if (m_pattern.m_numSubpatterns)
-            return;
-
-        Vector&lt;PatternAlternative*&gt;&amp; alternatives = \
                m_pattern.m_body-&gt;m_alternatives;
-        for (size_t i = 0; i &lt; alternatives.size(); ++i) {
-            Vector&lt;PatternTerm&gt;&amp; terms = alternatives[i]-&gt;m_terms;
-            if (terms.size()) {
-                PatternTerm&amp; term = terms.last();
-                if (term.type == PatternTerm::TypeParenthesesSubpattern
-                    &amp;&amp; term.quantityType == QuantifierGreedy
-                    &amp;&amp; term.quantityCount == quantifyInfinite
-                    &amp;&amp; !term.capture())
-                    term.parentheses.isTerminal = true;
-            }
-        }
-    }
-
-    void optimizeBOL()
-    {
-        // Look for expressions containing beginning of line (^) anchoring and \
                unroll them.
-        // e.g. /^a|^b|c/ becomes /^a|^b|c/ which is executed once followed by /c/ \
                which loops
-        // This code relies on the parsing code tagging alternatives with \
                m_containsBOL and
-        // m_startsWithBOL and rolling those up to containing alternatives.
-        // At this point, this is only valid for non-multiline expressions.
-        PatternDisjunction* disjunction = m_pattern.m_body;
-        
-        if (!m_pattern.m_containsBOL || m_pattern.m_multiline)
-            return;
-        
-        PatternDisjunction* loopDisjunction = copyDisjunction(disjunction, true);
-
-        // Set alternatives in disjunction to &quot;onceThrough&quot;
-        for (unsigned alt = 0; alt &lt; disjunction-&gt;m_alternatives.size(); \
                ++alt)
-            disjunction-&gt;m_alternatives[alt]-&gt;setOnceThrough();
-
-        if (loopDisjunction) {
-            // Move alternatives from loopDisjunction to disjunction
-            for (unsigned alt = 0; alt &lt; \
                loopDisjunction-&gt;m_alternatives.size(); ++alt)
-                disjunction-&gt;m_alternatives.append(loopDisjunction-&gt;m_alternatives[alt]);
                
-                
-            loopDisjunction-&gt;m_alternatives.clear();
-        }
-    }
-
-    bool addBeginTerm(PatternTerm term, Vector&lt;TermChain&gt;* beginTerms, \
PatternAlternative* alternative, unsigned numTerms, unsigned termIndex, unsigned \
                depth)
-    {
-        if (term.quantityType == QuantifierFixedCount) {
-            beginTerms-&gt;append(TermChain(term));
-            if (depth &lt; 2 &amp;&amp; termIndex &lt; numTerms - 1 &amp;&amp; \
                term.quantityCount == 1)
-                setupAlternativeBeginTerms(alternative, \
                &amp;beginTerms-&gt;last().hotTerms, termIndex + 1, depth + 1);
-        } else if (termIndex != numTerms - 1) {
-            beginTerms-&gt;append(TermChain(term));
-            return true;
-        }
-
-        return false;
-    }
-
-    // This function collects the terms which are potentially matching the first \
                number of depth characters in the result.
-    // If this function returns false then it found at least one term which makes \
                the beginning character
-    // look-up optimization inefficient.
-    bool setupDisjunctionBeginTerms(PatternDisjunction* disjunction, \
                Vector&lt;TermChain&gt;* beginTerms, unsigned depth)
-    {
-        for (unsigned alt = 0; alt &lt; disjunction-&gt;m_alternatives.size(); \
                ++alt) {
-            PatternAlternative* alternative = disjunction-&gt;m_alternatives[alt];
-
-            if (!setupAlternativeBeginTerms(alternative, beginTerms, 0, depth))
-                return false;
-        }
-
-        return true;
-    }
-
-    bool setupAlternativeBeginTerms(PatternAlternative* alternative, \
                Vector&lt;TermChain&gt;* beginTerms, unsigned termIndex, unsigned \
                depth)
-    {
-        bool checkNext = true;
-        unsigned numTerms = alternative-&gt;m_terms.size();
-
-        while (checkNext &amp;&amp; termIndex &lt; numTerms) {
-            PatternTerm term = alternative-&gt;m_terms[termIndex];
-            checkNext = false;
-
-            switch (term.type) {
-            case PatternTerm::TypeAssertionBOL:
-            case PatternTerm::TypeAssertionEOL:
-            case PatternTerm::TypeAssertionWordBoundary:
-                return false;
-
-            case PatternTerm::TypeBackReference:
-            case PatternTerm::TypeForwardReference:
-                return false;
-
-            case PatternTerm::TypePatternCharacter:
-                if (addBeginTerm(term, beginTerms, alternative, numTerms, termIndex, \
                depth)) {
-                    termIndex++;
-                    checkNext = true;
-                }
-                break;
-
-            case PatternTerm::TypeCharacterClass:
-                return false;
-
-            case PatternTerm::TypeParentheticalAssertion:
-                if (term.invert())
-                    return false;
-
-            case PatternTerm::TypeParenthesesSubpattern:
-                if (term.quantityType != QuantifierFixedCount) {
-                    if (termIndex == numTerms - 1)
-                        break;
-
-                    termIndex++;
-                    checkNext = true;
-
-                }
-
-                if (!setupDisjunctionBeginTerms(term.parentheses.disjunction, \
                beginTerms, depth))
-                    return false;
-
-                break;
-            }
-        }
-
-        return true;
-    }
-
-    void setupBeginChars()
-    {
-        Vector&lt;TermChain&gt; beginTerms;
-        bool containsFixedCharacter = false;
-
-        if ((!m_pattern.m_body-&gt;m_hasFixedSize || \
                m_pattern.m_body-&gt;m_alternatives.size() &gt; 1)
-                &amp;&amp; setupDisjunctionBeginTerms(m_pattern.m_body, \
                &amp;beginTerms, 0)) {
-            unsigned size = beginTerms.size();
-
-            // If we haven't collected any terms we should abort the preparation of \
                beginning character look-up optimization.
-            if (!size)
-                return;
-
-            m_pattern.m_containsBeginChars = true;
-
-            for (unsigned i = 0; i &lt; size; i++) {
-                PatternTerm term = beginTerms[i].term;
-
-                // We have just collected PatternCharacter terms, other terms are \
                not allowed.
-                ASSERT(term.type == PatternTerm::TypePatternCharacter);
-
-                if (term.quantityType == QuantifierFixedCount)
-                    containsFixedCharacter = true;
-
-                UChar character = term.patternCharacter;
-                unsigned mask = 0;
-
-                if (character &lt;= 0x7f) {
-                    if (m_pattern.m_ignoreCase &amp;&amp; isASCIIAlpha(character)) {
-                        mask = 32;
-                        character = toASCIILower(character);
-                    }
-
-                    m_beginCharHelper.addBeginChar(BeginChar(character, mask), \
                &amp;beginTerms[i].hotTerms, term.quantityType, term.quantityCount);
-                } else {
-                    UChar upper, lower;
-                    if (m_pattern.m_ignoreCase &amp;&amp; ((upper = \
                Unicode::toUpper(character)) != (lower = \
                Unicode::toLower(character)))) {
-                        m_beginCharHelper.addBeginChar(BeginChar(upper, mask), \
                &amp;beginTerms[i].hotTerms, term.quantityType, term.quantityCount);
-                        m_beginCharHelper.addBeginChar(BeginChar(lower, mask), \
                &amp;beginTerms[i].hotTerms, term.quantityType, term.quantityCount);
-                    } else
-                        m_beginCharHelper.addBeginChar(BeginChar(character, mask), \
                &amp;beginTerms[i].hotTerms, term.quantityType, term.quantityCount);
-                }
-            }
-
-            // If the pattern doesn't contain terms with fixed quantifiers then the \
                beginning character look-up optimization is inefficient.
-            if (!containsFixedCharacter) {
-                m_pattern.m_containsBeginChars = false;
-                return;
-            }
-
-            size = m_pattern.m_beginChars.size();
-
-            if (size &gt; 2)
-                m_beginCharHelper.merge(size - 1);
-            else if (size &lt;= 1)
-                m_pattern.m_containsBeginChars = false;
-        }
-    }
-
-private:
-    RegexPattern&amp; m_pattern;
-    PatternAlternative* m_alternative;
-    CharacterClassConstructor m_characterClassConstructor;
-    BeginCharHelper m_beginCharHelper;
-    bool m_invertCharacterClass;
-    bool m_invertParentheticalAssertion;
-};
-
-
-const char* compileRegex(const UString&amp; patternString, RegexPattern&amp; \
                pattern)
-{
-    RegexPatternConstructor constructor(pattern);
-
-    if (const char* error = parse(constructor, patternString))
-        return error;
-    
-    // If the pattern contains illegal backreferences reset &amp; reparse.
-    // Quoting Netscape's &quot;What's new in JavaScript 1.2&quot;,
-    //      &quot;Note: if the number of left parentheses is less than the number \
                specified
-    //       in \#, the \# is taken as an octal escape as described in the next \
                row.&quot;
-    if (pattern.containsIllegalBackReference()) {
-        unsigned numSubpatterns = pattern.m_numSubpatterns;
-
-        constructor.reset();
-#if !ASSERT_DISABLED
-        const char* error =
-#endif
-            parse(constructor, patternString, numSubpatterns);
-
-        ASSERT(!error);
-        ASSERT(numSubpatterns == pattern.m_numSubpatterns);
-    }
-
-    constructor.checkForTerminalParentheses();
-    constructor.optimizeBOL();
-        
-    constructor.setupOffsets();
-    constructor.setupBeginChars();
-
-    return 0;
-};
-
-
-} }
</del></span></pre></div>
<a id="trunkJavaScriptCoreyarrRegexCompilerh"></a>
<div class="delfile"><h4>Deleted: trunk/JavaScriptCore/yarr/RegexCompiler.h (74599 => \
74600)</h4> <pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/yarr/RegexCompiler.h	2010-12-24 01:36:39 \
                UTC (rev 74599)
+++ trunk/JavaScriptCore/yarr/RegexCompiler.h	2010-12-24 01:40:54 UTC (rev 74600)
</span><span class="lines">@@ -1,39 +0,0 @@
</span><del>-/*
- * Copyright (C) 2009 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. ``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
- * 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. 
- */
-
-#ifndef RegexCompiler_h
-#define RegexCompiler_h
-
-#include &quot;RegexParser.h&quot;
-#include &quot;RegexPattern.h&quot;
-#include &lt;wtf/unicode/Unicode.h&gt;
-
-namespace JSC { namespace Yarr {
-
-const char* compileRegex(const UString&amp; patternString, RegexPattern&amp; \
                pattern);
-
-} } // namespace JSC::Yarr
-
-#endif // RegexCompiler_h
</del></span></pre></div>
<a id="trunkJavaScriptCoreyarrRegexInterpretercpp"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/yarr/RegexInterpreter.cpp \
(74599 => 74600)</h4> <pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/yarr/RegexInterpreter.cpp	2010-12-24 \
                01:36:39 UTC (rev 74599)
+++ trunk/JavaScriptCore/yarr/RegexInterpreter.cpp	2010-12-24 01:40:54 UTC (rev \
74600) </span><span class="lines">@@ -27,7 +27,6 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;RegexInterpreter.h&quot;
</span><span class="cx"> 
</span><del>-#include &quot;RegexCompiler.h&quot;
</del><span class="cx"> #include &quot;RegexPattern.h&quot;
</span><span class="cx"> #include &lt;wtf/BumpPointerAllocator.h&gt;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkJavaScriptCoreyarrRegexJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/yarr/RegexJIT.cpp (74599 => \
74600)</h4> <pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/yarr/RegexJIT.cpp	2010-12-24 01:36:39 UTC \
                (rev 74599)
+++ trunk/JavaScriptCore/yarr/RegexJIT.cpp	2010-12-24 01:40:54 UTC (rev 74600)
</span><span class="lines">@@ -30,7 +30,7 @@
</span><span class="cx"> #include &quot;JSGlobalData.h&quot;
</span><span class="cx"> #include &quot;LinkBuffer.h&quot;
</span><span class="cx"> #include &quot;MacroAssembler.h&quot;
</span><del>-#include &quot;RegexCompiler.h&quot;
</del><ins>+#include &quot;RegexParser.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> #if ENABLE(YARR_JIT)
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkJavaScriptCoreyarrRegexPatterncppfromrev74496trunkJavaScriptCoreyarrRegexCompilercpp"></a>
 <div class="copfile"><h4>Copied: trunk/JavaScriptCore/yarr/RegexPattern.cpp (from \
rev 74496, trunk/JavaScriptCore/yarr/RegexCompiler.cpp) (0 => 74600)</h4> <pre \
class="diff"><span> <span class="info">--- \
                trunk/JavaScriptCore/yarr/RegexPattern.cpp	                        \
                (rev 0)
+++ trunk/JavaScriptCore/yarr/RegexPattern.cpp	2010-12-24 01:40:54 UTC (rev 74600)
</span><span class="lines">@@ -0,0 +1,991 @@
</span><ins>+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Peter Varga (pvarga@inf.u-szeged.hu), University of Szeged
+ *
+ * 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. ``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
+ * 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;RegexInterpreter.h&quot;
+#include &quot;RegexPattern.h&quot;
+#include &lt;wtf/Vector.h&gt;
+
+using namespace WTF;
+
+namespace JSC { namespace Yarr {
+
+#include &quot;RegExpJitTables.h&quot;
+
+class CharacterClassConstructor {
+public:
+    CharacterClassConstructor(bool isCaseInsensitive = false)
+        : m_isCaseInsensitive(isCaseInsensitive)
+    {
+    }
+    
+    void reset()
+    {
+        m_matches.clear();
+        m_ranges.clear();
+        m_matchesUnicode.clear();
+        m_rangesUnicode.clear();
+    }
+
+    void append(const CharacterClass* other)
+    {
+        for (size_t i = 0; i &lt; other-&gt;m_matches.size(); ++i)
+            addSorted(m_matches, other-&gt;m_matches[i]);
+        for (size_t i = 0; i &lt; other-&gt;m_ranges.size(); ++i)
+            addSortedRange(m_ranges, other-&gt;m_ranges[i].begin, \
other-&gt;m_ranges[i].end); +        for (size_t i = 0; i &lt; \
other-&gt;m_matchesUnicode.size(); ++i) +            addSorted(m_matchesUnicode, \
other-&gt;m_matchesUnicode[i]); +        for (size_t i = 0; i &lt; \
other-&gt;m_rangesUnicode.size(); ++i) +            addSortedRange(m_rangesUnicode, \
other-&gt;m_rangesUnicode[i].begin, other-&gt;m_rangesUnicode[i].end); +    }
+
+    void putChar(UChar ch)
+    {
+        if (ch &lt;= 0x7f) {
+            if (m_isCaseInsensitive &amp;&amp; isASCIIAlpha(ch)) {
+                addSorted(m_matches, toASCIIUpper(ch));
+                addSorted(m_matches, toASCIILower(ch));
+            } else
+                addSorted(m_matches, ch);
+        } else {
+            UChar upper, lower;
+            if (m_isCaseInsensitive &amp;&amp; ((upper = Unicode::toUpper(ch)) != \
(lower = Unicode::toLower(ch)))) { +                addSorted(m_matchesUnicode, \
upper); +                addSorted(m_matchesUnicode, lower);
+            } else
+                addSorted(m_matchesUnicode, ch);
+        }
+    }
+
+    // returns true if this character has another case, and 'ch' is the upper case \
form. +    static inline bool isUnicodeUpper(UChar ch)
+    {
+        return ch != Unicode::toLower(ch);
+    }
+
+    // returns true if this character has another case, and 'ch' is the lower case \
form. +    static inline bool isUnicodeLower(UChar ch)
+    {
+        return ch != Unicode::toUpper(ch);
+    }
+
+    void putRange(UChar lo, UChar hi)
+    {
+        if (lo &lt;= 0x7f) {
+            char asciiLo = lo;
+            char asciiHi = std::min(hi, (UChar)0x7f);
+            addSortedRange(m_ranges, lo, asciiHi);
+            
+            if (m_isCaseInsensitive) {
+                if ((asciiLo &lt;= 'Z') &amp;&amp; (asciiHi &gt;= 'A'))
+                    addSortedRange(m_ranges, std::max(asciiLo, 'A')+('a'-'A'), \
std::min(asciiHi, 'Z')+('a'-'A')); +                if ((asciiLo &lt;= 'z') \
&amp;&amp; (asciiHi &gt;= 'a')) +                    addSortedRange(m_ranges, \
std::max(asciiLo, 'a')+('A'-'a'), std::min(asciiHi, 'z')+('A'-'a')); +            }
+        }
+        if (hi &gt;= 0x80) {
+            uint32_t unicodeCurr = std::max(lo, (UChar)0x80);
+            addSortedRange(m_rangesUnicode, unicodeCurr, hi);
+            
+            if (m_isCaseInsensitive) {
+                while (unicodeCurr &lt;= hi) {
+                    // If the upper bound of the range (hi) is 0xffff, the \
increments to +                    // unicodeCurr in this loop may take it to \
0x10000.  This is fine +                    // (if so we won't re-enter the loop, \
since the loop condition above +                    // will definitely fail) - but \
this does mean we cannot use a UChar +                    // to represent \
unicodeCurr, we must use a 32-bit value instead. +                    \
ASSERT(unicodeCurr &lt;= 0xffff); +
+                    if (isUnicodeUpper(unicodeCurr)) {
+                        UChar lowerCaseRangeBegin = Unicode::toLower(unicodeCurr);
+                        UChar lowerCaseRangeEnd = lowerCaseRangeBegin;
+                        while ((++unicodeCurr &lt;= hi) &amp;&amp; \
isUnicodeUpper(unicodeCurr) &amp;&amp; (Unicode::toLower(unicodeCurr) == \
(lowerCaseRangeEnd + 1))) +                            lowerCaseRangeEnd++;
+                        addSortedRange(m_rangesUnicode, lowerCaseRangeBegin, \
lowerCaseRangeEnd); +                    } else if (isUnicodeLower(unicodeCurr)) {
+                        UChar upperCaseRangeBegin = Unicode::toUpper(unicodeCurr);
+                        UChar upperCaseRangeEnd = upperCaseRangeBegin;
+                        while ((++unicodeCurr &lt;= hi) &amp;&amp; \
isUnicodeLower(unicodeCurr) &amp;&amp; (Unicode::toUpper(unicodeCurr) == \
(upperCaseRangeEnd + 1))) +                            upperCaseRangeEnd++;
+                        addSortedRange(m_rangesUnicode, upperCaseRangeBegin, \
upperCaseRangeEnd); +                    } else
+                        ++unicodeCurr;
+                }
+            }
+        }
+    }
+
+    CharacterClass* charClass()
+    {
+        CharacterClass* characterClass = new CharacterClass(0);
+
+        characterClass-&gt;m_matches.append(m_matches);
+        characterClass-&gt;m_ranges.append(m_ranges);
+        characterClass-&gt;m_matchesUnicode.append(m_matchesUnicode);
+        characterClass-&gt;m_rangesUnicode.append(m_rangesUnicode);
+
+        reset();
+
+        return characterClass;
+    }
+
+private:
+    void addSorted(Vector&lt;UChar&gt;&amp; matches, UChar ch)
+    {
+        unsigned pos = 0;
+        unsigned range = matches.size();
+
+        // binary chop, find position to insert char.
+        while (range) {
+            unsigned index = range &gt;&gt; 1;
+
+            int val = matches[pos+index] - ch;
+            if (!val)
+                return;
+            else if (val &gt; 0)
+                range = index;
+            else {
+                pos += (index+1);
+                range -= (index+1);
+            }
+        }
+        
+        if (pos == matches.size())
+            matches.append(ch);
+        else
+            matches.insert(pos, ch);
+    }
+
+    void addSortedRange(Vector&lt;CharacterRange&gt;&amp; ranges, UChar lo, UChar \
hi) +    {
+        unsigned end = ranges.size();
+        
+        // Simple linear scan - I doubt there are that many ranges anyway...
+        // feel free to fix this with something faster (eg binary chop).
+        for (unsigned i = 0; i &lt; end; ++i) {
+            // does the new range fall before the current position in the array
+            if (hi &lt; ranges[i].begin) {
+                // optional optimization: concatenate appending ranges? - may not be \
worthwhile. +                if (hi == (ranges[i].begin - 1)) {
+                    ranges[i].begin = lo;
+                    return;
+                }
+                ranges.insert(i, CharacterRange(lo, hi));
+                return;
+            }
+            // Okay, since we didn't hit the last case, the end of the new range is \
definitely at or after the begining +            // If the new range start at or \
before the end of the last range, then the overlap (if it starts one after the +      \
// end of the last range they concatenate, which is just as good. +            if (lo \
&lt;= (ranges[i].end + 1)) { +                // found an intersect! we'll replace \
this entry in the array. +                ranges[i].begin = std::min(ranges[i].begin, \
lo); +                ranges[i].end = std::max(ranges[i].end, hi);
+
+                // now check if the new range can subsume any subsequent ranges.
+                unsigned next = i+1;
+                // each iteration of the loop we will either remove something from \
the list, or break the loop. +                while (next &lt; ranges.size()) {
+                    if (ranges[next].begin &lt;= (ranges[i].end + 1)) {
+                        // the next entry now overlaps / concatenates this one.
+                        ranges[i].end = std::max(ranges[i].end, ranges[next].end);
+                        ranges.remove(next);
+                    } else
+                        break;
+                }
+                
+                return;
+            }
+        }
+
+        // CharacterRange comes after all existing ranges.
+        ranges.append(CharacterRange(lo, hi));
+    }
+
+    bool m_isCaseInsensitive;
+
+    Vector&lt;UChar&gt; m_matches;
+    Vector&lt;CharacterRange&gt; m_ranges;
+    Vector&lt;UChar&gt; m_matchesUnicode;
+    Vector&lt;CharacterRange&gt; m_rangesUnicode;
+};
+
+struct BeginCharHelper {
+    BeginCharHelper(Vector&lt;BeginChar&gt;* beginChars, bool isCaseInsensitive = \
false) +        : m_beginChars(beginChars)
+        , m_isCaseInsensitive(isCaseInsensitive)
+    {}
+
+    void addBeginChar(BeginChar beginChar, Vector&lt;TermChain&gt;* hotTerms, \
QuantifierType quantityType, unsigned quantityCount) +    {
+        if (quantityType == QuantifierFixedCount &amp;&amp; quantityCount &gt; 1) {
+            // We duplicate the first found character if the quantity of the term is \
more than one. eg.: /a{3}/ +            beginChar.value |= beginChar.value &lt;&lt; \
16; +            beginChar.mask |= beginChar.mask &lt;&lt; 16;
+            addCharacter(beginChar);
+        } else if (quantityType == QuantifierFixedCount &amp;&amp; quantityCount == \
1 &amp;&amp; hotTerms-&gt;size()) +            // In case of characters with fixed \
quantifier we should check the next character as well. +            \
linkHotTerms(beginChar, hotTerms); +        else
+            // In case of greedy matching the next character checking is unnecessary \
therefore we just store +            // the first character.
+            addCharacter(beginChar);
+    }
+
+    // Merge two following BeginChars in the vector to reduce the number of \
character checks. +    void merge(unsigned size)
+    {
+        for (unsigned i = 0; i &lt; size; i++) {
+            BeginChar* curr = &amp;m_beginChars-&gt;at(i);
+            BeginChar* next = &amp;m_beginChars-&gt;at(i + 1);
+
+            // If the current and the next size of value is different we should skip \
the merge process +            // because the 16bit and 32bit values are unmergable.
+            if (curr-&gt;value &lt;= 0xFFFF &amp;&amp; next-&gt;value &gt; 0xFFFF)
+                continue;
+
+            unsigned diff = curr-&gt;value ^ next-&gt;value;
+
+            curr-&gt;mask |= diff;
+            curr-&gt;value |= curr-&gt;mask;
+
+            m_beginChars-&gt;remove(i + 1);
+            size--;
+        }
+    }
+
+private:
+    void addCharacter(BeginChar beginChar)
+    {
+        unsigned pos = 0;
+        unsigned range = m_beginChars-&gt;size();
+
+        // binary chop, find position to insert char.
+        while (range) {
+            unsigned index = range &gt;&gt; 1;
+
+            int val = m_beginChars-&gt;at(pos+index).value - beginChar.value;
+            if (!val)
+                return;
+            if (val &lt; 0)
+                range = index;
+            else {
+                pos += (index+1);
+                range -= (index+1);
+            }
+        }
+
+        if (pos == m_beginChars-&gt;size())
+            m_beginChars-&gt;append(beginChar);
+        else
+            m_beginChars-&gt;insert(pos, beginChar);
+    }
+
+    // Create BeginChar objects by appending each terms from a hotTerms vector to an \
existing BeginChar object. +    void linkHotTerms(BeginChar beginChar, \
Vector&lt;TermChain&gt;* hotTerms) +    {
+        for (unsigned i = 0; i &lt; hotTerms-&gt;size(); i++) {
+            PatternTerm hotTerm = hotTerms-&gt;at(i).term;
+            ASSERT(hotTerm.type == PatternTerm::TypePatternCharacter);
+
+            UChar characterNext = hotTerm.patternCharacter;
+
+            // Append a character to an existing BeginChar object.
+            if (characterNext &lt;= 0x7f) {
+                unsigned mask = 0;
+
+                if (m_isCaseInsensitive &amp;&amp; isASCIIAlpha(characterNext)) {
+                    mask = 32;
+                    characterNext = toASCIILower(characterNext);
+                }
+
+                addCharacter(BeginChar(beginChar.value | (characterNext &lt;&lt; \
16), beginChar.mask | (mask &lt;&lt; 16))); +            } else {
+                UChar upper, lower;
+                if (m_isCaseInsensitive &amp;&amp; ((upper = \
Unicode::toUpper(characterNext)) != (lower = Unicode::toLower(characterNext)))) { +   \
addCharacter(BeginChar(beginChar.value | (upper &lt;&lt; 16), beginChar.mask)); +     \
addCharacter(BeginChar(beginChar.value | (lower &lt;&lt; 16), beginChar.mask)); +     \
} else +                    addCharacter(BeginChar(beginChar.value | (characterNext \
&lt;&lt; 16), beginChar.mask)); +            }
+        }
+    }
+
+    Vector&lt;BeginChar&gt;* m_beginChars;
+    bool m_isCaseInsensitive;
+};
+
+class RegexPatternConstructor {
+public:
+    RegexPatternConstructor(RegexPattern&amp; pattern)
+        : m_pattern(pattern)
+        , m_characterClassConstructor(pattern.m_ignoreCase)
+        , m_beginCharHelper(&amp;pattern.m_beginChars, pattern.m_ignoreCase)
+        , m_invertParentheticalAssertion(false)
+    {
+    }
+
+    ~RegexPatternConstructor()
+    {
+    }
+
+    void reset()
+    {
+        m_pattern.reset();
+        m_characterClassConstructor.reset();
+    }
+    
+    void assertionBOL()
+    {
+        if (!m_alternative-&gt;m_terms.size() &amp; !m_invertParentheticalAssertion) \
{ +            m_alternative-&gt;m_startsWithBOL = true;
+            m_alternative-&gt;m_containsBOL = true;
+            m_pattern.m_containsBOL = true;
+        }
+        m_alternative-&gt;m_terms.append(PatternTerm::BOL());
+    }
+    void assertionEOL()
+    {
+        m_alternative-&gt;m_terms.append(PatternTerm::EOL());
+    }
+    void assertionWordBoundary(bool invert)
+    {
+        m_alternative-&gt;m_terms.append(PatternTerm::WordBoundary(invert));
+    }
+
+    void atomPatternCharacter(UChar ch)
+    {
+        // We handle case-insensitive checking of unicode characters which do have \
both +        // cases by handling them as if they were defined using a \
CharacterClass. +        if (m_pattern.m_ignoreCase &amp;&amp; !isASCII(ch) \
&amp;&amp; (Unicode::toUpper(ch) != Unicode::toLower(ch))) { +            \
atomCharacterClassBegin(); +            atomCharacterClassAtom(ch);
+            atomCharacterClassEnd();
+        } else
+            m_alternative-&gt;m_terms.append(PatternTerm(ch));
+    }
+
+    void atomBuiltInCharacterClass(BuiltInCharacterClassID classID, bool invert)
+    {
+        switch (classID) {
+        case DigitClassID:
+            m_alternative-&gt;m_terms.append(PatternTerm(m_pattern.digitsCharacterClass(), \
invert)); +            break;
+        case SpaceClassID:
+            m_alternative-&gt;m_terms.append(PatternTerm(m_pattern.spacesCharacterClass(), \
invert)); +            break;
+        case WordClassID:
+            m_alternative-&gt;m_terms.append(PatternTerm(m_pattern.wordcharCharacterClass(), \
invert)); +            break;
+        case NewlineClassID:
+            m_alternative-&gt;m_terms.append(PatternTerm(m_pattern.newlineCharacterClass(), \
invert)); +            break;
+        }
+    }
+
+    void atomCharacterClassBegin(bool invert = false)
+    {
+        m_invertCharacterClass = invert;
+    }
+
+    void atomCharacterClassAtom(UChar ch)
+    {
+        m_characterClassConstructor.putChar(ch);
+    }
+
+    void atomCharacterClassRange(UChar begin, UChar end)
+    {
+        m_characterClassConstructor.putRange(begin, end);
+    }
+
+    void atomCharacterClassBuiltIn(BuiltInCharacterClassID classID, bool invert)
+    {
+        ASSERT(classID != NewlineClassID);
+
+        switch (classID) {
+        case DigitClassID:
+            m_characterClassConstructor.append(invert ? \
m_pattern.nondigitsCharacterClass() : m_pattern.digitsCharacterClass()); +            \
break; +        
+        case SpaceClassID:
+            m_characterClassConstructor.append(invert ? \
m_pattern.nonspacesCharacterClass() : m_pattern.spacesCharacterClass()); +            \
break; +        
+        case WordClassID:
+            m_characterClassConstructor.append(invert ? \
m_pattern.nonwordcharCharacterClass() : m_pattern.wordcharCharacterClass()); +        \
break; +        
+        default:
+            ASSERT_NOT_REACHED();
+        }
+    }
+
+    void atomCharacterClassEnd()
+    {
+        CharacterClass* newCharacterClass = m_characterClassConstructor.charClass();
+        m_pattern.m_userCharacterClasses.append(newCharacterClass);
+        m_alternative-&gt;m_terms.append(PatternTerm(newCharacterClass, \
m_invertCharacterClass)); +    }
+
+    void atomParenthesesSubpatternBegin(bool capture = true)
+    {
+        unsigned subpatternId = m_pattern.m_numSubpatterns + 1;
+        if (capture)
+            m_pattern.m_numSubpatterns++;
+
+        PatternDisjunction* parenthesesDisjunction = new \
PatternDisjunction(m_alternative); +        \
m_pattern.m_disjunctions.append(parenthesesDisjunction); +        \
m_alternative-&gt;m_terms.append(PatternTerm(PatternTerm::TypeParenthesesSubpattern, \
subpatternId, parenthesesDisjunction, capture, false)); +        m_alternative = \
parenthesesDisjunction-&gt;addNewAlternative(); +    }
+
+    void atomParentheticalAssertionBegin(bool invert = false)
+    {
+        PatternDisjunction* parenthesesDisjunction = new \
PatternDisjunction(m_alternative); +        \
m_pattern.m_disjunctions.append(parenthesesDisjunction); +        \
m_alternative-&gt;m_terms.append(PatternTerm(PatternTerm::TypeParentheticalAssertion, \
m_pattern.m_numSubpatterns + 1, parenthesesDisjunction, false, invert)); +        \
m_alternative = parenthesesDisjunction-&gt;addNewAlternative(); +        \
m_invertParentheticalAssertion = invert; +    }
+
+    void atomParenthesesEnd()
+    {
+        ASSERT(m_alternative-&gt;m_parent);
+        ASSERT(m_alternative-&gt;m_parent-&gt;m_parent);
+
+        PatternDisjunction* parenthesesDisjunction = m_alternative-&gt;m_parent;
+        m_alternative = m_alternative-&gt;m_parent-&gt;m_parent;
+
+        PatternTerm&amp; lastTerm = m_alternative-&gt;lastTerm();
+        
+        unsigned numParenAlternatives = \
parenthesesDisjunction-&gt;m_alternatives.size(); +        unsigned \
numBOLAnchoredAlts = 0; +        // Bubble up BOL flags
+        for (unsigned i = 0; i &lt; numParenAlternatives; i++) {
+            if (parenthesesDisjunction-&gt;m_alternatives[i]-&gt;m_startsWithBOL)
+                numBOLAnchoredAlts++;
+        }
+        
+        if (numBOLAnchoredAlts) {
+            m_alternative-&gt;m_containsBOL = true;
+            // If all the alternatives in parens start with BOL, then so does this \
one +            if (numBOLAnchoredAlts == numParenAlternatives)
+                m_alternative-&gt;m_startsWithBOL = true;
+        }
+        
+        lastTerm.parentheses.lastSubpatternId = m_pattern.m_numSubpatterns;
+        m_invertParentheticalAssertion = false;
+    }
+
+    void atomBackReference(unsigned subpatternId)
+    {
+        ASSERT(subpatternId);
+        m_pattern.m_containsBackreferences = true;
+        m_pattern.m_maxBackReference = std::max(m_pattern.m_maxBackReference, \
subpatternId); +
+        if (subpatternId &gt; m_pattern.m_numSubpatterns) {
+            m_alternative-&gt;m_terms.append(PatternTerm::ForwardReference());
+            return;
+        }
+
+        PatternAlternative* currentAlternative = m_alternative;
+        ASSERT(currentAlternative);
+
+        // Note to self: if we waited until the AST was baked, we could also remove \
forwards refs  +        while ((currentAlternative = \
currentAlternative-&gt;m_parent-&gt;m_parent)) { +            PatternTerm&amp; term = \
currentAlternative-&gt;lastTerm(); +            ASSERT((term.type == \
PatternTerm::TypeParenthesesSubpattern) || (term.type == \
PatternTerm::TypeParentheticalAssertion)); +
+            if ((term.type == PatternTerm::TypeParenthesesSubpattern) &amp;&amp; \
term.capture() &amp;&amp; (subpatternId == term.parentheses.subpatternId)) { +        \
m_alternative-&gt;m_terms.append(PatternTerm::ForwardReference()); +                \
return; +            }
+        }
+
+        m_alternative-&gt;m_terms.append(PatternTerm(subpatternId));
+    }
+
+    // deep copy the argument disjunction.  If filterStartsWithBOL is true, 
+    // skip alternatives with m_startsWithBOL set true.
+    PatternDisjunction* copyDisjunction(PatternDisjunction* disjunction, bool \
filterStartsWithBOL = false) +    {
+        PatternDisjunction* newDisjunction = 0;
+        for (unsigned alt = 0; alt &lt; disjunction-&gt;m_alternatives.size(); \
++alt) { +            PatternAlternative* alternative = \
disjunction-&gt;m_alternatives[alt]; +            if (!filterStartsWithBOL || \
!alternative-&gt;m_startsWithBOL) { +                if (!newDisjunction) {
+                    newDisjunction = new PatternDisjunction();
+                    newDisjunction-&gt;m_parent = disjunction-&gt;m_parent;
+                }
+                PatternAlternative* newAlternative = \
newDisjunction-&gt;addNewAlternative(); +                for (unsigned i = 0; i &lt; \
alternative-&gt;m_terms.size(); ++i) +                    \
newAlternative-&gt;m_terms.append(copyTerm(alternative-&gt;m_terms[i], \
filterStartsWithBOL)); +            }
+        }
+        
+        if (newDisjunction)
+            m_pattern.m_disjunctions.append(newDisjunction);
+        return newDisjunction;
+    }
+    
+    PatternTerm copyTerm(PatternTerm&amp; term, bool filterStartsWithBOL = false)
+    {
+        if ((term.type != PatternTerm::TypeParenthesesSubpattern) &amp;&amp; \
(term.type != PatternTerm::TypeParentheticalAssertion)) +            return \
PatternTerm(term); +        
+        PatternTerm termCopy = term;
+        termCopy.parentheses.disjunction = \
copyDisjunction(termCopy.parentheses.disjunction, filterStartsWithBOL); +        \
return termCopy; +    }
+    
+    void quantifyAtom(unsigned min, unsigned max, bool greedy)
+    {
+        ASSERT(min &lt;= max);
+        ASSERT(m_alternative-&gt;m_terms.size());
+
+        if (!max) {
+            m_alternative-&gt;removeLastTerm();
+            return;
+        }
+
+        PatternTerm&amp; term = m_alternative-&gt;lastTerm();
+        ASSERT(term.type &gt; PatternTerm::TypeAssertionWordBoundary);
+        ASSERT((term.quantityCount == 1) &amp;&amp; (term.quantityType == \
QuantifierFixedCount)); +
+        // For any assertion with a zero minimum, not matching is valid and has no \
effect, +        // remove it.  Otherwise, we need to match as least once, but there \
is no point +        // matching more than once, so remove the quantifier.  It is not \
entirely clear +        // from the spec whether or not this behavior is correct, but \
I believe this +        // matches Firefox. :-/
+        if (term.type == PatternTerm::TypeParentheticalAssertion) {
+            if (!min)
+                m_alternative-&gt;removeLastTerm();
+            return;
+        }
+
+        if (min == 0)
+            term.quantify(max, greedy   ? QuantifierGreedy : QuantifierNonGreedy);
+        else if (min == max)
+            term.quantify(min, QuantifierFixedCount);
+        else {
+            term.quantify(min, QuantifierFixedCount);
+            m_alternative-&gt;m_terms.append(copyTerm(term));
+            // NOTE: this term is interesting from an analysis perspective, in that \
it can be ignored..... +            m_alternative-&gt;lastTerm().quantify((max == \
quantifyInfinite) ? max : max - min, greedy ? QuantifierGreedy : \
QuantifierNonGreedy); +            if (m_alternative-&gt;lastTerm().type == \
PatternTerm::TypeParenthesesSubpattern) +                \
m_alternative-&gt;lastTerm().parentheses.isCopy = true; +        }
+    }
+
+    void disjunction()
+    {
+        m_alternative = m_alternative-&gt;m_parent-&gt;addNewAlternative();
+    }
+
+    void regexBegin()
+    {
+        m_pattern.m_body = new PatternDisjunction();
+        m_alternative = m_pattern.m_body-&gt;addNewAlternative();
+        m_pattern.m_disjunctions.append(m_pattern.m_body);
+    }
+    void regexEnd()
+    {
+    }
+    void regexError()
+    {
+    }
+
+    unsigned setupAlternativeOffsets(PatternAlternative* alternative, unsigned \
currentCallFrameSize, unsigned initialInputPosition) +    {
+        alternative-&gt;m_hasFixedSize = true;
+        unsigned currentInputPosition = initialInputPosition;
+
+        for (unsigned i = 0; i &lt; alternative-&gt;m_terms.size(); ++i) {
+            PatternTerm&amp; term = alternative-&gt;m_terms[i];
+
+            switch (term.type) {
+            case PatternTerm::TypeAssertionBOL:
+            case PatternTerm::TypeAssertionEOL:
+            case PatternTerm::TypeAssertionWordBoundary:
+                term.inputPosition = currentInputPosition;
+                break;
+
+            case PatternTerm::TypeBackReference:
+                term.inputPosition = currentInputPosition;
+                term.frameLocation = currentCallFrameSize;
+                currentCallFrameSize += \
RegexStackSpaceForBackTrackInfoBackReference; +                \
alternative-&gt;m_hasFixedSize = false; +                break;
+
+            case PatternTerm::TypeForwardReference:
+                break;
+
+            case PatternTerm::TypePatternCharacter:
+                term.inputPosition = currentInputPosition;
+                if (term.quantityType != QuantifierFixedCount) {
+                    term.frameLocation = currentCallFrameSize;
+                    currentCallFrameSize += \
RegexStackSpaceForBackTrackInfoPatternCharacter; +                    \
alternative-&gt;m_hasFixedSize = false; +                } else
+                    currentInputPosition += term.quantityCount;
+                break;
+
+            case PatternTerm::TypeCharacterClass:
+                term.inputPosition = currentInputPosition;
+                if (term.quantityType != QuantifierFixedCount) {
+                    term.frameLocation = currentCallFrameSize;
+                    currentCallFrameSize += \
RegexStackSpaceForBackTrackInfoCharacterClass; +                    \
alternative-&gt;m_hasFixedSize = false; +                } else
+                    currentInputPosition += term.quantityCount;
+                break;
+
+            case PatternTerm::TypeParenthesesSubpattern:
+                // Note: for fixed once parentheses we will ensure at least the \
minimum is available; others are on their own. +                term.frameLocation = \
currentCallFrameSize; +                if (term.quantityCount == 1 &amp;&amp; \
!term.parentheses.isCopy) { +                    if (term.quantityType != \
QuantifierFixedCount) +                        currentCallFrameSize += \
RegexStackSpaceForBackTrackInfoParenthesesOnce; +                    \
currentCallFrameSize = setupDisjunctionOffsets(term.parentheses.disjunction, \
currentCallFrameSize, currentInputPosition); +                    // If quantity is \
fixed, then pre-check its minimum size. +                    if (term.quantityType == \
QuantifierFixedCount) +                        currentInputPosition += \
term.parentheses.disjunction-&gt;m_minimumSize; +                    \
term.inputPosition = currentInputPosition; +                } else if \
(term.parentheses.isTerminal) { +                    currentCallFrameSize += \
RegexStackSpaceForBackTrackInfoParenthesesTerminal; +                    \
currentCallFrameSize = setupDisjunctionOffsets(term.parentheses.disjunction, \
currentCallFrameSize, currentInputPosition); +                    term.inputPosition \
= currentInputPosition; +                } else {
+                    term.inputPosition = currentInputPosition;
+                    setupDisjunctionOffsets(term.parentheses.disjunction, 0, \
currentInputPosition); +                    currentCallFrameSize += \
RegexStackSpaceForBackTrackInfoParentheses; +                }
+                // Fixed count of 1 could be accepted, if they have a fixed size \
*AND* if all alternatives are of the same length. +                \
alternative-&gt;m_hasFixedSize = false; +                break;
+
+            case PatternTerm::TypeParentheticalAssertion:
+                term.inputPosition = currentInputPosition;
+                term.frameLocation = currentCallFrameSize;
+                currentCallFrameSize = \
setupDisjunctionOffsets(term.parentheses.disjunction, currentCallFrameSize + \
RegexStackSpaceForBackTrackInfoParentheticalAssertion, currentInputPosition); +       \
break; +            }
+        }
+
+        alternative-&gt;m_minimumSize = currentInputPosition - initialInputPosition;
+        return currentCallFrameSize;
+    }
+
+    unsigned setupDisjunctionOffsets(PatternDisjunction* disjunction, unsigned \
initialCallFrameSize, unsigned initialInputPosition) +    {
+        if ((disjunction != m_pattern.m_body) &amp;&amp; \
(disjunction-&gt;m_alternatives.size() &gt; 1)) +            initialCallFrameSize += \
RegexStackSpaceForBackTrackInfoAlternative; +
+        unsigned minimumInputSize = UINT_MAX;
+        unsigned maximumCallFrameSize = 0;
+        bool hasFixedSize = true;
+
+        for (unsigned alt = 0; alt &lt; disjunction-&gt;m_alternatives.size(); \
++alt) { +            PatternAlternative* alternative = \
disjunction-&gt;m_alternatives[alt]; +            unsigned \
currentAlternativeCallFrameSize = setupAlternativeOffsets(alternative, \
initialCallFrameSize, initialInputPosition); +            minimumInputSize = \
min(minimumInputSize, alternative-&gt;m_minimumSize); +            \
maximumCallFrameSize = max(maximumCallFrameSize, currentAlternativeCallFrameSize); +  \
hasFixedSize &amp;= alternative-&gt;m_hasFixedSize; +        }
+        
+        ASSERT(minimumInputSize != UINT_MAX);
+        ASSERT(maximumCallFrameSize &gt;= initialCallFrameSize);
+
+        disjunction-&gt;m_hasFixedSize = hasFixedSize;
+        disjunction-&gt;m_minimumSize = minimumInputSize;
+        disjunction-&gt;m_callFrameSize = maximumCallFrameSize;
+        return maximumCallFrameSize;
+    }
+
+    void setupOffsets()
+    {
+        setupDisjunctionOffsets(m_pattern.m_body, 0, 0);
+    }
+
+    // This optimization identifies sets of parentheses that we will never need to \
backtrack. +    // In these cases we do not need to store state from prior \
iterations. +    // We can presently avoid backtracking for:
+    //   * where the parens are at the end of the regular expression (last term in \
any of the +    //     alternatives of the main body disjunction).
+    //   * where the parens are non-capturing, and quantified unbounded greedy (*).
+    //   * where the parens do not contain any capturing subpatterns.
+    void checkForTerminalParentheses()
+    {
+        // This check is much too crude; should be just checking whether the \
candidate +        // node contains nested capturing subpatterns, not the whole \
expression! +        if (m_pattern.m_numSubpatterns)
+            return;
+
+        Vector&lt;PatternAlternative*&gt;&amp; alternatives = \
m_pattern.m_body-&gt;m_alternatives; +        for (size_t i = 0; i &lt; \
alternatives.size(); ++i) { +            Vector&lt;PatternTerm&gt;&amp; terms = \
alternatives[i]-&gt;m_terms; +            if (terms.size()) {
+                PatternTerm&amp; term = terms.last();
+                if (term.type == PatternTerm::TypeParenthesesSubpattern
+                    &amp;&amp; term.quantityType == QuantifierGreedy
+                    &amp;&amp; term.quantityCount == quantifyInfinite
+                    &amp;&amp; !term.capture())
+                    term.parentheses.isTerminal = true;
+            }
+        }
+    }
+
+    void optimizeBOL()
+    {
+        // Look for expressions containing beginning of line (^) anchoring and \
unroll them. +        // e.g. /^a|^b|c/ becomes /^a|^b|c/ which is executed once \
followed by /c/ which loops +        // This code relies on the parsing code tagging \
alternatives with m_containsBOL and +        // m_startsWithBOL and rolling those up \
to containing alternatives. +        // At this point, this is only valid for \
non-multiline expressions. +        PatternDisjunction* disjunction = \
m_pattern.m_body; +        
+        if (!m_pattern.m_containsBOL || m_pattern.m_multiline)
+            return;
+        
+        PatternDisjunction* loopDisjunction = copyDisjunction(disjunction, true);
+
+        // Set alternatives in disjunction to &quot;onceThrough&quot;
+        for (unsigned alt = 0; alt &lt; disjunction-&gt;m_alternatives.size(); \
++alt) +            disjunction-&gt;m_alternatives[alt]-&gt;setOnceThrough();
+
+        if (loopDisjunction) {
+            // Move alternatives from loopDisjunction to disjunction
+            for (unsigned alt = 0; alt &lt; \
loopDisjunction-&gt;m_alternatives.size(); ++alt) +                \
disjunction-&gt;m_alternatives.append(loopDisjunction-&gt;m_alternatives[alt]); +     \
 +            loopDisjunction-&gt;m_alternatives.clear();
+        }
+    }
+
+    bool addBeginTerm(PatternTerm term, Vector&lt;TermChain&gt;* beginTerms, \
PatternAlternative* alternative, unsigned numTerms, unsigned termIndex, unsigned \
depth) +    {
+        if (term.quantityType == QuantifierFixedCount) {
+            beginTerms-&gt;append(TermChain(term));
+            if (depth &lt; 2 &amp;&amp; termIndex &lt; numTerms - 1 &amp;&amp; \
term.quantityCount == 1) +                setupAlternativeBeginTerms(alternative, \
&amp;beginTerms-&gt;last().hotTerms, termIndex + 1, depth + 1); +        } else if \
(termIndex != numTerms - 1) { +            beginTerms-&gt;append(TermChain(term));
+            return true;
+        }
+
+        return false;
+    }
+
+    // This function collects the terms which are potentially matching the first \
number of depth characters in the result. +    // If this function returns false then \
it found at least one term which makes the beginning character +    // look-up \
optimization inefficient. +    bool setupDisjunctionBeginTerms(PatternDisjunction* \
disjunction, Vector&lt;TermChain&gt;* beginTerms, unsigned depth) +    {
+        for (unsigned alt = 0; alt &lt; disjunction-&gt;m_alternatives.size(); \
++alt) { +            PatternAlternative* alternative = \
disjunction-&gt;m_alternatives[alt]; +
+            if (!setupAlternativeBeginTerms(alternative, beginTerms, 0, depth))
+                return false;
+        }
+
+        return true;
+    }
+
+    bool setupAlternativeBeginTerms(PatternAlternative* alternative, \
Vector&lt;TermChain&gt;* beginTerms, unsigned termIndex, unsigned depth) +    {
+        bool checkNext = true;
+        unsigned numTerms = alternative-&gt;m_terms.size();
+
+        while (checkNext &amp;&amp; termIndex &lt; numTerms) {
+            PatternTerm term = alternative-&gt;m_terms[termIndex];
+            checkNext = false;
+
+            switch (term.type) {
+            case PatternTerm::TypeAssertionBOL:
+            case PatternTerm::TypeAssertionEOL:
+            case PatternTerm::TypeAssertionWordBoundary:
+                return false;
+
+            case PatternTerm::TypeBackReference:
+            case PatternTerm::TypeForwardReference:
+                return false;
+
+            case PatternTerm::TypePatternCharacter:
+                if (addBeginTerm(term, beginTerms, alternative, numTerms, termIndex, \
depth)) { +                    termIndex++;
+                    checkNext = true;
+                }
+                break;
+
+            case PatternTerm::TypeCharacterClass:
+                return false;
+
+            case PatternTerm::TypeParentheticalAssertion:
+                if (term.invert())
+                    return false;
+
+            case PatternTerm::TypeParenthesesSubpattern:
+                if (term.quantityType != QuantifierFixedCount) {
+                    if (termIndex == numTerms - 1)
+                        break;
+
+                    termIndex++;
+                    checkNext = true;
+
+                }
+
+                if (!setupDisjunctionBeginTerms(term.parentheses.disjunction, \
beginTerms, depth)) +                    return false;
+
+                break;
+            }
+        }
+
+        return true;
+    }
+
+    void setupBeginChars()
+    {
+        Vector&lt;TermChain&gt; beginTerms;
+        bool containsFixedCharacter = false;
+
+        if ((!m_pattern.m_body-&gt;m_hasFixedSize || \
m_pattern.m_body-&gt;m_alternatives.size() &gt; 1) +                &amp;&amp; \
setupDisjunctionBeginTerms(m_pattern.m_body, &amp;beginTerms, 0)) { +            \
unsigned size = beginTerms.size(); +
+            // If we haven't collected any terms we should abort the preparation of \
beginning character look-up optimization. +            if (!size)
+                return;
+
+            m_pattern.m_containsBeginChars = true;
+
+            for (unsigned i = 0; i &lt; size; i++) {
+                PatternTerm term = beginTerms[i].term;
+
+                // We have just collected PatternCharacter terms, other terms are \
not allowed. +                ASSERT(term.type == PatternTerm::TypePatternCharacter);
+
+                if (term.quantityType == QuantifierFixedCount)
+                    containsFixedCharacter = true;
+
+                UChar character = term.patternCharacter;
+                unsigned mask = 0;
+
+                if (character &lt;= 0x7f) {
+                    if (m_pattern.m_ignoreCase &amp;&amp; isASCIIAlpha(character)) {
+                        mask = 32;
+                        character = toASCIILower(character);
+                    }
+
+                    m_beginCharHelper.addBeginChar(BeginChar(character, mask), \
&amp;beginTerms[i].hotTerms, term.quantityType, term.quantityCount); +                \
} else { +                    UChar upper, lower;
+                    if (m_pattern.m_ignoreCase &amp;&amp; ((upper = \
Unicode::toUpper(character)) != (lower = Unicode::toLower(character)))) { +           \
m_beginCharHelper.addBeginChar(BeginChar(upper, mask), &amp;beginTerms[i].hotTerms, \
term.quantityType, term.quantityCount); +                        \
m_beginCharHelper.addBeginChar(BeginChar(lower, mask), &amp;beginTerms[i].hotTerms, \
term.quantityType, term.quantityCount); +                    } else
+                        m_beginCharHelper.addBeginChar(BeginChar(character, mask), \
&amp;beginTerms[i].hotTerms, term.quantityType, term.quantityCount); +                \
} +            }
+
+            // If the pattern doesn't contain terms with fixed quantifiers then the \
beginning character look-up optimization is inefficient. +            if \
(!containsFixedCharacter) { +                m_pattern.m_containsBeginChars = false;
+                return;
+            }
+
+            size = m_pattern.m_beginChars.size();
+
+            if (size &gt; 2)
+                m_beginCharHelper.merge(size - 1);
+            else if (size &lt;= 1)
+                m_pattern.m_containsBeginChars = false;
+        }
+    }
+
+private:
+    RegexPattern&amp; m_pattern;
+    PatternAlternative* m_alternative;
+    CharacterClassConstructor m_characterClassConstructor;
+    BeginCharHelper m_beginCharHelper;
+    bool m_invertCharacterClass;
+    bool m_invertParentheticalAssertion;
+};
+
+
+static const char* compileRegex(const UString&amp; patternString, RegexPattern&amp; \
pattern) +{
+    RegexPatternConstructor constructor(pattern);
+
+    if (const char* error = parse(constructor, patternString))
+        return error;
+    
+    // If the pattern contains illegal backreferences reset &amp; reparse.
+    // Quoting Netscape's &quot;What's new in JavaScript 1.2&quot;,
+    //      &quot;Note: if the number of left parentheses is less than the number \
specified +    //       in \#, the \# is taken as an octal escape as described in the \
next row.&quot; +    if (pattern.containsIllegalBackReference()) {
+        unsigned numSubpatterns = pattern.m_numSubpatterns;
+
+        constructor.reset();
+#if !ASSERT_DISABLED
+        const char* error =
+#endif
+            parse(constructor, patternString, numSubpatterns);
+
+        ASSERT(!error);
+        ASSERT(numSubpatterns == pattern.m_numSubpatterns);
+    }
+
+    constructor.checkForTerminalParentheses();
+    constructor.optimizeBOL();
+        
+    constructor.setupOffsets();
+    constructor.setupBeginChars();
+
+    return 0;
+};
+
+RegexPattern::RegexPattern(const UString&amp; pattern, bool ignoreCase, bool \
multiline, const char** error) +    : m_ignoreCase(ignoreCase)
+    , m_multiline(multiline)
+    , m_containsBackreferences(false)
+    , m_containsBeginChars(false)
+    , m_containsBOL(false)
+    , m_numSubpatterns(0)
+    , m_maxBackReference(0)
+    , newlineCached(0)
+    , digitsCached(0)
+    , spacesCached(0)
+    , wordcharCached(0)
+    , nondigitsCached(0)
+    , nonspacesCached(0)
+    , nonwordcharCached(0)
+{
+    *error = compileRegex(pattern, *this);
+}
+
+} }
</ins></span></pre></div>
<a id="trunkJavaScriptCoreyarrRegexPatternh"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/yarr/RegexPattern.h (74599 => \
74600)</h4> <pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/yarr/RegexPattern.h	2010-12-24 01:36:39 \
                UTC (rev 74599)
+++ trunk/JavaScriptCore/yarr/RegexPattern.h	2010-12-24 01:40:54 UTC (rev 74600)
</span><span class="lines">@@ -30,6 +30,8 @@
</span><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><span class="cx"> #include &lt;wtf/unicode/Unicode.h&gt;
</span><span class="cx"> 
</span><ins>+#include &lt;UString.h&gt;
+
</ins><span class="cx"> namespace JSC { namespace Yarr {
</span><span class="cx"> 
</span><span class="cx"> #define RegexStackSpaceForBackTrackInfoPatternCharacter 1 // \
Only for !fixed quantifiers. </span><span class="lines">@@ -315,23 +317,7 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> struct RegexPattern {
</span><del>-    RegexPattern(bool ignoreCase, bool multiline)
-        : m_ignoreCase(ignoreCase)
-        , m_multiline(multiline)
-        , m_containsBackreferences(false)
-        , m_containsBeginChars(false)
-        , m_containsBOL(false)
-        , m_numSubpatterns(0)
-        , m_maxBackReference(0)
-        , newlineCached(0)
-        , digitsCached(0)
-        , spacesCached(0)
-        , wordcharCached(0)
-        , nondigitsCached(0)
-        , nonspacesCached(0)
-        , nonwordcharCached(0)
-    {
-    }
</del><ins>+    RegexPattern(const UString&amp; pattern, bool ignoreCase, bool \
multiline, const char** error); </ins><span class="cx"> 
</span><span class="cx">     ~RegexPattern()
</span><span class="cx">     {
</span></span></pre>
</div>
</div>

</body>
</html>



_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic