}
+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)
.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"),
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,
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);
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);
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);
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);
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);
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);
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);
}
-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)
{
{ 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") },