<!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>[181497] 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/181497">181497</a></dd>
<dt>Author</dt> <dd>msaboff@apple.com</dd>
<dt>Date</dt> <dd>2015-03-14 09:29:20 -0700 (Sat, 14 Mar 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>ES6: Add binary and octal literal support
https://bugs.webkit.org/show_bug.cgi?id=142681

Reviewed by Ryosuke Niwa.

Source/JavaScriptCore:

Added a binary literal parser function, parseBinary(), to Lexer patterned after the octal parser.
Refactored the parseBinary, parseOctal and parseDecimal to use a constant size for the number of
characters to try and handle directly. Factored out the shifting past any prefix to be handled by
the caller. Added binary and octal parsing to toDouble() via helper functions.

* parser/Lexer.cpp:
(JSC::Lexer&lt;T&gt;::parseHex):
(JSC::Lexer&lt;T&gt;::parseBinary):
(JSC::Lexer&lt;T&gt;::parseOctal):
(JSC::Lexer&lt;T&gt;::parseDecimal):
(JSC::Lexer&lt;T&gt;::lex):
* parser/Lexer.h:
* parser/ParserTokens.h:
* runtime/JSGlobalObjectFunctions.cpp:
(JSC::jsBinaryIntegerLiteral):
(JSC::jsOctalIntegerLiteral):
(JSC::toDouble):

Source/WTF:

* wtf/ASCIICType.h:
(WTF::isASCIIBinaryDigit): New support function.
(WTF::isASCIIOctalDigit): Updated to use logical and (&amp;&amp;) instead of binary and (&amp;).

LayoutTests:

New tests.

* js/binary-literals-expected.txt: Added.
* js/binary-literals.html: Added.
* js/octal-literals-expected.txt: Added.
* js/octal-literals.html: Added.
* js/script-tests/binary-literals.js: Added.
* js/script-tests/octal-literals.js: 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="#trunkSourceJavaScriptCoreparserLexercpp">trunk/Source/JavaScriptCore/parser/Lexer.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserLexerh">trunk/Source/JavaScriptCore/parser/Lexer.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserParserTokensh">trunk/Source/JavaScriptCore/parser/ParserTokens.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGlobalObjectFunctionscpp">trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp</a></li>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtfASCIICTypeh">trunk/Source/WTF/wtf/ASCIICType.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsjsbinaryliteralsexpectedtxt">trunk/LayoutTests/js/binary-literals-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsbinaryliteralshtml">trunk/LayoutTests/js/binary-literals.html</a></li>
<li><a href="#trunkLayoutTestsjsoctalliteralsexpectedtxt">trunk/LayoutTests/js/octal-literals-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsoctalliteralshtml">trunk/LayoutTests/js/octal-literals.html</a></li>
<li><a href="#trunkLayoutTestsjsscripttestsbinaryliteralsjs">trunk/LayoutTests/js/script-tests/binary-literals.js</a></li>
<li><a href="#trunkLayoutTestsjsscripttestsoctalliteralsjs">trunk/LayoutTests/js/script-tests/octal-literals.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (181496 => 181497)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-03-14 02:57:54 UTC (rev 181496)
+++ trunk/LayoutTests/ChangeLog        2015-03-14 16:29:20 UTC (rev 181497)
</span><span class="lines">@@ -1,3 +1,19 @@
</span><ins>+2015-03-14  Michael Saboff  &lt;msaboff@apple.com&gt;
+
+        ES6: Add binary and octal literal support
+        https://bugs.webkit.org/show_bug.cgi?id=142681
+
+        Reviewed by Ryosuke Niwa.
+
+        New tests.
+
+        * js/binary-literals-expected.txt: Added.
+        * js/binary-literals.html: Added.
+        * js/octal-literals-expected.txt: Added.
+        * js/octal-literals.html: Added.
+        * js/script-tests/binary-literals.js: Added.
+        * js/script-tests/octal-literals.js: Added.
+
</ins><span class="cx"> 2015-03-13  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Class constructor should throw TypeError when &quot;called&quot;
</span></span></pre></div>
<a id="trunkLayoutTestsjsbinaryliteralsexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/binary-literals-expected.txt (0 => 181497)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/binary-literals-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/binary-literals-expected.txt        2015-03-14 16:29:20 UTC (rev 181497)
</span><span class="lines">@@ -0,0 +1,43 @@
</span><ins>+Make sure that we correctly handle binary literals
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS 0b0 is 0
+PASS 0b1 is 1
+PASS 0B1 is 1
+PASS 0b00000000000000000000000000000000 is 0
+PASS 0B2 threw exception SyntaxError: No binary digits after '0b'.
+PASS 0ba threw exception SyntaxError: No binary digits after '0b'.
+PASS 0b0.0 threw exception SyntaxError: Unexpected number '.0'. Parse error..
+PASS x=0b1y=42 threw exception SyntaxError: No space between binary literal and identifier.
+PASS 0b1010 is 0xa
+PASS 0b00000001001000110100010101100111 is 0x01234567
+PASS 0b10001001101010111100110111101111 is 0x89abcdef
+PASS 0o100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 is 3.00300673152188e+256
+PASS 0b11111111111111111111111111111111111111111111111111110 is 9007199254740990
+PASS 0b11111111111111111111111111111111111111111111111111111 is 9007199254740991
+PASS 0b111111111111111111111111111111111111111111111111111110 is 18014398509481982
+PASS 0b111111111111111111111111111111111111111111111111111111 is 18014398509481984
+PASS !!0b1 is true
+PASS !!0b0 is false
+PASS Number('0b0') is 0
+PASS Number('0b1') is 1
+PASS Number('0B1') is 1
+PASS Number('0b00000000000000000000000000000000') is 0
+PASS Number('0B2') is NaN
+PASS Number('0ba') is NaN
+PASS Number('0b0.0') is NaN
+PASS Number('0b1010') is 0xa
+PASS Number('0b00000001001000110100010101100111') is 0x01234567
+PASS Number('0b10001001101010111100110111101111') is 0x89abcdef
+PASS Number('0b11111111111111111111111111111111111111111111111111110') is 9007199254740990
+PASS Number('0b11111111111111111111111111111111111111111111111111111') is 9007199254740991
+PASS Number('0b111111111111111111111111111111111111111111111111111110') is 18014398509481982
+PASS Number('0b111111111111111111111111111111111111111111111111111111') is 18014398509481984
+PASS !!Number('0b1') is true
+PASS !!Number('0b0') is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsbinaryliteralshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/binary-literals.html (0 => 181497)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/binary-literals.html                                (rev 0)
+++ trunk/LayoutTests/js/binary-literals.html        2015-03-14 16:29:20 UTC (rev 181497)
</span><span class="lines">@@ -0,0 +1,10 @@
</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;script-tests/binary-literals.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="trunkLayoutTestsjsoctalliteralsexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/octal-literals-expected.txt (0 => 181497)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/octal-literals-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/octal-literals-expected.txt        2015-03-14 16:29:20 UTC (rev 181497)
</span><span class="lines">@@ -0,0 +1,43 @@
</span><ins>+Make sure that we correctly handle octal literals
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS 0o0 is 0
+PASS 0o1 is 1
+PASS 0O1 is 1
+PASS 0o000000000000 is 0
+PASS 0O8 threw exception SyntaxError: No octal digits after '0o'.
+PASS 0oa threw exception SyntaxError: No octal digits after '0o'.
+PASS 0o0.0 threw exception SyntaxError: Unexpected number '.0'. Parse error..
+PASS x=0o1y=42 threw exception SyntaxError: No space between octal literal and identifier.
+PASS 0o12 is 0xa
+PASS 0o110642547 is 0x01234567
+PASS 0o21152746757 is 0x89abcdef
+FAIL 0o70000000000000000000000000000000000000000000000000000000 should be 3.00300673152188e+256. Was 3.2737636676212225e+50.
+PASS 0o377777777777777776 is 9007199254740990
+PASS 0o377777777777777777 is 9007199254740991
+PASS 0o777777777777777776 is 18014398509481982
+PASS 0o777777777777777777 is 18014398509481984
+PASS !!0o1 is true
+PASS !!0o0 is false
+PASS Number('0o0') is 0
+PASS Number('0o1') is 1
+PASS Number('0O1') is 1
+PASS Number('0o00000000000000000') is 0
+PASS Number('0O8') is NaN
+PASS Number('0oa') is NaN
+PASS Number('0o0.0') is NaN
+PASS Number('0o77') is 0x3f
+PASS Number('0o110642547') is 0x01234567
+PASS Number('0o21152746757') is 0x89abcdef
+PASS Number('0o377777777777777776') is 9007199254740990
+PASS Number('0o377777777777777777') is 9007199254740991
+PASS Number('0o777777777777777776') is 18014398509481982
+PASS Number('0o777777777777777777') is 18014398509481984
+PASS !!Number('0o1') is true
+PASS !!Number('0o0') is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsoctalliteralshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/octal-literals.html (0 => 181497)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/octal-literals.html                                (rev 0)
+++ trunk/LayoutTests/js/octal-literals.html        2015-03-14 16:29:20 UTC (rev 181497)
</span><span class="lines">@@ -0,0 +1,10 @@
</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;script-tests/octal-literals.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="trunkLayoutTestsjsscripttestsbinaryliteralsjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/script-tests/binary-literals.js (0 => 181497)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/script-tests/binary-literals.js                                (rev 0)
+++ trunk/LayoutTests/js/script-tests/binary-literals.js        2015-03-14 16:29:20 UTC (rev 181497)
</span><span class="lines">@@ -0,0 +1,47 @@
</span><ins>+description(&quot;Make sure that we correctly handle binary literals&quot;);
+
+shouldBe(&quot;0b0&quot;, &quot;0&quot;);
+shouldBe(&quot;0b1&quot;, &quot;1&quot;);
+shouldBe(&quot;0B1&quot;, &quot;1&quot;);
+shouldBe(&quot;0b00000000000000000000000000000000&quot;, &quot;0&quot;);
+shouldThrow(&quot;0B2&quot;);
+shouldThrow(&quot;0ba&quot;);
+shouldThrow(&quot;0b0.0&quot;);
+shouldThrow(&quot;x=0b1y=42&quot;);
+shouldBe(&quot;0b1010&quot;, &quot;0xa&quot;);
+shouldBe(&quot;0b00000001001000110100010101100111&quot;, &quot;0x01234567&quot;);
+shouldBe(&quot;0b10001001101010111100110111101111&quot;, &quot;0x89abcdef&quot;);
+shouldBe(&quot;0o100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000&quot;, &quot;3.00300673152188e+256&quot;);
+
+// Try 53 bits
+shouldBe(&quot;0b11111111111111111111111111111111111111111111111111110&quot;, &quot;9007199254740990&quot;);
+shouldBe(&quot;0b11111111111111111111111111111111111111111111111111111&quot;, &quot;9007199254740991&quot;);
+
+// 54 bits and above should add zeroes
+shouldBe(&quot;0b111111111111111111111111111111111111111111111111111110&quot;, &quot;18014398509481982&quot;);
+shouldBe(&quot;0b111111111111111111111111111111111111111111111111111111&quot;, &quot;18014398509481984&quot;);
+
+shouldBeTrue(&quot;!!0b1&quot;);
+shouldBeFalse(&quot;!!0b0&quot;);
+
+shouldBe(&quot;Number('0b0')&quot;, &quot;0&quot;);
+shouldBe(&quot;Number('0b1')&quot;, &quot;1&quot;);
+shouldBe(&quot;Number('0B1')&quot;, &quot;1&quot;);
+shouldBe(&quot;Number('0b00000000000000000000000000000000')&quot;, &quot;0&quot;);
+shouldBeNaN(&quot;Number('0B2')&quot;);
+shouldBeNaN(&quot;Number('0ba')&quot;);
+shouldBeNaN(&quot;Number('0b0.0')&quot;);
+shouldBe(&quot;Number('0b1010')&quot;, &quot;0xa&quot;);
+shouldBe(&quot;Number('0b00000001001000110100010101100111')&quot;, &quot;0x01234567&quot;);
+shouldBe(&quot;Number('0b10001001101010111100110111101111')&quot;, &quot;0x89abcdef&quot;);
+
+// Try 53 bits
+shouldBe(&quot;Number('0b11111111111111111111111111111111111111111111111111110')&quot;, &quot;9007199254740990&quot;);
+shouldBe(&quot;Number('0b11111111111111111111111111111111111111111111111111111')&quot;, &quot;9007199254740991&quot;);
+
+// 54 bits and above should add zeroes
+shouldBe(&quot;Number('0b111111111111111111111111111111111111111111111111111110')&quot;, &quot;18014398509481982&quot;);
+shouldBe(&quot;Number('0b111111111111111111111111111111111111111111111111111111')&quot;, &quot;18014398509481984&quot;);
+
+shouldBeTrue(&quot;!!Number('0b1')&quot;);
+shouldBeFalse(&quot;!!Number('0b0')&quot;);
</ins></span></pre></div>
<a id="trunkLayoutTestsjsscripttestsoctalliteralsjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/script-tests/octal-literals.js (0 => 181497)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/script-tests/octal-literals.js                                (rev 0)
+++ trunk/LayoutTests/js/script-tests/octal-literals.js        2015-03-14 16:29:20 UTC (rev 181497)
</span><span class="lines">@@ -0,0 +1,47 @@
</span><ins>+description(&quot;Make sure that we correctly handle octal literals&quot;);
+
+shouldBe(&quot;0o0&quot;, &quot;0&quot;);
+shouldBe(&quot;0o1&quot;, &quot;1&quot;);
+shouldBe(&quot;0O1&quot;, &quot;1&quot;);
+shouldBe(&quot;0o000000000000&quot;, &quot;0&quot;);
+shouldThrow(&quot;0O8&quot;);
+shouldThrow(&quot;0oa&quot;);
+shouldThrow(&quot;0o0.0&quot;);
+shouldThrow(&quot;x=0o1y=42&quot;);
+shouldBe(&quot;0o12&quot;, &quot;0xa&quot;);
+shouldBe(&quot;0o110642547&quot;, &quot;0x01234567&quot;);
+shouldBe(&quot;0o21152746757&quot;, &quot;0x89abcdef&quot;);
+shouldBe(&quot;0o70000000000000000000000000000000000000000000000000000000&quot;, &quot;3.00300673152188e+256&quot;);
+
+// Try 53 bits
+shouldBe(&quot;0o377777777777777776&quot;, &quot;9007199254740990&quot;);
+shouldBe(&quot;0o377777777777777777&quot;, &quot;9007199254740991&quot;);
+
+// 54 bits and above should add zeroes
+shouldBe(&quot;0o777777777777777776&quot;, &quot;18014398509481982&quot;);
+shouldBe(&quot;0o777777777777777777&quot;, &quot;18014398509481984&quot;);
+
+shouldBeTrue(&quot;!!0o1&quot;);
+shouldBeFalse(&quot;!!0o0&quot;);
+
+shouldBe(&quot;Number('0o0')&quot;, &quot;0&quot;);
+shouldBe(&quot;Number('0o1')&quot;, &quot;1&quot;);
+shouldBe(&quot;Number('0O1')&quot;, &quot;1&quot;);
+shouldBe(&quot;Number('0o00000000000000000')&quot;, &quot;0&quot;);
+shouldBeNaN(&quot;Number('0O8')&quot;);
+shouldBeNaN(&quot;Number('0oa')&quot;);
+shouldBeNaN(&quot;Number('0o0.0')&quot;);
+shouldBe(&quot;Number('0o77')&quot;, &quot;0x3f&quot;);
+shouldBe(&quot;Number('0o110642547')&quot;, &quot;0x01234567&quot;);
+shouldBe(&quot;Number('0o21152746757')&quot;, &quot;0x89abcdef&quot;);
+
+// Try 53 bits
+shouldBe(&quot;Number('0o377777777777777776')&quot;, &quot;9007199254740990&quot;);
+shouldBe(&quot;Number('0o377777777777777777')&quot;, &quot;9007199254740991&quot;);
+
+// 54 bits and above should add zeroes
+shouldBe(&quot;Number('0o777777777777777776')&quot;, &quot;18014398509481982&quot;);
+shouldBe(&quot;Number('0o777777777777777777')&quot;, &quot;18014398509481984&quot;);
+
+shouldBeTrue(&quot;!!Number('0o1')&quot;);
+shouldBeFalse(&quot;!!Number('0o0')&quot;);
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (181496 => 181497)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-03-14 02:57:54 UTC (rev 181496)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-03-14 16:29:20 UTC (rev 181497)
</span><span class="lines">@@ -1,3 +1,28 @@
</span><ins>+2015-03-14  Michael Saboff  &lt;msaboff@apple.com&gt;
+
+        ES6: Add binary and octal literal support
+        https://bugs.webkit.org/show_bug.cgi?id=142681
+
+        Reviewed by Ryosuke Niwa.
+
+        Added a binary literal parser function, parseBinary(), to Lexer patterned after the octal parser.
+        Refactored the parseBinary, parseOctal and parseDecimal to use a constant size for the number of
+        characters to try and handle directly. Factored out the shifting past any prefix to be handled by
+        the caller. Added binary and octal parsing to toDouble() via helper functions.
+
+        * parser/Lexer.cpp:
+        (JSC::Lexer&lt;T&gt;::parseHex):
+        (JSC::Lexer&lt;T&gt;::parseBinary):
+        (JSC::Lexer&lt;T&gt;::parseOctal):
+        (JSC::Lexer&lt;T&gt;::parseDecimal):
+        (JSC::Lexer&lt;T&gt;::lex):
+        * parser/Lexer.h:
+        * parser/ParserTokens.h:
+        * runtime/JSGlobalObjectFunctions.cpp:
+        (JSC::jsBinaryIntegerLiteral):
+        (JSC::jsOctalIntegerLiteral):
+        (JSC::toDouble):
+
</ins><span class="cx"> 2015-03-13  Alex Christensen  &lt;achristensen@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Progress towards CMake on Mac.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserLexercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/Lexer.cpp (181496 => 181497)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/Lexer.cpp        2015-03-14 02:57:54 UTC (rev 181496)
+++ trunk/Source/JavaScriptCore/parser/Lexer.cpp        2015-03-14 16:29:20 UTC (rev 181497)
</span><span class="lines">@@ -1222,9 +1222,6 @@
</span><span class="cx">     uint32_t hexValue = 0;
</span><span class="cx">     int maximumDigits = 7;
</span><span class="cx"> 
</span><del>-    // Shift out the 'x' prefix.
-    shift();
-
</del><span class="cx">     do {
</span><span class="cx">         hexValue = (hexValue &lt;&lt; 4) + toASCIIHexValue(m_current);
</span><span class="cx">         shift();
</span><span class="lines">@@ -1256,28 +1253,67 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template &lt;typename T&gt;
</span><ins>+ALWAYS_INLINE bool Lexer&lt;T&gt;::parseBinary(double&amp; returnValue)
+{
+    // Optimization: most binary values fit into 4 bytes.
+    uint32_t binaryValue = 0;
+    const unsigned maximumDigits = 32;
+    int digit = maximumDigits - 1;
+    // Temporary buffer for the digits. Makes easier
+    // to reconstruct the input characters when needed.
+    LChar digits[maximumDigits];
+
+    do {
+        binaryValue = (binaryValue &lt;&lt; 1) + (m_current - '0');
+        digits[digit] = m_current;
+        shift();
+        --digit;
+    } while (isASCIIBinaryDigit(m_current) &amp;&amp; digit &gt;= 0);
+
+    if (!isASCIIDigit(m_current) &amp;&amp; digit &gt;= 0) {
+        returnValue = binaryValue;
+        return true;
+    }
+
+    for (int i = maximumDigits - 1; i &gt; digit; --i)
+        record8(digits[i]);
+
+    while (isASCIIBinaryDigit(m_current)) {
+        record8(m_current);
+        shift();
+    }
+
+    if (isASCIIDigit(m_current))
+        return false;
+
+    returnValue = parseIntOverflow(m_buffer8.data(), m_buffer8.size(), 2);
+    return true;
+}
+
+template &lt;typename T&gt;
</ins><span class="cx"> ALWAYS_INLINE bool Lexer&lt;T&gt;::parseOctal(double&amp; returnValue)
</span><span class="cx"> {
</span><span class="cx">     // Optimization: most octal values fit into 4 bytes.
</span><span class="cx">     uint32_t octalValue = 0;
</span><del>-    int maximumDigits = 9;
</del><ins>+    const unsigned maximumDigits = 10;
+    int digit = maximumDigits - 1;
</ins><span class="cx">     // Temporary buffer for the digits. Makes easier
</span><span class="cx">     // to reconstruct the input characters when needed.
</span><del>-    LChar digits[10];
</del><ins>+    LChar digits[maximumDigits];
</ins><span class="cx"> 
</span><span class="cx">     do {
</span><span class="cx">         octalValue = octalValue * 8 + (m_current - '0');
</span><del>-        digits[maximumDigits] = m_current;
</del><ins>+        digits[digit] = m_current;
</ins><span class="cx">         shift();
</span><del>-        --maximumDigits;
-    } while (isASCIIOctalDigit(m_current) &amp;&amp; maximumDigits &gt;= 0);
</del><ins>+        --digit;
+    } while (isASCIIOctalDigit(m_current) &amp;&amp; digit &gt;= 0);
</ins><span class="cx"> 
</span><del>-    if (!isASCIIDigit(m_current) &amp;&amp; maximumDigits &gt;= 0) {
</del><ins>+    if (!isASCIIDigit(m_current) &amp;&amp; digit &gt;= 0) {
</ins><span class="cx">         returnValue = octalValue;
</span><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    for (int i = 9; i &gt; maximumDigits; --i)
</del><ins>+    for (int i = maximumDigits - 1; i &gt; digit; --i)
</ins><span class="cx">          record8(digits[i]);
</span><span class="cx"> 
</span><span class="cx">     while (isASCIIOctalDigit(m_current)) {
</span><span class="lines">@@ -1301,24 +1337,25 @@
</span><span class="cx">     // Since parseOctal may be executed before parseDecimal,
</span><span class="cx">     // the m_buffer8 may hold ascii digits.
</span><span class="cx">     if (!m_buffer8.size()) {
</span><del>-        int maximumDigits = 9;
</del><ins>+        const unsigned maximumDigits = 10;
+        int digit = maximumDigits - 1;
</ins><span class="cx">         // Temporary buffer for the digits. Makes easier
</span><span class="cx">         // to reconstruct the input characters when needed.
</span><del>-        LChar digits[10];
</del><ins>+        LChar digits[maximumDigits];
</ins><span class="cx"> 
</span><span class="cx">         do {
</span><span class="cx">             decimalValue = decimalValue * 10 + (m_current - '0');
</span><del>-            digits[maximumDigits] = m_current;
</del><ins>+            digits[digit] = m_current;
</ins><span class="cx">             shift();
</span><del>-            --maximumDigits;
-        } while (isASCIIDigit(m_current) &amp;&amp; maximumDigits &gt;= 0);
</del><ins>+            --digit;
+        } while (isASCIIDigit(m_current) &amp;&amp; digit &gt;= 0);
</ins><span class="cx"> 
</span><del>-        if (maximumDigits &gt;= 0 &amp;&amp; m_current != '.' &amp;&amp; (m_current | 0x20) != 'e') {
</del><ins>+        if (digit &gt;= 0 &amp;&amp; m_current != '.' &amp;&amp; (m_current | 0x20) != 'e') {
</ins><span class="cx">             returnValue = decimalValue;
</span><span class="cx">             return true;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        for (int i = 9; i &gt; maximumDigits; --i)
</del><ins>+        for (int i = maximumDigits - 1; i &gt; digit; --i)
</ins><span class="cx">             record8(digits[i]);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -1688,6 +1725,10 @@
</span><span class="cx">                 token = INVALID_HEX_NUMBER_ERRORTOK;
</span><span class="cx">                 goto returnError;
</span><span class="cx">             }
</span><ins>+
+            // Shift out the 'x' prefix.
+            shift();
+
</ins><span class="cx">             parseHex(tokenData-&gt;doubleValue);
</span><span class="cx">             if (isIdentStart(m_current)) {
</span><span class="cx">                 m_lexErrorMessage = ASCIILiteral(&quot;No space between hexadecimal literal and identifier&quot;);
</span><span class="lines">@@ -1698,7 +1739,48 @@
</span><span class="cx">             m_buffer8.resize(0);
</span><span class="cx">             break;
</span><span class="cx">         }
</span><ins>+        if ((m_current | 0x20) == 'b') {
+            if (!isASCIIBinaryDigit(peek(1))) {
+                m_lexErrorMessage = ASCIILiteral(&quot;No binary digits after '0b'&quot;);
+                token = INVALID_BINARY_NUMBER_ERRORTOK;
+                goto returnError;
+            }
</ins><span class="cx"> 
</span><ins>+            // Shift out the 'b' prefix.
+            shift();
+
+            parseBinary(tokenData-&gt;doubleValue);
+            if (isIdentStart(m_current)) {
+                m_lexErrorMessage = ASCIILiteral(&quot;No space between binary literal and identifier&quot;);
+                token = INVALID_BINARY_NUMBER_ERRORTOK;
+                goto returnError;
+            }
+            token = tokenTypeForIntegerLikeToken(tokenData-&gt;doubleValue);
+            m_buffer8.resize(0);
+            break;
+        }
+
+        if ((m_current | 0x20) == 'o') {
+            if (!isASCIIOctalDigit(peek(1))) {
+                m_lexErrorMessage = ASCIILiteral(&quot;No octal digits after '0o'&quot;);
+                token = INVALID_OCTAL_NUMBER_ERRORTOK;
+                goto returnError;
+            }
+
+            // Shift out the 'o' prefix.
+            shift();
+
+            parseOctal(tokenData-&gt;doubleValue);
+            if (isIdentStart(m_current)) {
+                m_lexErrorMessage = ASCIILiteral(&quot;No space between octal literal and identifier&quot;);
+                token = INVALID_OCTAL_NUMBER_ERRORTOK;
+                goto returnError;
+            }
+            token = tokenTypeForIntegerLikeToken(tokenData-&gt;doubleValue);
+            m_buffer8.resize(0);
+            break;
+        }
+
</ins><span class="cx">         record8('0');
</span><span class="cx">         if (strictMode &amp;&amp; isASCIIDigit(m_current)) {
</span><span class="cx">             m_lexErrorMessage = ASCIILiteral(&quot;Decimal integer literals with a leading zero are forbidden in strict mode&quot;);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserLexerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/Lexer.h (181496 => 181497)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/Lexer.h        2015-03-14 02:57:54 UTC (rev 181496)
+++ trunk/Source/JavaScriptCore/parser/Lexer.h        2015-03-14 16:29:20 UTC (rev 181497)
</span><span class="lines">@@ -203,6 +203,7 @@
</span><span class="cx">     template &lt;bool shouldBuildStrings&gt; ALWAYS_INLINE StringParseResult parseString(JSTokenData*, bool strictMode);
</span><span class="cx">     template &lt;bool shouldBuildStrings&gt; NEVER_INLINE StringParseResult parseStringSlowCase(JSTokenData*, bool strictMode);
</span><span class="cx">     ALWAYS_INLINE void parseHex(double&amp; returnValue);
</span><ins>+    ALWAYS_INLINE bool parseBinary(double&amp; returnValue);
</ins><span class="cx">     ALWAYS_INLINE bool parseOctal(double&amp; returnValue);
</span><span class="cx">     ALWAYS_INLINE bool parseDecimal(double&amp; returnValue);
</span><span class="cx">     ALWAYS_INLINE void parseNumberAfterDecimalPoint();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserParserTokensh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/ParserTokens.h (181496 => 181497)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/ParserTokens.h        2015-03-14 02:57:54 UTC (rev 181496)
+++ trunk/Source/JavaScriptCore/parser/ParserTokens.h        2015-03-14 16:29:20 UTC (rev 181497)
</span><span class="lines">@@ -160,7 +160,8 @@
</span><span class="cx">     UNTERMINATED_STRING_LITERAL_ERRORTOK = 8 | ErrorTokenFlag | UnterminatedErrorTokenFlag,
</span><span class="cx">     INVALID_STRING_LITERAL_ERRORTOK = 9 | ErrorTokenFlag,
</span><span class="cx">     INVALID_PRIVATE_NAME_ERRORTOK = 10 | ErrorTokenFlag,
</span><del>-    INVALID_HEX_NUMBER_ERRORTOK = 11 | ErrorTokenFlag
</del><ins>+    INVALID_HEX_NUMBER_ERRORTOK = 11 | ErrorTokenFlag,
+    INVALID_BINARY_NUMBER_ERRORTOK = 12 | ErrorTokenFlag
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> struct JSTextPosition {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGlobalObjectFunctionscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp (181496 => 181497)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp        2015-03-14 02:57:54 UTC (rev 181496)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp        2015-03-14 16:29:20 UTC (rev 181497)
</span><span class="lines">@@ -343,8 +343,52 @@
</span><span class="cx">         &amp;&amp; data[7] == 'y';
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-// See ecma-262 9.3.1
</del><ins>+// See ecma-262 6th 11.8.3
</ins><span class="cx"> template &lt;typename CharType&gt;
</span><ins>+static double jsBinaryIntegerLiteral(const CharType*&amp; data, const CharType* end)
+{
+    // Binary number.
+    data += 2;
+    const CharType* firstDigitPosition = data;
+    double number = 0;
+    while (true) {
+        number = number * 2 + (*data - '0');
+        ++data;
+        if (data == end)
+            break;
+        if (!isASCIIBinaryDigit(*data))
+            break;
+    }
+    if (number &gt;= mantissaOverflowLowerBound)
+        number = parseIntOverflow(firstDigitPosition, data - firstDigitPosition, 2);
+
+    return number;
+}
+
+// See ecma-262 6th 11.8.3
+template &lt;typename CharType&gt;
+static double jsOctalIntegerLiteral(const CharType*&amp; data, const CharType* end)
+{
+    // Octal number.
+    data += 2;
+    const CharType* firstDigitPosition = data;
+    double number = 0;
+    while (true) {
+        number = number * 8 + (*data - '0');
+        ++data;
+        if (data == end)
+            break;
+        if (!isASCIIOctalDigit(*data))
+            break;
+    }
+    if (number &gt;= mantissaOverflowLowerBound)
+        number = parseIntOverflow(firstDigitPosition, data - firstDigitPosition, 8);
+    
+    return number;
+}
+
+// See ecma-262 6th 11.8.3
+template &lt;typename CharType&gt;
</ins><span class="cx"> static double jsHexIntegerLiteral(const CharType*&amp; data, const CharType* end)
</span><span class="cx"> {
</span><span class="cx">     // Hex number.
</span><span class="lines">@@ -365,7 +409,7 @@
</span><span class="cx">     return number;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-// See ecma-262 9.3.1
</del><ins>+// See ecma-262 6th 11.8.3
</ins><span class="cx"> template &lt;typename CharType&gt;
</span><span class="cx"> static double jsStrDecimalLiteral(const CharType*&amp; data, const CharType* end)
</span><span class="cx"> {
</span><span class="lines">@@ -422,9 +466,16 @@
</span><span class="cx">         return 0.0;
</span><span class="cx">     
</span><span class="cx">     double number;
</span><del>-    if (characters[0] == '0' &amp;&amp; characters + 2 &lt; endCharacters &amp;&amp; (characters[1] | 0x20) == 'x' &amp;&amp; isASCIIHexDigit(characters[2]))
-        number = jsHexIntegerLiteral(characters, endCharacters);
-    else
</del><ins>+    if (characters[0] == '0' &amp;&amp; characters + 2 &lt; endCharacters) {
+        if ((characters[1] | 0x20) == 'x' &amp;&amp; isASCIIHexDigit(characters[2]))
+            number = jsHexIntegerLiteral(characters, endCharacters);
+        else if ((characters[1] | 0x20) == 'o' &amp;&amp; isASCIIOctalDigit(characters[2]))
+            number = jsOctalIntegerLiteral(characters, endCharacters);
+        else if ((characters[1] | 0x20) == 'b' &amp;&amp; isASCIIBinaryDigit(characters[2]))
+            number = jsBinaryIntegerLiteral(characters, endCharacters);
+        else
+            number = jsStrDecimalLiteral(characters, endCharacters);
+    } else
</ins><span class="cx">         number = jsStrDecimalLiteral(characters, endCharacters);
</span><span class="cx">     
</span><span class="cx">     // Allow trailing white space.
</span><span class="lines">@@ -438,7 +489,7 @@
</span><span class="cx">     return number;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-// See ecma-262 9.3.1
</del><ins>+// See ecma-262 6th 11.8.3
</ins><span class="cx"> double jsToNumber(const String&amp; s)
</span><span class="cx"> {
</span><span class="cx">     unsigned size = s.length();
</span></span></pre></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (181496 => 181497)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2015-03-14 02:57:54 UTC (rev 181496)
+++ trunk/Source/WTF/ChangeLog        2015-03-14 16:29:20 UTC (rev 181497)
</span><span class="lines">@@ -1,3 +1,14 @@
</span><ins>+2015-03-14  Michael Saboff  &lt;msaboff@apple.com&gt;
+
+        ES6: Add binary and octal literal support
+        https://bugs.webkit.org/show_bug.cgi?id=142681
+
+        Reviewed by Ryosuke Niwa.
+
+        * wtf/ASCIICType.h:
+        (WTF::isASCIIBinaryDigit): New support function.
+        (WTF::isASCIIOctalDigit): Updated to use logical and (&amp;&amp;) instead of binary and (&amp;).
+
</ins><span class="cx"> 2015-03-13  Mark Lam  &lt;mark.lam@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Replace TCSpinLock with a new WTF::SpinLock based on WTF::Atomic.
</span></span></pre></div>
<a id="trunkSourceWTFwtfASCIICTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/ASCIICType.h (181496 => 181497)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/ASCIICType.h        2015-03-14 02:57:54 UTC (rev 181496)
+++ trunk/Source/WTF/wtf/ASCIICType.h        2015-03-14 16:29:20 UTC (rev 181497)
</span><span class="lines">@@ -73,9 +73,14 @@
</span><span class="cx">     return c &gt;= 'a' &amp;&amp; c &lt;= 'z';
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+template&lt;typename CharType&gt; inline bool isASCIIBinaryDigit(CharType c)
+{
+    return (c == '0') || (c == '1');
+}
+
</ins><span class="cx"> template&lt;typename CharType&gt; inline bool isASCIIOctalDigit(CharType c)
</span><span class="cx"> {
</span><del>-    return (c &gt;= '0') &amp; (c &lt;= '7');
</del><ins>+    return (c &gt;= '0') &amp;&amp; (c &lt;= '7');
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename CharType&gt; inline bool isASCIIPrintable(CharType c)
</span><span class="lines">@@ -166,6 +171,7 @@
</span><span class="cx"> using WTF::isASCIIDigit;
</span><span class="cx"> using WTF::isASCIIHexDigit;
</span><span class="cx"> using WTF::isASCIILower;
</span><ins>+using WTF::isASCIIBinaryDigit;
</ins><span class="cx"> using WTF::isASCIIOctalDigit;
</span><span class="cx"> using WTF::isASCIIPrintable;
</span><span class="cx"> using WTF::isASCIISpace;
</span></span></pre>
</div>
</div>

</body>
</html>