From: Valentin Bartenev Date: Sun, 6 Nov 2016 13:03:29 +0000 (+0300) Subject: Various Number methods. X-Git-Tag: 0.1.5~14 X-Git-Url: http://git.kaiwu.me/postgresql/log/contrib/postgres_fdw/static/gitweb.js?a=commitdiff_plain;h=e8b5c65517dfa8873592226db7b8eb1880f779e5;p=njs.git Various Number methods. --- diff --git a/njs/njs_builtin.c b/njs/njs_builtin.c index 4f2d281d..a87539f5 100644 --- a/njs/njs_builtin.c +++ b/njs/njs_builtin.c @@ -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 --git a/njs/njs_number.c b/njs/njs_number.c index 66dea2ba..2b9e1501 100644 --- a/njs/njs_number.c +++ b/njs/njs_number.c @@ -260,6 +260,74 @@ njs_number_constructor(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, } +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_number_constructor_properties[] = .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_prototype_init = { 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_value_t *args, nxt_uint_t nargs, 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 --git a/njs/njs_number.h b/njs/njs_number.h index 8190a6cc..724dfbbe 100644 --- a/njs/njs_number.h +++ b/njs/njs_number.h @@ -19,8 +19,8 @@ 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); +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 --git a/njs/test/njs_unit_test.c b/njs/test/njs_unit_test.c index f891b83d..203661bb 100644 --- a/njs/test/njs_unit_test.c +++ b/njs/test/njs_unit_test.c @@ -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("") },