From c22a7a23d06621b4321ef3e79d8ea078434d1f9d Mon Sep 17 00:00:00 2001 From: Tom Schuster Date: Fri, 11 Apr 2014 17:24:58 +0200 Subject: [PATCH] Bug 925123 - Add Math.clz32 builtin. r=till --- js/src/jsmath.cpp | 24 +++++++++++++++++++ js/src/jsmath.h | 3 +++ js/src/tests/ecma_6/Math/clz32.js | 38 +++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 js/src/tests/ecma_6/Math/clz32.js diff --git a/js/src/jsmath.cpp b/js/src/jsmath.cpp index 591985d55e8..9dd6f4a7377 100644 --- a/js/src/jsmath.cpp +++ b/js/src/jsmath.cpp @@ -309,6 +309,29 @@ js::math_ceil(JSContext *cx, unsigned argc, Value *vp) 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]. @@ -1535,6 +1558,7 @@ static const JSFunctionSpec math_static_methods[] = { 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), diff --git a/js/src/jsmath.h b/js/src/jsmath.h index d977febaedc..997575ae383 100644 --- a/js/src/jsmath.h +++ b/js/src/jsmath.h @@ -247,6 +247,9 @@ 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); diff --git a/js/src/tests/ecma_6/Math/clz32.js b/js/src/tests/ecma_6/Math/clz32.js new file mode 100644 index 00000000000..769cf18fc0f --- /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);