<!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>[161839] trunk</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/161839">161839</a></dd>
<dt>Author</dt> <dd>benjamin@webkit.org</dd>
<dt>Date</dt> <dd>2014-01-12 15:04:19 -0800 (Sun, 12 Jan 2014)</dd>
</dl>
<h3>Log Message</h3>
<pre>Use the Selector Code Generator for matching in SelectorQuery
https://bugs.webkit.org/show_bug.cgi?id=126185
Reviewed by Ryosuke Niwa.
Source/WebCore:
Compile selectors on demand and use the generated binary to perform
element matching in SelectorQuery.
Tests: fast/selectors/querySelector-long-adjacent-backtracking.html
fast/selectors/querySelector-long-child-backtracking.html
fast/selectors/querySelector-mixed-child-adjacent-backtracking.html
fast/selectors/querySelector-multiple-simple-child-backtracking.html
fast/selectors/querySelector-simple-adjacent-backtracking.html
fast/selectors/querySelector-simple-child-backtracking.html
* dom/SelectorQuery.cpp:
(WebCore::SelectorDataList::executeCompiledSimpleSelectorChecker):
(WebCore::SelectorDataList::executeCompiledSelectorCheckerWithContext):
(WebCore::SelectorDataList::execute):
* dom/SelectorQuery.h:
LayoutTests:
Add some tests for longer backtracking cases typically not covered by the other tests.
* fast/selectors/querySelector-long-adjacent-backtracking-expected.txt: Added.
* fast/selectors/querySelector-long-adjacent-backtracking.html: Added.
* fast/selectors/querySelector-long-child-backtracking-expected.txt: Added.
* fast/selectors/querySelector-long-child-backtracking.html: Added.
* fast/selectors/querySelector-mixed-child-adjacent-backtracking-expected.txt: Added.
* fast/selectors/querySelector-mixed-child-adjacent-backtracking.html: Added.
* fast/selectors/querySelector-multiple-simple-child-backtracking-expected.txt: Added.
* fast/selectors/querySelector-multiple-simple-child-backtracking.html: Added.
* fast/selectors/querySelector-simple-adjacent-backtracking-expected.txt: Added.
* fast/selectors/querySelector-simple-adjacent-backtracking.html: Added.
* fast/selectors/querySelector-simple-child-backtracking-expected.txt: Added.
* fast/selectors/querySelector-simple-child-backtracking.html: Added.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorecssjitSelectorCompilerh">trunk/Source/WebCore/cssjit/SelectorCompiler.h</a></li>
<li><a href="#trunkSourceWebCoredomSelectorQuerycpp">trunk/Source/WebCore/dom/SelectorQuery.cpp</a></li>
<li><a href="#trunkSourceWebCoredomSelectorQueryh">trunk/Source/WebCore/dom/SelectorQuery.h</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfastselectorsquerySelectorlongadjacentbacktrackingexpectedtxt">trunk/LayoutTests/fast/selectors/querySelector-long-adjacent-backtracking-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastselectorsquerySelectorlongadjacentbacktrackinghtml">trunk/LayoutTests/fast/selectors/querySelector-long-adjacent-backtracking.html</a></li>
<li><a href="#trunkLayoutTestsfastselectorsquerySelectorlongchildbacktrackingexpectedtxt">trunk/LayoutTests/fast/selectors/querySelector-long-child-backtracking-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastselectorsquerySelectorlongchildbacktrackinghtml">trunk/LayoutTests/fast/selectors/querySelector-long-child-backtracking.html</a></li>
<li><a href="#trunkLayoutTestsfastselectorsquerySelectormixedchildadjacentbacktrackingexpectedtxt">trunk/LayoutTests/fast/selectors/querySelector-mixed-child-adjacent-backtracking-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastselectorsquerySelectormixedchildadjacentbacktrackinghtml">trunk/LayoutTests/fast/selectors/querySelector-mixed-child-adjacent-backtracking.html</a></li>
<li><a href="#trunkLayoutTestsfastselectorsquerySelectormultiplesimplechildbacktrackingexpectedtxt">trunk/LayoutTests/fast/selectors/querySelector-multiple-simple-child-backtracking-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastselectorsquerySelectormultiplesimplechildbacktrackinghtml">trunk/LayoutTests/fast/selectors/querySelector-multiple-simple-child-backtracking.html</a></li>
<li><a href="#trunkLayoutTestsfastselectorsquerySelectorsimpleadjacentbacktrackingexpectedtxt">trunk/LayoutTests/fast/selectors/querySelector-simple-adjacent-backtracking-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastselectorsquerySelectorsimpleadjacentbacktrackinghtml">trunk/LayoutTests/fast/selectors/querySelector-simple-adjacent-backtracking.html</a></li>
<li><a href="#trunkLayoutTestsfastselectorsquerySelectorsimplechildbacktrackingexpectedtxt">trunk/LayoutTests/fast/selectors/querySelector-simple-child-backtracking-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastselectorsquerySelectorsimplechildbacktrackinghtml">trunk/LayoutTests/fast/selectors/querySelector-simple-child-backtracking.html</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (161838 => 161839)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2014-01-12 22:07:44 UTC (rev 161838)
+++ trunk/LayoutTests/ChangeLog        2014-01-12 23:04:19 UTC (rev 161839)
</span><span class="lines">@@ -1,3 +1,25 @@
</span><ins>+2014-01-12 Benjamin Poulain <benjamin@webkit.org>
+
+ Use the Selector Code Generator for matching in SelectorQuery
+ https://bugs.webkit.org/show_bug.cgi?id=126185
+
+ Reviewed by Ryosuke Niwa.
+
+ Add some tests for longer backtracking cases typically not covered by the other tests.
+
+ * fast/selectors/querySelector-long-adjacent-backtracking-expected.txt: Added.
+ * fast/selectors/querySelector-long-adjacent-backtracking.html: Added.
+ * fast/selectors/querySelector-long-child-backtracking-expected.txt: Added.
+ * fast/selectors/querySelector-long-child-backtracking.html: Added.
+ * fast/selectors/querySelector-mixed-child-adjacent-backtracking-expected.txt: Added.
+ * fast/selectors/querySelector-mixed-child-adjacent-backtracking.html: Added.
+ * fast/selectors/querySelector-multiple-simple-child-backtracking-expected.txt: Added.
+ * fast/selectors/querySelector-multiple-simple-child-backtracking.html: Added.
+ * fast/selectors/querySelector-simple-adjacent-backtracking-expected.txt: Added.
+ * fast/selectors/querySelector-simple-adjacent-backtracking.html: Added.
+ * fast/selectors/querySelector-simple-child-backtracking-expected.txt: Added.
+ * fast/selectors/querySelector-simple-child-backtracking.html: Added.
+
</ins><span class="cx"> 2014-01-12 Andreas Kling <akling@apple.com>
</span><span class="cx">
</span><span class="cx"> REGRESSION(r160806): line-height is not applied when only present in :link style.
</span></span></pre></div>
<a id="trunkLayoutTestsfastselectorsquerySelectorlongadjacentbacktrackingexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/querySelector-long-adjacent-backtracking-expected.txt (0 => 161839)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/querySelector-long-adjacent-backtracking-expected.txt         (rev 0)
+++ trunk/LayoutTests/fast/selectors/querySelector-long-adjacent-backtracking-expected.txt        2014-01-12 23:04:19 UTC (rev 161839)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+Test backtracking with a long sequence of direct sibling relations.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS document.querySelectorAll("li+div+li+blockquote+li~span").length is 1
+PASS document.querySelectorAll("li+div+li+blockquote+li~span")[0].id is "target"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorsquerySelectorlongadjacentbacktrackinghtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/querySelector-long-adjacent-backtracking.html (0 => 161839)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/querySelector-long-adjacent-backtracking.html         (rev 0)
+++ trunk/LayoutTests/fast/selectors/querySelector-long-adjacent-backtracking.html        2014-01-12 23:04:19 UTC (rev 161839)
</span><span class="lines">@@ -0,0 +1,52 @@
</span><ins>+<!doctype html>
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<div style="display:none">
+ <ul>
+ <!-- Correct sequence. -->
+ <li></li>
+ <div></div>
+ <li></li>
+ <blockquote></blockquote>
+ <li></li>
+
+ <!-- Lacks the ending <li>. -->
+ <li></li>
+ <div></div>
+ <li></li>
+ <blockquote></blockquote>
+
+ <!-- Lacks the <blockquote>. -->
+ <li></li>
+ <div></div>
+ <li></li>
+ <li></li>
+
+ <!-- Lacks the middle <li>. -->
+ <li></li>
+ <div></div>
+ <blockquote></blockquote>
+ <li></li>
+
+ <!-- Lacks the <div>. -->
+ <li></li>
+ <li></li>
+ <blockquote></blockquote>
+ <li></li>
+
+ <span id=target>Target</span>
+ <div>
+ </ul>
+</div>
+</body>
+<script>
+description('Test backtracking with a long sequence of direct sibling relations.');
+
+shouldBe('document.querySelectorAll("li+div+li+blockquote+li~span").length', '1');
+shouldBeEqualToString('document.querySelectorAll("li+div+li+blockquote+li~span")[0].id', 'target');
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorsquerySelectorlongchildbacktrackingexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/querySelector-long-child-backtracking-expected.txt (0 => 161839)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/querySelector-long-child-backtracking-expected.txt         (rev 0)
+++ trunk/LayoutTests/fast/selectors/querySelector-long-child-backtracking-expected.txt        2014-01-12 23:04:19 UTC (rev 161839)
</span><span class="lines">@@ -0,0 +1,13 @@
</span><ins>+Test backtracking with multiple child selector relations.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS document.querySelectorAll("ul>li>div>pre span").length is 3
+PASS document.querySelectorAll("ul>li>div>pre span")[0].id is "target1"
+PASS document.querySelectorAll("ul>li>div>pre span")[1].id is "target2"
+PASS document.querySelectorAll("ul>li>div>pre span")[2].id is "target3"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorsquerySelectorlongchildbacktrackinghtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/querySelector-long-child-backtracking.html (0 => 161839)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/querySelector-long-child-backtracking.html         (rev 0)
+++ trunk/LayoutTests/fast/selectors/querySelector-long-child-backtracking.html        2014-01-12 23:04:19 UTC (rev 161839)
</span><span class="lines">@@ -0,0 +1,94 @@
</span><ins>+<!doctype html>
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<div style="display:none">
+<!-- Fails on the <li> tag. -->
+<ul>
+ <li>
+ <div>
+ <div>
+ <pre>
+ <blockquote><span>Fail.</span></blockquote>
+ </pre>
+ </div>
+ </div>
+ </li>
+</ul>
+
+<!-- Fails on the <ul> tag. -->
+<div>
+ <li>
+ <div>
+ <pre>
+ <blockquote><span>Fail.</span></blockquote>
+ </pre>
+ </div>
+ </li>
+</div>
+
+<!-- Simple matches. -->
+<ul>
+ <li>
+ <div>
+ <pre>
+ <blockquote><span id="target1">Target 1</span></blockquote>
+ </pre>
+ </div>
+ </li>
+</ul>
+<ul>
+ <li>
+ <div>
+ <pre>
+ <pre>
+ <blockquote><span id="target2">Target 2</span></blockquote>
+ </pre>
+ </pre>
+ </div>
+ </li>
+</ul>
+
+<!-- Multiple failures before a match. -->
+<ul>
+ <li>
+ <div>
+ <pre>
+
+ <!-- This subtree lacks the ul. -->
+ <li>
+ <div>
+ <div>
+
+ <!-- This subtree lacks the li. -->
+ <div>
+ <div>
+ <div>
+ <blockquote><span id="target3">Target 3</span></blockquote>
+ </div>
+ </div>
+ </div>
+
+ </div>
+ </div>
+ </li>
+
+ </pre>
+ </div>
+ </li>
+</ul>
+
+</div>
+</body>
+<script>
+description('Test backtracking with multiple child selector relations.');
+
+shouldBe('document.querySelectorAll("ul>li>div>pre span").length', '3');
+shouldBeEqualToString('document.querySelectorAll("ul>li>div>pre span")[0].id', 'target1');
+shouldBeEqualToString('document.querySelectorAll("ul>li>div>pre span")[1].id', 'target2');
+shouldBeEqualToString('document.querySelectorAll("ul>li>div>pre span")[2].id', 'target3');
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorsquerySelectormixedchildadjacentbacktrackingexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/querySelector-mixed-child-adjacent-backtracking-expected.txt (0 => 161839)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/querySelector-mixed-child-adjacent-backtracking-expected.txt         (rev 0)
+++ trunk/LayoutTests/fast/selectors/querySelector-mixed-child-adjacent-backtracking-expected.txt        2014-01-12 23:04:19 UTC (rev 161839)
</span><span class="lines">@@ -0,0 +1,18 @@
</span><ins>+Test backtracking of adjacent and child relation mixed together.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS document.querySelectorAll("html>head+body div>div~h1+blockquote>p+div+blockquote~ul p").length is 8
+PASS document.querySelectorAll("html>head+body div>div~h1+blockquote>p+div+blockquote~ul p")[0].id is "target1"
+PASS document.querySelectorAll("html>head+body div>div~h1+blockquote>p+div+blockquote~ul p")[1].id is "target2"
+PASS document.querySelectorAll("html>head+body div>div~h1+blockquote>p+div+blockquote~ul p")[2].id is "target3"
+PASS document.querySelectorAll("html>head+body div>div~h1+blockquote>p+div+blockquote~ul p")[3].id is "target4"
+PASS document.querySelectorAll("html>head+body div>div~h1+blockquote>p+div+blockquote~ul p")[4].id is "target5"
+PASS document.querySelectorAll("html>head+body div>div~h1+blockquote>p+div+blockquote~ul p")[5].id is "target6"
+PASS document.querySelectorAll("html>head+body div>div~h1+blockquote>p+div+blockquote~ul p")[6].id is "target7"
+PASS document.querySelectorAll("html>head+body div>div~h1+blockquote>p+div+blockquote~ul p")[7].id is "target8"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorsquerySelectormixedchildadjacentbacktrackinghtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/querySelector-mixed-child-adjacent-backtracking.html (0 => 161839)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/querySelector-mixed-child-adjacent-backtracking.html         (rev 0)
+++ trunk/LayoutTests/fast/selectors/querySelector-mixed-child-adjacent-backtracking.html        2014-01-12 23:04:19 UTC (rev 161839)
</span><span class="lines">@@ -0,0 +1,135 @@
</span><ins>+<!doctype html>
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<div style="display:none">
+
+ <!-- Direct matching, no need to backtrack. -->
+ <div></div>
+ <table></table>
+ <h1></h1>
+ <blockquote>
+ <p></p>
+ <div></div>
+ <blockquote></blockquote>
+ <table></table>
+ <ul>
+ <li><p id="target1">Target 1</p></li>
+ </ul>
+ </blockquote>
+
+ <!-- A first block lacks the <p>. -->
+ <div></div>
+ <table></table>
+ <h1></h1>
+ <blockquote>
+ <p></p>
+ <div></div>
+ <blockquote></blockquote>
+ <table></table>
+ <div></div>
+ <blockquote></blockquote>
+ <table></table>
+ <ul>
+ <li><p id="target2">Target 2</p></li>
+ </ul>
+ </blockquote>
+
+ <!-- A second block lacks the <h1>. -->
+ <div></div>
+ <table></table>
+ <h1></h1>
+ <blockquote>
+ <p></p>
+ <div></div>
+ <blockquote></blockquote>
+ <table></table>
+ <ul>
+ <li>
+
+ <h2></h2>
+ <blockquote>
+ <p id="target3">Target 3</p>
+ <div></div>
+ <blockquote></blockquote>
+ <table></table>
+ <ul>
+ <li><p id="target4">Target 4</p></li>
+ </ul>
+ </blockquote>
+
+ </li>
+ </ul>
+ </blockquote>
+
+ <!-- A second block lacks the <div>. -->
+ <div></div>
+ <table></table>
+ <h1></h1>
+ <blockquote>
+ <p></p>
+ <div></div>
+ <blockquote></blockquote>
+ <table></table>
+ <ul>
+ <li>
+
+ <table></table>
+ <h1></h1>
+ <blockquote>
+ <p id="target5">Target 5</p>
+ <div></div>
+ <blockquote></blockquote>
+ <table></table>
+ <ul>
+ <li><p id="target6">Target 6</p></li>
+ </ul>
+ </blockquote>
+
+ </li>
+ </ul>
+ </blockquote>
+
+ <!-- A third block lacks the div. -->
+ <div></div>
+ <table></table>
+ <h1></h1>
+ <blockquote>
+ <p></p>
+ <div></div>
+ <blockquote></blockquote>
+ <table></table>
+ <ul>
+ <li>
+
+ <div></div>
+ <table></table>
+ <h1></h1>
+ <blockquote>
+ <p id="target7">Target 7</p>
+ <div></div>
+ <blockquote></blockquote>
+ <table></table>
+ <ul>
+ <li><p id="target8">Target 8</p></li>
+ </ul>
+ </blockquote>
+
+ </li>
+ </ul>
+ </blockquote>
+
+</div>
+</body>
+<script>
+description('Test backtracking of adjacent and child relation mixed together.');
+
+shouldBe('document.querySelectorAll("html>head+body div>div~h1+blockquote>p+div+blockquote~ul p").length', '8');
+for (var i = 0; i < document.querySelectorAll("html>head+body div>div~h1+blockquote>p+div+blockquote~ul p").length; ++i)
+ shouldBeEqualToString('document.querySelectorAll("html>head+body div>div~h1+blockquote>p+div+blockquote~ul p")[' + i +'].id', 'target' + (i + 1));
+</script>
+
+<script src="../../resources/js-test-post.js"></script>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorsquerySelectormultiplesimplechildbacktrackingexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/querySelector-multiple-simple-child-backtracking-expected.txt (0 => 161839)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/querySelector-multiple-simple-child-backtracking-expected.txt         (rev 0)
+++ trunk/LayoutTests/fast/selectors/querySelector-multiple-simple-child-backtracking-expected.txt        2014-01-12 23:04:19 UTC (rev 161839)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+Test backtracking with multiple chains of child relations.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS document.querySelectorAll("div>ul>li>div ul>li ul>li p").length is 1
+PASS document.querySelectorAll("div>ul>li>div ul>li ul>li p")[0].id is "target"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorsquerySelectormultiplesimplechildbacktrackinghtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/querySelector-multiple-simple-child-backtracking.html (0 => 161839)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/querySelector-multiple-simple-child-backtracking.html         (rev 0)
+++ trunk/LayoutTests/fast/selectors/querySelector-multiple-simple-child-backtracking.html        2014-01-12 23:04:19 UTC (rev 161839)
</span><span class="lines">@@ -0,0 +1,38 @@
</span><ins>+<!doctype html>
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<div style="display:none">
+<div>
+ <ul>
+ <li>
+ <div>
+ <ul>
+ <li>
+ <div>
+ <div>
+ <ul>
+ <li>
+ <p id="target"><span>Target.</span></p>
+ </li>
+ </ul>
+ </div>
+ <div>
+ </li>
+ </ul>
+ </div>
+ </li>
+ </ul>
+</div>
+</div>
+</body>
+<script>
+description('Test backtracking with multiple chains of child relations.');
+
+shouldBe('document.querySelectorAll("div>ul>li>div ul>li ul>li p").length', '1');
+shouldBeEqualToString('document.querySelectorAll("div>ul>li>div ul>li ul>li p")[0].id', 'target');
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorsquerySelectorsimpleadjacentbacktrackingexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/querySelector-simple-adjacent-backtracking-expected.txt (0 => 161839)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/querySelector-simple-adjacent-backtracking-expected.txt         (rev 0)
+++ trunk/LayoutTests/fast/selectors/querySelector-simple-adjacent-backtracking-expected.txt        2014-01-12 23:04:19 UTC (rev 161839)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+Test backtracking with a single direct adjacent relation.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS document.querySelectorAll("blockquote+li~li").length is 2
+PASS document.querySelectorAll("blockquote+li~li")[0].id is "target1"
+PASS document.querySelectorAll("blockquote+li~li")[1].id is "target2"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorsquerySelectorsimpleadjacentbacktrackinghtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/querySelector-simple-adjacent-backtracking.html (0 => 161839)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/querySelector-simple-adjacent-backtracking.html         (rev 0)
+++ trunk/LayoutTests/fast/selectors/querySelector-simple-adjacent-backtracking.html        2014-01-12 23:04:19 UTC (rev 161839)
</span><span class="lines">@@ -0,0 +1,27 @@
</span><ins>+<!doctype html>
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<div style="display:none">
+ <ul>
+ <li></li>
+ <div></div>
+ <li></li>
+ <blockquote></blockquote>
+ <li></li>
+ <li id=target1>Target 1</li>
+ <li id=target2>Target 2</li>
+ </ul>
+</div>
+</body>
+<script>
+description('Test backtracking with a single direct adjacent relation.');
+
+shouldBe('document.querySelectorAll("blockquote+li~li").length', '2');
+shouldBeEqualToString('document.querySelectorAll("blockquote+li~li")[0].id', 'target1');
+shouldBeEqualToString('document.querySelectorAll("blockquote+li~li")[1].id', 'target2');
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorsquerySelectorsimplechildbacktrackingexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/querySelector-simple-child-backtracking-expected.txt (0 => 161839)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/querySelector-simple-child-backtracking-expected.txt         (rev 0)
+++ trunk/LayoutTests/fast/selectors/querySelector-simple-child-backtracking-expected.txt        2014-01-12 23:04:19 UTC (rev 161839)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+Test backtracking with a single child selector relation.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS document.querySelectorAll("ul>li p").length is 2
+PASS document.querySelectorAll("ul>li p")[0].id is "target1"
+PASS document.querySelectorAll("ul>li p")[1].id is "target2"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastselectorsquerySelectorsimplechildbacktrackinghtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/selectors/querySelector-simple-child-backtracking.html (0 => 161839)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/selectors/querySelector-simple-child-backtracking.html         (rev 0)
+++ trunk/LayoutTests/fast/selectors/querySelector-simple-child-backtracking.html        2014-01-12 23:04:19 UTC (rev 161839)
</span><span class="lines">@@ -0,0 +1,36 @@
</span><ins>+<!doctype html>
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<div style="display:none">
+ <ul>
+ <li></li>
+ <li>
+ <ol>
+ <li></li>
+ <li><p id="target1">Target 1</p></li>
+ <li></li>
+ </ol>
+ </li>
+ <li></li>
+ </ul>
+ <ul>
+ <li>
+ <li>
+ <li><p id="target2">Target 2</p></li>
+ </li>
+ </li>
+ </ul>
+</div>
+</body>
+<script>
+description('Test backtracking with a single child selector relation.');
+
+shouldBe('document.querySelectorAll("ul>li p").length', '2');
+shouldBeEqualToString('document.querySelectorAll("ul>li p")[0].id', 'target1');
+shouldBeEqualToString('document.querySelectorAll("ul>li p")[1].id', 'target2');
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</html>
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (161838 => 161839)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-01-12 22:07:44 UTC (rev 161838)
+++ trunk/Source/WebCore/ChangeLog        2014-01-12 23:04:19 UTC (rev 161839)
</span><span class="lines">@@ -1,3 +1,26 @@
</span><ins>+2014-01-12 Benjamin Poulain <benjamin@webkit.org>
+
+ Use the Selector Code Generator for matching in SelectorQuery
+ https://bugs.webkit.org/show_bug.cgi?id=126185
+
+ Reviewed by Ryosuke Niwa.
+
+ Compile selectors on demand and use the generated binary to perform
+ element matching in SelectorQuery.
+
+ Tests: fast/selectors/querySelector-long-adjacent-backtracking.html
+ fast/selectors/querySelector-long-child-backtracking.html
+ fast/selectors/querySelector-mixed-child-adjacent-backtracking.html
+ fast/selectors/querySelector-multiple-simple-child-backtracking.html
+ fast/selectors/querySelector-simple-adjacent-backtracking.html
+ fast/selectors/querySelector-simple-child-backtracking.html
+
+ * dom/SelectorQuery.cpp:
+ (WebCore::SelectorDataList::executeCompiledSimpleSelectorChecker):
+ (WebCore::SelectorDataList::executeCompiledSelectorCheckerWithContext):
+ (WebCore::SelectorDataList::execute):
+ * dom/SelectorQuery.h:
+
</ins><span class="cx"> 2014-01-12 Anders Carlsson <andersca@apple.com>
</span><span class="cx">
</span><span class="cx"> Simplify creation of XMLHttpRequestStaticData
</span></span></pre></div>
<a id="trunkSourceWebCorecssjitSelectorCompilerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/cssjit/SelectorCompiler.h (161838 => 161839)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/cssjit/SelectorCompiler.h        2014-01-12 22:07:44 UTC (rev 161838)
+++ trunk/Source/WebCore/cssjit/SelectorCompiler.h        2014-01-12 23:04:19 UTC (rev 161839)
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> #if ENABLE(CSS_SELECTOR_JIT)
</span><span class="cx">
</span><span class="cx"> #include "SelectorChecker.h"
</span><ins>+#include <JavaScriptCore/MacroAssemblerCodeRef.h>
</ins><span class="cx">
</span><span class="cx"> namespace JSC {
</span><span class="cx"> class MacroAssemblerCodeRef;
</span></span></pre></div>
<a id="trunkSourceWebCoredomSelectorQuerycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/SelectorQuery.cpp (161838 => 161839)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/SelectorQuery.cpp        2014-01-12 22:07:44 UTC (rev 161838)
+++ trunk/Source/WebCore/dom/SelectorQuery.cpp        2014-01-12 23:04:19 UTC (rev 161839)
</span><span class="lines">@@ -266,7 +266,33 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+#if ENABLE(CSS_SELECTOR_JIT)
</ins><span class="cx"> template <typename SelectorQueryTrait>
</span><ins>+ALWAYS_INLINE void SelectorDataList::executeCompiledSimpleSelectorChecker(const ContainerNode& rootNode, SelectorCompiler::SimpleSelectorChecker selectorChecker, typename SelectorQueryTrait::OutputType& output) const
+{
+ for (auto& element : elementDescendants(const_cast<ContainerNode&>(rootNode))) {
+ if (selectorChecker(&element)) {
+ SelectorQueryTrait::appendOutputForElement(output, &element);
+ if (SelectorQueryTrait::shouldOnlyMatchFirstElement)
+ return;
+ }
+ }
+}
+
+template <typename SelectorQueryTrait>
+ALWAYS_INLINE void SelectorDataList::executeCompiledSelectorCheckerWithContext(const ContainerNode& rootNode, SelectorCompiler::SelectorCheckerWithCheckingContext selectorChecker, const SelectorCompiler::CheckingContext& context, typename SelectorQueryTrait::OutputType& output) const
+{
+ for (auto& element : elementDescendants(const_cast<ContainerNode&>(rootNode))) {
+ if (selectorChecker(&element, &context)) {
+ SelectorQueryTrait::appendOutputForElement(output, &element);
+ if (SelectorQueryTrait::shouldOnlyMatchFirstElement)
+ return;
+ }
+ }
+}
+#endif // ENABLE(CSS_SELECTOR_JIT)
+
+template <typename SelectorQueryTrait>
</ins><span class="cx"> ALWAYS_INLINE void SelectorDataList::execute(ContainerNode& rootNode, typename SelectorQueryTrait::OutputType& output) const
</span><span class="cx"> {
</span><span class="cx"> if (m_selectors.size() == 1) {
</span><span class="lines">@@ -277,8 +303,33 @@
</span><span class="cx"> executeSingleTagNameSelectorData<SelectorQueryTrait>(rootNode, selectorData, output);
</span><span class="cx"> else if (isSingleClassNameSelector(*selectorData.selector))
</span><span class="cx"> executeSingleClassNameSelectorData<SelectorQueryTrait>(rootNode, selectorData, output);
</span><del>- else
</del><ins>+ else {
+#if ENABLE(CSS_SELECTOR_JIT)
+ void* compiledSelectorChecker = selectorData.compiledSelectorCodeRef.code().executableAddress();
+ if (!compiledSelectorChecker && selectorData.compilationStatus == SelectorCompilationStatus::NotCompiled) {
+ JSC::VM* vm = rootNode.document().scriptExecutionContext()->vm();
+ selectorData.compilationStatus = SelectorCompiler::compileSelector(selectorData.selector, vm, selectorData.compiledSelectorCodeRef);
+ }
+
+ if (compiledSelectorChecker) {
+ if (selectorData.compilationStatus == SelectorCompilationStatus::SimpleSelectorChecker) {
+ SelectorCompiler::SimpleSelectorChecker selectorChecker = SelectorCompiler::simpleSelectorCheckerFunction(compiledSelectorChecker, selectorData.compilationStatus);
+ executeCompiledSimpleSelectorChecker<SelectorQueryTrait>(rootNode, selectorChecker, output);
+ } else {
+ ASSERT(selectorData.compilationStatus == SelectorCompilationStatus::SelectorCheckerWithCheckingContext);
+ SelectorCompiler::SelectorCheckerWithCheckingContext selectorChecker = SelectorCompiler::selectorCheckerFunctionWithCheckingContext(compiledSelectorChecker, selectorData.compilationStatus);
+
+ SelectorCompiler::CheckingContext context;
+ context.elementStyle = nullptr;
+ context.resolvingMode = SelectorChecker::QueryingRules;
+ executeCompiledSelectorCheckerWithContext<SelectorQueryTrait>(rootNode, selectorChecker, context, output);
+ }
+ return;
+ }
+#endif // ENABLE(CSS_SELECTOR_JIT)
+
</ins><span class="cx"> executeSingleSelectorData<SelectorQueryTrait>(rootNode, selectorData, output);
</span><ins>+ }
</ins><span class="cx"> return;
</span><span class="cx"> }
</span><span class="cx"> executeSingleMultiSelectorData<SelectorQueryTrait>(rootNode, output);
</span></span></pre></div>
<a id="trunkSourceWebCoredomSelectorQueryh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/SelectorQuery.h (161838 => 161839)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/SelectorQuery.h        2014-01-12 22:07:44 UTC (rev 161838)
+++ trunk/Source/WebCore/dom/SelectorQuery.h        2014-01-12 23:04:19 UTC (rev 161839)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx">
</span><span class="cx"> #include "CSSSelectorList.h"
</span><span class="cx"> #include "NodeList.h"
</span><ins>+#include "SelectorCompiler.h"
</ins><span class="cx"> #include <wtf/HashMap.h>
</span><span class="cx"> #include <wtf/Vector.h>
</span><span class="cx"> #include <wtf/text/AtomicStringHash.h>
</span><span class="lines">@@ -55,6 +56,11 @@
</span><span class="cx"> SelectorData(const CSSSelector* selector, bool isFastCheckable) : selector(selector), isFastCheckable(isFastCheckable) { }
</span><span class="cx"> const CSSSelector* selector;
</span><span class="cx"> bool isFastCheckable;
</span><ins>+
+#if ENABLE(CSS_SELECTOR_JIT)
+ mutable SelectorCompilationStatus compilationStatus;
+ mutable JSC::MacroAssemblerCodeRef compiledSelectorCodeRef;
+#endif // ENABLE(CSS_SELECTOR_JIT)
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> bool selectorMatches(const SelectorData&, Element&, const ContainerNode& rootNode) const;
</span><span class="lines">@@ -65,6 +71,10 @@
</span><span class="cx"> template <typename SelectorQueryTrait> void executeSingleClassNameSelectorData(const ContainerNode& rootNode, const SelectorData&, typename SelectorQueryTrait::OutputType&) const;
</span><span class="cx"> template <typename SelectorQueryTrait> void executeSingleSelectorData(const ContainerNode& rootNode, const SelectorData&, typename SelectorQueryTrait::OutputType&) const;
</span><span class="cx"> template <typename SelectorQueryTrait> void executeSingleMultiSelectorData(const ContainerNode& rootNode, typename SelectorQueryTrait::OutputType&) const;
</span><ins>+#if ENABLE(CSS_SELECTOR_JIT)
+ template <typename SelectorQueryTrait> void executeCompiledSimpleSelectorChecker(const ContainerNode& rootNode, SelectorCompiler::SimpleSelectorChecker, typename SelectorQueryTrait::OutputType&) const;
+ template <typename SelectorQueryTrait> void executeCompiledSelectorCheckerWithContext(const ContainerNode& rootNode, SelectorCompiler::SelectorCheckerWithCheckingContext, const SelectorCompiler::CheckingContext&, typename SelectorQueryTrait::OutputType&) const;
+#endif // ENABLE(CSS_SELECTOR_JIT)
</ins><span class="cx">
</span><span class="cx"> Vector<SelectorData> m_selectors;
</span><span class="cx"> };
</span></span></pre>
</div>
</div>
</body>
</html>