[njs] Refactored working with built-in strings, symbols and small integers.

noreply at nginx.com noreply at nginx.com
Wed Apr 30 01:50:02 UTC 2025


details:   https://github.com/nginx/njs/commit/b28e50b1952d8788485e0f6c6126320702add1d3
branches:  master
commit:    b28e50b1952d8788485e0f6c6126320702add1d3
user:      Vadim Zhestikov <v.zhestikov at f5.com>
date:      Wed, 28 Aug 2024 22:03:14 -0700
description:
Refactored working with built-in strings, symbols and small integers.

- Implemented atom IDs for strings, symbols and small numbers, enabling
  equality checks via ID comparison
- Optimized string operations for faster property lookups and comparisons
- Removed short string inlining from njs_value_t structure

Performance improvements (arewefastyet/benchmarks/v8-v7 benchmark):
- Richards: +57% (631 → 989)
- Crypto: +7% (1445 → 1551)
- RayTrace: +37% (562 → 772)
- NavierStokes: +20% (2062 → 2465)
- Overall score: +29% (1014 → 1307)

In collaboration with Dmitry Volyntsev.

---
 auto/sources                       |   2 +-
 external/njs_crypto_module.c       |   8 +-
 external/njs_fs_module.c           |  28 +-
 external/njs_query_string_module.c |  44 +-
 external/njs_shell.c               |  13 +-
 external/njs_webcrypto_module.c    |  44 +-
 external/njs_xml_module.c          |  74 ++--
 external/njs_zlib_module.c         |   5 +-
 nginx/ngx_http_js_module.c         | 105 ++---
 nginx/ngx_js.c                     |  62 +--
 nginx/ngx_js.h                     |   8 +-
 nginx/ngx_js_fetch.c               | 121 ++++--
 nginx/ngx_js_shared_dict.c         |  67 +--
 nginx/ngx_js_shared_dict.h         |   3 +-
 nginx/ngx_stream_js_module.c       |  31 +-
 src/njs.h                          |  80 +++-
 src/njs_array.c                    | 215 +++++-----
 src/njs_array_buffer.c             |  38 +-
 src/njs_async.c                    |  30 +-
 src/njs_atom.c                     | 333 +++++++++++++++
 src/njs_atom.h                     |  70 +++
 src/njs_atom_defs.h                | 502 ++++++++++++++++++++++
 src/njs_boolean.c                  |  54 +--
 src/njs_buffer.c                   | 296 +++++++------
 src/njs_buffer.h                   |   2 +-
 src/njs_builtin.c                  | 543 +++++++++++-------------
 src/njs_date.c                     | 171 ++++----
 src/njs_encoding.c                 |  99 +++--
 src/njs_error.c                    | 259 ++++++------
 src/njs_extern.c                   |  56 ++-
 src/njs_flathsh.c                  | 175 +++++++-
 src/njs_flathsh.h                  |  38 +-
 src/njs_function.c                 | 160 +++----
 src/njs_function.h                 |   9 +-
 src/njs_generator.c                | 128 ++----
 src/njs_iterator.c                 |  69 ++-
 src/njs_json.c                     | 208 +++++----
 src/njs_lexer.c                    | 127 +-----
 src/njs_lexer.h                    |  28 +-
 src/njs_lexer_tables.h             | 445 --------------------
 src/njs_main.h                     |   4 +-
 src/njs_math.c                     | 131 +++---
 src/njs_module.c                   |   2 +-
 src/njs_number.c                   | 107 +++--
 src/njs_number.h                   |  27 +-
 src/njs_object.c                   | 607 +++++++++++++-------------
 src/njs_object.h                   | 166 ++++----
 src/njs_object_hash.h              | 842 -------------------------------------
 src/njs_object_prop.c              | 279 +++++-------
 src/njs_object_prop_declare.h      |  65 ++-
 src/njs_parser.c                   | 211 +++++-----
 src/njs_parser.h                   |   6 +-
 src/njs_promise.c                  | 121 +++---
 src/njs_regexp.c                   | 236 +++++------
 src/njs_scope.c                    |  25 +-
 src/njs_string.c                   | 505 +++++++++-------------
 src/njs_string.h                   |  27 +-
 src/njs_symbol.c                   | 195 ++++-----
 src/njs_typed_array.c              | 461 ++++++++++----------
 src/njs_value.c                    | 318 ++++++--------
 src/njs_value.h                    | 310 +++++++-------
 src/njs_value_conversion.h         |   2 +-
 src/njs_variable.c                 |  75 ++--
 src/njs_variable.h                 |  16 +-
 src/njs_vm.c                       | 199 ++++-----
 src/njs_vm.h                       |  27 +-
 src/njs_vmcode.c                   | 200 +++++----
 src/test/njs_benchmark.c           |   4 +-
 src/test/njs_externals_test.c      |  31 +-
 src/test/njs_unit_test.c           |  13 +
 70 files changed, 4704 insertions(+), 5258 deletions(-)

diff --git a/auto/sources b/auto/sources
index 9b33eead..0e8db2cd 100644
--- a/auto/sources
+++ b/auto/sources
@@ -19,10 +19,10 @@ NJS_LIB_SRCS=" \
    src/njs_utils.c \
    src/njs_chb.c \
    src/njs_value.c \
+   src/njs_atom.c \
    src/njs_vm.c \
    src/njs_vmcode.c \
    src/njs_lexer.c \
-   src/njs_lexer_keyword.c \
    src/njs_parser.c \
    src/njs_variable.c \
    src/njs_scope.c \
diff --git a/external/njs_crypto_module.c b/external/njs_crypto_module.c
index 2781a485..cdbb4b30 100644
--- a/external/njs_crypto_module.c
+++ b/external/njs_crypto_module.c
@@ -362,7 +362,7 @@ njs_hash_prototype_update(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             return NJS_ERROR;
         }
 
-        njs_value_string_get(njs_value_arg(&result), &data);
+        njs_value_string_get(vm, njs_value_arg(&result), &data);
 
     } else if (njs_value_is_buffer(value)) {
         ret = njs_value_buffer_get(vm, value, &data);
@@ -526,7 +526,7 @@ njs_crypto_create_hmac(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             return NJS_ERROR;
         }
 
-        njs_value_string_get(njs_value_arg(&result), &key);
+        njs_value_string_get(vm, njs_value_arg(&result), &key);
 
     } else if (njs_value_is_buffer(value)) {
         ret = njs_value_buffer_get(vm, value, &key);
@@ -589,7 +589,7 @@ njs_crypto_algorithm(njs_vm_t *vm, njs_value_t *value)
         return NULL;
     }
 
-    njs_value_string_get(value, &name);
+    njs_value_string_get(vm, value, &name);
 
     for (e = &njs_hash_algorithms[0]; e->name.length != 0; e++) {
         if (njs_strstr_eq(&name, &e->name)) {
@@ -618,7 +618,7 @@ njs_crypto_encoding(njs_vm_t *vm, njs_value_t *value)
         return &njs_encodings[0];
     }
 
-    njs_value_string_get(value, &name);
+    njs_value_string_get(vm, value, &name);
 
     for (e = &njs_encodings[1]; e->name.length != 0; e++) {
         if (njs_strstr_eq(&name, &e->name)) {
diff --git a/external/njs_fs_module.c b/external/njs_fs_module.c
index 5f8924ae..c56a685a 100644
--- a/external/njs_fs_module.c
+++ b/external/njs_fs_module.c
@@ -180,7 +180,8 @@ static njs_int_t njs_fs_write_file(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t calltype, njs_value_t *retval);
 
 static njs_int_t njs_fs_constant(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval);
 
 static njs_int_t njs_fs_dirent_constructor(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
@@ -190,7 +191,8 @@ static njs_int_t njs_fs_dirent_test(njs_vm_t *vm, njs_value_t *args,
 static njs_int_t njs_fs_stats_test(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t testtype, njs_value_t *retval);
 static njs_int_t njs_fs_stats_prop(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval);
 static njs_int_t njs_fs_stats_create(njs_vm_t *vm, struct stat *st,
     njs_value_t *retval);
 
@@ -1966,7 +1968,7 @@ njs_fs_readdir(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 
     if (njs_value_is_string(njs_value_arg(&encode))) {
-        njs_value_string_get(njs_value_arg(&encode), &s);
+        njs_value_string_get(vm, njs_value_arg(&encode), &s);
 
     } else {
         s.length = 0;
@@ -2111,7 +2113,7 @@ njs_fs_readlink(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     encoding = NULL;
 
     if (njs_value_is_string(njs_value_arg(&encode))) {
-        njs_value_string_get(njs_value_arg(&encode), &s);
+        njs_value_string_get(vm, njs_value_arg(&encode), &s);
 
     } else {
         s.length = 0;
@@ -2203,7 +2205,7 @@ njs_fs_realpath(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     encoding = NULL;
 
     if (njs_value_is_string(njs_value_arg(&encode))) {
-        njs_value_string_get(njs_value_arg(&encode), &s);
+        njs_value_string_get(vm, njs_value_arg(&encode), &s);
 
     } else {
         s.length = 0;
@@ -2610,7 +2612,7 @@ njs_fs_write(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             return NJS_ERROR;
         }
 
-        njs_value_string_get(njs_value_arg(&result), &data);
+        njs_value_string_get(vm, njs_value_arg(&result), &data);
 
         goto process;
     }
@@ -2790,7 +2792,7 @@ njs_fs_write_file(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             return NJS_ERROR;
         }
 
-        njs_value_string_get(njs_value_arg(&result), &content);
+        njs_value_string_get(vm, njs_value_arg(&result), &content);
     }
 
     flags = njs_fs_flags(vm, njs_value_arg(&flag), O_CREAT | O_WRONLY);
@@ -3213,7 +3215,7 @@ njs_fs_path(njs_vm_t *vm, char storage[NJS_MAX_PATH + 1], njs_value_t *src,
     njs_int_t  ret;
 
     if (njs_value_is_string(src)) {
-        njs_value_string_get(src, &str);
+        njs_value_string_get(vm, src, &str);
 
     } else if (njs_value_is_buffer(src)) {
         ret = njs_value_buffer_get(vm, src, &str);
@@ -3261,7 +3263,7 @@ njs_fs_flags(njs_vm_t *vm, njs_value_t *value, int default_flags)
         return -1;
     }
 
-    njs_value_string_get(value, &flags);
+    njs_value_string_get(vm, value, &flags);
 
     for (fl = &njs_flags_table[0]; fl->name.length != 0; fl++) {
         if (njs_strstr_eq(&flags, &fl->name)) {
@@ -3651,8 +3653,8 @@ njs_fs_stats_test(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 
 static njs_int_t
-njs_fs_stats_prop(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value,
-    njs_value_t *setval, njs_value_t *retval)
+njs_fs_stats_prop(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
+    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     double      v;
     njs_int_t   ret;
@@ -3870,8 +3872,8 @@ njs_fs_bytes_written_create(njs_vm_t *vm, int bytes, njs_value_t *buffer,
 
 
 njs_int_t
-njs_fs_constant(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value,
-    njs_value_t *setval, njs_value_t *retval)
+njs_fs_constant(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
+    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     njs_value_number_set(retval,  njs_vm_prop_magic32(prop));
 
diff --git a/external/njs_query_string_module.c b/external/njs_query_string_module.c
index e2f849d2..c5b4d58a 100644
--- a/external/njs_query_string_module.c
+++ b/external/njs_query_string_module.c
@@ -294,8 +294,8 @@ njs_query_string_append(njs_vm_t *vm, njs_value_t *object, const u_char *key,
         }
     }
 
-    ret = njs_value_property(vm, object, njs_value_arg(&name),
-                             njs_value_arg(&retval));
+    ret = njs_value_property_val(vm, object, njs_value_arg(&name),
+                                 njs_value_arg(&retval));
 
     if (ret == NJS_OK) {
         if (njs_value_is_array(njs_value_arg(&retval))) {
@@ -331,8 +331,8 @@ njs_query_string_append(njs_vm_t *vm, njs_value_t *object, const u_char *key,
         njs_value_assign(&value, &array);
     }
 
-    return njs_value_property_set(vm, object, njs_value_arg(&name),
-                                  njs_value_arg(&value));
+    return njs_value_property_val_set(vm, object, njs_value_arg(&name),
+                                      njs_value_arg(&value));
 }
 
 
@@ -383,7 +383,7 @@ njs_query_string_parse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     string = njs_arg(args, nargs, 1);
 
     if (njs_value_is_string(string)) {
-        njs_value_string_get(string, &str);
+        njs_value_string_get(vm, string, &str);
 
     } else {
         str = njs_str_value("");
@@ -399,8 +399,8 @@ njs_query_string_parse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             return ret;
         }
 
-        if (njs_string_length(njs_value_arg(&val_sep)) != 0) {
-            njs_value_string_get(njs_value_arg(&val_sep), &sep);
+        if (njs_value_string_length(vm, njs_value_arg(&val_sep)) != 0) {
+            njs_value_string_get(vm, njs_value_arg(&val_sep), &sep);
         }
     }
 
@@ -411,8 +411,8 @@ njs_query_string_parse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             return ret;
         }
 
-        if (njs_string_length(njs_value_arg(&val_eq)) != 0) {
-            njs_value_string_get(njs_value_arg(&val_eq), &eq);
+        if (njs_value_string_length(vm, njs_value_arg(&val_eq)) != 0) {
+            njs_value_string_get(vm, njs_value_arg(&val_eq), &eq);
         }
     }
 
@@ -614,7 +614,7 @@ njs_query_string_encoder_call(njs_vm_t *vm, njs_chb_t *chain,
     }
 
     if (njs_fast_path(njs_query_string_is_native_encoder(encoder))) {
-        njs_value_string_get(string, &str);
+        njs_value_string_get(vm, string, &str);
         return njs_query_string_encode(chain, &str);
     }
 
@@ -631,7 +631,7 @@ njs_query_string_encoder_call(njs_vm_t *vm, njs_chb_t *chain,
         }
     }
 
-    njs_value_string_get(njs_value_arg(&retval), &str);
+    njs_value_string_get(vm, njs_value_arg(&retval), &str);
 
     njs_chb_append_str(chain, &str);
 
@@ -705,8 +705,8 @@ njs_query_string_stringify(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             return ret;
         }
 
-        if (njs_string_length(arg) > 0) {
-            njs_value_string_get(arg, &sep);
+        if (njs_value_string_length(vm, arg) > 0) {
+            njs_value_string_get(vm, arg, &sep);
         }
     }
 
@@ -717,8 +717,8 @@ njs_query_string_stringify(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             return ret;
         }
 
-        if (njs_string_length(arg) > 0) {
-            njs_value_string_get(arg, &eq);
+        if (njs_value_string_length(vm, arg) > 0) {
+            njs_value_string_get(vm, arg, &eq);
         }
     }
 
@@ -764,8 +764,8 @@ njs_query_string_stringify(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     for (n = 0; n < keys_length; n++, string++) {
-        ret = njs_value_property(vm, object, njs_value_arg(string),
-                                 njs_value_arg(&value));
+        ret = njs_value_property_val(vm, object, njs_value_arg(string),
+                                     njs_value_arg(&value));
         if (njs_slow_path(ret == NJS_ERROR)) {
             goto failed;
         }
@@ -775,9 +775,9 @@ njs_query_string_stringify(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
             for (i = 0; i < len; i++) {
                 njs_value_number_set(njs_value_arg(&key), i);
-                ret = njs_value_property(vm, njs_value_arg(&value),
-                                         njs_value_arg(&key),
-                                         njs_value_arg(&result));
+                ret = njs_value_property_val(vm, njs_value_arg(&value),
+                                             njs_value_arg(&key),
+                                             njs_value_arg(&result));
                 if (njs_slow_path(ret == NJS_ERROR)) {
                     goto failed;
                 }
@@ -839,7 +839,7 @@ njs_query_string_escape(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         string = njs_value_arg(&value);
     }
 
-    njs_value_string_get(string, &str);
+    njs_value_string_get(vm, string, &str);
 
     NJS_CHB_MP_INIT(&chain, njs_vm_memory_pool(vm));
 
@@ -876,7 +876,7 @@ njs_query_string_unescape(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         string = njs_value_arg(&value);
     }
 
-    njs_value_string_get(string, &str);
+    njs_value_string_get(vm, string, &str);
 
     return njs_query_string_decode(vm, retval, str.start, str.length);
 }
diff --git a/external/njs_shell.c b/external/njs_shell.c
index aeab226c..75316339 100644
--- a/external/njs_shell.c
+++ b/external/njs_shell.c
@@ -1585,8 +1585,9 @@ njs_engine_njs_complete(njs_engine_t *engine, njs_str_t *expression)
             return NULL;
         }
 
-        ret = njs_value_property(vm, njs_value_arg(&value), njs_value_arg(&key),
-                                 njs_value_arg(&retval));
+        ret = njs_value_property_val(vm, njs_value_arg(&value),
+                                     njs_value_arg(&key),
+                                     njs_value_arg(&retval));
         if (njs_slow_path(ret != NJS_OK)) {
             if (ret == NJS_DECLINED && !global) {
                 goto done;
@@ -3664,11 +3665,11 @@ njs_ext_console_time(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
                 return ret;
             }
 
-            njs_value_string_get(value, &name);
+            njs_value_string_get(vm, value, &name);
         }
 
     } else {
-        njs_value_string_get(value, &name);
+        njs_value_string_get(vm, value, &name);
     }
 
     if (njs_console_time(console, &name) != NJS_OK) {
@@ -3713,11 +3714,11 @@ njs_ext_console_time_end(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
                 return ret;
             }
 
-            njs_value_string_get(value, &name);
+            njs_value_string_get(vm, value, &name);
         }
 
     } else {
-        njs_value_string_get(value, &name);
+        njs_value_string_get(vm, value, &name);
     }
 
     njs_console_time_end(console, &name, ns);
diff --git a/external/njs_webcrypto_module.c b/external/njs_webcrypto_module.c
index 59d02c1d..d2918891 100644
--- a/external/njs_webcrypto_module.c
+++ b/external/njs_webcrypto_module.c
@@ -129,13 +129,17 @@ static njs_int_t njs_ext_unwrap_key(njs_vm_t *vm, njs_value_t *args,
 static njs_int_t njs_ext_wrap_key(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 static njs_int_t njs_key_ext_algorithm(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval);
 static njs_int_t njs_key_ext_extractable(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval);
 static njs_int_t njs_key_ext_type(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval);
 static njs_int_t njs_key_ext_usages(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval);
 static njs_int_t njs_ext_get_random_values(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 
@@ -2767,7 +2771,7 @@ fail0:
             return NULL;
         }
 
-        njs_value_string_get(val, &alg);
+        njs_value_string_get(vm, val, &alg);
 
         for (w = &njs_webcrypto_alg_hash[0]; w->name.length != 0; w++) {
             if (njs_strstr_eq(&alg, &w->name)) {
@@ -3068,7 +3072,7 @@ fail0:
 
     val = njs_vm_object_prop(vm, jwk, &string_crv, &value);
     if (val != NULL && !njs_value_is_undefined(val)) {
-        njs_value_string_get(val, &name);
+        njs_value_string_get(vm, val, &name);
 
         for (e = &njs_webcrypto_curve[0]; e->name.length != 0; e++) {
             if (njs_strstr_eq(&name, &e->name)) {
@@ -3194,7 +3198,7 @@ njs_import_jwk_oct(njs_vm_t *vm, njs_value_t *jwk, njs_webcrypto_key_t *key)
         return NJS_ERROR;
     }
 
-    njs_value_string_get(val, &b64);
+    njs_value_string_get(vm, val, &b64);
 
     (void) njs_decode_base64url_length(&b64, &key->u.s.raw.length);
 
@@ -3213,7 +3217,7 @@ njs_import_jwk_oct(njs_vm_t *vm, njs_value_t *jwk, njs_webcrypto_key_t *key)
         return NJS_ERROR;
     }
 
-    njs_value_string_get(val, &alg);
+    njs_value_string_get(vm, val, &alg);
 
     size = 16;
 
@@ -4133,8 +4137,8 @@ njs_ext_wrap_key(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 
 static njs_int_t
-njs_key_ext_algorithm(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value,
-    njs_value_t *setval, njs_value_t *retval)
+njs_key_ext_algorithm(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
+    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     u_char               *start;
     njs_int_t            ret;
@@ -4292,7 +4296,7 @@ njs_key_ext_algorithm(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value,
 
 
 static njs_int_t
-njs_key_ext_extractable(njs_vm_t *vm, njs_object_prop_t *prop,
+njs_key_ext_extractable(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     njs_webcrypto_key_t  *key;
@@ -4310,8 +4314,8 @@ njs_key_ext_extractable(njs_vm_t *vm, njs_object_prop_t *prop,
 
 
 static njs_int_t
-njs_key_ext_type(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value,
-    njs_value_t *setval, njs_value_t *retval)
+njs_key_ext_type(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
+    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     const char           *type;
     njs_webcrypto_key_t  *key;
@@ -4336,8 +4340,8 @@ njs_key_ext_type(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value,
 
 
 static njs_int_t
-njs_key_ext_usages(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value,
-    njs_value_t *setval, njs_value_t *retval)
+njs_key_ext_usages(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
+    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     njs_webcrypto_key_t  *key;
 
@@ -4436,7 +4440,7 @@ njs_key_format(njs_vm_t *vm, njs_value_t *value)
         return NJS_KEY_FORMAT_UNKNOWN;
     }
 
-    njs_value_string_get(njs_value_arg(&string), &format);
+    njs_value_string_get(vm, njs_value_arg(&string), &format);
 
     for (e = &njs_webcrypto_format[0]; e->name.length != 0; e++) {
         if (njs_strstr_eq(&format, &e->name)) {
@@ -4482,7 +4486,7 @@ njs_key_usage_array_handler(njs_vm_t *vm, njs_iterator_args_t *args,
         return NJS_ERROR;
     }
 
-    njs_value_string_get(njs_value_arg(&usage), &u);
+    njs_value_string_get(vm, njs_value_arg(&usage), &u);
 
     for (e = &njs_webcrypto_usage[0]; e->name.length != 0; e++) {
         if (njs_strstr_eq(&u, &e->name)) {
@@ -4585,7 +4589,7 @@ njs_key_algorithm(njs_vm_t *vm, njs_value_t *options)
         return NULL;
     }
 
-    njs_value_string_get(njs_value_arg(&name), &a);
+    njs_value_string_get(vm, njs_value_arg(&name), &a);
 
     for (e = &njs_webcrypto_alg[0]; e->name.length != 0; e++) {
         if (njs_strstr_case_eq(&a, &e->name)) {
@@ -4647,7 +4651,7 @@ njs_algorithm_hash(njs_vm_t *vm, njs_value_t *options,
         return NJS_ERROR;
     }
 
-    njs_value_string_get(njs_value_arg(&value), &name);
+    njs_value_string_get(vm, njs_value_arg(&value), &name);
 
     for (e = &njs_webcrypto_hash[0]; e->name.length != 0; e++) {
         if (njs_strstr_eq(&name, &e->name)) {
@@ -4722,7 +4726,7 @@ njs_algorithm_curve(njs_vm_t *vm, njs_value_t *options, int *curve)
         return NJS_ERROR;
     }
 
-    njs_value_string_get(njs_value_arg(&value), &name);
+    njs_value_string_get(vm, njs_value_arg(&value), &name);
 
     for (e = &njs_webcrypto_curve[0]; e->name.length != 0; e++) {
         if (njs_strstr_eq(&name, &e->name)) {
diff --git a/external/njs_xml_module.c b/external/njs_xml_module.c
index e524ba5c..95e5024a 100644
--- a/external/njs_xml_module.c
+++ b/external/njs_xml_module.c
@@ -43,27 +43,32 @@ static njs_int_t njs_xml_ext_canonicalization(njs_vm_t *vm, njs_value_t *args,
 static njs_int_t njs_xml_doc_ext_prop_keys(njs_vm_t *vm, njs_value_t *value,
     njs_value_t *keys);
 static njs_int_t njs_xml_doc_ext_root(njs_vm_t *vm, njs_object_prop_t *prop,
-     njs_value_t *value, njs_value_t *unused, njs_value_t *retval);
+    uint32_t atom_id, njs_value_t *value, njs_value_t *unused,
+    njs_value_t *retval);
 static njs_int_t njs_xml_node_ext_prop_keys(njs_vm_t *vm, njs_value_t *value,
     njs_value_t *keys);
 static njs_int_t njs_xml_node_ext_prop_handler(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *unused,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t atom_id, njs_value_t *value,
+    njs_value_t *unused, njs_value_t *retval);
 static njs_int_t njs_xml_attr_ext_prop_keys(njs_vm_t *vm, njs_value_t *value,
     njs_value_t *keys);
 static njs_int_t njs_xml_attr_ext_prop_handler(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *unused,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t atom_id, njs_value_t *value,
+    njs_value_t *unused, njs_value_t *retval);
 static njs_int_t njs_xml_node_ext_add_child(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 static njs_int_t njs_xml_node_ext_attrs(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval);
 static njs_int_t njs_xml_node_ext_name(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval);
 static njs_int_t njs_xml_node_ext_ns(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval);
 static njs_int_t njs_xml_node_ext_parent(njs_vm_t *vm, njs_object_prop_t *prop,
-     njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval);
 static njs_int_t njs_xml_node_ext_remove_all_attributes(njs_vm_t *vm,
     njs_value_t *args, njs_uint_t nargs, njs_index_t unused,
     njs_value_t *retval);
@@ -83,9 +88,11 @@ static njs_int_t njs_xml_node_ext_set_text(njs_vm_t *vm,
     njs_value_t *args, njs_uint_t nargs, njs_index_t unused,
     njs_value_t *retval);
 static njs_int_t njs_xml_node_ext_tags(njs_vm_t *vm, njs_object_prop_t *prop,
-     njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval);
 static njs_int_t njs_xml_node_ext_text(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval);
 
 static njs_int_t njs_xml_node_attr_handler(njs_vm_t *vm, xmlNode *current,
     njs_str_t *name, njs_value_t *setval, njs_value_t *retval);
@@ -505,8 +512,8 @@ njs_xml_doc_ext_prop_keys(njs_vm_t *vm, njs_value_t *value, njs_value_t *keys)
 
 
 static njs_int_t
-njs_xml_doc_ext_root(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value,
-     njs_value_t *unused, njs_value_t *retval)
+njs_xml_doc_ext_root(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t atom_id,
+     njs_value_t *value, njs_value_t *unused, njs_value_t *retval)
 {
     xmlNode        *node;
     njs_int_t      ret;
@@ -523,7 +530,7 @@ njs_xml_doc_ext_root(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value,
     any = njs_vm_prop_magic32(prop);
 
     if (!any) {
-        ret = njs_vm_prop_name(vm, prop, &name);
+        ret = njs_vm_prop_name(vm, atom_id, &name);
         if (njs_slow_path(ret != NJS_OK)) {
             njs_value_undefined_set(retval);
             return NJS_DECLINED;
@@ -656,7 +663,8 @@ njs_xml_node_ext_prop_keys(njs_vm_t *vm, njs_value_t *value, njs_value_t *keys)
 
 static njs_int_t
 njs_xml_node_ext_prop_handler(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t atom_id, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     xmlNode    *current;
     njs_int_t  ret;
@@ -675,7 +683,7 @@ njs_xml_node_ext_prop_handler(njs_vm_t *vm, njs_object_prop_t *prop,
         return NJS_DECLINED;
     }
 
-    ret = njs_vm_prop_name(vm, prop, &name);
+    ret = njs_vm_prop_name(vm, atom_id, &name);
     if (njs_slow_path(ret != NJS_OK)) {
         njs_value_undefined_set(retval);
         return NJS_DECLINED;
@@ -773,7 +781,7 @@ error:
 
 
 static njs_int_t
-njs_xml_node_ext_attrs(njs_vm_t *vm, njs_object_prop_t *prop,
+njs_xml_node_ext_attrs(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     xmlNode  *current;
@@ -790,8 +798,8 @@ njs_xml_node_ext_attrs(njs_vm_t *vm, njs_object_prop_t *prop,
 
 
 static njs_int_t
-njs_xml_node_ext_name(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value,
-     njs_value_t *setval, njs_value_t *retval)
+njs_xml_node_ext_name(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
+     njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     xmlNode  *current;
 
@@ -807,7 +815,7 @@ njs_xml_node_ext_name(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value,
 
 
 static njs_int_t
-njs_xml_node_ext_ns(njs_vm_t *vm, njs_object_prop_t *prop,
+njs_xml_node_ext_ns(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     xmlNode  *current;
@@ -824,7 +832,7 @@ njs_xml_node_ext_ns(njs_vm_t *vm, njs_object_prop_t *prop,
 
 
 static njs_int_t
-njs_xml_node_ext_parent(njs_vm_t *vm, njs_object_prop_t *prop,
+njs_xml_node_ext_parent(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     xmlNode  *current;
@@ -853,7 +861,8 @@ njs_xml_node_ext_remove_attribute(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_xml_node_ext_remove_all_attributes(njs_vm_t *vm,
-    njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval)
+    njs_value_t *args, njs_uint_t nargs, njs_index_t unused,
+    njs_value_t *retval)
 {
     xmlNode  *current;
 
@@ -898,7 +907,7 @@ njs_xml_node_ext_remove_children(njs_vm_t *vm, njs_value_t *args,
             return NJS_ERROR;
         }
 
-        njs_value_string_get(selector, &name);
+        njs_value_string_get(vm, selector, &name);
 
         return njs_xml_node_tag_remove(vm, current, &name);
     }
@@ -924,7 +933,7 @@ static njs_int_t
 njs_xml_node_ext_remove_text(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused, njs_value_t *retval)
 {
-    return njs_xml_node_ext_text(vm, NULL, njs_argument(args, 0), NULL, NULL);
+    return njs_xml_node_ext_text(vm, NULL, 0, njs_argument(args, 0), NULL, NULL);
 }
 
 
@@ -949,7 +958,7 @@ njs_xml_node_ext_set_attribute(njs_vm_t *vm, njs_value_t *args,
         return NJS_ERROR;
     }
 
-    njs_value_string_get(name, &str);
+    njs_value_string_get(vm, name, &str);
 
     return njs_xml_node_attr_handler(vm, current, &str, njs_arg(args, nargs, 2),
                                      !remove ? retval : NULL);
@@ -960,14 +969,14 @@ static njs_int_t
 njs_xml_node_ext_set_text(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused, njs_value_t *retval)
 {
-    return njs_xml_node_ext_text(vm, NULL, njs_argument(args, 0),
+    return njs_xml_node_ext_text(vm, NULL, 0, njs_argument(args, 0),
                                  njs_arg(args, nargs, 1), retval);
 }
 
 
 static njs_int_t
-njs_xml_node_ext_tags(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value,
-     njs_value_t *setval, njs_value_t *retval)
+njs_xml_node_ext_tags(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
+     njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     xmlNode    *current;
     njs_str_t  name;
@@ -986,7 +995,7 @@ njs_xml_node_ext_tags(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value,
 
 
 static njs_int_t
-njs_xml_node_ext_text(njs_vm_t *vm, njs_object_prop_t *unused,
+njs_xml_node_ext_text(njs_vm_t *vm, njs_object_prop_t *unused, uint32_t unused1,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     u_char     *text;
@@ -1022,7 +1031,7 @@ njs_xml_node_ext_text(njs_vm_t *vm, njs_object_prop_t *unused,
             return NJS_ERROR;
         }
 
-        njs_value_string_get(setval, &content);
+        njs_value_string_get(vm, setval, &content);
 
         ret = njs_xml_encode_special_chars(vm, &content, &enc);
         if (njs_slow_path(ret != NJS_OK)) {
@@ -1875,7 +1884,8 @@ njs_xml_attr_ext_prop_keys(njs_vm_t *vm, njs_value_t *value, njs_value_t *keys)
 
 static njs_int_t
 njs_xml_attr_ext_prop_handler(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *unused, njs_value_t *retval)
+    uint32_t atom_id, njs_value_t *value, njs_value_t *unused,
+    njs_value_t *retval)
 {
     size_t     size;
     xmlAttr    *node, *current;
@@ -1888,7 +1898,7 @@ njs_xml_attr_ext_prop_handler(njs_vm_t *vm, njs_object_prop_t *prop,
         return NJS_DECLINED;
     }
 
-    ret = njs_vm_prop_name(vm, prop, &name);
+    ret = njs_vm_prop_name(vm, atom_id, &name);
     if (njs_slow_path(ret != NJS_OK)) {
         njs_value_undefined_set(retval);
         return NJS_DECLINED;
diff --git a/external/njs_zlib_module.c b/external/njs_zlib_module.c
index d3a667d8..46202fb9 100644
--- a/external/njs_zlib_module.c
+++ b/external/njs_zlib_module.c
@@ -15,7 +15,8 @@ static njs_int_t njs_zlib_ext_deflate(njs_vm_t *vm, njs_value_t *args,
 static njs_int_t njs_zlib_ext_inflate(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 njs_int_t njs_zlib_constant(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval);
 static njs_int_t njs_zlib_init(njs_vm_t *vm);
 static void *njs_zlib_alloc(void *opaque, u_int items, u_int size);
 static void njs_zlib_free(void *opaque, void *address);
@@ -520,7 +521,7 @@ fail:
 
 
 njs_int_t
-njs_zlib_constant(njs_vm_t *vm, njs_object_prop_t *prop,
+njs_zlib_constant(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     njs_value_number_set(retval,  njs_vm_prop_magic32(prop));
diff --git a/nginx/ngx_http_js_module.c b/nginx/ngx_http_js_module.c
index ce4ce365..3ac95478 100644
--- a/nginx/ngx_http_js_module.c
+++ b/nginx/ngx_http_js_module.c
@@ -129,11 +129,11 @@ static ngx_table_elt_t *ngx_http_js_get_header(ngx_list_part_t *part,
     u_char *data, size_t len);
 #endif
 static njs_int_t ngx_http_js_ext_raw_header(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t unused, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 static njs_int_t ngx_http_js_ext_header_out(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t atom_id, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 #if defined(nginx_version) && (nginx_version < 1023000)
 static njs_int_t ngx_http_js_header_single(njs_vm_t *vm,
     ngx_http_request_t *r, ngx_list_t *headers, njs_str_t *name,
@@ -172,7 +172,8 @@ static njs_int_t ngx_http_js_server122(njs_vm_t *vm, ngx_http_request_t *r,
 static njs_int_t ngx_http_js_ext_keys_header_out(njs_vm_t *vm,
     njs_value_t *value, njs_value_t *keys);
 static njs_int_t ngx_http_js_ext_status(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval);
 static njs_int_t ngx_http_js_ext_send_header(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 static njs_int_t ngx_http_js_ext_send(njs_vm_t *vm, njs_value_t *args,
@@ -193,23 +194,23 @@ static njs_int_t ngx_http_js_ext_internal_redirect(njs_vm_t *vm,
     njs_value_t *retval);
 
 static njs_int_t ngx_http_js_ext_get_http_version(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t unused, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 static njs_int_t ngx_http_js_ext_internal(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t unused, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 static njs_int_t ngx_http_js_ext_get_remote_address(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t unused, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 static njs_int_t ngx_http_js_ext_get_args(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t unused, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 static njs_int_t ngx_http_js_ext_get_request_body(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t unused, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 static njs_int_t ngx_http_js_ext_header_in(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t atom_id, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 #if defined(nginx_version) && (nginx_version < 1023000)
 static njs_int_t ngx_http_js_header_cookie(njs_vm_t *vm,
     ngx_http_request_t *r, ngx_list_t *headers, njs_str_t *name,
@@ -225,21 +226,21 @@ static njs_int_t ngx_http_js_header_in_array(njs_vm_t *vm,
 static njs_int_t ngx_http_js_ext_keys_header_in(njs_vm_t *vm,
     njs_value_t *value, njs_value_t *keys);
 static njs_int_t ngx_http_js_ext_variables(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t atom_id, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 static njs_int_t ngx_http_js_periodic_session_variables(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t atom_id, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 static njs_int_t ngx_http_js_ext_subrequest(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 static ngx_int_t ngx_http_js_subrequest_done(ngx_http_request_t *r,
     void *data, ngx_int_t rc);
 static njs_int_t ngx_http_js_ext_get_parent(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t unused, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 static njs_int_t ngx_http_js_ext_get_response_body(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t unused, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 
 #if defined(nginx_version) && (nginx_version >= 1023000)
 static njs_int_t ngx_http_js_header_in(njs_vm_t *vm, ngx_http_request_t *r,
@@ -1705,7 +1706,7 @@ ngx_http_js_ext_keys_header(njs_vm_t *vm, njs_value_t *value, njs_value_t *keys,
         start = njs_vm_array_start(vm, keys);
 
         for (i = 0; i < length; i++) {
-            njs_value_string_get(njs_argument(start, i), &hdr);
+            njs_value_string_get(vm, njs_argument(start, i), &hdr);
 
             if (h->key.len == hdr.length
                 && ngx_strncasecmp(h->key.data, hdr.start, hdr.length) == 0)
@@ -1772,7 +1773,8 @@ ngx_http_js_get_header(ngx_list_part_t *part, u_char *data, size_t len)
 
 static njs_int_t
 ngx_http_js_ext_raw_header(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     njs_int_t            rc;
     ngx_uint_t           i;
@@ -1854,7 +1856,8 @@ ngx_http_js_ext_raw_header(njs_vm_t *vm, njs_object_prop_t *prop,
 
 static njs_int_t
 ngx_http_js_ext_header_out(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t atom_id, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     njs_int_t              rc;
     njs_str_t              name;
@@ -1910,7 +1913,7 @@ ngx_http_js_ext_header_out(njs_vm_t *vm, njs_object_prop_t *prop,
         return NJS_DECLINED;
     }
 
-    rc = njs_vm_prop_name(vm, prop, &name);
+    rc = njs_vm_prop_name(vm, atom_id, &name);
     if (rc != NJS_OK) {
         if (retval != NULL) {
             njs_value_undefined_set(retval);
@@ -2395,7 +2398,7 @@ ngx_http_js_ext_keys_header_out(njs_vm_t *vm, njs_value_t *value,
 
 
 static njs_int_t
-ngx_http_js_ext_status(njs_vm_t *vm, njs_object_prop_t *prop,
+ngx_http_js_ext_status(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     ngx_int_t            n;
@@ -2792,7 +2795,8 @@ ngx_http_js_ext_internal_redirect(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 ngx_http_js_ext_get_http_version(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     ngx_str_t            v;
     ngx_http_request_t  *r;
@@ -2837,7 +2841,7 @@ ngx_http_js_ext_get_http_version(njs_vm_t *vm, njs_object_prop_t *prop,
 
 
 static njs_int_t
-ngx_http_js_ext_internal(njs_vm_t *vm, njs_object_prop_t *prop,
+ngx_http_js_ext_internal(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     ngx_http_request_t  *r;
@@ -2856,7 +2860,8 @@ ngx_http_js_ext_internal(njs_vm_t *vm, njs_object_prop_t *prop,
 
 static njs_int_t
 ngx_http_js_ext_get_remote_address(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     ngx_connection_t    *c;
     ngx_http_request_t  *r;
@@ -2875,7 +2880,7 @@ ngx_http_js_ext_get_remote_address(njs_vm_t *vm, njs_object_prop_t *prop,
 
 
 static njs_int_t
-ngx_http_js_ext_get_args(njs_vm_t *vm, njs_object_prop_t *prop,
+ngx_http_js_ext_get_args(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     u_char              *data;
@@ -2911,7 +2916,8 @@ ngx_http_js_ext_get_args(njs_vm_t *vm, njs_object_prop_t *prop,
 
 static njs_int_t
 ngx_http_js_ext_get_request_body(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     u_char              *p, *body;
     size_t               len;
@@ -3021,7 +3027,7 @@ done:
 
 #if defined(nginx_version) && (nginx_version < 1023000)
 static njs_int_t
-ngx_http_js_ext_header_in(njs_vm_t *vm, njs_object_prop_t *prop,
+ngx_http_js_ext_header_in(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t atom_id,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     njs_int_t              rc;
@@ -3055,7 +3061,7 @@ ngx_http_js_ext_header_in(njs_vm_t *vm, njs_object_prop_t *prop,
         return NJS_DECLINED;
     }
 
-    rc = njs_vm_prop_name(vm, prop, &name);
+    rc = njs_vm_prop_name(vm, atom_id, &name);
     if (rc != NJS_OK) {
         if (retval != NULL) {
             njs_value_undefined_set(retval);
@@ -3136,7 +3142,7 @@ ngx_http_js_header_in_array(njs_vm_t *vm, ngx_http_request_t *r,
 }
 #else
 static njs_int_t
-ngx_http_js_ext_header_in(njs_vm_t *vm, njs_object_prop_t *prop,
+ngx_http_js_ext_header_in(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t atom_id,
     njs_value_t *value, njs_value_t *unused, njs_value_t *retval)
 {
     unsigned             flags;
@@ -3164,7 +3170,7 @@ ngx_http_js_ext_header_in(njs_vm_t *vm, njs_object_prop_t *prop,
         return NJS_DECLINED;
     }
 
-    rc = njs_vm_prop_name(vm, prop, &name);
+    rc = njs_vm_prop_name(vm, atom_id, &name);
     if (rc != NJS_OK) {
         if (retval != NULL) {
             njs_value_undefined_set(retval);
@@ -3212,7 +3218,8 @@ ngx_http_js_ext_keys_header_in(njs_vm_t *vm, njs_value_t *value,
 
 static njs_int_t
 ngx_http_js_request_variables(njs_vm_t *vm, njs_object_prop_t *prop,
-    ngx_http_request_t *r, njs_value_t *setval, njs_value_t *retval)
+    uint32_t atom_id, ngx_http_request_t *r, njs_value_t *setval,
+    njs_value_t *retval)
 {
     njs_int_t                   rc, is_capture, start, length;
     njs_str_t                   val, s;
@@ -3223,7 +3230,7 @@ ngx_http_js_request_variables(njs_vm_t *vm, njs_object_prop_t *prop,
     ngx_http_variable_value_t  *vv;
     u_char                      storage[64];
 
-    rc = njs_vm_prop_name(vm, prop, &val);
+    rc = njs_vm_prop_name(vm, atom_id, &val);
     if (rc != NJS_OK) {
         njs_value_undefined_set(retval);
         return NJS_DECLINED;
@@ -3350,7 +3357,8 @@ ngx_http_js_request_variables(njs_vm_t *vm, njs_object_prop_t *prop,
 
 static njs_int_t
 ngx_http_js_ext_variables(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t atom_id, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     ngx_http_request_t  *r;
 
@@ -3360,13 +3368,14 @@ ngx_http_js_ext_variables(njs_vm_t *vm, njs_object_prop_t *prop,
         return NJS_DECLINED;
     }
 
-    return ngx_http_js_request_variables(vm, prop, r, setval, retval);
+    return ngx_http_js_request_variables(vm, prop, atom_id, r, setval, retval);
 }
 
 
 static njs_int_t
 ngx_http_js_periodic_session_variables(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t atom_id, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     ngx_http_request_t  *r;
 
@@ -3376,7 +3385,7 @@ ngx_http_js_periodic_session_variables(njs_vm_t *vm, njs_object_prop_t *prop,
         return NJS_DECLINED;
     }
 
-    return ngx_http_js_request_variables(vm, prop, r, setval, retval);
+    return ngx_http_js_request_variables(vm, prop, atom_id, r, setval, retval);
 }
 
 
@@ -3708,7 +3717,8 @@ ngx_http_js_subrequest_done(ngx_http_request_t *r, void *data, ngx_int_t rc)
 
 static njs_int_t
 ngx_http_js_ext_get_parent(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     ngx_http_js_ctx_t   *ctx;
     ngx_http_request_t  *r;
@@ -3735,7 +3745,8 @@ ngx_http_js_ext_get_parent(njs_vm_t *vm, njs_object_prop_t *prop,
 
 static njs_int_t
 ngx_http_js_ext_get_response_body(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     size_t               len;
     u_char              *p;
diff --git a/nginx/ngx_js.c b/nginx/ngx_js.c
index 316a2076..f91fcd99 100644
--- a/nginx/ngx_js.c
+++ b/nginx/ngx_js.c
@@ -108,21 +108,26 @@ static JSModuleDef *ngx_qjs_core_init(JSContext *cx, const char *name);
 #endif
 
 static njs_int_t ngx_js_ext_build(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
-static njs_int_t ngx_js_ext_conf_file_path(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
     njs_value_t *retval);
+static njs_int_t ngx_js_ext_conf_file_path(njs_vm_t *vm,
+    njs_object_prop_t *prop, uint32_t unused, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 static njs_int_t ngx_js_ext_conf_prefix(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
-static njs_int_t ngx_js_ext_error_log_path(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
     njs_value_t *retval);
+static njs_int_t ngx_js_ext_error_log_path(njs_vm_t *vm,
+    njs_object_prop_t *prop, uint32_t unused, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 static njs_int_t ngx_js_ext_prefix(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval);
 static njs_int_t ngx_js_ext_version(njs_vm_t *vm, njs_object_prop_t *prop,
+    uint32_t unused,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
 static njs_int_t ngx_js_ext_worker_id(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval);
 static njs_int_t ngx_js_ext_console_time(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 static njs_int_t ngx_js_ext_console_time_end(njs_vm_t *vm, njs_value_t *args,
@@ -2403,8 +2408,8 @@ ngx_js_core_init(njs_vm_t *vm)
 
 
 njs_int_t
-ngx_js_ext_string(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value,
-    njs_value_t *setval, njs_value_t *retval)
+ngx_js_ext_string(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
+    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     char       *p;
     ngx_str_t  *field;
@@ -2422,8 +2427,8 @@ ngx_js_ext_string(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value,
 
 
 njs_int_t
-ngx_js_ext_uint(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value,
-    njs_value_t *setval, njs_value_t *retval)
+ngx_js_ext_uint(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
+    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     char        *p;
     ngx_uint_t   field;
@@ -2443,7 +2448,7 @@ ngx_js_ext_uint(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value,
 
 
 njs_int_t
-ngx_js_ext_constant(njs_vm_t *vm, njs_object_prop_t *prop,
+ngx_js_ext_constant(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     uint32_t  magic32;
@@ -2466,7 +2471,7 @@ ngx_js_ext_constant(njs_vm_t *vm, njs_object_prop_t *prop,
 
 
 njs_int_t
-ngx_js_ext_flags(njs_vm_t *vm, njs_object_prop_t *prop,
+ngx_js_ext_flags(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     uintptr_t  data;
@@ -2491,8 +2496,8 @@ ngx_js_ext_flags(njs_vm_t *vm, njs_object_prop_t *prop,
 
 
 njs_int_t
-ngx_js_ext_build(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value,
-    njs_value_t *setval, njs_value_t *retval)
+ngx_js_ext_build(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
+    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     return njs_vm_value_string_create(vm, retval,
 #ifdef NGX_BUILD
@@ -2508,7 +2513,8 @@ ngx_js_ext_build(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value,
 
 njs_int_t
 ngx_js_ext_conf_file_path(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     return njs_vm_value_string_create(vm, retval, ngx_cycle->conf_file.data,
                                       ngx_cycle->conf_file.len);
@@ -2516,7 +2522,7 @@ ngx_js_ext_conf_file_path(njs_vm_t *vm, njs_object_prop_t *prop,
 
 
 njs_int_t
-ngx_js_ext_conf_prefix(njs_vm_t *vm, njs_object_prop_t *prop,
+ngx_js_ext_conf_prefix(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     return njs_vm_value_string_create(vm, retval, ngx_cycle->conf_prefix.data,
@@ -2525,7 +2531,7 @@ ngx_js_ext_conf_prefix(njs_vm_t *vm, njs_object_prop_t *prop,
 
 
 njs_int_t
-ngx_js_ext_error_log_path(njs_vm_t *vm, njs_object_prop_t *prop,
+ngx_js_ext_error_log_path(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     return njs_vm_value_string_create(vm, retval, ngx_cycle->error_log.data,
@@ -2534,7 +2540,7 @@ ngx_js_ext_error_log_path(njs_vm_t *vm, njs_object_prop_t *prop,
 
 
 njs_int_t
-ngx_js_ext_prefix(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value,
+ngx_js_ext_prefix(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, njs_value_t *value,
     njs_value_t *setval, njs_value_t *retval)
 {
     return njs_vm_value_string_create(vm, retval, ngx_cycle->prefix.data,
@@ -2543,8 +2549,8 @@ ngx_js_ext_prefix(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value,
 
 
 njs_int_t
-ngx_js_ext_version(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value,
-    njs_value_t *setval, njs_value_t *retval)
+ngx_js_ext_version(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
+    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     return njs_vm_value_string_create(vm, retval, (u_char *) NGINX_VERSION,
                                       njs_strlen(NGINX_VERSION));
@@ -2552,8 +2558,8 @@ ngx_js_ext_version(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value,
 
 
 njs_int_t
-ngx_js_ext_worker_id(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value,
-    njs_value_t *setval, njs_value_t *retval)
+ngx_js_ext_worker_id(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
+    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     njs_value_number_set(retval, ngx_worker);
     return NJS_OK;
@@ -2640,11 +2646,11 @@ ngx_js_ext_console_time(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
                 return ret;
             }
 
-            njs_value_string_get(value, &name);
+            njs_value_string_get(vm, value, &name);
         }
 
     } else {
-        njs_value_string_get(value, &name);
+        njs_value_string_get(vm, value, &name);
     }
 
     console = njs_value_external(this);
@@ -2733,11 +2739,11 @@ ngx_js_ext_console_time_end(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
                 return ret;
             }
 
-            njs_value_string_get(value, &name);
+            njs_value_string_get(vm, value, &name);
         }
 
     } else {
-        njs_value_string_get(value, &name);
+        njs_value_string_get(vm, value, &name);
     }
 
     console = njs_value_external(this);
diff --git a/nginx/ngx_js.h b/nginx/ngx_js.h
index 0a99a696..0e811f44 100644
--- a/nginx/ngx_js.h
+++ b/nginx/ngx_js.h
@@ -405,13 +405,13 @@ char * ngx_js_merge_conf(ngx_conf_t *cf, void *parent, void *child,
 char *ngx_js_shared_dict_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf,
     void *tag);
 
-njs_int_t ngx_js_ext_string(njs_vm_t *vm, njs_object_prop_t *prop,
+njs_int_t ngx_js_ext_string(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
-njs_int_t ngx_js_ext_uint(njs_vm_t *vm, njs_object_prop_t *prop,
+njs_int_t ngx_js_ext_uint(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
-njs_int_t ngx_js_ext_constant(njs_vm_t *vm, njs_object_prop_t *prop,
+njs_int_t ngx_js_ext_constant(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
-njs_int_t ngx_js_ext_flags(njs_vm_t *vm, njs_object_prop_t *prop,
+njs_int_t ngx_js_ext_flags(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
 
 ngx_int_t ngx_js_string(njs_vm_t *vm, njs_value_t *value, njs_str_t *str);
diff --git a/nginx/ngx_js_fetch.c b/nginx/ngx_js_fetch.c
index 63e7a298..4902fe4f 100644
--- a/nginx/ngx_js_fetch.c
+++ b/nginx/ngx_js_fetch.c
@@ -210,8 +210,8 @@ static njs_int_t ngx_headers_js_ext_get(njs_vm_t *vm, njs_value_t *args,
 static njs_int_t ngx_headers_js_ext_has(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 static njs_int_t ngx_headers_js_ext_prop(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t atom_id, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 static njs_int_t ngx_headers_js_ext_keys(njs_vm_t *vm, njs_value_t *value,
     njs_value_t *keys);
 static njs_int_t ngx_headers_js_ext_set(njs_vm_t *vm, njs_value_t *args,
@@ -219,37 +219,38 @@ static njs_int_t ngx_headers_js_ext_set(njs_vm_t *vm, njs_value_t *args,
 static njs_int_t ngx_request_js_ext_body(njs_vm_t *vm, njs_value_t *args,
      njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 static njs_int_t ngx_request_js_ext_body_used(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t unused, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 static njs_int_t ngx_request_js_ext_cache(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t unused, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 static njs_int_t ngx_request_js_ext_credentials(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t unused, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 static njs_int_t ngx_request_js_ext_headers(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t unused, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 static njs_int_t ngx_request_js_ext_mode(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
-static njs_int_t ngx_response_js_ext_status(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
     njs_value_t *retval);
+static njs_int_t ngx_response_js_ext_status(njs_vm_t *vm,
+    njs_object_prop_t *prop, uint32_t unused, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 static njs_int_t ngx_response_js_ext_status_text(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t unused, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 static njs_int_t ngx_response_js_ext_ok(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t unused, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 static njs_int_t ngx_response_js_ext_body_used(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t unused, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 static njs_int_t ngx_response_js_ext_headers(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t unused, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 static njs_int_t ngx_response_js_ext_type(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t unused, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 static njs_int_t ngx_response_js_ext_body(njs_vm_t *vm, njs_value_t *args,
      njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 
@@ -3523,13 +3524,13 @@ ngx_headers_js_ext_has(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 
 static njs_int_t
-ngx_headers_js_ext_prop(njs_vm_t *vm, njs_object_prop_t *prop,
+ngx_headers_js_ext_prop(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t atom_id,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     njs_int_t  ret;
     njs_str_t  name;
 
-    ret = njs_vm_prop_name(vm, prop, &name);
+    ret = njs_vm_prop_name(vm, atom_id, &name);
     if (ret != NJS_OK) {
         return NJS_ERROR;
     }
@@ -3539,9 +3540,40 @@ ngx_headers_js_ext_prop(njs_vm_t *vm, njs_object_prop_t *prop,
 
 
 static ngx_int_t
-ngx_string_compare(const void *s1, const void *s2)
+ngx_string_compare(const void *s1, const void *s2, void *ctx)
 {
-    return njs_vm_string_compare(s1, s2);
+    return njs_vm_string_compare(ctx, s1, s2);
+}
+
+
+static void
+ngx_js_sort(void *base, size_t n, size_t size,
+    ngx_int_t (*cmp)(const void *, const void *, void *), void *ctx)
+{
+    u_char  *p1, *p2, *p;
+
+    p = ngx_alloc(size, ngx_cycle->log);
+    if (p == NULL) {
+        return;
+    }
+
+    for (p1 = (u_char *) base + size;
+         p1 < (u_char *) base + n * size;
+         p1 += size)
+    {
+        ngx_memcpy(p, p1, size);
+
+        for (p2 = p1;
+             p2 > (u_char *) base && cmp(p2 - size, p, ctx) > 0;
+             p2 -= size)
+        {
+            ngx_memcpy(p2, p2 - size, size);
+        }
+
+        ngx_memcpy(p2, p, size);
+    }
+
+    ngx_free(p);
 }
 
 
@@ -3591,7 +3623,7 @@ ngx_headers_js_ext_keys(njs_vm_t *vm, njs_value_t *value, njs_value_t *keys)
         start = njs_vm_array_start(vm, keys);
 
         for (k = 0; k < length; k++) {
-            njs_value_string_get(njs_argument(start, k), &hdr);
+            njs_value_string_get(vm, njs_argument(start, k), &hdr);
 
             if (h[i].key.len == hdr.length
                 && njs_strncasecmp(h[i].key.data, hdr.start, hdr.length) == 0)
@@ -3618,8 +3650,8 @@ ngx_headers_js_ext_keys(njs_vm_t *vm, njs_value_t *value, njs_value_t *keys)
 
     start = njs_vm_array_start(vm, keys);
 
-    ngx_sort(start, (size_t) length, sizeof(njs_opaque_value_t),
-             ngx_string_compare);
+    ngx_js_sort(start, (size_t) length, sizeof(njs_opaque_value_t),
+                ngx_string_compare, vm);
 
     return NJS_OK;
 }
@@ -3762,7 +3794,8 @@ ngx_request_js_ext_body(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 ngx_request_js_ext_body_used(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     ngx_js_request_t  *request;
 
@@ -3779,7 +3812,7 @@ ngx_request_js_ext_body_used(njs_vm_t *vm, njs_object_prop_t *prop,
 
 
 static njs_int_t
-ngx_request_js_ext_cache(njs_vm_t *vm, njs_object_prop_t *prop,
+ngx_request_js_ext_cache(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     ngx_js_request_t  *request;
@@ -3797,7 +3830,8 @@ ngx_request_js_ext_cache(njs_vm_t *vm, njs_object_prop_t *prop,
 
 static njs_int_t
 ngx_request_js_ext_credentials(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     ngx_js_request_t  *request;
 
@@ -3814,7 +3848,8 @@ ngx_request_js_ext_credentials(njs_vm_t *vm, njs_object_prop_t *prop,
 
 static njs_int_t
 ngx_request_js_ext_headers(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     njs_int_t          ret;
     ngx_js_request_t  *request;
@@ -3842,7 +3877,7 @@ ngx_request_js_ext_headers(njs_vm_t *vm, njs_object_prop_t *prop,
 
 
 static njs_int_t
-ngx_request_js_ext_mode(njs_vm_t *vm, njs_object_prop_t *prop,
+ngx_request_js_ext_mode(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     ngx_js_request_t  *request;
@@ -3921,7 +3956,8 @@ ngx_response_js_ext_body(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 ngx_response_js_ext_body_used(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     ngx_js_response_t  *response;
 
@@ -3939,7 +3975,8 @@ ngx_response_js_ext_body_used(njs_vm_t *vm, njs_object_prop_t *prop,
 
 static njs_int_t
 ngx_response_js_ext_headers(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     njs_int_t           ret;
     ngx_js_response_t  *response;
@@ -3967,7 +4004,7 @@ ngx_response_js_ext_headers(njs_vm_t *vm, njs_object_prop_t *prop,
 
 
 static njs_int_t
-ngx_response_js_ext_ok(njs_vm_t *vm, njs_object_prop_t *prop,
+ngx_response_js_ext_ok(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     ngx_uint_t          code;
@@ -3989,7 +4026,8 @@ ngx_response_js_ext_ok(njs_vm_t *vm, njs_object_prop_t *prop,
 
 static njs_int_t
 ngx_response_js_ext_status(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     ngx_js_response_t  *response;
 
@@ -4007,7 +4045,8 @@ ngx_response_js_ext_status(njs_vm_t *vm, njs_object_prop_t *prop,
 
 static njs_int_t
 ngx_response_js_ext_status_text(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     ngx_js_response_t  *response;
 
@@ -4025,7 +4064,7 @@ ngx_response_js_ext_status_text(njs_vm_t *vm, njs_object_prop_t *prop,
 
 
 static njs_int_t
-ngx_response_js_ext_type(njs_vm_t *vm, njs_object_prop_t *prop,
+ngx_response_js_ext_type(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     ngx_js_response_t  *response;
diff --git a/nginx/ngx_js_shared_dict.c b/nginx/ngx_js_shared_dict.c
index c0928088..ccca530d 100644
--- a/nginx/ngx_js_shared_dict.c
+++ b/nginx/ngx_js_shared_dict.c
@@ -47,8 +47,8 @@ struct ngx_js_dict_s {
 
 
 static njs_int_t njs_js_ext_shared_dict_capacity(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t unused, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 static njs_int_t njs_js_ext_shared_dict_clear(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t flags, njs_value_t *retval);
 static njs_int_t njs_js_ext_shared_dict_delete(njs_vm_t *vm, njs_value_t *args,
@@ -67,8 +67,8 @@ static njs_int_t njs_js_ext_shared_dict_incr(njs_vm_t *vm, njs_value_t *args,
 static njs_int_t njs_js_ext_shared_dict_items(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 static njs_int_t njs_js_ext_shared_dict_name(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t unused, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 static njs_int_t njs_js_ext_shared_dict_pop(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 static njs_int_t njs_js_ext_shared_dict_set(njs_vm_t *vm, njs_value_t *args,
@@ -76,8 +76,8 @@ static njs_int_t njs_js_ext_shared_dict_set(njs_vm_t *vm, njs_value_t *args,
 static njs_int_t njs_js_ext_shared_dict_size(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 static njs_int_t njs_js_ext_shared_dict_type(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t unused, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 static ngx_js_dict_node_t *ngx_js_dict_lookup(ngx_js_dict_t *dict,
     njs_str_t *key);
 
@@ -86,15 +86,16 @@ static ngx_js_dict_node_t *ngx_js_dict_lookup(ngx_js_dict_t *dict,
 
 static ngx_int_t ngx_js_dict_set(njs_vm_t *vm, ngx_js_dict_t *dict,
     njs_str_t *key, njs_value_t *value, ngx_msec_t timeout, unsigned flags);
-static ngx_int_t ngx_js_dict_add(ngx_js_dict_t *dict, njs_str_t *key,
-    njs_value_t *value, ngx_msec_t timeout, ngx_msec_t now);
-static ngx_int_t ngx_js_dict_update(ngx_js_dict_t *dict,
+static ngx_int_t ngx_js_dict_add(njs_vm_t *vm, ngx_js_dict_t *dict,
+    njs_str_t *key, njs_value_t *value, ngx_msec_t timeout, ngx_msec_t now);
+static ngx_int_t ngx_js_dict_update(njs_vm_t *vm, ngx_js_dict_t *dict,
     ngx_js_dict_node_t *node, njs_value_t *value, ngx_msec_t timeout,
     ngx_msec_t now);
 static ngx_int_t ngx_js_dict_get(njs_vm_t *vm, ngx_js_dict_t *dict,
     njs_str_t *key, njs_value_t *retval);
-static ngx_int_t ngx_js_dict_incr(ngx_js_dict_t *dict, njs_str_t *key,
-    njs_value_t *delta, njs_value_t *init, double *value, ngx_msec_t timeout);
+static ngx_int_t ngx_js_dict_incr(njs_vm_t *vm, ngx_js_dict_t *dict,
+    njs_str_t *key, njs_value_t *delta, njs_value_t *init, double *value,
+    ngx_msec_t timeout);
 static ngx_int_t ngx_js_dict_delete(njs_vm_t *vm, ngx_js_dict_t *dict,
     njs_str_t *key, njs_value_t *retval);
 static ngx_int_t ngx_js_dict_copy_value_locked(njs_vm_t *vm,
@@ -104,8 +105,8 @@ static void ngx_js_dict_expire(ngx_js_dict_t *dict, ngx_msec_t now);
 static void ngx_js_dict_evict(ngx_js_dict_t *dict, ngx_int_t count);
 
 static njs_int_t ngx_js_dict_shared_error_name(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t unused, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 
 static ngx_int_t ngx_js_dict_init_zone(ngx_shm_zone_t *shm_zone, void *data);
 static njs_int_t ngx_js_shared_dict_preinit(njs_vm_t *vm);
@@ -480,7 +481,8 @@ qjs_module_t  ngx_qjs_ngx_shared_dict_module = {
 
 njs_int_t
 njs_js_ext_global_shared_prop(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t atom_id, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     njs_int_t            ret;
     njs_str_t            name;
@@ -488,7 +490,7 @@ njs_js_ext_global_shared_prop(njs_vm_t *vm, njs_object_prop_t *prop,
     ngx_shm_zone_t      *shm_zone;
     ngx_js_main_conf_t  *conf;
 
-    ret = njs_vm_prop_name(vm, prop, &name);
+    ret = njs_vm_prop_name(vm, atom_id, &name);
     if (ret != NJS_OK) {
         return NJS_ERROR;
     }
@@ -559,7 +561,8 @@ njs_js_ext_global_shared_keys(njs_vm_t *vm, njs_value_t *unused,
 
 static njs_int_t
 njs_js_ext_shared_dict_capacity(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     ngx_shm_zone_t  *shm_zone;
 
@@ -912,7 +915,8 @@ njs_js_ext_shared_dict_incr(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         timeout = dict->timeout;
     }
 
-    rc = ngx_js_dict_incr(shm_zone->data, &key, delta, init, &value, timeout);
+    rc = ngx_js_dict_incr(vm, shm_zone->data, &key, delta, init, &value,
+                          timeout);
     if (rc == NGX_ERROR) {
         njs_vm_error(vm, "failed to increment value in shared dict");
         return NJS_ERROR;
@@ -1033,7 +1037,8 @@ fail:
 
 static njs_int_t
 njs_js_ext_shared_dict_name(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     ngx_shm_zone_t  *shm_zone;
 
@@ -1210,7 +1215,8 @@ njs_js_ext_shared_dict_size(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_js_ext_shared_dict_type(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     njs_str_t        type;
     ngx_js_dict_t   *dict;
@@ -1308,7 +1314,7 @@ ngx_js_dict_set(njs_vm_t *vm, ngx_js_dict_t *dict, njs_str_t *key,
             return NGX_DECLINED;
         }
 
-        if (ngx_js_dict_add(dict, key, value, timeout, now) != NGX_OK) {
+        if (ngx_js_dict_add(vm, dict, key, value, timeout, now) != NGX_OK) {
             goto memory_error;
         }
 
@@ -1320,7 +1326,7 @@ ngx_js_dict_set(njs_vm_t *vm, ngx_js_dict_t *dict, njs_str_t *key,
             }
         }
 
-        if (ngx_js_dict_update(dict, node, value, timeout, now) != NGX_OK) {
+        if (ngx_js_dict_update(vm, dict, node, value, timeout, now) != NGX_OK) {
             goto memory_error;
         }
     }
@@ -1340,8 +1346,8 @@ memory_error:
 
 
 static ngx_int_t
-ngx_js_dict_add(ngx_js_dict_t *dict, njs_str_t *key, njs_value_t *value,
-    ngx_msec_t timeout, ngx_msec_t now)
+ngx_js_dict_add(njs_vm_t *vm, ngx_js_dict_t *dict, njs_str_t *key,
+    njs_value_t *value, ngx_msec_t timeout, ngx_msec_t now)
 {
     size_t               n;
     uint32_t             hash;
@@ -1363,7 +1369,7 @@ ngx_js_dict_add(ngx_js_dict_t *dict, njs_str_t *key, njs_value_t *value,
     node->sn.str.data = (u_char *) node + sizeof(ngx_js_dict_node_t);
 
     if (dict->type == NGX_JS_DICT_TYPE_STRING) {
-        njs_value_string_get(value, &string);
+        njs_value_string_get(vm, value, &string);
         node->u.value.data = ngx_js_dict_alloc(dict, string.length);
         if (node->u.value.data == NULL) {
             ngx_slab_free_locked(dict->shpool, node);
@@ -1394,14 +1400,14 @@ ngx_js_dict_add(ngx_js_dict_t *dict, njs_str_t *key, njs_value_t *value,
 
 
 static ngx_int_t
-ngx_js_dict_update(ngx_js_dict_t *dict, ngx_js_dict_node_t *node,
+ngx_js_dict_update(njs_vm_t *vm, ngx_js_dict_t *dict, ngx_js_dict_node_t *node,
     njs_value_t *value, ngx_msec_t timeout, ngx_msec_t now)
 {
     u_char     *p;
     njs_str_t   string;
 
     if (dict->type == NGX_JS_DICT_TYPE_STRING) {
-        njs_value_string_get(value, &string);
+        njs_value_string_get(vm, value, &string);
 
         p = ngx_js_dict_alloc(dict, string.length);
         if (p == NULL) {
@@ -1476,8 +1482,8 @@ ngx_js_dict_delete(njs_vm_t *vm, ngx_js_dict_t *dict, njs_str_t *key,
 
 
 static ngx_int_t
-ngx_js_dict_incr(ngx_js_dict_t *dict, njs_str_t *key, njs_value_t *delta,
-    njs_value_t *init, double *value, ngx_msec_t timeout)
+ngx_js_dict_incr(njs_vm_t *vm, ngx_js_dict_t *dict, njs_str_t *key,
+    njs_value_t *delta, njs_value_t *init, double *value, ngx_msec_t timeout)
 {
     ngx_msec_t           now;
     ngx_time_t          *tp;
@@ -1493,7 +1499,7 @@ ngx_js_dict_incr(ngx_js_dict_t *dict, njs_str_t *key, njs_value_t *delta,
     if (node == NULL) {
         njs_value_number_set(init, njs_value_number(init)
                                    + njs_value_number(delta));
-        if (ngx_js_dict_add(dict, key, init, timeout, now) != NGX_OK) {
+        if (ngx_js_dict_add(vm, dict, key, init, timeout, now) != NGX_OK) {
             ngx_rwlock_unlock(&dict->sh->rwlock);
             return NGX_ERROR;
         }
@@ -1653,7 +1659,8 @@ ngx_js_dict_evict(ngx_js_dict_t *dict, ngx_int_t count)
 
 static njs_int_t
 ngx_js_dict_shared_error_name(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     return njs_vm_value_string_create(vm, retval,
                                       (u_char *) "SharedMemoryError", 17);
diff --git a/nginx/ngx_js_shared_dict.h b/nginx/ngx_js_shared_dict.h
index ed1f4de7..b9c7f967 100644
--- a/nginx/ngx_js_shared_dict.h
+++ b/nginx/ngx_js_shared_dict.h
@@ -9,7 +9,8 @@
 #define _NGX_JS_SHARED_DICT_H_INCLUDED_
 
 njs_int_t njs_js_ext_global_shared_prop(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
+    uint32_t atom_id, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval);
 njs_int_t njs_js_ext_global_shared_keys(njs_vm_t *vm, njs_value_t *value,
     njs_value_t *keys);
 
diff --git a/nginx/ngx_stream_js_module.c b/nginx/ngx_stream_js_module.c
index 7620f2e0..5c837494 100644
--- a/nginx/ngx_stream_js_module.c
+++ b/nginx/ngx_stream_js_module.c
@@ -120,8 +120,8 @@ static ngx_stream_js_ev_t *ngx_stream_js_event(ngx_stream_session_t *s,
     njs_str_t *event);
 
 static njs_int_t ngx_stream_js_ext_get_remote_address(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t unused, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 
 static njs_int_t ngx_stream_js_ext_done(njs_vm_t *vm, njs_value_t *args,
      njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
@@ -137,11 +137,11 @@ static njs_int_t ngx_stream_js_ext_set_return_value(njs_vm_t *vm,
     njs_value_t *retval);
 
 static njs_int_t ngx_stream_js_ext_variables(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t atom_id, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 static njs_int_t ngx_stream_js_periodic_variables(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t atom_id, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 
 #if (NJS_HAVE_QUICKJS)
 
@@ -1405,8 +1405,8 @@ ngx_stream_js_event(ngx_stream_session_t *s, njs_str_t *event)
 
 static njs_int_t
 ngx_stream_js_ext_get_remote_address(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval)
+    njs_object_prop_t *prop, uint32_t unused, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval)
 {
     ngx_connection_t      *c;
     ngx_stream_session_t  *s;
@@ -1708,7 +1708,8 @@ ngx_stream_js_ext_set_return_value(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 ngx_stream_js_session_variables(njs_vm_t *vm, njs_object_prop_t *prop,
-    ngx_stream_session_t *s, njs_value_t *setval, njs_value_t *retval)
+    uint32_t atom_id, ngx_stream_session_t *s, njs_value_t *setval,
+    njs_value_t *retval)
 {
     njs_int_t                     rc;
     njs_str_t                     val;
@@ -1719,7 +1720,7 @@ ngx_stream_js_session_variables(njs_vm_t *vm, njs_object_prop_t *prop,
     ngx_stream_variable_value_t  *vv;
     u_char                        storage[64];
 
-    rc = njs_vm_prop_name(vm, prop, &val);
+    rc = njs_vm_prop_name(vm, atom_id, &val);
     if (rc != NJS_OK) {
         njs_value_undefined_set(retval);
         return NJS_DECLINED;
@@ -1818,7 +1819,8 @@ ngx_stream_js_session_variables(njs_vm_t *vm, njs_object_prop_t *prop,
 
 static njs_int_t
 ngx_stream_js_ext_variables(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t atom_id, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     ngx_stream_session_t  *s;
 
@@ -1828,13 +1830,14 @@ ngx_stream_js_ext_variables(njs_vm_t *vm, njs_object_prop_t *prop,
         return NJS_DECLINED;
     }
 
-    return ngx_stream_js_session_variables(vm, prop, s, setval, retval);
+    return ngx_stream_js_session_variables(vm, prop, atom_id, s, setval, retval);
 }
 
 
 static njs_int_t
 ngx_stream_js_periodic_variables(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t atom_id, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     ngx_stream_session_t  *s;
 
@@ -1844,7 +1847,7 @@ ngx_stream_js_periodic_variables(njs_vm_t *vm, njs_object_prop_t *prop,
         return NJS_DECLINED;
     }
 
-    return ngx_stream_js_session_variables(vm, prop, s, setval, retval);
+    return ngx_stream_js_session_variables(vm, prop, atom_id, s, setval, retval);
 }
 
 
diff --git a/src/njs.h b/src/njs.h
index 0e2855d1..0a196321 100644
--- a/src/njs.h
+++ b/src/njs.h
@@ -34,6 +34,7 @@ typedef struct njs_function_s         njs_function_t;
 typedef struct njs_vm_shared_s        njs_vm_shared_t;
 typedef struct njs_object_init_s      njs_object_init_t;
 typedef struct njs_object_prop_s      njs_object_prop_t;
+typedef struct njs_object_prop_init_s njs_object_prop_init_t;
 typedef struct njs_object_type_init_s njs_object_type_init_t;
 typedef struct njs_external_s         njs_external_t;
 
@@ -43,7 +44,7 @@ typedef struct njs_external_s         njs_external_t;
  */
 
 typedef struct {
-    uint64_t                        filler[2];
+    uint32_t                        filler[4];
 } njs_opaque_value_t;
 
 /* sizeof(njs_value_t) is 16 bytes. */
@@ -61,6 +62,11 @@ extern const njs_value_t            njs_value_undefined;
     memcpy(dst, src, sizeof(njs_opaque_value_t))
 
 #define njs_value_arg(val) ((njs_value_t *) val)
+#define njs_value_atom(val) (((njs_opaque_value_t *) (val))->filler[0])
+
+#define njs_atom_is_number(atom_id) ((atom_id) & 0x80000000)
+#define njs_atom_number(atom_id) ((atom_id) & 0x7FFFFFFF)
+#define njs_number_atom(n) ((n) | 0x80000000)
 
 #define njs_lvalue_arg(lvalue, args, nargs, n)                                \
     ((n < nargs) ? njs_argument(args, n)                                      \
@@ -104,7 +110,8 @@ extern const njs_value_t            njs_value_undefined;
  *   the exception value.
  */
 typedef njs_int_t (*njs_prop_handler_t) (njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
+    uint32_t atom_id, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval);
 typedef njs_int_t (*njs_exotic_keys_t)(njs_vm_t *vm, njs_value_t *value,
     njs_value_t *retval);
 typedef njs_int_t (*njs_function_native_t) (njs_vm_t *vm, njs_value_t *args,
@@ -354,23 +361,24 @@ NJS_EXPORT njs_int_t njs_vm_external_create(njs_vm_t *vm, njs_value_t *value,
 NJS_EXPORT njs_external_ptr_t njs_vm_external(njs_vm_t *vm,
     njs_int_t proto_id, const njs_value_t *value);
 NJS_EXPORT njs_int_t njs_external_property(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t unused, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
+NJS_EXPORT njs_int_t njs_atom_atomize_key(njs_vm_t *vm, njs_value_t *value);
 NJS_EXPORT njs_int_t njs_value_property(njs_vm_t *vm, njs_value_t *value,
-    njs_value_t *key, njs_value_t *retval);
+    uint32_t atom_id, njs_value_t *retval);
 NJS_EXPORT njs_int_t njs_value_property_set(njs_vm_t *vm, njs_value_t *value,
-    njs_value_t *key, njs_value_t *setval);
+    uint32_t atom_id, njs_value_t *setval);
 NJS_EXPORT uintptr_t njs_vm_meta(njs_vm_t *vm, njs_uint_t index);
 NJS_EXPORT njs_vm_opt_t *njs_vm_options(njs_vm_t *vm);
 
 NJS_EXPORT njs_int_t njs_error_constructor(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t type, njs_value_t *retval);
 NJS_EXPORT njs_int_t njs_object_prototype_create_constructor(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t unused, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 NJS_EXPORT njs_int_t njs_object_prototype_create(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t unused, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 
 NJS_EXPORT njs_function_t *njs_vm_function_alloc(njs_vm_t *vm,
     njs_function_native_t native, njs_bool_t shared, njs_bool_t ctor);
@@ -403,12 +411,13 @@ NJS_EXPORT njs_int_t njs_value_to_integer(njs_vm_t *vm, njs_value_t *value,
     int64_t *dst);
 
 /*  Gets string value, no copy. */
-NJS_EXPORT void njs_value_string_get(njs_value_t *value, njs_str_t *dst);
+NJS_EXPORT void njs_value_string_get(njs_vm_t *vm, njs_value_t *value,
+    njs_str_t *dst);
 NJS_EXPORT njs_int_t njs_vm_value_string_create(njs_vm_t *vm,
     njs_value_t *value, const u_char *start, uint32_t size);
 NJS_EXPORT njs_int_t njs_vm_value_string_create_chb(njs_vm_t *vm,
     njs_value_t *value, njs_chb_t *chain);
-NJS_EXPORT njs_int_t njs_vm_string_compare(const njs_value_t *v1,
+NJS_EXPORT njs_int_t njs_vm_string_compare(njs_vm_t *vm, const njs_value_t *v1,
     const njs_value_t *v2);
 
 NJS_EXPORT njs_int_t njs_vm_value_array_buffer_set(njs_vm_t *vm,
@@ -477,7 +486,7 @@ NJS_EXPORT njs_int_t njs_value_external_tag(const njs_value_t *value);
 
 NJS_EXPORT uint16_t njs_vm_prop_magic16(njs_object_prop_t *prop);
 NJS_EXPORT uint32_t njs_vm_prop_magic32(njs_object_prop_t *prop);
-NJS_EXPORT njs_int_t njs_vm_prop_name(njs_vm_t *vm, njs_object_prop_t *prop,
+NJS_EXPORT njs_int_t njs_vm_prop_name(njs_vm_t *vm, uint32_t atom_id,
     njs_str_t *dst);
 
 NJS_EXPORT njs_int_t njs_value_is_null(const njs_value_t *value);
@@ -536,4 +545,49 @@ NJS_EXPORT njs_int_t njs_vm_promise_create(njs_vm_t *vm, njs_value_t *retval,
     njs_value_t *callbacks);
 
 
+njs_inline njs_int_t
+njs_value_property_val(njs_vm_t *vm, njs_value_t *value, njs_value_t *key,
+    njs_value_t *retval)
+{
+    njs_int_t  ret;
+
+    if (njs_value_atom(key) == 0 /* NJS_ATOM_STRING_unknown */) {
+        ret = njs_atom_atomize_key(vm, key);
+        if (ret != NJS_OK) {
+            return ret;
+        }
+    }
+
+    return njs_value_property(vm, value, njs_value_atom(key), retval);
+}
+
+
+njs_inline njs_int_t
+njs_value_property_val_set(njs_vm_t *vm, njs_value_t *value, njs_value_t *key,
+    njs_value_t *setval)
+{
+    njs_int_t  ret;
+
+    if (njs_value_atom(key) == 0 /* NJS_ATOM_STRING_unknown */) {
+        ret = njs_atom_atomize_key(vm, key);
+        if (ret != NJS_OK) {
+            return ret;
+        }
+    }
+
+    return njs_value_property_set(vm, value, njs_value_atom(key), setval);
+}
+
+
+njs_inline size_t
+njs_value_string_length(njs_vm_t *vm, njs_value_t *value)
+{
+    njs_str_t  str;
+
+    njs_value_string_get(vm, value, &str);
+
+    return str.length;
+}
+
+
 #endif /* _NJS_H_INCLUDED_ */
diff --git a/src/njs_array.c b/src/njs_array.c
index 913bc8cf..e6f8ed83 100644
--- a/src/njs_array.c
+++ b/src/njs_array.c
@@ -139,7 +139,7 @@ njs_int_t
 njs_array_convert_to_slow_array(njs_vm_t *vm, njs_array_t *array)
 {
     uint32_t           i, length;
-    njs_value_t        index, value;
+    njs_value_t        value;
     njs_object_prop_t  *prop;
 
     if (njs_slow_path(!array->object.fast_array)) {
@@ -153,8 +153,7 @@ njs_array_convert_to_slow_array(njs_vm_t *vm, njs_array_t *array)
 
     for (i = 0; i < length; i++) {
         if (njs_is_valid(&array->start[i])) {
-            njs_uint32_to_string(&index, i);
-            prop = njs_object_property_add(vm, &value, &index, 0);
+            prop = njs_object_property_add(vm, &value, njs_number_atom(i), 0);
             if (njs_slow_path(prop == NULL)) {
                 return NJS_ERROR;
             }
@@ -176,15 +175,13 @@ njs_array_length_redefine(njs_vm_t *vm, njs_value_t *value, uint32_t length,
 {
     njs_object_prop_t  *prop;
 
-    static const njs_value_t  string_length = njs_string("length");
-
     if (njs_slow_path(!njs_is_array(value))) {
         njs_internal_error(vm, "njs_array_length_redefine() "
                            "applied to non-array");
         return NJS_ERROR;
     }
 
-    prop = njs_object_property_add(vm, value, njs_value_arg(&string_length), 1);
+    prop = njs_object_property_add(vm, value, NJS_ATOM_STRING_length, 1);
     if (njs_slow_path(prop == NULL)) {
         njs_internal_error(vm, "njs_array_length_redefine() "
                            "cannot redefine \"length\"");
@@ -241,7 +238,8 @@ njs_array_length_set(njs_vm_t *vm, njs_value_t *value,
             do {
                 idx = njs_string_to_index(&keys->start[i]);
                 if (idx >= length) {
-                    ret = njs_value_property_delete(vm, value, &keys->start[i],
+                    ret = njs_value_property_delete(vm, value,
+                                                    keys->start[i].atom_id,
                                                     NULL, 1);
                     if (njs_slow_path(ret == NJS_ERROR)) {
                         goto done;
@@ -603,19 +601,20 @@ njs_array_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 }
 
 
-static const njs_object_prop_t  njs_array_constructor_properties[] =
+static const njs_object_prop_init_t  njs_array_constructor_properties[] =
 {
     NJS_DECLARE_PROP_LENGTH(1),
 
     NJS_DECLARE_PROP_NAME("Array"),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
+                             0, 0),
 
-    NJS_DECLARE_PROP_NATIVE("from", njs_array_from, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_from, njs_array_from, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("isArray", njs_array_is_array, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_isArray, njs_array_is_array, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("of", njs_array_of, 0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_of, njs_array_of, 0, 0),
 };
 
 
@@ -626,8 +625,8 @@ const njs_object_init_t  njs_array_constructor_init = {
 
 
 static njs_int_t
-njs_array_length(njs_vm_t *vm,njs_object_prop_t *prop, njs_value_t *value,
-    njs_value_t *setval, njs_value_t *retval)
+njs_array_length(njs_vm_t *vm,njs_object_prop_t *prop, uint32_t unused,
+    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     double        num;
     int64_t       size;
@@ -787,8 +786,8 @@ static njs_int_t
 njs_array_prototype_slice_copy(njs_vm_t *vm, njs_value_t *this,
     int64_t start, int64_t length, njs_value_t *retval)
 {
+    u_char             *c, buf[4];
     size_t             size;
-    u_char             *dst;
     uint32_t           n;
     njs_int_t          ret;
     njs_array_t        *array, *keys;
@@ -819,7 +818,7 @@ njs_array_prototype_slice_copy(njs_vm_t *vm, njs_value_t *this,
 
             string_slice.start = start;
             string_slice.length = length;
-            string_slice.string_length = njs_string_prop(&string, this);
+            string_slice.string_length = njs_string_prop(vm, &string, this);
 
             njs_string_slice_string_prop(&string, &string, &string_slice);
 
@@ -828,10 +827,14 @@ njs_array_prototype_slice_copy(njs_vm_t *vm, njs_value_t *this,
 
             do {
                 value = &array->start[n++];
-                dst = njs_string_short_start(value);
-                dst = njs_utf8_copy(dst, &src, end);
-                size = dst - njs_string_short_start(value);
-                njs_string_short_set(value, size, 1);
+                c = buf;
+                c = njs_utf8_copy(c, &src, end);
+                size = c - buf;
+
+                ret = njs_string_new(vm, value, buf, size, 1);
+                if (njs_slow_path(ret != NJS_OK)) {
+                    return NJS_ERROR;
+                }
 
                 length--;
             } while (length != 0);
@@ -896,12 +899,12 @@ njs_array_prototype_slice_copy(njs_vm_t *vm, njs_value_t *this,
     }
 
     for (n = 0; n < keys->length; n++) {
-        ret = njs_value_property(vm, this, &keys->start[n], &val);
+        ret = njs_value_property(vm, this, keys->start[n].atom_id, &val);
         if (njs_slow_path(ret == NJS_ERROR)) {
             goto done;
         }
 
-        ret = njs_value_property_set(vm, &self, &keys->start[n], &val);
+        ret = njs_value_property_set(vm, &self, keys->start[n].atom_id, &val);
         if (njs_slow_path(ret == NJS_ERROR)) {
             goto done;
         }
@@ -1108,7 +1111,8 @@ njs_array_prototype_unshift(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         from = keys->length;
 
         while (from > 0) {
-            ret = njs_value_property_delete(vm, this, &keys->start[--from],
+            ret = njs_value_property_delete(vm, this,
+                                            keys->start[--from].atom_id,
                                             &entry, 1);
             if (njs_slow_path(ret == NJS_ERROR)) {
                 njs_array_destroy(vm, keys);
@@ -1607,14 +1611,13 @@ njs_int_t
 njs_array_prototype_to_string(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused, njs_value_t *retval)
 {
-    njs_int_t           ret;
-    njs_value_t         value;
-    njs_lvlhsh_query_t  lhq;
-
-    static const njs_value_t  join_string = njs_string("join");
+    njs_int_t            ret;
+    njs_value_t          value;
+    njs_flathsh_query_t  lhq;
 
     if (njs_is_object(njs_argument(args, 0))) {
-        njs_object_property_init(&lhq, &join_string, NJS_JOIN_HASH);
+        lhq.proto = &njs_object_hash_proto;
+        lhq.key_hash = NJS_ATOM_STRING_join;
 
         ret = njs_object_property(vm, njs_object(njs_argument(args, 0)), &lhq,
                                   &value);
@@ -1655,7 +1658,7 @@ njs_array_prototype_join(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     if (njs_slow_path(!njs_is_string(value))) {
         if (njs_is_undefined(value)) {
-            value = njs_value_arg(&njs_string_comma);
+            value = NULL;
 
         } else {
             ret = njs_value_to_string(vm, value, value);
@@ -1665,10 +1668,17 @@ njs_array_prototype_join(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         }
     }
 
-    (void) njs_string_prop(&separator, value);
+    if (value != NULL) {
+        (void) njs_string_prop(vm, &separator, value);
+
+    } else {
+        separator.start = (u_char *) ",";
+        separator.length = 1;
+        separator.size = 1;
+    }
 
     if (njs_slow_path(!njs_is_object(this))) {
-        njs_value_assign(retval, &njs_string_empty);
+        njs_set_empty_string(vm, retval);
         return NJS_OK;
     }
 
@@ -1680,7 +1690,7 @@ njs_array_prototype_join(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     if (njs_slow_path(len == 0)) {
-        njs_value_assign(retval, &njs_string_empty);
+        njs_set_empty_string(vm, retval);
         return NJS_OK;
     }
 
@@ -1704,7 +1714,7 @@ njs_array_prototype_join(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
                 length += ret;
 
             } else {
-                (void) njs_string_prop(&string, value);
+                (void) njs_string_prop(vm, &string, value);
                 length += string.length;
                 njs_chb_append(&chain, string.start, string.size);
             }
@@ -1773,8 +1783,9 @@ njs_array_indices_handler(const void *first, const void *second, void *ctx)
         return diff != 0;
     }
 
-    njs_string_get(val1, &str1);
-    njs_string_get(val2, &str2);
+    /* properties from njs_value_own_enumerate() are always intialized. */
+    njs_string_get_unsafe(val1, &str1);
+    njs_string_get_unsafe(val2, &str2);
 
     cmp_res = strncmp((const char *) str1.start, (const char *) str2.start,
                       njs_min(str1.length, str2.length));
@@ -1886,14 +1897,12 @@ njs_is_concat_spreadable(njs_vm_t *vm, njs_value_t *value)
     njs_int_t    ret;
     njs_value_t  retval;
 
-    static const njs_value_t  key =
-                         njs_wellknown_symbol(NJS_SYMBOL_IS_CONCAT_SPREADABLE);
-
     if (njs_slow_path(!njs_is_object(value))) {
         return NJS_DECLINED;
     }
 
-    ret = njs_value_property(vm, value, njs_value_arg(&key), &retval);
+    ret = njs_value_property(vm, value, NJS_ATOM_SYMBOL_isConcatSpreadable,
+                             &retval);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return NJS_ERROR;
     }
@@ -1980,7 +1989,7 @@ njs_array_prototype_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             }
 
             for (k = 0; k < keys->length; k++) {
-                ret = njs_value_property(vm, e, &keys->start[k], &value);
+                ret = njs_value_property_val(vm, e, &keys->start[k], &value);
                 if (njs_slow_path(ret == NJS_ERROR)) {
                     return ret;
                 }
@@ -2162,7 +2171,7 @@ njs_array_handler_includes(njs_vm_t *vm, njs_iterator_args_t *args,
         entry = njs_value_arg(&njs_value_undefined);
     }
 
-    if (njs_values_same_zero(njs_value_arg(&args->argument), entry)) {
+    if (njs_values_same_zero(vm, njs_value_arg(&args->argument), entry)) {
         njs_set_true(retval);
 
         return NJS_DONE;
@@ -2176,7 +2185,7 @@ static njs_int_t
 njs_array_handler_index_of(njs_vm_t *vm, njs_iterator_args_t *args,
     njs_value_t *entry, int64_t n, njs_value_t *retval)
 {
-    if (njs_values_strict_equal(njs_value_arg(&args->argument), entry)) {
+    if (njs_values_strict_equal(vm, njs_value_arg(&args->argument), entry)) {
         njs_set_number(retval, n);
 
         return NJS_DONE;
@@ -2714,7 +2723,7 @@ njs_array_compare(const void *a, const void *b, void *c)
         }
     }
 
-    ret = njs_string_cmp(aslot->str, bslot->str);
+    ret = njs_string_cmp(ctx->vm, aslot->str, bslot->str);
 
     if (ret != 0) {
         return ret;
@@ -2776,8 +2785,12 @@ njs_sort_indexed_properties(njs_vm_t *vm, njs_value_t *obj, int64_t length,
                 njs_value_assign(&p->value, &start[i]);
 
             } else {
-                njs_uint32_to_string(&key, i);
-                ret = njs_value_property(vm, obj, &key, &p->value);
+                ret = njs_uint32_to_string(vm, &key, i);
+                if (njs_slow_path(ret != NJS_OK)) {
+                    goto exception;
+                }
+
+                ret = njs_value_property_val(vm, obj, &key, &p->value);
                 if (njs_slow_path(ret == NJS_ERROR)) {
                     goto exception;
                 }
@@ -2820,7 +2833,7 @@ njs_sort_indexed_properties(njs_vm_t *vm, njs_value_t *obj, int64_t length,
             ilength = njs_min(keys->length, length);
 
             for (i = 0; i < ilength; i++) {
-                ret = njs_value_property(vm, obj, &keys->start[i], &p->value);
+                ret = njs_value_property_val(vm, obj, &keys->start[i], &p->value);
                 if (njs_slow_path(ret == NJS_ERROR)) {
                     goto exception;
                 }
@@ -3179,103 +3192,105 @@ njs_array_prototype_iterator_obj(njs_vm_t *vm, njs_value_t *args,
 }
 
 
-static const njs_object_prop_t  njs_array_prototype_properties[] =
+static const njs_object_prop_init_t  njs_array_prototype_properties[] =
 {
-    NJS_DECLARE_PROP_HANDLER("length", njs_array_length, 0, 0,
+    NJS_DECLARE_PROP_HANDLER(STRING_length, njs_array_length, 0,
                              NJS_OBJECT_PROP_VALUE_W),
 
-    NJS_DECLARE_PROP_HANDLER("constructor",
-                             njs_object_prototype_create_constructor,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
+                             njs_object_prototype_create_constructor, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_NATIVE("concat", njs_array_prototype_concat, 1, 0),
-
-    NJS_DECLARE_PROP_NATIVE("copyWithin", njs_array_prototype_copy_within, 2,
+    NJS_DECLARE_PROP_NATIVE(STRING_concat, njs_array_prototype_concat, 1,
                             0),
 
-    NJS_DECLARE_PROP_NATIVE("entries", njs_array_prototype_iterator_obj, 0,
-                            NJS_ENUM_BOTH),
+    NJS_DECLARE_PROP_NATIVE(STRING_copyWithin,
+                            njs_array_prototype_copy_within, 2, 0),
+
+    NJS_DECLARE_PROP_NATIVE(STRING_entries,
+                            njs_array_prototype_iterator_obj, 0, NJS_ENUM_BOTH),
 
-    NJS_DECLARE_PROP_NATIVE("every", njs_array_prototype_iterator, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_every, njs_array_prototype_iterator, 1,
                             njs_array_func(NJS_ARRAY_EVERY)),
 
-    NJS_DECLARE_PROP_NATIVE("fill", njs_array_prototype_fill, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_fill, njs_array_prototype_fill, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("filter", njs_array_prototype_iterator, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_filter, njs_array_prototype_iterator, 1,
                             njs_array_func(NJS_ARRAY_FILTER)),
 
-    NJS_DECLARE_PROP_NATIVE("find", njs_array_prototype_iterator, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_find, njs_array_prototype_iterator, 1,
                             njs_array_func(NJS_ARRAY_FIND)),
 
-    NJS_DECLARE_PROP_NATIVE("findIndex", njs_array_prototype_iterator, 1,
-                            njs_array_func(NJS_ARRAY_FIND_INDEX)),
+    NJS_DECLARE_PROP_NATIVE(STRING_findIndex, njs_array_prototype_iterator,
+                            1, njs_array_func(NJS_ARRAY_FIND_INDEX)),
 
-    NJS_DECLARE_PROP_NATIVE("forEach", njs_array_prototype_iterator, 1,
-                            njs_array_func(NJS_ARRAY_FOR_EACH)),
+    NJS_DECLARE_PROP_NATIVE(STRING_forEach, njs_array_prototype_iterator,
+                            1, njs_array_func(NJS_ARRAY_FOR_EACH)),
 
-    NJS_DECLARE_PROP_NATIVE("includes", njs_array_prototype_iterator, 1,
-                            njs_array_arg(NJS_ARRAY_INCLUDES)),
+    NJS_DECLARE_PROP_NATIVE(STRING_includes, njs_array_prototype_iterator,
+                            1, njs_array_arg(NJS_ARRAY_INCLUDES)),
 
-    NJS_DECLARE_PROP_NATIVE("indexOf", njs_array_prototype_iterator, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_indexOf, njs_array_prototype_iterator, 1,
                             njs_array_arg(NJS_ARRAY_INDEX_OF)),
 
-    NJS_DECLARE_PROP_NATIVE("join", njs_array_prototype_join, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_join, njs_array_prototype_join, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("keys", njs_array_prototype_iterator_obj, 0,
-                            NJS_ENUM_KEYS),
+    NJS_DECLARE_PROP_NATIVE(STRING_keys, njs_array_prototype_iterator_obj,
+                            0, NJS_ENUM_KEYS),
 
-    NJS_DECLARE_PROP_NATIVE("lastIndexOf",
+    NJS_DECLARE_PROP_NATIVE(STRING_lastIndexOf,
                             njs_array_prototype_reverse_iterator, 1,
                             NJS_ARRAY_LAST_INDEX_OF),
 
-    NJS_DECLARE_PROP_NATIVE("map", njs_array_prototype_iterator, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_map, njs_array_prototype_iterator, 1,
                             njs_array_func(NJS_ARRAY_MAP)),
 
-    NJS_DECLARE_PROP_NATIVE("pop", njs_array_prototype_pop, 0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_pop, njs_array_prototype_pop, 0, 0),
 
-    NJS_DECLARE_PROP_NATIVE("push", njs_array_prototype_push, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_push, njs_array_prototype_push, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("reduce", njs_array_prototype_iterator, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_reduce, njs_array_prototype_iterator, 1,
                             njs_array_func(NJS_ARRAY_REDUCE)),
 
-    NJS_DECLARE_PROP_NATIVE("reduceRight",
+    NJS_DECLARE_PROP_NATIVE(STRING_reduceRight,
                             njs_array_prototype_reverse_iterator, 1,
                             njs_array_func(NJS_ARRAY_REDUCE_RIGHT)),
 
-    NJS_DECLARE_PROP_NATIVE("reverse", njs_array_prototype_reverse, 0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_reverse, njs_array_prototype_reverse, 0, 0),
 
-    NJS_DECLARE_PROP_NATIVE("shift", njs_array_prototype_shift, 0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_shift, njs_array_prototype_shift, 0, 0),
 
-    NJS_DECLARE_PROP_NATIVE("slice", njs_array_prototype_slice, 2, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_slice, njs_array_prototype_slice, 2, 0),
 
-    NJS_DECLARE_PROP_NATIVE("some", njs_array_prototype_iterator, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_some, njs_array_prototype_iterator, 1,
                             njs_array_func(NJS_ARRAY_SOME)),
 
-    NJS_DECLARE_PROP_NATIVE("sort", njs_array_prototype_sort, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_sort, njs_array_prototype_sort, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("splice", njs_array_prototype_splice, 2, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_splice, njs_array_prototype_splice, 2,
+                            0),
 
-    NJS_DECLARE_PROP_NATIVE("toReversed", njs_array_prototype_to_reversed, 0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_toReversed,
+                            njs_array_prototype_to_reversed, 0, 0),
 
-    NJS_DECLARE_PROP_NATIVE("toSorted", njs_array_prototype_to_sorted, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_toSorted, njs_array_prototype_to_sorted,
+                            1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("toSpliced", njs_array_prototype_to_spliced, 2, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_toSpliced,
+                            njs_array_prototype_to_spliced, 2, 0),
 
-    NJS_DECLARE_PROP_NATIVE("toString", njs_array_prototype_to_string, 0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_toString, njs_array_prototype_to_string,
+                            0, 0),
 
-    NJS_DECLARE_PROP_NATIVE("unshift", njs_array_prototype_unshift, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_unshift, njs_array_prototype_unshift, 1,
+                            0),
 
-    NJS_DECLARE_PROP_NATIVE("values", njs_array_prototype_iterator_obj, 0,
-                            NJS_ENUM_VALUES),
+    NJS_DECLARE_PROP_NATIVE(STRING_values, njs_array_prototype_iterator_obj,
+                            0, NJS_ENUM_VALUES),
 
-    {
-        .type = NJS_PROPERTY,
-        .name = njs_wellknown_symbol(NJS_SYMBOL_ITERATOR),
-        .u.value = njs_native_function2(njs_array_prototype_iterator_obj, 0,
-                                        NJS_ENUM_VALUES),
-        .writable = 1,
-        .configurable = 1,
-    },
+    NJS_DECLARE_PROP_NATIVE(SYMBOL_iterator,
+                            njs_array_prototype_iterator_obj, 0,
+                            NJS_ENUM_VALUES),
 };
 
 
@@ -3285,9 +3300,9 @@ const njs_object_init_t  njs_array_prototype_init = {
 };
 
 
-const njs_object_prop_t  njs_array_instance_properties[] =
+const njs_object_prop_init_t  njs_array_instance_properties[] =
 {
-    NJS_DECLARE_PROP_HANDLER("length", njs_array_length, 0, 0,
+    NJS_DECLARE_PROP_HANDLER(STRING_length, njs_array_length, 0,
                              NJS_OBJECT_PROP_VALUE_W),
 };
 
diff --git a/src/njs_array_buffer.c b/src/njs_array_buffer.c
index dece7329..c0e51c9f 100644
--- a/src/njs_array_buffer.c
+++ b/src/njs_array_buffer.c
@@ -139,23 +139,20 @@ njs_array_buffer_writable(njs_vm_t *vm, njs_array_buffer_t *buffer)
 }
 
 
-static const njs_object_prop_t  njs_array_buffer_constructor_properties[] =
+static const njs_object_prop_init_t  njs_array_buffer_constructor_properties[] =
 {
     NJS_DECLARE_PROP_LENGTH(1),
 
     NJS_DECLARE_PROP_NAME("ArrayBuffer"),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
+                             0, 0),
 
-    {
-        .type = NJS_ACCESSOR,
-        .name = njs_wellknown_symbol(NJS_SYMBOL_SPECIES),
-        .u.accessor = njs_getter(njs_array_buffer_get_this, 0),
-        .writable = NJS_ATTRIBUTE_UNSET,
-        .configurable = 1,
-    },
+    NJS_DECLARE_PROP_GETTER(SYMBOL_species,
+                            njs_array_buffer_get_this,
+                            0),
 
-    NJS_DECLARE_PROP_NATIVE("isView", njs_array_buffer_is_view, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_isView, njs_array_buffer_is_view, 1, 0),
 };
 
 
@@ -265,23 +262,20 @@ njs_array_buffer_detach(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 
 
-static const njs_object_prop_t  njs_array_buffer_prototype_properties[] =
+static const njs_object_prop_init_t  njs_array_buffer_prototype_properties[] =
 {
-    NJS_DECLARE_PROP_HANDLER("constructor",
-                             njs_object_prototype_create_constructor,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
+                             njs_object_prototype_create_constructor, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_GETTER("byteLength",
+    NJS_DECLARE_PROP_GETTER(STRING_byteLength,
                             njs_array_buffer_prototype_byte_length, 0),
 
-    NJS_DECLARE_PROP_NATIVE("slice", njs_array_buffer_prototype_slice, 2, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_slice, njs_array_buffer_prototype_slice,
+                            2, 0),
 
-    {
-        .type = NJS_PROPERTY,
-        .name = njs_wellknown_symbol(NJS_SYMBOL_TO_STRING_TAG),
-        .u.value = njs_string("ArrayBuffer"),
-        .configurable = 1,
-    },
+    NJS_DECLARE_PROP_VALUE(SYMBOL_toStringTag, njs_ascii_strval("ArrayBuffer"),
+                           NJS_OBJECT_PROP_VALUE_C),
 };
 
 
diff --git a/src/njs_async.c b/src/njs_async.c
index 77b4605f..c352e86e 100644
--- a/src/njs_async.c
+++ b/src/njs_async.c
@@ -161,13 +161,14 @@ njs_async_context_free(njs_vm_t *vm, njs_async_ctx_t *ctx)
 }
 
 
-static const njs_object_prop_t  njs_async_constructor_properties[] =
+static const njs_object_prop_init_t  njs_async_constructor_properties[] =
 {
     NJS_DECLARE_PROP_LENGTH(1),
 
     NJS_DECLARE_PROP_NAME("AsyncFunction"),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
+                             0, 0),
 };
 
 
@@ -177,18 +178,15 @@ const njs_object_init_t  njs_async_constructor_init = {
 };
 
 
-static const njs_object_prop_t  njs_async_prototype_properties[] =
+static const njs_object_prop_init_t  njs_async_prototype_properties[] =
 {
-    {
-        .type = NJS_PROPERTY,
-        .name = njs_wellknown_symbol(NJS_SYMBOL_TO_STRING_TAG),
-        .u.value = njs_string("AsyncFunction"),
-        .configurable = 1,
-    },
-
-    NJS_DECLARE_PROP_HANDLER("constructor",
-                             njs_object_prototype_create_constructor,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_VALUE(SYMBOL_toStringTag,
+                           njs_ascii_strval("AsyncFunction"),
+                           NJS_OBJECT_PROP_VALUE_C),
+
+    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
+                             njs_object_prototype_create_constructor, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 };
 
 
@@ -206,12 +204,12 @@ const njs_object_type_init_t  njs_async_function_type_init = {
 };
 
 
-const njs_object_prop_t  njs_async_function_instance_properties[] =
+const njs_object_prop_init_t  njs_async_function_instance_properties[] =
 {
-    NJS_DECLARE_PROP_HANDLER("length", njs_function_instance_length, 0, 0,
+    NJS_DECLARE_PROP_HANDLER(STRING_length, njs_function_instance_length, 0,
                              NJS_OBJECT_PROP_VALUE_C),
 
-    NJS_DECLARE_PROP_HANDLER("name", njs_function_instance_name, 0, 0,
+    NJS_DECLARE_PROP_HANDLER(STRING_name, njs_function_instance_name, 0,
                              NJS_OBJECT_PROP_VALUE_C),
 };
 
diff --git a/src/njs_atom.c b/src/njs_atom.c
new file mode 100644
index 00000000..24e6dc17
--- /dev/null
+++ b/src/njs_atom.c
@@ -0,0 +1,333 @@
+
+/*
+ * Copyright (C) Vadim Zhestkov
+ * Copyright (C) F5, Inc.
+ */
+
+
+#include <njs_main.h>
+
+
+static njs_int_t njs_lexer_hash_test(njs_lvlhsh_query_t *lhq, void *data);
+static njs_int_t njs_atom_hash_test(njs_flathsh_query_t *lhq, void *data);
+
+
+const njs_value_t njs_atom[] = {
+#define NJS_DEF_SYMBOL(_id, _s) njs_symval(_id, _s),
+#define NJS_DEF_STRING(_id, _s, _typ, _tok) (njs_value_t) {                   \
+    .string = {                                                               \
+        .type = NJS_STRING,                                                   \
+        .truth = njs_length(_s) ? 1 : 0,                                      \
+        .atom_id = NJS_ATOM_STRING_ ## _id,                                   \
+        .token_type = _typ,                                                   \
+        .token_id = _tok,                                                     \
+        .data = & (njs_string_t) {                                            \
+            .start = (u_char *) _s,                                           \
+            .length = njs_length(_s),                                         \
+            .size = njs_length(_s),                                           \
+        },                                                                    \
+    }                                                                         \
+},
+
+    #include <njs_atom_defs.h>
+};
+
+
+const njs_lvlhsh_proto_t  njs_lexer_hash_proto
+    njs_aligned(64) =
+{
+    NJS_LVLHSH_DEFAULT,
+    njs_lexer_hash_test,
+    njs_lvlhsh_alloc,
+    njs_lvlhsh_free,
+};
+
+
+const njs_flathsh_proto_t  njs_atom_hash_proto
+    njs_aligned(64) =
+{
+    0,
+    njs_atom_hash_test,
+    njs_lvlhsh_alloc,
+    njs_lvlhsh_free,
+};
+
+
+static njs_int_t
+njs_lexer_hash_test(njs_lvlhsh_query_t *lhq, void *data)
+{
+    u_char       *start;
+    njs_value_t  *name;
+
+    name = data;
+
+    njs_assert(name->type == NJS_STRING);
+
+    if (lhq->key.length != name->string.data->size) {
+        return NJS_DECLINED;
+    }
+
+    start = name->string.data->start;
+
+    if (memcmp(start, lhq->key.start, lhq->key.length) == 0) {
+        return NJS_OK;
+    }
+
+    return NJS_DECLINED;
+}
+
+
+njs_value_t *
+njs_atom_find_or_add(njs_vm_t *vm, u_char *key, size_t size, size_t length,
+    uint32_t hash)
+{
+    njs_int_t           ret;
+    njs_value_t         *entry;
+    njs_lvlhsh_query_t  lhq;
+
+    lhq.key.start = key;
+    lhq.key.length = size;
+    lhq.key_hash = hash;
+    lhq.proto = &njs_lexer_hash_proto;
+
+    ret = njs_lvlhsh_find(vm->atom_hash_current, &lhq);
+    if (ret == NJS_OK) {
+        return lhq.value;
+    }
+
+    ret = njs_lvlhsh_find(&vm->atom_hash_shared, &lhq);
+    if (ret == NJS_OK) {
+        return lhq.value;
+    }
+
+    entry = njs_mp_alloc(vm->mem_pool, sizeof(njs_value_t));
+    if (njs_slow_path(entry == NULL)) {
+        return NULL;
+    }
+
+    ret = njs_string_create(vm, entry, key, size);
+    if (njs_slow_path(ret != NJS_OK)) {
+        return NULL;
+    }
+
+    entry->string.atom_id = vm->atom_id_generator++;
+    if (njs_atom_is_number(entry->string.atom_id)) {
+        njs_internal_error(vm, "too many atoms");
+        return NULL;
+    }
+
+    entry->string.token_type = NJS_KEYWORD_TYPE_UNDEF;
+
+    lhq.value = entry;
+    lhq.pool = vm->mem_pool;
+
+    ret = njs_lvlhsh_insert(vm->atom_hash_current, &lhq);
+    if (njs_slow_path(ret != NJS_OK)) {
+        return NULL;
+    }
+
+    return entry;
+}
+
+
+static njs_int_t
+njs_atom_hash_test(njs_flathsh_query_t *lhq, void *data)
+{
+    size_t       size;
+    u_char       *start;
+    njs_value_t  *name;
+
+    name = data;
+
+    if (name->type == NJS_STRING
+        && ((njs_value_t *) lhq->value)->type == NJS_STRING)
+    {
+        size = name->string.data->length;
+
+        if (lhq->key.length != size) {
+            return NJS_DECLINED;
+        }
+
+        start = (u_char *) name->string.data->start;
+
+        if (memcmp(start, lhq->key.start, lhq->key.length) == 0) {
+           return NJS_OK;
+        }
+    }
+
+    if (name->type == NJS_SYMBOL
+        && ((njs_value_t *) lhq->value)->type == NJS_SYMBOL)
+    {
+        if (lhq->key_hash == name->atom_id) {
+            return NJS_OK;
+        }
+    }
+
+    return NJS_DECLINED;
+}
+
+
+uint32_t
+njs_atom_hash_init(njs_vm_t *vm)
+{
+    u_char               *start;
+    size_t               len;
+    njs_int_t            ret;
+    njs_uint_t           n;
+    const njs_value_t    *value, *values;
+    njs_flathsh_query_t  lhq;
+
+    values = &njs_atom[0];
+
+    njs_lvlhsh_init(&vm->atom_hash_shared);
+
+    lhq.replace = 0;
+    lhq.proto = &njs_atom_hash_proto;
+    lhq.pool = vm->mem_pool;
+
+    for (n = 0; n < NJS_ATOM_SIZE; n++) {
+        value = &values[n];
+
+        if (value->type == NJS_SYMBOL) {
+            lhq.key_hash = value->string.atom_id;
+            lhq.value = (void *) value;
+
+            ret = njs_flathsh_insert(&vm->atom_hash_shared, &lhq);
+            if (njs_slow_path(ret != NJS_OK)) {
+                njs_internal_error(vm, "flathsh insert/replace failed");
+                return 0xffffffff;
+            }
+        }
+
+        if (value->type == NJS_STRING) {
+            start = value->string.data->start;
+            len = value->string.data->length;
+
+            lhq.key_hash = njs_djb_hash(start, len);
+            lhq.key.length = len;
+            lhq.key.start = start;
+            lhq.value = (void *) value;
+
+            ret = njs_flathsh_insert(&vm->atom_hash_shared, &lhq);
+            if (njs_slow_path(ret != NJS_OK)) {
+                njs_internal_error(vm, "flathsh insert/replace failed");
+                return 0xffffffff;
+            }
+        }
+    }
+
+    vm->atom_hash_current = &vm->atom_hash_shared;
+
+    return NJS_ATOM_SIZE;
+}
+
+
+njs_int_t
+njs_atom_atomize_key(njs_vm_t *vm, njs_value_t *value)
+{
+    double             num;
+    uint32_t           hash_id, u32;
+    njs_int_t          ret;
+    njs_value_t        val_str;
+    const njs_value_t  *entry;
+
+    njs_assert(value->atom_id == NJS_ATOM_STRING_unknown);
+
+    switch (value->type) {
+    case NJS_STRING:
+        num = njs_key_to_index(value);
+        u32 = (uint32_t) num;
+
+        if (njs_fast_path(u32 == num && (u32 < 0x80000000)
+                          && !(num == 0 && signbit(num))))
+        {
+            value->atom_id = njs_number_atom(u32);
+
+        } else {
+            hash_id = njs_djb_hash(value->string.data->start,
+                                   value->string.data->size);
+
+            entry = njs_atom_find_or_add(vm, value->string.data->start,
+                                         value->string.data->size,
+                                         value->string.data->length,
+                                         hash_id);
+            if (njs_slow_path(entry == NULL)) {
+                return NJS_ERROR;
+            }
+
+            *value = *entry;
+        }
+
+        break;
+
+    case NJS_NUMBER:
+        num = njs_number(value);
+        u32 = (uint32_t) num;
+
+        if (njs_fast_path(u32 == num && (u32 < 0x80000000))) {
+            value->atom_id = njs_number_atom(u32);
+
+        } else {
+            ret = njs_number_to_string(vm, &val_str, value);
+            if (ret != NJS_OK) {
+                return ret;
+            }
+
+            if (val_str.atom_id == NJS_ATOM_STRING_unknown) {
+                hash_id = njs_djb_hash(val_str.string.data->start,
+                                       val_str.string.data->size);
+
+                entry = njs_atom_find_or_add(vm, val_str.string.data->start,
+                                             val_str.string.data->size,
+                                             val_str.string.data->length,
+                                             hash_id);
+                if (njs_slow_path(entry == NULL)) {
+                    return NJS_ERROR;
+                }
+
+                value->atom_id = entry->atom_id;
+
+            } else {
+                value->atom_id = val_str.atom_id;
+            }
+        }
+
+        break;
+
+    case NJS_SYMBOL:
+    default:
+        /* do nothing. */
+        break;
+    }
+
+    return NJS_OK;
+}
+
+
+njs_int_t
+njs_atom_symbol_add(njs_vm_t *vm, njs_value_t *value)
+{
+    njs_int_t            ret;
+    njs_flathsh_query_t  lhq;
+
+    njs_assert(value->atom_id == NJS_ATOM_STRING_unknown);
+
+    lhq.replace = 0;
+    lhq.proto = &njs_lexer_hash_proto;
+    lhq.pool = vm->mem_pool;
+
+    value->atom_id = vm->atom_id_generator++;
+
+    if (value->type == NJS_SYMBOL) {
+        lhq.key_hash = value->atom_id;
+        lhq.value = (void *) value;
+
+        ret = njs_flathsh_insert(vm->atom_hash_current, &lhq);
+        if (njs_slow_path(ret != NJS_OK)) {
+            njs_internal_error(vm, "flathsh insert/replace failed");
+            return NJS_ERROR;
+        }
+    }
+
+    return NJS_OK;
+}
diff --git a/src/njs_atom.h b/src/njs_atom.h
new file mode 100644
index 00000000..12bb0e54
--- /dev/null
+++ b/src/njs_atom.h
@@ -0,0 +1,70 @@
+
+/*
+ * Copyright (C) Vadim Zhestkov
+ * Copyright (C) F5, Inc.
+ */
+
+
+#ifndef _NJS_ATOM_H_INCLUDED_
+#define _NJS_ATOM_H_INCLUDED_
+
+
+enum {
+#define NJS_DEF_STRING(name, _1, _2, _3) NJS_ATOM_STRING_ ## name,
+#define NJS_DEF_SYMBOL(name, str) NJS_ATOM_SYMBOL_ ## name,
+#include <njs_atom_defs.h>
+    NJS_ATOM_SIZE,
+#undef NJS_DEF_SYMBOL
+#undef NJS_DEF_STRING
+};
+
+
+uint32_t njs_atom_hash_init(njs_vm_t *vm);
+njs_int_t njs_atom_symbol_add(njs_vm_t *vm, njs_value_t *value);
+njs_value_t *njs_atom_find_or_add(njs_vm_t *vm, u_char *key, size_t size,
+    size_t length, uint32_t hash);
+
+
+njs_inline njs_int_t
+njs_atom_to_value(njs_vm_t *vm, njs_value_t *dst, uint32_t atom_id)
+{
+    size_t               size;
+    double               num;
+    njs_flathsh_descr_t  *h;
+    u_char               buf[128];
+
+    njs_assert(atom_id != NJS_ATOM_STRING_unknown);
+
+    if (njs_atom_is_number(atom_id)) {
+        num = njs_atom_number(atom_id);
+        size = njs_dtoa(num, (char *) buf);
+
+        if (njs_string_new(vm, dst, buf, size, size) != NJS_OK) {
+            return NJS_ERROR;
+        }
+
+        dst->atom_id = atom_id;
+
+        return NJS_OK;
+    }
+
+    if (atom_id < vm->shared_atom_count) {
+        h = vm->atom_hash_shared.slot;
+
+        njs_assert(atom_id < h->elts_count);
+
+        *dst = *((njs_value_t *) njs_hash_elts(h)[atom_id].value);
+
+    } else {
+        h = vm->atom_hash_current->slot;
+        atom_id -= vm->shared_atom_count;
+
+        njs_assert(atom_id < h->elts_count);
+
+        *dst = *((njs_value_t *) njs_hash_elts(h)[atom_id].value);
+    }
+
+    return NJS_OK;
+}
+
+#endif /* _NJS_ATOM_H_INCLUDED_ */
diff --git a/src/njs_atom_defs.h b/src/njs_atom_defs.h
new file mode 100644
index 00000000..f940648a
--- /dev/null
+++ b/src/njs_atom_defs.h
@@ -0,0 +1,502 @@
+
+/*
+ * Copyright (C) Vadim Zhestkov
+ * Copyright (C) F5, Inc.
+ */
+
+
+NJS_DEF_STRING(unknown, "unknown", 0, NJS_TOKEN_ILLEGAL)
+
+NJS_DEF_SYMBOL(asyncIterator, "Symbol.asyncIterator")
+NJS_DEF_SYMBOL(hasInstance, "Symbol.hasInstance")
+NJS_DEF_SYMBOL(isConcatSpreadable, "Symbol.isConcatSpreadable")
+NJS_DEF_SYMBOL(iterator, "Symbol.iterator")
+NJS_DEF_SYMBOL(match, "Symbol.match")
+NJS_DEF_SYMBOL(matchAll, "Symbol.matchAll")
+NJS_DEF_SYMBOL(replace, "Symbol.replace")
+NJS_DEF_SYMBOL(search, "Symbol.search")
+NJS_DEF_SYMBOL(species, "Symbol.species")
+NJS_DEF_SYMBOL(split, "Symbol.split")
+NJS_DEF_SYMBOL(toPrimitive, "Symbol.toPrimitive")
+NJS_DEF_SYMBOL(toStringTag, "Symbol.toStringTag")
+NJS_DEF_SYMBOL(unscopables, "Symbol.unscopables")
+
+/* Keywords. */
+
+#define NJS_KWD (NJS_KEYWORD_TYPE_KEYWORD)
+#define NJS_KWD_RESERVED (NJS_KEYWORD_TYPE_RESERVED | NJS_KEYWORD_TYPE_KEYWORD)
+
+NJS_DEF_STRING(arguments, "arguments", NJS_KWD, NJS_TOKEN_ARGUMENTS)
+NJS_DEF_STRING(async, "async", NJS_KWD, NJS_TOKEN_ASYNC)
+NJS_DEF_STRING(await, "await", NJS_KWD_RESERVED, NJS_TOKEN_AWAIT)
+NJS_DEF_STRING(break, "break", NJS_KWD_RESERVED, NJS_TOKEN_BREAK)
+NJS_DEF_STRING(case, "case", NJS_KWD_RESERVED, NJS_TOKEN_CASE)
+NJS_DEF_STRING(catch, "catch", NJS_KWD_RESERVED, NJS_TOKEN_CATCH)
+NJS_DEF_STRING(class, "class", NJS_KWD_RESERVED, NJS_TOKEN_CLASS)
+NJS_DEF_STRING(const, "const", NJS_KWD_RESERVED, NJS_TOKEN_CONST)
+NJS_DEF_STRING(continue, "continue", NJS_KWD_RESERVED, NJS_TOKEN_CONTINUE)
+NJS_DEF_STRING(debugger, "debugger", NJS_KWD_RESERVED, NJS_TOKEN_DEBUGGER)
+NJS_DEF_STRING(default, "default", NJS_KWD_RESERVED, NJS_TOKEN_DEFAULT)
+NJS_DEF_STRING(delete, "delete", NJS_KWD_RESERVED, NJS_TOKEN_DELETE)
+NJS_DEF_STRING(do, "do", NJS_KWD_RESERVED, NJS_TOKEN_DO)
+NJS_DEF_STRING(else, "else", NJS_KWD_RESERVED, NJS_TOKEN_ELSE)
+NJS_DEF_STRING(enum, "enum", NJS_KWD_RESERVED, NJS_TOKEN_ENUM)
+NJS_DEF_STRING(eval, "eval", NJS_KWD, NJS_TOKEN_EVAL)
+NJS_DEF_STRING(export, "export", NJS_KWD_RESERVED, NJS_TOKEN_EXPORT)
+NJS_DEF_STRING(extends, "extends", NJS_KWD_RESERVED, NJS_TOKEN_EXTENDS)
+NJS_DEF_STRING(false, "false", NJS_KWD_RESERVED, NJS_TOKEN_FALSE)
+NJS_DEF_STRING(finally, "finally", NJS_KWD_RESERVED, NJS_TOKEN_FINALLY)
+NJS_DEF_STRING(for, "for", NJS_KWD_RESERVED, NJS_TOKEN_FOR)
+NJS_DEF_STRING(from, "from", NJS_KWD, NJS_TOKEN_FROM)
+NJS_DEF_STRING(function, "function", NJS_KWD_RESERVED, NJS_TOKEN_FUNCTION)
+NJS_DEF_STRING(if, "if", NJS_KWD_RESERVED, NJS_TOKEN_IF)
+NJS_DEF_STRING(implements, "implements", NJS_KWD_RESERVED, NJS_TOKEN_IMPLEMENTS)
+NJS_DEF_STRING(import, "import", NJS_KWD_RESERVED, NJS_TOKEN_IMPORT)
+NJS_DEF_STRING(in, "in", NJS_KWD_RESERVED, NJS_TOKEN_IN)
+NJS_DEF_STRING(instanceof, "instanceof", NJS_KWD_RESERVED, NJS_TOKEN_INSTANCEOF)
+NJS_DEF_STRING(interface, "interface", NJS_KWD_RESERVED, NJS_TOKEN_INTERFACE)
+NJS_DEF_STRING(let, "let", NJS_KWD_RESERVED, NJS_TOKEN_LET)
+NJS_DEF_STRING(meta, "meta", NJS_KWD, NJS_TOKEN_META)
+NJS_DEF_STRING(new, "new", NJS_KWD_RESERVED, NJS_TOKEN_NEW)
+NJS_DEF_STRING(null, "null", NJS_KWD_RESERVED, NJS_TOKEN_NULL)
+NJS_DEF_STRING(of, "of", NJS_KWD, NJS_TOKEN_OF)
+NJS_DEF_STRING(package, "package", NJS_KWD_RESERVED, NJS_TOKEN_PACKAGE)
+NJS_DEF_STRING(private, "private", NJS_KWD_RESERVED, NJS_TOKEN_PRIVATE)
+NJS_DEF_STRING(protected, "protected", NJS_KWD_RESERVED, NJS_TOKEN_PROTECTED)
+NJS_DEF_STRING(public, "public", NJS_KWD_RESERVED, NJS_TOKEN_PUBLIC)
+NJS_DEF_STRING(return, "return", NJS_KWD_RESERVED, NJS_TOKEN_RETURN)
+NJS_DEF_STRING(static, "static", NJS_KWD_RESERVED, NJS_TOKEN_STATIC)
+NJS_DEF_STRING(super, "super", NJS_KWD_RESERVED, NJS_TOKEN_SUPER)
+NJS_DEF_STRING(switch, "switch", NJS_KWD_RESERVED, NJS_TOKEN_SWITCH)
+NJS_DEF_STRING(target, "target", NJS_KWD, NJS_TOKEN_TARGET)
+NJS_DEF_STRING(this, "this", NJS_KWD_RESERVED, NJS_TOKEN_THIS)
+NJS_DEF_STRING(throw, "throw", NJS_KWD_RESERVED, NJS_TOKEN_THROW)
+NJS_DEF_STRING(true, "true", NJS_KWD_RESERVED, NJS_TOKEN_TRUE)
+NJS_DEF_STRING(try, "try", NJS_KWD_RESERVED, NJS_TOKEN_TRY)
+NJS_DEF_STRING(typeof, "typeof", NJS_KWD_RESERVED, NJS_TOKEN_TYPEOF)
+NJS_DEF_STRING(undefined, "undefined",  NJS_KWD, NJS_TOKEN_UNDEFINED)
+NJS_DEF_STRING(var, "var", NJS_KWD_RESERVED, NJS_TOKEN_VAR)
+NJS_DEF_STRING(void, "void", NJS_KWD_RESERVED, NJS_TOKEN_VOID)
+NJS_DEF_STRING(while, "while", NJS_KWD_RESERVED, NJS_TOKEN_WHILE)
+NJS_DEF_STRING(with, "with", NJS_KWD_RESERVED, NJS_TOKEN_WITH)
+NJS_DEF_STRING(yield, "yield", NJS_KWD_RESERVED, NJS_TOKEN_YIELD)
+
+/* Other predefined strings. */
+
+NJS_DEF_STRING(spec_EMPTY_REGEXP, "(?:)", 0, 0)
+
+NJS_DEF_STRING(empty, "", 0, 0)
+NJS_DEF_STRING(_262, "$262", 0, 0)
+NJS_DEF_STRING(_Infinity, "-Infinity", 0, 0)
+NJS_DEF_STRING(AggregateError, "AggregateError", 0, 0)
+NJS_DEF_STRING(All_promises_were_rejected, "All promises were rejected", 0, 0)
+NJS_DEF_STRING(Array, "Array", 0, 0)
+NJS_DEF_STRING(Array_Iterator, "Array Iterator", 0, 0)
+NJS_DEF_STRING(ArrayBuffer, "ArrayBuffer", 0, 0)
+NJS_DEF_STRING(AsyncFunction, "AsyncFunction", 0, 0)
+NJS_DEF_STRING(Boolean, "Boolean", 0, 0)
+NJS_DEF_STRING(Buffer, "Buffer", 0, 0)
+NJS_DEF_STRING(BYTES_PER_ELEMENT, "BYTES_PER_ELEMENT", 0, 0)
+NJS_DEF_STRING(DataView, "DataView", 0, 0)
+NJS_DEF_STRING(Date, "Date", 0, 0)
+NJS_DEF_STRING(E, "E", 0, 0)
+NJS_DEF_STRING(EPSILON, "EPSILON", 0, 0)
+NJS_DEF_STRING(Error, "Error", 0, 0)
+NJS_DEF_STRING(EvalError, "EvalError", 0, 0)
+NJS_DEF_STRING(Float32Array, "Float32Array", 0, 0)
+NJS_DEF_STRING(Float64Array, "Float64Array", 0, 0)
+NJS_DEF_STRING(Function, "Function", 0, 0)
+NJS_DEF_STRING(Infinity, "Infinity", 0, 0)
+NJS_DEF_STRING(Int16Array, "Int16Array", 0, 0)
+NJS_DEF_STRING(Int32Array, "Int32Array", 0, 0)
+NJS_DEF_STRING(Int8Array, "Int8Array", 0, 0)
+NJS_DEF_STRING(InternalError, "InternalError", 0, 0)
+NJS_DEF_STRING(Invalid_Date, "Invalid Date", 0, 0)
+NJS_DEF_STRING(JSON, "JSON", 0, 0)
+NJS_DEF_STRING(LN10, "LN10", 0, 0)
+NJS_DEF_STRING(LN2, "LN2", 0, 0)
+NJS_DEF_STRING(LOG10E, "LOG10E", 0, 0)
+NJS_DEF_STRING(LOG2E, "LOG2E", 0, 0)
+NJS_DEF_STRING(MAX_LENGTH, "MAX_LENGTH", 0, 0)
+NJS_DEF_STRING(MAX_SAFE_INTEGER, "MAX_SAFE_INTEGER", 0, 0)
+NJS_DEF_STRING(MAX_STRING_LENGTH, "MAX_STRING_LENGTH", 0, 0)
+NJS_DEF_STRING(MAX_VALUE, "MAX_VALUE", 0, 0)
+NJS_DEF_STRING(MIN_SAFE_INTEGER, "MIN_SAFE_INTEGER", 0, 0)
+NJS_DEF_STRING(MIN_VALUE, "MIN_VALUE", 0, 0)
+NJS_DEF_STRING(Math, "Math", 0, 0)
+NJS_DEF_STRING(MemoryError, "MemoryError", 0, 0)
+NJS_DEF_STRING(NEGATIVE_INFINITY, "NEGATIVE_INFINITY", 0, 0)
+NJS_DEF_STRING(NaN, "NaN", 0, 0)
+NJS_DEF_STRING(Number, "Number", 0, 0)
+NJS_DEF_STRING(Object, "Object", 0, 0)
+NJS_DEF_STRING(PI, "PI", 0, 0)
+NJS_DEF_STRING(POSITIVE_INFINITY, "POSITIVE_INFINITY", 0, 0)
+NJS_DEF_STRING(Promise, "Promise", 0, 0)
+NJS_DEF_STRING(RangeError, "RangeError", 0, 0)
+NJS_DEF_STRING(ReferenceError, "ReferenceError", 0, 0)
+NJS_DEF_STRING(RegExp, "RegExp", 0, 0)
+NJS_DEF_STRING(SQRT1_2, "SQRT1_2", 0, 0)
+NJS_DEF_STRING(SQRT2, "SQRT2", 0, 0)
+NJS_DEF_STRING(String, "String", 0, 0)
+NJS_DEF_STRING(Symbol, "Symbol", 0, 0)
+NJS_DEF_STRING(SyntaxError, "SyntaxError", 0, 0)
+NJS_DEF_STRING(TextDecoder, "TextDecoder", 0, 0)
+NJS_DEF_STRING(TextEncoder, "TextEncoder", 0, 0)
+NJS_DEF_STRING(TypeError, "TypeError", 0, 0)
+NJS_DEF_STRING(TypedArray, "TypedArray", 0, 0)
+NJS_DEF_STRING(URIError, "URIError", 0, 0)
+NJS_DEF_STRING(UTC, "UTC", 0, 0)
+NJS_DEF_STRING(Uint16Array, "Uint16Array", 0, 0)
+NJS_DEF_STRING(Uint32Array, "Uint32Array", 0, 0)
+NJS_DEF_STRING(Uint8Array, "Uint8Array", 0, 0)
+NJS_DEF_STRING(Uint8ClampedArray, "Uint8ClampedArray", 0, 0)
+NJS_DEF_STRING(_Getter_, "[Getter]", 0, 0)
+NJS_DEF_STRING(_Setter_, "[Setter]", 0, 0)
+NJS_DEF_STRING(_Getter_Setter_, "[Getter/Setter]", 0, 0)
+NJS_DEF_STRING(_object_Array_, "[object Array]", 0, 0)
+NJS_DEF_STRING(_object_Arguments_, "[object Arguments]", 0, 0)
+NJS_DEF_STRING(_object_Boolean_, "[object Boolean]", 0, 0)
+NJS_DEF_STRING(_object_Date_, "[object Date]", 0, 0)
+NJS_DEF_STRING(_object_Error_, "[object Error]", 0, 0)
+NJS_DEF_STRING(_object_Function_, "[object Function]", 0, 0)
+NJS_DEF_STRING(_object_Null_, "[object Null]", 0, 0)
+NJS_DEF_STRING(_object_Number_, "[object Number]", 0, 0)
+NJS_DEF_STRING(_object_Object_, "[object Object]", 0, 0)
+NJS_DEF_STRING(_object_RegExp_, "[object RegExp]", 0, 0)
+NJS_DEF_STRING(_object_String_, "[object String]", 0, 0)
+NJS_DEF_STRING(_object_Undefined_, "[object Undefined]", 0, 0)
+NJS_DEF_STRING(__proto__, "__proto__", 0, 0)
+NJS_DEF_STRING(abs, "abs", 0, 0)
+NJS_DEF_STRING(acos, "acos", 0, 0)
+NJS_DEF_STRING(acosh, "acosh", 0, 0)
+NJS_DEF_STRING(all, "all", 0, 0)
+NJS_DEF_STRING(alloc, "alloc", 0, 0)
+NJS_DEF_STRING(allocUnsafe, "allocUnsafe", 0, 0)
+NJS_DEF_STRING(allocUnsafeSlow, "allocUnsafeSlow", 0, 0)
+NJS_DEF_STRING(allSettled, "allSettled", 0, 0)
+NJS_DEF_STRING(anonymous, "anonymous", 0, 0)
+NJS_DEF_STRING(any, "any", 0, 0)
+NJS_DEF_STRING(apply, "apply", 0, 0)
+NJS_DEF_STRING(argv, "argv", 0, 0)
+NJS_DEF_STRING(asin, "asin", 0, 0)
+NJS_DEF_STRING(asinh, "asinh", 0, 0)
+NJS_DEF_STRING(assign, "assign", 0, 0)
+NJS_DEF_STRING(asyncIterator, "asyncIterator", 0, 0)
+NJS_DEF_STRING(atan, "atan", 0, 0)
+NJS_DEF_STRING(atan2, "atan2", 0, 0)
+NJS_DEF_STRING(atanh, "atanh", 0, 0)
+NJS_DEF_STRING(atob, "atob", 0, 0)
+NJS_DEF_STRING(bind, "bind", 0, 0)
+NJS_DEF_STRING(boolean, "boolean", 0, 0)
+NJS_DEF_STRING(btoa, "btoa", 0, 0)
+NJS_DEF_STRING(buffer, "buffer", 0, 0)
+NJS_DEF_STRING(byteLength, "byteLength", 0, 0)
+NJS_DEF_STRING(byteOffset, "byteOffset", 0, 0)
+NJS_DEF_STRING(call, "call", 0, 0)
+NJS_DEF_STRING(callee, "callee", 0, 0)
+NJS_DEF_STRING(caller, "caller", 0, 0)
+NJS_DEF_STRING(cbrt, "cbrt", 0, 0)
+NJS_DEF_STRING(ceil, "ceil", 0, 0)
+NJS_DEF_STRING(charAt, "charAt", 0, 0)
+NJS_DEF_STRING(charCodeAt, "charCodeAt", 0, 0)
+NJS_DEF_STRING(cluster_size, "cluster_size", 0, 0)
+NJS_DEF_STRING(clz32, "clz32", 0, 0)
+NJS_DEF_STRING(codePointAt, "codePointAt", 0, 0)
+NJS_DEF_STRING(compare, "compare", 0, 0)
+NJS_DEF_STRING(concat, "concat", 0, 0)
+NJS_DEF_STRING(configurable, "configurable", 0, 0)
+NJS_DEF_STRING(constructor, "constructor", 0, 0)
+NJS_DEF_STRING(copy, "copy", 0, 0)
+NJS_DEF_STRING(copyWithin, "copyWithin", 0, 0)
+NJS_DEF_STRING(cos, "cos", 0, 0)
+NJS_DEF_STRING(cosh, "cosh", 0, 0)
+NJS_DEF_STRING(create, "create", 0, 0)
+NJS_DEF_STRING(data, "data", 0, 0)
+NJS_DEF_STRING(decode, "decode", 0, 0)
+NJS_DEF_STRING(decodeURI, "decodeURI", 0, 0)
+NJS_DEF_STRING(decodeURIComponent, "decodeURIComponent", 0, 0)
+NJS_DEF_STRING(defineProperty, "defineProperty", 0, 0)
+NJS_DEF_STRING(defineProperties, "defineProperties", 0, 0)
+NJS_DEF_STRING(description, "description", 0, 0)
+NJS_DEF_STRING(done, "done", 0, 0)
+NJS_DEF_STRING(dump, "dump", 0, 0)
+NJS_DEF_STRING(encode, "encode", 0, 0)
+NJS_DEF_STRING(encodeInto, "encodeInto", 0, 0)
+NJS_DEF_STRING(encodeURI, "encodeURI", 0, 0)
+NJS_DEF_STRING(encodeURIComponent, "encodeURIComponent", 0, 0)
+NJS_DEF_STRING(encoding, "encoding", 0, 0)
+NJS_DEF_STRING(endsWith, "endsWith", 0, 0)
+NJS_DEF_STRING(engine, "engine", 0, 0)
+NJS_DEF_STRING(enumerable, "enumerable", 0, 0)
+NJS_DEF_STRING(entries, "entries", 0, 0)
+NJS_DEF_STRING(env, "env", 0, 0)
+NJS_DEF_STRING(equals, "equals", 0, 0)
+NJS_DEF_STRING(errors, "errors", 0, 0)
+NJS_DEF_STRING(every, "every", 0, 0)
+NJS_DEF_STRING(exec, "exec", 0, 0)
+NJS_DEF_STRING(exp, "exp", 0, 0)
+NJS_DEF_STRING(expm1, "expm1", 0, 0)
+NJS_DEF_STRING(external, "external", 0, 0)
+NJS_DEF_STRING(fatal, "fatal", 0, 0)
+NJS_DEF_STRING(fileName, "fileName", 0, 0)
+NJS_DEF_STRING(fill, "fill", 0, 0)
+NJS_DEF_STRING(filter, "filter", 0, 0)
+NJS_DEF_STRING(find, "find", 0, 0)
+NJS_DEF_STRING(findIndex, "findIndex", 0, 0)
+NJS_DEF_STRING(flags, "flags", 0, 0)
+NJS_DEF_STRING(floor, "floor", 0, 0)
+NJS_DEF_STRING(forEach, "forEach", 0, 0)
+NJS_DEF_STRING(freeze, "freeze", 0, 0)
+NJS_DEF_STRING(fromCharCode, "fromCharCode", 0, 0)
+NJS_DEF_STRING(fromCodePoint, "fromCodePoint", 0, 0)
+NJS_DEF_STRING(fround, "fround", 0, 0)
+NJS_DEF_STRING(fulfilled, "fulfilled", 0, 0)
+NJS_DEF_STRING(get, "get", 0, 0)
+NJS_DEF_STRING(getDate, "getDate", 0, 0)
+NJS_DEF_STRING(getDay, "getDay", 0, 0)
+NJS_DEF_STRING(getFloat32, "getFloat32", 0, 0)
+NJS_DEF_STRING(getFloat64, "getFloat64", 0, 0)
+NJS_DEF_STRING(getFullYear, "getFullYear", 0, 0)
+NJS_DEF_STRING(getHours, "getHours", 0, 0)
+NJS_DEF_STRING(getInt16, "getInt16", 0, 0)
+NJS_DEF_STRING(getInt32, "getInt32", 0, 0)
+NJS_DEF_STRING(getInt8, "getInt8", 0, 0)
+NJS_DEF_STRING(getMilliseconds, "getMilliseconds", 0, 0)
+NJS_DEF_STRING(getMinutes, "getMinutes", 0, 0)
+NJS_DEF_STRING(getOwnPropertyDescriptor, "getOwnPropertyDescriptor", 0, 0)
+NJS_DEF_STRING(getOwnPropertyDescriptors, "getOwnPropertyDescriptors", 0, 0)
+NJS_DEF_STRING(getOwnPropertyNames, "getOwnPropertyNames", 0, 0)
+NJS_DEF_STRING(getOwnPropertySymbols, "getOwnPropertySymbols", 0, 0)
+NJS_DEF_STRING(getPrototypeOf, "getPrototypeOf", 0, 0)
+NJS_DEF_STRING(getSeconds, "getSeconds", 0, 0)
+NJS_DEF_STRING(getTime, "getTime", 0, 0)
+NJS_DEF_STRING(getTimezoneOffset, "getTimezoneOffset", 0, 0)
+NJS_DEF_STRING(getUTCDate, "getUTCDate", 0, 0)
+NJS_DEF_STRING(getUTCDay, "getUTCDay", 0, 0)
+NJS_DEF_STRING(getUTCFullYear, "getUTCFullYear", 0, 0)
+NJS_DEF_STRING(getUTCHours, "getUTCHours", 0, 0)
+NJS_DEF_STRING(getUTCMilliseconds, "getUTCMilliseconds", 0, 0)
+NJS_DEF_STRING(getUTCMinutes, "getUTCMinutes", 0, 0)
+NJS_DEF_STRING(getUTCMonth, "getUTCMonth", 0, 0)
+NJS_DEF_STRING(getUTCSeconds, "getUTCSeconds", 0, 0)
+NJS_DEF_STRING(getUint16, "getUint16", 0, 0)
+NJS_DEF_STRING(getUint32, "getUint32", 0, 0)
+NJS_DEF_STRING(getUint8, "getUint8", 0, 0)
+NJS_DEF_STRING(getMonth, "getMonth", 0, 0)
+NJS_DEF_STRING(global, "global", 0, 0)
+NJS_DEF_STRING(globalThis, "globalThis", 0, 0)
+NJS_DEF_STRING(groups, "groups", 0, 0)
+NJS_DEF_STRING(hasOwnProperty, "hasOwnProperty", 0, 0)
+NJS_DEF_STRING(hasInstance, "hasInstance", 0, 0)
+NJS_DEF_STRING(hypot, "hypot", 0, 0)
+NJS_DEF_STRING(ignoreBOM, "ignoreBOM", 0, 0)
+NJS_DEF_STRING(ignoreCase, "ignoreCase", 0, 0)
+NJS_DEF_STRING(imul, "imul", 0, 0)
+NJS_DEF_STRING(includes, "includes", 0, 0)
+NJS_DEF_STRING(index, "index", 0, 0)
+NJS_DEF_STRING(indexOf, "indexOf", 0, 0)
+NJS_DEF_STRING(input, "input", 0, 0)
+NJS_DEF_STRING(is, "is", 0, 0)
+NJS_DEF_STRING(isArray, "isArray", 0, 0)
+NJS_DEF_STRING(isBuffer, "isBuffer", 0, 0)
+NJS_DEF_STRING(isConcatSpreadable, "isConcatSpreadable", 0, 0)
+NJS_DEF_STRING(isEncoding, "isEncoding", 0, 0)
+NJS_DEF_STRING(isExtensible, "isExtensible", 0, 0)
+NJS_DEF_STRING(isFinite, "isFinite", 0, 0)
+NJS_DEF_STRING(isFrozen, "isFrozen", 0, 0)
+NJS_DEF_STRING(isInteger, "isInteger", 0, 0)
+NJS_DEF_STRING(isNaN, "isNaN", 0, 0)
+NJS_DEF_STRING(isPrototypeOf, "isPrototypeOf", 0, 0)
+NJS_DEF_STRING(isSafeInteger, "isSafeInteger", 0, 0)
+NJS_DEF_STRING(isSealed, "isSealed", 0, 0)
+NJS_DEF_STRING(isView, "isView", 0, 0)
+NJS_DEF_STRING(iterator, "iterator", 0, 0)
+NJS_DEF_STRING(join, "join", 0, 0)
+NJS_DEF_STRING(keyFor, "keyFor", 0, 0)
+NJS_DEF_STRING(keys, "keys", 0, 0)
+NJS_DEF_STRING(kill, "kill", 0, 0)
+NJS_DEF_STRING(lastIndex, "lastIndex", 0, 0)
+NJS_DEF_STRING(lastIndexOf, "lastIndexOf", 0, 0)
+NJS_DEF_STRING(length, "length", 0, 0)
+NJS_DEF_STRING(lineNumber, "lineNumber", 0, 0)
+NJS_DEF_STRING(log, "log", 0, 0)
+NJS_DEF_STRING(log10, "log10", 0, 0)
+NJS_DEF_STRING(log1p, "log1p", 0, 0)
+NJS_DEF_STRING(log2, "log2", 0, 0)
+NJS_DEF_STRING(map, "map", 0, 0)
+NJS_DEF_STRING(matchAll, "matchAll", 0, 0)
+NJS_DEF_STRING(match, "match", 0, 0)
+NJS_DEF_STRING(max, "max", 0, 0)
+NJS_DEF_STRING(min, "min", 0, 0)
+NJS_DEF_STRING(memoryStats, "memoryStats", 0, 0)
+NJS_DEF_STRING(message, "message", 0, 0)
+NJS_DEF_STRING(multiline, "multiline", 0, 0)
+NJS_DEF_STRING(name, "name", 0, 0)
+NJS_DEF_STRING(nblocks, "nblocks", 0, 0)
+NJS_DEF_STRING(next, "next", 0, 0)
+NJS_DEF_STRING(njs, "njs", 0, 0)
+NJS_DEF_STRING(now, "now", 0, 0)
+NJS_DEF_STRING(number, "number", 0, 0)
+NJS_DEF_STRING(object, "object", 0, 0)
+NJS_DEF_STRING(on, "on", 0, 0)
+NJS_DEF_STRING(padEnd, "padEnd", 0, 0)
+NJS_DEF_STRING(padStart, "padStart", 0, 0)
+NJS_DEF_STRING(page_size, "page_size", 0, 0)
+NJS_DEF_STRING(parse, "parse", 0, 0)
+NJS_DEF_STRING(parseFloat, "parseFloat", 0, 0)
+NJS_DEF_STRING(parseInt, "parseInt", 0, 0)
+NJS_DEF_STRING(pid, "pid", 0, 0)
+NJS_DEF_STRING(pop, "pop", 0, 0)
+NJS_DEF_STRING(pow, "pow", 0, 0)
+NJS_DEF_STRING(ppid, "ppid", 0, 0)
+NJS_DEF_STRING(preventExtensions, "preventExtensions", 0, 0)
+NJS_DEF_STRING(process, "process", 0, 0)
+NJS_DEF_STRING(propertyIsEnumerable, "propertyIsEnumerable", 0, 0)
+NJS_DEF_STRING(prototype, "prototype", 0, 0)
+NJS_DEF_STRING(push, "push", 0, 0)
+NJS_DEF_STRING(race, "race", 0, 0)
+NJS_DEF_STRING(random, "random", 0, 0)
+NJS_DEF_STRING(read, "read", 0, 0)
+NJS_DEF_STRING(readDoubleBE, "readDoubleBE", 0, 0)
+NJS_DEF_STRING(readDoubleLE, "readDoubleLE", 0, 0)
+NJS_DEF_STRING(readFloatBE, "readFloatBE", 0, 0)
+NJS_DEF_STRING(readFloatLE, "readFloatLE", 0, 0)
+NJS_DEF_STRING(readInt16BE, "readInt16BE", 0, 0)
+NJS_DEF_STRING(readInt16LE, "readInt16LE", 0, 0)
+NJS_DEF_STRING(readInt32BE, "readInt32BE", 0, 0)
+NJS_DEF_STRING(readInt32LE, "readInt32LE", 0, 0)
+NJS_DEF_STRING(readInt8, "readInt8", 0, 0)
+NJS_DEF_STRING(readIntBE, "readIntBE", 0, 0)
+NJS_DEF_STRING(readIntLE, "readIntLE", 0, 0)
+NJS_DEF_STRING(readUInt16BE, "readUInt16BE", 0, 0)
+NJS_DEF_STRING(readUInt16LE, "readUInt16LE", 0, 0)
+NJS_DEF_STRING(readUInt32BE, "readUInt32BE", 0, 0)
+NJS_DEF_STRING(readUInt32LE, "readUInt32LE", 0, 0)
+NJS_DEF_STRING(readUInt8, "readUInt8", 0, 0)
+NJS_DEF_STRING(readUIntBE, "readUIntBE", 0, 0)
+NJS_DEF_STRING(readUIntLE, "readUIntLE", 0, 0)
+NJS_DEF_STRING(reason, "reason", 0, 0)
+NJS_DEF_STRING(reduce, "reduce", 0, 0)
+NJS_DEF_STRING(reduceRight, "reduceRight", 0, 0)
+NJS_DEF_STRING(reject, "reject", 0, 0)
+NJS_DEF_STRING(rejected, "rejected", 0, 0)
+NJS_DEF_STRING(repeat, "repeat", 0, 0)
+NJS_DEF_STRING(replace, "replace", 0, 0)
+NJS_DEF_STRING(replaceAll, "replaceAll", 0, 0)
+NJS_DEF_STRING(require, "require", 0, 0)
+NJS_DEF_STRING(resolve, "resolve", 0, 0)
+NJS_DEF_STRING(reverse, "reverse", 0, 0)
+NJS_DEF_STRING(round, "round", 0, 0)
+NJS_DEF_STRING(seal, "seal", 0, 0)
+NJS_DEF_STRING(search, "search", 0, 0)
+NJS_DEF_STRING(set, "set", 0, 0)
+NJS_DEF_STRING(setDate, "setDate", 0, 0)
+NJS_DEF_STRING(setFloat32, "setFloat32", 0, 0)
+NJS_DEF_STRING(setFloat64, "setFloat64", 0, 0)
+NJS_DEF_STRING(setFullYear, "setFullYear", 0, 0)
+NJS_DEF_STRING(setHours, "setHours", 0, 0)
+NJS_DEF_STRING(setInt16, "setInt16", 0, 0)
+NJS_DEF_STRING(setInt32, "setInt32", 0, 0)
+NJS_DEF_STRING(setInt8, "setInt8", 0, 0)
+NJS_DEF_STRING(setMilliseconds, "setMilliseconds", 0, 0)
+NJS_DEF_STRING(setMinutes, "setMinutes", 0, 0)
+NJS_DEF_STRING(setMonth, "setMonth", 0, 0)
+NJS_DEF_STRING(setPrototypeOf, "setPrototypeOf", 0, 0)
+NJS_DEF_STRING(setSeconds, "setSeconds", 0, 0)
+NJS_DEF_STRING(setTime, "setTime", 0, 0)
+NJS_DEF_STRING(setUint16, "setUint16", 0, 0)
+NJS_DEF_STRING(setUint32, "setUint32", 0, 0)
+NJS_DEF_STRING(setUint8, "setUint8", 0, 0)
+NJS_DEF_STRING(setUTCDate, "setUTCDate", 0, 0)
+NJS_DEF_STRING(setUTCFullYear, "setUTCFullYear", 0, 0)
+NJS_DEF_STRING(setUTCHours, "setUTCHours", 0, 0)
+NJS_DEF_STRING(setUTCMilliseconds, "setUTCMilliseconds", 0, 0)
+NJS_DEF_STRING(setUTCMinutes, "setUTCMinutes", 0, 0)
+NJS_DEF_STRING(setUTCMonth, "setUTCMonth", 0, 0)
+NJS_DEF_STRING(setUTCSeconds, "setUTCSeconds", 0, 0)
+NJS_DEF_STRING(shift, "shift", 0, 0)
+NJS_DEF_STRING(sign, "sign", 0, 0)
+NJS_DEF_STRING(sin, "sin", 0, 0)
+NJS_DEF_STRING(sinh, "sinh", 0, 0)
+NJS_DEF_STRING(size, "size", 0, 0)
+NJS_DEF_STRING(slice, "slice", 0, 0)
+NJS_DEF_STRING(some, "some", 0, 0)
+NJS_DEF_STRING(sort, "sort", 0, 0)
+NJS_DEF_STRING(source, "source", 0, 0)
+NJS_DEF_STRING(species, "species", 0, 0)
+NJS_DEF_STRING(splice, "splice", 0, 0)
+NJS_DEF_STRING(split, "split", 0, 0)
+NJS_DEF_STRING(sqrt, "sqrt", 0, 0)
+NJS_DEF_STRING(stack, "stack", 0, 0)
+NJS_DEF_STRING(startsWith, "startsWith", 0, 0)
+NJS_DEF_STRING(status, "status", 0, 0)
+NJS_DEF_STRING(sticky, "sticky", 0, 0)
+NJS_DEF_STRING(stream, "stream", 0, 0)
+NJS_DEF_STRING(string, "string", 0, 0)
+NJS_DEF_STRING(stringify, "stringify", 0, 0)
+NJS_DEF_STRING(subarray, "subarray", 0, 0)
+NJS_DEF_STRING(substr, "substr", 0, 0)
+NJS_DEF_STRING(substring, "substring", 0, 0)
+NJS_DEF_STRING(symbol, "symbol", 0, 0)
+NJS_DEF_STRING(swap16, "swap16", 0, 0)
+NJS_DEF_STRING(swap32, "swap32", 0, 0)
+NJS_DEF_STRING(swap64, "swap64", 0, 0)
+NJS_DEF_STRING(tan, "tan", 0, 0)
+NJS_DEF_STRING(tanh, "tanh", 0, 0)
+NJS_DEF_STRING(test, "test", 0, 0)
+NJS_DEF_STRING(then, "then", 0, 0)
+NJS_DEF_STRING(times, "times", 0, 0)
+NJS_DEF_STRING(toDateString, "toDateString", 0, 0)
+NJS_DEF_STRING(toExponential, "toExponential", 0, 0)
+NJS_DEF_STRING(toFixed, "toFixed", 0, 0)
+NJS_DEF_STRING(toISOString, "toISOString", 0, 0)
+NJS_DEF_STRING(toJSON, "toJSON", 0, 0)
+NJS_DEF_STRING(toLocaleDateString, "toLocaleDateString", 0, 0)
+NJS_DEF_STRING(toLocaleString, "toLocaleString", 0, 0)
+NJS_DEF_STRING(toLocaleTimeString, "toLocaleTimeString", 0, 0)
+NJS_DEF_STRING(toLowerCase, "toLowerCase", 0, 0)
+NJS_DEF_STRING(toPrimitive, "toPrimitive", 0, 0)
+NJS_DEF_STRING(toPrecision, "toPrecision", 0, 0)
+NJS_DEF_STRING(toReversed, "toReversed", 0, 0)
+NJS_DEF_STRING(toSorted, "toSorted", 0, 0)
+NJS_DEF_STRING(toSpliced, "toSpliced", 0, 0)
+NJS_DEF_STRING(toStringTag, "toStringTag", 0, 0)
+NJS_DEF_STRING(toString, "toString", 0, 0)
+NJS_DEF_STRING(toTimeString, "toTimeString", 0, 0)
+NJS_DEF_STRING(toUpperCase, "toUpperCase", 0, 0)
+NJS_DEF_STRING(toUTCString, "toUTCString", 0, 0)
+NJS_DEF_STRING(trimEnd, "trimEnd", 0, 0)
+NJS_DEF_STRING(trimStart, "trimStart", 0, 0)
+NJS_DEF_STRING(trim, "trim", 0, 0)
+NJS_DEF_STRING(trunc, "trunc", 0, 0)
+NJS_DEF_STRING(type, "type", 0, 0)
+NJS_DEF_STRING(usec, "usec", 0, 0)
+NJS_DEF_STRING(unscopables, "unscopables", 0, 0)
+NJS_DEF_STRING(unshift, "unshift", 0, 0)
+NJS_DEF_STRING(utf_8, "utf-8", 0, 0)
+NJS_DEF_STRING(value, "value", 0, 0)
+NJS_DEF_STRING(valueOf, "valueOf", 0, 0)
+NJS_DEF_STRING(values, "values", 0, 0)
+NJS_DEF_STRING(version, "version", 0, 0)
+NJS_DEF_STRING(version_number, "version_number", 0, 0)
+NJS_DEF_STRING(write, "write", 0, 0)
+NJS_DEF_STRING(writable, "writable", 0, 0)
+NJS_DEF_STRING(writeDoubleBE, "writeDoubleBE", 0, 0)
+NJS_DEF_STRING(writeDoubleLE, "writeDoubleLE", 0, 0)
+NJS_DEF_STRING(writeFloatBE, "writeFloatBE", 0, 0)
+NJS_DEF_STRING(writeFloatLE, "writeFloatLE", 0, 0)
+NJS_DEF_STRING(writeIntBE, "writeIntBE", 0, 0)
+NJS_DEF_STRING(writeIntLE, "writeIntLE", 0, 0)
+NJS_DEF_STRING(writeInt16BE, "writeInt16BE", 0, 0)
+NJS_DEF_STRING(writeInt16LE, "writeInt16LE", 0, 0)
+NJS_DEF_STRING(writeInt32BE, "writeInt32BE", 0, 0)
+NJS_DEF_STRING(writeInt32LE, "writeInt32LE", 0, 0)
+NJS_DEF_STRING(writeInt8, "writeInt8", 0, 0)
+NJS_DEF_STRING(writeUIntBE, "writeUIntBE", 0, 0)
+NJS_DEF_STRING(writeUIntLE, "writeUIntLE", 0, 0)
+NJS_DEF_STRING(writeUInt16BE, "writeUInt16BE", 0, 0)
+NJS_DEF_STRING(writeUInt16LE, "writeUInt16LE", 0, 0)
+NJS_DEF_STRING(writeUInt32BE, "writeUInt32BE", 0, 0)
+NJS_DEF_STRING(writeUInt32LE, "writeUInt32LE", 0, 0)
+NJS_DEF_STRING(writeUInt8, "writeUInt8", 0, 0)
+NJS_DEF_STRING(written, "written", 0, 0)
diff --git a/src/njs_boolean.c b/src/njs_boolean.c
index ba26f751..39119060 100644
--- a/src/njs_boolean.c
+++ b/src/njs_boolean.c
@@ -38,23 +38,16 @@ njs_boolean_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 }
 
 
-static const njs_object_prop_t  njs_boolean_constructor_properties[] =
+static const njs_object_prop_init_t  njs_boolean_constructor_properties[] =
 {
-    {
-        .type = NJS_PROPERTY,
-        .name = njs_string("name"),
-        .u.value = njs_string("Boolean"),
-        .configurable = 1,
-    },
-
-    {
-        .type = NJS_PROPERTY,
-        .name = njs_string("length"),
-        .u.value = njs_value(NJS_NUMBER, 1, 1.0),
-        .configurable = 1,
-    },
-
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
+    NJS_DECLARE_PROP_VALUE(STRING_name, njs_ascii_strval("Boolean"),
+                           NJS_OBJECT_PROP_VALUE_C),
+
+    NJS_DECLARE_PROP_VALUE(STRING_length, njs_value(NJS_NUMBER, 1, 1.0),
+                           NJS_OBJECT_PROP_VALUE_C),
+
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
+                             0, 0),
 };
 
 
@@ -110,29 +103,36 @@ njs_boolean_prototype_to_string(njs_vm_t *vm, njs_value_t *args,
         }
     }
 
-    njs_value_assign(retval, njs_is_true(value) ? &njs_string_true
-                                                : &njs_string_false);
+    if (njs_is_true(value)) {
+        njs_atom_to_value(vm, retval, NJS_ATOM_STRING_true);
+
+    } else {
+        njs_atom_to_value(vm, retval, NJS_ATOM_STRING_false);
+    }
 
     return NJS_OK;
 }
 
 
-static const njs_object_prop_t  njs_boolean_prototype_properties[] =
+static const njs_object_prop_init_t  njs_boolean_prototype_properties[] =
 {
-    NJS_DECLARE_PROP_HANDLER("__proto__", njs_primitive_prototype_get_proto,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING___proto__,
+                             njs_primitive_prototype_get_proto, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("constructor",
-                             njs_object_prototype_create_constructor,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
+                             njs_object_prototype_create_constructor, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_NATIVE("valueOf", njs_boolean_prototype_value_of, 0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_valueOf, njs_boolean_prototype_value_of,
+                            0, 0),
 
-    NJS_DECLARE_PROP_NATIVE("toString", njs_boolean_prototype_to_string, 0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_toString,
+                            njs_boolean_prototype_to_string, 0, 0),
 };
 
 
-const njs_object_init_t  njs_boolean_prototype_init = {
+static const njs_object_init_t  njs_boolean_prototype_init = {
     njs_boolean_prototype_properties,
     njs_nitems(njs_boolean_prototype_properties),
 };
diff --git a/src/njs_buffer.c b/src/njs_buffer.c
index 3ce1b90a..3f0469e7 100644
--- a/src/njs_buffer.c
+++ b/src/njs_buffer.c
@@ -76,7 +76,7 @@ static njs_int_t njs_buffer_write_string(njs_vm_t *vm, njs_value_t *value,
     njs_typed_array_t *array, const njs_buffer_encoding_t *encoding,
     uint64_t offset, uint64_t length, njs_value_t *retval);
 static njs_int_t njs_buffer_fill(njs_vm_t *vm, njs_typed_array_t *array,
-    const njs_value_t *fill, const njs_value_t *encoding, uint64_t offset,
+    const njs_value_t *fill, njs_value_t *encoding, uint64_t offset,
     uint64_t end);
 static njs_int_t njs_buffer_fill_string(njs_vm_t *vm, const njs_value_t *value,
     njs_typed_array_t *array, const njs_buffer_encoding_t *encoding,
@@ -86,14 +86,14 @@ static njs_int_t njs_buffer_fill_typed_array(njs_vm_t *vm,
     uint8_t *end);
 
 static njs_int_t njs_buffer(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t atom_id, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 static njs_int_t njs_buffer_constants(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t atom_id, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 static njs_int_t njs_buffer_constant(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t atom_id, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 
 static njs_int_t njs_buffer_init(njs_vm_t *vm);
 
@@ -349,20 +349,17 @@ njs_buffer_from_object(njs_vm_t *vm, njs_value_t *value, njs_value_t *retval)
     njs_value_t        val, data, length;
     njs_typed_array_t  *buffer;
 
-    static const njs_value_t  string_length = njs_string("length");
     static const njs_str_t  str_buffer = njs_str("Buffer");
 
 next:
 
-    ret = njs_value_property(vm, value, njs_value_arg(&string_length),
-                             &length);
+    ret = njs_value_property(vm, value, NJS_ATOM_STRING_length, &length);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return ret;
     }
 
     if (ret == NJS_DECLINED) {
-        ret = njs_value_property(vm, value, njs_value_arg(&njs_string_type),
-                                 &val);
+        ret = njs_value_property(vm, value, NJS_ATOM_STRING_type, &val);
         if (njs_slow_path(ret != NJS_OK)) {
             return ret;
         }
@@ -372,14 +369,13 @@ next:
             return ret;
         }
 
-        njs_string_get(&val, &str);
+        njs_string_get(vm, &val, &str);
 
         if (!njs_strstr_eq(&str, &str_buffer)) {
             return NJS_DECLINED;
         }
 
-        ret = njs_value_property(vm, value, njs_value_arg(&njs_string_data),
-                                 &val);
+        ret = njs_value_property(vm, value, NJS_ATOM_STRING_data, &val);
         if (njs_slow_path(ret != NJS_OK)) {
             return ret;
         }
@@ -527,7 +523,7 @@ njs_buffer_from_string(njs_vm_t *vm, njs_value_t *value,
         return NJS_ERROR;
     }
 
-    njs_string_get(&dst, &str);
+    njs_string_get(vm, &dst, &str);
 
     buffer = njs_buffer_alloc(vm, str.length, 0);
     if (njs_slow_path(buffer == NULL)) {
@@ -543,14 +539,14 @@ njs_buffer_from_string(njs_vm_t *vm, njs_value_t *value,
 
 
 static size_t
-njs_buffer_decode_string_length(njs_value_t *value,
+njs_buffer_decode_string_length(njs_vm_t *vm, njs_value_t *value,
     const njs_buffer_encoding_t *encoding)
 {
     size_t             size;
     njs_str_t          str;
     njs_string_prop_t  string;
 
-    (void) njs_string_prop(&string, value);
+    (void) njs_string_prop(vm, &string, value);
 
     str.start = string.start;
     str.length = string.size;
@@ -595,7 +591,7 @@ njs_buffer_byte_length(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             return NJS_ERROR;
         }
 
-        size = njs_buffer_decode_string_length(value, encoding);
+        size = njs_buffer_decode_string_length(vm, value, encoding);
 
         njs_set_number(retval, size);
 
@@ -965,7 +961,7 @@ static njs_int_t
 njs_buffer_is_encoding(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused, njs_value_t *retval)
 {
-    const njs_value_t  *value;
+    njs_value_t  *value;
 
     value = njs_arg(args, nargs, 1);
     njs_set_boolean(retval, njs_is_defined(value)
@@ -977,7 +973,8 @@ njs_buffer_is_encoding(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_buffer_prototype_length(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     njs_typed_array_t  *array;
 
@@ -1703,7 +1700,7 @@ njs_buffer_write_string(njs_vm_t *vm, njs_value_t *value,
         return NJS_ERROR;
     }
 
-    njs_string_get(&dst, &str);
+    njs_string_get(vm, &dst, &str);
 
     start = &buffer->u.u8[array->offset + offset];
 
@@ -1812,7 +1809,7 @@ done:
 
 static njs_int_t
 njs_buffer_fill(njs_vm_t *vm, njs_typed_array_t *array, const njs_value_t *fill,
-    const njs_value_t *encode, uint64_t offset, uint64_t end)
+    njs_value_t *encode, uint64_t offset, uint64_t end)
 {
     double                       num;
     uint8_t                      *start, *stop;
@@ -1887,7 +1884,7 @@ njs_buffer_fill_string(njs_vm_t *vm, const njs_value_t *value,
         return NJS_ERROR;
     }
 
-    njs_string_get(&dst, &str);
+    njs_string_get(vm, &dst, &str);
 
     if (str.length == 0) {
         memset(start, 0, end - start);
@@ -1992,7 +1989,7 @@ njs_buffer_prototype_to_string(njs_vm_t *vm, njs_value_t *args,
     str.length = end - start;
 
     if (njs_slow_path(str.length == 0)) {
-        njs_value_assign(retval, &njs_string_empty);
+        njs_set_empty_string(vm, retval);
         return NJS_OK;
     }
 
@@ -2173,7 +2170,7 @@ encoding:
                 return ret;
             }
 
-            njs_string_get(&dst, &str);
+            njs_string_get(vm, &dst, &str);
 
         } else {
             src = njs_typed_array(value);
@@ -2347,15 +2344,13 @@ njs_buffer_prototype_to_json(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 {
     u_char              *p, *end;
     njs_int_t           ret;
-    njs_value_t         *value;
+    njs_value_t         *value, setval;
     njs_value_t         object, array;
     njs_array_t         *arr;
     njs_object_t        *obj;
     njs_typed_array_t   *ta;
     njs_array_buffer_t  *buffer;
 
-    static const njs_value_t  string_buffer = njs_string("Buffer");
-
     ta = njs_buffer_slot(vm, njs_argument(args, 0), "this");
     if (njs_slow_path(ta == NULL)) {
         return NJS_ERROR;
@@ -2367,9 +2362,9 @@ njs_buffer_prototype_to_json(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     njs_set_object(&object, obj);
+    njs_atom_to_value(vm, &setval, NJS_ATOM_STRING_Buffer);
 
-    ret = njs_value_property_set(vm, &object, njs_value_arg(&njs_string_type),
-                                 njs_value_arg(&string_buffer));
+    ret = njs_value_property_set(vm, &object, NJS_ATOM_STRING_type, &setval);
     if (njs_slow_path(ret != NJS_OK)) {
         return NJS_ERROR;
     }
@@ -2395,8 +2390,7 @@ njs_buffer_prototype_to_json(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     njs_set_array(&array, arr);
 
-    ret = njs_value_property_set(vm, &object, njs_value_arg(&njs_string_data),
-                                 &array);
+    ret = njs_value_property_set(vm, &object, NJS_ATOM_STRING_data, &array);
     if (njs_slow_path(ret != NJS_OK)) {
         return NJS_ERROR;
     }
@@ -2408,10 +2402,10 @@ njs_buffer_prototype_to_json(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 
 const njs_buffer_encoding_t *
-njs_buffer_encoding(njs_vm_t *vm, const njs_value_t *value, njs_bool_t throw)
+njs_buffer_encoding(njs_vm_t *vm, njs_value_t *value, njs_bool_t throw)
 {
-    njs_str_t              name;
-    njs_buffer_encoding_t  *encoding;
+    njs_str_t                    name;
+    const njs_buffer_encoding_t  *encoding;
 
     if (njs_slow_path(!njs_is_string(value))) {
         if (njs_is_defined(value)) {
@@ -2422,7 +2416,7 @@ njs_buffer_encoding(njs_vm_t *vm, const njs_value_t *value, njs_bool_t throw)
         return &njs_buffer_encodings[0];
     }
 
-    njs_string_get(value, &name);
+    njs_string_get(vm, value, &name);
 
     for (encoding = &njs_buffer_encodings[0];
          encoding->name.length != 0;
@@ -2449,7 +2443,7 @@ njs_buffer_decode_string(njs_vm_t *vm, const njs_value_t *value,
     njs_str_t          str;
     njs_string_prop_t  string;
 
-    (void) njs_string_prop(&string, value);
+    (void) njs_string_prop(vm, &string, value);
 
     str.start = string.start;
     str.length = string.size;
@@ -2469,159 +2463,197 @@ njs_buffer_decode_string(njs_vm_t *vm, const njs_value_t *value,
 }
 
 
-static const njs_object_prop_t  njs_buffer_prototype_properties[] =
+static const njs_object_prop_init_t  njs_buffer_prototype_properties[] =
 {
-    {
-        .type = NJS_PROPERTY,
-        .name = njs_wellknown_symbol(NJS_SYMBOL_TO_STRING_TAG),
-        .u.value = njs_string("Buffer"),
-        .configurable = 1,
-    },
+    NJS_DECLARE_PROP_VALUE(SYMBOL_toStringTag, njs_ascii_strval("Buffer"),
+                           NJS_OBJECT_PROP_VALUE_C),
 
-    NJS_DECLARE_PROP_HANDLER("constructor",
-                             njs_object_prototype_create_constructor,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
+                             njs_object_prototype_create_constructor, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("length", njs_buffer_prototype_length, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_length, njs_buffer_prototype_length, 0,
+                             0),
 
-    NJS_DECLARE_PROP_NATIVE("readInt8", njs_buffer_prototype_read_int, 1,
-                            njs_buffer_magic(1, 1, 1)),
+    NJS_DECLARE_PROP_NATIVE(STRING_readInt8, njs_buffer_prototype_read_int,
+                            1, njs_buffer_magic(1, 1, 1)),
 
-    NJS_DECLARE_PROP_NATIVE("readUInt8", njs_buffer_prototype_read_int, 1,
-                            njs_buffer_magic(1, 0, 1)),
+    NJS_DECLARE_PROP_NATIVE(STRING_readUInt8, njs_buffer_prototype_read_int,
+                            1, njs_buffer_magic(1, 0, 1)),
 
-    NJS_DECLARE_PROP_NATIVE("readInt16LE", njs_buffer_prototype_read_int, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_readInt16LE,
+                            njs_buffer_prototype_read_int, 1,
                             njs_buffer_magic(2, 1, 1)),
 
-    NJS_DECLARE_PROP_NATIVE("readUInt16LE", njs_buffer_prototype_read_int, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_readUInt16LE,
+                            njs_buffer_prototype_read_int, 1,
                             njs_buffer_magic(2, 0, 1)),
 
-    NJS_DECLARE_PROP_NATIVE("readInt16BE", njs_buffer_prototype_read_int, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_readInt16BE,
+                            njs_buffer_prototype_read_int, 1,
                             njs_buffer_magic(2, 1, 0)),
 
-    NJS_DECLARE_PROP_NATIVE("readUInt16BE", njs_buffer_prototype_read_int, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_readUInt16BE,
+                            njs_buffer_prototype_read_int, 1,
                             njs_buffer_magic(2, 0, 0)),
 
-    NJS_DECLARE_PROP_NATIVE("readInt32LE", njs_buffer_prototype_read_int, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_readInt32LE,
+                            njs_buffer_prototype_read_int, 1,
                             njs_buffer_magic(4, 1, 1)),
 
-    NJS_DECLARE_PROP_NATIVE("readUInt32LE", njs_buffer_prototype_read_int, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_readUInt32LE,
+                            njs_buffer_prototype_read_int, 1,
                             njs_buffer_magic(4, 0, 1)),
 
-    NJS_DECLARE_PROP_NATIVE("readInt32BE", njs_buffer_prototype_read_int, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_readInt32BE,
+                            njs_buffer_prototype_read_int, 1,
                             njs_buffer_magic(4, 1, 0)),
 
-    NJS_DECLARE_PROP_NATIVE("readUInt32BE", njs_buffer_prototype_read_int, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_readUInt32BE,
+                            njs_buffer_prototype_read_int, 1,
                             njs_buffer_magic(4, 0, 0)),
 
-    NJS_DECLARE_PROP_NATIVE("readIntLE", njs_buffer_prototype_read_int, 2,
+    NJS_DECLARE_PROP_NATIVE(STRING_readIntLE,
+                            njs_buffer_prototype_read_int, 2,
                             njs_buffer_magic(0, 1, 1)),
 
-    NJS_DECLARE_PROP_NATIVE("readUIntLE", njs_buffer_prototype_read_int, 2,
+    NJS_DECLARE_PROP_NATIVE(STRING_readUIntLE,
+                            njs_buffer_prototype_read_int, 2,
                             njs_buffer_magic(0, 0, 1)),
 
-    NJS_DECLARE_PROP_NATIVE("readIntBE", njs_buffer_prototype_read_int, 2,
+    NJS_DECLARE_PROP_NATIVE(STRING_readIntBE,
+                            njs_buffer_prototype_read_int, 2,
                             njs_buffer_magic(0, 1, 0)),
 
-    NJS_DECLARE_PROP_NATIVE("readUIntBE", njs_buffer_prototype_read_int, 2,
+    NJS_DECLARE_PROP_NATIVE(STRING_readUIntBE,
+                            njs_buffer_prototype_read_int, 2,
                             njs_buffer_magic(0, 0, 0)),
 
-    NJS_DECLARE_PROP_NATIVE("readFloatLE", njs_buffer_prototype_read_float, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_readFloatLE,
+                            njs_buffer_prototype_read_float, 1,
                             njs_buffer_magic(4, 0, 1)),
 
-    NJS_DECLARE_PROP_NATIVE("readFloatBE", njs_buffer_prototype_read_float, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_readFloatBE,
+                            njs_buffer_prototype_read_float, 1,
                             njs_buffer_magic(4, 0, 0)),
 
-    NJS_DECLARE_PROP_NATIVE("readDoubleLE", njs_buffer_prototype_read_float, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_readDoubleLE,
+                            njs_buffer_prototype_read_float, 1,
                             njs_buffer_magic(8, 0, 1)),
 
-    NJS_DECLARE_PROP_NATIVE("readDoubleBE", njs_buffer_prototype_read_float, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_readDoubleBE,
+                            njs_buffer_prototype_read_float, 1,
                             njs_buffer_magic(8, 0, 0)),
 
-    NJS_DECLARE_PROP_NATIVE("writeInt8", njs_buffer_prototype_write_int, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_writeInt8,
+                            njs_buffer_prototype_write_int, 1,
                             njs_buffer_magic(1, 1, 0)),
 
-    NJS_DECLARE_PROP_NATIVE("writeUInt8", njs_buffer_prototype_write_int, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_writeUInt8,
+                            njs_buffer_prototype_write_int, 1,
                             njs_buffer_magic(1, 0, 0)),
 
-    NJS_DECLARE_PROP_NATIVE("writeInt16LE", njs_buffer_prototype_write_int, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_writeInt16LE,
+                            njs_buffer_prototype_write_int, 1,
                             njs_buffer_magic(2, 1, 1)),
 
-    NJS_DECLARE_PROP_NATIVE("writeUInt16LE", njs_buffer_prototype_write_int, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_writeUInt16LE,
+                            njs_buffer_prototype_write_int, 1,
                             njs_buffer_magic(2, 0, 1)),
 
-    NJS_DECLARE_PROP_NATIVE("writeInt16BE", njs_buffer_prototype_write_int, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_writeInt16BE,
+                            njs_buffer_prototype_write_int, 1,
                             njs_buffer_magic(2, 1, 0)),
 
-    NJS_DECLARE_PROP_NATIVE("writeUInt16BE", njs_buffer_prototype_write_int, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_writeUInt16BE,
+                            njs_buffer_prototype_write_int, 1,
                             njs_buffer_magic(2, 0, 0)),
 
-    NJS_DECLARE_PROP_NATIVE("writeInt32LE", njs_buffer_prototype_write_int, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_writeInt32LE,
+                            njs_buffer_prototype_write_int, 1,
                             njs_buffer_magic(4, 1, 1)),
 
-    NJS_DECLARE_PROP_NATIVE("writeUInt32LE", njs_buffer_prototype_write_int, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_writeUInt32LE,
+                            njs_buffer_prototype_write_int, 1,
                             njs_buffer_magic(4, 0, 1)),
 
-    NJS_DECLARE_PROP_NATIVE("writeInt32BE", njs_buffer_prototype_write_int, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_writeInt32BE,
+                            njs_buffer_prototype_write_int, 1,
                             njs_buffer_magic(4, 1, 0)),
 
-    NJS_DECLARE_PROP_NATIVE("writeUInt32BE", njs_buffer_prototype_write_int, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_writeUInt32BE,
+                            njs_buffer_prototype_write_int, 1,
                             njs_buffer_magic(4, 0, 0)),
 
-    NJS_DECLARE_PROP_NATIVE("writeIntLE", njs_buffer_prototype_write_int, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_writeIntLE,
+                            njs_buffer_prototype_write_int, 1,
                             njs_buffer_magic(0, 1, 1)),
 
-    NJS_DECLARE_PROP_NATIVE("writeUIntLE", njs_buffer_prototype_write_int, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_writeUIntLE,
+                            njs_buffer_prototype_write_int, 1,
                             njs_buffer_magic(0, 0, 1)),
 
-    NJS_DECLARE_PROP_NATIVE("writeIntBE", njs_buffer_prototype_write_int, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_writeIntBE,
+                            njs_buffer_prototype_write_int, 1,
                             njs_buffer_magic(0, 1, 0)),
 
-    NJS_DECLARE_PROP_NATIVE("writeUIntBE", njs_buffer_prototype_write_int, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_writeUIntBE,
+                            njs_buffer_prototype_write_int, 1,
                             njs_buffer_magic(0, 0, 0)),
 
-    NJS_DECLARE_PROP_NATIVE("writeFloatLE", njs_buffer_prototype_write_float,
+    NJS_DECLARE_PROP_NATIVE(STRING_writeFloatLE,
+                            njs_buffer_prototype_write_float,
                             1, njs_buffer_magic(4, 0, 1)),
 
-    NJS_DECLARE_PROP_NATIVE("writeFloatBE", njs_buffer_prototype_write_float,
+    NJS_DECLARE_PROP_NATIVE(STRING_writeFloatBE,
+                            njs_buffer_prototype_write_float,
                             1, njs_buffer_magic(4, 0, 0)),
 
-    NJS_DECLARE_PROP_NATIVE("writeDoubleLE", njs_buffer_prototype_write_float,
+    NJS_DECLARE_PROP_NATIVE(STRING_writeDoubleLE,
+                            njs_buffer_prototype_write_float,
                             1, njs_buffer_magic(8, 0, 1)),
 
-    NJS_DECLARE_PROP_NATIVE("writeDoubleBE", njs_buffer_prototype_write_float,
+    NJS_DECLARE_PROP_NATIVE(STRING_writeDoubleBE,
+                            njs_buffer_prototype_write_float,
                             1, njs_buffer_magic(8, 0, 0)),
 
-    NJS_DECLARE_PROP_NATIVE("write", njs_buffer_prototype_write, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_write, njs_buffer_prototype_write, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("fill", njs_buffer_prototype_fill, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_fill, njs_buffer_prototype_fill, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("toString", njs_buffer_prototype_to_string, 0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_toString, njs_buffer_prototype_to_string,
+                            0, 0),
 
-    NJS_DECLARE_PROP_NATIVE("compare", njs_buffer_prototype_compare, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_compare, njs_buffer_prototype_compare, 1,
+                            0),
 
-    NJS_DECLARE_PROP_NATIVE("copy", njs_buffer_prototype_copy, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_copy, njs_buffer_prototype_copy, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("equals", njs_buffer_prototype_equals, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_equals, njs_buffer_prototype_equals, 1,
+                            0),
 
-    NJS_DECLARE_PROP_NATIVE("indexOf", njs_buffer_prototype_index_of, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_indexOf, njs_buffer_prototype_index_of,
+                            1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("lastIndexOf", njs_buffer_prototype_index_of, 1,
-                            1),
+    NJS_DECLARE_PROP_NATIVE(STRING_lastIndexOf,
+                            njs_buffer_prototype_index_of, 1, 1),
 
-    NJS_DECLARE_PROP_NATIVE("includes", njs_buffer_prototype_includes, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_includes, njs_buffer_prototype_includes, 1,
+                            0),
 
-    NJS_DECLARE_PROP_NATIVE("subarray", njs_buffer_prototype_slice, 2, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_subarray, njs_buffer_prototype_slice, 2,
+                            0),
 
-    NJS_DECLARE_PROP_NATIVE("slice", njs_buffer_prototype_slice, 2, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_slice, njs_buffer_prototype_slice, 2, 0),
 
-    NJS_DECLARE_PROP_NATIVE("swap16", njs_buffer_prototype_swap, 0, 2),
+    NJS_DECLARE_PROP_NATIVE(STRING_swap16, njs_buffer_prototype_swap, 0, 2),
 
-    NJS_DECLARE_PROP_NATIVE("swap32", njs_buffer_prototype_swap, 0, 4),
+    NJS_DECLARE_PROP_NATIVE(STRING_swap32, njs_buffer_prototype_swap, 0, 4),
 
-    NJS_DECLARE_PROP_NATIVE("swap64", njs_buffer_prototype_swap, 0, 8),
+    NJS_DECLARE_PROP_NATIVE(STRING_swap64, njs_buffer_prototype_swap, 0, 8),
 
-    NJS_DECLARE_PROP_NATIVE("toJSON", njs_buffer_prototype_to_json, 0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_toJSON, njs_buffer_prototype_to_json, 0,
+                            0),
 };
 
 
@@ -2631,31 +2663,36 @@ const njs_object_init_t  njs_buffer_prototype_init = {
 };
 
 
-static const njs_object_prop_t  njs_buffer_constructor_properties[] =
+static const njs_object_prop_init_t  njs_buffer_constructor_properties[] =
 {
     NJS_DECLARE_PROP_LENGTH(0),
 
     NJS_DECLARE_PROP_NAME("Buffer"),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
+                             0, 0),
 
-    NJS_DECLARE_PROP_NATIVE("alloc", njs_buffer_alloc_safe, 0, 1),
+    NJS_DECLARE_PROP_NATIVE(STRING_alloc, njs_buffer_alloc_safe, 0, 1),
 
-    NJS_DECLARE_PROP_NATIVE("allocUnsafe", njs_buffer_alloc_safe, 0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_allocUnsafe, njs_buffer_alloc_safe, 0,
+                            0),
 
-    NJS_DECLARE_PROP_LNATIVE("allocUnsafeSlow", njs_buffer_alloc_safe, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_allocUnsafeSlow, njs_buffer_alloc_safe,
+                            1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("byteLength", njs_buffer_byte_length, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_byteLength, njs_buffer_byte_length, 1,
+                            0),
 
-    NJS_DECLARE_PROP_NATIVE("compare", njs_buffer_compare, 2, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_compare, njs_buffer_compare, 2, 0),
 
-    NJS_DECLARE_PROP_NATIVE("concat", njs_buffer_concat, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_concat, njs_buffer_concat, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("from", njs_buffer_from, 3, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_from, njs_buffer_from, 3, 0),
 
-    NJS_DECLARE_PROP_NATIVE("isBuffer", njs_buffer_is_buffer, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_isBuffer, njs_buffer_is_buffer, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("isEncoding", njs_buffer_is_encoding, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_isEncoding, njs_buffer_is_encoding, 1,
+                            0),
 };
 
 
@@ -2673,14 +2710,15 @@ const njs_object_type_init_t  njs_buffer_type_init = {
 };
 
 
-static const njs_object_prop_t  njs_buffer_constants_properties[] =
+static const njs_object_prop_init_t  njs_buffer_constants_properties[] =
 {
-    NJS_DECLARE_PROP_VALUE("MAX_LENGTH", njs_value(NJS_NUMBER, 1, INT32_MAX),
+    NJS_DECLARE_PROP_VALUE(STRING_MAX_LENGTH,
+                           njs_value(NJS_NUMBER, 1, INT32_MAX),
                            NJS_OBJECT_PROP_VALUE_E),
 
-    NJS_DECLARE_PROP_LVALUE("MAX_STRING_LENGTH",
-                            njs_value(NJS_NUMBER, 1, NJS_STRING_MAX_LENGTH),
-                            NJS_OBJECT_PROP_VALUE_E),
+    NJS_DECLARE_PROP_VALUE(STRING_MAX_STRING_LENGTH,
+                           njs_value(NJS_NUMBER, 1, NJS_STRING_MAX_LENGTH),
+                           NJS_OBJECT_PROP_VALUE_E),
 };
 
 
@@ -2691,26 +2729,26 @@ static const njs_object_init_t  njs_buffer_constants_init = {
 
 
 static njs_int_t
-njs_buffer(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value,
-    njs_value_t *unused, njs_value_t *retval)
+njs_buffer(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t atom_id,
+    njs_value_t *value, njs_value_t *unused, njs_value_t *retval)
 {
-    return njs_object_prop_init(vm, &njs_buffer_constructor_init, prop, value,
-                                retval);
+    return njs_object_prop_init(vm, &njs_buffer_constructor_init, prop, atom_id,
+                                value, retval);
 }
 
 
 static njs_int_t
-njs_buffer_constants(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value,
-    njs_value_t *unused, njs_value_t *retval)
+njs_buffer_constants(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t atom_id,
+    njs_value_t *value, njs_value_t *unused, njs_value_t *retval)
 {
-    return njs_object_prop_init(vm, &njs_buffer_constants_init, prop, value,
-                                retval);
+    return njs_object_prop_init(vm, &njs_buffer_constants_init, prop, atom_id,
+                                value, retval);
 }
 
 
 static njs_int_t
-njs_buffer_constant(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value,
-    njs_value_t *unused, njs_value_t *retval)
+njs_buffer_constant(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t not_used,
+    njs_value_t *value, njs_value_t *unused, njs_value_t *retval)
 {
     njs_value_number_set(retval, njs_vm_prop_magic32(prop));
 
diff --git a/src/njs_buffer.h b/src/njs_buffer.h
index 696653c2..0ac4db79 100644
--- a/src/njs_buffer.h
+++ b/src/njs_buffer.h
@@ -27,7 +27,7 @@ njs_int_t njs_buffer_new(njs_vm_t *vm, njs_value_t *value, const u_char *start,
     uint32_t size);
 
 const njs_buffer_encoding_t *njs_buffer_encoding(njs_vm_t *vm,
-    const njs_value_t *value, njs_bool_t thrw);
+    njs_value_t *value, njs_bool_t thrw);
 njs_int_t njs_buffer_decode_string(njs_vm_t *vm, const njs_value_t *value,
     njs_value_t *dst, const njs_buffer_encoding_t *encoding);
 
diff --git a/src/njs_builtin.c b/src/njs_builtin.c
index 279c2158..230b4c1c 100644
--- a/src/njs_builtin.c
+++ b/src/njs_builtin.c
@@ -18,7 +18,7 @@ typedef struct {
 
     njs_function_t             *func;
 
-    njs_lvlhsh_t               keys;
+    njs_flathsh_t              keys;
     njs_str_t                  match;
 } njs_builtin_traverse_t;
 
@@ -30,10 +30,10 @@ typedef struct {
 
 
 static njs_int_t njs_global_this_prop_handler(njs_vm_t *vm,
-    njs_object_prop_t *self, njs_value_t *global, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *self, uint32_t atom_id, njs_value_t *global,
+    njs_value_t *setval, njs_value_t *retval);
 
-static njs_int_t njs_env_hash_init(njs_vm_t *vm, njs_lvlhsh_t *hash,
+static njs_int_t njs_env_hash_init(njs_vm_t *vm, njs_flathsh_t *hash,
     char **environment);
 
 
@@ -132,7 +132,7 @@ static njs_signal_entry_t njs_signals_table[] = {
 
 
 njs_inline njs_int_t
-njs_object_hash_init(njs_vm_t *vm, njs_lvlhsh_t *hash,
+njs_object_hash_init(njs_vm_t *vm, njs_flathsh_t *hash,
     const njs_object_init_t *init)
 {
     return njs_object_hash_create(vm, hash, init->properties, init->items);
@@ -158,9 +158,13 @@ njs_builtin_objects_create(njs_vm_t *vm)
 
     vm->shared = shared;
 
-    njs_lvlhsh_init(&shared->keywords_hash);
     njs_lvlhsh_init(&shared->values_hash);
 
+    vm->atom_id_generator = njs_atom_hash_init(vm);
+    if (njs_slow_path(vm->atom_id_generator == 0xffffffff)) {
+        return NJS_ERROR;
+    }
+
     pattern = njs_regexp_pattern_create(vm, (u_char *) "(?:)",
                                         njs_length("(?:)"), 0);
     if (njs_slow_path(pattern == NULL)) {
@@ -245,6 +249,16 @@ njs_builtin_objects_create(njs_vm_t *vm)
         prototype = njs_shared_prototype(shared, i);
         *prototype = njs_object_type_init[i]->prototype_value;
 
+        if (njs_object_type_init[i] == &njs_boolean_type_init) {
+            prototype->object_value.value = njs_value(NJS_BOOLEAN, 0, 0.0);
+
+        } else if (njs_object_type_init[i] == &njs_number_type_init) {
+            prototype->object_value.value = njs_value(NJS_NUMBER, 0, 0.0);
+
+        } else if (njs_object_type_init[i] == &njs_string_type_init) {
+            njs_set_empty_string(vm, &prototype->object_value.value);
+        }
+
         ret = njs_object_hash_init(vm, &prototype->object.shared_hash,
                                    njs_object_type_init[i]->prototype_props);
         if (njs_slow_path(ret != NJS_OK)) {
@@ -306,10 +320,10 @@ njs_builtin_traverse(njs_vm_t *vm, njs_traverse_t *traverse, void *data)
     njs_int_t               ret, n;
     njs_str_t               name;
     njs_bool_t              symbol;
-    njs_value_t             key, *value;
+    njs_value_t             key, *value, prop_name;
     njs_function_t          *func, *target;
     njs_object_prop_t       *prop;
-    njs_lvlhsh_query_t      lhq;
+    njs_flathsh_query_t     lhq;
     njs_builtin_traverse_t  *ctx;
     njs_traverse_t          *path[NJS_TRAVERSE_MAX_DEPTH];
     u_char                  buf[256];
@@ -356,13 +370,17 @@ njs_builtin_traverse(njs_vm_t *vm, njs_traverse_t *traverse, void *data)
 
     do {
         symbol = 0;
-        key = path[n]->prop->name;
+
+        ret = njs_atom_to_value(vm, &key, path[n]->atom_id);
+        if (ret != NJS_OK) {
+            return NJS_ERROR;
+        }
 
         if (njs_slow_path(njs_is_symbol(&key))) {
             symbol = 1;
             key = *njs_symbol_description(&key);
             if (njs_is_undefined(&key)) {
-                key = njs_string_empty;
+                njs_set_empty_string(vm, &key);
             }
         }
 
@@ -371,7 +389,7 @@ njs_builtin_traverse(njs_vm_t *vm, njs_traverse_t *traverse, void *data)
             return NJS_OK;
         }
 
-        njs_string_get(&key, &name);
+        njs_string_get(vm, &key, &name);
 
         if (njs_slow_path((p + name.length + 3) > end)) {
             njs_type_error(vm, "njs_builtin_traverse() key is too long");
@@ -415,24 +433,23 @@ njs_builtin_traverse(njs_vm_t *vm, njs_traverse_t *traverse, void *data)
 
     /* NJS_BUILTIN_TRAVERSE_KEYS. */
 
-    prop = njs_object_prop_alloc(vm, &njs_value_undefined, &njs_value_null, 0);
+    prop = njs_object_prop_alloc(vm, &njs_value_null, 0);
     if (njs_slow_path(prop == NULL)) {
         return NJS_ERROR;
     }
 
-    ret = njs_string_create(vm, &prop->name, buf, p - buf);
+    ret = njs_atom_string_create(vm, &prop_name, buf, p - buf);
     if (njs_slow_path(ret != NJS_OK)) {
         return ret;
     }
 
     lhq.value = prop;
-    njs_string_get(&prop->name, &lhq.key);
-    lhq.key_hash = njs_djb_hash(lhq.key.start, lhq.key.length);
+    lhq.key_hash = prop_name.atom_id;
     lhq.replace = 1;
     lhq.pool = vm->mem_pool;
     lhq.proto = &njs_object_hash_proto;
 
-    ret = njs_lvlhsh_insert(&ctx->keys, &lhq);
+    ret = njs_flathsh_unique_insert(&ctx->keys, &lhq);
     if (njs_slow_path(ret != NJS_OK)) {
         njs_internal_error(vm, "lvlhsh insert/replace failed");
         return NJS_ERROR;
@@ -503,11 +520,9 @@ njs_builtin_match_native_function(njs_vm_t *vm, njs_function_t *function,
     for (i = NJS_OBJ_TYPE_HIDDEN_MIN; i < NJS_OBJ_TYPE_HIDDEN_MAX; i++) {
         njs_set_object(&value, &njs_vm_ctor(vm, i).object);
 
-        ret = njs_value_property(vm, &value, njs_value_arg(&njs_string_name),
-                                 &tag);
-
+        ret = njs_value_property(vm, &value, NJS_ATOM_STRING_name, &tag);
         if (ret == NJS_OK && njs_is_string(&tag)) {
-            njs_string_get(&tag, &ctx.match);
+            njs_string_get(vm, &tag, &ctx.match);
         }
 
         ret = njs_object_traverse(vm, njs_object(&value), &ctx,
@@ -560,7 +575,7 @@ njs_builtin_match_native_function(njs_vm_t *vm, njs_function_t *function,
 
         ret = njs_object_string_tag(vm, &value, &tag);
         if (ret == NJS_OK && njs_is_string(&tag)) {
-            njs_string_get(&tag, &ctx.match);
+            njs_string_get(vm, &tag, &ctx.match);
         }
 
         ret = njs_object_traverse(vm, njs_object(&value), &ctx,
@@ -651,7 +666,7 @@ njs_ext_on(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    njs_string_get(value, &type);
+    njs_string_get(vm, value, &type);
 
     i = 0;
     n = sizeof(hooks) / sizeof(hooks[0]);
@@ -683,19 +698,14 @@ njs_ext_on(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 
 static njs_int_t
-njs_ext_memory_stats(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *unused, njs_value_t *unused2, njs_value_t *retval)
+njs_ext_memory_stats(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
+    njs_value_t *unused2, njs_value_t *unused3, njs_value_t *retval)
 {
     njs_int_t      ret;
     njs_value_t    object, value;
     njs_object_t   *stat;
     njs_mp_stat_t  mp_stat;
 
-    static const njs_value_t  size_string = njs_string("size");
-    static const njs_value_t  nblocks_string = njs_string("nblocks");
-    static const njs_value_t  page_string = njs_string("page_size");
-    static const njs_value_t  cluster_string = njs_string("cluster_size");
-
     stat = njs_object_alloc(vm);
     if (njs_slow_path(stat == NULL)) {
         return NJS_ERROR;
@@ -707,23 +717,21 @@ njs_ext_memory_stats(njs_vm_t *vm, njs_object_prop_t *prop,
 
     njs_set_number(&value, mp_stat.size);
 
-    ret = njs_value_property_set(vm, &object, njs_value_arg(&size_string),
-                                 &value);
+    ret = njs_value_property_set(vm, &object, NJS_ATOM_STRING_size, &value);
     if (njs_slow_path(ret != NJS_OK)) {
         return NJS_ERROR;
     }
 
     njs_set_number(&value, mp_stat.nblocks);
 
-    ret = njs_value_property_set(vm, &object, njs_value_arg(&nblocks_string),
-                                 &value);
+    ret = njs_value_property_set(vm, &object, NJS_ATOM_STRING_nblocks, &value);
     if (njs_slow_path(ret != NJS_OK)) {
         return NJS_ERROR;
     }
 
     njs_set_number(&value, mp_stat.cluster_size);
 
-    ret = njs_value_property_set(vm, &object, njs_value_arg(&cluster_string),
+    ret = njs_value_property_set(vm, &object, NJS_ATOM_STRING_cluster_size,
                                  &value);
     if (njs_slow_path(ret != NJS_OK)) {
         return NJS_ERROR;
@@ -731,8 +739,7 @@ njs_ext_memory_stats(njs_vm_t *vm, njs_object_prop_t *prop,
 
     njs_set_number(&value, mp_stat.page_size);
 
-    ret = njs_value_property_set(vm, &object, njs_value_arg(&page_string),
-                                 &value);
+    ret = njs_value_property_set(vm, &object, NJS_ATOM_STRING_page_size, &value);
     if (njs_slow_path(ret != NJS_OK)) {
         return NJS_ERROR;
     }
@@ -747,32 +754,25 @@ njs_ext_memory_stats(njs_vm_t *vm, njs_object_prop_t *prop,
 
 static njs_int_t
 njs_global_this_prop_handler(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *global, njs_value_t *setval, njs_value_t *retval)
+    uint32_t atom_id, njs_value_t *global, njs_value_t *setval,
+    njs_value_t *retval)
 {
-    njs_int_t            ret;
     njs_value_t          *value;
     njs_variable_t       *var;
     njs_function_t       *function;
     njs_rbtree_node_t    *rb_node;
-    njs_lvlhsh_query_t   lhq;
     njs_variable_node_t  *node, var_node;
 
     if (retval == NULL) {
         return NJS_DECLINED;
     }
 
-    njs_string_get(&prop->name, &lhq.key);
-    lhq.key_hash = njs_djb_hash(lhq.key.start, lhq.key.length);
-    lhq.proto = &njs_lexer_hash_proto;
+    var_node.key = atom_id;
 
-    ret = njs_lvlhsh_find(&vm->shared->keywords_hash, &lhq);
-
-    if (njs_slow_path(ret != NJS_OK || lhq.value == NULL)) {
+    if (njs_slow_path(vm->global_scope == NULL)) {
         return NJS_DECLINED;
     }
 
-    var_node.key = (uintptr_t) lhq.value;
-
     rb_node = njs_rbtree_find(&vm->global_scope->variables, &var_node.node);
     if (rb_node == NULL) {
         return NJS_DECLINED;
@@ -808,12 +808,12 @@ njs_global_this_prop_handler(njs_vm_t *vm, njs_object_prop_t *prop,
 
 
 static njs_int_t
-njs_global_this_object(njs_vm_t *vm, njs_object_prop_t *self,
+njs_global_this_object(njs_vm_t *vm, njs_object_prop_t *self, uint32_t atom_id,
     njs_value_t *global, njs_value_t *setval, njs_value_t *retval)
 {
-    njs_int_t           ret;
-    njs_object_prop_t   *prop;
-    njs_lvlhsh_query_t  lhq;
+    njs_int_t            ret;
+    njs_object_prop_t    *prop;
+    njs_flathsh_query_t  lhq;
 
     if (retval == NULL) {
         return NJS_DECLINED;
@@ -825,7 +825,7 @@ njs_global_this_object(njs_vm_t *vm, njs_object_prop_t *self,
         njs_value_assign(retval, setval);
     }
 
-    prop = njs_object_prop_alloc(vm, &self->name, retval, 1);
+    prop = njs_object_prop_alloc(vm, retval, 1);
     if (njs_slow_path(prop == NULL)) {
         return NJS_ERROR;
     }
@@ -834,13 +834,12 @@ njs_global_this_object(njs_vm_t *vm, njs_object_prop_t *self,
     prop->enumerable = self->enumerable;
 
     lhq.value = prop;
-    njs_string_get(&self->name, &lhq.key);
-    lhq.key_hash = njs_prop_magic32(self);
+    lhq.key_hash = atom_id;
     lhq.replace = 1;
     lhq.pool = vm->mem_pool;
     lhq.proto = &njs_object_hash_proto;
 
-    ret = njs_lvlhsh_insert(njs_object_hash(global), &lhq);
+    ret = njs_flathsh_unique_insert(njs_object_hash(global), &lhq);
     if (njs_slow_path(ret != NJS_OK)) {
         njs_internal_error(vm, "lvlhsh insert/replace failed");
         return NJS_ERROR;
@@ -851,13 +850,13 @@ njs_global_this_object(njs_vm_t *vm, njs_object_prop_t *self,
 
 
 static njs_int_t
-njs_top_level_object(njs_vm_t *vm, njs_object_prop_t *self,
+njs_top_level_object(njs_vm_t *vm, njs_object_prop_t *self, uint32_t atom_id,
     njs_value_t *global, njs_value_t *setval, njs_value_t *retval)
 {
-    njs_int_t           ret;
-    njs_object_t        *object;
-    njs_object_prop_t   *prop;
-    njs_lvlhsh_query_t  lhq;
+    njs_int_t            ret;
+    njs_object_t         *object;
+    njs_object_prop_t    *prop;
+    njs_flathsh_query_t  lhq;
 
     if (njs_slow_path(setval != NULL)) {
         njs_value_assign(retval, setval);
@@ -877,7 +876,7 @@ njs_top_level_object(njs_vm_t *vm, njs_object_prop_t *self,
         object->__proto__ = njs_vm_proto(vm, NJS_OBJ_TYPE_OBJECT);
     }
 
-    prop = njs_object_prop_alloc(vm, &self->name, retval, 1);
+    prop = njs_object_prop_alloc(vm, retval, 1);
     if (njs_slow_path(prop == NULL)) {
         return NJS_ERROR;
     }
@@ -886,13 +885,12 @@ njs_top_level_object(njs_vm_t *vm, njs_object_prop_t *self,
     prop->enumerable = self->enumerable;
 
     lhq.value = prop;
-    njs_string_get(&self->name, &lhq.key);
-    lhq.key_hash = njs_prop_magic32(self);
+    lhq.key_hash = atom_id;
     lhq.replace = 1;
     lhq.pool = vm->mem_pool;
     lhq.proto = &njs_object_hash_proto;
 
-    ret = njs_lvlhsh_insert(njs_object_hash(global), &lhq);
+    ret = njs_flathsh_unique_insert(njs_object_hash(global), &lhq);
     if (njs_slow_path(ret != NJS_OK)) {
         njs_internal_error(vm, "lvlhsh insert/replace failed");
         return NJS_ERROR;
@@ -904,12 +902,13 @@ njs_top_level_object(njs_vm_t *vm, njs_object_prop_t *self,
 
 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)
+    uint32_t atom_id, 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;
+    njs_int_t            ret;
+    njs_function_t       *ctor;
+    njs_object_prop_t    *prop;
+    njs_flathsh_query_t  lhq;
 
     if (njs_slow_path(setval != NULL)) {
         njs_value_assign(retval, setval);
@@ -926,7 +925,7 @@ njs_top_level_constructor(njs_vm_t *vm, njs_object_prop_t *self,
         return NJS_OK;
     }
 
-    prop = njs_object_prop_alloc(vm, &self->name, retval, 1);
+    prop = njs_object_prop_alloc(vm, retval, 1);
     if (njs_slow_path(prop == NULL)) {
         return NJS_ERROR;
     }
@@ -935,13 +934,12 @@ njs_top_level_constructor(njs_vm_t *vm, njs_object_prop_t *self,
     prop->enumerable = 0;
 
     lhq.value = prop;
-    njs_string_get(&self->name, &lhq.key);
-    lhq.key_hash = njs_prop_magic32(self);
+    lhq.key_hash = atom_id;
     lhq.replace = 1;
     lhq.pool = vm->mem_pool;
     lhq.proto = &njs_object_hash_proto;
 
-    ret = njs_lvlhsh_insert(njs_object_hash(global), &lhq);
+    ret = njs_flathsh_unique_insert(njs_object_hash(global), &lhq);
     if (njs_slow_path(ret != NJS_OK)) {
         njs_internal_error(vm, "lvlhsh insert/replace failed");
         return NJS_ERROR;
@@ -951,227 +949,205 @@ njs_top_level_constructor(njs_vm_t *vm, njs_object_prop_t *self,
 }
 
 
-static const njs_object_prop_t  njs_global_this_object_properties[] =
+static const njs_object_prop_init_t  njs_global_this_object_properties[] =
 {
-    {
-        .type = NJS_PROPERTY,
-        .name = njs_wellknown_symbol(NJS_SYMBOL_TO_STRING_TAG),
-        .u.value = njs_string("global"),
-        .configurable = 1,
-    },
+    NJS_DECLARE_PROP_VALUE(SYMBOL_toStringTag, njs_ascii_strval("global"),
+                           NJS_OBJECT_PROP_VALUE_C),
 
     /* Global aliases. */
 
-    NJS_DECLARE_PROP_HANDLER("global", njs_global_this_object, 0,
-                             NJS_GLOBAL_HASH, NJS_OBJECT_PROP_VALUE_ECW),
+    NJS_DECLARE_PROP_HANDLER(STRING_global, njs_global_this_object, 0,
+                             NJS_OBJECT_PROP_VALUE_ECW),
 
-    NJS_DECLARE_PROP_HANDLER("globalThis", njs_global_this_object, 0,
-                             NJS_GLOBAL_THIS_HASH, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_globalThis, njs_global_this_object, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
     /* Global constants. */
 
-    NJS_DECLARE_PROP_VALUE("NaN",  njs_value(NJS_NUMBER, 0, NAN), 0),
+    NJS_DECLARE_PROP_VALUE(STRING_NaN,  njs_value(NJS_NUMBER, 0, NAN), 0),
 
-    NJS_DECLARE_PROP_VALUE("Infinity",  njs_value(NJS_NUMBER, 1, INFINITY), 0),
+    NJS_DECLARE_PROP_VALUE(STRING_Infinity,
+                           njs_value(NJS_NUMBER, 1, INFINITY), 0),
 
-    NJS_DECLARE_PROP_VALUE("undefined",  njs_value(NJS_UNDEFINED, 0, NAN), 0),
+    NJS_DECLARE_PROP_VALUE(STRING_undefined,
+                           njs_value(NJS_UNDEFINED, 0, NAN), 0),
 
     /* Global functions. */
 
-    NJS_DECLARE_PROP_NATIVE("isFinite", njs_number_global_is_finite, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_isFinite, njs_number_global_is_finite, 1,
+                            0),
 
-    NJS_DECLARE_PROP_NATIVE("isNaN", njs_number_global_is_nan, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_isNaN, njs_number_global_is_nan, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("parseFloat", njs_number_parse_float, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_parseFloat, njs_number_parse_float, 1,
+                            0),
 
-    NJS_DECLARE_PROP_NATIVE("parseInt", njs_number_parse_int, 2, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_parseInt, njs_number_parse_int, 2, 0),
 
-    NJS_DECLARE_PROP_NATIVE("toString", njs_object_prototype_to_string, 0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_toString, njs_object_prototype_to_string,
+                            0, 0),
 
-    NJS_DECLARE_PROP_NATIVE("encodeURI", njs_string_encode_uri, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_encodeURI, njs_string_encode_uri, 1, 0),
 
-    NJS_DECLARE_PROP_LNATIVE("encodeURIComponent", njs_string_encode_uri, 1, 1),
+    NJS_DECLARE_PROP_NATIVE(STRING_encodeURIComponent,
+                            njs_string_encode_uri, 1, 1),
 
-    NJS_DECLARE_PROP_NATIVE("decodeURI", njs_string_decode_uri, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_decodeURI, njs_string_decode_uri, 1, 0),
 
-    NJS_DECLARE_PROP_LNATIVE("decodeURIComponent", njs_string_decode_uri, 1, 1),
+    NJS_DECLARE_PROP_NATIVE(STRING_decodeURIComponent,
+                            njs_string_decode_uri, 1, 1),
 
-    NJS_DECLARE_PROP_NATIVE("atob", njs_string_atob, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_atob, njs_string_atob, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("btoa", njs_string_btoa, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_btoa, njs_string_btoa, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("eval", njs_eval_function, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_eval, njs_eval_function, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("require", njs_module_require, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_require, njs_module_require, 1, 0),
 
     /* Global objects. */
 
-    NJS_DECLARE_PROP_HANDLER("njs", njs_top_level_object, NJS_OBJECT_NJS,
-                             NJS_NJS_HASH, NJS_OBJECT_PROP_VALUE_ECW),
+    NJS_DECLARE_PROP_HANDLER(STRING_njs, njs_top_level_object,
+                             NJS_OBJECT_NJS, NJS_OBJECT_PROP_VALUE_ECW),
 
-    NJS_DECLARE_PROP_HANDLER("process", njs_top_level_object,
-                             NJS_OBJECT_PROCESS, NJS_PROCESS_HASH,
-                             NJS_OBJECT_PROP_VALUE_ECW),
+    NJS_DECLARE_PROP_HANDLER(STRING_process, njs_top_level_object,
+                             NJS_OBJECT_PROCESS, NJS_OBJECT_PROP_VALUE_ECW),
 
-    NJS_DECLARE_PROP_HANDLER("Math", njs_top_level_object,
-                             NJS_OBJECT_MATH, NJS_MATH_HASH,
-                             NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_Math, njs_top_level_object,
+                             NJS_OBJECT_MATH, NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("JSON", njs_top_level_object,
-                             NJS_OBJECT_JSON, NJS_JSON_HASH,
-                             NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_JSON, njs_top_level_object,
+                             NJS_OBJECT_JSON, NJS_OBJECT_PROP_VALUE_CW),
 
 
 #ifdef NJS_TEST262
-    NJS_DECLARE_PROP_HANDLER("$262", njs_top_level_object,
-                             NJS_OBJECT_262, NJS_262_HASH,
-                             NJS_OBJECT_PROP_VALUE_ECW),
+    NJS_DECLARE_PROP_HANDLER(STRING__262, njs_top_level_object,
+                             NJS_OBJECT_262, NJS_OBJECT_PROP_VALUE_ECW),
 #endif
 
     /* Global constructors. */
 
-    NJS_DECLARE_PROP_HANDLER("Object", njs_top_level_constructor,
-                             NJS_OBJ_TYPE_OBJECT, NJS_OBJECT_HASH,
-                             NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_Object, njs_top_level_constructor,
+                             NJS_OBJ_TYPE_OBJECT, NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("Array", njs_top_level_constructor,
-                             NJS_OBJ_TYPE_ARRAY, NJS_ARRAY_HASH,
-                             NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_Array, njs_top_level_constructor,
+                             NJS_OBJ_TYPE_ARRAY, NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("ArrayBuffer", njs_top_level_constructor,
-                             NJS_OBJ_TYPE_ARRAY_BUFFER, NJS_ARRAY_BUFFER_HASH,
+    NJS_DECLARE_PROP_HANDLER(STRING_ArrayBuffer, njs_top_level_constructor,
+                             NJS_OBJ_TYPE_ARRAY_BUFFER,
                              NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("DataView", njs_top_level_constructor,
-                             NJS_OBJ_TYPE_DATA_VIEW, NJS_DATA_VIEW_HASH,
+    NJS_DECLARE_PROP_HANDLER(STRING_DataView, njs_top_level_constructor,
+                             NJS_OBJ_TYPE_DATA_VIEW,
                              NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("TextDecoder", njs_top_level_constructor,
-                             NJS_OBJ_TYPE_TEXT_DECODER, NJS_TEXT_DECODER_HASH,
+    NJS_DECLARE_PROP_HANDLER(STRING_TextDecoder, njs_top_level_constructor,
+                             NJS_OBJ_TYPE_TEXT_DECODER,
                              NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("TextEncoder", njs_top_level_constructor,
-                             NJS_OBJ_TYPE_TEXT_ENCODER, NJS_TEXT_ENCODER_HASH,
+    NJS_DECLARE_PROP_HANDLER(STRING_TextEncoder, njs_top_level_constructor,
+                             NJS_OBJ_TYPE_TEXT_ENCODER,
                              NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("Buffer", njs_top_level_constructor,
-                             NJS_OBJ_TYPE_BUFFER, NJS_BUFFER_HASH,
-                             NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_Buffer, njs_top_level_constructor,
+                             NJS_OBJ_TYPE_BUFFER, NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("Uint8Array", njs_top_level_constructor,
-                             NJS_OBJ_TYPE_UINT8_ARRAY, NJS_UINT8ARRAY_HASH,
+    NJS_DECLARE_PROP_HANDLER(STRING_Uint8Array, njs_top_level_constructor,
+                             NJS_OBJ_TYPE_UINT8_ARRAY,
                              NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("Uint16Array", njs_top_level_constructor,
-                             NJS_OBJ_TYPE_UINT16_ARRAY, NJS_UINT16ARRAY_HASH,
+    NJS_DECLARE_PROP_HANDLER(STRING_Uint16Array, njs_top_level_constructor,
+                             NJS_OBJ_TYPE_UINT16_ARRAY,
                              NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("Uint32Array", njs_top_level_constructor,
-                             NJS_OBJ_TYPE_UINT32_ARRAY, NJS_UINT32ARRAY_HASH,
+    NJS_DECLARE_PROP_HANDLER(STRING_Uint32Array, njs_top_level_constructor,
+                             NJS_OBJ_TYPE_UINT32_ARRAY,
                              NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("Int8Array", njs_top_level_constructor,
-                             NJS_OBJ_TYPE_INT8_ARRAY, NJS_INT8ARRAY_HASH,
+    NJS_DECLARE_PROP_HANDLER(STRING_Int8Array, njs_top_level_constructor,
+                             NJS_OBJ_TYPE_INT8_ARRAY,
                              NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("Int16Array", njs_top_level_constructor,
-                             NJS_OBJ_TYPE_INT16_ARRAY, NJS_INT16ARRAY_HASH,
+    NJS_DECLARE_PROP_HANDLER(STRING_Int16Array, njs_top_level_constructor,
+                             NJS_OBJ_TYPE_INT16_ARRAY,
                              NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("Int32Array", njs_top_level_constructor,
-                             NJS_OBJ_TYPE_INT32_ARRAY, NJS_INT32ARRAY_HASH,
+    NJS_DECLARE_PROP_HANDLER(STRING_Int32Array, njs_top_level_constructor,
+                             NJS_OBJ_TYPE_INT32_ARRAY,
                              NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("Float32Array", njs_top_level_constructor,
-                             NJS_OBJ_TYPE_FLOAT32_ARRAY, NJS_FLOAT32ARRAY_HASH,
+    NJS_DECLARE_PROP_HANDLER(STRING_Float32Array, njs_top_level_constructor,
+                             NJS_OBJ_TYPE_FLOAT32_ARRAY,
                              NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("Float64Array", njs_top_level_constructor,
-                             NJS_OBJ_TYPE_FLOAT64_ARRAY, NJS_FLOAT64ARRAY_HASH,
+    NJS_DECLARE_PROP_HANDLER(STRING_Float64Array, njs_top_level_constructor,
+                             NJS_OBJ_TYPE_FLOAT64_ARRAY,
                              NJS_OBJECT_PROP_VALUE_CW),
 
-    {
-        .type = NJS_PROPERTY_HANDLER,
-        .name = njs_long_string("Uint8ClampedArray"),
-        .u.value = njs_prop_handler2(njs_top_level_constructor,
-                                   NJS_OBJ_TYPE_UINT8_CLAMPED_ARRAY,
-                                   NJS_UINT8CLAMPEDARRAY_HASH),
-        .writable = 1,
-        .configurable = 1,
-    },
-
-    NJS_DECLARE_PROP_HANDLER("Boolean", njs_top_level_constructor,
-                             NJS_OBJ_TYPE_BOOLEAN, NJS_BOOLEAN_HASH,
+    NJS_DECLARE_PROP_HANDLER(STRING_Uint8ClampedArray,
+                             njs_top_level_constructor,
+                             NJS_OBJ_TYPE_UINT8_CLAMPED_ARRAY,
                              NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("Number", njs_top_level_constructor,
-                             NJS_OBJ_TYPE_NUMBER, NJS_NUMBER_HASH,
-                             NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_Boolean, njs_top_level_constructor,
+                             NJS_OBJ_TYPE_BOOLEAN, NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("Symbol", njs_top_level_constructor,
-                             NJS_OBJ_TYPE_SYMBOL, NJS_SYMBOL_HASH,
-                             NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_Number, njs_top_level_constructor,
+                             NJS_OBJ_TYPE_NUMBER, NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("String", njs_top_level_constructor,
-                             NJS_OBJ_TYPE_STRING, NJS_STRING_HASH,
-                             NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_Symbol, njs_top_level_constructor,
+                             NJS_OBJ_TYPE_SYMBOL, NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("Function", njs_top_level_constructor,
-                             NJS_OBJ_TYPE_FUNCTION, NJS_FUNCTION_HASH,
-                             NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_String, njs_top_level_constructor,
+                             NJS_OBJ_TYPE_STRING, NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("RegExp", njs_top_level_constructor,
-                             NJS_OBJ_TYPE_REGEXP, NJS_REGEXP_HASH,
-                             NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_Function, njs_top_level_constructor,
+                             NJS_OBJ_TYPE_FUNCTION, NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("Date", njs_top_level_constructor,
-                             NJS_OBJ_TYPE_DATE, NJS_DATE_HASH,
-                             NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_RegExp, njs_top_level_constructor,
+                             NJS_OBJ_TYPE_REGEXP, NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("Promise", njs_top_level_constructor,
-                             NJS_OBJ_TYPE_PROMISE, NJS_PROMISE_HASH,
-                             NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_Date, njs_top_level_constructor,
+                             NJS_OBJ_TYPE_DATE, NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("Error", njs_top_level_constructor,
-                             NJS_OBJ_TYPE_ERROR, NJS_ERROR_HASH,
-                             NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_Promise, njs_top_level_constructor,
+                             NJS_OBJ_TYPE_PROMISE, NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("EvalError", njs_top_level_constructor,
-                             NJS_OBJ_TYPE_EVAL_ERROR, NJS_EVAL_ERROR_HASH,
-                             NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_Error, njs_top_level_constructor,
+                             NJS_OBJ_TYPE_ERROR, NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("InternalError", njs_top_level_constructor,
+    NJS_DECLARE_PROP_HANDLER(STRING_EvalError, njs_top_level_constructor,
+                             NJS_OBJ_TYPE_EVAL_ERROR, NJS_OBJECT_PROP_VALUE_CW),
+
+    NJS_DECLARE_PROP_HANDLER(STRING_InternalError,
+                             njs_top_level_constructor,
                              NJS_OBJ_TYPE_INTERNAL_ERROR,
-                             NJS_INTERNAL_ERROR_HASH,
                              NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("RangeError", njs_top_level_constructor,
-                             NJS_OBJ_TYPE_RANGE_ERROR, NJS_RANGE_ERROR_HASH,
+    NJS_DECLARE_PROP_HANDLER(STRING_RangeError, njs_top_level_constructor,
+                             NJS_OBJ_TYPE_RANGE_ERROR,
                              NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("ReferenceError", njs_top_level_constructor,
-                             NJS_OBJ_TYPE_REF_ERROR, NJS_REF_ERROR_HASH,
-                             NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_ReferenceError,
+                             njs_top_level_constructor,
+                             NJS_OBJ_TYPE_REF_ERROR, NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("SyntaxError", njs_top_level_constructor,
-                             NJS_OBJ_TYPE_SYNTAX_ERROR, NJS_SYNTAX_ERROR_HASH,
+    NJS_DECLARE_PROP_HANDLER(STRING_SyntaxError, njs_top_level_constructor,
+                             NJS_OBJ_TYPE_SYNTAX_ERROR,
                              NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("TypeError", njs_top_level_constructor,
-                             NJS_OBJ_TYPE_TYPE_ERROR, NJS_TYPE_ERROR_HASH,
-                             NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_TypeError, njs_top_level_constructor,
+                             NJS_OBJ_TYPE_TYPE_ERROR, NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("URIError", njs_top_level_constructor,
-                             NJS_OBJ_TYPE_URI_ERROR, NJS_URI_ERROR_HASH,
-                             NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_URIError, njs_top_level_constructor,
+                             NJS_OBJ_TYPE_URI_ERROR, NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("MemoryError", njs_top_level_constructor,
-                             NJS_OBJ_TYPE_MEMORY_ERROR, NJS_MEMORY_ERROR_HASH,
+    NJS_DECLARE_PROP_HANDLER(STRING_MemoryError, njs_top_level_constructor,
+                             NJS_OBJ_TYPE_MEMORY_ERROR,
                              NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("AggregateError", njs_top_level_constructor,
+    NJS_DECLARE_PROP_HANDLER(STRING_AggregateError, njs_top_level_constructor,
                              NJS_OBJ_TYPE_AGGREGATE_ERROR,
-                             NJS_AGGREGATE_ERROR_HASH,
                              NJS_OBJECT_PROP_VALUE_CW),
 };
 
@@ -1182,30 +1158,26 @@ static const njs_object_init_t  njs_global_this_init = {
 };
 
 
-static const njs_object_prop_t  njs_njs_object_properties[] =
+static const njs_object_prop_init_t  njs_njs_object_properties[] =
 {
-    {
-        .type = NJS_PROPERTY,
-        .name = njs_wellknown_symbol(NJS_SYMBOL_TO_STRING_TAG),
-        .u.value = njs_string("njs"),
-        .configurable = 1,
-    },
-
-    NJS_DECLARE_PROP_VALUE("engine", njs_string("njs"),
+    NJS_DECLARE_PROP_VALUE(SYMBOL_toStringTag, njs_ascii_strval("njs"),
+                           NJS_OBJECT_PROP_VALUE_C),
+
+    NJS_DECLARE_PROP_VALUE(STRING_engine, njs_ascii_strval("njs"),
                            NJS_OBJECT_PROP_VALUE_EC),
 
-    NJS_DECLARE_PROP_VALUE("version", njs_string(NJS_VERSION),
+    NJS_DECLARE_PROP_VALUE(STRING_version, njs_ascii_strval(NJS_VERSION),
                            NJS_OBJECT_PROP_VALUE_EC),
 
-    NJS_DECLARE_PROP_VALUE("version_number",
+    NJS_DECLARE_PROP_VALUE(STRING_version_number,
                            njs_value(NJS_NUMBER, 1, NJS_VERSION_NUMBER),
                            NJS_OBJECT_PROP_VALUE_EC),
 
-    NJS_DECLARE_PROP_NATIVE("dump", njs_ext_dump, 0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_dump, njs_ext_dump, 0, 0),
 
-    NJS_DECLARE_PROP_NATIVE("on", njs_ext_on, 0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_on, njs_ext_on, 0, 0),
 
-    NJS_DECLARE_PROP_HANDLER("memoryStats", njs_ext_memory_stats, 0, 0,
+    NJS_DECLARE_PROP_HANDLER(STRING_memoryStats, njs_ext_memory_stats, 0,
                              NJS_OBJECT_PROP_VALUE_EC),
 
 };
@@ -1218,17 +1190,15 @@ static const njs_object_init_t  njs_njs_object_init = {
 
 
 static njs_int_t
-njs_process_object_argv(njs_vm_t *vm, njs_object_prop_t *pr,
-    njs_value_t *process, njs_value_t *unused, njs_value_t *retval)
+njs_process_object_argv(njs_vm_t *vm, njs_object_prop_t *pr, uint32_t unused,
+    njs_value_t *process, njs_value_t *unused2, njs_value_t *retval)
 {
-    char                **arg;
-    njs_int_t           ret;
-    njs_uint_t          i;
-    njs_array_t         *argv;
-    njs_object_prop_t   *prop;
-    njs_lvlhsh_query_t  lhq;
-
-    static const njs_value_t  argv_string = njs_string("argv");
+    char                 **arg;
+    njs_int_t            ret;
+    njs_uint_t           i;
+    njs_array_t          *argv;
+    njs_object_prop_t    *prop;
+    njs_flathsh_query_t  lhq;
 
     argv = njs_array_alloc(vm, 1, vm->options.argc, 0);
     if (njs_slow_path(argv == NULL)) {
@@ -1238,11 +1208,14 @@ njs_process_object_argv(njs_vm_t *vm, njs_object_prop_t *pr,
     i = 0;
 
     for (arg = vm->options.argv; i < vm->options.argc; arg++) {
-        njs_string_create(vm, &argv->start[i++], (u_char *) *arg,
-                          njs_strlen(*arg));
+        ret = njs_string_create(vm, &argv->start[i++], (u_char *) *arg,
+                                njs_strlen(*arg));
+        if (njs_slow_path(ret != NJS_OK)) {
+            return NJS_ERROR;
+        }
     }
 
-    prop = njs_object_prop_alloc(vm, &argv_string, &njs_value_undefined, 1);
+    prop = njs_object_prop_alloc(vm, &njs_value_undefined, 1);
     if (njs_slow_path(prop == NULL)) {
         return NJS_ERROR;
     }
@@ -1250,14 +1223,12 @@ njs_process_object_argv(njs_vm_t *vm, njs_object_prop_t *pr,
     njs_set_array(njs_prop_value(prop), argv);
 
     lhq.value = prop;
-    lhq.key_hash = NJS_ARGV_HASH;
-    lhq.key = njs_str_value("argv");
+    lhq.key_hash = NJS_ATOM_STRING_argv;
     lhq.replace = 1;
     lhq.pool = vm->mem_pool;
     lhq.proto = &njs_object_hash_proto;
 
-    ret = njs_lvlhsh_insert(njs_object_hash(process), &lhq);
-
+    ret = njs_flathsh_unique_insert(njs_object_hash(process), &lhq);
     if (njs_fast_path(ret == NJS_OK)) {
         njs_value_assign(retval, njs_prop_value(prop));
         return NJS_OK;
@@ -1270,17 +1241,18 @@ njs_process_object_argv(njs_vm_t *vm, njs_object_prop_t *pr,
 
 
 static njs_int_t
-njs_env_hash_init(njs_vm_t *vm, njs_lvlhsh_t *hash, char **environment)
+njs_env_hash_init(njs_vm_t *vm, njs_flathsh_t *hash, char **environment)
 {
-    char                **ep;
-    u_char              *dst;
-    ssize_t             length;
-    uint32_t            cp;
-    njs_int_t           ret;
-    const u_char        *val, *entry, *s, *end;
-    njs_object_prop_t   *prop;
-    njs_string_prop_t   string;
-    njs_lvlhsh_query_t  lhq;
+    char                 **ep;
+    u_char               *dst;
+    ssize_t              length;
+    uint32_t             cp;
+    njs_int_t            ret;
+    njs_value_t          prop_name;
+    const u_char         *val, *entry, *s, *end;
+    njs_object_prop_t    *prop;
+    njs_string_prop_t    string;
+    njs_flathsh_query_t  lhq;
 
     lhq.replace = 0;
     lhq.pool = vm->mem_pool;
@@ -1289,8 +1261,7 @@ njs_env_hash_init(njs_vm_t *vm, njs_lvlhsh_t *hash, char **environment)
     ep = environment;
 
     while (*ep != NULL) {
-        prop = njs_object_prop_alloc(vm, &njs_value_undefined,
-                                     &njs_value_undefined, 1);
+        prop = njs_object_prop_alloc(vm, &njs_value_undefined, 1);
         if (njs_slow_path(prop == NULL)) {
             return NJS_ERROR;
         }
@@ -1302,12 +1273,12 @@ njs_env_hash_init(njs_vm_t *vm, njs_lvlhsh_t *hash, char **environment)
             continue;
         }
 
-        ret = njs_string_create(vm, &prop->name, entry, val - entry);
+        ret = njs_string_create(vm, &prop_name, entry, val - entry);
         if (njs_slow_path(ret != NJS_OK)) {
             return NJS_ERROR;
         }
 
-        (void) njs_string_prop(&string, &prop->name);
+        (void) njs_string_prop(vm, &string, &prop_name);
 
         length = string.length;
         s = string.start;
@@ -1327,11 +1298,15 @@ njs_env_hash_init(njs_vm_t *vm, njs_lvlhsh_t *hash, char **environment)
             return NJS_ERROR;
         }
 
+        ret = njs_atom_atomize_key(vm, &prop_name);
+        if (ret != NJS_OK) {
+            return ret;
+        }
+
         lhq.value = prop;
-        njs_string_get(&prop->name, &lhq.key);
-        lhq.key_hash = njs_djb_hash(lhq.key.start, lhq.key.length);
+        lhq.key_hash = prop_name.atom_id;
 
-        ret = njs_lvlhsh_insert(hash, &lhq);
+        ret = njs_flathsh_unique_insert(hash, &lhq);
         if (njs_slow_path(ret != NJS_OK)) {
             if (ret == NJS_ERROR) {
                 njs_internal_error(vm, "lvlhsh insert failed");
@@ -1352,15 +1327,13 @@ njs_env_hash_init(njs_vm_t *vm, njs_lvlhsh_t *hash, char **environment)
 
 
 static njs_int_t
-njs_process_object_env(njs_vm_t *vm, njs_object_prop_t *pr,
-    njs_value_t *process, njs_value_t *unused, njs_value_t *retval)
+njs_process_object_env(njs_vm_t *vm, njs_object_prop_t *pr, uint32_t unused,
+    njs_value_t *process, njs_value_t *unused2, njs_value_t *retval)
 {
-    njs_int_t           ret;
-    njs_object_t        *env;
-    njs_object_prop_t   *prop;
-    njs_lvlhsh_query_t  lhq;
-
-    static const njs_value_t  env_string = njs_string("env");
+    njs_int_t            ret;
+    njs_object_t         *env;
+    njs_object_prop_t    *prop;
+    njs_flathsh_query_t  lhq;
 
     env = njs_object_alloc(vm);
     if (njs_slow_path(env == NULL)) {
@@ -1369,7 +1342,7 @@ njs_process_object_env(njs_vm_t *vm, njs_object_prop_t *pr,
 
     env->shared_hash = vm->shared->env_hash;
 
-    prop = njs_object_prop_alloc(vm, &env_string, &njs_value_undefined, 1);
+    prop = njs_object_prop_alloc(vm, &njs_value_undefined, 1);
     if (njs_slow_path(prop == NULL)) {
         return NJS_ERROR;
     }
@@ -1380,11 +1353,9 @@ njs_process_object_env(njs_vm_t *vm, njs_object_prop_t *pr,
     lhq.pool = vm->mem_pool;
     lhq.proto = &njs_object_hash_proto;
     lhq.value = prop;
-    lhq.key = njs_str_value("env");
-    lhq.key_hash = NJS_ENV_HASH;
-
-    ret = njs_lvlhsh_insert(njs_object_hash(process), &lhq);
+    lhq.key_hash = NJS_ATOM_STRING_env;
 
+    ret = njs_flathsh_unique_insert(njs_object_hash(process), &lhq);
     if (njs_fast_path(ret == NJS_OK)) {
         njs_value_assign(retval, njs_prop_value(prop));
         return NJS_OK;
@@ -1397,8 +1368,8 @@ njs_process_object_env(njs_vm_t *vm, njs_object_prop_t *pr,
 
 
 static njs_int_t
-njs_process_object_pid(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *unused, njs_value_t *unused2, njs_value_t *retval)
+njs_process_object_pid(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
+    njs_value_t *unused2, njs_value_t *unused3, njs_value_t *retval)
 {
     njs_set_number(retval, getpid());
 
@@ -1407,8 +1378,8 @@ njs_process_object_pid(njs_vm_t *vm, njs_object_prop_t *prop,
 
 
 static njs_int_t
-njs_process_object_ppid(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *unused, njs_value_t *unused2, njs_value_t *retval)
+njs_process_object_ppid(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
+    njs_value_t *unused2, njs_value_t *unused3, njs_value_t *retval)
 {
     njs_set_number(retval, getppid());
 
@@ -1420,11 +1391,11 @@ static njs_int_t
 njs_ext_process_kill(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t magic, njs_value_t *retval)
 {
-    int                 signal;
-    njs_str_t           str;
-    njs_uint_t          pid;
-    njs_value_t         *arg;
-    njs_signal_entry_t  *s;
+    int                       signal;
+    njs_str_t                 str;
+    njs_uint_t                pid;
+    njs_value_t               *arg;
+    const njs_signal_entry_t  *s;
 
     arg = njs_arg(args, nargs, 1);
     if (!njs_value_is_number(arg)) {
@@ -1440,7 +1411,7 @@ njs_ext_process_kill(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         signal = njs_value_number(arg);
 
     } else if (njs_value_is_string(arg)) {
-        njs_value_string_get(arg, &str);
+        njs_string_get(vm, arg, &str);
 
         if (str.length < 3 || memcmp(str.start, "SIG", 3) != 0) {
             njs_vm_type_error(vm, "\"signal\" unknown value: \"%V\"", &str);
@@ -1477,24 +1448,20 @@ njs_ext_process_kill(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 }
 
 
-static const njs_object_prop_t  njs_process_object_properties[] =
+static const njs_object_prop_init_t  njs_process_object_properties[] =
 {
-    {
-        .type = NJS_PROPERTY,
-        .name = njs_wellknown_symbol(NJS_SYMBOL_TO_STRING_TAG),
-        .u.value = njs_string("process"),
-        .configurable = 1,
-    },
+    NJS_DECLARE_PROP_VALUE(SYMBOL_toStringTag, njs_ascii_strval("process"),
+                           NJS_OBJECT_PROP_VALUE_C),
 
-    NJS_DECLARE_PROP_HANDLER("argv", njs_process_object_argv, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_argv, njs_process_object_argv, 0, 0),
 
-    NJS_DECLARE_PROP_HANDLER("env", njs_process_object_env, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_env, njs_process_object_env, 0, 0),
 
-    NJS_DECLARE_PROP_HANDLER("pid", njs_process_object_pid, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_pid, njs_process_object_pid, 0, 0),
 
-    NJS_DECLARE_PROP_HANDLER("ppid", njs_process_object_ppid, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_ppid, njs_process_object_ppid, 0, 0),
 
-    NJS_DECLARE_PROP_NATIVE("kill", njs_ext_process_kill, 2, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_kill, njs_ext_process_kill, 2, 0),
 };
 
 
diff --git a/src/njs_date.c b/src/njs_date.c
index cd10abd5..2832abbd 100644
--- a/src/njs_date.c
+++ b/src/njs_date.c
@@ -52,7 +52,7 @@ typedef enum {
 } njs_date_fmt_t;
 
 
-static double njs_date_string_parse(njs_value_t *date);
+static double njs_date_string_parse(njs_vm_t *vm, njs_value_t *date);
 static double njs_date_rfc2822_string_parse(int64_t tm[], const u_char *p,
     const u_char *end);
 static double njs_date_js_string_parse(int64_t tm[], const u_char *p,
@@ -69,9 +69,6 @@ static njs_int_t njs_date_string(njs_vm_t *vm, njs_value_t *retval,
     njs_date_fmt_t fmt, double time);
 
 
-static const njs_value_t  njs_string_invalid_date = njs_string("Invalid Date");
-
-
 njs_inline int64_t
 njs_mod(int64_t a, int64_t b)
 {
@@ -425,7 +422,7 @@ njs_date_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             time = njs_date(&args[1])->time;
 
         } else if (njs_is_string(&args[1])) {
-            time = njs_date_string_parse(&args[1]);
+            time = njs_date_string_parse(vm, &args[1]);
 
         } else {
             time = njs_timeclip(njs_number(&args[1]));
@@ -502,7 +499,7 @@ njs_date_parse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             }
         }
 
-        time = njs_date_string_parse(&args[1]);
+        time = njs_date_string_parse(vm, &args[1]);
 
     } else {
         time = NAN;
@@ -548,7 +545,7 @@ njs_date_utc_offset_parse(const u_char *start, const u_char *end)
 }
 
 static double
-njs_date_string_parse(njs_value_t *date)
+njs_date_string_parse(njs_vm_t *vm, njs_value_t *date)
 {
     size_t         ms_length;
     int64_t        ext, utc_off;
@@ -557,7 +554,7 @@ njs_date_string_parse(njs_value_t *date)
     const u_char   *p, *next, *end;
     int64_t        tm[NJS_DATE_MAX_FIELDS];
 
-    njs_string_get(date, &string);
+    njs_string_get(vm, date, &string);
 
     p = string.start;
     end = p + string.length;
@@ -1127,19 +1124,20 @@ njs_date_number_parse(int64_t *value, const u_char *p, const u_char *end,
 }
 
 
-static const njs_object_prop_t  njs_date_constructor_properties[] =
+static const njs_object_prop_init_t  njs_date_constructor_properties[] =
 {
     NJS_DECLARE_PROP_LENGTH(7),
 
     NJS_DECLARE_PROP_NAME("Date"),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
+                             0, 0),
 
-    NJS_DECLARE_PROP_NATIVE("UTC", njs_date_utc, 7, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_UTC, njs_date_utc, 7, 0),
 
-    NJS_DECLARE_PROP_NATIVE("now", njs_date_now, 0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_now, njs_date_now, 0, 0),
 
-    NJS_DECLARE_PROP_NATIVE("parse", njs_date_parse, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_parse, njs_date_parse, 1, 0),
 };
 
 
@@ -1206,7 +1204,7 @@ njs_date_string(njs_vm_t *vm, njs_value_t *retval, njs_date_fmt_t fmt,
                                     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
 
     if (njs_slow_path(isnan(time))) {
-        *retval = njs_string_invalid_date;
+        njs_atom_to_value(vm, retval, NJS_ATOM_STRING_Invalid_Date);
         return NJS_OK;
     }
 
@@ -1443,14 +1441,13 @@ static njs_int_t
 njs_date_prototype_to_json(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused, njs_value_t *retval)
 {
-    njs_int_t           ret;
-    njs_value_t         value;
-    njs_lvlhsh_query_t  lhq;
-
-    static const njs_value_t  to_iso_string = njs_string("toISOString");
+    njs_int_t            ret;
+    njs_value_t          value;
+    njs_flathsh_query_t  lhq;
 
     if (njs_is_object(njs_argument(args, 0))) {
-        njs_object_property_init(&lhq, &to_iso_string, NJS_TO_ISO_STRING_HASH);
+        lhq.proto = &njs_object_hash_proto;
+        lhq.key_hash = NJS_ATOM_STRING_toISOString;
 
         ret = njs_object_property(vm, njs_object(njs_argument(args, 0)), &lhq,
                                   &value);
@@ -1471,171 +1468,179 @@ njs_date_prototype_to_json(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 }
 
 
-static const njs_object_prop_t  njs_date_prototype_properties[] =
+static const njs_object_prop_init_t  njs_date_prototype_properties[] =
 {
-    NJS_DECLARE_PROP_HANDLER("__proto__", njs_primitive_prototype_get_proto,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING___proto__,
+                             njs_primitive_prototype_get_proto, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("constructor",
-                             njs_object_prototype_create_constructor,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
+                             njs_object_prototype_create_constructor, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_NATIVE("valueOf", njs_date_prototype_value_of, 0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_valueOf, njs_date_prototype_value_of, 0,
+                            0),
 
-    NJS_DECLARE_PROP_NATIVE("toString", njs_date_prototype_to_string, 0,
-                            NJS_DATE_FMT_TO_STRING),
+    NJS_DECLARE_PROP_NATIVE(STRING_toString, njs_date_prototype_to_string,
+                            0, NJS_DATE_FMT_TO_STRING),
 
-    NJS_DECLARE_PROP_NATIVE("toDateString", njs_date_prototype_to_string, 0,
+    NJS_DECLARE_PROP_NATIVE(STRING_toDateString,
+                            njs_date_prototype_to_string, 0,
                             NJS_DATE_FMT_TO_DATE_STRING),
 
-    NJS_DECLARE_PROP_NATIVE("toTimeString", njs_date_prototype_to_string, 0,
+    NJS_DECLARE_PROP_NATIVE(STRING_toTimeString,
+                            njs_date_prototype_to_string, 0,
                             NJS_DATE_FMT_TO_TIME_STRING),
 
-    NJS_DECLARE_PROP_NATIVE("toLocaleString", njs_date_prototype_to_string, 0,
+    NJS_DECLARE_PROP_NATIVE(STRING_toLocaleString,
+                            njs_date_prototype_to_string, 0,
                             NJS_DATE_FMT_TO_STRING),
 
-    NJS_DECLARE_PROP_LNATIVE("toLocaleDateString",
-                             njs_date_prototype_to_string, 0,
-                             NJS_DATE_FMT_TO_DATE_STRING),
+    NJS_DECLARE_PROP_NATIVE(STRING_toLocaleDateString,
+                            njs_date_prototype_to_string, 0,
+                            NJS_DATE_FMT_TO_DATE_STRING),
 
-    NJS_DECLARE_PROP_LNATIVE("toLocaleTimeString",
-                             njs_date_prototype_to_string, 0,
-                             NJS_DATE_FMT_TO_TIME_STRING),
+    NJS_DECLARE_PROP_NATIVE(STRING_toLocaleTimeString,
+                            njs_date_prototype_to_string, 0,
+                            NJS_DATE_FMT_TO_TIME_STRING),
 
-    NJS_DECLARE_PROP_NATIVE("toUTCString",
+    NJS_DECLARE_PROP_NATIVE(STRING_toUTCString,
                             njs_date_prototype_to_string, 0,
                             NJS_DATE_FMT_TO_UTC_STRING),
 
-    NJS_DECLARE_PROP_NATIVE("toISOString",
+    NJS_DECLARE_PROP_NATIVE(STRING_toISOString,
                             njs_date_prototype_to_string, 0,
                             NJS_DATE_FMT_TO_ISO_STRING),
 
-    NJS_DECLARE_PROP_NATIVE("toJSON", njs_date_prototype_to_json, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_toJSON, njs_date_prototype_to_json, 1,
+                            0),
 
-    NJS_DECLARE_PROP_NATIVE("getTime", njs_date_prototype_value_of, 0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_getTime, njs_date_prototype_value_of, 0,
+                            0),
 
-    NJS_DECLARE_PROP_NATIVE("getFullYear",
+    NJS_DECLARE_PROP_NATIVE(STRING_getFullYear,
                             njs_date_prototype_get_field, 0,
                             njs_date_magic(NJS_DATE_YR, 1)),
 
-    NJS_DECLARE_PROP_NATIVE("getUTCFullYear",
+    NJS_DECLARE_PROP_NATIVE(STRING_getUTCFullYear,
                             njs_date_prototype_get_field, 0,
                             njs_date_magic(NJS_DATE_YR, 0)),
 
-    NJS_DECLARE_PROP_NATIVE("getMonth",
+    NJS_DECLARE_PROP_NATIVE(STRING_getMonth,
                             njs_date_prototype_get_field, 0,
                             njs_date_magic(NJS_DATE_MON, 1)),
 
-    NJS_DECLARE_PROP_NATIVE("getUTCMonth",
+    NJS_DECLARE_PROP_NATIVE(STRING_getUTCMonth,
                             njs_date_prototype_get_field, 0,
                             njs_date_magic(NJS_DATE_MON, 0)),
 
-    NJS_DECLARE_PROP_NATIVE("getDate",
+    NJS_DECLARE_PROP_NATIVE(STRING_getDate,
                             njs_date_prototype_get_field, 0,
                             njs_date_magic(NJS_DATE_DAY, 1)),
 
-    NJS_DECLARE_PROP_NATIVE("getUTCDate",
+    NJS_DECLARE_PROP_NATIVE(STRING_getUTCDate,
                             njs_date_prototype_get_field, 0,
                             njs_date_magic(NJS_DATE_DAY, 0)),
 
-    NJS_DECLARE_PROP_NATIVE("getDay",
+    NJS_DECLARE_PROP_NATIVE(STRING_getDay,
                             njs_date_prototype_get_field, 0,
                             njs_date_magic(NJS_DATE_WDAY, 1)),
 
-    NJS_DECLARE_PROP_NATIVE("getUTCDay",
+    NJS_DECLARE_PROP_NATIVE(STRING_getUTCDay,
                             njs_date_prototype_get_field, 0,
                             njs_date_magic(NJS_DATE_WDAY, 0)),
 
-    NJS_DECLARE_PROP_NATIVE("getHours",
+    NJS_DECLARE_PROP_NATIVE(STRING_getHours,
                             njs_date_prototype_get_field, 0,
                             njs_date_magic(NJS_DATE_HR, 1)),
 
-    NJS_DECLARE_PROP_NATIVE("getUTCHours",
+    NJS_DECLARE_PROP_NATIVE(STRING_getUTCHours,
                             njs_date_prototype_get_field, 0,
                             njs_date_magic(NJS_DATE_HR, 0)),
 
-    NJS_DECLARE_PROP_NATIVE("getMinutes",
+    NJS_DECLARE_PROP_NATIVE(STRING_getMinutes,
                             njs_date_prototype_get_field, 0,
                             njs_date_magic(NJS_DATE_MIN, 1)),
 
-    NJS_DECLARE_PROP_NATIVE("getUTCMinutes",
+    NJS_DECLARE_PROP_NATIVE(STRING_getUTCMinutes,
                             njs_date_prototype_get_field, 0,
                             njs_date_magic(NJS_DATE_MIN, 0)),
 
-    NJS_DECLARE_PROP_NATIVE("getSeconds",
+    NJS_DECLARE_PROP_NATIVE(STRING_getSeconds,
                             njs_date_prototype_get_field, 0,
                             njs_date_magic(NJS_DATE_SEC, 1)),
 
-    NJS_DECLARE_PROP_NATIVE("getUTCSeconds",
+    NJS_DECLARE_PROP_NATIVE(STRING_getUTCSeconds,
                             njs_date_prototype_get_field, 0,
                             njs_date_magic(NJS_DATE_SEC, 0)),
 
-    NJS_DECLARE_PROP_LNATIVE("getMilliseconds",
-                             njs_date_prototype_get_field, 0,
-                             njs_date_magic(NJS_DATE_MSEC, 1)),
+    NJS_DECLARE_PROP_NATIVE(STRING_getMilliseconds,
+                            njs_date_prototype_get_field, 0,
+                            njs_date_magic(NJS_DATE_MSEC, 1)),
 
-    NJS_DECLARE_PROP_LNATIVE("getUTCMilliseconds",
-                             njs_date_prototype_get_field, 0,
-                             njs_date_magic(NJS_DATE_MSEC, 0)),
+    NJS_DECLARE_PROP_NATIVE(STRING_getUTCMilliseconds,
+                            njs_date_prototype_get_field, 0,
+                            njs_date_magic(NJS_DATE_MSEC, 0)),
 
-    NJS_DECLARE_PROP_LNATIVE("getTimezoneOffset",
-                             njs_date_prototype_get_timezone_offset, 0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_getTimezoneOffset,
+                            njs_date_prototype_get_timezone_offset, 0, 0),
 
-    NJS_DECLARE_PROP_NATIVE("setTime", njs_date_prototype_set_time, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_setTime, njs_date_prototype_set_time, 1,
+                            0),
 
-    NJS_DECLARE_PROP_LNATIVE("setMilliseconds",
-                             njs_date_prototype_set_fields, 1,
-                             njs_date_magic2(NJS_DATE_MSEC, 1, 1)),
+    NJS_DECLARE_PROP_NATIVE(STRING_setMilliseconds,
+                            njs_date_prototype_set_fields, 1,
+                            njs_date_magic2(NJS_DATE_MSEC, 1, 1)),
 
-    NJS_DECLARE_PROP_LNATIVE("setUTCMilliseconds",
-                             njs_date_prototype_set_fields, 1,
-                             njs_date_magic2(NJS_DATE_MSEC, 1, 0)),
+    NJS_DECLARE_PROP_NATIVE(STRING_setUTCMilliseconds,
+                            njs_date_prototype_set_fields, 1,
+                            njs_date_magic2(NJS_DATE_MSEC, 1, 0)),
 
-    NJS_DECLARE_PROP_NATIVE("setSeconds",
+    NJS_DECLARE_PROP_NATIVE(STRING_setSeconds,
                             njs_date_prototype_set_fields, 2,
                             njs_date_magic2(NJS_DATE_SEC, 2, 1)),
 
-    NJS_DECLARE_PROP_NATIVE("setUTCSeconds",
+    NJS_DECLARE_PROP_NATIVE(STRING_setUTCSeconds,
                             njs_date_prototype_set_fields, 2,
                             njs_date_magic2(NJS_DATE_SEC, 2, 0)),
 
-    NJS_DECLARE_PROP_NATIVE("setMinutes",
+    NJS_DECLARE_PROP_NATIVE(STRING_setMinutes,
                             njs_date_prototype_set_fields, 3,
                             njs_date_magic2(NJS_DATE_MIN, 3, 1)),
 
-    NJS_DECLARE_PROP_NATIVE("setUTCMinutes",
+    NJS_DECLARE_PROP_NATIVE(STRING_setUTCMinutes,
                             njs_date_prototype_set_fields, 3,
                             njs_date_magic2(NJS_DATE_MIN, 3, 0)),
 
-    NJS_DECLARE_PROP_NATIVE("setHours",
+    NJS_DECLARE_PROP_NATIVE(STRING_setHours,
                             njs_date_prototype_set_fields, 4,
                             njs_date_magic2(NJS_DATE_HR, 4, 1)),
 
-    NJS_DECLARE_PROP_NATIVE("setUTCHours",
+    NJS_DECLARE_PROP_NATIVE(STRING_setUTCHours,
                             njs_date_prototype_set_fields, 4,
                             njs_date_magic2(NJS_DATE_HR, 4, 0)),
 
-    NJS_DECLARE_PROP_NATIVE("setDate",
+    NJS_DECLARE_PROP_NATIVE(STRING_setDate,
                             njs_date_prototype_set_fields, 1,
                             njs_date_magic2(NJS_DATE_DAY, 1, 1)),
 
-    NJS_DECLARE_PROP_NATIVE("setUTCDate",
+    NJS_DECLARE_PROP_NATIVE(STRING_setUTCDate,
                             njs_date_prototype_set_fields, 1,
                             njs_date_magic2(NJS_DATE_DAY, 1, 0)),
 
-    NJS_DECLARE_PROP_NATIVE("setMonth",
+    NJS_DECLARE_PROP_NATIVE(STRING_setMonth,
                             njs_date_prototype_set_fields, 2,
                             njs_date_magic2(NJS_DATE_MON, 2, 1)),
 
-    NJS_DECLARE_PROP_NATIVE("setUTCMonth",
+    NJS_DECLARE_PROP_NATIVE(STRING_setUTCMonth,
                             njs_date_prototype_set_fields, 2,
                             njs_date_magic2(NJS_DATE_MON, 2, 0)),
 
-    NJS_DECLARE_PROP_NATIVE("setFullYear",
+    NJS_DECLARE_PROP_NATIVE(STRING_setFullYear,
                             njs_date_prototype_set_fields, 3,
                             njs_date_magic2(NJS_DATE_YR, 3, 1)),
 
-    NJS_DECLARE_PROP_NATIVE("setUTCFullYear",
+    NJS_DECLARE_PROP_NATIVE(STRING_setUTCFullYear,
                             njs_date_prototype_set_fields, 3,
                             njs_date_magic2(NJS_DATE_YR, 3, 0)),
 };
diff --git a/src/njs_encoding.c b/src/njs_encoding.c
index f70c084d..37bdecf3 100644
--- a/src/njs_encoding.c
+++ b/src/njs_encoding.c
@@ -100,7 +100,7 @@ njs_text_encoder_encode(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             }
         }
 
-        (void) njs_string_prop(&prop, input);
+        (void) njs_string_prop(vm, &prop, input);
 
         if (prop.length != 0) {
             return njs_text_encoder_encode_utf8(vm, &prop, retval);
@@ -164,13 +164,11 @@ njs_text_encoder_encode_into(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_int_t             ret;
     njs_str_t             str;
     njs_value_t           *this, *input, *dest, value, read, written;
+    njs_object_t          *object;
     const u_char          *start, *end;
     njs_typed_array_t     *array;
     njs_unicode_decode_t  ctx;
 
-    static const njs_value_t  read_str = njs_string("read");
-    static const njs_value_t  written_str = njs_string("written");
-
     this = njs_argument(args, 0);
     input = njs_arg(args, nargs, 1);
     dest = njs_arg(args, nargs, 2);
@@ -195,7 +193,7 @@ njs_text_encoder_encode_into(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    njs_string_get(input, &str);
+    njs_string_get(vm, input, &str);
 
     start = str.start;
     end = start + str.length;
@@ -228,22 +226,41 @@ njs_text_encoder_encode_into(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         to = njs_utf8_encode(to, cp);
     }
 
-    return njs_vm_object_alloc(vm, retval, &read_str, &read,
-                               &written_str, &written, NULL);
+    object = njs_object_alloc(vm);
+    if (njs_slow_path(object == NULL)) {
+        return NJS_ERROR;
+    }
+
+    njs_set_object(retval, object);
+
+    ret = njs_object_prop_define(vm, retval, NJS_ATOM_STRING_read, &read,
+                                 NJS_OBJECT_PROP_VALUE_CW);
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
+    }
+
+    ret = njs_object_prop_define(vm, retval, NJS_ATOM_STRING_written, &written,
+                                 NJS_OBJECT_PROP_VALUE_CW);
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
+    }
+
+    return NJS_OK;
 }
 
 
-static const njs_object_prop_t  njs_text_encoder_properties[] =
+static const njs_object_prop_init_t  njs_text_encoder_properties[] =
 {
-    NJS_DECLARE_PROP_HANDLER("constructor",
-                             njs_object_prototype_create_constructor,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
+                             njs_object_prototype_create_constructor, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_VALUE("encoding", njs_string("utf-8"), 0),
+    NJS_DECLARE_PROP_VALUE(STRING_encoding, njs_ascii_strval("utf-8"), 0),
 
-    NJS_DECLARE_PROP_NATIVE("encode", njs_text_encoder_encode, 0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_encode, njs_text_encoder_encode, 0, 0),
 
-    NJS_DECLARE_PROP_NATIVE("encodeInto", njs_text_encoder_encode_into, 2, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_encodeInto, njs_text_encoder_encode_into,
+                            2, 0),
 };
 
 
@@ -253,13 +270,14 @@ const njs_object_init_t  njs_text_encoder_init = {
 };
 
 
-static const njs_object_prop_t  njs_text_encoder_constructor_properties[] =
+static const njs_object_prop_init_t  njs_text_encoder_constructor_properties[] =
 {
     NJS_DECLARE_PROP_LENGTH(0),
 
     NJS_DECLARE_PROP_NAME("TextEncoder"),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
+                             0, 0),
 };
 
 
@@ -341,7 +359,7 @@ njs_text_decoder_arg_encoding(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         }
     }
 
-    njs_string_get(value, &str);
+    njs_string_get(vm, value, &str);
 
     for (label = &njs_encoding_labels[0]; label->name.length != 0; label++) {
         if (njs_strstr_eq(&str, &label->name)) {
@@ -363,9 +381,6 @@ njs_text_decoder_arg_options(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_int_t    ret;
     njs_value_t  retval, *value;
 
-    static const njs_value_t  fatal_str = njs_string("fatal");
-    static const njs_value_t  ignore_bom_str = njs_string("ignoreBOM");
-
     if (nargs < 3) {
         data->fatal = 0;
         data->ignore_bom = 0;
@@ -380,15 +395,14 @@ njs_text_decoder_arg_options(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    ret = njs_value_property(vm, value, njs_value_arg(&fatal_str), &retval);
+    ret = njs_value_property(vm, value, NJS_ATOM_STRING_fatal, &retval);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return ret;
     }
 
     data->fatal = njs_bool(&retval);
 
-    ret = njs_value_property(vm, value, njs_value_arg(&ignore_bom_str),
-                             &retval);
+    ret = njs_value_property(vm, value, NJS_ATOM_STRING_ignoreBOM, &retval);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return ret;
     }
@@ -400,13 +414,11 @@ njs_text_decoder_arg_options(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 
 static njs_int_t
-njs_text_decoder_encoding(njs_vm_t *vm, njs_object_prop_t *prop,
+njs_text_decoder_encoding(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     njs_encoding_decode_t  *data;
 
-    static const njs_value_t  utf8_str = njs_string("utf-8");
-
     if (njs_slow_path(!njs_is_object_data(value, NJS_DATA_TAG_TEXT_DECODER))) {
         njs_set_undefined(retval);
         return NJS_DECLINED;
@@ -416,7 +428,7 @@ njs_text_decoder_encoding(njs_vm_t *vm, njs_object_prop_t *prop,
 
     switch (data->encoding) {
     case NJS_ENCODING_UTF8:
-        *retval = utf8_str;
+        njs_atom_to_value(vm, retval, NJS_ATOM_STRING_utf_8);
         break;
 
     default:
@@ -429,7 +441,7 @@ njs_text_decoder_encoding(njs_vm_t *vm, njs_object_prop_t *prop,
 
 
 static njs_int_t
-njs_text_decoder_fatal(njs_vm_t *vm, njs_object_prop_t *prop,
+njs_text_decoder_fatal(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     njs_encoding_decode_t  *data;
@@ -449,7 +461,8 @@ njs_text_decoder_fatal(njs_vm_t *vm, njs_object_prop_t *prop,
 
 static njs_int_t
 njs_text_decoder_ignore_bom(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     njs_encoding_decode_t  *data;
 
@@ -482,8 +495,6 @@ njs_text_decoder_decode(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     const njs_typed_array_t   *array;
     const njs_array_buffer_t  *buffer;
 
-    static const njs_value_t  stream_str = njs_string("stream");
-
     start = NULL;
     end = NULL;
 
@@ -527,8 +538,7 @@ njs_text_decoder_decode(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             return NJS_ERROR;
         }
 
-        ret = njs_value_property(vm, options, njs_value_arg(&stream_str),
-                                 retval);
+        ret = njs_value_property(vm, options, NJS_ATOM_STRING_stream, retval);
         if (njs_slow_path(ret == NJS_ERROR)) {
             return ret;
         }
@@ -568,19 +578,21 @@ njs_text_decoder_decode(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 }
 
 
-static const njs_object_prop_t  njs_text_decoder_properties[] =
+static const njs_object_prop_init_t  njs_text_decoder_properties[] =
 {
-    NJS_DECLARE_PROP_HANDLER("constructor",
-                             njs_object_prototype_create_constructor,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
+                             njs_object_prototype_create_constructor, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("encoding", njs_text_decoder_encoding, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_encoding, njs_text_decoder_encoding, 0,
+                             0),
 
-    NJS_DECLARE_PROP_HANDLER("fatal", njs_text_decoder_fatal, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_fatal, njs_text_decoder_fatal, 0, 0),
 
-    NJS_DECLARE_PROP_HANDLER("ignoreBOM", njs_text_decoder_ignore_bom, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_ignoreBOM, njs_text_decoder_ignore_bom,
+                             0, 0),
 
-    NJS_DECLARE_PROP_NATIVE("decode", njs_text_decoder_decode, 0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_decode, njs_text_decoder_decode, 0, 0),
 };
 
 
@@ -590,13 +602,14 @@ const njs_object_init_t  njs_text_decoder_init = {
 };
 
 
-static const njs_object_prop_t  njs_text_decoder_constructor_properties[] =
+static const njs_object_prop_init_t  njs_text_decoder_constructor_properties[] =
 {
     NJS_DECLARE_PROP_LENGTH(0),
 
     NJS_DECLARE_PROP_NAME("TextDecoder"),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
+                             0, 0),
 };
 
 
diff --git a/src/njs_error.c b/src/njs_error.c
index b9da6597..6e12aa61 100644
--- a/src/njs_error.c
+++ b/src/njs_error.c
@@ -30,12 +30,6 @@ static njs_int_t njs_backtrace_to_string(njs_vm_t *vm, njs_arr_t *backtrace,
     njs_str_t *dst);
 
 
-static const njs_value_t  njs_error_message_string = njs_string("message");
-static const njs_value_t  njs_error_name_string = njs_string("name");
-static const njs_value_t  njs_error_stack_string = njs_string("stack");
-static const njs_value_t  njs_error_errors_string = njs_string("errors");
-
-
 void
 njs_error_new(njs_vm_t *vm, njs_value_t *dst, njs_object_t *proto,
     u_char *start, size_t size)
@@ -171,8 +165,7 @@ njs_error_stack(njs_vm_t *vm, njs_value_t *value, njs_value_t *stack)
 {
     njs_int_t  ret;
 
-    ret = njs_value_property(vm, value, njs_value_arg(&njs_error_stack_string),
-                             stack);
+    ret = njs_value_property(vm, value, NJS_ATOM_STRING_stack, stack);
     if (njs_slow_path(ret != NJS_OK)) {
         return ret;
     }
@@ -189,11 +182,11 @@ njs_object_t *
 njs_error_alloc(njs_vm_t *vm, njs_object_t *proto, const njs_value_t *name,
     const njs_value_t *message, const njs_value_t *errors)
 {
-    njs_int_t           ret;
-    njs_object_t        *error;
-    njs_object_prop_t   *prop;
-    njs_object_value_t  *ov;
-    njs_lvlhsh_query_t  lhq;
+    njs_int_t            ret;
+    njs_object_t         *error;
+    njs_object_prop_t    *prop;
+    njs_object_value_t   *ov;
+    njs_flathsh_query_t  lhq;
 
     ov = njs_mp_alloc(vm->mem_pool, sizeof(njs_object_value_t));
     if (njs_slow_path(ov == NULL)) {
@@ -219,17 +212,15 @@ njs_error_alloc(njs_vm_t *vm, njs_object_t *proto, const njs_value_t *name,
     lhq.proto = &njs_object_hash_proto;
 
     if (name != NULL) {
-        lhq.key = njs_str_value("name");
-        lhq.key_hash = NJS_NAME_HASH;
-
-        prop = njs_object_prop_alloc(vm, &njs_error_name_string, name, 1);
+        prop = njs_object_prop_alloc(vm, name, 1);
         if (njs_slow_path(prop == NULL)) {
             goto memory_error;
         }
 
         lhq.value = prop;
+        lhq.key_hash = NJS_ATOM_STRING_name;
 
-        ret = njs_lvlhsh_insert(&error->hash, &lhq);
+        ret = njs_flathsh_unique_insert(&error->hash, &lhq);
         if (njs_slow_path(ret != NJS_OK)) {
             njs_internal_error(vm, "lvlhsh insert failed");
             return NULL;
@@ -237,10 +228,7 @@ njs_error_alloc(njs_vm_t *vm, njs_object_t *proto, const njs_value_t *name,
     }
 
     if (message!= NULL) {
-        lhq.key = njs_str_value("message");
-        lhq.key_hash = NJS_MESSAGE_HASH;
-
-        prop = njs_object_prop_alloc(vm, &njs_error_message_string, message, 1);
+        prop = njs_object_prop_alloc(vm, message, 1);
         if (njs_slow_path(prop == NULL)) {
             goto memory_error;
         }
@@ -248,8 +236,9 @@ njs_error_alloc(njs_vm_t *vm, njs_object_t *proto, const njs_value_t *name,
         prop->enumerable = 0;
 
         lhq.value = prop;
+        lhq.key_hash = NJS_ATOM_STRING_message;
 
-        ret = njs_lvlhsh_insert(&error->hash, &lhq);
+        ret = njs_flathsh_unique_insert(&error->hash, &lhq);
         if (njs_slow_path(ret != NJS_OK)) {
             njs_internal_error(vm, "lvlhsh insert failed");
             return NULL;
@@ -257,10 +246,7 @@ njs_error_alloc(njs_vm_t *vm, njs_object_t *proto, const njs_value_t *name,
     }
 
     if (errors != NULL) {
-        lhq.key = njs_str_value("errors");
-        lhq.key_hash = NJS_ERRORS_HASH;
-
-        prop = njs_object_prop_alloc(vm, &njs_error_errors_string, errors, 1);
+        prop = njs_object_prop_alloc(vm, errors, 1);
         if (njs_slow_path(prop == NULL)) {
             goto memory_error;
         }
@@ -268,8 +254,9 @@ njs_error_alloc(njs_vm_t *vm, njs_object_t *proto, const njs_value_t *name,
         prop->enumerable = 0;
 
         lhq.value = prop;
+        lhq.key_hash = NJS_ATOM_STRING_errors;
 
-        ret = njs_lvlhsh_insert(&error->hash, &lhq);
+        ret = njs_flathsh_unique_insert(&error->hash, &lhq);
         if (njs_slow_path(ret != NJS_OK)) {
             njs_internal_error(vm, "lvlhsh insert failed");
             return NULL;
@@ -340,13 +327,14 @@ njs_error_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 }
 
 
-static const njs_object_prop_t  njs_error_constructor_properties[] =
+static const njs_object_prop_init_t  njs_error_constructor_properties[] =
 {
     NJS_DECLARE_PROP_LENGTH(1),
 
     NJS_DECLARE_PROP_NAME("Error"),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
+                             0, 0),
 };
 
 
@@ -356,13 +344,14 @@ const njs_object_init_t  njs_error_constructor_init = {
 };
 
 
-static const njs_object_prop_t  njs_eval_error_constructor_properties[] =
+static const njs_object_prop_init_t  njs_eval_error_constructor_properties[] =
 {
     NJS_DECLARE_PROP_LENGTH(1),
 
     NJS_DECLARE_PROP_NAME("EvalError"),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
+                             0, 0),
 };
 
 
@@ -372,13 +361,14 @@ const njs_object_init_t  njs_eval_error_constructor_init = {
 };
 
 
-static const njs_object_prop_t  njs_internal_error_constructor_properties[] =
+static const njs_object_prop_init_t  njs_internal_error_constructor_properties[] =
 {
     NJS_DECLARE_PROP_LENGTH(1),
 
     NJS_DECLARE_PROP_NAME("InternalError"),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
+                             0, 0),
 };
 
 
@@ -388,13 +378,14 @@ const njs_object_init_t  njs_internal_error_constructor_init = {
 };
 
 
-static const njs_object_prop_t  njs_range_error_constructor_properties[] =
+static const njs_object_prop_init_t  njs_range_error_constructor_properties[] =
 {
     NJS_DECLARE_PROP_LENGTH(1),
 
     NJS_DECLARE_PROP_NAME("RangeError"),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
+                             0, 0),
 };
 
 
@@ -404,13 +395,14 @@ const njs_object_init_t  njs_range_error_constructor_init = {
 };
 
 
-static const njs_object_prop_t  njs_reference_error_constructor_properties[] =
+static const njs_object_prop_init_t  njs_reference_error_constructor_properties[] =
 {
     NJS_DECLARE_PROP_LENGTH(1),
 
     NJS_DECLARE_PROP_NAME("ReferenceError"),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
+                             0, 0),
 };
 
 
@@ -420,13 +412,14 @@ const njs_object_init_t  njs_reference_error_constructor_init = {
 };
 
 
-static const njs_object_prop_t  njs_syntax_error_constructor_properties[] =
+static const njs_object_prop_init_t  njs_syntax_error_constructor_properties[] =
 {
     NJS_DECLARE_PROP_LENGTH(1),
 
     NJS_DECLARE_PROP_NAME("SyntaxError"),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
+                             0, 0),
 };
 
 
@@ -436,13 +429,14 @@ const njs_object_init_t  njs_syntax_error_constructor_init = {
 };
 
 
-static const njs_object_prop_t  njs_type_error_constructor_properties[] =
+static const njs_object_prop_init_t  njs_type_error_constructor_properties[] =
 {
     NJS_DECLARE_PROP_LENGTH(1),
 
     NJS_DECLARE_PROP_NAME("TypeError"),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
+                             0, 0),
 };
 
 
@@ -452,13 +446,14 @@ const njs_object_init_t  njs_type_error_constructor_init = {
 };
 
 
-static const njs_object_prop_t  njs_uri_error_constructor_properties[] =
+static const njs_object_prop_init_t  njs_uri_error_constructor_properties[] =
 {
     NJS_DECLARE_PROP_LENGTH(1),
 
     NJS_DECLARE_PROP_NAME("URIError"),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
+                             0, 0),
 };
 
 
@@ -468,13 +463,14 @@ const njs_object_init_t  njs_uri_error_constructor_init = {
 };
 
 
-static const njs_object_prop_t  njs_aggregate_error_constructor_properties[] =
+static const njs_object_prop_init_t  njs_aggregate_error_constructor_properties[] =
 {
     NJS_DECLARE_PROP_LENGTH(1),
 
     NJS_DECLARE_PROP_NAME("AggregateError"),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
+                             0, 0),
 };
 
 
@@ -532,7 +528,8 @@ njs_memory_error_constructor(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_memory_error_prototype_create(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     int32_t            index;
     njs_function_t     *function;
@@ -555,14 +552,14 @@ njs_memory_error_prototype_create(njs_vm_t *vm, njs_object_prop_t *prop,
 }
 
 
-static const njs_object_prop_t  njs_memory_error_constructor_properties[] =
+static const njs_object_prop_init_t  njs_memory_error_constructor_properties[] =
 {
     NJS_DECLARE_PROP_LENGTH(1),
 
     NJS_DECLARE_PROP_NAME("MemoryError"),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_memory_error_prototype_create,
-                             0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype,
+                             njs_memory_error_prototype_create, 0, 0),
 };
 
 
@@ -593,9 +590,6 @@ njs_error_to_string2(njs_vm_t *vm, njs_value_t *retval,
     njs_value_t        *name_value, *message_value;
     njs_string_prop_t  name, message;
 
-    static const njs_value_t  string_message = njs_string("message");
-    static const njs_value_t  default_name = njs_string("Error");
-
     njs_assert(njs_is_object(error));
 
     if (want_stack) {
@@ -609,34 +603,38 @@ njs_error_to_string2(njs_vm_t *vm, njs_value_t *retval,
         }
     }
 
-    ret = njs_value_property(vm, (njs_value_t *) error,
-                             njs_value_arg(&njs_string_name),
+    ret = njs_value_property(vm, (njs_value_t *) error, NJS_ATOM_STRING_name,
                              &value1);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return ret;
     }
 
-    name_value = (ret == NJS_OK) ? &value1 : njs_value_arg(&default_name);
+    if (ret == NJS_DECLINED) {
+        njs_atom_to_value(vm, &value1, NJS_ATOM_STRING_Error);
+    }
+
+    name_value = &value1;
 
     if (njs_slow_path(!njs_is_string(name_value))) {
         ret = njs_value_to_string(vm, &value1, name_value);
         if (njs_slow_path(ret != NJS_OK)) {
             return ret;
         }
-
-        name_value = &value1;
     }
 
-    (void) njs_string_prop(&name, name_value);
+    (void) njs_string_prop(vm, &name, name_value);
 
-    ret = njs_value_property(vm,  (njs_value_t *) error,
-                             njs_value_arg(&string_message), &value2);
+    ret = njs_value_property(vm,  (njs_value_t *) error, NJS_ATOM_STRING_message,
+                             &value2);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return ret;
     }
 
-    message_value = (ret == NJS_OK) ? &value2
-                                    : njs_value_arg(&njs_string_empty);
+    if (ret == NJS_DECLINED) {
+        njs_set_empty_string(vm, &value2);
+    }
+
+    message_value = &value2;
 
     if (njs_slow_path(!njs_is_string(message_value))) {
         ret = njs_value_to_string(vm, &value2, message_value);
@@ -647,7 +645,7 @@ njs_error_to_string2(njs_vm_t *vm, njs_value_t *retval,
         message_value = &value2;
     }
 
-    (void) njs_string_prop(&message, message_value);
+    (void) njs_string_prop(vm, &message, message_value);
 
     if (name.size == 0) {
         *retval = *message_value;
@@ -697,7 +695,7 @@ njs_error_prototype_to_string(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 
 static njs_int_t
-njs_error_prototype_stack(njs_vm_t *vm, njs_object_prop_t *prop,
+njs_error_prototype_stack(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     njs_int_t          ret;
@@ -750,7 +748,7 @@ njs_error_prototype_stack(njs_vm_t *vm, njs_object_prop_t *prop,
             return ret;
         }
 
-        njs_string_get(&rv, &string);
+        njs_string_get(vm, &rv, &string);
 
         ret = njs_backtrace_to_string(vm, backtrace, &string);
 
@@ -794,23 +792,26 @@ njs_error_to_string(njs_vm_t *vm, njs_value_t *retval, const njs_value_t *error)
 }
 
 
-static const njs_object_prop_t  njs_error_prototype_properties[] =
+static const njs_object_prop_init_t  njs_error_prototype_properties[] =
 {
-    NJS_DECLARE_PROP_HANDLER("constructor",
-                             njs_object_prototype_create_constructor,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
+                             njs_object_prototype_create_constructor, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_VALUE("name", njs_string("Error"),
+    NJS_DECLARE_PROP_VALUE(STRING_name, njs_ascii_strval("Error"),
                            NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_VALUE("message", njs_string(""), NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_VALUE(STRING_message, njs_ascii_strval(""),
+                           NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_NATIVE("valueOf", njs_error_prototype_value_of, 0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_valueOf, njs_error_prototype_value_of,
+                            0, 0),
 
-    NJS_DECLARE_PROP_NATIVE("toString", njs_error_prototype_to_string, 0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_toString, njs_error_prototype_to_string,
+                            0, 0),
 
-    NJS_DECLARE_PROP_HANDLER("stack", njs_error_prototype_stack,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_stack, njs_error_prototype_stack,
+                             0, NJS_OBJECT_PROP_VALUE_CW),
 };
 
 
@@ -829,16 +830,17 @@ const njs_object_type_init_t  njs_error_type_init = {
 };
 
 
-static const njs_object_prop_t  njs_eval_error_prototype_properties[] =
+static const njs_object_prop_init_t  njs_eval_error_prototype_properties[] =
 {
-    NJS_DECLARE_PROP_HANDLER("constructor",
-                             njs_object_prototype_create_constructor,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
+                             njs_object_prototype_create_constructor, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_VALUE("name", njs_string("EvalError"),
+    NJS_DECLARE_PROP_VALUE(STRING_name, njs_ascii_strval("EvalError"),
                            NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_VALUE("message", njs_string(""), NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_VALUE(STRING_message, njs_ascii_strval(""),
+                           NJS_OBJECT_PROP_VALUE_CW),
 };
 
 
@@ -861,12 +863,10 @@ static njs_int_t
 njs_internal_error_prototype_to_string(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused, njs_value_t *retval)
 {
-    static const njs_value_t name = njs_string("MemoryError");
-
     if (nargs >= 1 && njs_is_object(&args[0])) {
         /* MemoryError is a nonextensible internal error. */
         if (!njs_object(&args[0])->extensible) {
-            njs_value_assign(retval, &name);
+            njs_atom_to_value(vm, retval, NJS_ATOM_STRING_MemoryError);
             return NJS_OK;
         }
     }
@@ -875,15 +875,16 @@ njs_internal_error_prototype_to_string(njs_vm_t *vm, njs_value_t *args,
 }
 
 
-static const njs_object_prop_t  njs_internal_error_prototype_properties[] =
+static const njs_object_prop_init_t  njs_internal_error_prototype_properties[] =
 {
-    NJS_DECLARE_PROP_VALUE("name", njs_string("InternalError"),
+    NJS_DECLARE_PROP_VALUE(STRING_name, njs_ascii_strval("InternalError"),
                            NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_VALUE("message", njs_string(""), NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_VALUE(STRING_message, njs_ascii_strval(""),
+                           NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_NATIVE("toString", njs_internal_error_prototype_to_string,
-                            0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_toString,
+                            njs_internal_error_prototype_to_string, 0, 0),
 };
 
 
@@ -910,16 +911,17 @@ const njs_object_type_init_t  njs_memory_error_type_init = {
 };
 
 
-static const njs_object_prop_t  njs_range_error_prototype_properties[] =
+static const njs_object_prop_init_t  njs_range_error_prototype_properties[] =
 {
-    NJS_DECLARE_PROP_HANDLER("constructor",
-                             njs_object_prototype_create_constructor,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
+                             njs_object_prototype_create_constructor, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_VALUE("name", njs_string("RangeError"),
+    NJS_DECLARE_PROP_VALUE(STRING_name, njs_ascii_strval("RangeError"),
                            NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_VALUE("message", njs_string(""), NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_VALUE(STRING_message, njs_ascii_strval(""),
+                           NJS_OBJECT_PROP_VALUE_CW),
 };
 
 
@@ -938,16 +940,17 @@ const njs_object_type_init_t  njs_range_error_type_init = {
 };
 
 
-static const njs_object_prop_t  njs_reference_error_prototype_properties[] =
+static const njs_object_prop_init_t  njs_reference_error_prototype_properties[] =
 {
-    NJS_DECLARE_PROP_HANDLER("constructor",
-                             njs_object_prototype_create_constructor,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
+                             njs_object_prototype_create_constructor, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_VALUE("name", njs_string("ReferenceError"),
+    NJS_DECLARE_PROP_VALUE(STRING_name, njs_ascii_strval("ReferenceError"),
                            NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_VALUE("message", njs_string(""), NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_VALUE(STRING_message, njs_ascii_strval(""),
+                           NJS_OBJECT_PROP_VALUE_CW),
 };
 
 
@@ -966,16 +969,17 @@ const njs_object_type_init_t  njs_reference_error_type_init = {
 };
 
 
-static const njs_object_prop_t  njs_syntax_error_prototype_properties[] =
+static const njs_object_prop_init_t  njs_syntax_error_prototype_properties[] =
 {
-    NJS_DECLARE_PROP_HANDLER("constructor",
-                             njs_object_prototype_create_constructor,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
+                             njs_object_prototype_create_constructor, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_VALUE("name", njs_string("SyntaxError"),
+    NJS_DECLARE_PROP_VALUE(STRING_name, njs_ascii_strval("SyntaxError"),
                            NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_VALUE("message", njs_string(""), NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_VALUE(STRING_message, njs_ascii_strval(""),
+                           NJS_OBJECT_PROP_VALUE_CW),
 };
 
 
@@ -994,16 +998,17 @@ const njs_object_type_init_t  njs_syntax_error_type_init = {
 };
 
 
-static const njs_object_prop_t  njs_type_error_prototype_properties[] =
+static const njs_object_prop_init_t  njs_type_error_prototype_properties[] =
 {
-    NJS_DECLARE_PROP_HANDLER("constructor",
-                             njs_object_prototype_create_constructor,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
+                             njs_object_prototype_create_constructor, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_VALUE("name", njs_string("TypeError"),
+    NJS_DECLARE_PROP_VALUE(STRING_name, njs_ascii_strval("TypeError"),
                            NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_VALUE("message", njs_string(""), NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_VALUE(STRING_message, njs_ascii_strval(""),
+                           NJS_OBJECT_PROP_VALUE_CW),
 };
 
 
@@ -1022,16 +1027,17 @@ const njs_object_type_init_t  njs_type_error_type_init = {
 };
 
 
-static const njs_object_prop_t  njs_uri_error_prototype_properties[] =
+static const njs_object_prop_init_t  njs_uri_error_prototype_properties[] =
 {
-    NJS_DECLARE_PROP_HANDLER("constructor",
-                             njs_object_prototype_create_constructor,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
+                             njs_object_prototype_create_constructor, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_VALUE("name", njs_string("URIError"),
+    NJS_DECLARE_PROP_VALUE(STRING_name, njs_ascii_strval("URIError"),
                            NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_VALUE("message", njs_string(""), NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_VALUE(STRING_message, njs_ascii_strval(""),
+                           NJS_OBJECT_PROP_VALUE_CW),
 };
 
 
@@ -1050,16 +1056,17 @@ const njs_object_type_init_t  njs_uri_error_type_init = {
 };
 
 
-static const njs_object_prop_t  njs_aggregate_error_prototype_properties[] =
+static const njs_object_prop_init_t  njs_aggregate_error_prototype_properties[] =
 {
-    NJS_DECLARE_PROP_HANDLER("constructor",
-                             njs_object_prototype_create_constructor,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
+                             njs_object_prototype_create_constructor, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_VALUE("name", njs_string("AggregateError"),
+    NJS_DECLARE_PROP_VALUE(STRING_name, njs_ascii_strval("AggregateError"),
                            NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_VALUE("message", njs_string(""), NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_VALUE(STRING_message, njs_ascii_strval(""),
+                           NJS_OBJECT_PROP_VALUE_CW),
 };
 
 
diff --git a/src/njs_extern.c b/src/njs_extern.c
index 621cb76d..077d2a5f 100644
--- a/src/njs_extern.c
+++ b/src/njs_extern.c
@@ -9,8 +9,8 @@
 
 
 static njs_int_t njs_external_prop_handler(njs_vm_t *vm,
-    njs_object_prop_t *self, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *self, uint32_t atom_id, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 
 
 static njs_int_t
@@ -19,12 +19,13 @@ njs_external_add(njs_vm_t *vm, njs_arr_t *protos,
 {
     size_t                size;
     njs_int_t             ret;
-    njs_lvlhsh_t          *hash;
+    njs_value_t           prop_name;
     const u_char          *start;
+    njs_flathsh_t         *hash;
     njs_function_t        *function;
     njs_object_prop_t     *prop;
-    njs_lvlhsh_query_t    lhq;
     njs_exotic_slots_t    *slot, *next;
+    njs_flathsh_query_t   lhq;
     const njs_external_t  *end;
 
     slot = njs_arr_add(protos);
@@ -57,8 +58,7 @@ njs_external_add(njs_vm_t *vm, njs_arr_t *protos,
             continue;
         }
 
-        prop = njs_object_prop_alloc(vm, &njs_string_empty,
-                                     &njs_value_invalid, 1);
+        prop = njs_object_prop_alloc(vm, &njs_value_invalid, 1);
         if (njs_slow_path(prop == NULL)) {
             goto memory_error;
         }
@@ -68,20 +68,17 @@ njs_external_add(njs_vm_t *vm, njs_arr_t *protos,
         prop->enumerable = external->enumerable;
 
         if (external->flags & NJS_EXTERN_SYMBOL) {
-            njs_set_symbol(&prop->name, external->name.symbol, NULL);
-
             lhq.key_hash = external->name.symbol;
 
         } else {
-            ret = njs_string_create(vm, &prop->name,
-                                    external->name.string.start,
-                                    external->name.string.length);
+            ret = njs_atom_string_create(vm, &prop_name,
+                                         external->name.string.start,
+                                         external->name.string.length);
             if (njs_slow_path(ret != NJS_OK)) {
                 return NJS_ERROR;
             }
 
-            lhq.key = external->name.string;
-            lhq.key_hash = njs_djb_hash(lhq.key.start, lhq.key.length);
+            lhq.key_hash = prop_name.atom_id;
         }
 
         lhq.value = prop;
@@ -170,7 +167,7 @@ njs_external_add(njs_vm_t *vm, njs_arr_t *protos,
             break;
         }
 
-        ret = njs_lvlhsh_insert(hash, &lhq);
+        ret = njs_flathsh_unique_insert(hash, &lhq);
         if (njs_slow_path(ret != NJS_OK)) {
             njs_internal_error(vm, "lvlhsh insert failed");
             return NJS_ERROR;
@@ -191,14 +188,15 @@ memory_error:
 
 static njs_int_t
 njs_external_prop_handler(njs_vm_t *vm, njs_object_prop_t *self,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t atom_id, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
-    njs_int_t           ret;
-    njs_object_prop_t   *prop;
-    njs_external_ptr_t  external;
-    njs_object_value_t  *ov;
-    njs_lvlhsh_query_t  lhq;
-    njs_exotic_slots_t  *slots;
+    njs_int_t            ret;
+    njs_object_prop_t    *prop;
+    njs_external_ptr_t   external;
+    njs_object_value_t   *ov;
+    njs_exotic_slots_t   *slots;
+    njs_flathsh_query_t  lhq;
 
     if (njs_slow_path(retval == NULL)) {
         return NJS_DECLINED;
@@ -226,7 +224,7 @@ njs_external_prop_handler(njs_vm_t *vm, njs_object_prop_t *self,
         njs_set_object_value(retval, ov);
     }
 
-    prop = njs_object_prop_alloc(vm, &self->name, retval, 1);
+    prop = njs_object_prop_alloc(vm, retval, 1);
     if (njs_slow_path(prop == NULL)) {
         return NJS_ERROR;
     }
@@ -236,13 +234,12 @@ njs_external_prop_handler(njs_vm_t *vm, njs_object_prop_t *self,
     prop->enumerable = self->enumerable;
 
     lhq.value = prop;
-    njs_string_get(&self->name, &lhq.key);
-    lhq.key_hash = njs_prop_magic32(self);
+    lhq.key_hash = atom_id;
     lhq.replace = 1;
     lhq.pool = vm->mem_pool;
     lhq.proto = &njs_object_hash_proto;
 
-    ret = njs_lvlhsh_insert(njs_object_hash(value), &lhq);
+    ret = njs_flathsh_unique_insert(njs_object_hash(value), &lhq);
     if (njs_slow_path(ret != NJS_OK)) {
         njs_internal_error(vm, "lvlhsh insert/replace failed");
         return NJS_ERROR;
@@ -315,7 +312,8 @@ njs_vm_external_prototype(njs_vm_t *vm, const njs_external_t *definition,
 
 static njs_int_t
 njs_vm_external_constructor_handler(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t atom_id, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     njs_set_function(retval, &njs_vm_ctor(vm, njs_prop_magic32(prop)));
 
@@ -325,7 +323,7 @@ njs_vm_external_constructor_handler(njs_vm_t *vm, njs_object_prop_t *prop,
 
 njs_int_t
 njs_vm_external_constructor(njs_vm_t *vm, const njs_str_t *name,
-    njs_function_native_t native, const njs_external_t *ctor_props,
+    const njs_function_native_t native, const njs_external_t *ctor_props,
     njs_uint_t ctor_nprops, const njs_external_t *proto_props,
     njs_uint_t proto_nprops)
 {
@@ -445,8 +443,8 @@ njs_value_external_tag(const njs_value_t *value)
 
 
 njs_int_t
-njs_external_property(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value,
-    njs_value_t *setval, njs_value_t *retval)
+njs_external_property(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
+    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     char        *p;
     njs_int_t   i;
diff --git a/src/njs_flathsh.c b/src/njs_flathsh.c
index c823c466..f2387c95 100644
--- a/src/njs_flathsh.c
+++ b/src/njs_flathsh.c
@@ -144,13 +144,6 @@ njs_flathsh_chunk(njs_flathsh_descr_t *h)
 }
 
 
-njs_inline njs_flathsh_elt_t *
-njs_hash_elts(njs_flathsh_descr_t *h)
-{
-    return (njs_flathsh_elt_t *) ((char *) h + sizeof(njs_flathsh_descr_t));
-}
-
-
 /*
  * Create a new empty flat hash.
  */
@@ -343,8 +336,6 @@ njs_flathsh_find(const njs_flathsh_t *fh, njs_flathsh_query_t *fhq)
     while (elt_num != 0) {
         e = &elts[elt_num - 1];
 
-        /* TODO: need to be replaced by atomic test. */
-
         if (e->key_hash == fhq->key_hash &&
             fhq->proto->test(fhq, e->value) == NJS_OK)
         {
@@ -359,6 +350,37 @@ njs_flathsh_find(const njs_flathsh_t *fh, njs_flathsh_query_t *fhq)
 }
 
 
+njs_int_t
+njs_flathsh_unique_find(const njs_flathsh_t *fh, njs_flathsh_query_t *fhq)
+{
+    njs_int_t            cell_num, elt_num;
+    njs_flathsh_elt_t    *e, *elts;
+    njs_flathsh_descr_t  *h;
+
+    h = fh->slot;
+    if (njs_slow_path(h == NULL)) {
+        return NJS_DECLINED;
+    }
+
+    cell_num = fhq->key_hash & h->hash_mask;
+    elt_num = njs_hash_cells_end(h)[-cell_num - 1];
+    elts = njs_hash_elts(h);
+
+    while (elt_num != 0) {
+        e = &elts[elt_num - 1];
+
+        if (e->key_hash == fhq->key_hash) {
+            fhq->value = e->value;
+            return NJS_OK;
+        }
+
+        elt_num = e->next_elt;
+    }
+
+    return NJS_DECLINED;
+}
+
+
 njs_int_t
 njs_flathsh_insert(njs_flathsh_t *fh, njs_flathsh_query_t *fhq)
 {
@@ -385,8 +407,6 @@ njs_flathsh_insert(njs_flathsh_t *fh, njs_flathsh_query_t *fhq)
     while (elt_num != 0) {
         elt = &elts[elt_num - 1];
 
-        /* TODO: need to be replaced by atomic test. */
-
         if (elt->key_hash == fhq->key_hash &&
             fhq->proto->test(fhq, elt->value) == NJS_OK)
         {
@@ -418,6 +438,61 @@ njs_flathsh_insert(njs_flathsh_t *fh, njs_flathsh_query_t *fhq)
 }
 
 
+njs_int_t
+njs_flathsh_unique_insert(njs_flathsh_t *fh, njs_flathsh_query_t *fhq)
+{
+    void                 *tmp;
+    njs_int_t            cell_num, elt_num;
+    njs_flathsh_elt_t    *elt, *elts;
+    njs_flathsh_descr_t  *h;
+
+    h = fh->slot;
+
+    if (h == NULL) {
+        h = njs_flathsh_new(fhq);
+        if (h == NULL) {
+            return NJS_ERROR;
+        }
+
+        fh->slot = h;
+    }
+
+    cell_num = fhq->key_hash & h->hash_mask;
+    elt_num = njs_hash_cells_end(h)[-cell_num - 1];
+    elts = njs_hash_elts(h);
+
+    while (elt_num != 0) {
+        elt = &elts[elt_num - 1];
+
+        if (elt->key_hash == fhq->key_hash) {
+            if (fhq->replace) {
+                tmp = fhq->value;
+                fhq->value = elt->value;
+                elt->value = tmp;
+
+                return NJS_OK;
+
+            } else {
+                fhq->value = elt->value;
+
+                return NJS_DECLINED;
+            }
+        }
+
+        elt_num = elt->next_elt;
+    }
+
+    elt = njs_flathsh_add_elt(fh, fhq);
+    if (elt == NULL) {
+        return NJS_ERROR;
+    }
+
+    elt->value = fhq->value;
+
+    return NJS_OK;
+}
+
+
 static njs_flathsh_descr_t *
 njs_shrink_elts(njs_flathsh_query_t *fhq, njs_flathsh_descr_t *h)
 {
@@ -502,8 +577,6 @@ njs_flathsh_delete(njs_flathsh_t *fh, njs_flathsh_query_t *fhq)
     while (elt_num != 0) {
         elt = &elts[elt_num - 1];
 
-        /* TODO: use atomic comparision. */
-
         if (elt->key_hash == fhq->key_hash &&
             fhq->proto->test(fhq, elt->value) == NJS_OK)
         {
@@ -550,11 +623,75 @@ njs_flathsh_delete(njs_flathsh_t *fh, njs_flathsh_query_t *fhq)
 }
 
 
-void *
+njs_int_t
+njs_flathsh_unique_delete(njs_flathsh_t *fh, njs_flathsh_query_t *fhq)
+{
+    njs_int_t            cell_num, elt_num;
+    njs_flathsh_elt_t    *elt, *elt_prev, *elts;
+    njs_flathsh_descr_t  *h;
+
+    h = fh->slot;
+
+    if (njs_slow_path(h == NULL)) {
+        return NJS_DECLINED;
+    }
+
+    cell_num = fhq->key_hash & h->hash_mask;
+    elt_num = njs_hash_cells_end(h)[-cell_num - 1];
+    elts = njs_hash_elts(h);
+    elt_prev = NULL;
+
+    while (elt_num != 0) {
+        elt = &elts[elt_num - 1];
+
+        if (elt->key_hash == fhq->key_hash) {
+            fhq->value = elt->value;
+
+            if (elt_prev != NULL) {
+                elt_prev->next_elt = elt->next_elt;
+
+            } else {
+                njs_hash_cells_end(h)[-cell_num - 1] = elt->next_elt;
+            }
+
+            h->elts_deleted_count++;
+
+            elt->value = NULL;
+
+            /* Shrink elts if elts_deleted_count is eligible. */
+
+            if (h->elts_deleted_count >= NJS_FLATHSH_ELTS_MINIMUM_TO_SHRINK
+                && h->elts_deleted_count
+                   >= (h->elts_count / NJS_FLATHSH_ELTS_FRACTION_TO_SHRINK))
+            {
+                h = njs_shrink_elts(fhq, h);
+                if (njs_slow_path(h == NULL)) {
+                    return NJS_ERROR;
+                }
+
+                fh->slot = h;
+            }
+
+            if (h->elts_deleted_count == h->elts_count) {
+                njs_flathsh_free(fhq, njs_flathsh_chunk(h));
+                fh->slot = NULL;
+            }
+
+            return NJS_OK;
+        }
+
+        elt_prev = elt;
+        elt_num = elt->next_elt;
+    }
+
+    return NJS_DECLINED;
+}
+
+
+njs_flathsh_elt_t *
 njs_flathsh_each(const njs_flathsh_t *fh, njs_flathsh_each_t *fhe)
 {
-    void                 *v;
-    njs_flathsh_elt_t    *elt;
+    njs_flathsh_elt_t    *e, *elt;
     njs_flathsh_descr_t  *h;
 
     h = fh->slot;
@@ -565,9 +702,9 @@ njs_flathsh_each(const njs_flathsh_t *fh, njs_flathsh_each_t *fhe)
     elt = njs_hash_elts(h);
 
     while (fhe->cp < h->elts_count) {
-        v = elt[fhe->cp++].value;
-        if (v != NULL) {
-            return v;
+        e = &elt[fhe->cp++];
+        if (e->value != NULL) {
+            return e;
         }
     }
 
diff --git a/src/njs_flathsh.h b/src/njs_flathsh.h
index d347bb81..651afcff 100644
--- a/src/njs_flathsh.h
+++ b/src/njs_flathsh.h
@@ -64,6 +64,10 @@ struct njs_flathsh_query_s {
     ((fhl)->slot == (fhr)->slot)
 
 
+#define njs_hash_elts(h)                                                       \
+    ((njs_flathsh_elt_t *) ((char *) (h) + 16 /* njs_flathsh_descr_t size */))
+
+
 /*
  * njs_flathsh_find() finds a hash element.  If the element has been
  * found then it is stored in the fhq->value and njs_flathsh_find()
@@ -73,6 +77,11 @@ struct njs_flathsh_query_s {
  */
 NJS_EXPORT njs_int_t njs_flathsh_find(const njs_flathsh_t *fh,
     njs_flathsh_query_t *fhq);
+/*
+ * The same as njs_flathsh_find(), but for hashes with unique keys.
+ */
+NJS_EXPORT njs_int_t njs_flathsh_unique_find(const njs_flathsh_t *fh,
+    njs_flathsh_query_t *fhq);
 
 /*
  * njs_flathsh_insert() adds a hash element.  If the element is already
@@ -91,6 +100,11 @@ NJS_EXPORT njs_int_t njs_flathsh_find(const njs_flathsh_t *fh,
  */
 NJS_EXPORT njs_int_t njs_flathsh_insert(njs_flathsh_t *fh,
     njs_flathsh_query_t *fhq);
+/*
+ * The same as njs_flathsh_insert(), but for hashes with unique keys.
+ */
+NJS_EXPORT njs_int_t njs_flathsh_unique_insert(njs_flathsh_t *fh,
+    njs_flathsh_query_t *fhq);
 
 /*
  * njs_flathsh_delete() deletes a hash element.  If the element has been
@@ -102,11 +116,14 @@ NJS_EXPORT njs_int_t njs_flathsh_insert(njs_flathsh_t *fh,
  */
 NJS_EXPORT njs_int_t njs_flathsh_delete(njs_flathsh_t *fh,
     njs_flathsh_query_t *fhq);
+/*
+ * The same as njs_flathsh_delete(), but for hashes with unique keys.
+ */
+NJS_EXPORT njs_int_t njs_flathsh_unique_delete(njs_flathsh_t *fh,
+    njs_flathsh_query_t *fhq);
 
 
 typedef struct {
-    const njs_flathsh_proto_t  *proto;
-    uint32_t                   key_hash;
     uint32_t                   cp;
 } njs_flathsh_each_t;
 
@@ -114,11 +131,10 @@ typedef struct {
 #define njs_flathsh_each_init(lhe, _proto)                                     \
     do {                                                                       \
         njs_memzero(lhe, sizeof(njs_flathsh_each_t));                          \
-        (lhe)->proto = _proto;                                                 \
     } while (0)
 
 
-NJS_EXPORT void *njs_flathsh_each(const njs_flathsh_t *fh,
+NJS_EXPORT njs_flathsh_elt_t *njs_flathsh_each(const njs_flathsh_t *fh,
     njs_flathsh_each_t *fhe);
 
 /*
@@ -151,7 +167,19 @@ typedef struct njs_flathsh_proto_s  njs_lvlhsh_proto_t;
 #define njs_lvlhsh_insert(lh, lhq) njs_flathsh_insert(lh, lhq)
 #define njs_lvlhsh_delete(lh, lhq) njs_flathsh_delete(lh, lhq)
 #define njs_lvlhsh_each_init(lhe, _proto)  njs_flathsh_each_init(lhe, _proto)
-#define njs_lvlhsh_each(lh, lhe) njs_flathsh_each(lh, lhe)
+
+njs_inline void *
+njs_lvlhsh_each(const njs_flathsh_t *lh, njs_flathsh_each_t *lhe)
+{
+    njs_flathsh_elt_t  *e;
+
+    e = njs_flathsh_each(lh, lhe);
+    if (e == NULL) {
+        return NULL;
+    }
+
+    return e->value;
+}
 
 
 #endif /* _NJS_FLATHSH_H_INCLUDED_ */
diff --git a/src/njs_function.c b/src/njs_function.c
index 326549f5..0840d437 100644
--- a/src/njs_function.c
+++ b/src/njs_function.c
@@ -118,15 +118,15 @@ njs_int_t
 njs_function_name_set(njs_vm_t *vm, njs_function_t *function,
     njs_value_t *name, const char *prefix)
 {
-    u_char              *p;
-    size_t              len, symbol;
-    njs_int_t           ret;
-    njs_value_t         value;
-    njs_string_prop_t   string;
-    njs_object_prop_t   *prop;
-    njs_lvlhsh_query_t  lhq;
-
-    prop = njs_object_prop_alloc(vm, &njs_string_name, name, 0);
+    u_char               *p;
+    size_t               len, symbol;
+    njs_int_t            ret;
+    njs_value_t          value;
+    njs_string_prop_t    string;
+    njs_object_prop_t    *prop;
+    njs_flathsh_query_t  lhq;
+
+    prop = njs_object_prop_alloc(vm, name, 0);
     if (njs_slow_path(prop == NULL)) {
         return NJS_ERROR;
     }
@@ -142,7 +142,7 @@ njs_function_name_set(njs_vm_t *vm, njs_function_t *function,
     if (prefix != NULL || symbol != 0) {
         if (njs_is_defined(njs_prop_value(prop))) {
             njs_value_assign(&value, njs_prop_value(prop));
-            (void) njs_string_prop(&string, &value);
+            (void) njs_string_prop(vm, &string, &value);
 
             len = (prefix != NULL) ? njs_strlen(prefix) + 1: 0;
             p = njs_string_alloc(vm, njs_prop_value(prop),
@@ -168,20 +168,19 @@ njs_function_name_set(njs_vm_t *vm, njs_function_t *function,
             }
 
         } else {
-            njs_value_assign(njs_prop_value(prop), &njs_string_empty);
+            njs_set_empty_string(vm, njs_prop_value(prop));
         }
     }
 
     prop->configurable = 1;
 
-    lhq.key_hash = NJS_NAME_HASH;
-    lhq.key = njs_str_value("name");
-    lhq.replace = 0;
     lhq.value = prop;
-    lhq.proto = &njs_object_hash_proto;
+    lhq.key_hash = NJS_ATOM_STRING_name;
+    lhq.replace = 0;
     lhq.pool = vm->mem_pool;
+    lhq.proto = &njs_object_hash_proto;
 
-    ret = njs_lvlhsh_insert(&function->object.hash, &lhq);
+    ret = njs_flathsh_unique_insert(&function->object.hash, &lhq);
     if (njs_slow_path(ret != NJS_OK)) {
         njs_internal_error(vm, "lvlhsh insert failed");
         return NJS_ERROR;
@@ -251,8 +250,6 @@ njs_function_arguments_object_init(njs_vm_t *vm, njs_native_frame_t *frame)
     njs_value_t   value, length;
     njs_object_t  *arguments;
 
-    static const njs_value_t  string_length = njs_string("length");
-
     arguments = njs_object_alloc(vm);
     if (njs_slow_path(arguments == NULL)) {
         return NJS_ERROR;
@@ -263,9 +260,8 @@ njs_function_arguments_object_init(njs_vm_t *vm, njs_native_frame_t *frame)
     njs_set_object(&value, arguments);
     njs_set_number(&length, frame->nargs);
 
-    ret = njs_object_prop_define(vm, &value, njs_value_arg(&string_length),
-                                 &length, NJS_OBJECT_PROP_VALUE_CW,
-                                 NJS_LENGTH_HASH);
+    ret = njs_object_prop_define(vm, &value, NJS_ATOM_STRING_length, &length,
+                                 NJS_OBJECT_PROP_VALUE_CW);
     if (njs_slow_path(ret != NJS_OK)) {
         return NJS_ERROR;
     }
@@ -328,14 +324,16 @@ njs_function_prototype_thrower(njs_vm_t *vm, njs_value_t *args,
 }
 
 
-const njs_object_prop_t  njs_arguments_object_instance_properties[] =
+const njs_object_prop_init_t  njs_arguments_object_instance_properties[] =
 {
     {
-        .type = NJS_ACCESSOR,
-        .name = njs_string("callee"),
-        .u.accessor = njs_accessor(njs_function_prototype_thrower, 0,
-                                   njs_function_prototype_thrower, 0),
-        .writable = NJS_ATTRIBUTE_UNSET,
+        .atom_id = NJS_ATOM_STRING_callee,
+        .desc = {
+            .type = NJS_ACCESSOR,
+            .u.accessor = njs_accessor(njs_function_prototype_thrower, 0,
+                                       njs_function_prototype_thrower, 0),
+            .writable = NJS_ATTRIBUTE_UNSET,
+        },
     },
 };
 
@@ -905,16 +903,14 @@ njs_function_capture_global_closures(njs_vm_t *vm, njs_function_t *function)
 
 
 static njs_value_t *
-njs_function_property_prototype_set(njs_vm_t *vm, njs_lvlhsh_t *hash,
+njs_function_property_prototype_set(njs_vm_t *vm, njs_flathsh_t *hash,
     njs_value_t *prototype)
 {
-    njs_int_t           ret;
-    njs_object_prop_t   *prop;
-    njs_lvlhsh_query_t  lhq;
+    njs_int_t            ret;
+    njs_object_prop_t    *prop;
+    njs_flathsh_query_t  lhq;
 
-    const njs_value_t  proto_string = njs_string("prototype");
-
-    prop = njs_object_prop_alloc(vm, &proto_string, prototype, 0);
+    prop = njs_object_prop_alloc(vm, prototype, 0);
     if (njs_slow_path(prop == NULL)) {
         return NULL;
     }
@@ -922,13 +918,12 @@ njs_function_property_prototype_set(njs_vm_t *vm, njs_lvlhsh_t *hash,
     prop->writable = 1;
 
     lhq.value = prop;
-    lhq.key_hash = NJS_PROTOTYPE_HASH;
-    lhq.key = njs_str_value("prototype");
+    lhq.key_hash = NJS_ATOM_STRING_prototype;
     lhq.replace = 1;
     lhq.pool = vm->mem_pool;
     lhq.proto = &njs_object_hash_proto;
 
-    ret = njs_lvlhsh_insert(hash, &lhq);
+    ret = njs_flathsh_unique_insert(hash, &lhq);
 
     if (njs_fast_path(ret == NJS_OK)) {
         return njs_prop_value(prop);
@@ -952,7 +947,8 @@ njs_function_property_prototype_set(njs_vm_t *vm, njs_lvlhsh_t *hash,
 
 njs_int_t
 njs_function_prototype_create(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     njs_value_t     *proto, proto_value, *cons;
     njs_object_t    *prototype;
@@ -1002,6 +998,7 @@ njs_function_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_int_t               ret;
     njs_str_t               str, file;
     njs_uint_t              i;
+    njs_value_t             name;
     njs_parser_t            parser;
     njs_vm_code_t           *code;
     njs_function_t          *function;
@@ -1072,7 +1069,7 @@ njs_function_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     file = njs_str_value("runtime");
 
     ret = njs_parser_init(vm, &parser, NULL, &file, str.start,
-                          str.start + str.length, 1);
+                          str.start + str.length);
     if (njs_slow_path(ret != NJS_OK)) {
         return ret;
     }
@@ -1139,8 +1136,9 @@ njs_function_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     function->global_this = 1;
     function->args_count = lambda->nargs - lambda->rest_parameters;
 
-    ret = njs_function_name_set(vm, function,
-                                njs_value_arg(&njs_string_anonymous), NULL);
+    njs_atom_to_value(vm, &name, NJS_ATOM_STRING_anonymous);
+
+    ret = njs_function_name_set(vm, function, &name, NULL);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return ret;
     }
@@ -1156,13 +1154,14 @@ fail:
 }
 
 
-static const njs_object_prop_t  njs_function_constructor_properties[] =
+static const njs_object_prop_init_t  njs_function_constructor_properties[] =
 {
     NJS_DECLARE_PROP_LENGTH(1),
 
     NJS_DECLARE_PROP_NAME("Function"),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
+                             0, 0),
 };
 
 
@@ -1174,7 +1173,8 @@ const njs_object_init_t  njs_function_constructor_init = {
 
 njs_int_t
 njs_function_instance_length(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     njs_function_t  *function;
 
@@ -1193,7 +1193,8 @@ njs_function_instance_length(njs_vm_t *vm, njs_object_prop_t *prop,
 
 njs_int_t
 njs_function_instance_name(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     njs_function_t  *function;
 
@@ -1209,7 +1210,7 @@ njs_function_instance_name(njs_vm_t *vm, njs_object_prop_t *prop,
         return NJS_OK;
     }
 
-    njs_value_assign(retval, &njs_string_empty);
+    njs_set_empty_string(vm, retval);
 
     return NJS_OK;
 }
@@ -1376,14 +1377,13 @@ njs_function_prototype_bind(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     function->context = njs_function(&args[0]);
 
-    ret = njs_value_property(vm, &args[0], njs_value_arg(&njs_string_name),
-                             &name);
+    ret = njs_value_property(vm, &args[0], NJS_ATOM_STRING_name, &name);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return ret;
     }
 
     if (!njs_is_string(&name)) {
-        name = njs_string_empty;
+        njs_set_empty_string(vm, &name);
     }
 
     ret = njs_function_name_set(vm, function, &name, "bound");
@@ -1428,38 +1428,43 @@ njs_function_prototype_bind(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 }
 
 
-static const njs_object_prop_t  njs_function_prototype_properties[] =
+static const njs_object_prop_init_t  njs_function_prototype_properties[] =
 {
     NJS_DECLARE_PROP_LENGTH(0),
 
     NJS_DECLARE_PROP_NAME(""),
 
-    NJS_DECLARE_PROP_HANDLER("constructor",
-                             njs_object_prototype_create_constructor,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
+                             njs_object_prototype_create_constructor, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_NATIVE("call", njs_function_prototype_call, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_call, njs_function_prototype_call, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("apply", njs_function_prototype_apply, 2, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_apply, njs_function_prototype_apply, 2,
+                            0),
 
-    NJS_DECLARE_PROP_NATIVE("bind", njs_function_prototype_bind, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_bind, njs_function_prototype_bind, 1, 0),
 
     {
-        .type = NJS_ACCESSOR,
-        .name = njs_string("caller"),
-        .u.accessor = njs_accessor(njs_function_prototype_thrower, 0,
-                                   njs_function_prototype_thrower, 0),
-        .writable = NJS_ATTRIBUTE_UNSET,
-        .configurable = 1,
+        .atom_id = NJS_ATOM_STRING_caller,
+        .desc = {
+            .type = NJS_ACCESSOR,
+            .u.accessor = njs_accessor(njs_function_prototype_thrower, 0,
+                                       njs_function_prototype_thrower, 0),
+            .writable = NJS_ATTRIBUTE_UNSET,
+            .configurable = 1,
+        },
     },
 
     {
-        .type = NJS_ACCESSOR,
-        .name = njs_string("arguments"),
-        .u.accessor = njs_accessor(njs_function_prototype_thrower, 0,
-                                   njs_function_prototype_thrower, 0),
-        .writable = NJS_ATTRIBUTE_UNSET,
-        .configurable = 1,
+        .atom_id = NJS_ATOM_STRING_arguments,
+        .desc = {
+            .type = NJS_ACCESSOR,
+            .u.accessor = njs_accessor(njs_function_prototype_thrower, 0,
+                                       njs_function_prototype_thrower, 0),
+            .writable = NJS_ATTRIBUTE_UNSET,
+            .configurable = 1,
+        },
     },
 };
 
@@ -1470,15 +1475,16 @@ const njs_object_init_t  njs_function_prototype_init = {
 };
 
 
-const njs_object_prop_t  njs_function_instance_properties[] =
+const njs_object_prop_init_t  njs_function_instance_properties[] =
 {
-    NJS_DECLARE_PROP_HANDLER("length", njs_function_instance_length, 0, 0,
-                             NJS_OBJECT_PROP_VALUE_C),
+    NJS_DECLARE_PROP_HANDLER(STRING_length, njs_function_instance_length,
+                             0, NJS_OBJECT_PROP_VALUE_C),
 
-    NJS_DECLARE_PROP_HANDLER("name", njs_function_instance_name, 0, 0,
+    NJS_DECLARE_PROP_HANDLER(STRING_name, njs_function_instance_name, 0,
                              NJS_OBJECT_PROP_VALUE_C),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_function_prototype_create, 0, 0,
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype,
+                             njs_function_prototype_create, 0,
                              NJS_OBJECT_PROP_VALUE_W),
 };
 
@@ -1489,12 +1495,12 @@ const njs_object_init_t  njs_function_instance_init = {
 };
 
 
-const njs_object_prop_t  njs_arrow_instance_properties[] =
+const njs_object_prop_init_t  njs_arrow_instance_properties[] =
 {
-    NJS_DECLARE_PROP_HANDLER("length", njs_function_instance_length, 0, 0,
-                             NJS_OBJECT_PROP_VALUE_C),
+    NJS_DECLARE_PROP_HANDLER(STRING_length, njs_function_instance_length,
+                             0, NJS_OBJECT_PROP_VALUE_C),
 
-    NJS_DECLARE_PROP_HANDLER("name", njs_function_instance_name, 0, 0,
+    NJS_DECLARE_PROP_HANDLER(STRING_name, njs_function_instance_name, 0,
                              NJS_OBJECT_PROP_VALUE_C),
 };
 
diff --git a/src/njs_function.h b/src/njs_function.h
index 0b316251..6516ff78 100644
--- a/src/njs_function.h
+++ b/src/njs_function.h
@@ -94,13 +94,16 @@ njs_int_t njs_function_arguments_object_init(njs_vm_t *vm,
 njs_int_t njs_function_rest_parameters_init(njs_vm_t *vm,
     njs_native_frame_t *frame);
 njs_int_t njs_function_prototype_create(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval);
 njs_int_t njs_function_constructor(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 njs_int_t njs_function_instance_length(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
+     uint32_t unused, njs_value_t *value, njs_value_t *setval,
+     njs_value_t *retval);
 njs_int_t njs_function_instance_name(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval);
 njs_int_t njs_eval_function(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused, njs_value_t *retval);
 njs_int_t njs_function_native_frame(njs_vm_t *vm, njs_function_t *function,
diff --git a/src/njs_generator.c b/src/njs_generator.c
index 2e81a407..a2cc4b1c 100644
--- a/src/njs_generator.c
+++ b/src/njs_generator.c
@@ -1062,11 +1062,11 @@ static njs_int_t
 njs_generate_var_statement_after(njs_vm_t *vm, njs_generator_t *generator,
     njs_parser_node_t *node)
 {
-    njs_int_t                ret;
-    njs_variable_t           *var;
-    njs_parser_node_t        *lvalue, *expr;
-    njs_vmcode_move_t        *move;
-    const njs_lexer_entry_t  *lex_entry;
+    njs_int_t          ret;
+    njs_string_t       name;
+    njs_variable_t     *var;
+    njs_parser_node_t  *lvalue, *expr;
+    njs_vmcode_move_t  *move;
 
     lvalue = node->left;
     expr = node->right;
@@ -1093,20 +1093,14 @@ njs_generate_var_statement_after(njs_vm_t *vm, njs_generator_t *generator,
     node->index = expr->index;
     node->temporary = expr->temporary;
 
-    if ((expr->token_type == NJS_TOKEN_FUNCTION_EXPRESSION
+    if (expr->token_type == NJS_TOKEN_FUNCTION_EXPRESSION
          || expr->token_type == NJS_TOKEN_ASYNC_FUNCTION_EXPRESSION)
-        && njs_values_same(&expr->u.value.data.u.lambda->name,
-                           &njs_string_empty))
     {
-        lex_entry = njs_lexer_entry(node->left->u.reference.unique_id);
-        if (njs_slow_path(lex_entry == NULL)) {
-            return NJS_ERROR;
-        }
+        njs_string_get_unsafe(&expr->u.value.data.u.lambda->name, &name);
 
-        ret = njs_string_create(vm, &expr->u.value.data.u.lambda->name,
-                                lex_entry->name.start, lex_entry->name.length);
-        if (njs_slow_path(ret != NJS_OK)) {
-            return NJS_ERROR;
+        if (name.length == 0) {
+            njs_atom_to_value(vm, &expr->u.value.data.u.lambda->name,
+                              node->left->u.reference.atom_id);
         }
     }
 
@@ -3023,11 +3017,9 @@ static njs_int_t
 njs_generate_global_property_set(njs_vm_t *vm, njs_generator_t *generator,
     njs_parser_node_t *node_dst, njs_parser_node_t *node_src)
 {
-    njs_int_t                ret;
-    njs_value_t              property;
-    njs_variable_t           *var;
-    njs_vmcode_prop_set_t    *prop_set;
-    const njs_lexer_entry_t  *lex_entry;
+    njs_value_t            property;
+    njs_variable_t         *var;
+    njs_vmcode_prop_set_t  *prop_set;
 
     var = njs_variable_reference(vm, node_dst);
     if (var == NULL) {
@@ -3037,16 +3029,7 @@ njs_generate_global_property_set(njs_vm_t *vm, njs_generator_t *generator,
         prop_set->value = node_dst->index;
         prop_set->object = njs_scope_global_this_index();
 
-        lex_entry = njs_lexer_entry(node_dst->u.reference.unique_id);
-        if (njs_slow_path(lex_entry == NULL)) {
-            return NJS_ERROR;
-        }
-
-        ret = njs_string_create(vm, &property, lex_entry->name.start,
-                                lex_entry->name.length);
-        if (njs_slow_path(ret != NJS_OK)) {
-            return NJS_ERROR;
-        }
+        njs_atom_to_value(vm, &property,node_dst->u.reference.atom_id);
 
         prop_set->property = njs_scope_global_index(vm, &property,
                                                 generator->runtime);
@@ -3628,11 +3611,11 @@ static njs_int_t
 njs_generate_function_expression(njs_vm_t *vm, njs_generator_t *generator,
     njs_parser_node_t *node)
 {
-    njs_int_t                ret;
-    njs_variable_t           *var;
-    njs_function_lambda_t    *lambda;
-    njs_vmcode_function_t    *function;
-    const njs_lexer_entry_t  *lex_entry;
+    njs_int_t              ret;
+    njs_str_t              name;
+    njs_variable_t         *var;
+    njs_function_lambda_t  *lambda;
+    njs_vmcode_function_t  *function;
 
     var = njs_variable_reference(vm, node->left);
     if (njs_slow_path(var == NULL)) {
@@ -3646,23 +3629,14 @@ njs_generate_function_expression(njs_vm_t *vm, njs_generator_t *generator,
 
     lambda = node->u.value.data.u.lambda;
 
-    lex_entry = njs_lexer_entry(var->unique_id);
-    if (njs_slow_path(lex_entry == NULL)) {
-        return NJS_ERROR;
-    }
+    njs_atom_to_value(vm, &lambda->name, var->atom_id);
+    njs_string_get(vm, &lambda->name, &name);
 
-    ret = njs_generate_function_scope(vm, generator, lambda, node,
-                                      &lex_entry->name);
+    ret = njs_generate_function_scope(vm, generator, lambda, node, &name);
     if (njs_slow_path(ret != NJS_OK)) {
         return ret;
     }
 
-    ret = njs_string_create(vm, &lambda->name, lex_entry->name.start,
-                            lex_entry->name.length);
-    if (njs_slow_path(ret != NJS_OK)) {
-        return NJS_ERROR;
-    }
-
     njs_generate_code(generator, njs_vmcode_function_t, function,
                       NJS_VMCODE_FUNCTION, node);
     function->lambda = lambda;
@@ -4188,12 +4162,12 @@ static njs_int_t
 njs_generate_function_declaration(njs_vm_t *vm, njs_generator_t *generator,
     njs_parser_node_t *node)
 {
-    njs_int_t                ret;
-    njs_bool_t               async;
-    njs_variable_t           *var;
-    njs_function_t           *function;
-    njs_function_lambda_t    *lambda;
-    const njs_lexer_entry_t  *lex_entry;
+    njs_int_t              ret;
+    njs_str_t              name;
+    njs_bool_t             async;
+    njs_variable_t         *var;
+    njs_function_t         *function;
+    njs_function_lambda_t  *lambda;
 
     var = njs_variable_reference(vm, node);
     if (njs_slow_path(var == NULL)) {
@@ -4207,19 +4181,10 @@ njs_generate_function_declaration(njs_vm_t *vm, njs_generator_t *generator,
 
     lambda = njs_variable_lambda(var);
 
-    lex_entry = njs_lexer_entry(node->u.reference.unique_id);
-    if (njs_slow_path(lex_entry == NULL)) {
-        return NJS_ERROR;
-    }
+    njs_atom_to_value(vm, &lambda->name, node->u.reference.atom_id);
+    njs_string_get(vm, &lambda->name, &name);
 
-    ret = njs_string_create(vm, &lambda->name, lex_entry->name.start,
-                            lex_entry->name.length);
-    if (njs_slow_path(ret != NJS_OK)) {
-        return NJS_ERROR;
-    }
-
-    ret = njs_generate_function_scope(vm, generator, lambda, node,
-                                      &lex_entry->name);
+    ret = njs_generate_function_scope(vm, generator, lambda, node, &name);
     if (njs_slow_path(ret != NJS_OK)) {
         return ret;
     }
@@ -5388,11 +5353,9 @@ static njs_int_t
 njs_generate_global_reference(njs_vm_t *vm, njs_generator_t *generator,
     njs_parser_node_t *node, njs_bool_t exception)
 {
-    njs_int_t                ret;
-    njs_index_t              index;
-    njs_value_t              property;
-    njs_vmcode_prop_get_t    *prop_get;
-    const njs_lexer_entry_t  *lex_entry;
+    njs_index_t            index;
+    njs_value_t            property;
+    njs_vmcode_prop_get_t  *prop_get;
 
     index = njs_generate_temp_index_get(vm, generator, node);
     if (njs_slow_path(index == NJS_INDEX_ERROR)) {
@@ -5410,16 +5373,7 @@ njs_generate_global_reference(njs_vm_t *vm, njs_generator_t *generator,
         return NJS_ERROR;
     }
 
-    lex_entry = njs_lexer_entry(node->u.reference.unique_id);
-    if (njs_slow_path(lex_entry == NULL)) {
-        return NJS_ERROR;
-    }
-
-    ret = njs_string_create(vm, &property, lex_entry->name.start,
-                            lex_entry->name.length);
-    if (njs_slow_path(ret != NJS_OK)) {
-        return NJS_ERROR;
-    }
+    njs_atom_to_value(vm, &property, node->u.reference.atom_id);
 
     prop_get->property = njs_scope_global_index(vm, &property,
                                                 generator->runtime);
@@ -5441,8 +5395,8 @@ static njs_int_t
 njs_generate_reference_error(njs_vm_t *vm, njs_generator_t *generator,
     njs_parser_node_t *node)
 {
-    njs_vmcode_error_t       *ref_err;
-    const njs_lexer_entry_t  *lex_entry;
+    njs_str_t           entry;
+    njs_vmcode_error_t  *ref_err;
 
     if (njs_slow_path(!node->u.reference.not_defined)) {
         njs_internal_error(vm, "variable is not defined but not_defined "
@@ -5454,12 +5408,10 @@ njs_generate_reference_error(njs_vm_t *vm, njs_generator_t *generator,
                       NULL);
 
     ref_err->type = NJS_OBJ_TYPE_REF_ERROR;
-    lex_entry = njs_lexer_entry(node->u.reference.unique_id);
-    if (njs_slow_path(lex_entry == NULL)) {
-        return NJS_ERROR;
-    }
 
-    return njs_name_copy(vm, &ref_err->u.name, &lex_entry->name);
+    njs_lexer_entry(vm, node->u.reference.atom_id, &entry);
+
+    return njs_name_copy(vm, &ref_err->u.name, &entry);
 }
 
 
diff --git a/src/njs_iterator.c b/src/njs_iterator.c
index 34bb073e..7bb6a6ce 100644
--- a/src/njs_iterator.c
+++ b/src/njs_iterator.c
@@ -18,10 +18,6 @@ struct njs_value_iterator_s {
 typedef struct njs_value_iterator_s  njs_array_iterator_t;
 
 
-static const njs_value_t  string_done = njs_string("done");
-static const njs_value_t  string_value = njs_string("value");
-
-
 static njs_int_t njs_iterator_object_handler(njs_vm_t *vm,
     njs_iterator_handler_t handler, njs_iterator_args_t *args,
     njs_value_t *key, int64_t i, njs_value_t *retval);
@@ -179,15 +175,10 @@ njs_iterator_prototype_get_this(njs_vm_t *vm, njs_value_t *args,
 }
 
 
-static const njs_object_prop_t  njs_iterator_prototype_properties[] =
+static const njs_object_prop_init_t  njs_iterator_prototype_properties[] =
 {
-    {
-        .type = NJS_PROPERTY,
-        .name = njs_wellknown_symbol(NJS_SYMBOL_ITERATOR),
-        .u.value = njs_native_function(njs_iterator_prototype_get_this, 0),
-        .configurable = 1,
-        .writable = 1,
-    },
+    NJS_DECLARE_PROP_NATIVE(SYMBOL_iterator,
+                            njs_iterator_prototype_get_this, 0, 0),
 };
 
 
@@ -232,14 +223,12 @@ njs_array_iterator_prototype_next(njs_vm_t *vm, njs_value_t *args,
 
     njs_set_object(retval, object);
 
-    prop_value = njs_object_property_add(vm, retval,
-                                         njs_value_arg(&string_value), 0);
+    prop_value = njs_object_property_add(vm, retval, NJS_ATOM_STRING_value, 0);
     if (njs_slow_path(prop_value == NULL)) {
         return NJS_ERROR;
     }
 
-    prop_done = njs_object_property_add(vm, retval,
-                                        njs_value_arg(&string_done), 0);
+    prop_done = njs_object_property_add(vm, retval, NJS_ATOM_STRING_done, 0);
     if (njs_slow_path(prop_done == NULL)) {
         return NJS_ERROR;
     }
@@ -262,17 +251,14 @@ njs_array_iterator_prototype_next(njs_vm_t *vm, njs_value_t *args,
 }
 
 
-static const njs_object_prop_t  njs_array_iterator_prototype_properties[] =
+static const njs_object_prop_init_t  njs_array_iterator_prototype_properties[] =
 {
-    NJS_DECLARE_PROP_NATIVE("next", njs_array_iterator_prototype_next, 0,
-                            NJS_DATA_TAG_ARRAY_ITERATOR),
-
-    {
-        .type = NJS_PROPERTY,
-        .name = njs_wellknown_symbol(NJS_SYMBOL_TO_STRING_TAG),
-        .u.value = njs_string("Array Iterator"),
-        .configurable = 1,
-    },
+    NJS_DECLARE_PROP_NATIVE(STRING_next, njs_array_iterator_prototype_next,
+                            0, NJS_DATA_TAG_ARRAY_ITERATOR),
+
+    NJS_DECLARE_PROP_VALUE(SYMBOL_toStringTag,
+                           njs_ascii_strval("Array Iterator"),
+                           NJS_OBJECT_PROP_VALUE_C),
 };
 
 
@@ -349,7 +335,7 @@ njs_object_iterate(njs_vm_t *vm, njs_iterator_args_t *args,
             value = njs_object_value(value);
         }
 
-        length = njs_string_prop(&string_prop, value);
+        length = njs_string_prop(vm, &string_prop, value);
 
         p = string_prop.start;
         end = p + string_prop.size;
@@ -358,8 +344,10 @@ njs_object_iterate(njs_vm_t *vm, njs_iterator_args_t *args,
             /* ASCII string. */
 
             for (i = from; i < to; i++) {
-                /* This cannot fail. */
-                (void) njs_string_new(vm, &character, p + i, 1, 1);
+                ret = njs_string_new(vm, &character, p + i, 1, 1);
+                if (njs_slow_path(ret != NJS_OK)) {
+                    return NJS_ERROR;
+                }
 
                 ret = handler(vm, args, &character, i, retval);
                 if (njs_slow_path(ret != NJS_OK)) {
@@ -377,8 +365,10 @@ njs_object_iterate(njs_vm_t *vm, njs_iterator_args_t *args,
             for (i = from; i < to; i++) {
                 pos = njs_utf8_next(p, end);
 
-                /* This cannot fail. */
-                (void) njs_string_new(vm, &character, p, pos - p, 1);
+                ret = njs_string_new(vm, &character, p, pos - p, 1);
+                if (njs_slow_path(ret != NJS_OK)) {
+                    return NJS_ERROR;
+                }
 
                 ret = handler(vm, args, &character, i, retval);
                 if (njs_slow_path(ret != NJS_OK)) {
@@ -502,7 +492,7 @@ njs_object_iterate_reverse(njs_vm_t *vm, njs_iterator_args_t *args,
             value = njs_object_value(value);
         }
 
-        length = njs_string_prop(&string_prop, value);
+        length = njs_string_prop(vm, &string_prop, value);
         end = string_prop.start + string_prop.size;
 
         if ((size_t) length == string_prop.size) {
@@ -513,8 +503,10 @@ njs_object_iterate_reverse(njs_vm_t *vm, njs_iterator_args_t *args,
             i = from + 1;
 
             while (i-- > to) {
-                /* This cannot fail. */
-                (void) njs_string_new(vm, &character, p, 1, 1);
+                ret = njs_string_new(vm, &character, p, 1, 1);
+                if (njs_slow_path(ret != NJS_OK)) {
+                    return NJS_ERROR;
+                }
 
                 ret = handler(vm, args, &character, i, retval);
                 if (njs_slow_path(ret != NJS_OK)) {
@@ -542,8 +534,10 @@ njs_object_iterate_reverse(njs_vm_t *vm, njs_iterator_args_t *args,
             while (i-- > to) {
                 pos = njs_utf8_prev(p, string_prop.start);
 
-                /* This cannot fail. */
-                (void) njs_string_new(vm, &character, pos, p - pos , 1);
+                ret = njs_string_new(vm, &character, pos, p - pos , 1);
+                if (njs_slow_path(ret != NJS_OK)) {
+                    return NJS_ERROR;
+                }
 
                 ret = handler(vm, args, &character, i, retval);
                 if (njs_slow_path(ret != NJS_OK)) {
@@ -616,7 +610,8 @@ njs_iterator_object_handler(njs_vm_t *vm, njs_iterator_handler_t handler,
     njs_value_t  prop, *entry;
 
     if (key != NULL) {
-        ret = njs_value_property(vm, njs_value_arg(&args->value), key, &prop);
+        ret = njs_value_property_val(vm, njs_value_arg(&args->value), key,
+                                     &prop);
         if (njs_slow_path(ret == NJS_ERROR)) {
             return ret;
         }
diff --git a/src/njs_json.c b/src/njs_json.c
index 8ba13314..e79b1eb4 100644
--- a/src/njs_json.c
+++ b/src/njs_json.c
@@ -63,7 +63,7 @@ static const u_char *njs_json_skip_space(const u_char *start,
     const u_char *end);
 
 static njs_int_t njs_json_internalize_property(njs_vm_t *vm,
-    njs_function_t *reviver, njs_value_t *holder, njs_value_t *name,
+    njs_function_t *reviver, njs_value_t *holder, uint32_t atom_id,
     njs_int_t depth, njs_value_t *retval);
 static void njs_json_parse_exception(njs_json_parse_ctx_t *ctx,
     const char *msg, const u_char *pos);
@@ -80,15 +80,15 @@ static njs_int_t njs_json_stringify_array(njs_json_stringify_t *stringify);
 
 static njs_int_t njs_json_append_value(njs_vm_t *vm, njs_chb_t *chain,
     njs_value_t *value);
-static void njs_json_append_string(njs_chb_t *chain, const njs_value_t *value,
-    char quote);
+static void njs_json_append_string(njs_vm_t *vm, njs_chb_t *chain,
+    const njs_value_t *value, char quote);
 static void njs_json_append_number(njs_chb_t *chain, const njs_value_t *value);
 
 static njs_object_t *njs_json_wrap_value(njs_vm_t *vm, njs_value_t *wrapper,
     const njs_value_t *value);
 
 
-static const njs_object_prop_t  njs_json_object_properties[];
+static const njs_object_prop_init_t  njs_json_object_properties[];
 
 
 static njs_int_t
@@ -112,7 +112,7 @@ njs_json_parse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         }
     }
 
-    (void) njs_string_prop(&string, text);
+    (void) njs_string_prop(vm, &string, text);
 
     p = string.start;
     end = p + string.size;
@@ -149,9 +149,8 @@ njs_json_parse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         }
 
         return njs_json_internalize_property(vm, njs_function(reviver),
-                                             &wrapper,
-                                             njs_value_arg(&njs_string_empty),
-                                             0, retval);
+                                             &wrapper, NJS_ATOM_STRING_empty, 0,
+                                             retval);
     }
 
     njs_value_assign(retval, &value);
@@ -166,7 +165,7 @@ njs_vm_json_parse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 {
     njs_function_t  *parse;
 
-    parse = njs_function(&njs_json_object_properties[1].u.value);
+    parse = njs_function(&njs_json_object_properties[1].desc.u.value);
 
     return njs_vm_invoke(vm, parse, args, nargs, retval);
 }
@@ -225,7 +224,7 @@ njs_json_stringify(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     switch (space->type) {
     case NJS_STRING:
-        length = njs_string_prop(&prop, space);
+        length = njs_string_prop(vm, &prop, space);
         p = njs_string_offset(&prop, njs_min(length, 10));
 
         stringify->space.start = prop.start;
@@ -272,7 +271,7 @@ njs_vm_json_stringify(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 {
     njs_function_t  *stringify;
 
-    stringify = njs_function(&njs_json_object_properties[2].u.value);
+    stringify = njs_function(&njs_json_object_properties[2].desc.u.value);
 
     return njs_vm_invoke(vm, stringify, args, nargs, retval);
 }
@@ -336,11 +335,11 @@ static const u_char *
 njs_json_parse_object(njs_json_parse_ctx_t *ctx, njs_value_t *value,
     const u_char *p)
 {
-    njs_int_t           ret;
-    njs_object_t        *object;
-    njs_value_t         prop_name, prop_value;
-    njs_object_prop_t   *prop;
-    njs_lvlhsh_query_t  lhq;
+    njs_int_t            ret;
+    njs_object_t         *object;
+    njs_value_t          prop_name, prop_value;
+    njs_object_prop_t    *prop;
+    njs_flathsh_query_t  lhq;
 
     if (njs_slow_path(--ctx->depth == 0)) {
         njs_json_parse_exception(ctx, "Nested too deep", p);
@@ -395,19 +394,18 @@ njs_json_parse_object(njs_json_parse_ctx_t *ctx, njs_value_t *value,
             return NULL;
         }
 
-        prop = njs_object_prop_alloc(ctx->vm, &prop_name, &prop_value, 1);
+        prop = njs_object_prop_alloc(ctx->vm, &prop_value, 1);
         if (njs_slow_path(prop == NULL)) {
             goto memory_error;
         }
 
-        njs_string_get(&prop_name, &lhq.key);
-        lhq.key_hash = njs_djb_hash(lhq.key.start, lhq.key.length);
         lhq.value = prop;
+        lhq.key_hash = prop_name.atom_id;
         lhq.replace = 1;
         lhq.pool = ctx->pool;
         lhq.proto = &njs_object_hash_proto;
 
-        ret = njs_lvlhsh_insert(&object->hash, &lhq);
+        ret = njs_flathsh_unique_insert(&object->hash, &lhq);
         if (njs_slow_path(ret != NJS_OK)) {
             njs_internal_error(ctx->vm, "lvlhsh insert/replace failed");
             return NULL;
@@ -734,7 +732,7 @@ njs_json_parse_string(njs_json_parse_ctx_t *ctx, njs_value_t *value,
         start = dst;
     }
 
-    ret = njs_string_create(ctx->vm, value, (u_char *) start, size);
+    ret = njs_atom_string_create(ctx->vm, value, (u_char *) start, size);
     if (njs_slow_path(ret != NJS_OK)) {
         return NULL;
     }
@@ -829,12 +827,12 @@ njs_json_skip_space(const u_char *start, const u_char *end)
 
 static njs_int_t
 njs_json_internalize_property(njs_vm_t *vm, njs_function_t *reviver,
-    njs_value_t *holder, njs_value_t *name, njs_int_t depth,
+    njs_value_t *holder, uint32_t atom_id, njs_int_t depth,
     njs_value_t *retval)
 {
     int64_t       k, length;
     njs_int_t     ret;
-    njs_value_t   val, new_elem, index;
+    njs_value_t   val, new_elem;
     njs_value_t   arguments[3];
     njs_array_t   *keys;
 
@@ -843,7 +841,7 @@ njs_json_internalize_property(njs_vm_t *vm, njs_function_t *reviver,
         return NJS_ERROR;
     }
 
-    ret = njs_value_property(vm, holder, name, &val);
+    ret = njs_value_property(vm, holder, atom_id, &val);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return NJS_ERROR;
     }
@@ -859,19 +857,21 @@ njs_json_internalize_property(njs_vm_t *vm, njs_function_t *reviver,
 
             for (k = 0; k < keys->length; k++) {
                 ret = njs_json_internalize_property(vm, reviver, &val,
-                                                    &keys->start[k], depth,
-                                                    &new_elem);
+                                                    keys->start[k].atom_id,
+                                                    depth, &new_elem);
 
                 if (njs_slow_path(ret != NJS_OK)) {
                     goto done;
                 }
 
                 if (njs_is_undefined(&new_elem)) {
-                    ret = njs_value_property_delete(vm, &val, &keys->start[k],
+                    ret = njs_value_property_delete(vm, &val,
+                                                    keys->start[k].atom_id,
                                                     NULL, 0);
 
                 } else {
-                    ret = njs_value_property_set(vm, &val, &keys->start[k],
+                    ret = njs_value_property_set(vm, &val,
+                                                 keys->start[k].atom_id,
                                                  &new_elem);
                 }
 
@@ -888,12 +888,8 @@ njs_json_internalize_property(njs_vm_t *vm, njs_function_t *reviver,
             }
 
             for (k = 0; k < length; k++) {
-                ret = njs_int64_to_string(vm, &index, k);
-                if (njs_slow_path(ret != NJS_OK)) {
-                    return NJS_ERROR;
-                }
-
-                ret = njs_json_internalize_property(vm, reviver, &val, &index,
+                ret = njs_json_internalize_property(vm, reviver, &val,
+                                                    njs_number_atom(k),
                                                     depth, &new_elem);
 
                 if (njs_slow_path(ret != NJS_OK)) {
@@ -901,10 +897,13 @@ njs_json_internalize_property(njs_vm_t *vm, njs_function_t *reviver,
                 }
 
                 if (njs_is_undefined(&new_elem)) {
-                    ret = njs_value_property_delete(vm, &val, &index, NULL, 0);
+                    ret = njs_value_property_delete(vm, &val,
+                                                    njs_number_atom(k), NULL,
+                                                    0);
 
                 } else {
-                    ret = njs_value_property_set(vm, &val, &index, &new_elem);
+                    ret = njs_value_property_set(vm, &val, njs_number_atom(k),
+                                                 &new_elem);
                 }
 
                 if (njs_slow_path(ret == NJS_ERROR)) {
@@ -915,7 +914,7 @@ njs_json_internalize_property(njs_vm_t *vm, njs_function_t *reviver,
     }
 
     njs_value_assign(&arguments[0], holder);
-    njs_value_assign(&arguments[1], name);
+    njs_atom_to_value(vm, &arguments[1], atom_id);
     njs_value_assign(&arguments[2], &val);
 
     ret = njs_function_apply(vm, reviver, arguments, 3, retval);
@@ -1123,7 +1122,7 @@ njs_json_stringify_iterator(njs_json_stringify_t *stringify,
             key = &state->keys->start[state->index];
         }
 
-        ret = njs_value_property(stringify->vm, &state->value, key, value);
+        ret = njs_value_property_val(stringify->vm, &state->value, key, value);
         if (njs_slow_path(ret == NJS_ERROR)) {
             return ret;
         }
@@ -1161,7 +1160,7 @@ njs_json_stringify_iterator(njs_json_stringify_t *stringify,
         state->written = 1;
 
         if (!state->array) {
-            njs_json_append_string(&chain, key, '\"');
+            njs_json_append_string(stringify->vm, &chain, key, '\"');
             njs_chb_append_literal(&chain,":");
             if (stringify->space.length != 0) {
                 njs_chb_append_literal(&chain," ");
@@ -1232,14 +1231,13 @@ memory_error:
 static njs_function_t *
 njs_object_to_json_function(njs_vm_t *vm, njs_value_t *value)
 {
-    njs_int_t           ret;
-    njs_value_t         retval;
-    njs_lvlhsh_query_t  lhq;
-
-    static const njs_value_t  to_json_string = njs_string("toJSON");
+    njs_int_t            ret;
+    njs_value_t          retval;
+    njs_flathsh_query_t  lhq;
 
     if (njs_is_object(value)) {
-        njs_object_property_init(&lhq, &to_json_string, NJS_TO_JSON_HASH);
+        lhq.proto = &njs_object_hash_proto;
+        lhq.key_hash = NJS_ATOM_STRING_toJSON;
 
         ret = njs_object_property(vm, njs_object(value), &lhq, &retval);
 
@@ -1258,6 +1256,7 @@ static njs_int_t
 njs_json_stringify_to_json(njs_json_stringify_t* stringify,
     njs_json_state_t *state, njs_value_t *key, njs_value_t *value)
 {
+    njs_int_t       ret;
     njs_value_t     arguments[2];
     njs_function_t  *to_json;
 
@@ -1276,7 +1275,10 @@ njs_json_stringify_to_json(njs_json_stringify_t* stringify,
         arguments[1] = *key;
 
     } else {
-        njs_uint32_to_string(&arguments[1], state->index);
+        ret = njs_uint32_to_string(stringify->vm, &arguments[1], state->index);
+        if (njs_slow_path(ret != NJS_OK)) {
+            return NJS_ERROR;
+        }
     }
 
     return njs_function_apply(stringify->vm, to_json, arguments, 2,
@@ -1288,6 +1290,7 @@ static njs_int_t
 njs_json_stringify_replacer(njs_json_stringify_t* stringify,
     njs_json_state_t *state, njs_value_t *key, njs_value_t *value)
 {
+    njs_int_t    ret;
     njs_value_t  arguments[3];
 
     if (!njs_is_function(&stringify->replacer)) {
@@ -1301,7 +1304,10 @@ njs_json_stringify_replacer(njs_json_stringify_t* stringify,
         arguments[1] = *key;
 
     } else {
-        njs_uint32_to_string(&arguments[1], state->index);
+        ret = njs_uint32_to_string(stringify->vm, &arguments[1], state->index);
+        if (njs_slow_path(ret != NJS_OK)) {
+            return NJS_ERROR;
+        }
     }
 
     return njs_function_apply(stringify->vm, njs_function(&stringify->replacer),
@@ -1328,7 +1334,7 @@ njs_json_stringify_array(njs_json_stringify_t *stringify)
     }
 
     item = njs_array_push(stringify->vm, properties);
-    njs_value_assign(item, &njs_string_empty);
+    njs_set_empty_string(stringify->vm, item);
 
     for (i = 0; i < length; i++) {
         ret = njs_value_property_i64(stringify->vm, &stringify->replacer, i,
@@ -1373,7 +1379,9 @@ njs_json_stringify_array(njs_json_stringify_t *stringify)
         }
 
         for (k = 0; k < properties->length; k++) {
-            if (njs_values_strict_equal(value, &properties->start[k]) == 1) {
+            if (njs_values_strict_equal(stringify->vm, value,
+                                        &properties->start[k]) == 1)
+            {
                 break;
             }
         }
@@ -1428,7 +1436,7 @@ njs_json_append_value(njs_vm_t *vm, njs_chb_t *chain, njs_value_t *value)
 
     switch (value->type) {
     case NJS_STRING:
-        njs_json_append_string(chain, value, '\"');
+        njs_json_append_string(vm, chain, value, '\"');
         break;
 
     case NJS_NUMBER:
@@ -1459,7 +1467,8 @@ njs_json_append_value(njs_vm_t *vm, njs_chb_t *chain, njs_value_t *value)
 
 
 static void
-njs_json_append_string(njs_chb_t *chain, const njs_value_t *value, char quote)
+njs_json_append_string(njs_vm_t *vm, njs_chb_t *chain, const njs_value_t *value,
+    char quote)
 {
     size_t             size;
     u_char             c, *dst, *dst_end;
@@ -1470,7 +1479,7 @@ njs_json_append_string(njs_chb_t *chain, const njs_value_t *value, char quote)
     static char  hex2char[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
                                   '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
 
-    (void) njs_string_prop(&string, value);
+    (void) njs_string_prop(vm, &string, value);
 
     p = string.start;
     end = p + string.size;
@@ -1588,9 +1597,9 @@ static njs_object_t *
 njs_json_wrap_value(njs_vm_t *vm, njs_value_t *wrapper,
     const njs_value_t *value)
 {
-    njs_int_t           ret;
-    njs_object_prop_t   *prop;
-    njs_lvlhsh_query_t  lhq;
+    njs_int_t            ret;
+    njs_object_prop_t    *prop;
+    njs_flathsh_query_t  lhq;
 
     wrapper->data.u.object = njs_object_alloc(vm);
     if (njs_slow_path(njs_object(wrapper) == NULL)) {
@@ -1600,20 +1609,18 @@ njs_json_wrap_value(njs_vm_t *vm, njs_value_t *wrapper,
     wrapper->type = NJS_OBJECT;
     wrapper->data.truth = 1;
 
-    lhq.replace = 0;
-    lhq.proto = &njs_object_hash_proto;
-    lhq.pool = vm->mem_pool;
-    lhq.key = njs_str_value("");
-    lhq.key_hash = NJS_DJB_HASH_INIT;
-
-    prop = njs_object_prop_alloc(vm, &njs_string_empty, value, 1);
+    prop = njs_object_prop_alloc(vm, value, 1);
     if (njs_slow_path(prop == NULL)) {
         return NULL;
     }
 
     lhq.value = prop;
+    lhq.key_hash = NJS_ATOM_STRING_empty;
+    lhq.replace = 0;
+    lhq.pool = vm->mem_pool;
+    lhq.proto = &njs_object_hash_proto;
 
-    ret = njs_lvlhsh_insert(njs_object_hash(wrapper), &lhq);
+    ret = njs_flathsh_unique_insert(njs_object_hash(wrapper), &lhq);
     if (njs_slow_path(ret != NJS_OK)) {
         return NULL;
     }
@@ -1622,18 +1629,14 @@ njs_json_wrap_value(njs_vm_t *vm, njs_value_t *wrapper,
 }
 
 
-static const njs_object_prop_t  njs_json_object_properties[] =
+static const njs_object_prop_init_t  njs_json_object_properties[] =
 {
-    {
-        .type = NJS_PROPERTY,
-        .name = njs_wellknown_symbol(NJS_SYMBOL_TO_STRING_TAG),
-        .u.value = njs_string("JSON"),
-        .configurable = 1,
-    },
+    NJS_DECLARE_PROP_VALUE(SYMBOL_toStringTag, njs_ascii_strval("JSON"),
+                           NJS_OBJECT_PROP_VALUE_C),
 
-    NJS_DECLARE_PROP_NATIVE("parse", njs_json_parse, 2, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_parse, njs_json_parse, 2, 0),
 
-    NJS_DECLARE_PROP_NATIVE("stringify", njs_json_stringify, 3, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_stringify, njs_json_stringify, 3, 0),
 };
 
 
@@ -1653,8 +1656,6 @@ njs_dump_terminal(njs_json_stringify_t *stringify, njs_chb_t *chain,
     njs_typed_array_t  *array;
     njs_string_prop_t  string;
 
-    static const njs_value_t  name_string = njs_string("name");
-
     njs_int_t   (*to_string)(njs_vm_t *, njs_value_t *, const njs_value_t *);
 
     switch (value->type) {
@@ -1677,10 +1678,10 @@ njs_dump_terminal(njs_json_stringify_t *stringify, njs_chb_t *chain,
         break;
 
     case NJS_STRING:
-        njs_string_get(value, &str);
+        njs_string_get(stringify->vm, value, &str);
 
         if (!console || stringify->depth != 0) {
-            njs_json_append_string(chain, value, '\'');
+            njs_json_append_string(stringify->vm, chain, value, '\'');
             return NJS_OK;
         }
 
@@ -1694,7 +1695,7 @@ njs_dump_terminal(njs_json_stringify_t *stringify, njs_chb_t *chain,
             return NJS_ERROR;
         }
 
-        njs_string_get(&str_val, &str);
+        njs_string_get(stringify->vm, &str_val, &str);
         njs_chb_append_str(chain, &str);
 
         break;
@@ -1731,7 +1732,7 @@ njs_dump_terminal(njs_json_stringify_t *stringify, njs_chb_t *chain,
                 return NJS_ERROR;
             }
 
-            njs_string_get(&str_val, &str);
+            njs_string_get(stringify->vm, &str_val, &str);
             njs_chb_sprintf(chain, 16 + str.length, "[Number: %V]", &str);
             break;
 
@@ -1741,7 +1742,7 @@ njs_dump_terminal(njs_json_stringify_t *stringify, njs_chb_t *chain,
                 return NJS_ERROR;
             }
 
-            njs_string_get(&str_val, &str);
+            njs_string_get(stringify->vm, &str_val, &str);
             njs_chb_sprintf(chain, 16 + str.length, "[Symbol: %V]", &str);
 
             break;
@@ -1749,7 +1750,7 @@ njs_dump_terminal(njs_json_stringify_t *stringify, njs_chb_t *chain,
         case NJS_STRING:
         default:
             njs_chb_append_literal(chain, "[String: ");
-            njs_json_append_string(chain, value, '\'');
+            njs_json_append_string(stringify->vm, chain, value, '\'');
             njs_chb_append_literal(chain, "]");
             break;
         }
@@ -1764,14 +1765,14 @@ njs_dump_terminal(njs_json_stringify_t *stringify, njs_chb_t *chain,
             str = njs_str_value("");
         }
 
-        ret = njs_value_property(stringify->vm, value,
-                                 njs_value_arg(&name_string), &tag);
+        ret = njs_value_property(stringify->vm, value, NJS_ATOM_STRING_name,
+                                 &tag);
         if (njs_slow_path(ret == NJS_ERROR)) {
             return ret;
         }
 
         if (njs_is_string(&tag)) {
-            njs_string_get(&tag, &str);
+            njs_string_get(stringify->vm, &tag, &str);
         }
 
         if (str.length != 0) {
@@ -1791,7 +1792,7 @@ njs_dump_terminal(njs_json_stringify_t *stringify, njs_chb_t *chain,
         }
 
         if (ret == NJS_OK) {
-            (void) njs_string_prop(&string, &tag);
+            (void) njs_string_prop(stringify->vm, &string, &tag);
             njs_chb_append(chain, string.start, string.size);
             njs_chb_append_literal(chain, " ");
         }
@@ -1841,7 +1842,7 @@ njs_dump_terminal(njs_json_stringify_t *stringify, njs_chb_t *chain,
             return NJS_ERROR;
         }
 
-        njs_string_get(&str_val, &str);
+        njs_string_get(stringify->vm, &str_val, &str);
         njs_chb_append_str(chain, &str);
 
         break;
@@ -1874,7 +1875,7 @@ njs_dump_visited(njs_vm_t *vm, njs_json_stringify_t *stringify,
     depth = stringify->depth - 1;
 
     for (; depth >= 0; depth--) {
-        if (njs_values_same(&stringify->states[depth].value, value)) {
+        if (njs_values_same(vm, &stringify->states[depth].value, value)) {
             return 1;
         }
     }
@@ -1943,11 +1944,6 @@ njs_dump_empty(njs_json_stringify_t *stringify, njs_json_state_t *state,
 }
 
 
-static const njs_value_t  string_get = njs_string("[Getter]");
-static const njs_value_t  string_set = njs_string("[Setter]");
-static const njs_value_t  string_get_set = njs_long_string("[Getter/Setter]");
-
-
 njs_int_t
 njs_vm_value_dump(njs_vm_t *vm, njs_str_t *retval, njs_value_t *value,
     njs_uint_t console, njs_uint_t indent)
@@ -1955,7 +1951,7 @@ njs_vm_value_dump(njs_vm_t *vm, njs_str_t *retval, njs_value_t *value,
     njs_int_t             ret;
     njs_chb_t             chain;
     njs_str_t             str;
-    njs_value_t           *key, *val, tag, exception;
+    njs_value_t           *key, *val, s, tag, exception;
     njs_json_state_t      *state;
     njs_string_prop_t     string;
     njs_object_prop_t     *prop;
@@ -2009,7 +2005,7 @@ njs_vm_value_dump(njs_vm_t *vm, njs_str_t *retval, njs_value_t *value,
             }
 
             if (ret == NJS_OK) {
-                (void) njs_string_prop(&string, &tag);
+                (void) njs_string_prop(vm, &string, &tag);
                 njs_chb_append(&chain, string.start, string.size);
                 njs_chb_append_literal(&chain, " ");
             }
@@ -2032,22 +2028,17 @@ njs_vm_value_dump(njs_vm_t *vm, njs_str_t *retval, njs_value_t *value,
             continue;
         }
 
-        njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0, 0);
+        njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0);
 
         key = &state->keys->start[state->index++];
 
-        if(state->array) {
-            if (key->type == NJS_STRING) {
-                njs_string_get(key, &str);
-                if (str.length == 6 && memcmp(str.start, "length", 6) == 0) {
-                    continue;
-                }
-            }
+        if (state->array && key->atom_id == NJS_ATOM_STRING_length) {
+            continue;
         }
 
         state->key = key;
 
-        ret = njs_property_query(vm, &pq, &state->value, key);
+        ret = njs_property_query_val(vm, &pq, &state->value, key);
         if (njs_slow_path(ret != NJS_OK)) {
             if (ret == NJS_DECLINED) {
                 continue;
@@ -2074,7 +2065,7 @@ njs_vm_value_dump(njs_vm_t *vm, njs_str_t *retval, njs_value_t *value,
         njs_dump_empty(stringify, state, &chain, 1);
 
         if (!state->array || isnan(njs_key_to_index(key))) {
-            njs_key_string_get(vm, key, &pq.lhq.key);
+            njs_atom_string_get(vm, key->atom_id, &pq.lhq.key);
             njs_chb_append(&chain, pq.lhq.key.start, pq.lhq.key.length);
             njs_chb_append_literal(&chain, ":");
             if (stringify->space.length != 0) {
@@ -2087,7 +2078,8 @@ njs_vm_value_dump(njs_vm_t *vm, njs_str_t *retval, njs_value_t *value,
         if (prop->type == NJS_PROPERTY_HANDLER) {
             pq.scratch = *prop;
             prop = &pq.scratch;
-            ret = njs_prop_handler(prop)(vm, prop, &state->value, NULL,
+            ret = njs_prop_handler(prop)(vm, prop, pq.lhq.key_hash,
+                                         &state->value, NULL,
                                          njs_prop_value(prop));
 
             if (njs_slow_path(ret == NJS_ERROR)) {
@@ -2100,15 +2092,17 @@ njs_vm_value_dump(njs_vm_t *vm, njs_str_t *retval, njs_value_t *value,
         if (njs_is_accessor_descriptor(prop)) {
             if (njs_prop_getter(prop) != NULL) {
                 if (njs_prop_setter(prop) != NULL) {
-                    val = njs_value_arg(&string_get_set);
+                    njs_atom_to_value(vm, &s, NJS_ATOM_STRING__Getter_Setter_);
 
                 } else {
-                    val = njs_value_arg(&string_get);
+                    njs_atom_to_value(vm, &s, NJS_ATOM_STRING__Getter_);
                 }
 
             } else {
-                val = njs_value_arg(&string_set);
+                njs_atom_to_value(vm, &s, NJS_ATOM_STRING__Setter_);
             }
+
+            val = &s;
         }
 
         if (njs_dump_is_recursive(val)) {
diff --git a/src/njs_lexer.c b/src/njs_lexer.c
index 4a51c668..4131301d 100644
--- a/src/njs_lexer.c
+++ b/src/njs_lexer.c
@@ -18,7 +18,6 @@ struct njs_lexer_multi_s {
 };
 
 
-static njs_int_t njs_lexer_hash_test(njs_lvlhsh_query_t *lhq, void *data);
 static njs_int_t njs_lexer_word(njs_lexer_t *lexer, njs_lexer_token_t *token);
 static void njs_lexer_string(njs_lexer_t *lexer, njs_lexer_token_t *token,
     u_char quote);
@@ -28,16 +27,6 @@ static void njs_lexer_multi(njs_lexer_t *lexer, njs_lexer_token_t *token,
 static void njs_lexer_division(njs_lexer_t *lexer, njs_lexer_token_t *token);
 
 
-const njs_lvlhsh_proto_t  njs_lexer_hash_proto
-    njs_aligned(64) =
-{
-    NJS_LVLHSH_DEFAULT,
-    njs_lexer_hash_test,
-    njs_lvlhsh_alloc,
-    njs_lvlhsh_free,
-};
-
-
 static const uint8_t  njs_tokens[256]  njs_aligned(64) = {
 
                 NJS_TOKEN_ILLEGAL,           NJS_TOKEN_ILLEGAL,
@@ -290,21 +279,13 @@ static const njs_lexer_multi_t  njs_assignment_token[] = {
 
 njs_int_t
 njs_lexer_init(njs_vm_t *vm, njs_lexer_t *lexer, njs_str_t *file,
-    u_char *start, u_char *end, njs_uint_t runtime,
-    njs_int_t init_lexer_memory)
+    u_char *start, u_char *end)
 {
-    if (init_lexer_memory) {
-        njs_memzero(lexer, sizeof(njs_lexer_t));
-
-    }
-
     lexer->file = *file;
     lexer->start = start;
     lexer->end = end;
     lexer->line = 1;
-    lexer->keywords_hash = (runtime) ? &vm->keywords_hash
-                                     : &vm->shared->keywords_hash;
-    lexer->mem_pool = vm->mem_pool;
+    lexer->vm = vm;
 
     njs_queue_init(&lexer->preread);
 
@@ -316,7 +297,7 @@ njs_int_t
 njs_lexer_in_stack_init(njs_lexer_t *lexer)
 {
     lexer->in_stack_size = 128;
-    lexer->in_stack = njs_mp_zalloc(lexer->mem_pool, lexer->in_stack_size);
+    lexer->in_stack = njs_mp_zalloc(lexer->vm->mem_pool, lexer->in_stack_size);
     if (lexer->in_stack == NULL) {
         return NJS_ERROR;
     }
@@ -345,7 +326,7 @@ njs_lexer_in_stack_push(njs_lexer_t *lexer)
     size = lexer->in_stack_size;
     lexer->in_stack_size = size * 2;
 
-    tmp = njs_mp_alloc(lexer->mem_pool, size * 2);
+    tmp = njs_mp_alloc(lexer->vm->mem_pool, size * 2);
     if (tmp == NULL) {
         return NJS_ERROR;
     }
@@ -353,7 +334,7 @@ njs_lexer_in_stack_push(njs_lexer_t *lexer)
     memcpy(tmp, lexer->in_stack, size);
     memset(&tmp[size], 0, size);
 
-    njs_mp_free(lexer->mem_pool, lexer->in_stack);
+    njs_mp_free(lexer->vm->mem_pool, lexer->in_stack);
     lexer->in_stack = tmp;
 
     return NJS_OK;
@@ -417,7 +398,7 @@ njs_lexer_next_token(njs_lexer_t *lexer)
     njs_int_t          ret;
     njs_lexer_token_t  *token;
 
-    token = njs_mp_zalloc(lexer->mem_pool, sizeof(njs_lexer_token_t));
+    token = njs_mp_zalloc(lexer->vm->mem_pool, sizeof(njs_lexer_token_t));
     if (njs_slow_path(token == NULL)) {
         return NULL;
     }
@@ -537,7 +518,7 @@ njs_lexer_consume_token(njs_lexer_t *lexer, unsigned length)
 
         njs_queue_remove(lnk);
 
-        njs_mp_free(lexer->mem_pool, token);
+        njs_mp_free(lexer->vm->mem_pool, token);
     }
 }
 
@@ -709,76 +690,12 @@ njs_lexer_make_token(njs_lexer_t *lexer, njs_lexer_token_t *token)
 }
 
 
-static njs_int_t
-njs_lexer_hash_test(njs_lvlhsh_query_t *lhq, void *data)
-{
-    njs_lexer_entry_t  *entry;
-
-    entry = data;
-
-    if (entry->name.length == lhq->key.length
-        && memcmp(entry->name.start, lhq->key.start, lhq->key.length) == 0)
-    {
-        return NJS_OK;
-    }
-
-    return NJS_DECLINED;
-}
-
-
-static njs_lexer_entry_t *
-njs_lexer_keyword_find(njs_lexer_t *lexer, u_char *key, size_t length,
-    uint32_t hash)
-{
-    njs_int_t           ret;
-    njs_lexer_entry_t   *entry;
-    njs_lvlhsh_query_t  lhq;
-
-    lhq.key.start = key;
-    lhq.key.length = length;
-
-    lhq.key_hash = hash;
-    lhq.proto = &njs_lexer_hash_proto;
-
-    ret = njs_lvlhsh_find(lexer->keywords_hash, &lhq);
-    if (ret == NJS_OK) {
-        return lhq.value;
-    }
-
-    entry = njs_mp_alloc(lexer->mem_pool, sizeof(njs_lexer_entry_t));
-    if (njs_slow_path(entry == NULL)) {
-        return NULL;
-    }
-
-    entry->name.start = njs_mp_alloc(lexer->mem_pool, length + 1);
-    if (njs_slow_path(entry->name.start == NULL)) {
-        return NULL;
-    }
-
-    memcpy(entry->name.start, key, length);
-
-    entry->name.start[length] = '\0';
-    entry->name.length = length;
-
-    lhq.value = entry;
-    lhq.pool = lexer->mem_pool;
-
-    ret = njs_lvlhsh_insert(lexer->keywords_hash, &lhq);
-    if (njs_slow_path(ret != NJS_OK)) {
-        return NULL;
-    }
-
-    return entry;
-}
-
-
 static njs_int_t
 njs_lexer_word(njs_lexer_t *lexer, njs_lexer_token_t *token)
 {
-    u_char                           *p, c;
-    uint32_t                         hash_id;
-    const njs_lexer_entry_t          *entry;
-    const njs_lexer_keyword_entry_t  *key_entry;
+    u_char             *p, c;
+    uint32_t           hash_id;
+    const njs_value_t  *entry;
 
     /* TODO: UTF-8 */
 
@@ -817,27 +734,23 @@ njs_lexer_word(njs_lexer_t *lexer, njs_lexer_token_t *token)
     token->text.length = p - token->text.start;
     lexer->start = p;
 
-    key_entry = njs_lexer_keyword(token->text.start, token->text.length);
-
-    if (key_entry == NULL) {
-        entry = njs_lexer_keyword_find(lexer, token->text.start,
-                                       token->text.length, hash_id);
-        if (njs_slow_path(entry == NULL)) {
-            return NJS_ERROR;
-        }
+    entry = njs_atom_find_or_add(lexer->vm, token->text.start,
+                                 token->text.length, token->text.length,
+                                 hash_id);
+    if (njs_slow_path(entry == NULL)) {
+        return NJS_ERROR;
+    }
 
+    if (entry->string.token_type == NJS_KEYWORD_TYPE_UNDEF) {
         token->type = NJS_TOKEN_NAME;
         token->keyword_type = NJS_KEYWORD_TYPE_UNDEF;
 
     } else {
-        entry = &key_entry->value->entry;
-        token->type = key_entry->value->type;
-
-        token->keyword_type = NJS_KEYWORD_TYPE_KEYWORD;
-        token->keyword_type |= key_entry->value->reserved;
+        token->type = entry->string.token_id;
+        token->keyword_type = entry->string.token_type;
     }
 
-    token->unique_id = (uintptr_t) entry;
+    token->atom_id = entry->atom_id;
 
     return NJS_OK;
 }
diff --git a/src/njs_lexer.h b/src/njs_lexer.h
index 6b1d04b6..42f612a6 100644
--- a/src/njs_lexer.h
+++ b/src/njs_lexer.h
@@ -219,12 +219,6 @@ typedef enum {
 
 
 typedef struct {
-    njs_str_t                       name;
-} njs_lexer_entry_t;
-
-
-typedef struct {
-    njs_lexer_entry_t               entry;
     njs_token_type_t                type;
     njs_bool_t                      reserved;
 } njs_keyword_t;
@@ -243,7 +237,7 @@ typedef struct {
     njs_token_type_t                type:16;
     njs_keyword_type_t              keyword_type;
     uint32_t                        line;
-    uintptr_t                       unique_id;
+    uint32_t                        atom_id;
     njs_str_t                       text;
     double                          number;
     njs_queue_link_t                link;
@@ -261,9 +255,7 @@ typedef struct {
     uint32_t                        line;
     njs_str_t                       file;
 
-    njs_lvlhsh_t                    *keywords_hash;
-
-    njs_mp_t                        *mem_pool;
+    njs_vm_t                        *vm;
 
     u_char                          *start;
     u_char                          *end;
@@ -276,8 +268,7 @@ typedef struct {
 
 
 njs_int_t njs_lexer_init(njs_vm_t *vm, njs_lexer_t *lexer, njs_str_t *file,
-    u_char *start, u_char *end, njs_uint_t runtime,
-    njs_int_t init_lexer_memory);
+    u_char *start, u_char *end);
 
 njs_lexer_token_t *njs_lexer_token(njs_lexer_t *lexer,
     njs_bool_t with_end_line);
@@ -297,10 +288,13 @@ const njs_lexer_keyword_entry_t *njs_lexer_keyword(const u_char *key,
 njs_int_t njs_lexer_keywords(njs_arr_t *array);
 
 
-njs_inline const njs_lexer_entry_t *
-njs_lexer_entry(uintptr_t unique_id)
+njs_inline void
+njs_lexer_entry(njs_vm_t *vm, uintptr_t atom_id, njs_str_t *entry)
 {
-    return (const njs_lexer_entry_t *) unique_id;
+    njs_value_t  value;
+
+    njs_atom_to_value(vm, &value, atom_id);
+    njs_string_get(vm, &value, entry);
 }
 
 
@@ -363,8 +357,4 @@ njs_lexer_token_is_identifier_reference(njs_lexer_token_t *token)
     return njs_lexer_token_is_binding_identifier(token);
 }
 
-
-extern const njs_lvlhsh_proto_t  njs_lexer_hash_proto;
-
-
 #endif /* _NJS_LEXER_H_INCLUDED_ */
diff --git a/src/njs_lexer_tables.h b/src/njs_lexer_tables.h
deleted file mode 100644
index e6503252..00000000
--- a/src/njs_lexer_tables.h
+++ /dev/null
@@ -1,445 +0,0 @@
-
-/*
- * Copyright (C) Nginx, Inc.
- *
- * Do not edit, generated by: utils/lexer_keyword.py.
- */
-
-
-#ifndef _NJS_LEXER_TABLES_H_INCLUDED_
-#define _NJS_LEXER_TABLES_H_INCLUDED_
-
-
-static const njs_keyword_t njs_lexer_kws[54] =
-{
-    {
-        .entry = { njs_str("arguments") },
-        .type = NJS_TOKEN_ARGUMENTS,
-        .reserved = 0
-    },
-
-    {
-        .entry = { njs_str("async") },
-        .type = NJS_TOKEN_ASYNC,
-        .reserved = 0
-    },
-
-    {
-        .entry = { njs_str("await") },
-        .type = NJS_TOKEN_AWAIT,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("break") },
-        .type = NJS_TOKEN_BREAK,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("case") },
-        .type = NJS_TOKEN_CASE,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("catch") },
-        .type = NJS_TOKEN_CATCH,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("class") },
-        .type = NJS_TOKEN_CLASS,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("const") },
-        .type = NJS_TOKEN_CONST,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("continue") },
-        .type = NJS_TOKEN_CONTINUE,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("debugger") },
-        .type = NJS_TOKEN_DEBUGGER,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("default") },
-        .type = NJS_TOKEN_DEFAULT,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("delete") },
-        .type = NJS_TOKEN_DELETE,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("do") },
-        .type = NJS_TOKEN_DO,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("else") },
-        .type = NJS_TOKEN_ELSE,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("enum") },
-        .type = NJS_TOKEN_ENUM,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("eval") },
-        .type = NJS_TOKEN_EVAL,
-        .reserved = 0
-    },
-
-    {
-        .entry = { njs_str("export") },
-        .type = NJS_TOKEN_EXPORT,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("extends") },
-        .type = NJS_TOKEN_EXTENDS,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("false") },
-        .type = NJS_TOKEN_FALSE,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("finally") },
-        .type = NJS_TOKEN_FINALLY,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("for") },
-        .type = NJS_TOKEN_FOR,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("from") },
-        .type = NJS_TOKEN_FROM,
-        .reserved = 0
-    },
-
-    {
-        .entry = { njs_str("function") },
-        .type = NJS_TOKEN_FUNCTION,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("if") },
-        .type = NJS_TOKEN_IF,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("implements") },
-        .type = NJS_TOKEN_IMPLEMENTS,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("import") },
-        .type = NJS_TOKEN_IMPORT,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("in") },
-        .type = NJS_TOKEN_IN,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("instanceof") },
-        .type = NJS_TOKEN_INSTANCEOF,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("interface") },
-        .type = NJS_TOKEN_INTERFACE,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("let") },
-        .type = NJS_TOKEN_LET,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("meta") },
-        .type = NJS_TOKEN_META,
-        .reserved = 0
-    },
-
-    {
-        .entry = { njs_str("new") },
-        .type = NJS_TOKEN_NEW,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("null") },
-        .type = NJS_TOKEN_NULL,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("of") },
-        .type = NJS_TOKEN_OF,
-        .reserved = 0
-    },
-
-    {
-        .entry = { njs_str("package") },
-        .type = NJS_TOKEN_PACKAGE,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("private") },
-        .type = NJS_TOKEN_PRIVATE,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("protected") },
-        .type = NJS_TOKEN_PROTECTED,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("public") },
-        .type = NJS_TOKEN_PUBLIC,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("return") },
-        .type = NJS_TOKEN_RETURN,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("static") },
-        .type = NJS_TOKEN_STATIC,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("super") },
-        .type = NJS_TOKEN_SUPER,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("switch") },
-        .type = NJS_TOKEN_SWITCH,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("target") },
-        .type = NJS_TOKEN_TARGET,
-        .reserved = 0
-    },
-
-    {
-        .entry = { njs_str("this") },
-        .type = NJS_TOKEN_THIS,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("throw") },
-        .type = NJS_TOKEN_THROW,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("true") },
-        .type = NJS_TOKEN_TRUE,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("try") },
-        .type = NJS_TOKEN_TRY,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("typeof") },
-        .type = NJS_TOKEN_TYPEOF,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("undefined") },
-        .type = NJS_TOKEN_UNDEFINED,
-        .reserved = 0
-    },
-
-    {
-        .entry = { njs_str("var") },
-        .type = NJS_TOKEN_VAR,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("void") },
-        .type = NJS_TOKEN_VOID,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("while") },
-        .type = NJS_TOKEN_WHILE,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("with") },
-        .type = NJS_TOKEN_WITH,
-        .reserved = 1
-    },
-
-    {
-        .entry = { njs_str("yield") },
-        .type = NJS_TOKEN_YIELD,
-        .reserved = 1
-    },
-};
-
-
-static const njs_lexer_keyword_entry_t njs_lexer_keyword_entries[99] =
-{
-    { NULL, NULL, 98, 0 },
-    { "continue", &njs_lexer_kws[8], 8, 0 },
-    { "finally", &njs_lexer_kws[19], 7, 0 },
-    { "return", &njs_lexer_kws[38], 6, 0 },
-    { "static", &njs_lexer_kws[39], 6, 0 },
-    { "async", &njs_lexer_kws[1], 5, 0 },
-    { "break", &njs_lexer_kws[3], 5, 0 },
-    { "interface", &njs_lexer_kws[28], 9, 0 },
-    { "case", &njs_lexer_kws[4], 4, 0 },
-    { "import", &njs_lexer_kws[25], 6, 0 },
-    { "protected", &njs_lexer_kws[36], 9, 0 },
-    { "switch", &njs_lexer_kws[41], 6, 0 },
-    { "catch", &njs_lexer_kws[5], 5, 1 },
-    { "delete", &njs_lexer_kws[11], 6, 0 },
-    { "else", &njs_lexer_kws[13], 4, 0 },
-    { "private", &njs_lexer_kws[35], 7, 0 },
-    { "extends", &njs_lexer_kws[17], 7, 0 },
-    { "this", &njs_lexer_kws[43], 4, 0 },
-    { "false", &njs_lexer_kws[18], 5, 0 },
-    { "await", &njs_lexer_kws[2], 5, 0 },
-    { NULL, NULL, 0, 0 },
-    { "public", &njs_lexer_kws[37], 6, 0 },
-    { NULL, NULL, 0, 0 },
-    { "class", &njs_lexer_kws[6], 5, 0 },
-    { "const", &njs_lexer_kws[7], 5, 4 },
-    { NULL, NULL, 0, 0 },
-    { "try", &njs_lexer_kws[46], 3, 0 },
-    { "null", &njs_lexer_kws[32], 4, 0 },
-    { NULL, NULL, 0, 0 },
-    { "do", &njs_lexer_kws[12], 2, 0 },
-    { "var", &njs_lexer_kws[49], 3, 0 },
-    { "if", &njs_lexer_kws[23], 2, 7 },
-    { "implements", &njs_lexer_kws[24], 10, 0 },
-    { "with", &njs_lexer_kws[52], 4, 0 },
-    { NULL, NULL, 0, 0 },
-    { "eval", &njs_lexer_kws[15], 4, 9 },
-    { NULL, NULL, 0, 0 },
-    { "target", &njs_lexer_kws[42], 6, 0 },
-    { "enum", &njs_lexer_kws[14], 4, 10 },
-    { "instanceof", &njs_lexer_kws[27], 10, 0 },
-    { NULL, NULL, 0, 0 },
-    { "debugger", &njs_lexer_kws[9], 8, 0 },
-    { NULL, NULL, 0, 0 },
-    { NULL, NULL, 0, 0 },
-    { "default", &njs_lexer_kws[10], 7, 0 },
-    { "void", &njs_lexer_kws[50], 4, 0 },
-    { NULL, NULL, 0, 0 },
-    { NULL, NULL, 0, 0 },
-    { "undefined", &njs_lexer_kws[48], 9, 0 },
-    { "from", &njs_lexer_kws[21], 4, 0 },
-    { "package", &njs_lexer_kws[34], 7, 15 },
-    { NULL, NULL, 0, 0 },
-    { "yield", &njs_lexer_kws[53], 5, 0 },
-    { NULL, NULL, 0, 0 },
-    { NULL, NULL, 0, 0 },
-    { "of", &njs_lexer_kws[33], 2, 0 },
-    { NULL, NULL, 0, 0 },
-    { "function", &njs_lexer_kws[22], 8, 0 },
-    { NULL, NULL, 0, 0 },
-    { "true", &njs_lexer_kws[45], 4, 16 },
-    { "new", &njs_lexer_kws[31], 3, 0 },
-    { "export", &njs_lexer_kws[16], 6, 0 },
-    { NULL, NULL, 0, 0 },
-    { NULL, NULL, 0, 0 },
-    { NULL, NULL, 0, 0 },
-    { NULL, NULL, 0, 0 },
-    { NULL, NULL, 0, 0 },
-    { NULL, NULL, 0, 0 },
-    { "for", &njs_lexer_kws[20], 3, 0 },
-    { "while", &njs_lexer_kws[51], 5, 0 },
-    { NULL, NULL, 0, 0 },
-    { NULL, NULL, 0, 0 },
-    { NULL, NULL, 0, 0 },
-    { NULL, NULL, 0, 0 },
-    { NULL, NULL, 0, 0 },
-    { NULL, NULL, 0, 0 },
-    { NULL, NULL, 0, 0 },
-    { NULL, NULL, 0, 0 },
-    { NULL, NULL, 0, 0 },
-    { "typeof", &njs_lexer_kws[47], 6, 0 },
-    { NULL, NULL, 0, 0 },
-    { NULL, NULL, 0, 0 },
-    { "super", &njs_lexer_kws[40], 5, 0 },
-    { NULL, NULL, 0, 0 },
-    { NULL, NULL, 0, 0 },
-    { NULL, NULL, 0, 0 },
-    { "let", &njs_lexer_kws[29], 3, 19 },
-    { "in", &njs_lexer_kws[26], 2, 0 },
-    { NULL, NULL, 0, 0 },
-    { NULL, NULL, 0, 0 },
-    { "throw", &njs_lexer_kws[44], 5, 0 },
-    { "arguments", &njs_lexer_kws[0], 9, 0 },
-    { "meta", &njs_lexer_kws[30], 4, 0 },
-    { NULL, NULL, 0, 0 },
-    { NULL, NULL, 0, 0 },
-    { NULL, NULL, 0, 0 },
-    { NULL, NULL, 0, 0 },
-    { NULL, NULL, 0, 0 },
-    { NULL, NULL, 0, 0 },
-};
-
-
-#endif /* _NJS_LEXER_TABLES_H_INCLUDED_ */
diff --git a/src/njs_main.h b/src/njs_main.h
index 563065a1..e40fe085 100644
--- a/src/njs_main.h
+++ b/src/njs_main.h
@@ -45,6 +45,8 @@
 #include <njs_vm.h>
 #include <njs_object_prop_declare.h>
 #include <njs_error.h>
+#include <njs_string.h>
+#include <njs_atom.h>
 #include <njs_number.h>
 #include <njs_value_conversion.h>
 #include <njs_vmcode.h>
@@ -56,9 +58,7 @@
 
 #include <njs_boolean.h>
 #include <njs_symbol.h>
-#include <njs_string.h>
 #include <njs_object.h>
-#include <njs_object_hash.h>
 #include <njs_array.h>
 #include <njs_array_buffer.h>
 #include <njs_typed_array.h>
diff --git a/src/njs_math.c b/src/njs_math.c
index 6bc76fd1..b2892e7e 100644
--- a/src/njs_math.c
+++ b/src/njs_math.c
@@ -374,101 +374,132 @@ njs_object_math_random(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 }
 
 
-static const njs_object_prop_t  njs_math_object_properties[] =
+static const njs_object_prop_init_t  njs_math_object_properties[] =
 {
-    {
-        .type = NJS_PROPERTY,
-        .name = njs_wellknown_symbol(NJS_SYMBOL_TO_STRING_TAG),
-        .u.value = njs_string("Math"),
-        .configurable = 1,
-    },
+    NJS_DECLARE_PROP_VALUE(SYMBOL_toStringTag, njs_ascii_strval("Math"),
+                           NJS_OBJECT_PROP_VALUE_C),
 
-    NJS_DECLARE_PROP_VALUE("E", njs_value(NJS_NUMBER, 1, M_E), 0),
+    NJS_DECLARE_PROP_VALUE(STRING_E, njs_value(NJS_NUMBER, 1, M_E), 0),
 
-    NJS_DECLARE_PROP_VALUE("LN10", njs_value(NJS_NUMBER, 1, M_LN10), 0),
+    NJS_DECLARE_PROP_VALUE(STRING_LN10, njs_value(NJS_NUMBER, 1, M_LN10),
+                           0),
 
-    NJS_DECLARE_PROP_VALUE("LN2", njs_value(NJS_NUMBER, 1, M_LN2), 0),
+    NJS_DECLARE_PROP_VALUE(STRING_LN2, njs_value(NJS_NUMBER, 1, M_LN2), 0),
 
-    NJS_DECLARE_PROP_VALUE("LOG10E", njs_value(NJS_NUMBER, 1, M_LOG10E), 0),
+    NJS_DECLARE_PROP_VALUE(STRING_LOG10E,
+                           njs_value(NJS_NUMBER, 1, M_LOG10E), 0),
 
-    NJS_DECLARE_PROP_VALUE("LOG2E", njs_value(NJS_NUMBER, 1, M_LOG2E), 0),
+    NJS_DECLARE_PROP_VALUE(STRING_LOG2E, njs_value(NJS_NUMBER, 1, M_LOG2E),
+                           0),
 
-    NJS_DECLARE_PROP_VALUE("PI", njs_value(NJS_NUMBER, 1, M_PI), 0),
+    NJS_DECLARE_PROP_VALUE(STRING_PI, njs_value(NJS_NUMBER, 1, M_PI), 0),
 
-    NJS_DECLARE_PROP_VALUE("SQRT1_2", njs_value(NJS_NUMBER, 1, M_SQRT1_2), 0),
+    NJS_DECLARE_PROP_VALUE(STRING_SQRT1_2,
+                           njs_value(NJS_NUMBER, 1, M_SQRT1_2), 0),
 
-    NJS_DECLARE_PROP_VALUE("SQRT2", njs_value(NJS_NUMBER, 1, M_SQRT2), 0),
+    NJS_DECLARE_PROP_VALUE(STRING_SQRT2, njs_value(NJS_NUMBER, 1, M_SQRT2),
+                           0),
 
-    NJS_DECLARE_PROP_NATIVE("abs", njs_object_math_func, 1, NJS_MATH_ABS),
+    NJS_DECLARE_PROP_NATIVE(STRING_abs, njs_object_math_func, 1,
+                            NJS_MATH_ABS),
 
-    NJS_DECLARE_PROP_NATIVE("acos", njs_object_math_func, 1, NJS_MATH_ACOS),
+    NJS_DECLARE_PROP_NATIVE(STRING_acos, njs_object_math_func, 1,
+                            NJS_MATH_ACOS),
 
-    NJS_DECLARE_PROP_NATIVE("acosh", njs_object_math_func, 1, NJS_MATH_ACOSH),
+    NJS_DECLARE_PROP_NATIVE(STRING_acosh, njs_object_math_func, 1,
+                            NJS_MATH_ACOSH),
 
-    NJS_DECLARE_PROP_NATIVE("asin", njs_object_math_func, 1, NJS_MATH_ASIN),
+    NJS_DECLARE_PROP_NATIVE(STRING_asin, njs_object_math_func, 1,
+                            NJS_MATH_ASIN),
 
-    NJS_DECLARE_PROP_NATIVE("asinh", njs_object_math_func, 1, NJS_MATH_ASINH),
+    NJS_DECLARE_PROP_NATIVE(STRING_asinh, njs_object_math_func, 1,
+                            NJS_MATH_ASINH),
 
-    NJS_DECLARE_PROP_NATIVE("atan", njs_object_math_func, 1, NJS_MATH_ATAN),
+    NJS_DECLARE_PROP_NATIVE(STRING_atan, njs_object_math_func, 1,
+                            NJS_MATH_ATAN),
 
-    NJS_DECLARE_PROP_NATIVE("atan2", njs_object_math_func, 2, NJS_MATH_ATAN2),
+    NJS_DECLARE_PROP_NATIVE(STRING_atan2, njs_object_math_func, 2,
+                            NJS_MATH_ATAN2),
 
-    NJS_DECLARE_PROP_NATIVE("atanh", njs_object_math_func, 1, NJS_MATH_ATANH),
+    NJS_DECLARE_PROP_NATIVE(STRING_atanh, njs_object_math_func, 1,
+                            NJS_MATH_ATANH),
 
-    NJS_DECLARE_PROP_NATIVE("cbrt", njs_object_math_func, 1, NJS_MATH_CBRT),
+    NJS_DECLARE_PROP_NATIVE(STRING_cbrt, njs_object_math_func, 1,
+                            NJS_MATH_CBRT),
 
-    NJS_DECLARE_PROP_NATIVE("ceil", njs_object_math_func, 1, NJS_MATH_CEIL),
+    NJS_DECLARE_PROP_NATIVE(STRING_ceil, njs_object_math_func, 1,
+                            NJS_MATH_CEIL),
 
-    NJS_DECLARE_PROP_NATIVE("clz32", njs_object_math_func, 1, NJS_MATH_CLZ32),
+    NJS_DECLARE_PROP_NATIVE(STRING_clz32, njs_object_math_func, 1,
+                            NJS_MATH_CLZ32),
 
-    NJS_DECLARE_PROP_NATIVE("cos", njs_object_math_func, 1, NJS_MATH_COS),
+    NJS_DECLARE_PROP_NATIVE(STRING_cos, njs_object_math_func, 1,
+                            NJS_MATH_COS),
 
-    NJS_DECLARE_PROP_NATIVE("cosh", njs_object_math_func, 1, NJS_MATH_COSH),
+    NJS_DECLARE_PROP_NATIVE(STRING_cosh, njs_object_math_func, 1,
+                            NJS_MATH_COSH),
 
-    NJS_DECLARE_PROP_NATIVE("exp", njs_object_math_func, 1, NJS_MATH_EXP),
+    NJS_DECLARE_PROP_NATIVE(STRING_exp, njs_object_math_func, 1,
+                            NJS_MATH_EXP),
 
-    NJS_DECLARE_PROP_NATIVE("expm1", njs_object_math_func, 1, NJS_MATH_EXPM1),
+    NJS_DECLARE_PROP_NATIVE(STRING_expm1, njs_object_math_func, 1,
+                            NJS_MATH_EXPM1),
 
-    NJS_DECLARE_PROP_NATIVE("floor", njs_object_math_func, 1, NJS_MATH_FLOOR),
+    NJS_DECLARE_PROP_NATIVE(STRING_floor, njs_object_math_func, 1,
+                            NJS_MATH_FLOOR),
 
-    NJS_DECLARE_PROP_NATIVE("fround", njs_object_math_func, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_fround, njs_object_math_func, 1,
                             NJS_MATH_FROUND),
 
-    NJS_DECLARE_PROP_NATIVE("hypot", njs_object_math_hypot, 2, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_hypot, njs_object_math_hypot, 2, 0),
 
-    NJS_DECLARE_PROP_NATIVE("imul", njs_object_math_func, 2, NJS_MATH_IMUL),
+    NJS_DECLARE_PROP_NATIVE(STRING_imul, njs_object_math_func, 2,
+                            NJS_MATH_IMUL),
 
-    NJS_DECLARE_PROP_NATIVE("log", njs_object_math_func, 1, NJS_MATH_LOG),
+    NJS_DECLARE_PROP_NATIVE(STRING_log, njs_object_math_func, 1,
+                            NJS_MATH_LOG),
 
-    NJS_DECLARE_PROP_NATIVE("log10", njs_object_math_func, 1, NJS_MATH_LOG10),
+    NJS_DECLARE_PROP_NATIVE(STRING_log10, njs_object_math_func, 1,
+                            NJS_MATH_LOG10),
 
-    NJS_DECLARE_PROP_NATIVE("log1p", njs_object_math_func, 1, NJS_MATH_LOG1P),
+    NJS_DECLARE_PROP_NATIVE(STRING_log1p, njs_object_math_func, 1,
+                            NJS_MATH_LOG1P),
 
-    NJS_DECLARE_PROP_NATIVE("log2", njs_object_math_func, 1, NJS_MATH_LOG2),
+    NJS_DECLARE_PROP_NATIVE(STRING_log2, njs_object_math_func, 1,
+                            NJS_MATH_LOG2),
 
-    NJS_DECLARE_PROP_NATIVE("max", njs_object_math_min_max, 2, 1),
+    NJS_DECLARE_PROP_NATIVE(STRING_max, njs_object_math_min_max, 2, 1),
 
-    NJS_DECLARE_PROP_NATIVE("min", njs_object_math_min_max, 2, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_min, njs_object_math_min_max, 2, 0),
 
-    NJS_DECLARE_PROP_NATIVE("pow", njs_object_math_func, 2, NJS_MATH_POW),
+    NJS_DECLARE_PROP_NATIVE(STRING_pow, njs_object_math_func, 2,
+                            NJS_MATH_POW),
 
-    NJS_DECLARE_PROP_NATIVE("random", njs_object_math_random, 0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_random, njs_object_math_random, 0, 0),
 
-    NJS_DECLARE_PROP_NATIVE("round", njs_object_math_func, 1, NJS_MATH_ROUND),
+    NJS_DECLARE_PROP_NATIVE(STRING_round, njs_object_math_func, 1,
+                            NJS_MATH_ROUND),
 
-    NJS_DECLARE_PROP_NATIVE("sign", njs_object_math_func, 1, NJS_MATH_SIGN),
+    NJS_DECLARE_PROP_NATIVE(STRING_sign, njs_object_math_func, 1,
+                            NJS_MATH_SIGN),
 
-    NJS_DECLARE_PROP_NATIVE("sin", njs_object_math_func, 1, NJS_MATH_SIN),
+    NJS_DECLARE_PROP_NATIVE(STRING_sin, njs_object_math_func, 1,
+                            NJS_MATH_SIN),
 
-    NJS_DECLARE_PROP_NATIVE("sinh", njs_object_math_func, 1, NJS_MATH_SINH),
+    NJS_DECLARE_PROP_NATIVE(STRING_sinh, njs_object_math_func, 1,
+                            NJS_MATH_SINH),
 
-    NJS_DECLARE_PROP_NATIVE("sqrt", njs_object_math_func, 1, NJS_MATH_SQRT),
+    NJS_DECLARE_PROP_NATIVE(STRING_sqrt, njs_object_math_func, 1,
+                            NJS_MATH_SQRT),
 
-    NJS_DECLARE_PROP_NATIVE("tan", njs_object_math_func, 1, NJS_MATH_TAN),
+    NJS_DECLARE_PROP_NATIVE(STRING_tan, njs_object_math_func, 1,
+                            NJS_MATH_TAN),
 
-    NJS_DECLARE_PROP_NATIVE("tanh", njs_object_math_func, 1, NJS_MATH_TANH),
+    NJS_DECLARE_PROP_NATIVE(STRING_tanh, njs_object_math_func, 1,
+                            NJS_MATH_TANH),
 
-    NJS_DECLARE_PROP_NATIVE("trunc", njs_object_math_func, 1, NJS_MATH_TRUNC),
+    NJS_DECLARE_PROP_NATIVE(STRING_trunc, njs_object_math_func, 1,
+                            NJS_MATH_TRUNC),
 };
 
 
diff --git a/src/njs_module.c b/src/njs_module.c
index 5d9c96ae..5af174f3 100644
--- a/src/njs_module.c
+++ b/src/njs_module.c
@@ -144,7 +144,7 @@ njs_module_require(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return ret;
     }
 
-    njs_string_get(path, &name);
+    njs_string_get(vm, path, &name);
 
     module = njs_module_find(vm, &name, 0);
     if (njs_slow_path(module == NULL)) {
diff --git a/src/njs_number.c b/src/njs_number.c
index 4ca6456d..29df50a5 100644
--- a/src/njs_number.c
+++ b/src/njs_number.c
@@ -217,23 +217,22 @@ njs_int_t
 njs_number_to_string(njs_vm_t *vm, njs_value_t *string,
     const njs_value_t *number)
 {
-    double             num;
-    size_t             size;
-    const njs_value_t  *value;
-    u_char             buf[128];
+    double  num;
+    size_t  size;
+    u_char  buf[128];
 
     num = njs_number(number);
 
     if (isnan(num)) {
-        value = &njs_string_nan;
+        njs_atom_to_value(vm, string, NJS_ATOM_STRING_NaN);
 
     } else if (isinf(num)) {
 
         if (num < 0) {
-            value = &njs_string_minus_infinity;
+            njs_atom_to_value(vm, string, NJS_ATOM_STRING__Infinity);
 
         } else {
-            value = &njs_string_plus_infinity;
+            njs_atom_to_value(vm, string, NJS_ATOM_STRING_Infinity);
         }
 
     } else {
@@ -242,8 +241,6 @@ njs_number_to_string(njs_vm_t *vm, njs_value_t *string,
         return njs_string_new(vm, string, buf, size, size);
     }
 
-    *string = *value;
-
     return NJS_OK;
 }
 
@@ -252,20 +249,8 @@ njs_int_t
 njs_int64_to_string(njs_vm_t *vm, njs_value_t *value, int64_t i64)
 {
     size_t  size;
-    u_char  *dst, *p;
     u_char  buf[128];
 
-    if (njs_fast_path(i64 >= 0 && i64 < 0x3fffffffffffLL)) {
-        /* Fits to short_string. */
-        dst = njs_string_short_start(value);
-
-        p = njs_sprintf(dst, dst + NJS_STRING_SHORT, "%L", i64);
-
-        njs_string_short_set(value, p - dst, p - dst);
-
-        return NJS_OK;
-    }
-
     size = njs_dtoa(i64, (char *) buf);
 
     return njs_string_new(vm, value, buf, size, size);
@@ -439,49 +424,55 @@ njs_number_is_finite(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 }
 
 
-static const njs_object_prop_t  njs_number_constructor_properties[] =
+static const njs_object_prop_init_t  njs_number_constructor_properties[] =
 {
     NJS_DECLARE_PROP_LENGTH(1),
 
     NJS_DECLARE_PROP_NAME("Number"),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
+                             0, 0),
 
-    NJS_DECLARE_PROP_VALUE("EPSILON", njs_value(NJS_NUMBER, 1, DBL_EPSILON), 0),
+    NJS_DECLARE_PROP_VALUE(STRING_EPSILON,
+                           njs_value(NJS_NUMBER, 1, DBL_EPSILON), 0),
 
-    NJS_DECLARE_PROP_LVALUE("MAX_SAFE_INTEGER",
-                            njs_value(NJS_NUMBER, 1, NJS_MAX_SAFE_INTEGER), 0),
+    NJS_DECLARE_PROP_VALUE(STRING_MAX_SAFE_INTEGER,
+                           njs_value(NJS_NUMBER, 1, NJS_MAX_SAFE_INTEGER), 0),
 
-    NJS_DECLARE_PROP_LVALUE("MIN_SAFE_INTEGER",
-                            njs_value(NJS_NUMBER, 1, -NJS_MAX_SAFE_INTEGER), 0),
+    NJS_DECLARE_PROP_VALUE(STRING_MIN_SAFE_INTEGER,
+                           njs_value(NJS_NUMBER, 1, -NJS_MAX_SAFE_INTEGER), 0),
 
-    NJS_DECLARE_PROP_VALUE("MAX_VALUE", njs_value(NJS_NUMBER, 1, DBL_MAX), 0),
+    NJS_DECLARE_PROP_VALUE(STRING_MAX_VALUE,
+                           njs_value(NJS_NUMBER, 1, DBL_MAX), 0),
 
-    NJS_DECLARE_PROP_VALUE("MIN_VALUE", njs_value(NJS_NUMBER, 1, DBL_MIN), 0),
+    NJS_DECLARE_PROP_VALUE(STRING_MIN_VALUE,
+                           njs_value(NJS_NUMBER, 1, DBL_MIN), 0),
 
-    NJS_DECLARE_PROP_VALUE("NaN", njs_value(NJS_NUMBER, 0, NAN), 0),
+    NJS_DECLARE_PROP_VALUE(STRING_NaN, njs_value(NJS_NUMBER, 0, NAN), 0),
 
-    NJS_DECLARE_PROP_LVALUE("POSITIVE_INFINITY",
-                            njs_value(NJS_NUMBER, 1, INFINITY), 0),
+    NJS_DECLARE_PROP_VALUE(STRING_POSITIVE_INFINITY,
+                           njs_value(NJS_NUMBER, 1, INFINITY), 0),
 
-    NJS_DECLARE_PROP_LVALUE("NEGATIVE_INFINITY",
-                            njs_value(NJS_NUMBER, 1, -INFINITY), 0),
+    NJS_DECLARE_PROP_VALUE(STRING_NEGATIVE_INFINITY,
+                           njs_value(NJS_NUMBER, 1, -INFINITY), 0),
 
-    NJS_DECLARE_PROP_NATIVE("isFinite", njs_number_is_finite, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_isFinite, njs_number_is_finite, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("isInteger", njs_number_is_integer, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_isInteger, njs_number_is_integer, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("isSafeInteger", njs_number_is_safe_integer, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_isSafeInteger,
+                            njs_number_is_safe_integer, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("isNaN", njs_number_is_nan, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_isNaN, njs_number_is_nan, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("parseFloat", njs_number_parse_float, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_parseFloat, njs_number_parse_float, 1,
+                            0),
 
-    NJS_DECLARE_PROP_NATIVE("parseInt", njs_number_parse_int, 2, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_parseInt, njs_number_parse_int, 2, 0),
 };
 
 
-const njs_object_init_t  njs_number_constructor_init = {
+static const njs_object_init_t  njs_number_constructor_init = {
     njs_number_constructor_properties,
     njs_nitems(njs_number_constructor_properties),
 };
@@ -884,25 +875,29 @@ njs_number_to_string_radix(njs_vm_t *vm, njs_value_t *string,
 }
 
 
-static const njs_object_prop_t  njs_number_prototype_properties[] =
+static const njs_object_prop_init_t  njs_number_prototype_properties[] =
 {
-    NJS_DECLARE_PROP_HANDLER("__proto__", njs_primitive_prototype_get_proto,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING___proto__,
+                             njs_primitive_prototype_get_proto, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("constructor",
-                             njs_object_prototype_create_constructor,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
+                             njs_object_prototype_create_constructor, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_NATIVE("valueOf", njs_number_prototype_value_of, 0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_valueOf, njs_number_prototype_value_of,
+                            0, 0),
 
-    NJS_DECLARE_PROP_NATIVE("toString", njs_number_prototype_to_string, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_toString,
+                            njs_number_prototype_to_string, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("toFixed", njs_number_prototype_to_fixed, 1, 0),
-
-    NJS_DECLARE_PROP_NATIVE("toPrecision", njs_number_prototype_to_precision,
+    NJS_DECLARE_PROP_NATIVE(STRING_toFixed, njs_number_prototype_to_fixed,
                             1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("toExponential",
+    NJS_DECLARE_PROP_NATIVE(STRING_toPrecision,
+                            njs_number_prototype_to_precision, 1, 0),
+
+    NJS_DECLARE_PROP_NATIVE(STRING_toExponential,
                             njs_number_prototype_to_exponential, 1, 0),
 };
 
@@ -970,7 +965,7 @@ njs_number_parse_int(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return ret;
     }
 
-    (void) njs_string_trim(value, &string, NJS_TRIM_START);
+    (void) njs_string_trim(vm, value, &string, NJS_TRIM_START);
 
     if (string.size == 0) {
         goto done;
@@ -1048,7 +1043,7 @@ njs_number_parse_float(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return ret;
     }
 
-    (void) njs_string_trim(value, &string, NJS_TRIM_START);
+    (void) njs_string_trim(vm, value, &string, NJS_TRIM_START);
 
     p = string.start;
     end = p + string.size;
diff --git a/src/njs_number.h b/src/njs_number.h
index 98137a5d..d4c7a286 100644
--- a/src/njs_number.h
+++ b/src/njs_number.h
@@ -168,15 +168,30 @@ njs_char_to_hex(u_char c)
 }
 
 
-njs_inline void
-njs_uint32_to_string(njs_value_t *value, uint32_t u32)
+njs_inline njs_int_t
+njs_uint32_to_string(njs_vm_t *vm, njs_value_t *value, uint32_t u32)
 {
-    u_char  *dst, *p;
+    size_t  size;
+    u_char  *p;
+
+    if (!(u32 & 0x80000000)) {
+        value->type = NJS_STRING;
+        value->data.truth = (u32 != 0);
+        value->atom_id = njs_number_atom(u32);
+        value->string.data = NULL;
+        return NJS_OK;
+    }
+
+    p = njs_string_alloc(vm, value, 10, 10);
+    if (njs_slow_path(p == NULL)) {
+        return NJS_ERROR;
+    }
 
-    dst = njs_string_short_start(value);
-    p = njs_sprintf(dst, dst + NJS_STRING_SHORT, "%uD", u32);
+    size = njs_sprintf(p, p + 10, "%uD", u32) - p;
+    value->string.data->length = size;
+    value->string.data->size = size;
 
-    njs_string_short_set(value, p - dst, p - dst);
+    return NJS_OK;
 }
 
 
diff --git a/src/njs_object.c b/src/njs_object.c
index b3eae9a8..63273628 100644
--- a/src/njs_object.c
+++ b/src/njs_object.c
@@ -14,9 +14,8 @@ typedef enum {
 } njs_object_integrity_level_t;
 
 
-static njs_int_t njs_object_hash_test(njs_lvlhsh_query_t *lhq, void *data);
 static njs_object_prop_t *njs_object_exist_in_proto(const njs_object_t *begin,
-    const njs_object_t *end, njs_lvlhsh_query_t *lhq);
+    const njs_object_t *end, njs_flathsh_query_t *lhq);
 static njs_int_t njs_object_enumerate_array(njs_vm_t *vm,
     const njs_array_t *array, njs_array_t *items, uint32_t flags);
 static njs_int_t njs_object_enumerate_typed_array(njs_vm_t *vm,
@@ -154,23 +153,21 @@ njs_object_value_alloc(njs_vm_t *vm, njs_uint_t prototype_index, size_t extra,
 
 
 njs_int_t
-njs_object_hash_create(njs_vm_t *vm, njs_lvlhsh_t *hash,
-    const njs_object_prop_t *prop, njs_uint_t n)
+njs_object_hash_create(njs_vm_t *vm, njs_flathsh_t *hash,
+    const njs_object_prop_init_t *prop, njs_uint_t n)
 {
-    njs_int_t           ret;
-    njs_lvlhsh_query_t  lhq;
+    njs_int_t            ret;
+    njs_flathsh_query_t  lhq;
 
     lhq.replace = 0;
     lhq.proto = &njs_object_hash_proto;
     lhq.pool = vm->mem_pool;
 
     while (n != 0) {
-
-        njs_object_property_key_set(&lhq, &prop->name, 0);
-
+        lhq.key_hash = prop->atom_id;
         lhq.value = (void *) prop;
 
-        ret = njs_lvlhsh_insert(hash, &lhq);
+        ret = njs_flathsh_unique_insert(hash, &lhq);
         if (njs_slow_path(ret != NJS_OK)) {
             njs_internal_error(vm, "lvlhsh insert failed");
             return NJS_ERROR;
@@ -184,59 +181,16 @@ njs_object_hash_create(njs_vm_t *vm, njs_lvlhsh_t *hash,
 }
 
 
-const njs_lvlhsh_proto_t  njs_object_hash_proto
+const njs_flathsh_proto_t  njs_object_hash_proto
     njs_aligned(64) =
 {
-    NJS_LVLHSH_DEFAULT,
-    njs_object_hash_test,
+    0,
+    NULL,
     njs_lvlhsh_alloc,
     njs_lvlhsh_free,
 };
 
 
-static njs_int_t
-njs_object_hash_test(njs_lvlhsh_query_t *lhq, void *data)
-{
-    size_t             size;
-    u_char             *start;
-    njs_value_t        *name;
-    njs_object_prop_t  *prop;
-
-    prop = data;
-    name = &prop->name;
-
-    if (njs_slow_path(njs_is_symbol(name))) {
-        return ((njs_symbol_key(name) == lhq->key_hash)
-                && lhq->key.start == NULL) ? NJS_OK : NJS_DECLINED;
-    }
-
-    /* string. */
-
-    size = name->short_string.size;
-
-    if (size != NJS_STRING_LONG) {
-        if (lhq->key.length != size) {
-            return NJS_DECLINED;
-        }
-
-        start = name->short_string.start;
-
-    } else {
-        if (lhq->key.length != name->long_string.size) {
-            return NJS_DECLINED;
-        }
-
-        start = name->long_string.data->start;
-    }
-
-    if (memcmp(start, lhq->key.start, lhq->key.length) == 0) {
-        return NJS_OK;
-    }
-
-    return NJS_DECLINED;
-}
-
-
 static njs_int_t
 njs_object_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused, njs_value_t *retval)
@@ -417,13 +371,13 @@ njs_object_entries(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_object_prop_t *
 njs_object_exist_in_proto(const njs_object_t *object, const njs_object_t *end,
-    njs_lvlhsh_query_t *lhq)
+    njs_flathsh_query_t *lhq)
 {
     njs_int_t          ret;
     njs_object_prop_t  *prop;
 
     while (object != end) {
-        ret = njs_lvlhsh_find(&object->hash, lhq);
+        ret = njs_flathsh_unique_find(&object->hash, lhq);
 
         if (njs_fast_path(ret == NJS_OK)) {
             prop = lhq->value;
@@ -435,7 +389,7 @@ njs_object_exist_in_proto(const njs_object_t *object, const njs_object_t *end,
             return lhq->value;
         }
 
-        ret = njs_lvlhsh_find(&object->shared_hash, lhq);
+        ret = njs_flathsh_unique_find(&object->shared_hash, lhq);
 
         if (njs_fast_path(ret == NJS_OK)) {
             return lhq->value;
@@ -628,7 +582,11 @@ njs_object_enumerate_array(njs_vm_t *vm, const njs_array_t *array,
                     return NJS_ERROR;
                 }
 
-                njs_uint32_to_string(&items->start[items->length++], p - start);
+                ret = njs_uint32_to_string(vm, &items->start[items->length++],
+                                           p - start);
+                if (njs_slow_path(ret != NJS_OK)) {
+                    return NJS_ERROR;
+                }
             }
 
             p++;
@@ -658,7 +616,11 @@ njs_object_enumerate_array(njs_vm_t *vm, const njs_array_t *array,
                     return NJS_ERROR;
                 }
 
-                njs_uint32_to_string(&entry->start[0], p - start);
+                ret = njs_uint32_to_string(vm, &entry->start[0], p - start);
+                if (njs_slow_path(ret != NJS_OK)) {
+                    return NJS_ERROR;
+                }
+
                 entry->start[1] = *p;
 
                 ret = njs_array_expand(vm, items, 0, 1);
@@ -700,7 +662,10 @@ njs_object_enumerate_typed_array(njs_vm_t *vm, const njs_typed_array_t *array,
     switch (njs_object_enum_kind(flags)) {
     case NJS_ENUM_KEYS:
         for (i = 0; i < length; i++) {
-            njs_uint32_to_string(item++, i);
+            ret = njs_uint32_to_string(vm, item++, i);
+            if (njs_slow_path(ret != NJS_OK)) {
+                return NJS_ERROR;
+            }
         }
 
         break;
@@ -719,7 +684,11 @@ njs_object_enumerate_typed_array(njs_vm_t *vm, const njs_typed_array_t *array,
                 return NJS_ERROR;
             }
 
-            njs_uint32_to_string(&entry->start[0], i);
+            ret = njs_uint32_to_string(vm, &entry->start[0], i);
+            if (njs_slow_path(ret != NJS_OK)) {
+                return NJS_ERROR;
+            }
+
             njs_set_number(&entry->start[1], njs_typed_array_prop(array, i));
 
             njs_set_array(item++, entry);
@@ -738,7 +707,7 @@ static njs_int_t
 njs_object_enumerate_string(njs_vm_t *vm, const njs_value_t *value,
     njs_array_t *items, uint32_t flags)
 {
-    u_char             *begin;
+    u_char             buf[4], *c;
     uint32_t           i, len, size;
     njs_int_t          ret;
     njs_value_t        *item, *string;
@@ -746,7 +715,7 @@ njs_object_enumerate_string(njs_vm_t *vm, const njs_value_t *value,
     const u_char       *src, *end;
     njs_string_prop_t  str_prop;
 
-    len = (uint32_t) njs_string_prop(&str_prop, value);
+    len = (uint32_t) njs_string_prop(vm, &str_prop, value);
 
     ret = njs_array_expand(vm, items, 0, len);
     if (njs_slow_path(ret != NJS_OK)) {
@@ -758,7 +727,10 @@ njs_object_enumerate_string(njs_vm_t *vm, const njs_value_t *value,
     switch (njs_object_enum_kind(flags)) {
     case NJS_ENUM_KEYS:
         for (i = 0; i < len; i++) {
-            njs_uint32_to_string(item++, i);
+            ret = njs_uint32_to_string(vm, item++, i);
+            if (njs_slow_path(ret != NJS_OK)) {
+                return NJS_ERROR;
+            }
         }
 
         break;
@@ -768,10 +740,10 @@ njs_object_enumerate_string(njs_vm_t *vm, const njs_value_t *value,
             /* ASCII string. */
 
             for (i = 0; i < len; i++) {
-                begin = njs_string_short_start(item);
-                *begin = str_prop.start[i];
-
-                njs_string_short_set(item, 1, 1);
+                ret = njs_string_new(vm, item, &str_prop.start[i], 1, 1);
+                if (njs_slow_path(ret != NJS_OK)) {
+                    return NJS_ERROR;
+                }
 
                 item++;
             }
@@ -783,11 +755,15 @@ njs_object_enumerate_string(njs_vm_t *vm, const njs_value_t *value,
             end = src + str_prop.size;
 
             do {
-                begin = (u_char *) src;
-                njs_utf8_copy(njs_string_short_start(item), &src, end);
-                size = (uint32_t) (src - begin);
+                c = buf;
 
-                njs_string_short_set(item, size, 1);
+                c = njs_utf8_copy(c, &src, end);
+                size = c - buf;
+
+                ret = njs_string_new(vm, item, buf, size, 1);
+                if (njs_slow_path(ret != NJS_OK)) {
+                    return NJS_ERROR;
+                }
 
                 item++;
 
@@ -807,14 +783,17 @@ njs_object_enumerate_string(njs_vm_t *vm, const njs_value_t *value,
                     return NJS_ERROR;
                 }
 
-                njs_uint32_to_string(&entry->start[0], i);
+                ret = njs_uint32_to_string(vm, &entry->start[0], i);
+                if (njs_slow_path(ret != NJS_OK)) {
+                    return NJS_ERROR;
+                }
 
                 string = &entry->start[1];
 
-                begin = njs_string_short_start(string);
-                *begin = str_prop.start[i];
-
-                njs_string_short_set(string, 1, 1);
+                ret = njs_string_new(vm, string, &str_prop.start[i], 1, 1);
+                if (njs_slow_path(ret != NJS_OK)) {
+                    return NJS_ERROR;
+                }
 
                 njs_set_array(item, entry);
 
@@ -834,15 +813,22 @@ njs_object_enumerate_string(njs_vm_t *vm, const njs_value_t *value,
                     return NJS_ERROR;
                 }
 
-                njs_uint32_to_string(&entry->start[0], i++);
+                ret = njs_uint32_to_string(vm, &entry->start[0], i++);
+                if (njs_slow_path(ret != NJS_OK)) {
+                    return NJS_ERROR;
+                }
 
                 string = &entry->start[1];
 
-                begin = (u_char *) src;
-                njs_utf8_copy(njs_string_short_start(string), &src, end);
-                size = (uint32_t) (src - begin);
+                c = buf;
 
-                njs_string_short_set(string, size, 1);
+                c = njs_utf8_copy(c, &src, end);
+                size = c - buf;
+
+                ret = njs_string_new(vm, string, buf, size, 1);
+                if (njs_slow_path(ret != NJS_OK)) {
+                    return NJS_ERROR;
+                }
 
                 njs_set_array(item, entry);
 
@@ -887,14 +873,14 @@ njs_object_enumerate_object(njs_vm_t *vm, const njs_object_t *object,
 }
 
 
-#define njs_process_prop(vm, prop, flags, items, items_symbol)                 \
-    if (!(flags & NJS_ENUM_SYMBOL && njs_is_symbol(&prop->name))) {            \
+#define njs_process_prop(vm, prop_name, flags, items, items_symbol)            \
+    if (!(flags & NJS_ENUM_SYMBOL && njs_is_symbol(prop_name))) {              \
         /*                                                                     \
          * prop from shared_hash is not symbol:                                \
          * add to items before props from hash                                 \
          */                                                                    \
                                                                                \
-        ret = njs_array_add(vm, items, &prop->name);                           \
+        ret = njs_array_add(vm, items, prop_name);                             \
         if (njs_slow_path(ret != NJS_OK)) {                                    \
             return NJS_ERROR;                                                  \
         }                                                                      \
@@ -904,7 +890,7 @@ njs_object_enumerate_object(njs_vm_t *vm, const njs_object_t *object,
          * prop from shared_hash is symbol:                                    \
          * add to items_symbol                                                 \
          */                                                                    \
-        ret = njs_array_add(vm, items_symbol, &prop->name);                    \
+        ret = njs_array_add(vm, items_symbol, prop_name);                      \
         if (njs_slow_path(ret != NJS_OK)) {                                    \
             return NJS_ERROR;                                                  \
         }                                                                      \
@@ -915,14 +901,16 @@ static njs_int_t
 njs_get_own_ordered_keys(njs_vm_t *vm, const njs_object_t *object,
     const njs_object_t *parent, njs_array_t *items, uint32_t flags)
 {
-    double              num;
-    uint32_t            items_length;
-    njs_int_t           ret;
-    njs_array_t         *items_string, *items_symbol;
-    njs_lvlhsh_each_t   lhe;
-    njs_object_prop_t   *prop, *ext_prop;
-    njs_lvlhsh_query_t  lhq;
-    const njs_lvlhsh_t  *hash;
+    double               num;
+    uint32_t             items_length;
+    njs_int_t            ret;
+    njs_array_t          *items_string, *items_symbol;
+    njs_value_t          prop_name;
+    njs_object_prop_t    *prop, *ext_prop;
+    njs_flathsh_elt_t    *elt;
+    njs_flathsh_each_t   lhe;
+    const njs_flathsh_t  *hash;
+    njs_flathsh_query_t  lhq;
 
     items_length = items->length;
 
@@ -938,7 +926,7 @@ njs_get_own_ordered_keys(njs_vm_t *vm, const njs_object_t *object,
 
     lhq.proto = &njs_object_hash_proto;
 
-    njs_lvlhsh_each_init(&lhe, &njs_object_hash_proto);
+    njs_flathsh_each_init(&lhe, &njs_object_hash_proto);
     hash = &object->shared_hash;
 
     if (flags & NJS_ENUM_NON_SHARED_ONLY) {
@@ -946,24 +934,30 @@ njs_get_own_ordered_keys(njs_vm_t *vm, const njs_object_t *object,
     }
 
     for ( ;; ) {
-        prop = njs_lvlhsh_each(hash, &lhe);
-
-        if (prop == NULL) {
+        elt = njs_flathsh_each(hash, &lhe);
+        if (elt == NULL) {
             break;
         }
 
-        if (!njs_is_enumerable(&prop->name, flags)) {
+        prop = elt->value;
+
+        ret = njs_atom_to_value(vm, &prop_name, elt->key_hash);
+        if (ret != NJS_OK) {
+            return NJS_ERROR;
+        }
+
+        if (!njs_is_enumerable(&prop_name, flags)) {
             continue;
         }
 
-        njs_object_property_key_set(&lhq, &prop->name, lhe.key_hash);
+        lhq.key_hash = elt->key_hash;
 
         ext_prop = njs_object_exist_in_proto(parent, object, &lhq);
         if (ext_prop != NULL) {
             continue;
         }
 
-        ret = njs_lvlhsh_find(&object->hash, &lhq);
+        ret = njs_flathsh_unique_find(&object->hash, &lhq);
         if (ret != NJS_OK) {
 
             if (!(prop->enumerable || !(flags & NJS_ENUM_ENUMERABLE_ONLY))) {
@@ -972,12 +966,13 @@ njs_get_own_ordered_keys(njs_vm_t *vm, const njs_object_t *object,
 
             /* prop is:  !in_hash && in_shared_hash */
 
-            num = njs_string_to_index(&prop->name);
+            num = njs_string_to_index(&prop_name);
             if (!njs_number_is_integer_index(num)) {
-                njs_process_prop(vm, prop, flags, items_string, items_symbol);
+                njs_process_prop(vm, &prop_name, flags, items_string,
+                                 items_symbol);
 
             } else {
-                ret = njs_array_add(vm, items, &prop->name);
+                ret = njs_array_add(vm, items, &prop_name);
                 if (njs_slow_path(ret != NJS_OK)) {
                     return NJS_ERROR;
                 }
@@ -993,7 +988,7 @@ njs_get_own_ordered_keys(njs_vm_t *vm, const njs_object_t *object,
 
             /* prop is:  in_hash && in_shared_hash */
 
-            num = njs_string_to_index(&prop->name);
+            num = njs_string_to_index(&prop_name);
             if (!njs_number_is_integer_index(num)) {
 
                 njs_object_prop_t *hash_prop = lhq.value;
@@ -1005,7 +1000,7 @@ njs_get_own_ordered_keys(njs_vm_t *vm, const njs_object_t *object,
                 if (hash_prop->type != NJS_WHITEOUT &&
                     !(hash_prop->enum_in_object_hash))
                 {
-                    njs_process_prop(vm, prop, flags, items_string,
+                    njs_process_prop(vm, &prop_name, flags, items_string,
                                      items_symbol);
                 }
             }
@@ -1014,56 +1009,60 @@ njs_get_own_ordered_keys(njs_vm_t *vm, const njs_object_t *object,
 
 local_hash:
 
-    njs_lvlhsh_each_init(&lhe, &njs_object_hash_proto);
+    njs_flathsh_each_init(&lhe, &njs_object_hash_proto);
     hash = &object->hash;
 
     for ( ;; ) {
-        prop = njs_lvlhsh_each(hash, &lhe);
-
-        if (prop == NULL) {
+        elt = njs_flathsh_each(hash, &lhe);
+        if (elt == NULL) {
             break;
         }
 
-        if (!njs_is_enumerable(&prop->name, flags) ||
+        prop = elt->value;
+
+        ret = njs_atom_to_value(vm, &prop_name, elt->key_hash);
+        if (ret != NJS_OK) {
+            return NJS_ERROR;
+        }
+
+        if (!njs_is_enumerable(&prop_name, flags) ||
             !(prop->enumerable || !(flags & NJS_ENUM_ENUMERABLE_ONLY)) ||
             prop->type == NJS_WHITEOUT)
         {
             continue;
         }
 
-        njs_object_property_key_set(&lhq, &prop->name, lhe.key_hash);
+        lhq.key_hash = elt->key_hash;
 
         ext_prop = njs_object_exist_in_proto(parent, object, &lhq);
         if (ext_prop != NULL) {
             continue;
         }
 
-        num = njs_string_to_index(&prop->name);
+        num = njs_string_to_index(&prop_name);
         if (njs_number_is_integer_index(num)) {
 
-            ret = njs_array_add(vm, items, &prop->name);
+            ret = njs_array_add(vm, items, &prop_name);
             if (njs_slow_path(ret != NJS_OK)) {
                 return NJS_ERROR;
             }
 
         } else {
 
-            ret = njs_lvlhsh_find(&object->shared_hash, &lhq);
+            ret = njs_flathsh_unique_find(&object->shared_hash, &lhq);
             if (ret != NJS_OK) {
                 /* prop is:  in_hash && !in_shared_hash */
 
                 /* select names of not deleted props */
-
-                njs_process_prop(vm, prop, flags, items_string,
+                njs_process_prop(vm, &prop_name, flags, items_string,
                                  items_symbol);
 
             } else {
                 /* prop is:  in_hash && in_shared_hash */
 
                 /* select names of not deleted and created again */
-
                 if (prop->enum_in_object_hash) {
-                    njs_process_prop(vm, prop, flags, items_string,
+                    njs_process_prop(vm, &prop_name, flags, items_string,
                                      items_symbol);
                 }
             }
@@ -1139,8 +1138,8 @@ njs_object_own_enumerate_object(njs_vm_t *vm, const njs_object_t *object,
         njs_set_object(&value, (njs_object_t *) object);
 
         for (i = 0; i< items_sorted->length; i++) {
-            ret = njs_value_property(vm, &value, &items_sorted->start[i],
-                                     &retval);
+            ret = njs_value_property_val(vm, &value, &items_sorted->start[i],
+                                         &retval);
             if (njs_slow_path(ret != NJS_OK)) {
                 njs_array_destroy(vm, items_sorted);
                 return NJS_ERROR;
@@ -1221,8 +1220,10 @@ static njs_int_t
 njs_object_copy_shared_hash(njs_vm_t *vm, njs_object_t *object)
 {
     njs_int_t            ret;
+    njs_value_t          prop_name;
     njs_flathsh_t        new_hash, *shared_hash;
     njs_object_prop_t    *prop;
+    njs_flathsh_elt_t    *elt;
     njs_flathsh_each_t   fhe;
     njs_flathsh_query_t  fhq;
 
@@ -1236,24 +1237,30 @@ njs_object_copy_shared_hash(njs_vm_t *vm, njs_object_t *object)
     njs_flathsh_each_init(&fhe, &njs_object_hash_proto);
 
     for ( ;; ) {
-        prop = njs_flathsh_each(shared_hash, &fhe);
-
-        if (prop == NULL) {
+        elt = njs_flathsh_each(shared_hash, &fhe);
+        if (elt == NULL) {
             break;
         }
 
-        if (njs_is_symbol(&prop->name)) {
-            fhq.key_hash = njs_symbol_key(&prop->name);
+        prop = elt->value;
+
+        ret = njs_atom_to_value(vm, &prop_name, elt->key_hash);
+        if (ret != NJS_OK) {
+            return NJS_ERROR;
+        }
+
+        if (njs_is_symbol(&prop_name)) {
+            fhq.key_hash = njs_symbol_key(&prop_name);
             fhq.key.start = NULL;
 
         } else {
-            njs_string_get(&prop->name, &fhq.key);
-            fhq.key_hash = njs_djb_hash(fhq.key.start, fhq.key.length);
+            njs_string_get(vm, &prop_name, &fhq.key);
+            fhq.key_hash = elt->key_hash;
         }
 
         fhq.value = prop;
 
-        ret = njs_flathsh_insert(&new_hash, &fhq);
+        ret = njs_flathsh_unique_insert(&new_hash, &fhq);
         if (njs_slow_path(ret != NJS_OK)) {
             njs_internal_error(vm, "flathsh insert failed");
             return NJS_ERROR;
@@ -1331,10 +1338,10 @@ njs_object_make_shared(njs_vm_t *vm, njs_object_t *object)
         }
 
 
-        njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0, 0);
+        njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0);
         key = &s->keys->start[s->index++];
 
-        ret = njs_property_query(vm, &pq, &s->value, key);
+        ret = njs_property_query_val(vm, &pq, &s->value, key);
         if (njs_slow_path(ret != NJS_OK)) {
             if (ret == NJS_DECLINED) {
                 continue;
@@ -1346,7 +1353,8 @@ njs_object_make_shared(njs_vm_t *vm, njs_object_t *object)
 
         prop = pq.lhq.value;
 
-        ret = njs_flathsh_insert(&njs_object(&s->value)->shared_hash, &pq.lhq);
+        ret = njs_flathsh_unique_insert(&njs_object(&s->value)->shared_hash,
+                                        &pq.lhq);
         if (njs_slow_path(ret != NJS_OK)) {
             njs_internal_error(vm, "flathsh insert failed");
             return NJS_ERROR;
@@ -1445,10 +1453,10 @@ njs_object_traverse(njs_vm_t *vm, njs_object_t *object, void *ctx,
             continue;
         }
 
-        njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0, 0);
+        njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0);
         key = &s->keys->start[s->index++];
 
-        ret = njs_property_query(vm, &pq, &s->value, key);
+        ret = njs_property_query_val(vm, &pq, &s->value, key);
         if (njs_slow_path(ret != NJS_OK)) {
             if (ret == NJS_DECLINED) {
                 continue;
@@ -1459,6 +1467,7 @@ njs_object_traverse(njs_vm_t *vm, njs_object_t *object, void *ctx,
 
         prop = pq.lhq.value;
         s->prop = prop;
+        s->atom_id = pq.lhq.key_hash;
 
         ret = cb(vm, s, ctx);
         if (njs_slow_path(ret != NJS_OK)) {
@@ -1472,7 +1481,8 @@ njs_object_traverse(njs_vm_t *vm, njs_object_t *object, void *ctx,
         njs_value_assign(&value, njs_prop_value(prop));
 
         if (prop->type == NJS_PROPERTY_HANDLER) {
-            ret = njs_prop_handler(prop)(vm, prop, &s->value, NULL, &value);
+            ret = njs_prop_handler(prop)(vm, prop, pq.lhq.key_hash, &s->value,
+                                         NULL, &value);
             if (njs_slow_path(ret == NJS_ERROR)) {
                 return ret;
 
@@ -1536,8 +1546,13 @@ njs_object_define_property(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     value = njs_argument(args, 1);
     name = njs_lvalue_arg(&lvalue, args, nargs, 2);
 
-    ret = njs_object_prop_define(vm, value, name, desc,
-                                 NJS_OBJECT_PROP_DESCRIPTOR, 0);
+    ret = njs_value_to_key(vm, name, name);
+    if (njs_slow_path(ret != NJS_OK)) {
+        return NJS_ERROR;
+    }
+
+    ret = njs_object_prop_define_val(vm, value, name, desc,
+                                     NJS_OBJECT_PROP_DESCRIPTOR);
     if (njs_slow_path(ret != NJS_OK)) {
         return NJS_ERROR;
     }
@@ -1578,12 +1593,10 @@ njs_object_define_properties(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     length = keys->length;
     value = njs_argument(args, 1);
-    njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0, 0);
+    njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0);
 
     for (i = 0; i < length; i++) {
-        pq.lhq.key_hash = 0;
-
-        ret = njs_property_query(vm, &pq, descs, &keys->start[i]);
+        ret = njs_property_query_val(vm, &pq, descs, &keys->start[i]);
         if (njs_slow_path(ret == NJS_ERROR)) {
             goto done;
         }
@@ -1594,13 +1607,13 @@ njs_object_define_properties(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             continue;
         }
 
-        ret = njs_value_property(vm, descs, &keys->start[i], &desc);
+        ret = njs_value_property(vm, descs, keys->start[i].atom_id, &desc);
         if (njs_slow_path(ret == NJS_ERROR)) {
             goto done;
         }
 
-        ret = njs_object_prop_define(vm, value, &keys->start[i], &desc,
-                                     NJS_OBJECT_PROP_DESCRIPTOR, 0);
+        ret = njs_object_prop_define(vm, value, keys->start[i].atom_id, &desc,
+                                     NJS_OBJECT_PROP_DESCRIPTOR);
         if (njs_slow_path(ret != NJS_OK)) {
             goto done;
         }
@@ -1641,13 +1654,13 @@ static njs_int_t
 njs_object_get_own_property_descriptors(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused, njs_value_t *retval)
 {
-    njs_int_t           ret;
-    uint32_t            i, length;
-    njs_array_t         *names;
-    njs_value_t         descriptor, *value, *key;
-    njs_object_t        *descriptors;
-    njs_object_prop_t   *pr;
-    njs_lvlhsh_query_t  lhq;
+    uint32_t             i, length;
+    njs_int_t            ret;
+    njs_array_t          *names;
+    njs_value_t          descriptor, *value, *key;
+    njs_object_t         *descriptors;
+    njs_object_prop_t    *pr;
+    njs_flathsh_query_t  lhq;
 
     value = njs_arg(args, nargs, 1);
 
@@ -1684,16 +1697,16 @@ njs_object_get_own_property_descriptors(njs_vm_t *vm, njs_value_t *args,
             goto done;
         }
 
-        pr = njs_object_prop_alloc(vm, key, &descriptor, 1);
+        pr = njs_object_prop_alloc(vm, &descriptor, 1);
         if (njs_slow_path(pr == NULL)) {
             ret = NJS_ERROR;
             goto done;
         }
 
-        njs_object_property_key_set(&lhq, key, 0);
+        lhq.key_hash = key->atom_id;
         lhq.value = pr;
 
-        ret = njs_lvlhsh_insert(&descriptors->hash, &lhq);
+        ret = njs_flathsh_unique_insert(&descriptors->hash, &lhq);
         if (njs_slow_path(ret != NJS_OK)) {
             njs_internal_error(vm, "lvlhsh insert failed");
             goto done;
@@ -1748,7 +1761,7 @@ njs_object_get_prototype_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     value = njs_arg(args, nargs, 1);
 
     if (njs_is_object(value)) {
-        njs_object_prototype_proto(vm, NULL, value, NULL, retval);
+        njs_object_prototype_proto(vm, NULL, 0, value, NULL, retval);
         return NJS_OK;
     }
 
@@ -1823,14 +1836,15 @@ static njs_int_t
 njs_object_set_integrity_level(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t level, njs_value_t *retval)
 {
-    uint32_t           length;
-    njs_int_t          ret;
-    njs_array_t        *array;
-    njs_value_t        *value;
-    njs_lvlhsh_t       *hash;
-    njs_object_t       *object;
-    njs_object_prop_t  *prop;
-    njs_lvlhsh_each_t  lhe;
+    uint32_t                length;
+    njs_int_t               ret;
+    njs_array_t             *array;
+    njs_value_t             *value;
+    njs_object_t            *object;
+    njs_flathsh_t           *hash;
+    njs_object_prop_t       *prop;
+    njs_flathsh_elt_t   *elt;
+    njs_flathsh_each_t  lhe;
 
     value = njs_arg(args, nargs, 1);
 
@@ -1865,17 +1879,18 @@ njs_object_set_integrity_level(njs_vm_t *vm, njs_value_t *args,
     object = njs_object(value);
     object->extensible = 0;
 
-    njs_lvlhsh_each_init(&lhe, &njs_object_hash_proto);
+    njs_flathsh_each_init(&lhe, &njs_object_hash_proto);
 
     hash = &object->hash;
 
     for ( ;; ) {
-        prop = njs_lvlhsh_each(hash, &lhe);
-
-        if (prop == NULL) {
+        elt = njs_flathsh_each(hash, &lhe);
+        if (elt == NULL) {
             break;
         }
 
+        prop = elt->value;
+
         if (level == NJS_OBJECT_INTEGRITY_FROZEN
             && !njs_is_accessor_descriptor(prop))
         {
@@ -1895,11 +1910,12 @@ static njs_int_t
 njs_object_test_integrity_level(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t level, njs_value_t *retval)
 {
-    njs_value_t        *value;
-    njs_lvlhsh_t       *hash;
-    njs_object_t       *object;
-    njs_object_prop_t  *prop;
-    njs_lvlhsh_each_t  lhe;
+    njs_value_t             *value;
+    njs_object_t            *object;
+    njs_flathsh_t           *hash;
+    njs_object_prop_t       *prop;
+    njs_flathsh_elt_t   *elt;
+    njs_flathsh_each_t  lhe;
 
     value = njs_arg(args, nargs, 1);
 
@@ -1923,17 +1939,18 @@ njs_object_test_integrity_level(njs_vm_t *vm, njs_value_t *args,
         goto done;
     }
 
-    njs_lvlhsh_each_init(&lhe, &njs_object_hash_proto);
+    njs_flathsh_each_init(&lhe, &njs_object_hash_proto);
 
     hash = &object->hash;
 
     for ( ;; ) {
-        prop = njs_lvlhsh_each(hash, &lhe);
-
-        if (prop == NULL) {
+        elt = njs_flathsh_each(hash, &lhe);
+        if (elt == NULL) {
             break;
         }
 
+        prop = elt->value;
+
         if (prop->configurable) {
             goto done;
         }
@@ -2027,9 +2044,9 @@ njs_object_assign(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         for (j = 0; j < length; j++) {
             key = &names->start[j];
 
-            njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0, 1);
+            njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 1);
 
-            ret = njs_property_query(vm, &pq, source, key);
+            ret = njs_property_query_val(vm, &pq, source, key);
             if (njs_slow_path(ret != NJS_OK)) {
                 goto exception;
             }
@@ -2039,12 +2056,12 @@ njs_object_assign(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
                 continue;
             }
 
-            ret = njs_value_property(vm, source, key, &setval);
+            ret = njs_value_property(vm, source, key->atom_id, &setval);
             if (njs_slow_path(ret != NJS_OK)) {
                 goto exception;
             }
 
-            ret = njs_value_property_set(vm, value, key, &setval);
+            ret = njs_value_property_set(vm, value, key->atom_id, &setval);
             if (njs_slow_path(ret != NJS_OK)) {
                 goto exception;
             }
@@ -2069,8 +2086,8 @@ static njs_int_t
 njs_object_is(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused, njs_value_t *retval)
 {
-    njs_set_boolean(retval, njs_values_same(njs_arg(args, nargs, 1),
-                                                 njs_arg(args, nargs, 2)));
+    njs_set_boolean(retval, njs_values_same(vm, njs_arg(args, nargs, 1),
+                                            njs_arg(args, nargs, 2)));
 
     return NJS_OK;
 }
@@ -2084,7 +2101,8 @@ njs_object_is(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 njs_int_t
 njs_primitive_prototype_get_proto(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     njs_uint_t    index;
     njs_object_t  *proto;
@@ -2120,7 +2138,8 @@ njs_primitive_prototype_get_proto(njs_vm_t *vm, njs_object_prop_t *prop,
 
 njs_int_t
 njs_object_prototype_create(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     int64_t            index;
     njs_function_t     *function;
@@ -2146,30 +2165,29 @@ njs_object_prototype_create(njs_vm_t *vm, njs_object_prop_t *prop,
 
 
 njs_value_t *
-njs_property_prototype_create(njs_vm_t *vm, njs_lvlhsh_t *hash,
+njs_property_prototype_create(njs_vm_t *vm, njs_flathsh_t *hash,
     njs_object_t *prototype)
 {
-    njs_int_t           ret;
-    njs_object_prop_t   *prop;
-    njs_lvlhsh_query_t  lhq;
-
-    static const njs_value_t  proto_string = njs_string("prototype");
+    njs_int_t            ret;
+    njs_object_prop_t    *prop;
+    njs_flathsh_query_t  lhq;
 
-    prop = njs_object_prop_alloc(vm, &proto_string, &njs_value_undefined, 0);
+    prop = njs_object_prop_alloc(vm, &njs_value_undefined, 0);
     if (njs_slow_path(prop == NULL)) {
         return NULL;
     }
 
+    lhq.value = prop;
+
     njs_set_type_object(njs_prop_value(prop), prototype, prototype->type);
 
-    lhq.value = prop;
-    lhq.key_hash = NJS_PROTOTYPE_HASH;
-    lhq.key = njs_str_value("prototype");
+    lhq.key_hash = NJS_ATOM_STRING_prototype;
+
     lhq.replace = 1;
     lhq.pool = vm->mem_pool;
     lhq.proto = &njs_object_hash_proto;
 
-    ret = njs_lvlhsh_insert(hash, &lhq);
+    ret = njs_flathsh_unique_insert(hash, &lhq);
 
     if (njs_fast_path(ret == NJS_OK)) {
         return njs_prop_value(prop);
@@ -2181,65 +2199,70 @@ njs_property_prototype_create(njs_vm_t *vm, njs_lvlhsh_t *hash,
 }
 
 
-static const njs_object_prop_t  njs_object_constructor_properties[] =
+static const njs_object_prop_init_t  njs_object_constructor_properties[] =
 {
     NJS_DECLARE_PROP_LENGTH(1),
 
     NJS_DECLARE_PROP_NAME("Object"),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
+                             0, 0),
 
-    NJS_DECLARE_PROP_NATIVE("create", njs_object_create, 2, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_create, njs_object_create, 2, 0),
 
-    NJS_DECLARE_PROP_NATIVE("keys", njs_object_keys, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_keys, njs_object_keys, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("values", njs_object_values, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_values, njs_object_values, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("entries", njs_object_entries, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_entries, njs_object_entries, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("defineProperty", njs_object_define_property, 3, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_defineProperty,
+                            njs_object_define_property, 3, 0),
 
-    NJS_DECLARE_PROP_LNATIVE("defineProperties",
-                             njs_object_define_properties, 2, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_defineProperties,
+                            njs_object_define_properties, 2, 0),
 
-    NJS_DECLARE_PROP_LNATIVE("getOwnPropertyDescriptor",
-                             njs_object_get_own_property_descriptor, 2, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_getOwnPropertyDescriptor,
+                            njs_object_get_own_property_descriptor, 2, 0),
 
-    NJS_DECLARE_PROP_LNATIVE("getOwnPropertyDescriptors",
-                             njs_object_get_own_property_descriptors, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_getOwnPropertyDescriptors,
+                            njs_object_get_own_property_descriptors, 1, 0),
 
-    NJS_DECLARE_PROP_LNATIVE("getOwnPropertyNames",
-                             njs_object_get_own_property, 1, NJS_ENUM_STRING),
+    NJS_DECLARE_PROP_NATIVE(STRING_getOwnPropertyNames,
+                            njs_object_get_own_property, 1, NJS_ENUM_STRING),
 
-    NJS_DECLARE_PROP_LNATIVE("getOwnPropertySymbols",
-                             njs_object_get_own_property, 1, NJS_ENUM_SYMBOL),
+    NJS_DECLARE_PROP_NATIVE(STRING_getOwnPropertySymbols,
+                            njs_object_get_own_property, 1, NJS_ENUM_SYMBOL),
 
-    NJS_DECLARE_PROP_NATIVE("getPrototypeOf", njs_object_get_prototype_of, 1,
-                            0),
+    NJS_DECLARE_PROP_NATIVE(STRING_getPrototypeOf,
+                            njs_object_get_prototype_of, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("setPrototypeOf", njs_object_set_prototype_of, 2,
-                            0),
+    NJS_DECLARE_PROP_NATIVE(STRING_setPrototypeOf,
+                            njs_object_set_prototype_of, 2, 0),
 
-    NJS_DECLARE_PROP_NATIVE("freeze", njs_object_set_integrity_level, 1,
-                            NJS_OBJECT_INTEGRITY_FROZEN),
+    NJS_DECLARE_PROP_NATIVE(STRING_freeze, njs_object_set_integrity_level,
+                            1, NJS_OBJECT_INTEGRITY_FROZEN),
 
-    NJS_DECLARE_PROP_NATIVE("isFrozen", njs_object_test_integrity_level, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_isFrozen,
+                            njs_object_test_integrity_level, 1,
                             NJS_OBJECT_INTEGRITY_FROZEN),
 
-    NJS_DECLARE_PROP_NATIVE("seal", njs_object_set_integrity_level, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_seal, njs_object_set_integrity_level, 1,
                             NJS_OBJECT_INTEGRITY_SEALED),
 
-    NJS_DECLARE_PROP_NATIVE("isSealed", njs_object_test_integrity_level, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_isSealed,
+                            njs_object_test_integrity_level, 1,
                             NJS_OBJECT_INTEGRITY_SEALED),
 
-    NJS_DECLARE_PROP_LNATIVE("preventExtensions", njs_object_prevent_extensions,
-                             1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_preventExtensions,
+                            njs_object_prevent_extensions, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("isExtensible", njs_object_is_extensible, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_isExtensible, njs_object_is_extensible,
+                            1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("assign", njs_object_assign, 2, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_assign, njs_object_assign, 2, 0),
 
-    NJS_DECLARE_PROP_NATIVE("is", njs_object_is, 2, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_is, njs_object_is, 2, 0),
 };
 
 
@@ -2287,7 +2310,8 @@ njs_object_set_prototype(njs_vm_t *vm, njs_object_t *object,
 
 njs_int_t
 njs_object_prototype_proto(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     njs_int_t     ret;
     njs_object_t  *proto, *object;
@@ -2334,7 +2358,8 @@ njs_object_prototype_proto(njs_vm_t *vm, njs_object_prop_t *prop,
 
 njs_int_t
 njs_object_prototype_create_constructor(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     int64_t                 index;
     njs_value_t             *cons, constructor;
@@ -2401,16 +2426,14 @@ found:
 
 
 njs_value_t *
-njs_property_constructor_set(njs_vm_t *vm, njs_lvlhsh_t *hash,
+njs_property_constructor_set(njs_vm_t *vm, njs_flathsh_t *hash,
     njs_value_t *constructor)
 {
-    njs_int_t                 ret;
-    njs_object_prop_t         *prop;
-    njs_lvlhsh_query_t        lhq;
-
-    static const njs_value_t  constructor_string = njs_string("constructor");
+    njs_int_t            ret;
+    njs_object_prop_t    *prop;
+    njs_flathsh_query_t  lhq;
 
-    prop = njs_object_prop_alloc(vm, &constructor_string, constructor, 1);
+    prop = njs_object_prop_alloc(vm, constructor, 1);
     if (njs_slow_path(prop == NULL)) {
         return NULL;
     }
@@ -2419,14 +2442,14 @@ njs_property_constructor_set(njs_vm_t *vm, njs_lvlhsh_t *hash,
     prop->enumerable = 0;
 
     lhq.value = prop;
-    lhq.key_hash = NJS_CONSTRUCTOR_HASH;
-    lhq.key = njs_str_value("constructor");
+
+    lhq.key_hash = NJS_ATOM_STRING_constructor;
+
     lhq.replace = 1;
     lhq.pool = vm->mem_pool;
     lhq.proto = &njs_object_hash_proto;
 
-    ret = njs_lvlhsh_insert(hash, &lhq);
-
+    ret = njs_flathsh_unique_insert(hash, &lhq);
     if (njs_fast_path(ret == NJS_OK)) {
         return njs_prop_value(prop);
     }
@@ -2457,30 +2480,6 @@ njs_object_prototype_value_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 }
 
 
-static const njs_value_t  njs_object_null_string = njs_string("[object Null]");
-static const njs_value_t  njs_object_undefined_string =
-                                     njs_long_string("[object Undefined]");
-static const njs_value_t  njs_object_boolean_string =
-                                     njs_long_string("[object Boolean]");
-static const njs_value_t  njs_object_number_string =
-                                     njs_long_string("[object Number]");
-static const njs_value_t  njs_object_string_string =
-                                     njs_long_string("[object String]");
-static const njs_value_t  njs_object_object_string =
-                                     njs_long_string("[object Object]");
-static const njs_value_t  njs_object_array_string =
-                                     njs_string("[object Array]");
-static const njs_value_t  njs_object_function_string =
-                                     njs_long_string("[object Function]");
-static const njs_value_t  njs_object_regexp_string =
-                                     njs_long_string("[object RegExp]");
-static const njs_value_t  njs_object_date_string = njs_string("[object Date]");
-static const njs_value_t  njs_object_error_string =
-                                     njs_string("[object Error]");
-static const njs_value_t  njs_object_arguments_string =
-                                     njs_long_string("[object Arguments]");
-
-
 njs_int_t
 njs_object_prototype_to_string(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused, njs_value_t *retval)
@@ -2493,16 +2492,15 @@ njs_int_t
 njs_object_to_string(njs_vm_t *vm, njs_value_t *this, njs_value_t *retval)
 {
     u_char             *p;
+    uint32_t           name;
     njs_int_t          ret;
     njs_value_t        tag;
     njs_string_prop_t  string;
-    const njs_value_t  *name;
 
     if (njs_is_null_or_undefined(this)) {
-        njs_value_assign(retval,
-                         njs_is_null(this) ? &njs_object_null_string
-                                           : &njs_object_undefined_string);
-
+        njs_atom_to_value(vm, retval,
+                          njs_is_null(this) ? NJS_ATOM_STRING__object_Null_
+                                           : NJS_ATOM_STRING__object_Undefined_);
         return NJS_OK;
     }
 
@@ -2511,36 +2509,36 @@ njs_object_to_string(njs_vm_t *vm, njs_value_t *this, njs_value_t *retval)
         return ret;
     }
 
-    name = &njs_object_object_string;
+    name = NJS_ATOM_STRING__object_Object_;
 
     if (njs_is_array(this)) {
-        name = &njs_object_array_string;
+        name = NJS_ATOM_STRING__object_Array_;
 
     } else if (njs_is_object(this)
         && njs_lvlhsh_eq(&njs_object(this)->shared_hash,
                          &vm->shared->arguments_object_instance_hash))
     {
-        name = &njs_object_arguments_string;
+        name = NJS_ATOM_STRING__object_Arguments_;
 
     } else if (njs_is_function(this)) {
-        name = &njs_object_function_string;
+        name = NJS_ATOM_STRING__object_Function_;
 
     } else if (njs_is_error(this)) {
-        name = &njs_object_error_string;
+        name = NJS_ATOM_STRING__object_Error_;
 
     } else if (njs_is_object_value(this)) {
 
         switch (njs_object_value(this)->type) {
         case NJS_BOOLEAN:
-            name = &njs_object_boolean_string;
+            name = NJS_ATOM_STRING__object_Boolean_;
             break;
 
         case NJS_NUMBER:
-            name = &njs_object_number_string;
+            name = NJS_ATOM_STRING__object_Number_;
             break;
 
         case NJS_STRING:
-            name = &njs_object_string_string;
+            name = NJS_ATOM_STRING__object_String_;
             break;
 
         default:
@@ -2548,10 +2546,10 @@ njs_object_to_string(njs_vm_t *vm, njs_value_t *this, njs_value_t *retval)
         }
 
     } else if (njs_is_date(this)) {
-        name = &njs_object_date_string;
+        name = NJS_ATOM_STRING__object_Date_;
 
     } else if (njs_is_regexp(this)) {
-        name = &njs_object_regexp_string;
+        name = NJS_ATOM_STRING__object_RegExp_;
     }
 
     ret = njs_object_string_tag(vm, this, &tag);
@@ -2560,18 +2558,12 @@ njs_object_to_string(njs_vm_t *vm, njs_value_t *this, njs_value_t *retval)
     }
 
     if (ret == NJS_DECLINED) {
-        if (njs_slow_path(name == NULL)) {
-            njs_internal_error(vm, "Unknown value type");
-
-            return NJS_ERROR;
-        }
-
-        njs_value_assign(retval, name);
+        njs_atom_to_value(vm, retval, name);
 
         return NJS_OK;
     }
 
-    (void) njs_string_prop(&string, &tag);
+    (void) njs_string_prop(vm, &string, &tag);
 
     p = njs_string_alloc(vm, retval, string.size + njs_length("[object ]"),
                          string.length + njs_length("[object ]"));
@@ -2612,9 +2604,9 @@ njs_object_prototype_has_own_property(njs_vm_t *vm, njs_value_t *args,
         }
     }
 
-    njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0, 1);
+    njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 1);
 
-    ret = njs_property_query(vm, &pq, value, property);
+    ret = njs_property_query_val(vm, &pq, value, property);
 
     switch (ret) {
     case NJS_OK:
@@ -2658,9 +2650,9 @@ njs_object_prototype_prop_is_enumerable(njs_vm_t *vm, njs_value_t *args,
         }
     }
 
-    njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0, 1);
+    njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 1);
 
-    ret = njs_property_query(vm, &pq, value, property);
+    ret = njs_property_query_val(vm, &pq, value, property);
 
     switch (ret) {
     case NJS_OK:
@@ -2717,26 +2709,28 @@ njs_object_prototype_is_prototype_of(njs_vm_t *vm, njs_value_t *args,
 }
 
 
-static const njs_object_prop_t  njs_object_prototype_properties[] =
+static const njs_object_prop_init_t  njs_object_prototype_properties[] =
 {
-    NJS_DECLARE_PROP_HANDLER("__proto__", njs_object_prototype_proto,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING___proto__, njs_object_prototype_proto,
+                             0, NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("constructor",
-                             njs_object_prototype_create_constructor,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
+                             njs_object_prototype_create_constructor, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_NATIVE("valueOf", njs_object_prototype_value_of, 0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_valueOf, njs_object_prototype_value_of,
+                            0, 0),
 
-    NJS_DECLARE_PROP_NATIVE("toString", njs_object_prototype_to_string, 0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_toString, njs_object_prototype_to_string,
+                            0, 0),
 
-    NJS_DECLARE_PROP_NATIVE("hasOwnProperty",
+    NJS_DECLARE_PROP_NATIVE(STRING_hasOwnProperty,
                             njs_object_prototype_has_own_property, 1, 0),
 
-    NJS_DECLARE_PROP_LNATIVE("propertyIsEnumerable",
-                             njs_object_prototype_prop_is_enumerable, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_propertyIsEnumerable,
+                            njs_object_prototype_prop_is_enumerable, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("isPrototypeOf",
+    NJS_DECLARE_PROP_NATIVE(STRING_isPrototypeOf,
                             njs_object_prototype_is_prototype_of, 1, 0),
 };
 
@@ -2753,15 +2747,12 @@ njs_object_length(njs_vm_t *vm, njs_value_t *value, int64_t *length)
     njs_int_t    ret;
     njs_value_t  value_length;
 
-    const njs_value_t  string_length = njs_string("length");
-
     if (njs_is_fast_array(value)) {
         *length = njs_array(value)->length;
         return NJS_OK;
     }
 
-    ret = njs_value_property(vm, value, njs_value_arg(&string_length),
-                             &value_length);
+    ret = njs_value_property(vm, value, NJS_ATOM_STRING_length, &value_length);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return ret;
     }
diff --git a/src/njs_object.h b/src/njs_object.h
index e3f58fdd..6b2438df 100644
--- a/src/njs_object.h
+++ b/src/njs_object.h
@@ -19,6 +19,7 @@ typedef enum {
     NJS_OBJECT_PROP_CONFIGURABLE = 16,
     NJS_OBJECT_PROP_WRITABLE = 32,
     NJS_OBJECT_PROP_UNSET = 64,
+    NJS_OBJECT_PROP_IS_STRING = 128,
 #define NJS_OBJECT_PROP_VALUE_ECW (NJS_OBJECT_PROP_VALUE                     \
                                    | NJS_OBJECT_PROP_ENUMERABLE              \
                                    | NJS_OBJECT_PROP_CONFIGURABLE            \
@@ -39,8 +40,8 @@ typedef enum {
 
 
 struct njs_object_init_s {
-    const njs_object_prop_t     *properties;
-    njs_uint_t                  items;
+    const njs_object_prop_init_t  *properties;
+    njs_uint_t                    items;
 };
 
 
@@ -49,6 +50,7 @@ typedef struct njs_traverse_s  njs_traverse_t;
 struct njs_traverse_s {
     struct njs_traverse_s      *parent;
     njs_object_prop_t          *prop;
+    uint32_t                   atom_id;
 
     njs_value_t                value;
     njs_array_t                *keys;
@@ -73,21 +75,23 @@ njs_array_t *njs_object_own_enumerate(njs_vm_t *vm, const njs_object_t *object,
 njs_int_t njs_object_traverse(njs_vm_t *vm, njs_object_t *object, void *ctx,
     njs_object_traverse_cb_t cb);
 njs_int_t njs_object_make_shared(njs_vm_t *vm, njs_object_t *object);
-njs_int_t njs_object_hash_create(njs_vm_t *vm, njs_lvlhsh_t *hash,
-    const njs_object_prop_t *prop, njs_uint_t n);
+njs_int_t njs_object_hash_create(njs_vm_t *vm, njs_flathsh_t *hash,
+    const njs_object_prop_init_t *prop, njs_uint_t n);
 njs_int_t njs_primitive_prototype_get_proto(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
-    njs_value_t *retval);
+    njs_object_prop_t *prop, uint32_t unused, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
 njs_int_t njs_object_prototype_create(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
-njs_value_t *njs_property_prototype_create(njs_vm_t *vm, njs_lvlhsh_t *hash,
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval);
+njs_value_t *njs_property_prototype_create(njs_vm_t *vm, njs_flathsh_t *hash,
     njs_object_t *prototype);
 njs_int_t njs_object_prototype_proto(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
-njs_int_t njs_object_prototype_create_constructor(njs_vm_t *vm,
-    njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
     njs_value_t *retval);
-njs_value_t *njs_property_constructor_set(njs_vm_t *vm, njs_lvlhsh_t *hash,
+njs_int_t njs_object_prototype_create_constructor(njs_vm_t *vm,
+    njs_object_prop_t *prop, uint32_t unused, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval);
+njs_value_t *njs_property_constructor_set(njs_vm_t *vm, njs_flathsh_t *hash,
     njs_value_t *constructor);
 njs_int_t njs_object_to_string(njs_vm_t *vm, njs_value_t *value,
     njs_value_t *retval);
@@ -97,21 +101,22 @@ njs_int_t njs_object_length(njs_vm_t *vm, njs_value_t *value, int64_t *dst);
 
 njs_int_t njs_prop_private_copy(njs_vm_t *vm, njs_property_query_t *pq,
     njs_object_t *proto);
-njs_object_prop_t *njs_object_prop_alloc(njs_vm_t *vm, const njs_value_t *name,
+njs_object_prop_t *njs_object_prop_alloc(njs_vm_t *vm,
     const njs_value_t *value, uint8_t attributes);
 njs_int_t njs_object_property(njs_vm_t *vm, njs_object_t *object,
-    njs_lvlhsh_query_t *lhq, njs_value_t *retval);
+    njs_flathsh_query_t *lhq, njs_value_t *retval);
 njs_object_prop_t *njs_object_property_add(njs_vm_t *vm, njs_value_t *object,
-    njs_value_t *key, njs_bool_t replace);
+    uint32_t atom_id, njs_bool_t replace);
 njs_int_t njs_object_prop_define(njs_vm_t *vm, njs_value_t *object,
-    njs_value_t *name, njs_value_t *value, unsigned flags, uint32_t hash);
+    uint32_t atom_id, njs_value_t *value, uint32_t flags);
 njs_int_t njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest,
     njs_value_t *value, njs_value_t *setval);
 njs_int_t njs_object_get_prototype_of(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 const char *njs_prop_type_string(njs_object_prop_type_t type);
 njs_int_t njs_object_prop_init(njs_vm_t *vm, const njs_object_init_t* init,
-    const njs_object_prop_t *base, njs_value_t *value, njs_value_t *retval);
+    njs_object_prop_t *base, uint32_t atom_id, njs_value_t *value,
+    njs_value_t *retval);
 
 
 njs_inline njs_bool_t
@@ -138,77 +143,38 @@ njs_is_generic_descriptor(njs_object_prop_t *prop)
 }
 
 
-njs_inline void
-njs_object_property_key_set(njs_lvlhsh_query_t *lhq, const njs_value_t *key,
-    uint32_t hash)
-{
-    if (njs_is_symbol(key)) {
-
-        lhq->key.length = 0;
-        lhq->key.start = NULL;
-        lhq->key_hash = njs_symbol_key(key);
-
-    } else {
-
-        /* string. */
-
-        njs_string_get(key, &lhq->key);
-
-        if (hash == 0) {
-            lhq->key_hash = njs_djb_hash(lhq->key.start, lhq->key.length);
-
-        } else {
-            lhq->key_hash = hash;
-        }
-    }
-}
-
-
-njs_inline void
-njs_object_property_init(njs_lvlhsh_query_t *lhq, const njs_value_t *key,
-    uint32_t hash)
-{
-    lhq->proto = &njs_object_hash_proto;
-
-    njs_object_property_key_set(lhq, key, hash);
-}
-
-
 njs_inline njs_int_t
 njs_primitive_value_to_key(njs_vm_t *vm, njs_value_t *dst,
     const njs_value_t *src)
 {
-    const njs_value_t  *value;
-
     switch (src->type) {
-
     case NJS_NULL:
-        value = &njs_string_null;
-        break;
+        njs_atom_to_value(vm, dst, NJS_ATOM_STRING_null);
+        return NJS_OK;
 
     case NJS_UNDEFINED:
-        value = &njs_string_undefined;
-        break;
+        njs_atom_to_value(vm, dst, NJS_ATOM_STRING_undefined);
+        return NJS_OK;
 
     case NJS_BOOLEAN:
-        value = njs_is_true(src) ? &njs_string_true : &njs_string_false;
-        break;
+        if (njs_is_true(src)) {
+            njs_atom_to_value(vm, dst, NJS_ATOM_STRING_true);
 
-    case NJS_NUMBER:
-        return njs_number_to_string(vm, dst, src);
+        } else {
+            njs_atom_to_value(vm, dst, NJS_ATOM_STRING_false);
+        }
 
+        return NJS_OK;
+
+    case NJS_NUMBER:
     case NJS_SYMBOL:
     case NJS_STRING:
-        value = src;
-        break;
+        *dst = *src;
+        return NJS_OK;
 
     default:
         return NJS_ERROR;
     }
-
-    *dst = *value;
-
-    return NJS_OK;
 }
 
 
@@ -261,21 +227,63 @@ njs_key_string_get(njs_vm_t *vm, njs_value_t *key, njs_str_t *str)
         if (njs_slow_path(ret != NJS_OK)) {
             return ret;
         }
+
+    } else if (njs_slow_path(!njs_is_string(key))) {
+        ret = njs_value_to_string(vm, key, key);
+        if (njs_slow_path(ret != NJS_OK)) {
+            return ret;
+        }
+    }
+
+    njs_string_get(vm, key, str);
+
+    return NJS_OK;
+}
+
+
+njs_inline njs_int_t
+njs_atom_string_get(njs_vm_t *vm, uint32_t atom_id, njs_str_t *str)
+{
+    njs_value_t  value;
+
+    if (njs_atom_to_value(vm, &value, atom_id) != NJS_OK) {
+        return NJS_ERROR;
     }
 
-    njs_string_get(key, str);
+    njs_key_string_get(vm, &value, str);
 
     return NJS_OK;
 }
 
 
+njs_inline njs_int_t
+njs_object_prop_define_val(njs_vm_t *vm, njs_value_t *object, njs_value_t *name,
+    njs_value_t *value, unsigned flags)
+{
+    njs_int_t  ret;
+
+    if (njs_value_atom(name) == NJS_ATOM_STRING_unknown) {
+        ret = njs_atom_atomize_key(vm, name);
+        if (ret != NJS_OK) {
+            return ret;
+        }
+    }
+
+    if (njs_is_string(name)) {
+       flags |= NJS_OBJECT_PROP_IS_STRING;
+    }
+
+    return njs_object_prop_define(vm, object, name->atom_id, value, flags);
+}
+
+
 njs_inline njs_int_t
 njs_value_create_data_prop(njs_vm_t *vm, njs_value_t *value,
     njs_value_t *name, njs_value_t *setval, uint32_t hash)
 {
-    return njs_object_prop_define(vm, value, name, setval,
-                                  NJS_OBJECT_PROP_CREATE
-                                  | NJS_OBJECT_PROP_VALUE_ECW, hash);
+    return njs_object_prop_define_val(vm, value, name, setval,
+                                      NJS_OBJECT_PROP_CREATE
+                                      | NJS_OBJECT_PROP_VALUE_ECW);
 }
 
 
@@ -296,12 +304,9 @@ njs_object_length_set(njs_vm_t *vm, njs_value_t *value, int64_t length)
 {
     njs_value_t  index;
 
-    static const njs_value_t  string_length = njs_string("length");
-
     njs_value_number_set(&index, length);
 
-    return njs_value_property_set(vm, value, njs_value_arg(&string_length),
-                                  &index);
+    return njs_value_property_set(vm, value, NJS_ATOM_STRING_length, &index);
 }
 
 
@@ -310,10 +315,7 @@ njs_object_string_tag(njs_vm_t *vm, njs_value_t *value, njs_value_t *tag)
 {
     njs_int_t  ret;
 
-    static const njs_value_t  to_string_tag =
-                                njs_wellknown_symbol(NJS_SYMBOL_TO_STRING_TAG);
-
-    ret = njs_value_property(vm, value, njs_value_arg(&to_string_tag), tag);
+    ret = njs_value_property(vm, value, NJS_ATOM_SYMBOL_toStringTag, tag);
     if (njs_slow_path(ret != NJS_OK)) {
         return ret;
     }
diff --git a/src/njs_object_hash.h b/src/njs_object_hash.h
deleted file mode 100644
index 163c814c..00000000
--- a/src/njs_object_hash.h
+++ /dev/null
@@ -1,842 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) NGINX, Inc.
- */
-
-#ifndef _NJS_OBJECT_HASH_H_INCLUDED_
-#define _NJS_OBJECT_HASH_H_INCLUDED_
-
-
-#define NJS___PROTO___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,                                       \
-        '_'), '_'), '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(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
-        '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(                                                         \
-    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,                                       \
-        'c'), 'o'), 'n'), 'f'), 'i'), 'g'), 'u'), 'r'), 'a'), 'b'), 'l'), 'e')
-
-
-#define NJS_CONSTRUCTOR_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,                                       \
-        '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_PROMISE_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,                                       \
-        'P'), 'r'), 'o'), 'm'), 'i'), 's'), 'e')
-
-
-#define NJS_ENUMERABLE_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,                                       \
-        'e'), 'n'), 'u'), 'm'), 'e'), 'r'), 'a'), 'b'), 'l'), 'e')
-
-
-#define NJS_ERRNO_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'), '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(                                                         \
-    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'), 'n'), 'c'), 'o'), 'd'), 'i'), 'n'), 'g')
-
-
-#define NJS_ENV_HASH                                                          \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
-        '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(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
-        '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_GLOBAL_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,                                       \
-        'g'), 'l'), 'o'), 'b'), 'a'), 'l')
-
-
-#define NJS_GLOBAL_THIS_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,                                       \
-        'g'), 'l'), 'o'), 'b'), 'a'), 'l'), 'T'), 'h'), 'i'), 's')
-
-
-#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(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
-        'i'), 'n'), 'd'), 'e'), 'x')
-
-
-#define NJS_INPUT_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,                                       \
-        '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(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
-        'g'), 'r'), 'o'), 'u'), 'p'), 's')
-
-
-#define NJS_JOIN_HASH                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
-        'j'), 'o'), 'i'), 'n')
-
-
-#define NJS_JSON_HASH                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
-        'J'), 'S'), 'O'), 'N')
-
-
-#define NJS_LENGTH_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,                                       \
-        'l'), 'e'), 'n'), 'g'), 't'), 'h')
-
-
-#define NJS_NAME_HASH                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
-        'n'), 'a'), 'm'), 'e')
-
-
-#define NJS_NJS_HASH                                                          \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
-        'n'), 'j'), 's')
-
-
-#define NJS_262_HASH                                                          \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
-        '$'), '2'), '6'), '2')
-
-
-#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(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
-        '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_AGGREGATE_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,                                       \
-        'A'), 'g'), 'g'), 'r'), 'e'), 'g'), 'a'), 't'), 'e'),                 \
-        'E'), 'r'), 'r'), 'o'), 'r')
-
-
-#define NJS_MESSAGE_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,                                       \
-        'm'), 'e'), 's'), 's'), 'a'), 'g'), 'e')
-
-
-#define NJS_ERRORS_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,                                       \
-        'e'), 'r'), 'r'), 'o'), 'r'), 's')
-
-
-#define NJS_MODE_HASH                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
-        'm'), 'o'), 'd'), 'e')
-
-
-#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,                                       \
-        'O'), 'b'), 'j'), 'e'), 'c'), 't')
-
-
-#define NJS_PATH_HASH                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
-        'p'), 'a'), 't'), 'h')
-
-
-#define NJS_PROCESS_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,                                       \
-        'p'), 'r'), 'o'), 'c'), 'e'), 's'), 's')
-
-
-#define NJS_PROTOTYPE_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,                                       \
-        '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_STACK_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,                                       \
-        's'), 't'), 'a'), 'c'), 'k')
-
-
-#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_SYMBOL_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'), 'm'), 'b'), 'o'), 'l')
-
-
-#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(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
-        't'), 'o'), 'J'), 'S'), 'O'), 'N')
-
-
-#define NJS_TO_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_INIT,                                       \
-        '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(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
-        'v'), 'a'), 'l'), 'u'), 'e')
-
-
-#define NJS_VALUE_OF_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,                                       \
-        'v'), 'a'), 'l'), 'u'), 'e'), 'O'), 'f')
-
-
-#define NJS_WRITABABLE_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,                                       \
-        'w'), 'r'), 'i'), 't'), 'a'), 'b'), 'l'), 'e')
-
-
-#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_INIT,                                       \
-        'U'), 'R'), 'I'), 'E'), 'r'), 'r'), 'o'), 'r')
-
-
-#define NJS_ARRAY_BUFFER_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,                                       \
-        'A'), 'r'), 'r'), 'a'), 'y'), 'B'), 'u'), 'f'), 'f'), 'e'), 'r')
-
-
-#define NJS_DATA_VIEW_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,                                       \
-        'D'), 'a'), 't'), 'a'), 'V'), 'i'), 'e'), 'w')
-
-
-#define NJS_UINT8ARRAY_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,                                       \
-        'U'), 'i'), 'n'), 't'), '8'), 'A'), 'r'), 'r'), 'a'), 'y')
-
-
-#define NJS_UINT16ARRAY_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,                                       \
-        'U'), 'i'), 'n'), 't'), '1'), '6'), 'A'), 'r'), 'r'), 'a'), 'y')
-
-
-#define NJS_UINT32ARRAY_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,                                       \
-        'U'), 'i'), 'n'), 't'), '3'), '2'), 'A'), 'r'), 'r'), 'a'), 'y')
-
-
-#define NJS_INT8ARRAY_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,                                       \
-        'I'), 'n'), 't'), '8'), 'A'), 'r'), 'r'), 'a'), 'y')
-
-
-#define NJS_INT16ARRAY_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,                                       \
-        'I'), 'n'), 't'), '1'), '6'), 'A'), 'r'), 'r'), 'a'), 'y')
-
-
-#define NJS_INT32ARRAY_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,                                       \
-        'I'), 'n'), 't'), '3'), '2'), 'A'), 'r'), 'r'), 'a'), 'y')
-
-
-#define NJS_FLOAT32ARRAY_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_INIT,                                       \
-        'F'), 'l'), 'o'), 'a'), 't'), '3'), '2'), 'A'), 'r'), 'r'), 'a'), 'y')
-
-
-#define NJS_FLOAT64ARRAY_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_INIT,                                       \
-        'F'), 'l'), 'o'), 'a'), 't'), '6'), '4'), 'A'), 'r'), 'r'), 'a'), 'y')
-
-
-#define NJS_UINT8CLAMPEDARRAY_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_add(                                                         \
-    njs_djb_hash_add(                                                         \
-    njs_djb_hash_add(NJS_DJB_HASH_INIT,                                       \
-        'U'), 'i'), 'n'), 't'), '8'), 'C'), 'l'), 'a'), 'm'), 'p'), 'e'),     \
-        'd'), 'A'), 'r'), 'r'), 'a'), 'y')
-
-
-#define NJS_TEXT_DECODER_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'), 'e'), 'x'), 't'), 'D'), 'e'), 'c'), 'o'), 'd'), 'e'), 'r')
-
-
-#define NJS_TEXT_ENCODER_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'), 'e'), 'x'), 't'), 'E'), 'n'), 'c'), 'o'), 'd'), 'e'), 'r')
-
-
-#define NJS_BUFFER_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,                                       \
-        'B'), 'u'), 'f'), 'f'), 'e'), 'r')
-
-
-#endif /* _NJS_OBJECT_HASH_H_INCLUDED_ */
diff --git a/src/njs_object_prop.c b/src/njs_object_prop.c
index a24af753..d7c55d3a 100644
--- a/src/njs_object_prop.c
+++ b/src/njs_object_prop.c
@@ -9,13 +9,13 @@
 
 
 static njs_object_prop_t *njs_object_prop_alloc2(njs_vm_t *vm,
-    const njs_value_t *name, njs_object_prop_type_t type, unsigned flags);
+    njs_object_prop_type_t type, unsigned flags);
 static njs_object_prop_t *njs_descriptor_prop(njs_vm_t *vm,
-    const njs_value_t *name, const njs_value_t *desc);
+    const njs_value_t *desc);
 
 
 njs_object_prop_t *
-njs_object_prop_alloc(njs_vm_t *vm, const njs_value_t *name,
+njs_object_prop_alloc(njs_vm_t *vm,
     const njs_value_t *value, uint8_t attributes)
 {
     unsigned           flags;
@@ -33,7 +33,7 @@ njs_object_prop_alloc(njs_vm_t *vm, const njs_value_t *name,
         break;
     }
 
-    prop = njs_object_prop_alloc2(vm, name, NJS_PROPERTY, flags);
+    prop = njs_object_prop_alloc2(vm, NJS_PROPERTY, flags);
     if (njs_slow_path(prop == NULL)) {
         return NULL;
     }
@@ -45,10 +45,9 @@ njs_object_prop_alloc(njs_vm_t *vm, const njs_value_t *name,
 
 
 static njs_object_prop_t *
-njs_object_prop_alloc2(njs_vm_t *vm, const njs_value_t *name,
+njs_object_prop_alloc2(njs_vm_t *vm,
     njs_object_prop_type_t type, unsigned flags)
 {
-    njs_int_t          ret;
     njs_object_prop_t  *prop;
 
     prop = njs_mp_align(vm->mem_pool, sizeof(njs_value_t),
@@ -58,15 +57,6 @@ njs_object_prop_alloc2(njs_vm_t *vm, const njs_value_t *name,
         return NULL;
     }
 
-    njs_value_assign(&prop->name, name);
-
-    if (njs_slow_path(!njs_is_key(&prop->name))) {
-        ret = njs_value_to_key(vm, &prop->name, &prop->name);
-        if (njs_slow_path(ret != NJS_OK)) {
-            return NULL;
-        }
-    }
-
     prop->type = type;
     prop->enum_in_object_hash = 0;
 
@@ -92,15 +82,15 @@ njs_object_prop_alloc2(njs_vm_t *vm, const njs_value_t *name,
 
 
 njs_int_t
-njs_object_property(njs_vm_t *vm, njs_object_t *object, njs_lvlhsh_query_t *lhq,
-    njs_value_t *retval)
+njs_object_property(njs_vm_t *vm, njs_object_t *object,
+    njs_flathsh_query_t *lhq, njs_value_t *retval)
 {
     njs_int_t          ret;
     njs_value_t        value;
     njs_object_prop_t  *prop;
 
     do {
-        ret = njs_lvlhsh_find(&object->hash, lhq);
+        ret = njs_flathsh_unique_find(&object->hash, lhq);
 
         if (njs_fast_path(ret == NJS_OK)) {
             prop = lhq->value;
@@ -110,7 +100,7 @@ njs_object_property(njs_vm_t *vm, njs_object_t *object, njs_lvlhsh_query_t *lhq,
             }
         }
 
-        ret = njs_lvlhsh_find(&object->shared_hash, lhq);
+        ret = njs_flathsh_unique_find(&object->shared_hash, lhq);
 
         if (njs_fast_path(ret == NJS_OK)) {
             goto found;
@@ -145,32 +135,25 @@ found:
 
 
 njs_object_prop_t *
-njs_object_property_add(njs_vm_t *vm, njs_value_t *object, njs_value_t *key,
+njs_object_property_add(njs_vm_t *vm, njs_value_t *object, unsigned atom_id,
     njs_bool_t replace)
 {
-    njs_int_t           ret;
-    njs_value_t         key_value;
-    njs_object_prop_t   *prop;
-    njs_lvlhsh_query_t  lhq;
+    njs_int_t            ret;
+    njs_object_prop_t    *prop;
+    njs_flathsh_query_t  lhq;
 
-    prop = njs_object_prop_alloc(vm, key, &njs_value_invalid, 1);
+    prop = njs_object_prop_alloc(vm, &njs_value_invalid, 1);
     if (njs_slow_path(prop == NULL)) {
         return NULL;
     }
 
-    ret = njs_value_to_key(vm, &key_value, key);
-    if (njs_slow_path(ret != NJS_OK)) {
-        return NULL;
-    }
-
-    lhq.proto = &njs_object_hash_proto;
-    njs_string_get(&key_value, &lhq.key);
-    lhq.key_hash = njs_djb_hash(lhq.key.start, lhq.key.length);
     lhq.value = prop;
+    lhq.key_hash = atom_id;
     lhq.replace = replace;
     lhq.pool = vm->mem_pool;
+    lhq.proto = &njs_object_hash_proto;
 
-    ret = njs_lvlhsh_insert(njs_object_hash(object), &lhq);
+    ret = njs_flathsh_unique_insert(njs_object_hash(object), &lhq);
     if (njs_slow_path(ret != NJS_OK)) {
         njs_internal_error(vm, "lvlhsh insert failed");
         return NULL;
@@ -184,32 +167,23 @@ njs_object_property_add(njs_vm_t *vm, njs_value_t *object, njs_value_t *key,
  * ES5.1, 8.12.9: [[DefineOwnProperty]]
  */
 njs_int_t
-njs_object_prop_define(njs_vm_t *vm, njs_value_t *object,
-    njs_value_t *name, njs_value_t *value, unsigned flags, uint32_t hash)
+njs_object_prop_define(njs_vm_t *vm, njs_value_t *object, unsigned atom_id,
+    njs_value_t *value, unsigned flags)
 {
     uint32_t              length, index;
     njs_int_t             ret;
     njs_array_t           *array;
-    njs_value_t           retval;
+    njs_value_t           key, retval;
     njs_object_prop_t     *prop, *prev;
     njs_property_query_t  pq;
 
-    static const njs_str_t  length_key = njs_str("length");
-
-    if (njs_slow_path(!njs_is_index_or_key(name))) {
-        ret = njs_value_to_key(vm, name, name);
-        if (njs_slow_path(ret != NJS_OK)) {
-            return ret;
-        }
-    }
-
 again:
 
-    njs_property_query_init(&pq, NJS_PROPERTY_QUERY_SET, hash, 1);
+    njs_property_query_init(&pq, NJS_PROPERTY_QUERY_SET, 1);
 
     ret = (flags & NJS_OBJECT_PROP_CREATE)
                 ? NJS_DECLINED
-                : njs_property_query(vm, &pq, object, name);
+                : njs_property_query(vm, &pq, object, atom_id);
 
     if (njs_slow_path(ret == NJS_ERROR)) {
         return ret;
@@ -217,7 +191,7 @@ again:
 
     switch (njs_prop_type(flags)) {
     case NJS_OBJECT_PROP_DESCRIPTOR:
-        prop = njs_descriptor_prop(vm, name, value);
+        prop = njs_descriptor_prop(vm, value);
         if (njs_slow_path(prop == NULL)) {
             return NJS_ERROR;
         }
@@ -227,20 +201,18 @@ again:
     case NJS_OBJECT_PROP_VALUE:
         if (((flags & NJS_OBJECT_PROP_VALUE_ECW) == NJS_OBJECT_PROP_VALUE_ECW)
             && njs_is_fast_array(object)
-            && njs_is_number(name))
+            && njs_atom_is_number(atom_id))
         {
-            if (njs_number_is_integer_index(njs_number(name))) {
-                array = njs_array(object);
-                index = (uint32_t) njs_number(name);
+            array = njs_array(object);
+            index = njs_atom_number(atom_id);
 
-                if (index < array->length) {
-                    njs_value_assign(&array->start[index], value);
-                    return NJS_OK;
-                }
+            if (index < array->length) {
+                njs_value_assign(&array->start[index], value);
+                return NJS_OK;
             }
         }
 
-        prop = njs_object_prop_alloc2(vm, name, NJS_PROPERTY,
+        prop = njs_object_prop_alloc2(vm, NJS_PROPERTY,
                                       flags & NJS_OBJECT_PROP_VALUE_ECW);
         if (njs_slow_path(prop == NULL)) {
             return NJS_ERROR;
@@ -254,7 +226,7 @@ again:
     default:
         njs_assert(njs_is_function(value));
 
-        prop = njs_object_prop_alloc2(vm, name, NJS_ACCESSOR,
+        prop = njs_object_prop_alloc2(vm, NJS_ACCESSOR,
                                       NJS_OBJECT_PROP_VALUE_EC);
         if (njs_slow_path(prop == NULL)) {
             return NJS_ERROR;
@@ -277,17 +249,23 @@ again:
 set_prop:
 
         if (!njs_object(object)->extensible) {
-            njs_key_string_get(vm, name,  &pq.lhq.key);
+            njs_atom_string_get(vm, atom_id, &pq.lhq.key);
             njs_type_error(vm, "Cannot add property \"%V\", "
                            "object is not extensible", &pq.lhq.key);
             return NJS_ERROR;
         }
 
-        if (njs_slow_path(njs_is_typed_array(object)
-                          && njs_is_string(name)))
+        if (njs_slow_path(njs_is_typed_array(object) &&
+           (flags & NJS_OBJECT_PROP_IS_STRING)))
         {
             /* Integer-Indexed Exotic Objects [[DefineOwnProperty]]. */
-            if (!isnan(njs_string_to_index(name))) {
+
+            ret = njs_atom_to_value(vm, &key, atom_id);
+            if (njs_slow_path(ret != NJS_OK)) {
+                return ret;
+            }
+
+            if (!isnan(njs_string_to_index(&key))) {
                 njs_type_error(vm, "Invalid typed array index");
                 return NJS_ERROR;
             }
@@ -332,32 +310,13 @@ set_prop:
 
         } else {
 
-            if ((flags & NJS_OBJECT_PROP_CREATE)) {
-                ret = njs_primitive_value_to_key(vm, &pq.key, name);
-                if (njs_slow_path(ret != NJS_OK)) {
-                    return NJS_ERROR;
-                }
-
-                if (njs_is_symbol(name)) {
-                    pq.lhq.key_hash = njs_symbol_key(name);
-                    pq.lhq.key.start = NULL;
-
-                } else {
-                    njs_string_get(&pq.key, &pq.lhq.key);
-                    pq.lhq.key_hash = (hash == 0)
-                                           ? njs_djb_hash(pq.lhq.key.start,
-                                                          pq.lhq.key.length)
-                                           : hash;
-                }
-
-                pq.lhq.proto = &njs_object_hash_proto;
-            }
-
+            pq.lhq.key_hash = atom_id;
+            pq.lhq.proto = &njs_object_hash_proto;
             pq.lhq.value = prop;
             pq.lhq.replace = 0;
             pq.lhq.pool = vm->mem_pool;
 
-            ret = njs_lvlhsh_insert(njs_object_hash(object), &pq.lhq);
+            ret = njs_flathsh_unique_insert(njs_object_hash(object), &pq.lhq);
             if (njs_slow_path(ret != NJS_OK)) {
                 njs_internal_error(vm, "lvlhsh insert failed");
                 return NJS_ERROR;
@@ -498,7 +457,8 @@ set_prop:
 
             if (njs_is_valid(njs_prop_value(prop))
                 && prev->type != NJS_PROPERTY_HANDLER
-                && !njs_values_same(njs_prop_value(prop), njs_prop_value(prev)))
+                && !njs_values_same(vm, njs_prop_value(prop),
+                                    njs_prop_value(prev)))
             {
                 goto exception;
             }
@@ -523,8 +483,7 @@ set_prop:
 done:
 
     if (njs_slow_path(njs_is_fast_array(object)
-                      && pq.lhq.key_hash == NJS_LENGTH_HASH)
-                      && njs_strstr_eq(&pq.lhq.key, &length_key)
+                      && pq.lhq.key_hash == NJS_ATOM_STRING_length)
                       && prop->writable == NJS_ATTRIBUTE_FALSE)
     {
         array = njs_array(object);
@@ -558,7 +517,7 @@ done:
 
         if (prev->type == NJS_PROPERTY_HANDLER) {
             if (prev->writable) {
-                ret = njs_prop_handler(prev)(vm, prev, object,
+                ret = njs_prop_handler(prev)(vm, prev, atom_id, object,
                                              njs_prop_value(prop), &retval);
                 if (njs_slow_path(ret == NJS_ERROR)) {
                     return ret;
@@ -578,13 +537,12 @@ done:
         } else {
 
             if (njs_slow_path(njs_is_array(object)
-                              && pq.lhq.key_hash == NJS_LENGTH_HASH)
-                              && njs_strstr_eq(&pq.lhq.key, &length_key))
+                              && pq.lhq.key_hash == NJS_ATOM_STRING_length))
             {
                 if (prev->configurable != NJS_ATTRIBUTE_TRUE
                     && prev->writable != NJS_ATTRIBUTE_TRUE
-                    && !njs_values_strict_equal(njs_prop_value(prev),
-                                                 njs_prop_value(prop)))
+                    && !njs_values_strict_equal(vm, njs_prop_value(prev),
+                                                njs_prop_value(prop)))
                 {
                     njs_type_error(vm, "Cannot redefine property: \"length\"");
                     return NJS_ERROR;
@@ -623,7 +581,7 @@ done:
 
 exception:
 
-    njs_key_string_get(vm, &pq.key,  &pq.lhq.key);
+    njs_atom_string_get(vm, atom_id, &pq.lhq.key);
     njs_type_error(vm, "Cannot redefine property: \"%V\"", &pq.lhq.key);
 
     return NJS_ERROR;
@@ -635,7 +593,7 @@ njs_prop_private_copy(njs_vm_t *vm, njs_property_query_t *pq,
     njs_object_t *proto)
 {
     njs_int_t          ret;
-    njs_value_t        *value;
+    njs_value_t        *value, prop_name;
     njs_object_t       *object;
     njs_function_t     *function;
     njs_object_prop_t  *prop, *shared;
@@ -654,7 +612,7 @@ njs_prop_private_copy(njs_vm_t *vm, njs_property_query_t *pq,
     pq->lhq.value = prop;
     pq->lhq.pool = vm->mem_pool;
 
-    ret = njs_lvlhsh_insert(&proto->hash, &pq->lhq);
+    ret = njs_flathsh_unique_insert(&proto->hash, &pq->lhq);
     if (njs_slow_path(ret != NJS_OK)) {
         njs_internal_error(vm, "lvlhsh insert failed");
         return NJS_ERROR;
@@ -710,7 +668,12 @@ njs_prop_private_copy(njs_vm_t *vm, njs_property_query_t *pq,
             return NJS_ERROR;
         }
 
-        return njs_function_name_set(vm, function, &prop->name, NULL);
+        ret = njs_atom_to_value(vm, &prop_name, pq->lhq.key_hash);
+        if (ret != NJS_OK) {
+            return NJS_ERROR;
+        }
+
+        return njs_function_name_set(vm, function, &prop_name, NULL);
 
     default:
         break;
@@ -721,25 +684,22 @@ njs_prop_private_copy(njs_vm_t *vm, njs_property_query_t *pq,
 
 
 static njs_object_prop_t *
-njs_descriptor_prop(njs_vm_t *vm, const njs_value_t *name,
-    const njs_value_t *desc)
+njs_descriptor_prop(njs_vm_t *vm, const njs_value_t *desc)
 {
-    njs_int_t           ret;
-    njs_bool_t          data, accessor;
-    njs_value_t         value;
-    njs_object_t        *desc_object;
-    njs_function_t      *getter, *setter;
-    njs_object_prop_t   *prop;
-    njs_lvlhsh_query_t  lhq;
-
-    static const njs_value_t  get_string = njs_string("get");
+    njs_int_t            ret;
+    njs_bool_t           data, accessor;
+    njs_value_t          value;
+    njs_object_t         *desc_object;
+    njs_function_t       *getter, *setter;
+    njs_object_prop_t    *prop;
+    njs_flathsh_query_t  lhq;
 
     if (!njs_is_object(desc)) {
         njs_type_error(vm, "property descriptor must be an object");
         return NULL;
     }
 
-    prop = njs_object_prop_alloc(vm, name, &njs_value_invalid,
+    prop = njs_object_prop_alloc(vm, &njs_value_invalid,
                                  NJS_ATTRIBUTE_UNSET);
     if (njs_slow_path(prop == NULL)) {
         return NULL;
@@ -751,7 +711,8 @@ njs_descriptor_prop(njs_vm_t *vm, const njs_value_t *name,
     setter = NJS_PROP_PTR_UNSET;
     desc_object = njs_object(desc);
 
-    njs_object_property_init(&lhq, &get_string, NJS_GET_HASH);
+    lhq.proto = &njs_object_hash_proto;
+    lhq.key_hash = NJS_ATOM_STRING_get;
 
     ret = njs_object_property(vm, desc_object, &lhq, &value);
     if (njs_slow_path(ret == NJS_ERROR)) {
@@ -768,8 +729,7 @@ njs_descriptor_prop(njs_vm_t *vm, const njs_value_t *name,
         getter = njs_is_function(&value) ? njs_function(&value) : NULL;
     }
 
-    lhq.key = njs_str_value("set");
-    lhq.key_hash = NJS_SET_HASH;
+    lhq.key_hash = NJS_ATOM_STRING_set;
 
     ret = njs_object_property(vm, desc_object, &lhq, &value);
     if (njs_slow_path(ret == NJS_ERROR)) {
@@ -786,8 +746,7 @@ njs_descriptor_prop(njs_vm_t *vm, const njs_value_t *name,
         setter = njs_is_function(&value) ? njs_function(&value) : NULL;
     }
 
-    lhq.key = njs_str_value("value");
-    lhq.key_hash = NJS_VALUE_HASH;
+    lhq.key_hash = NJS_ATOM_STRING_value;
 
     ret = njs_object_property(vm, desc_object, &lhq, &value);
     if (njs_slow_path(ret == NJS_ERROR)) {
@@ -799,8 +758,7 @@ njs_descriptor_prop(njs_vm_t *vm, const njs_value_t *name,
         njs_value_assign(njs_prop_value(prop), &value);
     }
 
-    lhq.key = njs_str_value("writable");
-    lhq.key_hash = NJS_WRITABABLE_HASH;
+    lhq.key_hash = NJS_ATOM_STRING_writable;
 
     ret = njs_object_property(vm, desc_object, &lhq, &value);
     if (njs_slow_path(ret == NJS_ERROR)) {
@@ -818,8 +776,7 @@ njs_descriptor_prop(njs_vm_t *vm, const njs_value_t *name,
         return NULL;
     }
 
-    lhq.key = njs_str_value("enumerable");
-    lhq.key_hash = NJS_ENUMERABLE_HASH;
+    lhq.key_hash = NJS_ATOM_STRING_enumerable;
 
     ret = njs_object_property(vm, desc_object, &lhq, &value);
     if (njs_slow_path(ret == NJS_ERROR)) {
@@ -830,8 +787,7 @@ njs_descriptor_prop(njs_vm_t *vm, const njs_value_t *name,
         prop->enumerable = njs_is_true(&value);
     }
 
-    lhq.key = njs_str_value("configurable");
-    lhq.key_hash = NJS_CONFIGURABLE_HASH;
+    lhq.key_hash = NJS_ATOM_STRING_configurable;
 
     ret = njs_object_property(vm, desc_object, &lhq, &value);
     if (njs_slow_path(ret == NJS_ERROR)) {
@@ -852,17 +808,6 @@ njs_descriptor_prop(njs_vm_t *vm, const njs_value_t *name,
 }
 
 
-static const njs_value_t  njs_object_value_string = njs_string("value");
-static const njs_value_t  njs_object_get_string = njs_string("get");
-static const njs_value_t  njs_object_set_string = njs_string("set");
-static const njs_value_t  njs_object_writable_string =
-                                                    njs_string("writable");
-static const njs_value_t  njs_object_enumerable_string =
-                                                    njs_string("enumerable");
-static const njs_value_t  njs_object_configurable_string =
-                                                    njs_string("configurable");
-
-
 njs_int_t
 njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest,
     njs_value_t *value, njs_value_t *key)
@@ -871,10 +816,10 @@ njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest,
     njs_object_t          *desc;
     njs_object_prop_t     *pr, *prop;
     const njs_value_t     *setval;
-    njs_lvlhsh_query_t    lhq;
+    njs_flathsh_query_t   lhq;
     njs_property_query_t  pq;
 
-    njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0, 1);
+    njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 1);
 
     if (njs_slow_path(!njs_is_key(key))) {
         ret = njs_value_to_key(vm, key, key);
@@ -883,7 +828,7 @@ njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest,
         }
     }
 
-    ret = njs_property_query(vm, &pq, value, key);
+    ret = njs_property_query_val(vm, &pq, value, key);
 
     switch (ret) {
     case NJS_OK:
@@ -897,7 +842,7 @@ njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest,
         case NJS_PROPERTY_HANDLER:
             pq.scratch = *prop;
             prop = &pq.scratch;
-            ret = njs_prop_handler(prop)(vm, prop, value, NULL,
+            ret = njs_prop_handler(prop)(vm, prop, key->atom_id, value, NULL,
                                          njs_prop_value(prop));
             if (njs_slow_path(ret == NJS_ERROR)) {
                 return ret;
@@ -932,37 +877,33 @@ njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest,
     lhq.pool = vm->mem_pool;
 
     if (njs_is_data_descriptor(prop)) {
+        lhq.key_hash = NJS_ATOM_STRING_value;
 
-        lhq.key = njs_str_value("value");
-        lhq.key_hash = NJS_VALUE_HASH;
-
-        pr = njs_object_prop_alloc(vm, &njs_object_value_string,
-                                   njs_prop_value(prop), 1);
+        pr = njs_object_prop_alloc(vm, njs_prop_value(prop), 1);
         if (njs_slow_path(pr == NULL)) {
             return NJS_ERROR;
         }
 
         lhq.value = pr;
 
-        ret = njs_lvlhsh_insert(&desc->hash, &lhq);
+        ret = njs_flathsh_unique_insert(&desc->hash, &lhq);
         if (njs_slow_path(ret != NJS_OK)) {
             njs_internal_error(vm, "lvlhsh insert failed");
             return NJS_ERROR;
         }
 
-        lhq.key = njs_str_value("writable");
-        lhq.key_hash = NJS_WRITABABLE_HASH;
+        lhq.key_hash = NJS_ATOM_STRING_writable;
 
         setval = (prop->writable == 1) ? &njs_value_true : &njs_value_false;
 
-        pr = njs_object_prop_alloc(vm, &njs_object_writable_string, setval, 1);
+        pr = njs_object_prop_alloc(vm,  setval, 1);
         if (njs_slow_path(pr == NULL)) {
             return NJS_ERROR;
         }
 
         lhq.value = pr;
 
-        ret = njs_lvlhsh_insert(&desc->hash, &lhq);
+        ret = njs_flathsh_unique_insert(&desc->hash, &lhq);
         if (njs_slow_path(ret != NJS_OK)) {
             njs_internal_error(vm, "lvlhsh insert failed");
             return NJS_ERROR;
@@ -970,11 +911,9 @@ njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest,
 
     } else {
 
-        lhq.key = njs_str_value("get");
-        lhq.key_hash = NJS_GET_HASH;
+        lhq.key_hash = NJS_ATOM_STRING_get;
 
-        pr = njs_object_prop_alloc(vm, &njs_object_get_string,
-                                   &njs_value_undefined, 1);
+        pr = njs_object_prop_alloc(vm, &njs_value_undefined, 1);
         if (njs_slow_path(pr == NULL)) {
             return NJS_ERROR;
         }
@@ -985,17 +924,15 @@ njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest,
 
         lhq.value = pr;
 
-        ret = njs_lvlhsh_insert(&desc->hash, &lhq);
+        ret = njs_flathsh_unique_insert(&desc->hash, &lhq);
         if (njs_slow_path(ret != NJS_OK)) {
             njs_internal_error(vm, "lvlhsh insert failed");
             return NJS_ERROR;
         }
 
-        lhq.key = njs_str_value("set");
-        lhq.key_hash = NJS_SET_HASH;
+        lhq.key_hash = NJS_ATOM_STRING_set;
 
-        pr = njs_object_prop_alloc(vm, &njs_object_set_string,
-                                   &njs_value_undefined, 1);
+        pr = njs_object_prop_alloc(vm, &njs_value_undefined, 1);
         if (njs_slow_path(pr == NULL)) {
             return NJS_ERROR;
         }
@@ -1006,44 +943,42 @@ njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest,
 
         lhq.value = pr;
 
-        ret = njs_lvlhsh_insert(&desc->hash, &lhq);
+        ret = njs_flathsh_unique_insert(&desc->hash, &lhq);
         if (njs_slow_path(ret != NJS_OK)) {
             njs_internal_error(vm, "lvlhsh insert failed");
             return NJS_ERROR;
         }
     }
 
-    lhq.key = njs_str_value("enumerable");
-    lhq.key_hash = NJS_ENUMERABLE_HASH;
+    lhq.key_hash = NJS_ATOM_STRING_enumerable;
 
     setval = (prop->enumerable == 1) ? &njs_value_true : &njs_value_false;
 
-    pr = njs_object_prop_alloc(vm, &njs_object_enumerable_string, setval, 1);
+    pr = njs_object_prop_alloc(vm, setval, 1);
     if (njs_slow_path(pr == NULL)) {
         return NJS_ERROR;
     }
 
     lhq.value = pr;
 
-    ret = njs_lvlhsh_insert(&desc->hash, &lhq);
+    ret = njs_flathsh_unique_insert(&desc->hash, &lhq);
     if (njs_slow_path(ret != NJS_OK)) {
         njs_internal_error(vm, "lvlhsh insert failed");
         return NJS_ERROR;
     }
 
-    lhq.key = njs_str_value("configurable");
-    lhq.key_hash = NJS_CONFIGURABLE_HASH;
+    lhq.key_hash = NJS_ATOM_STRING_configurable;
 
     setval = (prop->configurable == 1) ? &njs_value_true : &njs_value_false;
 
-    pr = njs_object_prop_alloc(vm, &njs_object_configurable_string, setval, 1);
+    pr = njs_object_prop_alloc(vm, setval, 1);
     if (njs_slow_path(pr == NULL)) {
         return NJS_ERROR;
     }
 
     lhq.value = pr;
 
-    ret = njs_lvlhsh_insert(&desc->hash, &lhq);
+    ret = njs_flathsh_unique_insert(&desc->hash, &lhq);
     if (njs_slow_path(ret != NJS_OK)) {
         njs_internal_error(vm, "lvlhsh insert failed");
         return NJS_ERROR;
@@ -1080,12 +1015,13 @@ njs_prop_type_string(njs_object_prop_type_t type)
 
 njs_int_t
 njs_object_prop_init(njs_vm_t *vm, const njs_object_init_t* init,
-    const njs_object_prop_t *base, njs_value_t *value, njs_value_t *retval)
+    njs_object_prop_t *base, uint32_t atom_id, njs_value_t *value,
+    njs_value_t *retval)
 {
-    njs_int_t           ret;
-    njs_object_t        *object;
-    njs_object_prop_t   *prop;
-    njs_lvlhsh_query_t  lhq;
+    njs_int_t            ret;
+    njs_object_t         *object;
+    njs_object_prop_t    *prop;
+    njs_flathsh_query_t  lhq;
 
     object = njs_object_alloc(vm);
     if (object == NULL) {
@@ -1110,14 +1046,13 @@ njs_object_prop_init(njs_vm_t *vm, const njs_object_init_t* init,
     prop->type = NJS_PROPERTY;
     njs_set_object(njs_prop_value(prop), object);
 
-    lhq.proto = &njs_object_hash_proto;
-    njs_string_get(&prop->name, &lhq.key);
-    lhq.key_hash = njs_djb_hash(lhq.key.start, lhq.key.length);
     lhq.value = prop;
+    lhq.key_hash = atom_id;
     lhq.replace = 1;
     lhq.pool = vm->mem_pool;
+    lhq.proto = &njs_object_hash_proto;
 
-    ret = njs_lvlhsh_insert(njs_object_hash(value), &lhq);
+    ret = njs_flathsh_unique_insert(njs_object_hash(value), &lhq);
     if (njs_fast_path(ret == NJS_OK)) {
         njs_value_assign(retval, njs_prop_value(prop));
         return NJS_OK;
diff --git a/src/njs_object_prop_declare.h b/src/njs_object_prop_declare.h
index ecc0801c..f2f7a5eb 100644
--- a/src/njs_object_prop_declare.h
+++ b/src/njs_object_prop_declare.h
@@ -9,23 +9,14 @@
 
 #define NJS_DECLARE_PROP_VALUE(_name, _v, _fl)                                \
     {                                                                         \
-        .type = NJS_PROPERTY,                                                 \
-        .name = njs_string(_name),                                            \
-        .u.value = _v,                                                        \
-        .enumerable = !!(_fl & NJS_OBJECT_PROP_ENUMERABLE),                   \
-        .configurable = !!(_fl & NJS_OBJECT_PROP_CONFIGURABLE),               \
-        .writable = !!(_fl & NJS_OBJECT_PROP_WRITABLE),                       \
-    }
-
-
-#define NJS_DECLARE_PROP_LVALUE(_name, _v, _fl)                               \
-    {                                                                         \
-        .type = NJS_PROPERTY,                                                 \
-        .name = njs_long_string(_name),                                       \
-        .u.value = _v,                                                        \
-        .enumerable = !!(_fl & NJS_OBJECT_PROP_ENUMERABLE),                   \
-        .configurable = !!(_fl & NJS_OBJECT_PROP_CONFIGURABLE),               \
-        .writable = !!(_fl & NJS_OBJECT_PROP_WRITABLE),                       \
+        .atom_id = NJS_ATOM_ ## _name,                                        \
+        .desc = {                                                             \
+            .type = NJS_PROPERTY,                                             \
+            .u.value = _v,                                                    \
+            .enumerable = !!(_fl & NJS_OBJECT_PROP_ENUMERABLE),               \
+            .configurable = !!(_fl & NJS_OBJECT_PROP_CONFIGURABLE),           \
+            .writable = !!(_fl & NJS_OBJECT_PROP_WRITABLE),                   \
+        },                                                                    \
     }
 
 
@@ -35,39 +26,39 @@
                            NJS_OBJECT_PROP_VALUE_CW)
 
 
-#define NJS_DECLARE_PROP_LNATIVE(_name, _native, _nargs, _magic)              \
-    NJS_DECLARE_PROP_LVALUE(_name,                                            \
-                           njs_native_function2(_native, _nargs, _magic),     \
-                           NJS_OBJECT_PROP_VALUE_CW)
-
-
-#define NJS_DECLARE_PROP_HANDLER(_name, _native, _m16, _m32, _fl)             \
+#define NJS_DECLARE_PROP_HANDLER(_name, _native, _m16, _fl)                   \
     {                                                                         \
-        .type = NJS_PROPERTY_HANDLER,                                         \
-        .name = njs_string(_name),                                            \
-        .u.value = njs_prop_handler2(_native, _m16, _m32),                    \
-        .enumerable = !!(_fl & NJS_OBJECT_PROP_ENUMERABLE),                   \
-        .configurable = !!(_fl & NJS_OBJECT_PROP_CONFIGURABLE),               \
-        .writable = !!(_fl & NJS_OBJECT_PROP_WRITABLE),                       \
+        .atom_id = NJS_ATOM_ ## _name,                                        \
+        .desc = {                                                             \
+            .type = NJS_PROPERTY_HANDLER,                                     \
+            .u.value = njs_prop_handler2(_native, _m16),                      \
+            .enumerable = !!(_fl & NJS_OBJECT_PROP_ENUMERABLE),               \
+            .configurable = !!(_fl & NJS_OBJECT_PROP_CONFIGURABLE),           \
+            .writable = !!(_fl & NJS_OBJECT_PROP_WRITABLE),                   \
+        },                                                                    \
     }
 
 
 #define NJS_DECLARE_PROP_GETTER(_name, _native, _magic)                       \
     {                                                                         \
-        .type = NJS_ACCESSOR,                                                 \
-        .name = njs_string(_name),                                            \
-        .u.accessor = njs_getter(_native, _magic),                            \
-        .writable = NJS_ATTRIBUTE_UNSET,                                      \
-        .configurable = 1,                                                    \
+        .atom_id = NJS_ATOM_ ## _name,                                        \
+        .desc = {                                                             \
+            .type = NJS_ACCESSOR,                                             \
+            .u.accessor = njs_getter(_native, _magic),                        \
+            .writable = NJS_ATTRIBUTE_UNSET,                                  \
+            .configurable = 1,                                                \
+        },                                                                    \
     }
 
 
 #define NJS_DECLARE_PROP_NAME(_name)                                          \
-    NJS_DECLARE_PROP_VALUE("name", njs_string(_name), NJS_OBJECT_PROP_VALUE_C)
+    NJS_DECLARE_PROP_VALUE(STRING_name, njs_ascii_strval(_name),              \
+                           NJS_OBJECT_PROP_VALUE_C)
 
 
 #define NJS_DECLARE_PROP_LENGTH(_v)                                           \
-    NJS_DECLARE_PROP_VALUE("length", njs_value(NJS_NUMBER, !!(_v), _v),       \
+    NJS_DECLARE_PROP_VALUE(STRING_length,                                     \
+                           njs_value(NJS_NUMBER, !!(_v), _v),                 \
                            NJS_OBJECT_PROP_VALUE_C)
 
 
diff --git a/src/njs_parser.c b/src/njs_parser.c
index 7fe596c2..a3564396 100644
--- a/src/njs_parser.c
+++ b/src/njs_parser.c
@@ -451,7 +451,7 @@ static njs_int_t njs_parser_export_sink(njs_parser_t *parser);
 static njs_parser_node_t *njs_parser_return_set(njs_parser_t *parser,
     njs_parser_node_t *expr);
 static njs_parser_node_t *njs_parser_variable_node(njs_parser_t *parser,
-    uintptr_t unique_id, njs_variable_type_t type, njs_variable_t  **retvar);
+    uintptr_t atom_id, njs_variable_type_t type, njs_variable_t  **retvar);
 
 static njs_parser_node_t *njs_parser_reference(njs_parser_t *parser,
     njs_lexer_token_t *token);
@@ -529,7 +529,7 @@ njs_parser_reject(njs_parser_t *parser)
 
 njs_int_t
 njs_parser_init(njs_vm_t *vm, njs_parser_t *parser, njs_parser_scope_t *scope,
-    njs_str_t *file, u_char *start, u_char *end, njs_uint_t runtime)
+    njs_str_t *file, u_char *start, u_char *end)
 {
     njs_lexer_t  *lexer;
 
@@ -542,17 +542,15 @@ njs_parser_init(njs_vm_t *vm, njs_parser_t *parser, njs_parser_scope_t *scope,
 
     parser->use_lhs = 0;
 
-    return njs_lexer_init(vm, lexer, file, start, end, runtime, 0);
+    return njs_lexer_init(vm, lexer, file, start, end);
 }
 
 
 njs_int_t
 njs_parser(njs_vm_t *vm, njs_parser_t *parser)
 {
-    njs_int_t                        ret;
-    njs_str_t                        str;
-    njs_lexer_token_t                *token;
-    const njs_lexer_keyword_entry_t  *keyword;
+    njs_int_t          ret;
+    njs_lexer_token_t  *token;
 
     parser->vm = vm;
 
@@ -572,16 +570,6 @@ njs_parser(njs_vm_t *vm, njs_parser_t *parser)
         parser->ret = NJS_OK;
     }
 
-    /* Add this as first variable. */
-    njs_string_get(&njs_string_undefined, &str);
-
-    keyword = njs_lexer_keyword(str.start, str.length);
-    if (njs_slow_path(keyword == NULL)) {
-        return NJS_ERROR;
-    }
-
-    parser->undefined_id = (uintptr_t) keyword->value;
-
     njs_queue_init(&parser->stack);
 
     parser->target = NULL;
@@ -665,11 +653,8 @@ static njs_int_t
 njs_parser_scope_begin(njs_parser_t *parser, njs_scope_t type,
     njs_bool_t init_this)
 {
-    njs_variable_t                   *var;
-    njs_parser_scope_t               *scope, *parent;
-    const njs_lexer_keyword_entry_t  *keyword;
-
-    static const njs_str_t  njs_this_str = njs_str("this");
+    njs_variable_t      *var;
+    njs_parser_scope_t  *scope, *parent;
 
     scope = njs_mp_zalloc(parser->vm->mem_pool, sizeof(njs_parser_scope_t));
     if (njs_slow_path(scope == NULL)) {
@@ -689,13 +674,7 @@ njs_parser_scope_begin(njs_parser_t *parser, njs_scope_t type,
     if (type == NJS_SCOPE_FUNCTION || type == NJS_SCOPE_GLOBAL) {
         if (init_this) {
             /* Add this as first variable. */
-            keyword = njs_lexer_keyword(njs_this_str.start,
-                                        njs_this_str.length);
-            if (njs_slow_path(keyword == NULL)) {
-                return NJS_ERROR;
-            }
-
-            var = njs_variable_add(parser, scope, (uintptr_t) keyword->value,
+            var = njs_variable_add(parser, scope, NJS_ATOM_STRING_this,
                                    NJS_VARIABLE_VAR);
             if (njs_slow_path(var == NULL)) {
                 return NJS_ERROR;
@@ -1004,6 +983,13 @@ njs_parser_primary_expression_test(njs_parser_t *parser,
         }
 
         njs_set_number(&node->u.value, token->number);
+
+        if (njs_number_is_integer_index(token->number)
+            && token->number < 0x80000000)
+        {
+            node->u.value.atom_id = njs_number_atom((uint32_t) token->number);
+        }
+
         node->token_line = token->line;
 
         parser->node = node;
@@ -1207,6 +1193,8 @@ reference:
         return NJS_ERROR;
     }
 
+    node->u.value.atom_id = token->atom_id;
+
     node->token_line = token->line;
     parser->node = node;
 
@@ -1230,8 +1218,6 @@ njs_parser_regexp_literal(njs_parser_t *parser, njs_lexer_token_t *token,
     njs_regex_flags_t     flags;
     njs_regexp_pattern_t  *pattern;
 
-    static const njs_value_t  string_message = njs_string("message");
-
     value = &parser->node->u.value;
     lexer = parser->lexer;
 
@@ -1302,13 +1288,12 @@ njs_parser_regexp_literal(njs_parser_t *parser, njs_lexer_token_t *token,
             if (njs_slow_path(pattern == NULL)) {
                 retval = njs_vm_exception(parser->vm);
                 ret = njs_value_property(parser->vm, &retval,
-                                         njs_value_arg(&string_message),
-                                         &retval);
+                                         NJS_ATOM_STRING_message, &retval);
                 if (njs_slow_path(ret != NJS_OK)) {
                     return NJS_ERROR;
                 }
 
-                njs_string_get(&retval, &text);
+                njs_string_get(parser->vm, &retval, &text);
 
                 njs_parser_syntax_error(parser, "%V", &text);
 
@@ -2087,7 +2072,7 @@ njs_parser_property_definition_after(njs_parser_t *parser,
     if (property->index != NJS_TOKEN_OPEN_BRACKET
         && njs_is_string(&property->u.value))
     {
-        njs_string_get(&property->u.value, &name);
+        njs_string_get(parser->vm, &property->u.value, &name);
 
         if (njs_slow_path(njs_strstr_eq(&name, &proto_string))) {
             if (temp->token_type == NJS_TOKEN_PROTO_INIT) {
@@ -5092,7 +5077,7 @@ njs_parser_variable_declaration(njs_parser_t *parser,
         return NJS_DONE;
     }
 
-    name = njs_parser_variable_node(parser, token->unique_id, parser->var_type,
+    name = njs_parser_variable_node(parser, token->atom_id, parser->var_type,
                                     &var);
     if (name == NULL) {
         return NJS_ERROR;
@@ -5879,8 +5864,7 @@ njs_parser_for_var_binding_or_var_list(njs_parser_t *parser,
                 return NJS_ERROR;
             }
 
-            var = njs_parser_variable_node(parser, token->unique_id,
-                                           type, NULL);
+            var = njs_parser_variable_node(parser, token->atom_id, type, NULL);
             if (var == NULL) {
                 return NJS_ERROR;
             }
@@ -6257,8 +6241,8 @@ njs_parser_break_continue(njs_parser_t *parser, njs_lexer_token_t *token,
                 return njs_parser_stack_pop(parser);
             }
 
-            if (njs_label_find(parser->vm, parser->scope,
-                               token->unique_id) == NULL)
+            if (njs_label_find(parser->vm, parser->scope, token->atom_id)
+                == NULL)
             {
                 njs_parser_syntax_error(parser, "Undefined label \"%V\"",
                                         &token->text);
@@ -6671,19 +6655,19 @@ static njs_int_t
 njs_parser_labelled_statement(njs_parser_t *parser, njs_lexer_token_t *token,
     njs_queue_link_t *current)
 {
-    uintptr_t          unique_id;
-    njs_variable_t     *label;
+    uintptr_t       atom_id;
+    njs_variable_t  *label;
 
-    unique_id = token->unique_id;
+    atom_id = token->atom_id;
 
-    label = njs_label_find(parser->vm, parser->scope, unique_id);
+    label = njs_label_find(parser->vm, parser->scope, atom_id);
     if (label != NULL) {
         njs_parser_syntax_error(parser, "Label \"%V\" "
                                 "has already been declared", &token->text);
         return NJS_DONE;
     }
 
-    label = njs_label_add(parser->vm, parser->scope, unique_id);
+    label = njs_label_add(parser->vm, parser->scope, atom_id);
     if (label == NULL) {
         return NJS_ERROR;
     }
@@ -6706,7 +6690,7 @@ njs_parser_labelled_statement(njs_parser_t *parser, njs_lexer_token_t *token,
         njs_parser_next(parser, njs_parser_statement_wo_node);
     }
 
-    return njs_parser_after(parser, current, (void *) unique_id, 1,
+    return njs_parser_after(parser, current, (void *) atom_id, 1,
                             njs_parser_labelled_statement_after);
 }
 
@@ -6715,10 +6699,11 @@ static njs_int_t
 njs_parser_labelled_statement_after(njs_parser_t *parser,
     njs_lexer_token_t *token, njs_queue_link_t *current)
 {
-    njs_int_t                ret;
-    uintptr_t                unique_id;
-    njs_parser_node_t        *node;
-    const njs_lexer_entry_t  *entry;
+    njs_int_t          ret;
+    njs_str_t          str;
+    uintptr_t          atom_id;
+    njs_value_t        entry;
+    njs_parser_node_t  *node;
 
     node = parser->node;
     if (node == NULL) {
@@ -6732,15 +6717,17 @@ njs_parser_labelled_statement_after(njs_parser_t *parser,
         parser->node = node;
     }
 
-    unique_id = (uintptr_t) parser->target;
-    entry = (const njs_lexer_entry_t *) unique_id;
+    atom_id = (uint32_t) (uintptr_t) parser->target;
+
+    njs_atom_to_value(parser->vm, &entry, atom_id);
+    njs_string_get(parser->vm, &entry, &str);
 
-    ret = njs_name_copy(parser->vm, &parser->node->name, &entry->name);
+    ret = njs_name_copy(parser->vm, &parser->node->name, &str);
     if (ret != NJS_OK) {
         return NJS_ERROR;
     }
 
-    ret = njs_label_remove(parser->vm, parser->scope, unique_id);
+    ret = njs_label_remove(parser->vm, parser->scope, atom_id);
     if (ret != NJS_OK) {
         return NJS_ERROR;
     }
@@ -6907,7 +6894,7 @@ njs_parser_catch_or_finally(njs_parser_t *parser, njs_lexer_token_t *token,
     try->right = catch;
 
     if (njs_lexer_token_is_binding_identifier(token)) {
-        node = njs_parser_variable_node(parser, token->unique_id,
+        node = njs_parser_variable_node(parser, token->atom_id,
                                         NJS_VARIABLE_CATCH, NULL);
         if (node == NULL) {
             return NJS_ERROR;
@@ -7075,7 +7062,7 @@ njs_parser_function_declaration(njs_parser_t *parser, njs_lexer_token_t *token,
     njs_queue_link_t *current)
 {
     njs_int_t          ret;
-    uintptr_t          unique_id;
+    uintptr_t          atom_id;
     njs_bool_t         async;
     njs_variable_t     *var;
     njs_parser_node_t  *node;
@@ -7091,7 +7078,7 @@ njs_parser_function_declaration(njs_parser_t *parser, njs_lexer_token_t *token,
     }
 
     node = parser->node;
-    unique_id = token->unique_id;
+    atom_id = token->atom_id;
 
     njs_lexer_consume_token(parser->lexer, 1);
 
@@ -7106,7 +7093,7 @@ njs_parser_function_declaration(njs_parser_t *parser, njs_lexer_token_t *token,
 
     njs_lexer_consume_token(parser->lexer, 1);
 
-    var = njs_variable_function_add(parser, parser->scope, unique_id,
+    var = njs_variable_function_add(parser, parser->scope, atom_id,
                                     NJS_VARIABLE_FUNCTION);
     if (var == NULL) {
         return NJS_ERROR;
@@ -7114,7 +7101,7 @@ njs_parser_function_declaration(njs_parser_t *parser, njs_lexer_token_t *token,
 
     node->u.value.data.u.lambda = njs_variable_lambda(var);
 
-    node->left = (njs_parser_node_t *) unique_id;
+    node->left = (njs_parser_node_t *) atom_id;
 
     parser->node = node;
 
@@ -7138,16 +7125,16 @@ njs_parser_function_declaration_after(njs_parser_t *parser,
     njs_lexer_token_t *token, njs_queue_link_t *current)
 {
     njs_int_t  ret;
-    uintptr_t  unique_id;
+    uintptr_t  atom_id;
 
-    unique_id = (uintptr_t) parser->node->left;
+    atom_id = (uint32_t) (uintptr_t) parser->node->left;
 
     parser->node->left = NULL;
 
     njs_value_null_set(&parser->node->u.value);
 
     ret = njs_parser_variable_reference(parser, parser->scope, parser->node,
-                                        unique_id, NJS_DECLARATION);
+                                        atom_id, NJS_DECLARATION);
     if (ret != NJS_OK) {
         return NJS_ERROR;
     }
@@ -7170,18 +7157,12 @@ njs_parser_function_parse(njs_parser_t *parser, njs_lexer_token_t *token,
 }
 
 
-static const njs_lexer_entry_t njs_parser_empty_entry =
-{
-    .name = njs_str("")
-};
-
-
 static njs_int_t
 njs_parser_function_expression(njs_parser_t *parser, njs_lexer_token_t *token,
     njs_queue_link_t *current)
 {
     njs_int_t              ret;
-    uintptr_t              unique_id;
+    uintptr_t              atom_id;
     njs_bool_t             async;
     njs_variable_t         *var;
     njs_function_lambda_t  *lambda;
@@ -7197,7 +7178,7 @@ njs_parser_function_expression(njs_parser_t *parser, njs_lexer_token_t *token,
     var = NULL;
 
     if (njs_lexer_token_is_binding_identifier(token)) {
-        unique_id = token->unique_id;
+        atom_id = token->atom_id;
 
         njs_lexer_consume_token(parser->lexer, 1);
 
@@ -7207,7 +7188,7 @@ njs_parser_function_expression(njs_parser_t *parser, njs_lexer_token_t *token,
         }
 
     } else {
-        unique_id = (uintptr_t) &njs_parser_empty_entry;
+        atom_id = NJS_ATOM_STRING_empty;
     }
 
     if (token->type != NJS_TOKEN_OPEN_PARENTHESIS) {
@@ -7222,7 +7203,7 @@ njs_parser_function_expression(njs_parser_t *parser, njs_lexer_token_t *token,
     }
 
     var = njs_variable_scope_add(parser, parser->scope, parser->scope,
-                                 unique_id, NJS_VARIABLE_FUNCTION, 1);
+                                 atom_id, NJS_VARIABLE_FUNCTION, 1);
     if (var == NULL) {
         return NJS_ERROR;
     }
@@ -7230,7 +7211,7 @@ njs_parser_function_expression(njs_parser_t *parser, njs_lexer_token_t *token,
     var->self = 1;
 
     ret = njs_parser_variable_reference(parser, parser->scope,
-                                        parser->node->left, unique_id,
+                                        parser->node->left, atom_id,
                                         NJS_DECLARATION);
     if (ret != NJS_OK) {
         return NJS_ERROR;
@@ -7330,7 +7311,7 @@ njs_parser_formal_parameters(njs_parser_t *parser, njs_lexer_token_t *token,
     default:
         /* SingleNameBinding */
         if (njs_lexer_token_is_binding_identifier(token)) {
-            var_node.key = token->unique_id;
+            var_node.key = token->atom_id;
 
             rb_node = njs_rbtree_find(&parser->scope->variables,
                                       &var_node.node);
@@ -7347,7 +7328,7 @@ njs_parser_formal_parameters(njs_parser_t *parser, njs_lexer_token_t *token,
 
             } else {
                 arg = njs_variable_add(parser, parser->scope,
-                                       token->unique_id, NJS_VARIABLE_VAR);
+                                       token->atom_id, NJS_VARIABLE_VAR);
             }
 
             if (arg == NULL) {
@@ -7410,7 +7391,6 @@ njs_parser_arrow_function(njs_parser_t *parser, njs_lexer_token_t *token,
     njs_queue_link_t *current)
 {
     njs_int_t              ret;
-    uintptr_t              unique_id;
     njs_bool_t             async;
     njs_variable_t         *arg, *var;
     njs_parser_node_t      *node, *name;
@@ -7453,16 +7433,15 @@ njs_parser_arrow_function(njs_parser_t *parser, njs_lexer_token_t *token,
 
     node->left = name;
 
-    unique_id = (uintptr_t) &njs_parser_empty_entry;
-
     var = njs_variable_scope_add(parser, parser->scope, parser->scope,
-                                 unique_id, NJS_VARIABLE_FUNCTION, 1);
+                                 NJS_ATOM_STRING_empty, NJS_VARIABLE_FUNCTION,
+                                 1);
     if (var == NULL) {
         return NJS_ERROR;
     }
 
     ret = njs_parser_variable_reference(parser, parser->scope, node->left,
-                                        unique_id, NJS_DECLARATION);
+                                        NJS_ATOM_STRING_empty, NJS_DECLARATION);
     if (ret != NJS_OK) {
         return NJS_ERROR;
     }
@@ -7490,7 +7469,7 @@ njs_parser_arrow_function(njs_parser_t *parser, njs_lexer_token_t *token,
                                 njs_parser_arrow_function_args_after);
 
     } else if (njs_lexer_token_is_binding_identifier(token)) {
-        arg = njs_variable_add(parser, parser->scope, token->unique_id,
+        arg = njs_variable_add(parser, parser->scope, token->atom_id,
                                NJS_VARIABLE_VAR);
         if (arg == NULL) {
             return NJS_ERROR;
@@ -8189,7 +8168,7 @@ njs_parser_import(njs_parser_t *parser, njs_lexer_token_t *token,
         return njs_parser_failed(parser);
      }
 
-    name = njs_parser_variable_node(parser, token->unique_id, NJS_VARIABLE_LET,
+    name = njs_parser_variable_node(parser, token->atom_id, NJS_VARIABLE_LET,
                                     &var);
     if (name == NULL) {
         return NJS_ERROR;
@@ -8337,14 +8316,14 @@ njs_parser_return_set(njs_parser_t *parser, njs_parser_node_t *expr)
 
 
 static njs_parser_node_t *
-njs_parser_variable_node(njs_parser_t *parser, uintptr_t unique_id,
+njs_parser_variable_node(njs_parser_t *parser, uintptr_t atom_id,
     njs_variable_type_t type, njs_variable_t  **retvar)
 {
     njs_int_t          ret;
     njs_variable_t     *var;
     njs_parser_node_t  *node;
 
-    var = njs_variable_add(parser, parser->scope, unique_id, type);
+    var = njs_variable_add(parser, parser->scope, atom_id, type);
     if (njs_slow_path(var == NULL)) {
         return NULL;
     }
@@ -8358,7 +8337,7 @@ njs_parser_variable_node(njs_parser_t *parser, uintptr_t unique_id,
         return NULL;
     }
 
-    ret = njs_parser_variable_reference(parser, parser->scope, node, unique_id,
+    ret = njs_parser_variable_reference(parser, parser->scope, node, atom_id,
                                         NJS_DECLARATION);
     if (njs_slow_path(ret != NJS_OK)) {
         return NULL;
@@ -8371,14 +8350,11 @@ njs_parser_variable_node(njs_parser_t *parser, uintptr_t unique_id,
 static njs_parser_node_t *
 njs_parser_reference(njs_parser_t *parser, njs_lexer_token_t *token)
 {
-    njs_int_t                        ret;
-    njs_index_t                      index;
-    njs_variable_t                   *var;
-    njs_parser_node_t                *node;
-    njs_parser_scope_t               *scope;
-    const njs_lexer_keyword_entry_t  *keyword;
-
-    static const njs_str_t  njs_undefined_str = njs_str("undefined");
+    njs_int_t           ret;
+    njs_index_t         index;
+    njs_variable_t      *var;
+    njs_parser_node_t   *node;
+    njs_parser_scope_t  *scope;
 
     node = njs_parser_node_new(parser, token->type);
     if (njs_slow_path(node == NULL)) {
@@ -8402,19 +8378,13 @@ njs_parser_reference(njs_parser_t *parser, njs_lexer_token_t *token)
         }
 
         if (parser->vm->options.module) {
-            keyword = njs_lexer_keyword(njs_undefined_str.start,
-                                        njs_undefined_str.length);
-            if (njs_slow_path(keyword == NULL)) {
-                return NULL;
-            }
-
-            token->unique_id = (uintptr_t) keyword->value;
+            token->atom_id = NJS_ATOM_STRING_undefined;
 
         } else if (!scope->arrow_function) {
             index = njs_scope_index(scope->type, 0, NJS_LEVEL_LOCAL,
                                     NJS_VARIABLE_VAR);
 
-            var = njs_variable_scope_add(parser, scope, scope, token->unique_id,
+            var = njs_variable_scope_add(parser, scope, scope, token->atom_id,
                                          NJS_VARIABLE_VAR, index);
             if (njs_slow_path(var == NULL)) {
                 return NULL;
@@ -8425,7 +8395,7 @@ njs_parser_reference(njs_parser_t *parser, njs_lexer_token_t *token)
         node->token_line = token->line;
 
         ret = njs_parser_variable_reference(parser, parser->scope, node,
-                                            token->unique_id, NJS_REFERENCE);
+                                            token->atom_id, NJS_REFERENCE);
         if (njs_slow_path(ret != NJS_OK)) {
             return NULL;
         }
@@ -8450,12 +8420,12 @@ njs_parser_reference(njs_parser_t *parser, njs_lexer_token_t *token)
         node->token_line = token->line;
 
         ret = njs_parser_variable_reference(parser, parser->scope, node,
-                                            token->unique_id, NJS_REFERENCE);
+                                            token->atom_id, NJS_REFERENCE);
         if (njs_slow_path(ret != NJS_OK)) {
             return NULL;
         }
 
-        var = njs_variable_add(parser, scope, token->unique_id,
+        var = njs_variable_add(parser, scope, token->atom_id,
                                NJS_VARIABLE_VAR);
         if (njs_slow_path(var == NULL)) {
             return NULL;
@@ -8478,7 +8448,7 @@ njs_parser_reference(njs_parser_t *parser, njs_lexer_token_t *token)
             node->token_line = token->line;
 
             ret = njs_parser_variable_reference(parser, parser->scope, node,
-                                               token->unique_id, NJS_REFERENCE);
+                                               token->atom_id, NJS_REFERENCE);
             if (njs_slow_path(ret != NJS_OK)) {
                 return NULL;
             }
@@ -8735,6 +8705,7 @@ njs_parser_string_create(njs_vm_t *vm, njs_lexer_token_t *token,
     njs_value_t *value)
 {
     size_t     length;
+    njs_int_t  ret;
     njs_str_t  dst;
 
     length = njs_decode_utf8_length(&token->text, &dst.length);
@@ -8746,10 +8717,15 @@ njs_parser_string_create(njs_vm_t *vm, njs_lexer_token_t *token,
     njs_decode_utf8(&dst, &token->text);
 
     if (length > NJS_STRING_MAP_STRIDE && dst.length != length) {
-        njs_string_utf8_offset_map_init(value->long_string.data->start,
+        njs_string_utf8_offset_map_init(value->string.data->start,
                                         dst.length);
     }
 
+    ret = njs_atom_atomize_key(vm, value);
+    if (njs_slow_path(ret != NJS_OK)) {
+        return NJS_TOKEN_ERROR;
+    }
+
     return NJS_OK;
 }
 
@@ -8994,6 +8970,11 @@ next_char:
         njs_string_utf8_offset_map_init(start, size);
     }
 
+    ret = njs_atom_atomize_key(parser->vm, value);
+    if (njs_slow_path(ret != NJS_OK)) {
+        return NJS_TOKEN_ERROR;
+    }
+
     return NJS_TOKEN_STRING;
 }
 
@@ -9183,7 +9164,7 @@ njs_parser_has_side_effect(njs_parser_node_t *node)
 
 njs_int_t
 njs_parser_variable_reference(njs_parser_t *parser, njs_parser_scope_t *scope,
-    njs_parser_node_t *node, uintptr_t unique_id, njs_reference_type_t type)
+    njs_parser_node_t *node, uintptr_t atom_id, njs_reference_type_t type)
 {
     njs_rbtree_node_t         *rb_node;
     njs_variable_reference_t  *vr;
@@ -9191,10 +9172,10 @@ njs_parser_variable_reference(njs_parser_t *parser, njs_parser_scope_t *scope,
 
     vr = &node->u.reference;
 
-    vr->unique_id = unique_id;
+    vr->atom_id = atom_id;
     vr->type = type;
 
-    parse_node.key = unique_id;
+    parse_node.key = atom_id;
 
     rb_node = njs_rbtree_find(&scope->references, &parse_node.node);
     if (rb_node != NULL) {
@@ -9207,7 +9188,7 @@ njs_parser_variable_reference(njs_parser_t *parser, njs_parser_scope_t *scope,
         return NJS_ERROR;
     }
 
-    rb_parse_node->key = unique_id;
+    rb_parse_node->key = atom_id;
     rb_parse_node->index = NJS_INDEX_NONE;
 
     njs_rbtree_insert(&scope->references, &rb_parse_node->node);
@@ -9241,9 +9222,6 @@ njs_parser_error(njs_vm_t *vm, njs_object_type_t type, njs_str_t *file,
     njs_int_t    ret;
     njs_value_t  value, error;
 
-    static const njs_value_t  file_name = njs_string("fileName");
-    static const njs_value_t  line_number = njs_string("lineNumber");
-
     if (njs_slow_path(vm->top_frame == NULL)) {
         njs_vm_runtime_init(vm);
     }
@@ -9269,13 +9247,12 @@ njs_parser_error(njs_vm_t *vm, njs_object_type_t type, njs_str_t *file,
     njs_error_new(vm, &error, njs_vm_proto(vm, type), msg, p - msg);
 
     njs_set_number(&value, line);
-    njs_value_property_set(vm, &error, njs_value_arg(&line_number), &value);
+    njs_value_property_set(vm, &error, NJS_ATOM_STRING_lineNumber, &value);
 
     if (file->length != 0) {
         ret = njs_string_create(vm, &value, file->start, file->length);
         if (ret == NJS_OK) {
-            njs_value_property_set(vm, &error, njs_value_arg(&file_name),
-                                   &value);
+            njs_value_property_set(vm, &error, NJS_ATOM_STRING_fileName, &value);
         }
     }
 
@@ -9440,7 +9417,7 @@ njs_parser_serialize_tree(njs_chb_t *chain, njs_parser_node_t *node,
                                 njs_number(&node->u.value));
 
             } else {
-                njs_string_get(&node->u.value, &str);
+                njs_string_get_unsafe(&node->u.value, &str);
                 njs_chb_append_literal(chain, " \"value\": \"");
                 njs_chb_append_str(chain, &str);
                 njs_chb_append_literal(chain, "\"");
diff --git a/src/njs_parser.h b/src/njs_parser.h
index db4db02d..2f7cff79 100644
--- a/src/njs_parser.h
+++ b/src/njs_parser.h
@@ -80,7 +80,6 @@ struct njs_parser_s {
     njs_parser_scope_t              *scope;
     njs_variable_type_t             var_type;
     njs_int_t                       ret;
-    uintptr_t                       undefined_id;
 
     uint8_t                         use_lhs;
 
@@ -125,8 +124,7 @@ njs_int_t njs_parser_failed_state(njs_parser_t *parser,
 intptr_t njs_parser_scope_rbtree_compare(njs_rbtree_node_t *node1,
     njs_rbtree_node_t *node2);
 njs_int_t njs_parser_init(njs_vm_t *vm, njs_parser_t *parser,
-    njs_parser_scope_t *scope, njs_str_t *file, u_char *start, u_char *end,
-    njs_uint_t runtime);
+    njs_parser_scope_t *scope, njs_str_t *file, u_char *start, u_char *end);
 njs_int_t njs_parser(njs_vm_t *vm, njs_parser_t *parser);
 
 njs_bool_t njs_variable_closure_test(njs_parser_scope_t *root,
@@ -135,7 +133,7 @@ njs_variable_t *njs_variable_resolve(njs_vm_t *vm, njs_parser_node_t *node);
 njs_index_t njs_variable_index(njs_vm_t *vm, njs_parser_node_t *node);
 njs_bool_t njs_parser_has_side_effect(njs_parser_node_t *node);
 njs_int_t njs_parser_variable_reference(njs_parser_t *parser,
-    njs_parser_scope_t *scope, njs_parser_node_t *node, uintptr_t unique_id,
+    njs_parser_scope_t *scope, njs_parser_node_t *node, uintptr_t atom_id,
     njs_reference_type_t type);
 njs_token_type_t njs_parser_unexpected_token(njs_vm_t *vm, njs_parser_t *parser,
     njs_str_t *name, njs_token_type_t type);
diff --git a/src/njs_promise.c b/src/njs_promise.c
index 79b93a11..f8951cca 100644
--- a/src/njs_promise.c
+++ b/src/njs_promise.c
@@ -105,11 +105,6 @@ static njs_int_t njs_promise_perform_race_handler(njs_vm_t *vm,
     njs_value_t *retval);
 
 
-static const njs_value_t  string_resolve = njs_string("resolve");
-static const njs_value_t  string_any_rejected =
-                                 njs_long_string("All promises were rejected");
-
-
 static njs_promise_t *
 njs_promise_alloc(njs_vm_t *vm)
 {
@@ -391,15 +386,12 @@ njs_promise_value_constructor(njs_vm_t *vm, njs_value_t *value,
 {
     njs_int_t  ret;
 
-    static const njs_value_t  string_constructor = njs_string("constructor");
-
     if (njs_is_function(value)) {
         *dst = *value;
         return NJS_OK;
     }
 
-    ret = njs_value_property(vm, value, njs_value_arg(&string_constructor),
-                             dst);
+    ret = njs_value_property(vm, value, NJS_ATOM_STRING_constructor, dst);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return ret;
     }
@@ -552,10 +544,7 @@ njs_promise_invoke_then(njs_vm_t *vm, njs_value_t *promise, njs_value_t *args,
     njs_int_t    ret;
     njs_value_t  function;
 
-    static const njs_value_t  string_then = njs_string("then");
-
-    ret = njs_value_property(vm, promise, njs_value_arg(&string_then),
-                             &function);
+    ret = njs_value_property(vm, promise, NJS_ATOM_STRING_then, &function);
     if (njs_slow_path(ret != NJS_OK)) {
         if (ret == NJS_DECLINED) {
             goto failed;
@@ -588,8 +577,6 @@ njs_promise_resolve_function(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_native_frame_t     *active_frame;
     njs_promise_context_t  *context;
 
-    static const njs_value_t  string_then = njs_string("then");
-
     active_frame = vm->top_frame;
     context = active_frame->function->context;
     promise = njs_promise(&context->promise);
@@ -603,7 +590,7 @@ njs_promise_resolve_function(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     resolution = njs_arg(args, nargs, 1);
 
-    if (njs_values_same(resolution, &context->promise)) {
+    if (njs_values_same(vm, resolution, &context->promise)) {
         njs_error_fmt_new(vm, &error, NJS_OBJ_TYPE_TYPE_ERROR,
                           "promise self resolution");
         if (njs_slow_path(!njs_is_error(&error))) {
@@ -619,8 +606,7 @@ njs_promise_resolve_function(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         goto fulfill;
     }
 
-    ret = njs_value_property(vm, resolution, njs_value_arg(&string_then),
-                             &then);
+    ret = njs_value_property(vm, resolution, NJS_ATOM_STRING_then, &then);
     if (njs_slow_path(ret == NJS_ERROR)) {
         if (njs_slow_path(njs_is_memory_error(vm, &vm->exception))) {
             return NJS_ERROR;
@@ -693,16 +679,13 @@ njs_promise_resolve(njs_vm_t *vm, njs_value_t *constructor, njs_value_t *x,
     njs_value_t               value;
     njs_promise_capability_t  *capability;
 
-    static const njs_value_t  string_constructor = njs_string("constructor");
-
     if (njs_is_promise(x)) {
-        ret = njs_value_property(vm, x, njs_value_arg(&string_constructor),
-                                 &value);
+        ret = njs_value_property(vm, x, NJS_ATOM_STRING_constructor, &value);
         if (njs_slow_path(ret == NJS_ERROR)) {
             return NJS_ERROR;
         }
 
-        if (njs_values_same(&value, constructor)) {
+        if (njs_values_same(vm, &value, constructor)) {
             njs_value_assign(retval, x);
             return NJS_OK;
         }
@@ -1173,7 +1156,7 @@ njs_promise_all(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    ret = njs_value_property(vm, promise_ctor, njs_value_arg(&string_resolve),
+    ret = njs_value_property(vm, promise_ctor, NJS_ATOM_STRING_resolve,
                              &resolve);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return ret;
@@ -1213,7 +1196,7 @@ njs_promise_perform_all(njs_vm_t *vm, njs_value_t *iterator,
 {
     int64_t       length;
     njs_int_t     ret;
-    njs_value_t   argument;
+    njs_value_t   argument, message;
     njs_object_t  *error;
 
     if (njs_slow_path(!njs_is_object(pargs->constructor))) {
@@ -1253,11 +1236,13 @@ njs_promise_perform_all(njs_vm_t *vm, njs_value_t *iterator,
         njs_mp_free(vm->mem_pool, pargs->remaining);
 
         njs_set_array(&argument, pargs->args.data);
+        njs_atom_to_value(vm, &message,
+                          NJS_ATOM_STRING_All_promises_were_rejected);
 
         if (handler == njs_promise_perform_any_handler) {
             error = njs_error_alloc(vm,
                                 njs_vm_proto(vm, NJS_OBJ_TYPE_AGGREGATE_ERROR),
-                                NULL, &string_any_rejected, &argument);
+                                NULL, &message, &argument);
             if (njs_slow_path(error == NULL)) {
                 return NJS_ERROR;
             }
@@ -1467,17 +1452,12 @@ njs_promise_all_settled_element_functions(njs_vm_t *vm,
     njs_value_t *retval)
 {
     njs_int_t                  ret;
+    uint32_t                   set_atom_id;
+    njs_value_t                status;
     njs_value_t                obj_value, arr_value;
     njs_object_t               *obj;
-    const njs_value_t          *status, *set;
     njs_promise_all_context_t  *context;
 
-    static const njs_value_t  string_status = njs_string("status");
-    static const njs_value_t  string_fulfilled = njs_string("fulfilled");
-    static const njs_value_t  string_value = njs_string("value");
-    static const njs_value_t  string_rejected = njs_string("rejected");
-    static const njs_value_t  string_reason = njs_string("reason");
-
     context = vm->top_frame->function->context;
 
     if (context->already_called) {
@@ -1495,21 +1475,21 @@ njs_promise_all_settled_element_functions(njs_vm_t *vm,
     njs_set_object(&obj_value, obj);
 
     if (rejected) {
-        status = &string_rejected;
-        set = &string_reason;
+        njs_atom_to_value(vm, &status, NJS_ATOM_STRING_rejected);
+        set_atom_id = NJS_ATOM_STRING_reason;
 
     } else {
-        status = &string_fulfilled;
-        set = &string_value;
+        njs_atom_to_value(vm, &status, NJS_ATOM_STRING_fulfilled);
+        set_atom_id = NJS_ATOM_STRING_value;
     }
 
-    ret = njs_value_property_set(vm, &obj_value, njs_value_arg(&string_status),
-                                 njs_value_arg(status));
+    ret = njs_value_property_set(vm, &obj_value, NJS_ATOM_STRING_status,
+                                 njs_value_arg(&status));
     if (njs_slow_path(ret == NJS_ERROR)) {
         return ret;
     }
 
-    ret = njs_value_property_set(vm, &obj_value, njs_value_arg(set),
+    ret = njs_value_property_set(vm, &obj_value, set_atom_id,
                                  njs_arg(args, nargs, 1));
     if (njs_slow_path(ret == NJS_ERROR)) {
         return ret;
@@ -1609,7 +1589,7 @@ njs_promise_any_reject_element_functions(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused, njs_value_t *retval)
 {
     njs_int_t                  ret;
-    njs_value_t                argument, arr_value;
+    njs_value_t                argument, message, arr_value;
     njs_object_t               *error;
     njs_promise_all_context_t  *context;
 
@@ -1633,9 +1613,12 @@ njs_promise_any_reject_element_functions(njs_vm_t *vm, njs_value_t *args,
     if (--(*context->remaining_elements) == 0) {
         njs_mp_free(vm->mem_pool, context->remaining_elements);
 
+        njs_atom_to_value(vm, &message,
+                          NJS_ATOM_STRING_All_promises_were_rejected);
+
         error = njs_error_alloc(vm,
                                 njs_vm_proto(vm, NJS_OBJ_TYPE_AGGREGATE_ERROR),
-                                NULL, &string_any_rejected, &arr_value);
+                                NULL, &message, &arr_value);
         if (njs_slow_path(error == NULL)) {
             return NJS_ERROR;
         }
@@ -1670,7 +1653,7 @@ njs_promise_race(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    ret = njs_value_property(vm, promise_ctor, njs_value_arg(&string_resolve),
+    ret = njs_value_property(vm, promise_ctor, NJS_ATOM_STRING_resolve,
                              &resolve);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return ret;
@@ -1748,34 +1731,32 @@ njs_promise_species(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 }
 
 
-static const njs_object_prop_t  njs_promise_constructor_properties[] =
+static const njs_object_prop_init_t  njs_promise_constructor_properties[] =
 {
     NJS_DECLARE_PROP_LENGTH(1),
 
     NJS_DECLARE_PROP_NAME("Promise"),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
+                             0, 0),
 
-    NJS_DECLARE_PROP_NATIVE("resolve", njs_promise_object_resolve, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_resolve, njs_promise_object_resolve, 1,
+                            0),
 
-    NJS_DECLARE_PROP_NATIVE("reject", njs_promise_object_reject, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_reject, njs_promise_object_reject, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("all", njs_promise_all, 1, NJS_PROMISE_ALL),
+    NJS_DECLARE_PROP_NATIVE(STRING_all, njs_promise_all, 1,
+                            NJS_PROMISE_ALL),
 
-    NJS_DECLARE_PROP_NATIVE("allSettled", njs_promise_all, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_allSettled, njs_promise_all, 1,
                              NJS_PROMISE_ALL_SETTLED),
 
-    NJS_DECLARE_PROP_NATIVE("any", njs_promise_all, 1, NJS_PROMISE_ANY),
+    NJS_DECLARE_PROP_NATIVE(STRING_any, njs_promise_all, 1,
+                            NJS_PROMISE_ANY),
 
-    NJS_DECLARE_PROP_NATIVE("race", njs_promise_race, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_race, njs_promise_race, 1, 0),
 
-    {
-        .type = NJS_ACCESSOR,
-        .name = njs_wellknown_symbol(NJS_SYMBOL_SPECIES),
-        .u.accessor = njs_getter(njs_promise_species, 0),
-        .writable = NJS_ATTRIBUTE_UNSET,
-        .configurable = 1,
-    },
+    NJS_DECLARE_PROP_GETTER(SYMBOL_species, njs_promise_species, 0),
 };
 
 
@@ -1785,24 +1766,22 @@ const njs_object_init_t  njs_promise_constructor_init = {
 };
 
 
-static const njs_object_prop_t  njs_promise_prototype_properties[] =
+static const njs_object_prop_init_t  njs_promise_prototype_properties[] =
 {
-    NJS_DECLARE_PROP_HANDLER("constructor",
-                             njs_object_prototype_create_constructor,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
+                             njs_object_prototype_create_constructor, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    {
-        .type = NJS_PROPERTY,
-        .name = njs_wellknown_symbol(NJS_SYMBOL_TO_STRING_TAG),
-        .u.value = njs_string("Promise"),
-        .configurable = 1,
-    },
+    NJS_DECLARE_PROP_VALUE(SYMBOL_toStringTag, njs_ascii_strval("Promise"),
+                           NJS_OBJECT_PROP_VALUE_C),
 
-    NJS_DECLARE_PROP_NATIVE("then", njs_promise_prototype_then, 2, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_then, njs_promise_prototype_then, 2, 0),
 
-    NJS_DECLARE_PROP_NATIVE("catch", njs_promise_prototype_catch, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_catch, njs_promise_prototype_catch, 1,
+                            0),
 
-    NJS_DECLARE_PROP_NATIVE("finally", njs_promise_prototype_finally, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_finally, njs_promise_prototype_finally,
+                            1, 0),
 };
 
 
diff --git a/src/njs_regexp.c b/src/njs_regexp.c
index 479f0b75..4f1bb180 100644
--- a/src/njs_regexp.c
+++ b/src/njs_regexp.c
@@ -32,9 +32,6 @@ static njs_array_t *njs_regexp_exec_result(njs_vm_t *vm, njs_value_t *r,
     njs_utf8_t utf8, njs_string_prop_t *string, njs_regex_match_data_t *data);
 
 
-const njs_value_t  njs_string_lindex = njs_string("lastIndex");
-
-
 njs_int_t
 njs_regexp_init(njs_vm_t *vm)
 {
@@ -134,9 +131,6 @@ njs_regexp_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             if (njs_slow_path(ret != NJS_OK)) {
                 return ret;
             }
-
-        } else {
-            pattern = njs_value_arg(&njs_string_empty);
         }
 
         re_flags = 0;
@@ -150,7 +144,7 @@ njs_regexp_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             return ret;
         }
 
-        njs_string_get(flags, &string);
+        njs_string_get(vm, flags, &string);
 
         start = string.start;
 
@@ -163,7 +157,12 @@ njs_regexp_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         }
     }
 
-    njs_string_get(pattern, &string);
+    if (njs_is_defined(pattern)) {
+        njs_string_get(vm, pattern, &string);
+
+    } else {
+        string = njs_str_value("");
+    }
 
     return njs_regexp_create(vm, retval, string.start, string.length,
                              re_flags);
@@ -513,7 +512,7 @@ njs_regexp_alloc(njs_vm_t *vm, njs_regexp_pattern_t *pattern)
         regexp->object.error_data = 0;
         njs_set_number(&regexp->last_index, 0);
         regexp->pattern = pattern;
-        njs_string_short_set(&regexp->string, 0, 0);
+        njs_set_empty_string(vm, &regexp->string);
         return regexp;
     }
 
@@ -525,7 +524,8 @@ njs_regexp_alloc(njs_vm_t *vm, njs_regexp_pattern_t *pattern)
 
 static njs_int_t
 njs_regexp_prototype_last_index(njs_vm_t *vm, njs_object_prop_t *unused,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t unused2, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     njs_regexp_t  *regexp;
 
@@ -557,11 +557,6 @@ njs_regexp_prototype_flags(njs_vm_t *vm, njs_value_t *args,
     njs_value_t  *this, value;
     u_char       dst[4];
 
-    static const njs_value_t  string_global = njs_string("global");
-    static const njs_value_t  string_ignore_case = njs_string("ignoreCase");
-    static const njs_value_t  string_multiline = njs_string("multiline");
-    static const njs_value_t  string_sticky = njs_string("sticky");
-
     this = njs_argument(args, 0);
     if (njs_slow_path(!njs_is_object(this))) {
         njs_type_error(vm, "\"this\" argument is not an object");
@@ -570,8 +565,7 @@ njs_regexp_prototype_flags(njs_vm_t *vm, njs_value_t *args,
 
     p = &dst[0];
 
-    ret = njs_value_property(vm, this, njs_value_arg(&string_global),
-                             &value);
+    ret = njs_value_property(vm, this, NJS_ATOM_STRING_global, &value);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return NJS_ERROR;
     }
@@ -580,8 +574,7 @@ njs_regexp_prototype_flags(njs_vm_t *vm, njs_value_t *args,
         *p++ = 'g';
     }
 
-    ret = njs_value_property(vm, this, njs_value_arg(&string_ignore_case),
-                             &value);
+    ret = njs_value_property(vm, this, NJS_ATOM_STRING_ignoreCase, &value);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return NJS_ERROR;
     }
@@ -590,8 +583,7 @@ njs_regexp_prototype_flags(njs_vm_t *vm, njs_value_t *args,
         *p++ = 'i';
     }
 
-    ret = njs_value_property(vm, this, njs_value_arg(&string_multiline),
-                             &value);
+    ret = njs_value_property(vm, this, NJS_ATOM_STRING_multiline, &value);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return NJS_ERROR;
     }
@@ -600,8 +592,7 @@ njs_regexp_prototype_flags(njs_vm_t *vm, njs_value_t *args,
         *p++ = 'm';
     }
 
-    ret = njs_value_property(vm, this, njs_value_arg(&string_sticky),
-                             &value);
+    ret = njs_value_property(vm, this, NJS_ATOM_STRING_sticky, &value);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return NJS_ERROR;
     }
@@ -681,7 +672,7 @@ njs_regexp_prototype_source(njs_vm_t *vm, njs_value_t *args,
 
     if (njs_slow_path(!njs_is_regexp(this))) {
         if (njs_object(this) == njs_vm_proto(vm, NJS_OBJ_TYPE_REGEXP)) {
-            njs_value_assign(retval, &njs_string_empty_regexp);
+            njs_atom_to_value(vm, retval, NJS_ATOM_STRING_spec_EMPTY_REGEXP);
             return NJS_OK;
         }
 
@@ -708,9 +699,6 @@ njs_regexp_prototype_to_string(njs_vm_t *vm, njs_value_t *args,
     njs_value_t        *r, source, flags;
     njs_string_prop_t  source_string, flags_string;
 
-    static const njs_value_t  string_source = njs_string("source");
-    static const njs_value_t  string_flags = njs_string("flags");
-
     r = njs_argument(args, 0);
 
     if (njs_slow_path(!njs_is_object(r))) {
@@ -718,8 +706,7 @@ njs_regexp_prototype_to_string(njs_vm_t *vm, njs_value_t *args,
         return NJS_ERROR;
     }
 
-    ret = njs_value_property(vm, r, njs_value_arg(&string_source),
-                             &source);
+    ret = njs_value_property(vm, r, NJS_ATOM_STRING_source, &source);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return NJS_ERROR;
     }
@@ -729,8 +716,7 @@ njs_regexp_prototype_to_string(njs_vm_t *vm, njs_value_t *args,
         return NJS_ERROR;
     }
 
-    ret = njs_value_property(vm, r, njs_value_arg(&string_flags),
-                             &flags);
+    ret = njs_value_property(vm, r, NJS_ATOM_STRING_flags, &flags);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return NJS_ERROR;
     }
@@ -740,8 +726,8 @@ njs_regexp_prototype_to_string(njs_vm_t *vm, njs_value_t *args,
         return NJS_ERROR;
     }
 
-    (void) njs_string_prop(&source_string, &source);
-    (void) njs_string_prop(&flags_string, &flags);
+    (void) njs_string_prop(vm, &source_string, &source);
+    (void) njs_string_prop(vm, &flags_string, &flags);
 
     size = source_string.size + flags_string.size + njs_length("//");
     length = source_string.length + flags_string.length + njs_length("//");
@@ -879,8 +865,7 @@ njs_regexp_builtin_exec(njs_vm_t *vm, njs_value_t *r, njs_value_t *s,
     regexp->string = *s;
     pattern = regexp->pattern;
 
-    ret = njs_value_property(vm, r, njs_value_arg(&njs_string_lindex),
-                             &value);
+    ret = njs_value_property(vm, r, NJS_ATOM_STRING_lastIndex, &value);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return NJS_ERROR;
     }
@@ -894,7 +879,7 @@ njs_regexp_builtin_exec(njs_vm_t *vm, njs_value_t *r, njs_value_t *s,
         last_index = 0;
     }
 
-    length = njs_string_prop(&string, s);
+    length = njs_string_prop(vm, &string, s);
 
     if (njs_slow_path((size_t) last_index > length)) {
         goto not_found;
@@ -952,8 +937,7 @@ njs_regexp_builtin_exec(njs_vm_t *vm, njs_value_t *r, njs_value_t *s,
             }
 
             njs_set_number(&value, index);
-            ret = njs_value_property_set(vm, r,
-                                         njs_value_arg(&njs_string_lindex),
+            ret = njs_value_property_set(vm, r, NJS_ATOM_STRING_lastIndex,
                                          &value);
             if (njs_slow_path(ret != NJS_OK)) {
                 njs_regex_match_data_free(match_data, vm->regex_generic_ctx);
@@ -989,8 +973,7 @@ not_found:
 
     if (pattern->global || pattern->sticky) {
         njs_set_number(&value, 0);
-        ret = njs_value_property_set(vm, r, njs_value_arg(&njs_string_lindex),
-                                     &value);
+        ret = njs_value_property_set(vm, r, NJS_ATOM_STRING_lastIndex, &value);
         if (njs_slow_path(ret != NJS_OK)) {
             return NJS_ERROR;
         }
@@ -1024,13 +1007,9 @@ njs_regexp_exec_result(njs_vm_t *vm, njs_value_t *r, njs_utf8_t utf8,
     njs_regexp_t          *regexp;
     njs_object_prop_t     *prop;
     njs_regexp_group_t    *group;
-    njs_lvlhsh_query_t    lhq;
+    njs_flathsh_query_t   lhq;
     njs_regexp_pattern_t  *pattern;
 
-    static const njs_value_t  string_index = njs_string("index");
-    static const njs_value_t  string_input = njs_string("input");
-    static const njs_value_t  string_groups = njs_string("groups");
-
     regexp = njs_regexp(r);
     pattern = regexp->pattern;
     array = njs_array_alloc(vm, 0, pattern->ncaptures, 0);
@@ -1059,7 +1038,7 @@ njs_regexp_exec_result(njs_vm_t *vm, njs_value_t *r, njs_utf8_t utf8,
     }
 
     /* FIXME: implement fast CreateDataPropertyOrThrow(). */
-    prop = njs_object_prop_alloc(vm, &string_index, &njs_value_undefined, 1);
+    prop = njs_object_prop_alloc(vm, &njs_value_undefined, 1);
     if (njs_slow_path(prop == NULL)) {
         goto fail;
     }
@@ -1075,42 +1054,39 @@ njs_regexp_exec_result(njs_vm_t *vm, njs_value_t *r, njs_utf8_t utf8,
 
     njs_set_number(&prop->u.value, index);
 
-    lhq.key_hash = NJS_INDEX_HASH;
-    lhq.key = njs_str_value("index");
+    lhq.key_hash = NJS_ATOM_STRING_index;
     lhq.replace = 0;
     lhq.value = prop;
     lhq.pool = vm->mem_pool;
     lhq.proto = &njs_object_hash_proto;
 
-    ret = njs_lvlhsh_insert(&array->object.hash, &lhq);
+    ret = njs_flathsh_unique_insert(&array->object.hash, &lhq);
     if (njs_slow_path(ret != NJS_OK)) {
         goto insert_fail;
     }
 
-    prop = njs_object_prop_alloc(vm, &string_input, &regexp->string, 1);
+    prop = njs_object_prop_alloc(vm, &regexp->string, 1);
     if (njs_slow_path(prop == NULL)) {
         goto fail;
     }
 
-    lhq.key_hash = NJS_INPUT_HASH;
-    lhq.key = njs_str_value("input");
+    lhq.key_hash = NJS_ATOM_STRING_input;
     lhq.value = prop;
 
-    ret = njs_lvlhsh_insert(&array->object.hash, &lhq);
+    ret = njs_flathsh_unique_insert(&array->object.hash, &lhq);
     if (njs_slow_path(ret != NJS_OK)) {
         goto insert_fail;
     }
 
-    prop = njs_object_prop_alloc(vm, &string_groups, &njs_value_undefined, 1);
+    prop = njs_object_prop_alloc(vm, &njs_value_undefined, 1);
     if (njs_slow_path(prop == NULL)) {
         goto fail;
     }
 
-    lhq.key_hash = NJS_GROUPS_HASH;
-    lhq.key = njs_str_value("groups");
+    lhq.key_hash = NJS_ATOM_STRING_groups;
     lhq.value = prop;
 
-    ret = njs_lvlhsh_insert(&array->object.hash, &lhq);
+    ret = njs_flathsh_unique_insert(&array->object.hash, &lhq);
     if (njs_slow_path(ret != NJS_OK)) {
         goto insert_fail;
     }
@@ -1128,23 +1104,21 @@ njs_regexp_exec_result(njs_vm_t *vm, njs_value_t *r, njs_utf8_t utf8,
         do {
             group = &pattern->groups[i];
 
-            ret = njs_string_create(vm, &name, group->name.start,
-                                    group->name.length);
+            ret = njs_atom_string_create(vm, &name, group->name.start,
+                                         group->name.length);
             if (njs_slow_path(ret != NJS_OK)) {
                 goto fail;
             }
 
-            prop = njs_object_prop_alloc(vm, &name,
-                                         &array->start[group->capture], 1);
+            prop = njs_object_prop_alloc(vm, &array->start[group->capture], 1);
             if (njs_slow_path(prop == NULL)) {
                 goto fail;
             }
 
-            lhq.key_hash = group->hash;
-            lhq.key = group->name;
+            lhq.key_hash = name.atom_id;
             lhq.value = prop;
 
-            ret = njs_lvlhsh_insert(&groups->hash, &lhq);
+            ret = njs_flathsh_unique_insert(&groups->hash, &lhq);
             if (njs_slow_path(ret != NJS_OK)) {
                 goto insert_fail;
             }
@@ -1174,38 +1148,39 @@ done:
 static void
 njs_regexp_exec_result_free(njs_vm_t *vm, njs_array_t *result)
 {
-    njs_uint_t          n;
-    njs_value_t         *start;
-    njs_flathsh_t       *hash;
-    njs_object_prop_t   *prop;
-    njs_lvlhsh_each_t   lhe;
-    njs_lvlhsh_query_t  lhq;
+    njs_uint_t           n;
+    njs_value_t          *start;
+    njs_flathsh_t        *hash;
+    njs_object_prop_t    *prop;
+    njs_flathsh_elt_t    *elt;
+    njs_flathsh_each_t   lhe;
+    njs_flathsh_query_t  lhq;
 
     if (result->object.fast_array) {
         start = result->start;
 
         for (n = 0; n < result->length; n++) {
-            if (start[n].short_string.size == NJS_STRING_LONG) {
-                njs_mp_free(vm->mem_pool, start[n].long_string.data);
+            if (start[n].type == NJS_STRING) {
+                njs_mp_free(vm->mem_pool, start[n].string.data);
             }
         }
     }
 
-    njs_lvlhsh_each_init(&lhe, &njs_object_hash_proto);
+    njs_flathsh_each_init(&lhe, &njs_object_hash_proto);
 
     hash = &result->object.hash;
 
     for ( ;; ) {
-        prop = njs_flathsh_each(hash, &lhe);
-
-        if (prop == NULL) {
+        elt = njs_flathsh_each(hash, &lhe);
+        if (elt == NULL) {
             break;
         }
 
+        prop = elt->value;
+
         njs_mp_free(vm->mem_pool, prop);
     }
 
-
     lhq.pool = vm->mem_pool;
     lhq.proto = &njs_object_hash_proto;
 
@@ -1257,9 +1232,7 @@ njs_regexp_exec(njs_vm_t *vm, njs_value_t *r, njs_value_t *s, unsigned flags,
     njs_value_t  exec;
     njs_value_t  arguments[2];
 
-    static const njs_value_t  string_exec = njs_string("exec");
-
-    ret = njs_value_property(vm, r, njs_value_arg(&string_exec), &exec);
+    ret = njs_value_property(vm, r, NJS_ATOM_STRING_exec, &exec);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return NJS_ERROR;
     }
@@ -1324,10 +1297,6 @@ njs_regexp_prototype_symbol_replace(njs_vm_t *vm, njs_value_t *args,
     njs_function_t     *func_replace;
     njs_string_prop_t  s;
 
-    static const njs_value_t  string_global = njs_string("global");
-    static const njs_value_t  string_groups = njs_string("groups");
-    static const njs_value_t  string_index = njs_string("index");
-
     rx = njs_argument(args, 0);
 
     if (njs_slow_path(!njs_is_object(rx))) {
@@ -1342,7 +1311,7 @@ njs_regexp_prototype_symbol_replace(njs_vm_t *vm, njs_value_t *args,
         return ret;
     }
 
-    length = njs_string_prop(&s, string);
+    length = njs_string_prop(vm, &s, string);
 
     rep.start = NULL;
     rep.length = 0;
@@ -1357,7 +1326,7 @@ njs_regexp_prototype_symbol_replace(njs_vm_t *vm, njs_value_t *args,
         }
     }
 
-    ret = njs_value_property(vm, rx, njs_value_arg(&string_global), &value);
+    ret = njs_value_property(vm, rx, NJS_ATOM_STRING_global, &value);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return NJS_ERROR;
     }
@@ -1366,8 +1335,7 @@ njs_regexp_prototype_symbol_replace(njs_vm_t *vm, njs_value_t *args,
 
     if (global) {
         njs_set_number(&value, 0);
-        ret = njs_value_property_set(vm, rx, njs_value_arg(&njs_string_lindex),
-                                     &value);
+        ret = njs_value_property_set(vm, rx, NJS_ATOM_STRING_lastIndex, &value);
         if (njs_slow_path(ret != NJS_OK)) {
             return NJS_ERROR;
         }
@@ -1418,12 +1386,13 @@ njs_regexp_prototype_symbol_replace(njs_vm_t *vm, njs_value_t *args,
             goto exception;
         }
 
-        if (njs_string_length(&value) != 0) {
+        njs_string_get(vm, &value, &m);
+
+        if (m.length != 0) {
             continue;
         }
 
-        ret = njs_value_property(vm, rx, njs_value_arg(&njs_string_lindex),
-                                 &value);
+        ret = njs_value_property(vm, rx, NJS_ATOM_STRING_lastIndex, &value);
         if (njs_slow_path(ret == NJS_ERROR)) {
             goto exception;
         }
@@ -1434,8 +1403,7 @@ njs_regexp_prototype_symbol_replace(njs_vm_t *vm, njs_value_t *args,
         }
 
         njs_set_number(&value, last_index + 1);
-        ret = njs_value_property_set(vm, rx, njs_value_arg(&njs_string_lindex),
-                                     &value);
+        ret = njs_value_property_set(vm, rx, NJS_ATOM_STRING_lastIndex, &value);
         if (njs_slow_path(ret != NJS_OK)) {
             goto exception;
         }
@@ -1462,7 +1430,7 @@ njs_regexp_prototype_symbol_replace(njs_vm_t *vm, njs_value_t *args,
             goto exception;
         }
 
-        ret = njs_value_property(vm, r, njs_value_arg(&string_index), &value);
+        ret = njs_value_property(vm, r, NJS_ATOM_STRING_index, &value);
         if (njs_slow_path(ret == NJS_ERROR)) {
             goto exception;
         }
@@ -1505,7 +1473,7 @@ njs_regexp_prototype_symbol_replace(njs_vm_t *vm, njs_value_t *args,
             }
         }
 
-        ret = njs_value_property(vm, r, njs_value_arg(&string_groups), &groups);
+        ret = njs_value_property(vm, r, NJS_ATOM_STRING_groups, &groups);
         if (njs_slow_path(ret == NJS_ERROR)) {
             goto exception;
         }
@@ -1558,10 +1526,10 @@ njs_regexp_prototype_symbol_replace(njs_vm_t *vm, njs_value_t *args,
         if (p >= next) {
             njs_chb_append(&chain, next, p - next);
 
-            njs_string_get(retval, &rep);
+            njs_string_get(vm, retval, &rep);
             njs_chb_append_str(&chain, &rep);
 
-            njs_string_get(&matched, &m);
+            njs_string_get(vm, &matched, &m);
 
             next = p + m.length;
         }
@@ -1616,9 +1584,6 @@ njs_regexp_prototype_symbol_split(njs_vm_t *vm, njs_value_t *args,
     njs_string_prop_t  s, sv;
     njs_value_t        arguments[2];
 
-    static const njs_value_t  string_lindex = njs_string("lastIndex");
-    static const njs_value_t  string_flags = njs_string("flags");
-
     rx = njs_argument(args, 0);
 
     if (njs_slow_path(!njs_is_object(rx))) {
@@ -1640,7 +1605,7 @@ njs_regexp_prototype_symbol_split(njs_vm_t *vm, njs_value_t *args,
         return ret;
     }
 
-    ret = njs_value_property(vm, rx, njs_value_arg(&string_flags), retval);
+    ret = njs_value_property(vm, rx, NJS_ATOM_STRING_flags, retval);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return NJS_ERROR;
     }
@@ -1650,7 +1615,7 @@ njs_regexp_prototype_symbol_split(njs_vm_t *vm, njs_value_t *args,
         return ret;
     }
 
-    (void) njs_string_prop(&s, retval);
+    (void) njs_string_prop(vm, &s, retval);
 
     sticky = memchr(s.start, 'y', s.size) != NULL;
 
@@ -1705,7 +1670,7 @@ njs_regexp_prototype_symbol_split(njs_vm_t *vm, njs_value_t *args,
         goto done;
     }
 
-    length = njs_string_prop(&s, string);
+    length = njs_string_prop(vm, &s, string);
 
     if (njs_slow_path(s.size == 0)) {
         ret = njs_regexp_exec(vm, rx, string, NJS_REGEXP_FLAG_TEST, &z);
@@ -1731,8 +1696,7 @@ njs_regexp_prototype_symbol_split(njs_vm_t *vm, njs_value_t *args,
 
     while (q < length) {
         njs_set_number(&setval, q);
-        ret = njs_value_property_set(vm, rx, njs_value_arg(&string_lindex),
-                                     &setval);
+        ret = njs_value_property_set(vm, rx, NJS_ATOM_STRING_lastIndex, &setval);
         if (njs_slow_path(ret != NJS_OK)) {
             return NJS_ERROR;
         }
@@ -1747,8 +1711,7 @@ njs_regexp_prototype_symbol_split(njs_vm_t *vm, njs_value_t *args,
             continue;
         }
 
-        ret = njs_value_property(vm, rx, njs_value_arg(&string_lindex),
-                                 retval);
+        ret = njs_value_property(vm, rx, NJS_ATOM_STRING_lastIndex, retval);
         if (njs_slow_path(ret == NJS_ERROR)) {
             return NJS_ERROR;
         }
@@ -1808,7 +1771,7 @@ njs_regexp_prototype_symbol_split(njs_vm_t *vm, njs_value_t *args,
                 return NJS_ERROR;
             }
 
-            (void) njs_string_prop(&sv, retval);
+            (void) njs_string_prop(vm, &sv, retval);
 
             ret = njs_array_string_add(vm, array, sv.start, sv.size,
                                        sv.length);
@@ -1869,13 +1832,14 @@ done:
 }
 
 
-static const njs_object_prop_t  njs_regexp_constructor_properties[] =
+static const njs_object_prop_init_t  njs_regexp_constructor_properties[] =
 {
     NJS_DECLARE_PROP_LENGTH(2),
 
     NJS_DECLARE_PROP_NAME("RegExp"),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
+                             0, 0),
 };
 
 
@@ -1885,56 +1849,48 @@ const njs_object_init_t  njs_regexp_constructor_init = {
 };
 
 
-static const njs_object_prop_t  njs_regexp_prototype_properties[] =
+static const njs_object_prop_init_t  njs_regexp_prototype_properties[] =
 {
-    NJS_DECLARE_PROP_HANDLER("constructor",
-                             njs_object_prototype_create_constructor,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
+                             njs_object_prototype_create_constructor, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_GETTER("flags", njs_regexp_prototype_flags, 0),
+    NJS_DECLARE_PROP_GETTER(STRING_flags, njs_regexp_prototype_flags, 0),
 
-    NJS_DECLARE_PROP_GETTER("global", njs_regexp_prototype_flag,
+    NJS_DECLARE_PROP_GETTER(STRING_global, njs_regexp_prototype_flag,
                             NJS_REGEX_GLOBAL),
 
-    NJS_DECLARE_PROP_GETTER("ignoreCase", njs_regexp_prototype_flag,
+    NJS_DECLARE_PROP_GETTER(STRING_ignoreCase, njs_regexp_prototype_flag,
                             NJS_REGEX_IGNORE_CASE),
 
-    NJS_DECLARE_PROP_GETTER("multiline", njs_regexp_prototype_flag,
+    NJS_DECLARE_PROP_GETTER(STRING_multiline, njs_regexp_prototype_flag,
                             NJS_REGEX_MULTILINE),
 
-    NJS_DECLARE_PROP_GETTER("source", njs_regexp_prototype_source, 0),
+    NJS_DECLARE_PROP_GETTER(STRING_source, njs_regexp_prototype_source, 0),
 
-    NJS_DECLARE_PROP_GETTER("sticky", njs_regexp_prototype_flag,
+    NJS_DECLARE_PROP_GETTER(STRING_sticky, njs_regexp_prototype_flag,
                             NJS_REGEX_STICKY),
 
-    NJS_DECLARE_PROP_NATIVE("toString", njs_regexp_prototype_to_string, 0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_toString,
+                            njs_regexp_prototype_to_string, 0, 0),
 
-    NJS_DECLARE_PROP_NATIVE("test", njs_regexp_prototype_test, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_test, njs_regexp_prototype_test, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("exec", njs_regexp_prototype_exec, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_exec, njs_regexp_prototype_exec, 1, 0),
 
-    {
-        .type = NJS_PROPERTY,
-        .name = njs_wellknown_symbol(NJS_SYMBOL_REPLACE),
-        .u.value = njs_native_function(njs_regexp_prototype_symbol_replace, 2),
-        .writable = 1,
-        .configurable = 1,
-    },
+    NJS_DECLARE_PROP_NATIVE(SYMBOL_replace,
+                            njs_regexp_prototype_symbol_replace, 2, 0),
 
-    {
-        .type = NJS_PROPERTY,
-        .name = njs_wellknown_symbol(NJS_SYMBOL_SPLIT),
-        .u.value = njs_native_function(njs_regexp_prototype_symbol_split, 2),
-        .writable = 1,
-        .configurable = 1,
-    },
+    NJS_DECLARE_PROP_NATIVE(SYMBOL_split,
+                            njs_regexp_prototype_symbol_split, 2, 0),
 };
 
 
-const njs_object_prop_t  njs_regexp_instance_properties[] =
+const njs_object_prop_init_t  njs_regexp_instance_properties[] =
 {
-    NJS_DECLARE_PROP_HANDLER("lastIndex", njs_regexp_prototype_last_index,
-                             0, 0, NJS_OBJECT_PROP_VALUE_W),
+    NJS_DECLARE_PROP_HANDLER(STRING_lastIndex,
+                             njs_regexp_prototype_last_index, 0,
+                             NJS_OBJECT_PROP_VALUE_W),
 };
 
 
diff --git a/src/njs_scope.c b/src/njs_scope.c
index 36ba0ec5..304e4e33 100644
--- a/src/njs_scope.c
+++ b/src/njs_scope.c
@@ -127,7 +127,8 @@ njs_scope_values_hash_test(njs_lvlhsh_query_t *lhq, void *data)
     value = data;
 
     if (njs_is_string(value)) {
-        njs_string_get(value, &string);
+        /* parser strings are always initialized. */
+        njs_string_get_unsafe(value, &string);
 
     } else {
         string.start = (u_char *) value;
@@ -167,24 +168,23 @@ njs_scope_value_index(njs_vm_t *vm, const njs_value_t *src, njs_uint_t runtime,
     uint32_t            value_size, size, length;
     njs_int_t           ret;
     njs_str_t           str;
-    njs_bool_t          long_string;
+    njs_bool_t          is_string;
     njs_value_t         *value;
     njs_string_t        *string;
     njs_lvlhsh_t        *values_hash;
     njs_lvlhsh_query_t  lhq;
 
-    long_string = 0;
+    is_string = 0;
     value_size = sizeof(njs_value_t);
 
     if (njs_is_string(src)) {
-        njs_string_get(src, &str);
+        /* parser strings are always initialized. */
+        njs_string_get_unsafe(src, &str);
 
         size = (uint32_t) str.length;
         start = str.start;
 
-        if (src->short_string.size == NJS_STRING_LONG) {
-            long_string = 1;
-        }
+        is_string = 1;
 
     } else {
         size = value_size;
@@ -207,8 +207,8 @@ njs_scope_value_index(njs_vm_t *vm, const njs_value_t *src, njs_uint_t runtime,
         *index = (njs_index_t *) ((u_char *) value + sizeof(njs_value_t));
 
     } else {
-        if (long_string) {
-            length = src->long_string.data->length;
+        if (is_string) {
+            length = src->string.data->length;
 
             if (size != length && length > NJS_STRING_MAP_STRIDE) {
                 size = njs_string_map_offset(size)
@@ -227,14 +227,15 @@ njs_scope_value_index(njs_vm_t *vm, const njs_value_t *src, njs_uint_t runtime,
 
         *value = *src;
 
-        if (long_string) {
+        if (is_string) {
             string = (njs_string_t *) ((u_char *) value + sizeof(njs_value_t)
                                        + sizeof(njs_index_t));
 
-            value->long_string.data = string;
+            value->string.data = string;
 
             string->start = (u_char *) string + sizeof(njs_string_t);
-            string->length = src->long_string.data->length;
+            string->length = src->string.data->length;
+            string->size = src->string.data->size;
 
             memcpy(string->start, start, size);
         }
diff --git a/src/njs_string.c b/src/njs_string.c
index 6a91cb4c..c38f455b 100644
--- a/src/njs_string.c
+++ b/src/njs_string.c
@@ -160,23 +160,8 @@ njs_string_alloc(njs_vm_t *vm, njs_value_t *value, uint64_t size,
     }
 
     value->type = NJS_STRING;
-    njs_string_truth(value, size);
-
-    if (size <= NJS_STRING_SHORT) {
-        value->short_string.size = size;
-        value->short_string.length = length;
-
-        return value->short_string.start;
-    }
-
-    /*
-     * Setting UTF-8 length is not required here, it just allows
-     * to store the constant in whole byte instead of bit twiddling.
-     */
-    value->short_string.size = NJS_STRING_LONG;
-    value->short_string.length = 0;
-    value->long_string.external = 0;
-    value->long_string.size = size;
+    value->truth = size != 0;
+    value->atom_id = NJS_ATOM_STRING_unknown;
 
     if (size != length && length > NJS_STRING_MAP_STRIDE) {
         map_offset = njs_string_map_offset(size);
@@ -190,9 +175,10 @@ njs_string_alloc(njs_vm_t *vm, njs_value_t *value, uint64_t size,
     string = njs_mp_alloc(vm->mem_pool, sizeof(njs_string_t) + total);
 
     if (njs_fast_path(string != NULL)) {
-        value->long_string.data = string;
+        value->string.data = string;
 
         string->start = (u_char *) string + sizeof(njs_string_t);
+        string->size = size;
         string->length = length;
 
         if (map_offset != 0) {
@@ -209,42 +195,23 @@ njs_string_alloc(njs_vm_t *vm, njs_value_t *value, uint64_t size,
 }
 
 
-uint32_t
-njs_string_length(njs_value_t *string)
-{
-    uint32_t  length, size;
-
-    if (string->short_string.size != NJS_STRING_LONG) {
-        size = string->short_string.size;
-        length = string->short_string.length;
-
-    } else {
-        size = string->long_string.size;
-        length = string->long_string.data->length;
-    }
-
-    return (length == 0) ? size : length;
-}
-
-
 size_t
-njs_string_prop(njs_string_prop_t *string, const njs_value_t *value)
+njs_string_prop(njs_vm_t *vm, njs_string_prop_t *string,
+    const njs_value_t *value)
 {
-    size_t     size;
-    uintptr_t  length;
-
-    size = value->short_string.size;
+    size_t       size, length;
+    njs_value_t  s;
 
-    if (size != NJS_STRING_LONG) {
-        string->start = (u_char *) value->short_string.start;
-        length = value->short_string.length;
-
-    } else {
-        string->start = (u_char *) value->long_string.data->start;
-        size = value->long_string.size;
-        length = value->long_string.data->length;
+    if (njs_slow_path(value->string.data == NULL)) {
+        njs_assert(value->atom_id != NJS_ATOM_STRING_unknown);
+        (void) njs_atom_to_value(vm, &s, value->atom_id);
+        value = &s;
     }
 
+    string->start = (u_char *) value->string.data->start;
+    size = value->string.data->size;
+    length = value->string.data->length;
+
     string->size = size;
     string->length = length;
 
@@ -255,32 +222,8 @@ njs_string_prop(njs_string_prop_t *string, const njs_value_t *value)
 void
 njs_string_truncate(njs_value_t *value, uint32_t size, uint32_t length)
 {
-    u_char    *dst, *src;
-    uint32_t  n;
-
-    if (size <= NJS_STRING_SHORT) {
-        if (value->short_string.size == NJS_STRING_LONG) {
-            dst = value->short_string.start;
-            src = value->long_string.data->start;
-
-            n = size;
-
-            while (n != 0) {
-                /* The maximum size is just 14 bytes. */
-                njs_pragma_loop_disable_vectorization;
-
-                *dst++ = *src++;
-                n--;
-            }
-        }
-
-        value->short_string.size = size;
-        value->short_string.length = length;
-
-    } else {
-        value->long_string.size = size;
-        value->long_string.data->length = length;
-    }
+    value->string.data->size = size;
+    value->string.data->length = length;
 }
 
 
@@ -430,7 +373,7 @@ njs_string_base64(njs_vm_t *vm, njs_value_t *retval, const njs_str_t *src)
     length = njs_encode_base64_length(src, &dst.length);
 
     if (njs_slow_path(dst.length == 0)) {
-        njs_value_assign(retval, &njs_string_empty);
+        njs_set_empty_string(vm, retval);
         return NJS_OK;
     }
 
@@ -452,7 +395,7 @@ njs_string_base64url(njs_vm_t *vm, njs_value_t *retval, const njs_str_t *src)
     njs_str_t  dst;
 
     if (njs_slow_path(src->length == 0)) {
-        njs_value_assign(retval, &njs_string_empty);
+        njs_set_empty_string(vm, retval);
         return NJS_OK;
     }
 
@@ -488,21 +431,21 @@ njs_string_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused, njs_value_t *retval)
 {
     njs_int_t           ret;
-    njs_value_t         *value;
+    njs_value_t         value;
     njs_object_value_t  *object;
 
     if (nargs == 1) {
-        value = njs_value_arg(&njs_string_empty);
+        njs_set_empty_string(vm, &value);
 
     } else {
-        value = &args[1];
+        value = args[1];
 
-        if (njs_slow_path(!njs_is_string(value))) {
-            if (!vm->top_frame->ctor && njs_is_symbol(value)) {
-                return njs_symbol_descriptive_string(vm, retval, value);
+        if (njs_slow_path(!njs_is_string(&value))) {
+            if (!vm->top_frame->ctor && njs_is_symbol(&value)) {
+                return njs_symbol_descriptive_string(vm, retval, &value);
             }
 
-            ret = njs_value_to_string(vm, value, value);
+            ret = njs_value_to_string(vm, &value, &value);
             if (njs_slow_path(ret != NJS_OK)) {
                 return ret;
             }
@@ -510,7 +453,7 @@ njs_string_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     if (vm->top_frame->ctor) {
-        object = njs_object_value_alloc(vm, NJS_OBJ_TYPE_STRING, 0, value);
+        object = njs_object_value_alloc(vm, NJS_OBJ_TYPE_STRING, 0, &value);
         if (njs_slow_path(object == NULL)) {
             return NJS_ERROR;
         }
@@ -518,28 +461,31 @@ njs_string_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         njs_set_object_value(retval, object);
 
     } else {
-        njs_value_assign(retval, value);
+        njs_value_assign(retval, &value);
     }
 
     return NJS_OK;
 }
 
 
-static const njs_object_prop_t  njs_string_constructor_properties[] =
+static const njs_object_prop_init_t  njs_string_constructor_properties[] =
 {
     NJS_DECLARE_PROP_LENGTH(1),
 
     NJS_DECLARE_PROP_NAME("String"),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
+                             0, 0),
 
-    NJS_DECLARE_PROP_NATIVE("fromCharCode", njs_string_from_char_code, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_fromCharCode, njs_string_from_char_code,
+                            1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("fromCodePoint", njs_string_from_char_code, 1, 1),
+    NJS_DECLARE_PROP_NATIVE(STRING_fromCodePoint,
+                            njs_string_from_char_code, 1, 1),
 };
 
 
-const njs_object_init_t  njs_string_constructor_init = {
+static const njs_object_init_t  njs_string_constructor_init = {
     njs_string_constructor_properties,
     njs_nitems(njs_string_constructor_properties),
 };
@@ -547,9 +493,9 @@ const njs_object_init_t  njs_string_constructor_init = {
 
 static njs_int_t
 njs_string_instance_length(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
-    size_t              size;
     uintptr_t           length;
     njs_object_value_t  *ov;
 
@@ -568,15 +514,12 @@ njs_string_instance_length(njs_vm_t *vm, njs_object_prop_t *prop,
     }
 
     if (njs_is_string(value)) {
-        size = value->short_string.size;
-        length = value->short_string.length;
-
-        if (size == NJS_STRING_LONG) {
-            size = value->long_string.size;
-            length = value->long_string.data->length;
+        if (njs_slow_path(value->string.data == NULL)) {
+            njs_assert(value->atom_id != NJS_ATOM_STRING_unknown);
+            njs_atom_to_value(vm, value, value->atom_id);
         }
 
-        length = (length == 0) ? size : length;
+        length = value->string.data->length;
     }
 
     njs_set_number(retval, length);
@@ -586,97 +529,37 @@ njs_string_instance_length(njs_vm_t *vm, njs_object_prop_t *prop,
 
 
 njs_bool_t
-njs_string_eq(const njs_value_t *v1, const njs_value_t *v2)
+njs_string_eq(njs_vm_t *vm, const njs_value_t *v1, const njs_value_t *v2)
 {
-    size_t        size, length1, length2;
-    const u_char  *start1, *start2;
+    njs_str_t  s1, s2;
 
-    size = v1->short_string.size;
+    njs_string_get(vm, v1, &s1);
+    njs_string_get(vm, v2, &s2);
 
-    if (size != v2->short_string.size) {
+    if (s1.length != s2.length) {
         return 0;
     }
 
-    if (size != NJS_STRING_LONG) {
-        length1 = v1->short_string.length;
-        length2 = v2->short_string.length;
-
-        /*
-         * Using full memcmp() comparison if at least one string
-         * is a Byte string.
-         */
-        if (length1 != 0 && length2 != 0 && length1 != length2) {
-            return 0;
-        }
-
-        start1 = v1->short_string.start;
-        start2 = v2->short_string.start;
-
-    } else {
-        size = v1->long_string.size;
-
-        if (size != v2->long_string.size) {
-            return 0;
-        }
-
-        length1 = v1->long_string.data->length;
-        length2 = v2->long_string.data->length;
-
-        /*
-         * Using full memcmp() comparison if at least one string
-         * is a Byte string.
-         */
-        if (length1 != 0 && length2 != 0 && length1 != length2) {
-            return 0;
-        }
-
-        start1 = v1->long_string.data->start;
-        start2 = v2->long_string.data->start;
-    }
-
-    return (memcmp(start1, start2, size) == 0);
+    return (memcmp(s1.start, s2.start, s1.length) == 0);
 }
 
 
 njs_int_t
-njs_string_cmp(const njs_value_t *v1, const njs_value_t *v2)
+njs_string_cmp(njs_vm_t *vm, const njs_value_t *v1, const njs_value_t *v2)
 {
-    size_t        size, size1, size2;
-    njs_int_t     ret;
-    const u_char  *start1, *start2;
-
-    njs_assert(njs_is_string(v1));
-    njs_assert(njs_is_string(v2));
-
-    size1 = v1->short_string.size;
-
-    if (size1 != NJS_STRING_LONG) {
-        start1 = v1->short_string.start;
-
-    } else {
-        size1 = v1->long_string.size;
-        start1 = v1->long_string.data->start;
-    }
-
-    size2 = v2->short_string.size;
-
-    if (size2 != NJS_STRING_LONG) {
-        start2 = v2->short_string.start;
-
-    } else {
-        size2 = v2->long_string.size;
-        start2 = v2->long_string.data->start;
-    }
+    njs_int_t  ret;
+    njs_str_t  s1, s2;
 
-    size = njs_min(size1, size2);
+    njs_string_get(vm, v1, &s1);
+    njs_string_get(vm, v2, &s2);
 
-    ret = memcmp(start1, start2, size);
+    ret = memcmp(s1.start, s2.start, njs_min(s1.length, s2.length));
 
     if (ret != 0) {
         return ret;
     }
 
-    return (size1 - size2);
+    return (s1.length - s2.length);
 }
 
 
@@ -748,7 +631,7 @@ njs_string_prototype_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     mask = -1;
 
     for (i = 0; i < nargs; i++) {
-        (void) njs_string_prop(&string, &args[i]);
+        (void) njs_string_prop(vm, &string, &args[i]);
 
         size += string.size;
         length += string.length;
@@ -764,7 +647,7 @@ njs_string_prototype_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     p = start;
 
     for (i = 0; i < nargs; i++) {
-        (void) njs_string_prop(&string, &args[i]);
+        (void) njs_string_prop(vm, &string, &args[i]);
 
         p = memcpy(p, string.start, string.size);
         p += string.size;
@@ -832,7 +715,7 @@ njs_string_prototype_substring(njs_vm_t *vm, njs_value_t *args,
         return ret;
     }
 
-    length = njs_string_prop(&string, njs_argument(args, 0));
+    length = njs_string_prop(vm, &string, njs_argument(args, 0));
 
     slice.string_length = length;
     start = 0;
@@ -910,7 +793,7 @@ njs_string_prototype_substr(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return ret;
     }
 
-    length = njs_string_prop(&string, njs_argument(args, 0));
+    length = njs_string_prop(vm, &string, njs_argument(args, 0));
 
     slice.string_length = length;
     start = 0;
@@ -988,7 +871,7 @@ njs_string_prototype_char_at(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return ret;
     }
 
-    slice.string_length = njs_string_prop(&string, njs_argument(args, 0));
+    slice.string_length = njs_string_prop(vm, &string, njs_argument(args, 0));
 
     ret = njs_value_to_integer(vm, njs_arg(args, nargs, 1), &start);
     if (njs_slow_path(ret != NJS_OK)) {
@@ -1013,7 +896,7 @@ 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]);
+    slice->string_length = njs_string_prop(vm, string, &args[0]);
 
     return njs_string_slice_args(vm, slice, args, nargs);
 }
@@ -1153,7 +1036,7 @@ njs_string_slice(njs_vm_t *vm, njs_value_t *retval,
         return njs_string_new(vm, retval, prop.start, prop.size, prop.length);
     }
 
-    njs_value_assign(retval, &njs_string_empty);
+    njs_set_empty_string(vm, retval);
 
     return NJS_OK;
 }
@@ -1177,7 +1060,7 @@ njs_string_prototype_char_code_at(njs_vm_t *vm, njs_value_t *args,
         return ret;
     }
 
-    length = njs_string_prop(&string, njs_argument(args, 0));
+    length = njs_string_prop(vm, &string, njs_argument(args, 0));
 
     ret = njs_value_to_integer(vm, njs_arg(args, nargs, 1), &index);
     if (njs_slow_path(ret != NJS_OK)) {
@@ -1306,7 +1189,7 @@ njs_string_decode_hex(njs_vm_t *vm, njs_value_t *retval, const njs_str_t *src)
     length = njs_decode_hex_length(src, &size);
 
     if (njs_slow_path(size == 0)) {
-        njs_value_assign(retval, &njs_string_empty);
+        njs_set_empty_string(vm, retval);
         return NJS_OK;
     }
 
@@ -1429,7 +1312,7 @@ njs_string_decode_base64_core(njs_vm_t *vm, njs_value_t *retval,
     length = njs_decode_base64_length_core(src, basis, &dst.length);
 
     if (njs_slow_path(dst.length == 0)) {
-        njs_value_assign(retval, &njs_string_empty);
+        njs_set_empty_string(vm, retval);
         return NJS_OK;
     }
 
@@ -1660,8 +1543,8 @@ njs_string_prototype_index_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return ret;
     }
 
-    length = njs_string_prop(&string, this);
-    (void) njs_string_prop(&s, search);
+    length = njs_string_prop(vm, &string, this);
+    (void) njs_string_prop(vm, &s, search);
 
     from = njs_min(njs_max(from, 0), length);
 
@@ -1713,11 +1596,11 @@ njs_string_prototype_last_index_of(njs_vm_t *vm, njs_value_t *args,
         start = INT64_MAX;
     }
 
-    length = njs_string_prop(&string, this);
+    length = njs_string_prop(vm, &string, this);
 
     start = njs_min(njs_max(start, 0), length);
 
-    search_length = njs_string_prop(&s, search);
+    search_length = njs_string_prop(vm, &s, search);
 
     index = length - search_length;
 
@@ -1801,7 +1684,7 @@ njs_string_prototype_includes(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             }
         }
 
-        search_length = njs_string_prop(&search, value);
+        search_length = njs_string_prop(vm, &search, value);
 
         if (nargs > 2) {
             value = njs_argument(args, 2);
@@ -1828,7 +1711,7 @@ njs_string_prototype_includes(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             return NJS_OK;
         }
 
-        length = njs_string_prop(&string, &args[0]);
+        length = njs_string_prop(vm, &string, &args[0]);
 
         if (length - index >= search_length) {
             end = string.start + string.size;
@@ -1879,7 +1762,7 @@ njs_string_prototype_starts_or_ends_with(njs_vm_t *vm, njs_value_t *args,
         }
     }
 
-    search_length = njs_string_prop(&search, value);
+    search_length = njs_string_prop(vm, &search, value);
 
     value = njs_arg(args, nargs, 2);
 
@@ -1902,7 +1785,7 @@ njs_string_prototype_starts_or_ends_with(njs_vm_t *vm, njs_value_t *args,
     }
 
     if (nargs > 1) {
-        length = njs_string_prop(&string, &args[0]);
+        length = njs_string_prop(vm, &string, &args[0]);
 
         if (starts) {
             if (index < 0) {
@@ -2072,7 +1955,7 @@ njs_string_prototype_to_lower_case(njs_vm_t *vm, njs_value_t *args,
         return ret;
     }
 
-    (void) njs_string_prop(&string, njs_argument(args, 0));
+    (void) njs_string_prop(vm, &string, njs_argument(args, 0));
 
     if (njs_is_ascii_string(&string)) {
 
@@ -2143,7 +2026,7 @@ njs_string_prototype_to_upper_case(njs_vm_t *vm, njs_value_t *args,
         return ret;
     }
 
-    (void) njs_string_prop(&string, njs_argument(args, 0));
+    (void) njs_string_prop(vm, &string, njs_argument(args, 0));
 
     if (njs_is_ascii_string(&string)) {
 
@@ -2194,8 +2077,8 @@ njs_string_prototype_to_upper_case(njs_vm_t *vm, njs_value_t *args,
 
 
 uint32_t
-njs_string_trim(const njs_value_t *value, njs_string_prop_t *string,
-    unsigned mode)
+njs_string_trim(njs_vm_t *vm, const njs_value_t *value,
+    njs_string_prop_t *string, unsigned mode)
 {
     uint32_t              cp, trim;
     const u_char          *p, *prev, *start, *end;
@@ -2203,7 +2086,7 @@ njs_string_trim(const njs_value_t *value, njs_string_prop_t *string,
 
     trim = 0;
 
-    njs_string_prop(string, value);
+    njs_string_prop(vm, string, value);
 
     start = string->start;
     end = string->start + string->size;
@@ -2326,7 +2209,7 @@ njs_string_prototype_trim(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return ret;
     }
 
-    trim = njs_string_trim(value, &string, mode);
+    trim = njs_string_trim(vm, value, &string, mode);
 
     if (trim == 0) {
         njs_value_assign(retval, value);
@@ -2334,7 +2217,7 @@ njs_string_prototype_trim(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     if (string.size == 0) {
-        njs_value_assign(retval, &njs_string_empty);
+        njs_set_empty_string(vm, retval);
         return NJS_OK;
     }
 
@@ -2377,10 +2260,10 @@ njs_string_prototype_repeat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    (void) njs_string_prop(&string, this);
+    (void) njs_string_prop(vm, &string, this);
 
     if (njs_slow_path(n == 0 || string.size == 0)) {
-        njs_value_assign(retval, &njs_string_empty);
+        njs_set_empty_string(vm, retval);
         return NJS_OK;
     }
 
@@ -2422,14 +2305,12 @@ njs_string_prototype_pad(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     const u_char       *end;
     njs_string_prop_t  string, pad_string;
 
-    static const njs_value_t  string_space = njs_string(" ");
-
     ret = njs_string_object_validate(vm, njs_argument(args, 0));
     if (njs_slow_path(ret != NJS_OK)) {
         return ret;
     }
 
-    length = njs_string_prop(&string, njs_argument(args, 0));
+    length = njs_string_prop(vm, &string, njs_argument(args, 0));
 
     new_length = 0;
 
@@ -2465,19 +2346,22 @@ njs_string_prototype_pad(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     pad = njs_arg(args, nargs, 2);
 
-    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_ERROR;
-            }
+    if (njs_slow_path(!njs_is_string(pad) && !njs_is_undefined(pad))) {
+        ret = njs_value_to_string(vm, pad, pad);
+        if (njs_slow_path(ret != NJS_OK)) {
+            return NJS_ERROR;
         }
     }
 
-    pad_length = njs_string_prop(&pad_string, pad);
+    if (njs_slow_path(njs_is_undefined(pad))) {
+        pad_string.start = (u_char *) " ";
+        pad_string.size = 1;
+        pad_string.length = 1;
+        pad_length = 1;
+
+    } else {
+        pad_length = njs_string_prop(vm, &pad_string, pad);
+    }
 
     if (pad_string.size == 0) {
         njs_value_assign(retval, njs_argument(args, 0));
@@ -2571,7 +2455,7 @@ njs_string_prototype_search(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
                 }
             }
 
-            (void) njs_string_prop(&string, value);
+            (void) njs_string_prop(vm, &string, value);
 
             if (string.size != 0) {
                 pattern = njs_regexp_pattern_create(vm, string.start,
@@ -2588,7 +2472,7 @@ njs_string_prototype_search(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
         index = -1;
 
-        (void) njs_string_prop(&string, &args[0]);
+        (void) njs_string_prop(vm, &string, &args[0]);
 
         n = (string.length != 0);
 
@@ -2657,11 +2541,11 @@ njs_string_prototype_match(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
                     return ret;
                 }
 
-                njs_string_get(&args[1], &string);
+                njs_string_get(vm, &args[1], &string);
             }
 
         } else {
-            njs_string_get(&args[1], &string);
+            njs_string_get(vm, &args[1], &string);
         }
 
         /* A void value. */
@@ -2694,7 +2578,7 @@ njs_string_match_multiple(njs_vm_t *vm, njs_value_t *args,
     njs_set_number(&args[1].data.u.regexp->last_index, 0);
     njs_set_null(retval);
 
-    (void) njs_string_prop(&string, &args[0]);
+    (void) njs_string_prop(vm, &string, &args[0]);
 
     utf8 = NJS_STRING_ASCII;
     type = NJS_REGEXP_BYTE;
@@ -2795,9 +2679,6 @@ njs_string_prototype_split(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_string_prop_t  string, split;
     njs_value_t        arguments[3];
 
-    static const njs_value_t  split_key =
-                                        njs_wellknown_symbol(NJS_SYMBOL_SPLIT);
-
     this = njs_argument(args, 0);
 
     if (njs_slow_path(njs_is_null_or_undefined(this))) {
@@ -2810,7 +2691,7 @@ njs_string_prototype_split(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     value = njs_lvalue_arg(&limit_lvalue, args, nargs, 2);
 
     if (!njs_is_null_or_undefined(separator)) {
-        ret = njs_value_method(vm, separator, njs_value_arg(&split_key),
+        ret = njs_value_method(vm, separator, NJS_ATOM_SYMBOL_split,
                                &splitter);
         if (njs_slow_path(ret != NJS_OK)) {
             return ret;
@@ -2859,8 +2740,8 @@ njs_string_prototype_split(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         goto single;
     }
 
-    (void) njs_string_prop(&string, this);
-    (void) njs_string_prop(&split, separator);
+    (void) njs_string_prop(vm, &string, this);
+    (void) njs_string_prop(vm, &split, separator);
 
     if (njs_slow_path(string.size == 0)) {
         if (split.size != 0) {
@@ -2951,7 +2832,7 @@ njs_string_get_substitution(njs_vm_t *vm, njs_value_t *matched,
     njs_value_t        name, value;
     njs_string_prop_t  s, m;
 
-    njs_string_get(replacement, &rep);
+    njs_string_get(vm, replacement, &rep);
     p = rep.start;
     end = rep.start + rep.length;
 
@@ -2981,21 +2862,21 @@ njs_string_get_substitution(njs_vm_t *vm, njs_value_t *matched,
             break;
 
         case '&':
-            (void) njs_string_prop(&m, matched);
+            (void) njs_string_prop(vm, &m, matched);
             njs_chb_append(&chain, m.start, m.size);
             p += 2;
             break;
 
         case '`':
-            (void) njs_string_prop(&s, string);
+            (void) njs_string_prop(vm, &s, string);
             n = njs_string_offset(&s, pos) - s.start;
             njs_chb_append(&chain, s.start, n);
             p += 2;
             break;
 
         case '\'':
-            length = njs_string_prop(&m, matched);
-            (void) njs_string_prop(&s, string);
+            length = njs_string_prop(vm, &m, matched);
+            (void) njs_string_prop(vm, &s, string);
 
             tail = njs_string_offset(&s, pos + length) - s.start;
 
@@ -3021,7 +2902,7 @@ njs_string_get_substitution(njs_vm_t *vm, njs_value_t *matched,
 
             p = r + 1;
 
-            ret = njs_value_property(vm, groups, &name, &value);
+            ret = njs_value_property_val(vm, groups, &name, &value);
             if (njs_slow_path(ret == NJS_ERROR)) {
                 goto exception;
             }
@@ -3032,7 +2913,7 @@ njs_string_get_substitution(njs_vm_t *vm, njs_value_t *matched,
                     goto exception;
                 }
 
-                njs_string_get(&value, &str);
+                njs_string_get(vm, &value, &str);
                 njs_chb_append_str(&chain, &str);
             }
 
@@ -3062,7 +2943,7 @@ njs_string_get_substitution(njs_vm_t *vm, njs_value_t *matched,
                 p += (c2 != 0) ? 3 : 2;
 
                 if (njs_is_defined(&captures[n])) {
-                    njs_string_get(&captures[n], &cap);
+                    njs_string_get(vm, &captures[n], &cap);
                     njs_chb_append_str(&chain, &cap);
                 }
 
@@ -3110,10 +2991,6 @@ njs_string_prototype_replace(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_function_t     *func_replace;
     njs_string_prop_t  string, s, ret_string;
 
-    static const njs_value_t  replace_key =
-                                      njs_wellknown_symbol(NJS_SYMBOL_REPLACE);
-    static const njs_value_t  string_flags = njs_string("flags");
-
     this = njs_argument(args, 0);
 
     if (njs_slow_path(njs_is_null_or_undefined(this))) {
@@ -3126,8 +3003,7 @@ njs_string_prototype_replace(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     replace = njs_lvalue_arg(&replace_lvalue, args, nargs, 2);
 
     if (!njs_is_null_or_undefined(search)) {
-        ret = njs_value_method(vm, search, njs_value_arg(&replace_key),
-                               &replacer);
+        ret = njs_value_method(vm, search, NJS_ATOM_SYMBOL_replace, &replacer);
         if (njs_slow_path(ret != NJS_OK)) {
             return ret;
         }
@@ -3140,8 +3016,8 @@ njs_string_prototype_replace(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
                 && njs_function(&replacer)->u.native ==
                 njs_regexp_prototype_symbol_replace)
             {
-                ret = njs_value_property(vm, search,
-                                         njs_value_arg(&string_flags), &value);
+                ret = njs_value_property(vm, search, NJS_ATOM_STRING_flags,
+                                         &value);
                 if (njs_slow_path(ret == NJS_ERROR)) {
                     return NJS_ERROR;
                 }
@@ -3151,7 +3027,7 @@ njs_string_prototype_replace(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
                     return NJS_ERROR;
                 }
 
-                njs_string_get(&value, &str);
+                njs_string_get(vm, &value, &str);
 
                 if (njs_strlchr(str.start, str.start + str.length, 'g')
                     == NULL)
@@ -3191,8 +3067,8 @@ njs_string_prototype_replace(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         njs_value_assign(&arguments[2], this);
     }
 
-    (void) njs_string_prop(&string, this);
-    (void) njs_string_prop(&s, search);
+    (void) njs_string_prop(vm, &string, this);
+    (void) njs_string_prop(vm, &s, search);
 
     pos = njs_string_index_of(&string, &s, 0);
     if (pos < 0) {
@@ -3227,7 +3103,7 @@ njs_string_prototype_replace(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
         end = njs_string_offset(&string, pos);
 
-        (void) njs_string_prop(&ret_string, &value);
+        (void) njs_string_prop(vm, &ret_string, &value);
 
         size = string.size + ret_string.size - s.size;
         length = string.length + ret_string.length - s.length;
@@ -3274,7 +3150,7 @@ njs_string_prototype_replace(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         }
 
         end = njs_string_offset(&string, pos);
-        (void) njs_string_prop(&ret_string, &value);
+        (void) njs_string_prop(vm, &ret_string, &value);
 
         njs_chb_append(&chain, start, end - start);
         njs_chb_append(&chain, ret_string.start, ret_string.size);
@@ -3332,7 +3208,7 @@ njs_string_prototype_iterator_obj(njs_vm_t *vm, njs_value_t *args,
 
 
 double
-njs_string_to_number(const njs_value_t *value)
+njs_string_to_number(njs_vm_t *vm, const njs_value_t *value)
 {
     double             num;
     njs_bool_t         minus;
@@ -3341,7 +3217,7 @@ njs_string_to_number(const njs_value_t *value)
 
     const size_t  infinity = njs_length("Infinity");
 
-    (void) njs_string_trim(value, &string, NJS_TRIM_START);
+    (void) njs_string_trim(vm, value, &string, NJS_TRIM_START);
 
     p = string.start;
     end = p + string.size;
@@ -3413,16 +3289,17 @@ njs_string_to_index(const njs_value_t *value)
     const u_char  *p, *start, *end;
     u_char        buf[128];
 
-    size = value->short_string.size;
-
-    if (size != NJS_STRING_LONG) {
-        start = value->short_string.start;
+    if (njs_slow_path(value->type == NJS_SYMBOL)) {
+        return NAN;
+    }
 
-    } else {
-        size = value->long_string.size;
-        start = value->long_string.data->start;
+    if (njs_atom_is_number(value->atom_id)) {
+        return njs_atom_number(value->atom_id);
     }
 
+    size = value->string.data->size;
+    start = value->string.data->start;
+
     p = start;
     end = p + size;
     minus = 0;
@@ -3493,89 +3370,99 @@ njs_string_to_index(const njs_value_t *value)
 }
 
 
-static const njs_object_prop_t  njs_string_prototype_properties[] =
+static const njs_object_prop_init_t  njs_string_prototype_properties[] =
 {
-    NJS_DECLARE_PROP_HANDLER("__proto__", njs_primitive_prototype_get_proto,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING___proto__,
+                             njs_primitive_prototype_get_proto, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
     NJS_DECLARE_PROP_LENGTH(0),
 
-    NJS_DECLARE_PROP_HANDLER("constructor",
-                             njs_object_prototype_create_constructor,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
-
-    NJS_DECLARE_PROP_NATIVE("valueOf", njs_string_prototype_value_of, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
+                             njs_object_prototype_create_constructor, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_NATIVE("toString", njs_string_prototype_to_string, 0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_valueOf, njs_string_prototype_value_of,
+                            0, 0),
 
-    NJS_DECLARE_PROP_NATIVE("concat", njs_string_prototype_concat, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_toString,
+                            njs_string_prototype_to_string, 0, 0),
 
-    NJS_DECLARE_PROP_NATIVE("slice", njs_string_prototype_slice, 2, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_concat,
+                            njs_string_prototype_concat, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("substring", njs_string_prototype_substring, 2, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_slice, njs_string_prototype_slice, 2,
+                            0),
 
-    NJS_DECLARE_PROP_NATIVE("substr", njs_string_prototype_substr, 2, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_substring,
+                            njs_string_prototype_substring, 2, 0),
 
-    NJS_DECLARE_PROP_NATIVE("charAt", njs_string_prototype_char_at, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_substr, njs_string_prototype_substr, 2,
+                            0),
 
-    NJS_DECLARE_PROP_NATIVE("charCodeAt", njs_string_prototype_char_code_at, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_charAt, njs_string_prototype_char_at, 1,
                             0),
 
-    NJS_DECLARE_PROP_NATIVE("codePointAt", njs_string_prototype_char_code_at,
-                            1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_charCodeAt,
+                            njs_string_prototype_char_code_at, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("indexOf", njs_string_prototype_index_of, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_codePointAt,
+                            njs_string_prototype_char_code_at, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("lastIndexOf", njs_string_prototype_last_index_of,
+    NJS_DECLARE_PROP_NATIVE(STRING_indexOf, njs_string_prototype_index_of,
                             1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("includes", njs_string_prototype_includes, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_lastIndexOf,
+                            njs_string_prototype_last_index_of, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("startsWith",
+    NJS_DECLARE_PROP_NATIVE(STRING_includes, njs_string_prototype_includes,
+                            1, 0),
+
+    NJS_DECLARE_PROP_NATIVE(STRING_startsWith,
                             njs_string_prototype_starts_or_ends_with, 1, 1),
 
-    NJS_DECLARE_PROP_NATIVE("endsWith",
+    NJS_DECLARE_PROP_NATIVE(STRING_endsWith,
                             njs_string_prototype_starts_or_ends_with, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("toLowerCase", njs_string_prototype_to_lower_case,
-                            0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_toLowerCase,
+                            njs_string_prototype_to_lower_case, 0, 0),
 
-    NJS_DECLARE_PROP_NATIVE("toUpperCase", njs_string_prototype_to_upper_case,
-                            0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_toUpperCase,
+                            njs_string_prototype_to_upper_case, 0, 0),
 
-    NJS_DECLARE_PROP_NATIVE("trim", njs_string_prototype_trim, 0,
+    NJS_DECLARE_PROP_NATIVE(STRING_trim, njs_string_prototype_trim, 0,
                             NJS_TRIM_START | NJS_TRIM_END),
 
-    NJS_DECLARE_PROP_NATIVE("trimStart", njs_string_prototype_trim, 0,
+    NJS_DECLARE_PROP_NATIVE(STRING_trimStart, njs_string_prototype_trim, 0,
                             NJS_TRIM_START),
 
-    NJS_DECLARE_PROP_NATIVE("trimEnd", njs_string_prototype_trim, 0,
+    NJS_DECLARE_PROP_NATIVE(STRING_trimEnd, njs_string_prototype_trim, 0,
                             NJS_TRIM_END),
 
-    NJS_DECLARE_PROP_NATIVE("repeat", njs_string_prototype_repeat, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_repeat, njs_string_prototype_repeat, 1,
+                            0),
 
-    NJS_DECLARE_PROP_NATIVE("padStart", njs_string_prototype_pad, 1, 1),
+    NJS_DECLARE_PROP_NATIVE(STRING_padStart, njs_string_prototype_pad, 1,
+                            1),
 
-    NJS_DECLARE_PROP_NATIVE("padEnd", njs_string_prototype_pad, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_padEnd, njs_string_prototype_pad, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("search", njs_string_prototype_search, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_search, njs_string_prototype_search, 1,
+                            0),
 
-    NJS_DECLARE_PROP_NATIVE("match", njs_string_prototype_match, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_match, njs_string_prototype_match, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("split", njs_string_prototype_split, 2, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_split, njs_string_prototype_split, 2, 0),
 
-    NJS_DECLARE_PROP_NATIVE("replace", njs_string_prototype_replace, 2, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_replace, njs_string_prototype_replace, 2,
+                            0),
 
-    NJS_DECLARE_PROP_NATIVE("replaceAll", njs_string_prototype_replace, 2, 1),
+    NJS_DECLARE_PROP_NATIVE(STRING_replaceAll, njs_string_prototype_replace,
+                            2, 1),
 
-    {
-        .type = NJS_PROPERTY,
-        .name = njs_wellknown_symbol(NJS_SYMBOL_ITERATOR),
-        .u.value = njs_native_function2(njs_string_prototype_iterator_obj, 0,
-                                        NJS_ENUM_VALUES),
-        .writable = 1,
-        .configurable = 1,
-    },
+    NJS_DECLARE_PROP_NATIVE(SYMBOL_iterator,
+                            njs_string_prototype_iterator_obj, 0,
+                            NJS_ENUM_VALUES),
 };
 
 
@@ -3585,9 +3472,10 @@ const njs_object_init_t  njs_string_prototype_init = {
 };
 
 
-const njs_object_prop_t  njs_string_instance_properties[] =
+const njs_object_prop_init_t  njs_string_instance_properties[] =
 {
-    NJS_DECLARE_PROP_HANDLER("length", njs_string_instance_length, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_length, njs_string_instance_length, 0,
+                             0),
 };
 
 
@@ -3649,7 +3537,7 @@ njs_string_encode_uri(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     };
 
     if (nargs < 2) {
-        njs_value_assign(retval, &njs_string_undefined);
+        njs_atom_to_value(vm, retval, NJS_ATOM_STRING_undefined);
         return NJS_OK;
     }
 
@@ -3663,7 +3551,7 @@ njs_string_encode_uri(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     njs_prefetch(escape);
 
-    (void) njs_string_prop(&string, value);
+    (void) njs_string_prop(vm, &string, value);
 
     size = 0;
     src = string.start;
@@ -3878,7 +3766,7 @@ njs_string_decode_uri(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     };
 
     if (nargs < 2) {
-        njs_value_assign(retval, &njs_string_undefined);
+        njs_atom_to_value(vm, retval, NJS_ATOM_STRING_undefined);
         return NJS_OK;
     }
 
@@ -3893,7 +3781,7 @@ njs_string_decode_uri(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_prefetch(reserve);
     njs_prefetch(&hex['0']);
 
-    (void) njs_string_prop(&string, value);
+    (void) njs_string_prop(vm, &string, value);
 
     length = 0;
     src = string.start;
@@ -4023,7 +3911,7 @@ njs_string_btoa(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return ret;
     }
 
-    len = njs_string_prop(&string, value);
+    len = njs_string_prop(vm, &string, value);
 
     p = string.start;
     end = string.start + string.size;
@@ -4121,7 +4009,7 @@ njs_string_atob(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     /* Forgiving-base64 decode. */
 
     b64 = njs_basis64;
-    njs_string_get(value, &str);
+    njs_string_get(vm, value, &str);
 
     tmp = njs_mp_alloc(vm->mem_pool, str.length);
     if (tmp == NULL) {
@@ -4208,7 +4096,7 @@ njs_string_atob(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     if (size == 0) {
-        njs_value_assign(retval, &njs_string_empty);
+        njs_set_empty_string(vm, retval);
         return NJS_OK;
     }
 
@@ -4237,7 +4125,6 @@ const njs_object_type_init_t  njs_string_type_init = {
     .constructor_props = &njs_string_constructor_init,
     .prototype_props = &njs_string_prototype_init,
     .prototype_value = { .object_value = {
-                            .value = njs_string(""),
                             .object = { .type = NJS_OBJECT_VALUE } }
                        },
 };
diff --git a/src/njs_string.h b/src/njs_string.h
index 686a5a74..1961152f 100644
--- a/src/njs_string.h
+++ b/src/njs_string.h
@@ -73,6 +73,7 @@
 struct njs_string_s {
     u_char    *start;
     uint32_t  length;   /* Length in UTF-8 characters. */
+    uint32_t  size;
 };
 
 
@@ -111,8 +112,8 @@ njs_int_t njs_string_create(njs_vm_t *vm, njs_value_t *value, const u_char *src,
 njs_int_t njs_string_create_chb(njs_vm_t *vm, njs_value_t *value,
     njs_chb_t *chain);
 
-uint32_t njs_string_length(njs_value_t *string);
-size_t njs_string_prop(njs_string_prop_t *string, const njs_value_t *value);
+size_t njs_string_prop(njs_vm_t *vm, njs_string_prop_t *string,
+    const njs_value_t *value);
 
 void njs_encode_hex(njs_str_t *dst, const njs_str_t *src);
 size_t njs_encode_hex_length(const njs_str_t *src, size_t *out_size);
@@ -143,10 +144,11 @@ njs_int_t njs_string_decode_base64(njs_vm_t *vm, njs_value_t *value,
 njs_int_t njs_string_decode_base64url(njs_vm_t *vm, njs_value_t *value,
     const njs_str_t *src);
 void njs_string_truncate(njs_value_t *value, uint32_t size, uint32_t length);
-uint32_t njs_string_trim(const njs_value_t *value, njs_string_prop_t *string,
-    unsigned mode);
+uint32_t njs_string_trim(njs_vm_t *vm, const njs_value_t *value,
+    njs_string_prop_t *string, unsigned mode);
 void njs_string_copy(njs_value_t *dst, njs_value_t *src);
-njs_int_t njs_string_cmp(const njs_value_t *val1, const njs_value_t *val2);
+njs_int_t njs_string_cmp(njs_vm_t *vm, const njs_value_t *val1,
+    const njs_value_t *val2);
 void njs_string_slice_string_prop(njs_string_prop_t *dst,
     const njs_string_prop_t *string, const njs_slice_prop_t *slice);
 njs_int_t njs_string_slice(njs_vm_t *vm, njs_value_t *dst,
@@ -172,6 +174,21 @@ njs_int_t njs_string_get_substitution(njs_vm_t *vm, njs_value_t *matched,
     njs_value_t *groups, njs_value_t *replacement, njs_value_t *retval);
 
 
+njs_inline njs_int_t
+njs_atom_string_create(njs_vm_t *vm, njs_value_t *value, const u_char *src,
+    size_t size)
+{
+    njs_int_t  ret;
+
+    ret = njs_string_create(vm, value, src, size);
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
+    }
+
+    return njs_atom_atomize_key(vm, value);
+}
+
+
 njs_inline njs_bool_t
 njs_is_ascii_string(njs_string_prop_t *string)
 {
diff --git a/src/njs_symbol.c b/src/njs_symbol.c
index a284d4e9..46634a61 100644
--- a/src/njs_symbol.c
+++ b/src/njs_symbol.c
@@ -8,63 +8,9 @@
 #include <njs_main.h>
 
 
-static const njs_value_t  njs_symbol_async_iterator_name =
-                            njs_long_string("Symbol.asyncIterator");
-static const njs_value_t  njs_symbol_has_instance_name =
-                            njs_long_string("Symbol.hasInstance");
-static const njs_value_t  njs_symbol_is_concat_spreadable_name =
-                            njs_long_string("Symbol.isConcatSpreadable");
-static const njs_value_t  njs_symbol_iterator_name =
-                            njs_long_string("Symbol.iterator");
-static const njs_value_t  njs_symbol_match_name =
-                            njs_string("Symbol.match");
-static const njs_value_t  njs_symbol_match_all_name =
-                            njs_long_string("Symbol.matchAll");
-static const njs_value_t  njs_symbol_replace_name =
-                            njs_string("Symbol.replace");
-static const njs_value_t  njs_symbol_search_name =
-                            njs_string("Symbol.search");
-static const njs_value_t  njs_symbol_species_name =
-                            njs_string("Symbol.species");
-static const njs_value_t  njs_symbol_split_name =
-                            njs_string("Symbol.split");
-static const njs_value_t  njs_symbol_to_primitive_name =
-                            njs_long_string("Symbol.toPrimitive");
-static const njs_value_t  njs_symbol_to_string_tag_name =
-                            njs_long_string("Symbol.toStringTag");
-static const njs_value_t  njs_symbol_unscopables_name =
-                            njs_long_string("Symbol.unscopables");
-
-
-static const njs_value_t  *njs_symbol_names[NJS_SYMBOL_KNOWN_MAX] = {
-    &njs_string_invalid,
-    &njs_symbol_async_iterator_name,
-    &njs_symbol_has_instance_name,
-    &njs_symbol_is_concat_spreadable_name,
-    &njs_symbol_iterator_name,
-    &njs_symbol_match_name,
-    &njs_symbol_match_all_name,
-    &njs_symbol_replace_name,
-    &njs_symbol_search_name,
-    &njs_symbol_species_name,
-    &njs_symbol_split_name,
-    &njs_symbol_to_primitive_name,
-    &njs_symbol_to_string_tag_name,
-    &njs_symbol_unscopables_name,
-};
-
-
 const njs_value_t *
 njs_symbol_description(const njs_value_t *value)
 {
-    uint32_t  key;
-
-    key = njs_symbol_key(value);
-
-    if (key < NJS_SYMBOL_KNOWN_MAX) {
-        return njs_symbol_names[key];
-    }
-
     return value->data.u.value != NULL ? value->data.u.value
                                        : &njs_value_undefined;
 }
@@ -80,11 +26,14 @@ njs_symbol_descriptive_string(njs_vm_t *vm, njs_value_t *dst,
 
     description = njs_symbol_description(value);
 
-    if (njs_is_undefined(description)) {
-        description = &njs_string_empty;
-    }
+    if (!njs_is_undefined(description)) {
+        (void) njs_string_prop(vm, &string, description);
 
-    (void) njs_string_prop(&string, description);
+    } else {
+        string.start = (u_char *) "";
+        string.size = 0;
+        string.length = 0;
+    }
 
     string.length += njs_length("Symbol()");
 
@@ -105,7 +54,6 @@ static njs_int_t
 njs_symbol_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused, njs_value_t *retval)
 {
-    uint64_t     key;
     njs_int_t    ret;
     njs_value_t  *value, *name;
 
@@ -125,13 +73,6 @@ njs_symbol_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         }
     }
 
-    key = ++vm->symbol_generator;
-
-    if (njs_slow_path(key >= UINT32_MAX)) {
-        njs_internal_error(vm, "Symbol generator overflow");
-        return NJS_ERROR;
-    }
-
     name = njs_mp_alloc(vm->mem_pool, sizeof(njs_value_t));
     if (njs_slow_path(name == NULL)) {
         njs_memory_error(vm);
@@ -139,7 +80,12 @@ njs_symbol_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     njs_value_assign(name, value);
-    njs_set_symbol(retval, key, name);
+    njs_set_symbol(retval, 0, name);
+
+    ret = njs_atom_symbol_add(vm, retval);
+    if (ret != NJS_OK) {
+        return NJS_ERROR;
+    }
 
     return NJS_OK;
 }
@@ -149,7 +95,6 @@ static njs_int_t
 njs_symbol_for(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused, njs_value_t *retval)
 {
-    uint64_t              key;
     njs_int_t             ret;
     njs_value_t           *value, lvalue;
     njs_rbtree_node_t     *rb_node;
@@ -171,7 +116,7 @@ njs_symbol_for(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         node = (njs_rb_symbol_node_t *) rb_node;
 
         if (njs_is_string(&node->name)
-            && njs_string_cmp(value, &node->name) == 0)
+            && njs_string_cmp(vm, value, &node->name) == 0)
         {
             njs_set_symbol(retval, node->key, &node->name);
             return NJS_OK;
@@ -180,25 +125,23 @@ njs_symbol_for(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         rb_node = njs_rbtree_node_successor(&vm->global_symbols, rb_node);
     }
 
-    key = ++vm->symbol_generator;
-
-    if (njs_slow_path(key >= UINT32_MAX)) {
-        njs_internal_error(vm, "Symbol generator overflow");
-        return NJS_ERROR;
-    }
-
     node = njs_mp_alloc(vm->mem_pool, sizeof(njs_rb_symbol_node_t));
     if (njs_slow_path(node == NULL)) {
         njs_memory_error(vm);
         return NJS_ERROR;
     }
 
-    node->key = key;
     njs_value_assign(&node->name, value);
+    njs_set_symbol(retval, 0, &node->name);
 
-    njs_rbtree_insert(&vm->global_symbols, &node->node);
+    ret = njs_atom_symbol_add(vm, retval);
+    if (ret != NJS_OK) {
+        return NJS_ERROR;
+    }
+
+    node->key = retval->atom_id;
 
-    njs_set_symbol(retval, key, &node->name);
+    njs_rbtree_insert(&vm->global_symbols, &node->node);
 
     return NJS_OK;
 }
@@ -229,56 +172,60 @@ njs_symbol_key_for(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 }
 
 
-static const njs_object_prop_t  njs_symbol_constructor_properties[] =
+static const njs_object_prop_init_t  njs_symbol_constructor_properties[] =
 {
     NJS_DECLARE_PROP_LENGTH(0),
 
     NJS_DECLARE_PROP_NAME("Symbol"),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
+                             0, 0),
 
-    NJS_DECLARE_PROP_NATIVE("for", njs_symbol_for, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_for, njs_symbol_for, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("keyFor", njs_symbol_key_for, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_keyFor, njs_symbol_key_for, 1, 0),
 
-    NJS_DECLARE_PROP_VALUE("asyncIterator",
-                           njs_wellknown_symbol(NJS_SYMBOL_ASYNC_ITERATOR), 0),
+    NJS_DECLARE_PROP_VALUE(STRING_asyncIterator,
+                           njs_symval(asyncIterator, "Symbol.asyncIterator"),
+                           0),
 
-    NJS_DECLARE_PROP_VALUE("hasInstance",
-                           njs_wellknown_symbol(NJS_SYMBOL_HAS_INSTANCE), 0),
+    NJS_DECLARE_PROP_VALUE(STRING_hasInstance,
+                           njs_symval(hasInstance, "Symbol.hasInstance"),
+                           0),
 
-    NJS_DECLARE_PROP_LVALUE("isConcatSpreadable",
-                     njs_wellknown_symbol(NJS_SYMBOL_IS_CONCAT_SPREADABLE), 0),
+    NJS_DECLARE_PROP_VALUE(STRING_isConcatSpreadable,
+                   njs_symval(isConcatSpreadable, "Symbol.isConcatSpreadable"),
+                   0),
 
-    NJS_DECLARE_PROP_VALUE("iterator",
-                           njs_wellknown_symbol(NJS_SYMBOL_ITERATOR), 0),
+    NJS_DECLARE_PROP_VALUE(STRING_iterator,
+                           njs_symval(iterator, "Symbol.iterator"), 0),
 
-    NJS_DECLARE_PROP_VALUE("match",
-                           njs_wellknown_symbol(NJS_SYMBOL_MATCH), 0),
+    NJS_DECLARE_PROP_VALUE(STRING_match, njs_symval(match, "Symbol.match"), 0),
 
-    NJS_DECLARE_PROP_VALUE("matchAll",
-                           njs_wellknown_symbol(NJS_SYMBOL_MATCH_ALL), 0),
+    NJS_DECLARE_PROP_VALUE(STRING_matchAll,
+                           njs_symval(matchAll, "Symbol.matchAll"), 0),
 
-    NJS_DECLARE_PROP_VALUE("replace",
-                           njs_wellknown_symbol(NJS_SYMBOL_REPLACE), 0),
+    NJS_DECLARE_PROP_VALUE(STRING_replace,
+                           njs_symval(replace, "Symbol.replace"), 0),
 
-    NJS_DECLARE_PROP_VALUE("search",
-                           njs_wellknown_symbol(NJS_SYMBOL_SEARCH), 0),
+    NJS_DECLARE_PROP_VALUE(STRING_search,
+                           njs_symval(search, "Symbol.search"), 0),
 
-    NJS_DECLARE_PROP_VALUE("species",
-                           njs_wellknown_symbol(NJS_SYMBOL_SPECIES), 0),
+    NJS_DECLARE_PROP_VALUE(STRING_species,
+                           njs_symval(species, "Symbol.species"), 0),
 
-    NJS_DECLARE_PROP_VALUE("split",
-                           njs_wellknown_symbol(NJS_SYMBOL_SPLIT), 0),
+    NJS_DECLARE_PROP_VALUE(STRING_split, njs_symval(split, "Symbol.split"), 0),
 
-    NJS_DECLARE_PROP_VALUE("toPrimitive",
-                           njs_wellknown_symbol(NJS_SYMBOL_TO_PRIMITIVE), 0),
+    NJS_DECLARE_PROP_VALUE(STRING_toPrimitive,
+                           njs_symval(toPrimitive, "Symbol.toPrimitive"),
+                           0),
 
-    NJS_DECLARE_PROP_VALUE("toStringTag",
-                           njs_wellknown_symbol(NJS_SYMBOL_TO_STRING_TAG), 0),
+    NJS_DECLARE_PROP_VALUE(STRING_toStringTag,
+                           njs_symval(toStringTag, "Symbol.toStringTag"), 0),
 
-    NJS_DECLARE_PROP_VALUE("unscopables",
-                           njs_wellknown_symbol(NJS_SYMBOL_UNSCOPABLES), 0),
+    NJS_DECLARE_PROP_VALUE(STRING_unscopables,
+                           njs_symval(unscopables, "Symbol.unscopables"),
+                           0),
 };
 
 
@@ -347,27 +294,27 @@ njs_symbol_prototype_description(njs_vm_t *vm, njs_value_t *args,
 }
 
 
-static const njs_object_prop_t  njs_symbol_prototype_properties[] =
+static const njs_object_prop_init_t  njs_symbol_prototype_properties[] =
 {
-    {
-        .type = NJS_PROPERTY,
-        .name = njs_wellknown_symbol(NJS_SYMBOL_TO_STRING_TAG),
-        .u.value = njs_string("Symbol"),
-        .configurable = 1,
-    },
+    NJS_DECLARE_PROP_VALUE(SYMBOL_toStringTag, njs_ascii_strval("Symbol"),
+                           NJS_OBJECT_PROP_VALUE_C),
 
-    NJS_DECLARE_PROP_HANDLER("__proto__", njs_primitive_prototype_get_proto,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING___proto__,
+                             njs_primitive_prototype_get_proto, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_HANDLER("constructor",
-                             njs_object_prototype_create_constructor,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
+                             njs_object_prototype_create_constructor, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_NATIVE("valueOf", njs_symbol_prototype_value_of, 0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_valueOf, njs_symbol_prototype_value_of,
+                            0, 0),
 
-    NJS_DECLARE_PROP_NATIVE("toString", njs_symbol_prototype_to_string, 0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_toString,
+                            njs_symbol_prototype_to_string, 0, 0),
 
-    NJS_DECLARE_PROP_GETTER("description", njs_symbol_prototype_description, 0),
+    NJS_DECLARE_PROP_GETTER(STRING_description,
+                            njs_symbol_prototype_description, 0),
 };
 
 
diff --git a/src/njs_typed_array.c b/src/njs_typed_array.c
index 5930dcb0..19399e3b 100644
--- a/src/njs_typed_array.c
+++ b/src/njs_typed_array.c
@@ -433,37 +433,22 @@ njs_typed_array_writable(njs_vm_t *vm, njs_typed_array_t *array)
 }
 
 
-static const njs_value_t  njs_typed_array_uint8_tag = njs_string("Uint8Array");
-static const njs_value_t  njs_typed_array_uint8_clamped_tag =
-                                        njs_long_string("Uint8ClampedArray");
-static const njs_value_t  njs_typed_array_int8_tag = njs_string("Int8Array");
-static const njs_value_t  njs_typed_array_uint16_tag =
-                                                    njs_string("Uint16Array");
-static const njs_value_t  njs_typed_array_int16_tag = njs_string("Int16Array");
-static const njs_value_t  njs_typed_array_uint32_tag =
-                                                    njs_string("Uint32Array");
-static const njs_value_t  njs_typed_array_int32_tag = njs_string("Int32Array");
-static const njs_value_t  njs_typed_array_float32_tag =
-                                                    njs_string("Float32Array");
-static const njs_value_t  njs_typed_array_float64_tag =
-                                                    njs_string("Float64Array");
-
 static njs_int_t
 njs_typed_array_get_string_tag(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_index_t unused, njs_value_t *retval)
 {
     njs_value_t  *this;
 
-    static const njs_value_t  *tags[NJS_OBJ_TYPE_TYPED_ARRAY_SIZE] = {
-        &njs_typed_array_uint8_tag,
-        &njs_typed_array_uint8_clamped_tag,
-        &njs_typed_array_int8_tag,
-        &njs_typed_array_uint16_tag,
-        &njs_typed_array_int16_tag,
-        &njs_typed_array_uint32_tag,
-        &njs_typed_array_int32_tag,
-        &njs_typed_array_float32_tag,
-        &njs_typed_array_float64_tag,
+    static const uint32_t  tags[NJS_OBJ_TYPE_TYPED_ARRAY_SIZE] = {
+        NJS_ATOM_STRING_Uint8Array,
+        NJS_ATOM_STRING_Uint8ClampedArray,
+        NJS_ATOM_STRING_Int8Array,
+        NJS_ATOM_STRING_Uint16Array,
+        NJS_ATOM_STRING_Int16Array,
+        NJS_ATOM_STRING_Uint32Array,
+        NJS_ATOM_STRING_Int32Array,
+        NJS_ATOM_STRING_Float32Array,
+        NJS_ATOM_STRING_Float64Array,
     };
 
     this = njs_argument(args, 0);
@@ -473,8 +458,8 @@ njs_typed_array_get_string_tag(njs_vm_t *vm, njs_value_t *args,
         return NJS_OK;
     }
 
-    njs_value_assign(retval,
-                     tags[njs_typed_array_index(njs_typed_array(this)->type)]);
+    njs_atom_to_value(vm, retval,
+                      tags[njs_typed_array_index(njs_typed_array(this)->type)]);
 
     return NJS_OK;
 }
@@ -2062,11 +2047,15 @@ njs_typed_array_to_chain(njs_vm_t *vm, njs_chb_t *chain,
     uint32_t           i;
     njs_string_prop_t  separator;
 
-    if (sep == NULL) {
-        sep = njs_value_arg(&njs_string_comma);
+    if (sep != NULL && njs_is_string(sep)) {
+        (void) njs_string_prop(vm, &separator, sep);
+
+    } else {
+        separator.start = (u_char *) ",";
+        separator.size = 1;
+        separator.length = 1;
     }
 
-    (void) njs_string_prop(&separator, sep);
 
     length = njs_typed_array_length(array);
 
@@ -2110,10 +2099,7 @@ njs_typed_array_prototype_join(njs_vm_t *vm, njs_value_t *args,
     separator = njs_arg(args, nargs, 1);
 
     if (njs_slow_path(!njs_is_string(separator))) {
-        if (njs_is_undefined(separator)) {
-            separator = njs_value_arg(&njs_string_comma);
-
-        } else {
+        if (njs_is_defined(separator)) {
             ret = njs_value_to_string(vm, separator, separator);
             if (njs_slow_path(ret != NJS_OK)) {
                 return ret;
@@ -2122,7 +2108,7 @@ njs_typed_array_prototype_join(njs_vm_t *vm, njs_value_t *args,
     }
 
     if (length == 0) {
-        njs_value_assign(retval, &njs_string_empty);
+        njs_set_empty_string(vm, retval);
         return NJS_OK;
     }
 
@@ -2176,26 +2162,20 @@ njs_typed_array_constructor_intrinsic(njs_vm_t *vm, njs_value_t *args,
 }
 
 
-static const njs_object_prop_t  njs_typed_array_constructor_props[] =
+static const njs_object_prop_init_t  njs_typed_array_constructor_props[] =
 {
     NJS_DECLARE_PROP_LENGTH(0),
 
     NJS_DECLARE_PROP_NAME("TypedArray"),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
+                             0, 0),
 
-    {
-        .type = NJS_ACCESSOR,
-        .name = njs_wellknown_symbol(NJS_SYMBOL_SPECIES),
-        .u.accessor = njs_getter(njs_typed_array_get_this, 0),
-        .writable = NJS_ATTRIBUTE_UNSET,
-        .configurable = 1,
-        .enumerable = 0,
-    },
+    NJS_DECLARE_PROP_GETTER(SYMBOL_species, njs_typed_array_get_this, 0),
 
-    NJS_DECLARE_PROP_NATIVE("of", njs_typed_array_of, 0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_of, njs_typed_array_of, 0, 0),
 
-    NJS_DECLARE_PROP_NATIVE("from", njs_typed_array_from, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_from, njs_typed_array_from, 1, 0),
 };
 
 
@@ -2205,118 +2185,120 @@ static const njs_object_init_t  njs_typed_array_constructor_init = {
 };
 
 
-static const njs_object_prop_t  njs_typed_array_prototype_properties[] =
+static const njs_object_prop_init_t  njs_typed_array_prototype_properties[] =
 {
-    {
-        .type = NJS_ACCESSOR,
-        .name = njs_wellknown_symbol(NJS_SYMBOL_TO_STRING_TAG),
-        .u.accessor = njs_getter(njs_typed_array_get_string_tag, 0),
-        .writable = NJS_ATTRIBUTE_UNSET,
-        .configurable = 1,
-        .enumerable = 0,
-    },
+    NJS_DECLARE_PROP_GETTER(SYMBOL_toStringTag,
+                            njs_typed_array_get_string_tag, 0),
 
-    NJS_DECLARE_PROP_HANDLER("constructor",
-                             njs_object_prototype_create_constructor,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
+                             njs_object_prototype_create_constructor, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_GETTER("buffer", njs_typed_array_prototype_buffer, 0),
+    NJS_DECLARE_PROP_GETTER(STRING_buffer, njs_typed_array_prototype_buffer,
+                            0),
 
-    NJS_DECLARE_PROP_GETTER("byteLength",
+    NJS_DECLARE_PROP_GETTER(STRING_byteLength,
                             njs_typed_array_prototype_byte_length, 0),
 
-    NJS_DECLARE_PROP_GETTER("byteOffset",
+    NJS_DECLARE_PROP_GETTER(STRING_byteOffset,
                             njs_typed_array_prototype_byte_offset, 0),
 
-    NJS_DECLARE_PROP_GETTER("length", njs_typed_array_prototype_length, 0),
+    NJS_DECLARE_PROP_GETTER(STRING_length, njs_typed_array_prototype_length,
+                            0),
 
-    NJS_DECLARE_PROP_NATIVE("copyWithin",
+    NJS_DECLARE_PROP_NATIVE(STRING_copyWithin,
                             njs_typed_array_prototype_copy_within, 2, 0),
 
-    NJS_DECLARE_PROP_NATIVE("entries",
+    NJS_DECLARE_PROP_NATIVE(STRING_entries,
                             njs_typed_array_prototype_iterator_obj, 0,
                             NJS_ENUM_BOTH),
 
-    NJS_DECLARE_PROP_NATIVE("every",
+    NJS_DECLARE_PROP_NATIVE(STRING_every,
                             njs_typed_array_prototype_iterator, 1,
                             NJS_ARRAY_EVERY),
 
-    NJS_DECLARE_PROP_NATIVE("filter",
+    NJS_DECLARE_PROP_NATIVE(STRING_filter,
                             njs_typed_array_prototype_iterator, 1,
                             NJS_ARRAY_FILTER),
 
-    NJS_DECLARE_PROP_NATIVE("find",
+    NJS_DECLARE_PROP_NATIVE(STRING_find,
                             njs_typed_array_prototype_iterator, 1,
                             NJS_ARRAY_FIND),
 
-    NJS_DECLARE_PROP_NATIVE("findIndex",
+    NJS_DECLARE_PROP_NATIVE(STRING_findIndex,
                             njs_typed_array_prototype_iterator, 1,
                             NJS_ARRAY_FIND_INDEX),
 
-    NJS_DECLARE_PROP_NATIVE("forEach",
+    NJS_DECLARE_PROP_NATIVE(STRING_forEach,
                             njs_typed_array_prototype_iterator, 1,
                             NJS_ARRAY_FOR_EACH),
 
-    NJS_DECLARE_PROP_NATIVE("includes",
-                             njs_typed_array_prototype_index_of, 1, 1),
+    NJS_DECLARE_PROP_NATIVE(STRING_includes,
+                            njs_typed_array_prototype_index_of, 1, 1),
 
-    NJS_DECLARE_PROP_NATIVE("indexOf",
-                             njs_typed_array_prototype_index_of, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_indexOf,
+                            njs_typed_array_prototype_index_of, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("join", njs_typed_array_prototype_join, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_join,
+                            njs_typed_array_prototype_join, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("fill", njs_typed_array_prototype_fill, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_fill,
+                            njs_typed_array_prototype_fill, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("keys", njs_typed_array_prototype_iterator_obj, 0,
+    NJS_DECLARE_PROP_NATIVE(STRING_keys,
+                            njs_typed_array_prototype_iterator_obj, 0,
                             NJS_ENUM_KEYS),
 
-    NJS_DECLARE_PROP_NATIVE("lastIndexOf",
+    NJS_DECLARE_PROP_NATIVE(STRING_lastIndexOf,
                             njs_typed_array_prototype_index_of, 1, 2),
 
-    NJS_DECLARE_PROP_NATIVE("map",
+    NJS_DECLARE_PROP_NATIVE(STRING_map,
                             njs_typed_array_prototype_iterator, 1,
                             NJS_ARRAY_MAP),
 
-    NJS_DECLARE_PROP_NATIVE("reduce", njs_typed_array_prototype_reduce, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_reduce,
+                            njs_typed_array_prototype_reduce, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("reduceRight", njs_typed_array_prototype_reduce,
-                            1, 1),
+    NJS_DECLARE_PROP_NATIVE(STRING_reduceRight,
+                            njs_typed_array_prototype_reduce, 1, 1),
 
-    NJS_DECLARE_PROP_NATIVE("reverse", njs_typed_array_prototype_reverse, 0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_reverse,
+                            njs_typed_array_prototype_reverse, 0, 0),
 
-    NJS_DECLARE_PROP_NATIVE("set", njs_typed_array_prototype_set, 2, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_set,
+                            njs_typed_array_prototype_set, 2, 0),
 
-    NJS_DECLARE_PROP_NATIVE("slice", njs_typed_array_prototype_slice, 2, 1),
+    NJS_DECLARE_PROP_NATIVE(STRING_slice,
+                            njs_typed_array_prototype_slice, 2, 1),
 
-    NJS_DECLARE_PROP_NATIVE("some",
+    NJS_DECLARE_PROP_NATIVE(STRING_some,
                             njs_typed_array_prototype_iterator, 1,
                             NJS_ARRAY_SOME),
 
-    NJS_DECLARE_PROP_NATIVE("sort", njs_typed_array_prototype_sort, 1, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_sort,
+                            njs_typed_array_prototype_sort, 1, 0),
 
-    NJS_DECLARE_PROP_NATIVE("subarray", njs_typed_array_prototype_slice, 2, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_subarray,
+                            njs_typed_array_prototype_slice, 2, 0),
 
-    NJS_DECLARE_PROP_NATIVE("toReversed", njs_typed_array_prototype_reverse, 0,
-                            1),
+    NJS_DECLARE_PROP_NATIVE(STRING_toReversed,
+                            njs_typed_array_prototype_reverse, 0, 1),
 
-    NJS_DECLARE_PROP_NATIVE("toSorted", njs_typed_array_prototype_sort, 1, 1),
+    NJS_DECLARE_PROP_NATIVE(STRING_toSorted,
+                            njs_typed_array_prototype_sort, 1, 1),
 
-    NJS_DECLARE_PROP_NATIVE("toString", njs_array_prototype_to_string, 0, 0),
+    NJS_DECLARE_PROP_NATIVE(STRING_toString, njs_array_prototype_to_string,
+                            0, 0),
 
-    NJS_DECLARE_PROP_NATIVE("values", njs_typed_array_prototype_iterator_obj,
-                            0, NJS_ENUM_VALUES),
+    NJS_DECLARE_PROP_NATIVE(STRING_values,
+                            njs_typed_array_prototype_iterator_obj, 0,
+                            NJS_ENUM_VALUES),
 
-    {
-        .type = NJS_PROPERTY,
-        .name = njs_wellknown_symbol(NJS_SYMBOL_ITERATOR),
-        .u.value = njs_native_function2(njs_typed_array_prototype_iterator_obj,
-                                        0, NJS_ENUM_VALUES),
-        .writable = 1,
-        .configurable = 1,
-    },
+    NJS_DECLARE_PROP_NATIVE(SYMBOL_iterator,
+                            njs_typed_array_prototype_iterator_obj, 0,
+                            NJS_ENUM_VALUES),
 };
 
-
 static const njs_object_init_t  njs_typed_array_prototype_init = {
     njs_typed_array_prototype_properties,
     njs_nitems(njs_typed_array_prototype_properties),
@@ -2413,13 +2395,14 @@ memory_error:
 }
 
 
-static const njs_object_prop_t  njs_data_view_constructor_props[] =
+static const njs_object_prop_init_t  njs_data_view_constructor_props[] =
 {
     NJS_DECLARE_PROP_LENGTH(1),
 
     NJS_DECLARE_PROP_NAME("DataView"),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
+                             0, 0),
 };
 
 
@@ -2658,74 +2641,71 @@ njs_data_view_prototype_set(njs_vm_t *vm, njs_value_t *args,
 }
 
 
-static const njs_object_prop_t  njs_data_view_prototype_properties[] =
+static const njs_object_prop_init_t  njs_data_view_prototype_properties[] =
 {
-    {
-        .type = NJS_PROPERTY,
-        .name = njs_wellknown_symbol(NJS_SYMBOL_TO_STRING_TAG),
-        .u.value = njs_string("DataView"),
-        .configurable = 1,
-    },
+    NJS_DECLARE_PROP_VALUE(SYMBOL_toStringTag, njs_ascii_strval("DataView"),
+                           NJS_OBJECT_PROP_VALUE_C),
 
-    NJS_DECLARE_PROP_HANDLER("constructor",
-                             njs_object_prototype_create_constructor,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
+                             njs_object_prototype_create_constructor, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_GETTER("buffer", njs_typed_array_prototype_buffer, 0),
+    NJS_DECLARE_PROP_GETTER(STRING_buffer, njs_typed_array_prototype_buffer,
+                            0),
 
-    NJS_DECLARE_PROP_GETTER("byteLength",
+    NJS_DECLARE_PROP_GETTER(STRING_byteLength,
                             njs_typed_array_prototype_byte_length, 0),
 
-    NJS_DECLARE_PROP_GETTER("byteOffset",
+    NJS_DECLARE_PROP_GETTER(STRING_byteOffset,
                             njs_typed_array_prototype_byte_offset, 0),
 
-    NJS_DECLARE_PROP_NATIVE("getUint8", njs_data_view_prototype_get, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_getUint8, njs_data_view_prototype_get, 1,
                             NJS_OBJ_TYPE_UINT8_ARRAY),
 
-    NJS_DECLARE_PROP_NATIVE("getInt8", njs_data_view_prototype_get, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_getInt8, njs_data_view_prototype_get, 1,
                             NJS_OBJ_TYPE_INT8_ARRAY),
 
-    NJS_DECLARE_PROP_NATIVE("getUint16", njs_data_view_prototype_get, 1,
-                            NJS_OBJ_TYPE_UINT16_ARRAY),
+    NJS_DECLARE_PROP_NATIVE(STRING_getUint16, njs_data_view_prototype_get,
+                            1, NJS_OBJ_TYPE_UINT16_ARRAY),
 
-    NJS_DECLARE_PROP_NATIVE("getInt16", njs_data_view_prototype_get, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_getInt16, njs_data_view_prototype_get, 1,
                             NJS_OBJ_TYPE_INT16_ARRAY),
 
-    NJS_DECLARE_PROP_NATIVE("getUint32", njs_data_view_prototype_get, 1,
-                            NJS_OBJ_TYPE_UINT32_ARRAY),
+    NJS_DECLARE_PROP_NATIVE(STRING_getUint32, njs_data_view_prototype_get,
+                            1, NJS_OBJ_TYPE_UINT32_ARRAY),
 
-    NJS_DECLARE_PROP_NATIVE("getInt32", njs_data_view_prototype_get, 1,
+    NJS_DECLARE_PROP_NATIVE(STRING_getInt32, njs_data_view_prototype_get, 1,
                             NJS_OBJ_TYPE_INT32_ARRAY),
 
-    NJS_DECLARE_PROP_NATIVE("getFloat32", njs_data_view_prototype_get, 1,
-                            NJS_OBJ_TYPE_FLOAT32_ARRAY),
+    NJS_DECLARE_PROP_NATIVE(STRING_getFloat32, njs_data_view_prototype_get,
+                            1, NJS_OBJ_TYPE_FLOAT32_ARRAY),
 
-    NJS_DECLARE_PROP_NATIVE("getFloat64", njs_data_view_prototype_get, 1,
-                            NJS_OBJ_TYPE_FLOAT64_ARRAY),
+    NJS_DECLARE_PROP_NATIVE(STRING_getFloat64, njs_data_view_prototype_get,
+                            1, NJS_OBJ_TYPE_FLOAT64_ARRAY),
 
-    NJS_DECLARE_PROP_NATIVE("setUint8", njs_data_view_prototype_set, 2,
+    NJS_DECLARE_PROP_NATIVE(STRING_setUint8, njs_data_view_prototype_set, 2,
                             NJS_OBJ_TYPE_UINT8_ARRAY),
 
-    NJS_DECLARE_PROP_NATIVE("setInt8", njs_data_view_prototype_set, 2,
+    NJS_DECLARE_PROP_NATIVE(STRING_setInt8, njs_data_view_prototype_set, 2,
                             NJS_OBJ_TYPE_INT8_ARRAY),
 
-    NJS_DECLARE_PROP_NATIVE("setUint16", njs_data_view_prototype_set, 2,
-                            NJS_OBJ_TYPE_UINT16_ARRAY),
+    NJS_DECLARE_PROP_NATIVE(STRING_setUint16, njs_data_view_prototype_set,
+                            2, NJS_OBJ_TYPE_UINT16_ARRAY),
 
-    NJS_DECLARE_PROP_NATIVE("setInt16", njs_data_view_prototype_set, 2,
+    NJS_DECLARE_PROP_NATIVE(STRING_setInt16, njs_data_view_prototype_set, 2,
                             NJS_OBJ_TYPE_INT16_ARRAY),
 
-    NJS_DECLARE_PROP_NATIVE("setUint32", njs_data_view_prototype_set, 2,
-                            NJS_OBJ_TYPE_UINT32_ARRAY),
+    NJS_DECLARE_PROP_NATIVE(STRING_setUint32, njs_data_view_prototype_set,
+                            2, NJS_OBJ_TYPE_UINT32_ARRAY),
 
-    NJS_DECLARE_PROP_NATIVE("setInt32", njs_data_view_prototype_set, 2,
+    NJS_DECLARE_PROP_NATIVE(STRING_setInt32, njs_data_view_prototype_set, 2,
                             NJS_OBJ_TYPE_INT32_ARRAY),
 
-    NJS_DECLARE_PROP_NATIVE("setFloat32", njs_data_view_prototype_set, 2,
-                            NJS_OBJ_TYPE_FLOAT32_ARRAY),
+    NJS_DECLARE_PROP_NATIVE(STRING_setFloat32, njs_data_view_prototype_set,
+                            2, NJS_OBJ_TYPE_FLOAT32_ARRAY),
 
-    NJS_DECLARE_PROP_NATIVE("setFloat64", njs_data_view_prototype_set, 2,
-                            NJS_OBJ_TYPE_FLOAT64_ARRAY),
+    NJS_DECLARE_PROP_NATIVE(STRING_setFloat64, njs_data_view_prototype_set,
+                            2, NJS_OBJ_TYPE_FLOAT64_ARRAY),
 };
 
 
@@ -2743,16 +2723,17 @@ const njs_object_type_init_t  njs_data_view_type_init = {
 };
 
 
-static const njs_object_prop_t  njs_typed_array_u8_constructor_props[] =
+static const njs_object_prop_init_t  njs_typed_array_u8_constructor_props[] =
 {
     NJS_DECLARE_PROP_LENGTH(3),
 
     NJS_DECLARE_PROP_NAME("Uint8Array"),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
+                             0, 0),
 
-    NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 1),
-                            0),
+    NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT,
+                           njs_value(NJS_NUMBER, 1, 1), 0),
 };
 
 
@@ -2762,14 +2743,14 @@ static const njs_object_init_t  njs_typed_array_u8_constructor_init = {
 };
 
 
-static const njs_object_prop_t  njs_typed_array_u8_prototype_properties[] =
+static const njs_object_prop_init_t  njs_typed_array_u8_prototype_properties[] =
 {
-    NJS_DECLARE_PROP_HANDLER("constructor",
-                             njs_object_prototype_create_constructor,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
+                             njs_object_prototype_create_constructor, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 1),
-                            0),
+    NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT,
+                           njs_value(NJS_NUMBER, 1, 1), 0),
 };
 
 
@@ -2788,21 +2769,18 @@ const njs_object_type_init_t  njs_typed_array_u8_type_init = {
 };
 
 
-static const njs_object_prop_t  njs_typed_array_u8c_constructor_props[] =
+static const njs_object_prop_init_t  njs_typed_array_u8c_constructor_props[] =
 {
-    {
-        .type = NJS_PROPERTY,
-        .name = njs_string("name"),
-        .u.value = njs_long_string("Uint8ClampedArray"),
-        .configurable = 1,
-    },
+    NJS_DECLARE_PROP_VALUE(STRING_name, njs_ascii_strval("Uint8ClampedArray"),
+                           NJS_OBJECT_PROP_VALUE_C),
 
     NJS_DECLARE_PROP_LENGTH(3),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
+                             0, 0),
 
-    NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 1),
-                            0),
+    NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT,
+                           njs_value(NJS_NUMBER, 1, 1), 0),
 };
 
 
@@ -2812,14 +2790,14 @@ static const njs_object_init_t  njs_typed_array_u8c_constructor_init = {
 };
 
 
-static const njs_object_prop_t  njs_typed_array_u8c_prototype_properties[] =
+static const njs_object_prop_init_t  njs_typed_array_u8c_prototype_properties[] =
 {
-    NJS_DECLARE_PROP_HANDLER("constructor",
-                             njs_object_prototype_create_constructor,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
+                             njs_object_prototype_create_constructor, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 1),
-                            0),
+    NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT,
+                           njs_value(NJS_NUMBER, 1, 1), 0),
 };
 
 
@@ -2838,16 +2816,17 @@ const njs_object_type_init_t  njs_typed_array_u8clamped_type_init = {
 };
 
 
-static const njs_object_prop_t  njs_typed_array_i8_constructor_props[] =
+static const njs_object_prop_init_t  njs_typed_array_i8_constructor_props[] =
 {
     NJS_DECLARE_PROP_LENGTH(3),
 
     NJS_DECLARE_PROP_NAME("Int8Array"),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
+                             0, 0),
 
-    NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 1),
-                            0),
+    NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT,
+                           njs_value(NJS_NUMBER, 1, 1), 0),
 };
 
 
@@ -2857,14 +2836,14 @@ static const njs_object_init_t  njs_typed_array_i8_constructor_init = {
 };
 
 
-static const njs_object_prop_t  njs_typed_array_i8_prototype_properties[] =
+static const njs_object_prop_init_t  njs_typed_array_i8_prototype_properties[] =
 {
-    NJS_DECLARE_PROP_HANDLER("constructor",
-                             njs_object_prototype_create_constructor,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
+                             njs_object_prototype_create_constructor, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 1),
-                            0),
+    NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT,
+                           njs_value(NJS_NUMBER, 1, 1), 0),
 };
 
 
@@ -2883,16 +2862,17 @@ const njs_object_type_init_t  njs_typed_array_i8_type_init = {
 };
 
 
-static const njs_object_prop_t  njs_typed_array_u16_constructor_props[] =
+static const njs_object_prop_init_t  njs_typed_array_u16_constructor_props[] =
 {
     NJS_DECLARE_PROP_LENGTH(3),
 
     NJS_DECLARE_PROP_NAME("Uint16Array"),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
+                             0, 0),
 
-    NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 2),
-                            0),
+    NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT,
+                           njs_value(NJS_NUMBER, 1, 2), 0),
 };
 
 
@@ -2902,14 +2882,14 @@ static const njs_object_init_t  njs_typed_array_u16_constructor_init = {
 };
 
 
-static const njs_object_prop_t  njs_typed_array_u16_prototype_properties[] =
+static const njs_object_prop_init_t  njs_typed_array_u16_prototype_properties[] =
 {
-    NJS_DECLARE_PROP_HANDLER("constructor",
-                             njs_object_prototype_create_constructor,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
+                             njs_object_prototype_create_constructor, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 2),
-                            0),
+    NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT,
+                           njs_value(NJS_NUMBER, 1, 2), 0),
 };
 
 
@@ -2928,16 +2908,17 @@ const njs_object_type_init_t  njs_typed_array_u16_type_init = {
 };
 
 
-static const njs_object_prop_t  njs_typed_array_i16_constructor_props[] =
+static const njs_object_prop_init_t  njs_typed_array_i16_constructor_props[] =
 {
     NJS_DECLARE_PROP_LENGTH(3),
 
     NJS_DECLARE_PROP_NAME("Int16Array"),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
+                             0, 0),
 
-    NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 2),
-                            0),
+    NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT,
+                           njs_value(NJS_NUMBER, 1, 2), 0),
 };
 
 
@@ -2947,14 +2928,14 @@ static const njs_object_init_t  njs_typed_array_i16_constructor_init = {
 };
 
 
-static const njs_object_prop_t  njs_typed_array_i16_prototype_properties[] =
+static const njs_object_prop_init_t  njs_typed_array_i16_prototype_properties[] =
 {
-    NJS_DECLARE_PROP_HANDLER("constructor",
-                             njs_object_prototype_create_constructor,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
+                             njs_object_prototype_create_constructor, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 2),
-                            0),
+    NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT,
+                           njs_value(NJS_NUMBER, 1, 2), 0),
 };
 
 
@@ -2973,16 +2954,17 @@ const njs_object_type_init_t  njs_typed_array_i16_type_init = {
 };
 
 
-static const njs_object_prop_t  njs_typed_array_u32_constructor_props[] =
+static const njs_object_prop_init_t  njs_typed_array_u32_constructor_props[] =
 {
     NJS_DECLARE_PROP_LENGTH(3),
 
     NJS_DECLARE_PROP_NAME("Uint32Array"),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
+                             0, 0),
 
-    NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 4),
-                            0),
+    NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT,
+                           njs_value(NJS_NUMBER, 1, 4), 0),
 };
 
 
@@ -2992,14 +2974,14 @@ static const njs_object_init_t  njs_typed_array_u32_constructor_init = {
 };
 
 
-static const njs_object_prop_t  njs_typed_array_u32_prototype_properties[] =
+static const njs_object_prop_init_t  njs_typed_array_u32_prototype_properties[] =
 {
-    NJS_DECLARE_PROP_HANDLER("constructor",
-                             njs_object_prototype_create_constructor,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
+                             njs_object_prototype_create_constructor, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 4),
-                            0),
+    NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT,
+                           njs_value(NJS_NUMBER, 1, 4), 0),
 };
 
 
@@ -3018,16 +3000,17 @@ const njs_object_type_init_t  njs_typed_array_u32_type_init = {
 };
 
 
-static const njs_object_prop_t  njs_typed_array_i32_constructor_props[] =
+static const njs_object_prop_init_t  njs_typed_array_i32_constructor_props[] =
 {
     NJS_DECLARE_PROP_LENGTH(3),
 
     NJS_DECLARE_PROP_NAME("Int32Array"),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
+                             0, 0),
 
-    NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 4),
-                            0),
+    NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT,
+                           njs_value(NJS_NUMBER, 1, 4), 0),
 };
 
 
@@ -3037,14 +3020,14 @@ static const njs_object_init_t  njs_typed_array_i32_constructor_init = {
 };
 
 
-static const njs_object_prop_t  njs_typed_array_i32_prototype_properties[] =
+static const njs_object_prop_init_t  njs_typed_array_i32_prototype_properties[] =
 {
-    NJS_DECLARE_PROP_HANDLER("constructor",
-                             njs_object_prototype_create_constructor,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
+                             njs_object_prototype_create_constructor, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 4),
-                            0),
+    NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT,
+                           njs_value(NJS_NUMBER, 1, 4), 0),
 };
 
 
@@ -3063,16 +3046,17 @@ const njs_object_type_init_t  njs_typed_array_i32_type_init = {
 };
 
 
-static const njs_object_prop_t  njs_typed_array_f32_constructor_props[] =
+static const njs_object_prop_init_t  njs_typed_array_f32_constructor_props[] =
 {
     NJS_DECLARE_PROP_LENGTH(3),
 
     NJS_DECLARE_PROP_NAME("Float32Array"),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create,
+                             0, 0),
 
-    NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 4),
-                            0),
+    NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT,
+                           njs_value(NJS_NUMBER, 1, 4), 0),
 };
 
 
@@ -3082,14 +3066,14 @@ static const njs_object_init_t  njs_typed_array_f32_constructor_init = {
 };
 
 
-static const njs_object_prop_t  njs_typed_array_f32_prototype_properties[] =
+static const njs_object_prop_init_t  njs_typed_array_f32_prototype_properties[] =
 {
-    NJS_DECLARE_PROP_HANDLER("constructor",
-                             njs_object_prototype_create_constructor,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
+                             njs_object_prototype_create_constructor, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 4),
-                            0),
+    NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT,
+                           njs_value(NJS_NUMBER, 1, 4), 0),
 };
 
 
@@ -3108,16 +3092,17 @@ const njs_object_type_init_t  njs_typed_array_f32_type_init = {
 };
 
 
-static const njs_object_prop_t  njs_typed_array_f64_constructor_props[] =
+static const njs_object_prop_init_t  njs_typed_array_f64_constructor_props[] =
 {
     NJS_DECLARE_PROP_LENGTH(3),
 
     NJS_DECLARE_PROP_NAME("Float64Array"),
 
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
+    NJS_DECLARE_PROP_HANDLER(STRING_prototype,
+                             njs_object_prototype_create, 0, 0),
 
-    NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 8),
-                            0),
+    NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT,
+                           njs_value(NJS_NUMBER, 1, 8), 0),
 };
 
 
@@ -3127,14 +3112,14 @@ static const njs_object_init_t  njs_typed_array_f64_constructor_init = {
 };
 
 
-static const njs_object_prop_t  njs_typed_array_f64_prototype_properties[] =
+static const njs_object_prop_init_t  njs_typed_array_f64_prototype_properties[] =
 {
-    NJS_DECLARE_PROP_HANDLER("constructor",
-                             njs_object_prototype_create_constructor,
-                             0, 0, NJS_OBJECT_PROP_VALUE_CW),
+    NJS_DECLARE_PROP_HANDLER(STRING_constructor,
+                             njs_object_prototype_create_constructor, 0,
+                             NJS_OBJECT_PROP_VALUE_CW),
 
-    NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 8),
-                            0),
+    NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT,
+                           njs_value(NJS_NUMBER, 1, 8), 0),
 };
 
 
diff --git a/src/njs_value.c b/src/njs_value.c
index a575f9af..dcdab5a2 100644
--- a/src/njs_value.c
+++ b/src/njs_value.c
@@ -9,10 +9,10 @@
 
 
 static njs_int_t njs_object_property_query(njs_vm_t *vm,
-    njs_property_query_t *pq, njs_object_t *object,
-    const njs_value_t *key);
+    njs_property_query_t *pq, njs_object_t *object, uint32_t atom_id);
 static njs_int_t njs_array_property_query(njs_vm_t *vm,
-    njs_property_query_t *pq, njs_array_t *array, uint32_t index);
+    njs_property_query_t *pq, njs_array_t *array, uint32_t index,
+    uint32_t atom_id);
 static njs_int_t njs_typed_array_property_query(njs_vm_t *vm,
     njs_property_query_t *pq, njs_typed_array_t *array, uint32_t index);
 static njs_int_t njs_string_property_query(njs_vm_t *vm,
@@ -29,35 +29,6 @@ const njs_value_t  njs_value_zero =         njs_value(NJS_NUMBER, 0, 0.0);
 const njs_value_t  njs_value_nan =          njs_value(NJS_NUMBER, 0, NAN);
 const njs_value_t  njs_value_invalid =      njs_value(NJS_INVALID, 0, 0.0);
 
-const njs_value_t  njs_string_empty =       njs_string("");
-const njs_value_t  njs_string_empty_regexp =
-                                            njs_string("(?:)");
-const njs_value_t  njs_string_comma =       njs_string(",");
-const njs_value_t  njs_string_null =        njs_string("null");
-const njs_value_t  njs_string_undefined =   njs_string("undefined");
-const njs_value_t  njs_string_boolean =     njs_string("boolean");
-const njs_value_t  njs_string_false =       njs_string("false");
-const njs_value_t  njs_string_true =        njs_string("true");
-const njs_value_t  njs_string_number =      njs_string("number");
-const njs_value_t  njs_string_minus_zero =  njs_string("-0");
-const njs_value_t  njs_string_minus_infinity =
-                                            njs_string("-Infinity");
-const njs_value_t  njs_string_plus_infinity =
-                                            njs_string("Infinity");
-const njs_value_t  njs_string_nan =         njs_string("NaN");
-const njs_value_t  njs_string_symbol =      njs_string("symbol");
-const njs_value_t  njs_string_string =      njs_string("string");
-const njs_value_t  njs_string_name =        njs_string("name");
-const njs_value_t  njs_string_data =        njs_string("data");
-const njs_value_t  njs_string_type =        njs_string("type");
-const njs_value_t  njs_string_external =    njs_string("external");
-const njs_value_t  njs_string_invalid =     njs_string("invalid");
-const njs_value_t  njs_string_object =      njs_string("object");
-const njs_value_t  njs_string_function =    njs_string("function");
-const njs_value_t  njs_string_anonymous =   njs_string("anonymous");
-const njs_value_t  njs_string_memory_error = njs_string("MemoryError");
-
-
 /*
  * A hint value is 0 for numbers and 1 for strings.  The value chooses
  * method calls order specified by ECMAScript 5.1: "valueOf", "toString"
@@ -68,22 +39,16 @@ njs_int_t
 njs_value_to_primitive(njs_vm_t *vm, njs_value_t *dst, njs_value_t *value,
     njs_uint_t hint)
 {
-    njs_int_t           ret;
-    njs_uint_t          tries;
-    njs_value_t         method, retval;
-    njs_lvlhsh_query_t  lhq;
-
-    static const uint32_t  hashes[] = {
-        NJS_VALUE_OF_HASH,
-        NJS_TO_STRING_HASH,
-    };
-
-    static const njs_str_t  names[] = {
-        njs_str("valueOf"),
-        njs_str("toString"),
+    njs_int_t            ret;
+    njs_uint_t           tries;
+    njs_value_t          method, retval;
+    njs_flathsh_query_t  lhq;
+
+    static const uint32_t atoms[] = {
+        NJS_ATOM_STRING_valueOf,
+        NJS_ATOM_STRING_toString,
     };
 
-
     if (njs_is_primitive(value)) {
         *dst = *value;
         return NJS_OK;
@@ -98,8 +63,7 @@ njs_value_to_primitive(njs_vm_t *vm, njs_value_t *dst, njs_value_t *value,
         if (njs_is_object(value) && tries < 2) {
             hint ^= tries++;
 
-            lhq.key_hash = hashes[hint];
-            lhq.key = names[hint];
+            lhq.key_hash = atoms[hint];
 
             ret = njs_object_property(vm, njs_object(value), &lhq, &method);
 
@@ -207,7 +171,7 @@ njs_value_own_enumerate(njs_vm_t *vm, njs_value_t *value, uint32_t flags)
             dst = values->start;
 
             while (k < end) {
-                ret = njs_value_property(vm, value, k++, dst++);
+                ret = njs_value_property_val(vm, value, k++, dst++);
                 if (njs_slow_path(ret != NJS_OK)) {
                     return NULL;
                 }
@@ -234,7 +198,7 @@ njs_value_own_enumerate(njs_vm_t *vm, njs_value_t *value, uint32_t flags)
                     return NULL;
                 }
 
-                ret = njs_value_property(vm, value, k, &entry->start[1]);
+                ret = njs_value_property_val(vm, value, k, &entry->start[1]);
                 if (njs_slow_path(ret != NJS_OK)) {
                     return NULL;
                 }
@@ -265,14 +229,11 @@ njs_value_of(njs_vm_t *vm, njs_value_t *value, njs_value_t *retval)
 
     njs_int_t  ret;
 
-    static const njs_value_t  value_of = njs_string("valueOf");
-
     if (njs_slow_path(!njs_is_object(value))) {
         return NJS_DECLINED;
     }
 
-    ret = njs_value_property(vm, value, njs_value_arg(&value_of),
-                             retval);
+    ret = njs_value_property(vm, value, NJS_ATOM_STRING_valueOf, retval);
     if (njs_slow_path(ret != NJS_OK)) {
         return ret;
     }
@@ -292,7 +253,7 @@ njs_value_length(njs_vm_t *vm, njs_value_t *value, int64_t *length)
     njs_string_prop_t  string_prop;
 
     if (njs_is_string(value)) {
-        *length = njs_string_prop(&string_prop, value);
+        *length = njs_string_prop(vm, &string_prop, value);
 
     } else if (njs_is_primitive(value)) {
         *length = 0;
@@ -595,15 +556,15 @@ njs_value_is_data_view(const njs_value_t *value)
 
 njs_int_t
 njs_property_query(njs_vm_t *vm, njs_property_query_t *pq, njs_value_t *value,
-    njs_value_t *key)
+    uint32_t atom_id)
 {
-    double          num;
     uint32_t        index;
     njs_int_t       ret;
+    njs_value_t     key;
     njs_object_t    *obj;
     njs_function_t  *function;
 
-    njs_assert(njs_is_index_or_key(key));
+    njs_assert(atom_id != NJS_ATOM_STRING_unknown);
 
     switch (value->type) {
     case NJS_BOOLEAN:
@@ -614,11 +575,9 @@ njs_property_query(njs_vm_t *vm, njs_property_query_t *pq, njs_value_t *value,
         break;
 
     case NJS_STRING:
-        if (njs_fast_path(!njs_is_null_or_undefined_or_boolean(key))) {
-            num = njs_key_to_index(key);
-            if (njs_fast_path(njs_key_is_integer_index(num, key))) {
-                return njs_string_property_query(vm, pq, value, num);
-            }
+        if (njs_atom_is_number(atom_id)) {
+            return njs_string_property_query(vm, pq, value,
+                                             njs_atom_number(atom_id));
         }
 
         obj = &vm->string_object;
@@ -648,10 +607,10 @@ njs_property_query(njs_vm_t *vm, njs_property_query_t *pq, njs_value_t *value,
     case NJS_UNDEFINED:
     case NJS_NULL:
     default:
-        ret = njs_primitive_value_to_string(vm, &pq->key, key);
+        ret = njs_atom_to_value(vm, &key, atom_id);
 
         if (njs_fast_path(ret == NJS_OK)) {
-            njs_string_get(&pq->key, &pq->lhq.key);
+            njs_string_get(vm, &key, &pq->lhq.key);
             njs_type_error(vm, "cannot get property \"%V\" of %s",
                            &pq->lhq.key, njs_is_null(value) ? "null"
                                                             : "undefined");
@@ -664,41 +623,24 @@ njs_property_query(njs_vm_t *vm, njs_property_query_t *pq, njs_value_t *value,
         return NJS_ERROR;
     }
 
-    ret = njs_primitive_value_to_key(vm, &pq->key, key);
-
-    if (njs_fast_path(ret == NJS_OK)) {
+    ret = njs_object_property_query(vm, pq, obj, atom_id);
 
-        if (njs_is_symbol(key)) {
-            pq->lhq.key_hash = njs_symbol_key(key);
-            pq->lhq.key.start = NULL;
-
-        } else {
-            njs_string_get(&pq->key, &pq->lhq.key);
-
-            if (pq->lhq.key_hash == 0) {
-                pq->lhq.key_hash = njs_djb_hash(pq->lhq.key.start,
-                                                pq->lhq.key.length);
-            }
-        }
-
-        ret = njs_object_property_query(vm, pq, obj, key);
-
-        if (njs_slow_path(ret == NJS_DECLINED && obj->slots != NULL)) {
-            return njs_external_property_query(vm, pq, value);
-        }
+    if (njs_slow_path(ret == NJS_DECLINED && obj->slots != NULL)) {
+        return njs_external_property_query(vm, pq, value);
     }
 
     return ret;
 }
 
 
-static njs_int_t
+njs_inline njs_int_t
 njs_object_property_query(njs_vm_t *vm, njs_property_query_t *pq,
-    njs_object_t *object, const njs_value_t *key)
+    njs_object_t *object, uint32_t atom_id)
 {
     double              num;
     njs_int_t           ret;
     njs_bool_t          own;
+    njs_value_t         key;
     njs_array_t         *array;
     njs_object_t        *proto;
     njs_object_prop_t   *prop;
@@ -716,10 +658,24 @@ njs_object_property_query(njs_vm_t *vm, njs_property_query_t *pq,
         switch (proto->type) {
         case NJS_ARRAY:
             array = (njs_array_t *) proto;
-            num = njs_key_to_index(key);
 
-            if (njs_fast_path(njs_key_is_integer_index(num, key))) {
-                ret = njs_array_property_query(vm, pq, array, num);
+            if (njs_fast_path(njs_atom_is_number(atom_id))) {
+                ret = njs_array_property_query(vm, pq, array,
+                                               njs_atom_number(atom_id), atom_id);
+                if (njs_fast_path(ret != NJS_DECLINED)) {
+                    return (ret == NJS_DONE) ? NJS_DECLINED : ret;
+                }
+            }
+
+            ret = njs_atom_to_value(vm, &key, atom_id);
+            if (njs_slow_path(ret != NJS_OK)) {
+                return ret;
+            }
+
+            num = njs_key_to_index(&key);
+
+            if (njs_key_is_integer_index(num, &key)) {
+                ret = njs_array_property_query(vm, pq, array, num, atom_id);
                 if (njs_fast_path(ret != NJS_DECLINED)) {
                     return (ret == NJS_DONE) ? NJS_DECLINED : ret;
                 }
@@ -728,12 +684,19 @@ njs_object_property_query(njs_vm_t *vm, njs_property_query_t *pq,
             break;
 
         case NJS_TYPED_ARRAY:
-            num = njs_key_to_index(key);
-            if (njs_fast_path(njs_key_is_integer_index(num, key))) {
+            if (njs_fast_path(njs_atom_is_number(atom_id))) {
                 tarray = (njs_typed_array_t *) proto;
-                return njs_typed_array_property_query(vm, pq, tarray, num);
+                return njs_typed_array_property_query(vm, pq, tarray,
+                                                      njs_atom_number(atom_id));
             }
 
+            ret = njs_atom_to_value(vm, &key, atom_id);
+            if (njs_slow_path(ret != NJS_OK)) {
+                return ret;
+            }
+
+            num = njs_key_to_index(&key);
+
             if (!isnan(num)) {
                 return NJS_DECLINED;
             }
@@ -746,10 +709,10 @@ njs_object_property_query(njs_vm_t *vm, njs_property_query_t *pq,
                 break;
             }
 
-            num = njs_key_to_index(key);
-            if (njs_fast_path(njs_key_is_integer_index(num, key))) {
+            if (njs_fast_path(njs_atom_is_number(atom_id))) {
                 ov = (njs_object_value_t *) proto;
-                ret = njs_string_property_query(vm, pq, &ov->value, num);
+                ret = njs_string_property_query(vm, pq, &ov->value,
+                                                njs_atom_number(atom_id));
                 if (njs_fast_path(ret != NJS_DECLINED)) {
                     return ret;
                 }
@@ -761,7 +724,9 @@ njs_object_property_query(njs_vm_t *vm, njs_property_query_t *pq,
             break;
         }
 
-        ret = njs_lvlhsh_find(&proto->hash, &pq->lhq);
+        pq->lhq.key_hash = atom_id;
+
+        ret = njs_flathsh_unique_find(&proto->hash, &pq->lhq);
 
         if (ret == NJS_OK) {
             prop = pq->lhq.value;
@@ -775,8 +740,7 @@ njs_object_property_query(njs_vm_t *vm, njs_property_query_t *pq,
             }
 
         } else {
-            ret = njs_lvlhsh_find(&proto->shared_hash, &pq->lhq);
-
+            ret = njs_flathsh_unique_find(&proto->shared_hash, &pq->lhq);
             if (ret == NJS_OK) {
                 return njs_prop_private_copy(vm, pq, proto);
             }
@@ -797,7 +761,7 @@ njs_object_property_query(njs_vm_t *vm, njs_property_query_t *pq,
 
 static njs_int_t
 njs_array_property_query(njs_vm_t *vm, njs_property_query_t *pq,
-    njs_array_t *array, uint32_t index)
+    njs_array_t *array, uint32_t index, uint32_t atom_id)
 {
     int64_t            length;
     uint64_t           size;
@@ -858,7 +822,9 @@ njs_array_property_query(njs_vm_t *vm, njs_property_query_t *pq,
             }
         }
 
-        ret = njs_lvlhsh_find(&array->object.hash, &pq->lhq);
+        pq->lhq.key_hash = atom_id;
+
+        ret = njs_flathsh_unique_find(&array->object.hash, &pq->lhq);
         if (ret == NJS_OK) {
             prop = pq->lhq.value;
 
@@ -901,8 +867,6 @@ prop:
         prop->type = resized ? NJS_PROPERTY_PLACE_REF : NJS_PROPERTY_REF;
     }
 
-    njs_set_number(&prop->name, index);
-
     prop->writable = 1;
     prop->enumerable = 1;
     prop->configurable = 1;
@@ -963,7 +927,7 @@ njs_string_property_query(njs_vm_t *vm, njs_property_query_t *pq,
 
     slice.start = index;
     slice.length = 1;
-    slice.string_length = njs_string_prop(&string, object);
+    slice.string_length = njs_string_prop(vm, &string, object);
 
     if (slice.start < slice.string_length) {
         /*
@@ -979,12 +943,6 @@ njs_string_property_query(njs_vm_t *vm, njs_property_query_t *pq,
 
         pq->lhq.value = prop;
 
-        if (pq->query != NJS_PROPERTY_QUERY_GET) {
-            /* pq->lhq.key is used by NJS_VMCODE_PROPERTY_SET for TypeError */
-            njs_uint32_to_string(&pq->key, index);
-            njs_string_get(&pq->key, &pq->lhq.key);
-        }
-
         return NJS_OK;
     }
 
@@ -1018,7 +976,6 @@ njs_external_property_query(njs_vm_t *vm, njs_property_query_t *pq,
      */
 
     njs_prop_magic32(prop) = slots->magic32;
-    prop->name = pq->key;
 
     pq->lhq.value = prop;
 
@@ -1029,7 +986,8 @@ njs_external_property_query(njs_vm_t *vm, njs_property_query_t *pq,
     switch (pq->query) {
 
     case NJS_PROPERTY_QUERY_GET:
-        return slots->prop_handler(vm, prop, value, NULL, njs_prop_value(prop));
+        return slots->prop_handler(vm, prop, pq->lhq.key_hash, value, NULL,
+                                   njs_prop_value(prop));
 
     case NJS_PROPERTY_QUERY_SET:
         if (slots->writable == 0) {
@@ -1054,10 +1012,9 @@ njs_external_property_query(njs_vm_t *vm, njs_property_query_t *pq,
 
 
 njs_int_t
-njs_value_property(njs_vm_t *vm, njs_value_t *value, njs_value_t *key,
+njs_value_property(njs_vm_t *vm, njs_value_t *value, uint32_t atom_id,
     njs_value_t *retval)
 {
-    double                num;
     uint32_t              index;
     njs_int_t             ret;
     njs_array_t          *array;
@@ -1065,16 +1022,8 @@ njs_value_property(njs_vm_t *vm, njs_value_t *value, njs_value_t *key,
     njs_typed_array_t     *tarray;
     njs_property_query_t  pq;
 
-    njs_assert(njs_is_index_or_key(key));
-
-    if (njs_fast_path(njs_is_number(key))) {
-        num = njs_number(key);
-
-        if (njs_slow_path(!njs_number_is_integer_index(num))) {
-            goto slow_path;
-        }
-
-        index = (uint32_t) num;
+    if (njs_fast_path(njs_atom_is_number(atom_id))) {
+        index = njs_atom_number(atom_id);
 
         if (njs_is_typed_array(value)) {
             tarray = njs_typed_array(value);
@@ -1116,9 +1065,9 @@ njs_value_property(njs_vm_t *vm, njs_value_t *value, njs_value_t *key,
 
 slow_path:
 
-    njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0, 0);
+    njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0);
 
-    ret = njs_property_query(vm, &pq, value, key);
+    ret = njs_property_query(vm, &pq, value, atom_id);
 
     switch (ret) {
 
@@ -1144,7 +1093,7 @@ slow_path:
         case NJS_PROPERTY_HANDLER:
             pq.scratch = *prop;
             prop = &pq.scratch;
-            ret = njs_prop_handler(prop)(vm, prop, value, NULL,
+            ret = njs_prop_handler(prop)(vm, prop, atom_id, value, NULL,
                                          njs_prop_value(prop));
 
             if (njs_slow_path(ret != NJS_OK)) {
@@ -1185,32 +1134,21 @@ slow_path:
 
 
 njs_int_t
-njs_value_property_set(njs_vm_t *vm, njs_value_t *value, njs_value_t *key,
+njs_value_property_set(njs_vm_t *vm, njs_value_t *value, uint32_t atom_id,
     njs_value_t *setval)
 {
-    double                num;
     uint32_t              index;
     njs_int_t             ret;
     njs_array_t           *array;
-    njs_value_t           retval;
-    njs_flathsh_elt_t     *elt;
+    njs_value_t           retval, key;
     njs_object_prop_t     *prop;
     njs_typed_array_t     *tarray;
+    njs_flathsh_elt_t     *elt;
     njs_flathsh_descr_t   *h;
     njs_property_query_t  pq;
 
-    static const njs_str_t  length_key = njs_str("length");
-
-    njs_assert(njs_is_index_or_key(key));
-
-    if (njs_fast_path(njs_is_number(key))) {
-        num = njs_number(key);
-
-        if (njs_slow_path(!njs_number_is_integer_index(num))) {
-            goto slow_path;
-        }
-
-        index = (uint32_t) num;
+    if (njs_fast_path(njs_atom_is_number(atom_id))) {
+        index = njs_atom_number(atom_id);
 
         if (njs_is_typed_array(value)) {
             tarray = njs_typed_array(value);
@@ -1249,9 +1187,9 @@ slow_path:
         return NJS_ERROR;
     }
 
-    njs_property_query_init(&pq, NJS_PROPERTY_QUERY_SET, 0, 0);
+    njs_property_query_init(&pq, NJS_PROPERTY_QUERY_SET, 0);
 
-    ret = njs_property_query(vm, &pq, value, key);
+    ret = njs_property_query(vm, &pq, value, atom_id);
 
     switch (ret) {
 
@@ -1260,7 +1198,7 @@ slow_path:
 
         if (njs_is_data_descriptor(prop)) {
             if (!prop->writable) {
-                njs_key_string_get(vm, &pq.key,  &pq.lhq.key);
+                njs_atom_string_get(vm, atom_id, &pq.lhq.key);
                 njs_type_error(vm,
                              "Cannot assign to read-only property \"%V\" of %s",
                                &pq.lhq.key, njs_type_string(value->type));
@@ -1273,7 +1211,7 @@ slow_path:
                                          value, setval, 1, &retval);
             }
 
-            njs_key_string_get(vm, &pq.key,  &pq.lhq.key);
+            njs_atom_string_get(vm, atom_id, &pq.lhq.key);
             njs_type_error(vm,
                      "Cannot set property \"%V\" of %s which has only a getter",
                            &pq.lhq.key, njs_type_string(value->type));
@@ -1281,7 +1219,8 @@ slow_path:
         }
 
         if (prop->type == NJS_PROPERTY_HANDLER) {
-            ret = njs_prop_handler(prop)(vm, prop, value, setval, &retval);
+            ret = njs_prop_handler(prop)(vm, prop, atom_id, value,
+                                         setval, &retval);
             if (njs_slow_path(ret != NJS_DECLINED)) {
                 return ret;
             }
@@ -1291,10 +1230,8 @@ slow_path:
             switch (prop->type) {
             case NJS_PROPERTY:
                 if (njs_is_array(value)) {
-                    if (njs_slow_path(pq.lhq.key_hash == NJS_LENGTH_HASH)) {
-                        if (njs_strstr_eq(&pq.lhq.key, &length_key)) {
-                            return njs_array_length_set(vm, value, prop, setval);
-                        }
+                    if (njs_slow_path(atom_id == NJS_ATOM_STRING_length)) {
+                        return njs_array_length_set(vm, value, prop, setval);
                     }
                 }
 
@@ -1340,7 +1277,7 @@ slow_path:
 
             pq.lhq.pool = vm->mem_pool;
 
-            int rc = njs_lvlhsh_delete(pq.own_whiteout, &pq.lhq);
+            int rc = njs_flathsh_unique_delete(pq.own_whiteout, &pq.lhq);
             if (rc != NJS_OK) {
                 return NJS_ERROR;
             }
@@ -1374,10 +1311,16 @@ slow_path:
         }
 
         if (njs_slow_path(pq.own && njs_is_typed_array(value)
-                          && njs_is_string(key)))
+                          && !njs_atom_is_number(atom_id)))
         {
             /* Integer-Indexed Exotic Objects [[DefineOwnProperty]]. */
-            if (!isnan(njs_string_to_index(key))) {
+
+            ret = njs_atom_to_value(vm, &key, atom_id);
+            if (njs_slow_path(ret != NJS_OK)) {
+                return ret;
+            }
+
+            if (!isnan(njs_string_to_index(&key))) {
                 return NJS_OK;
             }
         }
@@ -1394,16 +1337,17 @@ slow_path:
         goto fail;
     }
 
-    prop = njs_object_prop_alloc(vm, &pq.key, &njs_value_undefined, 1);
+    prop = njs_object_prop_alloc(vm, &njs_value_undefined, 1);
     if (njs_slow_path(prop == NULL)) {
         return NJS_ERROR;
     }
 
     pq.lhq.replace = 0;
     pq.lhq.value = prop;
+    pq.lhq.key_hash = atom_id;
     pq.lhq.pool = vm->mem_pool;
 
-    ret = njs_lvlhsh_insert(njs_object_hash(value), &pq.lhq);
+    ret = njs_flathsh_unique_insert(njs_object_hash(value), &pq.lhq);
     if (njs_slow_path(ret != NJS_OK)) {
         njs_internal_error(vm, "lvlhsh insert failed");
         return NJS_ERROR;
@@ -1417,7 +1361,7 @@ found:
 
 fail:
 
-    njs_key_string_get(vm, &pq.key, &pq.lhq.key);
+    njs_atom_string_get(vm, atom_id, &pq.lhq.key);
     njs_type_error(vm, "Cannot add property \"%V\", object is not extensible",
                    &pq.lhq.key);
 
@@ -1426,30 +1370,21 @@ fail:
 
 
 njs_int_t
-njs_value_property_delete(njs_vm_t *vm, njs_value_t *value, njs_value_t *key,
+njs_value_property_delete(njs_vm_t *vm, njs_value_t *value, uint32_t atom_id,
     njs_value_t *removed, njs_bool_t thrw)
 {
-    double                num;
     uint32_t              index;
     njs_int_t             ret;
     njs_array_t           *array;
     njs_object_prop_t     *prop;
     njs_property_query_t  pq;
 
-    njs_assert(njs_is_index_or_key(key));
-
-    if (njs_fast_path(njs_is_number(key))) {
+    if (njs_fast_path(njs_atom_is_number(atom_id))) {
         if (njs_slow_path(!(njs_is_fast_array(value)))) {
             goto slow_path;
         }
 
-        num = njs_number(key);
-
-        if (njs_slow_path(!njs_number_is_integer_index(num))) {
-            goto slow_path;
-        }
-
-        index = (uint32_t) num;
+        index = (uint32_t) njs_atom_number(atom_id);
 
         array = njs_array(value);
 
@@ -1464,9 +1399,9 @@ njs_value_property_delete(njs_vm_t *vm, njs_value_t *value, njs_value_t *key,
 
 slow_path:
 
-    njs_property_query_init(&pq, NJS_PROPERTY_QUERY_DELETE, 0, 1);
+    njs_property_query_init(&pq, NJS_PROPERTY_QUERY_DELETE, 1);
 
-    ret = njs_property_query(vm, &pq, value, key);
+    ret = njs_property_query(vm, &pq, value, atom_id);
     if (njs_slow_path(ret != NJS_OK)) {
         return ret;
     }
@@ -1475,7 +1410,7 @@ slow_path:
 
     if (njs_slow_path(!prop->configurable)) {
         if (thrw) {
-            njs_key_string_get(vm, &pq.key,  &pq.lhq.key);
+            njs_atom_string_get(vm, atom_id, &pq.lhq.key);
             njs_type_error(vm, "Cannot delete property \"%V\" of %s",
                            &pq.lhq.key, njs_type_string(value->type));
             return NJS_ERROR;
@@ -1487,7 +1422,8 @@ slow_path:
     switch (prop->type) {
     case NJS_PROPERTY_HANDLER:
         if (njs_is_object(value) && njs_object_slots(value) != NULL) {
-            ret = njs_prop_handler(prop)(vm, prop, value, NULL, NULL);
+            ret = njs_prop_handler(prop)(vm, prop, atom_id, value, NULL,
+                                         NULL);
             if (njs_slow_path(ret != NJS_DECLINED)) {
                 return ret;
             }
@@ -1550,16 +1486,22 @@ njs_primitive_value_to_string(njs_vm_t *vm, njs_value_t *dst,
     switch (src->type) {
 
     case NJS_NULL:
-        value = &njs_string_null;
-        break;
+        njs_atom_to_value(vm, dst, NJS_ATOM_STRING_null);
+        return NJS_OK;
 
     case NJS_UNDEFINED:
-        value = &njs_string_undefined;
-        break;
+        njs_atom_to_value(vm, dst, NJS_ATOM_STRING_undefined);
+        return NJS_OK;
 
     case NJS_BOOLEAN:
-        value = njs_is_true(src) ? &njs_string_true : &njs_string_false;
-        break;
+        if (njs_is_true(src)) {
+            njs_atom_to_value(vm, dst, NJS_ATOM_STRING_true);
+
+        } else {
+            njs_atom_to_value(vm, dst, NJS_ATOM_STRING_false);
+        }
+
+        return NJS_OK;
 
     case NJS_NUMBER:
         return njs_number_to_string(vm, dst, src);
@@ -1616,7 +1558,7 @@ njs_primitive_value_to_chain(njs_vm_t *vm, njs_chb_t *chain,
         return NJS_ERROR;
 
     case NJS_STRING:
-        (void) njs_string_prop(&string, src);
+        (void) njs_string_prop(vm, &string, src);
         njs_chb_append(chain, string.start, string.size);
         return string.length;
 
@@ -1712,11 +1654,7 @@ njs_value_species_constructor(njs_vm_t *vm, njs_value_t *object,
     njs_int_t    ret;
     njs_value_t  constructor, retval;
 
-    static const njs_value_t  string_constructor = njs_string("constructor");
-    static const njs_value_t  string_species =
-                                njs_wellknown_symbol(NJS_SYMBOL_SPECIES);
-
-    ret = njs_value_property(vm, object, njs_value_arg(&string_constructor),
+    ret = njs_value_property(vm, object, NJS_ATOM_STRING_constructor,
                              &constructor);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return NJS_ERROR;
@@ -1731,7 +1669,7 @@ njs_value_species_constructor(njs_vm_t *vm, njs_value_t *object,
         return NJS_ERROR;
     }
 
-    ret = njs_value_property(vm, &constructor, njs_value_arg(&string_species),
+    ret = njs_value_property(vm, &constructor, NJS_ATOM_SYMBOL_species,
                              &retval);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return NJS_ERROR;
@@ -1759,7 +1697,7 @@ default_constructor:
 
 
 njs_int_t
-njs_value_method(njs_vm_t *vm, njs_value_t *value, njs_value_t *key,
+njs_value_method(njs_vm_t *vm, njs_value_t *value, uint32_t atom_id,
     njs_value_t *retval)
 {
     njs_int_t  ret;
@@ -1769,7 +1707,7 @@ njs_value_method(njs_vm_t *vm, njs_value_t *value, njs_value_t *key,
         return ret;
     }
 
-    ret = njs_value_property(vm, value, key, retval);
+    ret = njs_value_property(vm, value, atom_id, retval);
     if (njs_slow_path(ret != NJS_OK)) {
         return (ret == NJS_DECLINED) ? NJS_OK : ret;
     }
diff --git a/src/njs_value.h b/src/njs_value.h
index 3751db71..7bc9eff3 100644
--- a/src/njs_value.h
+++ b/src/njs_value.h
@@ -91,33 +91,18 @@ typedef struct njs_property_next_s    njs_property_next_t;
 
 
 union njs_value_s {
-    /*
-     * The njs_value_t size is 16 bytes and must be aligned to 16 bytes
-     * to provide 4 bits to encode scope in njs_index_t.  This space is
-     * used to store short strings.  The maximum size of a short string
-     * is 14 (NJS_STRING_SHORT).  If the short_string.size field is 15
-     * (NJS_STRING_LONG) then the size is in the long_string.size field
-     * and the long_string.data field points to a long string.
-     *
-     * The number of the string types is limited to 2 types to minimize
-     * overhead of processing string fields.  It is also possible to add
-     * strings with size from 14 to 254 which size and length are stored in
-     * the string_size and string_length byte wide fields.  This will lessen
-     * the maximum size of short string to 13.
-     */
     struct {
-        njs_value_type_t              type:8;  /* 6 bits */
+        uint32_t                      magic32;
+        njs_value_type_t              type:8;  /* 5 bits */
+
         /*
          * The truth field is set during value assignment and then can be
          * quickly tested by logical and conditional operations regardless
-         * of value type.  The truth field coincides with short_string.size
-         * and short_string.length so when string size and length are zero
-         * the string's value is false.
+         * of value type.
          */
         uint8_t                       truth;
 
         uint16_t                      magic16;
-        uint32_t                      magic32;
 
         union {
             double                    number;
@@ -139,30 +124,19 @@ union njs_value_s {
     } data;
 
     struct {
-        njs_value_type_t              type:8;  /* 6 bits */
-
-#define NJS_STRING_SHORT              14
-#define NJS_STRING_LONG               15
-
-        uint8_t                       size:4;
-        uint8_t                       length:4;
-
-        u_char                        start[NJS_STRING_SHORT];
-    } short_string;
-
-    struct {
-        njs_value_type_t              type:8;  /* 6 bits */
+        uint32_t                      atom_id;
+        njs_value_type_t              type:8;  /* 5 bits */
         uint8_t                       truth;
-
-        /* 0xff if data is external string. */
-        uint8_t                       external;
-        uint8_t                       _spare;
-
-        uint32_t                      size;
+        uint8_t                       token_type;
+        uint8_t                       token_id;
         njs_string_t                  *data;
-    } long_string;
+    } string;
 
-    njs_value_type_t                  type:8;  /* 6 bits */
+    struct {
+        uint32_t                      atom_id;
+        njs_value_type_t              type:8;  /* 5 bits */
+        uint8_t                       truth;
+    };
 };
 
 
@@ -177,16 +151,16 @@ typedef struct {
     njs_exotic_keys_t   keys;
 
     /* A shared hash of njs_object_prop_t for externals. */
-    njs_lvlhsh_t        external_shared_hash;
+    njs_flathsh_t       external_shared_hash;
 } njs_exotic_slots_t;
 
 
 struct njs_object_s {
     /* A private hash of njs_object_prop_t. */
-    njs_lvlhsh_t                      hash;
+    njs_flathsh_t                     hash;
 
     /* A shared hash of njs_object_prop_t. */
-    njs_lvlhsh_t                      shared_hash;
+    njs_flathsh_t                     shared_hash;
 
     njs_object_t                      *__proto__;
     njs_exotic_slots_t                *slots;
@@ -315,10 +289,11 @@ struct njs_object_type_init_s {
 typedef enum {
     NJS_PROPERTY = 0,
     NJS_ACCESSOR,
+    NJS_PROPERTY_HANDLER,
+
     NJS_PROPERTY_REF,
     NJS_PROPERTY_PLACE_REF,
     NJS_PROPERTY_TYPED_ARRAY_REF,
-    NJS_PROPERTY_HANDLER,
     NJS_WHITEOUT,
 } njs_object_prop_type_t;
 
@@ -345,8 +320,6 @@ typedef enum {
 
 
 struct njs_object_prop_s {
-    njs_value_t                 name;
-
     union {
         njs_value_t             value;
         struct {
@@ -374,23 +347,28 @@ struct njs_object_prop_s {
 };
 
 
+struct njs_object_prop_init_s {
+    struct njs_object_prop_s    desc;
+    uint32_t                    atom_id;
+};
+
+
 typedef struct {
-    njs_lvlhsh_query_t          lhq;
+    njs_flathsh_query_t         lhq;
 
     uint8_t                     query;
 
     /* scratch is used to get the value of an NJS_PROPERTY_HANDLER property. */
     njs_object_prop_t           scratch;
 
-    njs_value_t                 key;
-    njs_lvlhsh_t                *own_whiteout;
+    njs_flathsh_t              *own_whiteout;
 
     uint8_t                     temp;
     uint8_t                     own;
 } njs_property_query_t;
 
 
-#define njs_value(_type, _truth, _number) {                                   \
+#define njs_value(_type, _truth, _number) (njs_value_t) {                     \
     .data = {                                                                 \
         .type = _type,                                                        \
         .truth = _truth,                                                      \
@@ -399,37 +377,26 @@ typedef struct {
 }
 
 
-#define njs_wellknown_symbol(key) {                                           \
+#define njs_symval(_sym_id, _s) {                                             \
     .data = {                                                                 \
         .type = NJS_SYMBOL,                                                   \
         .truth = 1,                                                           \
-        .magic32 = key,                                                       \
-        .u = { .value = NULL }                                                \
-    }                                                                         \
-}
-
-
-#define njs_string(s) {                                                       \
-    .short_string = {                                                         \
-        .type = NJS_STRING,                                                   \
-        .size = njs_length(s),                                                \
-        .length = njs_length(s),                                              \
-        .start = s,                                                           \
+        .magic32 = NJS_ATOM_SYMBOL_ ## _sym_id,                               \
+        .u = { .value = (njs_value_t *) &njs_ascii_strval(_s) }               \
     }                                                                         \
 }
 
 
-/* NJS_STRING_LONG is set for both big and little endian platforms. */
-
-#define njs_long_string(s) {                                                  \
-    .long_string = {                                                          \
+#define njs_ascii_strval(_s) (njs_value_t) {                                  \
+    .string = {                                                               \
+        .atom_id = NJS_ATOM_STRING_unknown,                                   \
         .type = NJS_STRING,                                                   \
-        .truth = (NJS_STRING_LONG << 4) | NJS_STRING_LONG,                    \
-        .size = njs_length(s),                                                \
+        .truth = njs_length(_s) ? 1 : 0,                                      \
         .data = & (njs_string_t) {                                            \
-            .start = (u_char *) s,                                            \
-            .length = njs_length(s),                                          \
-        }                                                                     \
+            .start = (u_char *) _s,                                           \
+            .length = njs_length(_s),                                         \
+            .size = njs_length(_s),                                           \
+        },                                                                    \
     }                                                                         \
 }
 
@@ -446,7 +413,7 @@ typedef struct {
 }
 
 
-#define _njs_native_function(_func, _args, _ctor, _magic) {                   \
+#define _njs_native_function(_func, _args, _ctor, _magic) (njs_value_t) {     \
     .data = {                                                                 \
         .type = NJS_FUNCTION,                                                 \
         .truth = 1,                                                           \
@@ -464,30 +431,28 @@ typedef struct {
     _njs_native_function(_function, _args_count, 0, _magic)
 
 
-#define njs_getter(_function, _magic)                                         \
-    {                                                                         \
-        .getter = & (njs_function_t) _njs_function(_function, 0, 0, _magic),  \
-        .setter = NULL,                                                       \
-    }
+#define njs_getter(_function, _magic) {                                       \
+    .getter = & (njs_function_t) _njs_function(_function, 0, 0, _magic),      \
+    .setter = NULL,                                                           \
+}
 
 
-#define njs_accessor(_getter, _m1, _setter, _m2)                              \
-    {                                                                         \
-        .getter = & (njs_function_t) _njs_function(_getter, 0, 0, _m1),       \
-        .setter = & (njs_function_t) _njs_function(_setter, 0, 0, _m2),       \
-    }
+#define njs_accessor(_getter, _m1, _setter, _m2) {                            \
+    .getter = & (njs_function_t) _njs_function(_getter, 0, 0, _m1),           \
+    .setter = & (njs_function_t) _njs_function(_setter, 0, 0, _m2),           \
+}
 
 
 #define njs_native_ctor(_function, _args_count, _magic)                       \
     _njs_function(_function, _args_count, 1, _magic)
 
 
-#define njs_prop_handler2(_handler, _magic16, _magic32) {                     \
+#define njs_prop_handler2(_handler, _magic16) (njs_value_t) {                 \
     .data = {                                                                 \
         .type = NJS_INVALID,                                                  \
         .truth = 1,                                                           \
         .magic16 = _magic16,                                                  \
-        .magic32 = _magic32,                                                  \
+        .magic32 = 2,                                                         \
         .u = { .prop_handler = _handler }                                     \
     }                                                                         \
 }
@@ -551,50 +516,32 @@ typedef struct {
     (njs_is_number(value) || njs_is_key(value))
 
 
-/*
- * The truth field coincides with short_string.size and short_string.length
- * so when string size and length are zero the string's value is false and
- * otherwise is true.
- */
-#define njs_string_truth(value, size)
-
-
-#define njs_string_get(value, str)                                            \
+#define njs_string_get_unsafe(value, str)                                     \
     do {                                                                      \
-        if ((value)->short_string.size != NJS_STRING_LONG) {                  \
-            (str)->length = (value)->short_string.size;                       \
-            (str)->start = (u_char *) (value)->short_string.start;            \
-                                                                              \
-        } else {                                                              \
-            (str)->length = (value)->long_string.size;                        \
-            (str)->start = (u_char *) (value)->long_string.data->start;       \
-        }                                                                     \
+        njs_assert((value)->string.data != NULL);                             \
+        (str)->length = (value)->string.data->size;                           \
+        (str)->start = (u_char *) (value)->string.data->start;                \
     } while (0)
 
 
-#define njs_string_short_start(value)                                         \
-    (value)->short_string.start
-
-
-#define njs_string_short_set(value, _size, _length)                           \
-    do {                                                                      \
-        (value)->type = NJS_STRING;                                           \
-        njs_string_truth(value, _size);                                       \
-        (value)->short_string.size = _size;                                   \
-        (value)->short_string.length = _length;                               \
-    } while (0)
-
-
-#define njs_string_length_set(value, _length)                                 \
+#define njs_string_get(vm, value, str)                                        \
     do {                                                                      \
-        if ((value)->short_string.size != NJS_STRING_LONG) {                  \
-            (value)->short_string.length = length;                            \
+        njs_value_t  _dst;                                                    \
+                                                                              \
+        njs_assert(njs_is_string(value));                                     \
+                                                                              \
+        if (njs_slow_path((value)->string.data == NULL)) {                    \
+            njs_assert((value)->atom_id != 0 /* NJS_ATOM_STRING_unknown */);  \
+            njs_atom_to_value(vm, &_dst, (value)->atom_id);                   \
+            njs_assert(njs_is_string(&_dst));                                 \
+            njs_string_get_unsafe(&_dst, str);                                \
                                                                               \
         } else {                                                              \
-            (value)->long_string.data->length = length;                       \
+            njs_string_get_unsafe(value, str);                                \
         }                                                                     \
     } while (0)
 
+
 #define njs_is_primitive(value)                                               \
     ((value)->type <= NJS_STRING)
 
@@ -828,32 +775,6 @@ extern const njs_value_t  njs_value_zero;
 extern const njs_value_t  njs_value_nan;
 extern const njs_value_t  njs_value_invalid;
 
-extern const njs_value_t  njs_string_empty;
-extern const njs_value_t  njs_string_empty_regexp;
-extern const njs_value_t  njs_string_comma;
-extern const njs_value_t  njs_string_null;
-extern const njs_value_t  njs_string_undefined;
-extern const njs_value_t  njs_string_boolean;
-extern const njs_value_t  njs_string_false;
-extern const njs_value_t  njs_string_true;
-extern const njs_value_t  njs_string_number;
-extern const njs_value_t  njs_string_minus_zero;
-extern const njs_value_t  njs_string_minus_infinity;
-extern const njs_value_t  njs_string_plus_infinity;
-extern const njs_value_t  njs_string_nan;
-extern const njs_value_t  njs_string_symbol;
-extern const njs_value_t  njs_string_string;
-extern const njs_value_t  njs_string_data;
-extern const njs_value_t  njs_string_type;
-extern const njs_value_t  njs_string_name;
-extern const njs_value_t  njs_string_external;
-extern const njs_value_t  njs_string_invalid;
-extern const njs_value_t  njs_string_object;
-extern const njs_value_t  njs_string_function;
-extern const njs_value_t  njs_string_anonymous;
-extern const njs_value_t  njs_string_memory_error;
-
-
 njs_inline void
 njs_set_boolean(njs_value_t *value, unsigned yn)
 {
@@ -872,15 +793,21 @@ njs_set_number(njs_value_t *value, double num)
     value->data.u.number = num;
     value->type = NJS_NUMBER;
     value->data.truth = njs_is_number_true(num);
+    value->atom_id = 0 /* NJS_ATOM_STRING_unknown */;
 }
 
 
+#define njs_set_empty_string(vm, value)                                       \
+    njs_atom_to_value(vm, value, NJS_ATOM_STRING_empty)
+
+
 njs_inline void
 njs_set_int32(njs_value_t *value, int32_t num)
 {
     value->data.u.number = num;
     value->type = NJS_NUMBER;
     value->data.truth = (num != 0);
+    value->atom_id = 0 /* NJS_ATOM_STRING_unknown */;
 }
 
 
@@ -890,6 +817,7 @@ njs_set_uint32(njs_value_t *value, uint32_t num)
     value->data.u.number = num;
     value->type = NJS_NUMBER;
     value->data.truth = (num != 0);
+    value->atom_id = 0 /* NJS_ATOM_STRING_unknown */;
 }
 
 
@@ -1030,20 +958,18 @@ njs_int_t njs_primitive_value_to_string(njs_vm_t *vm, njs_value_t *dst,
     const njs_value_t *src);
 njs_int_t njs_primitive_value_to_chain(njs_vm_t *vm, njs_chb_t *chain,
     const njs_value_t *src);
-double njs_string_to_number(const njs_value_t *value);
+double njs_string_to_number(njs_vm_t *vm, const njs_value_t *value);
 njs_int_t njs_int64_to_string(njs_vm_t *vm, njs_value_t *value, int64_t i64);
 
-njs_bool_t njs_string_eq(const njs_value_t *v1, const njs_value_t *v2);
+njs_bool_t njs_string_eq(njs_vm_t *vm, const njs_value_t *v1,
+    const njs_value_t *v2);
 
 njs_int_t njs_property_query(njs_vm_t *vm, njs_property_query_t *pq,
-    njs_value_t *value, njs_value_t *key);
-
-njs_int_t njs_value_property(njs_vm_t *vm, njs_value_t *value,
-    njs_value_t *key, njs_value_t *retval);
+    njs_value_t *value, uint32_t atom_id);
 njs_int_t njs_value_property_set(njs_vm_t *vm, njs_value_t *value,
-    njs_value_t *key, njs_value_t *setval);
+    uint32_t atom_id, njs_value_t *setval);
 njs_int_t njs_value_property_delete(njs_vm_t *vm, njs_value_t *value,
-    njs_value_t *key, njs_value_t *removed, njs_bool_t thrw);
+    uint32_t atom_id, njs_value_t *removed, njs_bool_t thrw);
 njs_int_t njs_value_to_object(njs_vm_t *vm, njs_value_t *value);
 
 void njs_symbol_conversion_failed(njs_vm_t *vm, njs_bool_t to_string);
@@ -1053,16 +979,15 @@ njs_int_t njs_value_construct(njs_vm_t *vm, njs_value_t *constructor,
 njs_int_t njs_value_species_constructor(njs_vm_t *vm, njs_value_t *object,
     njs_value_t *default_constructor, njs_value_t *dst);
 
-njs_int_t njs_value_method(njs_vm_t *vm, njs_value_t *value, njs_value_t *key,
+njs_int_t njs_value_method(njs_vm_t *vm, njs_value_t *value, uint32_t atom_id,
     njs_value_t *retval);
 
 
 njs_inline void
 njs_property_query_init(njs_property_query_t *pq, njs_prop_query_t query,
-    uint32_t hash, uint8_t own)
+    uint8_t own)
 {
         pq->query = query;
-        pq->lhq.key_hash = hash;
         pq->own = own;
 
         if (query == NJS_PROPERTY_QUERY_SET) {
@@ -1073,15 +998,36 @@ njs_property_query_init(njs_property_query_t *pq, njs_prop_query_t query,
 }
 
 
+njs_inline njs_int_t
+njs_property_query_val(njs_vm_t *vm, njs_property_query_t *pq,
+    njs_value_t *value, njs_value_t *key)
+{
+    njs_int_t  ret;
+
+    if (njs_value_atom(key) == 0 /* NJS_ATOM_STRING_unknown */) {
+        ret = njs_atom_atomize_key(vm, key);
+        if (ret != NJS_OK) {
+            return ret;
+        }
+    }
+
+    return njs_property_query(vm, pq, value, key->atom_id);
+}
+
+
 njs_inline njs_int_t
 njs_value_property_i64(njs_vm_t *vm, njs_value_t *value, int64_t index,
     njs_value_t *retval)
 {
     njs_value_t  key;
 
+    if (index < 0x80000000) {
+        return njs_value_property(vm, value, njs_number_atom(index), retval);
+    }
+
     njs_set_number(&key, index);
 
-    return njs_value_property(vm, value, &key, retval);
+    return njs_value_property_val(vm, value, &key, retval);
 }
 
 
@@ -1091,9 +1037,31 @@ njs_value_property_i64_set(njs_vm_t *vm, njs_value_t *value, int64_t index,
 {
     njs_value_t  key;
 
+    if (index < 0x80000000) {
+        return njs_value_property_set(vm, value, njs_number_atom(index),
+                                      setval);
+    }
+
     njs_set_number(&key, index);
 
-    return njs_value_property_set(vm, value, &key, setval);
+    return njs_value_property_val_set(vm, value, &key, setval);
+}
+
+
+njs_inline njs_int_t
+njs_value_property_val_delete(njs_vm_t *vm, njs_value_t *value,
+    njs_value_t *key, njs_value_t *removed, njs_bool_t thrw)
+{
+    njs_int_t  ret;
+
+    if (njs_value_atom(key) == 0 /* NJS_ATOM_STRING_unknown */) {
+        ret = njs_atom_atomize_key(vm, key);
+        if (ret != NJS_OK) {
+            return ret;
+        }
+    }
+
+    return njs_value_property_delete(vm, value, key->atom_id, removed, thrw);
 }
 
 
@@ -1103,17 +1071,23 @@ njs_value_property_i64_delete(njs_vm_t *vm, njs_value_t *value, int64_t index,
 {
     njs_value_t  key;
 
+    if (index < 0x80000000) {
+        return njs_value_property_delete(vm, value, njs_number_atom(index),
+                                         removed, 1);
+    }
+
     njs_set_number(&key, index);
 
-    return njs_value_property_delete(vm, value, &key, removed, 1);
+    return njs_value_property_val_delete(vm, value, &key, removed, 1);
 }
 
 
 njs_inline njs_bool_t
-njs_values_same_non_numeric(const njs_value_t *val1, const njs_value_t *val2)
+njs_values_same_non_numeric(njs_vm_t *vm, const njs_value_t *val1,
+    const njs_value_t *val2)
 {
     if (njs_is_string(val1)) {
-        return njs_string_eq(val1, val2);
+        return njs_string_eq(vm, val1, val2);
     }
 
     if (njs_is_symbol(val1)) {
@@ -1125,7 +1099,8 @@ njs_values_same_non_numeric(const njs_value_t *val1, const njs_value_t *val2)
 
 
 njs_inline njs_bool_t
-njs_values_strict_equal(const njs_value_t *val1, const njs_value_t *val2)
+njs_values_strict_equal(njs_vm_t *vm, const njs_value_t *val1,
+    const njs_value_t *val2)
 {
     if (val1->type != val2->type) {
         return 0;
@@ -1141,12 +1116,12 @@ njs_values_strict_equal(const njs_value_t *val1, const njs_value_t *val2)
         return (njs_number(val1) == njs_number(val2));
     }
 
-    return njs_values_same_non_numeric(val1, val2);
+    return njs_values_same_non_numeric(vm, val1, val2);
 }
 
 
 njs_inline njs_bool_t
-njs_values_same(const njs_value_t *val1, const njs_value_t *val2)
+njs_values_same(njs_vm_t *vm, const njs_value_t *val1, const njs_value_t *val2)
 {
     double  num1, num2;
 
@@ -1177,12 +1152,13 @@ njs_values_same(const njs_value_t *val1, const njs_value_t *val2)
         return num1 == num2;
     }
 
-    return njs_values_same_non_numeric(val1, val2);
+    return njs_values_same_non_numeric(vm, val1, val2);
 }
 
 
 njs_inline njs_bool_t
-njs_values_same_zero(const njs_value_t *val1, const njs_value_t *val2)
+njs_values_same_zero(njs_vm_t *vm, const njs_value_t *val1,
+    const njs_value_t *val2)
 {
     double  num1, num2;
 
@@ -1207,7 +1183,7 @@ njs_values_same_zero(const njs_value_t *val1, const njs_value_t *val2)
         return num1 == num2;
     }
 
-    return njs_values_same_non_numeric(val1, val2);
+    return njs_values_same_non_numeric(vm, val1, val2);
 }
 
 
diff --git a/src/njs_value_conversion.h b/src/njs_value_conversion.h
index 24483aa2..80c08b45 100644
--- a/src/njs_value_conversion.h
+++ b/src/njs_value_conversion.h
@@ -33,7 +33,7 @@ njs_value_to_number(njs_vm_t *vm, njs_value_t *value, double *dst)
         *dst = NAN;
 
         if (njs_is_string(value)) {
-            *dst = njs_string_to_number(value);
+            *dst = njs_string_to_number(vm, value);
         }
 
         return NJS_OK;
diff --git a/src/njs_variable.c b/src/njs_variable.c
index 85fd235a..78bd2afb 100644
--- a/src/njs_variable.c
+++ b/src/njs_variable.c
@@ -12,31 +12,31 @@
 static njs_declaration_t *njs_variable_scope_function_add(njs_parser_t *parser,
     njs_parser_scope_t *scope);
 static njs_parser_scope_t *njs_variable_scope_find(njs_parser_t *parser,
-     njs_parser_scope_t *scope, uintptr_t unique_id, njs_variable_type_t type);
-static njs_variable_t *njs_variable_alloc(njs_vm_t *vm, uintptr_t unique_id,
+     njs_parser_scope_t *scope, uintptr_t atom_id, njs_variable_type_t type);
+static njs_variable_t *njs_variable_alloc(njs_vm_t *vm, uintptr_t atom_id,
     njs_variable_type_t type);
 
 
 njs_variable_t *
 njs_variable_add(njs_parser_t *parser, njs_parser_scope_t *scope,
-    uintptr_t unique_id, njs_variable_type_t type)
+    uintptr_t atom_id, njs_variable_type_t type)
 {
     njs_parser_scope_t  *root;
 
-    root = njs_variable_scope_find(parser, scope, unique_id, type);
+    root = njs_variable_scope_find(parser, scope, atom_id, type);
     if (njs_slow_path(root == NULL)) {
         njs_parser_ref_error(parser, "scope not found");
         return NULL;
     }
 
-    return njs_variable_scope_add(parser, root, scope, unique_id, type,
+    return njs_variable_scope_add(parser, root, scope, atom_id, type,
                                   NJS_INDEX_NONE);
 }
 
 
 njs_variable_t *
 njs_variable_function_add(njs_parser_t *parser, njs_parser_scope_t *scope,
-    uintptr_t unique_id, njs_variable_type_t type)
+    uintptr_t atom_id, njs_variable_type_t type)
 {
     njs_bool_t             ctor;
     njs_variable_t         *var;
@@ -44,13 +44,13 @@ njs_variable_function_add(njs_parser_t *parser, njs_parser_scope_t *scope,
     njs_parser_scope_t     *root;
     njs_function_lambda_t  *lambda;
 
-    root = njs_variable_scope_find(parser, scope, unique_id, type);
+    root = njs_variable_scope_find(parser, scope, atom_id, type);
     if (njs_slow_path(root == NULL)) {
         njs_parser_ref_error(parser, "scope not found");
         return NULL;
     }
 
-    var = njs_variable_scope_add(parser, root, scope, unique_id, type,
+    var = njs_variable_scope_add(parser, root, scope, atom_id, type,
                                  NJS_INDEX_ERROR);
     if (njs_slow_path(var == NULL)) {
         return NULL;
@@ -107,7 +107,7 @@ njs_variable_scope_function_add(njs_parser_t *parser, njs_parser_scope_t *scope)
 
 
 static njs_parser_scope_t *
-njs_variable_scope(njs_parser_scope_t *scope, uintptr_t unique_id,
+njs_variable_scope(njs_parser_scope_t *scope, uintptr_t atom_id,
     njs_variable_t **retvar, njs_variable_type_t type)
 {
     njs_variable_t       *var;
@@ -116,7 +116,7 @@ njs_variable_scope(njs_parser_scope_t *scope, uintptr_t unique_id,
 
     *retvar = NULL;
 
-    var_node.key = unique_id;
+    var_node.key = atom_id;
 
     do {
         node = njs_rbtree_find(&scope->variables, &var_node.node);
@@ -146,14 +146,14 @@ njs_variable_scope(njs_parser_scope_t *scope, uintptr_t unique_id,
 
 static njs_parser_scope_t *
 njs_variable_scope_find(njs_parser_t *parser, njs_parser_scope_t *scope,
-     uintptr_t unique_id, njs_variable_type_t type)
+     uintptr_t atom_id, njs_variable_type_t type)
 {
-    njs_bool_t               module;
-    njs_variable_t           *var;
-    njs_parser_scope_t       *root;
-    const njs_lexer_entry_t  *entry;
+    njs_str_t           entry;
+    njs_bool_t          module;
+    njs_variable_t      *var;
+    njs_parser_scope_t  *root;
 
-    root = njs_variable_scope(scope, unique_id, &var, type);
+    root = njs_variable_scope(scope, atom_id, &var, type);
     if (njs_slow_path(root == NULL)) {
         return NULL;
     }
@@ -162,7 +162,7 @@ njs_variable_scope_find(njs_parser_t *parser, njs_parser_scope_t *scope,
     case NJS_VARIABLE_CONST:
     case NJS_VARIABLE_LET:
         if (scope->type == NJS_SCOPE_GLOBAL
-            && parser->undefined_id == unique_id)
+            && atom_id == NJS_ATOM_STRING_undefined)
         {
             goto failed;
         }
@@ -239,17 +239,16 @@ njs_variable_scope_find(njs_parser_t *parser, njs_parser_scope_t *scope,
 
 failed:
 
-    entry = njs_lexer_entry(unique_id);
+    njs_lexer_entry(parser->vm, atom_id, &entry);
 
-    njs_parser_syntax_error(parser, "\"%V\" has already been declared",
-                            &entry->name);
+    njs_parser_syntax_error(parser, "\"%V\" has already been declared", &entry);
     return NULL;
 }
 
 
 njs_variable_t *
 njs_variable_scope_add(njs_parser_t *parser, njs_parser_scope_t *scope,
-    njs_parser_scope_t *original, uintptr_t unique_id,
+    njs_parser_scope_t *original, uintptr_t atom_id,
     njs_variable_type_t type, njs_index_t index)
 {
     njs_variable_t       *var;
@@ -257,7 +256,7 @@ njs_variable_scope_add(njs_parser_t *parser, njs_parser_scope_t *scope,
     njs_parser_scope_t   *root;
     njs_variable_node_t  var_node, *var_node_new;
 
-    var_node.key = unique_id;
+    var_node.key = atom_id;
 
     node = njs_rbtree_find(&scope->variables, &var_node.node);
 
@@ -265,7 +264,7 @@ njs_variable_scope_add(njs_parser_t *parser, njs_parser_scope_t *scope,
         return ((njs_variable_node_t *) node)->variable;
     }
 
-    var = njs_variable_alloc(parser->vm, unique_id, type);
+    var = njs_variable_alloc(parser->vm, atom_id, type);
     if (njs_slow_path(var == NULL)) {
         goto memory_error;
     }
@@ -285,7 +284,7 @@ njs_variable_scope_add(njs_parser_t *parser, njs_parser_scope_t *scope,
         root->items++;
     }
 
-    var_node_new = njs_variable_node_alloc(parser->vm, var, unique_id);
+    var_node_new = njs_variable_node_alloc(parser->vm, var, atom_id);
     if (njs_slow_path(var_node_new == NULL)) {
         goto memory_error;
     }
@@ -303,13 +302,13 @@ memory_error:
 
 
 njs_variable_t *
-njs_label_add(njs_vm_t *vm, njs_parser_scope_t *scope, uintptr_t unique_id)
+njs_label_add(njs_vm_t *vm, njs_parser_scope_t *scope, uintptr_t atom_id)
 {
     njs_variable_t       *label;
     njs_rbtree_node_t    *node;
     njs_variable_node_t  var_node, *var_node_new;
 
-    var_node.key = unique_id;
+    var_node.key = atom_id;
 
     node = njs_rbtree_find(&scope->labels, &var_node.node);
 
@@ -317,12 +316,12 @@ njs_label_add(njs_vm_t *vm, njs_parser_scope_t *scope, uintptr_t unique_id)
         return ((njs_variable_node_t *) node)->variable;
     }
 
-    label = njs_variable_alloc(vm, unique_id, NJS_VARIABLE_CONST);
+    label = njs_variable_alloc(vm, atom_id, NJS_VARIABLE_CONST);
     if (njs_slow_path(label == NULL)) {
         goto memory_error;
     }
 
-    var_node_new = njs_variable_node_alloc(vm, label, unique_id);
+    var_node_new = njs_variable_node_alloc(vm, label, atom_id);
     if (njs_slow_path(var_node_new == NULL)) {
         goto memory_error;
     }
@@ -340,12 +339,12 @@ memory_error:
 
 
 njs_int_t
-njs_label_remove(njs_vm_t *vm, njs_parser_scope_t *scope, uintptr_t unique_id)
+njs_label_remove(njs_vm_t *vm, njs_parser_scope_t *scope, uintptr_t atom_id)
 {
     njs_rbtree_node_t    *node;
     njs_variable_node_t  var_node;
 
-    var_node.key = unique_id;
+    var_node.key = atom_id;
 
     node = njs_rbtree_find(&scope->labels, &var_node.node);
     if (njs_slow_path(node == NULL)) {
@@ -391,7 +390,7 @@ njs_variable_resolve(njs_vm_t *vm, njs_parser_node_t *node)
     ref = &node->u.reference;
     scope = node->scope;
 
-    var_node.key = ref->unique_id;
+    var_node.key = ref->atom_id;
 
     do {
         rb_node = njs_rbtree_find(&scope->variables, &var_node.node);
@@ -420,7 +419,7 @@ njs_variable_closure(njs_vm_t *vm, njs_variable_t *var,
 #define NJS_VAR_MAX_DEPTH     32
     njs_parser_scope_t        *list[NJS_VAR_MAX_DEPTH];
 
-    ref_node.key = var->unique_id;
+    ref_node.key = var->atom_id;
 
     p = list;
 
@@ -485,7 +484,7 @@ njs_variable_closure(njs_vm_t *vm, njs_variable_t *var,
                     return NJS_INDEX_ERROR;
                 }
 
-                parse_node->key = var->unique_id;
+                parse_node->key = var->atom_id;
 
                 njs_rbtree_insert(&scope->references, &parse_node->node);
             }
@@ -524,7 +523,7 @@ njs_variable_reference(njs_vm_t *vm, njs_parser_node_t *node)
     closure = njs_variable_closure_test(node->scope, ref->variable->scope);
     ref->scope = node->scope;
 
-    ref_node.key = ref->unique_id;
+    ref_node.key = ref->atom_id;
 
     rb_node = njs_rbtree_find(&scope->references, &ref_node.node);
     if (njs_slow_path(rb_node == NULL)) {
@@ -557,12 +556,12 @@ njs_variable_reference(njs_vm_t *vm, njs_parser_node_t *node)
 
 
 njs_variable_t *
-njs_label_find(njs_vm_t *vm, njs_parser_scope_t *scope, uintptr_t unique_id)
+njs_label_find(njs_vm_t *vm, njs_parser_scope_t *scope, uintptr_t atom_id)
 {
     njs_rbtree_node_t    *node;
     njs_variable_node_t  var_node;
 
-    var_node.key = unique_id;
+    var_node.key = atom_id;
 
     do {
         node = njs_rbtree_find(&scope->labels, &var_node.node);
@@ -580,7 +579,7 @@ njs_label_find(njs_vm_t *vm, njs_parser_scope_t *scope, uintptr_t unique_id)
 
 
 static njs_variable_t *
-njs_variable_alloc(njs_vm_t *vm, uintptr_t unique_id, njs_variable_type_t type)
+njs_variable_alloc(njs_vm_t *vm, uintptr_t atom_id, njs_variable_type_t type)
 {
     njs_variable_t  *var;
 
@@ -590,7 +589,7 @@ njs_variable_alloc(njs_vm_t *vm, uintptr_t unique_id, njs_variable_type_t type)
         return NULL;
     }
 
-    var->unique_id = unique_id;
+    var->atom_id = atom_id;
     var->type = type;
 
     return var;
diff --git a/src/njs_variable.h b/src/njs_variable.h
index dfcc99f3..2ed5220a 100644
--- a/src/njs_variable.h
+++ b/src/njs_variable.h
@@ -18,7 +18,7 @@ typedef enum {
 
 
 typedef struct {
-    uintptr_t             unique_id;
+    uintptr_t             atom_id;
 
     njs_variable_type_t   type:8;    /* 3 bits */
     njs_bool_t            argument;
@@ -45,7 +45,7 @@ typedef enum {
 
 typedef struct {
     njs_reference_type_t  type;
-    uintptr_t             unique_id;
+    uintptr_t             atom_id;
     njs_variable_t        *variable;
     njs_parser_scope_t    *scope;
     njs_bool_t            not_defined;
@@ -60,19 +60,19 @@ typedef struct {
 
 
 njs_variable_t *njs_variable_add(njs_parser_t *parser,
-    njs_parser_scope_t *scope, uintptr_t unique_id, njs_variable_type_t type);
+    njs_parser_scope_t *scope, uintptr_t atom_id, njs_variable_type_t type);
 njs_variable_t *njs_variable_function_add(njs_parser_t *parser,
-    njs_parser_scope_t *scope, uintptr_t unique_id, njs_variable_type_t type);
+    njs_parser_scope_t *scope, uintptr_t atom_id, njs_variable_type_t type);
 njs_variable_t * njs_label_add(njs_vm_t *vm, njs_parser_scope_t *scope,
-    uintptr_t unique_id);
+    uintptr_t atom_id);
 njs_variable_t *njs_label_find(njs_vm_t *vm, njs_parser_scope_t *scope,
-    uintptr_t unique_id);
+    uintptr_t atom_id);
 njs_int_t njs_label_remove(njs_vm_t *vm, njs_parser_scope_t *scope,
-    uintptr_t unique_id);
+    uintptr_t atom_id);
 njs_variable_t *njs_variable_reference(njs_vm_t *vm, njs_parser_node_t *node);
 njs_variable_t *njs_variable_scope_add(njs_parser_t *parser,
     njs_parser_scope_t *scope, njs_parser_scope_t *original,
-    uintptr_t unique_id, njs_variable_type_t type, njs_index_t index);
+    uintptr_t atom_id, njs_variable_type_t type, njs_index_t index);
 njs_int_t njs_name_copy(njs_vm_t *vm, njs_str_t *dst, const njs_str_t *src);
 
 
diff --git a/src/njs_vm.c b/src/njs_vm.c
index 43b2ccc2..008f9d04 100644
--- a/src/njs_vm.c
+++ b/src/njs_vm.c
@@ -138,8 +138,6 @@ njs_vm_create(njs_vm_opt_t *options)
         }
     }
 
-    vm->symbol_generator = NJS_SYMBOL_KNOWN_MAX;
-
     if (njs_scope_undefined_index(vm, 0) == NJS_INDEX_ERROR) {
         return NULL;
     }
@@ -222,7 +220,7 @@ njs_vm_compile(njs_vm_t *vm, u_char **start, u_char *end)
     global_items = (vm->global_scope != NULL) ? vm->global_scope->items : 0;
 
     ret = njs_parser_init(vm, &parser, vm->global_scope, &vm->options.file,
-                          *start, end, 0);
+                          *start, end);
     if (njs_slow_path(ret != NJS_OK)) {
         return NJS_ERROR;
     }
@@ -330,7 +328,7 @@ njs_vm_compile_module(njs_vm_t *vm, njs_str_t *name, u_char **start,
         return NULL;
     }
 
-    ret = njs_parser_init(vm, &parser, NULL, name, *start, end, 1);
+    ret = njs_parser_init(vm, &parser, NULL, name, *start, end);
     if (njs_slow_path(ret != NJS_OK)) {
         return NULL;
     }
@@ -419,6 +417,11 @@ njs_vm_clone(njs_vm_t *vm, njs_external_ptr_t external)
     nvm->trace.data = nvm;
     nvm->external = external;
 
+    nvm->shared_atom_count = vm->atom_id_generator;
+
+    njs_lvlhsh_init(&nvm->atom_hash);
+    nvm->atom_hash_current = &nvm->atom_hash;
+
     ret = njs_vm_runtime_init(nvm);
     if (njs_slow_path(ret != NJS_OK)) {
         goto fail;
@@ -495,7 +498,7 @@ njs_vm_runtime_init(njs_vm_t *vm)
     }
 
     njs_lvlhsh_init(&vm->values_hash);
-    njs_lvlhsh_init(&vm->keywords_hash);
+
     njs_lvlhsh_init(&vm->modules_hash);
 
     njs_rbtree_init(&vm->global_symbols, njs_symbol_rbtree_cmp);
@@ -874,12 +877,13 @@ njs_vm_value(njs_vm_t *vm, const njs_str_t *path, njs_value_t *retval)
             return NJS_ERROR;
         }
 
-        ret = njs_string_create(vm, &key, start, size);
+        ret = njs_atom_string_create(vm, &key, start, size);
         if (njs_slow_path(ret != NJS_OK)) {
             return NJS_ERROR;
         }
 
-        ret = njs_value_property(vm, &value, &key, njs_value_arg(retval));
+        ret = njs_value_property(vm, &value, key.atom_id,
+                                 njs_value_arg(retval));
         if (njs_slow_path(ret == NJS_ERROR)) {
             return ret;
         }
@@ -900,19 +904,20 @@ static njs_int_t
 njs_vm_bind2(njs_vm_t *vm, const njs_str_t *var_name, njs_object_prop_t *prop,
     njs_bool_t shared)
 {
-    njs_int_t           ret;
-    njs_object_t        *global;
-    njs_lvlhsh_t        *hash;
-    njs_lvlhsh_query_t  lhq;
+    njs_int_t            ret;
+    njs_value_t          prop_name;
+    njs_object_t         *global;
+    njs_flathsh_t        *hash;
+    njs_flathsh_query_t  lhq;
 
-    ret = njs_string_create(vm, &prop->name, var_name->start, var_name->length);
+    ret = njs_atom_string_create(vm, &prop_name, var_name->start,
+                                 var_name->length);
     if (njs_slow_path(ret != NJS_OK)) {
         return NJS_ERROR;
     }
 
     lhq.value = prop;
-    lhq.key = *var_name;
-    lhq.key_hash = njs_djb_hash(lhq.key.start, lhq.key.length);
+    lhq.key_hash = prop_name.atom_id;
     lhq.replace = 1;
     lhq.pool = vm->mem_pool;
     lhq.proto = &njs_object_hash_proto;
@@ -920,7 +925,7 @@ njs_vm_bind2(njs_vm_t *vm, const njs_str_t *var_name, njs_object_prop_t *prop,
     global = &vm->global_object;
     hash = shared ? &global->shared_hash : &global->hash;
 
-    ret = njs_lvlhsh_insert(hash, &lhq);
+    ret = njs_flathsh_unique_insert(hash, &lhq);
     if (njs_slow_path(ret != NJS_OK)) {
         njs_internal_error(vm, "lvlhsh insert failed");
         return ret;
@@ -936,7 +941,7 @@ njs_vm_bind(njs_vm_t *vm, const njs_str_t *var_name, const njs_value_t *value,
 {
     njs_object_prop_t   *prop;
 
-    prop = njs_object_prop_alloc(vm, &njs_value_undefined, value, 1);
+    prop = njs_object_prop_alloc(vm, value, 1);
     if (njs_slow_path(prop == NULL)) {
         return NJS_ERROR;
     }
@@ -952,8 +957,7 @@ njs_vm_bind_handler(njs_vm_t *vm, const njs_str_t *var_name,
 {
     njs_object_prop_t  *prop;
 
-    prop = njs_object_prop_alloc(vm, &njs_string_empty,
-                                 &njs_value_invalid, 1);
+    prop = njs_object_prop_alloc(vm, &njs_value_invalid, 1);
     if (njs_slow_path(prop == NULL)) {
         return NJS_ERROR;
     }
@@ -970,9 +974,9 @@ njs_vm_bind_handler(njs_vm_t *vm, const njs_str_t *var_name,
 
 
 void
-njs_value_string_get(njs_value_t *value, njs_str_t *dst)
+njs_value_string_get(njs_vm_t *vm, njs_value_t *value, njs_str_t *dst)
 {
-    njs_string_get(value, dst);
+    njs_string_get(vm, value, dst);
 }
 
 
@@ -1050,13 +1054,21 @@ njs_vm_prop_magic32(njs_object_prop_t *prop)
 
 
 njs_int_t
-njs_vm_prop_name(njs_vm_t *vm, njs_object_prop_t *prop, njs_str_t *dst)
+njs_vm_prop_name(njs_vm_t *vm, uint32_t atom_id, njs_str_t *dst)
 {
-    if (njs_slow_path(!njs_is_string(&prop->name))) {
+    njs_int_t    ret;
+    njs_value_t  prop_name;
+
+    ret = njs_atom_to_value(vm, &prop_name, atom_id);
+    if (ret != NJS_OK) {
         return NJS_ERROR;
     }
 
-    njs_string_get(&prop->name, dst);
+    if (njs_slow_path(!njs_is_string(&prop_name))) {
+        return NJS_ERROR;
+    }
+
+    njs_string_get(vm, &prop_name, dst);
 
     return NJS_OK;
 }
@@ -1090,7 +1102,7 @@ njs_vm_value_string(njs_vm_t *vm, njs_str_t *dst, njs_value_t *src)
                       && njs_number(src) == 0
                       && signbit(njs_number(src))))
     {
-        njs_string_get(&njs_string_minus_zero, dst);
+        *dst = njs_str_value("-0");
         return NJS_OK;
     }
 
@@ -1134,22 +1146,18 @@ njs_value_t *
 njs_vm_value_enumerate(njs_vm_t *vm, njs_value_t *value, uint32_t flags,
     njs_value_t *retval)
 {
-    njs_int_t                ret;
-    njs_value_t              *val;
-    njs_array_t              *keys;
-    njs_rbtree_t             *variables;
-    njs_rbtree_node_t        *rb_node;
-    njs_variable_node_t      *node;
-    const njs_lexer_entry_t  *lex_entry;
-
-    static const njs_str_t  njs_this_str = njs_str("this");
+    njs_value_t          *val;
+    njs_array_t          *keys;
+    njs_rbtree_t         *variables;
+    njs_rbtree_node_t    *rb_node;
+    njs_variable_node_t  *node;
 
     keys = njs_value_enumerate(vm, value, flags);
     if (njs_slow_path(keys == NULL)) {
         return NULL;
     }
 
-    if (!njs_values_same(value, &vm->global_value)
+    if (!njs_values_same(vm, value, &vm->global_value)
         || vm->global_scope == NULL)
     {
         goto done;
@@ -1163,12 +1171,7 @@ njs_vm_value_enumerate(njs_vm_t *vm, njs_value_t *value, uint32_t flags,
     while (njs_rbtree_is_there_successor(variables, rb_node)) {
         node = (njs_variable_node_t *) rb_node;
 
-        lex_entry = njs_lexer_entry(node->variable->unique_id);
-        if (njs_slow_path(lex_entry == NULL)) {
-            return NULL;
-        }
-
-        if (njs_strstr_eq(&lex_entry->name, &njs_this_str)) {
+        if (node->variable->atom_id == NJS_ATOM_STRING_this) {
             rb_node = njs_rbtree_node_successor(variables, rb_node);
             continue;
         }
@@ -1178,11 +1181,7 @@ njs_vm_value_enumerate(njs_vm_t *vm, njs_value_t *value, uint32_t flags,
             return NULL;
         }
 
-        ret = njs_string_create(vm, val, lex_entry->name.start,
-                                lex_entry->name.length);
-        if (njs_slow_path(ret != NJS_OK)) {
-            return NULL;
-        }
+        njs_atom_to_value(vm, val, node->variable->atom_id);
 
         rb_node = njs_rbtree_node_successor(variables, rb_node);
     }
@@ -1215,12 +1214,12 @@ njs_vm_value_own_enumerate(njs_vm_t *vm, njs_value_t *value, uint32_t flags,
 njs_int_t
 njs_vm_object_alloc(njs_vm_t *vm, njs_value_t *retval, ...)
 {
-    va_list             args;
-    njs_int_t           ret;
-    njs_value_t         *name, *value;
-    njs_object_t        *object;
-    njs_object_prop_t   *prop;
-    njs_lvlhsh_query_t  lhq;
+    va_list              args;
+    njs_int_t            ret;
+    njs_value_t          *name, *value;
+    njs_object_t         *object;
+    njs_object_prop_t    *prop;
+    njs_flathsh_query_t  lhq;
 
     object = njs_object_alloc(vm);
     if (njs_slow_path(object == NULL)) {
@@ -1248,21 +1247,25 @@ njs_vm_object_alloc(njs_vm_t *vm, njs_value_t *retval, ...)
             goto done;
         }
 
-        lhq.replace = 0;
-        lhq.pool = vm->mem_pool;
-        lhq.proto = &njs_object_hash_proto;
-
-        njs_string_get(name, &lhq.key);
-        lhq.key_hash = njs_djb_hash(lhq.key.start, lhq.key.length);
-
-        prop = njs_object_prop_alloc(vm, name, value, 1);
+        prop = njs_object_prop_alloc(vm, value, 1);
         if (njs_slow_path(prop == NULL)) {
             goto done;
         }
 
+        if (name->atom_id == NJS_ATOM_STRING_unknown) {
+            ret = njs_atom_atomize_key(vm, name);
+            if (ret != NJS_OK) {
+                goto done;
+            }
+        }
+
         lhq.value = prop;
+        lhq.key_hash = name->atom_id;
+        lhq.replace = 0;
+        lhq.pool = vm->mem_pool;
+        lhq.proto = &njs_object_hash_proto;
 
-        ret = njs_lvlhsh_insert(&object->hash, &lhq);
+        ret = njs_flathsh_unique_insert(&object->hash, &lhq);
         if (njs_slow_path(ret != NJS_OK)) {
             njs_internal_error(vm, NULL);
             goto done;
@@ -1357,7 +1360,7 @@ njs_vm_object_prop(njs_vm_t *vm, njs_value_t *value, const njs_str_t *prop,
         return NULL;
     }
 
-    ret = njs_value_property(vm, value, &key, njs_value_arg(retval));
+    ret = njs_value_property_val(vm, value, &key, njs_value_arg(retval));
     if (njs_slow_path(ret != NJS_OK)) {
         return NULL;
     }
@@ -1378,12 +1381,13 @@ njs_vm_object_prop_set(njs_vm_t *vm, njs_value_t *value, const njs_str_t *prop,
         return NJS_ERROR;
     }
 
-    ret = njs_vm_value_string_create(vm, &key, prop->start, prop->length);
+    ret = njs_atom_string_create(vm, &key, prop->start, prop->length);
     if (njs_slow_path(ret != NJS_OK)) {
         return NJS_ERROR;
     }
 
-    ret = njs_value_property_set(vm, value, &key, njs_value_arg(setval));
+    ret = njs_value_property_set(vm, value, key.atom_id,
+                                 njs_value_arg(setval));
     if (njs_slow_path(ret != NJS_OK)) {
         return NJS_ERROR;
     }
@@ -1473,8 +1477,6 @@ njs_vm_date_alloc(njs_vm_t *vm, njs_value_t *retval, double time)
 njs_int_t
 njs_vm_value_to_string(njs_vm_t *vm, njs_str_t *dst, njs_value_t *src)
 {
-    u_char       *start;
-    size_t       size;
     njs_int_t    ret;
     njs_value_t  value, stack;
 
@@ -1484,7 +1486,7 @@ njs_vm_value_to_string(njs_vm_t *vm, njs_str_t *dst, njs_value_t *src)
 
     if (njs_is_error(src)) {
         if (njs_is_memory_error(vm, src)) {
-            njs_string_get(&njs_string_memory_error, dst);
+            *dst = njs_str_value("MemoryError");
             return NJS_OK;
         }
 
@@ -1503,24 +1505,7 @@ njs_vm_value_to_string(njs_vm_t *vm, njs_str_t *dst, njs_value_t *src)
     ret = njs_value_to_string(vm, &value, &value);
 
     if (njs_fast_path(ret == NJS_OK)) {
-        size = value.short_string.size;
-
-        if (size != NJS_STRING_LONG) {
-            start = njs_mp_alloc(vm->mem_pool, size);
-            if (njs_slow_path(start == NULL)) {
-                njs_memory_error(vm);
-                return NJS_ERROR;
-            }
-
-            memcpy(start, value.short_string.start, size);
-
-        } else {
-            size = value.long_string.size;
-            start = value.long_string.data->start;
-        }
-
-        dst->length = size;
-        dst->start = start;
+        njs_string_get(vm, &value, dst);
     }
 
     return ret;
@@ -1535,24 +1520,12 @@ njs_vm_value_to_string(njs_vm_t *vm, njs_str_t *dst, njs_value_t *src)
 const char *
 njs_vm_value_to_c_string(njs_vm_t *vm, njs_value_t *value)
 {
-    u_char  *p, *data, *start;
+    u_char  *p, *data;
     size_t  size;
 
     njs_assert(njs_is_string(value));
 
-    if (value->short_string.size != NJS_STRING_LONG) {
-        start = value->short_string.start;
-        size = value->short_string.size;
-
-        if (size < NJS_STRING_SHORT) {
-            start[size] = '\0';
-            return (const char *) start;
-        }
-
-    } else {
-        start = value->long_string.data->start;
-        size = value->long_string.size;
-    }
+    size = value->string.data->size;
 
     data = njs_mp_alloc(vm->mem_pool, size + njs_length("\0"));
     if (njs_slow_path(data == NULL)) {
@@ -1560,7 +1533,7 @@ njs_vm_value_to_c_string(njs_vm_t *vm, njs_value_t *value)
         return NULL;
     }
 
-    p = njs_cpymem(data, start, size);
+    p = njs_cpymem(data, value->string.data->start, size);
     *p++ = '\0';
 
     return (const char *) data;
@@ -1595,8 +1568,7 @@ njs_value_to_string(njs_vm_t *vm, njs_value_t *dst, njs_value_t *value)
 njs_int_t
 njs_vm_value_to_bytes(njs_vm_t *vm, njs_str_t *dst, njs_value_t *src)
 {
-    u_char              *start;
-    size_t              size, length, offset;
+    size_t              length, offset;
     njs_int_t           ret;
     njs_value_t         value;
     njs_typed_array_t   *array;
@@ -1647,24 +1619,8 @@ njs_vm_value_to_bytes(njs_vm_t *vm, njs_str_t *dst, njs_value_t *src)
             return NJS_ERROR;
         }
 
-        size = value.short_string.size;
-
-        if (size != NJS_STRING_LONG) {
-            start = njs_mp_alloc(vm->mem_pool, size);
-            if (njs_slow_path(start == NULL)) {
-                njs_memory_error(vm);
-                return NJS_ERROR;
-            }
-
-            memcpy(start, value.short_string.start, size);
-
-        } else {
-            size = value.long_string.size;
-            start = value.long_string.data->start;
-        }
-
-        dst->length = size;
-        dst->start = start;
+        dst->length = value.string.data->size;
+        dst->start = value.string.data->start;
     }
 
     return ret;
@@ -1672,9 +1628,10 @@ njs_vm_value_to_bytes(njs_vm_t *vm, njs_str_t *dst, njs_value_t *src)
 
 
 njs_int_t
-njs_vm_string_compare(const njs_value_t *v1, const njs_value_t *v2)
+njs_vm_string_compare(njs_vm_t *vm, const njs_value_t *v1,
+    const njs_value_t *v2)
 {
-    return njs_string_cmp(v1, v2);
+    return njs_string_cmp(vm, v1, v2);
 }
 
 
diff --git a/src/njs_vm.h b/src/njs_vm.h
index a3f2b5a9..3e21fdf2 100644
--- a/src/njs_vm.h
+++ b/src/njs_vm.h
@@ -128,7 +128,12 @@ struct njs_vm_s {
     njs_native_frame_t       *top_frame;
     njs_frame_t              *active_frame;
 
-    njs_lvlhsh_t             keywords_hash;
+    njs_lvlhsh_t             atom_hash_shared;
+    njs_lvlhsh_t             atom_hash;
+    njs_lvlhsh_t             *atom_hash_current;
+    uint32_t                 shared_atom_count;
+    uint32_t                 atom_id_generator;
+
     njs_lvlhsh_t             values_hash;
 
     njs_arr_t                *modules;
@@ -178,7 +183,6 @@ struct njs_vm_s {
     njs_random_t             random;
 
     njs_rbtree_t             global_symbols;
-    uint64_t                 symbol_generator;
 
     njs_module_loader_t      module_loader;
     void                     *module_loader_opaque;
@@ -203,21 +207,20 @@ typedef struct {
 
 
 struct njs_vm_shared_s {
-    njs_lvlhsh_t             keywords_hash;
     njs_lvlhsh_t             values_hash;
 
-    njs_lvlhsh_t             array_instance_hash;
-    njs_lvlhsh_t             string_instance_hash;
-    njs_lvlhsh_t             function_instance_hash;
-    njs_lvlhsh_t             async_function_instance_hash;
-    njs_lvlhsh_t             arrow_instance_hash;
-    njs_lvlhsh_t             arguments_object_instance_hash;
-    njs_lvlhsh_t             regexp_instance_hash;
+    njs_flathsh_t            array_instance_hash;
+    njs_flathsh_t            string_instance_hash;
+    njs_flathsh_t            function_instance_hash;
+    njs_flathsh_t            async_function_instance_hash;
+    njs_flathsh_t            arrow_instance_hash;
+    njs_flathsh_t            arguments_object_instance_hash;
+    njs_flathsh_t            regexp_instance_hash;
 
     size_t                   module_items;
     njs_lvlhsh_t             modules_hash;
 
-    njs_lvlhsh_t             env_hash;
+    njs_flathsh_t            env_hash;
 
     njs_object_t             string_object;
     njs_object_t             objects[NJS_OBJECT_MAX];
@@ -261,7 +264,7 @@ extern const njs_str_t    njs_entry_native;
 extern const njs_str_t    njs_entry_unknown;
 extern const njs_str_t    njs_entry_anonymous;
 
-extern const njs_lvlhsh_proto_t  njs_object_hash_proto;
+extern const njs_flathsh_proto_t  njs_object_hash_proto;
 
 
 #endif /* _NJS_VM_H_INCLUDED_ */
diff --git a/src/njs_vmcode.c b/src/njs_vmcode.c
index dbf7b116..07054f67 100644
--- a/src/njs_vmcode.c
+++ b/src/njs_vmcode.c
@@ -272,7 +272,22 @@ NEXT_LBL;
             value2 = &primitive1;
         }
 
-        ret = njs_value_property(vm, value1, value2, retval);
+        if (value2->atom_id == NJS_ATOM_STRING_unknown) {
+            num = njs_number(value2);
+            u32 = (uint32_t) num;
+
+            if (njs_fast_path(u32 == num && (u32 < 0x80000000))) {
+                value2->atom_id = njs_number_atom(u32);
+
+            } else {
+                ret = njs_atom_atomize_key(vm, value2);
+                if (njs_slow_path(ret != NJS_OK)) {
+                    goto error;
+                }
+            }
+        }
+
+        ret = njs_value_property(vm, value1, value2->atom_id, retval);
         if (njs_slow_path(ret == NJS_ERROR)) {
             goto error;
         }
@@ -397,7 +412,7 @@ NEXT_LBL;
         get = (njs_vmcode_prop_get_t *) pc;
         njs_vmcode_operand(vm, get->value, retval);
 
-        ret = njs_value_property(vm, value1, value2, retval);
+        ret = njs_value_property_val(vm, value1, value2, retval);
         if (njs_slow_path(ret == NJS_ERROR)) {
             goto error;
         }
@@ -921,7 +936,7 @@ NEXT_LBL;
             value2 = &primitive1;
         }
 
-        ret = njs_value_property_delete(vm, value1, value2, NULL, 1);
+        ret = njs_value_property_val_delete(vm, value1, value2, NULL, 1);
         if (njs_slow_path(ret == NJS_ERROR)) {
             goto error;
         }
@@ -951,7 +966,7 @@ NEXT_LBL;
         njs_vmcode_operand(vm, vmcode->operand3, value2);
         njs_vmcode_operand(vm, vmcode->operand2, value1);
 
-        ret = njs_values_strict_equal(value1, value2);
+        ret = njs_values_strict_equal(vm, value1, value2);
 
         njs_vmcode_operand(vm, vmcode->operand1, retval);
         njs_set_boolean(retval, ret);
@@ -965,7 +980,7 @@ NEXT_LBL;
         njs_vmcode_operand(vm, vmcode->operand3, value2);
         njs_vmcode_operand(vm, vmcode->operand2, value1);
 
-        ret = njs_values_strict_equal(value1, value2);
+        ret = njs_values_strict_equal(vm, value1, value2);
 
         njs_vmcode_operand(vm, vmcode->operand1, retval);
         njs_set_boolean(retval, !ret);
@@ -1255,7 +1270,22 @@ NEXT_LBL;
             value2 = &primitive2;
         }
 
-        ret = njs_value_property_set(vm, value1, value2, retval);
+        if (value2->atom_id == NJS_ATOM_STRING_unknown) {
+            num = njs_number(value2);
+            u32 = (uint32_t) num;
+
+            if (njs_fast_path(u32 == num && (u32 < 0x80000000))) {
+                value2->atom_id = njs_number_atom(u32);
+
+            } else {
+                ret = njs_atom_atomize_key(vm, value2);
+                if (njs_slow_path(ret != NJS_OK)) {
+                    goto error;
+                }
+            }
+        }
+
+        ret = njs_value_property_set(vm, value1, value2->atom_id, retval);
         if (njs_slow_path(ret == NJS_ERROR)) {
             goto error;
         }
@@ -1280,8 +1310,8 @@ NEXT_LBL;
             goto error;
         }
 
-        ret = njs_object_prop_define(vm, value1, &name, function,
-                                     accessor->type, 0);
+        ret = njs_object_prop_define_val(vm, value1, &name, function,
+                                         accessor->type);
         if (njs_slow_path(ret != NJS_OK)) {
             goto error;
         }
@@ -1321,7 +1351,7 @@ NEXT_LBL;
         njs_vmcode_operand(vm, vmcode->operand3, value2);
         njs_vmcode_operand(vm, vmcode->operand2, value1);
 
-        if (njs_values_strict_equal(value1, value2)) {
+        if (njs_values_strict_equal(vm, value1, value2)) {
             equal = (njs_vmcode_equal_jump_t *) pc;
             ret = equal->offset;
 
@@ -1411,7 +1441,7 @@ NEXT_LBL;
             value2 = &primitive1;
         }
 
-        ret = njs_value_property(vm, value1, value2, &dst);
+        ret = njs_value_property_val(vm, value1, value2, &dst);
         if (njs_slow_path(ret == NJS_ERROR)) {
             goto error;
         }
@@ -1946,6 +1976,7 @@ njs_vmcode_template_literal(njs_vm_t *vm, njs_value_t *retval)
 {
     njs_array_t     *array;
     njs_jump_off_t  ret;
+    njs_value_t     arguments[1];
 
     static const njs_function_t  concat = {
           .native = 1,
@@ -1956,7 +1987,9 @@ njs_vmcode_template_literal(njs_vm_t *vm, njs_value_t *retval)
 
     array = njs_array(retval);
 
-    ret = njs_function_call(vm, (njs_function_t *) &concat, &njs_string_empty,
+    njs_set_empty_string(vm, &arguments[0]);
+
+    ret = njs_function_call(vm, (njs_function_t *) &concat, &arguments[0],
                             array->start, array->length, retval);
     if (njs_slow_path(ret != NJS_OK)) {
         return ret;
@@ -1991,13 +2024,13 @@ static njs_jump_off_t
 njs_vmcode_property_init(njs_vm_t *vm, njs_value_t *value, njs_value_t *key,
     njs_value_t *init)
 {
-    double              num;
-    uint32_t            index, size;
-    njs_int_t           ret;
-    njs_array_t         *array;
-    njs_value_t         *val, name;
-    njs_object_prop_t   *prop;
-    njs_lvlhsh_query_t  lhq;
+    double               num;
+    uint32_t             index, size;
+    njs_int_t            ret;
+    njs_array_t          *array;
+    njs_value_t          *val, name;
+    njs_object_prop_t    *prop;
+    njs_flathsh_query_t  lhq;
 
     switch (value->type) {
     case NJS_ARRAY:
@@ -2035,24 +2068,39 @@ njs_vmcode_property_init(njs_vm_t *vm, njs_value_t *value, njs_value_t *key,
         break;
 
     case NJS_OBJECT:
+        if (key->type == NJS_STRING) {
+            if (key->atom_id == NJS_ATOM_STRING_unknown) {
+                ret = njs_atom_atomize_key(vm, key);
+                if (ret != NJS_OK) {
+                    return ret;
+                }
+            }
+        }
+
         ret = njs_value_to_key(vm, &name, key);
         if (njs_slow_path(ret != NJS_OK)) {
             return NJS_ERROR;
         }
 
-        njs_object_property_key_set(&lhq, &name, 0);
-        lhq.proto = &njs_object_hash_proto;
-        lhq.pool = vm->mem_pool;
+        if (name.atom_id == NJS_ATOM_STRING_unknown) {
+            ret = njs_atom_atomize_key(vm, &name);
+            if (ret != NJS_OK) {
+                return ret;
+            }
+        }
 
-        prop = njs_object_prop_alloc(vm, &name, init, 1);
+        prop = njs_object_prop_alloc(vm, init, 1);
         if (njs_slow_path(prop == NULL)) {
             return NJS_ERROR;
         }
 
         lhq.value = prop;
+        lhq.key_hash = name.atom_id;
         lhq.replace = 1;
+        lhq.pool = vm->mem_pool;
+        lhq.proto = &njs_object_hash_proto;
 
-        ret = njs_lvlhsh_insert(njs_object_hash(value), &lhq);
+        ret = njs_flathsh_unique_insert(njs_object_hash(value), &lhq);
         if (njs_slow_path(ret != NJS_OK)) {
             njs_internal_error(vm, "lvlhsh insert/replace failed");
             return NJS_ERROR;
@@ -2076,20 +2124,19 @@ static njs_jump_off_t
 njs_vmcode_proto_init(njs_vm_t *vm, njs_value_t *value, njs_value_t *unused,
     njs_value_t *init)
 {
-    njs_object_t        *obj;
-    njs_value_t         retval;
-    njs_jump_off_t      ret;
-    njs_object_prop_t   *prop;
-    njs_lvlhsh_query_t  lhq;
-
-    lhq.key = njs_str_value("__proto__");
-    lhq.key_hash = NJS___PROTO___HASH;
+    njs_object_t         *obj;
+    njs_value_t          retval;
+    njs_jump_off_t       ret;
+    njs_object_prop_t    *prop;
+    njs_flathsh_query_t  lhq;
+
+    lhq.key_hash = NJS_ATOM_STRING___proto__;
     lhq.proto = &njs_object_hash_proto;
     lhq.pool = vm->mem_pool;
 
     obj = njs_object(value);
 
-    ret = njs_lvlhsh_find(&obj->__proto__->shared_hash, &lhq);
+    ret = njs_flathsh_unique_find(&obj->__proto__->shared_hash, &lhq);
     if (njs_slow_path(ret != NJS_OK)) {
         goto fail;
     }
@@ -2100,7 +2147,7 @@ njs_vmcode_proto_init(njs_vm_t *vm, njs_value_t *value, njs_value_t *unused,
         goto fail;
     }
 
-    ret = njs_prop_handler(prop)(vm, prop, value, init, &retval);
+    ret = njs_prop_handler(prop)(vm, prop, lhq.key_hash, value, init, &retval);
     if (njs_slow_path(ret != NJS_OK)) {
         goto fail;
     }
@@ -2137,9 +2184,9 @@ njs_vmcode_property_in(njs_vm_t *vm, njs_value_t *value, njs_value_t *key,
         key = &primitive;
     }
 
-    njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0, 0);
+    njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0);
 
-    ret = njs_property_query(vm, &pq, value, key);
+    ret = njs_property_query_val(vm, &pq, value, key);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return ret;
     }
@@ -2190,8 +2237,6 @@ njs_vmcode_instance_of(njs_vm_t *vm, njs_value_t *object,
     njs_function_t  *function;
     njs_jump_off_t  ret;
 
-    static const njs_value_t prototype_string = njs_string("prototype");
-
     if (!njs_is_function(constructor)) {
         njs_type_error(vm, "right argument is not callable");
         return NJS_ERROR;
@@ -2206,8 +2251,8 @@ njs_vmcode_instance_of(njs_vm_t *vm, njs_value_t *object,
     }
 
     if (njs_is_object(object)) {
-        ret = njs_value_property(vm, constructor,
-                                 njs_value_arg(&prototype_string), &value);
+        ret = njs_value_property(vm, constructor, NJS_ATOM_STRING_prototype,
+                                 &value);
 
         if (njs_slow_path(ret == NJS_ERROR)) {
             return ret;
@@ -2246,37 +2291,37 @@ njs_vmcode_typeof(njs_vm_t *vm, njs_value_t *value, njs_value_t *retval)
 {
     /* ECMAScript 5.1: null, array and regexp are objects. */
 
-    static const njs_value_t  *types[NJS_VALUE_TYPE_MAX] = {
-        &njs_string_object,
-        &njs_string_undefined,
-        &njs_string_boolean,
-        &njs_string_number,
-        &njs_string_symbol,
-        &njs_string_string,
-        &njs_string_data,
-        &njs_string_external,
-        &njs_string_invalid,
-        &njs_string_undefined,
-        &njs_string_undefined,
-        &njs_string_undefined,
-        &njs_string_undefined,
-        &njs_string_undefined,
-        &njs_string_undefined,
-        &njs_string_undefined,
-
-        &njs_string_object,
-        &njs_string_object,
-        &njs_string_function,
-        &njs_string_object,
-        &njs_string_object,
-        &njs_string_object,
-        &njs_string_object,
-        &njs_string_object,
-        &njs_string_object,
-        &njs_string_object,
+    static const uint32_t  types[NJS_VALUE_TYPE_MAX] = {
+        NJS_ATOM_STRING_object,
+        NJS_ATOM_STRING_undefined,
+        NJS_ATOM_STRING_boolean,
+        NJS_ATOM_STRING_number,
+        NJS_ATOM_STRING_symbol,
+        NJS_ATOM_STRING_string,
+        NJS_ATOM_STRING_data,
+        NJS_ATOM_STRING_external,
+        NJS_ATOM_STRING_unknown,
+        NJS_ATOM_STRING_undefined,
+        NJS_ATOM_STRING_undefined,
+        NJS_ATOM_STRING_undefined,
+        NJS_ATOM_STRING_undefined,
+        NJS_ATOM_STRING_undefined,
+        NJS_ATOM_STRING_undefined,
+        NJS_ATOM_STRING_undefined,
+
+        NJS_ATOM_STRING_object,
+        NJS_ATOM_STRING_object,
+        NJS_ATOM_STRING_function,
+        NJS_ATOM_STRING_object,
+        NJS_ATOM_STRING_object,
+        NJS_ATOM_STRING_object,
+        NJS_ATOM_STRING_object,
+        NJS_ATOM_STRING_object,
+        NJS_ATOM_STRING_object,
+        NJS_ATOM_STRING_object,
     };
 
-    njs_value_assign(retval, types[value->type]);
+    njs_atom_to_value(vm, retval, types[value->type]);
 
     return sizeof(njs_vmcode_2addr_t);
 }
@@ -2314,8 +2359,8 @@ njs_string_concat(njs_vm_t *vm, njs_value_t *val1, njs_value_t *val2,
     size_t             size, length;
     njs_string_prop_t  string1, string2;
 
-    (void) njs_string_prop(&string1, val1);
-    (void) njs_string_prop(&string2, val2);
+    (void) njs_string_prop(vm, &string1, val1);
+    (void) njs_string_prop(vm, &string2, val2);
 
     length = string1.length + string2.length;
     size = string1.size + string2.size;
@@ -2358,7 +2403,7 @@ again:
     if (val1->type == val2->type) {
 
         if (njs_is_string(val1)) {
-            return njs_string_eq(val1, val2);
+            return njs_string_eq(vm, val1, val2);
         }
 
         if (njs_is_symbol(val1)) {
@@ -2392,7 +2437,7 @@ again:
     /* If "hv" is a string then "lv" can be a numeric or symbol. */
     if (njs_is_string(hv)) {
         return !njs_is_symbol(lv)
-            && (njs_number(lv) == njs_string_to_number(hv));
+            && (njs_number(lv) == njs_string_to_number(vm, hv));
     }
 
     /* "hv" is an object and "lv" is either a string or a symbol or a numeric. */
@@ -2429,15 +2474,15 @@ njs_primitive_values_compare(njs_vm_t *vm, njs_value_t *val1, njs_value_t *val2)
             num2 = njs_number(val2);
 
         } else {
-            num2 = njs_string_to_number(val2);
+            num2 = njs_string_to_number(vm, val2);
         }
 
     } else if (njs_is_numeric(val2)) {
-        num1 = njs_string_to_number(val1);
+        num1 = njs_string_to_number(vm, val1);
         num2 = njs_number(val2);
 
     } else {
-        return (njs_string_cmp(val1, val2) < 0) ? 1 : 0;
+        return (njs_string_cmp(vm, val1, val2) < 0) ? 1 : 0;
     }
 
     /* NaN and void values are not comparable with anything. */
@@ -2521,8 +2566,6 @@ njs_function_new_object(njs_vm_t *vm, njs_value_t *constructor)
     njs_function_t  *function;
     njs_jump_off_t  ret;
 
-    const njs_value_t prototype_string = njs_string("prototype");
-
     object = njs_object_alloc(vm);
     if (njs_slow_path(object == NULL)) {
         return NULL;
@@ -2538,8 +2581,7 @@ njs_function_new_object(njs_vm_t *vm, njs_value_t *constructor)
         constructor = &bound;
     }
 
-    ret = njs_value_property(vm, constructor, njs_value_arg(&prototype_string),
-                             &proto);
+    ret = njs_value_property(vm, constructor, NJS_ATOM_STRING_prototype, &proto);
 
     if (njs_slow_path(ret == NJS_ERROR)) {
         return NULL;
diff --git a/src/test/njs_benchmark.c b/src/test/njs_benchmark.c
index 66c4e84b..7f1a7400 100644
--- a/src/test/njs_benchmark.c
+++ b/src/test/njs_benchmark.c
@@ -728,9 +728,9 @@ njs_benchmark_string(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_str_t           s, mode;
     njs_opaque_value_t  value;
 
-    njs_value_string_get(njs_arg(args, nargs, 1), &mode);
+    njs_value_string_get(vm, njs_arg(args, nargs, 1), &mode);
 
-    njs_value_string_get(njs_arg(args, nargs, 2), &s);
+    njs_value_string_get(vm, njs_arg(args, nargs, 2), &s);
 
     if (njs_value_to_integer(vm, njs_arg(args, nargs, 3), &n) != NJS_OK) {
         return NJS_ERROR;
diff --git a/src/test/njs_externals_test.c b/src/test/njs_externals_test.c
index 33f0020a..8d71aae7 100644
--- a/src/test/njs_externals_test.c
+++ b/src/test/njs_externals_test.c
@@ -146,7 +146,7 @@ lvlhsh_unit_test_add(njs_mp_t *pool, njs_unit_test_req_t *r,
 
 
 static njs_int_t
-njs_unit_test_r_uri(njs_vm_t *vm, njs_object_prop_t *prop,
+njs_unit_test_r_uri(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     char       *p;
@@ -169,8 +169,8 @@ njs_unit_test_r_uri(njs_vm_t *vm, njs_object_prop_t *prop,
 
 
 static njs_int_t
-njs_unit_test_r_a(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *unused, njs_value_t *retval)
+njs_unit_test_r_a(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
+    njs_value_t *value, njs_value_t *unused2, njs_value_t *retval)
 {
     u_char               *p;
     njs_unit_test_req_t  *r;
@@ -189,8 +189,8 @@ njs_unit_test_r_a(njs_vm_t *vm, njs_object_prop_t *prop,
 
 
 static njs_int_t
-njs_unit_test_r_b(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *unused, njs_value_t *retval)
+njs_unit_test_r_b(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
+    njs_value_t *value, njs_value_t *unused2, njs_value_t *retval)
 {
     njs_value_number_set(retval, njs_vm_prop_magic32(prop));
 
@@ -199,8 +199,8 @@ njs_unit_test_r_b(njs_vm_t *vm, njs_object_prop_t *prop,
 
 
 static njs_int_t
-njs_unit_test_r_d(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *unused, njs_value_t *retval)
+njs_unit_test_r_d(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
+    njs_value_t *value, njs_value_t *unused2, njs_value_t *retval)
 {
     njs_unit_test_req_t  *r;
 
@@ -217,7 +217,7 @@ njs_unit_test_r_d(njs_vm_t *vm, njs_object_prop_t *prop,
 
 
 static njs_int_t
-njs_unit_test_r_host(njs_vm_t *vm, njs_object_prop_t *prop,
+njs_unit_test_r_host(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     return njs_vm_value_string_create(vm, retval, (u_char *) "АБВГДЕЁЖЗИЙ", 22);
@@ -225,7 +225,7 @@ njs_unit_test_r_host(njs_vm_t *vm, njs_object_prop_t *prop,
 
 
 static njs_int_t
-njs_unit_test_r_buffer(njs_vm_t *vm, njs_object_prop_t *prop,
+njs_unit_test_r_buffer(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     return njs_vm_value_buffer_set(vm, retval, (u_char *) "АБВГДЕЁЖЗИЙ", 22);
@@ -233,7 +233,7 @@ njs_unit_test_r_buffer(njs_vm_t *vm, njs_object_prop_t *prop,
 
 
 static njs_int_t
-njs_unit_test_r_vars(njs_vm_t *vm, njs_object_prop_t *self,
+njs_unit_test_r_vars(njs_vm_t *vm, njs_object_prop_t *self, uint32_t atom_id,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     njs_int_t             ret;
@@ -247,7 +247,7 @@ njs_unit_test_r_vars(njs_vm_t *vm, njs_object_prop_t *self,
         return NJS_DECLINED;
     }
 
-    ret = njs_vm_prop_name(vm, self, &lhq.key);
+    ret = njs_vm_prop_name(vm, atom_id, &lhq.key);
     if (ret != NJS_OK) {
         if (setval == NULL && retval != NULL) {
             /* Get. */
@@ -314,14 +314,14 @@ njs_unit_test_r_vars(njs_vm_t *vm, njs_object_prop_t *self,
 
 
 static njs_int_t
-njs_unit_test_r_header(njs_vm_t *vm, njs_object_prop_t *prop,
+njs_unit_test_r_header(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t atom_id,
     njs_value_t *value, njs_value_t *unused, njs_value_t *retval)
 {
     njs_int_t  ret;
     njs_str_t  h;
     njs_chb_t  chain;
 
-    ret = njs_vm_prop_name(vm, prop, &h);
+    ret = njs_vm_prop_name(vm, atom_id, &h);
     if (ret == NJS_OK) {
         NJS_CHB_MP_INIT(&chain, njs_vm_memory_pool(vm));
 
@@ -640,7 +640,7 @@ njs_unit_test_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 
 static njs_int_t
-njs_unit_test_error_name(njs_vm_t *vm, njs_object_prop_t *prop,
+njs_unit_test_error_name(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
 {
     return njs_vm_value_string_create(vm, retval, (u_char *) "ExternalError",
@@ -650,7 +650,8 @@ njs_unit_test_error_name(njs_vm_t *vm, njs_object_prop_t *prop,
 
 static njs_int_t
 njs_unit_test_error_message(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+    uint32_t unused, njs_value_t *value, njs_value_t *setval,
+    njs_value_t *retval)
 {
     return njs_vm_value_string_create(vm, retval, (u_char *) "", 0);
 }
diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c
index 9c935e5b..cc1cc4c9 100644
--- a/src/test/njs_unit_test.c
+++ b/src/test/njs_unit_test.c
@@ -4172,6 +4172,11 @@ static njs_unit_test_t  njs_test[] =
     { njs_str("var a = [ 1, 2, 3 ]; a[4294967296] = 4; a + a[4294967296]"),
       njs_str("1,2,34") },
 
+    { njs_str("var x = []; var k = 1;"
+              "for (var i = 0; i < 32; i++) { k = k * 2; x[k - 2] = k; };"
+              "k = 1; for (i = 0; i < 32; i++) { k = k * 2; if (x[k - 2] != k) { throw 'error'; } }"),
+      njs_str("undefined") },
+
     { njs_str("delete[]['4e9']"),
       njs_str("true") },
 
@@ -5880,6 +5885,11 @@ static njs_unit_test_t  njs_test[] =
               "           return njs.dump(a) === `${v.name} [1,1,1]`})"),
       njs_str("true") },
 
+    { njs_str(NJS_TYPED_ARRAY_LIST
+              ".every(v=>{var a = new v([0]); var desc = Object.getOwnPropertyDescriptor(a, '0');"
+              "           try { Object.defineProperty(a, '1', desc) } catch (e) { return e.name == 'TypeError' }})"),
+      njs_str("true") },
+
     { njs_str(NJS_TYPED_ARRAY_LIST
               ".every(v=>{try {var a = new v([1,1]); Object.defineProperty(a, '1', {configurable:true})} "
               "           catch (e) { return e.message == 'Cannot redefine property: \"1\"'}})"),
@@ -14324,6 +14334,9 @@ static njs_unit_test_t  njs_test[] =
     { njs_str("Object.prototype.toString.call()"),
       njs_str("[object Undefined]") },
 
+    { njs_str("Object.prototype.toString.call().length"),
+      njs_str("18") },
+
     { njs_str("Object.prototype.toString.call(undefined)"),
       njs_str("[object Undefined]") },
 


More information about the nginx-devel mailing list