]> git.kaiwu.me - njs.git/commitdiff
Math.clz32 method.
authorValentin Bartenev <vbart@nginx.com>
Mon, 21 Nov 2016 21:06:46 +0000 (00:06 +0300)
committerValentin Bartenev <vbart@nginx.com>
Mon, 21 Nov 2016 21:06:46 +0000 (00:06 +0300)
njs/njs_math.c
njs/test/njs_unit_test.c
nxt/auto/clang
nxt/nxt_clang.h

index 0a7d7d24b1699c38af520976dc157819079b2e85..a0c57fe81d059b15187d50998363824edffb4151 100644 (file)
@@ -232,6 +232,27 @@ njs_object_math_ceil(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
 }
 
 
+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_object_properties[] =
                      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"),
index 2a5866e2db66aaf4cd3ac90009e1769bdf5a2cb0..92a332caf191aa65515cc5a0ddc0a64ee2ace94e 100644 (file)
@@ -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") },
 
index 50da1b02c431f822d16dfc701608456f7eaaab11..a2fe7040f2a01de5f71516640eece079f6961136 100644 (file)
@@ -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
index 03cb0a56014f43a1c8f85c7c865d208d469fb599..aeadb117264319657bc55252c03323bf3a49aed6 100644 (file)
 #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")))