<!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>[234713] trunk/Source/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/234713">234713</a></dd>
<dt>Author</dt> <dd>msaboff@apple.com</dd>
<dt>Date</dt> <dd>2018-08-08 15:42:30 -0700 (Wed, 08 Aug 2018)</dd>
</dl>

<h3>Log Message</h3>
<pre>Yarr JIT should include annotations with dumpDisassembly=true
https://bugs.webkit.org/show_bug.cgi?id=188415

Reviewed by Yusuke Suzuki.

Created a YarrDisassembler class that handles annotations similar to the baseline JIT.
Given that the Yarr creates matching code bu going through the YarrPattern ops forward and
then the backtracking code through the YarrPattern ops in reverse order, the disassembler
needs to do the same think.

Restructured some of the logging code in YarrPattern to eliminate redundent code and factor
out simple methods for what was needed by the YarrDisassembler.

Here is abbreviated sample output after this change.

Generated JIT code for 8-bit regular expression /ab*c/:
    Code at [0x469561c03720, 0x469561c03840):
        0x469561c03720: push %rbp
        0x469561c03721: mov %rsp, %rbp
        ...
        0x469561c03762: sub $0x40, %rsp
     == Matching ==
   0:OpBodyAlternativeBegin minimum size 2
        0x469561c03766: add $0x2, %esi
        0x469561c03769: cmp %edx, %esi
        0x469561c0376b: ja 0x469561c037fa
   1:OpTerm TypePatternCharacter 'a'
        0x469561c03771: movzx -0x2(%rdi,%rsi), %eax
        0x469561c03776: cmp $0x61, %eax
        0x469561c03779: jnz 0x469561c037e9
   2:OpTerm TypePatternCharacter 'b' {0,...} greedy
        0x469561c0377f: xor %r9d, %r9d
        0x469561c03782: cmp %edx, %esi
        0x469561c03784: jz 0x469561c037a2
        ...
        0x469561c0379d: jmp 0x469561c03782
        0x469561c037a2: mov %<a href="http://trac.webkit.org/projects/webkit/changeset/9">r9</a>, 0x8(%rsp)
   3:OpTerm TypePatternCharacter 'c'
        0x469561c037a7: movzx -0x1(%rdi,%rsi), %eax
        0x469561c037ac: cmp $0x63, %eax
        0x469561c037af: jnz 0x469561c037d1
   4:OpBodyAlternativeEnd
        0x469561c037b5: add $0x40, %rsp
        ...
        0x469561c037cf: pop %rbp
        0x469561c037d0: ret
     == Backtracking ==
   4:OpBodyAlternativeEnd
   3:OpTerm TypePatternCharacter 'c'
   2:OpTerm TypePatternCharacter 'b' {0,...} greedy
        0x469561c037d1: mov 0x8(%rsp), %<a href="http://trac.webkit.org/projects/webkit/changeset/9">r9</a>
        ...
        0x469561c037e4: jmp 0x469561c037a2
   1:OpTerm TypePatternCharacter 'a'
   0:OpBodyAlternativeBegin minimum size 2
        0x469561c037e9: mov %rsi, %rax
        ...
        0x469561c0382f: pop %rbp
        0x469561c03830: ret

* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* runtime/RegExp.cpp:
(JSC::RegExp::compile):
(JSC::RegExp::compileMatchOnly):
* yarr/YarrDisassembler.cpp: Added.
(JSC::Yarr::YarrDisassembler::indentString):
(JSC::Yarr::YarrDisassembler::YarrDisassembler):
(JSC::Yarr::YarrDisassembler::~YarrDisassembler):
(JSC::Yarr::YarrDisassembler::dump):
(JSC::Yarr::YarrDisassembler::dumpHeader):
(JSC::Yarr::YarrDisassembler::dumpVectorForInstructions):
(JSC::Yarr::YarrDisassembler::dumpForInstructions):
(JSC::Yarr::YarrDisassembler::dumpDisassembly):
* yarr/YarrDisassembler.h: Added.
(JSC::Yarr::YarrJITInfo::~YarrJITInfo):
(JSC::Yarr::YarrDisassembler::setStartOfCode):
(JSC::Yarr::YarrDisassembler::setForGenerate):
(JSC::Yarr::YarrDisassembler::setForBacktrack):
(JSC::Yarr::YarrDisassembler::setEndOfGenerate):
(JSC::Yarr::YarrDisassembler::setEndOfBacktrack):
(JSC::Yarr::YarrDisassembler::setEndOfCode):
(JSC::Yarr::YarrDisassembler::indentString):
* yarr/YarrJIT.cpp:
(JSC::Yarr::YarrGenerator::generate):
(JSC::Yarr::YarrGenerator::backtrack):
(JSC::Yarr::YarrGenerator::YarrGenerator):
(JSC::Yarr::YarrGenerator::compile):
(JSC::Yarr::jitCompile):
* yarr/YarrJIT.h:
* yarr/YarrPattern.cpp:
(JSC::Yarr::dumpCharacterClass):
(JSC::Yarr::PatternTerm::dump):
(JSC::Yarr::YarrPattern::dumpPatternString):
(JSC::Yarr::YarrPattern::dumpPattern):
* yarr/YarrPattern.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCoreSourcestxt">trunk/Source/JavaScriptCore/Sources.txt</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeRegExpcpp">trunk/Source/JavaScriptCore/runtime/RegExp.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreyarrYarrJITcpp">trunk/Source/JavaScriptCore/yarr/YarrJIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreyarrYarrJITh">trunk/Source/JavaScriptCore/yarr/YarrJIT.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreyarrYarrPatterncpp">trunk/Source/JavaScriptCore/yarr/YarrPattern.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreyarrYarrPatternh">trunk/Source/JavaScriptCore/yarr/YarrPattern.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreyarrYarrDisassemblercpp">trunk/Source/JavaScriptCore/yarr/YarrDisassembler.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreyarrYarrDisassemblerh">trunk/Source/JavaScriptCore/yarr/YarrDisassembler.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (234712 => 234713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog    2018-08-08 22:18:28 UTC (rev 234712)
+++ trunk/Source/JavaScriptCore/ChangeLog       2018-08-08 22:42:30 UTC (rev 234713)
</span><span class="lines">@@ -1,3 +1,102 @@
</span><ins>+2018-08-08  Michael Saboff  <msaboff@apple.com>
+
+        Yarr JIT should include annotations with dumpDisassembly=true
+        https://bugs.webkit.org/show_bug.cgi?id=188415
+
+        Reviewed by Yusuke Suzuki.
+
+        Created a YarrDisassembler class that handles annotations similar to the baseline JIT.
+        Given that the Yarr creates matching code bu going through the YarrPattern ops forward and
+        then the backtracking code through the YarrPattern ops in reverse order, the disassembler
+        needs to do the same think.
+
+        Restructured some of the logging code in YarrPattern to eliminate redundent code and factor
+        out simple methods for what was needed by the YarrDisassembler.
+
+        Here is abbreviated sample output after this change.
+
+        Generated JIT code for 8-bit regular expression /ab*c/:
+            Code at [0x469561c03720, 0x469561c03840):
+                0x469561c03720: push %rbp
+                0x469561c03721: mov %rsp, %rbp
+                ...
+                0x469561c03762: sub $0x40, %rsp
+             == Matching ==
+           0:OpBodyAlternativeBegin minimum size 2
+                0x469561c03766: add $0x2, %esi
+                0x469561c03769: cmp %edx, %esi
+                0x469561c0376b: ja 0x469561c037fa
+           1:OpTerm TypePatternCharacter 'a'
+                0x469561c03771: movzx -0x2(%rdi,%rsi), %eax
+                0x469561c03776: cmp $0x61, %eax
+                0x469561c03779: jnz 0x469561c037e9
+           2:OpTerm TypePatternCharacter 'b' {0,...} greedy
+                0x469561c0377f: xor %r9d, %r9d
+                0x469561c03782: cmp %edx, %esi
+                0x469561c03784: jz 0x469561c037a2
+                ...
+                0x469561c0379d: jmp 0x469561c03782
+                0x469561c037a2: mov %r9, 0x8(%rsp)
+           3:OpTerm TypePatternCharacter 'c'
+                0x469561c037a7: movzx -0x1(%rdi,%rsi), %eax
+                0x469561c037ac: cmp $0x63, %eax
+                0x469561c037af: jnz 0x469561c037d1
+           4:OpBodyAlternativeEnd
+                0x469561c037b5: add $0x40, %rsp
+                ...
+                0x469561c037cf: pop %rbp
+                0x469561c037d0: ret
+             == Backtracking ==
+           4:OpBodyAlternativeEnd
+           3:OpTerm TypePatternCharacter 'c'
+           2:OpTerm TypePatternCharacter 'b' {0,...} greedy
+                0x469561c037d1: mov 0x8(%rsp), %r9
+                ...
+                0x469561c037e4: jmp 0x469561c037a2
+           1:OpTerm TypePatternCharacter 'a'
+           0:OpBodyAlternativeBegin minimum size 2
+                0x469561c037e9: mov %rsi, %rax
+                ...
+                0x469561c0382f: pop %rbp
+                0x469561c03830: ret
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * Sources.txt:
+        * runtime/RegExp.cpp:
+        (JSC::RegExp::compile):
+        (JSC::RegExp::compileMatchOnly):
+        * yarr/YarrDisassembler.cpp: Added.
+        (JSC::Yarr::YarrDisassembler::indentString):
+        (JSC::Yarr::YarrDisassembler::YarrDisassembler):
+        (JSC::Yarr::YarrDisassembler::~YarrDisassembler):
+        (JSC::Yarr::YarrDisassembler::dump):
+        (JSC::Yarr::YarrDisassembler::dumpHeader):
+        (JSC::Yarr::YarrDisassembler::dumpVectorForInstructions):
+        (JSC::Yarr::YarrDisassembler::dumpForInstructions):
+        (JSC::Yarr::YarrDisassembler::dumpDisassembly):
+        * yarr/YarrDisassembler.h: Added.
+        (JSC::Yarr::YarrJITInfo::~YarrJITInfo):
+        (JSC::Yarr::YarrDisassembler::setStartOfCode):
+        (JSC::Yarr::YarrDisassembler::setForGenerate):
+        (JSC::Yarr::YarrDisassembler::setForBacktrack):
+        (JSC::Yarr::YarrDisassembler::setEndOfGenerate):
+        (JSC::Yarr::YarrDisassembler::setEndOfBacktrack):
+        (JSC::Yarr::YarrDisassembler::setEndOfCode):
+        (JSC::Yarr::YarrDisassembler::indentString):
+        * yarr/YarrJIT.cpp:
+        (JSC::Yarr::YarrGenerator::generate):
+        (JSC::Yarr::YarrGenerator::backtrack):
+        (JSC::Yarr::YarrGenerator::YarrGenerator):
+        (JSC::Yarr::YarrGenerator::compile):
+        (JSC::Yarr::jitCompile):
+        * yarr/YarrJIT.h:
+        * yarr/YarrPattern.cpp:
+        (JSC::Yarr::dumpCharacterClass):
+        (JSC::Yarr::PatternTerm::dump):
+        (JSC::Yarr::YarrPattern::dumpPatternString):
+        (JSC::Yarr::YarrPattern::dumpPattern):
+        * yarr/YarrPattern.h:
+
</ins><span class="cx"> 2018-08-05  Darin Adler  <darin@apple.com>
</span><span class="cx"> 
</span><span class="cx">         [Cocoa] More tweaks and refactoring to prepare for ARC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (234712 => 234713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj     2018-08-08 22:18:28 UTC (rev 234712)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2018-08-08 22:42:30 UTC (rev 234713)
</span><span class="lines">@@ -3586,6 +3586,8 @@
</span><span class="cx">          65B8392C1BACA92A0044E824 /* CachedRecovery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedRecovery.h; sourceTree = "<group>"; };
</span><span class="cx">          65B8392D1BACA9D30044E824 /* CachedRecovery.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CachedRecovery.cpp; sourceTree = "<group>"; };
</span><span class="cx">          65C02FBB0637462A003E7EE6 /* Protect.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = Protect.h; sourceTree = "<group>"; tabWidth = 8; };
</span><ins>+               65C6BEDF21128C3B006849C3 /* YarrDisassembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = YarrDisassembler.cpp; path = yarr/YarrDisassembler.cpp; sourceTree = "<group>"; };
+               65C6BEE021128C3B006849C3 /* YarrDisassembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = YarrDisassembler.h; path = yarr/YarrDisassembler.h; sourceTree = "<group>"; };
</ins><span class="cx">           65C7A1710A8EAACB00FA37EA /* JSWrapperObject.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSWrapperObject.cpp; sourceTree = "<group>"; };
</span><span class="cx">          65C7A1720A8EAACB00FA37EA /* JSWrapperObject.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSWrapperObject.h; sourceTree = "<group>"; };
</span><span class="cx">          65DA90461F87052A009BC546 /* generateYarrUnicodePropertyTables.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; name = generateYarrUnicodePropertyTables.py; path = Scripts/generateYarrUnicodePropertyTables.py; sourceTree = "<group>"; };
</span><span class="lines">@@ -7119,6 +7121,8 @@
</span><span class="cx">                          863C6D991521111200585E4E /* YarrCanonicalize.h */,
</span><span class="cx">                          863C6D981521111200585E4E /* YarrCanonicalizeUCS2.cpp */,
</span><span class="cx">                          863C6D9A1521111200585E4E /* YarrCanonicalizeUCS2.js */,
</span><ins>+                               65C6BEDF21128C3B006849C3 /* YarrDisassembler.cpp */,
+                               65C6BEE021128C3B006849C3 /* YarrDisassembler.h */,
</ins><span class="cx">                           E3282BB91FE930A300EDAF71 /* YarrErrorCode.cpp */,
</span><span class="cx">                          E3282BBA1FE930A400EDAF71 /* YarrErrorCode.h */,
</span><span class="cx">                          86704B7D12DBA33700A9FE7B /* YarrInterpreter.cpp */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreSourcestxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/Sources.txt (234712 => 234713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/Sources.txt  2018-08-08 22:18:28 UTC (rev 234712)
+++ trunk/Source/JavaScriptCore/Sources.txt     2018-08-08 22:42:30 UTC (rev 234713)
</span><span class="lines">@@ -1036,6 +1036,7 @@
</span><span class="cx"> 
</span><span class="cx"> yarr/RegularExpression.cpp
</span><span class="cx"> yarr/YarrCanonicalizeUCS2.cpp
</span><ins>+yarr/YarrDisassembler.cpp
</ins><span class="cx"> yarr/YarrErrorCode.cpp
</span><span class="cx"> yarr/YarrInterpreter.cpp
</span><span class="cx"> yarr/YarrJIT.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeRegExpcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/RegExp.cpp (234712 => 234713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/RegExp.cpp   2018-08-08 22:18:28 UTC (rev 234712)
+++ trunk/Source/JavaScriptCore/runtime/RegExp.cpp      2018-08-08 22:42:30 UTC (rev 234713)
</span><span class="lines">@@ -306,7 +306,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(YARR_JIT)
</span><span class="cx">     if (!pattern.m_containsBackreferences && !pattern.containsUnsignedLengthPattern() && VM::canUseRegExpJIT()) {
</span><del>-        Yarr::jitCompile(pattern, charSize, vm, m_regExpJITCode);
</del><ins>+        Yarr::jitCompile(pattern, m_patternString, charSize, vm, m_regExpJITCode);
</ins><span class="cx">         if (!m_regExpJITCode.failureReason()) {
</span><span class="cx">             m_state = JITCode;
</span><span class="cx">             return;
</span><span class="lines">@@ -362,7 +362,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(YARR_JIT)
</span><span class="cx">     if (!pattern.m_containsBackreferences && !pattern.containsUnsignedLengthPattern() && VM::canUseRegExpJIT()) {
</span><del>-        Yarr::jitCompile(pattern, charSize, vm, m_regExpJITCode, Yarr::MatchOnly);
</del><ins>+        Yarr::jitCompile(pattern, m_patternString, charSize, vm, m_regExpJITCode, Yarr::MatchOnly);
</ins><span class="cx">         if (!m_regExpJITCode.failureReason()) {
</span><span class="cx">             m_state = JITCode;
</span><span class="cx">             return;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreyarrYarrDisassemblercpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/yarr/YarrDisassembler.cpp (0 => 234713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/yarr/YarrDisassembler.cpp                            (rev 0)
+++ trunk/Source/JavaScriptCore/yarr/YarrDisassembler.cpp       2018-08-08 22:42:30 UTC (rev 234713)
</span><span class="lines">@@ -0,0 +1,152 @@
</span><ins>+/*
+ * Copyright (C) 2018 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. 
+ */
+
+#include "config.h"
+#include "YarrDisassembler.h"
+
+#if ENABLE(JIT)
+
+#include "Disassembler.h"
+#include "LinkBuffer.h"
+#include <wtf/StringPrintStream.h>
+
+namespace JSC { namespace Yarr {
+
+static constexpr char s_spaces[] = "                        ";
+static constexpr unsigned s_maxIndent = sizeof(s_spaces) - 1;
+
+const char* YarrDisassembler::indentString(unsigned level)
+{
+    unsigned indent = 6 + level * 2;
+    indent = std::min(indent, s_maxIndent);
+
+    return s_spaces + s_maxIndent - indent;
+}
+
+YarrDisassembler::YarrDisassembler(YarrJITInfo* yarrJITInfo)
+    : m_jitInfo(yarrJITInfo)
+    , m_labelForGenerateYarrOp(yarrJITInfo->opCount())
+    , m_labelForBacktrackYarrOp(yarrJITInfo->opCount())
+{
+}
+
+YarrDisassembler::~YarrDisassembler()
+{
+}
+
+void YarrDisassembler::dump(PrintStream& out, LinkBuffer& linkBuffer)
+{
+    dumpHeader(out, linkBuffer);
+    dumpDisassembly(out, indentString(), linkBuffer, m_startOfCode, m_labelForGenerateYarrOp[0]);
+
+    out.print("     == Matching ==\n");
+    dumpForInstructions(out, linkBuffer, m_labelForGenerateYarrOp, m_endOfGenerate);
+    out.print("     == Backtracking ==\n");
+    dumpForInstructions(out, linkBuffer, m_labelForBacktrackYarrOp, m_endOfBacktrack, VectorOrder::IterateReverse);
+
+    if (!(m_endOfBacktrack == m_endOfCode)) {
+        out.print("     == Helpers ==\n");
+
+        dumpDisassembly(out, indentString(), linkBuffer, m_endOfBacktrack, m_endOfCode);
+    }
+
+    linkBuffer.didAlreadyDisassemble();
+}
+
+void YarrDisassembler::dump(LinkBuffer& linkBuffer)
+{
+    dump(WTF::dataFile(), linkBuffer);
+}
+
+void YarrDisassembler::dumpHeader(PrintStream& out, LinkBuffer& linkBuffer)
+{
+    out.print("Generated JIT code for ", m_jitInfo->variant(), " ");
+    m_jitInfo->dumpPatternString(out);
+    out.print(":\n");
+    out.print("    Code at [", RawPointer(linkBuffer.debugAddress()), ", ", RawPointer(static_cast<char*>(linkBuffer.debugAddress()) + linkBuffer.size()), "):\n");
+}
+
+Vector<YarrDisassembler::DumpedOp> YarrDisassembler::dumpVectorForInstructions(LinkBuffer& linkBuffer, Vector<MacroAssembler::Label>& labels, MacroAssembler::Label endLabel, YarrDisassembler::VectorOrder vectorOrder)
+{
+    StringPrintStream out;
+    Vector<DumpedOp> result;
+
+    unsigned directionBias = (vectorOrder == VectorOrder::IterateForward) ? 0 : labels.size() - 1;
+
+    auto realIndex = [&](unsigned rawIndex) {
+        if (directionBias)
+            return directionBias - rawIndex;
+        return rawIndex;
+    };
+
+    for (unsigned i = 0; i < labels.size();) {
+        if (!labels[realIndex(i)].isSet()) {
+            i++;
+            continue;
+        }
+        out.reset();
+        result.append(DumpedOp());
+        result.last().index = realIndex(i);
+
+        int delta = m_jitInfo->dumpFor(out, realIndex(i));
+        m_indentLevel += (vectorOrder == VectorOrder::IterateForward) ? delta : -delta;
+
+        for (unsigned nextIndex = i + 1; ; nextIndex++) {
+            if (nextIndex >= labels.size()) {
+                dumpDisassembly(out, indentString(), linkBuffer, labels[realIndex(i)], endLabel);
+                result.last().disassembly = out.toCString();
+                return result;
+            }
+            if (labels[realIndex(nextIndex)].isSet()) {
+                dumpDisassembly(out, indentString(), linkBuffer, labels[realIndex(i)], labels[realIndex(nextIndex)]);
+                result.last().disassembly = out.toCString();
+                i = nextIndex;
+                break;
+            }
+        }
+    }
+
+    return result;
+}
+
+void YarrDisassembler::dumpForInstructions(PrintStream& out, LinkBuffer& linkBuffer, Vector<MacroAssembler::Label>& labels, MacroAssembler::Label endLabel, YarrDisassembler::VectorOrder vectorOrder)
+{
+    Vector<DumpedOp> dumpedOps = dumpVectorForInstructions(linkBuffer, labels, endLabel, vectorOrder);
+
+    for (unsigned i = 0; i < dumpedOps.size(); ++i)
+        out.print(dumpedOps[i].disassembly);
+}
+
+void YarrDisassembler::dumpDisassembly(PrintStream& out, const char* prefix, LinkBuffer& linkBuffer, MacroAssembler::Label from, MacroAssembler::Label to)
+{
+    CodeLocationLabel<DisassemblyPtrTag> fromLocation = linkBuffer.locationOf<DisassemblyPtrTag>(from);
+    CodeLocationLabel<DisassemblyPtrTag> toLocation = linkBuffer.locationOf<DisassemblyPtrTag>(to);
+    disassemble(fromLocation, toLocation.dataLocation<uintptr_t>() - fromLocation.dataLocation<uintptr_t>(), prefix, out);
+}
+
+}} // namespace Yarr namespace JSC
+
+#endif // ENABLE(JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreyarrYarrDisassemblerh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/yarr/YarrDisassembler.h (0 => 234713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/yarr/YarrDisassembler.h                              (rev 0)
+++ trunk/Source/JavaScriptCore/yarr/YarrDisassembler.h 2018-08-08 22:42:30 UTC (rev 234713)
</span><span class="lines">@@ -0,0 +1,114 @@
</span><ins>+/*
+ * Copyright (C) 2018 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. 
+ */
+
+#pragma once
+
+#if ENABLE(JIT)
+
+#include "MacroAssembler.h"
+#include <wtf/Vector.h>
+#include <wtf/text/CString.h>
+
+
+namespace JSC {
+
+class LinkBuffer;
+
+namespace Yarr {
+
+class YarrCodeBlock;
+
+class YarrJITInfo {
+public:
+    virtual ~YarrJITInfo() { };
+    virtual const char* variant() = 0;
+    virtual unsigned opCount() = 0;
+    virtual void dumpPatternString(PrintStream&) = 0;
+    virtual int dumpFor(PrintStream&, unsigned) = 0;
+};
+
+class YarrDisassembler {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    YarrDisassembler(YarrJITInfo*);
+    ~YarrDisassembler();
+
+    void setStartOfCode(MacroAssembler::Label label) { m_startOfCode = label; }
+    void setForGenerate(unsigned opIndex, MacroAssembler::Label label)
+    {
+        m_labelForGenerateYarrOp[opIndex] = label;
+    }
+
+    void setForBacktrack(unsigned opIndex, MacroAssembler::Label label)
+    {
+        m_labelForBacktrackYarrOp[opIndex] = label;
+    }
+
+    void setEndOfGenerate(MacroAssembler::Label label) { m_endOfGenerate = label; }
+    void setEndOfBacktrack(MacroAssembler::Label label) { m_endOfBacktrack = label; }
+    void setEndOfCode(MacroAssembler::Label label) { m_endOfCode = label; }
+
+    void dump(LinkBuffer&);
+    void dump(PrintStream&, LinkBuffer&);
+
+private:
+    enum class VectorOrder {
+        IterateForward,
+        IterateReverse
+    };
+
+    void dumpHeader(PrintStream&, LinkBuffer&);
+    MacroAssembler::Label firstSlowLabel();
+
+    struct DumpedOp {
+        unsigned index;
+        CString disassembly;
+    };
+
+    const char* indentString(unsigned);
+    const char* indentString()
+    {
+        return indentString(m_indentLevel);
+    }
+
+    Vector<DumpedOp> dumpVectorForInstructions(LinkBuffer&, Vector<MacroAssembler::Label>& labels, MacroAssembler::Label endLabel, YarrDisassembler::VectorOrder vectorOrder = VectorOrder::IterateForward);
+
+    void dumpForInstructions(PrintStream&, LinkBuffer&, Vector<MacroAssembler::Label>& labels, MacroAssembler::Label endLabel, YarrDisassembler::VectorOrder vectorOrder = VectorOrder::IterateForward);
+
+    void dumpDisassembly(PrintStream&, const char* prefix, LinkBuffer&, MacroAssembler::Label from, MacroAssembler::Label to);
+
+    YarrJITInfo* m_jitInfo;
+    MacroAssembler::Label m_startOfCode;
+    Vector<MacroAssembler::Label> m_labelForGenerateYarrOp;
+    Vector<MacroAssembler::Label> m_labelForBacktrackYarrOp;
+    MacroAssembler::Label m_endOfGenerate;
+    MacroAssembler::Label m_endOfBacktrack;
+    MacroAssembler::Label m_endOfCode;
+    unsigned m_indentLevel { 0 };
+};
+
+}} // namespace Yarr namespace JSC
+
+#endif // ENABLE(JIT)
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreyarrYarrJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/yarr/YarrJIT.cpp (234712 => 234713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/yarr/YarrJIT.cpp     2018-08-08 22:18:28 UTC (rev 234712)
+++ trunk/Source/JavaScriptCore/yarr/YarrJIT.cpp        2018-08-08 22:42:30 UTC (rev 234713)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx"> #include "VM.h"
</span><span class="cx"> #include "Yarr.h"
</span><span class="cx"> #include "YarrCanonicalize.h"
</span><ins>+#include "YarrDisassembler.h"
</ins><span class="cx"> 
</span><span class="cx"> #if ENABLE(YARR_JIT)
</span><span class="cx"> 
</span><span class="lines">@@ -40,8 +41,7 @@
</span><span class="cx"> namespace JSC { namespace Yarr {
</span><span class="cx"> 
</span><span class="cx"> template<YarrJITCompileMode compileMode>
</span><del>-class YarrGenerator : private MacroAssembler {
-    friend void jitCompile(VM*, YarrCodeBlock&, const String& pattern, unsigned& numSubpatterns, const char*& error, bool ignoreCase, bool multiline);
</del><ins>+class YarrGenerator : public YarrJITInfo, private MacroAssembler {
</ins><span class="cx"> 
</span><span class="cx"> #if CPU(ARM)
</span><span class="cx">     static const RegisterID input = ARMRegisters::r0;
</span><span class="lines">@@ -1856,6 +1856,9 @@
</span><span class="cx">         size_t opIndex = 0;
</span><span class="cx"> 
</span><span class="cx">         do {
</span><ins>+            if (m_disassembler)
+                m_disassembler->setForGenerate(opIndex, label());
+
</ins><span class="cx">             YarrOp& op = m_ops[opIndex];
</span><span class="cx">             switch (op.m_op) {
</span><span class="cx"> 
</span><span class="lines">@@ -2372,6 +2375,10 @@
</span><span class="cx"> 
</span><span class="cx">         do {
</span><span class="cx">             --opIndex;
</span><ins>+
+            if (m_disassembler)
+                m_disassembler->setForBacktrack(opIndex, label());
+
</ins><span class="cx">             YarrOp& op = m_ops[opIndex];
</span><span class="cx">             switch (op.m_op) {
</span><span class="cx"> 
</span><span class="lines">@@ -3424,9 +3431,10 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> public:
</span><del>-    YarrGenerator(VM* vm, YarrPattern& pattern, YarrCodeBlock& codeBlock, YarrCharSize charSize)
</del><ins>+    YarrGenerator(VM* vm, YarrPattern& pattern, String& patternString, YarrCodeBlock& codeBlock, YarrCharSize charSize)
</ins><span class="cx">         : m_vm(vm)
</span><span class="cx">         , m_pattern(pattern)
</span><ins>+        , m_patternString(patternString)
</ins><span class="cx">         , m_codeBlock(codeBlock)
</span><span class="cx">         , m_charSize(charSize)
</span><span class="cx">         , m_decodeSurrogatePairs(m_charSize == Char16 && m_pattern.unicode())
</span><span class="lines">@@ -3463,7 +3471,13 @@
</span><span class="cx">             codeBlock.setFallBackWithFailureReason(*m_failureReason);
</span><span class="cx">             return;
</span><span class="cx">         }
</span><del>-        
</del><ins>+
+        if (UNLIKELY(Options::dumpDisassembly()))
+            m_disassembler = std::make_unique<YarrDisassembler>(this);
+
+        if (m_disassembler)
+            m_disassembler->setStartOfCode(label());
+
</ins><span class="cx">         generateEnter();
</span><span class="cx"> 
</span><span class="cx">         Jump hasInput = checkInput();
</span><span class="lines">@@ -3499,12 +3513,19 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         generate();
</span><ins>+        if (m_disassembler)
+            m_disassembler->setEndOfGenerate(label());
</ins><span class="cx">         backtrack();
</span><ins>+        if (m_disassembler)
+            m_disassembler->setEndOfBacktrack(label());
</ins><span class="cx"> 
</span><span class="cx">         generateTryReadUnicodeCharacterHelper();
</span><span class="cx"> 
</span><span class="cx">         generateJITFailReturn();
</span><span class="cx"> 
</span><ins>+        if (m_disassembler)
+            m_disassembler->setEndOfCode(label());
+
</ins><span class="cx">         LinkBuffer linkBuffer(*this, REGEXP_CODE_ID, JITCompilationCanFail);
</span><span class="cx">         if (linkBuffer.didFailToAllocate()) {
</span><span class="cx">             codeBlock.setFallBackWithFailureReason(JITFailureReason::ExecutableMemoryAllocationFailure);
</span><span class="lines">@@ -3520,6 +3541,9 @@
</span><span class="cx"> 
</span><span class="cx">         m_backtrackingState.linkDataLabels(linkBuffer);
</span><span class="cx"> 
</span><ins>+        if (m_disassembler)
+            m_disassembler->dump(linkBuffer);
+
</ins><span class="cx">         if (compileMode == MatchOnly) {
</span><span class="cx">             if (m_charSize == Char8)
</span><span class="cx">                 codeBlock.set8BitCodeMatchOnly(FINALIZE_CODE(linkBuffer, YarrMatchOnly8BitPtrTag, "Match-only 8-bit regular expression"));
</span><span class="lines">@@ -3535,10 +3559,196 @@
</span><span class="cx">             codeBlock.setFallBackWithFailureReason(*m_failureReason);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    const char* variant() override
+    {
+        if (compileMode == MatchOnly) {
+            if (m_charSize == Char8)
+                return "Match-only 8-bit regular expression";
+
+            return "Match-only 16-bit regular expression";
+        }
+
+        if (m_charSize == Char8)
+            return "8-bit regular expression";
+
+        return "16-bit regular expression";
+    }
+
+    unsigned opCount() override
+    {
+        return m_ops.size();
+    }
+
+    void dumpPatternString(PrintStream& out) override
+    {
+        m_pattern.dumpPatternString(out, m_patternString);
+    }
+
+    int dumpFor(PrintStream& out, unsigned opIndex) override
+    {
+        if (opIndex >= opCount())
+            return 0;
+
+        out.printf("%4d:", opIndex);
+
+        YarrOp& op = m_ops[opIndex];
+        PatternTerm* term = op.m_term;
+        switch (op.m_op) {
+        case OpTerm: {
+            out.print("OpTerm ");
+            switch (term->type) {
+            case PatternTerm::TypeAssertionBOL:
+                out.print("Assert BOL");
+                break;
+
+            case PatternTerm::TypeAssertionEOL:
+                out.print("Assert EOL");
+                break;
+
+            case PatternTerm::TypePatternCharacter:
+                out.print("TypePatternCharacter ");
+                dumpUChar32(out, term->patternCharacter);
+                if (m_pattern.ignoreCase())
+                    out.print(" ignore case");
+
+                term->dumpQuantifier(out);
+                break;
+
+            case PatternTerm::TypeCharacterClass:
+                out.print("TypePatternCharacterClass ");
+                if (term->invert())
+                    out.print("not ");
+                dumpCharacterClass(out, &m_pattern, term->characterClass);
+                term->dumpQuantifier(out);
+                break;
+
+            case PatternTerm::TypeAssertionWordBoundary:
+                out.printf("%sword boundary", term->invert() ? "non-" : "");
+                break;
+
+            case PatternTerm::TypeDotStarEnclosure:
+                out.print(".* enclosure");
+                break;
+
+            case PatternTerm::TypeForwardReference:
+            case PatternTerm::TypeBackReference:
+            case PatternTerm::TypeParenthesesSubpattern:
+            case PatternTerm::TypeParentheticalAssertion:
+                RELEASE_ASSERT_NOT_REACHED();
+                break;
+            }
+
+            if (op.m_isDeadCode)
+                out.print(" already handled");
+            out.print("\n");
+            return(0);
+        }
+
+        case OpBodyAlternativeBegin:
+            out.printf("OpBodyAlternativeBegin minimum size %u\n", op.m_alternative->m_minimumSize);
+            return(0);
+
+        case OpBodyAlternativeNext:
+            out.printf("OpBodyAlternativeNext minimum size %u\n", op.m_alternative->m_minimumSize);
+            return(0);
+
+        case OpBodyAlternativeEnd:
+            out.print("OpBodyAlternativeEnd\n");
+            return(0);
+
+        case OpSimpleNestedAlternativeBegin:
+            out.printf("OpSimpleNestedAlternativeBegin minimum size %u\n", op.m_alternative->m_minimumSize);
+            return(1);
+
+        case OpNestedAlternativeBegin:
+            out.printf("OpNestedAlternativeBegin minimum size %u\n", op.m_alternative->m_minimumSize);
+            return(1);
+
+        case OpSimpleNestedAlternativeNext:
+            out.printf("OpSimpleNestedAlternativeNext minimum size %u\n", op.m_alternative->m_minimumSize);
+            return(0);
+
+        case OpNestedAlternativeNext:
+            out.printf("OpNestedAlternativeNext minimum size %u\n", op.m_alternative->m_minimumSize);
+            return(0);
+
+        case OpSimpleNestedAlternativeEnd:
+            out.print("OpSimpleNestedAlternativeEnd");
+            term->dumpQuantifier(out);
+            out.print("\n");
+            return(-1);
+
+        case OpNestedAlternativeEnd:
+            out.print("OpNestedAlternativeEnd");
+            term->dumpQuantifier(out);
+            out.print("\n");
+            return(-1);
+
+        case OpParenthesesSubpatternOnceBegin:
+            out.print("OpParenthesesSubpatternOnceBegin ");
+            if (term->capture())
+                out.printf("capturing pattern #%u\n", op.m_term->parentheses.subpatternId);
+            else
+                out.print("non-capturing\n");
+            return(0);
+
+        case OpParenthesesSubpatternOnceEnd:
+            out.print("OpParenthesesSubpatternOnceEnd\n");
+            return(0);
+
+        case OpParenthesesSubpatternTerminalBegin:
+            out.print("OpParenthesesSubpatternTerminalBegin ");
+            if (term->capture())
+                out.printf("capturing pattern #%u\n", op.m_term->parentheses.subpatternId);
+            else
+                out.print("non-capturing\n");
+            return(0);
+
+        case OpParenthesesSubpatternTerminalEnd:
+            out.print("OpParenthesesSubpatternTerminalEnd ");
+            if (term->capture())
+                out.printf("capturing pattern #%u\n", op.m_term->parentheses.subpatternId);
+            else
+                out.print("non-capturing\n");
+            return(0);
+
+        case OpParenthesesSubpatternBegin:
+            out.print("OpParenthesesSubpatternBegin ");
+            if (term->capture())
+                out.printf("capturing pattern #%u\n", op.m_term->parentheses.subpatternId);
+            else
+                out.print("non-capturing\n");
+            return(0);
+
+        case OpParenthesesSubpatternEnd:
+            out.print("OpParenthesesSubpatternEnd ");
+            if (term->capture())
+                out.printf("capturing pattern #%u\n", op.m_term->parentheses.subpatternId);
+            else
+                out.print("non-capturing\n");
+            return(0);
+
+        case OpParentheticalAssertionBegin:
+            out.printf("OpParentheticalAssertionBegin%s\n", op.m_term->invert() ? " inverted" : "");
+            return(0);
+
+        case OpParentheticalAssertionEnd:
+            out.print("OpParentheticalAssertionEnd%s\n", op.m_term->invert() ? " inverted" : "");
+            return(0);
+
+        case OpMatchFailed:
+            out.print("OpMatchFailed\n");
+            return(0);
+        }
+
+        return(0);
+    }
+
</ins><span class="cx"> private:
</span><span class="cx">     VM* m_vm;
</span><span class="cx"> 
</span><span class="cx">     YarrPattern& m_pattern;
</span><ins>+    String& m_patternString;
</ins><span class="cx"> 
</span><span class="cx">     YarrCodeBlock& m_codeBlock;
</span><span class="cx">     YarrCharSize m_charSize;
</span><span class="lines">@@ -3576,6 +3786,8 @@
</span><span class="cx"> 
</span><span class="cx">     // This class records state whilst generating the backtracking path of code.
</span><span class="cx">     BacktrackingState m_backtrackingState;
</span><ins>+    
+    std::unique_ptr<YarrDisassembler> m_disassembler;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> static void dumpCompileFailure(JITFailureReason failure)
</span><span class="lines">@@ -3602,12 +3814,12 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void jitCompile(YarrPattern& pattern, YarrCharSize charSize, VM* vm, YarrCodeBlock& codeBlock, YarrJITCompileMode mode)
</del><ins>+void jitCompile(YarrPattern& pattern, String& patternString, YarrCharSize charSize, VM* vm, YarrCodeBlock& codeBlock, YarrJITCompileMode mode)
</ins><span class="cx"> {
</span><span class="cx">     if (mode == MatchOnly)
</span><del>-        YarrGenerator<MatchOnly>(vm, pattern, codeBlock, charSize).compile();
</del><ins>+        YarrGenerator<MatchOnly>(vm, pattern, patternString, codeBlock, charSize).compile();
</ins><span class="cx">     else
</span><del>-        YarrGenerator<IncludeSubpatterns>(vm, pattern, codeBlock, charSize).compile();
</del><ins>+        YarrGenerator<IncludeSubpatterns>(vm, pattern, patternString, codeBlock, charSize).compile();
</ins><span class="cx"> 
</span><span class="cx">     if (auto failureReason = codeBlock.failureReason()) {
</span><span class="cx">         if (Options::dumpCompiledRegExpPatterns())
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreyarrYarrJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/yarr/YarrJIT.h (234712 => 234713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/yarr/YarrJIT.h       2018-08-08 22:18:28 UTC (rev 234712)
+++ trunk/Source/JavaScriptCore/yarr/YarrJIT.h  2018-08-08 22:42:30 UTC (rev 234713)
</span><span class="lines">@@ -210,7 +210,7 @@
</span><span class="cx">     MatchOnly,
</span><span class="cx">     IncludeSubpatterns
</span><span class="cx"> };
</span><del>-void jitCompile(YarrPattern&, YarrCharSize, VM*, YarrCodeBlock& jitObject, YarrJITCompileMode = IncludeSubpatterns);
</del><ins>+void jitCompile(YarrPattern&, String& patternString, YarrCharSize, VM*, YarrCodeBlock& jitObject, YarrJITCompileMode = IncludeSubpatterns);
</ins><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::Yarr
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreyarrYarrPatterncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/yarr/YarrPattern.cpp (234712 => 234713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/yarr/YarrPattern.cpp 2018-08-08 22:18:28 UTC (rev 234712)
+++ trunk/Source/JavaScriptCore/yarr/YarrPattern.cpp    2018-08-08 22:42:30 UTC (rev 234713)
</span><span class="lines">@@ -1169,7 +1169,7 @@
</span><span class="cx">     else if (characterClass == pattern->wordcharCharacterClass())
</span><span class="cx">         out.print("<word>");
</span><span class="cx">     else if (characterClass == pattern->wordUnicodeIgnoreCaseCharCharacterClass())
</span><del>-        out.print("<unicode ignore case>");
</del><ins>+        out.print("<unicode word ignore case>");
</ins><span class="cx">     else if (characterClass == pattern->nondigitsCharacterClass())
</span><span class="cx">         out.print("<non-digits>");
</span><span class="cx">     else if (characterClass == pattern->nonspacesCharacterClass())
</span><span class="lines">@@ -1177,7 +1177,7 @@
</span><span class="cx">     else if (characterClass == pattern->nonwordcharCharacterClass())
</span><span class="cx">         out.print("<non-word>");
</span><span class="cx">     else if (characterClass == pattern->nonwordUnicodeIgnoreCaseCharCharacterClass())
</span><del>-        out.print("<unicode non-ignore case>");
</del><ins>+        out.print("<unicode non-word ignore case>");
</ins><span class="cx">     else {
</span><span class="cx">         bool needMatchesRangesSeperator = false;
</span><span class="cx"> 
</span><span class="lines">@@ -1299,75 +1299,7 @@
</span><span class="cx">         break;
</span><span class="cx">     case TypeCharacterClass:
</span><span class="cx">         out.print("character class ");
</span><del>-        if (characterClass->m_anyCharacter)
-            out.print("<any character>");
-        else if (characterClass == thisPattern->newlineCharacterClass())
-            out.print("<newline>");
-        else if (characterClass == thisPattern->digitsCharacterClass())
-            out.print("<digits>");
-        else if (characterClass == thisPattern->spacesCharacterClass())
-            out.print("<whitespace>");
-        else if (characterClass == thisPattern->wordcharCharacterClass())
-            out.print("<word>");
-        else if (characterClass == thisPattern->wordUnicodeIgnoreCaseCharCharacterClass())
-            out.print("<unicode ignore case>");
-        else if (characterClass == thisPattern->nondigitsCharacterClass())
-            out.print("<non-digits>");
-        else if (characterClass == thisPattern->nonspacesCharacterClass())
-            out.print("<non-whitespace>");
-        else if (characterClass == thisPattern->nonwordcharCharacterClass())
-            out.print("<non-word>");
-        else if (characterClass == thisPattern->nonwordUnicodeIgnoreCaseCharCharacterClass())
-            out.print("<unicode non-ignore case>");
-        else {
-            bool needMatchesRangesSeperator = false;
-
-            auto dumpMatches = [&] (const char* prefix, Vector<UChar32> matches) {
-                size_t matchesSize = matches.size();
-                if (matchesSize) {
-                    if (needMatchesRangesSeperator)
-                        out.print(",");
-                    needMatchesRangesSeperator = true;
-
-                    out.print(prefix, ":(");
-                    for (size_t i = 0; i < matchesSize; ++i) {
-                        if (i)
-                            out.print(",");
-                        dumpUChar32(out, matches[i]);
-                    }
-                    out.print(")");
-                }
-            };
-
-            auto dumpRanges = [&] (const char* prefix, Vector<CharacterRange> ranges) {
-                size_t rangeSize = ranges.size();
-                if (rangeSize) {
-                    if (needMatchesRangesSeperator)
-                        out.print(",");
-                    needMatchesRangesSeperator = true;
-
-                    out.print(prefix, " ranges:(");
-                    for (size_t i = 0; i < rangeSize; ++i) {
-                        if (i)
-                            out.print(",");
-                        CharacterRange range = ranges[i];
-                        out.print("(");
-                        dumpUChar32(out, range.begin);
-                        out.print("..");
-                        dumpUChar32(out, range.end);
-                        out.print(")");
-                    }
-                    out.print(")");
-                }
-            };
-
-            out.print("[");
-            dumpMatches("ASCII", characterClass->m_matches);
-            dumpRanges("ASCII", characterClass->m_ranges);
-            dumpMatches("Unicode", characterClass->m_matchesUnicode);
-            dumpRanges("Unicode", characterClass->m_rangesUnicode);
-            out.print("]");
-        }
</del><ins>+        dumpCharacterClass(out, thisPattern, characterClass);
</ins><span class="cx">         dumpQuantifier(out);
</span><span class="cx">         if (quantityType != QuantifierFixedCount || thisPattern->unicode())
</span><span class="cx">             out.print(",frame location ", frameLocation);
</span><span class="lines">@@ -1440,16 +1372,10 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void YarrPattern::dumpPattern(const String& patternString)
</del><ins>+void YarrPattern::dumpPatternString(PrintStream& out, const String& patternString)
</ins><span class="cx"> {
</span><del>-    dumpPattern(WTF::dataFile(), patternString);
-}
</del><ins>+    out.print("/", patternString, "/");
</ins><span class="cx"> 
</span><del>-void YarrPattern::dumpPattern(PrintStream& out, const String& patternString)
-{
-    out.print("RegExp pattern for /");
-    out.print(patternString);
-    out.print("/");
</del><span class="cx">     if (global())
</span><span class="cx">         out.print("g");
</span><span class="cx">     if (ignoreCase())
</span><span class="lines">@@ -1460,6 +1386,18 @@
</span><span class="cx">         out.print("u");
</span><span class="cx">     if (sticky())
</span><span class="cx">         out.print("y");
</span><ins>+}
+
+void YarrPattern::dumpPattern(const String& patternString)
+{
+    dumpPattern(WTF::dataFile(), patternString);
+}
+
+void YarrPattern::dumpPattern(PrintStream& out, const String& patternString)
+{
+    out.print("RegExp pattern for ");
+    dumpPatternString(out, patternString);
+
</ins><span class="cx">     if (m_flags != NoFlags) {
</span><span class="cx">         bool printSeperator = false;
</span><span class="cx">         out.print(" (");
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreyarrYarrPatternh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/yarr/YarrPattern.h (234712 => 234713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/yarr/YarrPattern.h   2018-08-08 22:18:28 UTC (rev 234712)
+++ trunk/Source/JavaScriptCore/yarr/YarrPattern.h      2018-08-08 22:42:30 UTC (rev 234713)
</span><span class="lines">@@ -489,6 +489,7 @@
</span><span class="cx">         return unicodePropertiesCached.get(classID);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    void dumpPatternString(PrintStream& out, const String& patternString);
</ins><span class="cx">     void dumpPattern(const String& pattern);
</span><span class="cx">     void dumpPattern(PrintStream& out, const String& pattern);
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>