]> git.kaiwu.me - njs.git/commitdiff
Simplified code using magic arguments introduced in 6df48738a043.
authorDmitry Volyntsev <xeioex@nginx.com>
Mon, 17 Feb 2020 13:18:38 +0000 (16:18 +0300)
committerDmitry Volyntsev <xeioex@nginx.com>
Mon, 17 Feb 2020 13:18:38 +0000 (16:18 +0300)
This reduces code duplication and the binary size.

src/njs_error.c
src/njs_math.c
src/njs_string.c

index 60af3c5f592474e331dd23582554daea10f0541a..97fe51a83471bcebeecfc0e4ce81b67b2e7096d8 100644 (file)
@@ -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 } },
index 01bada64388c19d66b1c2c70574038ffcfdc8bcc..1b2dd300564d52ba39efbf4fea8db9b50fae4aca 100644 (file)
 #include <njs_main.h>
 
 
-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,
     },
index 59cc751da108ae8c3fddfe98ee55c2ebc1119dce..673bd4a2e865b0b65f2c4816c0907f08c6bda833 100644 (file)
@@ -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,
     },