Bug 886949 - Add Number.parseInt and Number.parseFloat. r=jwalden
authorTill Schneidereit <till@tillschneidereit.net>
Sat, 13 Jul 2013 15:10:46 +0200
changeset 138432 d520aeaf2e2c04f394ad4c0be8939576fcdbc33f
parent 138431 43744955a1921079b15c0893be938e24e5b3e62f
child 138433 f5bfa506a3a1776de13063632e9484e67ca19625
push id24954
push useremorley@mozilla.com
push dateMon, 15 Jul 2013 09:51:08 +0000
treeherdermozilla-central@ff0a372e3170 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwalden
bugs886949
milestone25.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 886949 - Add Number.parseInt and Number.parseFloat. r=jwalden
js/src/jsnum.cpp
js/src/tests/ecma_6/Number/browser.js
js/src/tests/ecma_6/Number/parseFloat-01.js
js/src/tests/ecma_6/Number/parseInt-01.js
js/src/tests/ecma_6/Number/parseInt-default-to-decimal.js
js/src/tests/ecma_6/Number/shell.js
--- a/js/src/jsnum.cpp
+++ b/js/src/jsnum.cpp
@@ -985,16 +985,19 @@ Number_toInteger(JSContext *cx, unsigned
 }
 
 
 static const JSFunctionSpec number_static_methods[] = {
     JS_FN("isFinite", Number_isFinite, 1, 0),
     JS_FN("isInteger", Number_isInteger, 1, 0),
     JS_FN("isNaN", Number_isNaN, 1, 0),
     JS_FN("toInteger", Number_toInteger, 1, 0),
+    /* ES6 additions. */
+    JS_FN("parseFloat", num_parseFloat, 1, 0),
+    JS_FN("parseInt", num_parseInt, 2, 0),
     JS_FS_END
 };
 
 
 /* NB: Keep this in synch with number_constants[]. */
 enum nc_slot {
     NC_NaN,
     NC_POSITIVE_INFINITY,
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/Number/parseFloat-01.js
@@ -0,0 +1,24 @@
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 886949;
+var summary = "ES6 (draft May 2013) 15.7.3.10 Number.parseFloat(string)";
+
+print(BUGNUMBER + ": " + summary);
+
+assertEq(Number.parseFloat("Infinity"), Infinity);
+assertEq(Number.parseFloat("+Infinity"), Infinity);
+assertEq(Number.parseFloat("-Infinity"), -Infinity);
+
+assertEq(Number.parseFloat("inf"), NaN);
+assertEq(Number.parseFloat("Inf"), NaN);
+assertEq(Number.parseFloat("infinity"), NaN);
+
+assertEq(Number.parseFloat("nan"), NaN);
+assertEq(Number.parseFloat("NaN"), NaN);
+
+if (typeof reportCompare === "function")
+  reportCompare(true, true);
+
+print("All tests passed!");
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/Number/parseInt-01.js
@@ -0,0 +1,170 @@
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 886949;
+var summary = "ES6 (draft May 2013) 15.7.3.9 Number.parseInt(string, radix)";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+var str, radix;
+var upvar;
+
+/* 1. Let inputString be ToString(string). */
+
+assertEq(Number.parseInt({ toString: function() { return "17" } }, 10), 17);
+
+upvar = 0;
+str = { get toString() { upvar++; return function() { upvar++; return "12345"; } } };
+assertEq(Number.parseInt(str, 10), 12345);
+assertEq(upvar, 2);
+
+
+/*
+ * 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.)
+ */
+
+var ws =
+  ["\t", "\v", "\f", " ", "\xA0", "\uFEFF",
+     "\u2004", "\u3000", // a few Unicode whitespaces
+   "\r", "\n", "\u2028", "\u2029"];
+
+str = "8675309";
+for (var i = 0, sz = ws.length; i < sz; i++)
+{
+  assertEq(Number.parseInt(ws[i] + str, 10), 8675309);
+  for (var j = 0, sz = ws.length; j < sz; j++)
+  {
+    assertEq(Number.parseInt(ws[i] + ws[j] + str, 10), 8675309,
+             ws[i].charCodeAt(0).toString(16) + ", " +
+             ws[j].charCodeAt(0).toString(16));
+  }
+}
+
+
+/*
+ * 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.
+ */
+str = "5552368";
+assertEq(Number.parseInt("-" + str, 10), -Number.parseInt(str, 10));
+assertEq(Number.parseInt(" -" + str, 10), -Number.parseInt(str, 10));
+assertEq(Number.parseInt("-", 10), NaN);
+assertEq(Number.parseInt("", 10), NaN);
+assertEq(Number.parseInt("-0", 10), -0);
+
+
+/*
+ * 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.
+ */
+assertEq(Number.parseInt("+12345", 10), 12345);
+assertEq(Number.parseInt(" +12345", 10), 12345);
+assertEq(Number.parseInt("-12345", 10), -12345);
+assertEq(Number.parseInt(" -12345", 10), -12345);
+
+
+/*
+ * 6.  Let R = ToInt32(radix).
+ */
+
+upvar = "";
+str =
+  { toString: function() { if (!upvar) upvar = "string"; return "42"; } };
+radix =
+  { toString: function() { if (!upvar) upvar = "radix"; return "10"; } };
+
+assertEq(Number.parseInt(str, radix), 42);
+assertEq(upvar, "string");
+
+assertEq(Number.parseInt("123", null), 123);
+assertEq(Number.parseInt("123", undefined), 123);
+assertEq(Number.parseInt("123", NaN), 123);
+assertEq(Number.parseInt("123", -0), 123);
+assertEq(Number.parseInt("10", 72057594037927950), 16);
+assertEq(Number.parseInt("10", -4294967292), 4);
+assertEq(Number.parseInt("0x10", 1e308), 16);
+assertEq(Number.parseInt("10", 1e308), 10);
+assertEq(Number.parseInt("10", { valueOf: function() { return 16; } }), 16);
+
+
+/*
+ * 7.  Let stripPrefix be true.
+ * 8.  If R ≠ 0, then
+ *     a. If R < 2 or R > 36, then return NaN.
+ *     b. If R ≠ 16, let stripPrefix be false.
+ * 9.  Else, R = 0
+ *     a. Let R = 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.
+ */
+var vs = ["1", "51", "917", "2343", "99963"];
+for (var i = 0, sz = vs.length; i < sz; i++)
+  assertEq(Number.parseInt(vs[i], 0), Number.parseInt(vs[i], 10), "bad " + vs[i]);
+
+assertEq(Number.parseInt("0x10"), 16);
+assertEq(Number.parseInt("0x10", 0), 16);
+assertEq(Number.parseInt("0x10", 16), 16);
+assertEq(Number.parseInt("0x10", 8), 0);
+assertEq(Number.parseInt("-0x10", 16), -16);
+
+assertEq(Number.parseInt("5", 1), NaN);
+assertEq(Number.parseInt("5", 37), NaN);
+assertEq(Number.parseInt("5", { valueOf: function() { return -1; } }), NaN);
+
+
+/*
+ * 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.
+ * 12. If Z is empty, return NaN.
+ */
+assertEq(Number.parseInt(""), NaN);
+assertEq(Number.parseInt("ohai"), NaN);
+assertEq(Number.parseInt("0xohai"), NaN);
+assertEq(Number.parseInt("-ohai"), NaN);
+assertEq(Number.parseInt("+ohai"), NaN);
+assertEq(Number.parseInt(" ohai"), NaN);
+
+assertEq(Number.parseInt("0xaohai"), 10);
+assertEq(Number.parseInt("hohai", 18), 17);
+
+
+/*
+ * 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.
+ * 15. Return sign × number.
+ */
+assertEq(Number.parseInt("ohai", 36), 1142154);
+assertEq(Number.parseInt("0ohai", 36), 1142154);
+assertEq(Number.parseInt("00ohai", 36), 1142154);
+assertEq(Number.parseInt("A", 16), 10);
+assertEq(Number.parseInt("0A", 16), 10);
+assertEq(Number.parseInt("00A", 16), 10);
+assertEq(Number.parseInt("A", 17), 10);
+assertEq(Number.parseInt("0A", 17), 10);
+assertEq(Number.parseInt("00A", 17), 10);
+
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+  reportCompare(true, true);
+
+print("All tests passed!");
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/Number/parseInt-default-to-decimal.js
@@ -0,0 +1,30 @@
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 886949;
+var summary = "ES6 (draft May 2013) 15.7.3.9 Number.parseInt(string, radix)." +
+			  " Verify that Number.parseInt defaults to decimal.";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+assertEq(Number.parseInt("08"), 8);
+assertEq(Number.parseInt("09"), 9);
+assertEq(Number.parseInt("014"), 14);
+
+function strictParseInt(s) { "use strict"; return Number.parseInt(s); }
+
+assertEq(strictParseInt("08"), 8);
+assertEq(strictParseInt("09"), 9);
+assertEq(strictParseInt("014"), 14);
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+  reportCompare(true, true);
+
+print("All tests passed!");
new file mode 100644