From 8c010422e99888c6a49a0f3ee2145acb4d229fd7 Mon Sep 17 00:00:00 2001 From: Valentin Bartenev Date: Tue, 22 Nov 2016 00:06:46 +0300 Subject: [PATCH] Math.clz32 method. --- 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(+) diff --git a/njs/njs_math.c b/njs/njs_math.c index 0a7d7d24..a0c57fe8 100644 --- a/njs/njs_math.c +++ b/njs/njs_math.c @@ -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"), diff --git a/njs/test/njs_unit_test.c b/njs/test/njs_unit_test.c index 2a5866e2..92a332ca 100644 --- a/njs/test/njs_unit_test.c +++ b/njs/test/njs_unit_test.c @@ -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 --git a/nxt/auto/clang b/nxt/auto/clang index 50da1b02..a2fe7040 100644 --- a/nxt/auto/clang +++ b/nxt/auto/clang @@ -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 --git a/nxt/nxt_clang.h b/nxt/nxt_clang.h index 03cb0a56..aeadb117 100644 --- a/nxt/nxt_clang.h +++ b/nxt/nxt_clang.h @@ -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"))) -- 2.47.3