Bug 925123 - Add Math.clz32 builtin. r=till
☠☠ backed out by d0bce5d9c518 ☠ ☠
authorTom Schuster <evilpies@gmail.com>
Fri, 11 Apr 2014 17:24:58 +0200
changeset 178110 e8dfde56e9ca31781856ab20abe09758d8122141
parent 178109 aac6762777be2da7d2242fa835d5d3ffc0498186
child 178111 b4eddd96d58f67617afa0ce3f9993b555586d0c3
push id26574
push userryanvm@gmail.com
push dateFri, 11 Apr 2014 20:47:50 +0000
treeherdermozilla-central@71a02d5403f9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstill
bugs925123
milestone31.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 925123 - Add Math.clz32 builtin. r=till
js/src/jsmath.cpp
js/src/jsmath.h
js/src/tests/ecma_6/Math/clz32.js
--- a/js/src/jsmath.cpp
+++ b/js/src/jsmath.cpp
@@ -304,16 +304,39 @@ js::math_ceil(JSContext *cx, unsigned ar
     if (!ToNumber(cx, args[0], &x))
         return false;
 
     double z = math_ceil_impl(x);
     args.rval().setNumber(z);
     return true;
 }
 
+bool
+js::math_clz32(JSContext *cx, unsigned argc, Value *vp)
+{
+    CallArgs args = CallArgsFromVp(argc, vp);
+
+    if (args.length() == 0) {
+        args.rval().setInt32(32);
+        return true;
+    }
+
+    uint32_t n;
+    if (!ToUint32(cx, args[0], &n))
+        return false;
+
+    if (n == 0) {
+        args.rval().setInt32(32);
+        return true;
+    }
+
+    args.rval().setInt32(mozilla::CountLeadingZeroes32(n));
+    return true;
+}
+
 /*
  * Fast sine and cosine approximation code, based on the sin [0] and cos [1]
  * implementations [2] in the cephes library [3].
  * Some of the optimization ideas are inspired by the fast_sincos in VDT [4].
  *
  * This implementation satisfies the requirements for sin and cos in JS [5].
  * However, it does not take the standard's recommendation to use fdlibm [6],
  * nor does it take advantage of the standard's intent to permit JS to use the
@@ -1530,16 +1553,17 @@ static const JSFunctionSpec math_static_
     JS_FN(js_toSource_str,  math_toSource,        0, 0),
 #endif
     JS_FN("abs",            js_math_abs,          1, 0),
     JS_FN("acos",           math_acos,            1, 0),
     JS_FN("asin",           math_asin,            1, 0),
     JS_FN("atan",           math_atan,            1, 0),
     JS_FN("atan2",          math_atan2,           2, 0),
     JS_FN("ceil",           math_ceil,            1, 0),
+    JS_FN("clz32",          math_clz32,           1, 0),
     JS_FN("cos",            math_cos,             1, 0),
     JS_FN("exp",            math_exp,             1, 0),
     JS_FN("floor",          math_floor,           1, 0),
     JS_FN("imul",           math_imul,            2, 0),
     JS_FN("fround",         math_fround,          1, 0),
     JS_FN("log",            math_log,             1, 0),
     JS_FN("max",            js_math_max,          2, 0),
     JS_FN("min",            js_math_min,          2, 0),
--- a/js/src/jsmath.h
+++ b/js/src/jsmath.h
@@ -243,16 +243,19 @@ math_acos(JSContext *cx, unsigned argc, 
 
 extern bool
 math_ceil(JSContext *cx, unsigned argc, Value *vp);
 
 extern double
 math_ceil_impl(double x);
 
 extern bool
+math_clz32(JSContext *cx, unsigned argc, Value *vp);
+
+extern bool
 math_floor(JSContext *cx, unsigned argc, Value *vp);
 
 extern double
 math_floor_impl(double x);
 
 extern bool
 math_round(JSContext *cx, unsigned argc, Value *vp);
 
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/Math/clz32.js
@@ -0,0 +1,38 @@
+// Undefined and NaN end up as zero after ToUint32
+assertEq(Math.clz32(), 32);
+assertEq(Math.clz32(NaN), 32);
+assertEq(Math.clz32.call(), 32);
+// 0
+assertEq(Math.clz32(null), 32);
+assertEq(Math.clz32(false), 32);
+// 1
+assertEq(Math.clz32(true), 31);
+// 3
+assertEq(Math.clz32(3.5), 30);
+// NaN -> 0
+assertEq(Math.clz32({}), 32);
+// 2
+assertEq(Math.clz32({valueOf: function() { return 2; }}), 30);
+// 0 -> 0
+assertEq(Math.clz32([]), 32);
+assertEq(Math.clz32(""), 32);
+// NaN -> 0
+assertEq(Math.clz32([1, 2, 3]), 32);
+assertEq(Math.clz32("bar"), 32);
+// 15
+assertEq(Math.clz32("15"), 28);
+
+
+assertEq(Math.clz32(0x80000000), 0);
+assertEq(Math.clz32(0xF0FF1000), 0);
+assertEq(Math.clz32(0x7F8F0001), 1);
+assertEq(Math.clz32(0x3FFF0100), 2);
+assertEq(Math.clz32(0x1FF50010), 3);
+assertEq(Math.clz32(0x00800000), 8);
+assertEq(Math.clz32(0x00400000), 9);
+assertEq(Math.clz32(0x00008000), 16);
+assertEq(Math.clz32(0x00004000), 17);
+assertEq(Math.clz32(0x00000080), 24);
+assertEq(Math.clz32(0x00000040), 25);
+assertEq(Math.clz32(0x00000001), 31);
+assertEq(Math.clz32(0), 32);