changeset 1211:c75a8fc6d534

Moving constructors to global object.
author Dmitry Volyntsev <xeioex@nginx.com>
date Thu, 31 Oct 2019 18:17:31 +0300
parents ba6f17a75b3a
children 2868545c461b
files src/njs_array.c src/njs_builtin.c src/njs_crypto.c src/njs_date.c src/njs_error.c src/njs_error.h src/njs_extern.c src/njs_fs.c src/njs_function.c src/njs_generator.c src/njs_lexer.h src/njs_lexer_keyword.c src/njs_module.c src/njs_object.c src/njs_object_hash.h src/njs_parser.c src/njs_parser.h src/njs_parser_expression.c src/njs_parser_terminal.c src/njs_regexp.c src/njs_vm.c src/njs_vm.h src/test/njs_benchmark.c src/test/njs_unit_test.c test/njs_expect_test.exp
diffstat 25 files changed, 598 insertions(+), 321 deletions(-) [+]
line wrap: on
line diff
--- a/src/njs_array.c	Thu Oct 31 18:17:31 2019 +0300
+++ b/src/njs_array.c	Thu Oct 31 18:17:31 2019 +0300
@@ -63,7 +63,7 @@
     array->start = array->data;
     njs_lvlhsh_init(&array->object.hash);
     array->object.shared_hash = vm->shared->array_instance_hash;
-    array->object.__proto__ = &vm->prototypes[NJS_PROTOTYPE_ARRAY].object;
+    array->object.__proto__ = &vm->prototypes[NJS_OBJ_TYPE_ARRAY].object;
     array->object.type = NJS_ARRAY;
     array->object.shared = 0;
     array->object.extensible = 1;
--- a/src/njs_builtin.c	Thu Oct 31 18:17:31 2019 +0300
+++ b/src/njs_builtin.c	Thu Oct 31 18:17:31 2019 +0300
@@ -39,8 +39,8 @@
 
 
 const njs_object_init_t  *njs_module_init[] = {
-    &njs_fs_object_init,          /* fs                 */
-    &njs_crypto_object_init,      /* crypto             */
+    &njs_fs_object_init,
+    &njs_crypto_object_init,
     NULL
 };
 
@@ -64,6 +64,7 @@
     &njs_syntax_error_prototype_init,
     &njs_type_error_prototype_init,
     &njs_uri_error_prototype_init,
+    &njs_internal_error_prototype_init,
     NULL
 };
 
@@ -324,7 +325,7 @@
         prototype++;
     }
 
-    shared->prototypes[NJS_PROTOTYPE_REGEXP].regexp.pattern =
+    shared->prototypes[NJS_OBJ_TYPE_REGEXP].regexp.pattern =
                                               shared->empty_regexp_pattern;
 
     string_object = &shared->string_object;
@@ -453,7 +454,6 @@
 {
     size_t        size;
     njs_uint_t    i;
-    njs_value_t   *values;
     njs_object_t  *object_prototype, *function_prototype, *error_prototype,
                   *error_constructor;
 
@@ -461,36 +461,32 @@
      * Copy both prototypes and constructors arrays by one memcpy()
      * because they are stored together.
      */
-    size = NJS_PROTOTYPE_MAX * sizeof(njs_object_prototype_t)
-           + NJS_CONSTRUCTOR_MAX * sizeof(njs_function_t);
+    size = (sizeof(njs_object_prototype_t) + sizeof(njs_function_t))
+           * NJS_OBJ_TYPE_MAX;
 
     memcpy(vm->prototypes, vm->shared->prototypes, size);
 
-    object_prototype = &vm->prototypes[NJS_PROTOTYPE_OBJECT].object;
+    object_prototype = &vm->prototypes[NJS_OBJ_TYPE_OBJECT].object;
 
-    for (i = NJS_PROTOTYPE_ARRAY; i < NJS_PROTOTYPE_EVAL_ERROR; i++) {
+    for (i = NJS_OBJ_TYPE_ARRAY; i < NJS_OBJ_TYPE_EVAL_ERROR; i++) {
         vm->prototypes[i].object.__proto__ = object_prototype;
     }
 
-    error_prototype = &vm->prototypes[NJS_PROTOTYPE_ERROR].object;
+    error_prototype = &vm->prototypes[NJS_OBJ_TYPE_ERROR].object;
 
-    for (i = NJS_PROTOTYPE_EVAL_ERROR; i < NJS_PROTOTYPE_MAX; i++) {
+    for (i = NJS_OBJ_TYPE_EVAL_ERROR; i < NJS_OBJ_TYPE_MAX; i++) {
         vm->prototypes[i].object.__proto__ = error_prototype;
     }
 
-    values = vm->scopes[NJS_SCOPE_GLOBAL];
+    function_prototype = &vm->prototypes[NJS_OBJ_TYPE_FUNCTION].object;
 
-    function_prototype = &vm->prototypes[NJS_PROTOTYPE_FUNCTION].object;
-
-    for (i = NJS_CONSTRUCTOR_OBJECT; i < NJS_CONSTRUCTOR_EVAL_ERROR; i++) {
-        njs_set_function(&values[i], &vm->constructors[i]);
+    for (i = NJS_OBJ_TYPE_OBJECT; i < NJS_OBJ_TYPE_EVAL_ERROR; i++) {
         vm->constructors[i].object.__proto__ = function_prototype;
     }
 
-    error_constructor = &vm->constructors[NJS_CONSTRUCTOR_ERROR].object;
+    error_constructor = &vm->constructors[NJS_OBJ_TYPE_ERROR].object;
 
-    for (i = NJS_CONSTRUCTOR_EVAL_ERROR; i < NJS_CONSTRUCTOR_MAX; i++) {
-        njs_set_function(&values[i], &vm->constructors[i]);
+    for (i = NJS_OBJ_TYPE_EVAL_ERROR; i < NJS_OBJ_TYPE_MAX; i++) {
         vm->constructors[i].object.__proto__ = error_constructor;
     }
 
@@ -501,7 +497,7 @@
     njs_set_object(global, &vm->global_object);
 
     vm->string_object = vm->shared->string_object;
-    vm->string_object.__proto__ = &vm->prototypes[NJS_PROTOTYPE_STRING].object;
+    vm->string_object.__proto__ = &vm->prototypes[NJS_OBJ_TYPE_STRING].object;
 
     return NJS_OK;
 }
@@ -1090,6 +1086,51 @@
 }
 
 
+static njs_int_t
+njs_top_level_constructor(njs_vm_t *vm, njs_object_prop_t *self,
+    njs_value_t *global, njs_value_t *setval, njs_value_t *retval)
+{
+    njs_int_t           ret;
+    njs_function_t      *ctor;
+    njs_object_prop_t   *prop;
+    njs_lvlhsh_query_t  lhq;
+
+    if (njs_slow_path(setval != NULL)) {
+        *retval = *setval;
+
+    } else {
+        ctor = &vm->constructors[self->value.data.magic16];
+
+        njs_set_function(retval, ctor);
+    }
+
+    prop = njs_object_prop_alloc(vm, &self->name, retval, 1);
+    if (njs_slow_path(prop == NULL)) {
+        return NJS_ERROR;
+    }
+
+    /* GC */
+
+    prop->value = *retval;
+    prop->enumerable = 0;
+
+    lhq.value = prop;
+    njs_string_get(&self->name, &lhq.key);
+    lhq.key_hash = self->value.data.magic32;
+    lhq.replace = 1;
+    lhq.pool = vm->mem_pool;
+    lhq.proto = &njs_object_hash_proto;
+
+    ret = njs_lvlhsh_insert(njs_object_hash(global), &lhq);
+    if (njs_slow_path(ret != NJS_OK)) {
+        njs_internal_error(vm, "lvlhsh insert/replace failed");
+        return NJS_ERROR;
+    }
+
+    return NJS_OK;
+}
+
+
 static const njs_object_prop_t  njs_global_this_object_properties[] =
 {
     /* Global constants. */
@@ -1264,6 +1305,167 @@
         .configurable = 1,
     },
 
+    /* Global constructors. */
+
+    {
+        .type = NJS_PROPERTY_HANDLER,
+        .name = njs_string("Object"),
+        .value = njs_prop_handler2(njs_top_level_constructor,
+                                   NJS_OBJ_TYPE_OBJECT, NJS_OBJECT_HASH),
+        .writable = 1,
+        .configurable = 1,
+    },
+
+    {
+        .type = NJS_PROPERTY_HANDLER,
+        .name = njs_string("Array"),
+        .value = njs_prop_handler2(njs_top_level_constructor,
+                                   NJS_OBJ_TYPE_ARRAY, NJS_ARRAY_HASH),
+        .writable = 1,
+        .configurable = 1,
+    },
+
+    {
+        .type = NJS_PROPERTY_HANDLER,
+        .name = njs_string("Boolean"),
+        .value = njs_prop_handler2(njs_top_level_constructor,
+                                   NJS_OBJ_TYPE_BOOLEAN, NJS_BOOLEAN_HASH),
+        .writable = 1,
+        .configurable = 1,
+    },
+
+    {
+        .type = NJS_PROPERTY_HANDLER,
+        .name = njs_string("Number"),
+        .value = njs_prop_handler2(njs_top_level_constructor,
+                                   NJS_OBJ_TYPE_NUMBER, NJS_NUMBER_HASH),
+        .writable = 1,
+        .configurable = 1,
+    },
+
+    {
+        .type = NJS_PROPERTY_HANDLER,
+        .name = njs_string("String"),
+        .value = njs_prop_handler2(njs_top_level_constructor,
+                                   NJS_OBJ_TYPE_STRING, NJS_STRING_HASH),
+        .writable = 1,
+        .configurable = 1,
+    },
+
+    {
+        .type = NJS_PROPERTY_HANDLER,
+        .name = njs_string("Function"),
+        .value = njs_prop_handler2(njs_top_level_constructor,
+                                   NJS_OBJ_TYPE_FUNCTION, NJS_FUNCTION_HASH),
+        .writable = 1,
+        .configurable = 1,
+    },
+
+    {
+        .type = NJS_PROPERTY_HANDLER,
+        .name = njs_string("RegExp"),
+        .value = njs_prop_handler2(njs_top_level_constructor,
+                                   NJS_OBJ_TYPE_REGEXP, NJS_REGEXP_HASH),
+        .writable = 1,
+        .configurable = 1,
+    },
+
+    {
+        .type = NJS_PROPERTY_HANDLER,
+        .name = njs_string("Date"),
+        .value = njs_prop_handler2(njs_top_level_constructor,
+                                   NJS_OBJ_TYPE_DATE, NJS_DATE_HASH),
+        .writable = 1,
+        .configurable = 1,
+    },
+
+    {
+        .type = NJS_PROPERTY_HANDLER,
+        .name = njs_string("Error"),
+        .value = njs_prop_handler2(njs_top_level_constructor,
+                                   NJS_OBJ_TYPE_ERROR, NJS_ERROR_HASH),
+        .writable = 1,
+        .configurable = 1,
+    },
+
+    {
+        .type = NJS_PROPERTY_HANDLER,
+        .name = njs_string("EvalError"),
+        .value = njs_prop_handler2(njs_top_level_constructor,
+                                   NJS_OBJ_TYPE_EVAL_ERROR,
+                                   NJS_EVAL_ERROR_HASH),
+        .writable = 1,
+        .configurable = 1,
+    },
+
+    {
+        .type = NJS_PROPERTY_HANDLER,
+        .name = njs_string("InternalError"),
+        .value = njs_prop_handler2(njs_top_level_constructor,
+                                   NJS_OBJ_TYPE_INTERNAL_ERROR,
+                                   NJS_INTERNAL_ERROR_HASH),
+        .writable = 1,
+        .configurable = 1,
+    },
+
+    {
+        .type = NJS_PROPERTY_HANDLER,
+        .name = njs_string("RangeError"),
+        .value = njs_prop_handler2(njs_top_level_constructor,
+                                   NJS_OBJ_TYPE_RANGE_ERROR,
+                                   NJS_RANGE_ERROR_HASH),
+        .writable = 1,
+        .configurable = 1,
+    },
+
+    {
+        .type = NJS_PROPERTY_HANDLER,
+        .name = njs_string("ReferenceError"),
+        .value = njs_prop_handler2(njs_top_level_constructor,
+                                   NJS_OBJ_TYPE_REF_ERROR, NJS_REF_ERROR_HASH),
+        .writable = 1,
+        .configurable = 1,
+    },
+
+    {
+        .type = NJS_PROPERTY_HANDLER,
+        .name = njs_string("SyntaxError"),
+        .value = njs_prop_handler2(njs_top_level_constructor,
+                                   NJS_OBJ_TYPE_SYNTAX_ERROR,
+                                   NJS_SYNTAX_ERROR_HASH),
+        .writable = 1,
+        .configurable = 1,
+    },
+
+    {
+        .type = NJS_PROPERTY_HANDLER,
+        .name = njs_string("TypeError"),
+        .value = njs_prop_handler2(njs_top_level_constructor,
+                                   NJS_OBJ_TYPE_TYPE_ERROR,
+                                   NJS_TYPE_ERROR_HASH),
+        .writable = 1,
+        .configurable = 1,
+    },
+
+    {
+        .type = NJS_PROPERTY_HANDLER,
+        .name = njs_string("URIError"),
+        .value = njs_prop_handler2(njs_top_level_constructor,
+                                   NJS_OBJ_TYPE_URI_ERROR,
+                                   NJS_URI_ERROR_HASH),
+        .writable = 1,
+        .configurable = 1,
+    },
+
+    {
+        .type = NJS_PROPERTY_HANDLER,
+        .name = njs_string("MemoryError"),
+        .value = njs_prop_handler2(njs_top_level_constructor,
+                                   NJS_OBJ_TYPE_MEMORY_ERROR,
+                                   NJS_MEMORY_ERROR_HASH),
+        .writable = 1,
+        .configurable = 1,
+    },
 };
 
 
--- a/src/njs_crypto.c	Thu Oct 31 18:17:31 2019 +0300
+++ b/src/njs_crypto.c	Thu Oct 31 18:17:31 2019 +0300
@@ -122,7 +122,7 @@
 
 
 static njs_object_value_t *
-njs_crypto_object_value_alloc(njs_vm_t *vm, njs_uint_t proto)
+njs_crypto_object_value_alloc(njs_vm_t *vm, njs_object_type_t type)
 {
     njs_object_value_t  *ov;
 
@@ -135,7 +135,7 @@
         ov->object.shared = 0;
         ov->object.extensible = 1;
 
-        ov->object.__proto__ = &vm->prototypes[proto].object;
+        ov->object.__proto__ = &vm->prototypes[type].object;
         return ov;
     }
 
@@ -166,7 +166,7 @@
         return NJS_ERROR;
     }
 
-    hash = njs_crypto_object_value_alloc(vm, NJS_PROTOTYPE_CRYPTO_HASH);
+    hash = njs_crypto_object_value_alloc(vm, NJS_OBJ_TYPE_CRYPTO_HASH);
     if (njs_slow_path(hash == NULL)) {
         return NJS_ERROR;
     }
@@ -431,7 +431,7 @@
     alg->init(&ctx->u);
     alg->update(&ctx->u, key_buf, 64);
 
-    hmac = njs_crypto_object_value_alloc(vm, NJS_PROTOTYPE_CRYPTO_HMAC);
+    hmac = njs_crypto_object_value_alloc(vm, NJS_OBJ_TYPE_CRYPTO_HMAC);
     if (njs_slow_path(hmac == NULL)) {
         return NJS_ERROR;
     }
--- a/src/njs_date.c	Thu Oct 31 18:17:31 2019 +0300
+++ b/src/njs_date.c	Thu Oct 31 18:17:31 2019 +0300
@@ -257,7 +257,7 @@
         date->object.type = NJS_DATE;
         date->object.shared = 0;
         date->object.extensible = 1;
-        date->object.__proto__ = &vm->prototypes[NJS_PROTOTYPE_DATE].object;
+        date->object.__proto__ = &vm->prototypes[NJS_OBJ_TYPE_DATE].object;
 
         date->time = njs_timeclip(time);
 
--- a/src/njs_error.c	Thu Oct 31 18:17:31 2019 +0300
+++ b/src/njs_error.c	Thu Oct 31 18:17:31 2019 +0300
@@ -13,7 +13,7 @@
 
 
 void
-njs_error_new(njs_vm_t *vm, njs_value_t *dst, njs_prototype_t type,
+njs_error_new(njs_vm_t *vm, njs_value_t *dst, njs_object_type_t type,
     u_char *start, size_t size)
 {
     ssize_t        length;
@@ -41,7 +41,7 @@
 
 
 void
-njs_error_fmt_new(njs_vm_t *vm, njs_value_t *dst, njs_prototype_t type,
+njs_error_fmt_new(njs_vm_t *vm, njs_value_t *dst, njs_object_type_t type,
     const char *fmt, ...)
 {
     va_list  args;
@@ -60,7 +60,7 @@
 
 
 njs_object_t *
-njs_error_alloc(njs_vm_t *vm, njs_prototype_t type, const njs_value_t *name,
+njs_error_alloc(njs_vm_t *vm, njs_object_type_t type, const njs_value_t *name,
     const njs_value_t *message)
 {
     njs_int_t           ret;
@@ -136,7 +136,7 @@
 
 static njs_int_t
 njs_error_create(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_prototype_t type)
+    njs_object_type_t type)
 {
     njs_int_t     ret;
     njs_value_t   *value;
@@ -169,7 +169,7 @@
 njs_error_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    return njs_error_create(vm, args, nargs, NJS_PROTOTYPE_ERROR);
+    return njs_error_create(vm, args, nargs, NJS_OBJ_TYPE_ERROR);
 }
 
 
@@ -211,7 +211,7 @@
 njs_eval_error_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    return njs_error_create(vm, args, nargs, NJS_PROTOTYPE_EVAL_ERROR);
+    return njs_error_create(vm, args, nargs, NJS_OBJ_TYPE_EVAL_ERROR);
 }
 
 
@@ -253,7 +253,7 @@
 njs_internal_error_constructor(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused)
 {
-    return njs_error_create(vm, args, nargs, NJS_PROTOTYPE_INTERNAL_ERROR);
+    return njs_error_create(vm, args, nargs, NJS_OBJ_TYPE_INTERNAL_ERROR);
 }
 
 
@@ -295,7 +295,7 @@
 njs_range_error_constructor(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused)
 {
-    return njs_error_create(vm, args, nargs, NJS_PROTOTYPE_RANGE_ERROR);
+    return njs_error_create(vm, args, nargs, NJS_OBJ_TYPE_RANGE_ERROR);
 }
 
 
@@ -337,7 +337,7 @@
 njs_reference_error_constructor(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused)
 {
-    return njs_error_create(vm, args, nargs, NJS_PROTOTYPE_REF_ERROR);
+    return njs_error_create(vm, args, nargs, NJS_OBJ_TYPE_REF_ERROR);
 }
 
 
@@ -379,7 +379,7 @@
 njs_syntax_error_constructor(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused)
 {
-    return njs_error_create(vm, args, nargs, NJS_PROTOTYPE_SYNTAX_ERROR);
+    return njs_error_create(vm, args, nargs, NJS_OBJ_TYPE_SYNTAX_ERROR);
 }
 
 
@@ -421,7 +421,7 @@
 njs_type_error_constructor(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused)
 {
-    return njs_error_create(vm, args, nargs, NJS_PROTOTYPE_TYPE_ERROR);
+    return njs_error_create(vm, args, nargs, NJS_OBJ_TYPE_TYPE_ERROR);
 }
 
 
@@ -463,7 +463,7 @@
 njs_uri_error_constructor(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused)
 {
-    return njs_error_create(vm, args, nargs, NJS_PROTOTYPE_URI_ERROR);
+    return njs_error_create(vm, args, nargs, NJS_OBJ_TYPE_URI_ERROR);
 }
 
 
@@ -512,7 +512,7 @@
 
     njs_lvlhsh_init(&object->hash);
     njs_lvlhsh_init(&object->shared_hash);
-    object->__proto__ = &prototypes[NJS_PROTOTYPE_INTERNAL_ERROR].object;
+    object->__proto__ = &prototypes[NJS_OBJ_TYPE_INTERNAL_ERROR].object;
     object->type = NJS_OBJECT;
     object->shared = 1;
 
@@ -554,7 +554,7 @@
 
     /* MemoryError has no its own prototype. */
 
-    index = NJS_PROTOTYPE_INTERNAL_ERROR;
+    index = NJS_OBJ_TYPE_INTERNAL_ERROR;
 
     function = njs_function(value);
     proto = njs_property_prototype_create(vm, &function->object.hash,
--- a/src/njs_error.h	Thu Oct 31 18:17:31 2019 +0300
+++ b/src/njs_error.h	Thu Oct 31 18:17:31 2019 +0300
@@ -9,38 +9,38 @@
 
 
 #define njs_error(vm, fmt, ...)                                               \
-    njs_error_fmt_new(vm, &vm->retval, NJS_PROTOTYPE_ERROR, fmt, ##__VA_ARGS__)
+    njs_error_fmt_new(vm, &vm->retval, NJS_OBJ_TYPE_ERROR, fmt, ##__VA_ARGS__)
 #define njs_eval_error(vm, fmt, ...)                                          \
-    njs_error_fmt_new(vm, &vm->retval, NJS_PROTOTYPE_EVAL_ERROR, fmt,         \
+    njs_error_fmt_new(vm, &vm->retval, NJS_OBJ_TYPE_EVAL_ERROR, fmt,          \
                       ##__VA_ARGS__)
 #define njs_internal_error(vm, fmt, ...)                                      \
-    njs_error_fmt_new(vm, &vm->retval, NJS_PROTOTYPE_INTERNAL_ERROR, fmt,     \
+    njs_error_fmt_new(vm, &vm->retval, NJS_OBJ_TYPE_INTERNAL_ERROR, fmt,      \
                       ##__VA_ARGS__)
 #define njs_range_error(vm, fmt, ...)                                         \
-    njs_error_fmt_new(vm, &vm->retval, NJS_PROTOTYPE_RANGE_ERROR, fmt,        \
+    njs_error_fmt_new(vm, &vm->retval, NJS_OBJ_TYPE_RANGE_ERROR, fmt,         \
                       ##__VA_ARGS__)
 #define njs_reference_error(vm, fmt, ...)                                     \
-    njs_error_fmt_new(vm, &vm->retval, NJS_PROTOTYPE_REF_ERROR, fmt,          \
+    njs_error_fmt_new(vm, &vm->retval, NJS_OBJ_TYPE_REF_ERROR, fmt,           \
                       ##__VA_ARGS__)
 #define njs_syntax_error(vm, fmt, ...)                                        \
-    njs_error_fmt_new(vm, &vm->retval, NJS_PROTOTYPE_SYNTAX_ERROR, fmt,       \
+    njs_error_fmt_new(vm, &vm->retval, NJS_OBJ_TYPE_SYNTAX_ERROR, fmt,        \
                       ##__VA_ARGS__)
 #define njs_type_error(vm, fmt, ...)                                          \
-    njs_error_fmt_new(vm, &vm->retval, NJS_PROTOTYPE_TYPE_ERROR, fmt,         \
+    njs_error_fmt_new(vm, &vm->retval, NJS_OBJ_TYPE_TYPE_ERROR, fmt,          \
                       ##__VA_ARGS__)
 #define njs_uri_error(vm, fmt, ...)                                           \
-    njs_error_fmt_new(vm, &vm->retval, NJS_PROTOTYPE_URI_ERROR, fmt,          \
+    njs_error_fmt_new(vm, &vm->retval, NJS_OBJ_TYPE_URI_ERROR, fmt,           \
                       ##__VA_ARGS__)
 
-void njs_error_new(njs_vm_t *vm, njs_value_t *dst, njs_prototype_t type,
+void njs_error_new(njs_vm_t *vm, njs_value_t *dst, njs_object_type_t type,
     u_char *start, size_t size);
 void njs_noinline njs_error_fmt_new(njs_vm_t *vm, njs_value_t *dst,
-    njs_prototype_t type, const char *fmt, ...);
+    njs_object_type_t type, const char *fmt, ...);
 
 void njs_memory_error(njs_vm_t *vm);
 void njs_memory_error_set(njs_vm_t *vm, njs_value_t *value);
 
-njs_object_t *njs_error_alloc(njs_vm_t *vm, njs_prototype_t type,
+njs_object_t *njs_error_alloc(njs_vm_t *vm, njs_object_type_t type,
     const njs_value_t *name, const njs_value_t *message);
 njs_int_t njs_error_constructor(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused);
--- a/src/njs_extern.c	Thu Oct 31 18:17:31 2019 +0300
+++ b/src/njs_extern.c	Thu Oct 31 18:17:31 2019 +0300
@@ -106,7 +106,7 @@
              */
 
             function->object.__proto__ =
-                              &vm->prototypes[NJS_CONSTRUCTOR_FUNCTION].object;
+                              &vm->prototypes[NJS_OBJ_TYPE_FUNCTION].object;
             function->object.shared_hash = vm->shared->arrow_instance_hash;
             function->object.type = NJS_FUNCTION;
             function->object.shared = 1;
--- a/src/njs_fs.c	Thu Oct 31 18:17:31 2019 +0300
+++ b/src/njs_fs.c	Thu Oct 31 18:17:31 2019 +0300
@@ -1028,7 +1028,7 @@
         return NJS_ERROR;
     }
 
-    error = njs_error_alloc(vm, NJS_PROTOTYPE_ERROR, NULL, &string);
+    error = njs_error_alloc(vm, NJS_OBJ_TYPE_ERROR, NULL, &string);
     if (njs_slow_path(error == NULL)) {
         return NJS_ERROR;
     }
--- a/src/njs_function.c	Thu Oct 31 18:17:31 2019 +0300
+++ b/src/njs_function.c	Thu Oct 31 18:17:31 2019 +0300
@@ -46,7 +46,7 @@
         function->object.shared_hash = vm->shared->arrow_instance_hash;
     }
 
-    function->object.__proto__ = &vm->prototypes[NJS_PROTOTYPE_FUNCTION].object;
+    function->object.__proto__ = &vm->prototypes[NJS_OBJ_TYPE_FUNCTION].object;
     function->object.type = NJS_FUNCTION;
     function->object.shared = shared;
     function->object.extensible = 1;
@@ -122,7 +122,7 @@
     }
 
     *copy = *function;
-    copy->object.__proto__ = &vm->prototypes[NJS_PROTOTYPE_FUNCTION].object;
+    copy->object.__proto__ = &vm->prototypes[NJS_OBJ_TYPE_FUNCTION].object;
     copy->object.shared = 0;
 
     if (nesting == 0) {
--- a/src/njs_generator.c	Thu Oct 31 18:17:31 2019 +0300
+++ b/src/njs_generator.c	Thu Oct 31 18:17:31 2019 +0300
@@ -247,7 +247,7 @@
 
 
 #define njs_generate_syntax_error(vm, node, fmt, ...)                         \
-    njs_parser_node_error(vm, node, NJS_PROTOTYPE_SYNTAX_ERROR, fmt,          \
+    njs_parser_node_error(vm, node, NJS_OBJ_TYPE_SYNTAX_ERROR, fmt,           \
                           ##__VA_ARGS__)
 
 
@@ -417,23 +417,6 @@
         return njs_generate_template_literal(vm, generator, node);
 
     case NJS_TOKEN_THIS:
-    case NJS_TOKEN_OBJECT_CONSTRUCTOR:
-    case NJS_TOKEN_ARRAY_CONSTRUCTOR:
-    case NJS_TOKEN_NUMBER_CONSTRUCTOR:
-    case NJS_TOKEN_BOOLEAN_CONSTRUCTOR:
-    case NJS_TOKEN_STRING_CONSTRUCTOR:
-    case NJS_TOKEN_FUNCTION_CONSTRUCTOR:
-    case NJS_TOKEN_REGEXP_CONSTRUCTOR:
-    case NJS_TOKEN_DATE_CONSTRUCTOR:
-    case NJS_TOKEN_ERROR_CONSTRUCTOR:
-    case NJS_TOKEN_EVAL_ERROR_CONSTRUCTOR:
-    case NJS_TOKEN_INTERNAL_ERROR_CONSTRUCTOR:
-    case NJS_TOKEN_RANGE_ERROR_CONSTRUCTOR:
-    case NJS_TOKEN_REF_ERROR_CONSTRUCTOR:
-    case NJS_TOKEN_SYNTAX_ERROR_CONSTRUCTOR:
-    case NJS_TOKEN_TYPE_ERROR_CONSTRUCTOR:
-    case NJS_TOKEN_URI_ERROR_CONSTRUCTOR:
-    case NJS_TOKEN_MEMORY_ERROR_CONSTRUCTOR:
     case NJS_TOKEN_EXTERNAL:
         return NJS_OK;
 
--- a/src/njs_lexer.h	Thu Oct 31 18:17:31 2019 +0300
+++ b/src/njs_lexer.h	Thu Oct 31 18:17:31 2019 +0300
@@ -171,24 +171,6 @@
     NJS_TOKEN_ARGUMENTS,
     NJS_TOKEN_EVAL,
 
-    NJS_TOKEN_OBJECT_CONSTRUCTOR,
-    NJS_TOKEN_ARRAY_CONSTRUCTOR,
-    NJS_TOKEN_BOOLEAN_CONSTRUCTOR,
-    NJS_TOKEN_NUMBER_CONSTRUCTOR,
-    NJS_TOKEN_STRING_CONSTRUCTOR,
-    NJS_TOKEN_FUNCTION_CONSTRUCTOR,
-    NJS_TOKEN_REGEXP_CONSTRUCTOR,
-    NJS_TOKEN_DATE_CONSTRUCTOR,
-    NJS_TOKEN_ERROR_CONSTRUCTOR,
-    NJS_TOKEN_EVAL_ERROR_CONSTRUCTOR,
-    NJS_TOKEN_INTERNAL_ERROR_CONSTRUCTOR,
-    NJS_TOKEN_RANGE_ERROR_CONSTRUCTOR,
-    NJS_TOKEN_REF_ERROR_CONSTRUCTOR,
-    NJS_TOKEN_SYNTAX_ERROR_CONSTRUCTOR,
-    NJS_TOKEN_TYPE_ERROR_CONSTRUCTOR,
-    NJS_TOKEN_URI_ERROR_CONSTRUCTOR,
-    NJS_TOKEN_MEMORY_ERROR_CONSTRUCTOR,
-
     NJS_TOKEN_IMPORT,
     NJS_TOKEN_EXPORT,
 
--- a/src/njs_lexer_keyword.c	Thu Oct 31 18:17:31 2019 +0300
+++ b/src/njs_lexer_keyword.c	Thu Oct 31 18:17:31 2019 +0300
@@ -47,26 +47,6 @@
     { njs_str("finally"),       NJS_TOKEN_FINALLY, 0 },
     { njs_str("throw"),         NJS_TOKEN_THROW, 0 },
 
-    /* Builtin functions. */
-
-    { njs_str("Object"),        NJS_TOKEN_OBJECT_CONSTRUCTOR, 0 },
-    { njs_str("Array"),         NJS_TOKEN_ARRAY_CONSTRUCTOR, 0 },
-    { njs_str("Boolean"),       NJS_TOKEN_BOOLEAN_CONSTRUCTOR, 0 },
-    { njs_str("Number"),        NJS_TOKEN_NUMBER_CONSTRUCTOR, 0 },
-    { njs_str("String"),        NJS_TOKEN_STRING_CONSTRUCTOR, 0 },
-    { njs_str("Function"),      NJS_TOKEN_FUNCTION_CONSTRUCTOR, 0 },
-    { njs_str("RegExp"),        NJS_TOKEN_REGEXP_CONSTRUCTOR, 0 },
-    { njs_str("Date"),          NJS_TOKEN_DATE_CONSTRUCTOR, 0 },
-    { njs_str("Error"),         NJS_TOKEN_ERROR_CONSTRUCTOR, 0 },
-    { njs_str("EvalError"),     NJS_TOKEN_EVAL_ERROR_CONSTRUCTOR, 0 },
-    { njs_str("InternalError"), NJS_TOKEN_INTERNAL_ERROR_CONSTRUCTOR, 0 },
-    { njs_str("RangeError"),    NJS_TOKEN_RANGE_ERROR_CONSTRUCTOR, 0 },
-    { njs_str("ReferenceError"), NJS_TOKEN_REF_ERROR_CONSTRUCTOR, 0 },
-    { njs_str("SyntaxError"),   NJS_TOKEN_SYNTAX_ERROR_CONSTRUCTOR, 0 },
-    { njs_str("TypeError"),     NJS_TOKEN_TYPE_ERROR_CONSTRUCTOR, 0 },
-    { njs_str("URIError"),      NJS_TOKEN_URI_ERROR_CONSTRUCTOR, 0 },
-    { njs_str("MemoryError"),   NJS_TOKEN_MEMORY_ERROR_CONSTRUCTOR, 0 },
-
     /* Module. */
 
     { njs_str("import"),        NJS_TOKEN_IMPORT, 0 },
--- a/src/njs_module.c	Thu Oct 31 18:17:31 2019 +0300
+++ b/src/njs_module.c	Thu Oct 31 18:17:31 2019 +0300
@@ -537,7 +537,7 @@
         }
 
         *object = module->object;
-        object->__proto__ = &vm->prototypes[NJS_PROTOTYPE_OBJECT].object;
+        object->__proto__ = &vm->prototypes[NJS_OBJ_TYPE_OBJECT].object;
         object->shared = 0;
         object->error_data = 0;
 
--- a/src/njs_object.c	Thu Oct 31 18:17:31 2019 +0300
+++ b/src/njs_object.c	Thu Oct 31 18:17:31 2019 +0300
@@ -39,7 +39,7 @@
     if (njs_fast_path(object != NULL)) {
         njs_lvlhsh_init(&object->hash);
         njs_lvlhsh_init(&object->shared_hash);
-        object->__proto__ = &vm->prototypes[NJS_PROTOTYPE_OBJECT].object;
+        object->__proto__ = &vm->prototypes[NJS_OBJ_TYPE_OBJECT].object;
         object->type = NJS_OBJECT;
         object->shared = 0;
         object->extensible = 1;
@@ -68,7 +68,7 @@
 
     if (njs_fast_path(object != NULL)) {
         *object = *njs_object(value);
-        object->__proto__ = &vm->prototypes[NJS_PROTOTYPE_OBJECT].object;
+        object->__proto__ = &vm->prototypes[NJS_OBJ_TYPE_OBJECT].object;
         object->shared = 0;
         value->data.u.object = object;
         return object;
@@ -1605,7 +1605,7 @@
     function = njs_function(value);
     index = function - vm->constructors;
 
-    if (index >= 0 && index < NJS_PROTOTYPE_MAX) {
+    if (index >= 0 && index < NJS_OBJ_TYPE_MAX) {
         proto = njs_property_prototype_create(vm, &function->object.hash,
                                               &vm->prototypes[index].object);
     }
@@ -1928,7 +1928,7 @@
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     int32_t                 index;
-    njs_value_t             *cons;
+    njs_value_t             *cons, constructor;
     njs_object_t            *object;
     njs_object_prototype_t  *prototype;
 
@@ -1939,7 +1939,7 @@
             prototype = (njs_object_prototype_t *) object;
             index = prototype - vm->prototypes;
 
-            if (index >= 0 && index < NJS_PROTOTYPE_MAX) {
+            if (index >= 0 && index < NJS_OBJ_TYPE_MAX) {
                 goto found;
             }
 
@@ -1959,7 +1959,8 @@
 found:
 
     if (setval == NULL) {
-        setval = &vm->scopes[NJS_SCOPE_GLOBAL][index];
+        njs_set_function(&constructor, &vm->constructors[index]);
+        setval = &constructor;
     }
 
     cons = njs_property_constructor_create(vm, &prototype->object.hash, setval);
--- a/src/njs_object_hash.h	Thu Oct 31 18:17:31 2019 +0300
+++ b/src/njs_object_hash.h	Thu Oct 31 18:17:31 2019 +0300
@@ -21,6 +21,15 @@
         '_'), '_'), 'p'), 'r'), 'o'), 't'), 'o'), '_'), '_')
 
 
+#define NJS_ARRAY_HASH                                                        \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
+        'A'), 'r'), 'r'), 'a'), 'y')
+
+
 #define NJS_ARGV_HASH                                                         \
     njs_djb_hash_add(                                                         \
     njs_djb_hash_add(                                                         \
@@ -29,6 +38,17 @@
         'a'), 'r'), 'g'), 'v')
 
 
+#define NJS_BOOLEAN_HASH                                                      \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
+        'B'), 'o'), 'o'), 'l'), 'e'), 'a'), 'n')
+
+
 #define NJS_CONFIGURABLE_HASH                                                 \
     njs_djb_hash_add(                                                         \
     njs_djb_hash_add(                                                         \
@@ -60,6 +80,14 @@
         'c'), 'o'), 'n'), 's'), 't'), 'r'), 'u'), 'c'), 't'), 'o'), 'r')
 
 
+#define NJS_DATE_HASH                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
+        'D'), 'a'), 't'), 'e')
+
+
 #define NJS_ENUMERABLE_HASH                                                   \
     njs_djb_hash_add(                                                         \
     njs_djb_hash_add(                                                         \
@@ -83,6 +111,15 @@
         'e'), 'r'), 'r'), 'n'), 'o')
 
 
+#define NJS_ERROR_HASH                                                        \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
+        'E'), 'r'), 'r'), 'o'), 'r')
+
+
 #define NJS_ENCODING_HASH                                                     \
     njs_djb_hash_add(                                                         \
     njs_djb_hash_add(                                                         \
@@ -102,6 +139,19 @@
         'e'), 'n'), 'v')
 
 
+#define NJS_EVAL_ERROR_HASH                                                   \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
+        'E'), 'v'), 'a'), 'l'), 'E'), 'r'), 'r'), 'o'), 'r')
+
+
 #define NJS_FLAG_HASH                                                         \
     njs_djb_hash_add(                                                         \
     njs_djb_hash_add(                                                         \
@@ -110,6 +160,25 @@
         'f'), 'l'), 'a'), 'g')
 
 
+#define NJS_GET_HASH                                                          \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
+        'g'), 'e'), 't')
+
+
+#define NJS_FUNCTION_HASH                                                     \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
+        'F'), 'u'), 'n'), 'c'), 't'), 'i'), 'o'), 'n')
+
+
 #define NJS_INDEX_HASH                                                        \
     njs_djb_hash_add(                                                         \
     njs_djb_hash_add(                                                         \
@@ -128,6 +197,24 @@
         'i'), 'n'), 'p'), 'u'), 't')
 
 
+#define NJS_INTERNAL_ERROR_HASH                                               \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
+        'I'), 'n'), 't'), 'e'), 'r'), 'n'), 'a'), 'l'),                       \
+        'E'), 'r'), 'r'), 'o'), 'r')
+
+
 #define NJS_GROUPS_HASH                                                       \
     njs_djb_hash_add(                                                         \
     njs_djb_hash_add(                                                         \
@@ -179,6 +266,16 @@
         'n'), 'j'), 's')
 
 
+#define NJS_NUMBER_HASH                                                       \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
+        'N'), 'u'), 'm'), 'b'), 'e'), 'r')
+
+
 #define NJS_MATH_HASH                                                         \
     njs_djb_hash_add(                                                         \
     njs_djb_hash_add(                                                         \
@@ -187,6 +284,22 @@
         'M'), 'a'), 't'), 'h')
 
 
+#define NJS_MEMORY_ERROR_HASH                                                 \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
+        'M'), 'e'), 'm'), 'o'), 'r'), 'y'),                                   \
+        'E'), 'r'), 'r'), 'o'), 'r')
+
+
 #define NJS_MESSAGE_HASH                                                      \
     njs_djb_hash_add(                                                         \
     njs_djb_hash_add(                                                         \
@@ -206,15 +319,14 @@
         'm'), 'o'), 'd'), 'e')
 
 
-#define NJS_SYSCALL_HASH                                                      \
-    njs_djb_hash_add(                                                         \
+#define NJS_OBJECT_HASH                                                       \
     njs_djb_hash_add(                                                         \
     njs_djb_hash_add(                                                         \
     njs_djb_hash_add(                                                         \
     njs_djb_hash_add(                                                         \
     njs_djb_hash_add(                                                         \
     njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
-        's'), 'y'), 's'), 'c'), 'a'), 'l'), 'l')
+        'O'), 'b'), 'j'), 'e'), 'c'), 't')
 
 
 #define NJS_PATH_HASH                                                         \
@@ -249,6 +361,93 @@
         'p'), 'r'), 'o'), 't'), 'o'), 't'), 'y'), 'p'), 'e')
 
 
+#define NJS_RANGE_ERROR_HASH                                                  \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
+        'R'), 'a'), 'n'), 'g'), 'e'), 'E'), 'r'), 'r'), 'o'), 'r')
+
+
+#define NJS_REF_ERROR_HASH                                                    \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
+        'R'), 'e'), 'f'), 'e'), 'r'), 'e'), 'n'), 'c'), 'e'),                 \
+        'E'), 'r'), 'r'), 'o'), 'r')
+
+
+#define NJS_REGEXP_HASH                                                       \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
+        'R'), 'e'), 'g'), 'E'), 'x'), 'p')
+
+
+#define NJS_SET_HASH                                                          \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
+        's'), 'e'), 't')
+
+
+#define NJS_STRING_HASH                                                       \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
+        'S'), 't'), 'r'), 'i'), 'n'), 'g')
+
+
+#define NJS_SYNTAX_ERROR_HASH                                                 \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
+        'S'), 'y'), 'n'), 't'), 'a'), 'x'),                                   \
+        'E'), 'r'), 'r'), 'o'), 'r')
+
+
+#define NJS_SYSCALL_HASH                                                      \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
+        's'), 'y'), 's'), 'c'), 'a'), 'l'), 'l')
+
+
 #define NJS_TO_JSON_HASH                                                      \
     njs_djb_hash_add(                                                         \
     njs_djb_hash_add(                                                         \
@@ -271,6 +470,34 @@
         't'), 'o'), 'S'), 't'), 'r'), 'i'), 'n'), 'g')
 
 
+#define NJS_TO_ISO_STRING_HASH                                                \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
+        't'), 'o'), 'I'), 'S'), 'O'), 'S'), 't'), 'r'), 'i'), 'n'), 'g')
+
+
+#define NJS_TYPE_ERROR_HASH                                                   \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
+        'T'), 'y'), 'p'), 'e'), 'E'), 'r'), 'r'), 'o'), 'r')
+
+
 #define NJS_VALUE_HASH                                                        \
     njs_djb_hash_add(                                                         \
     njs_djb_hash_add(                                                         \
@@ -291,21 +518,6 @@
         'v'), 'a'), 'l'), 'u'), 'e'), 'O'), 'f')
 
 
-#define NJS_TO_ISO_STRING_HASH                                                \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
-        't'), 'o'), 'I'), 'S'), 'O'), 'S'), 't'), 'r'), 'i'), 'n'), 'g')
-
-
 #define NJS_WRITABABLE_HASH                                                   \
     njs_djb_hash_add(                                                         \
     njs_djb_hash_add(                                                         \
@@ -318,18 +530,17 @@
         'w'), 'r'), 'i'), 't'), 'a'), 'b'), 'l'), 'e')
 
 
-#define NJS_GET_HASH                                                          \
+#define NJS_URI_ERROR_HASH                                                    \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
+    njs_djb_hash_add(                                                         \
     njs_djb_hash_add(                                                         \
     njs_djb_hash_add(                                                         \
     njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
-        'g'), 'e'), 't')
-
-
-#define NJS_SET_HASH                                                          \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
-        's'), 'e'), 't')
+        'U'), 'R'), 'I'), 'e'), 'E'), 'r'), 'r'), 'o'), 'r')
 
 
 #endif /* _NJS_OBJECT_HASH_H_INCLUDED_ */
--- a/src/njs_parser.c	Thu Oct 31 18:17:31 2019 +0300
+++ b/src/njs_parser.c	Thu Oct 31 18:17:31 2019 +0300
@@ -2300,7 +2300,7 @@
 
 static void
 njs_parser_scope_error(njs_vm_t *vm, njs_parser_scope_t *scope,
-    njs_prototype_t type, uint32_t line, const char *fmt, va_list args)
+    njs_object_type_t type, uint32_t line, const char *fmt, va_list args)
 {
     size_t     width;
     u_char     msg[NJS_MAX_ERROR_STR];
@@ -2333,7 +2333,7 @@
 
 void
 njs_parser_lexer_error(njs_vm_t *vm, njs_parser_t *parser,
-    njs_prototype_t type, const char *fmt, ...)
+    njs_object_type_t type, const char *fmt, ...)
 {
     va_list  args;
 
@@ -2350,7 +2350,7 @@
 
 void
 njs_parser_node_error(njs_vm_t *vm, njs_parser_node_t *node,
-    njs_prototype_t type, const char *fmt, ...)
+    njs_object_type_t type, const char *fmt, ...)
 {
     va_list  args;
 
--- a/src/njs_parser.h	Thu Oct 31 18:17:31 2019 +0300
+++ b/src/njs_parser.h	Thu Oct 31 18:17:31 2019 +0300
@@ -109,9 +109,9 @@
 u_char *njs_parser_trace_handler(njs_trace_t *trace, njs_trace_data_t *td,
     u_char *start);
 void njs_parser_lexer_error(njs_vm_t *vm, njs_parser_t *parser,
-    njs_prototype_t type, const char *fmt, ...);
+    njs_object_type_t type, const char *fmt, ...);
 void njs_parser_node_error(njs_vm_t *vm, njs_parser_node_t *node,
-    njs_prototype_t type, const char *fmt, ...);
+    njs_object_type_t type, const char *fmt, ...);
 
 
 #define njs_parser_enter(vm, parser)                                          \
@@ -155,12 +155,12 @@
 
 
 #define njs_parser_syntax_error(vm, parser, fmt, ...)                         \
-    njs_parser_lexer_error(vm, parser, NJS_PROTOTYPE_SYNTAX_ERROR, fmt,       \
+    njs_parser_lexer_error(vm, parser, NJS_OBJ_TYPE_SYNTAX_ERROR, fmt,        \
                            ##__VA_ARGS__)
 
 
 #define njs_parser_ref_error(vm, parser, fmt, ...)                            \
-    njs_parser_lexer_error(vm, parser, NJS_PROTOTYPE_REF_ERROR, fmt,          \
+    njs_parser_lexer_error(vm, parser, NJS_OBJ_TYPE_REF_ERROR, fmt,           \
                            ##__VA_ARGS__)
 
 
--- a/src/njs_parser_expression.c	Thu Oct 31 18:17:31 2019 +0300
+++ b/src/njs_parser_expression.c	Thu Oct 31 18:17:31 2019 +0300
@@ -829,13 +829,6 @@
          * NJS_TOKEN_FUNCTION_CALL,
          * NJS_TOKEN_FUNCTION_EXPRESSION,
          * NJS_TOKEN_OPEN_PARENTHESIS,
-         * NJS_TOKEN_OBJECT_CONSTRUCTOR,
-         * NJS_TOKEN_ARRAY_CONSTRUCTOR,
-         * NJS_TOKEN_BOOLEAN_CONSTRUCTOR,
-         * NJS_TOKEN_NUMBER_CONSTRUCTOR,
-         * NJS_TOKEN_STRING_CONSTRUCTOR,
-         * NJS_TOKEN_FUNCTION_CONSTRUCTOR,
-         * NJS_TOKEN_REGEXP_CONSTRUCTOR,
          * NJS_TOKEN_EVAL.
          */
         func = njs_parser_node_new(vm, parser, NJS_TOKEN_FUNCTION_CALL);
--- a/src/njs_parser_terminal.c	Thu Oct 31 18:17:31 2019 +0300
+++ b/src/njs_parser_terminal.c	Thu Oct 31 18:17:31 2019 +0300
@@ -256,74 +256,6 @@
 
         break;
 
-    case NJS_TOKEN_OBJECT_CONSTRUCTOR:
-        node->index = NJS_INDEX_OBJECT;
-        break;
-
-    case NJS_TOKEN_ARRAY_CONSTRUCTOR:
-        node->index = NJS_INDEX_ARRAY;
-        break;
-
-    case NJS_TOKEN_BOOLEAN_CONSTRUCTOR:
-        node->index = NJS_INDEX_BOOLEAN;
-        break;
-
-    case NJS_TOKEN_NUMBER_CONSTRUCTOR:
-        node->index = NJS_INDEX_NUMBER;
-        break;
-
-    case NJS_TOKEN_STRING_CONSTRUCTOR:
-        node->index = NJS_INDEX_STRING;
-        break;
-
-    case NJS_TOKEN_FUNCTION_CONSTRUCTOR:
-        node->index = NJS_INDEX_FUNCTION;
-        break;
-
-    case NJS_TOKEN_REGEXP_CONSTRUCTOR:
-        node->index = NJS_INDEX_REGEXP;
-        break;
-
-    case NJS_TOKEN_DATE_CONSTRUCTOR:
-        node->index = NJS_INDEX_DATE;
-        break;
-
-    case NJS_TOKEN_ERROR_CONSTRUCTOR:
-        node->index = NJS_INDEX_OBJECT_ERROR;
-        break;
-
-    case NJS_TOKEN_EVAL_ERROR_CONSTRUCTOR:
-        node->index = NJS_INDEX_OBJECT_EVAL_ERROR;
-        break;
-
-    case NJS_TOKEN_INTERNAL_ERROR_CONSTRUCTOR:
-        node->index = NJS_INDEX_OBJECT_INTERNAL_ERROR;
-        break;
-
-    case NJS_TOKEN_RANGE_ERROR_CONSTRUCTOR:
-        node->index = NJS_INDEX_OBJECT_RANGE_ERROR;
-        break;
-
-    case NJS_TOKEN_REF_ERROR_CONSTRUCTOR:
-        node->index = NJS_INDEX_OBJECT_REF_ERROR;
-        break;
-
-    case NJS_TOKEN_SYNTAX_ERROR_CONSTRUCTOR:
-        node->index = NJS_INDEX_OBJECT_SYNTAX_ERROR;
-        break;
-
-    case NJS_TOKEN_TYPE_ERROR_CONSTRUCTOR:
-        node->index = NJS_INDEX_OBJECT_TYPE_ERROR;
-        break;
-
-    case NJS_TOKEN_URI_ERROR_CONSTRUCTOR:
-        node->index = NJS_INDEX_OBJECT_URI_ERROR;
-        break;
-
-    case NJS_TOKEN_MEMORY_ERROR_CONSTRUCTOR:
-        node->index = NJS_INDEX_OBJECT_MEMORY_ERROR;
-        break;
-
     case NJS_TOKEN_ARGUMENTS:
         njs_thread_log_debug("JS: arguments");
 
--- a/src/njs_regexp.c	Thu Oct 31 18:17:31 2019 +0300
+++ b/src/njs_regexp.c	Thu Oct 31 18:17:31 2019 +0300
@@ -708,7 +708,7 @@
     if (njs_fast_path(regexp != NULL)) {
         njs_lvlhsh_init(&regexp->object.hash);
         njs_lvlhsh_init(&regexp->object.shared_hash);
-        regexp->object.__proto__ = &vm->prototypes[NJS_PROTOTYPE_REGEXP].object;
+        regexp->object.__proto__ = &vm->prototypes[NJS_OBJ_TYPE_REGEXP].object;
         regexp->object.type = NJS_REGEXP;
         regexp->object.shared = 0;
         regexp->object.extensible = 1;
--- a/src/njs_vm.c	Thu Oct 31 18:17:31 2019 +0300
+++ b/src/njs_vm.c	Thu Oct 31 18:17:31 2019 +0300
@@ -596,7 +596,7 @@
         va_end(args);
     }
 
-    njs_error_new(vm, value, NJS_PROTOTYPE_ERROR, buf, p - buf);
+    njs_error_new(vm, value, NJS_OBJ_TYPE_ERROR, buf, p - buf);
 }
 
 
@@ -940,7 +940,7 @@
 
         /* MemoryError is a nonextensible internal error. */
 
-        if (njs_has_prototype(vm, src, NJS_PROTOTYPE_INTERNAL_ERROR)
+        if (njs_has_prototype(vm, src, NJS_OBJ_TYPE_INTERNAL_ERROR)
             && !njs_object(src)->extensible)
         {
             njs_string_get(&njs_string_memory_error, dst);
--- a/src/njs_vm.h	Thu Oct 31 18:17:31 2019 +0300
+++ b/src/njs_vm.h	Thu Oct 31 18:17:31 2019 +0300
@@ -68,8 +68,6 @@
 #define NJS_SCOPE_SHIFT        4
 #define NJS_SCOPE_MASK         ((uintptr_t) ((1 << NJS_SCOPE_SHIFT) - 1))
 
-#define NJS_INDEX_CACHE        NJS_SCOPE_GLOBAL
-
 #define NJS_INDEX_NONE         ((njs_index_t) 0)
 #define NJS_INDEX_ERROR        ((njs_index_t) -1)
 #define NJS_INDEX_THIS         ((njs_index_t) (0 | NJS_SCOPE_ARGUMENTS))
@@ -82,65 +80,37 @@
 
 
 typedef enum {
-    NJS_PROTOTYPE_OBJECT = 0,
-    NJS_PROTOTYPE_ARRAY,
-    NJS_PROTOTYPE_BOOLEAN,
-    NJS_PROTOTYPE_NUMBER,
-    NJS_PROTOTYPE_STRING,
-    NJS_PROTOTYPE_FUNCTION,
-    NJS_PROTOTYPE_REGEXP,
-    NJS_PROTOTYPE_DATE,
-    NJS_PROTOTYPE_CRYPTO_HASH,
-    NJS_PROTOTYPE_CRYPTO_HMAC,
-    NJS_PROTOTYPE_ERROR,
-    NJS_PROTOTYPE_EVAL_ERROR,
-    NJS_PROTOTYPE_INTERNAL_ERROR,
-    NJS_PROTOTYPE_RANGE_ERROR,
-    NJS_PROTOTYPE_REF_ERROR,
-    NJS_PROTOTYPE_SYNTAX_ERROR,
-    NJS_PROTOTYPE_TYPE_ERROR,
-    NJS_PROTOTYPE_URI_ERROR,
-#define NJS_PROTOTYPE_MAX      (NJS_PROTOTYPE_URI_ERROR + 1)
-} njs_prototype_t;
+    NJS_OBJ_TYPE_OBJECT = 0,
+    NJS_OBJ_TYPE_ARRAY,
+    NJS_OBJ_TYPE_BOOLEAN,
+    NJS_OBJ_TYPE_NUMBER,
+    NJS_OBJ_TYPE_STRING,
+    NJS_OBJ_TYPE_FUNCTION,
+    NJS_OBJ_TYPE_REGEXP,
+    NJS_OBJ_TYPE_DATE,
+    NJS_OBJ_TYPE_CRYPTO_HASH,
+    NJS_OBJ_TYPE_CRYPTO_HMAC,
+    NJS_OBJ_TYPE_ERROR,
+    NJS_OBJ_TYPE_EVAL_ERROR,
+    NJS_OBJ_TYPE_INTERNAL_ERROR,
+    NJS_OBJ_TYPE_RANGE_ERROR,
+    NJS_OBJ_TYPE_REF_ERROR,
+    NJS_OBJ_TYPE_SYNTAX_ERROR,
+    NJS_OBJ_TYPE_TYPE_ERROR,
+    NJS_OBJ_TYPE_URI_ERROR,
+    NJS_OBJ_TYPE_MEMORY_ERROR,
+#define NJS_OBJ_TYPE_MAX      (NJS_OBJ_TYPE_MEMORY_ERROR + 1)
+} njs_object_type_t;
 
 
 #define njs_primitive_prototype_index(type)                                   \
-    (NJS_PROTOTYPE_BOOLEAN + ((type) - NJS_BOOLEAN))
-
-
-#define njs_error_prototype_index(type)                                       \
-    (NJS_PROTOTYPE_ERROR + ((type) - NJS_OBJECT_ERROR))
+    (NJS_OBJ_TYPE_BOOLEAN + ((type) - NJS_BOOLEAN))
 
 
 #define njs_prototype_type(index)                                             \
     (index + NJS_OBJECT)
 
 
-enum njs_constructor_e {
-    NJS_CONSTRUCTOR_OBJECT =         NJS_PROTOTYPE_OBJECT,
-    NJS_CONSTRUCTOR_ARRAY =          NJS_PROTOTYPE_ARRAY,
-    NJS_CONSTRUCTOR_BOOLEAN =        NJS_PROTOTYPE_BOOLEAN,
-    NJS_CONSTRUCTOR_NUMBER =         NJS_PROTOTYPE_NUMBER,
-    NJS_CONSTRUCTOR_STRING =         NJS_PROTOTYPE_STRING,
-    NJS_CONSTRUCTOR_FUNCTION =       NJS_PROTOTYPE_FUNCTION,
-    NJS_CONSTRUCTOR_REGEXP =         NJS_PROTOTYPE_REGEXP,
-    NJS_CONSTRUCTOR_DATE =           NJS_PROTOTYPE_DATE,
-    NJS_CONSTRUCTOR_CRYPTO_HASH =    NJS_PROTOTYPE_CRYPTO_HASH,
-    NJS_CONSTRUCTOR_CRYPTO_HMAC =    NJS_PROTOTYPE_CRYPTO_HMAC,
-    NJS_CONSTRUCTOR_ERROR =          NJS_PROTOTYPE_ERROR,
-    NJS_CONSTRUCTOR_EVAL_ERROR =     NJS_PROTOTYPE_EVAL_ERROR,
-    NJS_CONSTRUCTOR_INTERNAL_ERROR = NJS_PROTOTYPE_INTERNAL_ERROR,
-    NJS_CONSTRUCTOR_RANGE_ERROR =    NJS_PROTOTYPE_RANGE_ERROR,
-    NJS_CONSTRUCTOR_REF_ERROR =      NJS_PROTOTYPE_REF_ERROR,
-    NJS_CONSTRUCTOR_SYNTAX_ERROR =   NJS_PROTOTYPE_SYNTAX_ERROR,
-    NJS_CONSTRUCTOR_TYPE_ERROR =     NJS_PROTOTYPE_TYPE_ERROR,
-    NJS_CONSTRUCTOR_URI_ERROR =      NJS_PROTOTYPE_URI_ERROR,
-    /* MemoryError has no its own prototype. */
-    NJS_CONSTRUCTOR_MEMORY_ERROR,
-#define NJS_CONSTRUCTOR_MAX    (NJS_CONSTRUCTOR_MEMORY_ERROR + 1)
-};
-
-
 enum njs_object_e {
     NJS_OBJECT_THIS = 0,
     NJS_OBJECT_NJS,
@@ -154,44 +124,17 @@
 #define njs_scope_index(value, type)                                          \
     ((njs_index_t) (((value) << NJS_SCOPE_SHIFT) | (type)))
 
+
 #define njs_global_scope_index(value)                                         \
-    ((njs_index_t) (((value) << NJS_SCOPE_SHIFT) | NJS_SCOPE_GLOBAL))
+    (njs_scope_index(value, NJS_SCOPE_GLOBAL))
 
 
-#define NJS_INDEX_OBJECT         njs_global_scope_index(NJS_CONSTRUCTOR_OBJECT)
-#define NJS_INDEX_ARRAY          njs_global_scope_index(NJS_CONSTRUCTOR_ARRAY)
-#define NJS_INDEX_BOOLEAN        njs_global_scope_index(NJS_CONSTRUCTOR_BOOLEAN)
-#define NJS_INDEX_NUMBER         njs_global_scope_index(NJS_CONSTRUCTOR_NUMBER)
-#define NJS_INDEX_STRING         njs_global_scope_index(NJS_CONSTRUCTOR_STRING)
-#define NJS_INDEX_FUNCTION                                                    \
-    njs_global_scope_index(NJS_CONSTRUCTOR_FUNCTION)
-#define NJS_INDEX_REGEXP         njs_global_scope_index(NJS_CONSTRUCTOR_REGEXP)
-#define NJS_INDEX_DATE           njs_global_scope_index(NJS_CONSTRUCTOR_DATE)
-#define NJS_INDEX_OBJECT_ERROR   njs_global_scope_index(NJS_CONSTRUCTOR_ERROR)
-#define NJS_INDEX_OBJECT_EVAL_ERROR                                           \
-    njs_global_scope_index(NJS_CONSTRUCTOR_EVAL_ERROR)
-#define NJS_INDEX_OBJECT_INTERNAL_ERROR                                       \
-    njs_global_scope_index(NJS_CONSTRUCTOR_INTERNAL_ERROR)
-#define NJS_INDEX_OBJECT_RANGE_ERROR                                          \
-    njs_global_scope_index(NJS_CONSTRUCTOR_RANGE_ERROR)
-#define NJS_INDEX_OBJECT_REF_ERROR                                            \
-    njs_global_scope_index(NJS_CONSTRUCTOR_REF_ERROR)
-#define NJS_INDEX_OBJECT_SYNTAX_ERROR                                         \
-    njs_global_scope_index(NJS_CONSTRUCTOR_SYNTAX_ERROR)
-#define NJS_INDEX_OBJECT_TYPE_ERROR                                           \
-    njs_global_scope_index(NJS_CONSTRUCTOR_TYPE_ERROR)
-#define NJS_INDEX_OBJECT_URI_ERROR                                            \
-    njs_global_scope_index(NJS_CONSTRUCTOR_URI_ERROR)
-#define NJS_INDEX_OBJECT_MEMORY_ERROR                                         \
-    njs_global_scope_index(NJS_CONSTRUCTOR_MEMORY_ERROR)
+#define NJS_INDEX_GLOBAL_OBJECT  njs_global_scope_index(0)
+#define NJS_INDEX_GLOBAL_OBJECT_OFFSET  njs_scope_index(0, 0)
 
-#define NJS_INDEX_GLOBAL_OBJECT  njs_global_scope_index(NJS_CONSTRUCTOR_MAX)
-#define NJS_INDEX_GLOBAL_OBJECT_OFFSET                                        \
-    njs_scope_index(NJS_CONSTRUCTOR_MAX, 0)
 
-#define NJS_INDEX_GLOBAL_RETVAL                                               \
-    njs_global_scope_index(NJS_CONSTRUCTOR_MAX + 1)
-#define NJS_INDEX_GLOBAL_OFFSET  njs_scope_index(NJS_CONSTRUCTOR_MAX + 1, 0)
+#define NJS_INDEX_GLOBAL_RETVAL  njs_global_scope_index(1)
+#define NJS_INDEX_GLOBAL_OFFSET  njs_scope_index(1, 0)
 
 
 #define njs_scope_offset(index)                                               \
@@ -249,8 +192,8 @@
      * they are copied from njs_vm_shared_t by single memcpy()
      * in njs_builtin_objects_clone().
      */
-    njs_object_prototype_t   prototypes[NJS_PROTOTYPE_MAX];
-    njs_function_t           constructors[NJS_CONSTRUCTOR_MAX];
+    njs_object_prototype_t   prototypes[NJS_OBJ_TYPE_MAX];
+    njs_function_t           constructors[NJS_OBJ_TYPE_MAX];
 
     njs_mp_t                 *mem_pool;
 
@@ -316,8 +259,8 @@
      * The prototypes and constructors arrays must be togther because they are
      * copied to njs_vm_t by single memcpy() in njs_builtin_objects_clone().
      */
-    njs_object_prototype_t   prototypes[NJS_PROTOTYPE_MAX];
-    njs_function_t           constructors[NJS_CONSTRUCTOR_MAX];
+    njs_object_prototype_t   prototypes[NJS_OBJ_TYPE_MAX];
+    njs_function_t           constructors[NJS_OBJ_TYPE_MAX];
 
     njs_regexp_pattern_t     *empty_regexp_pattern;
 };
--- a/src/test/njs_benchmark.c	Thu Oct 31 18:17:31 2019 +0300
+++ b/src/test/njs_benchmark.c	Thu Oct 31 18:17:31 2019 +0300
@@ -140,7 +140,18 @@
         "}"
         "fibo(32).length");
 
+    static njs_str_t  json = njs_str(
+        "JSON.parse('{\"a\":123, \"XXX\":[3,4,null]}').a");
+
+    static njs_str_t  for_loop = njs_str(
+        "var i; for (i = 0; i < 100000000; i++); i");
+
+    static njs_str_t while_loop = njs_str(
+        "var i = 0; while (i < 100000000) { i++ }; i");
+
     static njs_str_t  fibo_result = njs_str("3524578");
+    static njs_str_t  json_result = njs_str("123");
+    static njs_str_t  loop_result = njs_str("100000000");
 
 
     if (argc > 1) {
@@ -150,6 +161,18 @@
             return njs_unit_test_benchmark(&script, &result,
                                            "nJSVM clone/destroy", 1000000);
 
+        case 'j':
+            return njs_unit_test_benchmark(&json, &json_result,
+                                           "JSON.parse", 1000000);
+
+        case 'f':
+            return njs_unit_test_benchmark(&for_loop, &loop_result,
+                                           "for loop 100M", 1);
+
+        case 'w':
+            return njs_unit_test_benchmark(&while_loop, &loop_result,
+                                           "while loop 100M", 1);
+
         case 'n':
             return njs_unit_test_benchmark(&fibo_number, &fibo_result,
                                            "fibobench numbers", 1);
--- a/src/test/njs_unit_test.c	Thu Oct 31 18:17:31 2019 +0300
+++ b/src/test/njs_unit_test.c	Thu Oct 31 18:17:31 2019 +0300
@@ -7313,6 +7313,9 @@
     { njs_str("function f(undefined,NaN, Infinity){ return undefined + NaN + Infinity}; f('x', 'y', 'z')"),
       njs_str("xyz") },
 
+    { njs_str("(function (Object, Array, Boolean){ return Object + Array + Boolean})('x', 'y', 'z')"),
+      njs_str("xyz") },
+
     /* Recursive factorial. */
 
     { njs_str("function f(a) {"
@@ -8713,6 +8716,7 @@
     /* NativeErrors. */
 
     { njs_str(
+        "var global = this;"
         "function isValidNativeError(e) {"
         "   var inst;"
         "   var proto = Object.getPrototypeOf(e) === Error;"
@@ -8729,10 +8733,13 @@
         "   var name_prop = Object.getOwnPropertyDescriptor(e.prototype, 'message');"
         "   name_prop = name_prop.writable && !name_prop.enumerable && name_prop.configurable;"
         "   var own_proto_ctor = e.prototype.hasOwnProperty('constructor');"
+        "   var props = Object.getOwnPropertyDescriptor(global, e.prototype.name);"
+        "   props = props.writable && !props.enumerable && props.configurable;"
+        "   var same = e === global[e.prototype.name];"
         ""
         "   return proto && proto2 && iproto && iproto2 "
         "          && tpof && ctor && msg && name && name2 && name3 && name4 "
-        "          && name_prop && own_proto_ctor;"
+        "          && name_prop && own_proto_ctor && props && same;"
         "};"
         "["
         "  EvalError,"
@@ -9538,6 +9545,9 @@
     { njs_str("Array.length"),
       njs_str("1") },
 
+    { njs_str("delete this.Array; Array"),
+      njs_str("ReferenceError: \"Array\" is not defined in 1") },
+
     { njs_str("Array.__proto__ === Function.prototype"),
       njs_str("true") },
 
@@ -13264,6 +13274,23 @@
     { njs_str("delete this.JSON; JSON"),
       njs_str("ReferenceError: \"JSON\" is not defined in 1") },
 
+    /* Top-level constructors. */
+
+    { njs_str(
+        "var global = this;"
+        "function isValidConstructor(c) {"
+        "   var props = Object.getOwnPropertyDescriptor(global, c.name);"
+        "   props = props.writable && !props.enumerable && props.configurable;"
+        "   var same = c === global[c.name];"
+        ""
+        "   return props && same;"
+        "};"
+        "Object.getOwnPropertyNames(global)"
+        ".filter((k)=>(global[k] && global[k].prototype && global[k].prototype.constructor))"
+        ".map(k=>global[k])"
+        ".every(c => isValidConstructor(c))"),
+      njs_str("true") },
+
     /* JSON.parse() */
 
     { njs_str("JSON.parse('null')"),
--- a/test/njs_expect_test.exp	Thu Oct 31 18:17:31 2019 +0300
+++ b/test/njs_expect_test.exp	Thu Oct 31 18:17:31 2019 +0300
@@ -101,8 +101,8 @@
 
 njs_test {
     {"O\t"
-     "O\a*bject"}
-    {".\t\t"
+     "O\a*bject."}
+    {"\t\t"
      "Object.create*Object.isSealed"}
 }