details: http://hg.nginx.org/njs/rev/91dc07616b19 branches: changeset: 264:91dc07616b19 user: Valentin Bartenev <vb...@nginx.com> date: Sat Nov 19 22:20:06 2016 +0300 description: Math.imul() method.
diffstat: njs/njs_math.c | 31 ++++++++++++++++++++++++++ njs/njs_number.c | 25 +++++++++++++++++++++ njs/njs_number.h | 1 + njs/njs_vm.c | 52 ++++++++++-------------------------------- njs/test/njs_unit_test.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 127 insertions(+), 39 deletions(-) diffs (276 lines): diff -r f06c2b48ff78 -r 91dc07616b19 njs/njs_math.c --- a/njs/njs_math.c Fri Nov 18 17:25:45 2016 +0300 +++ b/njs/njs_math.c Sat Nov 19 22:20:06 2016 +0300 @@ -378,6 +378,29 @@ njs_object_math_hypot(njs_vm_t *vm, njs_ static njs_ret_t +njs_object_math_imul(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + 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); + + num = (int32_t) (a * b); + + } else { + num = 0; + } + + njs_number_set(&vm->retval, num); + + return NXT_OK; +} + + +static njs_ret_t njs_object_math_log(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { @@ -898,6 +921,14 @@ static const njs_object_prop_t njs_math .value = njs_native_function(njs_object_math_hypot, 0, 0), }, + /* ES6. */ + { + .type = NJS_METHOD, + .name = njs_string("imul"), + .value = njs_native_function(njs_object_math_imul, 0, + NJS_SKIP_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG), + }, + { .type = NJS_METHOD, .name = njs_string("log"), diff -r f06c2b48ff78 -r 91dc07616b19 njs/njs_number.c --- a/njs/njs_number.c Fri Nov 18 17:25:45 2016 +0300 +++ b/njs/njs_number.c Sat Nov 19 22:20:06 2016 +0300 @@ -741,3 +741,28 @@ njs_number_parse_float(njs_vm_t *vm, njs return NXT_OK; } + + +nxt_noinline uint32_t +njs_number_to_integer(double num) +{ + int64_t i64; + + /* + * ECMAScript 5.1: integer must be modulo 2^32. + * 2^53 is the largest integer number which can be stored in the IEEE-754 + * format and numbers less than 2^53 can be just converted to int64_t + * eliding more expensive fmod() operation. Then the int64 integer is + * truncated to uint32_t. The NaN can be converted to 0x8000000000000000 + * and becomes 0 after truncation. fmod() of the infinity returns NaN. + */ + + if (num < 0 || num > 9007199254740992.0) { + i64 = fmod(num, 4294967296.0); + + } else { + i64 = num; + } + + return (uint32_t) i64; +} diff -r f06c2b48ff78 -r 91dc07616b19 njs/njs_number.h --- a/njs/njs_number.h Fri Nov 18 17:25:45 2016 +0300 +++ b/njs/njs_number.h Sat Nov 19 22:20:06 2016 +0300 @@ -27,6 +27,7 @@ njs_ret_t njs_number_parse_int(njs_vm_t nxt_uint_t nargs, njs_index_t unused); 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 uint32_t njs_number_to_integer(double num); extern const njs_object_init_t njs_number_constructor_init; diff -r f06c2b48ff78 -r 91dc07616b19 njs/njs_vm.c --- a/njs/njs_vm.c Fri Nov 18 17:25:45 2016 +0300 +++ b/njs/njs_vm.c Sat Nov 19 22:20:06 2016 +0300 @@ -78,7 +78,6 @@ static njs_ret_t njs_object_property_que njs_property_query_t *pq, njs_value_t *value, njs_object_t *object); static njs_ret_t njs_method_private_copy(njs_vm_t *vm, njs_property_query_t *pq); -static nxt_noinline uint32_t njs_integer_value(double num); static nxt_noinline njs_ret_t njs_values_equal(const njs_value_t *val1, const njs_value_t *val2); static nxt_noinline njs_ret_t njs_values_compare(const njs_value_t *val1, @@ -1639,8 +1638,8 @@ njs_vmcode_left_shift(njs_vm_t *vm, njs_ if (nxt_fast_path(njs_is_numeric(val1) && njs_is_numeric(val2))) { - num1 = njs_integer_value(val1->data.u.number); - num2 = njs_integer_value(val2->data.u.number); + num1 = njs_number_to_integer(val1->data.u.number); + num2 = njs_number_to_integer(val2->data.u.number); njs_number_set(&vm->retval, num1 << (num2 & 0x1f)); return sizeof(njs_vmcode_3addr_t); @@ -1658,8 +1657,8 @@ njs_vmcode_right_shift(njs_vm_t *vm, njs if (nxt_fast_path(njs_is_numeric(val1) && njs_is_numeric(val2))) { - num1 = njs_integer_value(val1->data.u.number); - num2 = njs_integer_value(val2->data.u.number); + num1 = njs_number_to_integer(val1->data.u.number); + num2 = njs_number_to_integer(val2->data.u.number); njs_number_set(&vm->retval, num1 >> (num2 & 0x1f)); return sizeof(njs_vmcode_3addr_t); @@ -1678,8 +1677,8 @@ njs_vmcode_unsigned_right_shift(njs_vm_t if (nxt_fast_path(njs_is_numeric(val1) && njs_is_numeric(val2))) { - num1 = njs_integer_value(val1->data.u.number); - num2 = njs_integer_value(val2->data.u.number); + num1 = njs_number_to_integer(val1->data.u.number); + num2 = njs_number_to_integer(val2->data.u.number); njs_number_set(&vm->retval, num1 >> (num2 & 0x1f)); return sizeof(njs_vmcode_3addr_t); @@ -1745,7 +1744,7 @@ njs_vmcode_bitwise_not(njs_vm_t *vm, njs int32_t num; if (nxt_fast_path(njs_is_numeric(value))) { - num = njs_integer_value(value->data.u.number); + num = njs_number_to_integer(value->data.u.number); njs_number_set(&vm->retval, ~num); return sizeof(njs_vmcode_2addr_t); @@ -1762,8 +1761,8 @@ njs_vmcode_bitwise_and(njs_vm_t *vm, njs if (nxt_fast_path(njs_is_numeric(val1) && njs_is_numeric(val2))) { - num1 = njs_integer_value(val1->data.u.number); - num2 = njs_integer_value(val2->data.u.number); + num1 = njs_number_to_integer(val1->data.u.number); + num2 = njs_number_to_integer(val2->data.u.number); njs_number_set(&vm->retval, num1 & num2); return sizeof(njs_vmcode_3addr_t); @@ -1780,8 +1779,8 @@ njs_vmcode_bitwise_xor(njs_vm_t *vm, njs if (nxt_fast_path(njs_is_numeric(val1) && njs_is_numeric(val2))) { - num1 = njs_integer_value(val1->data.u.number); - num2 = njs_integer_value(val2->data.u.number); + num1 = njs_number_to_integer(val1->data.u.number); + num2 = njs_number_to_integer(val2->data.u.number); njs_number_set(&vm->retval, num1 ^ num2); return sizeof(njs_vmcode_3addr_t); @@ -1798,8 +1797,8 @@ njs_vmcode_bitwise_or(njs_vm_t *vm, njs_ if (nxt_fast_path(njs_is_numeric(val1) && njs_is_numeric(val2))) { - num1 = njs_integer_value(val1->data.u.number); - num2 = njs_integer_value(val2->data.u.number); + num1 = njs_number_to_integer(val1->data.u.number); + num2 = njs_number_to_integer(val2->data.u.number); njs_number_set(&vm->retval, num1 | num2); return sizeof(njs_vmcode_3addr_t); @@ -1809,31 +1808,6 @@ njs_vmcode_bitwise_or(njs_vm_t *vm, njs_ } -static nxt_noinline uint32_t -njs_integer_value(double num) -{ - int64_t i64; - - /* - * ECMAScript 5.1: integer must be modulo 2^32. - * 2^53 is the largest integer number which can be stored in the IEEE-754 - * format and numbers less than 2^53 can be just converted to int64_t - * eliding more expensive fmod() operation. Then the int64 integer is - * truncated to uint32_t. The NaN can be converted to 0x8000000000000000 - * and becomes 0 after truncation. fmod() of the infinity returns NaN. - */ - - if (num < 0 || num > 9007199254740992.0) { - i64 = fmod(num, 4294967296.0); - - } else { - i64 = num; - } - - return (uint32_t) i64; -} - - njs_ret_t njs_vmcode_equal(njs_vm_t *vm, njs_value_t *val1, njs_value_t *val2) { diff -r f06c2b48ff78 -r 91dc07616b19 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Fri Nov 18 17:25:45 2016 +0300 +++ b/njs/test/njs_unit_test.c Sat Nov 19 22:20:06 2016 +0300 @@ -5968,6 +5968,63 @@ static njs_unit_test_t njs_test[] = { nxt_string("Math.hypot(3, -4, 12.0, '84', 132)"), nxt_string("157") }, + { nxt_string("Math.imul()"), + nxt_string("0") }, + + { nxt_string("Math.imul(1)"), + nxt_string("0") }, + + { nxt_string("Math.imul('a', 1)"), + nxt_string("0") }, + + { nxt_string("Math.imul(1, NaN)"), + nxt_string("0") }, + + { nxt_string("Math.imul(2, '3')"), + nxt_string("6") }, + + { nxt_string("Math.imul('3.9', -2.1)"), + nxt_string("-6") }, + + { nxt_string("Math.imul(2, 2147483647)"), + nxt_string("-2") }, + + { nxt_string("Math.imul(Number.MAX_SAFE_INTEGER, 2)"), + nxt_string("-2") }, + + { nxt_string("Math.imul(1, Number.MAX_SAFE_INTEGER + 1)"), + nxt_string("0") }, + + { nxt_string("Math.imul(2, Number.MIN_SAFE_INTEGER)"), + nxt_string("2") }, + + { nxt_string("Math.imul(Number.MIN_SAFE_INTEGER - 1, 1)"), + nxt_string("0") }, + + { nxt_string("Math.imul(2, 4294967297)"), + nxt_string("2") }, + + { nxt_string("Math.imul(-4294967297, 4294967297)"), + nxt_string("-1") }, + + { nxt_string("Math.imul(4294967297, -4294967298)"), + nxt_string("-2") }, + + { nxt_string("Math.imul(-4294967290, 4294967290)"), + nxt_string("-36") }, + + { nxt_string("Math.imul(-Infinity, 1)"), + nxt_string("0") }, + + { nxt_string("Math.imul(1, Infinity)"), + nxt_string("0") }, + + { nxt_string("Math.imul(Number.MAX_VALUE, 1)"), + nxt_string("0") }, + + { nxt_string("Math.imul(1, -Number.MAX_VALUE)"), + nxt_string("0") }, + { nxt_string("Math.log()"), nxt_string("NaN") }, _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel