]> git.kaiwu.me - njs.git/commitdiff
Removed argument prototypes for built-in functions.
authorAlexander Borisov <alexander.borisov@nginx.com>
Tue, 22 Oct 2019 16:58:52 +0000 (19:58 +0300)
committerAlexander Borisov <alexander.borisov@nginx.com>
Tue, 22 Oct 2019 16:58:52 +0000 (19:58 +0300)
Many JS functions do not have fixed prototypes as in C. For example
String.prototype.replace() accepts RegExp or String as the first argument.

21 files changed:
src/njs_array.c
src/njs_boolean.c
src/njs_builtin.c
src/njs_crypto.c
src/njs_date.c
src/njs_error.c
src/njs_fs.c
src/njs_function.c
src/njs_function.h
src/njs_json.c
src/njs_math.c
src/njs_module.c
src/njs_number.c
src/njs_number.h
src/njs_object.c
src/njs_regexp.c
src/njs_string.c
src/njs_value.c
src/njs_value.h
src/test/njs_interactive_test.c
src/test/njs_unit_test.c

index 6f01903268922e015187a0def4ca3d7f17bb3734..8eb333cb5936fe8489ca812be0ab714e6eec66ff 100644 (file)
@@ -304,7 +304,7 @@ static const njs_object_prop_t  njs_array_constructor_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("isArray"),
-        .value = njs_native_function(njs_array_is_array, 1, 0),
+        .value = njs_native_function(njs_array_is_array, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -314,7 +314,7 @@ static const njs_object_prop_t  njs_array_constructor_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("of"),
-        .value = njs_native_function(njs_array_of, 0, 0),
+        .value = njs_native_function(njs_array_of, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -423,6 +423,11 @@ njs_array_prototype_slice(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     uint32_t   object_length;
     njs_int_t  ret;
 
+    if (njs_slow_path(njs_is_null_or_undefined(njs_arg(args, nargs, 0)))) {
+        njs_type_error(vm, "cannot convert undefined to object");
+        return NJS_ERROR;
+    }
+
     ret = njs_object_length(vm, njs_arg(args, nargs, 0), &object_length);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return ret;
@@ -933,11 +938,17 @@ static njs_int_t
 njs_array_prototype_splice(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
+    int64_t      n, start, length, items, delta, delete;
     njs_int_t    ret;
-    njs_int_t    n, start, length, items, delta, delete;
     njs_uint_t   i;
+    njs_value_t  *value;
     njs_array_t  *array, *deleted;
 
+    if (njs_slow_path(njs_is_null_or_undefined(njs_arg(args, nargs, 0)))) {
+        njs_type_error(vm, "cannot convert undefined to object");
+        return NJS_ERROR;
+    }
+
     array = NULL;
     start = 0;
     delete = 0;
@@ -947,7 +958,17 @@ njs_array_prototype_splice(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         length = array->length;
 
         if (nargs > 1) {
-            start = njs_number(&args[1]);
+            value = njs_argument(args, 1);
+
+            if (njs_slow_path(!njs_is_number(value))) {
+                ret = njs_value_to_integer(vm, value, &start);
+                if (njs_slow_path(ret != NJS_OK)) {
+                    return ret;
+                }
+
+            } else {
+                start = njs_number_to_integer(njs_number(value));
+            }
 
             if (start < 0) {
                 start += length;
@@ -963,7 +984,17 @@ njs_array_prototype_splice(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             delete = length - start;
 
             if (nargs > 2) {
-                n = njs_number(&args[2]);
+                value = njs_argument(args, 2);
+
+                if (njs_slow_path(!njs_is_number(value))) {
+                    ret = njs_value_to_integer(vm, value, &n);
+                    if (njs_slow_path(ret != NJS_OK)) {
+                        return ret;
+                    }
+
+                } else {
+                    n = njs_number_to_integer(njs_number(value));
+                }
 
                 if (n < 0) {
                     delete = 0;
@@ -988,12 +1019,7 @@ njs_array_prototype_splice(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             deleted->start[i] = array->start[n];
         }
 
-        items = nargs - 3;
-
-        if (items < 0) {
-            items = 0;
-        }
-
+        items = (nargs > 3) ? nargs - 3: 0;
         delta = items - delete;
 
         if (delta != 0) {
@@ -1037,6 +1063,11 @@ njs_array_prototype_reverse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_value_t  value;
     njs_array_t  *array;
 
+    if (njs_slow_path(njs_is_null_or_undefined(njs_arg(args, nargs, 0)))) {
+        njs_type_error(vm, "cannot convert undefined to object");
+        return NJS_ERROR;
+    }
+
     if (njs_is_array(&args[0])) {
         array = njs_array(&args[0]);
         length = array->length;
@@ -1100,6 +1131,18 @@ njs_array_prototype_join(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_value_t        *value, *values;
     njs_string_prop_t  separator, string;
 
+    if (njs_slow_path(njs_is_null_or_undefined(njs_arg(args, nargs, 0)))) {
+        njs_type_error(vm, "cannot convert undefined to object");
+        return NJS_ERROR;
+    }
+
+    if (nargs > 1 && !njs_is_string(&args[1])) {
+        ret = njs_value_to_string(vm, &args[1], &args[1]);
+        if (njs_slow_path(ret != NJS_OK)) {
+            return ret;
+        }
+    }
+
     if (!njs_is_array(&args[0]) || njs_array_len(&args[0]) == 0) {
         vm->retval = njs_string_empty;
         return NJS_OK;
@@ -2614,7 +2657,6 @@ njs_array_string_sort(njs_vm_t *vm, njs_value_t *args,
 static const njs_function_t  njs_array_string_sort_function = {
     .object = { .type = NJS_FUNCTION, .shared = 1, .extensible = 1 },
     .native = 1,
-    .args_types = { NJS_SKIP_ARG, NJS_STRING_ARG, NJS_STRING_ARG },
     .args_offset = 1,
     .u.native = njs_array_string_sort,
 };
@@ -2735,8 +2777,7 @@ static const njs_object_prop_t  njs_array_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("slice"),
-        .value = njs_native_function(njs_array_prototype_slice, 2,
-                     NJS_OBJECT_ARG, NJS_INTEGER_ARG, NJS_INTEGER_ARG),
+        .value = njs_native_function(njs_array_prototype_slice, 2),
         .writable = 1,
         .configurable = 1,
     },
@@ -2744,7 +2785,7 @@ static const njs_object_prop_t  njs_array_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("push"),
-        .value = njs_native_function(njs_array_prototype_push, 1, 0),
+        .value = njs_native_function(njs_array_prototype_push, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -2752,7 +2793,7 @@ static const njs_object_prop_t  njs_array_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("pop"),
-        .value = njs_native_function(njs_array_prototype_pop, 0, 0),
+        .value = njs_native_function(njs_array_prototype_pop, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -2760,7 +2801,7 @@ static const njs_object_prop_t  njs_array_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("unshift"),
-        .value = njs_native_function(njs_array_prototype_unshift, 1, 0),
+        .value = njs_native_function(njs_array_prototype_unshift, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -2768,7 +2809,7 @@ static const njs_object_prop_t  njs_array_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("shift"),
-        .value = njs_native_function(njs_array_prototype_shift, 0, 0),
+        .value = njs_native_function(njs_array_prototype_shift, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -2776,8 +2817,7 @@ static const njs_object_prop_t  njs_array_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("splice"),
-        .value = njs_native_function(njs_array_prototype_splice, 2,
-                    NJS_OBJECT_ARG, NJS_INTEGER_ARG, NJS_INTEGER_ARG),
+        .value = njs_native_function(njs_array_prototype_splice, 2),
         .writable = 1,
         .configurable = 1,
     },
@@ -2785,8 +2825,7 @@ static const njs_object_prop_t  njs_array_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("reverse"),
-        .value = njs_native_function(njs_array_prototype_reverse, 0,
-                                     NJS_OBJECT_ARG),
+        .value = njs_native_function(njs_array_prototype_reverse, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -2794,7 +2833,7 @@ static const njs_object_prop_t  njs_array_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("toString"),
-        .value = njs_native_function(njs_array_prototype_to_string, 0, 0),
+        .value = njs_native_function(njs_array_prototype_to_string, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -2802,8 +2841,7 @@ static const njs_object_prop_t  njs_array_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("join"),
-        .value = njs_native_function(njs_array_prototype_join, 1,
-                     NJS_OBJECT_ARG, NJS_STRING_ARG),
+        .value = njs_native_function(njs_array_prototype_join, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -2811,7 +2849,7 @@ static const njs_object_prop_t  njs_array_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("concat"),
-        .value = njs_native_function(njs_array_prototype_concat, 1, 0),
+        .value = njs_native_function(njs_array_prototype_concat, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -2819,8 +2857,7 @@ static const njs_object_prop_t  njs_array_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("indexOf"),
-        .value = njs_native_function(njs_array_prototype_index_of, 1,
-                     NJS_OBJECT_ARG, NJS_SKIP_ARG, NJS_INTEGER_ARG),
+        .value = njs_native_function(njs_array_prototype_index_of, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -2828,8 +2865,7 @@ static const njs_object_prop_t  njs_array_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("lastIndexOf"),
-        .value = njs_native_function(njs_array_prototype_last_index_of, 1,
-                     NJS_OBJECT_ARG, NJS_SKIP_ARG, NJS_INTEGER_ARG),
+        .value = njs_native_function(njs_array_prototype_last_index_of, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -2838,8 +2874,7 @@ static const njs_object_prop_t  njs_array_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("includes"),
-        .value = njs_native_function(njs_array_prototype_includes, 1,
-                     NJS_OBJECT_ARG, NJS_SKIP_ARG, NJS_INTEGER_ARG),
+        .value = njs_native_function(njs_array_prototype_includes, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -2847,7 +2882,7 @@ static const njs_object_prop_t  njs_array_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("forEach"),
-        .value = njs_native_function(njs_array_prototype_for_each, 1, 0),
+        .value = njs_native_function(njs_array_prototype_for_each, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -2855,7 +2890,7 @@ static const njs_object_prop_t  njs_array_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("some"),
-        .value = njs_native_function(njs_array_prototype_some, 1, 0),
+        .value = njs_native_function(njs_array_prototype_some, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -2863,7 +2898,7 @@ static const njs_object_prop_t  njs_array_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("every"),
-        .value = njs_native_function(njs_array_prototype_every, 1, 0),
+        .value = njs_native_function(njs_array_prototype_every, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -2872,9 +2907,7 @@ static const njs_object_prop_t  njs_array_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("fill"),
-        .value = njs_native_function(njs_array_prototype_fill, 1,
-                     NJS_OBJECT_ARG, NJS_SKIP_ARG, NJS_NUMBER_ARG,
-                     NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_array_prototype_fill, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -2882,7 +2915,7 @@ static const njs_object_prop_t  njs_array_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("filter"),
-        .value = njs_native_function(njs_array_prototype_filter, 1, 0),
+        .value = njs_native_function(njs_array_prototype_filter, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -2891,7 +2924,7 @@ static const njs_object_prop_t  njs_array_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("find"),
-        .value = njs_native_function(njs_array_prototype_find, 1, 0),
+        .value = njs_native_function(njs_array_prototype_find, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -2900,7 +2933,7 @@ static const njs_object_prop_t  njs_array_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("findIndex"),
-        .value = njs_native_function(njs_array_prototype_find_index, 1, 0),
+        .value = njs_native_function(njs_array_prototype_find_index, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -2908,7 +2941,7 @@ static const njs_object_prop_t  njs_array_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("map"),
-        .value = njs_native_function(njs_array_prototype_map, 1, 0),
+        .value = njs_native_function(njs_array_prototype_map, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -2916,7 +2949,7 @@ static const njs_object_prop_t  njs_array_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("reduce"),
-        .value = njs_native_function(njs_array_prototype_reduce, 1, 0),
+        .value = njs_native_function(njs_array_prototype_reduce, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -2924,7 +2957,7 @@ static const njs_object_prop_t  njs_array_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("reduceRight"),
-        .value = njs_native_function(njs_array_prototype_reduce_right, 1, 0),
+        .value = njs_native_function(njs_array_prototype_reduce_right, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -2932,7 +2965,7 @@ static const njs_object_prop_t  njs_array_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("sort"),
-        .value = njs_native_function(njs_array_prototype_sort, 1, 0),
+        .value = njs_native_function(njs_array_prototype_sort, 1),
         .writable = 1,
         .configurable = 1,
     },
index 651392360dfaa220d6eb70c64e9ae560a5156fb4..79c54beddb760184f885965c9e8d0891eb713202 100644 (file)
@@ -145,7 +145,7 @@ static const njs_object_prop_t  njs_boolean_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("valueOf"),
-        .value = njs_native_function(njs_boolean_prototype_value_of, 0, 0),
+        .value = njs_native_function(njs_boolean_prototype_value_of, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -153,7 +153,7 @@ static const njs_object_prop_t  njs_boolean_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("toString"),
-        .value = njs_native_function(njs_boolean_prototype_to_string, 0, 0),
+        .value = njs_native_function(njs_boolean_prototype_to_string, 0),
         .writable = 1,
         .configurable = 1,
     },
index 8835b03d059ddec73abec6153af80194bff07b35..6d3438c687409858e255513fca6ab9f8008b8bc3 100644 (file)
@@ -11,7 +11,6 @@
 
 typedef struct {
     njs_function_native_t  native;
-    uint8_t                args_types[NJS_ARGS_TYPES_MAX];
 } njs_function_init_t;
 
 
@@ -95,29 +94,25 @@ const njs_object_init_t  *njs_constructor_init[] = {
 
 const njs_function_init_t  njs_native_constructors[] = {
     /* SunC does not allow empty array initialization. */
-    { njs_object_constructor,     { 0 } },
-    { njs_array_constructor,      { 0 } },
-    { njs_boolean_constructor,    { 0 } },
-    { njs_number_constructor,     { NJS_SKIP_ARG, NJS_NUMBER_ARG } },
-    { njs_string_constructor,     { NJS_SKIP_ARG, NJS_STRING_ARG } },
-    { njs_function_constructor,   { 0 } },
-    { njs_regexp_constructor,     { 0 } },
-    { njs_date_constructor,       { 0 } },
-    { njs_hash_constructor,       { NJS_SKIP_ARG, NJS_STRING_ARG } },
-    { njs_hmac_constructor,       { NJS_SKIP_ARG, NJS_STRING_ARG,
-                                    NJS_STRING_ARG } },
-    { njs_error_constructor,      { NJS_SKIP_ARG, NJS_STRING_ARG } },
-    { njs_eval_error_constructor, { NJS_SKIP_ARG, NJS_STRING_ARG } },
-    { njs_internal_error_constructor,
-      { NJS_SKIP_ARG, NJS_STRING_ARG } },
-    { njs_range_error_constructor,
-      { NJS_SKIP_ARG, NJS_STRING_ARG } },
-    { njs_reference_error_constructor,  { NJS_SKIP_ARG, NJS_STRING_ARG } },
-    { njs_syntax_error_constructor,
-      { NJS_SKIP_ARG, NJS_STRING_ARG } },
-    { njs_type_error_constructor, { NJS_SKIP_ARG, NJS_STRING_ARG } },
-    { njs_uri_error_constructor,  { NJS_SKIP_ARG, NJS_STRING_ARG } },
-    { njs_memory_error_constructor,  { NJS_SKIP_ARG, NJS_STRING_ARG } },
+    { njs_object_constructor },
+    { njs_array_constructor },
+    { njs_boolean_constructor },
+    { njs_number_constructor },
+    { njs_string_constructor },
+    { njs_function_constructor},
+    { njs_regexp_constructor },
+    { njs_date_constructor },
+    { njs_hash_constructor },
+    { njs_hmac_constructor },
+    { njs_error_constructor },
+    { njs_eval_error_constructor },
+    { njs_internal_error_constructor },
+    { njs_range_error_constructor },
+    { njs_reference_error_constructor },
+    { njs_syntax_error_constructor },
+    { njs_type_error_constructor },
+    { njs_uri_error_constructor },
+    { njs_memory_error_constructor },
 };
 
 
@@ -331,8 +326,6 @@ njs_builtin_objects_create(njs_vm_t *vm)
 
         func->u.native = f->native;
 
-        memcpy(func->args_types, f->args_types, NJS_ARGS_TYPES_MAX);
-
         ret = njs_object_hash_init(vm, &func->object.shared_hash, obj);
         if (njs_slow_path(ret != NJS_OK)) {
             return NJS_ERROR;
@@ -1038,8 +1031,7 @@ static const njs_object_prop_t  njs_global_this_object_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("isFinite"),
-        .value = njs_native_function(njs_number_is_finite, 1,
-                                     NJS_SKIP_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_number_global_is_finite, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1047,8 +1039,7 @@ static const njs_object_prop_t  njs_global_this_object_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("isNaN"),
-        .value = njs_native_function(njs_number_global_is_nan, 1,
-                                     NJS_SKIP_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_number_global_is_nan, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1056,8 +1047,7 @@ static const njs_object_prop_t  njs_global_this_object_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("parseFloat"),
-        .value = njs_native_function(njs_number_parse_float, 1,
-                                     NJS_SKIP_ARG, NJS_STRING_ARG),
+        .value = njs_native_function(njs_number_parse_float, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1065,8 +1055,7 @@ static const njs_object_prop_t  njs_global_this_object_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("parseInt"),
-        .value = njs_native_function(njs_number_parse_int, 2,
-                     NJS_SKIP_ARG, NJS_STRING_ARG, NJS_INTEGER_ARG),
+        .value = njs_native_function(njs_number_parse_int, 2),
         .writable = 1,
         .configurable = 1,
     },
@@ -1074,7 +1063,7 @@ static const njs_object_prop_t  njs_global_this_object_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("toString"),
-        .value = njs_native_function(njs_object_prototype_to_string, 0, 0),
+        .value = njs_native_function(njs_object_prototype_to_string, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -1082,8 +1071,7 @@ static const njs_object_prop_t  njs_global_this_object_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("encodeURI"),
-        .value = njs_native_function(njs_string_encode_uri, 1,
-                                     NJS_SKIP_ARG, NJS_STRING_ARG),
+        .value = njs_native_function(njs_string_encode_uri, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1091,8 +1079,7 @@ static const njs_object_prop_t  njs_global_this_object_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_long_string("encodeURIComponent"),
-        .value = njs_native_function(njs_string_encode_uri_component, 1,
-                                     NJS_SKIP_ARG, NJS_STRING_ARG),
+        .value = njs_native_function(njs_string_encode_uri_component, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1100,8 +1087,7 @@ static const njs_object_prop_t  njs_global_this_object_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("decodeURI"),
-        .value = njs_native_function(njs_string_decode_uri, 1,
-                                     NJS_SKIP_ARG, NJS_STRING_ARG),
+        .value = njs_native_function(njs_string_decode_uri, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1109,8 +1095,7 @@ static const njs_object_prop_t  njs_global_this_object_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_long_string("decodeURIComponent"),
-        .value = njs_native_function(njs_string_decode_uri_component, 1,
-                                     NJS_SKIP_ARG, NJS_STRING_ARG),
+        .value = njs_native_function(njs_string_decode_uri_component, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1118,7 +1103,7 @@ static const njs_object_prop_t  njs_global_this_object_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("eval"),
-        .value = njs_native_function(njs_eval_function, 1, 0),
+        .value = njs_native_function(njs_eval_function, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1126,9 +1111,7 @@ static const njs_object_prop_t  njs_global_this_object_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("setTimeout"),
-        .value = njs_native_function(njs_set_timeout, 2,
-                                     NJS_SKIP_ARG, NJS_FUNCTION_ARG,
-                                     NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_set_timeout, 2),
         .writable = 1,
         .configurable = 1,
     },
@@ -1136,8 +1119,7 @@ static const njs_object_prop_t  njs_global_this_object_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("setImmediate"),
-        .value = njs_native_function(njs_set_immediate, 4,
-                                     NJS_SKIP_ARG, NJS_FUNCTION_ARG),
+        .value = njs_native_function(njs_set_immediate, 4),
         .writable = 1,
         .configurable = 1,
     },
@@ -1145,8 +1127,7 @@ static const njs_object_prop_t  njs_global_this_object_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("clearTimeout"),
-        .value = njs_native_function(njs_clear_timeout, 1,
-                                     NJS_SKIP_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_clear_timeout, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1154,8 +1135,7 @@ static const njs_object_prop_t  njs_global_this_object_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("require"),
-        .value = njs_native_function(njs_module_require, 1,
-                                     NJS_SKIP_ARG, NJS_STRING_ARG),
+        .value = njs_native_function(njs_module_require, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1183,8 +1163,7 @@ static const njs_object_prop_t  njs_njs_object_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("dump"),
-        .value = njs_native_function(njs_dump_value, 0,
-                                    NJS_SKIP_ARG, NJS_SKIP_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_dump_value, 0),
         .configurable = 1,
     },
 };
index 2e79e5e02a60a5780c029a5febd91ffbd40c961c..1851a27a3d5c25ee03c4f3836d79d0701a1134bd 100644 (file)
@@ -323,7 +323,7 @@ static const njs_object_prop_t  njs_hash_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("toString"),
-        .value = njs_native_function(njs_hash_prototype_to_string, 0, 0),
+        .value = njs_native_function(njs_hash_prototype_to_string, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -331,8 +331,7 @@ static const njs_object_prop_t  njs_hash_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("update"),
-        .value = njs_native_function(njs_hash_prototype_update, 0,
-                                     NJS_OBJECT_ARG, NJS_SKIP_ARG),
+        .value = njs_native_function(njs_hash_prototype_update, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -340,8 +339,7 @@ static const njs_object_prop_t  njs_hash_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("digest"),
-        .value = njs_native_function(njs_hash_prototype_digest, 0,
-                                     NJS_OBJECT_ARG, NJS_SKIP_ARG),
+        .value = njs_native_function(njs_hash_prototype_digest, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -585,7 +583,7 @@ static const njs_object_prop_t  njs_hmac_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("toString"),
-        .value = njs_native_function(njs_hmac_prototype_to_string, 0, 0),
+        .value = njs_native_function(njs_hmac_prototype_to_string, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -593,8 +591,7 @@ static const njs_object_prop_t  njs_hmac_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("update"),
-        .value = njs_native_function(njs_hmac_prototype_update, 0,
-                                     NJS_OBJECT_ARG, NJS_SKIP_ARG),
+        .value = njs_native_function(njs_hmac_prototype_update, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -602,8 +599,7 @@ static const njs_object_prop_t  njs_hmac_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("digest"),
-        .value = njs_native_function(njs_hmac_prototype_digest, 0,
-                                     NJS_OBJECT_ARG, NJS_SKIP_ARG),
+        .value = njs_native_function(njs_hmac_prototype_digest, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -650,8 +646,7 @@ static const njs_object_prop_t  njs_crypto_object_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("createHash"),
-        .value = njs_native_function(njs_crypto_create_hash, 0,
-                                     NJS_SKIP_ARG),
+        .value = njs_native_function(njs_crypto_create_hash, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -659,8 +654,7 @@ static const njs_object_prop_t  njs_crypto_object_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("createHmac"),
-        .value = njs_native_function(njs_crypto_create_hmac, 0,
-                                     NJS_SKIP_ARG),
+        .value = njs_native_function(njs_crypto_create_hmac, 0),
         .writable = 1,
         .configurable = 1,
     },
index 379ae9c8567a900b89d5658167bcb4918c4b0cbb..8951590f19e529a42dab50212af5e4aa62856352 100644 (file)
@@ -389,9 +389,17 @@ static njs_int_t
 njs_date_parse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    double  time;
+    double     time;
+    njs_int_t  ret;
 
     if (nargs > 1) {
+        if (njs_slow_path(!njs_is_string(&args[1]))) {
+            ret = njs_value_to_string(vm, &args[1], &args[1]);
+            if (njs_slow_path(ret != NJS_OK)) {
+                return ret;
+            }
+        }
+
         time = njs_date_string_parse(&args[1]);
 
     } else {
@@ -1016,7 +1024,7 @@ static const njs_object_prop_t  njs_date_constructor_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("UTC"),
-        .value = njs_native_function(njs_date_utc, 7, 0),
+        .value = njs_native_function(njs_date_utc, 7),
         .writable = 1,
         .configurable = 1,
     },
@@ -1024,7 +1032,7 @@ static const njs_object_prop_t  njs_date_constructor_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("now"),
-        .value = njs_native_function(njs_date_now, 0, 0),
+        .value = njs_native_function(njs_date_now, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -1032,8 +1040,7 @@ static const njs_object_prop_t  njs_date_constructor_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("parse"),
-        .value = njs_native_function(njs_date_parse, 1,
-                                     NJS_SKIP_ARG, NJS_STRING_ARG),
+        .value = njs_native_function(njs_date_parse, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1051,6 +1058,13 @@ static njs_int_t
 njs_date_prototype_value_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
+    if (njs_slow_path(!njs_is_date(&args[0]))) {
+        njs_type_error(vm, "cannot convert %s to date",
+                       njs_type_string(args[0].type));
+
+        return NJS_ERROR;
+    }
+
     njs_set_number(&vm->retval, njs_date(&args[0])->time);
 
     return NJS_OK;
@@ -1061,6 +1075,13 @@ static njs_int_t
 njs_date_prototype_to_string(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
+    if (njs_slow_path(!njs_is_date(&args[0]))) {
+        njs_type_error(vm, "cannot convert %s to date",
+                       njs_type_string(args[0].type));
+
+        return NJS_ERROR;
+    }
+
     return njs_date_string(vm, "%a %b %d %Y %T GMT%z (%Z)",
                            njs_date(&args[0])->time);
 }
@@ -1070,6 +1091,13 @@ static njs_int_t
 njs_date_prototype_to_date_string(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused)
 {
+    if (njs_slow_path(!njs_is_date(&args[0]))) {
+        njs_type_error(vm, "cannot convert %s to date",
+                       njs_type_string(args[0].type));
+
+        return NJS_ERROR;
+    }
+
     return njs_date_string(vm, "%a %b %d %Y", njs_date(&args[0])->time);
 }
 
@@ -1078,6 +1106,13 @@ static njs_int_t
 njs_date_prototype_to_time_string(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused)
 {
+    if (njs_slow_path(!njs_is_date(&args[0]))) {
+        njs_type_error(vm, "cannot convert %s to date",
+                       njs_type_string(args[0].type));
+
+        return NJS_ERROR;
+    }
+
     return njs_date_string(vm, "%T GMT%z (%Z)", njs_date(&args[0])->time);
 }
 
@@ -1120,6 +1155,13 @@ njs_date_prototype_to_utc_string(njs_vm_t *vm, njs_value_t *args,
     static const char  *month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
                                     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
 
+    if (njs_slow_path(!njs_is_date(&args[0]))) {
+        njs_type_error(vm, "cannot convert %s to date",
+                       njs_type_string(args[0].type));
+
+        return NJS_ERROR;
+    }
+
     time = njs_date(&args[0])->time;
 
     if (!isnan(time)) {
@@ -1144,6 +1186,13 @@ static njs_int_t
 njs_date_prototype_to_iso_string(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused)
 {
+    if (njs_slow_path(!njs_is_date(&args[0]))) {
+        njs_type_error(vm, "cannot convert %s to date",
+                       njs_type_string(args[0].type));
+
+        return NJS_ERROR;
+    }
+
     return njs_date_to_string(vm, &vm->retval, &args[0]);
 }
 
@@ -1189,6 +1238,13 @@ njs_date_prototype_get_full_year(njs_vm_t *vm, njs_value_t *args,
     time_t     clock;
     struct tm  tm;
 
+    if (njs_slow_path(!njs_is_date(&args[0]))) {
+        njs_type_error(vm, "cannot convert %s to date",
+                       njs_type_string(args[0].type));
+
+        return NJS_ERROR;
+    }
+
     value = njs_date(&args[0])->time;
 
     if (njs_fast_path(!isnan(value))) {
@@ -1212,6 +1268,13 @@ njs_date_prototype_get_utc_full_year(njs_vm_t *vm, njs_value_t *args,
     time_t     clock;
     struct tm  tm;
 
+    if (njs_slow_path(!njs_is_date(&args[0]))) {
+        njs_type_error(vm, "cannot convert %s to date",
+                       njs_type_string(args[0].type));
+
+        return NJS_ERROR;
+    }
+
     value = njs_date(&args[0])->time;
 
     if (njs_fast_path(!isnan(value))) {
@@ -1235,6 +1298,13 @@ njs_date_prototype_get_month(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     time_t     clock;
     struct tm  tm;
 
+    if (njs_slow_path(!njs_is_date(&args[0]))) {
+        njs_type_error(vm, "cannot convert %s to date",
+                       njs_type_string(args[0].type));
+
+        return NJS_ERROR;
+    }
+
     value = njs_date(&args[0])->time;
 
     if (njs_fast_path(!isnan(value))) {
@@ -1258,6 +1328,13 @@ njs_date_prototype_get_utc_month(njs_vm_t *vm, njs_value_t *args,
     time_t     clock;
     struct tm  tm;
 
+    if (njs_slow_path(!njs_is_date(&args[0]))) {
+        njs_type_error(vm, "cannot convert %s to date",
+                       njs_type_string(args[0].type));
+
+        return NJS_ERROR;
+    }
+
     value = njs_date(&args[0])->time;
 
     if (njs_fast_path(!isnan(value))) {
@@ -1282,6 +1359,13 @@ njs_date_prototype_get_date(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     time_t     clock;
     struct tm  tm;
 
+    if (njs_slow_path(!njs_is_date(&args[0]))) {
+        njs_type_error(vm, "cannot convert %s to date",
+                       njs_type_string(args[0].type));
+
+        return NJS_ERROR;
+    }
+
     value = njs_date(&args[0])->time;
 
     if (njs_fast_path(!isnan(value))) {
@@ -1305,6 +1389,13 @@ njs_date_prototype_get_utc_date(njs_vm_t *vm, njs_value_t *args,
     time_t     clock;
     struct tm  tm;
 
+    if (njs_slow_path(!njs_is_date(&args[0]))) {
+        njs_type_error(vm, "cannot convert %s to date",
+                       njs_type_string(args[0].type));
+
+        return NJS_ERROR;
+    }
+
     value = njs_date(&args[0])->time;
 
     if (njs_fast_path(!isnan(value))) {
@@ -1328,6 +1419,13 @@ njs_date_prototype_get_day(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     time_t     clock;
     struct tm  tm;
 
+    if (njs_slow_path(!njs_is_date(&args[0]))) {
+        njs_type_error(vm, "cannot convert %s to date",
+                       njs_type_string(args[0].type));
+
+        return NJS_ERROR;
+    }
+
     value = njs_date(&args[0])->time;
 
     if (njs_fast_path(!isnan(value))) {
@@ -1351,6 +1449,13 @@ njs_date_prototype_get_utc_day(njs_vm_t *vm, njs_value_t *args,
     time_t     clock;
     struct tm  tm;
 
+    if (njs_slow_path(!njs_is_date(&args[0]))) {
+        njs_type_error(vm, "cannot convert %s to date",
+                       njs_type_string(args[0].type));
+
+        return NJS_ERROR;
+    }
+
     value = njs_date(&args[0])->time;
 
     if (njs_fast_path(!isnan(value))) {
@@ -1374,6 +1479,13 @@ njs_date_prototype_get_hours(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     time_t     clock;
     struct tm  tm;
 
+    if (njs_slow_path(!njs_is_date(&args[0]))) {
+        njs_type_error(vm, "cannot convert %s to date",
+                       njs_type_string(args[0].type));
+
+        return NJS_ERROR;
+    }
+
     value = njs_date(&args[0])->time;
 
     if (njs_fast_path(!isnan(value))) {
@@ -1398,6 +1510,13 @@ njs_date_prototype_get_utc_hours(njs_vm_t *vm, njs_value_t *args,
     time_t     clock;
     struct tm  tm;
 
+    if (njs_slow_path(!njs_is_date(&args[0]))) {
+        njs_type_error(vm, "cannot convert %s to date",
+                       njs_type_string(args[0].type));
+
+        return NJS_ERROR;
+    }
+
     value = njs_date(&args[0])->time;
 
     if (njs_fast_path(!isnan(value))) {
@@ -1421,6 +1540,13 @@ njs_date_prototype_get_minutes(njs_vm_t *vm, njs_value_t *args,
     time_t     clock;
     struct tm  tm;
 
+    if (njs_slow_path(!njs_is_date(&args[0]))) {
+        njs_type_error(vm, "cannot convert %s to date",
+                       njs_type_string(args[0].type));
+
+        return NJS_ERROR;
+    }
+
     value = njs_date(&args[0])->time;
 
     if (njs_fast_path(!isnan(value))) {
@@ -1445,6 +1571,13 @@ njs_date_prototype_get_utc_minutes(njs_vm_t *vm, njs_value_t *args,
     time_t     clock;
     struct tm  tm;
 
+    if (njs_slow_path(!njs_is_date(&args[0]))) {
+        njs_type_error(vm, "cannot convert %s to date",
+                       njs_type_string(args[0].type));
+
+        return NJS_ERROR;
+    }
+
     value = njs_date(&args[0])->time;
 
     if (njs_fast_path(!isnan(value))) {
@@ -1466,6 +1599,13 @@ njs_date_prototype_get_seconds(njs_vm_t *vm, njs_value_t *args,
 {
     double  value;
 
+    if (njs_slow_path(!njs_is_date(&args[0]))) {
+        njs_type_error(vm, "cannot convert %s to date",
+                       njs_type_string(args[0].type));
+
+        return NJS_ERROR;
+    }
+
     value = njs_date(&args[0])->time;
 
     if (njs_fast_path(!isnan(value))) {
@@ -1484,6 +1624,13 @@ njs_date_prototype_get_milliseconds(njs_vm_t *vm, njs_value_t *args,
 {
     double  value;
 
+    if (njs_slow_path(!njs_is_date(&args[0]))) {
+        njs_type_error(vm, "cannot convert %s to date",
+                       njs_type_string(args[0].type));
+
+        return NJS_ERROR;
+    }
+
     value = njs_date(&args[0])->time;
 
     if (njs_fast_path(!isnan(value))) {
@@ -1502,6 +1649,13 @@ njs_date_prototype_get_timezone_offset(njs_vm_t *vm, njs_value_t *args,
 {
     double  value;
 
+    if (njs_slow_path(!njs_is_date(&args[0]))) {
+        njs_type_error(vm, "cannot convert %s to date",
+                       njs_type_string(args[0].type));
+
+        return NJS_ERROR;
+    }
+
     value = njs_date(&args[0])->time;
 
     if (njs_fast_path(!isnan(value))) {
@@ -1518,9 +1672,24 @@ static njs_int_t
 njs_date_prototype_set_time(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    double  time;
+    double     time;
+    njs_int_t  ret;
+
+    if (njs_slow_path(!njs_is_date(&args[0]))) {
+        njs_type_error(vm, "cannot convert %s to date",
+                       njs_type_string(args[0].type));
+
+        return NJS_ERROR;
+    }
 
     if (nargs > 1) {
+        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;
+            }
+        }
+
         time = njs_timeclip(njs_number(&args[1]));
 
     } else {
@@ -1538,13 +1707,28 @@ static njs_int_t
 njs_date_prototype_set_milliseconds(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused)
 {
-    double  time;
+    double     time;
+    njs_int_t  ret;
+
+    if (njs_slow_path(!njs_is_date(&args[0]))) {
+        njs_type_error(vm, "cannot convert %s to date",
+                       njs_type_string(args[0].type));
+
+        return NJS_ERROR;
+    }
 
     time = njs_date(&args[0])->time;
 
     if (njs_fast_path(!isnan(time))) {
 
         if (nargs > 1) {
+            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;
+                }
+            }
+
             time = (int64_t) (time / 1000) * 1000 + njs_number(&args[1]);
 
         } else {
@@ -1563,16 +1747,44 @@ static njs_int_t
 njs_date_prototype_set_seconds(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused)
 {
-    double   time;
-    int64_t  sec, ms;
+    double     time;
+    int64_t    sec, ms;
+    njs_int_t  ret;
+
+    if (njs_slow_path(!njs_is_date(&args[0]))) {
+        njs_type_error(vm, "cannot convert %s to date",
+                       njs_type_string(args[0].type));
+
+        return NJS_ERROR;
+    }
 
     time = njs_date(&args[0])->time;
 
     if (njs_fast_path(!isnan(time))) {
 
         if (nargs > 1) {
+            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 (nargs > 2) {
+                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;
+                    }
+                }
+
+                ms = njs_number(&args[2]);
+
+            } else {
+                ms = (int64_t) time % 1000;
+            }
+
             sec = njs_number(&args[1]);
-            ms = (nargs > 2) ? njs_number(&args[2]) : (int64_t) time % 1000;
 
             time = (int64_t) (time / 60000) * 60000 + sec * 1000 + ms;
 
@@ -1595,23 +1807,57 @@ njs_date_prototype_set_minutes(njs_vm_t *vm, njs_value_t *args,
     double     time;
     time_t     clock;
     int64_t    ms;
+    njs_int_t  ret;
     struct tm  tm;
 
+    if (njs_slow_path(!njs_is_date(&args[0]))) {
+        njs_type_error(vm, "cannot convert %s to date",
+                       njs_type_string(args[0].type));
+
+        return NJS_ERROR;
+    }
+
     time = njs_date(&args[0])->time;
 
     if (njs_fast_path(!isnan(time))) {
 
         if (nargs > 1) {
+            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;
+                }
+            }
+
             clock = time / 1000;
             localtime_r(&clock, &tm);
 
             tm.tm_min = njs_number(&args[1]);
 
             if (nargs > 2) {
+                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;
+                    }
+                }
+
                 tm.tm_sec = njs_number(&args[2]);
             }
 
-            ms = (nargs > 3) ? njs_number(&args[3]) : (int64_t) time % 1000;
+            if (nargs > 3) {
+                if (njs_slow_path(!njs_is_number(&args[3]))) {
+                    ret = njs_value_to_numeric(vm, &args[3], &args[3]);
+                    if (njs_slow_path(ret != NJS_OK)) {
+                        return ret;
+                    }
+                }
+
+                ms = njs_number(&args[3]);
+
+            } else {
+                ms = (int64_t) time % 1000;
+            }
 
             time = njs_date_time(&tm, ms);
 
@@ -1631,22 +1877,61 @@ static njs_int_t
 njs_date_prototype_set_utc_minutes(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused)
 {
-    double   time;
-    int64_t  clock, min, sec, ms;
+    double     time;
+    int64_t    clock, min, sec, ms;
+    njs_int_t  ret;
+
+    if (njs_slow_path(!njs_is_date(&args[0]))) {
+        njs_type_error(vm, "cannot convert %s to date",
+                       njs_type_string(args[0].type));
+
+        return NJS_ERROR;
+    }
 
     time = njs_date(&args[0])->time;
 
     if (njs_fast_path(!isnan(time))) {
 
         if (nargs > 1) {
-            clock = time / 1000;
+            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;
+                }
+            }
 
-            sec = (nargs > 2) ? njs_number(&args[2]) : clock % 60;
+            clock = time / 1000;
             min = njs_number(&args[1]);
 
+            if (nargs > 2) {
+                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;
+                    }
+                }
+
+                sec = njs_number(&args[2]);
+
+            } else {
+                sec = clock % 60;
+            }
+
             clock = clock / 3600 * 3600 + min * 60 + sec;
 
-            ms = (nargs > 3) ? njs_number(&args[3]) : (int64_t) time % 1000;
+            if (nargs > 3) {
+                if (njs_slow_path(!njs_is_number(&args[3]))) {
+                    ret = njs_value_to_numeric(vm, &args[3], &args[3]);
+                    if (njs_slow_path(ret != NJS_OK)) {
+                        return ret;
+                    }
+                }
+
+                ms = njs_number(&args[3]);
+
+            } else {
+                ms = (int64_t) time % 1000;
+            }
 
             time = clock * 1000 + ms;
 
@@ -1669,27 +1954,68 @@ njs_date_prototype_set_hours(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     double     time;
     time_t     clock;
     int64_t    ms;
+    njs_int_t  ret;
     struct tm  tm;
 
+    if (njs_slow_path(!njs_is_date(&args[0]))) {
+        njs_type_error(vm, "cannot convert %s to date",
+                       njs_type_string(args[0].type));
+
+        return NJS_ERROR;
+    }
+
     time = njs_date(&args[0])->time;
 
     if (njs_fast_path(!isnan(time))) {
 
         if (nargs > 1) {
+            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;
+                }
+            }
+
             clock = time / 1000;
             localtime_r(&clock, &tm);
 
             tm.tm_hour = njs_number(&args[1]);
 
             if (nargs > 2) {
+                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;
+                    }
+                }
+
                 tm.tm_min = njs_number(&args[2]);
             }
 
             if (nargs > 3) {
+                if (njs_slow_path(!njs_is_number(&args[3]))) {
+                    ret = njs_value_to_numeric(vm, &args[3], &args[3]);
+                    if (njs_slow_path(ret != NJS_OK)) {
+                        return ret;
+                    }
+                }
+
                 tm.tm_sec = njs_number(&args[3]);
             }
 
-            ms = (nargs > 4) ? njs_number(&args[4]) : (int64_t) time % 1000;
+            if (nargs > 4) {
+                if (njs_slow_path(!njs_is_number(&args[4]))) {
+                    ret = njs_value_to_numeric(vm, &args[4], &args[4]);
+                    if (njs_slow_path(ret != NJS_OK)) {
+                        return ret;
+                    }
+                }
+
+                ms = njs_number(&args[4]);
+
+            } else {
+                ms = (int64_t) time % 1000;
+            }
 
             time = njs_date_time(&tm, ms);
 
@@ -1709,24 +2035,76 @@ static njs_int_t
 njs_date_prototype_set_utc_hours(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused)
 {
-    double   time;
-    int64_t  clock, hour, min, sec, ms;
+    double     time;
+    int64_t    clock, hour, min, sec, ms;
+    njs_int_t  ret;
+
+    if (njs_slow_path(!njs_is_date(&args[0]))) {
+        njs_type_error(vm, "cannot convert %s to date",
+                       njs_type_string(args[0].type));
+
+        return NJS_ERROR;
+    }
 
     time = njs_date(&args[0])->time;
 
     if (njs_fast_path(!isnan(time))) {
 
         if (nargs > 1) {
+            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;
+                }
+            }
+
             clock = time / 1000;
 
-            sec = (nargs > 3) ? njs_number(&args[3]) : clock % 60;
-            min = (nargs > 2) ? njs_number(&args[2]) : clock / 60 % 60;
             hour = njs_number(&args[1]);
 
-            clock = clock / 86400 * 86400 + hour * 3600 + min * 60 + sec;
+            if (nargs > 2) {
+                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;
+                    }
+                }
+
+                min = njs_number(&args[2]);
+
+            } else {
+                min = clock / 60 % 60;
+            }
 
-            ms = (nargs > 4) ? njs_number(&args[4]) : (int64_t) time % 1000;
+            if (nargs > 3) {
+                if (njs_slow_path(!njs_is_number(&args[3]))) {
+                    ret = njs_value_to_numeric(vm, &args[3], &args[3]);
+                    if (njs_slow_path(ret != NJS_OK)) {
+                        return ret;
+                    }
+                }
+
+                sec = njs_number(&args[3]);
+
+            } else {
+                sec = clock % 60;
+            }
+
+            if (nargs > 4) {
+                if (njs_slow_path(!njs_is_number(&args[4]))) {
+                    ret = njs_value_to_numeric(vm, &args[4], &args[4]);
+                    if (njs_slow_path(ret != NJS_OK)) {
+                        return ret;
+                    }
+                }
+
+                ms = njs_number(&args[4]);
+
+            } else {
+                ms = (int64_t) time % 1000;
+            }
 
+            clock = clock / 86400 * 86400 + hour * 3600 + min * 60 + sec;
             time = clock * 1000 + ms;
 
         } else {
@@ -1747,13 +2125,28 @@ njs_date_prototype_set_date(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 {
     double     time;
     time_t     clock;
+    njs_int_t  ret;
     struct tm  tm;
 
+    if (njs_slow_path(!njs_is_date(&args[0]))) {
+        njs_type_error(vm, "cannot convert %s to date",
+                       njs_type_string(args[0].type));
+
+        return NJS_ERROR;
+    }
+
     time = njs_date(&args[0])->time;
 
     if (njs_fast_path(!isnan(time))) {
 
         if (nargs > 1) {
+            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;
+                }
+            }
+
             clock = time / 1000;
             localtime_r(&clock, &tm);
 
@@ -1779,13 +2172,28 @@ njs_date_prototype_set_utc_date(njs_vm_t *vm, njs_value_t *args,
 {
     double     time;
     time_t     clock;
+    njs_int_t  ret;
     struct tm  tm;
 
+    if (njs_slow_path(!njs_is_date(&args[0]))) {
+        njs_type_error(vm, "cannot convert %s to date",
+                       njs_type_string(args[0].type));
+
+        return NJS_ERROR;
+    }
+
     time = njs_date(&args[0])->time;
 
     if (njs_fast_path(!isnan(time))) {
 
         if (nargs > 1) {
+            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;
+                }
+            }
+
             clock = time / 1000;
             gmtime_r(&clock, &tm);
 
@@ -1811,19 +2219,41 @@ njs_date_prototype_set_month(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 {
     double     time;
     time_t     clock;
+    njs_int_t  ret;
     struct tm  tm;
 
+    if (njs_slow_path(!njs_is_date(&args[0]))) {
+        njs_type_error(vm, "cannot convert %s to date",
+                       njs_type_string(args[0].type));
+
+        return NJS_ERROR;
+    }
+
     time = njs_date(&args[0])->time;
 
     if (njs_fast_path(!isnan(time))) {
 
         if (nargs > 1) {
+            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;
+                }
+            }
+
             clock = time / 1000;
             localtime_r(&clock, &tm);
 
             tm.tm_mon = njs_number(&args[1]);
 
             if (nargs > 2) {
+                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;
+                    }
+                }
+
                 tm.tm_mday = njs_number(&args[2]);
             }
 
@@ -1847,19 +2277,41 @@ njs_date_prototype_set_utc_month(njs_vm_t *vm, njs_value_t *args,
 {
     double     time;
     time_t     clock;
+    njs_int_t  ret;
     struct tm  tm;
 
+    if (njs_slow_path(!njs_is_date(&args[0]))) {
+        njs_type_error(vm, "cannot convert %s to date",
+                       njs_type_string(args[0].type));
+
+        return NJS_ERROR;
+    }
+
     time = njs_date(&args[0])->time;
 
     if (njs_fast_path(!isnan(time))) {
 
         if (nargs > 1) {
+            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;
+                }
+            }
+
             clock = time / 1000;
             gmtime_r(&clock, &tm);
 
             tm.tm_mon = njs_number(&args[1]);
 
             if (nargs > 2) {
+                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;
+                    }
+                }
+
                 tm.tm_mday = njs_number(&args[2]);
             }
 
@@ -1883,23 +2335,52 @@ njs_date_prototype_set_full_year(njs_vm_t *vm, njs_value_t *args,
 {
     double     time;
     time_t     clock;
+    njs_int_t  ret;
     struct tm  tm;
 
+    if (njs_slow_path(!njs_is_date(&args[0]))) {
+        njs_type_error(vm, "cannot convert %s to date",
+                       njs_type_string(args[0].type));
+
+        return NJS_ERROR;
+    }
+
     time = njs_date(&args[0])->time;
 
     if (njs_fast_path(!isnan(time))) {
 
         if (nargs > 1) {
+            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;
+                }
+            }
+
             clock = time / 1000;
             localtime_r(&clock, &tm);
 
             tm.tm_year = njs_number(&args[1]) - 1900;
 
             if (nargs > 2) {
+                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;
+                    }
+                }
+
                 tm.tm_mon = njs_number(&args[2]);
             }
 
             if (nargs > 3) {
+                if (njs_slow_path(!njs_is_number(&args[3]))) {
+                    ret = njs_value_to_numeric(vm, &args[3], &args[3]);
+                    if (njs_slow_path(ret != NJS_OK)) {
+                        return ret;
+                    }
+                }
+
                 tm.tm_mday = njs_number(&args[3]);
             }
 
@@ -1923,23 +2404,52 @@ njs_date_prototype_set_utc_full_year(njs_vm_t *vm, njs_value_t *args,
 {
     double     time;
     time_t     clock;
+    njs_int_t  ret;
     struct tm  tm;
 
+    if (njs_slow_path(!njs_is_date(&args[0]))) {
+        njs_type_error(vm, "cannot convert %s to date",
+                       njs_type_string(args[0].type));
+
+        return NJS_ERROR;
+    }
+
     time = njs_date(&args[0])->time;
 
     if (njs_fast_path(!isnan(time))) {
 
         if (nargs > 1) {
+            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;
+                }
+            }
+
             clock = time / 1000;
             gmtime_r(&clock, &tm);
 
             tm.tm_year = njs_number(&args[1]) - 1900;
 
             if (nargs > 2) {
+                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;
+                    }
+                }
+
                 tm.tm_mon = njs_number(&args[2]);
             }
 
             if (nargs > 3) {
+                if (njs_slow_path(!njs_is_number(&args[3]))) {
+                    ret = njs_value_to_numeric(vm, &args[3], &args[3]);
+                    if (njs_slow_path(ret != NJS_OK)) {
+                        return ret;
+                    }
+                }
+
                 tm.tm_mday = njs_number(&args[3]);
             }
 
@@ -2034,8 +2544,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("valueOf"),
-        .value = njs_native_function(njs_date_prototype_value_of, 0,
-                                     NJS_DATE_ARG),
+        .value = njs_native_function(njs_date_prototype_value_of, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -2043,8 +2552,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("toString"),
-        .value = njs_native_function(njs_date_prototype_to_string, 0,
-                                     NJS_DATE_ARG),
+        .value = njs_native_function(njs_date_prototype_to_string, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -2052,8 +2560,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("toDateString"),
-        .value = njs_native_function(njs_date_prototype_to_date_string, 0,
-                                     NJS_DATE_ARG),
+        .value = njs_native_function(njs_date_prototype_to_date_string, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -2061,8 +2568,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("toTimeString"),
-        .value = njs_native_function(njs_date_prototype_to_time_string, 0,
-                                     NJS_DATE_ARG),
+        .value = njs_native_function(njs_date_prototype_to_time_string, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -2070,8 +2576,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("toLocaleString"),
-        .value = njs_native_function(njs_date_prototype_to_string, 0,
-                                     NJS_DATE_ARG),
+        .value = njs_native_function(njs_date_prototype_to_string, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -2079,8 +2584,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_long_string("toLocaleDateString"),
-        .value = njs_native_function(njs_date_prototype_to_date_string, 0,
-                                     NJS_DATE_ARG),
+        .value = njs_native_function(njs_date_prototype_to_date_string, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -2088,8 +2592,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_long_string("toLocaleTimeString"),
-        .value = njs_native_function(njs_date_prototype_to_time_string, 0,
-                                     NJS_DATE_ARG),
+        .value = njs_native_function(njs_date_prototype_to_time_string, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -2097,8 +2600,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("toUTCString"),
-        .value = njs_native_function(njs_date_prototype_to_utc_string, 0,
-                                     NJS_DATE_ARG),
+        .value = njs_native_function(njs_date_prototype_to_utc_string, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -2106,8 +2608,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("toISOString"),
-        .value = njs_native_function(njs_date_prototype_to_iso_string, 0,
-                                     NJS_DATE_ARG),
+        .value = njs_native_function(njs_date_prototype_to_iso_string, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -2115,8 +2616,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("getTime"),
-        .value = njs_native_function(njs_date_prototype_value_of, 0,
-                                     NJS_DATE_ARG),
+        .value = njs_native_function(njs_date_prototype_value_of, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -2124,8 +2624,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("getFullYear"),
-        .value = njs_native_function(njs_date_prototype_get_full_year, 0,
-                                     NJS_DATE_ARG),
+        .value = njs_native_function(njs_date_prototype_get_full_year, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -2133,8 +2632,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("getUTCFullYear"),
-        .value = njs_native_function(njs_date_prototype_get_utc_full_year, 0,
-                                     NJS_DATE_ARG),
+        .value = njs_native_function(njs_date_prototype_get_utc_full_year, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -2142,8 +2640,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("getMonth"),
-        .value = njs_native_function(njs_date_prototype_get_month, 0,
-                                     NJS_DATE_ARG),
+        .value = njs_native_function(njs_date_prototype_get_month, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -2151,8 +2648,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("getUTCMonth"),
-        .value = njs_native_function(njs_date_prototype_get_utc_month, 0,
-                                     NJS_DATE_ARG),
+        .value = njs_native_function(njs_date_prototype_get_utc_month, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -2160,8 +2656,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("getDate"),
-        .value = njs_native_function(njs_date_prototype_get_date, 0,
-                                     NJS_DATE_ARG),
+        .value = njs_native_function(njs_date_prototype_get_date, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -2169,8 +2664,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("getUTCDate"),
-        .value = njs_native_function(njs_date_prototype_get_utc_date, 0,
-                                     NJS_DATE_ARG),
+        .value = njs_native_function(njs_date_prototype_get_utc_date, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -2178,8 +2672,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("getDay"),
-        .value = njs_native_function(njs_date_prototype_get_day, 0,
-                                     NJS_DATE_ARG),
+        .value = njs_native_function(njs_date_prototype_get_day, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -2187,8 +2680,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("getUTCDay"),
-        .value = njs_native_function(njs_date_prototype_get_utc_day, 0,
-                                     NJS_DATE_ARG),
+        .value = njs_native_function(njs_date_prototype_get_utc_day, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -2196,8 +2688,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("getHours"),
-        .value = njs_native_function(njs_date_prototype_get_hours, 0,
-                                     NJS_DATE_ARG),
+        .value = njs_native_function(njs_date_prototype_get_hours, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -2205,8 +2696,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("getUTCHours"),
-        .value = njs_native_function(njs_date_prototype_get_utc_hours, 0,
-                                     NJS_DATE_ARG),
+        .value = njs_native_function(njs_date_prototype_get_utc_hours, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -2214,8 +2704,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("getMinutes"),
-        .value = njs_native_function(njs_date_prototype_get_minutes, 0,
-                                     NJS_DATE_ARG),
+        .value = njs_native_function(njs_date_prototype_get_minutes, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -2223,8 +2712,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("getUTCMinutes"),
-        .value = njs_native_function(njs_date_prototype_get_utc_minutes, 0,
-                                     NJS_DATE_ARG),
+        .value = njs_native_function(njs_date_prototype_get_utc_minutes, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -2232,8 +2720,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("getSeconds"),
-        .value = njs_native_function(njs_date_prototype_get_seconds, 0,
-                                     NJS_DATE_ARG),
+        .value = njs_native_function(njs_date_prototype_get_seconds, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -2241,8 +2728,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("getUTCSeconds"),
-        .value = njs_native_function(njs_date_prototype_get_seconds, 0,
-                                     NJS_DATE_ARG),
+        .value = njs_native_function(njs_date_prototype_get_seconds, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -2250,8 +2736,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_long_string("getMilliseconds"),
-        .value = njs_native_function(njs_date_prototype_get_milliseconds, 0,
-                                     NJS_DATE_ARG),
+        .value = njs_native_function(njs_date_prototype_get_milliseconds, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -2259,8 +2744,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_long_string("getUTCMilliseconds"),
-        .value = njs_native_function(njs_date_prototype_get_milliseconds, 0,
-                                     NJS_DATE_ARG),
+        .value = njs_native_function(njs_date_prototype_get_milliseconds, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -2268,8 +2752,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_long_string("getTimezoneOffset"),
-        .value = njs_native_function(njs_date_prototype_get_timezone_offset, 0,
-                                     NJS_DATE_ARG),
+        .value = njs_native_function(njs_date_prototype_get_timezone_offset, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -2277,8 +2760,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("setTime"),
-        .value = njs_native_function(njs_date_prototype_set_time, 1,
-                                     NJS_DATE_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_date_prototype_set_time, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -2286,8 +2768,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_long_string("setMilliseconds"),
-        .value = njs_native_function(njs_date_prototype_set_milliseconds, 1,
-                                     NJS_DATE_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_date_prototype_set_milliseconds, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -2295,8 +2776,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_long_string("setUTCMilliseconds"),
-        .value = njs_native_function(njs_date_prototype_set_milliseconds, 1,
-                                     NJS_DATE_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_date_prototype_set_milliseconds, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -2304,8 +2784,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("setSeconds"),
-        .value = njs_native_function(njs_date_prototype_set_seconds, 2,
-                                     NJS_DATE_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_date_prototype_set_seconds, 2),
         .writable = 1,
         .configurable = 1,
     },
@@ -2313,8 +2792,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("setUTCSeconds"),
-        .value = njs_native_function(njs_date_prototype_set_seconds, 2,
-                     NJS_DATE_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_date_prototype_set_seconds, 2),
         .writable = 1,
         .configurable = 1,
     },
@@ -2322,9 +2800,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("setMinutes"),
-        .value = njs_native_function(njs_date_prototype_set_minutes, 3,
-                     NJS_DATE_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG,
-                     NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_date_prototype_set_minutes, 3),
         .writable = 1,
         .configurable = 1,
     },
@@ -2332,9 +2808,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("setUTCMinutes"),
-        .value = njs_native_function(njs_date_prototype_set_utc_minutes, 3,
-                     NJS_DATE_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG,
-                     NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_date_prototype_set_utc_minutes, 3),
         .writable = 1,
         .configurable = 1,
     },
@@ -2342,9 +2816,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("setHours"),
-        .value = njs_native_function(njs_date_prototype_set_hours, 4,
-                     NJS_DATE_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG,
-                     NJS_NUMBER_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_date_prototype_set_hours, 4),
         .writable = 1,
         .configurable = 1,
     },
@@ -2352,9 +2824,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("setUTCHours"),
-        .value = njs_native_function(njs_date_prototype_set_utc_hours, 4,
-                     NJS_DATE_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG,
-                     NJS_NUMBER_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_date_prototype_set_utc_hours, 4),
         .writable = 1,
         .configurable = 1,
     },
@@ -2362,8 +2832,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("setDate"),
-        .value = njs_native_function(njs_date_prototype_set_date, 1,
-                     NJS_DATE_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_date_prototype_set_date, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -2371,8 +2840,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("setUTCDate"),
-        .value = njs_native_function(njs_date_prototype_set_utc_date, 1,
-                     NJS_DATE_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_date_prototype_set_utc_date, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -2380,8 +2848,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("setMonth"),
-        .value = njs_native_function(njs_date_prototype_set_month, 2,
-                     NJS_DATE_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_date_prototype_set_month, 2),
         .writable = 1,
         .configurable = 1,
     },
@@ -2389,8 +2856,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("setUTCMonth"),
-        .value = njs_native_function(njs_date_prototype_set_utc_month, 2,
-                     NJS_DATE_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_date_prototype_set_utc_month, 2),
         .writable = 1,
         .configurable = 1,
     },
@@ -2398,9 +2864,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("setFullYear"),
-        .value = njs_native_function(njs_date_prototype_set_full_year, 3,
-                     NJS_DATE_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG,
-                     NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_date_prototype_set_full_year, 3),
         .writable = 1,
         .configurable = 1,
     },
@@ -2408,9 +2872,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("setUTCFullYear"),
-        .value = njs_native_function(njs_date_prototype_set_utc_full_year, 3,
-                     NJS_DATE_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG,
-                     NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_date_prototype_set_utc_full_year, 3),
         .writable = 1,
         .configurable = 1,
     },
@@ -2418,7 +2880,7 @@ static const njs_object_prop_t  njs_date_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("toJSON"),
-        .value = njs_native_function(njs_date_prototype_to_json, 1, 0),
+        .value = njs_native_function(njs_date_prototype_to_json, 1),
         .writable = 1,
         .configurable = 1,
     },
index 6ca7b11fbcc076e15dadb141fc98d78cc4ec2471..682be0414fb693145e3bfd3f5d78b4a086ab04ac 100644 (file)
@@ -137,11 +137,21 @@ static njs_int_t
 njs_error_create(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_value_type_t type)
 {
-    njs_object_t       *error;
-    const njs_value_t  *value;
+    njs_int_t     ret;
+    njs_value_t   *value;
+    njs_object_t  *error;
 
     value = njs_arg(args, nargs, 1);
 
+    if (njs_slow_path(!njs_is_string(value))) {
+        if (!njs_is_undefined(value)) {
+            ret = njs_value_to_string(vm, value, value);
+            if (njs_slow_path(ret != NJS_OK)) {
+                return ret;
+            }
+        }
+    }
+
     error = njs_error_alloc(vm, type, NULL,
                             njs_is_defined(value) ? value : NULL);
     if (njs_slow_path(error == NULL)) {
@@ -734,7 +744,7 @@ static const njs_object_prop_t  njs_error_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("valueOf"),
-        .value = njs_native_function(njs_error_prototype_value_of, 0, 0),
+        .value = njs_native_function(njs_error_prototype_value_of, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -742,7 +752,7 @@ static const njs_object_prop_t  njs_error_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("toString"),
-        .value = njs_native_function(njs_error_prototype_to_string, 0, 0),
+        .value = njs_native_function(njs_error_prototype_to_string, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -816,8 +826,7 @@ static const njs_object_prop_t  njs_internal_error_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("toString"),
-        .value = njs_native_function(njs_internal_error_prototype_to_string,
-                                     0, 0),
+        .value = njs_native_function(njs_internal_error_prototype_to_string, 0),
         .writable = 1,
         .configurable = 1,
     },
index 3256b3189168bf0af0d074d7104d01794a142ed3..9d89df32a143f544260865bb026e8031a20555c9 100644 (file)
@@ -896,25 +896,43 @@ static njs_int_t
 njs_fs_rename_sync(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    int         ret;
-    const char  *old_path, *new_path;
+    int          ret;
+    const char   *old_path, *new_path;
+    njs_value_t  *old, *new;
 
-    if (njs_slow_path(!njs_is_string(njs_arg(args, nargs, 1)))) {
-        njs_type_error(vm, "oldPath must be a string");
-        return NJS_ERROR;
-    }
+    if (njs_slow_path(nargs < 3)) {
+        if (nargs < 2) {
+            njs_type_error(vm, "oldPath must be a string");
+            return NJS_ERROR;
+        }
 
-    if (njs_slow_path(!njs_is_string(njs_arg(args, nargs, 2)))) {
         njs_type_error(vm, "newPath must be a string");
         return NJS_ERROR;
     }
 
-    old_path = njs_string_to_c_string(vm, njs_argument(args, 1));
+    old = njs_argument(args, 1);
+    new = njs_argument(args, 2);
+
+    if (njs_slow_path(!njs_is_string(old))) {
+        ret = njs_value_to_string(vm, old, old);
+        if (njs_slow_path(ret != NJS_OK)) {
+            return ret;
+        }
+    }
+
+    if (njs_slow_path(!njs_is_string(new))) {
+        ret = njs_value_to_string(vm, new, new);
+        if (njs_slow_path(ret != NJS_OK)) {
+            return ret;
+        }
+    }
+
+    old_path = njs_string_to_c_string(vm, old);
     if (njs_slow_path(old_path == NULL)) {
         return NJS_ERROR;
     }
 
-    new_path = njs_string_to_c_string(vm, njs_argument(args, 2));
+    new_path = njs_string_to_c_string(vm, new);
     if (njs_slow_path(new_path == NULL)) {
         return NJS_ERROR;
     }
@@ -1140,7 +1158,7 @@ static const njs_object_prop_t  njs_fs_object_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("readFile"),
-        .value = njs_native_function(njs_fs_read_file, 0, 0),
+        .value = njs_native_function(njs_fs_read_file, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -1148,7 +1166,7 @@ static const njs_object_prop_t  njs_fs_object_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("readFileSync"),
-        .value = njs_native_function(njs_fs_read_file_sync, 0, 0),
+        .value = njs_native_function(njs_fs_read_file_sync, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -1156,7 +1174,7 @@ static const njs_object_prop_t  njs_fs_object_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("appendFile"),
-        .value = njs_native_function(njs_fs_append_file, 0, 0),
+        .value = njs_native_function(njs_fs_append_file, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -1164,7 +1182,7 @@ static const njs_object_prop_t  njs_fs_object_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("appendFileSync"),
-        .value = njs_native_function(njs_fs_append_file_sync, 0, 0),
+        .value = njs_native_function(njs_fs_append_file_sync, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -1172,7 +1190,7 @@ static const njs_object_prop_t  njs_fs_object_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("writeFile"),
-        .value = njs_native_function(njs_fs_write_file, 0, 0),
+        .value = njs_native_function(njs_fs_write_file, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -1180,7 +1198,7 @@ static const njs_object_prop_t  njs_fs_object_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("writeFileSync"),
-        .value = njs_native_function(njs_fs_write_file_sync, 0, 0),
+        .value = njs_native_function(njs_fs_write_file_sync, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -1188,8 +1206,7 @@ static const njs_object_prop_t  njs_fs_object_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("renameSync"),
-        .value = njs_native_function(njs_fs_rename_sync, 0, NJS_STRING_ARG,
-                                     NJS_STRING_ARG, 0),
+        .value = njs_native_function(njs_fs_rename_sync, 0),
         .writable = 1,
         .configurable = 1,
     },
index 3bca28903d8ffce1e0f576df5c5c239c402d30cd..c59189c8ba4181abe0154b098fc6c6a54fbbb490 100644 (file)
@@ -11,8 +11,6 @@
 static njs_function_t *njs_function_copy(njs_vm_t *vm,
     njs_function_t *function);
 static njs_native_frame_t *njs_function_frame_alloc(njs_vm_t *vm, size_t size);
-static njs_int_t njs_normalize_args(njs_vm_t *vm, njs_value_t *args,
-    uint8_t *args_types, njs_uint_t nargs);
 
 
 njs_function_t *
@@ -269,8 +267,8 @@ const njs_object_prop_t  njs_arguments_object_instance_properties[] =
         .type = NJS_PROPERTY,
         .name = njs_string("callee"),
         .value = njs_value(NJS_INVALID, 1, NAN),
-        .getter = njs_native_function(njs_function_prototype_thrower, 0, 0),
-        .setter = njs_native_function(njs_function_prototype_thrower, 0, 0),
+        .getter = njs_native_function(njs_function_prototype_thrower, 0),
+        .setter = njs_native_function(njs_function_prototype_thrower, 0),
         .writable = NJS_ATTRIBUTE_UNSET,
     },
 };
@@ -586,12 +584,6 @@ njs_function_native_call(njs_vm_t *vm)
     frame = (njs_frame_t *) native;
     function = native->function;
 
-    ret = njs_normalize_args(vm, native->arguments, function->args_types,
-                             native->nargs);
-    if (ret != NJS_OK) {
-        return ret;
-    }
-
     ret = function->u.native(vm, native->arguments, native->nargs,
                              frame->retval);
 
@@ -622,142 +614,6 @@ njs_function_native_call(njs_vm_t *vm)
 }
 
 
-static njs_int_t
-njs_normalize_args(njs_vm_t *vm, njs_value_t *args, uint8_t *args_types,
-    njs_uint_t nargs)
-{
-    njs_int_t   ret;
-    njs_uint_t  n;
-
-    n = njs_min(nargs, NJS_ARGS_TYPES_MAX);
-
-    while (n != 0) {
-
-        switch (*args_types) {
-
-        case NJS_STRING_OBJECT_ARG:
-
-            if (njs_is_null_or_undefined(args)) {
-                goto type_error;
-            }
-
-            /* Fall through. */
-
-        case NJS_STRING_ARG:
-
-            if (!njs_is_string(args)) {
-                ret = njs_value_to_string(vm, args, args);
-                if (ret != NJS_OK) {
-                    return ret;
-                }
-            }
-
-            break;
-
-        case NJS_NUMBER_ARG:
-
-            if (!njs_is_numeric(args)) {
-                ret = njs_value_to_numeric(vm, args, args);
-                if (ret != NJS_OK) {
-                    return ret;
-                }
-            }
-
-            break;
-
-        case NJS_INTEGER_ARG:
-
-            if (!njs_is_numeric(args)) {
-                ret = njs_value_to_numeric(vm, args, args);
-                if (ret != NJS_OK) {
-                    return ret;
-                }
-            }
-
-            /* Numbers are truncated to fit in 32-bit integers. */
-
-            if (!isnan(njs_number(args))) {
-                if (njs_number(args) > 2147483647.0) {
-                    njs_number(args) = 2147483647.0;
-
-                } else if (njs_number(args) < -2147483648.0) {
-                    njs_number(args) = -2147483648.0;
-                }
-            }
-
-            break;
-
-        case NJS_FUNCTION_ARG:
-
-            switch (args->type) {
-            case NJS_STRING:
-            case NJS_FUNCTION:
-                break;
-
-            default:
-                ret = njs_value_to_string(vm, args, args);
-                if (ret != NJS_OK) {
-                    return ret;
-                }
-            }
-
-            break;
-
-        case NJS_REGEXP_ARG:
-
-            switch (args->type) {
-            case NJS_UNDEFINED:
-            case NJS_STRING:
-            case NJS_REGEXP:
-                break;
-
-            default:
-                ret = njs_value_to_string(vm, args, args);
-                if (ret != NJS_OK) {
-                    return ret;
-                }
-            }
-
-            break;
-
-        case NJS_DATE_ARG:
-            if (!njs_is_date(args)) {
-                goto type_error;
-            }
-
-            break;
-
-        case NJS_OBJECT_ARG:
-
-            if (njs_is_null_or_undefined(args)) {
-                goto type_error;
-            }
-
-            break;
-
-        case NJS_SKIP_ARG:
-            break;
-
-        case 0:
-            return NJS_OK;
-        }
-
-        args++;
-        args_types++;
-        n--;
-    }
-
-    return NJS_OK;
-
-type_error:
-
-    njs_type_error(vm, "cannot convert %s to %s", njs_type_string(args->type),
-                   njs_arg_type_string(*args_types));
-
-    return NJS_ERROR;
-}
-
-
 void
 njs_function_frame_free(njs_vm_t *vm, njs_native_frame_t *native)
 {
@@ -1257,7 +1113,7 @@ static const njs_object_prop_t  njs_function_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("call"),
-        .value = njs_native_function(njs_function_prototype_call, 1, 0),
+        .value = njs_native_function(njs_function_prototype_call, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1265,7 +1121,7 @@ static const njs_object_prop_t  njs_function_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("apply"),
-        .value = njs_native_function(njs_function_prototype_apply, 2, 0),
+        .value = njs_native_function(njs_function_prototype_apply, 2),
         .writable = 1,
         .configurable = 1,
     },
@@ -1273,7 +1129,7 @@ static const njs_object_prop_t  njs_function_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("bind"),
-        .value = njs_native_function(njs_function_prototype_bind, 1, 0),
+        .value = njs_native_function(njs_function_prototype_bind, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1282,8 +1138,8 @@ static const njs_object_prop_t  njs_function_prototype_properties[] =
         .type = NJS_PROPERTY,
         .name = njs_string("caller"),
         .value = njs_value(NJS_INVALID, 1, NAN),
-        .getter = njs_native_function(njs_function_prototype_thrower, 0, 0),
-        .setter = njs_native_function(njs_function_prototype_thrower, 0, 0),
+        .getter = njs_native_function(njs_function_prototype_thrower, 0),
+        .setter = njs_native_function(njs_function_prototype_thrower, 0),
         .writable = NJS_ATTRIBUTE_UNSET,
         .configurable = 1,
     },
@@ -1292,8 +1148,8 @@ static const njs_object_prop_t  njs_function_prototype_properties[] =
         .type = NJS_PROPERTY,
         .name = njs_string("arguments"),
         .value = njs_value(NJS_INVALID, 1, NAN),
-        .getter = njs_native_function(njs_function_prototype_thrower, 0, 0),
-        .setter = njs_native_function(njs_function_prototype_thrower, 0, 0),
+        .getter = njs_native_function(njs_function_prototype_thrower, 0),
+        .setter = njs_native_function(njs_function_prototype_thrower, 0),
         .writable = NJS_ATTRIBUTE_UNSET,
         .configurable = 1,
     },
index 29decd01f416a65407c5164928d4dcf81ea2d197..efaffc8193ef611d579bb437addceab287b89599 100644 (file)
@@ -8,17 +8,6 @@
 #define _NJS_FUNCTION_H_INCLUDED_
 
 
-#define NJS_SKIP_ARG               1
-#define NJS_NUMBER_ARG             2
-#define NJS_INTEGER_ARG            3
-#define NJS_STRING_ARG             4
-#define NJS_OBJECT_ARG             5
-#define NJS_STRING_OBJECT_ARG      6
-#define NJS_FUNCTION_ARG           7
-#define NJS_REGEXP_ARG             8
-#define NJS_DATE_ARG               9
-
-
 struct njs_function_lambda_s {
     uint32_t                       nargs;
     uint32_t                       local_size;
index feeeb40700674ba71c21a204a7de05dbf091da48..45e24db4374ad12408a36f11e25a556c2d6ad331 100644 (file)
@@ -146,10 +146,11 @@ static njs_int_t
 njs_json_parse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    njs_value_t           *value, *wrapper;
-    const njs_value_t     *text, *reviver;
+    njs_int_t             ret;
+    njs_value_t           *text, *value, *wrapper;
     const u_char          *p, *end;
     njs_json_parse_t      *parse, json_parse;
+    const njs_value_t     *reviver;
     njs_string_prop_t     string;
     njs_json_parse_ctx_t  ctx;
 
@@ -163,8 +164,16 @@ njs_json_parse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     text = njs_arg(args, nargs, 1);
 
-    if (njs_is_undefined(text)) {
-        text = &njs_string_undefined;
+    if (njs_slow_path(!njs_is_string(text))) {
+        if (njs_is_undefined(text)) {
+            text = njs_value_arg(&njs_string_undefined);
+
+        } else {
+            ret = njs_value_to_string(vm, text, text);
+            if (njs_slow_path(ret != NJS_OK)) {
+                return ret;
+            }
+        }
     }
 
     (void) njs_string_prop(&string, text);
@@ -2101,9 +2110,7 @@ static const njs_object_prop_t  njs_json_object_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("parse"),
-        .value = njs_native_function(njs_json_parse, 2,
-                                     NJS_SKIP_ARG, NJS_STRING_ARG,
-                                     NJS_OBJECT_ARG),
+        .value = njs_native_function(njs_json_parse, 2),
         .writable = 1,
         .configurable = 1,
     },
@@ -2112,9 +2119,7 @@ static const njs_object_prop_t  njs_json_object_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("stringify"),
-        .value = njs_native_function(njs_json_stringify, 3,
-                                     NJS_SKIP_ARG, NJS_SKIP_ARG, NJS_SKIP_ARG,
-                                     NJS_SKIP_ARG),
+        .value = njs_native_function(njs_json_stringify, 3),
         .writable = 1,
         .configurable = 1,
     },
index 48306e3e18c5be8dcf8ea7a9183a8783e9c99486..ab4393db36276b710f01acd26a778da6d0201b71 100644 (file)
@@ -12,16 +12,21 @@ static njs_int_t
 njs_object_math_abs(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    double  num;
+    njs_int_t  ret;
 
-    if (nargs > 1) {
-        num = fabs(njs_number(&args[1]));
+    if (njs_slow_path(nargs < 2)) {
+        njs_set_number(&vm->retval, NAN);
+        return NJS_OK;
+    }
 
-    } else {
-        num = NAN;
+    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, num);
+    njs_set_number(&vm->retval, fabs(njs_number(&args[1])));
 
     return NJS_OK;
 }
@@ -31,25 +36,31 @@ 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;
+    double     num;
+    njs_int_t  ret;
 
-    if (nargs > 1) {
-        num = njs_number(&args[1]);
+    if (njs_slow_path(nargs < 2)) {
+        njs_set_number(&vm->retval, NAN);
+        return NJS_OK;
+    }
 
-#if (NJS_SOLARIS)
-        /* On Solaris acos(x) returns 0 for x > 1. */
-        if (fabs(num) > 1.0) {
-            num = NAN;
+    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;
         }
-#endif
+    }
 
-        num = acos(num);
+    num = njs_number(&args[1]);
 
-    } else {
+#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, num);
+    njs_set_number(&vm->retval, acos(num));
 
     return NJS_OK;
 }
@@ -59,16 +70,21 @@ static njs_int_t
 njs_object_math_acosh(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    double  num;
+    njs_int_t  ret;
 
-    if (nargs > 1) {
-        num = acosh(njs_number(&args[1]));
+    if (njs_slow_path(nargs < 2)) {
+        njs_set_number(&vm->retval, NAN);
+        return NJS_OK;
+    }
 
-    } else {
-        num = NAN;
+    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, num);
+    njs_set_number(&vm->retval, acosh(njs_number(&args[1])));
 
     return NJS_OK;
 }
@@ -78,25 +94,31 @@ 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;
+    double     num;
+    njs_int_t  ret;
 
-    if (nargs > 1) {
-        num = njs_number(&args[1]);
+    if (njs_slow_path(nargs < 2)) {
+        njs_set_number(&vm->retval, NAN);
+        return NJS_OK;
+    }
 
-#if (NJS_SOLARIS)
-        /* On Solaris asin(x) returns 0 for x > 1. */
-        if (fabs(num) > 1.0) {
-            num = NAN;
+    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;
         }
-#endif
+    }
 
-        num = asin(num);
+    num = njs_number(&args[1]);
 
-    } else {
+#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, num);
+    njs_set_number(&vm->retval, asin(num));
 
     return NJS_OK;
 }
@@ -106,16 +128,21 @@ static njs_int_t
 njs_object_math_asinh(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    double  num;
+    njs_int_t  ret;
 
-    if (nargs > 1) {
-        num = asinh(njs_number(&args[1]));
+    if (njs_slow_path(nargs < 2)) {
+        njs_set_number(&vm->retval, NAN);
+        return NJS_OK;
+    }
 
-    } else {
-        num = NAN;
+    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, num);
+    njs_set_number(&vm->retval, asinh(njs_number(&args[1])));
 
     return NJS_OK;
 }
@@ -125,16 +152,21 @@ static njs_int_t
 njs_object_math_atan(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    double  num;
+    njs_int_t  ret;
 
-    if (nargs > 1) {
-        num = atan(njs_number(&args[1]));
+    if (njs_slow_path(nargs < 2)) {
+        njs_set_number(&vm->retval, NAN);
+        return NJS_OK;
+    }
 
-    } else {
-        num = NAN;
+    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, num);
+    njs_set_number(&vm->retval, atan(njs_number(&args[1])));
 
     return NJS_OK;
 }
@@ -144,19 +176,32 @@ 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  num, y, x;
+    double     y, x;
+    njs_int_t  ret;
 
-    if (nargs > 2) {
-        y = njs_number(&args[1]);
-        x = njs_number(&args[2]);
+    if (njs_slow_path(nargs < 3)) {
+        njs_set_number(&vm->retval, NAN);
+        return NJS_OK;
+    }
 
-        num = atan2(y, x);
+    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;
+    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;
+        }
     }
 
-    njs_set_number(&vm->retval, num);
+    y = njs_number(&args[1]);
+    x = njs_number(&args[2]);
+
+    njs_set_number(&vm->retval, atan2(y, x));
 
     return NJS_OK;
 }
@@ -166,16 +211,21 @@ static njs_int_t
 njs_object_math_atanh(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    double  num;
+    njs_int_t  ret;
 
-    if (nargs > 1) {
-        num = atanh(njs_number(&args[1]));
+    if (njs_slow_path(nargs < 2)) {
+        njs_set_number(&vm->retval, NAN);
+        return NJS_OK;
+    }
 
-    } else {
-        num = NAN;
+    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, num);
+    njs_set_number(&vm->retval, atanh(njs_number(&args[1])));
 
     return NJS_OK;
 }
@@ -185,16 +235,21 @@ static njs_int_t
 njs_object_math_cbrt(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    double  num;
+    njs_int_t  ret;
 
-    if (nargs > 1) {
-        num = cbrt(njs_number(&args[1]));
+    if (njs_slow_path(nargs < 2)) {
+        njs_set_number(&vm->retval, NAN);
+        return NJS_OK;
+    }
 
-    } else {
-        num = NAN;
+    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, num);
+    njs_set_number(&vm->retval, cbrt(njs_number(&args[1])));
 
     return NJS_OK;
 }
@@ -204,16 +259,21 @@ static njs_int_t
 njs_object_math_ceil(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    double  num;
+    njs_int_t  ret;
 
-    if (nargs > 1) {
-        num = ceil(njs_number(&args[1]));
+    if (njs_slow_path(nargs < 2)) {
+        njs_set_number(&vm->retval, NAN);
+        return NJS_OK;
+    }
 
-    } else {
-        num = NAN;
+    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, num);
+    njs_set_number(&vm->retval, ceil(njs_number(&args[1])));
 
     return NJS_OK;
 }
@@ -223,18 +283,25 @@ static njs_int_t
 njs_object_math_clz32(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    double    num;
-    uint32_t  ui32;
+    uint32_t   ui32;
+    njs_int_t  ret;
 
-    if (nargs > 1) {
-        ui32 = njs_number_to_uint32(njs_number(&args[1]));
-        num = njs_leading_zeros(ui32);
+    if (njs_slow_path(nargs < 2)) {
+        njs_set_number(&vm->retval, 32);
+        return NJS_OK;
+    }
+
+    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;
+        }
 
     } else {
-        num = 32;
+        ui32 = njs_number_to_uint32(njs_number(&args[1]));
     }
 
-    njs_set_number(&vm->retval, num);
+    njs_set_number(&vm->retval, njs_leading_zeros(ui32));
 
     return NJS_OK;
 }
@@ -244,16 +311,21 @@ static njs_int_t
 njs_object_math_cos(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    double  num;
+    njs_int_t  ret;
 
-    if (nargs > 1) {
-        num = cos(njs_number(&args[1]));
+    if (njs_slow_path(nargs < 2)) {
+        njs_set_number(&vm->retval, NAN);
+        return NJS_OK;
+    }
 
-    } else {
-        num = NAN;
+    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, num);
+    njs_set_number(&vm->retval, cos(njs_number(&args[1])));
 
     return NJS_OK;
 }
@@ -263,16 +335,21 @@ static njs_int_t
 njs_object_math_cosh(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    double  num;
+    njs_int_t  ret;
 
-    if (nargs > 1) {
-        num = cosh(njs_number(&args[1]));
+    if (njs_slow_path(nargs < 2)) {
+        njs_set_number(&vm->retval, NAN);
+        return NJS_OK;
+    }
 
-    } else {
-        num = NAN;
+    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, num);
+    njs_set_number(&vm->retval, cosh(njs_number(&args[1])));
 
     return NJS_OK;
 }
@@ -282,16 +359,21 @@ static njs_int_t
 njs_object_math_exp(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    double  num;
+    njs_int_t  ret;
 
-    if (nargs > 1) {
-        num = exp(njs_number(&args[1]));
+    if (njs_slow_path(nargs < 2)) {
+        njs_set_number(&vm->retval, NAN);
+        return NJS_OK;
+    }
 
-    } else {
-        num = NAN;
+    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, num);
+    njs_set_number(&vm->retval, exp(njs_number(&args[1])));
 
     return NJS_OK;
 }
@@ -301,16 +383,21 @@ static njs_int_t
 njs_object_math_expm1(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    double  num;
+    njs_int_t  ret;
 
-    if (nargs > 1) {
-        num = expm1(njs_number(&args[1]));
+    if (njs_slow_path(nargs < 2)) {
+        njs_set_number(&vm->retval, NAN);
+        return NJS_OK;
+    }
 
-    } else {
-        num = NAN;
+    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, num);
+    njs_set_number(&vm->retval, expm1(njs_number(&args[1])));
 
     return NJS_OK;
 }
@@ -320,16 +407,21 @@ static njs_int_t
 njs_object_math_floor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    double  num;
+    njs_int_t  ret;
 
-    if (nargs > 1) {
-        num = floor(njs_number(&args[1]));
+    if (njs_slow_path(nargs < 2)) {
+        njs_set_number(&vm->retval, NAN);
+        return NJS_OK;
+    }
 
-    } else {
-        num = NAN;
+    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, num);
+    njs_set_number(&vm->retval, floor(njs_number(&args[1])));
 
     return NJS_OK;
 }
@@ -339,16 +431,21 @@ static njs_int_t
 njs_object_math_fround(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    double  num;
+    njs_int_t  ret;
 
-    if (nargs > 1) {
-        num = (float) njs_number(&args[1]);
+    if (njs_slow_path(nargs < 2)) {
+        njs_set_number(&vm->retval, NAN);
+        return NJS_OK;
+    }
 
-    } else {
-        num = NAN;
+    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, num);
+    njs_set_number(&vm->retval, (float) njs_number(&args[1]));
 
     return NJS_OK;
 }
@@ -391,20 +488,35 @@ static njs_int_t
 njs_object_math_imul(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    double    num;
-    uint32_t  a, b;
+    uint32_t   a, b;
+    njs_int_t  ret;
+
+    if (njs_slow_path(nargs < 3)) {
+        njs_set_number(&vm->retval, 0);
+        return NJS_OK;
+    }
 
-    if (nargs > 2) {
+    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]));
-        b = njs_number_to_uint32(njs_number(&args[2]));
+    }
 
-        num = (int32_t) (a * b);
+    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 {
-        num = 0;
+        b = njs_number_to_uint32(njs_number(&args[2]));
     }
 
-    njs_set_number(&vm->retval, num);
+    njs_set_number(&vm->retval, (int32_t) (a * b));
 
     return NJS_OK;
 }
@@ -414,16 +526,21 @@ static njs_int_t
 njs_object_math_log(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    double  num;
+    njs_int_t  ret;
 
-    if (nargs > 1) {
-        num = log(njs_number(&args[1]));
+    if (njs_slow_path(nargs < 2)) {
+        njs_set_number(&vm->retval, NAN);
+        return NJS_OK;
+    }
 
-    } else {
-        num = NAN;
+    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, num);
+    njs_set_number(&vm->retval, log(njs_number(&args[1])));
 
     return NJS_OK;
 }
@@ -433,16 +550,21 @@ static njs_int_t
 njs_object_math_log10(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    double  num;
+    njs_int_t  ret;
 
-    if (nargs > 1) {
-        num = log10(njs_number(&args[1]));
+    if (njs_slow_path(nargs < 2)) {
+        njs_set_number(&vm->retval, NAN);
+        return NJS_OK;
+    }
 
-    } else {
-        num = NAN;
+    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, num);
+    njs_set_number(&vm->retval, log10(njs_number(&args[1])));
 
     return NJS_OK;
 }
@@ -452,16 +574,21 @@ static njs_int_t
 njs_object_math_log1p(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    double  num;
+    njs_int_t  ret;
 
-    if (nargs > 1) {
-        num = log1p(njs_number(&args[1]));
+    if (njs_slow_path(nargs < 2)) {
+        njs_set_number(&vm->retval, NAN);
+        return NJS_OK;
+    }
 
-    } else {
-        num = NAN;
+    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, num);
+    njs_set_number(&vm->retval, log1p(njs_number(&args[1])));
 
     return NJS_OK;
 }
@@ -471,25 +598,31 @@ 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;
+    double     num;
+    njs_int_t  ret;
 
-    if (nargs > 1) {
-        num = njs_number(&args[1]);
+    if (njs_slow_path(nargs < 2)) {
+        njs_set_number(&vm->retval, NAN);
+        return NJS_OK;
+    }
 
-#if (NJS_SOLARIS)
-        /* On Solaris 10 log(-1) returns -Infinity. */
-        if (num < 0) {
-            num = NAN;
+    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;
         }
-#endif
+    }
 
-        num = log2(num);
+    num = njs_number(&args[1]);
 
-    } else {
+#if (NJS_SOLARIS)
+    /* On Solaris 10 log(-1) returns -Infinity. */
+    if (num < 0) {
         num = NAN;
     }
+#endif
 
-    njs_set_number(&vm->retval, num);
+    njs_set_number(&vm->retval, log2(num));
 
     return NJS_OK;
 }
@@ -573,24 +706,39 @@ 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;
+    double     num, base, exponent;
+    njs_int_t  ret;
 
-    if (nargs > 2) {
-        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 (njs_slow_path(nargs < 3)) {
+        njs_set_number(&vm->retval, NAN);
+        return NJS_OK;
+    }
 
-        if (fabs(base) != 1 || (!isnan(exponent) && !isinf(exponent))) {
-            num = pow(base, exponent);
+    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;
+    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;
@@ -620,16 +768,21 @@ static njs_int_t
 njs_object_math_round(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    double  num;
+    njs_int_t  ret;
 
-    if (nargs > 1) {
-        num = round(njs_number(&args[1]));
+    if (njs_slow_path(nargs < 2)) {
+        njs_set_number(&vm->retval, NAN);
+        return NJS_OK;
+    }
 
-    } else {
-        num = NAN;
+    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, num);
+    njs_set_number(&vm->retval, round(njs_number(&args[1])));
 
     return NJS_OK;
 }
@@ -639,17 +792,25 @@ 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;
+    double     num;
+    njs_int_t  ret;
 
-    if (nargs > 1) {
-        num = njs_number(&args[1]);
+    if (njs_slow_path(nargs < 2)) {
+         njs_set_number(&vm->retval, NAN);
+         return NJS_OK;
+    }
 
-        if (!isnan(num) && num != 0) {
-            num = signbit(num) ? -1 : 1;
+    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;
+    num = njs_number(&args[1]);
+
+    if (!isnan(num) && num != 0) {
+        num = signbit(num) ? -1 : 1;
     }
 
     njs_set_number(&vm->retval, num);
@@ -662,16 +823,21 @@ static njs_int_t
 njs_object_math_sin(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    double  num;
+    njs_int_t  ret;
 
-    if (nargs > 1) {
-        num = sin(njs_number(&args[1]));
+    if (njs_slow_path(nargs < 2)) {
+        njs_set_number(&vm->retval, NAN);
+        return NJS_OK;
+    }
 
-    } else {
-        num = NAN;
+    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, num);
+    njs_set_number(&vm->retval, sin(njs_number(&args[1])));
 
     return NJS_OK;
 }
@@ -681,16 +847,21 @@ static njs_int_t
 njs_object_math_sinh(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    double  num;
+    njs_int_t  ret;
 
-    if (nargs > 1) {
-        num = sinh(njs_number(&args[1]));
+    if (njs_slow_path(nargs < 2)) {
+        njs_set_number(&vm->retval, NAN);
+        return NJS_OK;
+    }
 
-    } else {
-        num = NAN;
+    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, num);
+    njs_set_number(&vm->retval, sinh(njs_number(&args[1])));
 
     return NJS_OK;
 }
@@ -700,16 +871,21 @@ static njs_int_t
 njs_object_math_sqrt(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    double  num;
+    njs_int_t  ret;
 
-    if (nargs > 1) {
-        num = sqrt(njs_number(&args[1]));
+    if (njs_slow_path(nargs < 2)) {
+        njs_set_number(&vm->retval, NAN);
+        return NJS_OK;
+    }
 
-    } else {
-        num = NAN;
+    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, num);
+    njs_set_number(&vm->retval, sqrt(njs_number(&args[1])));
 
     return NJS_OK;
 }
@@ -719,16 +895,21 @@ static njs_int_t
 njs_object_math_tan(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    double  num;
+    njs_int_t  ret;
 
-    if (nargs > 1) {
-        num = tan(njs_number(&args[1]));
+    if (njs_slow_path(nargs < 2)) {
+        njs_set_number(&vm->retval, NAN);
+        return NJS_OK;
+    }
 
-    } else {
-        num = NAN;
+    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, num);
+    njs_set_number(&vm->retval, tan(njs_number(&args[1])));
 
     return NJS_OK;
 }
@@ -738,16 +919,21 @@ static njs_int_t
 njs_object_math_tanh(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    double  num;
+    njs_int_t  ret;
 
-    if (nargs > 1) {
-        num = tanh(njs_number(&args[1]));
+    if (njs_slow_path(nargs < 2)) {
+        njs_set_number(&vm->retval, NAN);
+        return NJS_OK;
+    }
 
-    } else {
-        num = NAN;
+    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, num);
+    njs_set_number(&vm->retval, tanh(njs_number(&args[1])));
 
     return NJS_OK;
 }
@@ -757,16 +943,21 @@ static njs_int_t
 njs_object_math_trunc(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    double  num;
+    njs_int_t  ret;
 
-    if (nargs > 1) {
-        num = trunc(njs_number(&args[1]));
+    if (njs_slow_path(nargs < 2)) {
+        njs_set_number(&vm->retval, NAN);
+        return NJS_OK;
+    }
 
-    } else {
-        num = NAN;
+    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, num);
+    njs_set_number(&vm->retval, trunc(njs_number(&args[1])));
 
     return NJS_OK;
 }
@@ -833,8 +1024,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,
-                                     NJS_SKIP_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_object_math_abs, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -842,8 +1032,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,
-                                     NJS_SKIP_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_object_math_acos, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -852,8 +1041,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,
-                                     NJS_SKIP_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_object_math_acosh, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -861,8 +1049,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,
-                                     NJS_SKIP_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_object_math_asin, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -871,8 +1058,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,
-                                     NJS_SKIP_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_object_math_asinh, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -880,8 +1066,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,
-                                     NJS_SKIP_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_object_math_atan, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -889,8 +1074,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,
-                     NJS_SKIP_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_object_math_atan2, 2),
         .writable = 1,
         .configurable = 1,
     },
@@ -899,8 +1083,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,
-                                     NJS_SKIP_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_object_math_atanh, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -909,8 +1092,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,
-                                     NJS_SKIP_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_object_math_cbrt, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -918,8 +1100,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,
-                                     NJS_SKIP_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_object_math_ceil, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -928,8 +1109,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,
-                                     NJS_SKIP_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_object_math_clz32, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -937,8 +1117,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,
-                                     NJS_SKIP_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_object_math_cos, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -947,8 +1126,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,
-                                     NJS_SKIP_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_object_math_cosh, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -956,8 +1134,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,
-                                     NJS_SKIP_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_object_math_exp, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -966,8 +1143,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,
-                                     NJS_SKIP_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_object_math_expm1, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -975,8 +1151,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,
-                                     NJS_SKIP_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_object_math_floor, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -985,8 +1160,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,
-                                     NJS_SKIP_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_object_math_fround, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -995,7 +1169,7 @@ static const njs_object_prop_t  njs_math_object_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("hypot"),
-        .value = njs_native_function(njs_object_math_hypot, 2, 0),
+        .value = njs_native_function(njs_object_math_hypot, 2),
         .writable = 1,
         .configurable = 1,
     },
@@ -1004,8 +1178,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,
-                     NJS_SKIP_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_object_math_imul, 2),
         .writable = 1,
         .configurable = 1,
     },
@@ -1013,8 +1186,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,
-                                     NJS_SKIP_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_object_math_log, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1023,8 +1195,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,
-                                     NJS_SKIP_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_object_math_log10, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1033,8 +1204,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,
-                                     NJS_SKIP_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_object_math_log1p, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1043,8 +1213,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,
-                                     NJS_SKIP_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_object_math_log2, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1052,7 +1221,7 @@ static const njs_object_prop_t  njs_math_object_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("max"),
-        .value = njs_native_function(njs_object_math_max, 2, 0),
+        .value = njs_native_function(njs_object_math_max, 2),
         .writable = 1,
         .configurable = 1,
     },
@@ -1060,7 +1229,7 @@ static const njs_object_prop_t  njs_math_object_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("min"),
-        .value = njs_native_function(njs_object_math_min, 2, 0),
+        .value = njs_native_function(njs_object_math_min, 2),
         .writable = 1,
         .configurable = 1,
     },
@@ -1068,8 +1237,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,
-                     NJS_SKIP_ARG, NJS_NUMBER_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_object_math_pow, 2),
         .writable = 1,
         .configurable = 1,
     },
@@ -1077,7 +1245,7 @@ static const njs_object_prop_t  njs_math_object_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("random"),
-        .value = njs_native_function(njs_object_math_random, 0, 0),
+        .value = njs_native_function(njs_object_math_random, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -1085,8 +1253,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,
-                                     NJS_SKIP_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_object_math_round, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1095,8 +1262,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,
-                                     NJS_SKIP_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_object_math_sign, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1104,8 +1270,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,
-                                     NJS_SKIP_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_object_math_sin, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1114,8 +1279,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,
-                                     NJS_SKIP_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_object_math_sinh, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1123,8 +1287,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,
-                                     NJS_SKIP_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_object_math_sqrt, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1132,8 +1295,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,
-                                     NJS_SKIP_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_object_math_tan, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1142,8 +1304,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,
-                                     NJS_SKIP_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_object_math_tanh, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1152,8 +1313,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,
-                                     NJS_SKIP_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_object_math_trunc, 1),
         .writable = 1,
         .configurable = 1,
     },
index 68eef62ebc11b322f2807f1cd3b96fdd9bc48a2f..1f3d508cfec6e93429b92da62ade4776abed539c 100644 (file)
@@ -506,6 +506,7 @@ njs_int_t
 njs_module_require(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
+    njs_int_t           ret;
     njs_object_t        *object;
     njs_module_t        *module;
     njs_lvlhsh_query_t  lhq;
@@ -515,6 +516,13 @@ njs_module_require(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
+    if (njs_slow_path(!njs_is_string(&args[1]))) {
+        ret = njs_value_to_string(vm, &args[1], &args[1]);
+        if (njs_slow_path(ret != NJS_OK)) {
+            return ret;
+        }
+    }
+
     njs_string_get(&args[1], &lhq.key);
     lhq.key_hash = njs_djb_hash(lhq.key.start, lhq.key.length);
     lhq.proto = &njs_modules_hash_proto;
index c74d2a72f2ce989d3fc1f711325d474b24b9ec38..b1f8fc112c714b549d246fe2864f7ba0875adea0 100644 (file)
@@ -241,14 +241,22 @@ njs_int_t
 njs_number_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    njs_object_t       *object;
-    const njs_value_t  *value;
+    njs_int_t     ret;
+    njs_value_t   *value;
+    njs_object_t  *object;
 
     if (nargs == 1) {
-        value = &njs_value_zero;
+        value = njs_value_arg(&njs_value_zero);
 
     } else {
         value = &args[1];
+
+        if (njs_slow_path(!njs_is_number(value))) {
+            ret = njs_value_to_numeric(vm, value, value);
+            if (njs_slow_path(ret != NJS_OK)) {
+                return NJS_ERROR;
+            }
+        }
     }
 
     if (vm->top_frame->ctor) {
@@ -335,6 +343,29 @@ njs_number_is_nan(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 }
 
 
+static njs_int_t
+njs_number_is_finite(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
+    njs_index_t unused)
+{
+    double             num;
+    const njs_value_t  *value;
+
+    value = &njs_value_false;
+
+    if (nargs > 1 && njs_is_number(&args[1])) {
+        num = njs_number(&args[1]);
+
+        if (!isnan(num) && !isinf(num)) {
+            value = &njs_value_true;
+        }
+    }
+
+    vm->retval = *value;
+
+    return NJS_OK;
+}
+
+
 static const njs_object_prop_t  njs_number_constructor_properties[] =
 {
     /* Number.name == "Number". */
@@ -415,7 +446,7 @@ static const njs_object_prop_t  njs_number_constructor_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("isFinite"),
-        .value = njs_native_function(njs_number_is_finite, 1, 0),
+        .value = njs_native_function(njs_number_is_finite, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -424,7 +455,7 @@ static const njs_object_prop_t  njs_number_constructor_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("isInteger"),
-        .value = njs_native_function(njs_number_is_integer, 1, 0),
+        .value = njs_native_function(njs_number_is_integer, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -433,7 +464,7 @@ static const njs_object_prop_t  njs_number_constructor_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("isSafeInteger"),
-        .value = njs_native_function(njs_number_is_safe_integer, 1, 0),
+        .value = njs_native_function(njs_number_is_safe_integer, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -442,7 +473,7 @@ static const njs_object_prop_t  njs_number_constructor_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("isNaN"),
-        .value = njs_native_function(njs_number_is_nan, 1, 0),
+        .value = njs_native_function(njs_number_is_nan, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -451,8 +482,7 @@ static const njs_object_prop_t  njs_number_constructor_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("parseFloat"),
-        .value = njs_native_function(njs_number_parse_float, 1,
-                                     NJS_SKIP_ARG, NJS_STRING_ARG),
+        .value = njs_native_function(njs_number_parse_float, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -461,8 +491,7 @@ static const njs_object_prop_t  njs_number_constructor_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("parseInt"),
-        .value = njs_native_function(njs_number_parse_int, 2,
-                     NJS_SKIP_ARG, NJS_STRING_ARG, NJS_INTEGER_ARG),
+        .value = njs_native_function(njs_number_parse_int, 2),
         .writable = 1,
         .configurable = 1,
     },
@@ -506,7 +535,9 @@ static njs_int_t
 njs_number_prototype_to_string(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused)
 {
-    double       number, radix;
+    double       number;
+    int32_t      radix;
+    njs_int_t    ret;
     njs_value_t  *value;
 
     value = &args[0];
@@ -524,7 +555,10 @@ njs_number_prototype_to_string(njs_vm_t *vm, njs_value_t *args,
     }
 
     if (nargs > 1) {
-        radix = njs_number(&args[1]);
+        ret = njs_value_to_int32(vm, &args[1], &radix);
+        if (njs_slow_path(ret != NJS_OK)) {
+            return ret;
+        }
 
         if (radix < 2 || radix > 36 || radix != (int) radix) {
             njs_range_error(vm, NULL);
@@ -671,17 +705,17 @@ njs_number_prototype_to_precision(njs_vm_t *vm, njs_value_t *args,
         return njs_number_to_string(vm, &vm->retval, value);
     }
 
+    ret = njs_value_to_integer(vm, njs_argument(args, 1), &precision);
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
+    }
+
     number = njs_number(value);
 
     if (njs_slow_path(isnan(number) || isinf(number))) {
         return njs_number_to_string(vm, &vm->retval, value);
     }
 
-    ret = njs_value_to_integer(vm, njs_argument(args, 1), &precision);
-    if (njs_slow_path(ret != NJS_OK)) {
-        return ret;
-    }
-
     if (njs_slow_path(precision < 1 || precision > 100)) {
         njs_range_error(vm, "precision argument must be between 1 and 100");
         return NJS_ERROR;
@@ -701,7 +735,7 @@ njs_number_prototype_to_exponential(njs_vm_t *vm, njs_value_t *args,
     size_t       size;
     int64_t      frac;
     njs_int_t    ret;
-    njs_value_t  *value;
+    njs_value_t  *value, *value_frac;
     u_char       buf[128];
 
     value = &args[0];
@@ -717,18 +751,20 @@ njs_number_prototype_to_exponential(njs_vm_t *vm, njs_value_t *args,
         }
     }
 
+    value_frac = njs_arg(args, nargs, 1);
+
+    ret = njs_value_to_integer(vm, value_frac, &frac);
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
+    }
+
     number = njs_number(value);
 
     if (njs_slow_path(isnan(number) || isinf(number))) {
         return njs_number_to_string(vm, &vm->retval, value);
     }
 
-    if (njs_is_defined(njs_arg(args, nargs, 1))) {
-        ret = njs_value_to_integer(vm, njs_argument(args, 1), &frac);
-        if (njs_slow_path(ret != NJS_OK)) {
-            return ret;
-        }
-
+    if (njs_is_defined(value_frac)) {
         if (njs_slow_path(frac < 0 || frac > 100)) {
             njs_range_error(vm, "digits argument must be between 0 and 100");
             return NJS_ERROR;
@@ -887,7 +923,7 @@ static const njs_object_prop_t  njs_number_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("valueOf"),
-        .value = njs_native_function(njs_number_prototype_value_of, 0, 0),
+        .value = njs_native_function(njs_number_prototype_value_of, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -895,8 +931,7 @@ static const njs_object_prop_t  njs_number_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("toString"),
-        .value = njs_native_function(njs_number_prototype_to_string, 1,
-                                     NJS_SKIP_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_number_prototype_to_string, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -904,8 +939,7 @@ static const njs_object_prop_t  njs_number_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("toFixed"),
-        .value = njs_native_function(njs_number_prototype_to_fixed, 1,
-                                     NJS_SKIP_ARG, NJS_INTEGER_ARG),
+        .value = njs_native_function(njs_number_prototype_to_fixed, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -913,8 +947,7 @@ static const njs_object_prop_t  njs_number_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("toPrecision"),
-        .value = njs_native_function(njs_number_prototype_to_precision, 1,
-                                     NJS_SKIP_ARG, NJS_INTEGER_ARG),
+        .value = njs_native_function(njs_number_prototype_to_precision, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -922,8 +955,7 @@ static const njs_object_prop_t  njs_number_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("toExponential"),
-        .value = njs_native_function(njs_number_prototype_to_exponential, 1,
-                                     NJS_SKIP_ARG, NJS_INTEGER_ARG),
+        .value = njs_native_function(njs_number_prototype_to_exponential, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -941,38 +973,33 @@ njs_int_t
 njs_number_global_is_nan(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    const njs_value_t  *value;
+    double     num;
+    njs_int_t  ret;
 
-    value = &njs_value_true;
-
-    if (nargs > 1 && !isnan(njs_number(&args[1]))) {
-        value = &njs_value_false;
+    ret = njs_value_to_number(vm, njs_arg(args, nargs, 1), &num);
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
     }
 
-    vm->retval = *value;
+    njs_set_boolean(&vm->retval, isnan(num));
 
     return NJS_OK;
 }
 
 
 njs_int_t
-njs_number_is_finite(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
+njs_number_global_is_finite(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    double             num;
-    const njs_value_t  *value;
+    double     num;
+    njs_int_t  ret;
 
-    value = &njs_value_false;
-
-    if (nargs > 1 && njs_is_number(&args[1])) {
-        num = njs_number(&args[1]);
-
-        if (!isnan(num) && !isinf(num)) {
-            value = &njs_value_true;
-        }
+    ret = njs_value_to_number(vm, njs_arg(args, nargs, 1), &num);
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
     }
 
-    vm->retval = *value;
+    njs_set_boolean(&vm->retval, !(isnan(num) || isinf(num)));
 
     return NJS_OK;
 }
@@ -982,72 +1009,88 @@ njs_int_t
 njs_number_parse_int(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    double             num;
-    int64_t            n;
-    uint8_t            radix;
-    njs_str_t          string;
-    njs_bool_t         minus, test_prefix;
-    const u_char       *p, *end;
+    double        num;
+    int64_t       n;
+    int32_t       radix;
+    njs_int_t     ret;
+    njs_str_t     string;
+    njs_bool_t    minus, test_prefix;
+    njs_value_t   *value;
+    const u_char  *p, *end;
 
     num = NAN;
 
-    if (nargs > 1) {
-        njs_string_get(&args[1], &string);
+    if (nargs < 2) {
+        goto done;
+    }
 
-        end = string.start + string.length;
+    value = njs_argument(args, 1);
 
-        for (p = string.start; p < end; p++) {
-            if (*p != ' ') {
-                goto found;
-            }
+    if (!njs_is_string(value)) {
+        ret = njs_value_to_string(vm, value, value);
+        if (njs_slow_path(ret != NJS_OK)) {
+            return ret;
         }
+    }
 
-        goto done;
+    njs_string_get(value, &string);
 
-    found:
+    end = string.start + string.length;
 
-        minus = 0;
+    for (p = string.start; p < end; p++) {
+        if (*p != ' ') {
+            goto found;
+        }
+    }
 
-        if (p[0] == '-') {
-            p++;
-            minus = 1;
+    goto done;
 
-        } else if (p[0] == '+') {
-            p++;
-        }
+found:
 
-        test_prefix = (end - p > 1);
-        radix = 0;
+    minus = 0;
 
-        if (nargs > 2) {
-            radix = njs_number(&args[2]);
+    if (p[0] == '-') {
+        p++;
+        minus = 1;
 
-            if (radix != 0) {
-                if (radix < 2 || radix > 36) {
-                    goto done;
-                }
+    } else if (p[0] == '+') {
+        p++;
+    }
 
-                if (radix != 16) {
-                    test_prefix = 0;
-                }
-            }
-        }
+    test_prefix = (end - p > 1);
+    radix = 0;
 
-        if (radix == 0) {
-            radix = 10;
+    if (nargs > 2) {
+        ret = njs_value_to_int32(vm, njs_argument(args, 2), &radix);
+        if (njs_slow_path(ret != NJS_OK)) {
+            return ret;
         }
 
-        if (test_prefix && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
-            p += 2;
-            radix = 16;
+        if (radix != 0) {
+            if (radix < 2 || radix > 36) {
+                goto done;
+            }
+
+            if (radix != 16) {
+                test_prefix = 0;
+            }
         }
+    }
 
-        n = njs_number_radix_parse(&p, end, radix);
+    if (radix == 0) {
+        radix = 10;
+    }
 
-        if (n >= 0) {
-            num = n;
-            num = minus ? -num : num;
-        }
+    if (test_prefix && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
+        p += 2;
+        radix = 16;
+    }
+
+    n = njs_number_radix_parse(&p, end, radix);
+
+    if (n >= 0) {
+        num = n;
+        num = minus ? -num : num;
     }
 
 done:
@@ -1062,11 +1105,17 @@ njs_int_t
 njs_number_parse_float(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    double  num;
+    double     num;
+    njs_int_t  ret;
 
     num = NAN;
 
     if (nargs > 1) {
+        ret = njs_value_to_string(vm, &args[1], &args[1]);
+        if (njs_slow_path(ret != NJS_OK)) {
+            return ret;
+        }
+
         num = njs_string_to_number(&args[1], 1);
     }
 
index 5924e6da698d42f77a0c9c7888cd9bec2e50b219..3fcc5c0b7cfa0241ea2bac2fe653fe2fc9e7df3d 100644 (file)
@@ -21,7 +21,7 @@ njs_int_t njs_number_constructor(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused);
 njs_int_t njs_number_global_is_nan(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused);
-njs_int_t njs_number_is_finite(njs_vm_t *vm, njs_value_t *args,
+njs_int_t njs_number_global_is_finite(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused);
 njs_int_t njs_number_parse_int(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused);
index d29ce635666feaa2cfde004d99fb18760e78bf0f..cb17691ea1687498688b67b21dd19becc26d28d2 100644 (file)
@@ -1112,6 +1112,18 @@ njs_object_define_property(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     name = njs_arg(args, nargs, 2);
 
+    if (njs_slow_path(!njs_is_string(name))) {
+        if (njs_is_undefined(name)) {
+            name = njs_value_arg(&njs_string_undefined);
+
+        } else {
+            ret = njs_value_to_string(vm, name, name);
+            if (njs_slow_path(ret != NJS_OK)) {
+                return ret;
+            }
+        }
+    }
+
     ret = njs_object_prop_define(vm, value, name, desc,
                                  NJS_OBJECT_PROP_DESCRIPTOR);
     if (njs_slow_path(ret != NJS_OK)) {
@@ -1679,7 +1691,7 @@ static const njs_object_prop_t  njs_object_constructor_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("create"),
-        .value = njs_native_function(njs_object_create, 2, 0),
+        .value = njs_native_function(njs_object_create, 2),
         .writable = 1,
         .configurable = 1,
     },
@@ -1688,8 +1700,7 @@ static const njs_object_prop_t  njs_object_constructor_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("keys"),
-        .value = njs_native_function(njs_object_keys, 1,
-                                     NJS_SKIP_ARG, NJS_OBJECT_ARG),
+        .value = njs_native_function(njs_object_keys, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1698,8 +1709,7 @@ static const njs_object_prop_t  njs_object_constructor_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("values"),
-        .value = njs_native_function(njs_object_values, 1,
-                                     NJS_SKIP_ARG, NJS_OBJECT_ARG),
+        .value = njs_native_function(njs_object_values, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1708,8 +1718,7 @@ static const njs_object_prop_t  njs_object_constructor_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("entries"),
-        .value = njs_native_function(njs_object_entries, 1,
-                                     NJS_SKIP_ARG, NJS_OBJECT_ARG),
+        .value = njs_native_function(njs_object_entries, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1718,9 +1727,7 @@ static const njs_object_prop_t  njs_object_constructor_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("defineProperty"),
-        .value = njs_native_function(njs_object_define_property, 3,
-                                     NJS_SKIP_ARG, NJS_OBJECT_ARG,
-                                     NJS_STRING_ARG, NJS_OBJECT_ARG),
+        .value = njs_native_function(njs_object_define_property, 3),
         .writable = 1,
         .configurable = 1,
     },
@@ -1729,9 +1736,7 @@ static const njs_object_prop_t  njs_object_constructor_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_long_string("defineProperties"),
-        .value = njs_native_function(njs_object_define_properties, 2,
-                                     NJS_SKIP_ARG, NJS_OBJECT_ARG,
-                                     NJS_OBJECT_ARG),
+        .value = njs_native_function(njs_object_define_properties, 2),
         .writable = 1,
         .configurable = 1,
     },
@@ -1740,9 +1745,7 @@ static const njs_object_prop_t  njs_object_constructor_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_long_string("getOwnPropertyDescriptor"),
-        .value = njs_native_function(njs_object_get_own_property_descriptor, 2,
-                                     NJS_SKIP_ARG, NJS_SKIP_ARG,
-                                     NJS_STRING_ARG),
+        .value = njs_native_function(njs_object_get_own_property_descriptor, 2),
         .writable = 1,
         .configurable = 1,
     },
@@ -1751,8 +1754,8 @@ static const njs_object_prop_t  njs_object_constructor_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_long_string("getOwnPropertyDescriptors"),
-        .value = njs_native_function(njs_object_get_own_property_descriptors, 1,
-                                     NJS_SKIP_ARG, NJS_OBJECT_ARG),
+        .value = njs_native_function(njs_object_get_own_property_descriptors,
+                                     1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1761,8 +1764,7 @@ static const njs_object_prop_t  njs_object_constructor_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_long_string("getOwnPropertyNames"),
-        .value = njs_native_function(njs_object_get_own_property_names, 1,
-                                     NJS_SKIP_ARG, NJS_OBJECT_ARG),
+        .value = njs_native_function(njs_object_get_own_property_names, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1771,8 +1773,7 @@ static const njs_object_prop_t  njs_object_constructor_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("getPrototypeOf"),
-        .value = njs_native_function(njs_object_get_prototype_of, 1,
-                                     NJS_SKIP_ARG, NJS_OBJECT_ARG),
+        .value = njs_native_function(njs_object_get_prototype_of, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1781,8 +1782,7 @@ static const njs_object_prop_t  njs_object_constructor_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("freeze"),
-        .value = njs_native_function(njs_object_freeze, 1,
-                                     NJS_SKIP_ARG, NJS_OBJECT_ARG),
+        .value = njs_native_function(njs_object_freeze, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1791,8 +1791,7 @@ static const njs_object_prop_t  njs_object_constructor_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("isFrozen"),
-        .value = njs_native_function(njs_object_is_frozen, 1,
-                                     NJS_SKIP_ARG, NJS_OBJECT_ARG),
+        .value = njs_native_function(njs_object_is_frozen, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1801,8 +1800,7 @@ static const njs_object_prop_t  njs_object_constructor_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("seal"),
-        .value = njs_native_function(njs_object_seal, 1,
-                                     NJS_SKIP_ARG, NJS_OBJECT_ARG),
+        .value = njs_native_function(njs_object_seal, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1811,8 +1809,7 @@ static const njs_object_prop_t  njs_object_constructor_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("isSealed"),
-        .value = njs_native_function(njs_object_is_sealed, 1,
-                                     NJS_SKIP_ARG, NJS_OBJECT_ARG),
+        .value = njs_native_function(njs_object_is_sealed, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1821,8 +1818,7 @@ static const njs_object_prop_t  njs_object_constructor_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_long_string("preventExtensions"),
-        .value = njs_native_function(njs_object_prevent_extensions, 1,
-                                     NJS_SKIP_ARG, NJS_OBJECT_ARG),
+        .value = njs_native_function(njs_object_prevent_extensions, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1831,8 +1827,7 @@ static const njs_object_prop_t  njs_object_constructor_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("isExtensible"),
-        .value = njs_native_function(njs_object_is_extensible, 1,
-                                     NJS_SKIP_ARG, NJS_OBJECT_ARG),
+        .value = njs_native_function(njs_object_is_extensible, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -2207,6 +2202,11 @@ njs_object_prototype_is_prototype_of(njs_vm_t *vm, njs_value_t *args,
     njs_object_t       *object, *proto;
     const njs_value_t  *retval;
 
+    if (njs_slow_path(njs_is_null_or_undefined(njs_arg(args, nargs, 0)))) {
+        njs_type_error(vm, "cannot convert undefined to object");
+        return NJS_ERROR;
+    }
+
     retval = &njs_value_false;
     prototype = &args[0];
     value = njs_arg(args, nargs, 1);
@@ -2253,7 +2253,7 @@ static const njs_object_prop_t  njs_object_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("valueOf"),
-        .value = njs_native_function(njs_object_prototype_value_of, 0, 0),
+        .value = njs_native_function(njs_object_prototype_value_of, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -2261,7 +2261,7 @@ static const njs_object_prop_t  njs_object_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("toString"),
-        .value = njs_native_function(njs_object_prototype_to_string, 0, 0),
+        .value = njs_native_function(njs_object_prototype_to_string, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -2269,8 +2269,7 @@ static const njs_object_prop_t  njs_object_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("hasOwnProperty"),
-        .value = njs_native_function(njs_object_prototype_has_own_property, 1,
-                                     NJS_OBJECT_ARG, NJS_STRING_ARG),
+        .value = njs_native_function(njs_object_prototype_has_own_property, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -2278,8 +2277,8 @@ static const njs_object_prop_t  njs_object_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_long_string("propertyIsEnumerable"),
-        .value = njs_native_function(njs_object_prototype_prop_is_enumerable, 1,
-                                     NJS_OBJECT_ARG, NJS_STRING_ARG),
+        .value = njs_native_function(njs_object_prototype_prop_is_enumerable,
+                                     1),
         .writable = 1,
         .configurable = 1,
     },
@@ -2287,8 +2286,7 @@ static const njs_object_prop_t  njs_object_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("isPrototypeOf"),
-        .value = njs_native_function(njs_object_prototype_is_prototype_of, 1,
-                                     NJS_OBJECT_ARG, NJS_OBJECT_ARG),
+        .value = njs_native_function(njs_object_prototype_is_prototype_of, 1),
         .writable = 1,
         .configurable = 1,
     },
index 3a45326379f0473c76fa51fd8dc9ed0ced98244d..6f7ce2a2e4b0104119a75c2be49156e046cbc243 100644 (file)
@@ -845,7 +845,8 @@ njs_regexp_prototype_test(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_int_t               ret;
     njs_uint_t              n;
     njs_regex_t             *regex;
-    const njs_value_t       *value, *retval;
+    njs_value_t             *value;
+    const njs_value_t       *retval;
     njs_string_prop_t       string;
     njs_regexp_pattern_t    *pattern;
     njs_regex_match_data_t  *match_data;
@@ -858,8 +859,17 @@ njs_regexp_prototype_test(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     retval = &njs_value_false;
 
     value = njs_arg(args, nargs, 1);
-    if (njs_is_undefined(value)) {
-        value = &njs_string_undefined;
+
+    if (!njs_is_string(value)) {
+        if (njs_is_undefined(value)) {
+            value = njs_value_arg(&njs_string_undefined);
+
+        } else {
+            ret = njs_value_to_string(vm, value, value);
+            if (njs_slow_path(ret != NJS_OK)) {
+                return ret;
+            }
+        }
     }
 
     (void) njs_string_prop(&string, value);
@@ -911,10 +921,10 @@ njs_regexp_prototype_exec(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 {
     njs_int_t               ret;
     njs_utf8_t              utf8;
+    njs_value_t             *value;
     njs_regexp_t            *regexp;
     njs_string_prop_t       string;
     njs_regexp_utf8_t       type;
-    const njs_value_t       *value;
     njs_regexp_pattern_t    *pattern;
     njs_regex_match_data_t  *match_data;
 
@@ -924,8 +934,17 @@ njs_regexp_prototype_exec(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     value = njs_arg(args, nargs, 1);
-    if (njs_is_undefined(value)) {
-        value = &njs_string_undefined;
+
+    if (!njs_is_string(value)) {
+        if (njs_is_undefined(value)) {
+            value = njs_value_arg(&njs_string_undefined);
+
+        } else {
+            ret = njs_value_to_string(vm, value, value);
+            if (njs_slow_path(ret != NJS_OK)) {
+                return ret;
+            }
+        }
     }
 
     regexp = njs_regexp(&args[0]);
@@ -1232,7 +1251,7 @@ static const njs_object_prop_t  njs_regexp_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("toString"),
-        .value = njs_native_function(njs_regexp_prototype_to_string, 0, 0),
+        .value = njs_native_function(njs_regexp_prototype_to_string, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -1240,8 +1259,7 @@ static const njs_object_prop_t  njs_regexp_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("test"),
-        .value = njs_native_function(njs_regexp_prototype_test, 1,
-                                     NJS_OBJECT_ARG, NJS_STRING_ARG),
+        .value = njs_native_function(njs_regexp_prototype_test, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -1249,8 +1267,7 @@ static const njs_object_prop_t  njs_regexp_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("exec"),
-        .value = njs_native_function(njs_regexp_prototype_exec, 1,
-                                     NJS_OBJECT_ARG, NJS_STRING_ARG),
+        .value = njs_native_function(njs_regexp_prototype_exec, 1),
         .writable = 1,
         .configurable = 1,
     },
index b9abfac45d40e94e8312dfc6f2b56dc4ea8ff512..1144cd2798da9af462ad08313dc98e2dae9f6d6b 100644 (file)
@@ -54,10 +54,10 @@ static void njs_encode_base64_core(njs_str_t *dst, const njs_str_t *src,
     const u_char *basis, njs_uint_t padding);
 static njs_int_t njs_decode_base64_core(njs_vm_t *vm,
     njs_value_t *value, const njs_str_t *src, const u_char *basis);
-static void njs_string_slice_prop(njs_string_prop_t *string,
+static njs_int_t njs_string_slice_prop(njs_vm_t *vm, njs_string_prop_t *string,
     njs_slice_prop_t *slice, njs_value_t *args, njs_uint_t nargs);
-static void njs_string_slice_args(njs_slice_prop_t *slice, njs_value_t *args,
-    njs_uint_t nargs);
+static njs_int_t njs_string_slice_args(njs_vm_t *vm, njs_slice_prop_t *slice,
+    njs_value_t *args, njs_uint_t nargs);
 static njs_int_t njs_string_from_char_code(njs_vm_t *vm,
     njs_value_t *args, njs_uint_t nargs, njs_index_t unused);
 static njs_int_t njs_string_from_code_point(njs_vm_t *vm, njs_value_t *args,
@@ -541,14 +541,22 @@ njs_int_t
 njs_string_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    njs_object_t       *object;
-    const njs_value_t  *value;
+    njs_int_t     ret;
+    njs_value_t   *value;
+    njs_object_t  *object;
 
     if (nargs == 1) {
-        value = &njs_string_empty;
+        value = njs_value_arg(&njs_string_empty);
 
     } else {
         value = &args[1];
+
+        if (njs_slow_path(!njs_is_string(value))) {
+            ret = njs_value_to_string(vm, value, value);
+            if (njs_slow_path(ret != NJS_OK)) {
+                return ret;
+            }
+        }
     }
 
     if (vm->top_frame->ctor) {
@@ -596,8 +604,7 @@ static const njs_object_prop_t  njs_string_constructor_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("bytesFrom"),
-        .value = njs_native_function(njs_string_bytes_from, 0, NJS_SKIP_ARG,
-                                     NJS_SKIP_ARG, NJS_STRING_ARG),
+        .value = njs_native_function(njs_string_bytes_from, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -606,7 +613,7 @@ static const njs_object_prop_t  njs_string_constructor_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("fromCharCode"),
-        .value = njs_native_function(njs_string_from_char_code, 1, 0),
+        .value = njs_native_function(njs_string_from_char_code, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -615,7 +622,7 @@ static const njs_object_prop_t  njs_string_constructor_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("fromCodePoint"),
-        .value = njs_native_function(njs_string_from_code_point, 1, 0),
+        .value = njs_native_function(njs_string_from_code_point, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -928,6 +935,27 @@ njs_string_prototype_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 }
 
 
+njs_inline njs_int_t
+njs_string_object_validate(njs_vm_t *vm, njs_value_t *object)
+{
+    njs_int_t  ret;
+
+    if (njs_slow_path(njs_is_null_or_undefined(object))) {
+        njs_type_error(vm, "cannot convert undefined to object");
+        return NJS_ERROR;
+    }
+
+    if (njs_slow_path(!njs_is_string(object))) {
+        ret = njs_value_to_string(vm, object, object);
+        if (njs_slow_path(ret != NJS_OK)) {
+            return ret;
+        }
+    }
+
+    return NJS_OK;
+}
+
+
 /*
  * String.fromUTF8(start[, end]).
  * The method converts an UTF-8 encoded byte string to an Unicode string.
@@ -938,10 +966,19 @@ njs_string_prototype_from_utf8(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused)
 {
     ssize_t            length;
+    njs_int_t          ret;
     njs_slice_prop_t   slice;
     njs_string_prop_t  string;
 
-    njs_string_slice_prop(&string, &slice, args, nargs);
+    ret = njs_string_object_validate(vm, njs_arg(args, nargs, 0));
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
+    }
+
+    ret = njs_string_slice_prop(vm, &string, &slice, args, nargs);
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
+    }
 
     if (string.length != 0) {
         /* ASCII or UTF8 string. */
@@ -972,15 +1009,24 @@ static njs_int_t
 njs_string_prototype_to_utf8(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
+    njs_int_t          ret;
     njs_slice_prop_t   slice;
     njs_string_prop_t  string;
 
-    (void) njs_string_prop(&string, &args[0]);
+    ret = njs_string_object_validate(vm, njs_arg(args, nargs, 0));
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
+    }
+
+    (void) njs_string_prop(&string, njs_argument(args, 0));
 
     string.length = 0;
     slice.string_length = string.size;
 
-    njs_string_slice_args(&slice, args, nargs);
+    ret = njs_string_slice_args(vm, &slice, args, nargs);
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
+    }
 
     return njs_string_slice(vm, &vm->retval, &string, &slice);
 }
@@ -997,10 +1043,19 @@ njs_string_prototype_from_bytes(njs_vm_t *vm, njs_value_t *args,
 {
     u_char             *p, *s, *start, *end;
     size_t             size;
+    njs_int_t          ret;
     njs_slice_prop_t   slice;
     njs_string_prop_t  string;
 
-    njs_string_slice_prop(&string, &slice, args, nargs);
+    ret = njs_string_object_validate(vm, njs_arg(args, nargs, 0));
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
+    }
+
+    ret = njs_string_slice_prop(vm, &string, &slice, args, nargs);
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
+    }
 
     if (string.length != 0) {
         /* ASCII or UTF8 string. */
@@ -1052,11 +1107,20 @@ njs_string_prototype_to_bytes(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     u_char             *p;
     size_t             length;
     uint32_t           byte;
+    njs_int_t          ret;
     const u_char       *s, *end;
     njs_slice_prop_t   slice;
     njs_string_prop_t  string;
 
-    njs_string_slice_prop(&string, &slice, args, nargs);
+    ret = njs_string_object_validate(vm, njs_arg(args, nargs, 0));
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
+    }
+
+    ret = njs_string_slice_prop(vm, &string, &slice, args, nargs);
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
+    }
 
     if (string.length == 0) {
         /* Byte string. */
@@ -1110,10 +1174,19 @@ static njs_int_t
 njs_string_prototype_slice(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
+    njs_int_t          ret;
     njs_slice_prop_t   slice;
     njs_string_prop_t  string;
 
-    njs_string_slice_prop(&string, &slice, args, nargs);
+    ret = njs_string_object_validate(vm, njs_arg(args, nargs, 0));
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
+    }
+
+    ret = njs_string_slice_prop(vm, &string, &slice, args, nargs);
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
+    }
 
     return njs_string_slice(vm, &vm->retval, &string, &slice);
 }
@@ -1128,17 +1201,34 @@ static njs_int_t
 njs_string_prototype_substring(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused)
 {
-    ssize_t            start, end, length;
+    int64_t            start, end, length;
+    njs_int_t          ret;
+    njs_value_t        *value;
     njs_slice_prop_t   slice;
     njs_string_prop_t  string;
 
-    length = njs_string_prop(&string, &args[0]);
+    ret = njs_string_object_validate(vm, njs_arg(args, nargs, 0));
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
+    }
+
+    length = njs_string_prop(&string, njs_argument(args, 0));
 
     slice.string_length = length;
     start = 0;
 
     if (nargs > 1) {
-        start = njs_number(&args[1]);
+        value = njs_argument(args, 1);
+
+        if (njs_slow_path(!njs_is_number(value))) {
+            ret = njs_value_to_integer(vm, value, &start);
+            if (njs_slow_path(ret != NJS_OK)) {
+                return ret;
+            }
+
+        } else {
+            start = njs_number_to_integer(njs_number(value));
+        }
 
         if (start < 0) {
             start = 0;
@@ -1150,7 +1240,17 @@ njs_string_prototype_substring(njs_vm_t *vm, njs_value_t *args,
         end = length;
 
         if (nargs > 2) {
-            end = njs_number(&args[2]);
+            value = njs_arg(args, nargs, 2);
+
+            if (njs_slow_path(!njs_is_number(value))) {
+                ret = njs_value_to_integer(vm, value, &end);
+                if (njs_slow_path(ret != NJS_OK)) {
+                    return ret;
+                }
+
+            } else {
+                end = njs_number_to_integer(njs_number(value));
+            }
 
             if (end < 0) {
                 end = 0;
@@ -1184,17 +1284,34 @@ static njs_int_t
 njs_string_prototype_substr(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    ssize_t            start, length, n;
+    int64_t            start, length, n;
+    njs_int_t          ret;
+    njs_value_t        *value;
     njs_slice_prop_t   slice;
     njs_string_prop_t  string;
 
-    length = njs_string_prop(&string, &args[0]);
+    ret = njs_string_object_validate(vm, njs_arg(args, nargs, 0));
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
+    }
+
+    length = njs_string_prop(&string, njs_argument(args, 0));
 
     slice.string_length = length;
     start = 0;
 
     if (nargs > 1) {
-        start = njs_number(&args[1]);
+        value = njs_arg(args, nargs, 1);
+
+        if (njs_slow_path(!njs_is_number(value))) {
+            ret = njs_value_to_integer(vm, value, &start);
+            if (njs_slow_path(ret != NJS_OK)) {
+                return ret;
+            }
+
+        } else {
+            start = njs_number_to_integer(njs_number(value));
+        }
 
         if (start < length) {
             if (start < 0) {
@@ -1208,7 +1325,17 @@ njs_string_prototype_substr(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             length -= start;
 
             if (nargs > 2) {
-                n = njs_number(&args[2]);
+                value = njs_arg(args, nargs, 2);
+
+                if (njs_slow_path(!njs_is_number(value))) {
+                    ret = njs_value_to_integer(vm, value, &n);
+                    if (njs_slow_path(ret != NJS_OK)) {
+                        return ret;
+                    }
+
+                } else {
+                    n = njs_number_to_integer(njs_number(value));
+                }
 
                 if (n < 0) {
                     length = 0;
@@ -1241,7 +1368,12 @@ njs_string_prototype_char_at(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_slice_prop_t   slice;
     njs_string_prop_t  string;
 
-    slice.string_length = njs_string_prop(&string, &args[0]);
+    ret = njs_string_object_validate(vm, njs_arg(args, nargs, 0));
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
+    }
+
+    slice.string_length = njs_string_prop(&string, njs_argument(args, 0));
 
     ret = njs_value_to_integer(vm, njs_arg(args, nargs, 1), &start);
     if (njs_slow_path(ret != NJS_OK)) {
@@ -1262,27 +1394,37 @@ njs_string_prototype_char_at(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 }
 
 
-static void
-njs_string_slice_prop(njs_string_prop_t *string, njs_slice_prop_t *slice,
-    njs_value_t *args, njs_uint_t nargs)
+static njs_int_t
+njs_string_slice_prop(njs_vm_t *vm, njs_string_prop_t *string,
+    njs_slice_prop_t *slice, njs_value_t *args, njs_uint_t nargs)
 {
     slice->string_length = njs_string_prop(string, &args[0]);
 
-    njs_string_slice_args(slice, args, nargs);
+    return njs_string_slice_args(vm, slice, args, nargs);
 }
 
 
-static void
-njs_string_slice_args(njs_slice_prop_t *slice, njs_value_t *args,
+static njs_int_t
+njs_string_slice_args(njs_vm_t *vm, njs_slice_prop_t *slice, njs_value_t *args,
     njs_uint_t nargs)
 {
-    ssize_t      start, end, length;
+    int64_t      start, end, length;
+    njs_int_t    ret;
     njs_value_t  *value;
 
     length = slice->string_length;
 
     value = njs_arg(args, nargs, 1);
-    start = njs_number(value);
+
+    if (njs_slow_path(!njs_is_number(value))) {
+        ret = njs_value_to_integer(vm, value, &start);
+        if (njs_slow_path(ret != NJS_OK)) {
+            return ret;
+        }
+
+    } else {
+        start = njs_number_to_integer(njs_number(value));
+    }
 
     if (start < 0) {
         start += length;
@@ -1297,12 +1439,21 @@ njs_string_slice_args(njs_slice_prop_t *slice, njs_value_t *args,
         length = 0;
 
     } else {
-        if (njs_is_defined(njs_arg(args, nargs, 2))) {
-            value = njs_argument(args, 2);
-            end = njs_number(value);
+        value = njs_arg(args, nargs, 2);
+
+        if (njs_slow_path(!njs_is_number(value))) {
+            if (njs_is_defined(value)) {
+                ret = njs_value_to_integer(vm, value, &end);
+                if (njs_slow_path(ret != NJS_OK)) {
+                    return ret;
+                }
+
+            } else {
+                end = length;
+            }
 
         } else {
-            end = length;
+            end = njs_number_to_integer(njs_number(value));
         }
 
         if (end < 0) {
@@ -1324,6 +1475,8 @@ njs_string_slice_args(njs_slice_prop_t *slice, njs_value_t *args,
 
     slice->start = start;
     slice->length = length;
+
+    return NJS_OK;
 }
 
 
@@ -1408,7 +1561,12 @@ njs_string_prototype_char_code_at(njs_vm_t *vm, njs_value_t *args,
     const u_char       *start, *end;
     njs_string_prop_t  string;
 
-    length = njs_string_prop(&string, &args[0]);
+    ret = njs_string_object_validate(vm, njs_arg(args, nargs, 0));
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
+    }
+
+    length = njs_string_prop(&string, njs_argument(args, 0));
 
     ret = njs_value_to_integer(vm, njs_arg(args, nargs, 1), &index);
     if (njs_slow_path(ret != NJS_OK)) {
@@ -1807,18 +1965,45 @@ static njs_int_t
 njs_string_prototype_index_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    ssize_t            index, length, search_length;
+    int64_t            index, length, search_length;
+    njs_int_t          ret;
+    njs_value_t        *value;
     const u_char       *p, *end;
     njs_string_prop_t  string, search;
 
+    ret = njs_string_object_validate(vm, njs_arg(args, nargs, 0));
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
+    }
+
     if (nargs > 1) {
-        length = njs_string_prop(&string, &args[0]);
-        search_length = njs_string_prop(&search, &args[1]);
+        length = njs_string_prop(&string, njs_argument(args, 0));
+
+        value = njs_argument(args, 1);
+
+        if (njs_slow_path(!njs_is_string(value))) {
+            ret = njs_value_to_string(vm, value, value);
+            if (njs_slow_path(ret != NJS_OK)) {
+                return ret;
+            }
+        }
+
+        search_length = njs_string_prop(&search, value);
 
         index = 0;
 
         if (nargs > 2) {
-            index = njs_number(&args[2]);
+            value = njs_argument(args, 2);
+
+            if (njs_slow_path(!njs_is_number(value))) {
+                ret = njs_value_to_integer(vm, value, &index);
+                if (njs_slow_path(ret != NJS_OK)) {
+                    return ret;
+                }
+
+            } else {
+                index = njs_number_to_integer(njs_number(value));
+            }
 
             if (index < 0) {
                 index = 0;
@@ -1879,18 +2064,34 @@ njs_string_prototype_last_index_of(njs_vm_t *vm, njs_value_t *args,
 {
     double             pos;
     ssize_t            index, start, length, search_length;
+    njs_int_t          ret;
+    njs_value_t        *value;
     const u_char       *p, *end;
     const njs_value_t  *search_string;
     njs_string_prop_t  string, search;
 
+    ret = njs_string_object_validate(vm, njs_arg(args, nargs, 0));
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
+    }
+
     index = -1;
 
-    length = njs_string_prop(&string, njs_arg(args, nargs, 0));
+    length = njs_string_prop(&string, njs_argument(args, 0));
 
     search_string = njs_arg(args, nargs, 1);
 
-    if (njs_is_undefined(search_string)) {
-        search_string = &njs_string_undefined;
+    if (njs_slow_path(!njs_is_string(search_string))) {
+        if (njs_is_undefined(search_string)) {
+            search_string = &njs_string_undefined;
+
+        } else {
+            ret = njs_value_to_string(vm, njs_value_arg(search_string),
+                                      njs_value_arg(search_string));
+            if (njs_slow_path(ret != NJS_OK)) {
+                return ret;
+            }
+        }
     }
 
     search_length = njs_string_prop(&search, search_string);
@@ -1899,7 +2100,17 @@ njs_string_prototype_last_index_of(njs_vm_t *vm, njs_value_t *args,
         goto done;
     }
 
-    pos = njs_number(njs_arg(args, nargs, 2));
+    value = njs_arg(args, nargs, 2);
+
+    if (njs_slow_path(!njs_is_number(value))) {
+        ret = njs_value_to_number(vm, value, &pos);
+        if (njs_slow_path(ret != NJS_OK)) {
+            return ret;
+        }
+
+    } else {
+        pos = njs_number(value);
+    }
 
     if (isnan(pos)) {
         index = NJS_STRING_MAX_LENGTH;
@@ -1981,32 +2192,59 @@ static njs_int_t
 njs_string_prototype_includes(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    ssize_t            index, length, search_length;
+    int64_t            index, length, search_length;
+    njs_int_t          ret;
+    njs_value_t        *value;
     const u_char       *p, *end;
     const njs_value_t  *retval;
     njs_string_prop_t  string, search;
 
+    ret = njs_string_object_validate(vm, njs_arg(args, nargs, 0));
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
+    }
+
     retval = &njs_value_true;
 
     if (nargs > 1) {
-        search_length = njs_string_prop(&search, &args[1]);
+        value = njs_argument(args, 1);
 
-        if (search_length == 0) {
-            goto done;
+        if (njs_slow_path(!njs_is_string(value))) {
+            ret = njs_value_to_string(vm, value, value);
+            if (njs_slow_path(ret != NJS_OK)) {
+                return ret;
+            }
         }
 
-        length = njs_string_prop(&string, &args[0]);
-
-        index = 0;
+        search_length = njs_string_prop(&search, value);
 
         if (nargs > 2) {
-            index = njs_number(&args[2]);
+            value = njs_argument(args, 2);
+
+            if (njs_slow_path(!njs_is_number(value))) {
+                ret = njs_value_to_integer(vm, value, &index);
+                if (njs_slow_path(ret != NJS_OK)) {
+                    return ret;
+                }
+
+            } else {
+                index = njs_number_to_integer(njs_number(value));
+            }
 
             if (index < 0) {
                 index = 0;
             }
+
+        } else {
+            index = 0;
+        }
+
+        if (search_length == 0) {
+            goto done;
         }
 
+        length = njs_string_prop(&string, &args[0]);
+
         if (length - index >= search_length) {
             end = string.start + string.size;
 
@@ -2061,23 +2299,58 @@ 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)
 {
-    ssize_t            index, length, search_length;
+    int64_t            index, length, search_length;
+    njs_int_t          ret;
+    njs_value_t        *value;
     const u_char       *p, *end;
     const njs_value_t  *retval;
     njs_string_prop_t  string, search;
 
     retval = &njs_value_true;
 
-    if (nargs > 1) {
-        search_length = njs_string_prop(&search, &args[1]);
+    ret = njs_string_object_validate(vm, njs_arg(args, nargs, 0));
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
+    }
 
-        if (search_length == 0) {
-            goto done;
+    value = njs_arg(args, nargs, 1);
+
+    if (njs_slow_path(!njs_is_string(value))) {
+        if (njs_is_undefined(value)) {
+            value = njs_value_arg(&njs_string_undefined);
+
+        } else {
+            ret = njs_value_to_string(vm, value, value);
+            if (njs_slow_path(ret != NJS_OK)) {
+                return ret;
+            }
         }
+    }
 
-        length = njs_string_prop(&string, &args[0]);
+    search_length = njs_string_prop(&search, value);
+
+    value = njs_arg(args, nargs, 2);
+
+    if (njs_slow_path(!njs_is_number(value))) {
+        index = -1;
+
+        if (!njs_is_undefined(value)) {
+            ret = njs_value_to_integer(vm, value, &index);
+            if (njs_slow_path(ret != NJS_OK)) {
+                return ret;
+            }
+        }
+
+    } else {
+        index = njs_number_to_integer(njs_number(value));
+    }
 
-        index = (nargs > 2) ? njs_number(&args[2]) : -1;
+    if (search_length == 0) {
+        goto done;
+    }
+
+    if (nargs > 1) {
+        length = njs_string_prop(&string, &args[0]);
 
         if (starts) {
             if (index < 0) {
@@ -2247,10 +2520,16 @@ njs_string_prototype_to_lower_case(njs_vm_t *vm, njs_value_t *args,
     size_t             size, length;
     u_char             *p;
     uint32_t           code;
+    njs_int_t          ret;
     const u_char       *s, *end;
     njs_string_prop_t  string;
 
-    (void) njs_string_prop(&string, &args[0]);
+    ret = njs_string_object_validate(vm, njs_arg(args, nargs, 0));
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
+    }
+
+    (void) njs_string_prop(&string, njs_argument(args, 0));
 
     if (string.length == 0 || string.length == string.size) {
         /* Byte or ASCII string. */
@@ -2314,10 +2593,16 @@ njs_string_prototype_to_upper_case(njs_vm_t *vm, njs_value_t *args,
     size_t             size, length;
     u_char             *p;
     uint32_t           code;
+    njs_int_t          ret;
     const u_char       *s, *end;
     njs_string_prop_t  string;
 
-    (void) njs_string_prop(&string, &args[0]);
+    ret = njs_string_object_validate(vm, njs_arg(args, nargs, 0));
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
+    }
+
+    (void) njs_string_prop(&string, njs_argument(args, 0));
 
     if (string.length == 0 || string.length == string.size) {
         /* Byte or ASCII string. */
@@ -2372,7 +2657,15 @@ static njs_int_t
 njs_string_prototype_trim(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    return njs_string_trim(vm, &args[0], NJS_TRIM_START|NJS_TRIM_END);
+    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);
 }
 
 
@@ -2380,7 +2673,14 @@ 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)
 {
-    return njs_string_trim(vm, &args[0], NJS_TRIM_START);
+    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);
 }
 
 
@@ -2388,7 +2688,14 @@ 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)
 {
-    return njs_string_trim(vm, &args[0], NJS_TRIM_END);
+    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_END);
 }
 
 
@@ -2517,12 +2824,17 @@ njs_string_prototype_repeat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_int_t          ret;
     njs_string_prop_t  string;
 
+    ret = njs_string_object_validate(vm, njs_arg(args, nargs, 0));
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
+    }
+
     ret = njs_value_to_integer(vm, njs_arg(args, nargs, 1), &n);
     if (njs_slow_path(ret != NJS_OK)) {
         return ret;
     }
 
-    (void) njs_string_prop(&string, &args[0]);
+    (void) njs_string_prop(&string, njs_argument(args, 0));
 
     max = (string.size > 1) ? NJS_STRING_MAX_LENGTH / string.size
                             : NJS_STRING_MAX_LENGTH;
@@ -2579,16 +2891,37 @@ njs_string_prototype_pad(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 {
     u_char             *p, *start;
     size_t             padding, trunc, new_size;
-    int32_t            length, new_length;
+    int64_t            length, new_length;
     uint32_t           n, pad_length;
+    njs_int_t          ret;
+    njs_value_t        *value, *pad;
     const u_char       *end;
-    const njs_value_t  *pad;
     njs_string_prop_t  string, pad_string;
 
     static const njs_value_t  string_space = njs_string(" ");
 
-    length = njs_string_prop(&string, &args[0]);
-    new_length = nargs > 1 ? njs_number(&args[1]) : 0;
+    ret = njs_string_object_validate(vm, njs_arg(args, nargs, 0));
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
+    }
+
+    length = njs_string_prop(&string, njs_argument(args, 0));
+
+    new_length = 0;
+
+    if (nargs > 1) {
+        value = njs_argument(args, 1);
+
+        if (njs_slow_path(!njs_is_number(value))) {
+            ret = njs_value_to_integer(vm, value, &new_length);
+            if (njs_slow_path(ret != NJS_OK)) {
+                return ret;
+            }
+
+        } else {
+            new_length = njs_number_to_integer(njs_number(value));
+        }
+    }
 
     if (new_length <= length) {
         vm->retval = args[0];
@@ -2607,7 +2940,18 @@ njs_string_prototype_pad(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     trunc = 0;
 
     pad = njs_arg(args, nargs, 2);
-    pad = njs_is_undefined(pad) ? &string_space : pad;
+
+    if (njs_slow_path(!njs_is_string(pad))) {
+        if (njs_is_undefined(pad)) {
+            pad = njs_value_arg(&string_space);
+
+        } else {
+            ret = njs_value_to_string(vm, pad, pad);
+            if (njs_slow_path(ret != NJS_OK)) {
+                return NJS_OK;
+            }
+        }
+    }
 
     pad_length = njs_string_prop(&pad_string, pad);
 
@@ -2673,24 +3017,41 @@ static njs_int_t
 njs_string_prototype_search(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    int                   ret, *captures;
-    njs_int_t             index;
+    int                   *captures;
+    njs_int_t             ret, index;
     njs_uint_t            n;
+    njs_value_t           *value;
     njs_string_prop_t     string;
     njs_regexp_pattern_t  *pattern;
 
+    ret = njs_string_object_validate(vm, njs_arg(args, nargs, 0));
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
+    }
+
     index = 0;
 
     if (nargs > 1) {
+        value = njs_argument(args, 1);
 
-        switch (args[1].type) {
+        switch (value->type) {
 
         case NJS_REGEXP:
-            pattern = njs_regexp_pattern(&args[1]);
+            pattern = njs_regexp_pattern(value);
             break;
 
-        case NJS_STRING:
-            (void) njs_string_prop(&string, &args[1]);
+        case NJS_UNDEFINED:
+            goto done;
+
+        default:
+            if (njs_slow_path(!njs_is_string(value))) {
+                ret = njs_value_to_string(vm, value, value);
+                if (njs_slow_path(ret != NJS_OK)) {
+                    return ret;
+                }
+            }
+
+            (void) njs_string_prop(&string, value);
 
             if (string.size != 0) {
                 pattern = njs_regexp_pattern_create(vm, string.start,
@@ -2703,10 +3064,6 @@ njs_string_prototype_search(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             }
 
             goto done;
-
-        case NJS_UNDEFINED:
-        default:
-            goto done;
         }
 
         index = -1;
@@ -2749,6 +3106,11 @@ njs_string_prototype_match(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_value_t           arguments[2];
     njs_regexp_pattern_t  *pattern;
 
+    ret = njs_string_object_validate(vm, njs_arg(args, nargs, 0));
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
+    }
+
     arguments[1] = args[0];
 
     string.start = NULL;
@@ -2772,8 +3134,17 @@ njs_string_prototype_match(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             goto match;
         }
 
-        if (njs_is_string(&args[1])) {
-            /* string1.match(string2) is the same as /string2/.exec(string1). */
+        if (!njs_is_string(&args[1])) {
+            if (!njs_is_undefined(&args[1])) {
+                ret = njs_value_to_string(vm, &args[1], &args[1]);
+                if (njs_slow_path(ret != NJS_OK)) {
+                    return ret;
+                }
+
+                njs_string_get(&args[1], &string);
+            }
+
+        } else {
             njs_string_get(&args[1], &string);
         }
 
@@ -2899,16 +3270,23 @@ static njs_int_t
 njs_string_prototype_split(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    int                   ret, *captures;
+    int                   *captures;
     size_t                size;
     uint32_t              limit;
+    njs_int_t             ret;
     njs_utf8_t            utf8;
+    njs_value_t           *value;
     njs_array_t           *array;
     const u_char          *p, *start, *next, *last, *end;
     njs_regexp_utf8_t     type;
     njs_string_prop_t     string, split;
     njs_regexp_pattern_t  *pattern;
 
+    ret = njs_string_object_validate(vm, njs_arg(args, nargs, 0));
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
+    }
+
     array = njs_array_alloc(vm, 0, NJS_ARRAY_SPARE);
     if (njs_slow_path(array == NULL)) {
         return NJS_ERROR;
@@ -2917,7 +3295,17 @@ njs_string_prototype_split(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     if (nargs > 1) {
 
         if (nargs > 2) {
-            limit = njs_number(&args[2]);
+            value = njs_argument(args, 2);
+
+            if (njs_slow_path(!njs_is_number(value))) {
+                ret = njs_value_to_uint32(vm, value, &limit);
+                if (njs_slow_path(ret != NJS_OK)) {
+                    return ret;
+                }
+
+            } else {
+                limit = njs_number_to_uint32(njs_number(value));
+            }
 
             if (limit == 0) {
                 goto done;
@@ -2947,31 +3335,34 @@ njs_string_prototype_split(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
         switch (args[1].type) {
 
-        case NJS_STRING:
-            (void) njs_string_prop(&split, &args[1]);
+        case NJS_REGEXP:
+            pattern = njs_regexp_pattern(&args[1]);
 
-            if (string.size < split.size) {
+            if (!njs_regex_is_valid(&pattern->regex[type])) {
                 goto single;
             }
 
             start = string.start;
             end = string.start + string.size;
-            last = end - split.size;
 
             do {
-                for (p = start; p <= last; p++) {
-                    if (memcmp(p, split.start, split.size) == 0) {
-                        goto found;
-                    }
-                }
+                ret = njs_regexp_match(vm, &pattern->regex[type], start,
+                                       end - start, vm->single_match_data);
+                if (ret >= 0) {
+                    captures = njs_regex_captures(vm->single_match_data);
 
-                p = end;
+                    p = start + captures[0];
+                    next = start + captures[1];
 
-found:
+                } else if (ret == NJS_REGEX_NOMATCH) {
+                    p = (u_char *) end;
+                    next = (u_char *) end + 1;
 
-                next = p + split.size;
+                } else {
+                    return NJS_ERROR;
+                }
 
-                /* Empty split string. */
+                /* Empty split regexp. */
                 if (p == next) {
                     p = (utf8 != NJS_STRING_BYTE) ? njs_utf8_next(p, end)
                                                   : p + 1;
@@ -2992,34 +3383,41 @@ found:
 
             goto done;
 
-        case NJS_REGEXP:
-            pattern = njs_regexp_pattern(&args[1]);
+        case NJS_UNDEFINED:
+            break;
 
-            if (!njs_regex_is_valid(&pattern->regex[type])) {
+        default:
+            if (njs_slow_path(!njs_is_string(&args[1]))) {
+                ret = njs_value_to_string(vm, &args[1], &args[1]);
+                if (njs_slow_path(ret != NJS_OK)) {
+                    return ret;
+                }
+            }
+
+            (void) njs_string_prop(&split, &args[1]);
+
+            if (string.size < split.size) {
                 goto single;
             }
 
             start = string.start;
             end = string.start + string.size;
+            last = end - split.size;
 
             do {
-                ret = njs_regexp_match(vm, &pattern->regex[type], start,
-                                       end - start, vm->single_match_data);
-                if (ret >= 0) {
-                    captures = njs_regex_captures(vm->single_match_data);
+                for (p = start; p <= last; p++) {
+                    if (memcmp(p, split.start, split.size) == 0) {
+                        goto found;
+                    }
+                }
 
-                    p = start + captures[0];
-                    next = start + captures[1];
+                p = end;
 
-                } else if (ret == NJS_REGEX_NOMATCH) {
-                    p = (u_char *) end;
-                    next = (u_char *) end + 1;
+found:
 
-                } else {
-                    return NJS_ERROR;
-                }
+                next = p + split.size;
 
-                /* Empty split regexp. */
+                /* Empty split string. */
                 if (p == next) {
                     p = (utf8 != NJS_STRING_BYTE) ? njs_utf8_next(p, end)
                                                   : p + 1;
@@ -3039,10 +3437,6 @@ found:
             } while (limit != 0 && p < end);
 
             goto done;
-
-        case NJS_UNDEFINED:
-        default:
-            break;
         }
     }
 
@@ -3088,20 +3482,12 @@ njs_string_prototype_replace(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_string_prop_t     string;
     njs_string_replace_t  *r, string_replace;
 
-    this = njs_arg(args, nargs, 0);
-
-    if (njs_slow_path(njs_value_is_null_or_undefined(this))) {
-        njs_type_error(vm, "\"this\" argument cannot be "
-                       "undefined or null value");
-        return NJS_ERROR;
+    ret = njs_string_object_validate(vm, njs_arg(args, nargs, 0));
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
     }
 
-    if (!njs_is_string(this)) {
-        ret = njs_value_to_string(vm, this, this);
-        if (njs_slow_path(ret != NJS_OK)) {
-            return ret;
-        }
-    }
+    this = njs_argument(args, 0);
 
     if (nargs == 1) {
         goto original;
@@ -3142,6 +3528,18 @@ njs_string_prototype_replace(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     } else {
         regex = NULL;
         ncaptures = 1;
+
+        if (!njs_is_string(search)) {
+            if (njs_is_undefined(search)) {
+                search = njs_value_arg(&njs_string_undefined);
+
+            } else {
+                ret = njs_value_to_string(vm, search, search);
+                if (njs_slow_path(ret != NJS_OK)) {
+                    return ret;
+                }
+            }
+        }
     }
 
     /* This cannot fail. */
@@ -3160,10 +3558,15 @@ njs_string_prototype_replace(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         r->function = njs_function(replace);
 
     } else {
-        if (!njs_is_string(replace)) {
-            ret = njs_value_to_string(vm, replace, replace);
-            if (njs_slow_path(ret != NJS_OK)) {
-                return ret;
+        if (njs_slow_path(!njs_is_string(replace))) {
+            if (njs_is_undefined(replace)) {
+                replace = njs_value_arg(&njs_string_undefined);
+
+            } else {
+                ret = njs_value_to_string(vm, replace, replace);
+                if (njs_slow_path(ret != NJS_OK)) {
+                    return ret;
+                }
             }
         }
 
@@ -3206,13 +3609,6 @@ njs_string_prototype_replace(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return njs_string_replace_regexp(vm, this, search, r);
     }
 
-    if (!njs_is_string(search)) {
-        ret = njs_value_to_string(vm, search, search);
-        if (njs_slow_path(ret != NJS_OK)) {
-            return ret;
-        }
-    }
-
     return njs_string_replace_search(vm, this, search, r);
 
 original:
@@ -4099,7 +4495,7 @@ static const njs_object_prop_t  njs_string_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("valueOf"),
-        .value = njs_native_function(njs_string_prototype_value_of, 0, 0),
+        .value = njs_native_function(njs_string_prototype_value_of, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -4107,7 +4503,7 @@ static const njs_object_prop_t  njs_string_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("toString"),
-        .value = njs_native_function(njs_string_prototype_to_string, 0, 0),
+        .value = njs_native_function(njs_string_prototype_to_string, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -4115,7 +4511,7 @@ static const njs_object_prop_t  njs_string_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("concat"),
-        .value = njs_native_function(njs_string_prototype_concat, 1, 0),
+        .value = njs_native_function(njs_string_prototype_concat, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -4123,8 +4519,7 @@ static const njs_object_prop_t  njs_string_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("fromUTF8"),
-        .value = njs_native_function(njs_string_prototype_from_utf8, 0,
-                     NJS_STRING_OBJECT_ARG, NJS_INTEGER_ARG, NJS_INTEGER_ARG),
+        .value = njs_native_function(njs_string_prototype_from_utf8, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -4132,8 +4527,7 @@ static const njs_object_prop_t  njs_string_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("toUTF8"),
-        .value = njs_native_function(njs_string_prototype_to_utf8, 0,
-                     NJS_STRING_OBJECT_ARG, NJS_INTEGER_ARG, NJS_INTEGER_ARG),
+        .value = njs_native_function(njs_string_prototype_to_utf8, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -4141,8 +4535,7 @@ static const njs_object_prop_t  njs_string_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("fromBytes"),
-        .value = njs_native_function(njs_string_prototype_from_bytes, 0,
-                     NJS_STRING_OBJECT_ARG, NJS_INTEGER_ARG, NJS_INTEGER_ARG),
+        .value = njs_native_function(njs_string_prototype_from_bytes, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -4150,8 +4543,7 @@ static const njs_object_prop_t  njs_string_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("toBytes"),
-        .value = njs_native_function(njs_string_prototype_to_bytes, 0,
-                     NJS_STRING_OBJECT_ARG, NJS_INTEGER_ARG, NJS_INTEGER_ARG),
+        .value = njs_native_function(njs_string_prototype_to_bytes, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -4159,8 +4551,7 @@ static const njs_object_prop_t  njs_string_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("slice"),
-        .value = njs_native_function(njs_string_prototype_slice, 2,
-                     NJS_STRING_OBJECT_ARG, NJS_INTEGER_ARG, NJS_INTEGER_ARG),
+        .value = njs_native_function(njs_string_prototype_slice, 2),
         .writable = 1,
         .configurable = 1,
     },
@@ -4168,8 +4559,7 @@ static const njs_object_prop_t  njs_string_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("substring"),
-        .value = njs_native_function(njs_string_prototype_substring, 2,
-                     NJS_STRING_OBJECT_ARG, NJS_INTEGER_ARG, NJS_INTEGER_ARG),
+        .value = njs_native_function(njs_string_prototype_substring, 2),
         .writable = 1,
         .configurable = 1,
     },
@@ -4177,8 +4567,7 @@ static const njs_object_prop_t  njs_string_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("substr"),
-        .value = njs_native_function(njs_string_prototype_substr, 2,
-                     NJS_STRING_OBJECT_ARG, NJS_INTEGER_ARG, NJS_INTEGER_ARG),
+        .value = njs_native_function(njs_string_prototype_substr, 2),
         .writable = 1,
         .configurable = 1,
     },
@@ -4186,8 +4575,7 @@ static const njs_object_prop_t  njs_string_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("charAt"),
-        .value = njs_native_function(njs_string_prototype_char_at, 1,
-                     NJS_STRING_OBJECT_ARG, NJS_INTEGER_ARG),
+        .value = njs_native_function(njs_string_prototype_char_at, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -4195,8 +4583,7 @@ static const njs_object_prop_t  njs_string_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("charCodeAt"),
-        .value = njs_native_function(njs_string_prototype_char_code_at, 1,
-                     NJS_STRING_OBJECT_ARG, NJS_INTEGER_ARG),
+        .value = njs_native_function(njs_string_prototype_char_code_at, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -4205,8 +4592,7 @@ static const njs_object_prop_t  njs_string_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("codePointAt"),
-        .value = njs_native_function(njs_string_prototype_char_code_at, 1,
-                     NJS_STRING_OBJECT_ARG, NJS_INTEGER_ARG),
+        .value = njs_native_function(njs_string_prototype_char_code_at, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -4214,8 +4600,7 @@ static const njs_object_prop_t  njs_string_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("indexOf"),
-        .value = njs_native_function(njs_string_prototype_index_of, 1,
-                     NJS_STRING_OBJECT_ARG, NJS_STRING_ARG, NJS_INTEGER_ARG),
+        .value = njs_native_function(njs_string_prototype_index_of, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -4223,8 +4608,7 @@ static const njs_object_prop_t  njs_string_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("lastIndexOf"),
-        .value = njs_native_function(njs_string_prototype_last_index_of, 1,
-                     NJS_STRING_OBJECT_ARG, NJS_STRING_ARG, NJS_NUMBER_ARG),
+        .value = njs_native_function(njs_string_prototype_last_index_of, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -4233,8 +4617,7 @@ static const njs_object_prop_t  njs_string_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("includes"),
-        .value = njs_native_function(njs_string_prototype_includes, 1,
-                     NJS_STRING_OBJECT_ARG, NJS_STRING_ARG, NJS_INTEGER_ARG),
+        .value = njs_native_function(njs_string_prototype_includes, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -4243,8 +4626,7 @@ 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,
-                     NJS_STRING_OBJECT_ARG, NJS_STRING_ARG, NJS_INTEGER_ARG),
+        .value = njs_native_function(njs_string_prototype_starts_with, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -4253,8 +4635,7 @@ 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,
-                     NJS_STRING_OBJECT_ARG, NJS_STRING_ARG, NJS_INTEGER_ARG),
+        .value = njs_native_function(njs_string_prototype_ends_with, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -4262,8 +4643,7 @@ static const njs_object_prop_t  njs_string_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("toLowerCase"),
-        .value = njs_native_function(njs_string_prototype_to_lower_case, 0,
-                                     NJS_STRING_OBJECT_ARG),
+        .value = njs_native_function(njs_string_prototype_to_lower_case, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -4271,8 +4651,7 @@ static const njs_object_prop_t  njs_string_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("toUpperCase"),
-        .value = njs_native_function(njs_string_prototype_to_upper_case, 0,
-                                     NJS_STRING_OBJECT_ARG),
+        .value = njs_native_function(njs_string_prototype_to_upper_case, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -4280,8 +4659,7 @@ 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,
-                                     NJS_STRING_OBJECT_ARG),
+        .value = njs_native_function(njs_string_prototype_trim, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -4290,8 +4668,7 @@ 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,
-                                     NJS_STRING_OBJECT_ARG),
+        .value = njs_native_function(njs_string_prototype_trim_start, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -4300,8 +4677,7 @@ 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,
-                                     NJS_STRING_OBJECT_ARG),
+        .value = njs_native_function(njs_string_prototype_trim_end, 0),
         .writable = 1,
         .configurable = 1,
     },
@@ -4310,8 +4686,7 @@ static const njs_object_prop_t  njs_string_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("repeat"),
-        .value = njs_native_function(njs_string_prototype_repeat, 1,
-                                     NJS_STRING_OBJECT_ARG, NJS_INTEGER_ARG),
+        .value = njs_native_function(njs_string_prototype_repeat, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -4320,8 +4695,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,
-                     NJS_STRING_OBJECT_ARG, NJS_INTEGER_ARG, NJS_STRING_ARG),
+        .value = njs_native_function(njs_string_prototype_pad_start, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -4330,8 +4704,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,
-                     NJS_STRING_OBJECT_ARG, NJS_INTEGER_ARG, NJS_STRING_ARG),
+        .value = njs_native_function(njs_string_prototype_pad_end, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -4339,8 +4712,7 @@ static const njs_object_prop_t  njs_string_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("search"),
-        .value = njs_native_function(njs_string_prototype_search, 1,
-                                     NJS_STRING_OBJECT_ARG, NJS_REGEXP_ARG),
+        .value = njs_native_function(njs_string_prototype_search, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -4348,8 +4720,7 @@ static const njs_object_prop_t  njs_string_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("match"),
-        .value = njs_native_function(njs_string_prototype_match, 1,
-                                     NJS_STRING_OBJECT_ARG, NJS_REGEXP_ARG),
+        .value = njs_native_function(njs_string_prototype_match, 1),
         .writable = 1,
         .configurable = 1,
     },
@@ -4357,8 +4728,7 @@ static const njs_object_prop_t  njs_string_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("split"),
-        .value = njs_native_function(njs_string_prototype_split, 2,
-                     NJS_STRING_OBJECT_ARG, NJS_REGEXP_ARG, NJS_INTEGER_ARG),
+        .value = njs_native_function(njs_string_prototype_split, 2),
         .writable = 1,
         .configurable = 1,
     },
@@ -4366,8 +4736,7 @@ static const njs_object_prop_t  njs_string_prototype_properties[] =
     {
         .type = NJS_PROPERTY,
         .name = njs_string("replace"),
-        .value = njs_native_function(njs_string_prototype_replace, 2,
-                     NJS_STRING_OBJECT_ARG, NJS_REGEXP_ARG, NJS_FUNCTION_ARG),
+        .value = njs_native_function(njs_string_prototype_replace, 2),
         .writable = 1,
         .configurable = 1,
     },
@@ -4406,6 +4775,9 @@ njs_int_t
 njs_string_encode_uri(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
+    njs_int_t    ret;
+    njs_value_t  *value;
+
     static const uint32_t  escape[] = {
         0xffffffff,  /* 1111 1111 1111 1111  1111 1111 1111 1111 */
 
@@ -4424,13 +4796,22 @@ njs_string_encode_uri(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         0xffffffff,  /* 1111 1111 1111 1111  1111 1111 1111 1111 */
     };
 
-    if (nargs > 1) {
-        return njs_string_encode(vm, &args[1], escape);
+    if (nargs < 2) {
+        njs_set_undefined(&vm->retval);
+
+        return NJS_OK;
     }
 
-    vm->retval = njs_string_undefined;
+    value = njs_argument(args, 1);
 
-    return NJS_OK;
+    if (!njs_is_string(value)) {
+        ret = njs_value_to_string(vm, value, value);
+        if (njs_slow_path(ret != NJS_OK)) {
+            return ret;
+        }
+    }
+
+    return njs_string_encode(vm, value, escape);
 }
 
 
@@ -4442,6 +4823,9 @@ njs_int_t
 njs_string_encode_uri_component(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused)
 {
+    njs_int_t    ret;
+    njs_value_t  *value;
+
     static const uint32_t  escape[] = {
         0xffffffff,  /* 1111 1111 1111 1111  1111 1111 1111 1111 */
 
@@ -4460,13 +4844,22 @@ njs_string_encode_uri_component(njs_vm_t *vm, njs_value_t *args,
         0xffffffff,  /* 1111 1111 1111 1111  1111 1111 1111 1111 */
     };
 
-    if (nargs > 1) {
-        return njs_string_encode(vm, &args[1], escape);
+    if (nargs < 2) {
+        njs_set_undefined(&vm->retval);
+
+        return NJS_OK;
     }
 
-    vm->retval = njs_string_undefined;
+    value = njs_argument(args, 1);
 
-    return NJS_OK;
+    if (!njs_is_string(value)) {
+        ret = njs_value_to_string(vm, value, value);
+        if (njs_slow_path(ret != NJS_OK)) {
+            return ret;
+        }
+    }
+
+    return njs_string_encode(vm, value, escape);
 }
 
 
@@ -4537,6 +4930,9 @@ njs_int_t
 njs_string_decode_uri(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
+    njs_int_t    ret;
+    njs_value_t  *value;
+
     static const uint32_t  reserve[] = {
         0x00000000,  /* 0000 0000 0000 0000  0000 0000 0000 0000 */
 
@@ -4555,13 +4951,22 @@ njs_string_decode_uri(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         0x00000000,  /* 0000 0000 0000 0000  0000 0000 0000 0000 */
     };
 
-    if (nargs > 1) {
-        return njs_string_decode(vm, &args[1], reserve);
+    if (nargs < 2) {
+        njs_set_undefined(&vm->retval);
+
+        return NJS_OK;
     }
 
-    vm->retval = njs_string_undefined;
+    value = njs_argument(args, 1);
 
-    return NJS_OK;
+    if (njs_slow_path(!njs_is_string(value))) {
+        ret = njs_value_to_string(vm, value, value);
+        if (njs_slow_path(ret != NJS_OK)) {
+            return ret;
+        }
+    }
+
+    return njs_string_decode(vm, value, reserve);
 }
 
 
@@ -4573,6 +4978,9 @@ njs_int_t
 njs_string_decode_uri_component(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused)
 {
+    njs_int_t    ret;
+    njs_value_t  *value;
+
     static const uint32_t  reserve[] = {
         0x00000000,  /* 0000 0000 0000 0000  0000 0000 0000 0000 */
 
@@ -4591,13 +4999,22 @@ njs_string_decode_uri_component(njs_vm_t *vm, njs_value_t *args,
         0x00000000,  /* 0000 0000 0000 0000  0000 0000 0000 0000 */
     };
 
-    if (nargs > 1) {
-        return njs_string_decode(vm, &args[1], reserve);
+    if (nargs < 2) {
+        njs_set_undefined(&vm->retval);
+
+        return NJS_OK;
     }
 
-    vm->retval = njs_string_undefined;
+    value = njs_argument(args, 1);
 
-    return NJS_OK;
+    if (njs_slow_path(!njs_is_string(value))) {
+        ret = njs_value_to_string(vm, value, value);
+        if (njs_slow_path(ret != NJS_OK)) {
+            return ret;
+        }
+    }
+
+    return njs_string_decode(vm, &args[1], reserve);
 }
 
 
index cbca82f66f07b019be63e18d2e8391ebb221d99a..7f23f15939b0976c48b1508f9db2e7e7c108edd6 100644 (file)
@@ -330,43 +330,6 @@ njs_type_string(njs_value_type_t type)
 }
 
 
-const char *
-njs_arg_type_string(uint8_t arg)
-{
-    switch (arg) {
-    case NJS_SKIP_ARG:
-        return "skip";
-
-    case NJS_NUMBER_ARG:
-        return "number";
-
-    case NJS_INTEGER_ARG:
-        return "integer";
-
-    case NJS_STRING_ARG:
-        return "string";
-
-    case NJS_OBJECT_ARG:
-        return "object";
-
-    case NJS_STRING_OBJECT_ARG:
-        return "string object";
-
-    case NJS_FUNCTION_ARG:
-        return "function";
-
-    case NJS_REGEXP_ARG:
-        return "regexp";
-
-    case NJS_DATE_ARG:
-        return "date";
-
-    default:
-        return "unknown";
-    }
-}
-
-
 void
 njs_value_undefined_set(njs_value_t *value)
 {
index effeebdcc9d8001f9a2d5d60386ec9accc398074..2a713618db395b695e562e7d5efa9a6d6aa6cf11 100644 (file)
@@ -235,12 +235,9 @@ typedef struct {
 } njs_closure_t;
 
 
-#define NJS_ARGS_TYPES_MAX            5
-
 struct njs_function_s {
     njs_object_t                      object;
 
-    uint8_t                           args_types[NJS_ARGS_TYPES_MAX];
     uint8_t                           args_offset;
     uint8_t                           args_count;
 
@@ -391,14 +388,13 @@ typedef struct {
 }
 
 
-#define njs_native_function(_function, _args_count, ...) {                    \
+#define njs_native_function(_function, _args_count) {                         \
     .data = {                                                                 \
         .type = NJS_FUNCTION,                                                 \
         .truth = 1,                                                           \
         .u.function = & (njs_function_t) {                                    \
             .native = 1,                                                      \
             .args_count = _args_count,                                        \
-            .args_types = { __VA_ARGS__ },                                    \
             .args_offset = 1,                                                 \
             .u.native = _function,                                            \
             .object = { .type = NJS_FUNCTION,                                 \
@@ -827,7 +823,6 @@ njs_array_t *njs_value_own_enumerate(njs_vm_t *vm, const njs_value_t *value,
     njs_object_enum_t kind, njs_bool_t all);
 njs_int_t njs_value_length(njs_vm_t *vm, njs_value_t *value, uint32_t *dest);
 const char *njs_type_string(njs_value_type_t type);
-const char *njs_arg_type_string(uint8_t arg);
 
 njs_int_t njs_primitive_value_to_string(njs_vm_t *vm, njs_value_t *dst,
     const njs_value_t *src);
index 41efac86be5e5e1919aca4736166693adf70b0dc..75bf97bda18c70755e67b0bdeb2f28f3e7a92f02 100644 (file)
@@ -144,7 +144,7 @@ static njs_interactive_test_t  njs_test[] =
 
     { njs_str("function f(o) {return Object.keys(o)}" ENTER
                  "f()" ENTER),
-      njs_str("TypeError: cannot convert undefined to object\n"
+      njs_str("TypeError: cannot convert undefined argument to object\n"
                  "    at Object.keys (native)\n"
                  "    at f (:1)\n"
                  "    at main (native)\n") },
index 59b538d84daab9c277c522aa3901fd9f8815dcca..c929b3e28a776c31afdecc9ddd2932c438f07512 100644 (file)
@@ -1492,6 +1492,9 @@ static njs_unit_test_t  njs_test[] =
     { njs_str("'1' == new Number(1)"),
       njs_str("true") },
 
+    { njs_str("new Number(null) + ''"),
+      njs_str("0") },
+
     { njs_str("new String('abc') == 'abc'"),
       njs_str("true") },
 
@@ -11419,6 +11422,9 @@ static njs_unit_test_t  njs_test[] =
     { njs_str("var o = Object.freeze({a:1}); Object.isFrozen(o)"),
       njs_str("true") },
 
+    { njs_str("Object.isFrozen(undefined)"),
+      njs_str("true") },
+
     { njs_str("var o = Object.seal({a:1}); o.a = 2; o.a"),
       njs_str("2") },
 
@@ -11443,6 +11449,9 @@ static njs_unit_test_t  njs_test[] =
     { njs_str("Object.seal('')"),
       njs_str("") },
 
+    { njs_str("Object.seal(undefined)"),
+      njs_str("undefined") },
+
     { njs_str("Object.isSealed({a:1})"),
       njs_str("false") },
 
@@ -11559,6 +11568,9 @@ static njs_unit_test_t  njs_test[] =
     { njs_str("Object.isExtensible(Object.freeze([]))"),
       njs_str("false") },
 
+    { njs_str("Object.isExtensible(undefined)"),
+      njs_str("false") },
+
     { njs_str(
         "var fail;"
         "function isConfigurableMethods(o) {"
@@ -13246,6 +13258,12 @@ static njs_unit_test_t  njs_test[] =
     { njs_str("1/parseInt('-0')"),
       njs_str("-Infinity") },
 
+    { njs_str("parseInt('11', new Number(Infinity)) === parseInt('11', Infinity)"),
+      njs_str("true") },
+
+    { njs_str("parseInt('11', Number.POSITIVE_INFINITY)"),
+      njs_str("11") },
+
     { njs_str("parseFloat.name"),
       njs_str("parseFloat") },