details: https://hg.nginx.org/njs/rev/381086beb15f branches: changeset: 894:381086beb15f user: Alexander Borisov <alexander.bori...@nginx.com> date: Mon Apr 15 17:23:02 2019 +0300 description: Added implementation of functions: ToInt32, ToUint32, ToLength.
According to ES6 type conversion: 7.1.5, 7.1.6, and 7.1.15. diffstat: njs/njs_array.c | 2 +- njs/njs_function.c | 2 +- njs/njs_math.c | 6 ++-- njs/njs_number.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++ njs/njs_number.h | 7 +++++- njs/njs_string.c | 2 +- njs/njs_vm.c | 19 +++++++-------- njs/test/njs_unit_test.c | 2 +- 8 files changed, 78 insertions(+), 18 deletions(-) diffs (221 lines): diff -r f0b5b01a7c55 -r 381086beb15f njs/njs_array.c --- a/njs/njs_array.c Mon Apr 15 17:23:21 2019 +0300 +++ b/njs/njs_array.c Mon Apr 15 17:23:02 2019 +0300 @@ -494,7 +494,7 @@ njs_array_prototype_slice_continuation(n } start = njs_primitive_value_to_integer(njs_arg(args, nargs, 1)); - length = njs_primitive_value_to_integer(&slice->length); + length = njs_primitive_value_to_length(&slice->length); if (start < 0) { start += length; diff -r f0b5b01a7c55 -r 381086beb15f njs/njs_function.c --- a/njs/njs_function.c Mon Apr 15 17:23:21 2019 +0300 +++ b/njs/njs_function.c Mon Apr 15 17:23:02 2019 +0300 @@ -1022,7 +1022,7 @@ njs_function_prototype_apply(njs_vm_t *v return NXT_ERROR; } - nargs = njs_primitive_value_to_number(&length); + nargs = njs_primitive_value_to_length(&length); arr = njs_array_alloc(vm, nargs, NJS_ARRAY_SPARE); if (nxt_slow_path(arr == NULL)) { diff -r f0b5b01a7c55 -r 381086beb15f njs/njs_math.c --- a/njs/njs_math.c Mon Apr 15 17:23:21 2019 +0300 +++ b/njs/njs_math.c Mon Apr 15 17:23:02 2019 +0300 @@ -227,7 +227,7 @@ njs_object_math_clz32(njs_vm_t *vm, njs_ uint32_t ui32; if (nargs > 1) { - ui32 = njs_number_to_integer(args[1].data.u.number); + ui32 = njs_number_to_uint32(args[1].data.u.number); num = nxt_leading_zeros(ui32); } else { @@ -393,8 +393,8 @@ njs_object_math_imul(njs_vm_t *vm, njs_v uint32_t a, b; if (nargs > 2) { - a = njs_number_to_integer(args[1].data.u.number); - b = njs_number_to_integer(args[2].data.u.number); + a = njs_number_to_uint32(args[1].data.u.number); + b = njs_number_to_uint32(args[2].data.u.number); num = (int32_t) (a * b); diff -r f0b5b01a7c55 -r 381086beb15f njs/njs_number.c --- a/njs/njs_number.c Mon Apr 15 17:23:21 2019 +0300 +++ b/njs/njs_number.c Mon Apr 15 17:23:02 2019 +0300 @@ -80,6 +80,27 @@ njs_primitive_value_to_integer(const njs } +int32_t +njs_primitive_value_to_int32(const njs_value_t *value) +{ + return njs_number_to_int32(njs_primitive_value_to_number(value)); +} + + +uint32_t +njs_primitive_value_to_uint32(const njs_value_t *value) +{ + return njs_number_to_uint32(njs_primitive_value_to_number(value)); +} + + +uint32_t +njs_primitive_value_to_length(const njs_value_t *value) +{ + return njs_number_to_length(njs_primitive_value_to_number(value)); +} + + double njs_number_dec_parse(const u_char **start, const u_char *end) { @@ -822,6 +843,41 @@ njs_number_to_integer(double num) } +nxt_noinline int32_t +njs_number_to_int32(double num) +{ + return (int32_t) njs_number_to_int64(num); +} + + +nxt_noinline uint32_t +njs_number_to_uint32(double num) +{ + return (uint32_t) njs_number_to_int64(num); +} + + +nxt_noinline uint32_t +njs_number_to_length(double num) +{ +#if (NXT_NAN_TO_UINT_CONVERSION != 0) + if (isnan(num)) { + return 0; + } +#endif + + if (num > UINT32_MAX) { + return UINT32_MAX; + + } else if (num < 0.0) { + return 0; + } + + return (uint32_t) (int64_t) num; +} + + + static const njs_object_prop_t njs_is_nan_function_properties[] = { /* isNaN.name == "isNaN". */ diff -r f0b5b01a7c55 -r 381086beb15f njs/njs_number.h --- a/njs/njs_number.h Mon Apr 15 17:23:21 2019 +0300 +++ b/njs/njs_number.h Mon Apr 15 17:23:02 2019 +0300 @@ -14,6 +14,9 @@ uint32_t njs_value_to_index(const njs_value_t *value); double njs_primitive_value_to_number(const njs_value_t *value); int32_t njs_primitive_value_to_integer(const njs_value_t *value); +int32_t njs_primitive_value_to_int32(const njs_value_t *value); +uint32_t njs_primitive_value_to_uint32(const njs_value_t *value); +uint32_t njs_primitive_value_to_length(const njs_value_t *value); double njs_number_dec_parse(const u_char **start, const u_char *end); uint64_t njs_number_oct_parse(const u_char **start, const u_char *end); uint64_t njs_number_bin_parse(const u_char **start, const u_char *end); @@ -33,7 +36,9 @@ njs_ret_t njs_number_parse_int(njs_vm_t njs_ret_t njs_number_parse_float(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); nxt_noinline int32_t njs_number_to_integer(double num); - +nxt_noinline int32_t njs_number_to_int32(double num); +nxt_noinline uint32_t njs_number_to_uint32(double num); +nxt_noinline uint32_t njs_number_to_length(double num); nxt_inline nxt_int_t njs_char_to_hex(u_char c) diff -r f0b5b01a7c55 -r 381086beb15f njs/njs_string.c --- a/njs/njs_string.c Mon Apr 15 17:23:21 2019 +0300 +++ b/njs/njs_string.c Mon Apr 15 17:23:02 2019 +0300 @@ -1445,7 +1445,7 @@ njs_string_bytes_from_array(njs_vm_t *vm octet = array->start; while (length != 0) { - *p++ = (u_char) njs_number_to_integer(octet->data.u.number); + *p++ = (u_char) njs_number_to_uint32(octet->data.u.number); octet++; length--; } diff -r f0b5b01a7c55 -r 381086beb15f njs/njs_vm.c --- a/njs/njs_vm.c Mon Apr 15 17:23:21 2019 +0300 +++ b/njs/njs_vm.c Mon Apr 15 17:23:02 2019 +0300 @@ -1303,8 +1303,8 @@ njs_vmcode_left_shift(njs_vm_t *vm, njs_ if (nxt_fast_path(njs_is_numeric(val1) && njs_is_numeric(val2))) { - num1 = njs_number_to_integer(val1->data.u.number); - num2 = njs_number_to_integer(val2->data.u.number); + num1 = njs_number_to_int32(val1->data.u.number); + num2 = njs_number_to_uint32(val2->data.u.number); njs_value_number_set(&vm->retval, num1 << (num2 & 0x1f)); return sizeof(njs_vmcode_3addr_t); @@ -1322,8 +1322,8 @@ njs_vmcode_right_shift(njs_vm_t *vm, njs if (nxt_fast_path(njs_is_numeric(val1) && njs_is_numeric(val2))) { - num1 = njs_number_to_integer(val1->data.u.number); - num2 = njs_number_to_integer(val2->data.u.number); + num1 = njs_number_to_int32(val1->data.u.number); + num2 = njs_number_to_uint32(val2->data.u.number); njs_value_number_set(&vm->retval, num1 >> (num2 & 0x1f)); return sizeof(njs_vmcode_3addr_t); @@ -1337,13 +1337,12 @@ njs_ret_t njs_vmcode_unsigned_right_shift(njs_vm_t *vm, njs_value_t *val1, njs_value_t *val2) { - int32_t num2; - uint32_t num1; + uint32_t num1, num2; if (nxt_fast_path(njs_is_numeric(val1) && njs_is_numeric(val2))) { - num1 = njs_number_to_integer(val1->data.u.number); - num2 = njs_number_to_integer(val2->data.u.number); + num1 = njs_number_to_uint32(val1->data.u.number); + num2 = njs_number_to_uint32(val2->data.u.number); njs_value_number_set(&vm->retval, num1 >> (num2 & 0x1f)); return sizeof(njs_vmcode_3addr_t); @@ -1462,8 +1461,8 @@ njs_vmcode_bitwise_or(njs_vm_t *vm, njs_ if (nxt_fast_path(njs_is_numeric(val1) && njs_is_numeric(val2))) { - num1 = njs_number_to_integer(val1->data.u.number); - num2 = njs_number_to_integer(val2->data.u.number); + num1 = njs_number_to_uint32(val1->data.u.number); + num2 = njs_number_to_uint32(val2->data.u.number); njs_value_number_set(&vm->retval, num1 | num2); return sizeof(njs_vmcode_3addr_t); diff -r f0b5b01a7c55 -r 381086beb15f njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Mon Apr 15 17:23:21 2019 +0300 +++ b/njs/test/njs_unit_test.c Mon Apr 15 17:23:02 2019 +0300 @@ -3617,7 +3617,7 @@ static njs_unit_test_t njs_test[] = nxt_string("TypeError: Cannot convert object to primitive value") }, { nxt_string("Array.prototype.slice.call({length:-1})"), - nxt_string("MemoryError") }, + nxt_string("") }, { nxt_string("Array.prototype.slice.call('αβZγ')"), nxt_string("α,β,Z,γ") }, _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel