<!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>[212939] 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/212939">212939</a></dd>
<dt>Author</dt> <dd>sbarati@apple.com</dd>
<dt>Date</dt> <dd>2017-02-23 20:07:30 -0800 (Thu, 23 Feb 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Intrinsicify parseInt
https://bugs.webkit.org/show_bug.cgi?id=168627

Reviewed by Filip Pizlo.

JSTests:

* stress/parse-int-intrinsic.js: Added.
(assert):
(testIntrinsic.let.s):
(testIntrinsic):
(testIntrinsic2.baz):
(testIntrinsic2):
(testIntrinsic3.foo):
(testIntrinsic3):
(testIntrinsic4.foo):
(testIntrinsic4):
(testIntrinsic5.foo):
(testIntrinsic5):
(testIntrinsic6.foo):
(testIntrinsic6):
(testIntrinsic7.foo):
(testIntrinsic7):

Source/JavaScriptCore:

This patch makes parseInt an intrinsic in the DFG and FTL.
We do our best to eliminate this node. If we speculate that
the first operand to the operation is an int32, and that there
isn't a second operand, we convert to the identity of the first
operand. That's because parseInt(someInt) === someInt.

If the first operand is proven to be an integer, and the second
operand is the integer 0 or the integer 10, we can eliminate the
node by making it an identity over its first operand. That's
because parseInt(someInt, 0) === someInt and parseInt(someInt, 10) === someInt.

If we are not able to constant fold the node away, we try to remove
checks. The most common use case of parseInt is that its first operand
is a proven string. The DFG might be able to remove type checks in this
case. We also set up CSE rules for parseInt(someString, someIntRadix)
because it's a &quot;pure&quot; operation (modulo resolving a rope).

This looks to be a 4% Octane/Box2D progression.

* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleIntrinsicCall):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGConstantFoldingPhase.cpp:
(JSC::DFG::ConstantFoldingPhase::foldConstants):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGNode.h:
(JSC::DFG::Node::hasHeapPrediction):
* dfg/DFGNodeType.h:
* dfg/DFGOperations.cpp:
(JSC::DFG::parseIntResult):
* dfg/DFGOperations.h:
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileParseInt):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::callOperation):
(JSC::DFG::SpeculativeJIT::appendCallSetResult):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileParseInt):
* jit/JITOperations.h:
* parser/Lexer.cpp:
* runtime/ErrorInstance.cpp:
* runtime/Intrinsic.h:
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
* runtime/JSGlobalObjectFunctions.cpp:
(JSC::toStringView): Deleted.
(JSC::isStrWhiteSpace): Deleted.
(JSC::parseDigit): Deleted.
(JSC::parseIntOverflow): Deleted.
(JSC::parseInt): Deleted.
* runtime/JSGlobalObjectFunctions.h:
* runtime/ParseInt.h: Added.
(JSC::parseDigit):
(JSC::parseIntOverflow):
(JSC::isStrWhiteSpace):
(JSC::parseInt):
(JSC::toStringView):
* runtime/StringPrototype.cpp:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkJSTestsChangeLog">trunk/JSTests/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh">trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp">trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGClobberizeh">trunk/Source/JavaScriptCore/dfg/DFGClobberize.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGConstantFoldingPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGDoesGCcpp">trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGFixupPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeh">trunk/Source/JavaScriptCore/dfg/DFGNode.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeTypeh">trunk/Source/JavaScriptCore/dfg/DFGNodeType.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOperationscpp">trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOperationsh">trunk/Source/JavaScriptCore/dfg/DFGOperations.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSafeToExecuteh">trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITh">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCapabilitiescpp">trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOperationsh">trunk/Source/JavaScriptCore/jit/JITOperations.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserLexercpp">trunk/Source/JavaScriptCore/parser/Lexer.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeErrorInstancecpp">trunk/Source/JavaScriptCore/runtime/ErrorInstance.cpp</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="#trunkSourceJavaScriptCoreruntimeJSGlobalObjectFunctionscpp">trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGlobalObjectFunctionsh">trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeStringPrototypecpp">trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkJSTestsstressparseintintrinsicjs">trunk/JSTests/stress/parse-int-intrinsic.js</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeParseInth">trunk/Source/JavaScriptCore/runtime/ParseInt.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkJSTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/ChangeLog (212938 => 212939)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/ChangeLog        2017-02-24 03:22:05 UTC (rev 212938)
+++ trunk/JSTests/ChangeLog        2017-02-24 04:07:30 UTC (rev 212939)
</span><span class="lines">@@ -1,3 +1,27 @@
</span><ins>+2017-02-23  Saam Barati  &lt;sbarati@apple.com&gt;
+
+        Intrinsicify parseInt
+        https://bugs.webkit.org/show_bug.cgi?id=168627
+
+        Reviewed by Filip Pizlo.
+
+        * stress/parse-int-intrinsic.js: Added.
+        (assert):
+        (testIntrinsic.let.s):
+        (testIntrinsic):
+        (testIntrinsic2.baz):
+        (testIntrinsic2):
+        (testIntrinsic3.foo):
+        (testIntrinsic3):
+        (testIntrinsic4.foo):
+        (testIntrinsic4):
+        (testIntrinsic5.foo):
+        (testIntrinsic5):
+        (testIntrinsic6.foo):
+        (testIntrinsic6):
+        (testIntrinsic7.foo):
+        (testIntrinsic7):
+
</ins><span class="cx"> 2017-02-23  JF Bastien  &lt;jfbastien@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         WebAssembly: support 0x1 version
</span></span></pre></div>
<a id="trunkJSTestsstressparseintintrinsicjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/stress/parse-int-intrinsic.js (0 => 212939)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/stress/parse-int-intrinsic.js                                (rev 0)
+++ trunk/JSTests/stress/parse-int-intrinsic.js        2017-02-24 04:07:30 UTC (rev 212939)
</span><span class="lines">@@ -0,0 +1,97 @@
</span><ins>+&quot;use strict&quot;;
+
+function assert(b) {
+    if (!b)
+        throw new Error(&quot;Bad&quot;)
+}
+
+function testIntrinsic(radix) {
+    let s = `
+        {
+            function foo(n) {
+                n = n|0;
+                return parseInt(n, ${radix});
+            }
+            noInline(foo);
+            for (let i = 0; i &lt; 10000; i++)
+                assert(foo(i) === i);
+            assert(foo(&quot;20&quot;) === 20);
+        }
+    `;
+
+    eval(s);
+}
+
+testIntrinsic(10);
+testIntrinsic(0);
+
+function testIntrinsic2() {
+    function baz(n) {
+        n = n | 0;
+        return parseInt(n, 16);
+    }
+    noInline(baz);
+
+    for (let i = 0; i &lt; 100000; i++)
+        assert(baz(i) === parseInt(&quot;0x&quot; + i));
+}
+noDFG(testIntrinsic2);
+testIntrinsic2();
+
+function testIntrinsic3() {
+    function foo(s) {
+        return parseInt(s) + 1;
+    }
+    noInline(foo);
+
+    for (let i = 0; i &lt; 100000; i++)
+        assert(foo(i + &quot;&quot;) === i + 1);
+}
+noDFG(testIntrinsic3);
+testIntrinsic3();
+
+function testIntrinsic4() {
+    function foo(s) {
+        return parseInt(s, 0) + 1;
+    }
+    noInline(foo);
+
+    for (let i = 0; i &lt; 100000; i++)
+        assert(foo(i + &quot;&quot;) === i + 1);
+}
+testIntrinsic4();
+
+function testIntrinsic5() {
+    function foo(s) {
+        return parseInt(s, 10) + 1;
+    }
+    noInline(foo);
+
+    for (let i = 0; i &lt; 100000; i++)
+        assert(foo(i + &quot;&quot;) === i + 1);
+}
+testIntrinsic5();
+
+function testIntrinsic6() {
+    function foo(s) {
+        return parseInt(s, 16) + 1;
+    }
+    noInline(foo);
+
+    for (let i = 0; i &lt; 100000; i++)
+        assert(foo(i + &quot;&quot;) === (parseInt(&quot;0x&quot; + i) + 1));
+}
+noDFG(testIntrinsic6);
+testIntrinsic6();
+
+function testIntrinsic7() {
+    function foo(s) {
+        return parseInt(s, 16) + parseInt(s, 16);
+    }
+    noInline(foo);
+
+    for (let i = 0; i &lt; 100000; i++)
+        assert(foo(i + &quot;&quot;) === (parseInt(&quot;0x&quot; + i) * 2));
+}
+noDFG(testIntrinsic7);
+testIntrinsic7();
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (212938 => 212939)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2017-02-24 03:22:05 UTC (rev 212938)
+++ trunk/Source/JavaScriptCore/ChangeLog        2017-02-24 04:07:30 UTC (rev 212939)
</span><span class="lines">@@ -1,3 +1,85 @@
</span><ins>+2017-02-23  Saam Barati  &lt;sbarati@apple.com&gt;
+
+        Intrinsicify parseInt
+        https://bugs.webkit.org/show_bug.cgi?id=168627
+
+        Reviewed by Filip Pizlo.
+
+        This patch makes parseInt an intrinsic in the DFG and FTL.
+        We do our best to eliminate this node. If we speculate that
+        the first operand to the operation is an int32, and that there
+        isn't a second operand, we convert to the identity of the first
+        operand. That's because parseInt(someInt) === someInt.
+        
+        If the first operand is proven to be an integer, and the second
+        operand is the integer 0 or the integer 10, we can eliminate the
+        node by making it an identity over its first operand. That's
+        because parseInt(someInt, 0) === someInt and parseInt(someInt, 10) === someInt.
+        
+        If we are not able to constant fold the node away, we try to remove
+        checks. The most common use case of parseInt is that its first operand
+        is a proven string. The DFG might be able to remove type checks in this
+        case. We also set up CSE rules for parseInt(someString, someIntRadix)
+        because it's a &quot;pure&quot; operation (modulo resolving a rope).
+
+        This looks to be a 4% Octane/Box2D progression.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleIntrinsicCall):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGConstantFoldingPhase.cpp:
+        (JSC::DFG::ConstantFoldingPhase::foldConstants):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::hasHeapPrediction):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGOperations.cpp:
+        (JSC::DFG::parseIntResult):
+        * dfg/DFGOperations.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileParseInt):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::callOperation):
+        (JSC::DFG::SpeculativeJIT::appendCallSetResult):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
+        (JSC::FTL::DFG::LowerDFGToB3::compileParseInt):
+        * jit/JITOperations.h:
+        * parser/Lexer.cpp:
+        * runtime/ErrorInstance.cpp:
+        * runtime/Intrinsic.h:
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        * runtime/JSGlobalObjectFunctions.cpp:
+        (JSC::toStringView): Deleted.
+        (JSC::isStrWhiteSpace): Deleted.
+        (JSC::parseDigit): Deleted.
+        (JSC::parseIntOverflow): Deleted.
+        (JSC::parseInt): Deleted.
+        * runtime/JSGlobalObjectFunctions.h:
+        * runtime/ParseInt.h: Added.
+        (JSC::parseDigit):
+        (JSC::parseIntOverflow):
+        (JSC::isStrWhiteSpace):
+        (JSC::parseInt):
+        (JSC::toStringView):
+        * runtime/StringPrototype.cpp:
+
</ins><span class="cx"> 2017-02-23  JF Bastien  &lt;jfbastien@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         WebAssembly: support 0x1 version
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (212938 => 212939)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2017-02-24 03:22:05 UTC (rev 212938)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2017-02-24 04:07:30 UTC (rev 212939)
</span><span class="lines">@@ -2928,6 +2928,29 @@
</span><span class="cx">     case CheckTypeInfoFlags:
</span><span class="cx">         break;
</span><span class="cx"> 
</span><ins>+    case ParseInt: {
+        AbstractValue value = forNode(node-&gt;child1());
+        if (value.m_type &amp;&amp; !(value.m_type &amp; ~SpecInt32Only)) {
+            JSValue radix;
+            if (!node-&gt;child2())
+                radix = jsNumber(0);
+            else
+                radix = forNode(node-&gt;child2()).m_value;
+
+            if (radix.isNumber()
+                &amp;&amp; (radix.asNumber() == 0 || radix.asNumber() == 10)) {
+                m_state.setFoundConstants(true);
+                forNode(node).setType(SpecInt32Only);
+                break;
+            }
+        }
+
+        if (node-&gt;child1().useKind() == UntypedUse)
+            clobberWorld(node-&gt;origin.semantic, clobberLimit);
+        forNode(node).setType(m_graph, SpecBytecodeNumber);
+        break;
+    }
+
</ins><span class="cx">     case CreateRest:
</span><span class="cx">         if (!m_graph.isWatchingHavingABadTimeWatchpoint(node)) {
</span><span class="cx">             // This means we're already having a bad time.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (212938 => 212939)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2017-02-24 03:22:05 UTC (rev 212938)
+++ trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2017-02-24 04:07:30 UTC (rev 212939)
</span><span class="lines">@@ -2360,6 +2360,27 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    case ParseIntIntrinsic: {
+        if (argumentCountIncludingThis &lt; 2)
+            return false;
+
+        if (m_inlineStackTop-&gt;m_exitProfile.hasExitSite(m_currentIndex, BadCell) || m_inlineStackTop-&gt;m_exitProfile.hasExitSite(m_currentIndex, BadType))
+            return false;
+
+        insertChecks();
+        VirtualRegister valueOperand = virtualRegisterForArgument(1, registerOffset);
+        Node* parseInt;
+        if (argumentCountIncludingThis == 2)
+            parseInt = addToGraph(ParseInt, OpInfo(), OpInfo(prediction), get(valueOperand));
+        else {
+            ASSERT(argumentCountIncludingThis &gt; 2);
+            VirtualRegister radixOperand = virtualRegisterForArgument(2, registerOffset);
+            parseInt = addToGraph(ParseInt, OpInfo(), OpInfo(prediction), get(valueOperand), get(radixOperand));
+        }
+        set(VirtualRegister(resultOperand), parseInt);
+        return true;
+    }
+
</ins><span class="cx">     case CharCodeAtIntrinsic: {
</span><span class="cx">         if (argumentCountIncludingThis != 2)
</span><span class="cx">             return false;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGClobberizeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGClobberize.h (212938 => 212939)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2017-02-24 03:22:05 UTC (rev 212938)
+++ trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2017-02-24 04:07:30 UTC (rev 212939)
</span><span class="lines">@@ -888,6 +888,17 @@
</span><span class="cx">         def(HeapLocation(CheckTypeInfoFlagsLoc, JSCell_typeInfoFlags, node-&gt;child1()), LazyNode(node));
</span><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+    case ParseInt:
+        // Note: We would have eliminated a ParseInt that has just a single child as an Int32Use inside fixup.
+        if (node-&gt;child1().useKind() == StringUse &amp;&amp; (!node-&gt;child2() || node-&gt;child2().useKind() == Int32Use)) {
+            def(PureValue(node));
+            return;
+        }
+
+        read(World);
+        write(Heap);
+        return;
+
</ins><span class="cx">     case OverridesHasInstance:
</span><span class="cx">         read(JSCell_typeInfoFlags);
</span><span class="cx">         def(HeapLocation(OverridesHasInstanceLoc, JSCell_typeInfoFlags, node-&gt;child1()), LazyNode(node));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGConstantFoldingPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp (212938 => 212939)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp        2017-02-24 03:22:05 UTC (rev 212938)
+++ trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp        2017-02-24 04:07:30 UTC (rev 212939)
</span><span class="lines">@@ -602,6 +602,29 @@
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx"> 
</span><ins>+            case ParseInt: {
+                AbstractValue&amp; value = m_state.forNode(node-&gt;child1());
+                if (!value.m_type || (value.m_type &amp; ~SpecInt32Only))
+                    break;
+
+                JSValue radix;
+                if (!node-&gt;child2())
+                    radix = jsNumber(0);
+                else
+                    radix = m_state.forNode(node-&gt;child2()).m_value;
+
+                if (!radix.isNumber())
+                    break;
+
+                if (radix.asNumber() == 0 || radix.asNumber() == 10) {
+                    node-&gt;child2() = Edge();
+                    node-&gt;convertToIdentity();
+                    changed = true;
+                }
+
+                break;
+            }
+
</ins><span class="cx">             case Check: {
</span><span class="cx">                 alreadyHandled = true;
</span><span class="cx">                 m_interpreter.execute(indexInBlock);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGDoesGCcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp (212938 => 212939)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2017-02-24 03:22:05 UTC (rev 212938)
+++ trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2017-02-24 04:07:30 UTC (rev 212939)
</span><span class="lines">@@ -310,6 +310,7 @@
</span><span class="cx">     case CallDOMGetter:
</span><span class="cx">     case CallDOM:
</span><span class="cx">     case ArraySlice:
</span><ins>+    case ParseInt: // We might resolve a rope even though we don't clobber anything.
</ins><span class="cx">         return true;
</span><span class="cx">         
</span><span class="cx">     case MultiPutByOffset:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (212938 => 212939)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2017-02-24 03:22:05 UTC (rev 212938)
+++ trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2017-02-24 04:07:30 UTC (rev 212939)
</span><span class="lines">@@ -1793,6 +1793,24 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        case ParseInt: {
+            if (node-&gt;child1()-&gt;shouldSpeculateInt32() &amp;&amp; !node-&gt;child2()) {
+                fixEdge&lt;Int32Use&gt;(node-&gt;child1());
+                node-&gt;convertToIdentity();
+                break;
+            }
+
+            if (node-&gt;child1()-&gt;shouldSpeculateString()) {
+                fixEdge&lt;StringUse&gt;(node-&gt;child1());
+                node-&gt;clearFlags(NodeMustGenerate);
+            }
+
+            if (node-&gt;child2())
+                fixEdge&lt;Int32Use&gt;(node-&gt;child2());
+
+            break;
+        }
+
</ins><span class="cx"> #if !ASSERT_DISABLED
</span><span class="cx">         // Have these no-op cases here to ensure that nobody forgets to add handlers for new opcodes.
</span><span class="cx">         case SetArgument:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNode.h (212938 => 212939)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNode.h        2017-02-24 03:22:05 UTC (rev 212938)
+++ trunk/Source/JavaScriptCore/dfg/DFGNode.h        2017-02-24 04:07:30 UTC (rev 212939)
</span><span class="lines">@@ -1484,6 +1484,7 @@
</span><span class="cx">         case LoadFromJSMapBucket:
</span><span class="cx">         case CallDOMGetter:
</span><span class="cx">         case CallDOM:
</span><ins>+        case ParseInt:
</ins><span class="cx">             return true;
</span><span class="cx">         default:
</span><span class="cx">             return false;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNodeType.h (212938 => 212939)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2017-02-24 03:22:05 UTC (rev 212938)
+++ trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2017-02-24 04:07:30 UTC (rev 212939)
</span><span class="lines">@@ -244,6 +244,7 @@
</span><span class="cx">     macro(CheckInBounds, NodeMustGenerate) \
</span><span class="cx">     macro(CheckStringIdent, NodeMustGenerate) \
</span><span class="cx">     macro(CheckTypeInfoFlags, NodeMustGenerate) /* Takes an OpInfo with the flags you want to test are set */\
</span><ins>+    macro(ParseInt, NodeMustGenerate | NodeResultJS) \
</ins><span class="cx">     \
</span><span class="cx">     /* Optimizations for array mutation. */\
</span><span class="cx">     macro(ArrayPush, NodeResultJS | NodeMustGenerate) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp (212938 => 212939)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2017-02-24 03:22:05 UTC (rev 212938)
+++ trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2017-02-24 04:07:30 UTC (rev 212939)
</span><span class="lines">@@ -56,6 +56,7 @@
</span><span class="cx"> #include &quot;JSSet.h&quot;
</span><span class="cx"> #include &quot;ObjectConstructor.h&quot;
</span><span class="cx"> #include &quot;Operations.h&quot;
</span><ins>+#include &quot;ParseInt.h&quot;
</ins><span class="cx"> #include &quot;RegExpObject.h&quot;
</span><span class="cx"> #include &quot;Repatch.h&quot;
</span><span class="cx"> #include &quot;ScopedArguments.h&quot;
</span><span class="lines">@@ -174,6 +175,14 @@
</span><span class="cx">     baseValue.putInline(exec, ident, putValue, slot);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static ALWAYS_INLINE EncodedJSValue parseIntResult(double input)
+{
+    int asInt = static_cast&lt;int&gt;(input);
+    if (static_cast&lt;double&gt;(asInt) == input)
+        return JSValue::encode(jsNumber(asInt));
+    return JSValue::encode(jsNumber(input));
+}
+
</ins><span class="cx"> extern &quot;C&quot; {
</span><span class="cx"> 
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationToThis(ExecState* exec, EncodedJSValue encodedOp)
</span><span class="lines">@@ -848,6 +857,53 @@
</span><span class="cx">     scope.release();
</span><span class="cx">     return JSValue::encode(asRegExpObject(base)-&gt;exec(exec, globalObject, input));
</span><span class="cx"> }
</span><ins>+
+EncodedJSValue JIT_OPERATION operationParseIntNoRadixGeneric(ExecState* exec, EncodedJSValue value)
+{
+    VM&amp; vm = exec-&gt;vm();
+    NativeCallFrameTracer tracer(&amp;vm, exec);
+
+    return toStringView(exec, JSValue::decode(value), [&amp;] (StringView view) {
+        // This version is as if radix was undefined. Hence, undefined.toNumber() === 0.
+        return parseIntResult(parseInt(view, 0));
+    });
+}
+
+EncodedJSValue JIT_OPERATION operationParseIntStringNoRadix(ExecState* exec, JSString* string)
+{
+    VM&amp; vm = exec-&gt;vm();
+    NativeCallFrameTracer tracer(&amp;vm, exec);
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    auto viewWithString = string-&gt;viewWithUnderlyingString(*exec);
+    RETURN_IF_EXCEPTION(scope, { });
+
+    // This version is as if radix was undefined. Hence, undefined.toNumber() === 0.
+    return parseIntResult(parseInt(viewWithString.view, 0));
+}
+
+EncodedJSValue JIT_OPERATION operationParseIntString(ExecState* exec, JSString* string, int32_t radix)
+{
+    VM&amp; vm = exec-&gt;vm();
+    NativeCallFrameTracer tracer(&amp;vm, exec);
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    auto viewWithString = string-&gt;viewWithUnderlyingString(*exec);
+    RETURN_IF_EXCEPTION(scope, { });
+
+    // This version is as if radix was undefined. Hence, undefined.toNumber() === 0.
+    return parseIntResult(parseInt(viewWithString.view, radix));
+}
+
+EncodedJSValue JIT_OPERATION operationParseIntGeneric(ExecState* exec, EncodedJSValue value, int32_t radix)
+{
+    VM&amp; vm = exec-&gt;vm();
+    NativeCallFrameTracer tracer(&amp;vm, exec);
+
+    return toStringView(exec, JSValue::decode(value), [&amp;] (StringView view) {
+        return parseIntResult(parseInt(view, radix));
+    });
+}
</ins><span class="cx">         
</span><span class="cx"> size_t JIT_OPERATION operationRegExpTestString(ExecState* exec, JSGlobalObject* globalObject, RegExpObject* regExpObject, JSString* input)
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOperationsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOperations.h (212938 => 212939)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOperations.h        2017-02-24 03:22:05 UTC (rev 212938)
+++ trunk/Source/JavaScriptCore/dfg/DFGOperations.h        2017-02-24 04:07:30 UTC (rev 212939)
</span><span class="lines">@@ -163,6 +163,11 @@
</span><span class="cx"> JSCell* JIT_OPERATION operationJSMapFindBucket(ExecState*, JSCell*, EncodedJSValue, int32_t);
</span><span class="cx"> JSCell* JIT_OPERATION operationJSSetFindBucket(ExecState*, JSCell*, EncodedJSValue, int32_t);
</span><span class="cx"> 
</span><ins>+EncodedJSValue JIT_OPERATION operationParseIntNoRadixGeneric(ExecState*, EncodedJSValue);
+EncodedJSValue JIT_OPERATION operationParseIntStringNoRadix(ExecState*, JSString*);
+EncodedJSValue JIT_OPERATION operationParseIntString(ExecState*, JSString*, int32_t);
+EncodedJSValue JIT_OPERATION operationParseIntGeneric(ExecState*, EncodedJSValue, int32_t);
+
</ins><span class="cx"> JSCell* JIT_OPERATION operationNewStringObject(ExecState*, JSString*, Structure*);
</span><span class="cx"> JSCell* JIT_OPERATION operationToStringOnCell(ExecState*, JSCell*);
</span><span class="cx"> JSCell* JIT_OPERATION operationToString(ExecState*, EncodedJSValue);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp (212938 => 212939)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2017-02-24 03:22:05 UTC (rev 212938)
+++ trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2017-02-24 04:07:30 UTC (rev 212939)
</span><span class="lines">@@ -966,6 +966,14 @@
</span><span class="cx">             setPrediction(SpecString);
</span><span class="cx">             break;
</span><span class="cx">         }
</span><ins>+        case ParseInt: {
+            // We expect this node to almost always produce an int32. However,
+            // it's possible it produces NaN or integers out of int32 range. We
+            // rely on the heap prediction since the parseInt() call profiled
+            // its result.
+            setPrediction(m_currentNode-&gt;getHeapPrediction());
+            break;
+        }
</ins><span class="cx"> 
</span><span class="cx">         case GetLocal:
</span><span class="cx">         case SetLocal:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSafeToExecuteh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h (212938 => 212939)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2017-02-24 03:22:05 UTC (rev 212938)
+++ trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2017-02-24 04:07:30 UTC (rev 212939)
</span><span class="lines">@@ -269,6 +269,7 @@
</span><span class="cx">     case ProfileType:
</span><span class="cx">     case ProfileControlFlow:
</span><span class="cx">     case CheckTypeInfoFlags:
</span><ins>+    case ParseInt:
</ins><span class="cx">     case OverridesHasInstance:
</span><span class="cx">     case InstanceOf:
</span><span class="cx">     case InstanceOfCustom:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (212938 => 212939)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2017-02-24 03:22:05 UTC (rev 212938)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2017-02-24 04:07:30 UTC (rev 212939)
</span><span class="lines">@@ -3120,6 +3120,71 @@
</span><span class="cx">     noResult(node);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void SpeculativeJIT::compileParseInt(Node* node)
+{
+    RELEASE_ASSERT(node-&gt;child1().useKind() == UntypedUse || node-&gt;child1().useKind() == StringUse);
+
+    GPRFlushedCallResult resultPayload(this);
+    GPRReg resultPayloadGPR = resultPayload.gpr();
+#if USE(JSVALUE64)
+    JSValueRegs resultRegs(resultPayloadGPR);
+#else
+    GPRFlushedCallResult2 resultTag(this);
+    GPRReg resultTagGPR = resultTag.gpr();
+    JSValueRegs resultRegs(resultTagGPR, resultPayloadGPR);
+#endif
+
+    if (node-&gt;child2()) {
+        SpeculateInt32Operand radix(this, node-&gt;child2());
+        GPRReg radixGPR = radix.gpr();
+        if (node-&gt;child1().useKind() == UntypedUse) {
+            JSValueOperand value(this, node-&gt;child1());
+
+            flushRegisters();
+#if USE(JSVALUE64)
+            callOperation(operationParseIntGeneric, resultRegs.gpr(), value.gpr(), radixGPR);
+#else
+            callOperation(operationParseIntGeneric, resultRegs, value.jsValueRegs(), radixGPR);
+#endif
+            m_jit.exceptionCheck();
+        } else {
+            SpeculateCellOperand value(this, node-&gt;child1());
+            GPRReg valueGPR = value.gpr();
+            speculateString(node-&gt;child1(), valueGPR);
+
+            flushRegisters();
+#if USE(JSVALUE64)
+            callOperation(operationParseIntString, resultRegs.gpr(), valueGPR, radixGPR);
+#else
+            callOperation(operationParseIntString, resultRegs, valueGPR, radixGPR);
+#endif
+            m_jit.exceptionCheck();
+        }
+    } else {
+        if (node-&gt;child1().useKind() == UntypedUse) {
+            JSValueOperand value(this, node-&gt;child1());
+
+            flushRegisters();
+#if USE(JSVALUE64)
+            callOperation(operationParseIntNoRadixGeneric, resultRegs.gpr(), value.jsValueRegs());
+#else
+            callOperation(operationParseIntNoRadixGeneric, resultRegs, value.jsValueRegs());
+#endif
+            m_jit.exceptionCheck();
+        } else {
+            SpeculateCellOperand value(this, node-&gt;child1());
+            GPRReg valueGPR = value.gpr();
+            speculateString(node-&gt;child1(), valueGPR);
+
+            flushRegisters();
+            callOperation(operationParseIntStringNoRadix, resultRegs, valueGPR);
+            m_jit.exceptionCheck();
+        }
+    }
+
+    jsValueResult(resultRegs, node);
+}
+
</ins><span class="cx"> void SpeculativeJIT::compileInstanceOf(Node* node)
</span><span class="cx"> {
</span><span class="cx">     if (node-&gt;child1().useKind() == UntypedUse) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (212938 => 212939)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2017-02-24 03:22:05 UTC (rev 212938)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h        2017-02-24 04:07:30 UTC (rev 212939)
</span><span class="lines">@@ -1307,6 +1307,13 @@
</span><span class="cx">         m_jit.setupArguments(arg1, arg2);
</span><span class="cx">         return appendCallSetResult(operation, result);
</span><span class="cx">     }
</span><ins>+
+    JITCompiler::Call callOperation(J_JITOperation_EJss operation, JSValueRegs result, GPRReg arg1)
+    {
+        m_jit.setupArgumentsWithExecState(arg1);
+        return appendCallSetResult(operation, result);
+    }
+
</ins><span class="cx">     JITCompiler::Call callOperation(T_JITOperation_EJss operation, GPRReg result, GPRReg arg1)
</span><span class="cx">     {
</span><span class="cx">         m_jit.setupArgumentsWithExecState(arg1);
</span><span class="lines">@@ -1889,6 +1896,11 @@
</span><span class="cx">         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg.payloadGPR(), arg.tagGPR(), mathIC);
</span><span class="cx">         return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR());
</span><span class="cx">     }
</span><ins>+    JITCompiler::Call callOperation(J_JITOperation_EJZ operation, JSValueRegs result, JSValueRegs arg1, GPRReg arg2)
+    {
+        m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1.payloadGPR(), arg1.tagGPR(), arg2);
+        return appendCallSetResult(operation, result);
+    }
</ins><span class="cx">     JITCompiler::Call callOperation(J_JITOperation_EJJMic operation, JSValueRegs result, JSValueRegs arg1, JSValueRegs arg2, TrustedImmPtr mathIC)
</span><span class="cx">     {
</span><span class="cx">         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1.payloadGPR(), arg1.tagGPR(), arg2.payloadGPR(), arg2.tagGPR(), mathIC);
</span><span class="lines">@@ -2435,6 +2447,14 @@
</span><span class="cx">         m_jit.setupResults(result1, result2);
</span><span class="cx">         return call;
</span><span class="cx">     }
</span><ins>+    JITCompiler::Call appendCallSetResult(const FunctionPtr&amp; function, JSValueRegs resultRegs)
+    {
+#if USE(JSVALUE64)
+        return appendCallSetResult(function, resultRegs.gpr());
+#else
+        return appendCallSetResult(function, resultRegs.payloadGPR(), resultRegs.tagGPR());
+#endif
+    }
</ins><span class="cx"> #if CPU(X86)
</span><span class="cx">     JITCompiler::Call appendCallSetResult(const FunctionPtr&amp; function, FPRReg result)
</span><span class="cx">     {
</span><span class="lines">@@ -2684,6 +2704,8 @@
</span><span class="cx"> 
</span><span class="cx">     void compileCheckTypeInfoFlags(Node*);
</span><span class="cx">     void compileCheckStringIdent(Node*);
</span><ins>+
+    void compileParseInt(Node*);
</ins><span class="cx">     
</span><span class="cx">     void compileValueRep(Node*);
</span><span class="cx">     void compileDoubleRep(Node*);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (212938 => 212939)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2017-02-24 03:22:05 UTC (rev 212938)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2017-02-24 04:07:30 UTC (rev 212939)
</span><span class="lines">@@ -4666,6 +4666,11 @@
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    case ParseInt: {
+        compileParseInt(node);
+        break;
+    }
+
</ins><span class="cx">     case CheckTypeInfoFlags: {
</span><span class="cx">         compileCheckTypeInfoFlags(node);
</span><span class="cx">         break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (212938 => 212939)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2017-02-24 03:22:05 UTC (rev 212938)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2017-02-24 04:07:30 UTC (rev 212939)
</span><span class="lines">@@ -4634,6 +4634,11 @@
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    case ParseInt: {
+        compileParseInt(node);
+        break;
+    }
+
</ins><span class="cx">     case OverridesHasInstance: {
</span><span class="cx"> 
</span><span class="cx">         Node* hasInstanceValueNode = node-&gt;child2().node();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp (212938 => 212939)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2017-02-24 03:22:05 UTC (rev 212938)
+++ trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2017-02-24 04:07:30 UTC (rev 212939)
</span><span class="lines">@@ -283,6 +283,7 @@
</span><span class="cx">     case CallDOM:
</span><span class="cx">     case CallDOMGetter:
</span><span class="cx">     case ArraySlice:
</span><ins>+    case ParseInt:
</ins><span class="cx">         // These are OK.
</span><span class="cx">         break;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (212938 => 212939)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2017-02-24 03:22:05 UTC (rev 212938)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2017-02-24 04:07:30 UTC (rev 212939)
</span><span class="lines">@@ -960,6 +960,9 @@
</span><span class="cx">         case IsTypedArrayView:
</span><span class="cx">             compileIsTypedArrayView();
</span><span class="cx">             break;
</span><ins>+        case ParseInt:
+            compileParseInt();
+            break;
</ins><span class="cx">         case TypeOf:
</span><span class="cx">             compileTypeOf();
</span><span class="cx">             break;
</span><span class="lines">@@ -8221,6 +8224,25 @@
</span><span class="cx">         setBoolean(m_out.phi(Int32, fastResult, slowResult));
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    void compileParseInt()
+    {
+        RELEASE_ASSERT(m_node-&gt;child1().useKind() == UntypedUse || m_node-&gt;child1().useKind() == StringUse);
+        LValue result;
+        if (m_node-&gt;child2()) {
+            LValue radix = lowInt32(m_node-&gt;child2());
+            if (m_node-&gt;child1().useKind() == UntypedUse)
+                result = vmCall(Int64, m_out.operation(operationParseIntGeneric), m_callFrame, lowJSValue(m_node-&gt;child1()), radix);
+            else
+                result = vmCall(Int64, m_out.operation(operationParseIntString), m_callFrame, lowString(m_node-&gt;child1()), radix);
+        } else {
+            if (m_node-&gt;child1().useKind() == UntypedUse)
+                result = vmCall(Int64, m_out.operation(operationParseIntNoRadixGeneric), m_callFrame, lowJSValue(m_node-&gt;child1()));
+            else
+                result = vmCall(Int64, m_out.operation(operationParseIntStringNoRadix), m_callFrame, lowString(m_node-&gt;child1()));
+        }
+        setJSValue(result);
+    }
+
</ins><span class="cx">     void compileOverridesHasInstance()
</span><span class="cx">     {
</span><span class="cx">         FrozenValue* defaultHasInstanceFunction = m_node-&gt;cellOperand();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.h (212938 => 212939)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.h        2017-02-24 03:22:05 UTC (rev 212938)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.h        2017-02-24 04:07:30 UTC (rev 212939)
</span><span class="lines">@@ -153,6 +153,7 @@
</span><span class="cx"> typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJJMic)(ExecState*, EncodedJSValue, EncodedJSValue, void*);
</span><span class="cx"> typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJMic)(ExecState*, EncodedJSValue, void*);
</span><span class="cx"> typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJssZ)(ExecState*, JSString*, int32_t);
</span><ins>+typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJss)(ExecState*, JSString*);
</ins><span class="cx"> typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJssReo)(ExecState*, JSString*, RegExpObject*);
</span><span class="cx"> typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJssReoJss)(ExecState*, JSString*, RegExpObject*, JSString*);
</span><span class="cx"> typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJP)(ExecState*, EncodedJSValue, void*);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserLexercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/Lexer.cpp (212938 => 212939)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/Lexer.cpp        2017-02-24 03:22:05 UTC (rev 212938)
+++ trunk/Source/JavaScriptCore/parser/Lexer.cpp        2017-02-24 04:07:30 UTC (rev 212939)
</span><span class="lines">@@ -29,10 +29,10 @@
</span><span class="cx"> #include &quot;Identifier.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="cx"> #include &quot;JSFunctionInlines.h&quot;
</span><del>-#include &quot;JSGlobalObjectFunctions.h&quot;
</del><span class="cx"> #include &quot;KeywordLookup.h&quot;
</span><span class="cx"> #include &quot;Lexer.lut.h&quot;
</span><span class="cx"> #include &quot;Nodes.h&quot;
</span><ins>+#include &quot;ParseInt.h&quot;
</ins><span class="cx"> #include &quot;Parser.h&quot;
</span><span class="cx"> #include &lt;ctype.h&gt;
</span><span class="cx"> #include &lt;limits.h&gt;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeErrorInstancecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/ErrorInstance.cpp (212938 => 212939)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ErrorInstance.cpp        2017-02-24 03:22:05 UTC (rev 212938)
+++ trunk/Source/JavaScriptCore/runtime/ErrorInstance.cpp        2017-02-24 04:07:30 UTC (rev 212939)
</span><span class="lines">@@ -25,7 +25,7 @@
</span><span class="cx"> #include &quot;InlineCallFrame.h&quot;
</span><span class="cx"> #include &quot;JSScope.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><del>-#include &quot;JSGlobalObjectFunctions.h&quot;
</del><ins>+#include &quot;ParseInt.h&quot;
</ins><span class="cx"> #include &lt;wtf/text/StringBuilder.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeIntrinsich"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Intrinsic.h (212938 => 212939)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Intrinsic.h        2017-02-24 03:22:05 UTC (rev 212938)
+++ trunk/Source/JavaScriptCore/runtime/Intrinsic.h        2017-02-24 04:07:30 UTC (rev 212939)
</span><span class="lines">@@ -79,6 +79,7 @@
</span><span class="cx">     AtomicsWakeIntrinsic,
</span><span class="cx">     AtomicsXorIntrinsic,
</span><span class="cx">     ToLowerCaseIntrinsic,
</span><ins>+    ParseIntIntrinsic,
</ins><span class="cx"> 
</span><span class="cx">     // Getter intrinsics.
</span><span class="cx">     TypedArrayLengthIntrinsic,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGlobalObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp (212938 => 212939)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp        2017-02-24 03:22:05 UTC (rev 212938)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp        2017-02-24 04:07:30 UTC (rev 212939)
</span><span class="lines">@@ -576,7 +576,7 @@
</span><span class="cx">     }
</span><span class="cx">     m_proxyRevokeStructure.set(vm, this, ProxyRevoke::createStructure(vm, this, m_functionPrototype.get()));
</span><span class="cx"> 
</span><del>-    m_parseIntFunction.set(vm, this, JSFunction::create(vm, this, 2, vm.propertyNames-&gt;parseInt.string(), globalFuncParseInt, NoIntrinsic));
</del><ins>+    m_parseIntFunction.set(vm, this, JSFunction::create(vm, this, 2, vm.propertyNames-&gt;parseInt.string(), globalFuncParseInt, ParseIntIntrinsic));
</ins><span class="cx">     putDirectWithoutTransition(vm, vm.propertyNames-&gt;parseInt, m_parseIntFunction.get(), DontEnum);
</span><span class="cx">     
</span><span class="cx">     m_arrayBufferPrototype.set(vm, this, JSArrayBufferPrototype::create(vm, this, JSArrayBufferPrototype::createStructure(vm, this, m_objectPrototype.get()), ArrayBufferSharingMode::Default));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGlobalObjectFunctionscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp (212938 => 212939)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp        2017-02-24 03:22:05 UTC (rev 212938)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp        2017-02-24 04:07:30 UTC (rev 212939)
</span><span class="lines">@@ -41,6 +41,7 @@
</span><span class="cx"> #include &quot;LiteralParser.h&quot;
</span><span class="cx"> #include &quot;Nodes.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><ins>+#include &quot;ParseInt.h&quot;
</ins><span class="cx"> #include &quot;Parser.h&quot;
</span><span class="cx"> #include &quot;StackVisitor.h&quot;
</span><span class="cx"> #include &lt;wtf/dtoa.h&gt;
</span><span class="lines">@@ -61,19 +62,6 @@
</span><span class="cx"> 
</span><span class="cx"> static const char* const ObjectProtoCalledOnNullOrUndefinedError = &quot;Object.prototype.__proto__ called on null or undefined&quot;;
</span><span class="cx"> 
</span><del>-template&lt;typename CallbackWhenNoException&gt;
-static ALWAYS_INLINE typename std::result_of&lt;CallbackWhenNoException(StringView)&gt;::type toStringView(ExecState* exec, JSValue value, CallbackWhenNoException callback)
-{
-    VM&amp; vm = exec-&gt;vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-    JSString* string = value.toStringOrNull(exec);
-    if (UNLIKELY(!string))
-        return { };
-    auto viewWithString = string-&gt;viewWithUnderlyingString(*exec);
-    RETURN_IF_EXCEPTION(scope, { });
-    return callback(viewWithString.view);
-}
-
</del><span class="cx"> template&lt;unsigned charactersCount&gt;
</span><span class="cx"> static Bitmap&lt;256&gt; makeCharacterBitmap(const char (&amp;characters)[charactersCount])
</span><span class="cx"> {
</span><span class="lines">@@ -251,185 +239,6 @@
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool isStrWhiteSpace(UChar c)
-{
-    switch (c) {
-        // ECMA-262-5th 7.2 &amp; 7.3
-        case 0x0009:
-        case 0x000A:
-        case 0x000B:
-        case 0x000C:
-        case 0x000D:
-        case 0x0020:
-        case 0x00A0:
-        case 0x180E: // This character used to be in Zs category before Unicode 6.3, and EcmaScript says that we should keep treating it as such.
-        case 0x2028:
-        case 0x2029:
-        case 0xFEFF:
-            return true;
-        default:
-            return c &gt; 0xFF &amp;&amp; u_charType(c) == U_SPACE_SEPARATOR;
-    }
-}
-
-static int parseDigit(unsigned short c, int radix)
-{
-    int digit = -1;
-
-    if (isASCIIDigit(c))
-        digit = c - '0';
-    else if (isASCIIUpper(c))
-        digit = c - 'A' + 10;
-    else if (isASCIILower(c))
-        digit = c - 'a' + 10;
-
-    if (digit &gt;= radix)
-        return -1;
-    return digit;
-}
-
-double parseIntOverflow(const LChar* s, unsigned length, int radix)
-{
-    double number = 0.0;
-    double radixMultiplier = 1.0;
-
-    for (const LChar* p = s + length - 1; p &gt;= s; p--) {
-        if (radixMultiplier == std::numeric_limits&lt;double&gt;::infinity()) {
-            if (*p != '0') {
-                number = std::numeric_limits&lt;double&gt;::infinity();
-                break;
-            }
-        } else {
-            int digit = parseDigit(*p, radix);
-            number += digit * radixMultiplier;
-        }
-
-        radixMultiplier *= radix;
-    }
-
-    return number;
-}
-
-static double parseIntOverflow(const UChar* s, unsigned length, int radix)
-{
-    double number = 0.0;
-    double radixMultiplier = 1.0;
-
-    for (const UChar* p = s + length - 1; p &gt;= s; p--) {
-        if (radixMultiplier == std::numeric_limits&lt;double&gt;::infinity()) {
-            if (*p != '0') {
-                number = std::numeric_limits&lt;double&gt;::infinity();
-                break;
-            }
-        } else {
-            int digit = parseDigit(*p, radix);
-            number += digit * radixMultiplier;
-        }
-
-        radixMultiplier *= radix;
-    }
-
-    return number;
-}
-
-static double parseIntOverflow(StringView string, int radix)
-{
-    if (string.is8Bit())
-        return parseIntOverflow(string.characters8(), string.length(), radix);
-    return parseIntOverflow(string.characters16(), string.length(), radix);
-}
-
-// ES5.1 15.1.2.2
-template &lt;typename CharType&gt;
-ALWAYS_INLINE
-static double parseInt(StringView s, const CharType* data, int radix)
-{
-    // 1. Let inputString be ToString(string).
-    // 2. Let S be a newly created substring of inputString consisting of the first character that is not a
-    //    StrWhiteSpaceChar and all characters following that character. (In other words, remove leading white
-    //    space.) If inputString does not contain any such characters, let S be the empty string.
-    int length = s.length();
-    int p = 0;
-    while (p &lt; length &amp;&amp; isStrWhiteSpace(data[p]))
-        ++p;
-
-    // 3. Let sign be 1.
-    // 4. If S is not empty and the first character of S is a minus sign -, let sign be -1.
-    // 5. If S is not empty and the first character of S is a plus sign + or a minus sign -, then remove the first character from S.
-    double sign = 1;
-    if (p &lt; length) {
-        if (data[p] == '+')
-            ++p;
-        else if (data[p] == '-') {
-            sign = -1;
-            ++p;
-        }
-    }
-
-    // 6. Let R = ToInt32(radix).
-    // 7. Let stripPrefix be true.
-    // 8. If R != 0,then
-    //   b. If R != 16, let stripPrefix be false.
-    // 9. Else, R == 0
-    //   a. LetR = 10.
-    // 10. If stripPrefix is true, then
-    //   a. If the length of S is at least 2 and the first two characters of S are either ―0x or ―0X,
-    //      then remove the first two characters from S and let R = 16.
-    // 11. If S contains any character that is not a radix-R digit, then let Z be the substring of S
-    //     consisting of all characters before the first such character; otherwise, let Z be S.
-    if ((radix == 0 || radix == 16) &amp;&amp; length - p &gt;= 2 &amp;&amp; data[p] == '0' &amp;&amp; (data[p + 1] == 'x' || data[p + 1] == 'X')) {
-        radix = 16;
-        p += 2;
-    } else if (radix == 0)
-        radix = 10;
-
-    // 8.a If R &lt; 2 or R &gt; 36, then return NaN.
-    if (radix &lt; 2 || radix &gt; 36)
-        return PNaN;
-
-    // 13. Let mathInt be the mathematical integer value that is represented by Z in radix-R notation, using the letters
-    //     A-Z and a-z for digits with values 10 through 35. (However, if R is 10 and Z contains more than 20 significant
-    //     digits, every significant digit after the 20th may be replaced by a 0 digit, at the option of the implementation;
-    //     and if R is not 2, 4, 8, 10, 16, or 32, then mathInt may be an implementation-dependent approximation to the
-    //     mathematical integer value that is represented by Z in radix-R notation.)
-    // 14. Let number be the Number value for mathInt.
-    int firstDigitPosition = p;
-    bool sawDigit = false;
-    double number = 0;
-    while (p &lt; length) {
-        int digit = parseDigit(data[p], radix);
-        if (digit == -1)
-            break;
-        sawDigit = true;
-        number *= radix;
-        number += digit;
-        ++p;
-    }
-
-    // 12. If Z is empty, return NaN.
-    if (!sawDigit)
-        return PNaN;
-
-    // Alternate code path for certain large numbers.
-    if (number &gt;= mantissaOverflowLowerBound) {
-        if (radix == 10) {
-            size_t parsedLength;
-            number = parseDouble(s.substring(firstDigitPosition, p - firstDigitPosition), parsedLength);
-        } else if (radix == 2 || radix == 4 || radix == 8 || radix == 16 || radix == 32)
-            number = parseIntOverflow(s.substring(firstDigitPosition, p - firstDigitPosition), radix);
-    }
-
-    // 15. Return sign x number.
-    return sign * number;
-}
-
-static double parseInt(StringView s, int radix)
-{
-    if (s.is8Bit())
-        return parseInt(s, s.characters8(), radix);
-    return parseInt(s, s.characters16(), radix);
-}
-
</del><span class="cx"> static const int SizeOfInfinity = 8;
</span><span class="cx"> 
</span><span class="cx"> template &lt;typename CharType&gt;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGlobalObjectFunctionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.h (212938 => 212939)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.h        2017-02-24 03:22:05 UTC (rev 212938)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.h        2017-02-24 04:07:30 UTC (rev 212939)
</span><span class="lines">@@ -52,9 +52,6 @@
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL globalFuncBuiltinLog(ExecState*);
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL globalFuncImportModule(ExecState*);
</span><span class="cx"> 
</span><del>-static const double mantissaOverflowLowerBound = 9007199254740992.0;
-double parseIntOverflow(const LChar*, unsigned length, int radix);
-bool isStrWhiteSpace(UChar);
</del><span class="cx"> double jsToNumber(StringView);
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeParseInth"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/runtime/ParseInt.h (0 => 212939)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ParseInt.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/runtime/ParseInt.h        2017-02-24 04:07:30 UTC (rev 212939)
</span><span class="lines">@@ -0,0 +1,227 @@
</span><ins>+/*
+ * Copyright (C) 2017 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
+
+#include &quot;JSCJSValue.h&quot;
+#include &lt;wtf/dtoa.h&gt;
+
+namespace JSC {
+
+static const double mantissaOverflowLowerBound = 9007199254740992.0;
+
+ALWAYS_INLINE static int parseDigit(unsigned short c, int radix)
+{
+    int digit = -1;
+
+    if (isASCIIDigit(c))
+        digit = c - '0';
+    else if (isASCIIUpper(c))
+        digit = c - 'A' + 10;
+    else if (isASCIILower(c))
+        digit = c - 'a' + 10;
+
+    if (digit &gt;= radix)
+        return -1;
+    return digit;
+}
+
+static double parseIntOverflow(const LChar* s, unsigned length, int radix)
+{
+    double number = 0.0;
+    double radixMultiplier = 1.0;
+
+    for (const LChar* p = s + length - 1; p &gt;= s; p--) {
+        if (radixMultiplier == std::numeric_limits&lt;double&gt;::infinity()) {
+            if (*p != '0') {
+                number = std::numeric_limits&lt;double&gt;::infinity();
+                break;
+            }
+        } else {
+            int digit = parseDigit(*p, radix);
+            number += digit * radixMultiplier;
+        }
+
+        radixMultiplier *= radix;
+    }
+
+    return number;
+}
+
+static double parseIntOverflow(const UChar* s, unsigned length, int radix)
+{
+    double number = 0.0;
+    double radixMultiplier = 1.0;
+
+    for (const UChar* p = s + length - 1; p &gt;= s; p--) {
+        if (radixMultiplier == std::numeric_limits&lt;double&gt;::infinity()) {
+            if (*p != '0') {
+                number = std::numeric_limits&lt;double&gt;::infinity();
+                break;
+            }
+        } else {
+            int digit = parseDigit(*p, radix);
+            number += digit * radixMultiplier;
+        }
+
+        radixMultiplier *= radix;
+    }
+
+    return number;
+}
+
+static double parseIntOverflow(StringView string, int radix)
+{
+    if (string.is8Bit())
+        return parseIntOverflow(string.characters8(), string.length(), radix);
+    return parseIntOverflow(string.characters16(), string.length(), radix);
+}
+
+ALWAYS_INLINE static bool isStrWhiteSpace(UChar c)
+{
+    switch (c) {
+    // ECMA-262-5th 7.2 &amp; 7.3
+    case 0x0009:
+    case 0x000A:
+    case 0x000B:
+    case 0x000C:
+    case 0x000D:
+    case 0x0020:
+    case 0x00A0:
+    case 0x180E: // This character used to be in Zs category before Unicode 6.3, and EcmaScript says that we should keep treating it as such.
+    case 0x2028:
+    case 0x2029:
+    case 0xFEFF:
+        return true;
+    default:
+        return c &gt; 0xFF &amp;&amp; u_charType(c) == U_SPACE_SEPARATOR;
+    }
+}
+
+// ES5.1 15.1.2.2
+template &lt;typename CharType&gt;
+ALWAYS_INLINE
+static double parseInt(StringView s, const CharType* data, int radix)
+{
+    // 1. Let inputString be ToString(string).
+    // 2. Let S be a newly created substring of inputString consisting of the first character that is not a
+    //    StrWhiteSpaceChar and all characters following that character. (In other words, remove leading white
+    //    space.) If inputString does not contain any such characters, let S be the empty string.
+    int length = s.length();
+    int p = 0;
+    while (p &lt; length &amp;&amp; isStrWhiteSpace(data[p]))
+        ++p;
+
+    // 3. Let sign be 1.
+    // 4. If S is not empty and the first character of S is a minus sign -, let sign be -1.
+    // 5. If S is not empty and the first character of S is a plus sign + or a minus sign -, then remove the first character from S.
+    double sign = 1;
+    if (p &lt; length) {
+        if (data[p] == '+')
+            ++p;
+        else if (data[p] == '-') {
+            sign = -1;
+            ++p;
+        }
+    }
+
+    // 6. Let R = ToInt32(radix).
+    // 7. Let stripPrefix be true.
+    // 8. If R != 0,then
+    //   b. If R != 16, let stripPrefix be false.
+    // 9. Else, R == 0
+    //   a. LetR = 10.
+    // 10. If stripPrefix is true, then
+    //   a. If the length of S is at least 2 and the first two characters of S are either ―0x or ―0X,
+    //      then remove the first two characters from S and let R = 16.
+    // 11. If S contains any character that is not a radix-R digit, then let Z be the substring of S
+    //     consisting of all characters before the first such character; otherwise, let Z be S.
+    if ((radix == 0 || radix == 16) &amp;&amp; length - p &gt;= 2 &amp;&amp; data[p] == '0' &amp;&amp; (data[p + 1] == 'x' || data[p + 1] == 'X')) {
+        radix = 16;
+        p += 2;
+    } else if (radix == 0)
+        radix = 10;
+
+    // 8.a If R &lt; 2 or R &gt; 36, then return NaN.
+    if (radix &lt; 2 || radix &gt; 36)
+        return PNaN;
+
+    // 13. Let mathInt be the mathematical integer value that is represented by Z in radix-R notation, using the letters
+    //     A-Z and a-z for digits with values 10 through 35. (However, if R is 10 and Z contains more than 20 significant
+    //     digits, every significant digit after the 20th may be replaced by a 0 digit, at the option of the implementation;
+    //     and if R is not 2, 4, 8, 10, 16, or 32, then mathInt may be an implementation-dependent approximation to the
+    //     mathematical integer value that is represented by Z in radix-R notation.)
+    // 14. Let number be the Number value for mathInt.
+    int firstDigitPosition = p;
+    bool sawDigit = false;
+    double number = 0;
+    while (p &lt; length) {
+        int digit = parseDigit(data[p], radix);
+        if (digit == -1)
+            break;
+        sawDigit = true;
+        number *= radix;
+        number += digit;
+        ++p;
+    }
+
+    // 12. If Z is empty, return NaN.
+    if (!sawDigit)
+        return PNaN;
+
+    // Alternate code path for certain large numbers.
+    if (number &gt;= mantissaOverflowLowerBound) {
+        if (radix == 10) {
+            size_t parsedLength;
+            number = parseDouble(s.substring(firstDigitPosition, p - firstDigitPosition), parsedLength);
+        } else if (radix == 2 || radix == 4 || radix == 8 || radix == 16 || radix == 32)
+            number = parseIntOverflow(s.substring(firstDigitPosition, p - firstDigitPosition), radix);
+    }
+
+    // 15. Return sign x number.
+    return sign * number;
+}
+
+ALWAYS_INLINE static double parseInt(StringView s, int radix)
+{
+    if (s.is8Bit())
+        return parseInt(s, s.characters8(), radix);
+    return parseInt(s, s.characters16(), radix);
+}
+
+template&lt;typename CallbackWhenNoException&gt;
+static ALWAYS_INLINE typename std::result_of&lt;CallbackWhenNoException(StringView)&gt;::type toStringView(ExecState* exec, JSValue value, CallbackWhenNoException callback)
+{
+    VM&amp; vm = exec-&gt;vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+    JSString* string = value.toStringOrNull(exec);
+    if (UNLIKELY(!string))
+        return { };
+    auto viewWithString = string-&gt;viewWithUnderlyingString(*exec);
+    RETURN_IF_EXCEPTION(scope, { });
+    return callback(viewWithString.view);
+}
+
+} // namespace JSC
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeStringPrototypecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp (212938 => 212939)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp        2017-02-24 03:22:05 UTC (rev 212938)
+++ trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp        2017-02-24 04:07:30 UTC (rev 212939)
</span><span class="lines">@@ -37,6 +37,7 @@
</span><span class="cx"> #include &quot;JSStringIterator.h&quot;
</span><span class="cx"> #include &quot;Lookup.h&quot;
</span><span class="cx"> #include &quot;ObjectPrototype.h&quot;
</span><ins>+#include &quot;ParseInt.h&quot;
</ins><span class="cx"> #include &quot;PropertyNameArray.h&quot;
</span><span class="cx"> #include &quot;RegExpCache.h&quot;
</span><span class="cx"> #include &quot;RegExpConstructor.h&quot;
</span></span></pre>
</div>
</div>

</body>
</html>