<!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>[199144] 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/199144">199144</a></dd>
<dt>Author</dt> <dd>mark.lam@apple.com</dd>
<dt>Date</dt> <dd>2016-04-06 20:17:58 -0700 (Wed, 06 Apr 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>String.prototype.match() should be calling internal function RegExpCreate.
https://bugs.webkit.org/show_bug.cgi?id=156318

Reviewed by Filip Pizlo.

RegExpCreate is not the same as the RegExp constructor.  The current implementation
invokes new @RegExp which calls the constructor.  This results in failures in
es6/Proxy_internal_get_calls_String.prototype.match.js, and
es6/Proxy_internal_get_calls_String.prototype.search.js due to observable side
effects.

This patch fixes this by factoring out the part of the RegExp constructor that
makes the RegExpCreate function, and changing String's match and search to call
RegExpCreate instead in accordance with the ES6 spec. 

* builtins/StringPrototype.js:
(match):
(search):
* runtime/CommonIdentifiers.h:
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
* runtime/RegExpConstructor.cpp:
(JSC::toFlags):
(JSC::regExpCreate):
(JSC::constructRegExp):
(JSC::esSpecRegExpCreate):
(JSC::constructWithRegExpConstructor):
* runtime/RegExpConstructor.h:
(JSC::isRegExp):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCorebuiltinsStringPrototypejs">trunk/Source/JavaScriptCore/builtins/StringPrototype.js</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeCommonIdentifiersh">trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGlobalObjectcpp">trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeRegExpConstructorcpp">trunk/Source/JavaScriptCore/runtime/RegExpConstructor.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeRegExpConstructorh">trunk/Source/JavaScriptCore/runtime/RegExpConstructor.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (199143 => 199144)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-04-07 02:09:07 UTC (rev 199143)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-04-07 03:17:58 UTC (rev 199144)
</span><span class="lines">@@ -1,3 +1,35 @@
</span><ins>+2016-04-06  Mark Lam  &lt;mark.lam@apple.com&gt;
+
+        String.prototype.match() should be calling internal function RegExpCreate.
+        https://bugs.webkit.org/show_bug.cgi?id=156318
+
+        Reviewed by Filip Pizlo.
+
+        RegExpCreate is not the same as the RegExp constructor.  The current implementation
+        invokes new @RegExp which calls the constructor.  This results in failures in
+        es6/Proxy_internal_get_calls_String.prototype.match.js, and
+        es6/Proxy_internal_get_calls_String.prototype.search.js due to observable side
+        effects.
+
+        This patch fixes this by factoring out the part of the RegExp constructor that
+        makes the RegExpCreate function, and changing String's match and search to call
+        RegExpCreate instead in accordance with the ES6 spec. 
+
+        * builtins/StringPrototype.js:
+        (match):
+        (search):
+        * runtime/CommonIdentifiers.h:
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        * runtime/RegExpConstructor.cpp:
+        (JSC::toFlags):
+        (JSC::regExpCreate):
+        (JSC::constructRegExp):
+        (JSC::esSpecRegExpCreate):
+        (JSC::constructWithRegExpConstructor):
+        * runtime/RegExpConstructor.h:
+        (JSC::isRegExp):
+
</ins><span class="cx"> 2016-04-06  Keith Miller  &lt;keith_miller@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, uncomment accidentally commented line in test.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebuiltinsStringPrototypejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/builtins/StringPrototype.js (199143 => 199144)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/builtins/StringPrototype.js        2016-04-07 02:09:07 UTC (rev 199143)
+++ trunk/Source/JavaScriptCore/builtins/StringPrototype.js        2016-04-07 03:17:58 UTC (rev 199144)
</span><span class="lines">@@ -1,6 +1,7 @@
</span><span class="cx"> /*
</span><span class="cx">  * Copyright (C) 2015 Andy VanWagoner &lt;thetalecrafter@gmail.com&gt;.
</span><span class="cx">  * Copyright (C) 2016 Yusuke Suzuki &lt;utatane.tea@gmail.com&gt;
</span><ins>+ * Copyright (C) 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -41,7 +42,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     let thisString = @toString(this);
</span><del>-    let createdRegExp = new @RegExp(regexp, @undefined);
</del><ins>+    let createdRegExp = @regExpCreate(regexp, @undefined);
</ins><span class="cx">     return createdRegExp[@symbolMatch](thisString);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -62,7 +63,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     var thisString = @toString(this);
</span><del>-    var createdRegExp = new @RegExp(regexp, @undefined);
</del><ins>+    var createdRegExp = @regExpCreate(regexp, @undefined);
</ins><span class="cx">     return createdRegExp[@symbolSearch](thisString);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeCommonIdentifiersh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h (199143 => 199144)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h        2016-04-07 02:09:07 UTC (rev 199143)
+++ trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h        2016-04-07 03:17:58 UTC (rev 199144)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- *  Copyright (C) 2003, 2007, 2009 Apple Inc. All rights reserved.
</del><ins>+ *  Copyright (C) 2003, 2007, 2009, 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="cx">  *  modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -419,6 +419,7 @@
</span><span class="cx">     macro(print) \
</span><span class="cx">     macro(isSet) \
</span><span class="cx">     macro(isMap) \
</span><ins>+    macro(regExpCreate) \
</ins><span class="cx">     macro(SetIterator) \
</span><span class="cx">     macro(setIteratorNext) \
</span><span class="cx">     macro(MapIterator) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGlobalObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp (199143 => 199144)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp        2016-04-07 02:09:07 UTC (rev 199143)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp        2016-04-07 03:17:58 UTC (rev 199144)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2007, 2008, 2009, 2014-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2007-2009, 2014-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  * Copyright (C) 2008 Cameron Zwarich (cwzwarich@uwaterloo.ca)
</span><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="lines">@@ -613,6 +613,8 @@
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;builtinNames().DateTimeFormatPrivateName(), intl-&gt;getDirect(vm, vm.propertyNames-&gt;DateTimeFormat), DontEnum | DontDelete | ReadOnly),
</span><span class="cx">         GlobalPropertyInfo(vm.propertyNames-&gt;builtinNames().NumberFormatPrivateName(), intl-&gt;getDirect(vm, vm.propertyNames-&gt;NumberFormat), DontEnum | DontDelete | ReadOnly),
</span><span class="cx"> #endif // ENABLE(INTL)
</span><ins>+
+        GlobalPropertyInfo(vm.propertyNames-&gt;regExpCreatePrivateName, JSFunction::create(vm, this, 2, String(), esSpecRegExpCreate, NoIntrinsic), DontEnum | DontDelete | ReadOnly),
</ins><span class="cx">     };
</span><span class="cx">     addStaticGlobals(staticGlobals, WTF_ARRAY_LENGTH(staticGlobals));
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeRegExpConstructorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/RegExpConstructor.cpp (199143 => 199144)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/RegExpConstructor.cpp        2016-04-07 02:09:07 UTC (rev 199143)
+++ trunk/Source/JavaScriptCore/runtime/RegExpConstructor.cpp        2016-04-07 03:17:58 UTC (rev 199144)
</span><span class="lines">@@ -1,6 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
</span><del>- *  Copyright (C) 2003, 2007, 2008, 2016 Apple Inc. All Rights Reserved.
</del><ins>+ *  Copyright (C) 2003, 2007-2008, 2016 Apple Inc. All Rights Reserved.
</ins><span class="cx">  *  Copyright (C) 2009 Torch Mobile, Inc.
</span><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="lines">@@ -277,6 +277,27 @@
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static JSObject* regExpCreate(ExecState* exec, JSGlobalObject* globalObject, JSValue newTarget, JSValue patternArg, JSValue flagsArg)
+{
+    VM&amp; vm = exec-&gt;vm();
+    String pattern = patternArg.isUndefined() ? emptyString() : patternArg.toString(exec)-&gt;value(exec);
+    if (exec-&gt;hadException())
+        return nullptr;
+
+    RegExpFlags flags = toFlags(exec, flagsArg);
+    if (flags == InvalidFlags)
+        return nullptr;
+
+    RegExp* regExp = RegExp::create(vm, pattern, flags);
+    if (!regExp-&gt;isValid())
+        return vm.throwException(exec, createSyntaxError(exec, regExp-&gt;errorMessage()));
+
+    Structure* structure = getRegExpStructure(exec, globalObject, newTarget);
+    if (vm.exception())
+        return nullptr;
+    return RegExpObject::create(vm, structure, regExp);
+}
+
</ins><span class="cx"> JSObject* constructRegExp(ExecState* exec, JSGlobalObject* globalObject, const ArgList&amp; args,  JSObject* callee, JSValue newTarget)
</span><span class="cx"> {
</span><span class="cx">     VM&amp; vm = exec-&gt;vm();
</span><span class="lines">@@ -319,22 +340,15 @@
</span><span class="cx">         patternArg = pattern;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    String pattern = patternArg.isUndefined() ? emptyString() : patternArg.toString(exec)-&gt;value(exec);
-    if (exec-&gt;hadException())
-        return nullptr;
</del><ins>+    return regExpCreate(exec, globalObject, newTarget, patternArg, flagsArg);
+}
</ins><span class="cx"> 
</span><del>-    RegExpFlags flags = toFlags(exec, flagsArg);
-    if (flags == InvalidFlags)
-        return nullptr;
-
-    RegExp* regExp = RegExp::create(vm, pattern, flags);
-    if (!regExp-&gt;isValid())
-        return vm.throwException(exec, createSyntaxError(exec, regExp-&gt;errorMessage()));
-
-    Structure* structure = getRegExpStructure(exec, globalObject, newTarget);
-    if (vm.exception())
-        return nullptr;
-    return RegExpObject::create(vm, structure, regExp);
</del><ins>+EncodedJSValue JSC_HOST_CALL esSpecRegExpCreate(ExecState* exec)
+{
+    JSGlobalObject* globalObject = exec-&gt;lexicalGlobalObject();
+    JSValue patternArg = exec-&gt;argument(0);
+    JSValue flagsArg = exec-&gt;argument(1);
+    return JSValue::encode(regExpCreate(exec, globalObject, jsUndefined(), patternArg, flagsArg));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL constructWithRegExpConstructor(ExecState* exec)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeRegExpConstructorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/RegExpConstructor.h (199143 => 199144)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/RegExpConstructor.h        2016-04-07 02:09:07 UTC (rev 199143)
+++ trunk/Source/JavaScriptCore/runtime/RegExpConstructor.h        2016-04-07 03:17:58 UTC (rev 199144)
</span><span class="lines">@@ -148,6 +148,8 @@
</span><span class="cx">     return object-&gt;inherits(RegExpObject::info());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+EncodedJSValue JSC_HOST_CALL esSpecRegExpCreate(ExecState*);
+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span><span class="cx"> #endif // RegExpConstructor_h
</span></span></pre>
</div>
</div>

</body>
</html>