[njs] Change: native methods are provided with retval argument.

Dmitry Volyntsev xeioex at nginx.com
Wed Apr 19 07:25:41 UTC 2023


details:   https://hg.nginx.org/njs/rev/0c95481158e4
branches:  
changeset: 2088:0c95481158e4
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Wed Apr 19 00:20:37 2023 -0700
description:
Change: native methods are provided with retval argument.

Previously, native methods were expected to return
their retval using vm->retval.  This caused problem in the part
(1aa137411b09, 293fe42c5e1c) because vm->retval can be overwritten
unexpectedly as a side-effect of operations like ToString(), ToNumber().

The fix is to never used a global retval. Instead methods
are provided with a retval argument to store their retval value.

As a part of the change, retval and exception values are split.
The normal value is returned in the retval argument.
The exception value is thrown by njs_vm_throw() or njs_vm_error().
The exception value can be acquired using njs_vm_exception_get().

diffstat:

 external/njs_crypto_module.c       |   32 +-
 external/njs_fs_module.c           |  289 +++++++++++++++++----------------
 external/njs_query_string_module.c |   32 +-
 external/njs_webcrypto_module.c    |  140 ++++++++-------
 external/njs_xml_module.c          |   62 +++---
 external/njs_zlib_module.c         |   12 +-
 nginx/ngx_http_js_module.c         |   67 ++++---
 nginx/ngx_js.c                     |   26 ++-
 nginx/ngx_js.h                     |    4 +-
 nginx/ngx_js_fetch.c               |  133 ++++++++-------
 nginx/ngx_js_fetch.h               |    2 +-
 nginx/ngx_stream_js_module.c       |   36 ++-
 src/njs.h                          |   32 +--
 src/njs_array.c                    |  235 +++++++++++++--------------
 src/njs_array.h                    |    2 +-
 src/njs_array_buffer.c             |   20 +-
 src/njs_async.c                    |   60 +++---
 src/njs_async.h                    |    4 +-
 src/njs_boolean.c                  |   15 +-
 src/njs_buffer.c                   |  216 +++++++++++++------------
 src/njs_buffer.h                   |    2 +-
 src/njs_builtin.c                  |   10 +-
 src/njs_date.c                     |   46 ++--
 src/njs_encoding.c                 |   41 ++--
 src/njs_error.c                    |   70 +++++--
 src/njs_error.h                    |   29 +-
 src/njs_function.c                 |   70 +++-----
 src/njs_function.h                 |   10 +-
 src/njs_generator.c                |    2 +-
 src/njs_iterator.c                 |   57 +++---
 src/njs_iterator.h                 |   10 +-
 src/njs_json.c                     |   43 +++-
 src/njs_math.c                     |   16 +-
 src/njs_module.c                   |    4 +-
 src/njs_module.h                   |    2 +-
 src/njs_number.c                   |  100 +++++-----
 src/njs_number.h                   |    8 +-
 src/njs_object.c                   |  155 ++++++++---------
 src/njs_object.h                   |    2 +-
 src/njs_object_prop.c              |    3 +-
 src/njs_parser.c                   |   23 +-
 src/njs_promise.c                  |  229 ++++++++++++++------------
 src/njs_promise.h                  |    4 +-
 src/njs_regexp.c                   |   82 ++++----
 src/njs_regexp.h                   |    5 +-
 src/njs_shell.c                    |   47 ++--
 src/njs_string.c                   |  315 ++++++++++++++++++------------------
 src/njs_string.h                   |   10 +-
 src/njs_symbol.c                   |   30 +-
 src/njs_timer.c                    |   18 +-
 src/njs_timer.h                    |    6 +-
 src/njs_typed_array.c              |  159 +++++++++---------
 src/njs_typed_array.h              |    2 +-
 src/njs_value.c                    |    5 +-
 src/njs_vm.c                       |  107 ++++++------
 src/njs_vm.h                       |    5 +-
 src/njs_vmcode.c                   |  267 +++++++++++++------------------
 src/njs_vmcode.h                   |    2 +-
 src/test/njs_benchmark.c           |   41 ++--
 src/test/njs_externals_test.c      |   33 +-
 src/test/njs_unit_test.c           |  102 +++++++----
 61 files changed, 1825 insertions(+), 1766 deletions(-)

diffs (truncated from 12324 to 1000 lines):

diff -r 5665eebfd00c -r 0c95481158e4 external/njs_crypto_module.c
--- a/external/njs_crypto_module.c	Wed Apr 12 18:26:42 2023 -0700
+++ b/external/njs_crypto_module.c	Wed Apr 19 00:20:37 2023 -0700
@@ -62,15 +62,15 @@ static njs_crypto_enc_t *njs_crypto_enco
 static njs_int_t njs_buffer_digest(njs_vm_t *vm, njs_value_t *value,
     const njs_str_t *src);
 static njs_int_t njs_crypto_create_hash(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t unused);
+    njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 static njs_int_t njs_hash_prototype_update(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t hmac);
+    njs_uint_t nargs, njs_index_t hmac, njs_value_t *retval);
 static njs_int_t njs_hash_prototype_digest(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t hmac);
+    njs_uint_t nargs, njs_index_t hmac, njs_value_t *retval);
 static njs_int_t njs_hash_prototype_copy(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t hmac);
+    njs_uint_t nargs, njs_index_t hmac, njs_value_t *retval);
 static njs_int_t njs_crypto_create_hmac(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t unused);
+    njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 
 static njs_int_t njs_crypto_init(njs_vm_t *vm);
 
@@ -288,7 +288,7 @@ njs_module_t  njs_crypto_module = {
 
 static njs_int_t
 njs_crypto_create_hash(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     njs_digest_t    *dgst;
     njs_hash_alg_t  *alg;
@@ -308,14 +308,14 @@ njs_crypto_create_hash(njs_vm_t *vm, njs
 
     alg->init(&dgst->u);
 
-    return njs_vm_external_create(vm, &vm->retval, njs_crypto_hash_proto_id,
+    return njs_vm_external_create(vm, retval, njs_crypto_hash_proto_id,
                                   dgst, 0);
 }
 
 
 static njs_int_t
 njs_hash_prototype_update(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t hmac)
+    njs_index_t hmac, njs_value_t *retval)
 {
     njs_str_t                    data;
     njs_int_t                    ret;
@@ -362,7 +362,7 @@ njs_hash_prototype_update(njs_vm_t *vm, 
 
     switch (value->type) {
     case NJS_STRING:
-        encoding = njs_buffer_encoding(vm, njs_arg(args, nargs, 2));
+        encoding = njs_buffer_encoding(vm, njs_arg(args, nargs, 2), 1);
         if (njs_slow_path(encoding == NULL)) {
             return NJS_ERROR;
         }
@@ -402,7 +402,7 @@ njs_hash_prototype_update(njs_vm_t *vm, 
         ctx->alg->update(&ctx->u, data.start, data.length);
     }
 
-    vm->retval = *this;
+    njs_value_assign(retval, this);
 
     return NJS_OK;
 }
@@ -410,7 +410,7 @@ njs_hash_prototype_update(njs_vm_t *vm, 
 
 static njs_int_t
 njs_hash_prototype_digest(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t hmac)
+    njs_index_t hmac, njs_value_t *retval)
 {
     njs_str_t         str;
     njs_hmac_t        *ctx;
@@ -473,7 +473,7 @@ njs_hash_prototype_digest(njs_vm_t *vm, 
     str.start = digest;
     str.length = alg->size;
 
-    return enc->encode(vm, &vm->retval, &str);
+    return enc->encode(vm, retval, &str);
 
 exception:
 
@@ -484,7 +484,7 @@ exception:
 
 static njs_int_t
 njs_hash_prototype_copy(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     njs_digest_t  *dgst, *copy;
 
@@ -507,14 +507,14 @@ njs_hash_prototype_copy(njs_vm_t *vm, nj
 
     memcpy(copy, dgst, sizeof(njs_digest_t));
 
-    return njs_vm_external_create(vm, njs_vm_retval(vm),
+    return njs_vm_external_create(vm, retval,
                                   njs_crypto_hash_proto_id, copy, 0);
 }
 
 
 static njs_int_t
 njs_crypto_create_hmac(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     njs_str_t           key;
     njs_uint_t          i;
@@ -590,7 +590,7 @@ njs_crypto_create_hmac(njs_vm_t *vm, njs
     alg->init(&ctx->u);
     alg->update(&ctx->u, key_buf, 64);
 
-    return njs_vm_external_create(vm, &vm->retval, njs_crypto_hmac_proto_id,
+    return njs_vm_external_create(vm, retval, njs_crypto_hmac_proto_id,
                                   ctx, 0);
 }
 
diff -r 5665eebfd00c -r 0c95481158e4 external/njs_fs_module.c
--- a/external/njs_fs_module.c	Wed Apr 12 18:26:42 2023 -0700
+++ b/external/njs_fs_module.c	Wed Apr 19 00:20:37 2023 -0700
@@ -143,35 +143,35 @@ typedef njs_int_t (*njs_file_tree_walk_c
 
 
 static njs_int_t njs_fs_access(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t calltype);
+    njs_uint_t nargs, njs_index_t calltype, njs_value_t *retval);
 static njs_int_t njs_fs_mkdir(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t calltype);
+    njs_uint_t nargs, njs_index_t calltype, njs_value_t *retval);
 static njs_int_t njs_fs_open(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t calltype);
+    njs_index_t calltype, njs_value_t *retval);
 static njs_int_t njs_fs_close(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t calltype);
+    njs_index_t calltype, njs_value_t *retval);
 static njs_int_t njs_fs_read(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t calltype);
+    njs_index_t calltype, njs_value_t *retval);
 static njs_int_t njs_fs_read_file(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t calltype);
+    njs_uint_t nargs, njs_index_t calltype, njs_value_t *retval);
 static njs_int_t njs_fs_readdir(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t calltype);
+    njs_uint_t nargs, njs_index_t calltype, njs_value_t *retval);
 static njs_int_t njs_fs_realpath(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t calltype);
+    njs_uint_t nargs, njs_index_t calltype, njs_value_t *retval);
 static njs_int_t njs_fs_rename(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t calltype);
+    njs_uint_t nargs, njs_index_t calltype, njs_value_t *retval);
 static njs_int_t njs_fs_rmdir(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t calltype);
+    njs_uint_t nargs, njs_index_t calltype, njs_value_t *retval);
 static njs_int_t njs_fs_stat(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t calltype);
+    njs_uint_t nargs, njs_index_t calltype, njs_value_t *retval);
 static njs_int_t njs_fs_symlink(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t calltype);
+    njs_uint_t nargs, njs_index_t calltype, njs_value_t *retval);
 static njs_int_t njs_fs_unlink(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t calltype);
+    njs_uint_t nargs, njs_index_t calltype, njs_value_t *retval);
 static njs_int_t njs_fs_write(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t calltype);
+    njs_index_t calltype, njs_value_t *retval);
 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_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);
@@ -179,21 +179,21 @@ static njs_int_t njs_fs_promises(njs_vm_
     njs_value_t *value, njs_value_t *unused, 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_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 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_uint_t nargs, njs_index_t testtype, njs_value_t *retval);
 
 static njs_int_t njs_fs_stats_test(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t testtype);
+    njs_uint_t nargs, njs_index_t testtype, njs_value_t *retval);
 static njs_int_t njs_fs_stats_prop(njs_vm_t *vm, njs_object_prop_t *prop,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
 static njs_int_t njs_fs_stats_create(njs_vm_t *vm, struct stat *st,
     njs_value_t *retval);
 
 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_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 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_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);
 
@@ -205,9 +205,10 @@ static njs_int_t njs_fs_bytes_written_cr
 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 *retval);
+    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,
-    njs_index_t calltype, const njs_value_t* callback, njs_uint_t nargs);
+    njs_index_t calltype, const njs_value_t* callback, njs_uint_t nargs,
+    njs_value_t *retval);
 
 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);
@@ -1172,12 +1173,12 @@ njs_module_t  njs_fs_module = {
 
 static njs_int_t
 njs_fs_access(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t calltype)
+    njs_index_t calltype, njs_value_t *retval)
 {
     int          md;
     njs_int_t    ret;
     const char  *path;
-    njs_value_t  retval, *callback, *mode;
+    njs_value_t  result, *callback, *mode;
     char         path_buf[NJS_MAX_PATH + 1];
 
     path = njs_fs_path(vm, path_buf, njs_arg(args, nargs, 1), "path");
@@ -1214,15 +1215,15 @@ njs_fs_access(njs_vm_t *vm, njs_value_t 
         return NJS_ERROR;
     }
 
-    njs_set_undefined(&retval);
+    njs_set_undefined(&result);
 
     ret = access(path, md);
     if (njs_slow_path(ret != 0)) {
-        ret = njs_fs_error(vm, "access", strerror(errno), path, errno, &retval);
+        ret = njs_fs_error(vm, "access", strerror(errno), path, errno, &result);
     }
 
     if (ret == NJS_OK) {
-        return njs_fs_result(vm, &retval, calltype, callback, 1);
+        return njs_fs_result(vm, &result, calltype, callback, 1, retval);
     }
 
     return NJS_ERROR;
@@ -1231,13 +1232,13 @@ njs_fs_access(njs_vm_t *vm, njs_value_t 
 
 static njs_int_t
 njs_fs_open(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t calltype)
+    njs_index_t calltype, njs_value_t *retval)
 {
     int          fd, flags;
     mode_t       md;
     njs_int_t    ret;
     const char   *path;
-    njs_value_t  retval, *value;
+    njs_value_t  result, *value;
     char         path_buf[NJS_MAX_PATH + 1];
 
     path = njs_fs_path(vm, path_buf, njs_arg(args, nargs, 1), "path");
@@ -1267,23 +1268,23 @@ njs_fs_open(njs_vm_t *vm, njs_value_t *a
 
     fd = open(path, flags, md);
     if (njs_slow_path(fd < 0)) {
-        ret = njs_fs_error(vm, "open", strerror(errno), path, errno, &retval);
+        ret = njs_fs_error(vm, "open", strerror(errno), path, errno, &result);
         goto done;
     }
 
-    ret = njs_fs_filehandle_create(vm, fd, calltype == NJS_FS_DIRECT, &retval);
+    ret = njs_fs_filehandle_create(vm, fd, calltype == NJS_FS_DIRECT, &result);
     if (njs_slow_path(ret != NJS_OK)) {
         goto done;
     }
 
     if (calltype == NJS_FS_DIRECT) {
-        njs_value_number_set(&retval, fd);
+        njs_value_number_set(&result, fd);
     }
 
 done:
 
     if (ret == NJS_OK) {
-        return njs_fs_result(vm, &retval, calltype, NULL, 2);
+        return njs_fs_result(vm, &result, calltype, NULL, 2, retval);
     }
 
     if (fd != -1) {
@@ -1296,11 +1297,11 @@ done:
 
 static njs_int_t
 njs_fs_close(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t calltype)
+    njs_index_t calltype, njs_value_t *retval)
 {
     int64_t      fd;
     njs_int_t    ret;
-    njs_value_t  retval, *fh;
+    njs_value_t  result, *fh;
 
     fh = njs_arg(args, nargs, 1);
 
@@ -1309,15 +1310,15 @@ njs_fs_close(njs_vm_t *vm, njs_value_t *
         return ret;
     }
 
-    njs_set_undefined(&retval);
+    njs_set_undefined(&result);
 
     ret = close((int) fd);
     if (njs_slow_path(ret != 0)) {
-        ret = njs_fs_error(vm, "close", strerror(errno), NULL, errno, &retval);
+        ret = njs_fs_error(vm, "close", strerror(errno), NULL, errno, &result);
     }
 
     if (ret == NJS_OK) {
-        return njs_fs_result(vm, &retval, calltype, NULL, 1);
+        return njs_fs_result(vm, &result, calltype, NULL, 1, retval);
     }
 
     return NJS_ERROR;
@@ -1326,12 +1327,12 @@ njs_fs_close(njs_vm_t *vm, njs_value_t *
 
 static njs_int_t
 njs_fs_mkdir(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t calltype)
+    njs_index_t calltype, njs_value_t *retval)
 {
     char         *path;
     mode_t       md;
     njs_int_t    ret;
-    njs_value_t  mode, recursive, retval, *callback, *options;
+    njs_value_t  mode, recursive, result, *callback, *options;
     char         path_buf[NJS_MAX_PATH + 1];
 
     path = (char *) njs_fs_path(vm, path_buf, njs_arg(args, nargs, 1), "path");
@@ -1390,10 +1391,10 @@ njs_fs_mkdir(njs_vm_t *vm, njs_value_t *
         return NJS_ERROR;
     }
 
-    ret = njs_fs_make_path(vm, path, md, njs_is_true(&recursive), &retval);
+    ret = njs_fs_make_path(vm, path, md, njs_is_true(&recursive), &result);
 
     if (ret == NJS_OK) {
-        return njs_fs_result(vm, &retval, calltype, callback, 1);
+        return njs_fs_result(vm, &result, calltype, callback, 1, retval);
     }
 
     return NJS_ERROR;
@@ -1402,14 +1403,14 @@ njs_fs_mkdir(njs_vm_t *vm, njs_value_t *
 
 static njs_int_t
 njs_fs_read(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t calltype)
+    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         retval, *buffer, *value;
+    njs_value_t         result, *buffer, *value;
     njs_typed_array_t   *array;
     njs_array_buffer_t  *array_buffer;
 
@@ -1487,24 +1488,24 @@ njs_fs_read(njs_vm_t *vm, njs_value_t *a
     }
 
     if (njs_slow_path(n == -1)) {
-        ret = njs_fs_error(vm, "read", strerror(errno), NULL, errno, &retval);
+        ret = njs_fs_error(vm, "read", strerror(errno), NULL, errno, &result);
         goto done;
     }
 
     if (calltype == NJS_FS_PROMISE) {
-        ret = njs_fs_bytes_read_create(vm, n, buffer, &retval);
+        ret = njs_fs_bytes_read_create(vm, n, buffer, &result);
         if (njs_slow_path(ret != NJS_OK)) {
             goto done;
         }
 
     } else {
-        njs_value_number_set(&retval, n);
+        njs_value_number_set(&result, n);
     }
 
 done:
 
     if (ret == NJS_OK) {
-        return njs_fs_result(vm, &retval, calltype, NULL, 1);
+        return njs_fs_result(vm, &result, calltype, NULL, 1, retval);
     }
 
     return NJS_ERROR;
@@ -1513,13 +1514,13 @@ done:
 
 static njs_int_t
 njs_fs_read_file(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t calltype)
+    njs_index_t calltype, njs_value_t *retval)
 {
     int                          fd, flags;
     njs_str_t                    data;
     njs_int_t                    ret;
     const char                   *path;
-    njs_value_t                  flag, encode, retval, *callback, *options;
+    njs_value_t                  flag, encode, result, *callback, *options;
     struct stat                  sb;
     const njs_buffer_encoding_t  *encoding;
     char                         path_buf[NJS_MAX_PATH + 1];
@@ -1584,7 +1585,7 @@ njs_fs_read_file(njs_vm_t *vm, njs_value
 
     encoding = NULL;
     if (njs_is_defined(&encode)) {
-        encoding = njs_buffer_encoding(vm, &encode);
+        encoding = njs_buffer_encoding(vm, &encode, 1);
         if (njs_slow_path(encoding == NULL)) {
             return NJS_ERROR;
         }
@@ -1592,18 +1593,18 @@ njs_fs_read_file(njs_vm_t *vm, njs_value
 
     fd = open(path, flags);
     if (njs_slow_path(fd < 0)) {
-        ret = njs_fs_error(vm, "open", strerror(errno), path, errno, &retval);
+        ret = njs_fs_error(vm, "open", strerror(errno), path, errno, &result);
         goto done;
     }
 
     ret = fstat(fd, &sb);
     if (njs_slow_path(ret == -1)) {
-        ret = njs_fs_error(vm, "stat", strerror(errno), path, errno, &retval);
+        ret = njs_fs_error(vm, "stat", strerror(errno), path, errno, &result);
         goto done;
     }
 
     if (njs_slow_path(!S_ISREG(sb.st_mode))) {
-        ret = njs_fs_error(vm, "stat", "File is not regular", path, 0, &retval);
+        ret = njs_fs_error(vm, "stat", "File is not regular", path, 0, &result);
         goto done;
     }
 
@@ -1614,17 +1615,17 @@ njs_fs_read_file(njs_vm_t *vm, njs_value
     if (njs_slow_path(ret != NJS_OK)) {
         if (ret == NJS_DECLINED) {
             ret = njs_fs_error(vm, "read", strerror(errno), path, errno,
-                               &retval);
+                               &result);
         }
 
         goto done;
     }
 
     if (encoding == NULL) {
-        ret = njs_buffer_set(vm, &retval, data.start, data.length);
+        ret = njs_buffer_set(vm, &result, data.start, data.length);
 
     } else {
-        ret = encoding->encode(vm, &retval, &data);
+        ret = encoding->encode(vm, &result, &data);
         njs_mp_free(vm->mem_pool, data.start);
     }
 
@@ -1635,7 +1636,7 @@ done:
     }
 
     if (ret == NJS_OK) {
-        return njs_fs_result(vm, &retval, calltype, callback, 2);
+        return njs_fs_result(vm, &result, calltype, callback, 2, retval);
     }
 
     return NJS_ERROR;
@@ -1644,13 +1645,13 @@ done:
 
 static njs_int_t
 njs_fs_readdir(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t calltype)
+    njs_index_t calltype, njs_value_t *retval)
 {
     DIR                          *dir;
     njs_str_t                    s;
     njs_int_t                    ret;
     const char                   *path;
-    njs_value_t                  encode, types, ename, etype, retval,
+    njs_value_t                  encode, types, ename, etype, result,
                                  *callback, *options, *value;
     njs_array_t                  *results;
     struct dirent                *entry;
@@ -1712,7 +1713,7 @@ njs_fs_readdir(njs_vm_t *vm, njs_value_t
 
     encoding = NULL;
     if (!njs_is_string(&encode) || !njs_string_eq(&encode, &string_buffer)) {
-        encoding = njs_buffer_encoding(vm, &encode);
+        encoding = njs_buffer_encoding(vm, &encode, 1);
         if (njs_slow_path(encoding == NULL)) {
             return NJS_ERROR;
         }
@@ -1723,12 +1724,12 @@ njs_fs_readdir(njs_vm_t *vm, njs_value_t
         return NJS_ERROR;
     }
 
-    njs_set_array(&retval, results);
+    njs_set_array(&result, results);
 
     dir = opendir(path);
     if (njs_slow_path(dir == NULL)) {
         ret = njs_fs_error(vm, "opendir", strerror(errno), path, errno,
-                           &retval);
+                           &result);
         goto done;
     }
 
@@ -1740,7 +1741,7 @@ njs_fs_readdir(njs_vm_t *vm, njs_value_t
         if (njs_slow_path(entry == NULL)) {
             if (errno != 0) {
                 ret = njs_fs_error(vm, "readdir", strerror(errno), path, errno,
-                                   &retval);
+                                   &result);
             }
 
             goto done;
@@ -1791,7 +1792,7 @@ done:
     }
 
     if (ret == NJS_OK) {
-        return njs_fs_result(vm, &retval, calltype, callback, 2);
+        return njs_fs_result(vm, &result, calltype, callback, 2, retval);
     }
 
     return NJS_ERROR;
@@ -1800,12 +1801,12 @@ done:
 
 static njs_int_t
 njs_fs_realpath(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t calltype)
+    njs_index_t calltype, njs_value_t *retval)
 {
     njs_int_t                    ret;
     njs_str_t                    s;
     const char                   *path;
-    njs_value_t                  encode, retval, *callback, *options;
+    njs_value_t                  encode, result, *callback, *options;
     const njs_buffer_encoding_t  *encoding;
     char                         path_buf[NJS_MAX_PATH + 1],
                                  dst_buf[NJS_MAX_PATH + 1];
@@ -1857,7 +1858,7 @@ njs_fs_realpath(njs_vm_t *vm, njs_value_
 
     encoding = NULL;
     if (!njs_is_string(&encode) || !njs_string_eq(&encode, &string_buffer)) {
-        encoding = njs_buffer_encoding(vm, &encode);
+        encoding = njs_buffer_encoding(vm, &encode, 1);
         if (njs_slow_path(encoding == NULL)) {
             return NJS_ERROR;
         }
@@ -1866,23 +1867,23 @@ njs_fs_realpath(njs_vm_t *vm, njs_value_
     s.start = (u_char *) realpath(path, dst_buf);
     if (njs_slow_path(s.start == NULL)) {
         ret = njs_fs_error(vm, "realpath", strerror(errno), path, errno,
-                           &retval);
+                           &result);
         goto done;
     }
 
     s.length = njs_strlen(s.start);
 
     if (encoding == NULL) {
-        ret = njs_buffer_new(vm, &retval, s.start, s.length);
+        ret = njs_buffer_new(vm, &result, s.start, s.length);
 
     } else {
-        ret = encoding->encode(vm, &retval, &s);
+        ret = encoding->encode(vm, &result, &s);
     }
 
 done:
 
     if (ret == NJS_OK) {
-        return njs_fs_result(vm, &retval, calltype, callback, 2);
+        return njs_fs_result(vm, &result, calltype, callback, 2, retval);
     }
 
     return NJS_ERROR;
@@ -1891,11 +1892,11 @@ done:
 
 static njs_int_t
 njs_fs_rename(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t calltype)
+    njs_index_t calltype, njs_value_t *retval)
 {
     njs_int_t    ret;
     const char   *path, *newpath;
-    njs_value_t  retval, *callback;
+    njs_value_t  result, *callback;
     char         path_buf[NJS_MAX_PATH + 1], newpath_buf[NJS_MAX_PATH + 1];
 
     callback = NULL;
@@ -1918,15 +1919,15 @@ njs_fs_rename(njs_vm_t *vm, njs_value_t 
         return NJS_ERROR;
     }
 
-    njs_set_undefined(&retval);
+    njs_set_undefined(&result);
 
     ret = rename(path, newpath);
     if (njs_slow_path(ret != 0)) {
-        ret = njs_fs_error(vm, "rename", strerror(errno), NULL, errno, &retval);
+        ret = njs_fs_error(vm, "rename", strerror(errno), NULL, errno, &result);
     }
 
     if (ret == NJS_OK) {
-        return njs_fs_result(vm, &retval, calltype, callback, 1);
+        return njs_fs_result(vm, &result, calltype, callback, 1, retval);
     }
 
     return NJS_ERROR;
@@ -1935,11 +1936,11 @@ njs_fs_rename(njs_vm_t *vm, njs_value_t 
 
 static njs_int_t
 njs_fs_rmdir(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t calltype)
+    njs_index_t calltype, njs_value_t *retval)
 {
     njs_int_t    ret;
     const char   *path;
-    njs_value_t  recursive, retval, *callback, *options;
+    njs_value_t  recursive, result, *callback, *options;
     char         path_buf[NJS_MAX_PATH + 1];
 
     path = njs_fs_path(vm, path_buf, njs_arg(args, nargs, 1), "path");
@@ -1982,10 +1983,10 @@ njs_fs_rmdir(njs_vm_t *vm, njs_value_t *
         }
     }
 
-    ret = njs_fs_rmtree(vm, path, njs_is_true(&recursive), &retval);
+    ret = njs_fs_rmtree(vm, path, njs_is_true(&recursive), &result);
 
     if (ret == NJS_OK) {
-        return njs_fs_result(vm, &retval, calltype, callback, 1);
+        return njs_fs_result(vm, &result, calltype, callback, 1, retval);
     }
 
     return NJS_ERROR;
@@ -1994,7 +1995,7 @@ njs_fs_rmdir(njs_vm_t *vm, njs_value_t *
 
 static njs_int_t
 njs_fs_stat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t magic)
+    njs_index_t magic, njs_value_t *retval)
 {
     int64_t            fd;
     njs_int_t          ret;
@@ -2002,7 +2003,7 @@ njs_fs_stat(njs_vm_t *vm, njs_value_t *a
     njs_bool_t         throw;
     struct stat        sb;
     const char         *path;
-    njs_value_t        retval, *callback, *options;
+    njs_value_t        result, *callback, *options;
     njs_fs_calltype_t  calltype;
     char               path_buf[NJS_MAX_PATH + 1];
 
@@ -2059,24 +2060,24 @@ njs_fs_stat(njs_vm_t *vm, njs_value_t *a
         }
 
         ret = njs_value_property(vm, options, njs_value_arg(&string_bigint),
-                                 &retval);
+                                 &result);
         if (njs_slow_path(ret == NJS_ERROR)) {
             return ret;
         }
 
-        if (njs_bool(&retval)) {
+        if (njs_bool(&result)) {
             njs_type_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),
-                                     &retval);
+                                     &result);
             if (njs_slow_path(ret == NJS_ERROR)) {
                 return ret;
             }
 
-            throw = njs_bool(&retval);
+            throw = njs_bool(&result);
         }
     }
 
@@ -2099,33 +2100,33 @@ njs_fs_stat(njs_vm_t *vm, njs_value_t *a
         if (errno != ENOENT || throw) {
             ret = njs_fs_error(vm,
                                ((magic >> 2) == NJS_FS_STAT) ? "stat" : "lstat",
-                               strerror(errno), path, errno, &retval);
+                               strerror(errno), path, errno, &result);
             if (njs_slow_path(ret != NJS_OK)) {
                 return NJS_ERROR;
             }
         } else {
-            njs_set_undefined(&retval);
+            njs_set_undefined(&result);
         }
 
-        return njs_fs_result(vm, &retval, calltype, callback, 2);
+        return njs_fs_result(vm, &result, calltype, callback, 2, retval);
     }
 
-    ret = njs_fs_stats_create(vm, &sb, &retval);
+    ret = njs_fs_stats_create(vm, &sb, &result);
     if (njs_slow_path(ret != NJS_OK)) {
         return NJS_ERROR;
     }
 
-    return njs_fs_result(vm, &retval, calltype, callback, 2);
+    return njs_fs_result(vm, &result, calltype, callback, 2, retval);
 }
 
 
 static njs_int_t
 njs_fs_symlink(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t calltype)
+    njs_index_t calltype, njs_value_t *retval)
 {
     njs_int_t    ret;
     const char  *target, *path;
-    njs_value_t  retval, *callback, *type;
+    njs_value_t  result, *callback, *type;
     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");
@@ -2158,16 +2159,16 @@ njs_fs_symlink(njs_vm_t *vm, njs_value_t
         return NJS_ERROR;
     }
 
-    njs_set_undefined(&retval);
+    njs_set_undefined(&result);
 
     ret = symlink(target, path);
     if (njs_slow_path(ret != 0)) {
         ret = njs_fs_error(vm, "symlink", strerror(errno), path, errno,
-                           &retval);
+                           &result);
     }
 
     if (ret == NJS_OK) {
-        return njs_fs_result(vm, &retval, calltype, callback, 1);
+        return njs_fs_result(vm, &result, calltype, callback, 1, retval);
     }
 
     return NJS_ERROR;
@@ -2176,11 +2177,11 @@ njs_fs_symlink(njs_vm_t *vm, njs_value_t
 
 static njs_int_t
 njs_fs_unlink(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t calltype)
+    njs_index_t calltype, njs_value_t *retval)
 {
     njs_int_t    ret;
     const char   *path;
-    njs_value_t  retval, *callback;
+    njs_value_t  result, *callback;
     char         path_buf[NJS_MAX_PATH + 1];
 
     path = njs_fs_path(vm, path_buf, njs_arg(args, nargs, 1), "path");
@@ -2198,15 +2199,15 @@ njs_fs_unlink(njs_vm_t *vm, njs_value_t 
         }
     }
 
-    njs_set_undefined(&retval);
+    njs_set_undefined(&result);
 
     ret = unlink(path);
     if (njs_slow_path(ret != 0)) {
-        ret = njs_fs_error(vm, "unlink", strerror(errno), path, errno, &retval);
+        ret = njs_fs_error(vm, "unlink", strerror(errno), path, errno, &result);
     }
 
     if (ret == NJS_OK) {
-        return njs_fs_result(vm, &retval, calltype, callback, 1);
+        return njs_fs_result(vm, &result, calltype, callback, 1, retval);
     }
 
     return NJS_ERROR;
@@ -2215,14 +2216,14 @@ njs_fs_unlink(njs_vm_t *vm, njs_value_t 
 
 static njs_int_t
 njs_fs_write(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t calltype)
+    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                  retval, *buffer, *value;
+    njs_value_t                  result, *buffer, *value;
     const njs_buffer_encoding_t  *encoding;
 
     fd_offset = !!(calltype == NJS_FS_DIRECT);
@@ -2252,17 +2253,18 @@ njs_fs_write(njs_vm_t *vm, njs_value_t *
             }
         }
 
-        encoding = njs_buffer_encoding(vm, njs_arg(args, nargs, fd_offset + 3));
+        encoding = njs_buffer_encoding(vm, njs_arg(args, nargs, fd_offset + 3),
+                                       1);
         if (njs_slow_path(encoding == NULL)) {
             return NJS_ERROR;
         }
 
-        ret = njs_buffer_decode_string(vm, buffer, &retval, encoding);
+        ret = njs_buffer_decode_string(vm, buffer, &result, encoding);
         if (njs_slow_path(ret != NJS_OK)) {
             return NJS_ERROR;
         }
 
-        njs_string_get(&retval, &data);
+        njs_string_get(&result, &data);
 
         goto process;
     }
@@ -2328,30 +2330,30 @@ process:
     }
 
     if (njs_slow_path(n == -1)) {
-        ret = njs_fs_error(vm, "write", strerror(errno), NULL, errno, &retval);
+        ret = njs_fs_error(vm, "write", strerror(errno), NULL, errno, &result);
         goto done;
     }
 
     if (njs_slow_path((size_t) n != data.length)) {
         ret = njs_fs_error(vm, "write", "failed to write all the data", NULL,
-                           0, &retval);
+                           0, &result);
         goto done;
     }
 
     if (calltype == NJS_FS_PROMISE) {
-        ret = njs_fs_bytes_written_create(vm, n, buffer, &retval);
+        ret = njs_fs_bytes_written_create(vm, n, buffer, &result);
         if (njs_slow_path(ret != NJS_OK)) {
             goto done;
         }
 
     } else {
-        njs_value_number_set(&retval, n);
+        njs_value_number_set(&result, n);
     }
 
 done:
 
     if (ret == NJS_OK) {
-        return njs_fs_result(vm, &retval, calltype, NULL, 1);
+        return njs_fs_result(vm, &result, calltype, NULL, 1, retval);
     }
 
     return NJS_ERROR;
@@ -2360,7 +2362,7 @@ done:
 
 static njs_int_t
 njs_fs_write_file(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t magic)
+    njs_index_t magic, njs_value_t *retval)
 {
     int                          fd, flags;
     u_char                       *p, *end;
@@ -2369,7 +2371,7 @@ njs_fs_write_file(njs_vm_t *vm, njs_valu
     njs_str_t                    content;
     njs_int_t                    ret;
     const char                   *path;
-    njs_value_t                  flag, mode, encode, retval, *data, *callback,
+    njs_value_t                  flag, mode, encode, result, *data, *callback,
                                  *options;
     njs_typed_array_t            *array;
     njs_fs_calltype_t            calltype;
@@ -2455,22 +2457,22 @@ njs_fs_write_file(njs_vm_t *vm, njs_valu
 
     case NJS_STRING:
     default:
-        encoding = njs_buffer_encoding(vm, &encode);
+        encoding = njs_buffer_encoding(vm, &encode, 1);
         if (njs_slow_path(encoding == NULL)) {
             return NJS_ERROR;
         }
 
-        ret = njs_value_to_string(vm, &retval, data);
+        ret = njs_value_to_string(vm, &result, data);
         if (njs_slow_path(ret != NJS_OK)) {
             return NJS_ERROR;
         }
 
-        ret = njs_buffer_decode_string(vm, &retval, &retval, encoding);
+        ret = njs_buffer_decode_string(vm, &result, &result, encoding);
         if (njs_slow_path(ret != NJS_OK)) {
             return NJS_ERROR;
         }
 
-        njs_string_get(&retval, &content);
+        njs_string_get(&result, &content);
         break;
     }
 
@@ -2488,7 +2490,7 @@ njs_fs_write_file(njs_vm_t *vm, njs_valu
 
     fd = open(path, flags, md);
     if (njs_slow_path(fd < 0)) {
-        ret = njs_fs_error(vm, "open", strerror(errno), path, errno, &retval);
+        ret = njs_fs_error(vm, "open", strerror(errno), path, errno, &result);
         goto done;
     }
 
@@ -2503,7 +2505,7 @@ njs_fs_write_file(njs_vm_t *vm, njs_valu
             }
 
             ret = njs_fs_error(vm, "write", strerror(errno), path, errno,
-                               &retval);
+                               &result);
             goto done;
         }
 
@@ -2511,7 +2513,7 @@ njs_fs_write_file(njs_vm_t *vm, njs_valu
     }
 
     ret = NJS_OK;
-    njs_set_undefined(&retval);
+    njs_set_undefined(&result);
 
 done:
 
@@ -2520,7 +2522,7 @@ done:
     }
 
     if (ret == NJS_OK) {
-        return njs_fs_result(vm, &retval, calltype, callback, 1);
+        return njs_fs_result(vm, &result, calltype, callback, 1, retval);
     }
 
     return NJS_ERROR;
@@ -3070,7 +3072,7 @@ njs_fs_error(njs_vm_t *vm, const char *s
 
 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_index_t unused, njs_value_t *retval)
 {
     njs_value_t value;
 
@@ -3085,15 +3087,20 @@ static const njs_value_t  promise_trampo
 
 static njs_int_t
 njs_fs_result(njs_vm_t *vm, njs_value_t *result, njs_index_t calltype,
-    const njs_value_t *callback, njs_uint_t nargs)
+    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];
 
     switch (calltype) {
     case NJS_FS_DIRECT:
-        vm->retval = *result;
-        return njs_is_error(result) ? NJS_ERROR : NJS_OK;
+        if (njs_is_error(result)) {
+            njs_vm_throw(vm, result);
+            return NJS_ERROR;
+        }
+
+        njs_value_assign(retval, result);
+        return NJS_OK;
 
     case NJS_FS_PROMISE:
         ret = njs_vm_promise_create(vm, &promise, &callbacks[0]);
@@ -3110,7 +3117,7 @@ njs_fs_result(njs_vm_t *vm, njs_value_t 
             return ret;
         }
 
-        vm->retval = promise;
+        njs_value_assign(retval, &promise);
 
         return NJS_OK;
 
@@ -3130,7 +3137,7 @@ njs_fs_result(njs_vm_t *vm, njs_value_t 
             return ret;
         }
 
-        njs_set_undefined(&vm->retval);
+        njs_set_undefined(retval);
 
         return NJS_OK;
 
@@ -3217,7 +3224,7 @@ njs_fs_dirent_create(njs_vm_t *vm, njs_v
 
 static njs_int_t
 njs_fs_dirent_constructor(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t unused)


More information about the nginx-devel mailing list