<!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>[200272] 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/200272">200272</a></dd>
<dt>Author</dt> <dd>mark.lam@apple.com</dd>
<dt>Date</dt> <dd>2016-04-29 17:34:01 -0700 (Fri, 29 Apr 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Make RegExp.prototype.test spec compliant.
https://bugs.webkit.org/show_bug.cgi?id=155862

Reviewed by Saam Barati.

Source/JavaScriptCore:

* builtins/RegExpPrototype.js:
(intrinsic.RegExpTestIntrinsic.test):

* create_hash_table:
- Delete obsoleted code.

* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::addToGraph):
(JSC::DFG::ByteCodeParser::handleIntrinsicCall):
- We now have 2 intrinsics for RegExp.prototype.test:
  RegExpTestIntrinsic and RegExpTestFastIntrinsic.

  RegExpTestIntrinsic maps to the entry at the top of the builtin ES6
  RegExp.prototype.test.
  RegExpTestFastIntrinsic maps to the fast path in the builtin ES6
  RegExp.prototype.test.

  Both will end up using the RegExpTest DFG node to implement the fast path
  of RegExp.prototype.test.  RegExpTestIntrinsic will have some additional checks
  before the RegExpTest node.  Those checks are for speculating that it is ok for
  us to take the fast path.

* runtime/CommonIdentifiers.h:
* runtime/Intrinsic.h:

* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
- Added the regExpTestFast function.
- Also fixed the parameter length on 2 other functions that were erroneous.

* runtime/RegExpPrototype.cpp:
(JSC::RegExpPrototype::finishCreation):
(JSC::regExpProtoFuncTestFast):
(JSC::regExpProtoFuncTest): Deleted.
* runtime/RegExpPrototype.h:
* tests/es6.yaml:

LayoutTests:

* js/regress/regexp-prototype-test-observable-side-effects-expected.txt: Added.
* js/regress/regexp-prototype-test-observable-side-effects.html: Added.
* js/regress/regexp-prototype-test-observable-side-effects2-expected.txt: Added.
* js/regress/regexp-prototype-test-observable-side-effects2.html: Added.
* js/regress/script-tests/regexp-prototype-test-observable-side-effects.js: Added.
* js/regress/script-tests/simple-regexp-test-folding-fail-with-hoisted-regexp.js: Added.
* js/regress/script-tests/simple-regexp-test-folding-with-hoisted-regexp.js: Added.
* js/regress/simple-regexp-test-folding-fail-with-hoisted-regexp-expected.txt: Added.
* js/regress/simple-regexp-test-folding-fail-with-hoisted-regexp.html: Added.
* js/regress/simple-regexp-test-folding-with-hoisted-regexp-expected.txt: Added.
* js/regress/simple-regexp-test-folding-with-hoisted-regexp.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCorebuiltinsRegExpPrototypejs">trunk/Source/JavaScriptCore/builtins/RegExpPrototype.js</a></li>
<li><a href="#trunkSourceJavaScriptCorecreate_hash_table">trunk/Source/JavaScriptCore/create_hash_table</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp">trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeCommonIdentifiersh">trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeIntrinsich">trunk/Source/JavaScriptCore/runtime/Intrinsic.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGlobalObjectcpp">trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeRegExpPrototypecpp">trunk/Source/JavaScriptCore/runtime/RegExpPrototype.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeRegExpPrototypeh">trunk/Source/JavaScriptCore/runtime/RegExpPrototype.h</a></li>
<li><a href="#trunkSourceJavaScriptCoretestses6yaml">trunk/Source/JavaScriptCore/tests/es6.yaml</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsjsregressregexpprototypetestobservablesideeffectsexpectedtxt">trunk/LayoutTests/js/regress/regexp-prototype-test-observable-side-effects-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregressregexpprototypetestobservablesideeffectshtml">trunk/LayoutTests/js/regress/regexp-prototype-test-observable-side-effects.html</a></li>
<li><a href="#trunkLayoutTestsjsregressregexpprototypetestobservablesideeffects2expectedtxt">trunk/LayoutTests/js/regress/regexp-prototype-test-observable-side-effects2-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregressregexpprototypetestobservablesideeffects2html">trunk/LayoutTests/js/regress/regexp-prototype-test-observable-side-effects2.html</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestsregexpprototypetestobservablesideeffectsjs">trunk/LayoutTests/js/regress/script-tests/regexp-prototype-test-observable-side-effects.js</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestsregexpprototypetestobservablesideeffects2js">trunk/LayoutTests/js/regress/script-tests/regexp-prototype-test-observable-side-effects2.js</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestssimpleregexptestfoldingfailwithhoistedregexpjs">trunk/LayoutTests/js/regress/script-tests/simple-regexp-test-folding-fail-with-hoisted-regexp.js</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestssimpleregexptestfoldingwithhoistedregexpjs">trunk/LayoutTests/js/regress/script-tests/simple-regexp-test-folding-with-hoisted-regexp.js</a></li>
<li><a href="#trunkLayoutTestsjsregresssimpleregexptestfoldingfailwithhoistedregexpexpectedtxt">trunk/LayoutTests/js/regress/simple-regexp-test-folding-fail-with-hoisted-regexp-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregresssimpleregexptestfoldingfailwithhoistedregexphtml">trunk/LayoutTests/js/regress/simple-regexp-test-folding-fail-with-hoisted-regexp.html</a></li>
<li><a href="#trunkLayoutTestsjsregresssimpleregexptestfoldingwithhoistedregexpexpectedtxt">trunk/LayoutTests/js/regress/simple-regexp-test-folding-with-hoisted-regexp-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregresssimpleregexptestfoldingwithhoistedregexphtml">trunk/LayoutTests/js/regress/simple-regexp-test-folding-with-hoisted-regexp.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (200271 => 200272)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-04-30 00:12:35 UTC (rev 200271)
+++ trunk/LayoutTests/ChangeLog        2016-04-30 00:34:01 UTC (rev 200272)
</span><span class="lines">@@ -1,3 +1,22 @@
</span><ins>+2016-04-29  Mark Lam  &lt;mark.lam@apple.com&gt;
+
+        Make RegExp.prototype.test spec compliant.
+        https://bugs.webkit.org/show_bug.cgi?id=155862
+
+        Reviewed by Saam Barati.
+
+        * js/regress/regexp-prototype-test-observable-side-effects-expected.txt: Added.
+        * js/regress/regexp-prototype-test-observable-side-effects.html: Added.
+        * js/regress/regexp-prototype-test-observable-side-effects2-expected.txt: Added.
+        * js/regress/regexp-prototype-test-observable-side-effects2.html: Added.
+        * js/regress/script-tests/regexp-prototype-test-observable-side-effects.js: Added.
+        * js/regress/script-tests/simple-regexp-test-folding-fail-with-hoisted-regexp.js: Added.
+        * js/regress/script-tests/simple-regexp-test-folding-with-hoisted-regexp.js: Added.
+        * js/regress/simple-regexp-test-folding-fail-with-hoisted-regexp-expected.txt: Added.
+        * js/regress/simple-regexp-test-folding-fail-with-hoisted-regexp.html: Added.
+        * js/regress/simple-regexp-test-folding-with-hoisted-regexp-expected.txt: Added.
+        * js/regress/simple-regexp-test-folding-with-hoisted-regexp.html: Added.
+
</ins><span class="cx"> 2016-04-29  Commit Queue  &lt;commit-queue@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, rolling out r200150 and r200256.
</span></span></pre></div>
<a id="trunkLayoutTestsjsregressregexpprototypetestobservablesideeffectsexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/regexp-prototype-test-observable-side-effects-expected.txt (0 => 200272)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/regexp-prototype-test-observable-side-effects-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/regexp-prototype-test-observable-side-effects-expected.txt        2016-04-30 00:34:01 UTC (rev 200272)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/regexp-prototype-test-observable-side-effects
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressregexpprototypetestobservablesideeffectshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/regexp-prototype-test-observable-side-effects.html (0 => 200272)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/regexp-prototype-test-observable-side-effects.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/regexp-prototype-test-observable-side-effects.html        2016-04-30 00:34:01 UTC (rev 200272)
</span><span class="lines">@@ -0,0 +1,13 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script src=&quot;../../resources/regress-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;script-tests/regexp-prototype-test-observable-side-effects.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/regress-post.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressregexpprototypetestobservablesideeffects2expectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/regexp-prototype-test-observable-side-effects2-expected.txt (0 => 200272)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/regexp-prototype-test-observable-side-effects2-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/regexp-prototype-test-observable-side-effects2-expected.txt        2016-04-30 00:34:01 UTC (rev 200272)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/regexp-prototype-test-observable-side-effects2
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressregexpprototypetestobservablesideeffects2html"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/regexp-prototype-test-observable-side-effects2.html (0 => 200272)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/regexp-prototype-test-observable-side-effects2.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/regexp-prototype-test-observable-side-effects2.html        2016-04-30 00:34:01 UTC (rev 200272)
</span><span class="lines">@@ -0,0 +1,13 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script src=&quot;../../resources/regress-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;script-tests/regexp-prototype-test-observable-side-effects2.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/regress-post.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestsregexpprototypetestobservablesideeffectsjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/regexp-prototype-test-observable-side-effects.js (0 => 200272)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/regexp-prototype-test-observable-side-effects.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/regexp-prototype-test-observable-side-effects.js        2016-04-30 00:34:01 UTC (rev 200272)
</span><span class="lines">@@ -0,0 +1,277 @@
</span><ins>+//@ runDefault
+
+function assert(testedValue, msg) {
+    if (!testedValue)
+        throw Error(msg);
+}
+
+// RegExp subclass overriding exec.
+(function () {
+    let accesses = [];
+    class SubRegExp extends RegExp {
+        exec(str) {
+            accesses.push(&quot;exec&quot;);
+            return super.exec(str);
+        }
+    }
+
+    let obj = new SubRegExp(/rch/);
+
+    assert(accesses == &quot;&quot;, &quot;unexpected call to overridden props&quot;);
+    let result = RegExp.prototype.test.call(obj, &quot;searchme&quot;);
+    assert(accesses == &quot;exec&quot;, &quot;Property accesses do not match expectation&quot;);
+    assert(result === true, &quot;Unexpected result&quot;);
+
+    accesses = [];
+    obj = new SubRegExp(/not/);
+
+    assert(accesses == &quot;&quot;, &quot;unexpected call to overridden props&quot;);
+    result = RegExp.prototype.test.call(obj, &quot;searchme&quot;);
+    assert(accesses == &quot;exec&quot;, &quot;Property accesses do not match expectation&quot;);
+    assert(result === false, &quot;Unexpected result&quot;);
+})();

+// Any object with custom prototype overriding exec.
+(function () {
+    let accesses = [];
+    let TestRegExpProto = {
+        exec(str) {
+            accesses.push(&quot;exec&quot;);
+            return this._regex.exec(str);
+        }
+    }
+    TestRegExpProto.__proto__ = RegExp.prototype;
+
+    let TestRegExp = function(regex) {
+        this._regex = new RegExp(regex);
+    }
+    TestRegExp.prototype = TestRegExpProto;
+    TestRegExpProto.constructor = TestRegExp;
+
+    let obj = new TestRegExp(/rch/);
+
+    assert(accesses == &quot;&quot;, &quot;unexpected call to overridden props&quot;);
+    let result = RegExp.prototype.test.call(obj, &quot;searchme&quot;);
+    assert(accesses == &quot;exec&quot;, &quot;Property accesses do not match expectation&quot;);
+    assert(result === true, &quot;Unexpected result&quot;);
+
+    accesses = [];
+    obj = new TestRegExp(/not/);
+
+    assert(accesses == &quot;&quot;, &quot;unexpected call to overridden props&quot;);
+    result = RegExp.prototype.test.call(obj, &quot;searchme&quot;);
+    assert(accesses == &quot;exec&quot;, &quot;Property accesses do not match expectation&quot;);
+    assert(result === false, &quot;Unexpected result&quot;);
+})();
+
+// 2 levels of RegExp subclasses with the middle parent overriding exec.
+(function () {
+    let accesses = [];
+    class RegExpB extends RegExp {
+        exec(str) {
+            accesses.push(&quot;exec&quot;);
+            return super.exec(str);
+        }
+    }
+    class RegExpC extends RegExpB { }
+
+    assert(RegExpB.__proto__ == RegExp);
+    assert(RegExpC.__proto__ == RegExpB);
+
+    let obj = new RegExpC(/rch/);
+
+    assert(accesses == &quot;&quot;, &quot;unexpected call to overridden props&quot;);
+    let result = RegExp.prototype.test.call(obj, &quot;searchme&quot;);
+    assert(accesses == &quot;exec&quot;, &quot;Property accesses do not match expectation&quot;);
+    assert(result === true, &quot;Unexpected result&quot;);
+
+    accesses = [];
+    obj = new RegExpC(/not/);
+
+    assert(accesses == &quot;&quot;, &quot;unexpected call to overridden props&quot;);
+    result = RegExp.prototype.test.call(obj, &quot;searchme&quot;);
+    assert(accesses == &quot;exec&quot;, &quot;Property accesses do not match expectation&quot;);
+    assert(result === false, &quot;Unexpected result&quot;);
+})();
+
+// 2 levels of RegExp subclasses with substituted prototype before instantiation.
+(function () {
+    let accesses = [];
+    let regExpForOverriddenExec = /rch/;
+
+    class B extends RegExp { }
+    class C extends B { }
+
+    assert(B.__proto__ === RegExp);
+    assert(C.__proto__ === B);
+    assert(B.prototype.__proto__ === RegExp.prototype);
+    assert(C.prototype.__proto__ === B.prototype);
+
+    let X = function () {}
+    Object.defineProperty(X.prototype, &quot;exec&quot;, {
+        value: function(str) {
+            accesses.push(&quot;exec&quot;);
+            return regExpForOverriddenExec.exec(str);
+        }
+    });
+
+    // Monkey with the prototype chain before instantiating C.
+    X.__proto__ = RegExp;
+    X.prototype.__proto__ = RegExp.prototype;
+    C.__proto__ = X;
+    C.prototype.__proto__ = X.prototype;
+
+    assert(X.__proto__ === RegExp);
+    assert(C.__proto__ === X);
+    assert(X.prototype.__proto__ === RegExp.prototype);
+    assert(C.prototype.__proto__ === X.prototype);
+
+    let obj = new C();
+
+    assert(accesses == &quot;&quot;, &quot;unexpected call to overridden props&quot;);
+    let result = RegExp.prototype.test.call(obj, &quot;searchme&quot;);
+    assert(accesses == &quot;exec&quot;, &quot;Property accesses do not match expectation&quot;);
+    assert(result === true, &quot;Unexpected result&quot;);
+
+    accesses = [];
+    regExpForOverriddenExec = /not/;
+
+    assert(accesses == &quot;&quot;, &quot;unexpected call to overridden props&quot;);
+    result = RegExp.prototype.test.call(obj, &quot;searchme&quot;);
+    assert(accesses == &quot;exec&quot;, &quot;Property accesses do not match expectation&quot;);
+    assert(result === false, &quot;Unexpected result&quot;);
+})();
+
+// 2 levels of RegExp subclasses with substituted prototype after instantiation.
+(function () {
+    let accesses = [];
+    let regExpForOverriddenExec = /rch/;
+
+    class B extends RegExp { }
+    class C extends B { }
+
+    assert(B.__proto__ === RegExp);
+    assert(C.__proto__ === B);
+    assert(B.prototype.__proto__ === RegExp.prototype);
+    assert(C.prototype.__proto__ === B.prototype);
+
+    let obj = new C();
+
+    let X = function () {}
+    Object.defineProperty(X.prototype, &quot;exec&quot;, {
+        value: function(str) {
+            accesses.push(&quot;exec&quot;);
+            return regExpForOverriddenExec.exec(str);
+        }
+    });
+
+    // Monkey with the prototype chain after instantiating C.
+    X.__proto__ = RegExp;
+    X.prototype.__proto__ = RegExp.prototype;
+    C.__proto__ = X;
+    C.prototype.__proto__ = X.prototype;
+
+    assert(X.__proto__ === RegExp);
+    assert(C.__proto__ === X);
+    assert(X.prototype.__proto__ === RegExp.prototype);
+    assert(C.prototype.__proto__ === X.prototype);
+
+    assert(accesses == &quot;&quot;, &quot;unexpected call to overridden props&quot;);
+    let result = RegExp.prototype.test.call(obj, &quot;searchme&quot;);
+    assert(accesses == &quot;exec&quot;, &quot;Property accesses do not match expectation&quot;);
+    assert(result === true, &quot;Unexpected result&quot;);
+
+    accesses = [];
+    regExpForOverriddenExec = /not/;
+
+    assert(accesses == &quot;&quot;, &quot;unexpected call to overridden props&quot;);
+    result = RegExp.prototype.test.call(obj, &quot;searchme&quot;);
+    assert(accesses == &quot;exec&quot;, &quot;Property accesses do not match expectation&quot;);
+    assert(result === false, &quot;Unexpected result&quot;);
+})();
+
+// 2 levels of RegExp subclasses with proxied prototype.
+(function () {
+    let accesses = [];
+    let regExpForOverriddenExec = /rch/;
+
+    class B extends RegExp { };
+
+    assert(B.__proto__ === RegExp);
+    assert(B.prototype.__proto__ === RegExp.prototype);
+
+    let proxy = new Proxy(RegExp.prototype, {
+        get: function(obj, prop) {
+            accesses.push(&quot;get_&quot; + prop.toString());
+
+            function proxyExec(str) {
+                accesses.push(&quot;exec&quot;);
+                return regExpForOverriddenExec.exec(str);
+            }
+
+            if (prop === &quot;exec&quot;)
+                return proxyExec;
+            return obj[prop];
+        },
+        set: function(obj, prop, value) {
+            accesses.push(&quot;set_&quot; + prop.toString());
+        }
+    });
+    B.prototype.__proto__ = proxy;
+
+    let obj = new B();
+
+    assert(accesses == &quot;&quot;, &quot;unexpected call to overridden props&quot;);
+    let result = RegExp.prototype.test.call(obj, &quot;searchme&quot;);
+    assert(accesses == &quot;get_exec,exec&quot;, &quot;Property accesses do not match expectation&quot;);
+    assert(result === true, &quot;Unexpected result&quot;);
+
+    accesses = [];
+    regExpForOverriddenExec = /not/;
+
+    assert(accesses == &quot;&quot;, &quot;unexpected call to overridden props&quot;);
+    result = RegExp.prototype.test.call(obj, &quot;searchme&quot;);
+    assert(accesses == &quot;get_exec,exec&quot;, &quot;Property accesses do not match expectation&quot;);
+    assert(result === false, &quot;Unexpected result&quot;);
+})();
+
+// Proxied RegExp observing every get.
+(function () {
+    let accesses = [];
+    let regexp = new RegExp(/rch/);
+    let proxy = new Proxy(regexp, {
+        get(obj, prop) {
+            accesses.push(prop.toString());
+            if (prop == &quot;exec&quot;) {
+                return function(str) {
+                    return obj.exec(str);
+                }
+            }
+            return obj[prop];
+        }
+    });
+
+    assert(accesses == &quot;&quot;, &quot;unexpected call to overridden props&quot;);
+    let result = RegExp.prototype.test.call(proxy, &quot;searchme&quot;);
+    assert(accesses.toString() == &quot;exec&quot;, &quot;Proxy not able to observe some gets&quot;);
+    assert(result === true, &quot;Unexpected result&quot;);
+
+    accesses = [];
+    regexp = new RegExp(/not/);
+    proxy = new Proxy(regexp, {
+        get(obj, prop) {
+            accesses.push(prop.toString());
+            if (prop == &quot;exec&quot;) {
+                return function(str) {
+                    return obj.exec(str);
+                }
+            }
+            return obj[prop];
+        }
+    });
+
+    assert(accesses == &quot;&quot;, &quot;unexpected call to overridden props&quot;);
+    result = RegExp.prototype.test.call(proxy, &quot;searchme&quot;);
+    assert(accesses.toString() == &quot;exec&quot;, &quot;Proxy not able to observe some gets&quot;);
+    assert(result === false, &quot;Unexpected result&quot;);
+})();
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestsregexpprototypetestobservablesideeffects2js"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/regexp-prototype-test-observable-side-effects2.js (0 => 200272)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/regexp-prototype-test-observable-side-effects2.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/regexp-prototype-test-observable-side-effects2.js        2016-04-30 00:34:01 UTC (rev 200272)
</span><span class="lines">@@ -0,0 +1,34 @@
</span><ins>+//@ runDefault
+
+function assert(testedValue, msg) {
+    if (!testedValue)
+        throw Error(msg);
+}
+
+// RegExp.prototype with overridden exec.
+(function () {
+    let accesses = [];
+    let origExec = RegExp.prototype.exec;
+
+    let obj = /rch/;
+    Object.defineProperty(RegExp.prototype, &quot;exec&quot;, {
+        value: function(str) {
+            accesses.push(&quot;exec&quot;);
+            return origExec.call(this, str);
+        }
+    });
+
+    assert(accesses == &quot;&quot;, &quot;unexpected call to overridden props&quot;);
+    let result = RegExp.prototype.test.call(obj, &quot;searchme&quot;);
+    assert(accesses == &quot;exec&quot;, &quot;Property accesses do not match expectation&quot;);
+    assert(result === true, &quot;Unexpected result&quot;);
+
+    accesses = [];
+    obj = /not/;
+
+    assert(accesses == &quot;&quot;, &quot;unexpected call to overridden props&quot;);
+    result = RegExp.prototype.test.call(obj, &quot;searchme&quot;);
+    assert(accesses == &quot;exec&quot;, &quot;Property accesses do not match expectation&quot;);
+    assert(result === false, &quot;Unexpected result&quot;);
+})();
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestssimpleregexptestfoldingfailwithhoistedregexpjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/simple-regexp-test-folding-fail-with-hoisted-regexp.js (0 => 200272)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/simple-regexp-test-folding-fail-with-hoisted-regexp.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/simple-regexp-test-folding-fail-with-hoisted-regexp.js        2016-04-30 00:34:01 UTC (rev 200272)
</span><span class="lines">@@ -0,0 +1,9 @@
</span><ins>+(function() {
+    for (var j = 0; j &lt; 10; ++j) {
+        (function () {
+            var regExp = /foo/;
+            for (var i = 0; i &lt; 100000; ++i)
+                regExp.test(&quot;bar&quot;);
+        })();
+    }
+})();
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestssimpleregexptestfoldingwithhoistedregexpjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/simple-regexp-test-folding-with-hoisted-regexp.js (0 => 200272)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/simple-regexp-test-folding-with-hoisted-regexp.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/simple-regexp-test-folding-with-hoisted-regexp.js        2016-04-30 00:34:01 UTC (rev 200272)
</span><span class="lines">@@ -0,0 +1,9 @@
</span><ins>+(function() {
+    for (var j = 0; j &lt; 10; ++j) {
+        (function () {
+            var regExp = /foo/;
+            for (var i = 0; i &lt; 100000; ++i)
+                regExp.test(&quot;foo&quot;);
+        })();
+    }
+})();
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregresssimpleregexptestfoldingfailwithhoistedregexpexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/simple-regexp-test-folding-fail-with-hoisted-regexp-expected.txt (0 => 200272)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/simple-regexp-test-folding-fail-with-hoisted-regexp-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/simple-regexp-test-folding-fail-with-hoisted-regexp-expected.txt        2016-04-30 00:34:01 UTC (rev 200272)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/simple-regexp-test-folding-fail-with-hoisted-regexp
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregresssimpleregexptestfoldingfailwithhoistedregexphtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/simple-regexp-test-folding-fail-with-hoisted-regexp.html (0 => 200272)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/simple-regexp-test-folding-fail-with-hoisted-regexp.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/simple-regexp-test-folding-fail-with-hoisted-regexp.html        2016-04-30 00:34:01 UTC (rev 200272)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script src=&quot;../../resources/regress-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;script-tests/simple-regexp-test-folding-fail-with-hoisted-regexp.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/regress-post.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregresssimpleregexptestfoldingwithhoistedregexpexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/simple-regexp-test-folding-with-hoisted-regexp-expected.txt (0 => 200272)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/simple-regexp-test-folding-with-hoisted-regexp-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/simple-regexp-test-folding-with-hoisted-regexp-expected.txt        2016-04-30 00:34:01 UTC (rev 200272)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/simple-regexp-test-folding-with-hoisted-regexp
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregresssimpleregexptestfoldingwithhoistedregexphtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/simple-regexp-test-folding-with-hoisted-regexp.html (0 => 200272)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/simple-regexp-test-folding-with-hoisted-regexp.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/simple-regexp-test-folding-with-hoisted-regexp.html        2016-04-30 00:34:01 UTC (rev 200272)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script src=&quot;../../resources/regress-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;script-tests/simple-regexp-test-folding-with-hoisted-regexp.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/regress-post.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (200271 => 200272)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-04-30 00:12:35 UTC (rev 200271)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-04-30 00:34:01 UTC (rev 200272)
</span><span class="lines">@@ -1,3 +1,47 @@
</span><ins>+2016-04-29  Mark Lam  &lt;mark.lam@apple.com&gt;
+
+        Make RegExp.prototype.test spec compliant.
+        https://bugs.webkit.org/show_bug.cgi?id=155862
+
+        Reviewed by Saam Barati.
+
+        * builtins/RegExpPrototype.js:
+        (intrinsic.RegExpTestIntrinsic.test):
+
+        * create_hash_table:
+        - Delete obsoleted code.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::addToGraph):
+        (JSC::DFG::ByteCodeParser::handleIntrinsicCall):
+        - We now have 2 intrinsics for RegExp.prototype.test:
+          RegExpTestIntrinsic and RegExpTestFastIntrinsic.
+
+          RegExpTestIntrinsic maps to the entry at the top of the builtin ES6
+          RegExp.prototype.test.
+          RegExpTestFastIntrinsic maps to the fast path in the builtin ES6
+          RegExp.prototype.test.
+
+          Both will end up using the RegExpTest DFG node to implement the fast path
+          of RegExp.prototype.test.  RegExpTestIntrinsic will have some additional checks
+          before the RegExpTest node.  Those checks are for speculating that it is ok for
+          us to take the fast path.
+
+        * runtime/CommonIdentifiers.h:
+        * runtime/Intrinsic.h:
+
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        - Added the regExpTestFast function.
+        - Also fixed the parameter length on 2 other functions that were erroneous.
+
+        * runtime/RegExpPrototype.cpp:
+        (JSC::RegExpPrototype::finishCreation):
+        (JSC::regExpProtoFuncTestFast):
+        (JSC::regExpProtoFuncTest): Deleted.
+        * runtime/RegExpPrototype.h:
+        * tests/es6.yaml:
+
</ins><span class="cx"> 2016-04-29  Benjamin Poulain  &lt;benjamin@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Extend math-pow-stable-results.js to get more information about the failure
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebuiltinsRegExpPrototypejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/builtins/RegExpPrototype.js (200271 => 200272)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/builtins/RegExpPrototype.js        2016-04-30 00:12:35 UTC (rev 200271)
+++ trunk/Source/JavaScriptCore/builtins/RegExpPrototype.js        2016-04-30 00:34:01 UTC (rev 200272)
</span><span class="lines">@@ -487,3 +487,31 @@
</span><span class="cx">     // 22. Return A.
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><ins>+
+// ES 21.2.5.13 RegExp.prototype.test(string)
+[intrinsic=RegExpTestIntrinsic] function test(strArg)
+{
+    &quot;use strict&quot;;
+
+    let regexp = this;
+
+    // Check for observable side effects and call the fast path if there aren't any.
+    if (@isRegExpObject(regexp) &amp;&amp; @tryGetById(regexp, &quot;exec&quot;) === @regExpBuiltinExec)
+        return @regExpTestFast.@call(regexp, strArg);
+
+    // 1. Let R be the this value.
+    // 2. If Type(R) is not Object, throw a TypeError exception.
+    if (!@isObject(regexp))
+        throw new @TypeError(&quot;RegExp.prototype.test requires that |this| be an Object&quot;);
+
+    // 3. Let string be ? ToString(S).
+    let str = @toString(strArg);
+
+    // 4. Let match be ? RegExpExec(R, string).
+    let match = @regExpExec(regexp, str);
+
+    // 5. If match is not null, return true; else return false.
+    if (match !== null)
+        return true;
+    return false;
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorecreate_hash_table"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/create_hash_table (200271 => 200272)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/create_hash_table        2016-04-30 00:12:35 UTC (rev 200271)
+++ trunk/Source/JavaScriptCore/create_hash_table        2016-04-30 00:34:01 UTC (rev 200272)
</span><span class="lines">@@ -306,10 +306,6 @@
</span><span class="cx">             $intrinsic = &quot;ArrayPushIntrinsic&quot; if ($key eq &quot;push&quot;);
</span><span class="cx">             $intrinsic = &quot;ArrayPopIntrinsic&quot; if ($key eq &quot;pop&quot;);
</span><span class="cx">         }
</span><del>-        if ($name eq &quot;regExpPrototypeTable&quot;) {
-            $intrinsic = &quot;RegExpExecIntrinsic&quot; if ($key eq &quot;exec&quot;);
-            $intrinsic = &quot;RegExpTestIntrinsic&quot; if ($key eq &quot;test&quot;);
-        }
</del><span class="cx"> 
</span><span class="cx">         if ($values[$i]{&quot;type&quot;} eq &quot;Function&quot; &amp;&amp; $firstValue eq &quot;JSBuiltin&quot;)  {
</span><span class="cx">             my $tableHead = $name;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (200271 => 200272)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2016-04-30 00:12:35 UTC (rev 200271)
+++ trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2016-04-30 00:34:01 UTC (rev 200272)
</span><span class="lines">@@ -48,7 +48,7 @@
</span><span class="cx"> #include &quot;PreciseJumpTargets.h&quot;
</span><span class="cx"> #include &quot;PutByIdFlags.h&quot;
</span><span class="cx"> #include &quot;PutByIdStatus.h&quot;
</span><del>-#include &lt;RegExpPrototype.h&gt;
</del><ins>+#include &quot;RegExpPrototype.h&quot;
</ins><span class="cx"> #include &quot;StackAlignment.h&quot;
</span><span class="cx"> #include &quot;StringConstructor.h&quot;
</span><span class="cx"> #include &quot;StructureStubInfo.h&quot;
</span><span class="lines">@@ -721,6 +721,11 @@
</span><span class="cx">             Edge(child3));
</span><span class="cx">         return addToGraph(result);
</span><span class="cx">     }
</span><ins>+    Node* addToGraph(NodeType op, OpInfo info, Edge child1, Edge child2 = Edge(), Edge child3 = Edge())
+    {
+        Node* result = m_graph.addNode(SpecNone, op, currentNodeOrigin(), info, child1, child2, child3);
+        return addToGraph(result);
+    }
</ins><span class="cx">     Node* addToGraph(NodeType op, OpInfo info1, OpInfo info2, Node* child1 = 0, Node* child2 = 0, Node* child3 = 0)
</span><span class="cx">     {
</span><span class="cx">         Node* result = m_graph.addNode(
</span><span class="lines">@@ -728,6 +733,12 @@
</span><span class="cx">             Edge(child1), Edge(child2), Edge(child3));
</span><span class="cx">         return addToGraph(result);
</span><span class="cx">     }
</span><ins>+    Node* addToGraph(NodeType op, OpInfo info1, OpInfo info2, Edge child1, Edge child2 = Edge(), Edge child3 = Edge())
+    {
+        Node* result = m_graph.addNode(
+            SpecNone, op, currentNodeOrigin(), info1, info2, child1, child2, child3);
+        return addToGraph(result);
+    }
</ins><span class="cx">     
</span><span class="cx">     Node* addToGraph(Node::VarArgTag, NodeType op, OpInfo info1, OpInfo info2)
</span><span class="cx">     {
</span><span class="lines">@@ -2205,12 +2216,52 @@
</span><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx">         
</span><del>-    case RegExpTestIntrinsic: {
</del><ins>+    case RegExpTestIntrinsic:
+    case RegExpTestFastIntrinsic: {
</ins><span class="cx">         if (argumentCountIncludingThis != 2)
</span><span class="cx">             return false;
</span><del>-        
</del><ins>+
+        if (intrinsic == RegExpTestIntrinsic) {
+            // Don't inline intrinsic if we exited due to one of the primordial RegExp checks failing.
+            if (m_inlineStackTop-&gt;m_exitProfile.hasExitSite(m_currentIndex, BadCell))
+                return false;
+
+            JSGlobalObject* globalObject = m_inlineStackTop-&gt;m_codeBlock-&gt;globalObject();
+            Structure* regExpStructure = globalObject-&gt;regExpStructure();
+            m_graph.registerStructure(regExpStructure);
+            ASSERT(regExpStructure-&gt;storedPrototype().isObject());
+            ASSERT(regExpStructure-&gt;storedPrototype().asCell()-&gt;classInfo() == RegExpPrototype::info());
+
+            FrozenValue* regExpPrototypeObjectValue = m_graph.freeze(regExpStructure-&gt;storedPrototype());
+            Structure* regExpPrototypeStructure = regExpPrototypeObjectValue-&gt;structure();
+
+            auto isRegExpPropertySame = [&amp;] (JSValue primordialProperty, UniquedStringImpl* propertyUID) {
+                JSValue currentProperty;
+                if (!m_graph.getRegExpPrototypeProperty(regExpStructure-&gt;storedPrototypeObject(), regExpPrototypeStructure, propertyUID, currentProperty))
+                    return false;
+                
+                return currentProperty == primordialProperty;
+            };
+
+            // Check that RegExp.exec is still the primordial RegExp.prototype.exec
+            if (!isRegExpPropertySame(globalObject-&gt;regExpProtoExecFunction(), m_vm-&gt;propertyNames-&gt;exec.impl()))
+                return false;
+
+            // Check that regExpObject is actually a RegExp object.
+            Node* regExpObject = get(virtualRegisterForArgument(0, registerOffset));
+            addToGraph(Check, Edge(regExpObject, RegExpObjectUse));
+
+            // Check that regExpObject's exec is actually the primodial RegExp.prototype.exec.
+            UniquedStringImpl* execPropertyID = m_vm-&gt;propertyNames-&gt;exec.impl();
+            unsigned execIndex = m_graph.identifiers().ensure(execPropertyID);
+            Node* actualProperty = addToGraph(TryGetById, OpInfo(execIndex), OpInfo(SpecFunction), Edge(regExpObject, CellUse));
+            FrozenValue* regExpPrototypeExec = m_graph.freeze(globalObject-&gt;regExpProtoExecFunction());
+            addToGraph(CheckCell, OpInfo(regExpPrototypeExec), Edge(actualProperty, CellUse));
+        }
+
</ins><span class="cx">         insertChecks();
</span><del>-        Node* regExpExec = addToGraph(RegExpTest, OpInfo(0), OpInfo(prediction), addToGraph(GetGlobalObject, callee), get(virtualRegisterForArgument(0, registerOffset)), get(virtualRegisterForArgument(1, registerOffset)));
</del><ins>+        Node* regExpObject = get(virtualRegisterForArgument(0, registerOffset));
+        Node* regExpExec = addToGraph(RegExpTest, OpInfo(0), OpInfo(prediction), addToGraph(GetGlobalObject, callee), regExpObject, get(virtualRegisterForArgument(1, registerOffset)));
</ins><span class="cx">         set(VirtualRegister(resultOperand), regExpExec);
</span><span class="cx">         
</span><span class="cx">         return true;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeCommonIdentifiersh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h (200271 => 200272)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h        2016-04-30 00:12:35 UTC (rev 200271)
+++ trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h        2016-04-30 00:34:01 UTC (rev 200272)
</span><span class="lines">@@ -436,10 +436,11 @@
</span><span class="cx">     macro(regExpProtoSourceGetter) \
</span><span class="cx">     macro(regExpProtoStickyGetter) \
</span><span class="cx">     macro(regExpProtoUnicodeGetter) \
</span><ins>+    macro(regExpPrototypeSymbolReplace) \
</ins><span class="cx">     macro(regExpReplaceFast) \
</span><span class="cx">     macro(regExpSearchFast) \
</span><span class="cx">     macro(regExpSplitFast) \
</span><del>-    macro(regExpPrototypeSymbolReplace) \
</del><ins>+    macro(regExpTestFast) \
</ins><span class="cx">     macro(stringIncludesInternal) \
</span><span class="cx">     macro(stringSplitFast) \
</span><span class="cx">     macro(stringSubstrInternal) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeIntrinsich"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Intrinsic.h (200271 => 200272)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Intrinsic.h        2016-04-30 00:12:35 UTC (rev 200271)
+++ trunk/Source/JavaScriptCore/runtime/Intrinsic.h        2016-04-30 00:34:01 UTC (rev 200272)
</span><span class="lines">@@ -51,6 +51,7 @@
</span><span class="cx">     LogIntrinsic,
</span><span class="cx">     RegExpExecIntrinsic,
</span><span class="cx">     RegExpTestIntrinsic,
</span><ins>+    RegExpTestFastIntrinsic,
</ins><span class="cx">     StringPrototypeValueOfIntrinsic,
</span><span class="cx">     StringPrototypeReplaceIntrinsic,
</span><span class="cx">     StringPrototypeReplaceRegExpIntrinsic,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGlobalObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp (200271 => 200272)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp        2016-04-30 00:12:35 UTC (rev 200271)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp        2016-04-30 00:34:01 UTC (rev 200272)
</span><span class="lines">@@ -652,10 +652,11 @@
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;builtinNames().hasObservableSideEffectsForRegExpSplitPrivateName(), JSFunction::createBuiltinFunction(vm, regExpPrototypeHasObservableSideEffectsForRegExpSplitCodeGenerator(vm), this), DontEnum | DontDelete | ReadOnly),
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;builtinNames().advanceStringIndexPrivateName(), JSFunction::createBuiltinFunction(vm, regExpPrototypeAdvanceStringIndexCodeGenerator(vm), this), DontEnum | DontDelete | ReadOnly),
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;builtinNames().regExpExecPrivateName(), JSFunction::createBuiltinFunction(vm, regExpPrototypeRegExpExecCodeGenerator(vm), this), DontEnum | DontDelete | ReadOnly),
</span><del>-        GlobalPropertyInfo(vm.propertyNames-&gt;regExpMatchFastPrivateName, JSFunction::create(vm, this, 2, String(), regExpProtoFuncMatchFast), DontEnum | DontDelete | ReadOnly),
-        GlobalPropertyInfo(vm.propertyNames-&gt;regExpSearchFastPrivateName, JSFunction::create(vm, this, 2, String(), regExpProtoFuncSearchFast), DontEnum | DontDelete | ReadOnly),
</del><ins>+        GlobalPropertyInfo(vm.propertyNames-&gt;regExpMatchFastPrivateName, JSFunction::create(vm, this, 1, String(), regExpProtoFuncMatchFast), DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames-&gt;regExpSearchFastPrivateName, JSFunction::create(vm, this, 1, String(), regExpProtoFuncSearchFast), DontEnum | DontDelete | ReadOnly),
</ins><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;regExpSplitFastPrivateName, JSFunction::create(vm, this, 2, String(), regExpProtoFuncSplitFast), DontEnum | DontDelete | ReadOnly),
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;regExpPrototypeSymbolReplacePrivateName, m_regExpPrototype-&gt;getDirect(vm, vm.propertyNames-&gt;replaceSymbol), DontEnum | DontDelete | ReadOnly),
</span><ins>+        GlobalPropertyInfo(vm.propertyNames-&gt;regExpTestFastPrivateName, JSFunction::create(vm, this, 1, String(), regExpProtoFuncTestFast, RegExpTestFastIntrinsic), DontEnum | DontDelete | ReadOnly),
</ins><span class="cx"> 
</span><span class="cx">         // String.prototype helpers.
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;builtinNames().hasObservableSideEffectsForStringReplacePrivateName(), JSFunction::createBuiltinFunction(vm, stringPrototypeHasObservableSideEffectsForStringReplaceCodeGenerator(vm), this), DontEnum | DontDelete | ReadOnly),
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeRegExpPrototypecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/RegExpPrototype.cpp (200271 => 200272)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/RegExpPrototype.cpp        2016-04-30 00:12:35 UTC (rev 200271)
+++ trunk/Source/JavaScriptCore/runtime/RegExpPrototype.cpp        2016-04-30 00:34:01 UTC (rev 200272)
</span><span class="lines">@@ -44,7 +44,6 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><del>-static EncodedJSValue JSC_HOST_CALL regExpProtoFuncTest(ExecState*);
</del><span class="cx"> static EncodedJSValue JSC_HOST_CALL regExpProtoFuncExec(ExecState*);
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState*);
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL regExpProtoFuncToString(ExecState*);
</span><span class="lines">@@ -69,7 +68,6 @@
</span><span class="cx">     ASSERT(inherits(info()));
</span><span class="cx">     JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames-&gt;compile, regExpProtoFuncCompile, DontEnum, 2);
</span><span class="cx">     JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames-&gt;exec, regExpProtoFuncExec, DontEnum, 1, RegExpExecIntrinsic);
</span><del>-    JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames-&gt;test, regExpProtoFuncTest, DontEnum, 1, RegExpTestIntrinsic);
</del><span class="cx">     JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames-&gt;toString, regExpProtoFuncToString, DontEnum, 0);
</span><span class="cx">     JSC_NATIVE_GETTER(vm.propertyNames-&gt;global, regExpProtoGetterGlobal, DontEnum | Accessor);
</span><span class="cx">     JSC_NATIVE_GETTER(vm.propertyNames-&gt;ignoreCase, regExpProtoGetterIgnoreCase, DontEnum | Accessor);
</span><span class="lines">@@ -82,6 +80,7 @@
</span><span class="cx">     JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames-&gt;replaceSymbol, regExpPrototypeReplaceCodeGenerator, DontEnum);
</span><span class="cx">     JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames-&gt;searchSymbol, regExpPrototypeSearchCodeGenerator, DontEnum);
</span><span class="cx">     JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames-&gt;splitSymbol, regExpPrototypeSplitCodeGenerator, DontEnum);
</span><ins>+    JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames-&gt;test, regExpPrototypeTestCodeGenerator, DontEnum);
</ins><span class="cx"> 
</span><span class="cx">     m_emptyRegExp.set(vm, this, RegExp::create(vm, &quot;&quot;, NoFlags));
</span><span class="cx"> }
</span><span class="lines">@@ -97,7 +96,7 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------------------------ Functions ---------------------------
</span><span class="cx"> 
</span><del>-EncodedJSValue JSC_HOST_CALL regExpProtoFuncTest(ExecState* exec)
</del><ins>+EncodedJSValue JSC_HOST_CALL regExpProtoFuncTestFast(ExecState* exec)
</ins><span class="cx"> {
</span><span class="cx">     JSValue thisValue = exec-&gt;thisValue();
</span><span class="cx">     if (!thisValue.inherits(RegExpObject::info()))
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeRegExpPrototypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/RegExpPrototype.h (200271 => 200272)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/RegExpPrototype.h        2016-04-30 00:12:35 UTC (rev 200271)
+++ trunk/Source/JavaScriptCore/runtime/RegExpPrototype.h        2016-04-30 00:34:01 UTC (rev 200272)
</span><span class="lines">@@ -61,6 +61,7 @@
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL regExpProtoFuncMatchFast(ExecState*);
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL regExpProtoFuncSearchFast(ExecState*);
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL regExpProtoFuncSplitFast(ExecState*);
</span><ins>+EncodedJSValue JSC_HOST_CALL regExpProtoFuncTestFast(ExecState*);
</ins><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestses6yaml"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/tests/es6.yaml (200271 => 200272)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/es6.yaml        2016-04-30 00:12:35 UTC (rev 200271)
+++ trunk/Source/JavaScriptCore/tests/es6.yaml        2016-04-30 00:34:01 UTC (rev 200272)
</span><span class="lines">@@ -997,7 +997,7 @@
</span><span class="cx"> - path: es6/Proxy_internal_get_calls_RegExp.prototype.flags.js
</span><span class="cx">   cmd: runES6 :normal
</span><span class="cx"> - path: es6/Proxy_internal_get_calls_RegExp.prototype.test.js
</span><del>-  cmd: runES6 :fail
</del><ins>+  cmd: runES6 :normal
</ins><span class="cx"> - path: es6/Proxy_internal_get_calls_RegExp.prototype.toString.js
</span><span class="cx">   cmd: runES6 :normal
</span><span class="cx"> - path: es6/Proxy_internal_get_calls_RegExp.prototype[Symbol.match].js
</span></span></pre>
</div>
</div>

</body>
</html>