<!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>[208579] 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/208579">208579</a></dd>
<dt>Author</dt> <dd>utatane.tea@gmail.com</dd>
<dt>Date</dt> <dd>2016-11-10 22:08:18 -0800 (Thu, 10 Nov 2016)</dd>
</dl>
<h3>Log Message</h3>
<pre>[DOMJIT] Document#body should have DOMJIT patchpoint
https://bugs.webkit.org/show_bug.cgi?id=164627
Reviewed by Darin Adler.
Source/WebCore:
This patch implements document.body accessor. To implement it, we need,
1. DOM traversing ability from ASM.
2. Checking HTMLElement.
3. Checking HTMLElement's localName.
The above features are already implemented in CSSJIT.
We extract some of utilities from CSSJIT to share them with DOMJIT.
Test: js/dom/domjit-accessor-document-body.html
* cssjit/SelectorCompiler.cpp:
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateWalkToParentElement):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateWalkToNextAdjacentElement):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateWalkToPreviousAdjacentElement):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementAttributeMatching):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementAttributeValueExactMatching):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementAttributeFunctionCallValueMatching):
(WebCore::SelectorCompiler::jumpIfElementIsNotEmpty):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementHasTagName):
(WebCore::SelectorCompiler::testIsElementFlagOnNode): Deleted.
(WebCore::SelectorCompiler::testIsHTMLFlagOnNode): Deleted.
* dom/Document.idl:
* dom/Element.h:
* dom/QualifiedName.h:
* domjit/DOMJITAbstractHeapRepository.yaml:
* domjit/DOMJITHelpers.h:
(WebCore::DOMJIT::branchTestIsElementFlagOnNode):
(WebCore::DOMJIT::branchTestIsHTMLFlagOnNode):
* domjit/JSDocumentDOMJIT.cpp:
(WebCore::DocumentBodyDOMJIT::checkDOM):
(WebCore::loadLocalName):
(WebCore::DocumentBodyDOMJIT::callDOMGetter):
LayoutTests:
* js/dom/domjit-accessor-document-body-expected.txt: Added.
* js/dom/domjit-accessor-document-body.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="#trunkSourceWebCorecssjitSelectorCompilercpp">trunk/Source/WebCore/cssjit/SelectorCompiler.cpp</a></li>
<li><a href="#trunkSourceWebCoredomDocumentidl">trunk/Source/WebCore/dom/Document.idl</a></li>
<li><a href="#trunkSourceWebCoredomElementh">trunk/Source/WebCore/dom/Element.h</a></li>
<li><a href="#trunkSourceWebCoredomQualifiedNameh">trunk/Source/WebCore/dom/QualifiedName.h</a></li>
<li><a href="#trunkSourceWebCoredomjitDOMJITAbstractHeapRepositoryyaml">trunk/Source/WebCore/domjit/DOMJITAbstractHeapRepository.yaml</a></li>
<li><a href="#trunkSourceWebCoredomjitDOMJITHelpersh">trunk/Source/WebCore/domjit/DOMJITHelpers.h</a></li>
<li><a href="#trunkSourceWebCoredomjitJSDocumentDOMJITcpp">trunk/Source/WebCore/domjit/JSDocumentDOMJIT.cpp</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsjsdomdomjitaccessordocumentbodyexpectedtxt">trunk/LayoutTests/js/dom/domjit-accessor-document-body-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsdomdomjitaccessordocumentbodyhtml">trunk/LayoutTests/js/dom/domjit-accessor-document-body.html</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (208578 => 208579)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-11-11 04:37:06 UTC (rev 208578)
+++ trunk/LayoutTests/ChangeLog        2016-11-11 06:08:18 UTC (rev 208579)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2016-11-10 Yusuke Suzuki <utatane.tea@gmail.com>
+
+ [DOMJIT] Document#body should have DOMJIT patchpoint
+ https://bugs.webkit.org/show_bug.cgi?id=164627
+
+ Reviewed by Darin Adler.
+
+ * js/dom/domjit-accessor-document-body-expected.txt: Added.
+ * js/dom/domjit-accessor-document-body.html: Added.
+
</ins><span class="cx"> 2016-11-10 John Wilander <wilander@apple.com>
</span><span class="cx">
</span><span class="cx"> Add link information to data transfer pasteboard for drag and drop links
</span></span></pre></div>
<a id="trunkLayoutTestsjsdomdomjitaccessordocumentbodyexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/dom/domjit-accessor-document-body-expected.txt (0 => 208579)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/dom/domjit-accessor-document-body-expected.txt         (rev 0)
+++ trunk/LayoutTests/js/dom/domjit-accessor-document-body-expected.txt        2016-11-11 06:08:18 UTC (rev 208579)
</span><span class="lines">@@ -0,0 +1,79 @@
</span><ins>+Test DOMJIT document.body accessor works.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+PASS (
+ function testHTMLDocument(element, result)
+ {
+ for (var i = 0; i < 1e4; ++i) {
+ if (element.body !== result)
+ return false;
+ }
+ return true;
+ }
+ )(target, result) is true
+PASS (
+ function testXMLDocument(element, result)
+ {
+ for (var i = 0; i < 1e4; ++i) {
+ if (element.body !== result)
+ return false;
+ }
+ return true;
+ }
+ )(target, result) is true
+PASS (
+ function testXMLDocument2(element, result)
+ {
+ for (var i = 0; i < 1e4; ++i) {
+ if (element.body !== result)
+ return false;
+ }
+ return true;
+ }
+ )(target, result) is true
+PASS (
+ function testNull(element, result)
+ {
+ for (var i = 0; i < 1e4; ++i) {
+ if (element.body !== result)
+ return false;
+ }
+ return true;
+ }
+ )(target, result) is true
+PASS (
+ function testHTMLElement(element, result)
+ {
+ for (var i = 0; i < 1e4; ++i) {
+ if (element.body !== result)
+ return false;
+ }
+ return true;
+ }
+ )(target, result) is true
+PASS (
+ function testNoHTML(element, result)
+ {
+ for (var i = 0; i < 1e4; ++i) {
+ if (element.body !== result)
+ return false;
+ }
+ return true;
+ }
+ )(target, result) is true
+PASS (
+ function testFrameset(element, result)
+ {
+ for (var i = 0; i < 1e4; ++i) {
+ if (element.body !== result)
+ return false;
+ }
+ return true;
+ }
+ )(target, result) is true
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsdomdomjitaccessordocumentbodyhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/dom/domjit-accessor-document-body.html (0 => 208579)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/dom/domjit-accessor-document-body.html         (rev 0)
+++ trunk/LayoutTests/js/dom/domjit-accessor-document-body.html        2016-11-11 06:08:18 UTC (rev 208579)
</span><span class="lines">@@ -0,0 +1,78 @@
</span><ins>+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<iframe id="xmlframe" onload="frameLoaded()" style="height:0px" src="data:application/xhtml+xml,<?xml version='1.0' encoding='UTF-8'?><body/>"></iframe>
+<iframe id="xmlframe2" onload="frameLoaded()" style="height:0px" src="data:application/xhtml+xml,<?xml version='1.0' encoding='UTF-8'?><body/>"></iframe>
+<script>
+description('Test DOMJIT document.body accessor works.');
+
+if (window.testRunner)
+ testRunner.waitUntilDone();
+
+var target = null;
+var result = null;
+function runTest()
+{
+ var xmlDocument = document.getElementById('xmlframe').contentDocument;
+ var xmlDocument2 = document.getElementById('xmlframe2').contentDocument;
+ var html = document.createElement('html');
+ var body = document.createElement('body');
+
+ var htmlOnly = document.implementation.createDocument('', null, null);
+ htmlOnly.appendChild(htmlOnly.createElement('html'));
+
+ var noHTML = document.implementation.createDocument('', null, null);
+ var first = noHTML.createElement('nohtml');
+ first.appendChild(noHTML.createElement('body'));
+ noHTML.appendChild(first);
+
+ var framesetDoc = document.implementation.createDocument('', null, null);
+ var first = document.createElement('html');
+ var frameset = document.createElement('frameset');
+ first.appendChild(frameset);
+ framesetDoc.appendChild(first);
+
+ var targets = [
+ ['HTMLDocument', document, document.getElementsByTagName('body')[0]],
+ ['XMLDocument', xmlDocument, null],
+ ['XMLDocument2', xmlDocument2, body],
+ ['Null', document.implementation.createDocument('', null, null), null],
+ ['HTMLElement', htmlOnly, null],
+ ['NoHTML', noHTML, null],
+ ['Frameset', framesetDoc, frameset],
+ ];
+
+ // Put HTMLBodyElement in XMLDocument!
+ html.appendChild(body);
+ xmlDocument2.replaceChild(html, xmlDocument2.firstChild);
+
+ for ([name, target, result] of targets) {
+ var text = `
+ function test${name}(element, result)
+ {
+ for (var i = 0; i < 1e4; ++i) {
+ if (element.body !== result)
+ return false;
+ }
+ return true;
+ }
+ `;
+ shouldBeTrue(`(${text})(target, result)`);
+ }
+
+ if (window.testRunner)
+ testRunner.notifyDone();
+}
+var count = 0;
+function frameLoaded()
+{
+ if (++count === 2)
+ runTest();
+}
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (208578 => 208579)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-11-11 04:37:06 UTC (rev 208578)
+++ trunk/Source/WebCore/ChangeLog        2016-11-11 06:08:18 UTC (rev 208579)
</span><span class="lines">@@ -1,3 +1,44 @@
</span><ins>+2016-11-10 Yusuke Suzuki <utatane.tea@gmail.com>
+
+ [DOMJIT] Document#body should have DOMJIT patchpoint
+ https://bugs.webkit.org/show_bug.cgi?id=164627
+
+ Reviewed by Darin Adler.
+
+ This patch implements document.body accessor. To implement it, we need,
+
+ 1. DOM traversing ability from ASM.
+ 2. Checking HTMLElement.
+ 3. Checking HTMLElement's localName.
+
+ The above features are already implemented in CSSJIT.
+ We extract some of utilities from CSSJIT to share them with DOMJIT.
+
+ Test: js/dom/domjit-accessor-document-body.html
+
+ * cssjit/SelectorCompiler.cpp:
+ (WebCore::SelectorCompiler::SelectorCodeGenerator::generateWalkToParentElement):
+ (WebCore::SelectorCompiler::SelectorCodeGenerator::generateWalkToNextAdjacentElement):
+ (WebCore::SelectorCompiler::SelectorCodeGenerator::generateWalkToPreviousAdjacentElement):
+ (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementAttributeMatching):
+ (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementAttributeValueExactMatching):
+ (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementAttributeFunctionCallValueMatching):
+ (WebCore::SelectorCompiler::jumpIfElementIsNotEmpty):
+ (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementHasTagName):
+ (WebCore::SelectorCompiler::testIsElementFlagOnNode): Deleted.
+ (WebCore::SelectorCompiler::testIsHTMLFlagOnNode): Deleted.
+ * dom/Document.idl:
+ * dom/Element.h:
+ * dom/QualifiedName.h:
+ * domjit/DOMJITAbstractHeapRepository.yaml:
+ * domjit/DOMJITHelpers.h:
+ (WebCore::DOMJIT::branchTestIsElementFlagOnNode):
+ (WebCore::DOMJIT::branchTestIsHTMLFlagOnNode):
+ * domjit/JSDocumentDOMJIT.cpp:
+ (WebCore::DocumentBodyDOMJIT::checkDOM):
+ (WebCore::loadLocalName):
+ (WebCore::DocumentBodyDOMJIT::callDOMGetter):
+
</ins><span class="cx"> 2016-11-10 John Wilander <wilander@apple.com>
</span><span class="cx">
</span><span class="cx"> Remove unused parameter name to fix build error on iOS
</span></span></pre></div>
<a id="trunkSourceWebCorecssjitSelectorCompilercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/cssjit/SelectorCompiler.cpp (208578 => 208579)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/cssjit/SelectorCompiler.cpp        2016-11-11 04:37:06 UTC (rev 208578)
+++ trunk/Source/WebCore/cssjit/SelectorCompiler.cpp        2016-11-11 06:08:18 UTC (rev 208579)
</span><span class="lines">@@ -2021,11 +2021,6 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><del>-static inline Assembler::Jump testIsElementFlagOnNode(Assembler::ResultCondition condition, Assembler& assembler, Assembler::RegisterID nodeAddress)
-{
- return assembler.branchTest32(condition, Assembler::Address(nodeAddress, Node::nodeFlagsMemoryOffset()), Assembler::TrustedImm32(Node::flagIsElement()));
-}
-
</del><span class="cx"> void SelectorCodeGenerator::generateRightmostTreeWalker(Assembler::JumpList& failureCases, const SelectorFragment& fragment)
</span><span class="cx"> {
</span><span class="cx"> generateElementMatching(failureCases, failureCases, fragment);
</span><span class="lines">@@ -2043,7 +2038,7 @@
</span><span class="cx"> // failure
</span><span class="cx"> generateWalkToParentNode(targetRegister);
</span><span class="cx"> failureCases.append(m_assembler.branchTestPtr(Assembler::Zero, targetRegister));
</span><del>- failureCases.append(testIsElementFlagOnNode(Assembler::Zero, m_assembler, targetRegister));
</del><ins>+ failureCases.append(DOMJIT::branchTestIsElementFlagOnNode(m_assembler, Assembler::Zero, targetRegister));
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void SelectorCodeGenerator::generateParentElementTreeWalker(Assembler::JumpList& failureCases, const SelectorFragment& fragment)
</span><span class="lines">@@ -2096,7 +2091,7 @@
</span><span class="cx"> Assembler::Label loopStart = m_assembler.label();
</span><span class="cx"> m_assembler.loadPtr(Assembler::Address(workRegister, Node::nextSiblingMemoryOffset()), workRegister);
</span><span class="cx"> failureCases.append(m_assembler.branchTestPtr(Assembler::Zero, workRegister));
</span><del>- testIsElementFlagOnNode(Assembler::Zero, m_assembler, workRegister).linkTo(loopStart, &m_assembler);
</del><ins>+ DOMJIT::branchTestIsElementFlagOnNode(m_assembler, Assembler::Zero, workRegister).linkTo(loopStart, &m_assembler);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> inline void SelectorCodeGenerator::generateWalkToPreviousAdjacentElement(Assembler::JumpList& failureCases, Assembler::RegisterID workRegister)
</span><span class="lines">@@ -2104,7 +2099,7 @@
</span><span class="cx"> Assembler::Label loopStart = m_assembler.label();
</span><span class="cx"> m_assembler.loadPtr(Assembler::Address(workRegister, Node::previousSiblingMemoryOffset()), workRegister);
</span><span class="cx"> failureCases.append(m_assembler.branchTestPtr(Assembler::Zero, workRegister));
</span><del>- testIsElementFlagOnNode(Assembler::Zero, m_assembler, workRegister).linkTo(loopStart, &m_assembler);
</del><ins>+ DOMJIT::branchTestIsElementFlagOnNode(m_assembler, Assembler::Zero, workRegister).linkTo(loopStart, &m_assembler);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void SelectorCodeGenerator::generateWalkToPreviousAdjacent(Assembler::JumpList& failureCases, const SelectorFragment& fragment)
</span><span class="lines">@@ -2651,11 +2646,6 @@
</span><span class="cx"> generateElementIsLink(failureCases);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-static inline Assembler::Jump testIsHTMLFlagOnNode(Assembler::ResultCondition condition, Assembler& assembler, Assembler::RegisterID nodeAddress)
-{
- return assembler.branchTest32(condition, Assembler::Address(nodeAddress, Node::nodeFlagsMemoryOffset()), Assembler::TrustedImm32(Node::flagIsHTML()));
-}
-
</del><span class="cx"> static inline bool canMatchStyleAttribute(const SelectorFragment& fragment)
</span><span class="cx"> {
</span><span class="cx"> for (unsigned i = 0; i < fragment.attributes.size(); ++i) {
</span><span class="lines">@@ -2798,7 +2788,7 @@
</span><span class="cx"> m_assembler.move(Assembler::TrustedImmPtr(canonicalLocalName), localNameToMatch);
</span><span class="cx"> else {
</span><span class="cx"> m_assembler.move(Assembler::TrustedImmPtr(canonicalLocalName), localNameToMatch);
</span><del>- Assembler::Jump elementIsHTML = testIsHTMLFlagOnNode(Assembler::NonZero, m_assembler, elementAddressRegister);
</del><ins>+ Assembler::Jump elementIsHTML = DOMJIT::branchTestIsHTMLFlagOnNode(m_assembler, Assembler::NonZero, elementAddressRegister);
</ins><span class="cx"> m_assembler.move(Assembler::TrustedImmPtr(localName), localNameToMatch);
</span><span class="cx"> elementIsHTML.link(&m_assembler);
</span><span class="cx"> }
</span><span class="lines">@@ -2980,7 +2970,7 @@
</span><span class="cx"> // If the element is an HTML element, in a HTML dcoument (not including XHTML), value matching is case insensitive.
</span><span class="cx"> // Taking the contrapositive, if we find the element is not HTML or is not in a HTML document, the condition above
</span><span class="cx"> // sould be sufficient and we can fail early.
</span><del>- failureCases.append(testIsHTMLFlagOnNode(Assembler::Zero, m_assembler, elementAddressRegister));
</del><ins>+ failureCases.append(DOMJIT::branchTestIsHTMLFlagOnNode(m_assembler, Assembler::Zero, elementAddressRegister));
</ins><span class="cx">
</span><span class="cx"> {
</span><span class="cx"> LocalRegister document(m_registerAllocator);
</span><span class="lines">@@ -3030,7 +3020,7 @@
</span><span class="cx"> }
</span><span class="cx"> case AttributeCaseSensitivity::HTMLLegacyCaseInsensitive: {
</span><span class="cx"> Assembler::JumpList shouldUseCaseSensitiveComparison;
</span><del>- shouldUseCaseSensitiveComparison.append(testIsHTMLFlagOnNode(Assembler::Zero, m_assembler, elementAddressRegister));
</del><ins>+ shouldUseCaseSensitiveComparison.append(DOMJIT::branchTestIsHTMLFlagOnNode(m_assembler, Assembler::Zero, elementAddressRegister));
</ins><span class="cx"> {
</span><span class="cx"> LocalRegister scratchRegister(m_registerAllocator);
</span><span class="cx"> // scratchRegister = pointer to treeScope.
</span><span class="lines">@@ -3116,7 +3106,7 @@
</span><span class="cx"> Assembler::Label loopStart(assembler.label());
</span><span class="cx"> Assembler::Jump noMoreChildren = assembler.branchTestPtr(Assembler::Zero, currentChild);
</span><span class="cx">
</span><del>- notEmptyCases.append(testIsElementFlagOnNode(Assembler::NonZero, assembler, currentChild));
</del><ins>+ notEmptyCases.append(DOMJIT::branchTestIsElementFlagOnNode(assembler, Assembler::NonZero, currentChild));
</ins><span class="cx">
</span><span class="cx"> {
</span><span class="cx"> Assembler::Jump skipTextNodeCheck = assembler.branchTest32(Assembler::Zero, Assembler::Address(currentChild, Node::nodeFlagsMemoryOffset()), Assembler::TrustedImm32(Node::flagIsText()));
</span><span class="lines">@@ -3411,7 +3401,7 @@
</span><span class="cx"> failureCases.append(m_assembler.branchPtr(Assembler::NotEqual, Assembler::Address(qualifiedNameImpl, QualifiedName::QualifiedNameImpl::localNameMemoryOffset()), constantRegister));
</span><span class="cx"> } else {
</span><span class="cx"> Assembler::JumpList caseSensitiveCases;
</span><del>- caseSensitiveCases.append(testIsHTMLFlagOnNode(Assembler::Zero, m_assembler, elementAddressRegister));
</del><ins>+ caseSensitiveCases.append(DOMJIT::branchTestIsHTMLFlagOnNode(m_assembler, Assembler::Zero, elementAddressRegister));
</ins><span class="cx"> {
</span><span class="cx"> LocalRegister document(m_registerAllocator);
</span><span class="cx"> DOMJIT::loadDocument(m_assembler, elementAddressRegister, document);
</span></span></pre></div>
<a id="trunkSourceWebCoredomDocumentidl"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Document.idl (208578 => 208579)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Document.idl        2016-11-11 04:37:06 UTC (rev 208578)
+++ trunk/Source/WebCore/dom/Document.idl        2016-11-11 06:08:18 UTC (rev 208579)
</span><span class="lines">@@ -101,7 +101,7 @@
</span><span class="cx">
</span><span class="cx"> [GetterMayThrowException, SetterMayThrowException] attribute USVString cookie;
</span><span class="cx">
</span><del>- [CEReactions, ImplementedAs=bodyOrFrameset, SetterMayThrowException] attribute HTMLElement? body;
</del><ins>+ [CEReactions, DOMJIT, ImplementedAs=bodyOrFrameset, SetterMayThrowException] attribute HTMLElement? body;
</ins><span class="cx">
</span><span class="cx"> readonly attribute HTMLHeadElement? head;
</span><span class="cx"> readonly attribute HTMLCollection images;
</span></span></pre></div>
<a id="trunkSourceWebCoredomElementh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Element.h (208578 => 208579)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Element.h        2016-11-11 04:37:06 UTC (rev 208578)
+++ trunk/Source/WebCore/dom/Element.h        2016-11-11 06:08:18 UTC (rev 208579)
</span><span class="lines">@@ -202,9 +202,9 @@
</span><span class="cx"> virtual CSSStyleDeclaration* cssomStyle();
</span><span class="cx">
</span><span class="cx"> const QualifiedName& tagQName() const { return m_tagName; }
</span><del>-#if ENABLE(CSS_SELECTOR_JIT)
</del><ins>+#if ENABLE(JIT)
</ins><span class="cx"> static ptrdiff_t tagQNameMemoryOffset() { return OBJECT_OFFSETOF(Element, m_tagName); }
</span><del>-#endif // ENABLE(CSS_SELECTOR_JIT)
</del><ins>+#endif // ENABLE(JIT)
</ins><span class="cx"> String tagName() const { return nodeName(); }
</span><span class="cx"> bool hasTagName(const QualifiedName& tagName) const { return m_tagName.matches(tagName); }
</span><span class="cx"> bool hasTagName(const HTMLQualifiedName& tagName) const { return ContainerNode::hasTagName(tagName); }
</span></span></pre></div>
<a id="trunkSourceWebCoredomQualifiedNameh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/QualifiedName.h (208578 => 208579)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/QualifiedName.h        2016-11-11 04:37:06 UTC (rev 208578)
+++ trunk/Source/WebCore/dom/QualifiedName.h        2016-11-11 06:08:18 UTC (rev 208579)
</span><span class="lines">@@ -53,10 +53,10 @@
</span><span class="cx"> const AtomicString m_namespace;
</span><span class="cx"> mutable AtomicString m_localNameUpper;
</span><span class="cx">
</span><del>-#if ENABLE(CSS_SELECTOR_JIT)
</del><ins>+#if ENABLE(JIT)
</ins><span class="cx"> static ptrdiff_t localNameMemoryOffset() { return OBJECT_OFFSETOF(QualifiedNameImpl, m_localName); }
</span><span class="cx"> static ptrdiff_t namespaceMemoryOffset() { return OBJECT_OFFSETOF(QualifiedNameImpl, m_namespace); }
</span><del>-#endif // ENABLE(CSS_SELECTOR_JIT)
</del><ins>+#endif // ENABLE(JIT)
</ins><span class="cx">
</span><span class="cx"> private:
</span><span class="cx"> QualifiedNameImpl(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI)
</span><span class="lines">@@ -94,9 +94,9 @@
</span><span class="cx"> WEBCORE_EXPORT String toString() const;
</span><span class="cx">
</span><span class="cx"> QualifiedNameImpl* impl() const { return m_impl.get(); }
</span><del>-#if ENABLE(CSS_SELECTOR_JIT)
</del><ins>+#if ENABLE(JIT)
</ins><span class="cx"> static ptrdiff_t implMemoryOffset() { return OBJECT_OFFSETOF(QualifiedName, m_impl); }
</span><del>-#endif // ENABLE(CSS_SELECTOR_JIT)
</del><ins>+#endif // ENABLE(JIT)
</ins><span class="cx">
</span><span class="cx"> // Init routine for globals
</span><span class="cx"> static void init();
</span></span></pre></div>
<a id="trunkSourceWebCoredomjitDOMJITAbstractHeapRepositoryyaml"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/domjit/DOMJITAbstractHeapRepository.yaml (208578 => 208579)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/domjit/DOMJITAbstractHeapRepository.yaml        2016-11-11 04:37:06 UTC (rev 208578)
+++ trunk/Source/WebCore/domjit/DOMJITAbstractHeapRepository.yaml        2016-11-11 06:08:18 UTC (rev 208579)
</span><span class="lines">@@ -9,3 +9,4 @@
</span><span class="cx"> - Node_ownerDocument
</span><span class="cx"> Document:
</span><span class="cx"> - Document_documentElement
</span><ins>+ - Document_body
</ins></span></pre></div>
<a id="trunkSourceWebCoredomjitDOMJITHelpersh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/domjit/DOMJITHelpers.h (208578 => 208579)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/domjit/DOMJITHelpers.h        2016-11-11 04:37:06 UTC (rev 208578)
+++ trunk/Source/WebCore/domjit/DOMJITHelpers.h        2016-11-11 06:08:18 UTC (rev 208579)
</span><span class="lines">@@ -27,7 +27,7 @@
</span><span class="cx"> #pragma once
</span><span class="cx">
</span><span class="cx"> #include "JSDOMWrapper.h"
</span><del>-#include "ScriptWrappable.h"
</del><ins>+#include "Node.h"
</ins><span class="cx"> #include <domjit/DOMJITPatchpoint.h>
</span><span class="cx"> #include <domjit/DOMJITPatchpointParams.h>
</span><span class="cx"> #include <interpreter/FrameTracers.h>
</span><span class="lines">@@ -175,6 +175,16 @@
</span><span class="cx"> void loadDocument(MacroAssembler&, GPRReg node, GPRReg output);
</span><span class="cx"> void loadDocumentElement(MacroAssembler&, GPRReg document, GPRReg output);
</span><span class="cx">
</span><ins>+inline CCallHelpers::Jump branchTestIsElementFlagOnNode(MacroAssembler& jit, CCallHelpers::ResultCondition condition, GPRReg nodeAddress)
+{
+ return jit.branchTest32(condition, CCallHelpers::Address(nodeAddress, Node::nodeFlagsMemoryOffset()), CCallHelpers::TrustedImm32(Node::flagIsElement()));
+}
+
+inline CCallHelpers::Jump branchTestIsHTMLFlagOnNode(MacroAssembler& jit, CCallHelpers::ResultCondition condition, GPRReg nodeAddress)
+{
+ return jit.branchTest32(condition, CCallHelpers::Address(nodeAddress, Node::nodeFlagsMemoryOffset()), CCallHelpers::TrustedImm32(Node::flagIsHTML()));
+}
+
</ins><span class="cx"> } }
</span><span class="cx">
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCoredomjitJSDocumentDOMJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/domjit/JSDocumentDOMJIT.cpp (208578 => 208579)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/domjit/JSDocumentDOMJIT.cpp        2016-11-11 04:37:06 UTC (rev 208578)
+++ trunk/Source/WebCore/domjit/JSDocumentDOMJIT.cpp        2016-11-11 06:08:18 UTC (rev 208579)
</span><span class="lines">@@ -34,6 +34,7 @@
</span><span class="cx"> #include "Document.h"
</span><span class="cx"> #include "JSDOMWrapper.h"
</span><span class="cx"> #include "JSElement.h"
</span><ins>+#include "JSHTMLElement.h"
</ins><span class="cx"> #include <domjit/DOMJITPatchpoint.h>
</span><span class="cx"> #include <domjit/DOMJITPatchpointParams.h>
</span><span class="cx">
</span><span class="lines">@@ -73,6 +74,78 @@
</span><span class="cx"> return patchpoint;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+Ref<JSC::DOMJIT::Patchpoint> DocumentBodyDOMJIT::checkDOM()
+{
+ return DOMJIT::checkDOM<Document>();
</ins><span class="cx"> }
</span><span class="cx">
</span><ins>+static void loadLocalName(CCallHelpers& jit, GPRReg htmlElement, GPRReg localNameImpl)
+{
+ jit.loadPtr(CCallHelpers::Address(htmlElement, Element::tagQNameMemoryOffset() + QualifiedName::implMemoryOffset()), localNameImpl);
+ jit.loadPtr(CCallHelpers::Address(localNameImpl, QualifiedName::QualifiedNameImpl::localNameMemoryOffset()), localNameImpl);
+}
+
+Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> DocumentBodyDOMJIT::callDOMGetter()
+{
+ Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> patchpoint = JSC::DOMJIT::CallDOMGetterPatchpoint::create();
+ patchpoint->numGPScratchRegisters = 2;
+ patchpoint->setGenerator([=](CCallHelpers& jit, JSC::DOMJIT::PatchpointParams& params) {
+ JSValueRegs result = params[0].jsValueRegs();
+ GPRReg document = params[1].gpr();
+ GPRReg globalObject = params[2].gpr();
+ JSValue globalObjectValue = params[2].value();
+ GPRReg scratch1 = params.gpScratch(0);
+ GPRReg scratch2 = params.gpScratch(1);
+
+ jit.loadPtr(CCallHelpers::Address(document, JSDocument::offsetOfWrapped()), scratch1);
+ DOMJIT::loadDocumentElement(jit, scratch1, scratch1);
+
+ CCallHelpers::JumpList nullCases;
+ CCallHelpers::JumpList successCases;
+ nullCases.append(jit.branchTestPtr(CCallHelpers::Zero, scratch1));
+ nullCases.append(DOMJIT::branchTestIsHTMLFlagOnNode(jit, CCallHelpers::Zero, scratch1));
+ // We ensured that the name of the given element is HTML qualified.
+ // It allows us to perform local name comparison!
+ loadLocalName(jit, scratch1, scratch2);
+ nullCases.append(jit.branchPtr(CCallHelpers::NotEqual, scratch2, CCallHelpers::TrustedImmPtr(HTMLNames::htmlTag.localName().impl())));
+
+ RELEASE_ASSERT(!CAST_OFFSET(Node*, ContainerNode*));
+ RELEASE_ASSERT(!CAST_OFFSET(Node*, Element*));
+ RELEASE_ASSERT(!CAST_OFFSET(Node*, HTMLElement*));
+
+ // Node* node = current.firstChild();
+ // while (node && !is<HTMLElement>(*node))
+ // node = node->nextSibling();
+ // return downcast<HTMLElement>(node);
+ jit.loadPtr(CCallHelpers::Address(scratch1, ContainerNode::firstChildMemoryOffset()), scratch1);
+
+ CCallHelpers::Label loopStart = jit.label();
+ nullCases.append(jit.branchTestPtr(CCallHelpers::Zero, scratch1));
+ auto notHTMLElementCase = DOMJIT::branchTestIsHTMLFlagOnNode(jit, CCallHelpers::Zero, scratch1);
+ // We ensured that the name of the given element is HTML qualified.
+ // It allows us to perform local name comparison!
+ loadLocalName(jit, scratch1, scratch2);
+ successCases.append(jit.branchPtr(CCallHelpers::Equal, scratch2, CCallHelpers::TrustedImmPtr(HTMLNames::bodyTag.localName().impl())));
+ successCases.append(jit.branchPtr(CCallHelpers::Equal, scratch2, CCallHelpers::TrustedImmPtr(HTMLNames::framesetTag.localName().impl())));
+
+ notHTMLElementCase.link(&jit);
+ jit.loadPtr(CCallHelpers::Address(scratch1, Node::nextSiblingMemoryOffset()), scratch1);
+ jit.jump().linkTo(loopStart, &jit);
+
+ successCases.link(&jit);
+ DOMJIT::toWrapper<HTMLElement>(jit, params, scratch1, globalObject, result, DOMJIT::toWrapperSlow<HTMLElement>, globalObjectValue);
+ auto done = jit.jump();
+
+ nullCases.link(&jit);
+ jit.moveValue(jsNull(), result);
+ done.link(&jit);
+
+ return CCallHelpers::JumpList();
+ });
+ patchpoint->effect = JSC::DOMJIT::Effect::forDef(DOMJIT::AbstractHeapRepository::Document_body);
+ return patchpoint;
+}
+
+}
+
</ins><span class="cx"> #endif
</span></span></pre>
</div>
</div>
</body>
</html>