[njs] Math.clz32 method.

Valentin Bartenev vbart at nginx.com
Mon Nov 21 21:04:58 UTC 2016


details:   http://hg.nginx.org/njs/rev/fd2a05f9eacf
branches:  
changeset: 266:fd2a05f9eacf
user:      Valentin Bartenev <vbart at nginx.com>
date:      Tue Nov 22 00:06:46 2016 +0300
description:
Math.clz32 method.

diffstat:

 njs/njs_math.c           |  29 +++++++++++++++++++++++++++++
 njs/test/njs_unit_test.c |  27 +++++++++++++++++++++++++++
 nxt/auto/clang           |  14 ++++++++++++++
 nxt/nxt_clang.h          |  32 ++++++++++++++++++++++++++++++++
 4 files changed, 102 insertions(+), 0 deletions(-)

diffs (149 lines):

diff -r 9f0f13857c46 -r fd2a05f9eacf njs/njs_math.c
--- a/njs/njs_math.c	Sat Nov 19 22:20:06 2016 +0300
+++ b/njs/njs_math.c	Tue Nov 22 00:06:46 2016 +0300
@@ -233,6 +233,27 @@ njs_object_math_ceil(njs_vm_t *vm, njs_v
 
 
 static njs_ret_t
+njs_object_math_clz32(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
+    njs_index_t unused)
+{
+    double    num;
+    uint32_t  ui32;
+
+    if (nargs > 1) {
+        ui32 = njs_number_to_integer(args[1].data.u.number);
+        num = nxt_leading_zeros(ui32);
+
+    } else {
+        num = 32;
+    }
+
+    njs_number_set(&vm->retval, num);
+
+    return NXT_OK;
+}
+
+
+static njs_ret_t
 njs_object_math_cos(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
     njs_index_t unused)
 {
@@ -869,6 +890,14 @@ static const njs_object_prop_t  njs_math
                      NJS_SKIP_ARG, NJS_NUMBER_ARG),
     },
 
+    /* ES6. */
+    {
+        .type = NJS_METHOD,
+        .name = njs_string("clz32"),
+        .value = njs_native_function(njs_object_math_clz32, 0,
+                     NJS_SKIP_ARG, NJS_NUMBER_ARG),
+    },
+
     {
         .type = NJS_METHOD,
         .name = njs_string("cos"),
diff -r 9f0f13857c46 -r fd2a05f9eacf njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c	Sat Nov 19 22:20:06 2016 +0300
+++ b/njs/test/njs_unit_test.c	Tue Nov 22 00:06:46 2016 +0300
@@ -5799,6 +5799,33 @@ static njs_unit_test_t  njs_test[] =
     { nxt_string("Math.ceil(3.1)"),
       nxt_string("4") },
 
+    { nxt_string("Math.clz32()"),
+      nxt_string("32") },
+
+    { nxt_string("Math.clz32('abc')"),
+      nxt_string("32") },
+
+    { nxt_string("Math.clz32(NaN)"),
+      nxt_string("32") },
+
+    { nxt_string("Math.clz32(Infinity)"),
+      nxt_string("32") },
+
+    { nxt_string("Math.clz32('1')"),
+      nxt_string("31") },
+
+    { nxt_string("Math.clz32(0)"),
+      nxt_string("32") },
+
+    { nxt_string("Math.clz32('65535')"),
+      nxt_string("16") },
+
+    { nxt_string("Math.clz32(-1)"),
+      nxt_string("0") },
+
+    { nxt_string("Math.clz32(4294967298)"),
+      nxt_string("30") },
+
     { nxt_string("Math.cos()"),
       nxt_string("NaN") },
 
diff -r 9f0f13857c46 -r fd2a05f9eacf nxt/auto/clang
--- a/nxt/auto/clang	Sat Nov 19 22:20:06 2016 +0300
+++ b/nxt/auto/clang	Tue Nov 22 00:06:46 2016 +0300
@@ -203,6 +203,20 @@ nxt_feature_test="int main(void) {
 . ${NXT_AUTO}feature
 
 
+nxt_feature="GCC __builtin_clz()"
+nxt_feature_name=NXT_HAVE_BUILTIN_CLZ
+nxt_feature_run=no
+nxt_feature_incs=
+nxt_feature_libs=
+nxt_feature_test="int main(void) {
+                      if (__builtin_clz(1) != 31) {
+                          return 1;
+                      }
+                      return 0;
+                  }"
+. ${NXT_AUTO}feature
+
+
 nxt_feature="GCC __attribute__ visibility"
 nxt_feature_name=NXT_HAVE_GCC_ATTRIBUTE_VISIBILITY
 nxt_feature_run=no
diff -r 9f0f13857c46 -r fd2a05f9eacf nxt/nxt_clang.h
--- a/nxt/nxt_clang.h	Sat Nov 19 22:20:06 2016 +0300
+++ b/nxt/nxt_clang.h	Tue Nov 22 00:06:46 2016 +0300
@@ -52,6 +52,38 @@
 #endif
 
 
+#if (NXT_HAVE_BUILTIN_CLZ)
+#define nxt_leading_zeros(x)  (((x) == 0) ? 32 : __builtin_clz(x))
+
+#else
+
+nxt_inline uint32_t
+nxt_leading_zeros(uint32_t x)
+{
+    uint32_t  n;
+
+    /*
+     * There is no sense to optimize this function, since almost
+     * all platforms nowadays support the built-in instruction.
+     */
+
+    if (x == 0) {
+        return 32;
+    }
+
+    n = 0;
+
+    while ((x & 0x80000000) == 0) {
+        n++;
+        x <<= 1;
+    }
+
+    return n;
+}
+
+#endif
+
+
 #if (NXT_HAVE_GCC_ATTRIBUTE_VISIBILITY)
 #define NXT_EXPORT         __attribute__((visibility("default")))
 



More information about the nginx-devel mailing list