]> git.kaiwu.me - njs.git/commitdiff
isNaN() function.
authorIgor Sysoev <igor@sysoev.ru>
Thu, 21 Apr 2016 15:23:12 +0000 (18:23 +0300)
committerIgor Sysoev <igor@sysoev.ru>
Thu, 21 Apr 2016 15:23:12 +0000 (18:23 +0300)
njs/njs_builtin.c
njs/njs_generator.c
njs/njs_lexer_keyword.c
njs/njs_number.c
njs/njs_number.h
njs/njs_parser.c
njs/njs_parser.h
njs/njs_string.c
njs/njs_vm.h
njs/test/njs_unit_test.c

index 7e3257b684e98649e75883e4dd1c51cff47551d2..339b36cbb31ce594339dca70cd35ec678f88ec3a 100644 (file)
@@ -81,12 +81,14 @@ njs_builtin_objects_create(njs_vm_t *vm)
     static const njs_object_init_t    *function_init[] = {
         &njs_eval_function_init,
         NULL,
+        NULL,
     };
 
     static const njs_function_init_t  native_functions[] = {
         /* 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 } },
     };
 
     static const njs_object_prop_t    null_proto_property = {
index a74fef2ded6c7aa147795a6d34cc649b04eaaefd..580d0a4b1209893f6a7c33add70ecb7c664f8ddb 100644 (file)
@@ -295,6 +295,7 @@ njs_generator(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *node)
     case NJS_TOKEN_MATH:
     case NJS_TOKEN_EVAL:
     case NJS_TOKEN_TO_STRING:
+    case NJS_TOKEN_IS_NAN:
         return njs_generate_builtin_object(vm, parser, node);
 
     case NJS_TOKEN_FUNCTION:
index 4dc327160b00b21ae5e570f3d525d748fa5d7505..e216f434af29776eef8ccb0ad9f006ce26cb8459 100644 (file)
@@ -89,6 +89,7 @@ static const njs_keyword_t  njs_keywords[] = {
 
     { nxt_string("eval"),          NJS_TOKEN_EVAL, 0 },
     { nxt_string("toString"),      NJS_TOKEN_TO_STRING, 0 },
+    { nxt_string("isNaN"),         NJS_TOKEN_IS_NAN, 0 },
 
     /* Reserved words. */
 
index 041ffd99b2f967746f792d75df3a607e8ad51074..8e7b47328310a6a1c9f2d85facff1ba568338743 100644 (file)
@@ -433,3 +433,21 @@ const njs_object_init_t  njs_number_prototype_init = {
     njs_number_prototype_properties,
     nxt_nitems(njs_number_prototype_properties),
 };
+
+
+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_true;
+
+    if (nargs > 1 && !njs_is_nan(args[1].data.u.number)) {
+        value = &njs_value_false;
+    }
+
+    vm->retval = *value;
+
+    return NXT_OK;
+}
index 8e95fa4e2d5a4270fe044660c70a01cd1e1e307f..2dee8a1c85a4cfe34f34f1d25f79b65722d67a9c 100644 (file)
@@ -30,6 +30,9 @@ njs_ret_t njs_number_to_string(njs_vm_t *vm, njs_value_t *string,
     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);
+
 
 extern const njs_object_init_t  njs_number_constructor_init;
 extern const njs_object_init_t  njs_number_prototype_init;
index ff2bfb2a64c86b5ae616912ceee847c264971782..d654eb43c8be46a055173899eaa3192dd141cf62 100644 (file)
@@ -1645,6 +1645,7 @@ njs_parser_terminal(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token)
 
     case NJS_TOKEN_EVAL:
     case NJS_TOKEN_TO_STRING:
+    case NJS_TOKEN_IS_NAN:
         return njs_parser_builtin_function(vm, parser, node);
 
     default:
index 99759e9df28323a632a1f14151778def53f78ae5..4e1e5e62308c5d199ecd7a622e1fb1bed7097dfc 100644 (file)
@@ -176,6 +176,7 @@ typedef enum {
 
     NJS_TOKEN_EVAL,
     NJS_TOKEN_TO_STRING,
+    NJS_TOKEN_IS_NAN,
 
     NJS_TOKEN_RESERVED,
 } njs_token_t;
index 521af90b01c55c13f084c868965eac1e47778b54..d5bc353cf6739bfd6b0bb95069bc0154d5a46467 100644 (file)
@@ -1685,6 +1685,8 @@ njs_string_to_number(njs_value_t *value)
     nxt_bool_t    minus;
     const u_char  *p, *end;
 
+    const size_t  infinity = sizeof("Infinity") - 1;
+
     size = value->short_string.size;
 
     if (size != NJS_STRING_LONG) {
@@ -1719,11 +1721,20 @@ njs_string_to_number(njs_value_t *value)
         minus = 1;
     }
 
+    if (p == end) {
+        return NJS_NAN;
+    }
+
     if (*p >= '0' && *p <= '9') {
         num = njs_number_parse(&p, end);
 
     } else {
-        return NJS_NAN;
+        if (p + infinity > end || memcmp(p, "Infinity", infinity) != 0) {
+            return NJS_NAN;
+        }
+
+        num = NJS_INFINITY;
+        p += infinity;
     }
 
     while (p < end) {
index e9e226f92bd22a668381b43f984053f9c1837dde..0a0dcd08bd566c0b5e5da7072ab9dfeebb20abcd 100644 (file)
@@ -702,7 +702,8 @@ enum njs_object_e {
 enum njs_function_e {
     NJS_FUNCTION_EVAL =        0,
     NJS_FUNCTION_TO_STRING =   1,
-#define NJS_FUNCTION_MAX       (NJS_FUNCTION_TO_STRING + 1)
+    NJS_FUNCTION_IS_NAN =      2,
+#define NJS_FUNCTION_MAX       (NJS_FUNCTION_IS_NAN + 1)
 };
 
 
index cbb7edaf5f6e26046bf7344b06ebe1cbdb0b284c..d7eaef6c484ac777fa89c6ad628fcb35b756d934 100644 (file)
@@ -4395,6 +4395,24 @@ static njs_unit_test_t  njs_test[] =
     { nxt_string("Math"),
       nxt_string("[object Object]") },
 
+    { nxt_string("isNaN"),
+      nxt_string("[object Function]") },
+
+    { nxt_string("isNaN()"),
+      nxt_string("true") },
+
+    { nxt_string("isNaN(123)"),
+      nxt_string("false") },
+
+    { nxt_string("isNaN('123')"),
+      nxt_string("false") },
+
+    { nxt_string("isNaN('Infinity')"),
+      nxt_string("false") },
+
+    { nxt_string("isNaN('abc')"),
+      nxt_string("true") },
+
     /* External interface. */
 
     { nxt_string("function f(req) { return req.uri }"),