From: Dmitry Volyntsev Date: Mon, 17 Feb 2020 13:18:38 +0000 (+0300) Subject: Simplified code using magic arguments introduced in 6df48738a043. X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=81602e31f92703b8660dbc50723d30a99b7447b9;p=njs.git Simplified code using magic arguments introduced in 6df48738a043. This reduces code duplication and the binary size. --- diff --git a/src/njs_error.c b/src/njs_error.c index 60af3c5f..97fe51a8 100644 --- a/src/njs_error.c +++ b/src/njs_error.c @@ -257,8 +257,8 @@ memory_error: static njs_int_t -njs_error_create(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_object_type_t type) +njs_error_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, + njs_index_t type) { njs_int_t ret; njs_value_t *value; @@ -287,14 +287,6 @@ njs_error_create(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } -static njs_int_t -njs_error_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_index_t unused) -{ - return njs_error_create(vm, args, nargs, NJS_OBJ_TYPE_ERROR); -} - - static const njs_object_prop_t njs_error_constructor_properties[] = { { @@ -325,14 +317,6 @@ const njs_object_init_t njs_error_constructor_init = { }; -static njs_int_t -njs_eval_error_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_index_t unused) -{ - return njs_error_create(vm, args, nargs, NJS_OBJ_TYPE_EVAL_ERROR); -} - - static const njs_object_prop_t njs_eval_error_constructor_properties[] = { { @@ -363,14 +347,6 @@ const njs_object_init_t njs_eval_error_constructor_init = { }; -static njs_int_t -njs_internal_error_constructor(njs_vm_t *vm, njs_value_t *args, - njs_uint_t nargs, njs_index_t unused) -{ - return njs_error_create(vm, args, nargs, NJS_OBJ_TYPE_INTERNAL_ERROR); -} - - static const njs_object_prop_t njs_internal_error_constructor_properties[] = { { @@ -401,14 +377,6 @@ const njs_object_init_t njs_internal_error_constructor_init = { }; -static njs_int_t -njs_range_error_constructor(njs_vm_t *vm, njs_value_t *args, - njs_uint_t nargs, njs_index_t unused) -{ - return njs_error_create(vm, args, nargs, NJS_OBJ_TYPE_RANGE_ERROR); -} - - static const njs_object_prop_t njs_range_error_constructor_properties[] = { { @@ -439,14 +407,6 @@ const njs_object_init_t njs_range_error_constructor_init = { }; -static njs_int_t -njs_reference_error_constructor(njs_vm_t *vm, njs_value_t *args, - njs_uint_t nargs, njs_index_t unused) -{ - return njs_error_create(vm, args, nargs, NJS_OBJ_TYPE_REF_ERROR); -} - - static const njs_object_prop_t njs_reference_error_constructor_properties[] = { { @@ -477,14 +437,6 @@ const njs_object_init_t njs_reference_error_constructor_init = { }; -static njs_int_t -njs_syntax_error_constructor(njs_vm_t *vm, njs_value_t *args, - njs_uint_t nargs, njs_index_t unused) -{ - return njs_error_create(vm, args, nargs, NJS_OBJ_TYPE_SYNTAX_ERROR); -} - - static const njs_object_prop_t njs_syntax_error_constructor_properties[] = { { @@ -515,14 +467,6 @@ const njs_object_init_t njs_syntax_error_constructor_init = { }; -static njs_int_t -njs_type_error_constructor(njs_vm_t *vm, njs_value_t *args, - njs_uint_t nargs, njs_index_t unused) -{ - return njs_error_create(vm, args, nargs, NJS_OBJ_TYPE_TYPE_ERROR); -} - - static const njs_object_prop_t njs_type_error_constructor_properties[] = { { @@ -553,14 +497,6 @@ const njs_object_init_t njs_type_error_constructor_init = { }; -static njs_int_t -njs_uri_error_constructor(njs_vm_t *vm, njs_value_t *args, - njs_uint_t nargs, njs_index_t unused) -{ - return njs_error_create(vm, args, nargs, NJS_OBJ_TYPE_URI_ERROR); -} - - static const njs_object_prop_t njs_uri_error_constructor_properties[] = { { @@ -874,7 +810,8 @@ const njs_object_init_t njs_error_prototype_init = { const njs_object_type_init_t njs_error_type_init = { - .constructor = njs_native_ctor(njs_error_constructor, 1, 0), + .constructor = njs_native_ctor(njs_error_constructor, 1, + NJS_OBJ_TYPE_ERROR), .constructor_props = &njs_error_constructor_init, .prototype_props = &njs_error_prototype_init, .prototype_value = { .object = { .type = NJS_OBJECT } }, @@ -916,7 +853,8 @@ const njs_object_init_t njs_eval_error_prototype_init = { const njs_object_type_init_t njs_eval_error_type_init = { - .constructor = njs_native_ctor(njs_eval_error_constructor, 1, 0), + .constructor = njs_native_ctor(njs_error_constructor, 1, + NJS_OBJ_TYPE_EVAL_ERROR), .constructor_props = &njs_eval_error_constructor_init, .prototype_props = &njs_eval_error_prototype_init, .prototype_value = { .object = { .type = NJS_OBJECT } }, @@ -978,7 +916,8 @@ const njs_object_init_t njs_internal_error_prototype_init = { const njs_object_type_init_t njs_internal_error_type_init = { - .constructor = njs_native_ctor(njs_internal_error_constructor, 1, 0), + .constructor = njs_native_ctor(njs_error_constructor, 1, + NJS_OBJ_TYPE_INTERNAL_ERROR), .constructor_props = &njs_internal_error_constructor_init, .prototype_props = &njs_internal_error_prototype_init, .prototype_value = { .object = { .type = NJS_OBJECT } }, @@ -1028,7 +967,8 @@ const njs_object_init_t njs_range_error_prototype_init = { const njs_object_type_init_t njs_range_error_type_init = { - .constructor = njs_native_ctor(njs_range_error_constructor, 1, 0), + .constructor = njs_native_ctor(njs_error_constructor, 1, + NJS_OBJ_TYPE_RANGE_ERROR), .constructor_props = &njs_range_error_constructor_init, .prototype_props = &njs_range_error_prototype_init, .prototype_value = { .object = { .type = NJS_OBJECT } }, @@ -1070,7 +1010,8 @@ const njs_object_init_t njs_reference_error_prototype_init = { const njs_object_type_init_t njs_reference_error_type_init = { - .constructor = njs_native_ctor(njs_reference_error_constructor, 1, 0), + .constructor = njs_native_ctor(njs_error_constructor, 1, + NJS_OBJ_TYPE_REF_ERROR), .constructor_props = &njs_reference_error_constructor_init, .prototype_props = &njs_reference_error_prototype_init, .prototype_value = { .object = { .type = NJS_OBJECT } }, @@ -1112,7 +1053,8 @@ const njs_object_init_t njs_syntax_error_prototype_init = { const njs_object_type_init_t njs_syntax_error_type_init = { - .constructor = njs_native_ctor(njs_syntax_error_constructor, 1, 0), + .constructor = njs_native_ctor(njs_error_constructor, 1, + NJS_OBJ_TYPE_SYNTAX_ERROR), .constructor_props = &njs_syntax_error_constructor_init, .prototype_props = &njs_syntax_error_prototype_init, .prototype_value = { .object = { .type = NJS_OBJECT } }, @@ -1154,7 +1096,8 @@ const njs_object_init_t njs_type_error_prototype_init = { const njs_object_type_init_t njs_type_error_type_init = { - .constructor = njs_native_ctor(njs_type_error_constructor, 1, 0), + .constructor = njs_native_ctor(njs_error_constructor, 1, + NJS_OBJ_TYPE_TYPE_ERROR), .constructor_props = &njs_type_error_constructor_init, .prototype_props = &njs_type_error_prototype_init, .prototype_value = { .object = { .type = NJS_OBJECT } }, @@ -1196,7 +1139,8 @@ const njs_object_init_t njs_uri_error_prototype_init = { const njs_object_type_init_t njs_uri_error_type_init = { - .constructor = njs_native_ctor(njs_uri_error_constructor, 1, 0), + .constructor = njs_native_ctor(njs_error_constructor, 1, + NJS_OBJ_TYPE_URI_ERROR), .constructor_props = &njs_uri_error_constructor_init, .prototype_props = &njs_uri_error_prototype_init, .prototype_value = { .object = { .type = NJS_OBJECT } }, diff --git a/src/njs_math.c b/src/njs_math.c index 01bada64..1b2dd300 100644 --- a/src/njs_math.c +++ b/src/njs_math.c @@ -8,444 +8,267 @@ #include -static njs_int_t -njs_object_math_abs(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_index_t unused) -{ - njs_int_t ret; - - if (njs_slow_path(nargs < 2)) { - njs_set_number(&vm->retval, NAN); - return NJS_OK; - } - - if (njs_slow_path(!njs_is_number(&args[1]))) { - ret = njs_value_to_numeric(vm, &args[1], &args[1]); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - } - - njs_set_number(&vm->retval, fabs(njs_number(&args[1]))); - - return NJS_OK; -} - - -static njs_int_t -njs_object_math_acos(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_index_t unused) -{ - double num; - njs_int_t ret; +typedef enum { + NJS_MATH_ABS, + NJS_MATH_ACOS, + NJS_MATH_ACOSH, + NJS_MATH_ASIN, + NJS_MATH_ASINH, + NJS_MATH_ATAN, + NJS_MATH_ATAN2, + NJS_MATH_ATANH, + NJS_MATH_CBRT, + NJS_MATH_CEIL, + NJS_MATH_CLZ32, + NJS_MATH_COS, + NJS_MATH_COSH, + NJS_MATH_EXP, + NJS_MATH_EXPM1, + NJS_MATH_FLOOR, + NJS_MATH_FROUND, + NJS_MATH_IMUL, + NJS_MATH_LOG, + NJS_MATH_LOG10, + NJS_MATH_LOG1P, + NJS_MATH_LOG2, + NJS_MATH_POW, + NJS_MATH_ROUND, + NJS_MATH_SIGN, + NJS_MATH_SIN, + NJS_MATH_SINH, + NJS_MATH_SQRT, + NJS_MATH_TAN, + NJS_MATH_TANH, + NJS_MATH_TRUNC, +} njs_math_func_t; + + +static njs_int_t +njs_object_math_func(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, + njs_index_t magic) +{ + double num, num2; + uint8_t sign; + uint32_t u32; + uint64_t one, fraction_mask; + njs_int_t ret, ep; + njs_math_func_t func; + njs_diyfp_conv_t conv; - if (njs_slow_path(nargs < 2)) { - njs_set_number(&vm->retval, NAN); - return NJS_OK; - } + func = magic; - if (njs_slow_path(!njs_is_number(&args[1]))) { - ret = njs_value_to_numeric(vm, &args[1], &args[1]); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } + ret = njs_value_to_number(vm, njs_arg(args, nargs, 1), &num); + if (njs_slow_path(ret != NJS_OK)) { + return ret; } - num = njs_number(&args[1]); + switch (func) { + case NJS_MATH_ABS: + num = fabs(num); + break; + case NJS_MATH_ACOS: #if (NJS_SOLARIS) - /* On Solaris acos(x) returns 0 for x > 1. */ - if (fabs(num) > 1.0) { - num = NAN; - } -#endif - - njs_set_number(&vm->retval, acos(num)); - - return NJS_OK; -} - - -static njs_int_t -njs_object_math_acosh(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_index_t unused) -{ - njs_int_t ret; - - if (njs_slow_path(nargs < 2)) { - njs_set_number(&vm->retval, NAN); - return NJS_OK; - } - - if (njs_slow_path(!njs_is_number(&args[1]))) { - ret = njs_value_to_numeric(vm, &args[1], &args[1]); - if (njs_slow_path(ret != NJS_OK)) { - return ret; + /* On Solaris acos(x) returns 0 for x > 1. */ + if (fabs(num) > 1.0) { + num = NAN; } - } - - njs_set_number(&vm->retval, acosh(njs_number(&args[1]))); - - return NJS_OK; -} - - -static njs_int_t -njs_object_math_asin(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_index_t unused) -{ - double num; - njs_int_t ret; - - if (njs_slow_path(nargs < 2)) { - njs_set_number(&vm->retval, NAN); - return NJS_OK; - } - - if (njs_slow_path(!njs_is_number(&args[1]))) { - ret = njs_value_to_numeric(vm, &args[1], &args[1]); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - } - - num = njs_number(&args[1]); - -#if (NJS_SOLARIS) - /* On Solaris asin(x) returns 0 for x > 1. */ - if (fabs(num) > 1.0) { - num = NAN; - } #endif - njs_set_number(&vm->retval, asin(num)); + num = acos(num); + break; - return NJS_OK; -} - - -static njs_int_t -njs_object_math_asinh(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_index_t unused) -{ - njs_int_t ret; - - if (njs_slow_path(nargs < 2)) { - njs_set_number(&vm->retval, NAN); - return NJS_OK; - } - - if (njs_slow_path(!njs_is_number(&args[1]))) { - ret = njs_value_to_numeric(vm, &args[1], &args[1]); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - } - - njs_set_number(&vm->retval, asinh(njs_number(&args[1]))); - - return NJS_OK; -} - - -static njs_int_t -njs_object_math_atan(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_index_t unused) -{ - njs_int_t ret; - - if (njs_slow_path(nargs < 2)) { - njs_set_number(&vm->retval, NAN); - return NJS_OK; - } - - if (njs_slow_path(!njs_is_number(&args[1]))) { - ret = njs_value_to_numeric(vm, &args[1], &args[1]); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - } - - njs_set_number(&vm->retval, atan(njs_number(&args[1]))); - - return NJS_OK; -} - - -static njs_int_t -njs_object_math_atan2(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_index_t unused) -{ - double y, x; - njs_int_t ret; - - if (njs_slow_path(nargs < 3)) { - njs_set_number(&vm->retval, NAN); - return NJS_OK; - } - - if (njs_slow_path(!njs_is_number(&args[1]))) { - ret = njs_value_to_numeric(vm, &args[1], &args[1]); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - } - - if (njs_slow_path(!njs_is_number(&args[2]))) { - ret = njs_value_to_numeric(vm, &args[2], &args[2]); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - } - - y = njs_number(&args[1]); - x = njs_number(&args[2]); - - njs_set_number(&vm->retval, atan2(y, x)); - - return NJS_OK; -} - - -static njs_int_t -njs_object_math_atanh(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_index_t unused) -{ - njs_int_t ret; - - if (njs_slow_path(nargs < 2)) { - njs_set_number(&vm->retval, NAN); - return NJS_OK; - } + case NJS_MATH_ACOSH: + num = acosh(num); + break; - if (njs_slow_path(!njs_is_number(&args[1]))) { - ret = njs_value_to_numeric(vm, &args[1], &args[1]); - if (njs_slow_path(ret != NJS_OK)) { - return ret; + case NJS_MATH_ASIN: +#if (NJS_SOLARIS) + /* On Solaris asin(x) returns 0 for x > 1. */ + if (fabs(num) > 1.0) { + num = NAN; } - } - - njs_set_number(&vm->retval, atanh(njs_number(&args[1]))); +#endif - return NJS_OK; -} + num = asin(num); + break; + case NJS_MATH_ASINH: + num = asinh(num); + break; -static njs_int_t -njs_object_math_cbrt(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_index_t unused) -{ - njs_int_t ret; + case NJS_MATH_ATAN: + num = atan(num); + break; - if (njs_slow_path(nargs < 2)) { - njs_set_number(&vm->retval, NAN); - return NJS_OK; - } + case NJS_MATH_ATANH: + num = atanh(num); + break; - if (njs_slow_path(!njs_is_number(&args[1]))) { - ret = njs_value_to_numeric(vm, &args[1], &args[1]); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - } + case NJS_MATH_CBRT: + num = cbrt(num); + break; - njs_set_number(&vm->retval, cbrt(njs_number(&args[1]))); + case NJS_MATH_CEIL: + num = ceil(num); + break; - return NJS_OK; -} + case NJS_MATH_CLZ32: + u32 = njs_number_to_uint32(num); + num = njs_leading_zeros(u32); + break; + case NJS_MATH_COS: + num = cos(num); + break; -static njs_int_t -njs_object_math_ceil(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_index_t unused) -{ - njs_int_t ret; + case NJS_MATH_COSH: + num = cosh(num); + break; - if (njs_slow_path(nargs < 2)) { - njs_set_number(&vm->retval, NAN); - return NJS_OK; - } + case NJS_MATH_EXP: + num = exp(num); + break; - if (njs_slow_path(!njs_is_number(&args[1]))) { - ret = njs_value_to_numeric(vm, &args[1], &args[1]); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - } + case NJS_MATH_EXPM1: + num = expm1(num); + break; - njs_set_number(&vm->retval, ceil(njs_number(&args[1]))); + case NJS_MATH_FLOOR: + num = floor(num); + break; - return NJS_OK; -} + case NJS_MATH_FROUND: + num = (float) num; + break; + case NJS_MATH_LOG: + num = log(num); + break; -static njs_int_t -njs_object_math_clz32(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_index_t unused) -{ - uint32_t ui32; - njs_int_t ret; + case NJS_MATH_LOG10: + num = log10(num); + break; - if (njs_slow_path(nargs < 2)) { - njs_set_number(&vm->retval, 32); - return NJS_OK; - } + case NJS_MATH_LOG1P: + num = log1p(num); + break; - if (njs_slow_path(!njs_is_number(&args[1]))) { - ret = njs_value_to_uint32(vm, &args[1], &ui32); - if (njs_slow_path(ret != NJS_OK)) { - return ret; + case NJS_MATH_LOG2: +#if (NJS_SOLARIS) + /* On Solaris 10 log(-1) returns -Infinity. */ + if (num < 0) { + num = NAN; } +#endif - } else { - ui32 = njs_number_to_uint32(njs_number(&args[1])); - } - - njs_set_number(&vm->retval, njs_leading_zeros(ui32)); - - return NJS_OK; -} - - -static njs_int_t -njs_object_math_cos(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_index_t unused) -{ - njs_int_t ret; - - if (njs_slow_path(nargs < 2)) { - njs_set_number(&vm->retval, NAN); - return NJS_OK; - } + num = log2(num); + break; - if (njs_slow_path(!njs_is_number(&args[1]))) { - ret = njs_value_to_numeric(vm, &args[1], &args[1]); - if (njs_slow_path(ret != NJS_OK)) { - return ret; + case NJS_MATH_SIGN: + if (!isnan(num) && num != 0) { + num = signbit(num) ? -1 : 1; } - } - njs_set_number(&vm->retval, cos(njs_number(&args[1]))); + break; - return NJS_OK; -} + case NJS_MATH_SIN: + num = sin(num); + break; + case NJS_MATH_SINH: + num = sinh(num); + break; -static njs_int_t -njs_object_math_cosh(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_index_t unused) -{ - njs_int_t ret; + case NJS_MATH_SQRT: + num = sqrt(num); + break; - if (njs_slow_path(nargs < 2)) { - njs_set_number(&vm->retval, NAN); - return NJS_OK; - } + case NJS_MATH_ROUND: + conv.d = num; + ep = (conv.u64 & NJS_DBL_EXPONENT_MASK) >> NJS_DBL_SIGNIFICAND_SIZE; - if (njs_slow_path(!njs_is_number(&args[1]))) { - ret = njs_value_to_numeric(vm, &args[1], &args[1]); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - } - - njs_set_number(&vm->retval, cosh(njs_number(&args[1]))); + if (ep < NJS_DBL_EXPONENT_OFFSET) { - return NJS_OK; -} + /* |v| < 1. */ + if (ep == (NJS_DBL_EXPONENT_OFFSET - 1) + && conv.u64 != njs_uint64(0xbfe00000, 0x00000000)) + { + /* (|v| > 0.5 || v == 0.5) => +-1.0 */ -static njs_int_t -njs_object_math_exp(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_index_t unused) -{ - njs_int_t ret; + conv.u64 = conv.u64 & NJS_DBL_SIGN_MASK; + conv.u64 |= NJS_DBL_EXPONENT_OFFSET << NJS_DBL_SIGNIFICAND_SIZE; - if (njs_slow_path(nargs < 2)) { - njs_set_number(&vm->retval, NAN); - return NJS_OK; - } + } else { - if (njs_slow_path(!njs_is_number(&args[1]))) { - ret = njs_value_to_numeric(vm, &args[1], &args[1]); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - } + /* (|v| < 0.5 || v == -0.5) => +-0. */ - njs_set_number(&vm->retval, exp(njs_number(&args[1]))); + conv.u64 &= ((uint64_t) 1) << 63; + } - return NJS_OK; -} + } else if (ep < NJS_DBL_EXPONENT_BIAS) { + /* |v| <= 2^52 - 1 (largest safe integer). */ -static njs_int_t -njs_object_math_expm1(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_index_t unused) -{ - njs_int_t ret; + one = ((uint64_t) 1) << (NJS_DBL_EXPONENT_BIAS - ep); + fraction_mask = one - 1; - if (njs_slow_path(nargs < 2)) { - njs_set_number(&vm->retval, NAN); - return NJS_OK; - } + /* truncation. */ - if (njs_slow_path(!njs_is_number(&args[1]))) { - ret = njs_value_to_numeric(vm, &args[1], &args[1]); - if (njs_slow_path(ret != NJS_OK)) { - return ret; + sign = conv.u64 >> 63; + conv.u64 += (one >> 1) - sign; + conv.u64 &= ~fraction_mask; } - } - - njs_set_number(&vm->retval, expm1(njs_number(&args[1]))); - return NJS_OK; -} + num = conv.d; + break; + case NJS_MATH_TAN: + num = tan(num); + break; -static njs_int_t -njs_object_math_floor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_index_t unused) -{ - njs_int_t ret; + case NJS_MATH_TANH: + num = tanh(num); + break; - if (njs_slow_path(nargs < 2)) { - njs_set_number(&vm->retval, NAN); - return NJS_OK; - } + case NJS_MATH_TRUNC: + num = trunc(num); + break; - if (njs_slow_path(!njs_is_number(&args[1]))) { - ret = njs_value_to_numeric(vm, &args[1], &args[1]); + default: + ret = njs_value_to_number(vm, njs_arg(args, nargs, 2), &num2); if (njs_slow_path(ret != NJS_OK)) { return ret; } - } - njs_set_number(&vm->retval, floor(njs_number(&args[1]))); + switch (func) { + case NJS_MATH_ATAN2: + num = atan2(num, num2); + break; - return NJS_OK; -} + case NJS_MATH_IMUL: + u32 = njs_number_to_uint32(num); + num = (int32_t) (u32 * njs_number_to_uint32(num2)); + break; + default: + /* + * According to ECMA-262: + * 1. If exponent is NaN, the result should be NaN; + * 2. The result of Math.pow(+/-1, +/-Infinity) should be NaN. + */ -static njs_int_t -njs_object_math_fround(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_index_t unused) -{ - njs_int_t ret; - - if (njs_slow_path(nargs < 2)) { - njs_set_number(&vm->retval, NAN); - return NJS_OK; - } + if (fabs(num) != 1 || (!isnan(num2) && !isinf(num2))) { + num = pow(num, num2); - if (njs_slow_path(!njs_is_number(&args[1]))) { - ret = njs_value_to_numeric(vm, &args[1], &args[1]); - if (njs_slow_path(ret != NJS_OK)) { - return ret; + } else { + num = NAN; + } } } - njs_set_number(&vm->retval, (float) njs_number(&args[1])); + njs_set_number(&vm->retval, num); return NJS_OK; } @@ -459,170 +282,27 @@ njs_object_math_hypot(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_int_t ret; njs_uint_t i; - for (i = 1; i < nargs; i++) { - if (!njs_is_numeric(&args[i])) { - ret = njs_value_to_numeric(vm, &args[i], &args[i]); - if (ret != NJS_OK) { - return ret; - } - } + ret = njs_value_to_number(vm, njs_arg(args, nargs, 1), &num); + if (njs_slow_path(ret != NJS_OK)) { + return ret; } - num = (nargs > 1) ? fabs(njs_number(&args[1])) : 0; + num = (nargs > 1) ? fabs(num) : 0; for (i = 2; i < nargs; i++) { - num = hypot(num, njs_number(&args[i])); - - if (num == INFINITY) { - break; - } - } - - njs_set_number(&vm->retval, num); - - return NJS_OK; -} - - -static njs_int_t -njs_object_math_imul(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_index_t unused) -{ - uint32_t a, b; - njs_int_t ret; - - if (njs_slow_path(nargs < 3)) { - njs_set_number(&vm->retval, 0); - return NJS_OK; - } - - if (njs_slow_path(!njs_is_number(&args[1]))) { - ret = njs_value_to_uint32(vm, &args[1], &a); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - - } else { - a = njs_number_to_uint32(njs_number(&args[1])); - } - - if (njs_slow_path(!njs_is_number(&args[2]))) { - ret = njs_value_to_uint32(vm, &args[2], &b); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - - } else { - b = njs_number_to_uint32(njs_number(&args[2])); - } - - njs_set_number(&vm->retval, (int32_t) (a * b)); - - return NJS_OK; -} - - -static njs_int_t -njs_object_math_log(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_index_t unused) -{ - njs_int_t ret; - - if (njs_slow_path(nargs < 2)) { - njs_set_number(&vm->retval, NAN); - return NJS_OK; - } - - if (njs_slow_path(!njs_is_number(&args[1]))) { - ret = njs_value_to_numeric(vm, &args[1], &args[1]); + ret = njs_value_to_numeric(vm, &args[i], &args[i]); if (njs_slow_path(ret != NJS_OK)) { return ret; } - } - - njs_set_number(&vm->retval, log(njs_number(&args[1]))); - - return NJS_OK; -} - - -static njs_int_t -njs_object_math_log10(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_index_t unused) -{ - njs_int_t ret; - - if (njs_slow_path(nargs < 2)) { - njs_set_number(&vm->retval, NAN); - return NJS_OK; - } - - if (njs_slow_path(!njs_is_number(&args[1]))) { - ret = njs_value_to_numeric(vm, &args[1], &args[1]); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - } - - njs_set_number(&vm->retval, log10(njs_number(&args[1]))); - - return NJS_OK; -} - - -static njs_int_t -njs_object_math_log1p(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_index_t unused) -{ - njs_int_t ret; - - if (njs_slow_path(nargs < 2)) { - njs_set_number(&vm->retval, NAN); - return NJS_OK; - } - - if (njs_slow_path(!njs_is_number(&args[1]))) { - ret = njs_value_to_numeric(vm, &args[1], &args[1]); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - } - - njs_set_number(&vm->retval, log1p(njs_number(&args[1]))); - - return NJS_OK; -} - - -static njs_int_t -njs_object_math_log2(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_index_t unused) -{ - double num; - njs_int_t ret; - if (njs_slow_path(nargs < 2)) { - njs_set_number(&vm->retval, NAN); - return NJS_OK; - } + num = hypot(num, njs_number(&args[i])); - if (njs_slow_path(!njs_is_number(&args[1]))) { - ret = njs_value_to_numeric(vm, &args[1], &args[1]); - if (njs_slow_path(ret != NJS_OK)) { - return ret; + if (njs_slow_path(isinf(num))) { + break; } } - num = njs_number(&args[1]); - -#if (NJS_SOLARIS) - /* On Solaris 10 log(-1) returns -Infinity. */ - if (num < 0) { - num = NAN; - } -#endif - - njs_set_number(&vm->retval, log2(num)); + njs_set_number(&vm->retval, num); return NJS_OK; } @@ -680,54 +360,6 @@ njs_object_math_min_max(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } -static njs_int_t -njs_object_math_pow(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_index_t unused) -{ - double num, base, exponent; - njs_int_t ret; - - if (njs_slow_path(nargs < 3)) { - njs_set_number(&vm->retval, NAN); - return NJS_OK; - } - - if (njs_slow_path(!njs_is_number(&args[1]))) { - ret = njs_value_to_numeric(vm, &args[1], &args[1]); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - } - - if (njs_slow_path(!njs_is_number(&args[2]))) { - ret = njs_value_to_numeric(vm, &args[2], &args[2]); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - } - - base = njs_number(&args[1]); - exponent = njs_number(&args[2]); - - /* - * According to ECMA-262: - * 1. If exponent is NaN, the result should be NaN; - * 2. The result of Math.pow(+/-1, +/-Infinity) should be NaN. - */ - - if (fabs(base) != 1 || (!isnan(exponent) && !isinf(exponent))) { - num = pow(base, exponent); - - } else { - num = NAN; - } - - njs_set_number(&vm->retval, num); - - return NJS_OK; -} - - static njs_int_t njs_object_math_random(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) @@ -742,246 +374,6 @@ njs_object_math_random(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } -static njs_int_t -njs_object_math_round(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_index_t unused) -{ - uint8_t sign; - uint64_t one, fraction_mask; - njs_int_t ret, biased_exp; - njs_diyfp_conv_t conv; - - if (njs_slow_path(nargs < 2)) { - njs_set_number(&vm->retval, NAN); - return NJS_OK; - } - - if (njs_slow_path(!njs_is_numeric(&args[1]))) { - ret = njs_value_to_numeric(vm, &args[1], &args[1]); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - } - - conv.d = njs_number(&args[1]); - biased_exp = (conv.u64 & NJS_DBL_EXPONENT_MASK) >> NJS_DBL_SIGNIFICAND_SIZE; - - if (biased_exp < NJS_DBL_EXPONENT_OFFSET) { - - /* |v| < 1. */ - - if (biased_exp == (NJS_DBL_EXPONENT_OFFSET - 1) - && conv.u64 != njs_uint64(0xbfe00000, 0x00000000)) - { - /* (|v| > 0.5 || v == 0.5) => +-1.0 */ - - conv.u64 = (conv.u64 & NJS_DBL_SIGN_MASK) - | (NJS_DBL_EXPONENT_OFFSET << NJS_DBL_SIGNIFICAND_SIZE); - - } else { - - /* (|v| < 0.5 || v == -0.5) => +-0. */ - - conv.u64 &= ((uint64_t) 1) << 63; - } - - } else if (biased_exp < NJS_DBL_EXPONENT_BIAS) { - - /* |v| <= 2^52 - 1 (largest safe integer). */ - - one = ((uint64_t) 1) << (NJS_DBL_EXPONENT_BIAS - biased_exp); - fraction_mask = one - 1; - - /* truncation. */ - - sign = conv.u64 >> 63; - conv.u64 += (one >> 1) - sign; - conv.u64 &= ~fraction_mask; - } - - /* |v| >= 2^52, Infinity and NaNs => v. */ - - njs_set_number(&vm->retval, conv.d); - - return NJS_OK; -} - - -static njs_int_t -njs_object_math_sign(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_index_t unused) -{ - double num; - njs_int_t ret; - - if (njs_slow_path(nargs < 2)) { - njs_set_number(&vm->retval, NAN); - return NJS_OK; - } - - if (njs_slow_path(!njs_is_number(&args[1]))) { - ret = njs_value_to_numeric(vm, &args[1], &args[1]); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - } - - num = njs_number(&args[1]); - - if (!isnan(num) && num != 0) { - num = signbit(num) ? -1 : 1; - } - - njs_set_number(&vm->retval, num); - - return NJS_OK; -} - - -static njs_int_t -njs_object_math_sin(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_index_t unused) -{ - njs_int_t ret; - - if (njs_slow_path(nargs < 2)) { - njs_set_number(&vm->retval, NAN); - return NJS_OK; - } - - if (njs_slow_path(!njs_is_number(&args[1]))) { - ret = njs_value_to_numeric(vm, &args[1], &args[1]); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - } - - njs_set_number(&vm->retval, sin(njs_number(&args[1]))); - - return NJS_OK; -} - - -static njs_int_t -njs_object_math_sinh(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_index_t unused) -{ - njs_int_t ret; - - if (njs_slow_path(nargs < 2)) { - njs_set_number(&vm->retval, NAN); - return NJS_OK; - } - - if (njs_slow_path(!njs_is_number(&args[1]))) { - ret = njs_value_to_numeric(vm, &args[1], &args[1]); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - } - - njs_set_number(&vm->retval, sinh(njs_number(&args[1]))); - - return NJS_OK; -} - - -static njs_int_t -njs_object_math_sqrt(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_index_t unused) -{ - njs_int_t ret; - - if (njs_slow_path(nargs < 2)) { - njs_set_number(&vm->retval, NAN); - return NJS_OK; - } - - if (njs_slow_path(!njs_is_number(&args[1]))) { - ret = njs_value_to_numeric(vm, &args[1], &args[1]); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - } - - njs_set_number(&vm->retval, sqrt(njs_number(&args[1]))); - - return NJS_OK; -} - - -static njs_int_t -njs_object_math_tan(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_index_t unused) -{ - njs_int_t ret; - - if (njs_slow_path(nargs < 2)) { - njs_set_number(&vm->retval, NAN); - return NJS_OK; - } - - if (njs_slow_path(!njs_is_number(&args[1]))) { - ret = njs_value_to_numeric(vm, &args[1], &args[1]); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - } - - njs_set_number(&vm->retval, tan(njs_number(&args[1]))); - - return NJS_OK; -} - - -static njs_int_t -njs_object_math_tanh(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_index_t unused) -{ - njs_int_t ret; - - if (njs_slow_path(nargs < 2)) { - njs_set_number(&vm->retval, NAN); - return NJS_OK; - } - - if (njs_slow_path(!njs_is_number(&args[1]))) { - ret = njs_value_to_numeric(vm, &args[1], &args[1]); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - } - - njs_set_number(&vm->retval, tanh(njs_number(&args[1]))); - - return NJS_OK; -} - - -static njs_int_t -njs_object_math_trunc(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_index_t unused) -{ - njs_int_t ret; - - if (njs_slow_path(nargs < 2)) { - njs_set_number(&vm->retval, NAN); - return NJS_OK; - } - - if (njs_slow_path(!njs_is_number(&args[1]))) { - ret = njs_value_to_numeric(vm, &args[1], &args[1]); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - } - - njs_set_number(&vm->retval, trunc(njs_number(&args[1]))); - - return NJS_OK; -} - - static const njs_object_prop_t njs_math_object_properties[] = { { @@ -1050,7 +442,7 @@ static const njs_object_prop_t njs_math_object_properties[] = { .type = NJS_PROPERTY, .name = njs_string("abs"), - .value = njs_native_function(njs_object_math_abs, 1), + .value = njs_native_function2(njs_object_math_func, 1, NJS_MATH_ABS), .writable = 1, .configurable = 1, }, @@ -1058,7 +450,7 @@ static const njs_object_prop_t njs_math_object_properties[] = { .type = NJS_PROPERTY, .name = njs_string("acos"), - .value = njs_native_function(njs_object_math_acos, 1), + .value = njs_native_function2(njs_object_math_func, 1, NJS_MATH_ACOS), .writable = 1, .configurable = 1, }, @@ -1066,7 +458,7 @@ static const njs_object_prop_t njs_math_object_properties[] = { .type = NJS_PROPERTY, .name = njs_string("acosh"), - .value = njs_native_function(njs_object_math_acosh, 1), + .value = njs_native_function2(njs_object_math_func, 1, NJS_MATH_ACOSH), .writable = 1, .configurable = 1, }, @@ -1074,7 +466,7 @@ static const njs_object_prop_t njs_math_object_properties[] = { .type = NJS_PROPERTY, .name = njs_string("asin"), - .value = njs_native_function(njs_object_math_asin, 1), + .value = njs_native_function2(njs_object_math_func, 1, NJS_MATH_ASIN), .writable = 1, .configurable = 1, }, @@ -1082,7 +474,7 @@ static const njs_object_prop_t njs_math_object_properties[] = { .type = NJS_PROPERTY, .name = njs_string("asinh"), - .value = njs_native_function(njs_object_math_asinh, 1), + .value = njs_native_function2(njs_object_math_func, 1, NJS_MATH_ASINH), .writable = 1, .configurable = 1, }, @@ -1090,7 +482,7 @@ static const njs_object_prop_t njs_math_object_properties[] = { .type = NJS_PROPERTY, .name = njs_string("atan"), - .value = njs_native_function(njs_object_math_atan, 1), + .value = njs_native_function2(njs_object_math_func, 1, NJS_MATH_ATAN), .writable = 1, .configurable = 1, }, @@ -1098,7 +490,7 @@ static const njs_object_prop_t njs_math_object_properties[] = { .type = NJS_PROPERTY, .name = njs_string("atan2"), - .value = njs_native_function(njs_object_math_atan2, 2), + .value = njs_native_function2(njs_object_math_func, 2, NJS_MATH_ATAN2), .writable = 1, .configurable = 1, }, @@ -1106,7 +498,7 @@ static const njs_object_prop_t njs_math_object_properties[] = { .type = NJS_PROPERTY, .name = njs_string("atanh"), - .value = njs_native_function(njs_object_math_atanh, 1), + .value = njs_native_function2(njs_object_math_func, 1, NJS_MATH_ATANH), .writable = 1, .configurable = 1, }, @@ -1114,7 +506,7 @@ static const njs_object_prop_t njs_math_object_properties[] = { .type = NJS_PROPERTY, .name = njs_string("cbrt"), - .value = njs_native_function(njs_object_math_cbrt, 1), + .value = njs_native_function2(njs_object_math_func, 1, NJS_MATH_CBRT), .writable = 1, .configurable = 1, }, @@ -1122,7 +514,7 @@ static const njs_object_prop_t njs_math_object_properties[] = { .type = NJS_PROPERTY, .name = njs_string("ceil"), - .value = njs_native_function(njs_object_math_ceil, 1), + .value = njs_native_function2(njs_object_math_func, 1, NJS_MATH_CEIL), .writable = 1, .configurable = 1, }, @@ -1130,7 +522,7 @@ static const njs_object_prop_t njs_math_object_properties[] = { .type = NJS_PROPERTY, .name = njs_string("clz32"), - .value = njs_native_function(njs_object_math_clz32, 1), + .value = njs_native_function2(njs_object_math_func, 1, NJS_MATH_CLZ32), .writable = 1, .configurable = 1, }, @@ -1138,7 +530,7 @@ static const njs_object_prop_t njs_math_object_properties[] = { .type = NJS_PROPERTY, .name = njs_string("cos"), - .value = njs_native_function(njs_object_math_cos, 1), + .value = njs_native_function2(njs_object_math_func, 1, NJS_MATH_COS), .writable = 1, .configurable = 1, }, @@ -1146,7 +538,7 @@ static const njs_object_prop_t njs_math_object_properties[] = { .type = NJS_PROPERTY, .name = njs_string("cosh"), - .value = njs_native_function(njs_object_math_cosh, 1), + .value = njs_native_function2(njs_object_math_func, 1, NJS_MATH_COSH), .writable = 1, .configurable = 1, }, @@ -1154,7 +546,7 @@ static const njs_object_prop_t njs_math_object_properties[] = { .type = NJS_PROPERTY, .name = njs_string("exp"), - .value = njs_native_function(njs_object_math_exp, 1), + .value = njs_native_function2(njs_object_math_func, 1, NJS_MATH_EXP), .writable = 1, .configurable = 1, }, @@ -1162,7 +554,7 @@ static const njs_object_prop_t njs_math_object_properties[] = { .type = NJS_PROPERTY, .name = njs_string("expm1"), - .value = njs_native_function(njs_object_math_expm1, 1), + .value = njs_native_function2(njs_object_math_func, 1, NJS_MATH_EXPM1), .writable = 1, .configurable = 1, }, @@ -1170,7 +562,7 @@ static const njs_object_prop_t njs_math_object_properties[] = { .type = NJS_PROPERTY, .name = njs_string("floor"), - .value = njs_native_function(njs_object_math_floor, 1), + .value = njs_native_function2(njs_object_math_func, 1, NJS_MATH_FLOOR), .writable = 1, .configurable = 1, }, @@ -1178,7 +570,7 @@ static const njs_object_prop_t njs_math_object_properties[] = { .type = NJS_PROPERTY, .name = njs_string("fround"), - .value = njs_native_function(njs_object_math_fround, 1), + .value = njs_native_function2(njs_object_math_func, 1, NJS_MATH_FROUND), .writable = 1, .configurable = 1, }, @@ -1194,7 +586,7 @@ static const njs_object_prop_t njs_math_object_properties[] = { .type = NJS_PROPERTY, .name = njs_string("imul"), - .value = njs_native_function(njs_object_math_imul, 2), + .value = njs_native_function2(njs_object_math_func, 2, NJS_MATH_IMUL), .writable = 1, .configurable = 1, }, @@ -1202,7 +594,7 @@ static const njs_object_prop_t njs_math_object_properties[] = { .type = NJS_PROPERTY, .name = njs_string("log"), - .value = njs_native_function(njs_object_math_log, 1), + .value = njs_native_function2(njs_object_math_func, 1, NJS_MATH_LOG), .writable = 1, .configurable = 1, }, @@ -1210,7 +602,7 @@ static const njs_object_prop_t njs_math_object_properties[] = { .type = NJS_PROPERTY, .name = njs_string("log10"), - .value = njs_native_function(njs_object_math_log10, 1), + .value = njs_native_function2(njs_object_math_func, 1, NJS_MATH_LOG10), .writable = 1, .configurable = 1, }, @@ -1218,7 +610,7 @@ static const njs_object_prop_t njs_math_object_properties[] = { .type = NJS_PROPERTY, .name = njs_string("log1p"), - .value = njs_native_function(njs_object_math_log1p, 1), + .value = njs_native_function2(njs_object_math_func, 1, NJS_MATH_LOG1P), .writable = 1, .configurable = 1, }, @@ -1226,7 +618,7 @@ static const njs_object_prop_t njs_math_object_properties[] = { .type = NJS_PROPERTY, .name = njs_string("log2"), - .value = njs_native_function(njs_object_math_log2, 1), + .value = njs_native_function2(njs_object_math_func, 1, NJS_MATH_LOG2), .writable = 1, .configurable = 1, }, @@ -1250,7 +642,7 @@ static const njs_object_prop_t njs_math_object_properties[] = { .type = NJS_PROPERTY, .name = njs_string("pow"), - .value = njs_native_function(njs_object_math_pow, 2), + .value = njs_native_function2(njs_object_math_func, 2, NJS_MATH_POW), .writable = 1, .configurable = 1, }, @@ -1266,7 +658,7 @@ static const njs_object_prop_t njs_math_object_properties[] = { .type = NJS_PROPERTY, .name = njs_string("round"), - .value = njs_native_function(njs_object_math_round, 1), + .value = njs_native_function2(njs_object_math_func, 1, NJS_MATH_ROUND), .writable = 1, .configurable = 1, }, @@ -1274,7 +666,7 @@ static const njs_object_prop_t njs_math_object_properties[] = { .type = NJS_PROPERTY, .name = njs_string("sign"), - .value = njs_native_function(njs_object_math_sign, 1), + .value = njs_native_function2(njs_object_math_func, 1, NJS_MATH_SIGN), .writable = 1, .configurable = 1, }, @@ -1282,7 +674,7 @@ static const njs_object_prop_t njs_math_object_properties[] = { .type = NJS_PROPERTY, .name = njs_string("sin"), - .value = njs_native_function(njs_object_math_sin, 1), + .value = njs_native_function2(njs_object_math_func, 1, NJS_MATH_SIN), .writable = 1, .configurable = 1, }, @@ -1290,7 +682,7 @@ static const njs_object_prop_t njs_math_object_properties[] = { .type = NJS_PROPERTY, .name = njs_string("sinh"), - .value = njs_native_function(njs_object_math_sinh, 1), + .value = njs_native_function2(njs_object_math_func, 1, NJS_MATH_SINH), .writable = 1, .configurable = 1, }, @@ -1298,7 +690,7 @@ static const njs_object_prop_t njs_math_object_properties[] = { .type = NJS_PROPERTY, .name = njs_string("sqrt"), - .value = njs_native_function(njs_object_math_sqrt, 1), + .value = njs_native_function2(njs_object_math_func, 1, NJS_MATH_SQRT), .writable = 1, .configurable = 1, }, @@ -1306,7 +698,7 @@ static const njs_object_prop_t njs_math_object_properties[] = { .type = NJS_PROPERTY, .name = njs_string("tan"), - .value = njs_native_function(njs_object_math_tan, 1), + .value = njs_native_function2(njs_object_math_func, 1, NJS_MATH_TAN), .writable = 1, .configurable = 1, }, @@ -1314,7 +706,7 @@ static const njs_object_prop_t njs_math_object_properties[] = { .type = NJS_PROPERTY, .name = njs_string("tanh"), - .value = njs_native_function(njs_object_math_tanh, 1), + .value = njs_native_function2(njs_object_math_func, 1, NJS_MATH_TANH), .writable = 1, .configurable = 1, }, @@ -1322,7 +714,7 @@ static const njs_object_prop_t njs_math_object_properties[] = { .type = NJS_PROPERTY, .name = njs_string("trunc"), - .value = njs_native_function(njs_object_math_trunc, 1), + .value = njs_native_function2(njs_object_math_func, 1, NJS_MATH_TRUNC), .writable = 1, .configurable = 1, }, diff --git a/src/njs_string.c b/src/njs_string.c index 59cc751d..673bd4a2 100644 --- a/src/njs_string.c +++ b/src/njs_string.c @@ -68,12 +68,6 @@ static njs_int_t njs_string_bytes_from_array_like(njs_vm_t *vm, njs_value_t *value); static njs_int_t njs_string_bytes_from_string(njs_vm_t *vm, const njs_value_t *string, const njs_value_t *encoding); -static njs_int_t njs_string_starts_or_ends_with(njs_vm_t *vm, njs_value_t *args, - njs_uint_t nargs, njs_bool_t starts); -static njs_int_t njs_string_trim(njs_vm_t *vm, njs_value_t *value, - njs_uint_t mode); -static njs_int_t njs_string_prototype_pad(njs_vm_t *vm, njs_value_t *args, - njs_uint_t nargs, njs_bool_t pad_start); static njs_int_t njs_string_match_multiple(njs_vm_t *vm, njs_value_t *args, njs_regexp_pattern_t *pattern); static njs_int_t njs_string_split_part_add(njs_vm_t *vm, njs_array_t *array, @@ -2303,24 +2297,8 @@ done: static njs_int_t -njs_string_prototype_starts_with(njs_vm_t *vm, njs_value_t *args, - njs_uint_t nargs, njs_index_t unused) -{ - return njs_string_starts_or_ends_with(vm, args, nargs, 1); -} - - -static njs_int_t -njs_string_prototype_ends_with(njs_vm_t *vm, njs_value_t *args, - njs_uint_t nargs, njs_index_t unused) -{ - return njs_string_starts_or_ends_with(vm, args, nargs, 0); -} - - -static njs_int_t -njs_string_starts_or_ends_with(njs_vm_t *vm, njs_value_t *args, - njs_uint_t nargs, njs_bool_t starts) +njs_string_prototype_starts_or_ends_with(njs_vm_t *vm, njs_value_t *args, + njs_uint_t nargs, njs_index_t starts) { int64_t index, length, search_length; njs_int_t ret; @@ -2671,57 +2649,20 @@ njs_string_prototype_to_upper_case(njs_vm_t *vm, njs_value_t *args, static njs_int_t njs_string_prototype_trim(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_index_t unused) -{ - njs_int_t ret; - - ret = njs_string_object_validate(vm, njs_arg(args, nargs, 0)); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - - return njs_string_trim(vm, njs_argument(args, 0), - NJS_TRIM_START|NJS_TRIM_END); -} - - -static njs_int_t -njs_string_prototype_trim_start(njs_vm_t *vm, njs_value_t *args, - njs_uint_t nargs, njs_index_t unused) + njs_index_t mode) { - njs_int_t ret; - - ret = njs_string_object_validate(vm, njs_arg(args, nargs, 0)); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - - return njs_string_trim(vm, njs_argument(args, 0), NJS_TRIM_START); -} - - -static njs_int_t -njs_string_prototype_trim_end(njs_vm_t *vm, njs_value_t *args, - njs_uint_t nargs, njs_index_t unused) -{ - njs_int_t ret; + uint32_t u, trim, length; + njs_int_t ret; + njs_value_t *value; + const u_char *p, *prev, *start, *end; + njs_string_prop_t string; - ret = njs_string_object_validate(vm, njs_arg(args, nargs, 0)); + value = njs_argument(args, 0); + ret = njs_string_object_validate(vm, value); if (njs_slow_path(ret != NJS_OK)) { return ret; } - return njs_string_trim(vm, njs_argument(args, 0), NJS_TRIM_END); -} - - -static njs_int_t -njs_string_trim(njs_vm_t *vm, njs_value_t *value, njs_uint_t mode) -{ - uint32_t u, trim, length; - const u_char *p, *prev, *start, *end; - njs_string_prop_t string; - trim = 0; njs_string_prop(&string, value); @@ -2885,25 +2826,9 @@ njs_string_prototype_repeat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } -static njs_int_t -njs_string_prototype_pad_start(njs_vm_t *vm, njs_value_t *args, - njs_uint_t nargs, njs_index_t unused) -{ - return njs_string_prototype_pad(vm, args, nargs, 1); -} - - -static njs_int_t -njs_string_prototype_pad_end(njs_vm_t *vm, njs_value_t *args, - njs_uint_t nargs, njs_index_t unused) -{ - return njs_string_prototype_pad(vm, args, nargs, 0); -} - - static njs_int_t njs_string_prototype_pad(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, - njs_bool_t pad_start) + njs_index_t pad_start) { u_char *p, *start; size_t padding, trunc, new_size; @@ -4629,7 +4554,8 @@ static const njs_object_prop_t njs_string_prototype_properties[] = { .type = NJS_PROPERTY, .name = njs_string("startsWith"), - .value = njs_native_function(njs_string_prototype_starts_with, 1), + .value = njs_native_function2(njs_string_prototype_starts_or_ends_with, + 1, 1), .writable = 1, .configurable = 1, }, @@ -4637,7 +4563,8 @@ static const njs_object_prop_t njs_string_prototype_properties[] = { .type = NJS_PROPERTY, .name = njs_string("endsWith"), - .value = njs_native_function(njs_string_prototype_ends_with, 1), + .value = njs_native_function2(njs_string_prototype_starts_or_ends_with, + 1, 0), .writable = 1, .configurable = 1, }, @@ -4661,7 +4588,8 @@ static const njs_object_prop_t njs_string_prototype_properties[] = { .type = NJS_PROPERTY, .name = njs_string("trim"), - .value = njs_native_function(njs_string_prototype_trim, 0), + .value = njs_native_function2(njs_string_prototype_trim, 0, + NJS_TRIM_START | NJS_TRIM_END), .writable = 1, .configurable = 1, }, @@ -4669,7 +4597,8 @@ static const njs_object_prop_t njs_string_prototype_properties[] = { .type = NJS_PROPERTY, .name = njs_string("trimStart"), - .value = njs_native_function(njs_string_prototype_trim_start, 0), + .value = njs_native_function2(njs_string_prototype_trim, 0, + NJS_TRIM_START), .writable = 1, .configurable = 1, }, @@ -4677,7 +4606,8 @@ static const njs_object_prop_t njs_string_prototype_properties[] = { .type = NJS_PROPERTY, .name = njs_string("trimEnd"), - .value = njs_native_function(njs_string_prototype_trim_end, 0), + .value = njs_native_function2(njs_string_prototype_trim, 0, + NJS_TRIM_END), .writable = 1, .configurable = 1, }, @@ -4693,7 +4623,7 @@ static const njs_object_prop_t njs_string_prototype_properties[] = { .type = NJS_PROPERTY, .name = njs_string("padStart"), - .value = njs_native_function(njs_string_prototype_pad_start, 1), + .value = njs_native_function2(njs_string_prototype_pad, 1, 1), .writable = 1, .configurable = 1, }, @@ -4701,7 +4631,7 @@ static const njs_object_prop_t njs_string_prototype_properties[] = { .type = NJS_PROPERTY, .name = njs_string("padEnd"), - .value = njs_native_function(njs_string_prototype_pad_end, 1), + .value = njs_native_function2(njs_string_prototype_pad, 1, 0), .writable = 1, .configurable = 1, },