From: Igor Sysoev Date: Thu, 21 Apr 2016 15:23:12 +0000 (+0300) Subject: isNaN() function. X-Git-Tag: 0.1.0~25 X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=7725a97b813fa59c05f8c72fb78673f6e7e38c6f;p=njs.git isNaN() function. --- diff --git a/njs/njs_builtin.c b/njs/njs_builtin.c index 7e3257b6..339b36cb 100644 --- a/njs/njs_builtin.c +++ b/njs/njs_builtin.c @@ -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 = { diff --git a/njs/njs_generator.c b/njs/njs_generator.c index a74fef2d..580d0a4b 100644 --- a/njs/njs_generator.c +++ b/njs/njs_generator.c @@ -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: diff --git a/njs/njs_lexer_keyword.c b/njs/njs_lexer_keyword.c index 4dc32716..e216f434 100644 --- a/njs/njs_lexer_keyword.c +++ b/njs/njs_lexer_keyword.c @@ -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. */ diff --git a/njs/njs_number.c b/njs/njs_number.c index 041ffd99..8e7b4732 100644 --- a/njs/njs_number.c +++ b/njs/njs_number.c @@ -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; +} diff --git a/njs/njs_number.h b/njs/njs_number.h index 8e95fa4e..2dee8a1c 100644 --- a/njs/njs_number.h +++ b/njs/njs_number.h @@ -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; diff --git a/njs/njs_parser.c b/njs/njs_parser.c index ff2bfb2a..d654eb43 100644 --- a/njs/njs_parser.c +++ b/njs/njs_parser.c @@ -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: diff --git a/njs/njs_parser.h b/njs/njs_parser.h index 99759e9d..4e1e5e62 100644 --- a/njs/njs_parser.h +++ b/njs/njs_parser.h @@ -176,6 +176,7 @@ typedef enum { NJS_TOKEN_EVAL, NJS_TOKEN_TO_STRING, + NJS_TOKEN_IS_NAN, NJS_TOKEN_RESERVED, } njs_token_t; diff --git a/njs/njs_string.c b/njs/njs_string.c index 521af90b..d5bc353c 100644 --- a/njs/njs_string.c +++ b/njs/njs_string.c @@ -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) { diff --git a/njs/njs_vm.h b/njs/njs_vm.h index e9e226f9..0a0dcd08 100644 --- a/njs/njs_vm.h +++ b/njs/njs_vm.h @@ -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) }; diff --git a/njs/test/njs_unit_test.c b/njs/test/njs_unit_test.c index cbb7edaf..d7eaef6c 100644 --- a/njs/test/njs_unit_test.c +++ b/njs/test/njs_unit_test.c @@ -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 }"),