]> git.kaiwu.me - njs.git/commitdiff
FS: module is rewritten using public API.
authorDmitry Volyntsev <xeioex@nginx.com>
Wed, 3 May 2023 03:50:55 +0000 (20:50 -0700)
committerDmitry Volyntsev <xeioex@nginx.com>
Wed, 3 May 2023 03:50:55 +0000 (20:50 -0700)
external/njs_fs_module.c
src/njs.h
src/njs_value.c
src/njs_value_conversion.h
src/njs_vm.c
src/test/njs_unit_test.c
test/fs/methods.t.js
test/fs/promises_07.t.js

index b9df95c65d19501ba159950d20afbd212306ee0d..9ae1b7c7bbee242020e22a7b16daf806ea8f1155 100644 (file)
@@ -5,9 +5,11 @@
  */
 
 
-#include <njs_main.h>
-
+#include <njs.h>
+#include <njs_utils.h>
+#include <njs_buffer.h>
 #include <dirent.h>
+#include <njs_unix.h>
 
 #if (NJS_SOLARIS)
 
@@ -133,8 +135,8 @@ typedef struct {
 
 
 typedef struct {
-    njs_int_t       bytes;
-    njs_value_t     buffer;
+    njs_int_t           bytes;
+    njs_opaque_value_t  buffer;
 } njs_bytes_struct_t;
 
 
@@ -173,10 +175,8 @@ static njs_int_t njs_fs_write(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 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_constants(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *unused, njs_value_t *retval);
-static njs_int_t njs_fs_promises(njs_vm_t *vm, njs_object_prop_t *prop,
-    njs_value_t *value, njs_value_t *unused, 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);
 
 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);
@@ -195,18 +195,18 @@ static njs_int_t njs_fs_filehandle_close(njs_vm_t *vm, njs_value_t *args,
 static njs_int_t njs_fs_filehandle_value_of(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_fs_filehandle_create(njs_vm_t *vm, int fd,
-    njs_bool_t shadow, njs_value_t *retval);
+    njs_bool_t shadow, njs_opaque_value_t *retval);
 
 static njs_int_t njs_fs_bytes_read_create(njs_vm_t *vm, int bytes,
-    njs_value_t *buffer, njs_value_t *retval);
+    njs_value_t *buffer, njs_opaque_value_t *retval);
 static njs_int_t njs_fs_bytes_written_create(njs_vm_t *vm, int bytes,
-    njs_value_t *buffer, njs_value_t *retval);
+    njs_value_t *buffer, njs_opaque_value_t *retval);
 
 static njs_int_t njs_fs_fd_read(njs_vm_t *vm, int fd, njs_str_t *data);
 
 static njs_int_t njs_fs_error(njs_vm_t *vm, const char *syscall,
-    const char *desc, const char *path, int errn, njs_value_t *result);
-static njs_int_t njs_fs_result(njs_vm_t *vm, njs_value_t *result,
+    const char *desc, const char *path, int errn, njs_opaque_value_t *result);
+static njs_int_t njs_fs_result(njs_vm_t *vm, njs_opaque_value_t *result,
     njs_index_t calltype, const njs_value_t* callback, njs_uint_t nargs,
     njs_value_t *retval);
 
@@ -214,19 +214,16 @@ static njs_int_t njs_file_tree_walk(const char *path,
     njs_file_tree_walk_cb_t cb, int fd_limit, njs_ftw_flags_t flags);
 
 static njs_int_t njs_fs_make_path(njs_vm_t *vm, char *path, mode_t md,
-    njs_bool_t recursive, njs_value_t *retval);
+    njs_bool_t recursive, njs_opaque_value_t *retval);
 static njs_int_t njs_fs_rmtree(njs_vm_t *vm, const char *path,
-    njs_bool_t recursive, njs_value_t *retval);
+    njs_bool_t recursive, njs_opaque_value_t *retval);
 
 static const char *njs_fs_path(njs_vm_t *vm, char storage[NJS_MAX_PATH + 1],
-    const njs_value_t *src, const char *prop_name);
+    njs_value_t *src, const char *prop_name);
 static int njs_fs_flags(njs_vm_t *vm, njs_value_t *value, int default_flags);
 static mode_t njs_fs_mode(njs_vm_t *vm, njs_value_t *value,
     mode_t default_mode);
 
-static njs_int_t njs_fs_add_event(njs_vm_t *vm, const njs_value_t *callback,
-    const njs_value_t *args, njs_uint_t nargs);
-
 static njs_int_t njs_fs_dirent_create(njs_vm_t *vm, njs_value_t *name,
     njs_value_t *type, njs_value_t *retval);
 
@@ -234,11 +231,11 @@ static njs_int_t njs_fs_dirent_create(njs_vm_t *vm, njs_value_t *name,
 static njs_int_t njs_fs_init(njs_vm_t *vm);
 
 
-static const njs_value_t  string_flag = njs_string("flag");
-static const njs_value_t  string_mode = njs_string("mode");
-static const njs_value_t  string_buffer = njs_string("buffer");
-static const njs_value_t  string_encoding = njs_string("encoding");
-static const njs_value_t  string_recursive = njs_string("recursive");
+static const njs_str_t  string_flag = njs_str("flag");
+static const njs_str_t  string_mode = njs_str("mode");
+static const njs_str_t  string_buffer = njs_str("buffer");
+static const njs_str_t  string_encoding = njs_str("encoding");
+static const njs_str_t  string_recursive = njs_str("recursive");
 
 
 static njs_fs_entry_t njs_flags_table[] = {
@@ -259,6 +256,243 @@ static njs_fs_entry_t njs_flags_table[] = {
 };
 
 
+static njs_external_t  njs_ext_fs_constants[] = {
+
+    {
+        .flags = NJS_EXTERN_PROPERTY,
+        .name.string = njs_str("F_OK"),
+        .enumerable = 1,
+        .u.property = {
+            .handler = njs_fs_constant,
+            .magic32 = F_OK,
+        }
+    },
+
+    {
+        .flags = NJS_EXTERN_PROPERTY,
+        .name.string = njs_str("R_OK"),
+        .enumerable = 1,
+        .u.property = {
+            .handler = njs_fs_constant,
+            .magic32 = R_OK,
+        }
+    },
+
+    {
+        .flags = NJS_EXTERN_PROPERTY,
+        .name.string = njs_str("W_OK"),
+        .enumerable = 1,
+        .u.property = {
+            .handler = njs_fs_constant,
+            .magic32 = W_OK,
+        }
+    },
+
+    {
+        .flags = NJS_EXTERN_PROPERTY,
+        .name.string = njs_str("X_OK"),
+        .enumerable = 1,
+        .u.property = {
+            .handler = njs_fs_constant,
+            .magic32 = X_OK,
+        }
+    },
+
+};
+
+
+static njs_external_t  njs_ext_fs_promises[] = {
+
+    {
+        .flags = NJS_EXTERN_METHOD,
+        .name.string = njs_str("access"),
+        .writable = 1,
+        .configurable = 1,
+        .u.method = {
+            .native = njs_fs_access,
+            .magic8 = NJS_FS_PROMISE,
+        }
+    },
+
+    {
+        .flags = NJS_EXTERN_METHOD,
+        .name.string = njs_str("appendFile"),
+        .writable = 1,
+        .configurable = 1,
+        .u.method = {
+            .native = njs_fs_write_file,
+            .magic8 = njs_fs_magic(NJS_FS_PROMISE, NJS_FS_APPEND),
+        }
+    },
+
+    {
+        .flags = NJS_EXTERN_METHOD,
+        .name.string = njs_str("close"),
+        .writable = 1,
+        .configurable = 1,
+        .u.method = {
+            .native = njs_fs_close,
+            .magic8 = NJS_FS_PROMISE,
+        }
+    },
+
+    {
+        .flags = NJS_EXTERN_METHOD,
+        .name.string = njs_str("fstat"),
+        .writable = 1,
+        .configurable = 1,
+        .u.method = {
+            .native = njs_fs_stat,
+            .magic8 = njs_fs_magic(NJS_FS_PROMISE, NJS_FS_FSTAT),
+        }
+    },
+
+    {
+        .flags = NJS_EXTERN_METHOD,
+        .name.string = njs_str("mkdir"),
+        .writable = 1,
+        .configurable = 1,
+        .u.method = {
+            .native = njs_fs_mkdir,
+            .magic8 = NJS_FS_PROMISE,
+        }
+    },
+
+    {
+        .flags = NJS_EXTERN_METHOD,
+        .name.string = njs_str("lstat"),
+        .writable = 1,
+        .configurable = 1,
+        .u.method = {
+            .native = njs_fs_stat,
+            .magic8 = njs_fs_magic(NJS_FS_PROMISE, NJS_FS_LSTAT),
+        }
+    },
+
+    {
+        .flags = NJS_EXTERN_METHOD,
+        .name.string = njs_str("open"),
+        .writable = 1,
+        .configurable = 1,
+        .u.method = {
+            .native = njs_fs_open,
+            .magic8 = NJS_FS_PROMISE,
+        }
+    },
+
+    {
+        .flags = NJS_EXTERN_METHOD,
+        .name.string = njs_str("readFile"),
+        .writable = 1,
+        .configurable = 1,
+        .u.method = {
+            .native = njs_fs_read_file,
+            .magic8 = NJS_FS_PROMISE,
+        }
+    },
+
+    {
+        .flags = NJS_EXTERN_METHOD,
+        .name.string = njs_str("readSync"),
+        .writable = 1,
+        .configurable = 1,
+        .u.method = {
+            .native = njs_fs_read,
+            .magic8 = NJS_FS_PROMISE,
+        }
+    },
+
+    {
+        .flags = NJS_EXTERN_METHOD,
+        .name.string = njs_str("readdir"),
+        .writable = 1,
+        .configurable = 1,
+        .u.method = {
+            .native = njs_fs_readdir,
+            .magic8 = NJS_FS_PROMISE,
+        }
+    },
+
+    {
+        .flags = NJS_EXTERN_METHOD,
+        .name.string = njs_str("realpath"),
+        .writable = 1,
+        .configurable = 1,
+        .u.method = {
+            .native = njs_fs_realpath,
+            .magic8 = NJS_FS_PROMISE,
+        }
+    },
+
+    {
+        .flags = NJS_EXTERN_METHOD,
+        .name.string = njs_str("rename"),
+        .writable = 1,
+        .configurable = 1,
+        .u.method = {
+            .native = njs_fs_rename,
+            .magic8 = NJS_FS_PROMISE,
+        }
+    },
+
+    {
+        .flags = NJS_EXTERN_METHOD,
+        .name.string = njs_str("rmdir"),
+        .writable = 1,
+        .configurable = 1,
+        .u.method = {
+            .native = njs_fs_rmdir,
+            .magic8 = NJS_FS_PROMISE,
+        }
+    },
+
+    {
+        .flags = NJS_EXTERN_METHOD,
+        .name.string = njs_str("stat"),
+        .writable = 1,
+        .configurable = 1,
+        .u.method = {
+            .native = njs_fs_stat,
+            .magic8 = njs_fs_magic(NJS_FS_PROMISE, NJS_FS_STAT),
+        }
+    },
+
+    {
+        .flags = NJS_EXTERN_METHOD,
+        .name.string = njs_str("symlink"),
+        .writable = 1,
+        .configurable = 1,
+        .u.method = {
+            .native = njs_fs_symlink,
+            .magic8 = NJS_FS_PROMISE,
+        }
+    },
+
+    {
+        .flags = NJS_EXTERN_METHOD,
+        .name.string = njs_str("unlink"),
+        .writable = 1,
+        .configurable = 1,
+        .u.method = {
+            .native = njs_fs_unlink,
+            .magic8 = NJS_FS_PROMISE,
+        }
+    },
+
+    {
+        .flags = NJS_EXTERN_METHOD,
+        .name.string = njs_str("writeFile"),
+        .writable = 1,
+        .configurable = 1,
+        .u.method = {
+            .native = njs_fs_write_file,
+            .magic8 = njs_fs_magic(NJS_FS_PROMISE, NJS_FS_TRUNC),
+        }
+    },
+
+};
+
+
 static njs_external_t  njs_ext_fs[] = {
 
     {
@@ -325,11 +559,14 @@ static njs_external_t  njs_ext_fs[] = {
     },
 
     {
-        .flags = NJS_EXTERN_PROPERTY,
+        .flags = NJS_EXTERN_OBJECT,
         .name.string = njs_str("constants"),
+        .writable = 1,
         .enumerable = 1,
-        .u.property = {
-            .handler = njs_fs_constants,
+        .configurable = 1,
+        .u.object = {
+            .properties = njs_ext_fs_constants,
+            .nproperties = njs_nitems(njs_ext_fs_constants),
         }
     },
 
@@ -411,11 +648,14 @@ static njs_external_t  njs_ext_fs[] = {
     },
 
     {
-        .flags = NJS_EXTERN_PROPERTY,
+        .flags = NJS_EXTERN_OBJECT,
         .name.string = njs_str("promises"),
+        .writable = 1,
         .enumerable = 1,
-        .u.property = {
-            .handler = njs_fs_promises,
+        .configurable = 1,
+        .u.object = {
+            .properties = njs_ext_fs_promises,
+            .nproperties = njs_nitems(njs_ext_fs_promises),
         }
     },
 
@@ -757,7 +997,7 @@ static njs_external_t  njs_ext_stats[] = {
         .enumerable = 1,
         .u.property = {
             .handler = njs_fs_stats_prop,
-            .magic32 = njs_fs_magic2(NJS_FS_STAT_ATIME, NJS_DATE),
+            .magic32 = njs_fs_magic2(NJS_FS_STAT_ATIME, 1),
         }
     },
 
@@ -767,7 +1007,7 @@ static njs_external_t  njs_ext_stats[] = {
         .enumerable = 1,
         .u.property = {
             .handler = njs_fs_stats_prop,
-            .magic32 = njs_fs_magic2(NJS_FS_STAT_ATIME, NJS_NUMBER),
+            .magic32 = njs_fs_magic2(NJS_FS_STAT_ATIME, 0),
         }
     },
 
@@ -777,7 +1017,7 @@ static njs_external_t  njs_ext_stats[] = {
         .enumerable = 1,
         .u.property = {
             .handler = njs_fs_stats_prop,
-            .magic32 = njs_fs_magic2(NJS_FS_STAT_BIRTHTIME, NJS_DATE),
+            .magic32 = njs_fs_magic2(NJS_FS_STAT_BIRTHTIME, 1),
         }
     },
 
@@ -787,7 +1027,7 @@ static njs_external_t  njs_ext_stats[] = {
         .enumerable = 1,
         .u.property = {
             .handler = njs_fs_stats_prop,
-            .magic32 = njs_fs_magic2(NJS_FS_STAT_BIRTHTIME, NJS_NUMBER),
+            .magic32 = njs_fs_magic2(NJS_FS_STAT_BIRTHTIME, 0),
         }
     },
 
@@ -797,7 +1037,7 @@ static njs_external_t  njs_ext_stats[] = {
         .enumerable = 1,
         .u.property = {
             .handler = njs_fs_stats_prop,
-            .magic32 = njs_fs_magic2(NJS_FS_STAT_CTIME, NJS_DATE),
+            .magic32 = njs_fs_magic2(NJS_FS_STAT_CTIME, 1),
         }
     },
 
@@ -807,7 +1047,7 @@ static njs_external_t  njs_ext_stats[] = {
         .enumerable = 1,
         .u.property = {
             .handler = njs_fs_stats_prop,
-            .magic32 = njs_fs_magic2(NJS_FS_STAT_CTIME, NJS_NUMBER),
+            .magic32 = njs_fs_magic2(NJS_FS_STAT_CTIME, 0),
         }
     },
 
@@ -817,7 +1057,7 @@ static njs_external_t  njs_ext_stats[] = {
         .enumerable = 1,
         .u.property = {
             .handler = njs_fs_stats_prop,
-            .magic32 = njs_fs_magic2(NJS_FS_STAT_BLKSIZE, NJS_NUMBER),
+            .magic32 = njs_fs_magic2(NJS_FS_STAT_BLKSIZE, 0),
         }
     },
 
@@ -827,7 +1067,7 @@ static njs_external_t  njs_ext_stats[] = {
         .enumerable = 1,
         .u.property = {
             .handler = njs_fs_stats_prop,
-            .magic32 = njs_fs_magic2(NJS_FS_STAT_BLOCKS, NJS_NUMBER),
+            .magic32 = njs_fs_magic2(NJS_FS_STAT_BLOCKS, 0),
         }
     },
 
@@ -837,7 +1077,7 @@ static njs_external_t  njs_ext_stats[] = {
         .enumerable = 1,
         .u.property = {
             .handler = njs_fs_stats_prop,
-            .magic32 = njs_fs_magic2(NJS_FS_STAT_DEV, NJS_NUMBER),
+            .magic32 = njs_fs_magic2(NJS_FS_STAT_DEV, 0),
         }
     },
 
@@ -847,7 +1087,7 @@ static njs_external_t  njs_ext_stats[] = {
         .enumerable = 1,
         .u.property = {
             .handler = njs_fs_stats_prop,
-            .magic32 = njs_fs_magic2(NJS_FS_STAT_GID, NJS_NUMBER),
+            .magic32 = njs_fs_magic2(NJS_FS_STAT_GID, 0),
         }
     },
 
@@ -857,7 +1097,7 @@ static njs_external_t  njs_ext_stats[] = {
         .enumerable = 1,
         .u.property = {
             .handler = njs_fs_stats_prop,
-            .magic32 = njs_fs_magic2(NJS_FS_STAT_INO, NJS_NUMBER),
+            .magic32 = njs_fs_magic2(NJS_FS_STAT_INO, 0),
         }
     },
 
@@ -867,7 +1107,7 @@ static njs_external_t  njs_ext_stats[] = {
         .enumerable = 1,
         .u.property = {
             .handler = njs_fs_stats_prop,
-            .magic32 = njs_fs_magic2(NJS_FS_STAT_MODE, NJS_NUMBER),
+            .magic32 = njs_fs_magic2(NJS_FS_STAT_MODE, 0),
         }
     },
 
@@ -877,7 +1117,7 @@ static njs_external_t  njs_ext_stats[] = {
         .enumerable = 1,
         .u.property = {
             .handler = njs_fs_stats_prop,
-            .magic32 = njs_fs_magic2(NJS_FS_STAT_MTIME, NJS_DATE),
+            .magic32 = njs_fs_magic2(NJS_FS_STAT_MTIME, 1),
         }
     },
 
@@ -887,7 +1127,7 @@ static njs_external_t  njs_ext_stats[] = {
         .enumerable = 1,
         .u.property = {
             .handler = njs_fs_stats_prop,
-            .magic32 = njs_fs_magic2(NJS_FS_STAT_MTIME, NJS_NUMBER),
+            .magic32 = njs_fs_magic2(NJS_FS_STAT_MTIME, 0),
         }
     },
 
@@ -897,7 +1137,7 @@ static njs_external_t  njs_ext_stats[] = {
         .enumerable = 1,
         .u.property = {
             .handler = njs_fs_stats_prop,
-            .magic32 = njs_fs_magic2(NJS_FS_STAT_NLINK, NJS_NUMBER),
+            .magic32 = njs_fs_magic2(NJS_FS_STAT_NLINK, 0),
         }
     },
 
@@ -907,7 +1147,7 @@ static njs_external_t  njs_ext_stats[] = {
         .enumerable = 1,
         .u.property = {
             .handler = njs_fs_stats_prop,
-            .magic32 = njs_fs_magic2(NJS_FS_STAT_RDEV, NJS_NUMBER),
+            .magic32 = njs_fs_magic2(NJS_FS_STAT_RDEV, 0),
         }
     },
 
@@ -917,7 +1157,7 @@ static njs_external_t  njs_ext_stats[] = {
         .enumerable = 1,
         .u.property = {
             .handler = njs_fs_stats_prop,
-            .magic32 = njs_fs_magic2(NJS_FS_STAT_SIZE, NJS_NUMBER),
+            .magic32 = njs_fs_magic2(NJS_FS_STAT_SIZE, 0),
         }
     },
 
@@ -927,7 +1167,7 @@ static njs_external_t  njs_ext_stats[] = {
         .enumerable = 1,
         .u.property = {
             .handler = njs_fs_stats_prop,
-            .magic32 = njs_fs_magic2(NJS_FS_STAT_UID, NJS_NUMBER),
+            .magic32 = njs_fs_magic2(NJS_FS_STAT_UID, 0),
         }
     },
 
@@ -1175,11 +1415,12 @@ static njs_int_t
 njs_fs_access(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t calltype, njs_value_t *retval)
 {
-    int          md;
-    njs_int_t    ret;
-    const char  *path;
-    njs_value_t  result, *callback, *mode;
-    char         path_buf[NJS_MAX_PATH + 1];
+    int                 md;
+    njs_int_t           ret;
+    const char          *path;
+    njs_value_t         *callback, *mode;
+    njs_opaque_value_t  result;
+    char                path_buf[NJS_MAX_PATH + 1];
 
     path = njs_fs_path(vm, path_buf, njs_arg(args, nargs, 1), "path");
     if (njs_slow_path(path == NULL)) {
@@ -1191,8 +1432,8 @@ njs_fs_access(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     if (calltype == NJS_FS_CALLBACK) {
         callback = njs_arg(args, nargs, njs_min(nargs - 1, 3));
-        if (!njs_is_function(callback)) {
-            njs_type_error(vm, "\"callback\" must be a function");
+        if (!njs_value_is_function(callback)) {
+            njs_vm_error(vm, "\"callback\" must be a function");
             return NJS_ERROR;
         }
 
@@ -1201,21 +1442,18 @@ njs_fs_access(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         }
     }
 
-    switch (mode->type) {
-    case NJS_UNDEFINED:
-        md = F_OK;
-        break;
+    if (njs_value_is_number(mode)) {
+        md = njs_value_number(mode);
 
-    case NJS_NUMBER:
-        md = njs_number(mode);
-        break;
+    } else if (njs_value_is_undefined(mode)) {
+        md = F_OK;
 
-    default:
-        njs_type_error(vm, "\"mode\" must be a number");
+    } else {
+        njs_vm_error(vm, "\"mode\" must be a number");
         return NJS_ERROR;
     }
 
-    njs_set_undefined(&result);
+    njs_value_undefined_set(njs_value_arg(&result));
 
     ret = access(path, md);
     if (njs_slow_path(ret != 0)) {
@@ -1234,12 +1472,13 @@ static njs_int_t
 njs_fs_open(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t calltype, njs_value_t *retval)
 {
-    int          fd, flags;
-    mode_t       md;
-    njs_int_t    ret;
-    const char   *path;
-    njs_value_t  result, *value;
-    char         path_buf[NJS_MAX_PATH + 1];
+    int                 fd, flags;
+    mode_t              md;
+    njs_int_t           ret;
+    const char          *path;
+    njs_value_t         *value;
+    njs_opaque_value_t  result;
+    char                path_buf[NJS_MAX_PATH + 1];
 
     path = njs_fs_path(vm, path_buf, njs_arg(args, nargs, 1), "path");
     if (njs_slow_path(path == NULL)) {
@@ -1247,7 +1486,7 @@ njs_fs_open(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     value = njs_arg(args, nargs, 2);
-    if (njs_is_function(value)) {
+    if (njs_value_is_function(value)) {
         value = njs_value_arg(&njs_value_undefined);
     }
 
@@ -1257,7 +1496,7 @@ njs_fs_open(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     value = njs_arg(args, nargs, 3);
-    if (njs_is_function(value)) {
+    if (njs_value_is_function(value)) {
         value = njs_value_arg(&njs_value_undefined);
     }
 
@@ -1278,7 +1517,7 @@ njs_fs_open(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     if (calltype == NJS_FS_DIRECT) {
-        njs_value_number_set(&result, fd);
+        njs_value_number_set(njs_value_arg(&result), fd);
     }
 
 done:
@@ -1299,9 +1538,10 @@ static njs_int_t
 njs_fs_close(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t calltype, njs_value_t *retval)
 {
-    int64_t      fd;
-    njs_int_t    ret;
-    njs_value_t  result, *fh;
+    int64_t             fd;
+    njs_int_t           ret;
+    njs_value_t         *fh;
+    njs_opaque_value_t  result;
 
     fh = njs_arg(args, nargs, 1);
 
@@ -1310,7 +1550,7 @@ njs_fs_close(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return ret;
     }
 
-    njs_set_undefined(&result);
+    njs_value_undefined_set(njs_value_arg(&result));
 
     ret = close((int) fd);
     if (njs_slow_path(ret != 0)) {
@@ -1329,11 +1569,12 @@ static njs_int_t
 njs_fs_mkdir(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t calltype, njs_value_t *retval)
 {
-    char         *path;
-    mode_t       md;
-    njs_int_t    ret;
-    njs_value_t  mode, recursive, result, *callback, *options;
-    char         path_buf[NJS_MAX_PATH + 1];
+    char                *path;
+    mode_t              md;
+    njs_int_t           ret;
+    njs_value_t         *callback, *options;
+    njs_opaque_value_t  mode, recursive, result;
+    char                path_buf[NJS_MAX_PATH + 1];
 
     path = (char *) njs_fs_path(vm, path_buf, njs_arg(args, nargs, 1), "path");
     if (njs_slow_path(path == NULL)) {
@@ -1345,53 +1586,41 @@ njs_fs_mkdir(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     if (njs_slow_path(calltype == NJS_FS_CALLBACK)) {
         callback = njs_arg(args, nargs, njs_min(nargs - 1, 3));
-        if (!njs_is_function(callback)) {
-            njs_type_error(vm, "\"callback\" must be a function");
+        if (!njs_value_is_function(callback)) {
+            njs_vm_error(vm, "\"callback\" must be a function");
             return NJS_ERROR;
         }
+
         if (options == callback) {
             options = njs_value_arg(&njs_value_undefined);
         }
     }
 
-    njs_set_undefined(&mode);
-    njs_set_false(&recursive);
+    njs_value_undefined_set(njs_value_arg(&mode));
+    njs_value_boolean_set(njs_value_arg(&recursive), 0);
 
-    switch (options->type) {
-    case NJS_NUMBER:
-        mode = *options;
-        break;
-
-    case NJS_UNDEFINED:
-        break;
+    if (njs_value_is_number(options)) {
+        njs_value_assign(&mode, options);
 
-    default:
-        if (!njs_is_object(options)) {
-            njs_type_error(vm, "Unknown options type: \"%s\" "
-                           "(a number or object required)",
-                           njs_type_string(options->type));
+    } else if (!njs_value_is_undefined(options)) {
+        if (!njs_value_is_object(options)) {
+            njs_vm_error(vm, "Unknown options type"
+                         "(a number or object required)");
             return NJS_ERROR;
         }
 
-        ret = njs_value_property(vm, options, njs_value_arg(&string_mode),
-                                 &mode);
-        if (njs_slow_path(ret == NJS_ERROR)) {
-            return ret;
-        }
+        (void) njs_vm_object_prop(vm, options, &string_recursive, &recursive);
 
-        ret = njs_value_property(vm, options, njs_value_arg(&string_recursive),
-                                 &recursive);
-        if (njs_slow_path(ret == NJS_ERROR)) {
-            return ret;
-        }
+        (void) njs_vm_object_prop(vm, options, &string_mode, &mode);
     }
 
-    md = njs_fs_mode(vm, &mode, 0777);
+    md = njs_fs_mode(vm, njs_value_arg(&mode), 0777);
     if (njs_slow_path(md == (mode_t) -1)) {
         return NJS_ERROR;
     }
 
-    ret = njs_fs_make_path(vm, path, md, njs_is_true(&recursive), &result);
+    ret = njs_fs_make_path(vm, path, md,
+                           njs_value_bool(njs_value_arg(&recursive)), &result);
 
     if (ret == NJS_OK) {
         return njs_fs_result(vm, &result, calltype, callback, 1, retval);
@@ -1405,12 +1634,13 @@ static njs_int_t
 njs_fs_read(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t calltype, njs_value_t *retval)
 {
-    int64_t      fd, length, pos, offset;
-    ssize_t      n;
-    njs_int_t    ret;
-    njs_str_t    data;
-    njs_uint_t   fd_offset;
-    njs_value_t  result, *buffer, *value;
+    int64_t             fd, length, pos, offset;
+    ssize_t             n;
+    njs_int_t           ret;
+    njs_str_t           data;
+    njs_uint_t          fd_offset;
+    njs_value_t         *buffer, *value;
+    njs_opaque_value_t  result;
 
     fd_offset = !!(calltype == NJS_FS_DIRECT);
 
@@ -1439,8 +1669,7 @@ njs_fs_read(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     if (njs_slow_path(offset < 0 || (size_t) offset > data.length)) {
-        njs_range_error(vm, "offset is out of range (must be <= %z)",
-                        data.length);
+        njs_vm_error(vm, "offset is out of range (must be <= %z)", data.length);
         return NJS_ERROR;
     }
 
@@ -1449,15 +1678,15 @@ njs_fs_read(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     value = njs_arg(args, nargs, fd_offset + 3);
 
-    if (njs_is_defined(value)) {
+    if (!njs_value_is_undefined(value)) {
         ret = njs_value_to_integer(vm, value, &length);
         if (njs_slow_path(ret != NJS_OK)) {
             return ret;
         }
 
         if (njs_slow_path(length < 0 || (size_t) length > data.length)) {
-            njs_range_error(vm, "length is out of range (must be <= %z)",
-                            data.length);
+            njs_vm_error(vm, "length is out of range (must be <= %z)",
+                         data.length);
             return NJS_ERROR;
         }
 
@@ -1466,7 +1695,7 @@ njs_fs_read(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     value = njs_arg(args, nargs, fd_offset + 4);
 
-    if (!njs_is_null_or_undefined(value)) {
+    if (!njs_value_is_null_or_undefined(value)) {
         ret = njs_value_to_integer(vm, value, &pos);
         if (njs_slow_path(ret != NJS_OK)) {
             return ret;
@@ -1492,7 +1721,7 @@ njs_fs_read(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         }
 
     } else {
-        njs_value_number_set(&result, n);
+        njs_value_number_set(njs_value_arg(&result), n);
     }
 
 done:
@@ -1513,8 +1742,9 @@ njs_fs_read_file(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_str_t                    data;
     njs_int_t                    ret;
     const char                   *path;
-    njs_value_t                  flag, encode, result, *callback, *options;
+    njs_value_t                  *callback, *options;
     struct stat                  sb;
+    njs_opaque_value_t           flag, result, encode;
     const njs_buffer_encoding_t  *encoding;
     char                         path_buf[NJS_MAX_PATH + 1];
 
@@ -1529,8 +1759,8 @@ njs_fs_read_file(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     if (calltype == NJS_FS_CALLBACK) {
         callback = njs_arg(args, nargs, njs_min(nargs - 1, 3));
-        if (!njs_is_function(callback)) {
-            njs_type_error(vm, "\"callback\" must be a function");
+        if (!njs_value_is_function(callback)) {
+            njs_vm_error(vm, "\"callback\" must be a function");
             return NJS_ERROR;
         }
 
@@ -1539,46 +1769,32 @@ njs_fs_read_file(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         }
     }
 
-    njs_set_undefined(&flag);
-    njs_set_undefined(&encode);
-
-    switch (options->type) {
-    case NJS_STRING:
-        encode = *options;
-        break;
+    njs_value_undefined_set(njs_value_arg(&flag));
+    njs_value_undefined_set(njs_value_arg(&encode));
 
-    case NJS_UNDEFINED:
-        break;
+    if (njs_value_is_string(options)) {
+        njs_value_assign(&encode, options);
 
-    default:
-        if (!njs_is_object(options)) {
-            njs_type_error(vm, "Unknown options type: \"%s\" "
-                           "(a string or object required)",
-                           njs_type_string(options->type));
+    } else if (!njs_value_is_undefined(options)) {
+        if (!njs_value_is_object(options)) {
+            njs_vm_error(vm, "Unknown options type "
+                         "(a string or object required)");
             return NJS_ERROR;
         }
 
-        ret = njs_value_property(vm, options, njs_value_arg(&string_flag),
-                                 &flag);
-        if (njs_slow_path(ret == NJS_ERROR)) {
-            return ret;
-        }
+        (void) njs_vm_object_prop(vm, options, &string_flag, &flag);
 
-        ret = njs_value_property(vm, options, njs_value_arg(&string_encoding),
-                                 &encode);
-        if (njs_slow_path(ret == NJS_ERROR)) {
-            return ret;
-        }
+        (void) njs_vm_object_prop(vm, options, &string_encoding, &encode);
     }
 
-    flags = njs_fs_flags(vm, &flag, O_RDONLY);
+    flags = njs_fs_flags(vm, njs_value_arg(&flag), O_RDONLY);
     if (njs_slow_path(flags == -1)) {
         return NJS_ERROR;
     }
 
     encoding = NULL;
-    if (njs_is_defined(&encode)) {
-        encoding = njs_buffer_encoding(vm, &encode, 1);
+    if (!njs_value_is_undefined(njs_value_arg(&encode))) {
+        encoding = njs_buffer_encoding(vm, njs_value_arg(&encode), 1);
         if (njs_slow_path(encoding == NULL)) {
             return NJS_ERROR;
         }
@@ -1615,11 +1831,12 @@ njs_fs_read_file(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     if (encoding == NULL) {
-        ret = njs_buffer_set(vm, &result, data.start, data.length);
+        ret = njs_buffer_set(vm, njs_value_arg(&result), data.start,
+                             data.length);
 
     } else {
-        ret = encoding->encode(vm, &result, &data);
-        njs_mp_free(vm->mem_pool, data.start);
+        ret = encoding->encode(vm, njs_value_arg(&result), &data);
+        njs_mp_free(njs_vm_memory_pool(vm), data.start);
     }
 
 done:
@@ -1644,14 +1861,13 @@ njs_fs_readdir(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_str_t                    s;
     njs_int_t                    ret;
     const char                   *path;
-    njs_value_t                  encode, types, ename, etype, result,
-                                 *callback, *options, *value;
-    njs_array_t                  *results;
+    njs_value_t                  *callback, *options, *value;
     struct dirent                *entry;
+    njs_opaque_value_t           encode, types, ename, etype, result;
     const njs_buffer_encoding_t  *encoding;
     char                         path_buf[NJS_MAX_PATH + 1];
 
-    static const njs_value_t  string_types = njs_string("withFileTypes");
+    static const njs_str_t  string_types = njs_str("withFileTypes");
 
     path = njs_fs_path(vm, path_buf, njs_arg(args, nargs, 1), "path");
     if (njs_slow_path(path == NULL)) {
@@ -1663,8 +1879,8 @@ njs_fs_readdir(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     if (njs_slow_path(calltype == NJS_FS_CALLBACK)) {
         callback = njs_arg(args, nargs, njs_min(nargs - 1, 3));
-        if (!njs_is_function(callback)) {
-            njs_type_error(vm, "\"callback\" must be a function");
+        if (!njs_value_is_function(callback)) {
+            njs_vm_error(vm, "\"callback\" must be a function");
             return NJS_ERROR;
         }
         if (options == callback) {
@@ -1672,53 +1888,42 @@ njs_fs_readdir(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         }
     }
 
-    njs_set_false(&types);
-    njs_set_undefined(&encode);
+    njs_value_boolean_set(njs_value_arg(&types), 0);
+    njs_value_undefined_set(njs_value_arg(&encode));
 
-    switch (options->type) {
-    case NJS_STRING:
-        encode = *options;
-        break;
-
-    case NJS_UNDEFINED:
-        break;
+    if (njs_value_is_string(options)) {
+        njs_value_assign(&encode, options);
 
-    default:
-        if (!njs_is_object(options)) {
-            njs_type_error(vm, "Unknown options type: \"%s\" "
-                           "(a string or object required)",
-                           njs_type_string(options->type));
+    } else if (!njs_value_is_undefined(options)) {
+        if (!njs_value_is_object(options)) {
+            njs_vm_error(vm, "Unknown options type "
+                         "(a string or object required)");
             return NJS_ERROR;
         }
 
-        ret = njs_value_property(vm, options, njs_value_arg(&string_encoding),
-                                 &encode);
-        if (njs_slow_path(ret == NJS_ERROR)) {
-            return ret;
-        }
+        (void) njs_vm_object_prop(vm, options, &string_encoding, &encode);
 
-        ret = njs_value_property(vm, options, njs_value_arg(&string_types),
-                                 &types);
-        if (njs_slow_path(ret == NJS_ERROR)) {
-            return ret;
-        }
+        (void) njs_vm_object_prop(vm, options, &string_types, &types);
     }
 
     encoding = NULL;
-    if (!njs_is_string(&encode) || !njs_string_eq(&encode, &string_buffer)) {
-        encoding = njs_buffer_encoding(vm, &encode, 1);
-        if (njs_slow_path(encoding == NULL)) {
-            return NJS_ERROR;
+
+    if (!njs_value_is_string(njs_value_arg(&encode))) {
+        njs_value_string_get(njs_value_arg(&encode), &s);
+
+        if (!njs_strstr_eq(&s, &string_buffer)) {
+            encoding = njs_buffer_encoding(vm, njs_value_arg(&encode), 1);
+            if (njs_slow_path(encoding == NULL)) {
+                return NJS_ERROR;
+            }
         }
     }
 
-    results = njs_array_alloc(vm, 1, 0, NJS_ARRAY_SPARE);
-    if (njs_slow_path(results == NULL)) {
+    ret = njs_vm_array_alloc(vm, njs_value_arg(&result), 8);
+    if (njs_slow_path(ret != NJS_OK)) {
         return NJS_ERROR;
     }
 
-    njs_set_array(&result, results);
-
     dir = opendir(path);
     if (njs_slow_path(dir == NULL)) {
         ret = njs_fs_error(vm, "opendir", strerror(errno), path, errno,
@@ -1749,30 +1954,31 @@ njs_fs_readdir(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             continue;
         }
 
-        value = njs_array_push(vm, results);
+        value = njs_vm_array_push(vm, njs_value_arg(&result));
         if (njs_slow_path(value == NULL)) {
             goto done;
         }
 
         if (encoding == NULL) {
-            ret = njs_buffer_set(vm, &ename, s.start, s.length);
+            ret = njs_buffer_set(vm, njs_value_arg(&ename), s.start, s.length);
 
         } else {
-            ret = encoding->encode(vm, &ename, &s);
+            ret = encoding->encode(vm, njs_value_arg(&ename), &s);
         }
 
         if (njs_slow_path(ret != NJS_OK)) {
             goto done;
         }
 
-        if (njs_fast_path(!njs_is_true(&types))) {
-            *value = ename;
+        if (njs_fast_path(!njs_value_bool(njs_value_arg(&types)))) {
+            njs_value_assign(value, &ename);
             continue;
         }
 
-        njs_set_number(&etype, njs_dentry_type(entry));
+        njs_value_number_set(njs_value_arg(&etype), njs_dentry_type(entry));
 
-        ret = njs_fs_dirent_create(vm, &ename, &etype, value);
+        ret = njs_fs_dirent_create(vm, njs_value_arg(&ename),
+                                   njs_value_arg(&etype), value);
         if (njs_slow_path(ret != NJS_OK)) {
             goto done;
         }
@@ -1799,7 +2005,8 @@ njs_fs_realpath(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_int_t                    ret;
     njs_str_t                    s;
     const char                   *path;
-    njs_value_t                  encode, result, *callback, *options;
+    njs_value_t                  *callback, *options;
+    njs_opaque_value_t           encode, result;
     const njs_buffer_encoding_t  *encoding;
     char                         path_buf[NJS_MAX_PATH + 1],
                                  dst_buf[NJS_MAX_PATH + 1];
@@ -1814,8 +2021,8 @@ njs_fs_realpath(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     if (calltype == NJS_FS_CALLBACK) {
         callback = njs_arg(args, nargs, njs_min(nargs - 1, 3));
-        if (!njs_is_function(callback)) {
-            njs_type_error(vm, "\"callback\" must be a function");
+        if (!njs_value_is_function(callback)) {
+            njs_vm_error(vm, "\"callback\" must be a function");
             return NJS_ERROR;
         }
 
@@ -1824,36 +2031,31 @@ njs_fs_realpath(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         }
     }
 
-    njs_set_undefined(&encode);
-
-    switch (options->type) {
-    case NJS_STRING:
-        encode = *options;
-        break;
+    njs_value_undefined_set(njs_value_arg(&encode));
 
-    case NJS_UNDEFINED:
-        break;
+    if (njs_value_is_string(options)) {
+        njs_value_assign(&encode, options);
 
-    default:
-        if (!njs_is_object(options)) {
-            njs_type_error(vm, "Unknown options type: \"%s\" "
-                           "(a string or object required)",
-                           njs_type_string(options->type));
+    } else if (!njs_value_is_undefined(options)) {
+        if (!njs_value_is_object(options)) {
+            njs_vm_error(vm, "Unknown options type "
+                           "(a string or object required)");
             return NJS_ERROR;
         }
 
-        ret = njs_value_property(vm, options, njs_value_arg(&string_encoding),
-                                 &encode);
-        if (njs_slow_path(ret == NJS_ERROR)) {
-            return ret;
-        }
+        (void) njs_vm_object_prop(vm, options, &string_encoding, &encode);
     }
 
     encoding = NULL;
-    if (!njs_is_string(&encode) || !njs_string_eq(&encode, &string_buffer)) {
-        encoding = njs_buffer_encoding(vm, &encode, 1);
-        if (njs_slow_path(encoding == NULL)) {
-            return NJS_ERROR;
+
+    if (!njs_value_is_string(njs_value_arg(&encode))) {
+        njs_value_string_get(njs_value_arg(&encode), &s);
+
+        if (!njs_strstr_eq(&s, &string_buffer)) {
+            encoding = njs_buffer_encoding(vm, njs_value_arg(&encode), 1);
+            if (njs_slow_path(encoding == NULL)) {
+                return NJS_ERROR;
+            }
         }
     }
 
@@ -1867,10 +2069,10 @@ njs_fs_realpath(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     s.length = njs_strlen(s.start);
 
     if (encoding == NULL) {
-        ret = njs_buffer_new(vm, &result, s.start, s.length);
+        ret = njs_buffer_new(vm, njs_value_arg(&result), s.start, s.length);
 
     } else {
-        ret = encoding->encode(vm, &result, &s);
+        ret = encoding->encode(vm, njs_value_arg(&result), &s);
     }
 
 done:
@@ -1887,17 +2089,19 @@ static njs_int_t
 njs_fs_rename(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t calltype, njs_value_t *retval)
 {
-    njs_int_t    ret;
-    const char   *path, *newpath;
-    njs_value_t  result, *callback;
-    char         path_buf[NJS_MAX_PATH + 1], newpath_buf[NJS_MAX_PATH + 1];
+    njs_int_t            ret;
+    const char          *path, *newpath;
+    njs_value_t         *callback;
+    njs_opaque_value_t  result;
+    char                path_buf[NJS_MAX_PATH + 1],
+                        newpath_buf[NJS_MAX_PATH + 1];
 
     callback = NULL;
 
     if (calltype == NJS_FS_CALLBACK) {
         callback = njs_arg(args, nargs, 3);
-        if (!njs_is_function(callback)) {
-            njs_type_error(vm, "\"callback\" must be a function");
+        if (!njs_value_is_function(callback)) {
+            njs_vm_error(vm, "\"callback\" must be a function");
             return NJS_ERROR;
         }
     }
@@ -1912,7 +2116,7 @@ njs_fs_rename(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    njs_set_undefined(&result);
+    njs_value_undefined_set(njs_value_arg(&result));
 
     ret = rename(path, newpath);
     if (njs_slow_path(ret != 0)) {
@@ -1931,10 +2135,11 @@ static njs_int_t
 njs_fs_rmdir(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t calltype, njs_value_t *retval)
 {
-    njs_int_t    ret;
-    const char   *path;
-    njs_value_t  recursive, result, *callback, *options;
-    char         path_buf[NJS_MAX_PATH + 1];
+    njs_int_t           ret;
+    const char          *path;
+    njs_value_t         *callback, *options;
+    njs_opaque_value_t  recursive, result;
+    char                path_buf[NJS_MAX_PATH + 1];
 
     path = njs_fs_path(vm, path_buf, njs_arg(args, nargs, 1), "path");
     if (njs_slow_path(path == NULL)) {
@@ -1946,8 +2151,8 @@ njs_fs_rmdir(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     if (njs_slow_path(calltype == NJS_FS_CALLBACK)) {
         callback = njs_arg(args, nargs, njs_min(nargs - 1, 3));
-        if (!njs_is_function(callback)) {
-            njs_type_error(vm, "\"callback\" must be a function");
+        if (!njs_value_is_function(callback)) {
+            njs_vm_error(vm, "\"callback\" must be a function");
             return NJS_ERROR;
         }
         if (options == callback) {
@@ -1955,28 +2160,21 @@ njs_fs_rmdir(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         }
     }
 
-    njs_set_false(&recursive);
-
-    switch (options->type) {
-    case NJS_UNDEFINED:
-        break;
+    njs_value_boolean_set(njs_value_arg(&recursive), 0);
 
-    default:
-        if (!njs_is_object(options)) {
-            njs_type_error(vm, "Unknown options type: \"%s\" "
-                           "(an object required)",
-                           njs_type_string(options->type));
+    if (njs_slow_path(!njs_value_is_undefined(options))) {
+        if (!njs_value_is_object(options)) {
+            njs_vm_error(vm, "Unknown options type "
+                           "(an object required)");
             return NJS_ERROR;
         }
 
-        ret = njs_value_property(vm, options, njs_value_arg(&string_recursive),
-                                 &recursive);
-        if (njs_slow_path(ret == NJS_ERROR)) {
-            return ret;
-        }
+        (void) njs_vm_object_prop(vm, options, &string_recursive, &recursive);
     }
 
-    ret = njs_fs_rmtree(vm, path, njs_is_true(&recursive), &result);
+
+    ret = njs_fs_rmtree(vm, path, njs_value_bool(njs_value_arg(&recursive)),
+                        &result);
 
     if (ret == NJS_OK) {
         return njs_fs_result(vm, &result, calltype, callback, 1, retval);
@@ -1990,18 +2188,19 @@ static njs_int_t
 njs_fs_stat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t magic, njs_value_t *retval)
 {
-    int64_t            fd;
-    njs_int_t          ret;
-    njs_uint_t         fd_offset;
-    njs_bool_t         throw;
-    struct stat        sb;
-    const char         *path;
-    njs_value_t        result, *callback, *options;
-    njs_fs_calltype_t  calltype;
-    char               path_buf[NJS_MAX_PATH + 1];
-
-    static const njs_value_t  string_bigint = njs_string("bigint");
-    static const njs_value_t  string_throw = njs_string("throwIfNoEntry");
+    int64_t             fd;
+    njs_int_t           ret;
+    njs_uint_t          fd_offset;
+    njs_bool_t          throw;
+    struct stat         sb;
+    const char          *path;
+    njs_value_t         *callback, *options, *value;
+    njs_opaque_value_t  result;
+    njs_fs_calltype_t   calltype;
+    char                path_buf[NJS_MAX_PATH + 1];
+
+    static const njs_str_t  string_bigint = njs_str("bigint");
+    static const njs_str_t  string_throw = njs_str("throwIfNoEntry");
 
     fd = -1;
     path = NULL;
@@ -2029,10 +2228,11 @@ njs_fs_stat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     if (njs_slow_path(calltype == NJS_FS_CALLBACK)) {
         callback = njs_arg(args, nargs, njs_min(nargs - 1, 3));
-        if (!njs_is_function(callback)) {
-            njs_type_error(vm, "\"callback\" must be a function");
+        if (!njs_value_is_function(callback)) {
+            njs_vm_error(vm, "\"callback\" must be a function");
             return NJS_ERROR;
         }
+
         if (options == callback) {
             options = njs_value_arg(&njs_value_undefined);
         }
@@ -2040,37 +2240,25 @@ njs_fs_stat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     throw = 1;
 
-    switch (options->type) {
-    case NJS_UNDEFINED:
-        break;
-
-    default:
-        if (!njs_is_object(options)) {
-            njs_type_error(vm, "Unknown options type: \"%s\" "
-                           "(an object required)",
-                           njs_type_string(options->type));
+    if (!njs_value_is_undefined(options)) {
+        if (!njs_value_is_object(options)) {
+            njs_vm_error(vm, "Unknown options type "
+                           "(an object required)");
             return NJS_ERROR;
         }
 
-        ret = njs_value_property(vm, options, njs_value_arg(&string_bigint),
-                                 &result);
-        if (njs_slow_path(ret == NJS_ERROR)) {
-            return ret;
-        }
-
-        if (njs_bool(&result)) {
-            njs_type_error(vm, "\"bigint\" is not supported");
+        value = njs_vm_object_prop(vm, options, &string_bigint, &result);
+        if (value != NULL && njs_value_bool(value)) {
+            njs_vm_error(vm, "\"bigint\" is not supported");
             return NJS_ERROR;
         }
 
         if (calltype == NJS_FS_DIRECT) {
-            ret = njs_value_property(vm, options, njs_value_arg(&string_throw),
-                                     &result);
-            if (njs_slow_path(ret == NJS_ERROR)) {
-                return ret;
-            }
+            value = njs_vm_object_prop(vm, options, &string_throw, &result);
 
-            throw = njs_bool(&result);
+            if (value != NULL) {
+                throw = njs_value_bool(value);
+            }
         }
     }
 
@@ -2098,13 +2286,13 @@ njs_fs_stat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
                 return NJS_ERROR;
             }
         } else {
-            njs_set_undefined(&result);
+            njs_value_undefined_set(njs_value_arg(&result));
         }
 
         return njs_fs_result(vm, &result, calltype, callback, 2, retval);
     }
 
-    ret = njs_fs_stats_create(vm, &sb, &result);
+    ret = njs_fs_stats_create(vm, &sb, njs_value_arg(&result));
     if (njs_slow_path(ret != NJS_OK)) {
         return NJS_ERROR;
     }
@@ -2117,10 +2305,12 @@ static njs_int_t
 njs_fs_symlink(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t calltype, njs_value_t *retval)
 {
-    njs_int_t    ret;
-    const char  *target, *path;
-    njs_value_t  result, *callback, *type;
-    char         target_buf[NJS_MAX_PATH + 1], path_buf[NJS_MAX_PATH + 1];
+    njs_int_t           ret;
+    const char          *target, *path;
+    njs_value_t         *callback, *type;
+    njs_opaque_value_t  result;
+    char                target_buf[NJS_MAX_PATH + 1],
+                        path_buf[NJS_MAX_PATH + 1];
 
     target = njs_fs_path(vm, target_buf, njs_arg(args, nargs, 1), "target");
     if (njs_slow_path(target == NULL)) {
@@ -2137,8 +2327,8 @@ njs_fs_symlink(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     if (calltype == NJS_FS_CALLBACK) {
         callback = njs_arg(args, nargs, njs_min(nargs - 1, 4));
-        if (!njs_is_function(callback)) {
-            njs_type_error(vm, "\"callback\" must be a function");
+        if (!njs_value_is_function(callback)) {
+            njs_vm_error(vm, "\"callback\" must be a function");
             return NJS_ERROR;
         }
 
@@ -2147,12 +2337,14 @@ njs_fs_symlink(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         }
     }
 
-    if (njs_slow_path(!njs_is_undefined(type) && !njs_is_string(type))) {
-        njs_type_error(vm, "\"type\" must be a string");
+    if (njs_slow_path(!njs_value_is_undefined(type)
+                      && !njs_value_is_string(type)))
+    {
+        njs_vm_error(vm, "\"type\" must be a string");
         return NJS_ERROR;
     }
 
-    njs_set_undefined(&result);
+    njs_value_undefined_set(njs_value_arg(&result));
 
     ret = symlink(target, path);
     if (njs_slow_path(ret != 0)) {
@@ -2172,10 +2364,11 @@ static njs_int_t
 njs_fs_unlink(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t calltype, njs_value_t *retval)
 {
-    njs_int_t    ret;
-    const char   *path;
-    njs_value_t  result, *callback;
-    char         path_buf[NJS_MAX_PATH + 1];
+    njs_int_t           ret;
+    const char          *path;
+    njs_value_t         *callback;
+    njs_opaque_value_t  result;
+    char                path_buf[NJS_MAX_PATH + 1];
 
     path = njs_fs_path(vm, path_buf, njs_arg(args, nargs, 1), "path");
     if (njs_slow_path(path == NULL)) {
@@ -2186,13 +2379,13 @@ njs_fs_unlink(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     if (calltype == NJS_FS_CALLBACK) {
         callback = njs_arg(args, nargs, 2);
-        if (!njs_is_function(callback)) {
-            njs_type_error(vm, "\"callback\" must be a function");
+        if (!njs_value_is_function(callback)) {
+            njs_vm_error(vm, "\"callback\" must be a function");
             return NJS_ERROR;
         }
     }
 
-    njs_set_undefined(&result);
+    njs_value_undefined_set(njs_value_arg(&result));
 
     ret = unlink(path);
     if (njs_slow_path(ret != 0)) {
@@ -2216,7 +2409,8 @@ njs_fs_write(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_int_t                    ret;
     njs_str_t                    data;
     njs_uint_t                   fd_offset;
-    njs_value_t                  result, *buffer, *value;
+    njs_value_t                  *buffer, *value;
+    njs_opaque_value_t           result;
     const njs_buffer_encoding_t  *encoding;
 
     fd_offset = !!(calltype == NJS_FS_DIRECT);
@@ -2236,10 +2430,10 @@ njs_fs_write(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
      * fh.write(string[, position[, encoding]])
      */
 
-    if (njs_is_string(buffer)) {
+    if (njs_value_is_string(buffer)) {
         value = njs_arg(args, nargs, fd_offset + 2);
 
-        if (!njs_is_null_or_undefined(value)) {
+        if (!njs_value_is_null_or_undefined(value)) {
             ret = njs_value_to_integer(vm, value, &pos);
             if (njs_slow_path(ret != NJS_OK)) {
                 return ret;
@@ -2252,12 +2446,13 @@ njs_fs_write(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             return NJS_ERROR;
         }
 
-        ret = njs_buffer_decode_string(vm, buffer, &result, encoding);
+        ret = njs_buffer_decode_string(vm, buffer, njs_value_arg(&result),
+                                       encoding);
         if (njs_slow_path(ret != NJS_OK)) {
             return NJS_ERROR;
         }
 
-        njs_string_get(&result, &data);
+        njs_value_string_get(njs_value_arg(&result), &data);
 
         goto process;
     }
@@ -2279,8 +2474,8 @@ njs_fs_write(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     if (njs_slow_path(offset < 0 || (size_t) offset > data.length)) {
-        njs_range_error(vm, "offset is out of range (must be <= %z)",
-                        data.length);
+        njs_vm_error(vm, "offset is out of range (must be <= %z)",
+                     data.length);
         return NJS_ERROR;
     }
 
@@ -2289,15 +2484,15 @@ njs_fs_write(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     value = njs_arg(args, nargs, fd_offset + 3);
 
-    if (njs_is_defined(value)) {
+    if (!njs_value_is_undefined(value)) {
         ret = njs_value_to_integer(vm, value, &length);
         if (njs_slow_path(ret != NJS_OK)) {
             return ret;
         }
 
         if (njs_slow_path(length < 0 || (size_t) length > data.length)) {
-            njs_range_error(vm, "length is out of range (must be <= %z)",
-                            data.length);
+            njs_vm_error(vm, "length is out of range (must be <= %z)",
+                         data.length);
             return NJS_ERROR;
         }
 
@@ -2306,7 +2501,7 @@ njs_fs_write(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     value = njs_arg(args, nargs, fd_offset + 4);
 
-    if (!njs_is_null_or_undefined(value)) {
+    if (!njs_value_is_null_or_undefined(value)) {
         ret = njs_value_to_integer(vm, value, &pos);
         if (njs_slow_path(ret != NJS_OK)) {
             return ret;
@@ -2340,7 +2535,7 @@ process:
         }
 
     } else {
-        njs_value_number_set(&result, n);
+        njs_value_number_set(njs_value_arg(&result), n);
     }
 
 done:
@@ -2364,11 +2559,9 @@ njs_fs_write_file(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_str_t                    content;
     njs_int_t                    ret;
     const char                   *path;
-    njs_value_t                  flag, mode, encode, result, *data, *callback,
-                                 *options;
-    njs_typed_array_t            *array;
+    njs_value_t                  *data, *callback, *options;
+    njs_opaque_value_t           flag, mode, encode, result;
     njs_fs_calltype_t            calltype;
-    njs_array_buffer_t           *buffer;
     const njs_buffer_encoding_t  *encoding;
     char                         path_buf[NJS_MAX_PATH + 1];
 
@@ -2383,8 +2576,8 @@ njs_fs_write_file(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     if (calltype == NJS_FS_CALLBACK) {
         callback = njs_arg(args, nargs, njs_min(nargs - 1, 4));
-        if (!njs_is_function(callback)) {
-            njs_type_error(vm, "\"callback\" must be a function");
+        if (!njs_value_is_function(callback)) {
+            njs_vm_error(vm, "\"callback\" must be a function");
             return NJS_ERROR;
         }
 
@@ -2393,90 +2586,63 @@ njs_fs_write_file(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         }
     }
 
-    njs_set_undefined(&flag);
-    njs_set_undefined(&mode);
-    njs_set_undefined(&encode);
+    njs_value_undefined_set(njs_value_arg(&flag));
+    njs_value_undefined_set(njs_value_arg(&mode));
+    njs_value_undefined_set(njs_value_arg(&encode));
 
-    switch (options->type) {
-    case NJS_STRING:
-        encode = *options;
-        break;
+    if (njs_value_is_string(options)) {
+        njs_value_assign(&encode, options);
 
-    case NJS_UNDEFINED:
-        break;
-
-    default:
-        if (!njs_is_object(options)) {
-            njs_type_error(vm, "Unknown options type: \"%s\" "
-                           "(a string or object required)",
-                           njs_type_string(options->type));
+    } else if (!njs_value_is_undefined(options)) {
+        if (!njs_value_is_object(options)) {
+            njs_vm_error(vm, "Unknown options type "
+                         "(a string or object required)");
             return NJS_ERROR;
         }
 
-        ret = njs_value_property(vm, options, njs_value_arg(&string_flag),
-                                 &flag);
-        if (njs_slow_path(ret == NJS_ERROR)) {
-            return ret;
-        }
+        (void) njs_vm_object_prop(vm, options, &string_flag, &flag);
 
-        ret = njs_value_property(vm, options, njs_value_arg(&string_mode),
-                                 &mode);
-        if (njs_slow_path(ret == NJS_ERROR)) {
-            return ret;
-        }
+        (void) njs_vm_object_prop(vm, options, &string_mode, &mode);
 
-        ret = njs_value_property(vm, options, njs_value_arg(&string_encoding),
-                                 &encode);
-        if (njs_slow_path(ret == NJS_ERROR)) {
-            return ret;
-        }
+        (void) njs_vm_object_prop(vm, options, &string_encoding, &encode);
     }
 
     data = njs_arg(args, nargs, 2);
 
-    switch (data->type) {
-    case NJS_TYPED_ARRAY:
-    case NJS_DATA_VIEW:
-        array = njs_typed_array(data);
-        buffer = array->buffer;
-        if (njs_slow_path(njs_is_detached_buffer(buffer))) {
-            njs_type_error(vm, "detached buffer");
+    if (njs_value_is_buffer(data) || njs_value_is_data_view(data)) {
+        ret = njs_value_buffer_get(vm, data, &content);
+        if (njs_slow_path(ret != NJS_OK)) {
             return NJS_ERROR;
         }
 
-        content.start = &buffer->u.u8[array->offset];
-        content.length = array->byte_length;
-        break;
-
-    case NJS_STRING:
-    default:
-        encoding = njs_buffer_encoding(vm, &encode, 1);
+    } else {
+        encoding = njs_buffer_encoding(vm, njs_value_arg(&encode), 1);
         if (njs_slow_path(encoding == NULL)) {
             return NJS_ERROR;
         }
 
-        ret = njs_value_to_string(vm, &result, data);
+        ret = njs_value_to_string(vm, njs_value_arg(&result), data);
         if (njs_slow_path(ret != NJS_OK)) {
             return NJS_ERROR;
         }
 
-        ret = njs_buffer_decode_string(vm, &result, &result, encoding);
+        ret = njs_buffer_decode_string(vm, njs_value_arg(&result),
+                                       njs_value_arg(&result), encoding);
         if (njs_slow_path(ret != NJS_OK)) {
             return NJS_ERROR;
         }
 
-        njs_string_get(&result, &content);
-        break;
+        njs_value_string_get(njs_value_arg(&result), &content);
     }
 
-    flags = njs_fs_flags(vm, &flag, O_CREAT | O_WRONLY);
+    flags = njs_fs_flags(vm, njs_value_arg(&flag), O_CREAT | O_WRONLY);
     if (njs_slow_path(flags == -1)) {
         return NJS_ERROR;
     }
 
     flags |= ((magic >> 2) == NJS_FS_APPEND) ? O_APPEND : O_TRUNC;
 
-    md = njs_fs_mode(vm, &mode, 0666);
+    md = njs_fs_mode(vm, njs_value_arg(&mode), 0666);
     if (njs_slow_path(md == (mode_t) -1)) {
         return NJS_ERROR;
     }
@@ -2506,7 +2672,7 @@ njs_fs_write_file(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     ret = NJS_OK;
-    njs_set_undefined(&result);
+    njs_value_undefined_set(njs_value_arg(&result));
 
 done:
 
@@ -2535,9 +2701,9 @@ njs_fs_fd_read(njs_vm_t *vm, int fd, njs_str_t *data)
         size = 4096;
     }
 
-    data->start = njs_mp_alloc(vm->mem_pool, size);
+    data->start = njs_mp_alloc(njs_vm_memory_pool(vm), size);
     if (data->start == NULL) {
-        njs_memory_error(vm);
+        njs_vm_memory_error(vm);
         return NJS_ERROR;
     }
 
@@ -2560,15 +2726,15 @@ njs_fs_fd_read(njs_vm_t *vm, int fd, njs_str_t *data)
         if (end - p < 2048) {
             size *= 2;
 
-            start = njs_mp_alloc(vm->mem_pool, size);
+            start = njs_mp_alloc(njs_vm_memory_pool(vm), size);
             if (start == NULL) {
-                njs_memory_error(vm);
+                njs_vm_memory_error(vm);
                 return NJS_ERROR;
             }
 
             memcpy(start, data->start, p - data->start);
 
-            njs_mp_free(vm->mem_pool, data->start);
+            njs_mp_free(njs_vm_memory_pool(vm), data->start);
 
             p = start + (p - data->start);
             end = start + size;
@@ -2584,14 +2750,14 @@ njs_fs_fd_read(njs_vm_t *vm, int fd, njs_str_t *data)
 
 static njs_int_t
 njs_fs_make_path(njs_vm_t *vm, char *path, mode_t md, njs_bool_t recursive,
-    njs_value_t *retval)
+    njs_opaque_value_t *retval)
 {
     int          err;
     njs_int_t    ret;
     const char   *p, *prev, *end;
     struct stat  sb;
 
-    njs_set_undefined(retval);
+    njs_value_undefined_set(njs_value_arg(retval));
 
     end = path + njs_strlen(path);
 
@@ -2615,7 +2781,7 @@ njs_fs_make_path(njs_vm_t *vm, char *path, mode_t md, njs_bool_t recursive,
         }
 
         if (njs_slow_path((p - path) > NJS_MAX_PATH)) {
-            njs_internal_error(vm, "too large path");
+            njs_vm_error(vm, "too large path");
             return NJS_ERROR;
         }
 
@@ -2851,12 +3017,12 @@ njs_fs_rmtree_cb(const char *path, const struct stat *sb, njs_ftw_type_t type)
 
 static njs_int_t
 njs_fs_rmtree(njs_vm_t *vm, const char *path, njs_bool_t recursive,
-    njs_value_t *retval)
+    njs_opaque_value_t *retval)
 {
     njs_int_t   ret;
     const char  *description;
 
-    njs_set_undefined(retval);
+    njs_value_undefined_set(njs_value_arg(retval));
 
     ret = rmdir(path);
     if (ret == 0) {
@@ -2881,44 +3047,34 @@ njs_fs_rmtree(njs_vm_t *vm, const char *path, njs_bool_t recursive,
 
 
 static const char *
-njs_fs_path(njs_vm_t *vm, char storage[NJS_MAX_PATH + 1],
-    const njs_value_t *src, const char *prop_name)
+njs_fs_path(njs_vm_t *vm, char storage[NJS_MAX_PATH + 1], njs_value_t *src,
+    const char *prop_name)
 {
-    u_char              *p;
-    njs_str_t           str;
-    njs_typed_array_t   *array;
-    njs_array_buffer_t  *buffer;
-
-    switch (src->type) {
-    case NJS_STRING:
-        njs_string_get(src, &str);
-        break;
+    u_char     *p;
+    njs_str_t  str;
+    njs_int_t  ret;
 
-    case NJS_TYPED_ARRAY:
-    case NJS_DATA_VIEW:
-        array = njs_typed_array(src);
-        buffer = array->buffer;
-        if (njs_slow_path(njs_is_detached_buffer(buffer))) {
-            njs_type_error(vm, "detached buffer");
+    if (njs_value_is_string(src)) {
+        njs_value_string_get(src, &str);
+
+    } else if (njs_value_is_buffer(src)) {
+        ret = njs_value_buffer_get(vm, src, &str);
+        if (njs_slow_path(ret != NJS_OK)) {
             return NULL;
         }
 
-        str.start = &buffer->u.u8[array->offset];
-        str.length = array->byte_length;
-        break;
-
-    default:
-        njs_type_error(vm, "\"%s\" must be a string or Buffer", prop_name);
+    } else {
+        njs_vm_error(vm, "\"%s\" must be a string or Buffer", prop_name);
         return NULL;
     }
 
     if (njs_slow_path(str.length > NJS_MAX_PATH - 1)) {
-        njs_type_error(vm, "\"%s\" is too long >= %d", prop_name, NJS_MAX_PATH);
+        njs_vm_error(vm, "\"%s\" is too long >= %d", prop_name, NJS_MAX_PATH);
         return NULL;
     }
 
     if (njs_slow_path(memchr(str.start, '\0', str.length) != 0)) {
-        njs_type_error(vm, "\"%s\" must be a Buffer without null bytes",
+        njs_vm_error(vm, "\"%s\" must be a Buffer without null bytes",
                        prop_name);
         return NULL;
     }
@@ -2937,7 +3093,7 @@ njs_fs_flags(njs_vm_t *vm, njs_value_t *value, int default_flags)
     njs_int_t       ret;
     njs_fs_entry_t  *fl;
 
-    if (njs_is_undefined(value)) {
+    if (njs_value_is_undefined(value)) {
         return default_flags;
     }
 
@@ -2946,7 +3102,7 @@ njs_fs_flags(njs_vm_t *vm, njs_value_t *value, int default_flags)
         return -1;
     }
 
-    njs_string_get(value, &flags);
+    njs_value_string_get(value, &flags);
 
     for (fl = &njs_flags_table[0]; fl->name.length != 0; fl++) {
         if (njs_strstr_eq(&flags, &fl->name)) {
@@ -2954,7 +3110,7 @@ njs_fs_flags(njs_vm_t *vm, njs_value_t *value, int default_flags)
         }
     }
 
-    njs_type_error(vm, "Unknown file open flags: \"%V\"", &flags);
+    njs_vm_error(vm, "Unknown file open flags: \"%V\"", &flags);
 
     return -1;
 }
@@ -2963,70 +3119,62 @@ njs_fs_flags(njs_vm_t *vm, njs_value_t *value, int default_flags)
 static mode_t
 njs_fs_mode(njs_vm_t *vm, njs_value_t *value, mode_t default_mode)
 {
-    uint32_t   u32;
+    int64_t    i64;
     njs_int_t  ret;
 
-    /* GCC complains about uninitialized u32. */
-    u32 = 0;
+    /* GCC complains about uninitialized i64. */
+    i64 = 0;
 
-    if (njs_is_undefined(value)) {
+    if (njs_value_is_undefined(value)) {
         return default_mode;
     }
 
-    ret = njs_value_to_uint32(vm, value, &u32);
+    ret = njs_value_to_integer(vm, value, &i64);
     if (njs_slow_path(ret != NJS_OK)) {
         return (mode_t) -1;
     }
 
-    return (mode_t) u32;
+    return (mode_t) i64;
 }
 
 
 static njs_int_t
 njs_fs_error(njs_vm_t *vm, const char *syscall, const char *description,
-    const char *path, int errn, njs_value_t *retval)
+    const char *path, int errn, njs_opaque_value_t *retval)
 {
-    size_t        size;
-    njs_int_t     ret;
-    njs_value_t   value;
-    const char    *code;
-    njs_object_t  *error;
+    size_t              size;
+    njs_int_t           ret;
+    const char          *code;
+    njs_opaque_value_t  value;
 
-    static const njs_value_t  string_errno = njs_string("errno");
-    static const njs_value_t  string_code = njs_string("code");
-    static const njs_value_t  string_path = njs_string("path");
-    static const njs_value_t  string_syscall = njs_string("syscall");
+    static const njs_str_t  string_errno = njs_str("errno");
+    static const njs_str_t  string_code = njs_str("code");
+    static const njs_str_t  string_path = njs_str("path");
+    static const njs_str_t  string_syscall = njs_str("syscall");
 
     size = description != NULL ? njs_strlen(description) : 0;
 
-    ret = njs_string_create(vm, &value, description, size);
-    if (njs_slow_path(ret != NJS_OK)) {
-        return NJS_ERROR;
-    }
+    njs_vm_error(vm, "%*s", size, description);
 
-    error = njs_error_alloc(vm, NJS_OBJ_TYPE_ERROR, NULL, &value, NULL);
-    if (njs_slow_path(error == NULL)) {
-        return NJS_ERROR;
-    }
-
-    njs_set_object(retval, error);
+    njs_vm_exception_get(vm, njs_value_arg(retval));
 
     if (errn != 0) {
-        njs_set_number(&value, errn);
-        ret = njs_value_property_set(vm, retval, njs_value_arg(&string_errno),
-                                     &value);
+        njs_value_number_set(njs_value_arg(&value), errn);
+        ret = njs_vm_object_prop_set(vm, njs_value_arg(retval),
+                                     &string_errno, &value);
         if (njs_slow_path(ret != NJS_OK)) {
             return NJS_ERROR;
         }
 
         code = njs_errno_string(errn);
 
-        ret = njs_string_create(vm, &value, code, njs_strlen(code));
+        ret = njs_vm_value_string_create(vm, njs_value_arg(&value),
+                                         (u_char *) code, njs_strlen(code));
         if (njs_slow_path(ret != NJS_OK)) {
             return NJS_ERROR;
         }
 
-        ret = njs_value_property_set(vm, retval, njs_value_arg(&string_code),
+        ret = njs_vm_object_prop_set(vm, njs_value_arg(retval), &string_code,
                                      &value);
         if (njs_slow_path(ret != NJS_OK)) {
             return NJS_ERROR;
@@ -3034,12 +3182,13 @@ njs_fs_error(njs_vm_t *vm, const char *syscall, const char *description,
     }
 
     if (path != NULL) {
-        ret = njs_string_create(vm, &value, path, njs_strlen(path));
+        ret = njs_vm_value_string_create(vm, njs_value_arg(&value),
+                                         (u_char *) path, njs_strlen(path));
         if (njs_slow_path(ret != NJS_OK)) {
             return NJS_ERROR;
         }
 
-        ret = njs_value_property_set(vm, retval, njs_value_arg(&string_path),
+        ret = njs_vm_object_prop_set(vm, njs_value_arg(retval), &string_path,
                                      &value);
         if (njs_slow_path(ret != NJS_OK)) {
             return NJS_ERROR;
@@ -3047,12 +3196,14 @@ njs_fs_error(njs_vm_t *vm, const char *syscall, const char *description,
     }
 
     if (syscall != NULL) {
-        ret = njs_string_create(vm, &value, syscall, njs_strlen(syscall));
+        ret = njs_vm_value_string_create(vm, njs_value_arg(&value),
+                                         (u_char *) syscall,
+                                         njs_strlen(syscall));
         if (njs_slow_path(ret != NJS_OK)) {
             return NJS_ERROR;
         }
 
-        ret = njs_value_property_set(vm, retval, njs_value_arg(&string_syscall),
+        ret = njs_vm_object_prop_set(vm, njs_value_arg(retval), &string_syscall,
                                      &value);
         if (njs_slow_path(ret != NJS_OK)) {
             return NJS_ERROR;
@@ -3067,28 +3218,27 @@ static njs_int_t
 ngx_fs_promise_trampoline(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused, njs_value_t *retval)
 {
-    njs_value_t value;
+    njs_function_t  *callback;
 
-    return njs_function_call(vm, njs_function(&args[1]), &njs_value_undefined,
-                             &args[2], 1, &value);
-}
+    callback = njs_value_function(njs_argument(args, 1));
 
-
-static const njs_value_t  promise_trampoline  =
-    njs_native_function(ngx_fs_promise_trampoline, 2);
+    return njs_vm_call(vm, callback, njs_argument(args, 2), 1);
+}
 
 
 static njs_int_t
-njs_fs_result(njs_vm_t *vm, njs_value_t *result, njs_index_t calltype,
+njs_fs_result(njs_vm_t *vm, njs_opaque_value_t *result, njs_index_t calltype,
     const njs_value_t *callback, njs_uint_t nargs, njs_value_t *retval)
 {
-    njs_int_t    ret;
-    njs_value_t  promise, callbacks[2], arguments[2];
+    njs_int_t           ret;
+    njs_vm_event_t      vm_event;
+    njs_function_t      *cb;
+    njs_opaque_value_t  promise, callbacks[2], arguments[2];
 
     switch (calltype) {
     case NJS_FS_DIRECT:
-        if (njs_is_error(result)) {
-            njs_vm_throw(vm, result);
+        if (njs_value_is_error(njs_value_arg(result))) {
+            njs_vm_throw(vm, njs_value_arg(result));
             return NJS_ERROR;
         }
 
@@ -3096,18 +3246,29 @@ njs_fs_result(njs_vm_t *vm, njs_value_t *result, njs_index_t calltype,
         return NJS_OK;
 
     case NJS_FS_PROMISE:
-        ret = njs_vm_promise_create(vm, &promise, &callbacks[0]);
+        ret = njs_vm_promise_create(vm, njs_value_arg(&promise),
+                                    njs_value_arg(&callbacks[0]));
         if (njs_slow_path(ret != NJS_OK)) {
             return ret;
         }
 
-        arguments[0] = njs_is_error(result) ? callbacks[1] : callbacks[0];
-        arguments[1] = *result;
+        cb = njs_vm_function_alloc(vm, ngx_fs_promise_trampoline, 0, 0);
+        if (njs_slow_path(cb == NULL)) {
+            return NJS_ERROR;
+        }
 
-        ret = njs_fs_add_event(vm, njs_value_arg(&promise_trampoline),
-                               njs_value_arg(&arguments), 2);
-        if (njs_slow_path(ret != NJS_OK)) {
-            return ret;
+        vm_event = njs_vm_add_event(vm, cb, 1, NULL, NULL);
+        if (njs_slow_path(vm_event == NULL)) {
+            return NJS_ERROR;
+        }
+
+        njs_value_assign(&arguments[0],
+                         &callbacks[njs_value_is_error(njs_value_arg(result))]);
+        njs_value_assign(&arguments[1], result);
+
+        ret = njs_vm_post_event(vm, vm_event, njs_value_arg(&arguments), 2);
+        if (njs_slow_path(ret == NJS_ERROR)) {
+            return NJS_ERROR;
         }
 
         njs_value_assign(retval, &promise);
@@ -3115,77 +3276,35 @@ njs_fs_result(njs_vm_t *vm, njs_value_t *result, njs_index_t calltype,
         return NJS_OK;
 
     case NJS_FS_CALLBACK:
-        if (njs_is_error(result)) {
-            arguments[0] = *result;
-            njs_set_undefined(&arguments[1]);
+        if (njs_value_is_error(njs_value_arg(result))) {
+            njs_value_assign(&arguments[0], result);
+            njs_value_undefined_set(njs_value_arg(&arguments[1]));
 
         } else {
-            njs_set_undefined(&arguments[0]);
-            arguments[1] = *result;
+            njs_value_undefined_set(njs_value_arg(&arguments[0]));
+            njs_value_assign(&arguments[1], result);
         }
 
-        ret = njs_fs_add_event(vm, callback, njs_value_arg(&arguments),
-                               nargs);
-        if (njs_slow_path(ret != NJS_OK)) {
-            return ret;
+        vm_event = njs_vm_add_event(vm, njs_value_function(callback), 1, NULL,
+                                    NULL);
+        if (njs_slow_path(vm_event == NULL)) {
+            return NJS_ERROR;
         }
 
-        njs_set_undefined(retval);
+        ret = njs_vm_post_event(vm, vm_event, njs_value_arg(&arguments), 2);
+        if (njs_slow_path(ret == NJS_ERROR)) {
+            return NJS_ERROR;
+        }
+
+        njs_value_undefined_set(retval);
 
         return NJS_OK;
 
     default:
-        njs_internal_error(vm, "invalid calltype");
-
-        return NJS_ERROR;
-    }
-}
-
-
-static njs_int_t
-njs_fs_add_event(njs_vm_t *vm, const njs_value_t *callback,
-    const njs_value_t *args, njs_uint_t nargs)
-{
-    njs_event_t   *event;
-    njs_vm_ops_t  *ops;
-
-    ops = vm->options.ops;
-    if (njs_slow_path(ops == NULL)) {
-        njs_internal_error(vm, "not supported by host environment");
-        return NJS_ERROR;
-    }
+        njs_vm_error(vm, "invalid calltype");
 
-    event = njs_mp_alloc(vm->mem_pool, sizeof(njs_event_t));
-    if (njs_slow_path(event == NULL)) {
-        goto memory_error;
-    }
-
-    event->destructor = ops->clear_timer;
-    event->function = njs_function(callback);
-    event->nargs = nargs;
-    event->once = 1;
-    event->posted = 0;
-
-    event->args = njs_mp_alloc(vm->mem_pool, sizeof(njs_value_t) * nargs);
-    if (njs_slow_path(event->args == NULL)) {
-        goto memory_error;
-    }
-
-    memcpy(event->args, args, sizeof(njs_value_t) * nargs);
-
-    event->host_event = ops->set_timer(vm->external, 0, event);
-    if (njs_slow_path(event->host_event == NULL)) {
-        njs_internal_error(vm, "set_timer() failed");
         return NJS_ERROR;
     }
-
-    return njs_add_event(vm, event);
-
-memory_error:
-
-    njs_memory_error(vm);
-
-    return NJS_ERROR;
 }
 
 
@@ -3195,23 +3314,23 @@ njs_fs_dirent_create(njs_vm_t *vm, njs_value_t *name, njs_value_t *type,
 {
     njs_int_t  ret;
 
-    static const njs_value_t  string_name = njs_string("name");
-    static const njs_value_t  string_type = njs_string("type");
+    static const njs_str_t  string_name = njs_str("name");
+    static const njs_str_t  string_type = njs_str("type");
 
     ret = njs_vm_external_create(vm, retval, njs_fs_dirent_proto_id, NULL, 0);
     if (njs_slow_path(ret != NJS_OK)) {
         return ret;
     }
 
-    ret = njs_value_property_set(vm, retval, njs_value_arg(&string_name),
-                                 name);
+    ret = njs_vm_object_prop_set(vm, retval, &string_name,
+                                 (njs_opaque_value_t *) name);
     if (njs_slow_path(ret != NJS_OK)) {
         return ret;
     }
 
     /* TODO: use a private symbol as a key. */
-    return njs_value_property_set(vm, retval, njs_value_arg(&string_type),
-                                  type);
+    return njs_vm_object_prop_set(vm, retval, &string_type,
+                                  (njs_opaque_value_t *) type);
 }
 
 
@@ -3219,8 +3338,8 @@ 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)
 {
-    if (njs_slow_path(!vm->top_frame->ctor)) {
-        njs_type_error(vm, "the Dirent constructor must be called with new");
+    if (njs_slow_path(!njs_vm_constructor(vm))) {
+        njs_vm_error(vm, "the Dirent constructor must be called with new");
         return NJS_ERROR;
     }
 
@@ -3229,47 +3348,30 @@ njs_fs_dirent_constructor(njs_vm_t *vm, njs_value_t *args,
 }
 
 
-static const njs_object_prop_t  njs_dirent_constructor_properties[] =
-{
-    NJS_DECLARE_PROP_NAME("Dirent"),
-
-    NJS_DECLARE_PROP_LENGTH(2),
-
-    NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0),
-};
-
-
-const njs_object_init_t  njs_dirent_constructor_init = {
-    njs_dirent_constructor_properties,
-    njs_nitems(njs_dirent_constructor_properties),
-};
-
-
 static njs_int_t
 njs_fs_dirent_test(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t testtype, njs_value_t *retval)
 {
-    njs_int_t    ret;
-    njs_value_t  type, *this;
+    njs_value_t         *type;
+    njs_opaque_value_t  lvalue;
 
-    static const njs_value_t  string_type = njs_string("type");
+    static const njs_str_t  string_type = njs_str("type");
 
-    this = njs_argument(args, 0);
-
-    ret = njs_value_property(vm, this, njs_value_arg(&string_type), &type);
-    if (njs_slow_path(ret == NJS_ERROR)) {
-        return ret;
+    type = njs_vm_object_prop(vm, njs_argument(args, 0), &string_type, &lvalue);
+    if (njs_slow_path(type == NULL)) {
+        return NJS_ERROR;
     }
 
-    if (njs_slow_path(njs_is_number(&type)
-                      && (njs_number(&type) == NJS_DT_INVALID)))
+    if (njs_slow_path(njs_value_is_number(type)
+                      && (njs_value_number(type) == NJS_DT_INVALID)))
     {
-        njs_internal_error(vm, "dentry type is not supported on this platform");
+        njs_vm_error(vm, "dentry type is not supported on this platform");
         return NJS_ERROR;
     }
 
-    njs_set_boolean(retval,
-                    njs_is_number(&type) && testtype == njs_number(&type));
+    njs_value_boolean_set(retval,
+                          njs_value_is_number(type)
+                          && testtype == njs_value_number(type));
 
     return NJS_OK;
 }
@@ -3337,9 +3439,9 @@ njs_fs_stats_create(njs_vm_t *vm, struct stat *st, njs_value_t *retval)
 {
     njs_stat_t  *stat;
 
-    stat = njs_mp_alloc(vm->mem_pool, sizeof(njs_stat_t));
+    stat = njs_mp_alloc(njs_vm_memory_pool(vm), sizeof(njs_stat_t));
     if (njs_slow_path(stat == NULL)) {
-        njs_memory_error(vm);
+        njs_vm_memory_error(vm);
         return NJS_ERROR;
     }
 
@@ -3392,7 +3494,7 @@ njs_fs_stats_test(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         mask = S_IFSOCK;
     }
 
-    njs_set_boolean(retval, (st->st_mode & S_IFMT) == mask);
+    njs_value_boolean_set(retval, (st->st_mode & S_IFMT) == mask);
 
     return NJS_OK;
 }
@@ -3403,7 +3505,7 @@ 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)
 {
     double      v;
-    njs_date_t  *date;
+    njs_int_t   ret;
     njs_stat_t  *st;
 
 #define njs_fs_time_ms(ts) ((ts)->tv_sec * 1000.0 + (ts)->tv_nsec / 1000000.0)
@@ -3413,7 +3515,7 @@ njs_fs_stats_prop(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value,
         return NJS_DECLINED;
     }
 
-    switch (njs_prop_magic32(prop) & 0xf) {
+    switch (njs_vm_prop_magic32(prop) & 0xf) {
     case NJS_FS_STAT_DEV:
         v = st->st_dev;
         break;
@@ -3472,19 +3574,18 @@ njs_fs_stats_prop(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value,
         break;
     }
 
-    switch (njs_prop_magic32(prop) >> 4) {
-    case NJS_NUMBER:
-        njs_set_number(retval, v);
+    switch (njs_vm_prop_magic32(prop) >> 4) {
+    case 0:
+        njs_value_number_set(retval, v);
         break;
 
-    case NJS_DATE:
+    case 1:
     default:
-        date = njs_date_alloc(vm, v);
-        if (njs_slow_path(date == NULL)) {
+        ret = njs_vm_date_alloc(vm, retval, v);
+        if (njs_slow_path(ret != NJS_OK)) {
             return NJS_ERROR;
         }
 
-        njs_set_date(retval, date);
         break;
     }
 
@@ -3496,24 +3597,24 @@ static njs_int_t
 njs_fs_filehandle_close(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused, njs_value_t *retval)
 {
-    njs_value_t       result;
-    njs_filehandle_t  *fh;
+    njs_filehandle_t    *fh;
+    njs_opaque_value_t  result;
 
     fh = njs_vm_external(vm, njs_fs_filehandle_proto_id, njs_argument(args, 0));
     if (njs_slow_path(fh == NULL)) {
-        njs_type_error(vm, "\"this\" is not a filehandle object");
+        njs_vm_error(vm, "\"this\" is not a filehandle object");
         return NJS_ERROR;
     }
 
     if (njs_slow_path(fh->fd == -1)) {
-        njs_type_error(vm, "file was already closed");
+        njs_vm_error(vm, "file was already closed");
         return NJS_ERROR;
     }
 
     (void) close(fh->fd);
     fh->fd = -1;
 
-    njs_set_undefined(&result);
+    njs_value_undefined_set(njs_value_arg(&result));
 
     return njs_fs_result(vm, &result, NJS_FS_PROMISE, NULL, 1, retval);
 }
@@ -3527,11 +3628,11 @@ njs_fs_filehandle_value_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     fh = njs_vm_external(vm, njs_fs_filehandle_proto_id, njs_argument(args, 0));
     if (njs_slow_path(fh == NULL)) {
-        njs_type_error(vm, "\"this\" is not a filehandle object");
+        njs_vm_error(vm, "\"this\" is not a filehandle object");
         return NJS_ERROR;
     }
 
-    njs_set_number(retval, fh->fd);
+    njs_value_number_set(retval, fh->fd);
 
     return NJS_OK;
 }
@@ -3551,14 +3652,14 @@ njs_fs_filehandle_cleanup(void *data)
 
 static njs_int_t
 njs_fs_filehandle_create(njs_vm_t *vm, int fd, njs_bool_t shadow,
-    njs_value_t *retval)
+    njs_opaque_value_t *retval)
 {
     njs_filehandle_t  *fh;
     njs_mp_cleanup_t  *cln;
 
-    fh = njs_mp_alloc(vm->mem_pool, sizeof(njs_filehandle_t));
+    fh = njs_mp_alloc(njs_vm_memory_pool(vm), sizeof(njs_filehandle_t));
     if (njs_slow_path(fh == NULL)) {
-        njs_memory_error(vm);
+        njs_vm_memory_error(vm);
         return NJS_ERROR;
     }
 
@@ -3567,143 +3668,65 @@ njs_fs_filehandle_create(njs_vm_t *vm, int fd, njs_bool_t shadow,
 
     cln = njs_mp_cleanup_add(njs_vm_memory_pool(vm), 0);
     if (cln == NULL) {
-        njs_memory_error(vm);
+        njs_vm_memory_error(vm);
         return NJS_ERROR;
     }
 
     cln->handler = njs_fs_filehandle_cleanup;
     cln->data = fh;
 
-    return njs_vm_external_create(vm, retval, njs_fs_filehandle_proto_id,
-                                  fh, 0);
+    return njs_vm_external_create(vm, njs_value_arg(retval),
+                                  njs_fs_filehandle_proto_id, fh, 0);
 }
 
 
 static njs_int_t
 njs_fs_bytes_read_create(njs_vm_t *vm, int bytes, njs_value_t *buffer,
-    njs_value_t *retval)
+    njs_opaque_value_t *retval)
 {
     njs_bytes_struct_t  *bs;
 
-    bs = njs_mp_alloc(vm->mem_pool, sizeof(njs_bytes_struct_t));
+    bs = njs_mp_alloc(njs_vm_memory_pool(vm), sizeof(njs_bytes_struct_t));
     if (njs_slow_path(bs == NULL)) {
-        njs_memory_error(vm);
+        njs_vm_memory_error(vm);
         return NJS_ERROR;
     }
 
     bs->bytes = bytes;
     njs_value_assign(&bs->buffer, buffer);
 
-    return njs_vm_external_create(vm, retval, njs_fs_bytes_read_proto_id,
-                                  bs, 0);
+    return njs_vm_external_create(vm, njs_value_arg(retval),
+                                  njs_fs_bytes_read_proto_id, bs, 0);
 }
 
 
 static njs_int_t
 njs_fs_bytes_written_create(njs_vm_t *vm, int bytes, njs_value_t *buffer,
-    njs_value_t *retval)
+    njs_opaque_value_t *retval)
 {
     njs_bytes_struct_t  *bs;
 
-    bs = njs_mp_alloc(vm->mem_pool, sizeof(njs_bytes_struct_t));
+    bs = njs_mp_alloc(njs_vm_memory_pool(vm), sizeof(njs_bytes_struct_t));
     if (njs_slow_path(bs == NULL)) {
-        njs_memory_error(vm);
+        njs_vm_memory_error(vm);
         return NJS_ERROR;
     }
 
     bs->bytes = bytes;
     njs_value_assign(&bs->buffer, buffer);
 
-    return njs_vm_external_create(vm, retval, njs_fs_bytes_written_proto_id,
-                                  bs, 0);
-}
-
-
-static const njs_object_prop_t  njs_fs_promises_properties[] =
-{
-    NJS_DECLARE_PROP_NATIVE("readFile", njs_fs_read_file, 0, NJS_FS_PROMISE),
-
-    NJS_DECLARE_PROP_NATIVE("readSync", njs_fs_read, 0, NJS_FS_PROMISE),
-
-    NJS_DECLARE_PROP_NATIVE("appendFile", njs_fs_write_file, 0,
-                            njs_fs_magic(NJS_FS_PROMISE, NJS_FS_APPEND)),
-
-    NJS_DECLARE_PROP_NATIVE("writeFile", njs_fs_write_file, 0,
-                            njs_fs_magic(NJS_FS_PROMISE, NJS_FS_TRUNC)),
-
-    NJS_DECLARE_PROP_NATIVE("access", njs_fs_access, 0, NJS_FS_PROMISE),
-
-    NJS_DECLARE_PROP_NATIVE("mkdir", njs_fs_mkdir, 0, NJS_FS_PROMISE),
-
-    NJS_DECLARE_PROP_NATIVE("open", njs_fs_open, 0, NJS_FS_PROMISE),
-
-    NJS_DECLARE_PROP_NATIVE("close", njs_fs_close, 0, NJS_FS_PROMISE),
-
-    NJS_DECLARE_PROP_NATIVE("rename", njs_fs_rename, 0, NJS_FS_PROMISE),
-
-    NJS_DECLARE_PROP_NATIVE("rmdir", njs_fs_rmdir, 0, NJS_FS_PROMISE),
-
-    NJS_DECLARE_PROP_NATIVE("readdir", njs_fs_readdir, 0, NJS_FS_PROMISE),
-
-    NJS_DECLARE_PROP_NATIVE("fstat", njs_fs_stat, 0,
-                            njs_fs_magic(NJS_FS_PROMISE, NJS_FS_FSTAT)),
-
-    NJS_DECLARE_PROP_NATIVE("lstat", njs_fs_stat, 0,
-                            njs_fs_magic(NJS_FS_PROMISE, NJS_FS_LSTAT)),
-
-    NJS_DECLARE_PROP_NATIVE("stat", njs_fs_stat, 0,
-                            njs_fs_magic(NJS_FS_PROMISE, NJS_FS_STAT)),
-
-    NJS_DECLARE_PROP_NATIVE("symlink", njs_fs_symlink, 0, NJS_FS_PROMISE),
-
-    NJS_DECLARE_PROP_NATIVE("unlink", njs_fs_unlink, 0, NJS_FS_PROMISE),
-
-    NJS_DECLARE_PROP_NATIVE("realpath", njs_fs_realpath, 0, NJS_FS_PROMISE),
-};
-
-
-static const njs_object_init_t  njs_fs_promises_init = {
-    njs_fs_promises_properties,
-    njs_nitems(njs_fs_promises_properties),
-};
-
-
-static njs_int_t
-njs_fs_promises(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value,
-    njs_value_t *unused, njs_value_t *retval)
-{
-    return njs_object_prop_init(vm, &njs_fs_promises_init, prop, value, retval);
+    return njs_vm_external_create(vm, njs_value_arg(retval),
+                                  njs_fs_bytes_written_proto_id, bs, 0);
 }
 
 
-static const njs_object_prop_t  njs_fs_constants_properties[] =
+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_DECLARE_PROP_VALUE("F_OK", njs_value(NJS_NUMBER, 0, F_OK),
-                           NJS_OBJECT_PROP_VALUE_E),
-
-    NJS_DECLARE_PROP_VALUE("R_OK", njs_value(NJS_NUMBER, 0, R_OK),
-                           NJS_OBJECT_PROP_VALUE_E),
-
-    NJS_DECLARE_PROP_VALUE("W_OK", njs_value(NJS_NUMBER, 0, W_OK),
-                           NJS_OBJECT_PROP_VALUE_E),
-
-    NJS_DECLARE_PROP_VALUE("X_OK", njs_value(NJS_NUMBER, 0, X_OK),
-                           NJS_OBJECT_PROP_VALUE_E),
-};
+    njs_value_number_set(retval,  njs_vm_prop_magic32(prop));
 
-
-static const njs_object_init_t  njs_fs_constants_init = {
-    njs_fs_constants_properties,
-    njs_nitems(njs_fs_constants_properties),
-};
-
-
-static njs_int_t
-njs_fs_constants(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value,
-    njs_value_t *unused, njs_value_t *retval)
-{
-    return njs_object_prop_init(vm, &njs_fs_constants_init, prop, value,
-                                retval);
+    return NJS_OK;
 }
 
 
@@ -3714,7 +3737,7 @@ njs_fs_init(njs_vm_t *vm)
     njs_mod_t           *module;
     njs_opaque_value_t  value;
 
-    if (vm->options.sandbox) {
+    if (njs_vm_options(vm)->sandbox) {
         return NJS_OK;
     }
 
index 38f92d4a6359e77b35477824ccc568083ddb62c3..34e95e0f3d2ddc03441b5e147d824ec2fd242273 100644 (file)
--- a/src/njs.h
+++ b/src/njs.h
@@ -387,6 +387,7 @@ NJS_EXPORT njs_int_t njs_value_property(njs_vm_t *vm, njs_value_t *value,
 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);
 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_function_t *njs_vm_function_alloc(njs_vm_t *vm,
     njs_function_native_t native, njs_bool_t shared, njs_bool_t ctor);
@@ -398,6 +399,7 @@ NJS_EXPORT njs_int_t njs_vm_bind(njs_vm_t *vm, const njs_str_t *var_name,
 NJS_EXPORT njs_int_t njs_vm_value(njs_vm_t *vm, const njs_str_t *path,
     njs_value_t *retval);
 NJS_EXPORT njs_function_t *njs_vm_function(njs_vm_t *vm, const njs_str_t *name);
+NJS_EXPORT njs_bool_t njs_vm_constructor(njs_vm_t *vm);
 
 NJS_EXPORT void njs_vm_throw(njs_vm_t *vm, const njs_value_t *value);
 NJS_EXPORT void njs_vm_error(njs_vm_t *vm, const char *fmt, ...);
@@ -405,6 +407,9 @@ NJS_EXPORT void njs_vm_exception_get(njs_vm_t *vm, njs_value_t *retval);
 NJS_EXPORT njs_mp_t *njs_vm_memory_pool(njs_vm_t *vm);
 NJS_EXPORT njs_external_ptr_t njs_vm_external_ptr(njs_vm_t *vm);
 
+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);
 /*
@@ -501,9 +506,11 @@ NJS_EXPORT njs_int_t njs_value_is_number(const njs_value_t *value);
 NJS_EXPORT njs_int_t njs_value_is_valid_number(const njs_value_t *value);
 NJS_EXPORT njs_int_t njs_value_is_string(const njs_value_t *value);
 NJS_EXPORT njs_int_t njs_value_is_object(const njs_value_t *value);
+NJS_EXPORT njs_int_t njs_value_is_error(const njs_value_t *value);
 NJS_EXPORT njs_int_t njs_value_is_array(const njs_value_t *value);
 NJS_EXPORT njs_int_t njs_value_is_function(const njs_value_t *value);
 NJS_EXPORT njs_int_t njs_value_is_buffer(const njs_value_t *value);
+NJS_EXPORT njs_int_t njs_value_is_data_view(const njs_value_t *value);
 
 NJS_EXPORT njs_int_t njs_vm_object_alloc(njs_vm_t *vm, njs_value_t *retval,
     ...);
@@ -511,6 +518,8 @@ NJS_EXPORT njs_value_t *njs_vm_object_keys(njs_vm_t *vm, njs_value_t *value,
     njs_value_t *retval);
 NJS_EXPORT njs_value_t *njs_vm_object_prop(njs_vm_t *vm,
     njs_value_t *value, const njs_str_t *key, njs_opaque_value_t *retval);
+NJS_EXPORT njs_int_t njs_vm_object_prop_set(njs_vm_t *vm, njs_value_t *value,
+    const njs_str_t *prop, njs_opaque_value_t *setval);
 
 NJS_EXPORT njs_int_t njs_vm_array_alloc(njs_vm_t *vm, njs_value_t *retval,
     uint32_t spare);
@@ -520,6 +529,8 @@ NJS_EXPORT njs_value_t *njs_vm_array_start(njs_vm_t *vm, njs_value_t *value);
 NJS_EXPORT njs_value_t *njs_vm_array_prop(njs_vm_t *vm,
     njs_value_t *value, int64_t index, njs_opaque_value_t *retval);
 NJS_EXPORT njs_value_t *njs_vm_array_push(njs_vm_t *vm, njs_value_t *value);
+NJS_EXPORT njs_int_t njs_vm_date_alloc(njs_vm_t *vm, njs_value_t *retval,
+    double time);
 
 NJS_EXPORT njs_int_t njs_vm_json_parse(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_value_t *retval);
index 22bb87c35bd2e79edf50e24d3dc302795cc2c077..a5fec855c926c358ac6f8abbb5b8810af88ed74f 100644 (file)
@@ -569,6 +569,13 @@ njs_value_is_object(const njs_value_t *value)
 }
 
 
+njs_int_t
+njs_value_is_error(const njs_value_t *value)
+{
+    return njs_is_error(value);
+}
+
+
 njs_int_t
 njs_value_is_array(const njs_value_t *value)
 {
@@ -590,6 +597,13 @@ njs_value_is_buffer(const njs_value_t *value)
 }
 
 
+njs_int_t
+njs_value_is_data_view(const njs_value_t *value)
+{
+    return njs_is_data_view(value);
+}
+
+
 /*
  * ES5.1, 8.12.1: [[GetOwnProperty]], [[GetProperty]].
  * The njs_property_query() returns values
@@ -1606,6 +1620,23 @@ njs_primitive_value_to_chain(njs_vm_t *vm, njs_chb_t *chain,
 }
 
 
+njs_int_t
+njs_value_to_integer(njs_vm_t *vm, njs_value_t *value, int64_t *dst)
+{
+    double     num;
+    njs_int_t  ret;
+
+    ret = njs_value_to_number(vm, value, &num);
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
+    }
+
+    *dst = njs_number_to_integer(num);
+
+    return NJS_OK;
+}
+
+
 njs_int_t
 njs_value_to_object(njs_vm_t *vm, njs_value_t *value)
 {
index ba82ec18ec1c496fef756ef70a6ba9ee891065b4..f5a0e6767ea9daed393ab01898c535f7efaaa2bf 100644 (file)
@@ -62,23 +62,6 @@ njs_value_to_numeric(njs_vm_t *vm, njs_value_t *value, njs_value_t *dst)
 }
 
 
-njs_inline njs_int_t
-njs_value_to_integer(njs_vm_t *vm, njs_value_t *value, int64_t *dst)
-{
-    double     num;
-    njs_int_t  ret;
-
-    ret = njs_value_to_number(vm, value, &num);
-    if (njs_slow_path(ret != NJS_OK)) {
-        return ret;
-    }
-
-    *dst = njs_number_to_integer(num);
-
-    return NJS_OK;
-}
-
-
 njs_inline njs_int_t
 njs_value_to_length(njs_vm_t *vm, njs_value_t *value, int64_t *dst)
 {
index c28c0847b74b1e398ac09c581aac15d9956267c2..90a1795385ab1dc617a5ac85d6f9fef0c7439674 100644 (file)
@@ -687,6 +687,13 @@ njs_vm_external_ptr(njs_vm_t *vm)
 }
 
 
+njs_bool_t
+njs_vm_constructor(njs_vm_t *vm)
+{
+    return vm->top_frame->ctor;
+}
+
+
 uintptr_t
 njs_vm_meta(njs_vm_t *vm, njs_uint_t index)
 {
@@ -701,6 +708,13 @@ njs_vm_meta(njs_vm_t *vm, njs_uint_t index)
 }
 
 
+njs_vm_opt_t *
+njs_vm_options(njs_vm_t *vm)
+{
+    return &vm->options;
+}
+
+
 void
 njs_vm_throw(njs_vm_t *vm, const njs_value_t *value)
 {
@@ -1144,6 +1158,32 @@ njs_vm_object_prop(njs_vm_t *vm, njs_value_t *value, const njs_str_t *prop,
 }
 
 
+njs_int_t
+njs_vm_object_prop_set(njs_vm_t *vm, njs_value_t *value, const njs_str_t *prop,
+    njs_opaque_value_t *setval)
+{
+    njs_int_t    ret;
+    njs_value_t  key;
+
+    if (njs_slow_path(!njs_is_object(value))) {
+        njs_type_error(vm, "njs_vm_object_prop_set() argument is not object");
+        return NJS_ERROR;
+    }
+
+    ret = njs_vm_value_string_set(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));
+    if (njs_slow_path(ret != NJS_OK)) {
+        return NJS_ERROR;
+    }
+
+    return NJS_OK;
+}
+
+
 njs_value_t *
 njs_vm_array_prop(njs_vm_t *vm, njs_value_t *value, int64_t index,
     njs_opaque_value_t *retval)
@@ -1198,6 +1238,22 @@ njs_vm_array_length(njs_vm_t *vm, njs_value_t *value, int64_t *length)
 }
 
 
+njs_int_t
+njs_vm_date_alloc(njs_vm_t *vm, njs_value_t *retval, double time)
+{
+    njs_date_t  *date;
+
+    date = njs_date_alloc(vm, time);
+    if (njs_slow_path(date == NULL)) {
+        return NJS_ERROR;
+    }
+
+    njs_set_date(retval, date);
+
+    return NJS_OK;
+}
+
+
 njs_int_t
 njs_vm_value_to_string(njs_vm_t *vm, njs_str_t *dst, njs_value_t *src)
 {
index b47ac35a0abcfbd3b12d3724de9eae22589389b6..522af156d2a32c87f2e4cc97204f14e8f734b77d 100644 (file)
@@ -20035,32 +20035,32 @@ static njs_unit_test_t  njs_fs_module_test[] =
 
     { njs_str("var fs = require('fs');"
               "fs.readFile()"),
-      njs_str("TypeError: \"path\" must be a string or Buffer") },
+      njs_str("Error: \"path\" must be a string or Buffer") },
 
     { njs_str("var fs = require('fs');"
               "var path = Buffer.from('/broken'); path[3] = 0;"
               "fs.readFile(path)"),
-      njs_str("TypeError: \"path\" must be a Buffer without null bytes") },
+      njs_str("Error: \"path\" must be a Buffer without null bytes") },
 
     { njs_str("var fs = require('fs');"
               "fs.readFile('/njs_unknown_path')"),
-      njs_str("TypeError: \"callback\" must be a function") },
+      njs_str("Error: \"callback\" must be a function") },
 
     { njs_str("var fs = require('fs');"
               "fs.readFile('/njs_unknown_path', 'utf8')"),
-      njs_str("TypeError: \"callback\" must be a function") },
+      njs_str("Error: \"callback\" must be a function") },
 
     { njs_str("var fs = require('fs');"
               "fs.readFile('/njs_unknown_path', {flag:'xx'})"),
-      njs_str("TypeError: \"callback\" must be a function") },
+      njs_str("Error: \"callback\" must be a function") },
 
     { njs_str("var fs = require('fs');"
               "fs.readFile('/njs_unknown_path', {flag:'xx'}, 1)"),
-      njs_str("TypeError: \"callback\" must be a function") },
+      njs_str("Error: \"callback\" must be a function") },
 
     { njs_str("var fs = require('fs');"
               "fs.readFile('/njs_unknown_path', {flag:'xx'}, function () {})"),
-      njs_str("TypeError: Unknown file open flags: \"xx\"") },
+      njs_str("Error: Unknown file open flags: \"xx\"") },
 
     { njs_str("var fs = require('fs');"
               "fs.readFile('/njs_unknown_path', {encoding:'ascii'}, function () {})"),
@@ -20074,15 +20074,15 @@ static njs_unit_test_t  njs_fs_module_test[] =
 
     { njs_str("var fs = require('fs');"
               "fs.readFileSync()"),
-      njs_str("TypeError: \"path\" must be a string or Buffer") },
+      njs_str("Error: \"path\" must be a string or Buffer") },
 
     { njs_str("var fs = require('fs');"
               "fs.readFileSync({})"),
-      njs_str("TypeError: \"path\" must be a string or Buffer") },
+      njs_str("Error: \"path\" must be a string or Buffer") },
 
     { njs_str("var fs = require('fs');"
               "fs.readFileSync('/njs_unknown_path', {flag:'xx'})"),
-      njs_str("TypeError: Unknown file open flags: \"xx\"") },
+      njs_str("Error: Unknown file open flags: \"xx\"") },
 
     { njs_str("var fs = require('fs');"
               "fs.readFileSync(Buffer.from('/njs_unknown_path'), {encoding:'ascii'})"),
@@ -20094,38 +20094,38 @@ static njs_unit_test_t  njs_fs_module_test[] =
 
     { njs_str("var fs = require('fs');"
               "fs.readFileSync('/njs_unknown_path', true)"),
-      njs_str("TypeError: Unknown options type: \"boolean\" (a string or object required)") },
+      njs_str("Error: Unknown options type (a string or object required)") },
 
 
     /* require('fs').writeFile() */
 
     { njs_str("var fs = require('fs');"
               "fs.writeFile()"),
-      njs_str("TypeError: \"path\" must be a string or Buffer") },
+      njs_str("Error: \"path\" must be a string or Buffer") },
 
     { njs_str("var fs = require('fs');"
               "fs.writeFile({}, '', function () {})"),
-      njs_str("TypeError: \"path\" must be a string or Buffer") },
+      njs_str("Error: \"path\" must be a string or Buffer") },
 
     { njs_str("var fs = require('fs');"
               "fs.writeFile('/njs_unknown_path')"),
-      njs_str("TypeError: \"callback\" must be a function") },
+      njs_str("Error: \"callback\" must be a function") },
 
     { njs_str("var fs = require('fs');"
               "fs.writeFile('/njs_unknown_path', '')"),
-      njs_str("TypeError: \"callback\" must be a function") },
+      njs_str("Error: \"callback\" must be a function") },
 
     { njs_str("var fs = require('fs');"
               "fs.writeFile('/njs_unknown_path', '', undefined)"),
-      njs_str("TypeError: \"callback\" must be a function") },
+      njs_str("Error: \"callback\" must be a function") },
 
     { njs_str("var fs = require('fs');"
               "fs.writeFile('/njs_unknown_path', '', 'utf8')"),
-      njs_str("TypeError: \"callback\" must be a function") },
+      njs_str("Error: \"callback\" must be a function") },
 
     { njs_str("var fs = require('fs');"
               "fs.writeFile('/njs_unknown_path', '', {flag:'xx'}, function () {})"),
-      njs_str("TypeError: Unknown file open flags: \"xx\"") },
+      njs_str("Error: Unknown file open flags: \"xx\"") },
 
     { njs_str("var fs = require('fs');"
               "fs.writeFile('/njs_unknown_path', '', {encoding:'ascii'}, function () {})"),
@@ -20137,21 +20137,21 @@ static njs_unit_test_t  njs_fs_module_test[] =
 
     { njs_str("var fs = require('fs');"
               "fs.writeFile('/njs_unknown_path', '', true, function () {})"),
-      njs_str("TypeError: Unknown options type: \"boolean\" (a string or object required)") },
+      njs_str("Error: Unknown options type (a string or object required)") },
 
     /* require('fs').writeFileSync() */
 
     { njs_str("var fs = require('fs');"
               "fs.writeFileSync()"),
-      njs_str("TypeError: \"path\" must be a string or Buffer") },
+      njs_str("Error: \"path\" must be a string or Buffer") },
 
     { njs_str("var fs = require('fs');"
               "fs.writeFileSync({}, '')"),
-      njs_str("TypeError: \"path\" must be a string or Buffer") },
+      njs_str("Error: \"path\" must be a string or Buffer") },
 
     { njs_str("var fs = require('fs');"
               "fs.writeFileSync('/njs_unknown_path', '', {flag:'xx'})"),
-      njs_str("TypeError: Unknown file open flags: \"xx\"") },
+      njs_str("Error: Unknown file open flags: \"xx\"") },
 
     { njs_str("var fs = require('fs');"
               "fs.writeFileSync('/njs_unknown_path', '', {encoding:'ascii'})"),
@@ -20163,29 +20163,29 @@ static njs_unit_test_t  njs_fs_module_test[] =
 
     { njs_str("var fs = require('fs');"
               "fs.writeFileSync('/njs_unknown_path', '', true)"),
-      njs_str("TypeError: Unknown options type: \"boolean\" (a string or object required)") },
+      njs_str("Error: Unknown options type (a string or object required)") },
 
     /* require('fs').renameSync() */
 
     { njs_str("var fs = require('fs');"
               "fs.renameSync()"),
-      njs_str("TypeError: \"oldPath\" must be a string or Buffer") },
+      njs_str("Error: \"oldPath\" must be a string or Buffer") },
 
     { njs_str("var fs = require('fs');"
               "fs.renameSync('/njs_unknown_path')"),
-      njs_str("TypeError: \"newPath\" must be a string or Buffer") },
+      njs_str("Error: \"newPath\" must be a string or Buffer") },
 
     { njs_str("var fs = require('fs');"
               "[undefined, null, false, NaN, Symbol(), {}, Object('/njs_unknown_path')]"
               ".map((x) => { try { fs.renameSync(x, '/njs_unknown_path'); } "
-              "              catch (e) { return (e instanceof TypeError); } })"
+              "              catch (e) { return (e instanceof Error); } })"
               ".every((x) => x === true)"),
       njs_str("true")},
 
     { njs_str("var fs = require('fs');"
               "[undefined, null, false, NaN, Symbol(), {}, Object('/njs_unknown_path')]"
               ".map((x) => { try { fs.renameSync('/njs_unknown_path', x); } "
-              "              catch (e) { return (e instanceof TypeError); } })"
+              "              catch (e) { return (e instanceof Error); } })"
               ".every((x) => x === true)"),
       njs_str("true")},
 
@@ -20193,29 +20193,29 @@ static njs_unit_test_t  njs_fs_module_test[] =
 
     { njs_str("var fs = require('fs');"
               "fs.access()"),
-      njs_str("TypeError: \"path\" must be a string or Buffer") },
+      njs_str("Error: \"path\" must be a string or Buffer") },
 
     { njs_str("var fs = require('fs');"
               "fs.access('/njs_unknown_path')"),
-      njs_str("TypeError: \"callback\" must be a function") },
+      njs_str("Error: \"callback\" must be a function") },
 
     { njs_str("var fs = require('fs');"
               "fs.access('/njs_unknown_path', fs.constants.F_OK)"),
-      njs_str("TypeError: \"callback\" must be a function") },
+      njs_str("Error: \"callback\" must be a function") },
 
     { njs_str("var fs = require('fs');"
               "fs.access('/njs_unknown_path', 'fail', function () {})"),
-      njs_str("TypeError: \"mode\" must be a number") },
+      njs_str("Error: \"mode\" must be a number") },
 
     /* require('fs').accessSync() */
 
     { njs_str("var fs = require('fs');"
               "fs.accessSync()"),
-      njs_str("TypeError: \"path\" must be a string or Buffer") },
+      njs_str("Error: \"path\" must be a string or Buffer") },
 
     { njs_str("var fs = require('fs');"
               "fs.accessSync('/njs_unknown_path', 'fail')"),
-      njs_str("TypeError: \"mode\" must be a number") },
+      njs_str("Error: \"mode\" must be a number") },
 
     { njs_str("var "
               "fs = require('fs'),"
@@ -20246,7 +20246,7 @@ static njs_unit_test_t  njs_fs_module_test[] =
               "test = (fname) =>"
                 "[undefined, null, false, NaN, Symbol(), {}, Object('/njs_unknown_path')]"
                 ".map((x) => { try { fs[fname](x); } "
-                "              catch (e) { return (e instanceof TypeError); } })"
+                "              catch (e) { return (e instanceof Error); } })"
                 ".every((x) => x === true);"
               "func.map(test).every((x) => x)"),
       njs_str("true")},
@@ -20300,7 +20300,7 @@ static njs_unit_test_t  njs_fs_module_test[] =
 
     { njs_str("var fs = require('fs');"
               "fs.Dirent('file', 123)"),
-      njs_str("TypeError: the Dirent constructor must be called with new") },
+      njs_str("Error: the Dirent constructor must be called with new") },
 
     { njs_str("var fs = require('fs');"
               "var e = new fs.Dirent('file', 123); [e.name, e.type]"),
@@ -22800,12 +22800,12 @@ static njs_unit_test_t  njs_shared_test[] =
       njs_str("37") },
 
     { njs_str("var fs = require('fs'); fs.readFileSync()"),
-      njs_str("TypeError: \"path\" must be a string or Buffer\n"
+      njs_str("Error: \"path\" must be a string or Buffer\n"
               "    at fs.readFileSync (native)\n"
               "    at main (:1)\n") },
 
     { njs_str("import fs from 'fs'; fs.readFileSync()"),
-      njs_str("TypeError: \"path\" must be a string or Buffer\n"
+      njs_str("Error: \"path\" must be a string or Buffer\n"
               "    at fs.readFileSync (native)\n"
               "    at main (:1)\n") },
 
index 291db1627f699284af628cba3e44905f0c7252a0..1d39ff23ee6e9ea57409a2768fd7da48ab34b2a8 100644 (file)
@@ -898,8 +898,8 @@ let read_tests = () => [
         content: "ABC",
         read: [ [0, 5], ],
         check: (err, params) => {
-            if (err.name != "RangeError") {
-                throw Error(`${err.code} unexpected exception`);
+            if (err.message.indexOf('is out of range') == -1) {
+                throw Error(`${err.message} unexpected exception`);
             }
 
             return true;
@@ -910,8 +910,8 @@ let read_tests = () => [
         content: "ABC",
         read: [ [2, 3], ],
         check: (err, params) => {
-            if (err.name != "RangeError") {
-                throw Error(`${err.code} unexpected exception`);
+            if (err.message.indexOf('is out of range') == -1) {
+                throw Error(`${err.message} unexpected exception`);
             }
 
             return true;
@@ -1104,8 +1104,8 @@ let write_tests = () => [
         args: ["@", 'w'],
         write: [ [Buffer.from("__ABC__"), 8] ],
         check: (err, params) => {
-            if (err.name != "RangeError") {
-                throw Error(`${err.code} unexpected exception`);
+            if (err.message.indexOf('is out of range') == -1) {
+                throw Error(`${err.message} unexpected exception`);
             }
 
             return true;
@@ -1116,8 +1116,8 @@ let write_tests = () => [
         args: ["@", 'w'],
         write: [ [Buffer.from("__ABC__"), 7, 1] ],
         check: (err, params) => {
-            if (err.name != "RangeError") {
-                throw Error(`${err.code} unexpected exception`);
+            if (err.message.indexOf('is out of range') == -1) {
+                throw Error(`${err.message} unexpected exception`);
             }
 
             return true;
index 0b525fdcc7c812bfcb8f9d576dfee2ff866efe24..21ee3d786661841e51ead27649e0939d5197e4e5 100644 (file)
@@ -26,7 +26,7 @@ var match = (entry) => {
             return false;
         }
     } catch (e) {
-        if (e.name == 'InternalError') {
+        if (e.message == 'dentry type is not supported on this platform') {
             return true;
         }