[njs] Various Number methods.

Valentin Bartenev vbart at nginx.com
Sun Nov 6 13:05:25 UTC 2016


details:   http://hg.nginx.org/njs/rev/ad4b6e0b5014
branches:  
changeset: 241:ad4b6e0b5014
user:      Valentin Bartenev <vbart at nginx.com>
date:      Sun Nov 06 16:03:29 2016 +0300
description:
Various Number methods.

diffstat:

 njs/njs_builtin.c        |    2 +-
 njs/njs_number.c         |  116 ++++++++++++++++++++++++++++++++++++++++++++++-
 njs/njs_number.h         |    4 +-
 njs/test/njs_unit_test.c |   89 ++++++++++++++++++++++++++++++++++++
 4 files changed, 206 insertions(+), 5 deletions(-)

diffs (272 lines):

diff -r 8722dc4bdeb4 -r ad4b6e0b5014 njs/njs_builtin.c
--- a/njs/njs_builtin.c	Sun Nov 06 16:03:03 2016 +0300
+++ b/njs/njs_builtin.c	Sun Nov 06 16:03:29 2016 +0300
@@ -143,7 +143,7 @@ njs_builtin_objects_create(njs_vm_t *vm)
         /* SunC does not allow empty array initialization. */
         { njs_eval_function,               { 0 } },
         { njs_object_prototype_to_string,  { 0 } },
-        { njs_number_is_nan,               { NJS_SKIP_ARG, NJS_NUMBER_ARG } },
+        { njs_number_global_is_nan,        { NJS_SKIP_ARG, NJS_NUMBER_ARG } },
         { njs_number_is_finite,            { NJS_SKIP_ARG, NJS_NUMBER_ARG } },
         { njs_number_parse_int,
           { NJS_SKIP_ARG, NJS_STRING_ARG, NJS_INTEGER_ARG } },
diff -r 8722dc4bdeb4 -r ad4b6e0b5014 njs/njs_number.c
--- a/njs/njs_number.c	Sun Nov 06 16:03:03 2016 +0300
+++ b/njs/njs_number.c	Sun Nov 06 16:03:29 2016 +0300
@@ -260,6 +260,74 @@ njs_number_constructor(njs_vm_t *vm, njs
 }
 
 
+static njs_ret_t
+njs_number_is_integer(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
+    njs_index_t unused)
+{
+    double             num;
+    const njs_value_t  *value;
+
+    value = &njs_value_false;
+
+    if (nargs > 1 && njs_is_number(&args[1])) {
+        num = args[1].data.u.number;
+
+        if (num == trunc(num) && !isinf(num)) {
+            value = &njs_value_true;
+        }
+    }
+
+    vm->retval = *value;
+
+    return NXT_OK;
+}
+
+
+
+static njs_ret_t
+njs_number_is_safe_integer(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
+    njs_index_t unused)
+{
+    double             num;
+    const njs_value_t  *value;
+
+    value = &njs_value_false;
+
+    if (nargs > 1 && njs_is_number(&args[1])) {
+        num = args[1].data.u.number;
+
+        if (num == (int64_t) num && fabs(num) <= NJS_MAX_SAFE_INTEGER) {
+            value = &njs_value_true;
+        }
+    }
+
+    vm->retval = *value;
+
+    return NXT_OK;
+}
+
+
+static njs_ret_t
+njs_number_is_nan(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
+    njs_index_t unused)
+{
+    const njs_value_t  *value;
+
+    value = &njs_value_false;
+
+    if (nargs > 1
+        && njs_is_number(&args[1])
+        && isnan(args[1].data.u.number))
+    {
+        value = &njs_value_true;
+    }
+
+    vm->retval = *value;
+
+    return NXT_OK;
+}
+
+
 static const njs_object_prop_t  njs_number_constructor_properties[] =
 {
     /* Number.name == "Number". */
@@ -333,6 +401,50 @@ static const njs_object_prop_t  njs_numb
         .name = njs_long_string("NEGATIVE_INFINITY"),
         .value = njs_value(NJS_NUMBER, 1, -INFINITY),
     },
+
+    /* ES6. */
+    {
+        .type = NJS_METHOD,
+        .name = njs_string("isFinite"),
+        .value = njs_native_function(njs_number_is_finite, 0, 0),
+    },
+
+    /* ES6. */
+    {
+        .type = NJS_METHOD,
+        .name = njs_string("isInteger"),
+        .value = njs_native_function(njs_number_is_integer, 0, 0),
+    },
+
+    /* ES6. */
+    {
+        .type = NJS_METHOD,
+        .name = njs_string("isSafeInteger"),
+        .value = njs_native_function(njs_number_is_safe_integer, 0, 0),
+    },
+
+    /* ES6. */
+    {
+        .type = NJS_METHOD,
+        .name = njs_string("isNaN"),
+        .value = njs_native_function(njs_number_is_nan, 0, 0),
+    },
+
+    /* ES6. */
+    {
+        .type = NJS_METHOD,
+        .name = njs_string("parseFloat"),
+        .value = njs_native_function(njs_number_parse_float, 0,
+                     NJS_SKIP_ARG, NJS_STRING_ARG),
+    },
+
+    /* ES6. */
+    {
+        .type = NJS_METHOD,
+        .name = njs_string("parseInt"),
+        .value = njs_native_function(njs_number_parse_int, 0,
+                     NJS_SKIP_ARG, NJS_STRING_ARG, NJS_INTEGER_ARG),
+    },
 };
 
 
@@ -498,7 +610,7 @@ const njs_object_init_t  njs_number_prot
 
 
 njs_ret_t
-njs_number_is_nan(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
+njs_number_global_is_nan(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
     njs_index_t unused)
 {
     const njs_value_t  *value;
@@ -524,7 +636,7 @@ njs_number_is_finite(njs_vm_t *vm, njs_v
 
     value = &njs_value_false;
 
-    if (nargs > 1) {
+    if (nargs > 1 && njs_is_number(&args[1])) {
         num = args[1].data.u.number;
 
         if (!isnan(num) && !isinf(num)) {
diff -r 8722dc4bdeb4 -r ad4b6e0b5014 njs/njs_number.h
--- a/njs/njs_number.h	Sun Nov 06 16:03:03 2016 +0300
+++ b/njs/njs_number.h	Sun Nov 06 16:03:29 2016 +0300
@@ -19,8 +19,8 @@ njs_ret_t njs_number_to_string(njs_vm_t 
     const njs_value_t *number);
 njs_ret_t njs_number_constructor(njs_vm_t *vm, njs_value_t *args,
     nxt_uint_t nargs, njs_index_t unused);
-njs_ret_t njs_number_is_nan(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
-    njs_index_t unused);
+njs_ret_t njs_number_global_is_nan(njs_vm_t *vm, njs_value_t *args,
+    nxt_uint_t nargs, njs_index_t unused);
 njs_ret_t njs_number_is_finite(njs_vm_t *vm, njs_value_t *args,
     nxt_uint_t nargs, njs_index_t unused);
 njs_ret_t njs_number_parse_int(njs_vm_t *vm, njs_value_t *args,
diff -r 8722dc4bdeb4 -r ad4b6e0b5014 njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c	Sun Nov 06 16:03:03 2016 +0300
+++ b/njs/test/njs_unit_test.c	Sun Nov 06 16:03:29 2016 +0300
@@ -4766,6 +4766,95 @@ static njs_unit_test_t  njs_test[] =
     { nxt_string("var n = new Number(1); n.__proto__ === Number.prototype"),
       nxt_string("true") },
 
+    { nxt_string("Number.isFinite()"),
+      nxt_string("false") },
+
+    { nxt_string("Number.isFinite(123)"),
+      nxt_string("true") },
+
+    { nxt_string("Number.isFinite('123')"),
+      nxt_string("false") },
+
+    { nxt_string("Number.isFinite(Infinity)"),
+      nxt_string("false") },
+
+    { nxt_string("Number.isFinite(NaN)"),
+      nxt_string("false") },
+
+    { nxt_string("Number.isInteger()"),
+      nxt_string("false") },
+
+    { nxt_string("Number.isInteger('123')"),
+      nxt_string("false") },
+
+    { nxt_string("Number.isInteger(123)"),
+      nxt_string("true") },
+
+    { nxt_string("Number.isInteger(-123.0)"),
+      nxt_string("true") },
+
+    { nxt_string("Number.isInteger(123.4)"),
+      nxt_string("false") },
+
+    { nxt_string("Number.isInteger(Infinity)"),
+      nxt_string("false") },
+
+    { nxt_string("Number.isInteger(NaN)"),
+      nxt_string("false") },
+
+    { nxt_string("Number.isSafeInteger()"),
+      nxt_string("false") },
+
+    { nxt_string("Number.isSafeInteger('123')"),
+      nxt_string("false") },
+
+    { nxt_string("Number.isSafeInteger(9007199254740991)"),
+      nxt_string("true") },
+
+    { nxt_string("Number.isSafeInteger(-9007199254740991.0)"),
+      nxt_string("true") },
+
+    { nxt_string("Number.isSafeInteger(9007199254740992)"),
+      nxt_string("false") },
+
+    { nxt_string("Number.isSafeInteger(-9007199254740992.0)"),
+      nxt_string("false") },
+
+    { nxt_string("Number.isSafeInteger(123.4)"),
+      nxt_string("false") },
+
+    { nxt_string("Number.isSafeInteger(Infinity)"),
+      nxt_string("false") },
+
+    { nxt_string("Number.isSafeInteger(-Infinity)"),
+      nxt_string("false") },
+
+    { nxt_string("Number.isSafeInteger(NaN)"),
+      nxt_string("false") },
+
+    { nxt_string("Number.isNaN()"),
+      nxt_string("false") },
+
+    { nxt_string("Number.isNaN('NaN')"),
+      nxt_string("false") },
+
+    { nxt_string("Number.isNaN(NaN)"),
+      nxt_string("true") },
+
+    { nxt_string("Number.isNaN(123)"),
+      nxt_string("false") },
+
+    { nxt_string("Number.isNaN(Infinity)"),
+      nxt_string("false") },
+
+#if 0
+    { nxt_string("parseFloat === Number.parseFloat"),
+      nxt_string("true") },
+
+    { nxt_string("parseInt === Number.parseInt"),
+      nxt_string("true") },
+#endif
+
     { nxt_string("String()"),
       nxt_string("") },
 



More information about the nginx-devel mailing list