Bug 761495: add Number.isInteger and Number.toInteger, r=jorendorff
authorBenjamin Peterson <benjamin@python.org>
Wed, 06 Jun 2012 21:50:21 -0500
changeset 96027 0ac60eea3e4a
parent 96026 0cefd477885a
child 96028 ce0c716baefd
push id22869
push useremorley@mozilla.com
push date2012-06-07 09:35 +0000
Treeherderresults
reviewersjorendorff
bugs761495
milestone16.0a1
Bug 761495: add Number.isInteger and Number.toInteger, r=jorendorff
js/src/jit-test/tests/basic/number-isinteger.js
js/src/jit-test/tests/basic/number-tointeger.js
js/src/jsnum.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/number-isinteger.js
@@ -0,0 +1,15 @@
+assertEq(Number.isInteger(4), true);
+assertEq(Number.isInteger(4.), true);
+assertEq(Number.isInteger(4.2), false);
+assertEq(Number.isInteger(0.), true);
+assertEq(Number.isInteger(-0.), true);
+assertEq(Number.isInteger(Infinity), false);
+assertEq(Number.isInteger(-Infinity), false);
+assertEq(Number.isInteger(NaN), false);
+assertEq(Number.isInteger(true), false);
+assertEq(Number.isInteger(false), false);
+assertEq(Number.isInteger({valueOf: function () { return 3; }}), false);
+assertEq(Number.isInteger({valueOf: function () { return 0/0; }}), false);
+assertEq(Number.isInteger({ valueOf: function() { throw 17; } }), false);
+assertEq(Number.isInteger({ toString: function() { throw 17; } }), false);
+assertEq(Number.isInteger({ valueOf: function() { throw 17; }, toString: function() { throw 42; } }), false);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/number-tointeger.js
@@ -0,0 +1,20 @@
+assertEq(Number.toInteger(4), 4);
+assertEq(Number.toInteger(4.), 4);
+assertEq(Number.toInteger(4.3), 4);
+assertEq(Number.toInteger(-4), -4);
+assertEq(Number.toInteger(-4.), -4);
+assertEq(Number.toInteger(-4.3), -4);
+assertEq(Number.toInteger(0.), 0.);
+assertEq(Number.toInteger(-0.), -0.);
+assertEq(Number.toInteger(Infinity), Infinity);
+assertEq(Number.toInteger(-Infinity), -Infinity);
+assertEq(Number.toInteger(NaN), 0);
+assertEq(Number.toInteger(null), 0);
+assertEq(Number.toInteger(undefined), 0);
+assertEq(Number.toInteger(true), 1);
+assertEq(Number.toInteger(false), 0);
+assertEq(Number.toInteger({valueOf : function () { return 4; }}), 4);
+assertEq(Number.toInteger({valueOf : function () { return 4.3; }}), 4);
+assertEq(Number.toInteger({valueOf : function () { return "4"; }}), 4);
+assertEq(Number.toInteger({valueOf : function () { return {};}}), 0);
+assertEq(Number.toInteger(), 0);
--- a/js/src/jsnum.cpp
+++ b/js/src/jsnum.cpp
@@ -859,20 +859,54 @@ Number_isFinite(JSContext *cx, unsigned 
         args.rval().setBoolean(false);
         return true;
     }
     args.rval().setBoolean(args[0].isInt32() ||
                            MOZ_DOUBLE_IS_FINITE(args[0].toDouble()));
     return true;
 }
 
+// ES6 draft ES6 15.7.3.12
+static JSBool
+Number_isInteger(JSContext *cx, unsigned argc, Value *vp)
+{
+    CallArgs args = CallArgsFromVp(argc, vp);
+    if (args.length() < 1 || !args[0].isNumber()) {
+        args.rval().setBoolean(false);
+        return true;
+    }
+    Value val = args[0];
+    args.rval().setBoolean(val.isInt32() ||
+                           (MOZ_DOUBLE_IS_FINITE(val.toDouble()) &&
+                            ToInteger(val.toDouble()) == val.toDouble()));
+    return true;
+}
+
+// ES6 drafult ES6 15.7.3.13
+static JSBool
+Number_toInteger(JSContext *cx, unsigned argc, Value *vp)
+{
+    CallArgs args = CallArgsFromVp(argc, vp);
+    if (args.length() < 1) {
+        args.rval().setInt32(0);
+        return true;
+    }
+    double asint;
+    if (!ToInteger(cx, args[0], &asint))
+        return false;
+    args.rval().setNumber(asint);
+    return true;
+}
+
 
 static 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),
     JS_FS_END
 };
 
 
 /* NB: Keep this in synch with number_constants[]. */
 enum nc_slot {
     NC_NaN,
     NC_POSITIVE_INFINITY,