]> git.kaiwu.me - njs.git/commitdiff
Change: native methods are provided with retval argument.
authorDmitry Volyntsev <xeioex@nginx.com>
Wed, 19 Apr 2023 07:20:37 +0000 (00:20 -0700)
committerDmitry Volyntsev <xeioex@nginx.com>
Wed, 19 Apr 2023 07:20:37 +0000 (00:20 -0700)
Previously, native methods were expected to return
their retval using vm->retval.  This caused problem in the part
(1aa137411b09293fe42c5e1c) 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().

61 files changed:
external/njs_crypto_module.c
external/njs_fs_module.c
external/njs_query_string_module.c
external/njs_webcrypto_module.c
external/njs_xml_module.c
external/njs_zlib_module.c
nginx/ngx_http_js_module.c
nginx/ngx_js.c
nginx/ngx_js.h
nginx/ngx_js_fetch.c
nginx/ngx_js_fetch.h
nginx/ngx_stream_js_module.c
src/njs.h
src/njs_array.c
src/njs_array.h
src/njs_array_buffer.c
src/njs_async.c
src/njs_async.h
src/njs_boolean.c
src/njs_buffer.c
src/njs_buffer.h
src/njs_builtin.c
src/njs_date.c
src/njs_encoding.c
src/njs_error.c
src/njs_error.h
src/njs_function.c
src/njs_function.h
src/njs_generator.c
src/njs_iterator.c
src/njs_iterator.h
src/njs_json.c
src/njs_math.c
src/njs_module.c
src/njs_module.h
src/njs_number.c
src/njs_number.h
src/njs_object.c
src/njs_object.h
src/njs_object_prop.c
src/njs_parser.c
src/njs_promise.c
src/njs_promise.h
src/njs_regexp.c
src/njs_regexp.h
src/njs_shell.c
src/njs_string.c
src/njs_string.h
src/njs_symbol.c
src/njs_timer.c
src/njs_timer.h
src/njs_typed_array.c
src/njs_typed_array.h
src/njs_value.c
src/njs_vm.c
src/njs_vm.h
src/njs_vmcode.c
src/njs_vmcode.h
src/test/njs_benchmark.c
src/test/njs_externals_test.c
src/test/njs_unit_test.c

index 6a11c8a4b6e07706f991ee2568491782acb02100..116c591ea38b81101930cf895a4f4e3cdc0347cf 100644 (file)
@@ -62,15 +62,15 @@ static njs_crypto_enc_t *njs_crypto_encoding(njs_vm_t *vm,
 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_value_t *args, njs_uint_t nargs,
 
     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, njs_value_t *args, njs_uint_t nargs,
 
     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, njs_value_t *args, njs_uint_t nargs,
         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, njs_value_t *args, njs_uint_t nargs,
 
 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, njs_value_t *args, njs_uint_t nargs,
     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, njs_value_t *args, njs_uint_t nargs,
 
     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_value_t *args, njs_uint_t nargs,
     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);
 }
 
index 7aa9328d426ef02b4c6855bc63e7d1ac36866f2e..68d4cf67eecba1b6a96c48054d82f3932a1ee351 100644 (file)
@@ -143,35 +143,35 @@ typedef njs_int_t (*njs_file_tree_walk_cb_t)(const char *, const struct stat *,
 
 
 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_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_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_create(njs_vm_t *vm, int bytes,
 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 *args, njs_uint_t nargs,
         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 *args, njs_uint_t nargs,
 
 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 *args, njs_uint_t nargs,
 
     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 *args, njs_uint_t nargs,
         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 *args, njs_uint_t nargs,
 
 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 *args, njs_uint_t nargs,
         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 *args, njs_uint_t nargs,
 
 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 *args, njs_uint_t nargs,
     }
 
     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_t *args, njs_uint_t nargs,
 
     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_t *args, njs_uint_t nargs,
 
     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_t *args, njs_uint_t nargs,
     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 *args, njs_uint_t nargs,
 
     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 *args, njs_uint_t nargs,
         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 *args, njs_uint_t nargs,
         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_t *args, njs_uint_t nargs,
 
     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_t *args, njs_uint_t nargs,
     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 *args, njs_uint_t nargs,
         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 *args, njs_uint_t nargs,
 
 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 *args, njs_uint_t nargs,
         }
     }
 
-    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 *args, njs_uint_t nargs,
 
 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 *args, njs_uint_t nargs,
     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 *args, njs_uint_t nargs,
         }
 
         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 *args, njs_uint_t nargs,
         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 *args, njs_uint_t nargs,
         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 *args, njs_uint_t nargs,
 
 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 *args, njs_uint_t nargs,
         }
     }
 
-    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 *args, njs_uint_t nargs,
 
 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 *args, njs_uint_t nargs,
             }
         }
 
-        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_value_t *args, njs_uint_t nargs,
     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_value_t *args, njs_uint_t nargs,
 
     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_value_t *args, njs_uint_t nargs,
 
     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_value_t *args, njs_uint_t nargs,
             }
 
             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_value_t *args, njs_uint_t nargs,
     }
 
     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 *syscall, const char *description,
 
 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_trampoline  =
 
 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 *result, njs_index_t calltype,
             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 *result, njs_index_t calltype,
             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_value_t *name, njs_value_t *type,
 
 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)
 {
     if (njs_slow_path(!vm->top_frame->ctor)) {
         njs_type_error(vm, "the Dirent constructor must be called with new");
@@ -3225,7 +3232,7 @@ njs_fs_dirent_constructor(njs_vm_t *vm, njs_value_t *args,
     }
 
     return njs_fs_dirent_create(vm, njs_arg(args, nargs, 1),
-                                njs_arg(args, nargs, 2), &vm->retval);
+                                njs_arg(args, nargs, 2), retval);
 }
 
 
@@ -3247,7 +3254,7 @@ const njs_object_init_t  njs_dirent_constructor_init = {
 
 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_index_t testtype, njs_value_t *retval)
 {
     njs_int_t    ret;
     njs_value_t  type, *this;
@@ -3268,7 +3275,7 @@ njs_fs_dirent_test(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    njs_set_boolean(&vm->retval,
+    njs_set_boolean(retval,
                     njs_is_number(&type) && testtype == njs_number(&type));
 
     return NJS_OK;
@@ -3352,7 +3359,7 @@ njs_fs_stats_create(njs_vm_t *vm, struct stat *st, 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_index_t testtype, njs_value_t *retval)
 {
     unsigned    mask;
     njs_stat_t  *st;
@@ -3392,7 +3399,7 @@ njs_fs_stats_test(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         mask = S_IFSOCK;
     }
 
-    njs_set_boolean(&vm->retval, (st->st_mode & S_IFMT) == mask);
+    njs_set_boolean(retval, (st->st_mode & S_IFMT) == mask);
 
     return NJS_OK;
 }
@@ -3494,9 +3501,9 @@ njs_fs_stats_prop(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value,
 
 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_index_t unused, njs_value_t *retval)
 {
-    njs_value_t       retval;
+    njs_value_t       result;
     njs_filehandle_t  *fh;
 
     fh = njs_vm_external(vm, njs_fs_filehandle_proto_id, njs_argument(args, 0));
@@ -3513,15 +3520,15 @@ njs_fs_filehandle_close(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     (void) close(fh->fd);
     fh->fd = -1;
 
-    njs_set_undefined(&retval);
+    njs_set_undefined(&result);
 
-    return njs_fs_result(vm, &retval, NJS_FS_PROMISE, NULL, 1);
+    return njs_fs_result(vm, &result, NJS_FS_PROMISE, NULL, 1, 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_index_t unused, njs_value_t *retval)
 {
     njs_filehandle_t  *fh;
 
@@ -3531,7 +3538,7 @@ njs_fs_filehandle_value_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    njs_set_number(njs_vm_retval(vm), fh->fd);
+    njs_set_number(retval, fh->fd);
 
     return NJS_OK;
 }
index b1463f3e6cf954bd482ab368f367a38d1c658a84..9e2918c02514e6e8841fb9d313a7631f30fe437a 100644 (file)
@@ -13,13 +13,13 @@ static njs_int_t njs_query_string_parser(njs_vm_t *vm, u_char *query,
     u_char *end, const njs_str_t *sep, const njs_str_t *eq,
     njs_function_t *decode, njs_uint_t max_keys, njs_value_t *retval);
 static njs_int_t njs_query_string_parse(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_query_string_stringify(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_query_string_escape(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_query_string_unescape(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_query_string_init(njs_vm_t *vm);
 
@@ -382,7 +382,7 @@ njs_query_string_match(u_char *p, u_char *end, const njs_str_t *v)
 
 static njs_int_t
 njs_query_string_parse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     int64_t         max_keys;
     njs_int_t       ret;
@@ -476,7 +476,7 @@ njs_query_string_parse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     return njs_query_string_parser(vm, str.start, str.start + str.length,
-                                   &sep, &eq, decode, max_keys, &vm->retval);
+                                   &sep, &eq, decode, max_keys, retval);
 }
 
 
@@ -721,7 +721,7 @@ njs_query_string_push(njs_vm_t *vm, njs_chb_t *chain, njs_value_t *key,
 
 static njs_int_t
 njs_query_string_stringify(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     u_char             *p;
     int64_t            len;
@@ -730,7 +730,7 @@ njs_query_string_stringify(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     uint64_t           length;
     njs_int_t          ret;
     njs_chb_t          chain;
-    njs_value_t        value, retval, *string, *this, *object, *arg, *options;
+    njs_value_t        value, result, *string, *this, *object, *arg, *options;
     njs_array_t        *keys, *array;
     njs_function_t     *encode;
     njs_string_prop_t  sep, eq;
@@ -746,7 +746,7 @@ njs_query_string_stringify(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     object = njs_arg(args, nargs, 1);
 
     if (njs_slow_path(!njs_is_object(object))) {
-        vm->retval = njs_string_empty;
+        njs_value_assign(retval, &njs_string_empty);
         return NJS_OK;
     }
 
@@ -849,7 +849,7 @@ njs_query_string_stringify(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             }
 
             for (i = 0; i < len; i++) {
-                ret = njs_value_property_i64(vm, &value, i, &retval);
+                ret = njs_value_property_i64(vm, &value, i, &result);
                 if (njs_slow_path(ret == NJS_ERROR)) {
                     goto failed;
                 }
@@ -859,7 +859,7 @@ njs_query_string_stringify(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
                     length += sep.length;
                 }
 
-                ret = njs_query_string_push(vm, &chain, string, &retval, &eq,
+                ret = njs_query_string_push(vm, &chain, string, &result, &eq,
                                             encode);
                 if (njs_slow_path(ret < 0)) {
                     ret = NJS_ERROR;
@@ -892,7 +892,7 @@ njs_query_string_stringify(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    p = njs_string_alloc(vm, &vm->retval, size, length);
+    p = njs_string_alloc(vm, retval, size, length);
     if (njs_slow_path(p == NULL)) {
         return NJS_ERROR;
     }
@@ -911,7 +911,7 @@ failed:
 
 static njs_int_t
 njs_query_string_escape(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     u_char       *p;
     ssize_t      size, length;
@@ -942,7 +942,7 @@ njs_query_string_escape(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     size = njs_chb_size(&chain);
 
-    p = njs_string_alloc(vm, &vm->retval, size, length);
+    p = njs_string_alloc(vm, retval, size, length);
     if (njs_slow_path(p == NULL)) {
         return NJS_ERROR;
     }
@@ -957,7 +957,7 @@ njs_query_string_escape(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_query_string_unescape(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_int_t    ret;
     njs_str_t    str;
@@ -976,7 +976,7 @@ njs_query_string_unescape(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     njs_string_get(string, &str);
 
-    return njs_query_string_decode(vm, &vm->retval, str.start, str.length);
+    return njs_query_string_decode(vm, retval, str.start, str.length);
 }
 
 
index cb633d9365559299b9acdf49af302aca7961811a..f78280a1e43578faa0d840d441be2707d80fc7a4 100644 (file)
@@ -88,33 +88,36 @@ typedef int (*EVP_PKEY_cipher_t)(EVP_PKEY_CTX *ctx, unsigned char *out,
 
 
 static njs_int_t njs_ext_cipher(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_cipher_pkey(njs_vm_t *vm, njs_str_t *data,
-    njs_webcrypto_key_t *key, njs_index_t encrypt);
+    njs_webcrypto_key_t *key, njs_index_t encrypt, njs_value_t *retval);
 static njs_int_t njs_cipher_aes_gcm(njs_vm_t *vm, njs_str_t *data,
-    njs_webcrypto_key_t *key, njs_value_t *options, njs_bool_t encrypt);
+    njs_webcrypto_key_t *key, njs_value_t *options, njs_bool_t encrypt,
+    njs_value_t *retval);
 static njs_int_t njs_cipher_aes_ctr(njs_vm_t *vm, njs_str_t *data,
-    njs_webcrypto_key_t *key, njs_value_t *options, njs_bool_t encrypt);
+    njs_webcrypto_key_t *key, njs_value_t *options, njs_bool_t encrypt,
+    njs_value_t *retval);
 static njs_int_t njs_cipher_aes_cbc(njs_vm_t *vm, njs_str_t *data,
-    njs_webcrypto_key_t *key, njs_value_t *options, njs_bool_t encrypt);
+    njs_webcrypto_key_t *key, njs_value_t *options, njs_bool_t encrypt,
+    njs_value_t *retval);
 static njs_int_t njs_ext_derive(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t derive_key);
+    njs_uint_t nargs, njs_index_t derive_key, njs_value_t *retval);
 static njs_int_t njs_ext_digest(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_ext_export_key(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_ext_generate_key(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_ext_import_key(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_ext_sign(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t verify);
+    njs_uint_t nargs, njs_index_t verify, njs_value_t *retval);
 static njs_int_t njs_ext_unwrap_key(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_ext_wrap_key(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_ext_get_random_values(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_webcrypto_key_t *njs_webcrypto_key_alloc(njs_vm_t *vm,
     njs_webcrypto_algorithm_t *alg, unsigned usage, njs_bool_t extractable);
@@ -134,7 +137,7 @@ static njs_int_t njs_algorithm_curve(njs_vm_t *vm, njs_value_t *value,
     int *curve);
 
 static njs_int_t njs_webcrypto_result(njs_vm_t *vm, njs_value_t *result,
-    njs_int_t rc);
+    njs_int_t rc, njs_value_t *retval);
 static njs_int_t njs_webcrypto_array_buffer(njs_vm_t *vm, njs_value_t *retval,
     u_char *start, size_t length);
 static void njs_webcrypto_error(njs_vm_t *vm, const char *fmt, ...);
@@ -614,12 +617,12 @@ static njs_int_t    njs_webcrypto_crypto_key_proto_id;
 
 static njs_int_t
 njs_ext_cipher(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t encrypt)
+    njs_index_t encrypt, njs_value_t *retval)
 {
     unsigned                   mask;
     njs_int_t                  ret;
     njs_str_t                  data;
-    njs_value_t                *options;
+    njs_value_t                *options, value;
     njs_webcrypto_key_t        *key;
     njs_webcrypto_algorithm_t  *alg;
 
@@ -658,33 +661,33 @@ njs_ext_cipher(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     switch (alg->type) {
     case NJS_ALGORITHM_RSA_OAEP:
-        ret = njs_cipher_pkey(vm, &data, key, encrypt);
+        ret = njs_cipher_pkey(vm, &data, key, encrypt, &value);
         break;
 
     case NJS_ALGORITHM_AES_GCM:
-        ret = njs_cipher_aes_gcm(vm, &data, key, options, encrypt);
+        ret = njs_cipher_aes_gcm(vm, &data, key, options, encrypt, &value);
         break;
 
     case NJS_ALGORITHM_AES_CTR:
-        ret = njs_cipher_aes_ctr(vm, &data, key, options, encrypt);
+        ret = njs_cipher_aes_ctr(vm, &data, key, options, encrypt, &value);
         break;
 
     case NJS_ALGORITHM_AES_CBC:
     default:
-        ret = njs_cipher_aes_cbc(vm, &data, key, options, encrypt);
+        ret = njs_cipher_aes_cbc(vm, &data, key, options, encrypt, &value);
     }
 
-    return njs_webcrypto_result(vm, njs_vm_retval(vm), ret);
+    return njs_webcrypto_result(vm, &value, ret, retval);
 
 fail:
 
-    return njs_webcrypto_result(vm, njs_vm_retval(vm), NJS_ERROR);
+    return njs_webcrypto_result(vm, NULL, NJS_ERROR, retval);
 }
 
 
 static njs_int_t
 njs_cipher_pkey(njs_vm_t *vm, njs_str_t *data, njs_webcrypto_key_t *key,
-    njs_index_t encrypt)
+    njs_index_t encrypt, njs_value_t *retval)
 {
     u_char                  *dst;
     size_t                  outlen;
@@ -746,7 +749,7 @@ njs_cipher_pkey(njs_vm_t *vm, njs_str_t *data, njs_webcrypto_key_t *key,
         goto fail;
     }
 
-    ret = njs_vm_value_array_buffer_set(vm, njs_vm_retval(vm), dst, outlen);
+    ret = njs_vm_value_array_buffer_set(vm, retval, dst, outlen);
 
 fail:
 
@@ -758,7 +761,7 @@ fail:
 
 static njs_int_t
 njs_cipher_aes_gcm(njs_vm_t *vm, njs_str_t *data, njs_webcrypto_key_t *key,
-    njs_value_t *options, njs_bool_t encrypt)
+    njs_value_t *options, njs_bool_t encrypt, njs_value_t *retval)
 {
     int               len, outlen, dstlen;
     u_char            *dst, *p;
@@ -943,7 +946,7 @@ njs_cipher_aes_gcm(njs_vm_t *vm, njs_str_t *data, njs_webcrypto_key_t *key,
         outlen += taglen;
     }
 
-    ret = njs_vm_value_array_buffer_set(vm, njs_vm_retval(vm), dst, outlen);
+    ret = njs_vm_value_array_buffer_set(vm, retval, dst, outlen);
 
 fail:
 
@@ -1059,7 +1062,7 @@ njs_counter128_reset(u_char *src, u_char *dst, njs_uint_t bits)
 
 static njs_int_t
 njs_cipher_aes_ctr(njs_vm_t *vm, njs_str_t *data, njs_webcrypto_key_t *key,
-    njs_value_t *options, njs_bool_t encrypt)
+    njs_value_t *options, njs_bool_t encrypt, njs_value_t *retval)
 {
     int               len, len2;
     u_char            *dst;
@@ -1242,7 +1245,7 @@ njs_cipher_aes_ctr(njs_vm_t *vm, njs_str_t *data, njs_webcrypto_key_t *key,
 
 done:
 
-    ret = njs_vm_value_array_buffer_set(vm, njs_vm_retval(vm), dst, len);
+    ret = njs_vm_value_array_buffer_set(vm, retval, dst, len);
 
 fail:
 
@@ -1266,7 +1269,7 @@ fail:
 
 static njs_int_t
 njs_cipher_aes_cbc(njs_vm_t *vm, njs_str_t *data, njs_webcrypto_key_t *key,
-    njs_value_t *options, njs_bool_t encrypt)
+    njs_value_t *options, njs_bool_t encrypt, njs_value_t *retval)
 {
     int               olen_max, olen, olen2;
     u_char            *dst;
@@ -1363,7 +1366,7 @@ njs_cipher_aes_cbc(njs_vm_t *vm, njs_str_t *data, njs_webcrypto_key_t *key,
 
     olen += olen2;
 
-    ret = njs_vm_value_array_buffer_set(vm, njs_vm_retval(vm), dst, olen);
+    ret = njs_vm_value_array_buffer_set(vm, retval, dst, olen);
 
 fail:
 
@@ -1375,7 +1378,7 @@ fail:
 
 static njs_int_t
 njs_ext_derive(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t derive_key)
+    njs_index_t derive_key, njs_value_t *retval)
 {
     u_char                     *k;
     size_t                     olen;
@@ -1683,17 +1686,17 @@ free:
         goto fail;
     }
 
-    return njs_webcrypto_result(vm, &value, NJS_OK);
+    return njs_webcrypto_result(vm, &value, NJS_OK, retval);
 
 fail:
 
-    return njs_webcrypto_result(vm, njs_vm_retval(vm), NJS_ERROR);
+    return njs_webcrypto_result(vm, NULL, NJS_ERROR, retval);
 }
 
 
 static njs_int_t
 njs_ext_digest(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     unsigned              olen;
     u_char                *dst;
@@ -1733,11 +1736,11 @@ njs_ext_digest(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         goto fail;
     }
 
-    return njs_webcrypto_result(vm, &value, NJS_OK);
+    return njs_webcrypto_result(vm, &value, NJS_OK, retval);
 
 fail:
 
-    return njs_webcrypto_result(vm, njs_vm_retval(vm), NJS_ERROR);
+    return njs_webcrypto_result(vm, NULL, NJS_ERROR, retval);
 }
 
 
@@ -2133,7 +2136,7 @@ njs_export_jwk_oct(njs_vm_t *vm, njs_webcrypto_key_t *key, njs_value_t *retval)
 
 static njs_int_t
 njs_ext_export_key(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     BIO                         *bio;
     BUF_MEM                     *mem;
@@ -2295,17 +2298,17 @@ njs_ext_export_key(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         break;
     }
 
-    return njs_webcrypto_result(vm, &value, NJS_OK);
+    return njs_webcrypto_result(vm, &value, NJS_OK, retval);
 
 fail:
 
-    return njs_webcrypto_result(vm, njs_vm_retval(vm), NJS_ERROR);
+    return njs_webcrypto_result(vm, NULL, NJS_ERROR, retval);
 }
 
 
 static njs_int_t
 njs_ext_generate_key(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     int                        nid;
     unsigned                   usage;
@@ -2558,7 +2561,7 @@ njs_ext_generate_key(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    return njs_webcrypto_result(vm, &value, NJS_OK);
+    return njs_webcrypto_result(vm, &value, NJS_OK, retval);
 
 fail:
 
@@ -2566,7 +2569,7 @@ fail:
         EVP_PKEY_CTX_free(ctx);
     }
 
-    return njs_webcrypto_result(vm, njs_vm_retval(vm), NJS_ERROR);
+    return njs_webcrypto_result(vm, NULL, NJS_ERROR, retval);
 }
 
 
@@ -3186,7 +3189,7 @@ done:
 
 static njs_int_t
 njs_ext_import_key(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     int                         nid;
     BIO                         *bio;
@@ -3530,7 +3533,7 @@ njs_ext_import_key(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         goto fail;
     }
 
-    return njs_webcrypto_result(vm, &value, NJS_OK);
+    return njs_webcrypto_result(vm, &value, NJS_OK, retval);
 
 fail:
 
@@ -3538,7 +3541,7 @@ fail:
         EVP_PKEY_free(pkey);
     }
 
-    return njs_webcrypto_result(vm, njs_vm_retval(vm), NJS_ERROR);
+    return njs_webcrypto_result(vm, NULL, NJS_ERROR, retval);
 }
 
 
@@ -3767,7 +3770,7 @@ memory_error:
 
 static njs_int_t
 njs_ext_sign(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t verify)
+    njs_index_t verify, njs_value_t *retval)
 {
     u_char                     *dst, *p;
     size_t                     olen, outlen;
@@ -3993,7 +3996,7 @@ njs_ext_sign(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         njs_set_boolean(&value, ret != 0);
     }
 
-    return njs_webcrypto_result(vm, &value, NJS_OK);
+    return njs_webcrypto_result(vm, &value, NJS_OK, retval);
 
 fail:
 
@@ -4005,13 +4008,13 @@ fail:
         EVP_PKEY_CTX_free(pctx);
     }
 
-    return njs_webcrypto_result(vm, njs_vm_retval(vm), NJS_ERROR);
+    return njs_webcrypto_result(vm, NULL, NJS_ERROR, retval);
 }
 
 
 static njs_int_t
 njs_ext_unwrap_key(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_internal_error(vm, "\"unwrapKey\" not implemented");
     return NJS_ERROR;
@@ -4020,7 +4023,7 @@ njs_ext_unwrap_key(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_ext_wrap_key(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     njs_internal_error(vm, "\"wrapKey\" not implemented");
     return NJS_ERROR;
@@ -4029,7 +4032,7 @@ njs_ext_wrap_key(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_ext_get_random_values(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     njs_int_t  ret;
     njs_str_t  fill;
@@ -4138,7 +4141,7 @@ njs_format_string(njs_webcrypto_key_format_t fmt)
 
 static njs_int_t
 njs_key_usage_array_handler(njs_vm_t *vm, njs_iterator_args_t *args,
-    njs_value_t *value, int64_t index)
+    njs_value_t *value, int64_t index, njs_value_t *retval)
 {
     unsigned               *mask;
     njs_str_t              u;
@@ -4174,6 +4177,7 @@ njs_key_usage(njs_vm_t *vm, njs_value_t *value, unsigned *mask)
 {
     int64_t              length;
     njs_int_t            ret;
+    njs_value_t          retval;
     njs_iterator_args_t  args;
 
     if (!njs_value_is_object(value)) {
@@ -4193,7 +4197,8 @@ njs_key_usage(njs_vm_t *vm, njs_value_t *value, unsigned *mask)
     args.to = length;
     args.data = mask;
 
-    return njs_object_iterate(vm, &args, njs_key_usage_array_handler);
+    return njs_object_iterate(vm, &args, njs_key_usage_array_handler,
+                              &retval);
 }
 
 
@@ -4402,14 +4407,14 @@ njs_algorithm_curve(njs_vm_t *vm, njs_value_t *options, int *curve)
 
 static njs_int_t
 njs_promise_trampoline(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)
 {
     njs_function_t  *callback;
 
     callback = njs_value_function(njs_argument(args, 1));
 
     if (callback != NULL) {
-        return njs_vm_call(vm, callback, njs_argument(args, 2), 1);
+        return njs_vm_invoke(vm, callback, njs_argument(args, 2), 1, retval);
     }
 
     return NJS_OK;
@@ -4417,14 +4422,15 @@ njs_promise_trampoline(njs_vm_t *vm, njs_value_t *args,
 
 
 static njs_int_t
-njs_webcrypto_result(njs_vm_t *vm, njs_value_t *result, njs_int_t rc)
+njs_webcrypto_result(njs_vm_t *vm, njs_value_t *result, njs_int_t rc,
+    njs_value_t *retval)
 {
     njs_int_t       ret;
-    njs_value_t     retval, arguments[2];
+    njs_value_t     promise, arguments[2];
     njs_function_t  *callback;
     njs_vm_event_t  vm_event;
 
-    ret = njs_vm_promise_create(vm, &retval, njs_value_arg(&arguments));
+    ret = njs_vm_promise_create(vm, &promise, njs_value_arg(&arguments));
     if (ret != NJS_OK) {
         goto error;
     }
@@ -4440,14 +4446,20 @@ njs_webcrypto_result(njs_vm_t *vm, njs_value_t *result, njs_int_t rc)
     }
 
     njs_value_assign(&arguments[0], &arguments[(rc != NJS_OK)]);
-    njs_value_assign(&arguments[1], result);
+
+    if (rc != NJS_OK) {
+        njs_vm_exception_get(vm, njs_value_arg(&arguments[1]));
+
+    } else {
+        njs_value_assign(&arguments[1], result);
+    }
 
     ret = njs_vm_post_event(vm, vm_event, njs_value_arg(&arguments), 2);
     if (ret == NJS_ERROR) {
         goto error;
     }
 
-    njs_vm_retval_set(vm, njs_value_arg(&retval));
+    njs_value_assign(retval, &promise);
 
     return NJS_OK;
 
@@ -4557,7 +4569,7 @@ njs_webcrypto_error(njs_vm_t *vm, const char *fmt, ...)
         }
     }
 
-    njs_vm_value_error_set(vm, njs_vm_retval(vm), "%*s", p - errstr, errstr);
+    njs_vm_error(vm, "%*s", p - errstr, errstr);
 }
 
 
index 21f2f38440a80cd63615d831730763fad19395ff..a41ae58ade3ed8e088d575f9a3c82eac011e0462 100644 (file)
@@ -37,9 +37,9 @@ struct njs_xml_nset_s {
 };
 
 static njs_int_t njs_xml_ext_parse(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_xml_ext_canonicalization(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t magic);
+    njs_uint_t nargs, njs_index_t magic, njs_value_t *retval);
 static njs_int_t njs_xml_doc_ext_prop_keys(njs_vm_t *vm, njs_value_t *value,
     njs_value_t *keys);
 static njs_int_t njs_xml_doc_ext_root(njs_vm_t *vm, njs_object_prop_t *prop,
@@ -55,7 +55,7 @@ static njs_int_t njs_xml_attr_ext_prop_handler(njs_vm_t *vm,
     njs_object_prop_t *prop, njs_value_t *value, njs_value_t *unused,
     njs_value_t *retval);
 static njs_int_t njs_xml_node_ext_add_child(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t unused);
+    njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 static njs_int_t njs_xml_node_ext_attrs(njs_vm_t *vm, njs_object_prop_t *prop,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
 static njs_int_t njs_xml_node_ext_name(njs_vm_t *vm, njs_object_prop_t *prop,
@@ -65,17 +65,23 @@ static njs_int_t njs_xml_node_ext_ns(njs_vm_t *vm, njs_object_prop_t *prop,
 static njs_int_t njs_xml_node_ext_parent(njs_vm_t *vm, njs_object_prop_t *prop,
      njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
 static njs_int_t njs_xml_node_ext_remove_all_attributes(njs_vm_t *vm,
-    njs_value_t *args, njs_uint_t nargs, njs_index_t unused);
+    njs_value_t *args, njs_uint_t nargs, njs_index_t unused,
+    njs_value_t *retval);
 static njs_int_t njs_xml_node_ext_remove_attribute(njs_vm_t *vm,
-    njs_value_t *args, njs_uint_t nargs, njs_index_t unused);
+    njs_value_t *args, njs_uint_t nargs, njs_index_t unused,
+    njs_value_t *retval);
 static njs_int_t njs_xml_node_ext_remove_children(njs_vm_t *vm,
-    njs_value_t *args, njs_uint_t nargs, njs_index_t unused);
+    njs_value_t *args, njs_uint_t nargs, njs_index_t unused,
+    njs_value_t *retval);
 static njs_int_t njs_xml_node_ext_remove_text(njs_vm_t *vm,
-    njs_value_t *args, njs_uint_t nargs, njs_index_t unused);
+    njs_value_t *args, njs_uint_t nargs, njs_index_t unused,
+    njs_value_t *retval);
 static njs_int_t njs_xml_node_ext_set_attribute(njs_vm_t *vm,
-    njs_value_t *args, njs_uint_t nargs, njs_index_t unused);
+    njs_value_t *args, njs_uint_t nargs, njs_index_t unused,
+    njs_value_t *retval);
 static njs_int_t njs_xml_node_ext_set_text(njs_vm_t *vm,
-    njs_value_t *args, njs_uint_t nargs, njs_index_t unused);
+    njs_value_t *args, njs_uint_t nargs, njs_index_t unused,
+    njs_value_t *retval);
 static njs_int_t njs_xml_node_ext_tags(njs_vm_t *vm, njs_object_prop_t *prop,
      njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
 static njs_int_t njs_xml_node_ext_text(njs_vm_t *vm, njs_object_prop_t *prop,
@@ -407,7 +413,7 @@ static njs_int_t    njs_xml_attr_proto_id;
 
 static njs_int_t
 njs_xml_ext_parse(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_int_t         ret;
     njs_str_t         data;
@@ -448,7 +454,7 @@ njs_xml_ext_parse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     cln->handler = njs_xml_doc_cleanup;
     cln->data = tree;
 
-    return njs_vm_external_create(vm, njs_vm_retval(vm), njs_xml_doc_proto_id,
+    return njs_vm_external_create(vm, retval, njs_xml_doc_proto_id,
                                   tree, 0);
 }
 
@@ -705,7 +711,7 @@ njs_xml_node_ext_prop_handler(njs_vm_t *vm, njs_object_prop_t *prop,
 
 static njs_int_t
 njs_xml_node_ext_add_child(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t unused)
+    njs_uint_t nargs, njs_index_t unused, njs_value_t *retval)
 {
     xmlNode    *current, *node, *copy, *rnode;
     njs_int_t  ret;
@@ -747,7 +753,7 @@ njs_xml_node_ext_add_child(njs_vm_t *vm, njs_value_t *args,
         goto error;
     }
 
-    njs_value_undefined_set(njs_vm_retval(vm));
+    njs_value_undefined_set(retval);
 
     return njs_xml_replace_node(vm, current, copy);
 
@@ -832,15 +838,15 @@ njs_xml_node_ext_parent(njs_vm_t *vm, njs_object_prop_t *prop,
 
 static njs_int_t
 njs_xml_node_ext_remove_attribute(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)
 {
-    return njs_xml_node_ext_set_attribute(vm, args, nargs, 1);
+    return njs_xml_node_ext_set_attribute(vm, args, nargs, 1, retval);
 }
 
 
 static njs_int_t
 njs_xml_node_ext_remove_all_attributes(njs_vm_t *vm,
-    njs_value_t *args, njs_uint_t nargs, njs_index_t unused)
+    njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval)
 {
     xmlNode  *current;
 
@@ -855,7 +861,7 @@ njs_xml_node_ext_remove_all_attributes(njs_vm_t *vm,
         current->properties = NULL;
     }
 
-    njs_value_undefined_set(njs_vm_retval(vm));
+    njs_value_undefined_set(retval);
 
     return NJS_OK;
 }
@@ -863,7 +869,7 @@ njs_xml_node_ext_remove_all_attributes(njs_vm_t *vm,
 
 static njs_int_t
 njs_xml_node_ext_remove_children(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)
 {
     xmlNode      *current, *copy;
     njs_str_t    name;
@@ -877,7 +883,7 @@ njs_xml_node_ext_remove_children(njs_vm_t *vm, njs_value_t *args,
 
     selector = njs_arg(args, nargs, 1);
 
-    njs_value_undefined_set(njs_vm_retval(vm));
+    njs_value_undefined_set(retval);
 
     if (!njs_value_is_null_or_undefined(selector)) {
         if (njs_slow_path(!njs_value_is_string(selector))) {
@@ -909,7 +915,7 @@ njs_xml_node_ext_remove_children(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_xml_node_ext_remove_text(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t unused)
+    njs_uint_t nargs, njs_index_t unused, njs_value_t *retval)
 {
     return njs_xml_node_ext_text(vm, NULL, njs_argument(args, 0), NULL, NULL);
 }
@@ -917,7 +923,7 @@ njs_xml_node_ext_remove_text(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_xml_node_ext_set_attribute(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t remove)
+    njs_uint_t nargs, njs_index_t remove, njs_value_t *retval)
 {
     xmlNode      *current;
     njs_str_t    str;
@@ -939,16 +945,16 @@ njs_xml_node_ext_set_attribute(njs_vm_t *vm, njs_value_t *args,
     njs_value_string_get(name, &str);
 
     return njs_xml_node_attr_handler(vm, current, &str, njs_arg(args, nargs, 2),
-                                     !remove ? njs_vm_retval(vm) : NULL);
+                                     !remove ? retval : NULL);
 }
 
 
 static njs_int_t
 njs_xml_node_ext_set_text(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     return njs_xml_node_ext_text(vm, NULL, njs_argument(args, 0),
-                                 njs_arg(args, nargs, 1), njs_vm_retval(vm));
+                                 njs_arg(args, nargs, 1), retval);
 }
 
 
@@ -1701,7 +1707,7 @@ njs_xml_parse_ns_list(njs_vm_t *vm, njs_str_t *src)
 
 static njs_int_t
 njs_xml_ext_canonicalization(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t magic)
+    njs_index_t magic, njs_value_t *retval)
 {
     u_char           **prefix_list;
     ssize_t          size;
@@ -1792,7 +1798,7 @@ njs_xml_ext_canonicalization(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     if (magic & 0x2) {
-        ret = njs_vm_value_string_create_chb(vm, njs_vm_retval(vm), &chain);
+        ret = njs_vm_value_string_create_chb(vm, retval, &chain);
 
     } else {
         size = njs_chb_size(&chain);
@@ -1808,7 +1814,7 @@ njs_xml_ext_canonicalization(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             goto error;
         }
 
-        ret = njs_vm_value_buffer_set(vm, njs_vm_retval(vm), data.start,
+        ret = njs_vm_value_buffer_set(vm, retval, data.start,
                                       data.length);
     }
 
@@ -1990,7 +1996,7 @@ njs_xml_error(njs_vm_t *vm, njs_xml_doc_t *current, const char *fmt, ...)
                         err->int2);
     }
 
-    njs_vm_value_error_set(vm, njs_vm_retval(vm), "%*s", p - errstr, errstr);
+    njs_vm_error(vm, "%s", p - errstr, errstr);
 }
 
 
index fd674248285f72d00a32e991929f6aeafde55055..8dafb9dc0cc21702032340290f58617b1115396e 100644 (file)
@@ -11,9 +11,9 @@
 #define NJS_ZLIB_CHUNK_SIZE  1024
 
 static njs_int_t njs_zlib_ext_deflate(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_zlib_ext_inflate(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);
 njs_int_t njs_zlib_contant(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_zlib_init(njs_vm_t *vm);
@@ -182,7 +182,7 @@ njs_module_t  njs_zlib_module = {
 
 static njs_int_t
 njs_zlib_ext_deflate(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t raw)
+    njs_index_t raw, njs_value_t *retval)
 {
     int                 rc, level, mem_level, strategy, window_bits;
     u_char              *buffer;
@@ -355,7 +355,7 @@ njs_zlib_ext_deflate(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     njs_chb_destroy(&chain);
 
-    return njs_vm_value_buffer_set(vm, njs_vm_retval(vm), buffer, size);
+    return njs_vm_value_buffer_set(vm, retval, buffer, size);
 
 fail:
 
@@ -368,7 +368,7 @@ fail:
 
 static njs_int_t
 njs_zlib_ext_inflate(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t raw)
+    njs_index_t raw, njs_value_t *retval)
 {
     int                 rc, window_bits;
     u_char              *buffer;
@@ -502,7 +502,7 @@ njs_zlib_ext_inflate(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     njs_chb_destroy(&chain);
 
-    return njs_vm_value_buffer_set(vm, njs_vm_retval(vm), buffer, size);
+    return njs_vm_value_buffer_set(vm, retval, buffer, size);
 
 fail:
 
index 8f3ca9e65e9f69d3cbf5a777844b964de944212a..b9980f96e871847c6569941e32bb59751c8e69a5 100644 (file)
@@ -131,21 +131,23 @@ static njs_int_t ngx_http_js_ext_keys_header_out(njs_vm_t *vm,
 static njs_int_t ngx_http_js_ext_status(njs_vm_t *vm, njs_object_prop_t *prop,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
 static njs_int_t ngx_http_js_ext_send_header(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t unused);
+    njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 static njs_int_t ngx_http_js_ext_send(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t unused);
+    njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 static njs_int_t ngx_http_js_ext_send_buffer(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 ngx_http_js_ext_set_return_value(njs_vm_t *vm,
-    njs_value_t *args, njs_uint_t nargs, njs_index_t unused);
+    njs_value_t *args, njs_uint_t nargs, njs_index_t unused,
+    njs_value_t *retval);
 static njs_int_t ngx_http_js_ext_done(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 ngx_http_js_ext_finish(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 ngx_http_js_ext_return(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 ngx_http_js_ext_internal_redirect(njs_vm_t *vm,
-    njs_value_t *args, njs_uint_t nargs, njs_index_t unused);
+    njs_value_t *args, njs_uint_t nargs, njs_index_t unused,
+    njs_value_t *retval);
 
 static njs_int_t ngx_http_js_ext_get_http_version(njs_vm_t *vm,
     njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
@@ -183,7 +185,7 @@ static njs_int_t ngx_http_js_ext_variables(njs_vm_t *vm,
     njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
     njs_value_t *retval);
 static njs_int_t ngx_http_js_ext_subrequest(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t unused);
+    njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 static ngx_int_t ngx_http_js_subrequest(ngx_http_request_t *r,
     njs_str_t *uri_arg, njs_str_t *args_arg, njs_function_t *callback,
     ngx_http_request_t **sr);
@@ -1141,7 +1143,8 @@ ngx_http_js_variable_set(ngx_http_request_t *r, ngx_http_variable_value_t *v,
 
     pending = njs_vm_pending(ctx->vm);
 
-    rc = ngx_js_call(ctx->vm, fname, r->connection->log, &ctx->request, 1);
+    rc = ngx_js_invoke(ctx->vm, fname, r->connection->log, &ctx->request, 1,
+                       &ctx->retval);
 
     if (rc == NGX_ERROR) {
         v->not_found = 1;
@@ -1266,7 +1269,7 @@ ngx_http_js_init_vm(ngx_http_request_t *r)
         }
     }
 
-    if (njs_vm_start(ctx->vm) == NJS_ERROR) {
+    if (njs_vm_start(ctx->vm, njs_value_arg(&retval)) == NJS_ERROR) {
         ngx_js_retval(ctx->vm, NULL, &exception);
 
         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
@@ -2089,13 +2092,15 @@ ngx_http_js_ext_status(njs_vm_t *vm, njs_object_prop_t *prop,
 
     r->headers_out.status = n;
 
+    njs_value_undefined_set(retval);
+
     return NJS_OK;
 }
 
 
 static njs_int_t
 ngx_http_js_ext_send_header(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     ngx_http_request_t  *r;
 
@@ -2114,7 +2119,7 @@ ngx_http_js_ext_send_header(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    njs_value_undefined_set(njs_vm_retval(vm));
+    njs_value_undefined_set(retval);
 
     return NJS_OK;
 }
@@ -2122,7 +2127,7 @@ ngx_http_js_ext_send_header(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 ngx_http_js_ext_send(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_int_t            ret;
     njs_str_t            s;
@@ -2200,7 +2205,7 @@ ngx_http_js_ext_send(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    njs_value_undefined_set(njs_vm_retval(vm));
+    njs_value_undefined_set(retval);
 
     return NJS_OK;
 }
@@ -2208,7 +2213,7 @@ ngx_http_js_ext_send(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 ngx_http_js_ext_send_buffer(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     unsigned             last_buf, flush;
     njs_str_t            buffer;
@@ -2281,7 +2286,7 @@ ngx_http_js_ext_send_buffer(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     *ctx->last_out = cl;
     ctx->last_out = &cl->next;
 
-    njs_value_undefined_set(njs_vm_retval(vm));
+    njs_value_undefined_set(retval);
 
     return NJS_OK;
 }
@@ -2289,7 +2294,7 @@ ngx_http_js_ext_send_buffer(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 ngx_http_js_ext_set_return_value(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)
 {
     ngx_http_js_ctx_t   *ctx;
     ngx_http_request_t  *r;
@@ -2304,7 +2309,7 @@ ngx_http_js_ext_set_return_value(njs_vm_t *vm, njs_value_t *args,
     ctx = ngx_http_get_module_ctx(r, ngx_http_js_module);
 
     njs_value_assign(&ctx->retval, njs_arg(args, nargs, 1));
-    njs_value_undefined_set(njs_vm_retval(vm));
+    njs_value_undefined_set(retval);
 
     return NJS_OK;
 }
@@ -2312,7 +2317,7 @@ ngx_http_js_ext_set_return_value(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 ngx_http_js_ext_done(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     ngx_http_js_ctx_t   *ctx;
     ngx_http_request_t  *r;
@@ -2333,7 +2338,7 @@ ngx_http_js_ext_done(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     ctx->done = 1;
 
-    njs_value_undefined_set(njs_vm_retval(vm));
+    njs_value_undefined_set(retval);
 
     return NJS_OK;
 }
@@ -2341,7 +2346,7 @@ ngx_http_js_ext_done(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 ngx_http_js_ext_finish(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     ngx_http_js_ctx_t   *ctx;
     ngx_http_request_t  *r;
@@ -2361,7 +2366,7 @@ ngx_http_js_ext_finish(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     ctx->status = NGX_OK;
 
-    njs_value_undefined_set(njs_vm_retval(vm));
+    njs_value_undefined_set(retval);
 
     return NJS_OK;
 }
@@ -2369,7 +2374,7 @@ ngx_http_js_ext_finish(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 ngx_http_js_ext_return(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                  text;
     ngx_int_t                  status;
@@ -2417,7 +2422,7 @@ ngx_http_js_ext_return(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         ctx->status = status;
     }
 
-    njs_value_undefined_set(njs_vm_retval(vm));
+    njs_value_undefined_set(retval);
 
     return NJS_OK;
 }
@@ -2425,7 +2430,7 @@ ngx_http_js_ext_return(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 ngx_http_js_ext_internal_redirect(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)
 {
     njs_str_t            uri;
     ngx_http_js_ctx_t   *ctx;
@@ -2460,7 +2465,7 @@ ngx_http_js_ext_internal_redirect(njs_vm_t *vm, njs_value_t *args,
 
     ctx->status = NGX_DONE;
 
-    njs_value_undefined_set(njs_vm_retval(vm));
+    njs_value_undefined_set(retval);
 
     return NJS_OK;
 }
@@ -2979,7 +2984,7 @@ ngx_http_js_ext_variables(njs_vm_t *vm, njs_object_prop_t *prop,
 
 static njs_int_t
 ngx_http_js_promise_trampoline(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)
 {
     ngx_uint_t           i;
     njs_function_t      *callback;
@@ -3033,7 +3038,7 @@ fail:
 
 static njs_int_t
 ngx_http_js_ext_subrequest(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     ngx_int_t                 rc, promise;
     njs_str_t                 uri_arg, args_arg, method_name, body_arg;
@@ -3277,11 +3282,11 @@ ngx_http_js_ext_subrequest(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
         cb->request = sr;
 
-        return njs_vm_promise_create(vm, njs_vm_retval(vm),
+        return njs_vm_promise_create(vm, retval,
                                      njs_value_arg(&cb->callbacks));
     }
 
-    njs_value_undefined_set(njs_vm_retval(vm));
+    njs_value_undefined_set(retval);
 
     return NJS_OK;
 
index b90dafa6374a6b2230020efb01751713deb2e0ad..2b5be2cee6d72f6ca74fc340d73e8bdb60f46d21 100644 (file)
@@ -98,6 +98,16 @@ njs_module_t *njs_js_addon_modules[] = {
 ngx_int_t
 ngx_js_call(njs_vm_t *vm, ngx_str_t *fname, ngx_log_t *log,
     njs_opaque_value_t *args, njs_uint_t nargs)
+{
+    njs_opaque_value_t  unused;
+
+    return ngx_js_invoke(vm, fname, log, args, nargs, &unused);
+}
+
+
+ngx_int_t
+ngx_js_invoke(njs_vm_t *vm, ngx_str_t *fname, ngx_log_t *log,
+    njs_opaque_value_t *args, njs_uint_t nargs, njs_opaque_value_t *retval)
 {
     njs_int_t        ret;
     njs_str_t        name;
@@ -114,7 +124,8 @@ ngx_js_call(njs_vm_t *vm, ngx_str_t *fname, ngx_log_t *log,
         return NGX_ERROR;
     }
 
-    ret = njs_vm_call(vm, func, njs_value_arg(args), nargs);
+    ret = njs_vm_invoke(vm, func, njs_value_arg(args), nargs,
+                        njs_value_arg(retval));
     if (ret == NJS_ERROR) {
         ngx_js_retval(vm, NULL, &exception);
 
@@ -148,7 +159,7 @@ ngx_js_retval(njs_vm_t *vm, njs_opaque_value_t *retval, ngx_str_t *s)
         ret = njs_vm_value_string(vm, &str, njs_value_arg(retval));
 
     } else {
-        ret = njs_vm_retval_string(vm, &str);
+        ret = njs_vm_exception_string(vm, &str);
     }
 
     if (ret != NJS_OK) {
@@ -332,7 +343,7 @@ ngx_js_ext_conf_prefix(njs_vm_t *vm, njs_object_prop_t *prop,
 
 njs_int_t
 ngx_js_ext_log(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t level)
+    njs_index_t level, njs_value_t *retval)
 {
     char                *p;
     ngx_int_t            lvl;
@@ -370,7 +381,7 @@ ngx_js_ext_log(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     c->log->handler = handler;
 
-    njs_value_undefined_set(njs_vm_retval(vm));
+    njs_value_undefined_set(retval);
 
     return NJS_OK;
 }
@@ -628,6 +639,7 @@ ngx_js_init_preload_vm(ngx_conf_t *cf, ngx_js_conf_t *conf)
     njs_int_t             ret;
     ngx_uint_t            i;
     njs_vm_opt_t          options;
+    njs_opaque_value_t    retval;
     ngx_js_named_path_t  *preload;
 
     njs_vm_opt_init(&options);
@@ -695,7 +707,7 @@ ngx_js_init_preload_vm(ngx_conf_t *cf, ngx_js_conf_t *conf)
         goto error;
     }
 
-    ret = njs_vm_start(vm);
+    ret = njs_vm_start(vm, njs_value_arg(&retval));
     if (ret != NJS_OK) {
         goto error;
     }
@@ -991,8 +1003,8 @@ ngx_js_init_conf_vm(ngx_conf_t *cf, ngx_js_conf_t *conf,
     rc = njs_vm_compile(conf->vm, &start, end);
 
     if (rc != NJS_OK) {
-        njs_value_assign(&exception, njs_vm_retval(conf->vm));
-        njs_vm_retval_string(conf->vm, &text);
+        njs_vm_exception_get(conf->vm, njs_value_arg(&exception));
+        njs_vm_value_string(conf->vm, &text, njs_value_arg(&exception));
 
         value = njs_vm_object_prop(conf->vm, njs_value_arg(&exception),
                                    &file_name_key, &lvalue);
index 2e153fe9adb6808d6d444fe04395c2f16b95b46c..66cf22f0408a550b7be1b5bba0ba7e1e083823bc 100644 (file)
@@ -113,11 +113,13 @@ typedef struct {
 
 ngx_int_t ngx_js_call(njs_vm_t *vm, ngx_str_t *fname, ngx_log_t *log,
     njs_opaque_value_t *args, njs_uint_t nargs);
+ngx_int_t ngx_js_invoke(njs_vm_t *vm, ngx_str_t *fname, ngx_log_t *log,
+    njs_opaque_value_t *args, njs_uint_t nargs, njs_opaque_value_t *retval);
 ngx_int_t ngx_js_retval(njs_vm_t *vm, njs_opaque_value_t *retval,
     ngx_str_t *s);
 
 njs_int_t ngx_js_ext_log(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t level);
+    njs_index_t level, njs_value_t *retval);
 void ngx_js_logger(njs_vm_t *vm, njs_external_ptr_t external,
     njs_log_level_t level, const u_char *start, size_t length);
 char * ngx_js_import(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
index f329d71722fd70f9e514cd333025aacd12193410..8d4dde4d8bc950e7d1826e0fc85091240e47d5ed 100644 (file)
@@ -161,9 +161,9 @@ struct ngx_js_http_s {
 
 #define ngx_js_http_error(http, err, fmt, ...)                                \
     do {                                                                      \
-        njs_vm_value_error_set((http)->vm,                                    \
-                               njs_value_arg(&(http)->response_value),        \
-                               fmt, ##__VA_ARGS__);                           \
+        njs_vm_error((http)->vm, fmt, ##__VA_ARGS__);                         \
+        njs_vm_exception_get((http)->vm,                                      \
+                             njs_value_arg(&(http)->response_value));         \
         ngx_js_http_fetch_done(http, &(http)->response_value, NJS_ERROR);     \
     } while (0)
 
@@ -179,11 +179,12 @@ static void njs_js_http_destructor(njs_external_ptr_t external,
     njs_host_event_t host);
 static void ngx_js_resolve_handler(ngx_resolver_ctx_t *ctx);
 static njs_int_t ngx_js_fetch_promissified_result(njs_vm_t *vm,
-    njs_value_t *result, njs_int_t rc);
+    njs_value_t *result, njs_int_t rc, njs_value_t *retval);
 static void ngx_js_http_fetch_done(ngx_js_http_t *http,
     njs_opaque_value_t *retval, njs_int_t rc);
 static njs_int_t ngx_js_http_promise_trampoline(njs_vm_t *vm,
-    njs_value_t *args, njs_uint_t nargs, njs_index_t unused);
+    njs_value_t *args, njs_uint_t nargs, njs_index_t unused,
+    njs_value_t *retval);
 static void ngx_js_http_connect(ngx_js_http_t *http);
 static void ngx_js_http_next(ngx_js_http_t *http);
 static void ngx_js_http_write_handler(ngx_event_t *wev);
@@ -208,24 +209,24 @@ static ngx_int_t ngx_js_http_parse_chunked(ngx_js_http_chunk_parse_t *hcp,
 static void ngx_js_http_dummy_handler(ngx_event_t *ev);
 
 static njs_int_t ngx_headers_js_ext_append(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 ngx_headers_js_ext_delete(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 ngx_headers_js_ext_for_each(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t as_array);
+    njs_uint_t nargs, njs_index_t as_array, njs_value_t *retval);
 static njs_int_t ngx_headers_js_ext_get(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t as_array);
+    njs_uint_t nargs, njs_index_t as_array, njs_value_t *retval);
 static njs_int_t ngx_headers_js_ext_has(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t unused);
+    njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 static njs_int_t ngx_headers_js_ext_prop(njs_vm_t *vm,
     njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
     njs_value_t *retval);
 static njs_int_t ngx_headers_js_ext_keys(njs_vm_t *vm, njs_value_t *value,
     njs_value_t *keys);
 static njs_int_t ngx_headers_js_ext_set(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t unused);
+    njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 static njs_int_t ngx_request_js_ext_body(njs_vm_t *vm, njs_value_t *args,
-     njs_uint_t nargs, njs_index_t unused);
+     njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 static njs_int_t ngx_request_js_ext_body_used(njs_vm_t *vm,
     njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
     njs_value_t *retval);
@@ -259,7 +260,7 @@ static njs_int_t ngx_response_js_ext_type(njs_vm_t *vm,
     njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
     njs_value_t *retval);
 static njs_int_t ngx_response_js_ext_body(njs_vm_t *vm, njs_value_t *args,
-     njs_uint_t nargs, njs_index_t unused);
+     njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 
 #if (NGX_SSL)
 static void ngx_js_http_ssl_init_connection(ngx_js_http_t *http);
@@ -652,7 +653,7 @@ static njs_int_t    ngx_http_js_fetch_headers_proto_id;
 
 njs_int_t
 ngx_js_ext_fetch(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_int_t            ret;
     ngx_url_t            u;
@@ -816,7 +817,7 @@ ngx_js_ext_fetch(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             return NJS_ERROR;
         }
 
-        njs_vm_retval_set(vm, njs_value_arg(&http->promise));
+        njs_value_assign(retval, njs_value_arg(&http->promise));
 
         return NJS_OK;
     }
@@ -827,16 +828,18 @@ ngx_js_ext_fetch(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     ngx_js_http_connect(http);
 
-    njs_vm_retval_set(vm, njs_value_arg(&http->promise));
+    njs_value_assign(retval, njs_value_arg(&http->promise));
 
     return NJS_OK;
 
 fail:
 
-    ngx_js_http_fetch_done(http, (njs_opaque_value_t *) njs_vm_retval(vm),
-                           NJS_ERROR);
 
-    njs_vm_retval_set(vm, njs_value_arg(&http->promise));
+    njs_vm_exception_get(vm, njs_value_arg(&lvalue));
+
+    ngx_js_http_fetch_done(http, &lvalue, NJS_ERROR);
+
+    njs_value_assign(retval, njs_value_arg(&http->promise));
 
     return NJS_OK;
 }
@@ -844,7 +847,7 @@ fail:
 
 static njs_int_t
 ngx_js_ext_headers_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)
 {
     ngx_int_t          rc;
     njs_int_t          ret;
@@ -877,7 +880,7 @@ ngx_js_ext_headers_constructor(njs_vm_t *vm, njs_value_t *args,
         }
     }
 
-    return njs_vm_external_create(vm, njs_vm_retval(vm),
+    return njs_vm_external_create(vm, retval,
                                   ngx_http_js_fetch_headers_proto_id, headers,
                                   0);
 }
@@ -885,7 +888,7 @@ ngx_js_ext_headers_constructor(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 ngx_js_ext_request_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)
 {
     njs_int_t          ret;
     ngx_url_t          u;
@@ -903,7 +906,7 @@ ngx_js_ext_request_constructor(njs_vm_t *vm, njs_value_t *args,
         return NJS_ERROR;
     }
 
-    return njs_vm_external_create(vm, njs_vm_retval(vm),
+    return njs_vm_external_create(vm, retval,
                                   ngx_http_js_fetch_request_proto_id, request,
                                   0);
 }
@@ -911,7 +914,7 @@ ngx_js_ext_request_constructor(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 ngx_js_ext_response_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)
 {
     u_char              *p, *end;
     ngx_int_t            rc;
@@ -1026,7 +1029,7 @@ ngx_js_ext_response_constructor(njs_vm_t *vm, njs_value_t *args,
         }
     }
 
-    return njs_vm_external_create(vm, njs_vm_retval(vm),
+    return njs_vm_external_create(vm, retval,
                                   ngx_http_js_fetch_response_proto_id, response,
                                   0);
 }
@@ -1397,14 +1400,14 @@ njs_js_http_destructor(njs_external_ptr_t external, njs_host_event_t host)
 
 static njs_int_t
 ngx_js_fetch_promissified_result(njs_vm_t *vm, njs_value_t *result,
-    njs_int_t rc)
+    njs_int_t rc, njs_value_t *retval)
 {
     njs_int_t            ret;
     njs_function_t      *callback;
     njs_vm_event_t       vm_event;
-    njs_opaque_value_t   retval, arguments[2];
+    njs_opaque_value_t   promise, arguments[2];
 
-    ret = njs_vm_promise_create(vm, njs_value_arg(&retval),
+    ret = njs_vm_promise_create(vm, njs_value_arg(&promise),
                                 njs_value_arg(&arguments));
     if (ret != NJS_OK) {
         goto error;
@@ -1421,14 +1424,20 @@ ngx_js_fetch_promissified_result(njs_vm_t *vm, njs_value_t *result,
     }
 
     njs_value_assign(&arguments[0], &arguments[(rc != NJS_OK)]);
-    njs_value_assign(&arguments[1], result);
+
+    if (rc != NJS_OK) {
+        njs_vm_exception_get(vm, njs_value_arg(&arguments[1]));
+
+    } else {
+        njs_value_assign(&arguments[1], result);
+    }
 
     ret = njs_vm_post_event(vm, vm_event, njs_value_arg(&arguments), 2);
     if (ret == NJS_ERROR) {
         goto error;
     }
 
-    njs_vm_retval_set(vm, njs_value_arg(&retval));
+    njs_value_assign(retval, &promise);
 
     return NJS_OK;
 
@@ -1466,7 +1475,7 @@ ngx_js_http_fetch_done(ngx_js_http_t *http, njs_opaque_value_t *retval,
 
 static njs_int_t
 ngx_js_http_promise_trampoline(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)
 {
     njs_function_t  *callback;
 
@@ -3265,7 +3274,7 @@ ngx_headers_js_get(njs_vm_t *vm, njs_value_t *value, njs_str_t *name,
 
 static njs_int_t
 ngx_headers_js_ext_append(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_int_t          ret;
     njs_str_t          name, value;
@@ -3294,7 +3303,7 @@ ngx_headers_js_ext_append(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    njs_value_undefined_set(njs_vm_retval(vm));
+    njs_value_undefined_set(retval);
 
     return NJS_OK;
 }
@@ -3302,7 +3311,7 @@ ngx_headers_js_ext_append(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 ngx_headers_js_ext_delete(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_int_t          ret;
     njs_str_t          name;
@@ -3349,7 +3358,7 @@ ngx_headers_js_ext_delete(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         }
     }
 
-    njs_value_undefined_set(njs_vm_retval(vm));
+    njs_value_undefined_set(retval);
 
     return NJS_OK;
 }
@@ -3357,7 +3366,7 @@ ngx_headers_js_ext_delete(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 ngx_headers_js_ext_for_each(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     int64_t              length;
     njs_int_t            ret;
@@ -3418,7 +3427,7 @@ ngx_headers_js_ext_for_each(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 ngx_headers_js_ext_get(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t as_array)
+    njs_index_t as_array, njs_value_t *retval)
 {
     njs_int_t  ret;
     njs_str_t  name;
@@ -3429,7 +3438,7 @@ ngx_headers_js_ext_get(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     ret = ngx_headers_js_get(vm, njs_argument(args, 0), &name,
-                             njs_vm_retval(vm), as_array);
+                             retval, as_array);
 
     return (ret != NJS_ERROR) ? NJS_OK : NJS_ERROR;
 }
@@ -3437,7 +3446,7 @@ ngx_headers_js_ext_get(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 ngx_headers_js_ext_has(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     njs_int_t  ret;
     njs_str_t  name;
@@ -3448,12 +3457,12 @@ ngx_headers_js_ext_has(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     ret = ngx_headers_js_get(vm, njs_argument(args, 0), &name,
-                             njs_vm_retval(vm), 0);
+                             retval, 0);
     if (ret == NJS_ERROR) {
         return NJS_ERROR;
     }
 
-    njs_value_boolean_set(njs_vm_retval(vm), ret == NJS_OK);
+    njs_value_boolean_set(retval, ret == NJS_OK);
 
     return NJS_OK;
 }
@@ -3564,7 +3573,7 @@ ngx_headers_js_ext_keys(njs_vm_t *vm, njs_value_t *value, njs_value_t *keys)
 
 static njs_int_t
 ngx_headers_js_ext_set(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     njs_int_t          ret;
     njs_str_t          name, value;
@@ -3625,7 +3634,7 @@ ngx_headers_js_ext_set(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         }
     }
 
-    njs_value_undefined_set(njs_vm_retval(vm));
+    njs_value_undefined_set(retval);
 
     return NJS_OK;
 }
@@ -3633,16 +3642,16 @@ ngx_headers_js_ext_set(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 ngx_request_js_ext_body(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t type)
+    njs_index_t type, njs_value_t *retval)
 {
     njs_int_t            ret;
     ngx_js_request_t    *request;
-    njs_opaque_value_t   retval;
+    njs_opaque_value_t   result;
 
     request = njs_vm_external(vm, ngx_http_js_fetch_request_proto_id,
                               njs_argument(args, 0));
     if (request == NULL) {
-        njs_value_undefined_set(njs_vm_retval(vm));
+        njs_value_undefined_set(retval);
         return NJS_DECLINED;
     }
 
@@ -3655,7 +3664,7 @@ ngx_request_js_ext_body(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     switch (type) {
     case NGX_JS_BODY_ARRAY_BUFFER:
-        ret = njs_vm_value_array_buffer_set(vm, njs_value_arg(&retval),
+        ret = njs_vm_value_array_buffer_set(vm, njs_value_arg(&result),
                                             request->body.start,
                                             request->body.length);
         if (ret != NJS_OK) {
@@ -3668,7 +3677,7 @@ ngx_request_js_ext_body(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     case NGX_JS_BODY_JSON:
     case NGX_JS_BODY_TEXT:
     default:
-        ret = njs_vm_value_string_set(vm, njs_value_arg(&retval),
+        ret = njs_vm_value_string_set(vm, njs_value_arg(&result),
                                       request->body.start,
                                       request->body.length);
         if (ret != NJS_OK) {
@@ -3677,12 +3686,13 @@ ngx_request_js_ext_body(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         }
 
         if (type == NGX_JS_BODY_JSON) {
-            ret = njs_vm_json_parse(vm, njs_value_arg(&retval), 1);
-            njs_value_assign(&retval, njs_vm_retval(vm));
+            ret = njs_vm_json_parse(vm, njs_value_arg(&result), 1,
+                                    njs_value_arg(&result));
         }
     }
 
-    return ngx_js_fetch_promissified_result(vm, njs_value_arg(&retval), ret);
+    return ngx_js_fetch_promissified_result(vm, njs_value_arg(&result), ret,
+                                            retval);
 }
 
 
@@ -3786,17 +3796,17 @@ ngx_request_js_ext_mode(njs_vm_t *vm, njs_object_prop_t *prop,
 
 static njs_int_t
 ngx_response_js_ext_body(njs_vm_t *vm, njs_value_t *args,
-     njs_uint_t nargs, njs_index_t type)
+     njs_uint_t nargs, njs_index_t type, njs_value_t *retval)
 {
     njs_int_t            ret;
     njs_str_t            string;
     ngx_js_response_t   *response;
-    njs_opaque_value_t   retval;
+    njs_opaque_value_t   result;
 
     response = njs_vm_external(vm, ngx_http_js_fetch_response_proto_id,
                                njs_argument(args, 0));
     if (response == NULL) {
-        njs_value_undefined_set(njs_vm_retval(vm));
+        njs_value_undefined_set(retval);
         return NJS_DECLINED;
     }
 
@@ -3815,7 +3825,7 @@ ngx_response_js_ext_body(njs_vm_t *vm, njs_value_t *args,
 
     switch (type) {
     case NGX_JS_BODY_ARRAY_BUFFER:
-        ret = njs_vm_value_array_buffer_set(vm, njs_value_arg(&retval),
+        ret = njs_vm_value_array_buffer_set(vm, njs_value_arg(&result),
                                             string.start, string.length);
         if (ret != NJS_OK) {
             njs_vm_memory_error(vm);
@@ -3827,7 +3837,7 @@ ngx_response_js_ext_body(njs_vm_t *vm, njs_value_t *args,
     case NGX_JS_BODY_JSON:
     case NGX_JS_BODY_TEXT:
     default:
-        ret = njs_vm_value_string_set(vm, njs_value_arg(&retval),
+        ret = njs_vm_value_string_set(vm, njs_value_arg(&result),
                                       string.start, string.length);
         if (ret != NJS_OK) {
             njs_vm_memory_error(vm);
@@ -3835,12 +3845,13 @@ ngx_response_js_ext_body(njs_vm_t *vm, njs_value_t *args,
         }
 
         if (type == NGX_JS_BODY_JSON) {
-            ret = njs_vm_json_parse(vm, njs_value_arg(&retval), 1);
-            njs_value_assign(&retval, njs_vm_retval(vm));
+            ret = njs_vm_json_parse(vm, njs_value_arg(&result), 1, retval);
+            njs_value_assign(&result, retval);
         }
     }
 
-    return ngx_js_fetch_promissified_result(vm, njs_value_arg(&retval), ret);
+    return ngx_js_fetch_promissified_result(vm, njs_value_arg(&result), ret,
+                                            retval);
 }
 
 
index 7f107c41a23a13200c9d4eb0e2917ec49c9dc2be..1a1cc17316f0be2eb76aa4c458522ccbedc44e3e 100644 (file)
@@ -10,7 +10,7 @@
 
 
 njs_int_t ngx_js_ext_fetch(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t level);
+    njs_index_t level, njs_value_t *retval);
 
 ngx_int_t ngx_js_fetch_init(njs_vm_t *vm, ngx_log_t *log);
 
index a45c4e323e04bd7b4c48eb1e7a990a628156a54c..ca46d476d519cd5de46e58a2c7c4e76e1fae122d 100644 (file)
@@ -80,16 +80,17 @@ static njs_int_t ngx_stream_js_ext_get_remote_address(njs_vm_t *vm,
     njs_value_t *retval);
 
 static njs_int_t ngx_stream_js_ext_done(njs_vm_t *vm, njs_value_t *args,
-     njs_uint_t nargs, njs_index_t unused);
+     njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 
 static njs_int_t ngx_stream_js_ext_on(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 ngx_stream_js_ext_off(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 ngx_stream_js_ext_send(njs_vm_t *vm, njs_value_t *args,
-     njs_uint_t nargs, njs_index_t from_upstream);
+     njs_uint_t nargs, njs_index_t from_upstream, njs_value_t *retval);
 static njs_int_t ngx_stream_js_ext_set_return_value(njs_vm_t *vm,
-    njs_value_t *args, njs_uint_t nargs, njs_index_t unused);
+    njs_value_t *args, njs_uint_t nargs, njs_index_t unused,
+    njs_value_t *retval);
 
 static njs_int_t ngx_stream_js_ext_variables(njs_vm_t *vm,
     njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
@@ -812,7 +813,8 @@ ngx_stream_js_variable_set(ngx_stream_session_t *s,
 
     pending = njs_vm_pending(ctx->vm);
 
-    rc = ngx_js_call(ctx->vm, fname, s->connection->log, &ctx->args[0], 1);
+    rc = ngx_js_invoke(ctx->vm, fname, s->connection->log, &ctx->args[0], 1,
+                       &ctx->retval);
 
     if (rc == NGX_ERROR) {
         v->not_found = 1;
@@ -935,7 +937,7 @@ ngx_stream_js_init_vm(ngx_stream_session_t *s)
         }
     }
 
-    if (njs_vm_start(ctx->vm) == NJS_ERROR) {
+    if (njs_vm_start(ctx->vm, njs_value_arg(&retval)) == NJS_ERROR) {
         ngx_js_retval(ctx->vm, NULL, &exception);
 
         ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
@@ -1137,7 +1139,7 @@ ngx_stream_js_ext_get_remote_address(njs_vm_t *vm,
 
 static njs_int_t
 ngx_stream_js_ext_done(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t magic)
+    njs_index_t magic, njs_value_t *retval)
 {
     ngx_int_t              status;
     njs_value_t           *code;
@@ -1186,7 +1188,7 @@ ngx_stream_js_ext_done(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     ngx_stream_js_drop_events(ctx);
 
-    njs_value_undefined_set(njs_vm_retval(vm));
+    njs_value_undefined_set(retval);
 
     return NJS_OK;
 }
@@ -1194,7 +1196,7 @@ ngx_stream_js_ext_done(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 ngx_stream_js_ext_on(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              name;
     njs_value_t           *callback;
@@ -1235,7 +1237,7 @@ ngx_stream_js_ext_on(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    njs_value_undefined_set(njs_vm_retval(vm));
+    njs_value_undefined_set(retval);
 
     return NJS_OK;
 }
@@ -1243,7 +1245,7 @@ ngx_stream_js_ext_on(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 ngx_stream_js_ext_off(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              name;
     njs_vm_event_t        *event;
@@ -1270,7 +1272,7 @@ ngx_stream_js_ext_off(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     *event = NULL;
 
-    njs_value_undefined_set(njs_vm_retval(vm));
+    njs_value_undefined_set(retval);
 
     return NJS_OK;
 }
@@ -1278,7 +1280,7 @@ ngx_stream_js_ext_off(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 ngx_stream_js_ext_send(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t from_upstream)
+    njs_index_t from_upstream, njs_value_t *retval)
 {
     unsigned               last_buf, flush;
     njs_str_t              buffer;
@@ -1386,7 +1388,7 @@ ngx_stream_js_ext_send(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         }
     }
 
-    njs_value_undefined_set(njs_vm_retval(vm));
+    njs_value_undefined_set(retval);
 
     return NJS_OK;
 
@@ -1401,7 +1403,7 @@ exception:
 
 static njs_int_t
 ngx_stream_js_ext_set_return_value(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)
 {
     ngx_stream_js_ctx_t   *ctx;
     ngx_stream_session_t  *s;
@@ -1416,7 +1418,7 @@ ngx_stream_js_ext_set_return_value(njs_vm_t *vm, njs_value_t *args,
     ctx = ngx_stream_get_module_ctx(s, ngx_stream_js_module);
 
     njs_value_assign(&ctx->retval, njs_arg(args, nargs, 1));
-    njs_value_undefined_set(njs_vm_retval(vm));
+    njs_value_undefined_set(retval);
 
     return NJS_OK;
 }
index 477231378ffab24233bb64a24d7459ac6bccc370..fd07215f2f0eb147b9ce32da8d9ea85f05bdfc8d 100644 (file)
--- a/src/njs.h
+++ b/src/njs.h
@@ -71,9 +71,6 @@ extern const njs_value_t            njs_value_undefined;
     ((n < nargs) ? njs_argument(args, n)                                      \
                  : (njs_value_assign(lvalue, &njs_value_undefined), lvalue))
 
-#define njs_vm_error(vm, fmt, ...)                                            \
-    njs_vm_value_error_set(vm, njs_vm_retval(vm), fmt, ##__VA_ARGS__)
-
 #define njs_vm_log(vm, fmt, ...)  njs_vm_logger(vm, NJS_LOG_LEVEL_INFO, fmt,  \
                                                 ##__VA_ARGS__)
 #define njs_vm_warn(vm, fmt, ...)  njs_vm_logger(vm, NJS_LOG_LEVEL_WARN, fmt, \
@@ -102,14 +99,15 @@ extern const njs_value_t            njs_value_undefined;
  *   NJS_OK - handler executed successfully;
  *   NJS_DECLINED - handler was applied to inappropriate object, retval
  *   contains undefined value;
- *   NJS_ERROR - some error, vm->retval contains appropriate exception.
+ *   NJS_ERROR - some error, njs_vm_exception_get(vm) can be used to get
+ *   the exception value.
  */
 typedef njs_int_t (*njs_prop_handler_t) (njs_vm_t *vm, njs_object_prop_t *prop,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
 typedef njs_int_t (*njs_exotic_keys_t)(njs_vm_t *vm, njs_value_t *value,
     njs_value_t *retval);
 typedef njs_int_t (*njs_function_native_t) (njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t magic8);
+    njs_uint_t nargs, njs_index_t magic8, njs_value_t *retval);
 
 
 typedef enum {
@@ -344,7 +342,7 @@ NJS_EXPORT njs_int_t njs_vm_posted(njs_vm_t *vm);
  *  NJS_OK successful run.
  *  NJS_ERROR some exception or internal error happens.
  *
- *  njs_vm_retval(vm) can be used to get the retval or exception value.
+ *  njs_vm_exception_get(vm) can be used to get the exception value.
  */
 NJS_EXPORT njs_int_t njs_vm_call(njs_vm_t *vm, njs_function_t *function,
     const njs_value_t *args, njs_uint_t nargs);
@@ -357,7 +355,7 @@ NJS_EXPORT njs_int_t njs_vm_invoke(njs_vm_t *vm, njs_function_t *function,
  *  NJS_AGAIN successfully processed all events, some posted events are
  *    still pending.
  *  NJS_ERROR some exception or internal error happens.
- *    njs_vm_retval(vm) can be used to get the retval or exception value.
+ *    njs_vm_exception_get(vm) can be used to get the exception value.
  */
 NJS_EXPORT njs_int_t njs_vm_run(njs_vm_t *vm);
 
@@ -366,9 +364,9 @@ NJS_EXPORT njs_int_t njs_vm_run(njs_vm_t *vm);
  *   NJS_OK successful run.
  *   NJS_ERROR some exception or internal error happens.
  *
- *   njs_vm_retval(vm) can be used to get the retval or exception value.
+ *   njs_vm_exception_get(vm) can be used to get the exception value.
  */
-NJS_EXPORT njs_int_t njs_vm_start(njs_vm_t *vm);
+NJS_EXPORT njs_int_t njs_vm_start(njs_vm_t *vm, njs_value_t *retval);
 
 NJS_EXPORT njs_int_t njs_vm_add_path(njs_vm_t *vm, const njs_str_t *path);
 
@@ -397,7 +395,9 @@ NJS_EXPORT njs_int_t njs_vm_value(njs_vm_t *vm, const njs_str_t *path,
 NJS_EXPORT njs_function_t *njs_vm_function(njs_vm_t *vm, const njs_str_t *name);
 
 NJS_EXPORT njs_value_t *njs_vm_retval(njs_vm_t *vm);
-NJS_EXPORT void njs_vm_retval_set(njs_vm_t *vm, const njs_value_t *value);
+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, ...);
+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);
 
@@ -453,16 +453,12 @@ NJS_EXPORT njs_int_t njs_vm_value_string(njs_vm_t *vm, njs_str_t *dst,
  * the terminating zero byte.
  */
 NJS_EXPORT const char *njs_vm_value_to_c_string(njs_vm_t *vm,
-       njs_value_t *value);
-NJS_EXPORT njs_int_t njs_vm_retval_string(njs_vm_t *vm, njs_str_t *dst);
+    njs_value_t *value);
+NJS_EXPORT njs_int_t njs_vm_exception_string(njs_vm_t *vm, njs_str_t *dst);
 
 NJS_EXPORT njs_int_t njs_vm_value_dump(njs_vm_t *vm, njs_str_t *dst,
     njs_value_t *value, njs_uint_t console, njs_uint_t indent);
-NJS_EXPORT njs_int_t njs_vm_retval_dump(njs_vm_t *vm, njs_str_t *dst,
-    njs_uint_t indent);
 
-NJS_EXPORT void njs_vm_value_error_set(njs_vm_t *vm, njs_value_t *value,
-    const char *fmt, ...);
 NJS_EXPORT void njs_vm_memory_error(njs_vm_t *vm);
 
 NJS_EXPORT void njs_vm_logger(njs_vm_t *vm, njs_log_level_t level,
@@ -516,9 +512,9 @@ NJS_EXPORT njs_value_t *njs_vm_array_prop(njs_vm_t *vm,
 NJS_EXPORT njs_value_t *njs_vm_array_push(njs_vm_t *vm, njs_value_t *value);
 
 NJS_EXPORT njs_int_t njs_vm_json_parse(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs);
+    njs_uint_t nargs, njs_value_t *retval);
 NJS_EXPORT njs_int_t njs_vm_json_stringify(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs);
+    njs_uint_t nargs, njs_value_t *retval);
 
 NJS_EXPORT njs_int_t njs_vm_query_string_parse(njs_vm_t *vm, u_char *start,
     u_char *end, njs_value_t *retval);
index 7418a35c30dc0540888f13a8d6c66536b1ea3bce..2993689e12fd983e0ec76f9214cf510d17c9cd41 100644 (file)
@@ -47,7 +47,7 @@ typedef enum {
 
 
 static njs_int_t njs_array_prototype_slice_copy(njs_vm_t *vm,
-    njs_value_t *this, int64_t start, int64_t length);
+    njs_value_t *this, int64_t start, int64_t length, njs_value_t *retval);
 
 
 njs_array_t *
@@ -427,7 +427,7 @@ memory_error:
 
 static njs_int_t
 njs_array_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     double       num;
     uint32_t     size;
@@ -473,7 +473,7 @@ njs_array_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             }
         }
 
-        njs_set_array(&vm->retval, array);
+        njs_set_array(retval, array);
 
         return NJS_OK;
     }
@@ -484,18 +484,9 @@ njs_array_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_array_is_array(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)
 {
-    const njs_value_t  *value;
-
-    if (nargs > 1 && njs_is_array(&args[1])) {
-        value = &njs_value_true;
-
-    } else {
-        value = &njs_value_false;
-    }
-
-    vm->retval = *value;
+    njs_set_boolean(retval, nargs > 1 && njs_is_array(&args[1]));
 
     return NJS_OK;
 }
@@ -503,7 +494,7 @@ njs_array_is_array(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_array_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     uint32_t     length, i;
     njs_array_t  *array;
@@ -515,7 +506,7 @@ njs_array_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    njs_set_array(&vm->retval, array);
+    njs_set_array(retval, array);
 
     if (array->object.fast_array) {
         for (i = 0; i < length; i++) {
@@ -615,7 +606,7 @@ njs_array_length(njs_vm_t *vm,njs_object_prop_t *prop, njs_value_t *value,
 
             array->length = length;
 
-            *retval = *setval;
+            njs_value_assign(retval, setval);
             return NJS_OK;
         }
 
@@ -636,7 +627,7 @@ njs_array_length(njs_vm_t *vm,njs_object_prop_t *prop, njs_value_t *value,
 
 static njs_int_t
 njs_array_prototype_slice(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     int64_t      start, end, length, object_length;
     njs_int_t    ret;
@@ -701,20 +692,20 @@ njs_array_prototype_slice(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         }
     }
 
-    return njs_array_prototype_slice_copy(vm, this, start, length);
+    return njs_array_prototype_slice_copy(vm, this, start, length, retval);
 }
 
 
 static njs_int_t
 njs_array_prototype_slice_copy(njs_vm_t *vm, njs_value_t *this,
-    int64_t start, int64_t length)
+    int64_t start, int64_t length, njs_value_t *retval)
 {
     size_t             size;
     u_char             *dst;
     uint32_t           n;
     njs_int_t          ret;
     njs_array_t        *array, *keys;
-    njs_value_t        *value, *last, retval, self;
+    njs_value_t        *value, *last, val, self;
     const u_char       *src, *end;
     njs_slice_prop_t   string_slice;
     njs_string_prop_t  string;
@@ -807,13 +798,13 @@ njs_array_prototype_slice_copy(njs_vm_t *vm, njs_value_t *this,
 
     if (njs_fast_object(length)) {
         do {
-            ret = njs_value_property_i64(vm, this, start++, &retval);
+            ret = njs_value_property_i64(vm, this, start++, &val);
             if (njs_slow_path(ret == NJS_ERROR)) {
                 return NJS_ERROR;
             }
 
             if (ret == NJS_OK) {
-                ret = njs_value_property_i64_set(vm, &self, start, &retval);
+                ret = njs_value_property_i64_set(vm, &self, start, &val);
                 if (njs_slow_path(ret == NJS_ERROR)) {
                     return ret;
                 }
@@ -832,12 +823,12 @@ njs_array_prototype_slice_copy(njs_vm_t *vm, njs_value_t *this,
     }
 
     for (n = 0; n < keys->length; n++) {
-        ret = njs_value_property(vm, this, &keys->start[n], &retval);
+        ret = njs_value_property(vm, this, &keys->start[n], &val);
         if (njs_slow_path(ret == NJS_ERROR)) {
             goto done;
         }
 
-        ret = njs_value_property_set(vm, &self, &keys->start[n], &retval);
+        ret = njs_value_property_set(vm, &self, &keys->start[n], &val);
         if (njs_slow_path(ret == NJS_ERROR)) {
             goto done;
         }
@@ -851,7 +842,7 @@ done:
         njs_array_destroy(vm, keys);
     }
 
-    njs_set_array(&vm->retval, array);
+    njs_set_array(retval, array);
 
     return ret;
 }
@@ -859,7 +850,7 @@ done:
 
 static njs_int_t
 njs_array_prototype_push(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     int64_t      length;
     njs_int_t    ret;
@@ -890,7 +881,7 @@ njs_array_prototype_push(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             }
         }
 
-        njs_set_number(&vm->retval, array->length);
+        njs_set_number(retval, array->length);
 
         return NJS_OK;
     }
@@ -917,7 +908,7 @@ njs_array_prototype_push(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return ret;
     }
 
-    njs_set_number(&vm->retval, length);
+    njs_set_number(retval, length);
 
     return NJS_OK;
 }
@@ -925,7 +916,7 @@ njs_array_prototype_push(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_array_prototype_pop(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     int64_t      length;
     njs_int_t    ret;
@@ -949,12 +940,12 @@ njs_array_prototype_pop(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             return ret;
         }
 
-        njs_set_undefined(&vm->retval);
+        njs_set_undefined(retval);
 
         return NJS_OK;
     }
 
-    ret = njs_value_property_i64(vm, this, --length, &vm->retval);
+    ret = njs_value_property_i64(vm, this, --length, retval);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return ret;
     }
@@ -980,7 +971,7 @@ njs_array_prototype_pop(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_array_prototype_unshift(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     double       idx;
     int64_t      from, to, length;
@@ -1018,7 +1009,7 @@ njs_array_prototype_unshift(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             } while (n > 1);
         }
 
-        njs_set_number(&vm->retval, array->length);
+        njs_set_number(retval, array->length);
 
         return NJS_OK;
     }
@@ -1107,7 +1098,7 @@ done:
         return ret;
     }
 
-    njs_set_number(&vm->retval, length);
+    njs_set_number(retval, length);
 
     return NJS_OK;
 }
@@ -1115,7 +1106,7 @@ done:
 
 static njs_int_t
 njs_array_prototype_shift(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     int64_t      i, length;
     njs_int_t    ret;
@@ -1140,12 +1131,12 @@ njs_array_prototype_shift(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             return ret;
         }
 
-        njs_set_undefined(&vm->retval);
+        njs_set_undefined(retval);
 
         return NJS_OK;
     }
 
-    ret = njs_value_property_i64(vm, this, 0, &vm->retval);
+    ret = njs_value_property_i64(vm, this, 0, retval);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return NJS_ERROR;
     }
@@ -1158,7 +1149,7 @@ njs_array_prototype_shift(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     } else {
 
-        ret = njs_value_property_i64_delete(vm, this, 0, &vm->retval);
+        ret = njs_value_property_i64_delete(vm, this, 0, retval);
         if (njs_slow_path(ret == NJS_ERROR)) {
             return ret;
         }
@@ -1189,7 +1180,7 @@ njs_array_prototype_shift(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_array_prototype_splice(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     int64_t      i, n, start, length, items, delta, delete;
     njs_int_t    ret;
@@ -1314,7 +1305,7 @@ njs_array_prototype_splice(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    njs_set_array(&vm->retval, deleted);
+    njs_set_array(retval, deleted);
 
     return NJS_OK;
 }
@@ -1322,7 +1313,7 @@ njs_array_prototype_splice(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_array_prototype_reverse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     int64_t      length, l, h;
     njs_int_t    ret, lret, hret;
@@ -1341,7 +1332,7 @@ njs_array_prototype_reverse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     if (njs_slow_path(length < 2)) {
-        vm->retval = *this;
+        njs_value_assign(retval, this);
         return NJS_OK;
     }
 
@@ -1388,7 +1379,7 @@ njs_array_prototype_reverse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         }
     }
 
-    vm->retval = *this;
+    njs_value_assign(retval, this);
 
     return NJS_OK;
 }
@@ -1396,7 +1387,7 @@ njs_array_prototype_reverse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 njs_int_t
 njs_array_prototype_to_string(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     njs_int_t           ret;
     njs_value_t         value;
@@ -1416,17 +1407,17 @@ njs_array_prototype_to_string(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
         if (njs_is_function(&value)) {
             return njs_function_apply(vm, njs_function(&value), args, nargs,
-                                      &vm->retval);
+                                      retval);
         }
     }
 
-    return njs_object_prototype_to_string(vm, args, nargs, unused);
+    return njs_object_prototype_to_string(vm, args, nargs, unused, retval);
 }
 
 
 static njs_int_t
 njs_array_prototype_join(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     u_char             *p, *last;
     int64_t            i, size, len, length;
@@ -1460,7 +1451,7 @@ njs_array_prototype_join(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     (void) njs_string_prop(&separator, value);
 
     if (njs_slow_path(!njs_is_object(this))) {
-        vm->retval = njs_string_empty;
+        njs_value_assign(retval, &njs_string_empty);
         return NJS_OK;
     }
 
@@ -1473,7 +1464,7 @@ njs_array_prototype_join(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     if (njs_slow_path(len == 0)) {
-        vm->retval = njs_string_empty;
+        njs_value_assign(retval, &njs_string_empty);
         return NJS_OK;
     }
 
@@ -1536,7 +1527,7 @@ njs_array_prototype_join(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     length -= separator.length;
 
-    p = njs_string_alloc(vm, &vm->retval, size, utf8 ? length : 0);
+    p = njs_string_alloc(vm, retval, size, utf8 ? length : 0);
     if (njs_slow_path(p == NULL)) {
         return NJS_ERROR;
     }
@@ -1674,13 +1665,13 @@ njs_is_concat_spreadable(njs_vm_t *vm, njs_value_t *value)
 
 static njs_int_t
 njs_array_prototype_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     double       idx;
     int64_t      k, len, length;
     njs_int_t    ret;
     njs_uint_t   i;
-    njs_value_t  this, retval, *e;
+    njs_value_t  this, value, *e;
     njs_array_t  *array, *keys;
 
     ret = njs_value_to_object(vm, &args[0]);
@@ -1721,17 +1712,17 @@ njs_array_prototype_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
             if (njs_is_fast_array(e) || njs_fast_object(len)) {
                 for (k = 0; k < len; k++, length++) {
-                    ret = njs_value_property_i64(vm, e, k, &retval);
+                    ret = njs_value_property_i64(vm, e, k, &value);
                     if (njs_slow_path(ret != NJS_OK)) {
                         if (ret == NJS_ERROR) {
                             return NJS_ERROR;
                         }
 
-                        njs_set_invalid(&retval);
+                        njs_set_invalid(&value);
                     }
 
                     ret = njs_value_property_i64_set(vm, &this, length,
-                                                     &retval);
+                                                     &value);
                     if (njs_slow_path(ret == NJS_ERROR)) {
                         return ret;
                     }
@@ -1746,7 +1737,7 @@ njs_array_prototype_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             }
 
             for (k = 0; k < keys->length; k++) {
-                ret = njs_value_property(vm, e, &keys->start[k], &retval);
+                ret = njs_value_property(vm, e, &keys->start[k], &value);
                 if (njs_slow_path(ret == NJS_ERROR)) {
                     return ret;
                 }
@@ -1754,7 +1745,7 @@ njs_array_prototype_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
                 if (ret == NJS_OK) {
                     idx = njs_string_to_index(&keys->start[k]) + length;
 
-                    ret = njs_value_property_i64_set(vm, &this, idx, &retval);
+                    ret = njs_value_property_i64_set(vm, &this, idx, &value);
                     if (njs_slow_path(ret == NJS_ERROR)) {
                         njs_array_destroy(vm, keys);
                         return ret;
@@ -1787,7 +1778,7 @@ njs_array_prototype_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    vm->retval = this;
+    njs_value_assign(retval, &this);
 
     return NJS_OK;
 }
@@ -1795,7 +1786,7 @@ njs_array_prototype_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_array_prototype_fill(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     int64_t       i, length, start, end;
     njs_int_t     ret;
@@ -1843,7 +1834,7 @@ njs_array_prototype_fill(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             njs_value_assign(&array->start[i], value);
         }
 
-        njs_value_assign(&vm->retval, this);
+        njs_value_assign(retval, this);
 
         return NJS_OK;
     }
@@ -1855,7 +1846,7 @@ njs_array_prototype_fill(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         }
     }
 
-    njs_value_assign(&vm->retval, this);
+    njs_value_assign(retval, this);
 
     return NJS_OK;
 }
@@ -1863,7 +1854,7 @@ njs_array_prototype_fill(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 njs_inline njs_int_t
 njs_array_iterator_call(njs_vm_t *vm, njs_iterator_args_t *args,
-    const njs_value_t *entry, uint32_t n)
+    const njs_value_t *entry, uint32_t n, njs_value_t *retval)
 {
     njs_value_t  arguments[3];
 
@@ -1874,24 +1865,24 @@ njs_array_iterator_call(njs_vm_t *vm, njs_iterator_args_t *args,
     arguments[2] = *args->value;
 
     return njs_function_call(vm, args->function, args->argument, arguments, 3,
-                             &vm->retval);
+                             retval);
 }
 
 
 static njs_int_t
 njs_array_handler_every(njs_vm_t *vm, njs_iterator_args_t *args,
-    njs_value_t *entry, int64_t n)
+    njs_value_t *entry, int64_t n, njs_value_t *retval)
 {
     njs_int_t  ret;
 
     if (njs_is_valid(entry)) {
-        ret = njs_array_iterator_call(vm, args, entry, n);
+        ret = njs_array_iterator_call(vm, args, entry, n, retval);
         if (njs_slow_path(ret != NJS_OK)) {
             return ret;
         }
 
-        if (!njs_is_true(&vm->retval)) {
-            vm->retval = njs_value_false;
+        if (!njs_is_true(retval)) {
+            njs_value_assign(retval, &njs_value_false);
             return NJS_DONE;
         }
     }
@@ -1902,18 +1893,18 @@ njs_array_handler_every(njs_vm_t *vm, njs_iterator_args_t *args,
 
 static njs_int_t
 njs_array_handler_some(njs_vm_t *vm, njs_iterator_args_t *args,
-    njs_value_t *entry, int64_t n)
+    njs_value_t *entry, int64_t n, njs_value_t *retval)
 {
     njs_int_t  ret;
 
     if (njs_is_valid(entry)) {
-        ret = njs_array_iterator_call(vm, args, entry, n);
+        ret = njs_array_iterator_call(vm, args, entry, n, retval);
         if (njs_slow_path(ret != NJS_OK)) {
             return ret;
         }
 
-        if (njs_is_true(&vm->retval)) {
-            vm->retval = njs_value_true;
+        if (njs_is_true(retval)) {
+            njs_value_assign(retval, &njs_value_true);
             return NJS_DONE;
         }
     }
@@ -1924,14 +1915,14 @@ njs_array_handler_some(njs_vm_t *vm, njs_iterator_args_t *args,
 
 static njs_int_t
 njs_array_handler_includes(njs_vm_t *vm, njs_iterator_args_t *args,
-    njs_value_t *entry, int64_t n)
+    njs_value_t *entry, int64_t n, njs_value_t *retval)
 {
     if (!njs_is_valid(entry)) {
         entry = njs_value_arg(&njs_value_undefined);
     }
 
     if (njs_values_same_zero(args->argument, entry)) {
-        njs_set_true(&vm->retval);
+        njs_set_true(retval);
 
         return NJS_DONE;
     }
@@ -1942,10 +1933,10 @@ njs_array_handler_includes(njs_vm_t *vm, njs_iterator_args_t *args,
 
 static njs_int_t
 njs_array_handler_index_of(njs_vm_t *vm, njs_iterator_args_t *args,
-    njs_value_t *entry, int64_t n)
+    njs_value_t *entry, int64_t n, njs_value_t *retval)
 {
     if (njs_values_strict_equal(args->argument, entry)) {
-        njs_set_number(&vm->retval, n);
+        njs_set_number(retval, n);
 
         return NJS_DONE;
     }
@@ -1956,10 +1947,10 @@ njs_array_handler_index_of(njs_vm_t *vm, njs_iterator_args_t *args,
 
 static njs_int_t
 njs_array_handler_for_each(njs_vm_t *vm, njs_iterator_args_t *args,
-    njs_value_t *entry, int64_t n)
+    njs_value_t *entry, int64_t n, njs_value_t *retval)
 {
     if (njs_is_valid(entry)) {
-        return njs_array_iterator_call(vm, args, entry, n);
+        return njs_array_iterator_call(vm, args, entry, n, retval);
     }
 
     return NJS_OK;
@@ -1968,7 +1959,7 @@ njs_array_handler_for_each(njs_vm_t *vm, njs_iterator_args_t *args,
 
 static njs_int_t
 njs_array_handler_find(njs_vm_t *vm, njs_iterator_args_t *args,
-    njs_value_t *entry, int64_t n)
+    njs_value_t *entry, int64_t n, njs_value_t *retval)
 {
     njs_int_t    ret;
     njs_value_t  copy;
@@ -1980,13 +1971,13 @@ njs_array_handler_find(njs_vm_t *vm, njs_iterator_args_t *args,
         njs_set_undefined(&copy);
     }
 
-    ret = njs_array_iterator_call(vm, args, &copy, n);
+    ret = njs_array_iterator_call(vm, args, &copy, n, retval);
     if (njs_slow_path(ret != NJS_OK)) {
         return ret;
     }
 
-    if (njs_is_true(&vm->retval)) {
-        vm->retval = copy;
+    if (njs_is_true(retval)) {
+        njs_value_assign(retval, &copy);
 
         return NJS_DONE;
     }
@@ -1997,7 +1988,7 @@ njs_array_handler_find(njs_vm_t *vm, njs_iterator_args_t *args,
 
 static njs_int_t
 njs_array_handler_find_index(njs_vm_t *vm, njs_iterator_args_t *args,
-    njs_value_t *entry, int64_t n)
+    njs_value_t *entry, int64_t n, njs_value_t *retval)
 {
     njs_int_t    ret;
     njs_value_t  copy;
@@ -2009,13 +2000,13 @@ njs_array_handler_find_index(njs_vm_t *vm, njs_iterator_args_t *args,
         njs_set_undefined(&copy);
     }
 
-    ret = njs_array_iterator_call(vm, args, &copy, n);
+    ret = njs_array_iterator_call(vm, args, &copy, n, retval);
     if (njs_slow_path(ret != NJS_OK)) {
         return ret;
     }
 
-    if (njs_is_true(&vm->retval)) {
-        njs_set_number(&vm->retval, n);
+    if (njs_is_true(retval)) {
+        njs_set_number(retval, n);
 
         return NJS_DONE;
     }
@@ -2026,7 +2017,7 @@ njs_array_handler_find_index(njs_vm_t *vm, njs_iterator_args_t *args,
 
 static njs_int_t
 njs_array_handler_reduce(njs_vm_t *vm, njs_iterator_args_t *args,
-    njs_value_t *entry, int64_t n)
+    njs_value_t *entry, int64_t n, njs_value_t *retval)
 {
     njs_int_t    ret;
     njs_value_t  arguments[5];
@@ -2058,7 +2049,7 @@ njs_array_handler_reduce(njs_vm_t *vm, njs_iterator_args_t *args,
 
 static njs_int_t
 njs_array_handler_filter(njs_vm_t *vm, njs_iterator_args_t *args,
-    njs_value_t *entry, int64_t n)
+    njs_value_t *entry, int64_t n, njs_value_t *retval)
 {
     njs_int_t    ret;
     njs_value_t  copy;
@@ -2066,12 +2057,12 @@ njs_array_handler_filter(njs_vm_t *vm, njs_iterator_args_t *args,
     if (njs_is_valid(entry)) {
         copy = *entry;
 
-        ret = njs_array_iterator_call(vm, args, &copy, n);
+        ret = njs_array_iterator_call(vm, args, &copy, n, retval);
         if (njs_slow_path(ret != NJS_OK)) {
             return ret;
         }
 
-        if (njs_is_true(&vm->retval)) {
+        if (njs_is_true(retval)) {
             ret = njs_array_add(vm, args->data, &copy);
             if (njs_slow_path(ret != NJS_OK)) {
                 return ret;
@@ -2085,32 +2076,32 @@ njs_array_handler_filter(njs_vm_t *vm, njs_iterator_args_t *args,
 
 static njs_int_t
 njs_array_handler_map(njs_vm_t *vm, njs_iterator_args_t *args,
-    njs_value_t *entry, int64_t n)
+    njs_value_t *entry, int64_t n, njs_value_t *retval)
 {
     njs_int_t    ret;
-    njs_array_t  *retval;
+    njs_array_t  *array;
     njs_value_t  this;
 
-    retval = args->data;
+    array = args->data;
 
-    if (retval->object.fast_array) {
-        njs_set_invalid(&retval->start[n]);
+    if (array->object.fast_array) {
+        njs_set_invalid(&array->start[n]);
     }
 
     if (njs_is_valid(entry)) {
-        ret = njs_array_iterator_call(vm, args, entry, n);
+        ret = njs_array_iterator_call(vm, args, entry, n, retval);
         if (njs_slow_path(ret != NJS_OK)) {
             return ret;
         }
 
-        if (njs_is_valid(&vm->retval)) {
-            if (retval->object.fast_array) {
-                retval->start[n] = vm->retval;
+        if (njs_is_valid(retval)) {
+            if (array->object.fast_array) {
+                njs_value_assign(&array->start[n], retval);
 
             } else {
-                njs_set_array(&this, retval);
+                njs_set_array(&this, array);
 
-                ret = njs_value_property_i64_set(vm, &this, n, &vm->retval);
+                ret = njs_value_property_i64_set(vm, &this, n, retval);
                 if (njs_slow_path(ret != NJS_OK)) {
                     return ret;
                 }
@@ -2124,7 +2115,7 @@ njs_array_handler_map(njs_vm_t *vm, njs_iterator_args_t *args,
 
 static njs_int_t
 njs_array_prototype_iterator(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                 i, length;
     njs_int_t               ret;
@@ -2252,7 +2243,7 @@ njs_array_prototype_iterator(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         break;
     }
 
-    ret = njs_object_iterate(vm, &iargs, handler);
+    ret = njs_object_iterate(vm, &iargs, handler, retval);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return ret;
     }
@@ -2267,22 +2258,22 @@ done:
 
     switch (njs_array_type(magic)) {
     case NJS_ARRAY_EVERY:
-        vm->retval = njs_value_true;
+        njs_set_boolean(retval, 1);
         break;
 
     case NJS_ARRAY_SOME:
     case NJS_ARRAY_INCLUDES:
-        vm->retval = njs_value_false;
+        njs_set_boolean(retval, 0);
         break;
 
     case NJS_ARRAY_INDEX_OF:
     case NJS_ARRAY_FIND_INDEX:
-        njs_set_number(&vm->retval, -1);
+        njs_set_number(retval, -1);
         break;
 
     case NJS_ARRAY_FOR_EACH:
     case NJS_ARRAY_FIND:
-        njs_set_undefined(&vm->retval);
+        njs_set_undefined(retval);
         break;
 
     case NJS_ARRAY_REDUCE:
@@ -2291,13 +2282,13 @@ done:
             return NJS_ERROR;
         }
 
-        vm->retval = accumulator;
+        njs_value_assign(retval, &accumulator);
         break;
 
     case NJS_ARRAY_FILTER:
     case NJS_ARRAY_MAP:
     default:
-        njs_set_array(&vm->retval, iargs.data);
+        njs_set_array(retval, iargs.data);
     }
 
     return NJS_OK;
@@ -2306,7 +2297,7 @@ done:
 
 static njs_int_t
 njs_array_prototype_reverse_iterator(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t type)
+    njs_uint_t nargs, njs_index_t type, njs_value_t *retval)
 {
     int64_t                 from, length;
     njs_int_t               ret;
@@ -2383,7 +2374,7 @@ njs_array_prototype_reverse_iterator(njs_vm_t *vm, njs_value_t *args,
     iargs.from = from;
     iargs.to = 0;
 
-    ret = njs_object_iterate_reverse(vm, &iargs, handler);
+    ret = njs_object_iterate_reverse(vm, &iargs, handler, retval);
     if (njs_fast_path(ret == NJS_ERROR)) {
         return NJS_ERROR;
     }
@@ -2396,7 +2387,7 @@ done:
 
     switch (type) {
     case NJS_ARRAY_LAST_INDEX_OF:
-        njs_set_number(&vm->retval, -1);
+        njs_set_number(retval, -1);
         break;
 
     case NJS_ARRAY_REDUCE_RIGHT:
@@ -2406,7 +2397,7 @@ done:
             return NJS_ERROR;
         }
 
-        vm->retval = accumulator;
+        njs_value_assign(retval, &accumulator);
         break;
     }
 
@@ -2512,7 +2503,7 @@ exception:
 
 static njs_int_t
 njs_array_prototype_sort(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     int64_t                i, und, len, nlen, length;
     njs_int_t              ret, fast_path;
@@ -2548,7 +2539,7 @@ njs_array_prototype_sort(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     if (njs_slow_path(length < 2)) {
-        vm->retval = *this;
+        njs_value_assign(retval, this);
         return NJS_OK;
     }
 
@@ -2702,7 +2693,7 @@ slow_path:
         }
     }
 
-    vm->retval = *this;
+    njs_value_assign(retval, this);
 
     ret = NJS_OK;
 
@@ -2720,7 +2711,7 @@ exception:
 
 static njs_int_t
 njs_array_prototype_copy_within(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)
 {
     int64_t      length, count, to, from, end;
     njs_int_t    ret;
@@ -2768,7 +2759,7 @@ njs_array_prototype_copy_within(njs_vm_t *vm, njs_value_t *args,
 
     count = njs_min(end - from, length - to);
 
-    njs_vm_retval_set(vm, this);
+    njs_value_assign(retval, this);
 
     return njs_array_copy_within(vm, this, to, from, count,
                                  !(from < to && to < from + count));
@@ -2777,7 +2768,7 @@ njs_array_prototype_copy_within(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_array_prototype_iterator_obj(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t kind)
+    njs_uint_t nargs, njs_index_t kind, njs_value_t *retval)
 {
     njs_int_t    ret;
     njs_value_t  *this;
@@ -2789,7 +2780,7 @@ njs_array_prototype_iterator_obj(njs_vm_t *vm, njs_value_t *args,
         return ret;
     }
 
-    return njs_array_iterator_create(vm, this, &vm->retval, kind);
+    return njs_array_iterator_create(vm, this, retval, kind);
 }
 
 
index 828b5de2d548b731060724910ee1f4945e2f9860..e513413a49690770e3d18505f44a85b33dfd6b47 100644 (file)
@@ -35,7 +35,7 @@ njs_int_t njs_array_string_add(njs_vm_t *vm, njs_array_t *array,
 njs_int_t njs_array_expand(njs_vm_t *vm, njs_array_t *array, uint32_t prepend,
     uint32_t append);
 njs_int_t njs_array_prototype_to_string(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t unused);
+    njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 
 
 njs_inline njs_value_t *
index 2155749d075c7a8c31d0f9e6a165ca158e89eda0..9d4a5ff17e7a816d9174d95068b40af3c816e1b4 100644 (file)
@@ -64,7 +64,7 @@ overflow:
 
 static njs_int_t
 njs_array_buffer_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     uint64_t            size;
     njs_int_t           ret;
@@ -89,7 +89,7 @@ njs_array_buffer_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    njs_set_array_buffer(&vm->retval, array);
+    njs_set_array_buffer(retval, array);
 
     return NJS_OK;
 }
@@ -97,9 +97,9 @@ njs_array_buffer_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_array_buffer_get_this(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)
 {
-    vm->retval = args[0];
+    njs_value_assign(retval, njs_argument(args, 0));
 
     return NJS_OK;
 }
@@ -107,9 +107,9 @@ njs_array_buffer_get_this(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_array_buffer_is_view(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_set_boolean(&vm->retval, njs_is_typed_array(njs_arg(args, nargs, 1)));
+    njs_set_boolean(retval, njs_is_typed_array(njs_arg(args, nargs, 1)));
 
     return NJS_OK;
 }
@@ -167,7 +167,7 @@ const njs_object_init_t  njs_array_buffer_constructor_init = {
 
 static njs_int_t
 njs_array_buffer_prototype_byte_length(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)
 {
     njs_value_t         *value;
     njs_array_buffer_t  *array;
@@ -186,7 +186,7 @@ njs_array_buffer_prototype_byte_length(njs_vm_t *vm, njs_value_t *args,
         return NJS_ERROR;
     }
 
-    njs_set_number(&vm->retval, array->size);
+    njs_set_number(retval, array->size);
 
     return NJS_OK;
 }
@@ -194,7 +194,7 @@ njs_array_buffer_prototype_byte_length(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_array_buffer_prototype_slice(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)
 {
     int64_t             len, start, end;
     njs_int_t           ret;
@@ -234,7 +234,7 @@ njs_array_buffer_prototype_slice(njs_vm_t *vm, njs_value_t *args,
         return NJS_ERROR;
     }
 
-    njs_set_array_buffer(&vm->retval, buffer);
+    njs_set_array_buffer(retval, buffer);
 
     return NJS_OK;
 }
index 1f918dfce234c7208096cabdd721f02da8d2d111..3a4dd87690fa057e7b909cddd264b7b57fe25d29 100644 (file)
@@ -16,12 +16,8 @@ njs_async_function_frame_invoke(njs_vm_t *vm, njs_value_t *retval)
 {
     njs_int_t                 ret;
     njs_value_t               ctor;
-    njs_native_frame_t        *frame;
     njs_promise_capability_t  *capability;
 
-    frame = vm->top_frame;
-    frame->retval = retval;
-
     njs_set_function(&ctor, &vm->constructors[NJS_OBJ_TYPE_PROMISE]);
 
     capability = njs_promise_new_capability(vm, &ctor);
@@ -29,26 +25,28 @@ njs_async_function_frame_invoke(njs_vm_t *vm, njs_value_t *retval)
         return NJS_ERROR;
     }
 
-    ret = njs_function_lambda_call(vm, capability);
+    ret = njs_function_lambda_call(vm, retval, capability);
 
     if (ret == NJS_OK) {
         ret = njs_function_call(vm, njs_function(&capability->resolve),
-                                &njs_value_undefined, retval, 1, &vm->retval);
+                                &njs_value_undefined, retval, 1, retval);
 
     } else if (ret == NJS_AGAIN) {
         ret = NJS_OK;
 
     } else if (ret == NJS_ERROR) {
-        if (njs_is_memory_error(vm, &vm->retval)) {
+        if (njs_is_memory_error(vm, &vm->exception)) {
             return NJS_ERROR;
         }
 
+        *retval = njs_vm_exception(vm);
+
         ret = njs_function_call(vm, njs_function(&capability->reject),
-                                &njs_value_undefined, &vm->retval, 1,
-                                &vm->retval);
+                                &njs_value_undefined, retval, 1,
+                                retval);
     }
 
-    *retval = capability->promise;
+    njs_value_assign(retval, &capability->promise);
 
     return ret;
 }
@@ -56,10 +54,10 @@ njs_async_function_frame_invoke(njs_vm_t *vm, njs_value_t *retval)
 
 njs_int_t
 njs_await_fulfilled(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t exception, njs_value_t *retval)
 {
     njs_int_t           ret;
-    njs_value_t         **cur_local, **cur_closures, *value;
+    njs_value_t         **cur_local, **cur_closures, *value, result;
     njs_frame_t         *frame, *async_frame;
     njs_async_ctx_t     *ctx;
     njs_native_frame_t  *top, *async;
@@ -83,12 +81,14 @@ njs_await_fulfilled(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     vm->top_frame = async;
     vm->active_frame = async_frame;
 
-    *njs_scope_value(vm, ctx->index) = *value;
-    vm->retval = *value;
+    if (exception) {
+        njs_vm_throw(vm, value);
 
-    vm->top_frame->retval = &vm->retval;
+    } else {
+        *njs_scope_value(vm, ctx->index) = *value;
+    }
 
-    ret = njs_vmcode_interpreter(vm, ctx->pc, ctx->capability, ctx);
+    ret = njs_vmcode_interpreter(vm, ctx->pc, &result, ctx->capability, ctx);
 
     vm->levels[NJS_LEVEL_LOCAL] = cur_local;
     vm->levels[NJS_LEVEL_CLOSURE] = cur_closures;
@@ -98,7 +98,7 @@ njs_await_fulfilled(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     if (ret == NJS_OK) {
         ret = njs_function_call(vm, njs_function(&ctx->capability->resolve),
-                            &njs_value_undefined, &vm->retval, 1, &vm->retval);
+                                &njs_value_undefined, &result, 1, retval);
 
         njs_async_context_free(vm, ctx);
 
@@ -106,31 +106,27 @@ njs_await_fulfilled(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         ret = NJS_OK;
 
     } else if (ret == NJS_ERROR) {
-        if (njs_is_memory_error(vm, &vm->retval)) {
+        if (njs_is_memory_error(vm, &vm->exception)) {
             return NJS_ERROR;
         }
 
-        value = &vm->retval;
-
-        goto failed;
-    }
-
-    return ret;
+        result = njs_vm_exception(vm);
 
-failed:
+        (void) njs_function_call(vm, njs_function(&ctx->capability->reject),
+                                 &njs_value_undefined, &result, 1, retval);
 
-    (void) njs_function_call(vm, njs_function(&ctx->capability->reject),
-                             &njs_value_undefined, value, 1, &vm->retval);
+        njs_async_context_free(vm, ctx);
 
-    njs_async_context_free(vm, ctx);
+        return NJS_ERROR;
+    }
 
-    return NJS_ERROR;
+    return ret;
 }
 
 
 njs_int_t
 njs_await_rejected(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;
     njs_async_ctx_t  *ctx;
@@ -142,7 +138,7 @@ njs_await_rejected(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     if (ctx->await->native.pc == ctx->pc) {
         /* No catch block was set before await. */
         (void) njs_function_call(vm, njs_function(&ctx->capability->reject),
-                                 &njs_value_undefined, value, 1, &vm->retval);
+                                 &njs_value_undefined, value, 1, retval);
 
         njs_async_context_free(vm, ctx);
 
@@ -153,7 +149,7 @@ njs_await_rejected(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     ctx->pc = ctx->await->native.pc;
 
-    return njs_await_fulfilled(vm, args, nargs, unused);
+    return njs_await_fulfilled(vm, args, nargs, 1, retval);
 }
 
 
index 28533cbdcc92887b1443396159b0c87146e34df3..3addb2d612939da401ef2f41394b1ae11bb4842a 100644 (file)
@@ -18,9 +18,9 @@ typedef struct {
 
 njs_int_t njs_async_function_frame_invoke(njs_vm_t *vm, njs_value_t *retval);
 njs_int_t njs_await_fulfilled(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_int_t njs_await_rejected(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused);
+    njs_index_t unused, njs_value_t *retval);
 
 
 extern const njs_object_type_init_t  njs_async_function_type_init;
index 0d0cb5885eca56f9e20f5221872a454fc5bcccf2..ba26f75142eb819dd805dccecae25350eb08ce9a 100644 (file)
@@ -10,7 +10,7 @@
 
 static njs_int_t
 njs_boolean_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     const njs_value_t   *value;
     njs_object_value_t  *object;
@@ -28,10 +28,10 @@ njs_boolean_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             return NJS_ERROR;
         }
 
-        njs_set_object_value(&vm->retval, object);
+        njs_set_object_value(retval, object);
 
     } else {
-        vm->retval = *value;
+        njs_value_assign(retval, value);
     }
 
     return NJS_OK;
@@ -66,7 +66,7 @@ const njs_object_init_t  njs_boolean_constructor_init = {
 
 static njs_int_t
 njs_boolean_prototype_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)
 {
     njs_value_t  *value;
 
@@ -84,7 +84,7 @@ njs_boolean_prototype_value_of(njs_vm_t *vm, njs_value_t *args,
         }
     }
 
-    vm->retval = *value;
+    njs_value_assign(retval, value);
 
     return NJS_OK;
 }
@@ -92,7 +92,7 @@ njs_boolean_prototype_value_of(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_boolean_prototype_to_string(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)
 {
     njs_value_t  *value;
 
@@ -110,7 +110,8 @@ njs_boolean_prototype_to_string(njs_vm_t *vm, njs_value_t *args,
         }
     }
 
-    vm->retval = njs_is_true(value) ? njs_string_true : njs_string_false;
+    njs_value_assign(retval, njs_is_true(value) ? &njs_string_true
+                                                : &njs_string_false);
 
     return NJS_OK;
 }
index d716adedd9e47473ad697515dc1be280fd158cd9..b40f7aff17c68f84cdc2c405681054f05404c709 100644 (file)
@@ -58,15 +58,17 @@ static njs_buffer_encoding_t  njs_buffer_encodings[] =
 };
 
 
-static njs_int_t njs_buffer_from_object(njs_vm_t *vm, njs_value_t *value);
+static njs_int_t njs_buffer_from_object(njs_vm_t *vm, njs_value_t *value,
+    njs_value_t *retval);
 static njs_int_t njs_buffer_from_array_buffer(njs_vm_t *vm, njs_value_t *value,
-    njs_value_t *length, njs_value_t *offset);
-static njs_int_t njs_buffer_from_typed_array(njs_vm_t *vm, njs_value_t *value);
+    njs_value_t *length, njs_value_t *offset, njs_value_t *retval);
+static njs_int_t njs_buffer_from_typed_array(njs_vm_t *vm, njs_value_t *value,
+    njs_value_t *retval);
 static njs_int_t njs_buffer_from_string(njs_vm_t *vm, njs_value_t *value,
-    const njs_buffer_encoding_t *encoding);
+    const njs_buffer_encoding_t *encoding, njs_value_t *retval);
 static njs_int_t njs_buffer_write_string(njs_vm_t *vm, njs_value_t *value,
     njs_typed_array_t *array, const njs_buffer_encoding_t *encoding,
-    uint64_t offset, uint64_t length);
+    uint64_t offset, uint64_t length, njs_value_t *retval);
 static njs_int_t njs_buffer_fill(njs_vm_t *vm, njs_typed_array_t *array,
     const njs_value_t *fill, const njs_value_t *encoding, uint64_t offset,
     uint64_t end);
@@ -222,7 +224,7 @@ njs_buffer_new(njs_vm_t *vm, njs_value_t *value, const u_char *start,
 
 static njs_int_t
 njs_buffer_constructor(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_type_error(vm, "Buffer is not a constructor");
 
@@ -232,7 +234,7 @@ njs_buffer_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_buffer_alloc_safe(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t safe)
+    njs_index_t safe, njs_value_t *retval)
 {
     double             size;
     njs_int_t          ret;
@@ -265,7 +267,7 @@ njs_buffer_alloc_safe(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         }
     }
 
-    njs_set_typed_array(&vm->retval, array);
+    njs_set_typed_array(retval, array);
 
     return NJS_OK;
 }
@@ -273,10 +275,10 @@ njs_buffer_alloc_safe(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_buffer_from(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_int_t                    ret;
-    njs_value_t                  *value, retval;
+    njs_value_t                  *value;
     const njs_buffer_encoding_t  *encoding;
 
     value = njs_arg(args, nargs, 1);
@@ -285,36 +287,36 @@ next:
 
     switch (value->type) {
     case NJS_TYPED_ARRAY:
-        return njs_buffer_from_typed_array(vm, value);
+        return njs_buffer_from_typed_array(vm, value, retval);
 
     case NJS_ARRAY_BUFFER:
         return njs_buffer_from_array_buffer(vm, value, njs_arg(args, nargs, 2),
-                                            njs_arg(args, nargs, 3));
+                                            njs_arg(args, nargs, 3), retval);
 
     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;
         }
 
-        return njs_buffer_from_string(vm, value, encoding);
+        return njs_buffer_from_string(vm, value, encoding, retval);
 
     default:
         if (njs_is_object(value)) {
-            ret = njs_value_of(vm, value, &retval);
+            ret = njs_value_of(vm, value, retval);
             if (njs_slow_path(ret == NJS_ERROR)) {
                 return ret;
             }
 
-            if (ret == NJS_OK && !njs_is_null(&retval)
-                && !(njs_is_object(&retval)
-                     && njs_object(&retval) == njs_object(value)))
+            if (ret == NJS_OK && !njs_is_null(retval)
+                && !(njs_is_object(retval)
+                     && njs_object(retval) == njs_object(value)))
             {
-                njs_value_assign(value, &retval);
+                njs_value_assign(value, retval);
                 goto next;
             }
 
-            ret = njs_buffer_from_object(vm, value);
+            ret = njs_buffer_from_object(vm, value, retval);
             if (njs_slow_path(ret != NJS_DECLINED)) {
                 return ret;
             }
@@ -329,7 +331,7 @@ next:
 
 
 static njs_int_t
-njs_buffer_from_object(njs_vm_t *vm, njs_value_t *value)
+njs_buffer_from_object(njs_vm_t *vm, njs_value_t *value, njs_value_t *retval)
 {
     double             num;
     int64_t            len;
@@ -337,7 +339,7 @@ njs_buffer_from_object(njs_vm_t *vm, njs_value_t *value)
     uint32_t           i;
     njs_str_t          str;
     njs_int_t          ret;
-    njs_value_t        data, retval, length;
+    njs_value_t        val, data, length;
     njs_typed_array_t  *buffer;
 
     static const njs_value_t  string_length = njs_string("length");
@@ -353,30 +355,30 @@ next:
 
     if (ret == NJS_DECLINED) {
         ret = njs_value_property(vm, value, njs_value_arg(&njs_string_type),
-                                 &retval);
+                                 &val);
         if (njs_slow_path(ret != NJS_OK)) {
             return ret;
         }
 
-        ret = njs_value_to_string(vm, &retval, &retval);
+        ret = njs_value_to_string(vm, &val, &val);
         if (njs_slow_path(ret != NJS_OK)) {
             return ret;
         }
 
-        njs_string_get(&retval, &str);
+        njs_string_get(&val, &str);
 
         if (!njs_strstr_eq(&str, &str_buffer)) {
             return NJS_DECLINED;
         }
 
         ret = njs_value_property(vm, value, njs_value_arg(&njs_string_data),
-                                 &retval);
+                                 &val);
         if (njs_slow_path(ret != NJS_OK)) {
             return ret;
         }
 
-        if (njs_is_object(&retval)) {
-            njs_value_assign(&data, &retval);
+        if (njs_is_object(&val)) {
+            njs_value_assign(&data, &val);
             value = &data;
             goto next;
         }
@@ -397,12 +399,12 @@ next:
     p = njs_typed_array_buffer(buffer)->u.u8;
 
     for (i = 0; i < len; i++) {
-        ret = njs_value_property_i64(vm, value, i, &retval);
+        ret = njs_value_property_i64(vm, value, i, &val);
         if (njs_slow_path(ret == NJS_ERROR)) {
             return ret;
         }
 
-        ret = njs_value_to_number(vm, &retval, &num);
+        ret = njs_value_to_number(vm, &val, &num);
         if (njs_slow_path(ret != NJS_OK)) {
             return ret;
         }
@@ -410,7 +412,7 @@ next:
         *p++ = njs_number_to_int32(num);
     }
 
-    njs_set_typed_array(&vm->retval, buffer);
+    njs_set_typed_array(retval, buffer);
 
     return NJS_OK;
 }
@@ -418,7 +420,7 @@ next:
 
 static njs_int_t
 njs_buffer_from_array_buffer(njs_vm_t *vm, njs_value_t *value,
-    njs_value_t *offset, njs_value_t *length)
+    njs_value_t *offset, njs_value_t *length, njs_value_t *retval)
 {
     int64_t             off, len;
     njs_int_t           ret;
@@ -465,14 +467,15 @@ njs_buffer_from_array_buffer(njs_vm_t *vm, njs_value_t *value,
     buffer->offset = off;
     buffer->byte_length = len;
 
-    njs_set_typed_array(&vm->retval, buffer);
+    njs_set_typed_array(retval, buffer);
 
     return NJS_OK;
 }
 
 
 static njs_int_t
-njs_buffer_from_typed_array(njs_vm_t *vm, njs_value_t *value)
+njs_buffer_from_typed_array(njs_vm_t *vm, njs_value_t *value,
+    njs_value_t *retval)
 {
     uint8_t            *p;
     uint32_t           i, length;
@@ -497,7 +500,7 @@ njs_buffer_from_typed_array(njs_vm_t *vm, njs_value_t *value)
         *p++ = njs_number_to_int32(njs_typed_array_prop(array, i));
     }
 
-    njs_set_typed_array(&vm->retval, buffer);
+    njs_set_typed_array(retval, buffer);
 
     return NJS_OK;
 }
@@ -505,7 +508,7 @@ njs_buffer_from_typed_array(njs_vm_t *vm, njs_value_t *value)
 
 static njs_int_t
 njs_buffer_from_string(njs_vm_t *vm, njs_value_t *value,
-    const njs_buffer_encoding_t *encoding)
+    const njs_buffer_encoding_t *encoding, njs_value_t *retval)
 {
     njs_int_t          ret;
     njs_str_t          str;
@@ -526,7 +529,7 @@ njs_buffer_from_string(njs_vm_t *vm, njs_value_t *value,
 
     memcpy(njs_typed_array_buffer(buffer)->u.u8, str.start, str.length);
 
-    njs_set_typed_array(&vm->retval, buffer);
+    njs_set_typed_array(retval, buffer);
 
     return NJS_OK;
 }
@@ -558,7 +561,7 @@ njs_buffer_decode_string_length(njs_value_t *value,
 
 static njs_int_t
 njs_buffer_byte_length(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     size_t                       size;
     njs_value_t                  *value;
@@ -568,26 +571,26 @@ njs_buffer_byte_length(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     switch (value->type) {
     case NJS_TYPED_ARRAY:
-        njs_set_number(&vm->retval, njs_typed_array(value)->byte_length);
+        njs_set_number(retval, njs_typed_array(value)->byte_length);
         return NJS_OK;
 
     case NJS_ARRAY_BUFFER:
-        njs_set_number(&vm->retval, njs_array_buffer(value)->size);
+        njs_set_number(retval, njs_array_buffer(value)->size);
         return NJS_OK;
 
     case NJS_DATA_VIEW:
-        njs_set_number(&vm->retval, njs_data_view(value)->byte_length);
+        njs_set_number(retval, njs_data_view(value)->byte_length);
         return NJS_OK;
 
     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;
         }
 
         size = njs_buffer_decode_string_length(value, encoding);
 
-        njs_set_number(&vm->retval, size);
+        njs_set_number(retval, size);
 
         return NJS_OK;
 
@@ -691,7 +694,8 @@ njs_buffer_array_range(njs_vm_t *vm, njs_typed_array_t *array,
 static njs_int_t
 njs_buffer_compare_array(njs_vm_t *vm, njs_value_t *val1, njs_value_t *val2,
     const njs_value_t *target_start, const njs_value_t *target_end,
-    const njs_value_t *source_start, const njs_value_t *source_end)
+    const njs_value_t *source_start, const njs_value_t *source_end,
+    njs_value_t *retval)
 {
     size_t             size, src_size, trg_size;
     uint8_t            *src, *src_end, *trg, *trg_end;
@@ -728,7 +732,7 @@ njs_buffer_compare_array(njs_vm_t *vm, njs_value_t *val1, njs_value_t *val2,
     ret = memcmp(trg, src, size);
 
     if (ret != 0) {
-        njs_set_number(&vm->retval, (ret < 0) ? 1 : -1);
+        njs_set_number(retval, (ret < 0) ? 1 : -1);
         return NJS_OK;
     }
 
@@ -739,7 +743,7 @@ njs_buffer_compare_array(njs_vm_t *vm, njs_value_t *val1, njs_value_t *val2,
         ret = 1;
     }
 
-    njs_set_number(&vm->retval, ret);
+    njs_set_number(retval, ret);
 
     return NJS_OK;
 }
@@ -747,24 +751,25 @@ njs_buffer_compare_array(njs_vm_t *vm, njs_value_t *val1, njs_value_t *val2,
 
 static njs_int_t
 njs_buffer_compare(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     return njs_buffer_compare_array(vm, njs_arg(args, nargs, 1),
                                     njs_arg(args, nargs, 2),
                                     &njs_value_undefined, &njs_value_undefined,
-                                    &njs_value_undefined, &njs_value_undefined);
+                                    &njs_value_undefined, &njs_value_undefined,
+                                    retval);
 }
 
 
 static njs_int_t
 njs_buffer_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     u_char             *p, *src;
     size_t             n;
     int64_t            i, len, list_len;
     njs_int_t          ret;
-    njs_value_t        *list, *value, *length, retval;
+    njs_value_t        *list, *value, *length, val;
     njs_array_t        *array;
     njs_typed_array_t  *buffer, *arr;
 
@@ -809,18 +814,18 @@ njs_buffer_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     } else {
 
         for (i = 0; i < list_len; i++) {
-            ret = njs_value_property_i64(vm, list, i, &retval);
+            ret = njs_value_property_i64(vm, list, i, &val);
             if (njs_slow_path(ret == NJS_ERROR)) {
                 return ret;
             }
 
-            if (njs_slow_path(!njs_is_typed_array(&retval))) {
+            if (njs_slow_path(!njs_is_typed_array(&val))) {
                 njs_type_error(vm, "\"list[%L]\" argument must be an "
                                    "instance of Buffer or Uint8Array", i);
                 return NJS_ERROR;
             }
 
-            arr = njs_typed_array(&retval);
+            arr = njs_typed_array(&val);
             if (njs_slow_path(njs_is_detached_buffer(arr->buffer))) {
                 njs_type_error(vm, "detached buffer");
                 return NJS_ERROR;
@@ -871,12 +876,12 @@ njs_buffer_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     } else {
         for (i = 0; len != 0 && i < list_len; i++) {
-            ret = njs_value_property_i64(vm, list, i, &retval);
+            ret = njs_value_property_i64(vm, list, i, &val);
             if (njs_slow_path(ret == NJS_ERROR)) {
                 return ret;
             }
 
-            arr = njs_typed_array(&retval);
+            arr = njs_typed_array(&val);
             n = njs_min((size_t) len, arr->byte_length);
             src = &njs_typed_array_buffer(arr)->u.u8[arr->offset];
 
@@ -890,7 +895,7 @@ njs_buffer_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         njs_memzero(p, len);
     }
 
-    njs_set_typed_array(&vm->retval, buffer);
+    njs_set_typed_array(retval, buffer);
 
     return NJS_OK;
 }
@@ -898,14 +903,14 @@ njs_buffer_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_buffer_is_buffer(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_bool_t         is;
     njs_typed_array_t  *array;
 
     is = 0;
 
-    array = njs_buffer_slot(vm, njs_arg(args, nargs, 1), "source");
+    array = njs_buffer_slot_internal(vm, njs_arg(args, nargs, 1));
 
     if (njs_fast_path(array != NULL && array->object.__proto__
                       == &vm->prototypes[NJS_OBJ_TYPE_BUFFER].object))
@@ -913,7 +918,7 @@ njs_buffer_is_buffer(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         is = 1;
     }
 
-    njs_set_boolean(&vm->retval, is);
+    njs_set_boolean(retval, is);
 
     return NJS_OK;
 }
@@ -921,13 +926,13 @@ njs_buffer_is_buffer(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_buffer_is_encoding(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     const njs_value_t  *value;
 
     value = njs_arg(args, nargs, 1);
-    njs_set_boolean(&vm->retval, njs_is_defined(value)
-                                 && njs_buffer_encoding(vm, value) != NULL);
+    njs_set_boolean(retval, njs_is_defined(value)
+                                 && njs_buffer_encoding(vm, value, 0) != NULL);
 
     return NJS_OK;
 }
@@ -953,7 +958,7 @@ njs_buffer_prototype_length(njs_vm_t *vm, njs_object_prop_t *prop,
 
 static njs_int_t
 njs_buffer_prototype_read_int(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t magic)
+    njs_index_t magic, njs_value_t *retval)
 {
     double              v;
     uint32_t            u32;
@@ -1143,7 +1148,7 @@ njs_buffer_prototype_read_int(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         break;
     }
 
-    njs_set_number(&vm->retval, v);
+    njs_set_number(retval, v);
 
     return NJS_OK;
 }
@@ -1151,7 +1156,7 @@ njs_buffer_prototype_read_int(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_buffer_prototype_read_float(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t magic)
+    njs_uint_t nargs, njs_index_t magic, njs_value_t *retval)
 {
     double              v;
     uint32_t            u32;
@@ -1222,7 +1227,7 @@ njs_buffer_prototype_read_float(njs_vm_t *vm, njs_value_t *args,
         v = conv_f64.f;
     }
 
-    njs_set_number(&vm->retval, v);
+    njs_set_number(retval, v);
 
     return NJS_OK;
 }
@@ -1230,7 +1235,7 @@ njs_buffer_prototype_read_float(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_buffer_prototype_write_int(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t magic)
+    njs_uint_t nargs, njs_index_t magic, njs_value_t *retval)
 {
     uint8_t             *u8;
     int64_t             i64;
@@ -1383,7 +1388,7 @@ njs_buffer_prototype_write_int(njs_vm_t *vm, njs_value_t *args,
         break;
     }
 
-    njs_set_number(&vm->retval, index + size);
+    njs_set_number(retval, index + size);
 
     return NJS_OK;
 }
@@ -1391,7 +1396,7 @@ njs_buffer_prototype_write_int(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_buffer_prototype_write_float(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t magic)
+    njs_uint_t nargs, njs_index_t magic, njs_value_t *retval)
 {
     double              v;
     uint8_t             *u8;
@@ -1468,7 +1473,7 @@ njs_buffer_prototype_write_float(njs_vm_t *vm, njs_value_t *args,
         *((uint64_t *) u8) = conv_f64.u;
     }
 
-    njs_set_undefined(&vm->retval);
+    njs_set_undefined(retval);
 
     return NJS_OK;
 }
@@ -1476,7 +1481,7 @@ njs_buffer_prototype_write_float(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_buffer_prototype_write(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     uint64_t                     offset, length;
     njs_int_t                    ret;
@@ -1531,7 +1536,7 @@ njs_buffer_prototype_write(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 encoding:
 
-    encoding = njs_buffer_encoding(vm, enc);
+    encoding = njs_buffer_encoding(vm, enc, 1);
     if (njs_slow_path(encoding == NULL)) {
         return NJS_ERROR;
     }
@@ -1546,14 +1551,15 @@ encoding:
         return NJS_ERROR;
     }
 
-    return njs_buffer_write_string(vm, value, array, encoding, offset, length);
+    return njs_buffer_write_string(vm, value, array, encoding, offset, length,
+                                   retval);
 }
 
 
 static njs_int_t
 njs_buffer_write_string(njs_vm_t *vm, njs_value_t *value,
     njs_typed_array_t *array, const njs_buffer_encoding_t *encoding,
-    uint64_t offset, uint64_t length)
+    uint64_t offset, uint64_t length, njs_value_t *retval)
 {
     uint8_t             *start;
     njs_int_t           ret;
@@ -1585,7 +1591,7 @@ njs_buffer_write_string(njs_vm_t *vm, njs_value_t *value,
 
 done:
 
-    njs_set_number(&vm->retval, length);
+    njs_set_number(retval, length);
 
     return NJS_OK;
 }
@@ -1593,7 +1599,7 @@ done:
 
 static njs_int_t
 njs_buffer_prototype_fill(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     uint64_t           offset, end;
     njs_int_t          ret;
@@ -1652,7 +1658,7 @@ fill:
 
 done:
 
-    njs_vm_retval_set(vm, this);
+    njs_value_assign(retval, this);
 
     return NJS_OK;
 }
@@ -1692,7 +1698,7 @@ njs_buffer_fill(njs_vm_t *vm, njs_typed_array_t *array, const njs_value_t *fill,
 
     switch (fill->type) {
     case NJS_STRING:
-        encoding = njs_buffer_encoding(vm, encode);
+        encoding = njs_buffer_encoding(vm, encode, 1);
         if (njs_slow_path(encoding == NULL)) {
             return NJS_ERROR;
         }
@@ -1787,7 +1793,7 @@ njs_buffer_fill_typed_array(njs_vm_t *vm, const njs_value_t *value,
 
 static njs_int_t
 njs_buffer_prototype_to_string(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)
 {
     uint64_t                     start, end;
     njs_int_t                    ret;
@@ -1808,7 +1814,7 @@ njs_buffer_prototype_to_string(njs_vm_t *vm, njs_value_t *args,
     start = 0;
     end = array->byte_length;
 
-    encoding = njs_buffer_encoding(vm,  njs_arg(args, nargs, 1));
+    encoding = njs_buffer_encoding(vm,  njs_arg(args, nargs, 1), 1);
     if (njs_slow_path(encoding == NULL)) {
         return NJS_ERROR;
     }
@@ -1840,28 +1846,28 @@ njs_buffer_prototype_to_string(njs_vm_t *vm, njs_value_t *args,
     str.length = end - start;
 
     if (njs_slow_path(str.length == 0)) {
-        njs_vm_retval_set(vm, &njs_string_empty);
+        njs_value_assign(retval, &njs_string_empty);
         return NJS_OK;
     }
 
-    return encoding->encode(vm, &vm->retval, &str);
+    return encoding->encode(vm, retval, &str);
 }
 
 
 static njs_int_t
 njs_buffer_prototype_compare(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     return njs_buffer_compare_array(vm, njs_argument(args, 0),
                                njs_arg(args, nargs, 1), njs_arg(args, nargs, 2),
                                njs_arg(args, nargs, 3), njs_arg(args, nargs, 4),
-                               njs_arg(args, nargs, 5));
+                               njs_arg(args, nargs, 5), retval);
 }
 
 
 static njs_int_t
 njs_buffer_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)
 {
     size_t              size;
     uint8_t             *src, *src_end, *trg, *trg_end;
@@ -1913,7 +1919,7 @@ njs_buffer_prototype_copy(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         memmove(trg, src, size);
     }
 
-    njs_set_number(&vm->retval, size);
+    njs_set_number(retval, size);
 
     return NJS_OK;
 }
@@ -1921,19 +1927,19 @@ njs_buffer_prototype_copy(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_buffer_prototype_equals(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_int_t  ret;
 
     ret = njs_buffer_compare_array(vm, njs_argument(args, 0),
                                   njs_arg(args, nargs, 1), &njs_value_undefined,
                                   &njs_value_undefined, &njs_value_undefined,
-                                  &njs_value_undefined);
+                                  &njs_value_undefined, retval);
     if (njs_slow_path(ret != NJS_OK)) {
         return ret;
     }
 
-    njs_set_boolean(&vm->retval, njs_number(&vm->retval) == 0);
+    njs_set_boolean(retval, njs_number(retval) == 0);
 
     return NJS_OK;
 }
@@ -1941,7 +1947,7 @@ njs_buffer_prototype_equals(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_buffer_prototype_index_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t last)
+    njs_index_t last, njs_value_t *retval)
 {
     uint8_t                      byte;
     int64_t                      from, to, increment, length, offset, index, i;
@@ -2022,7 +2028,7 @@ njs_buffer_prototype_index_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 encoding:
 
-    encoding = njs_buffer_encoding(vm, enc);
+    encoding = njs_buffer_encoding(vm, enc, 1);
     if (njs_slow_path(encoding == NULL)) {
         return NJS_ERROR;
     }
@@ -2112,7 +2118,7 @@ fail:
 
 done:
 
-    njs_set_number(&vm->retval, index);
+    njs_set_number(retval, index);
 
     return NJS_OK;
 }
@@ -2120,16 +2126,16 @@ done:
 
 static njs_int_t
 njs_buffer_prototype_includes(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_int_t  ret;
 
-    ret = njs_buffer_prototype_index_of(vm, args, nargs, unused);
+    ret = njs_buffer_prototype_index_of(vm, args, nargs, unused, retval);
     if (njs_slow_path(ret != NJS_OK)) {
         return ret;
     }
 
-    njs_set_boolean(&vm->retval, (njs_number(&vm->retval) != -1));
+    njs_set_boolean(retval, (njs_number(retval) != -1));
 
     return NJS_OK;
 }
@@ -2137,17 +2143,17 @@ njs_buffer_prototype_includes(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_buffer_prototype_slice(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_int_t          ret;
     njs_typed_array_t  *array;
 
-    ret = njs_typed_array_prototype_slice(vm, args, nargs, unused);
+    ret = njs_typed_array_prototype_slice(vm, args, nargs, unused, retval);
     if (njs_slow_path(ret != NJS_OK)) {
         return ret;
     }
 
-    array = njs_typed_array(&vm->retval);
+    array = njs_typed_array(retval);
     array->object.__proto__ = &vm->prototypes[NJS_OBJ_TYPE_BUFFER].object;
 
     return NJS_OK;
@@ -2156,7 +2162,7 @@ njs_buffer_prototype_slice(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_buffer_prototype_swap(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t size)
+    njs_index_t size, njs_value_t *retval)
 {
     uint8_t             *p, *end;
     njs_typed_array_t   *array;
@@ -2203,7 +2209,7 @@ njs_buffer_prototype_swap(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         }
     }
 
-    njs_set_typed_array(&vm->retval, array);
+    njs_set_typed_array(retval, array);
 
     return NJS_OK;
 }
@@ -2211,7 +2217,7 @@ njs_buffer_prototype_swap(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_buffer_prototype_to_json(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     u_char              *p, *end;
     njs_int_t           ret;
@@ -2269,14 +2275,14 @@ njs_buffer_prototype_to_json(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    njs_set_object(&vm->retval, obj);
+    njs_set_object(retval, obj);
 
     return NJS_OK;
 }
 
 
 const njs_buffer_encoding_t *
-njs_buffer_encoding(njs_vm_t *vm, const njs_value_t *value)
+njs_buffer_encoding(njs_vm_t *vm, const njs_value_t *value, njs_bool_t throw)
 {
     njs_str_t              name;
     njs_buffer_encoding_t  *encoding;
@@ -2301,7 +2307,9 @@ njs_buffer_encoding(njs_vm_t *vm, const njs_value_t *value)
         }
     }
 
-    njs_type_error(vm, "\"%V\" encoding is not supported", &name);
+    if (throw) {
+        njs_type_error(vm, "\"%V\" encoding is not supported", &name);
+    }
 
     return NULL;
 }
index 963c1fbd4d536540dfb2922d36f919d0d88d3b21..a765fedd2ca686d282cdaa99298947cc2bfef623 100644 (file)
@@ -31,7 +31,7 @@ njs_typed_array_t *njs_buffer_alloc(njs_vm_t *vm, size_t size,
     njs_bool_t zeroing);
 
 const njs_buffer_encoding_t *njs_buffer_encoding(njs_vm_t *vm,
-    const njs_value_t *value);
+    const njs_value_t *value, njs_bool_t thrw);
 njs_int_t njs_buffer_decode_string(njs_vm_t *vm, const njs_value_t *value,
     njs_value_t *dst, const njs_buffer_encoding_t *encoding);
 
index 50a53532ba77bd8470e31e47a663942dabdb67f0..fba1fb23348f710e718cc5687ddc0f2567d0fe85 100644 (file)
@@ -846,7 +846,7 @@ found:
 
 static njs_int_t
 njs_ext_dump(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     uint32_t     n;
     njs_int_t    ret;
@@ -867,13 +867,13 @@ njs_ext_dump(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    return njs_string_new(vm, &vm->retval, str.start, str.length, 0);
+    return njs_string_new(vm, retval, str.start, str.length, 0);
 }
 
 
 static njs_int_t
 njs_ext_on(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    type;
     njs_uint_t   i, n;
@@ -1696,7 +1696,7 @@ static const njs_object_init_t  njs_process_object_init = {
 
 static njs_int_t
 njs_262_detach_array_buffer(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;
     njs_array_buffer_t  *buffer;
@@ -1711,7 +1711,7 @@ njs_262_detach_array_buffer(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     buffer->u.data = NULL;
     buffer->size = 0;
 
-    njs_set_null(&vm->retval);
+    njs_set_null(retval);
 
     return NJS_OK;
 }
index 462a7139212ddc76b8e566d81d8ddbc7b99e621b..7df50725c81b40b4dd508b6bf62cd6919925ef94 100644 (file)
@@ -375,7 +375,7 @@ njs_date_alloc(njs_vm_t *vm, double time)
 
 static njs_int_t
 njs_date_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     double      time;
     njs_int_t   ret;
@@ -383,7 +383,7 @@ njs_date_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     int64_t     tm[NJS_DATE_MAX_FIELDS];
 
     if (!vm->top_frame->ctor) {
-        return njs_date_string(vm, &vm->retval, NJS_DATE_FMT_TO_STRING,
+        return njs_date_string(vm, retval, NJS_DATE_FMT_TO_STRING,
                                njs_gettime());
     }
 
@@ -425,7 +425,7 @@ njs_date_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    njs_set_date(&vm->retval, date);
+    njs_set_date(retval, date);
 
     return NJS_OK;
 }
@@ -433,7 +433,7 @@ njs_date_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_date_utc(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     double      time;
     njs_int_t   ret;
@@ -450,7 +450,7 @@ njs_date_utc(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         time = njs_make_date(tm, 0);
     }
 
-    njs_set_number(&vm->retval, time);
+    njs_set_number(retval, time);
 
     return NJS_OK;
 }
@@ -458,9 +458,9 @@ njs_date_utc(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_date_now(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_set_number(&vm->retval, njs_gettime());
+    njs_set_number(retval, njs_gettime());
 
     return NJS_OK;
 }
@@ -468,7 +468,7 @@ njs_date_now(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_date_parse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     double     time;
     njs_int_t  ret;
@@ -487,7 +487,7 @@ njs_date_parse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         time = NAN;
     }
 
-    njs_set_number(&vm->retval, time);
+    njs_set_number(retval, time);
 
     return NJS_OK;
 }
@@ -1087,7 +1087,7 @@ const njs_object_init_t  njs_date_constructor_init = {
 
 static njs_int_t
 njs_date_prototype_value_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     if (njs_slow_path(!njs_is_date(&args[0]))) {
         njs_type_error(vm, "cannot convert %s to date",
@@ -1096,7 +1096,7 @@ njs_date_prototype_value_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    njs_set_number(&vm->retval, njs_date(&args[0])->time);
+    njs_set_number(retval, njs_date(&args[0])->time);
 
     return NJS_OK;
 }
@@ -1104,7 +1104,7 @@ njs_date_prototype_value_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_date_prototype_to_string(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t fmt)
+    njs_index_t fmt, njs_value_t *retval)
 {
     double  time;
 
@@ -1122,7 +1122,7 @@ njs_date_prototype_to_string(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    return njs_date_string(vm, &vm->retval, fmt, time);
+    return njs_date_string(vm, retval, fmt, time);
 }
 
 
@@ -1235,7 +1235,7 @@ njs_date_to_string(njs_vm_t *vm, njs_value_t *retval, const njs_value_t *date)
 
 static njs_int_t
 njs_date_prototype_get_field(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t magic)
+    njs_uint_t nargs, njs_index_t magic, njs_value_t *retval)
 {
     double   value;
     int64_t  tm[NJS_DATE_MAX_FIELDS];
@@ -1253,7 +1253,7 @@ njs_date_prototype_get_field(njs_vm_t *vm, njs_value_t *args,
         value = njs_destruct_date(value, tm, magic & 0xf, magic & 0x40);
     }
 
-    njs_set_number(&vm->retval, value);
+    njs_set_number(retval, value);
 
     return NJS_OK;
 }
@@ -1261,7 +1261,7 @@ njs_date_prototype_get_field(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_date_prototype_get_timezone_offset(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)
 {
     double  value;
 
@@ -1278,7 +1278,7 @@ njs_date_prototype_get_timezone_offset(njs_vm_t *vm, njs_value_t *args,
         value = njs_tz_offset(value);
     }
 
-    njs_set_number(&vm->retval, value);
+    njs_set_number(retval, value);
 
     return NJS_OK;
 }
@@ -1286,7 +1286,7 @@ njs_date_prototype_get_timezone_offset(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_date_prototype_set_time(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     double     time;
     njs_int_t  ret;
@@ -1313,7 +1313,7 @@ njs_date_prototype_set_time(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     njs_date(&args[0])->time = time;
-    njs_set_number(&vm->retval, time);
+    njs_set_number(retval, time);
 
     return NJS_OK;
 }
@@ -1321,7 +1321,7 @@ njs_date_prototype_set_time(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_date_prototype_set_fields(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t magic)
+    njs_uint_t nargs, njs_index_t magic, njs_value_t *retval)
 {
     double      time, num;
     njs_int_t   ret;
@@ -1369,7 +1369,7 @@ njs_date_prototype_set_fields(njs_vm_t *vm, njs_value_t *args,
 done:
 
     njs_date(&args[0])->time = time;
-    njs_set_number(&vm->retval, time);
+    njs_set_number(retval, time);
 
     return NJS_OK;
 }
@@ -1377,7 +1377,7 @@ done:
 
 static njs_int_t
 njs_date_prototype_to_json(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t retval)
+    njs_index_t unused, njs_value_t *retval)
 {
     njs_int_t           ret;
     njs_value_t         value;
@@ -1397,7 +1397,7 @@ njs_date_prototype_to_json(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
         if (njs_is_function(&value)) {
             return njs_function_apply(vm, njs_function(&value), args, nargs,
-                                      &vm->retval);
+                                      retval);
         }
     }
 
index e7371587e7c2a8c5945c27502b01d4479d790bc8..edb16035997158da2f30c16dbb5bb17b5d1cd738 100644 (file)
@@ -37,7 +37,7 @@ static njs_encoding_label_t  njs_encoding_labels[] =
 
 
 static njs_int_t njs_text_encoder_encode_utf8(njs_vm_t *vm,
-    njs_string_prop_t *prop);
+    njs_string_prop_t *prop, njs_value_t *retval);
 static njs_int_t njs_text_decoder_arg_encoding(njs_vm_t *vm, njs_value_t *args,
     njs_uint_t nargs, njs_encoding_decode_t *data);
 static njs_int_t njs_text_decoder_arg_options(njs_vm_t *vm, njs_value_t *args,
@@ -46,7 +46,7 @@ static njs_int_t njs_text_decoder_arg_options(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_text_encoder_constructor(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_object_value_t  *encoder;
 
@@ -61,7 +61,7 @@ njs_text_encoder_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     njs_set_data(&encoder->value, NULL, NJS_DATA_TAG_TEXT_ENCODER);
-    njs_set_object_value(&vm->retval, encoder);
+    njs_set_object_value(retval, encoder);
 
     return NJS_OK;
 }
@@ -69,7 +69,7 @@ njs_text_encoder_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_text_encoder_encode(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     u_char                *dst;
     size_t                size;
@@ -103,7 +103,7 @@ njs_text_encoder_encode(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         (void) njs_string_prop(&prop, input);
 
         if (prop.length != 0) {
-            return njs_text_encoder_encode_utf8(vm, &prop);
+            return njs_text_encoder_encode_utf8(vm, &prop, retval);
         }
 
         start = prop.start;
@@ -126,14 +126,15 @@ njs_text_encoder_encode(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     (void) njs_utf8_stream_encode(&ctx, start, end, dst, 1, 0);
 
-    njs_set_typed_array(&vm->retval, array);
+    njs_set_typed_array(retval, array);
 
     return NJS_OK;
 }
 
 
 static njs_int_t
-njs_text_encoder_encode_utf8(njs_vm_t *vm, njs_string_prop_t *prop)
+njs_text_encoder_encode_utf8(njs_vm_t *vm, njs_string_prop_t *prop,
+    njs_value_t *retval)
 {
     njs_value_t        value;
     njs_typed_array_t  *array;
@@ -147,7 +148,7 @@ njs_text_encoder_encode_utf8(njs_vm_t *vm, njs_string_prop_t *prop)
 
     memcpy(njs_typed_array_buffer(array)->u.u8, prop->start, prop->size);
 
-    njs_set_typed_array(&vm->retval, array);
+    njs_set_typed_array(retval, array);
 
     return NJS_OK;
 }
@@ -155,14 +156,14 @@ njs_text_encoder_encode_utf8(njs_vm_t *vm, njs_string_prop_t *prop)
 
 static njs_int_t
 njs_text_encoder_encode_into(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     u_char                *to, *to_end;
     size_t                size;
     uint32_t              cp;
     njs_int_t             ret;
     njs_str_t             str;
-    njs_value_t           *this, *input, *dest, retval, read, written;
+    njs_value_t           *this, *input, *dest, value, read, written;
     const u_char          *start, *end;
     njs_typed_array_t     *array;
     njs_unicode_decode_t  ctx;
@@ -180,12 +181,12 @@ njs_text_encoder_encode_into(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     if (njs_slow_path(!njs_is_string(input))) {
-        ret = njs_value_to_string(vm, &retval, input);
+        ret = njs_value_to_string(vm, &value, input);
         if (njs_slow_path(ret != NJS_OK)) {
             return ret;
         }
 
-        input = &retval;
+        input = &value;
     }
 
     if (njs_slow_path(!njs_is_typed_array_uint8(dest))) {
@@ -228,7 +229,7 @@ njs_text_encoder_encode_into(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         to = njs_utf8_encode(to, cp);
     }
 
-    return njs_vm_object_alloc(vm, &vm->retval, &read_str, &read,
+    return njs_vm_object_alloc(vm, retval, &read_str, &read,
                                &written_str, &written, NULL);
 }
 
@@ -279,7 +280,7 @@ const njs_object_type_init_t  njs_text_encoder_type_init = {
 
 static njs_int_t
 njs_text_decoder_constructor(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_int_t              ret;
     njs_object_value_t     *decoder;
@@ -312,7 +313,7 @@ njs_text_decoder_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_utf8_decode_init(&data->ctx);
 
     njs_set_data(&decoder->value, data, NJS_DATA_TAG_TEXT_DECODER);
-    njs_set_object_value(&vm->retval, decoder);
+    njs_set_object_value(retval, decoder);
 
     return NJS_OK;
 }
@@ -468,14 +469,14 @@ njs_text_decoder_ignore_bom(njs_vm_t *vm, njs_object_prop_t *prop,
 
 static njs_int_t
 njs_text_decoder_decode(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     u_char                    *dst;
     size_t                    size;
     ssize_t                   length;
     njs_int_t                 ret;
     njs_bool_t                stream;
-    njs_value_t               retval, *this, *value, *options;
+    njs_value_t               *this, *value, *options;
     const u_char              *start, *end;
     njs_unicode_decode_t      ctx;
     njs_encoding_decode_t     *data;
@@ -528,12 +529,12 @@ njs_text_decoder_decode(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         }
 
         ret = njs_value_property(vm, options, njs_value_arg(&stream_str),
-                                 &retval);
+                                 retval);
         if (njs_slow_path(ret == NJS_ERROR)) {
             return ret;
         }
 
-        stream = njs_bool(&retval);
+        stream = njs_bool(retval);
     }
 
     data = njs_object_data(this);
@@ -553,7 +554,7 @@ njs_text_decoder_decode(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    dst = njs_string_alloc(vm, &vm->retval, size, length);
+    dst = njs_string_alloc(vm, retval, size, length);
     if (njs_slow_path(dst == NULL)) {
         return NJS_ERROR;
     }
index 3398020387ca016beb93e004b468f1c1b9231644..4cf2130e80e0809d4dba007296450ca27160f2e6 100644 (file)
@@ -54,6 +54,32 @@ njs_error_new(njs_vm_t *vm, njs_value_t *dst, njs_object_type_t type,
     njs_set_object(dst, error);
 }
 
+void
+njs_throw_error_va(njs_vm_t *vm, njs_object_type_t type, const char *fmt,
+    va_list args)
+{
+    u_char   buf[NJS_MAX_ERROR_STR], *p;
+
+    p = buf;
+
+    if (fmt != NULL) {
+        p = njs_vsprintf(buf, buf + sizeof(buf), fmt, args);
+    }
+
+    njs_error_new(vm, &vm->exception, type, buf, p - buf);
+}
+
+
+void
+njs_throw_error(njs_vm_t *vm, njs_object_type_t type, const char *fmt, ...)
+{
+    va_list  args;
+
+    va_start(args, fmt);
+    njs_throw_error_va(vm, type, fmt, args);
+    va_end(args);
+}
+
 
 void
 njs_error_fmt_new(njs_vm_t *vm, njs_value_t *dst, njs_object_type_t type,
@@ -126,13 +152,13 @@ njs_error_stack_new(njs_vm_t *vm, njs_object_t *error, njs_value_t *retval)
 
 
 njs_int_t
-njs_error_stack_attach(njs_vm_t *vm, njs_value_t *value)
+njs_error_stack_attach(njs_vm_t *vm, njs_value_t value)
 {
     njs_int_t    ret;
     njs_value_t  stack;
 
-    if (njs_slow_path(!njs_is_error(value))
-        || njs_object(value)->stack_attached)
+    if (njs_slow_path(!njs_is_error(&value))
+        || njs_object(&value)->stack_attached)
     {
         return NJS_DECLINED;
     }
@@ -141,15 +167,15 @@ njs_error_stack_attach(njs_vm_t *vm, njs_value_t *value)
         return NJS_OK;
     }
 
-    ret = njs_error_stack_new(vm, njs_object(value), &stack);
+    ret = njs_error_stack_new(vm, njs_object(&value), &stack);
     if (njs_slow_path(ret != NJS_OK)) {
         njs_internal_error(vm, "njs_error_stack_new() failed");
         return NJS_ERROR;
     }
 
-    njs_object(value)->stack_attached = 1;
+    njs_object(&value)->stack_attached = 1;
 
-    return njs_object_prop_define(vm, value,
+    return njs_object_prop_define(vm, &value,
                                   njs_value_arg(&njs_error_stack_string),
                                   &stack, NJS_OBJECT_PROP_VALUE_CW,
                                   NJS_STACK_HASH);
@@ -274,7 +300,7 @@ memory_error:
 
 static njs_int_t
 njs_error_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t type)
+    njs_index_t type, njs_value_t *retval)
 {
     njs_int_t     ret;
     njs_value_t   *iterator, *value, list;
@@ -296,7 +322,7 @@ njs_error_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             return NJS_ERROR;
         }
 
-        array = njs_iterator_to_array(vm, iterator);
+        array = njs_iterator_to_array(vm, iterator, retval);
         if (njs_slow_path(array == NULL)) {
             return NJS_ERROR;
         }
@@ -320,7 +346,7 @@ njs_error_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    njs_set_object(&vm->retval, error);
+    njs_set_object(retval, error);
 
     return NJS_OK;
 }
@@ -501,15 +527,15 @@ njs_memory_error_set(njs_vm_t *vm, njs_value_t *value)
 void
 njs_memory_error(njs_vm_t *vm)
 {
-    njs_memory_error_set(vm, &vm->retval);
+    njs_memory_error_set(vm, &vm->exception);
 }
 
 
 static njs_int_t
 njs_memory_error_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)
 {
-    njs_memory_error_set(vm, &vm->retval);
+    njs_memory_error_set(vm, retval);
 
     return NJS_OK;
 }
@@ -559,9 +585,9 @@ const njs_object_init_t  njs_memory_error_constructor_init = {
 
 static njs_int_t
 njs_error_prototype_value_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
-    vm->retval = args[0];
+    njs_value_assign(retval, njs_argument(args, 0));
 
     return NJS_OK;
 }
@@ -677,14 +703,14 @@ njs_error_to_string2(njs_vm_t *vm, njs_value_t *retval,
 
 static njs_int_t
 njs_error_prototype_to_string(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     if (nargs < 1 || !njs_is_object(&args[0])) {
         njs_type_error(vm, "\"this\" argument is not an object");
         return NJS_ERROR;
     }
 
-    return njs_error_to_string2(vm, &vm->retval, &args[0], 0);
+    return njs_error_to_string2(vm, retval, &args[0], 0);
 }
 
 
@@ -762,21 +788,19 @@ const njs_object_type_init_t  njs_eval_error_type_init = {
 
 static njs_int_t
 njs_internal_error_prototype_to_string(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t unused)
+    njs_uint_t nargs, njs_index_t unused, njs_value_t *retval)
 {
-    if (nargs >= 1 && njs_is_object(&args[0])) {
+    static const njs_value_t name = njs_string("MemoryError");
 
+    if (nargs >= 1 && njs_is_object(&args[0])) {
         /* MemoryError is a nonextensible internal error. */
         if (!njs_object(&args[0])->extensible) {
-            static const njs_value_t name = njs_string("MemoryError");
-
-            vm->retval = name;
-
+            njs_value_assign(retval, &name);
             return NJS_OK;
         }
     }
 
-    return njs_error_prototype_to_string(vm, args, nargs, unused);
+    return njs_error_prototype_to_string(vm, args, nargs, unused, retval);
 }
 
 
index c0a42dc59f3d53d0c3431cd8f2cd2fec17411328..e2d6ed854a0029c03ea19b94a70bbf7a1a543700 100644 (file)
@@ -9,33 +9,30 @@
 
 
 #define njs_error(vm, fmt, ...)                                               \
-    njs_error_fmt_new(vm, &vm->retval, NJS_OBJ_TYPE_ERROR, fmt, ##__VA_ARGS__)
+    njs_throw_error(vm, NJS_OBJ_TYPE_ERROR, fmt, ##__VA_ARGS__)
 #define njs_eval_error(vm, fmt, ...)                                          \
-    njs_error_fmt_new(vm, &vm->retval, NJS_OBJ_TYPE_EVAL_ERROR, fmt,          \
-                      ##__VA_ARGS__)
+    njs_throw_error(vm, NJS_OBJ_TYPE_EVAL_ERROR, fmt, ##__VA_ARGS__)
 #define njs_internal_error(vm, fmt, ...)                                      \
-    njs_error_fmt_new(vm, &vm->retval, NJS_OBJ_TYPE_INTERNAL_ERROR, fmt,      \
-                      ##__VA_ARGS__)
+    njs_throw_error(vm, NJS_OBJ_TYPE_INTERNAL_ERROR, fmt, ##__VA_ARGS__)
 #define njs_range_error(vm, fmt, ...)                                         \
-    njs_error_fmt_new(vm, &vm->retval, NJS_OBJ_TYPE_RANGE_ERROR, fmt,         \
-                      ##__VA_ARGS__)
+    njs_throw_error(vm, NJS_OBJ_TYPE_RANGE_ERROR, fmt, ##__VA_ARGS__)
 #define njs_reference_error(vm, fmt, ...)                                     \
-    njs_error_fmt_new(vm, &vm->retval, NJS_OBJ_TYPE_REF_ERROR, fmt,           \
-                      ##__VA_ARGS__)
+    njs_throw_error(vm, NJS_OBJ_TYPE_REF_ERROR, fmt, ##__VA_ARGS__)
 #define njs_syntax_error(vm, fmt, ...)                                        \
-    njs_error_fmt_new(vm, &vm->retval, NJS_OBJ_TYPE_SYNTAX_ERROR, fmt,        \
-                      ##__VA_ARGS__)
+    njs_throw_error(vm, NJS_OBJ_TYPE_SYNTAX_ERROR, fmt, ##__VA_ARGS__)
 #define njs_type_error(vm, fmt, ...)                                          \
-    njs_error_fmt_new(vm, &vm->retval, NJS_OBJ_TYPE_TYPE_ERROR, fmt,          \
-                      ##__VA_ARGS__)
+    njs_throw_error(vm, NJS_OBJ_TYPE_TYPE_ERROR, fmt, ##__VA_ARGS__)
 #define njs_uri_error(vm, fmt, ...)                                           \
-    njs_error_fmt_new(vm, &vm->retval, NJS_OBJ_TYPE_URI_ERROR, fmt,           \
-                      ##__VA_ARGS__)
+    njs_throw_error(vm, NJS_OBJ_TYPE_URI_ERROR, fmt, ##__VA_ARGS__)
 
 void njs_error_new(njs_vm_t *vm, njs_value_t *dst, njs_object_type_t type,
     u_char *start, size_t size);
 void njs_noinline njs_error_fmt_new(njs_vm_t *vm, njs_value_t *dst,
     njs_object_type_t type, const char *fmt, ...);
+void njs_throw_error(njs_vm_t *vm, njs_object_type_t type, const char *fmt,
+    ...);
+void njs_throw_error_va(njs_vm_t *vm, njs_object_type_t type, const char *fmt,
+    va_list args);
 
 void njs_memory_error(njs_vm_t *vm);
 void njs_memory_error_set(njs_vm_t *vm, njs_value_t *value);
@@ -46,7 +43,7 @@ njs_object_t *njs_error_alloc(njs_vm_t *vm, njs_object_type_t type,
 njs_int_t njs_error_to_string(njs_vm_t *vm, njs_value_t *retval,
     const njs_value_t *error);
 njs_int_t njs_error_stack(njs_vm_t *vm, njs_value_t *value, njs_value_t *stack);
-njs_int_t njs_error_stack_attach(njs_vm_t *vm, njs_value_t *value);
+njs_int_t njs_error_stack_attach(njs_vm_t *vm, njs_value_t value);
 
 
 extern const njs_object_type_init_t  njs_error_type_init;
index 35ff6aba22bb21bed9c19d7da3ec7efc4d7259d1..67f74db8d649bd84ba8e989ae5f1045448762070 100644 (file)
@@ -8,6 +8,9 @@
 #include <njs_main.h>
 
 
+static njs_int_t njs_function_native_call(njs_vm_t *vm, njs_value_t *retval);
+
+
 njs_function_t *
 njs_function_alloc(njs_vm_t *vm, njs_function_lambda_t *lambda,
     njs_bool_t async)
@@ -318,7 +321,7 @@ njs_function_rest_parameters_init(njs_vm_t *vm, njs_native_frame_t *frame)
 
 static njs_int_t
 njs_function_prototype_thrower(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)
 {
     njs_type_error(vm, "\"caller\", \"callee\", \"arguments\" "
                    "properties may not be accessed");
@@ -515,7 +518,7 @@ njs_function_call2(njs_vm_t *vm, njs_function_t *function,
 
 
 njs_int_t
-njs_function_lambda_call(njs_vm_t *vm, void *promise_cap)
+njs_function_lambda_call(njs_vm_t *vm, njs_value_t *retval, void *promise_cap)
 {
     uint32_t               n;
     njs_int_t              ret;
@@ -605,7 +608,7 @@ njs_function_lambda_call(njs_vm_t *vm, void *promise_cap)
         }
     }
 
-    ret = njs_vmcode_interpreter(vm, lambda->start, promise_cap, NULL);
+    ret = njs_vmcode_interpreter(vm, lambda->start, retval, promise_cap, NULL);
 
     /* Restore current level. */
     vm->levels[NJS_LEVEL_LOCAL] = cur_local;
@@ -616,7 +619,7 @@ njs_function_lambda_call(njs_vm_t *vm, void *promise_cap)
 
 
 njs_int_t
-njs_function_native_call(njs_vm_t *vm)
+njs_function_native_call(njs_vm_t *vm, njs_value_t *retval)
 {
     njs_int_t              ret;
     njs_function_t         *function;
@@ -643,7 +646,7 @@ njs_function_native_call(njs_vm_t *vm)
     call = function->u.native;
 
     ret = call(vm, &native->arguments[-1], 1 /* this */ + native->nargs,
-               function->magic8);
+               function->magic8, retval);
 
 #ifdef NJS_DEBUG_OPCODE
     if (vm->options.opcode_debug) {
@@ -658,8 +661,6 @@ njs_function_native_call(njs_vm_t *vm)
 
     njs_vm_scopes_restore(vm, native);
 
-    *native->retval = vm->retval;
-
     njs_function_frame_free(vm, native);
 
     return NJS_OK;
@@ -672,7 +673,6 @@ njs_function_frame_invoke(njs_vm_t *vm, njs_value_t *retval)
     njs_native_frame_t  *frame;
 
     frame = vm->top_frame;
-    frame->retval = retval;
 
     if (njs_function_object_type(vm, frame->function)
         == NJS_OBJ_TYPE_ASYNC_FUNCTION)
@@ -681,10 +681,10 @@ njs_function_frame_invoke(njs_vm_t *vm, njs_value_t *retval)
     }
 
     if (frame->native) {
-        return njs_function_native_call(vm);
+        return njs_function_native_call(vm, retval);
 
     } else {
-        return njs_function_lambda_call(vm, NULL);
+        return njs_function_lambda_call(vm, retval, NULL);
     }
 }
 
@@ -997,7 +997,7 @@ njs_function_prototype_create(njs_vm_t *vm, njs_object_prop_t *prop,
 
 njs_int_t
 njs_function_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t async)
+    njs_index_t async, njs_value_t *retval)
 {
     njs_chb_t               chain;
     njs_int_t               ret;
@@ -1118,7 +1118,7 @@ njs_function_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     code = njs_generate_scope(vm, &generator, parser.scope,
                               &njs_entry_anonymous);
     if (njs_slow_path(code == NULL)) {
-        if (!njs_is_error(&vm->retval)) {
+        if (!njs_is_error(retval)) {
             njs_internal_error(vm, "njs_generate_scope() failed");
         }
 
@@ -1144,7 +1144,7 @@ njs_function_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return ret;
     }
 
-    njs_set_function(&vm->retval, function);
+    njs_set_function(retval, function);
 
     return NJS_OK;
 
@@ -1216,10 +1216,8 @@ njs_function_instance_name(njs_vm_t *vm, njs_object_prop_t *prop,
 
 static njs_int_t
 njs_function_prototype_call(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_int_t          ret;
-    njs_value_t        retval;
     const njs_value_t  *this;
 
     if (!njs_is_function(&args[0])) {
@@ -1236,25 +1234,18 @@ njs_function_prototype_call(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         nargs = 0;
     }
 
-    ret = njs_function_call(vm, njs_function(&args[0]), this, &args[2], nargs,
-                            &retval);
-    if (njs_slow_path(ret != NJS_OK)) {
-        return ret;
-    }
-
-    njs_value_assign(&vm->retval, &retval);
-
-    return NJS_OK;
+    return njs_function_call(vm, njs_function(&args[0]), this, &args[2], nargs,
+                             retval);
 }
 
 
 static njs_int_t
 njs_function_prototype_apply(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     int64_t         i, length;
     njs_int_t       ret;
-    njs_value_t     retval, *this, *arr_like;
+    njs_value_t     *this, *arr_like;
     njs_array_t     *arr;
     njs_function_t  *func;
 
@@ -1303,20 +1294,13 @@ njs_function_prototype_apply(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 activate:
 
-    ret = njs_function_call(vm, func, this, args, length, &retval);
-    if (njs_slow_path(ret != NJS_OK)) {
-        return ret;
-    }
-
-    njs_value_assign(&vm->retval, &retval);
-
-    return NJS_OK;
+    return njs_function_call(vm, func, this, args, length, retval);
 }
 
 
 static njs_int_t
 njs_function_bound_call(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     u_char          *p;
     njs_int_t       ret;
@@ -1333,7 +1317,7 @@ njs_function_bound_call(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     if (nargs == 1) {
         return njs_function_apply(vm, bound, function->bound, args_count,
-                                 &vm->retval);
+                                 retval);
     }
 
     arguments = njs_mp_alloc(vm->mem_pool,
@@ -1348,7 +1332,7 @@ njs_function_bound_call(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     memcpy(p, &args[1], (nargs - 1) * sizeof(njs_value_t));
 
     ret = njs_function_apply(vm, bound, arguments, args_count + nargs - 1,
-                             &vm->retval);
+                             retval);
 
     njs_mp_free(vm->mem_pool, arguments);
 
@@ -1358,7 +1342,7 @@ njs_function_bound_call(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_function_prototype_bind(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     size_t          size;
     njs_int_t       ret;
@@ -1439,7 +1423,7 @@ njs_function_prototype_bind(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     memcpy(values, args, size);
 
-    njs_set_function(&vm->retval, function);
+    njs_set_function(retval, function);
 
     return NJS_OK;
 }
@@ -1524,7 +1508,7 @@ const njs_object_init_t  njs_arrow_instance_init = {
 
 njs_int_t
 njs_eval_function(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_internal_error(vm, "Not implemented");
 
@@ -1534,9 +1518,9 @@ njs_eval_function(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_prototype_function(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_set_undefined(&vm->retval);
+    njs_set_undefined(retval);
 
     return NJS_OK;
 }
index c5d539ed7a30c1668051da0d111346adfb757a96..0b316251e0aa9451c4555e0ba2e5583ed4dd4244 100644 (file)
@@ -55,8 +55,6 @@ struct njs_native_frame_s {
     uint32_t                       size;
     uint32_t                       free_size;
 
-    njs_value_t                    *retval;
-
     /* Number of allocated args on the frame. */
     uint32_t                       nargs;
     /* Number of already put args. */
@@ -98,13 +96,13 @@ njs_int_t njs_function_rest_parameters_init(njs_vm_t *vm,
 njs_int_t njs_function_prototype_create(njs_vm_t *vm, njs_object_prop_t *prop,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
 njs_int_t njs_function_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);
 njs_int_t njs_function_instance_length(njs_vm_t *vm, njs_object_prop_t *prop,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
 njs_int_t njs_function_instance_name(njs_vm_t *vm, njs_object_prop_t *prop,
     njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
 njs_int_t njs_eval_function(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_int_t njs_function_native_frame(njs_vm_t *vm, njs_function_t *function,
     const njs_value_t *this, const njs_value_t *args, njs_uint_t nargs,
     njs_bool_t ctor);
@@ -114,8 +112,8 @@ njs_int_t njs_function_lambda_frame(njs_vm_t *vm, njs_function_t *function,
 njs_int_t njs_function_call2(njs_vm_t *vm, njs_function_t *function,
     const njs_value_t *this, const njs_value_t *args,
     njs_uint_t nargs, njs_value_t *retval, njs_bool_t ctor);
-njs_int_t njs_function_lambda_call(njs_vm_t *vm, void *promise_cap);
-njs_int_t njs_function_native_call(njs_vm_t *vm);
+njs_int_t njs_function_lambda_call(njs_vm_t *vm, njs_value_t *retval,
+    void *promise_cap);
 njs_native_frame_t *njs_function_frame_alloc(njs_vm_t *vm, size_t size);
 void njs_function_frame_free(njs_vm_t *vm, njs_native_frame_t *frame);
 njs_int_t njs_function_frame_save(njs_vm_t *vm, njs_frame_t *native,
index f08b33fe2df55d39dc42b1c889bd291af2fa7342..3b45f4efcc9933884df5dd3f4a067793730a89c6 100644 (file)
@@ -4278,7 +4278,7 @@ njs_generate_function_scope(njs_vm_t *vm, njs_generator_t *prev,
 
     code = njs_generate_scope(vm, &generator, node->scope, name);
     if (njs_slow_path(code == NULL)) {
-        if (!njs_is_error(&vm->retval)) {
+        if (!njs_is_error(&vm->exception)) {
             njs_internal_error(vm, "njs_generate_scope() failed");
         }
 
index 4845b6289596c06e2696003d73604d6f20d45aeb..48c52eb48de6d9388b74b4af035f0b902b45cfb9 100644 (file)
@@ -24,10 +24,11 @@ static const njs_value_t  string_value = njs_string("value");
 
 static njs_int_t njs_iterator_object_handler(njs_vm_t *vm,
     njs_iterator_handler_t handler, njs_iterator_args_t *args,
-    njs_value_t *key, int64_t i);
+    njs_value_t *key, int64_t i, njs_value_t *retval);
 
 static njs_int_t njs_iterator_to_array_handler(njs_vm_t *vm,
-    njs_iterator_args_t *args, njs_value_t *value, int64_t index);
+    njs_iterator_args_t *args, njs_value_t *value, int64_t index,
+    njs_value_t *retval);
 
 
 njs_int_t
@@ -172,9 +173,9 @@ release:
 
 static njs_int_t
 njs_iterator_prototype_get_this(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)
 {
-    vm->retval = args[0];
+    njs_value_assign(retval, njs_argument(args, 0));
 
     return NJS_OK;
 }
@@ -206,7 +207,7 @@ const njs_object_type_init_t  njs_iterator_type_init = {
 
 static njs_int_t
 njs_array_iterator_prototype_next(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t tag)
+    njs_uint_t nargs, njs_index_t tag, njs_value_t *retval)
 {
     njs_int_t          ret;
     njs_bool_t         check;
@@ -231,15 +232,15 @@ njs_array_iterator_prototype_next(njs_vm_t *vm, njs_value_t *args,
         return NJS_ERROR;
     }
 
-    njs_set_object(&vm->retval, object);
+    njs_set_object(retval, object);
 
-    prop_value = njs_object_property_add(vm, &vm->retval,
+    prop_value = njs_object_property_add(vm, retval,
                                          njs_value_arg(&string_value), 0);
     if (njs_slow_path(prop_value == NULL)) {
         return NJS_ERROR;
     }
 
-    prop_done = njs_object_property_add(vm, &vm->retval,
+    prop_done = njs_object_property_add(vm, retval,
                                         njs_value_arg(&string_done), 0);
     if (njs_slow_path(prop_done == NULL)) {
         return NJS_ERROR;
@@ -291,7 +292,7 @@ const njs_object_type_init_t  njs_array_iterator_type_init = {
 
 njs_int_t
 njs_object_iterate(njs_vm_t *vm, njs_iterator_args_t *args,
-    njs_iterator_handler_t handler)
+    njs_iterator_handler_t handler, njs_value_t *retval)
 {
     double              idx;
     int64_t             length, i, from, to;
@@ -317,7 +318,7 @@ njs_object_iterate(njs_vm_t *vm, njs_iterator_args_t *args,
             if (njs_fast_path(from < array->length
                               && njs_is_valid(&array->start[from])))
             {
-                ret = handler(vm, args, &array->start[from], from);
+                ret = handler(vm, args, &array->start[from], from, retval);
 
             } else {
                 entry = njs_value_arg(&njs_value_invalid);
@@ -330,7 +331,7 @@ njs_object_iterate(njs_vm_t *vm, njs_iterator_args_t *args,
                     entry = &prop;
                 }
 
-                ret = handler(vm, args, entry, from);
+                ret = handler(vm, args, entry, from, retval);
             }
 
             if (njs_slow_path(ret != NJS_OK)) {
@@ -373,7 +374,7 @@ njs_object_iterate(njs_vm_t *vm, njs_iterator_args_t *args,
                 /* This cannot fail. */
                 (void) njs_string_new(vm, &character, p + i, 1, 1);
 
-                ret = handler(vm, args, &character, i);
+                ret = handler(vm, args, &character, i, retval);
                 if (njs_slow_path(ret != NJS_OK)) {
                     if (ret == NJS_DONE) {
                         return NJS_DONE;
@@ -392,7 +393,7 @@ njs_object_iterate(njs_vm_t *vm, njs_iterator_args_t *args,
                 /* This cannot fail. */
                 (void) njs_string_new(vm, &character, p, pos - p, 1);
 
-                ret = handler(vm, args, &character, i);
+                ret = handler(vm, args, &character, i, retval);
                 if (njs_slow_path(ret != NJS_OK)) {
                     if (ret == NJS_DONE) {
                         return NJS_DONE;
@@ -427,8 +428,8 @@ process_object:
                 continue;
             }
 
-            ret = njs_iterator_object_handler(vm, handler, args, &keys->start[i],
-                                           idx);
+            ret = njs_iterator_object_handler(vm, handler, args,
+                                              &keys->start[i], idx, retval);
             if (njs_slow_path(ret != NJS_OK)) {
                 njs_array_destroy(vm, keys);
                 return ret;
@@ -441,7 +442,7 @@ process_object:
     }
 
     for (i = from; i < to; i++) {
-        ret = njs_iterator_object_handler(vm, handler, args, NULL, i);
+        ret = njs_iterator_object_handler(vm, handler, args, NULL, i, retval);
         if (njs_slow_path(ret != NJS_OK)) {
             return ret;
         }
@@ -453,7 +454,7 @@ process_object:
 
 njs_int_t
 njs_object_iterate_reverse(njs_vm_t *vm, njs_iterator_args_t *args,
-    njs_iterator_handler_t handler)
+    njs_iterator_handler_t handler, njs_value_t *retval)
 {
     double              idx;
     int64_t             i, from, to, length;
@@ -481,7 +482,7 @@ njs_object_iterate_reverse(njs_vm_t *vm, njs_iterator_args_t *args,
             if (njs_fast_path(from < array->length
                               && njs_is_valid(&array->start[from])))
             {
-                ret = handler(vm, args, &array->start[from], from);
+                ret = handler(vm, args, &array->start[from], from, retval);
 
             } else {
                 entry = njs_value_arg(&njs_value_invalid);
@@ -494,7 +495,7 @@ njs_object_iterate_reverse(njs_vm_t *vm, njs_iterator_args_t *args,
                     entry = &prop;
                 }
 
-                ret = handler(vm, args, entry, from);
+                ret = handler(vm, args, entry, from, retval);
             }
 
             if (njs_slow_path(ret != NJS_OK)) {
@@ -539,7 +540,7 @@ njs_object_iterate_reverse(njs_vm_t *vm, njs_iterator_args_t *args,
                 /* This cannot fail. */
                 (void) njs_string_new(vm, &character, p, 1, 1);
 
-                ret = handler(vm, args, &character, i);
+                ret = handler(vm, args, &character, i, retval);
                 if (njs_slow_path(ret != NJS_OK)) {
                     if (ret == NJS_DONE) {
                         return NJS_DONE;
@@ -568,7 +569,7 @@ njs_object_iterate_reverse(njs_vm_t *vm, njs_iterator_args_t *args,
                 /* This cannot fail. */
                 (void) njs_string_new(vm, &character, pos, p - pos , 1);
 
-                ret = handler(vm, args, &character, i);
+                ret = handler(vm, args, &character, i, retval);
                 if (njs_slow_path(ret != NJS_OK)) {
                     if (ret == NJS_DONE) {
                         return NJS_DONE;
@@ -606,7 +607,7 @@ process_object:
             }
 
             ret = njs_iterator_object_handler(vm, handler, args,
-                                              &keys->start[i], idx);
+                                              &keys->start[i], idx, retval);
             if (njs_slow_path(ret != NJS_OK)) {
                 njs_array_destroy(vm, keys);
                 return ret;
@@ -621,7 +622,7 @@ process_object:
     i = from + 1;
 
     while (i-- > to) {
-        ret = njs_iterator_object_handler(vm, handler, args, NULL, i);
+        ret = njs_iterator_object_handler(vm, handler, args, NULL, i, retval);
         if (njs_slow_path(ret != NJS_OK)) {
             return ret;
         }
@@ -633,7 +634,7 @@ process_object:
 
 static njs_int_t
 njs_iterator_object_handler(njs_vm_t *vm, njs_iterator_handler_t handler,
-    njs_iterator_args_t *args, njs_value_t *key, int64_t i)
+    njs_iterator_args_t *args, njs_value_t *key, int64_t i, njs_value_t *retval)
 {
     njs_int_t    ret;
     njs_value_t  prop, *entry;
@@ -653,7 +654,7 @@ njs_iterator_object_handler(njs_vm_t *vm, njs_iterator_handler_t handler,
 
     entry = (ret == NJS_OK) ? &prop : njs_value_arg(&njs_value_invalid);
 
-    ret = handler(vm, args, entry, i);
+    ret = handler(vm, args, entry, i, retval);
     if (njs_slow_path(ret != NJS_OK)) {
         if (ret == NJS_DONE) {
             return NJS_DONE;
@@ -667,7 +668,7 @@ njs_iterator_object_handler(njs_vm_t *vm, njs_iterator_handler_t handler,
 
 
 njs_array_t *
-njs_iterator_to_array(njs_vm_t *vm, njs_value_t *iterator)
+njs_iterator_to_array(njs_vm_t *vm, njs_value_t *iterator, njs_value_t *retval)
 {
     int64_t              length;
     njs_int_t            ret;
@@ -689,7 +690,7 @@ njs_iterator_to_array(njs_vm_t *vm, njs_value_t *iterator)
     args.value = iterator;
     args.to = length;
 
-    ret = njs_object_iterate(vm, &args, njs_iterator_to_array_handler);
+    ret = njs_object_iterate(vm, &args, njs_iterator_to_array_handler, retval);
     if (njs_slow_path(ret == NJS_ERROR)) {
         njs_mp_free(vm->mem_pool, args.data);
         return NULL;
@@ -701,7 +702,7 @@ njs_iterator_to_array(njs_vm_t *vm, njs_value_t *iterator)
 
 static njs_int_t
 njs_iterator_to_array_handler(njs_vm_t *vm, njs_iterator_args_t *args,
-    njs_value_t *value, int64_t index)
+    njs_value_t *value, int64_t index, njs_value_t *retval)
 {
     njs_value_t  array;
 
index 8c02826c4354117c5ef56f0c707c41e039498cdb..7baf1dcf2a4d5a5db5f2159be9fab0524488a6f2 100644 (file)
@@ -21,7 +21,8 @@ typedef struct {
 
 
 typedef njs_int_t (*njs_iterator_handler_t)(njs_vm_t *vm,
-    njs_iterator_args_t *args, njs_value_t *entry, int64_t n);
+    njs_iterator_args_t *args, njs_value_t *entry, int64_t n,
+    njs_value_t *retval);
 
 
 njs_int_t njs_array_iterator_create(njs_vm_t *vm, const njs_value_t *src,
@@ -31,12 +32,13 @@ njs_int_t njs_array_iterator_next(njs_vm_t *vm, njs_value_t *iterator,
     njs_value_t *retval);
 
 njs_int_t njs_object_iterate(njs_vm_t *vm, njs_iterator_args_t *args,
-    njs_iterator_handler_t handler);
+    njs_iterator_handler_t handler, njs_value_t *retval);
 
 njs_int_t njs_object_iterate_reverse(njs_vm_t *vm, njs_iterator_args_t *args,
-    njs_iterator_handler_t handler);
+    njs_iterator_handler_t handler, njs_value_t *retval);
 
-njs_array_t *njs_iterator_to_array(njs_vm_t *vm, njs_value_t *iterator);
+njs_array_t *njs_iterator_to_array(njs_vm_t *vm, njs_value_t *iterator,
+    njs_value_t *retval);
 
 
 extern const njs_object_type_init_t  njs_iterator_type_init;
index 5d0fbffdf5f5204e14c33b6143fc4d9bc90d99e7..ffe68ff283fec63b2e9e6f5fa4c57f0edd7b1f0c 100644 (file)
@@ -69,7 +69,7 @@ static void njs_json_parse_exception(njs_json_parse_ctx_t *ctx,
     const char *msg, const u_char *pos);
 
 static njs_int_t njs_json_stringify_iterator(njs_vm_t *vm,
-    njs_json_stringify_t *stringify, njs_value_t *value);
+    njs_json_stringify_t *stringify, njs_value_t *value, njs_value_t *retval);
 static njs_function_t *njs_object_to_json_function(njs_vm_t *vm,
     njs_value_t *value);
 static njs_int_t njs_json_stringify_to_json(njs_json_stringify_t* stringify,
@@ -94,7 +94,7 @@ static const njs_object_prop_t  njs_json_object_properties[];
 
 static njs_int_t
 njs_json_parse(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_int_t             ret;
     njs_value_t           *text, value, lvalue, wrapper;
@@ -152,29 +152,30 @@ njs_json_parse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return njs_json_internalize_property(vm, njs_function(reviver),
                                              &wrapper,
                                              njs_value_arg(&njs_string_empty),
-                                             0, &vm->retval);
+                                             0, retval);
     }
 
-    vm->retval = value;
+    njs_value_assign(retval, &value);
 
     return NJS_OK;
 }
 
 
 njs_int_t
-njs_vm_json_parse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs)
+njs_vm_json_parse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
+    njs_value_t *retval)
 {
     njs_function_t  *parse;
 
     parse = njs_function(&njs_json_object_properties[1].u.value);
 
-    return njs_vm_call(vm, parse, args, nargs);
+    return njs_vm_invoke(vm, parse, args, nargs, retval);
 }
 
 
 static njs_int_t
 njs_json_stringify(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     size_t                length;
     int64_t               i64;
@@ -262,7 +263,8 @@ njs_json_stringify(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         break;
      }
 
-    return njs_json_stringify_iterator(vm, stringify, njs_arg(args, nargs, 1));
+    return njs_json_stringify_iterator(vm, stringify, njs_arg(args, nargs, 1),
+                                       retval);
 
 memory_error:
 
@@ -273,13 +275,14 @@ memory_error:
 
 
 njs_int_t
-njs_vm_json_stringify(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs)
+njs_vm_json_stringify(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
+    njs_value_t *retval)
 {
     njs_function_t  *stringify;
 
     stringify = njs_function(&njs_json_object_properties[2].u.value);
 
-    return njs_vm_call(vm, stringify, args, nargs);
+    return njs_vm_invoke(vm, stringify, args, nargs, retval);
 }
 
 
@@ -1083,7 +1086,7 @@ njs_json_stringify_done(njs_json_state_t *state, njs_bool_t array)
 
 static njs_int_t
 njs_json_stringify_iterator(njs_vm_t *vm, njs_json_stringify_t *stringify,
-    njs_value_t *object)
+    njs_value_t *object, njs_value_t *retval)
 {
     int64_t           size;
     njs_int_t         ret;
@@ -1214,11 +1217,11 @@ done:
     }
 
     if (size == 0) {
-        njs_set_undefined(&vm->retval);
+        njs_set_undefined(retval);
         goto release;
     }
 
-    ret = njs_string_create_chb(vm, &vm->retval, &chain);
+    ret = njs_string_create_chb(vm, retval, &chain);
     if (njs_slow_path(ret != NJS_OK)) {
         njs_chb_destroy(&chain);
         goto memory_error;
@@ -1962,7 +1965,7 @@ njs_vm_value_dump(njs_vm_t *vm, njs_str_t *retval, njs_value_t *value,
     njs_int_t             ret;
     njs_chb_t             chain;
     njs_str_t             str;
-    njs_value_t           *key, *val, tag;
+    njs_value_t           *key, *val, tag, exception;
     njs_json_state_t      *state;
     njs_string_prop_t     string;
     njs_object_prop_t     *prop;
@@ -1974,6 +1977,16 @@ njs_vm_value_dump(njs_vm_t *vm, njs_str_t *retval, njs_value_t *value,
     stringify->vm = vm;
     stringify->depth = 0;
 
+    if (njs_slow_path(vm->top_frame == NULL)) {
+        /* An exception was thrown during compilation. */
+        njs_vm_init(vm);
+    }
+
+    if (njs_is_valid(&vm->exception)) {
+        exception = njs_vm_exception(vm);
+        value = &exception;
+    }
+
     njs_chb_init(&chain, vm->mem_pool);
 
     if (!njs_dump_is_recursive(value)) {
@@ -2151,7 +2164,7 @@ memory_error:
 
 exception:
 
-    njs_vm_value_string(vm, retval, &vm->retval);
+    njs_vm_value_string(vm, retval, &vm->exception);
 
     return NJS_OK;
 }
index 3f9192306265b21c25e66cbd9592d2c8f3fde964..cc68d9b89f6ab2670528c8ebb8295e3a05b14820 100644 (file)
@@ -45,7 +45,7 @@ typedef enum {
 
 static njs_int_t
 njs_object_math_func(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t magic)
+    njs_index_t magic, njs_value_t *retval)
 {
     double            num, num2;
     uint8_t           sign;
@@ -268,7 +268,7 @@ njs_object_math_func(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         }
     }
 
-    njs_set_number(&vm->retval, num);
+    njs_set_number(retval, num);
 
     return NJS_OK;
 }
@@ -276,7 +276,7 @@ njs_object_math_func(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_object_math_hypot(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     double      num;
     njs_int_t   ret;
@@ -302,7 +302,7 @@ njs_object_math_hypot(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         }
     }
 
-    njs_set_number(&vm->retval, num);
+    njs_set_number(retval, num);
 
     return NJS_OK;
 }
@@ -332,7 +332,7 @@ njs_fmin(double x, double y)
 
 static njs_int_t
 njs_object_math_min_max(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t max)
+    njs_index_t max, njs_value_t *retval)
 {
     double      num, value;
     njs_int_t   ret;
@@ -354,7 +354,7 @@ njs_object_math_min_max(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         value = max ? njs_fmax(value, num) : njs_fmin(value, num);
     }
 
-    njs_set_number(&vm->retval, value);
+    njs_set_number(retval, value);
 
     return NJS_OK;
 }
@@ -362,13 +362,13 @@ njs_object_math_min_max(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_object_math_random(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     double  num;
 
     num = njs_random(&vm->random) / 4294967296.0;
 
-    njs_set_number(&vm->retval, num);
+    njs_set_number(retval, num);
 
     return NJS_OK;
 }
index 8856f6da84d230ec344a3830bb68180f5aebff0c..e146ffa07a4cbb8d76b625d17e0cfe1f951c164f 100644 (file)
@@ -325,7 +325,7 @@ njs_module_add(njs_vm_t *vm, njs_str_t *name, njs_value_t *value)
 
 njs_int_t
 njs_module_require(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_int_t    ret;
     njs_str_t    name;
@@ -352,7 +352,7 @@ njs_module_require(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    njs_value_assign(&vm->retval, &module->value);
+    njs_value_assign(retval, &module->value);
 
     return NJS_OK;
 }
index ead4a34da97171fe93ecd2a9ca41e6366cae13c5..5502d0d12cad7465ebb126f74581a9be56fdd585 100644 (file)
@@ -21,7 +21,7 @@ njs_mod_t *njs_module_find(njs_vm_t *vm, njs_str_t *name,
     njs_bool_t shared);
 njs_mod_t *njs_parser_module(njs_parser_t *parser, njs_str_t *name);
 njs_int_t njs_module_require(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);
 
 
 extern njs_module_t              *njs_modules[];
index 4292efd7e33fc975dcdb050397214e1867d85557..ebd64d326d53e197981f8e1983b1a224eb1bd046 100644 (file)
@@ -310,7 +310,7 @@ njs_number_to_chain(njs_vm_t *vm, njs_chb_t *chain, double num)
 
 static njs_int_t
 njs_number_constructor(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_int_t           ret;
     njs_value_t         *value;
@@ -336,10 +336,10 @@ njs_number_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             return NJS_ERROR;
         }
 
-        njs_set_object_value(&vm->retval, object);
+        njs_set_object_value(retval, object);
 
     } else {
-        njs_set_number(&vm->retval, njs_number(value));
+        njs_set_number(retval, njs_number(value));
     }
 
     return NJS_OK;
@@ -348,22 +348,22 @@ njs_number_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_number_is_integer(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
-    double             num;
-    const njs_value_t  *value;
+    double      num;
+    njs_bool_t  integer;
 
-    value = &njs_value_false;
+    integer = 0;
 
     if (nargs > 1 && njs_is_number(&args[1])) {
         num = njs_number(&args[1]);
 
         if (num == trunc(num) && !isinf(num)) {
-            value = &njs_value_true;
+            integer = 1;
         }
     }
 
-    vm->retval = *value;
+    njs_set_boolean(retval, integer);
 
     return NJS_OK;
 }
@@ -372,22 +372,22 @@ njs_number_is_integer(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_number_is_safe_integer(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
-    double             num;
-    const njs_value_t  *value;
+    double      num;
+    njs_bool_t  integer;
 
-    value = &njs_value_false;
+    integer = 0;
 
     if (nargs > 1 && njs_is_number(&args[1])) {
         num = njs_number(&args[1]);
 
         if (num == (int64_t) num && fabs(num) <= NJS_MAX_SAFE_INTEGER) {
-            value = &njs_value_true;
+            integer = 1;
         }
     }
 
-    vm->retval = *value;
+    njs_set_boolean(retval, integer);
 
     return NJS_OK;
 }
@@ -395,20 +395,20 @@ njs_number_is_safe_integer(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_number_is_nan(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
-    const njs_value_t  *value;
+    njs_bool_t  nan;
 
-    value = &njs_value_false;
+    nan = 0;
 
     if (nargs > 1
         && njs_is_number(&args[1])
         && isnan(njs_number(&args[1])))
     {
-        value = &njs_value_true;
+        nan = 1;
     }
 
-    vm->retval = *value;
+    njs_set_boolean(retval, nan);
 
     return NJS_OK;
 }
@@ -416,22 +416,22 @@ njs_number_is_nan(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_number_is_finite(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
-    double             num;
-    const njs_value_t  *value;
+    double      num;
+    njs_bool_t  finite;
 
-    value = &njs_value_false;
+    finite = 0;
 
     if (nargs > 1 && njs_is_number(&args[1])) {
         num = njs_number(&args[1]);
 
         if (!isnan(num) && !isinf(num)) {
-            value = &njs_value_true;
+            finite = 1;
         }
     }
 
-    vm->retval = *value;
+    njs_set_boolean(retval, finite);
 
     return NJS_OK;
 }
@@ -487,11 +487,11 @@ const njs_object_init_t  njs_number_constructor_init = {
 
 static njs_int_t
 njs_number_prototype_value_of(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;
 
-    value = &args[0];
+    value = njs_argument(args, 0);
 
     if (value->type != NJS_NUMBER) {
 
@@ -505,7 +505,7 @@ njs_number_prototype_value_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         }
     }
 
-    vm->retval = *value;
+    njs_value_assign(retval, value);
 
     return NJS_OK;
 }
@@ -513,7 +513,7 @@ njs_number_prototype_value_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_number_prototype_to_string(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t unused)
+    njs_uint_t nargs, njs_index_t unused, njs_value_t *retval)
 {
     double       number;
     int32_t      radix;
@@ -548,17 +548,17 @@ njs_number_prototype_to_string(njs_vm_t *vm, njs_value_t *args,
         number = njs_number(value);
 
         if (radix != 10 && !isnan(number) && !isinf(number) && number != 0) {
-            return njs_number_to_string_radix(vm, &vm->retval, number, radix);
+            return njs_number_to_string_radix(vm, retval, number, radix);
         }
     }
 
-    return njs_number_to_string(vm, &vm->retval, value);
+    return njs_number_to_string(vm, retval, value);
 }
 
 
 static njs_int_t
 njs_number_prototype_to_fixed(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)
 {
     u_char       *p;
     int64_t      frac;
@@ -596,7 +596,7 @@ njs_number_prototype_to_fixed(njs_vm_t *vm, njs_value_t *args,
     number = njs_number(value);
 
     if (njs_slow_path(isnan(number) || fabs(number) >= 1e21)) {
-        return njs_number_to_string(vm, &vm->retval, value);
+        return njs_number_to_string(vm, retval, value);
     }
 
     point = 0;
@@ -634,7 +634,7 @@ njs_number_prototype_to_fixed(njs_vm_t *vm, njs_value_t *args,
         *p++ = '0';
     }
 
-    p = njs_string_alloc(vm, &vm->retval, size, size);
+    p = njs_string_alloc(vm, retval, size, size);
     if (njs_slow_path(p == NULL)) {
         return NJS_ERROR;
     }
@@ -657,7 +657,7 @@ njs_number_prototype_to_fixed(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_number_prototype_to_precision(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)
 {
     double       number;
     size_t       size;
@@ -682,7 +682,7 @@ njs_number_prototype_to_precision(njs_vm_t *vm, njs_value_t *args,
     }
 
     if (njs_is_undefined(njs_arg(args, nargs, 1))) {
-        return njs_number_to_string(vm, &vm->retval, value);
+        return njs_number_to_string(vm, retval, value);
     }
 
     ret = njs_value_to_integer(vm, njs_argument(args, 1), &precision);
@@ -693,7 +693,7 @@ njs_number_prototype_to_precision(njs_vm_t *vm, njs_value_t *args,
     number = njs_number(value);
 
     if (njs_slow_path(isnan(number) || isinf(number))) {
-        return njs_number_to_string(vm, &vm->retval, value);
+        return njs_number_to_string(vm, retval, value);
     }
 
     if (njs_slow_path(precision < 1 || precision > 100)) {
@@ -703,13 +703,13 @@ njs_number_prototype_to_precision(njs_vm_t *vm, njs_value_t *args,
 
     size = njs_dtoa_precision(number, (char *) buf, (size_t) precision);
 
-    return njs_string_new(vm, &vm->retval, buf, size, size);
+    return njs_string_new(vm, retval, buf, size, size);
 }
 
 
 static njs_int_t
 njs_number_prototype_to_exponential(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)
 {
     double       number;
     size_t       size;
@@ -741,7 +741,7 @@ njs_number_prototype_to_exponential(njs_vm_t *vm, njs_value_t *args,
     number = njs_number(value);
 
     if (njs_slow_path(isnan(number) || isinf(number))) {
-        return njs_number_to_string(vm, &vm->retval, value);
+        return njs_number_to_string(vm, retval, value);
     }
 
     if (njs_is_defined(value_frac)) {
@@ -756,7 +756,7 @@ njs_number_prototype_to_exponential(njs_vm_t *vm, njs_value_t *args,
 
     size = njs_dtoa_exponential(number, (char *) buf, (njs_int_t) frac);
 
-    return njs_string_new(vm, &vm->retval, buf, size, size);
+    return njs_string_new(vm, retval, buf, size, size);
 }
 
 
@@ -913,7 +913,7 @@ const njs_object_init_t  njs_number_prototype_init = {
 
 njs_int_t
 njs_number_global_is_nan(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     double     num;
     njs_int_t  ret;
@@ -923,7 +923,7 @@ njs_number_global_is_nan(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return ret;
     }
 
-    njs_set_boolean(&vm->retval, isnan(num));
+    njs_set_boolean(retval, isnan(num));
 
     return NJS_OK;
 }
@@ -931,7 +931,7 @@ njs_number_global_is_nan(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 njs_int_t
 njs_number_global_is_finite(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     double     num;
     njs_int_t  ret;
@@ -941,7 +941,7 @@ njs_number_global_is_finite(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return ret;
     }
 
-    njs_set_boolean(&vm->retval, !(isnan(num) || isinf(num)));
+    njs_set_boolean(retval, !(isnan(num) || isinf(num)));
 
     return NJS_OK;
 }
@@ -949,7 +949,7 @@ njs_number_global_is_finite(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 njs_int_t
 njs_number_parse_int(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     double             num;
     int32_t            radix;
@@ -1022,7 +1022,7 @@ njs_number_parse_int(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 done:
 
-    njs_set_number(&vm->retval, num);
+    njs_set_number(retval, num);
 
     return NJS_OK;
 }
@@ -1030,7 +1030,7 @@ done:
 
 njs_int_t
 njs_number_parse_float(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     double             num;
     njs_int_t          ret;
@@ -1083,7 +1083,7 @@ njs_number_parse_float(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 done:
 
-    njs_set_number(&vm->retval, minus ? -num : num);
+    njs_set_number(retval, minus ? -num : num);
 
     return NJS_OK;
 }
index 8a4df15066ca05f3b457ad7206f9f95bd7ccb9c4..0683690216593f40291f992f9c8708af51c7799c 100644 (file)
@@ -27,13 +27,13 @@ njs_int_t njs_number_to_string(njs_vm_t *vm, njs_value_t *string,
 njs_int_t njs_number_to_chain(njs_vm_t *vm, njs_chb_t *chain,
     double number);
 njs_int_t njs_number_global_is_nan(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t unused);
+    njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 njs_int_t njs_number_global_is_finite(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t unused);
+    njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 njs_int_t njs_number_parse_int(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);
 njs_int_t njs_number_parse_float(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);
 
 
 njs_inline njs_bool_t
index 24738708168cb3b90dab60038394d2be8fe96785..287b354ab66e0edaf954fcf053904b3d5ad3b3a8 100644 (file)
@@ -30,7 +30,7 @@ static njs_int_t njs_object_own_enumerate_object(njs_vm_t *vm,
     const njs_object_t *object, const njs_object_t *parent, njs_array_t *items,
     njs_object_enum_t kind, njs_object_enum_type_t type, njs_bool_t all);
 static njs_int_t njs_object_define_properties(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_object_set_prototype(njs_vm_t *vm, njs_object_t *object,
     const njs_value_t *value);
 
@@ -216,7 +216,7 @@ njs_object_hash_test(njs_lvlhsh_query_t *lhq, void *data)
 
 static njs_int_t
 njs_object_constructor(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_uint_t          type, index;
     njs_value_t         *value;
@@ -232,7 +232,7 @@ njs_object_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             return NJS_ERROR;
         }
 
-        njs_set_object(&vm->retval, object);
+        njs_set_object(retval, object);
 
         return NJS_OK;
     }
@@ -244,7 +244,7 @@ njs_object_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             return NJS_ERROR;
         }
 
-        njs_set_object_value(&vm->retval, obj_val);
+        njs_set_object_value(retval, obj_val);
 
         return NJS_OK;
     }
@@ -256,7 +256,7 @@ njs_object_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    njs_value_assign(&vm->retval, value);
+    njs_value_assign(retval, value);
 
     return NJS_OK;
 }
@@ -264,7 +264,7 @@ njs_object_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_object_create(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, *descs, arguments[3];
     njs_object_t  *object;
@@ -286,18 +286,19 @@ njs_object_create(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             object->__proto__ = NULL;
         }
 
-        njs_set_object(&vm->retval, object);
-
         descs = njs_arg(args, nargs, 2);
 
         if (njs_slow_path(!njs_is_undefined(descs))) {
             arguments[0] = args[0];
-            arguments[1] = vm->retval;
+            njs_set_object(&arguments[1], object);
             arguments[2] = *descs;
 
-            return njs_object_define_properties(vm, arguments, 3, unused);
+            return njs_object_define_properties(vm, arguments, 3, unused,
+                                                retval);
         }
 
+        njs_set_object(retval, object);
+
         return NJS_OK;
     }
 
@@ -310,7 +311,7 @@ njs_object_create(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_object_keys(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;
     njs_array_t  *keys;
@@ -330,7 +331,7 @@ njs_object_keys(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    njs_set_array(&vm->retval, keys);
+    njs_set_array(retval, keys);
 
     return NJS_OK;
 }
@@ -338,7 +339,7 @@ njs_object_keys(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_object_values(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_array_t  *array;
     njs_value_t  *value;
@@ -358,7 +359,7 @@ njs_object_values(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    njs_set_array(&vm->retval, array);
+    njs_set_array(retval, array);
 
     return NJS_OK;
 }
@@ -366,7 +367,7 @@ njs_object_values(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_object_entries(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_array_t  *array;
     njs_value_t  *value;
@@ -386,7 +387,7 @@ njs_object_entries(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    njs_set_array(&vm->retval, array);
+    njs_set_array(retval, array);
 
     return NJS_OK;
 }
@@ -1259,7 +1260,7 @@ done:
 
 static njs_int_t
 njs_object_define_property(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_int_t    ret;
     njs_value_t  *value, *name, *desc, lvalue;
@@ -1285,7 +1286,7 @@ njs_object_define_property(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    vm->retval = *value;
+    njs_value_assign(retval, value);
 
     return NJS_OK;
 }
@@ -1293,7 +1294,7 @@ njs_object_define_property(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_object_define_properties(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     uint32_t              i, length;
     njs_int_t             ret;
@@ -1350,7 +1351,7 @@ njs_object_define_properties(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     ret = NJS_OK;
-    vm->retval = *value;
+    njs_value_assign(retval, value);
 
 done:
 
@@ -1362,7 +1363,7 @@ done:
 
 static njs_int_t
 njs_object_get_own_property_descriptor(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)
 {
     njs_value_t  lvalue, *value, *property;
 
@@ -1376,13 +1377,13 @@ njs_object_get_own_property_descriptor(njs_vm_t *vm, njs_value_t *args,
 
     property = njs_lvalue_arg(&lvalue, args, nargs, 2);
 
-    return njs_object_prop_descriptor(vm, &vm->retval, value, property);
+    return njs_object_prop_descriptor(vm, retval, value, property);
 }
 
 
 static njs_int_t
 njs_object_get_own_property_descriptors(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t unused)
+    njs_uint_t nargs, njs_index_t unused, njs_value_t *retval)
 {
     njs_int_t           ret;
     uint32_t            i, length;
@@ -1444,7 +1445,7 @@ njs_object_get_own_property_descriptors(njs_vm_t *vm, njs_value_t *args,
     }
 
     ret = NJS_OK;
-    njs_set_object(&vm->retval, descriptors);
+    njs_set_object(retval, descriptors);
 
 done:
 
@@ -1456,7 +1457,7 @@ done:
 
 static njs_int_t
 njs_object_get_own_property(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t type)
+    njs_uint_t nargs, njs_index_t type, njs_value_t *retval)
 {
     njs_array_t  *names;
     njs_value_t  *value;
@@ -1476,7 +1477,7 @@ njs_object_get_own_property(njs_vm_t *vm, njs_value_t *args,
         return NJS_ERROR;
     }
 
-    njs_set_array(&vm->retval, names);
+    njs_set_array(retval, names);
 
     return NJS_OK;
 }
@@ -1484,7 +1485,7 @@ njs_object_get_own_property(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_object_get_prototype_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     uint32_t     index;
     njs_value_t  *value;
@@ -1492,7 +1493,7 @@ njs_object_get_prototype_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     value = njs_arg(args, nargs, 1);
 
     if (njs_is_object(value)) {
-        njs_object_prototype_proto(vm, NULL, value, NULL, &vm->retval);
+        njs_object_prototype_proto(vm, NULL, value, NULL, retval);
         return NJS_OK;
     }
 
@@ -1500,10 +1501,10 @@ njs_object_get_prototype_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         index = njs_primitive_prototype_index(value->type);
 
         if (njs_is_symbol(value)) {
-            njs_set_object(&vm->retval, &vm->prototypes[index].object);
+            njs_set_object(retval, &vm->prototypes[index].object);
 
         } else {
-            njs_set_object_value(&vm->retval,
+            njs_set_object_value(retval,
                                  &vm->prototypes[index].object_value);
         }
 
@@ -1519,7 +1520,7 @@ njs_object_get_prototype_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_object_set_prototype_of(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_int_t    ret;
     njs_value_t  *value, *proto;
@@ -1539,15 +1540,13 @@ njs_object_set_prototype_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     if (njs_slow_path(!njs_is_object(value))) {
-        vm->retval = *value;
-
+        njs_value_assign(retval, value);
         return NJS_OK;
     }
 
     ret = njs_object_set_prototype(vm, njs_object(value), proto);
     if (njs_fast_path(ret == NJS_OK)) {
-        vm->retval = *value;
-
+        njs_value_assign(retval, value);
         return NJS_OK;
     }
 
@@ -1567,7 +1566,7 @@ njs_object_set_prototype_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_object_set_integrity_level(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t level)
+    njs_uint_t nargs, njs_index_t level, njs_value_t *retval)
 {
     uint32_t           length;
     njs_int_t          ret;
@@ -1581,7 +1580,7 @@ njs_object_set_integrity_level(njs_vm_t *vm, njs_value_t *args,
     value = njs_arg(args, nargs, 1);
 
     if (njs_slow_path(!njs_is_object(value))) {
-        vm->retval = *value;
+        njs_value_assign(retval, value);
         return NJS_OK;
     }
 
@@ -1631,7 +1630,7 @@ njs_object_set_integrity_level(njs_vm_t *vm, njs_value_t *args,
         prop->configurable = 0;
     }
 
-    vm->retval = *value;
+    njs_value_assign(retval, value);
 
     return NJS_OK;
 }
@@ -1639,23 +1638,22 @@ njs_object_set_integrity_level(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_object_test_integrity_level(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t level)
+    njs_uint_t nargs, njs_index_t level, njs_value_t *retval)
 {
     njs_value_t        *value;
     njs_lvlhsh_t       *hash;
     njs_object_t       *object;
     njs_object_prop_t  *prop;
     njs_lvlhsh_each_t  lhe;
-    const njs_value_t  *retval;
 
     value = njs_arg(args, nargs, 1);
 
     if (njs_slow_path(!njs_is_object(value))) {
-        vm->retval = njs_value_true;
+        njs_set_boolean(retval, 1);
         return NJS_OK;
     }
 
-    retval = &njs_value_false;
+    njs_set_boolean(retval, 0);
 
     object = njs_object(value);
 
@@ -1692,32 +1690,30 @@ njs_object_test_integrity_level(njs_vm_t *vm, njs_value_t *args,
         }
     }
 
-    retval = &njs_value_true;
+    njs_set_boolean(retval, 1);
 
 done:
 
-    vm->retval = *retval;
-
     return NJS_OK;
 }
 
 
 static njs_int_t
 njs_object_prevent_extensions(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;
 
     value = njs_arg(args, nargs, 1);
 
     if (!njs_is_object(value)) {
-        vm->retval = *value;
+        njs_value_assign(retval, value);
         return NJS_OK;
     }
 
     njs_object(&args[1])->extensible = 0;
 
-    vm->retval = *value;
+    njs_value_assign(retval, value);
 
     return NJS_OK;
 }
@@ -1725,22 +1721,18 @@ njs_object_prevent_extensions(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_object_is_extensible(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;
-    const njs_value_t  *retval;
+    njs_value_t  *value;
 
     value = njs_arg(args, nargs, 1);
 
     if (!njs_is_object(value)) {
-        vm->retval = njs_value_false;
+        njs_set_boolean(retval, 0);
         return NJS_OK;
     }
 
-    retval = njs_object(value)->extensible ? &njs_value_true
-                                           : &njs_value_false;
-
-    vm->retval = *retval;
+    njs_set_boolean(retval, njs_object(value)->extensible);
 
     return NJS_OK;
 }
@@ -1748,7 +1740,7 @@ njs_object_is_extensible(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_object_assign(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     uint32_t              i, j, length;
     njs_int_t             ret;
@@ -1806,7 +1798,7 @@ njs_object_assign(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         njs_array_destroy(vm, names);
     }
 
-    vm->retval = *value;
+    njs_value_assign(retval, value);
 
     return NJS_OK;
 
@@ -1820,9 +1812,9 @@ exception:
 
 static njs_int_t
 njs_object_is(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_set_boolean(&vm->retval, njs_values_same(njs_arg(args, nargs, 1),
+    njs_set_boolean(retval, njs_values_same(njs_arg(args, nargs, 1),
                                                  njs_arg(args, nargs, 2)));
 
     return NJS_OK;
@@ -2190,12 +2182,12 @@ njs_property_constructor_set(njs_vm_t *vm, njs_lvlhsh_t *hash,
 
 static njs_int_t
 njs_object_prototype_value_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
-    vm->retval = *njs_argument(args, 0);
+    njs_value_assign(retval, njs_argument(args, 0));
 
-    if (!njs_is_object(&vm->retval)) {
-        return njs_value_to_object(vm, &vm->retval);
+    if (!njs_is_object(retval)) {
+        return njs_value_to_object(vm, retval);
     }
 
     return NJS_OK;
@@ -2228,9 +2220,9 @@ static const njs_value_t  njs_object_arguments_string =
 
 njs_int_t
 njs_object_prototype_to_string(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t unused)
+    njs_uint_t nargs, njs_index_t unused, njs_value_t *retval)
 {
-    return njs_object_to_string(vm, &args[0], &vm->retval);
+    return njs_object_to_string(vm, &args[0], retval);
 }
 
 
@@ -2334,7 +2326,7 @@ njs_object_to_string(njs_vm_t *vm, njs_value_t *this, njs_value_t *retval)
 
 static njs_int_t
 njs_object_prototype_has_own_property(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)
 {
     njs_int_t             ret;
     njs_value_t           *value, *property, lvalue;
@@ -2363,11 +2355,11 @@ njs_object_prototype_has_own_property(njs_vm_t *vm, njs_value_t *args,
 
     switch (ret) {
     case NJS_OK:
-        vm->retval = njs_value_true;
+        njs_set_boolean(retval, 1);
         return NJS_OK;
 
     case NJS_DECLINED:
-        vm->retval = njs_value_false;
+        njs_set_boolean(retval, 0);
         return NJS_OK;
 
     case NJS_ERROR:
@@ -2379,11 +2371,10 @@ njs_object_prototype_has_own_property(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_object_prototype_prop_is_enumerable(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)
 {
     njs_int_t             ret;
     njs_value_t           *value, *property, lvalue;
-    const njs_value_t     *retval;
     njs_object_prop_t     *prop;
     njs_property_query_t  pq;
 
@@ -2411,11 +2402,11 @@ njs_object_prototype_prop_is_enumerable(njs_vm_t *vm, njs_value_t *args,
     switch (ret) {
     case NJS_OK:
         prop = pq.lhq.value;
-        retval = prop->enumerable ? &njs_value_true : &njs_value_false;
+        njs_set_boolean(retval, prop->enumerable);
         break;
 
     case NJS_DECLINED:
-        retval = &njs_value_false;
+        njs_set_boolean(retval, 0);
         break;
 
     case NJS_ERROR:
@@ -2423,26 +2414,22 @@ njs_object_prototype_prop_is_enumerable(njs_vm_t *vm, njs_value_t *args,
         return NJS_ERROR;
     }
 
-    vm->retval = *retval;
-
     return NJS_OK;
 }
 
 
 static njs_int_t
 njs_object_prototype_is_prototype_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)
 {
-    njs_value_t        *prototype, *value;
-    njs_object_t       *object, *proto;
-    const njs_value_t  *retval;
+    njs_value_t   *prototype, *value;
+    njs_object_t  *object, *proto;
 
     if (njs_slow_path(njs_is_null_or_undefined(njs_argument(args, 0)))) {
         njs_type_error(vm, "cannot convert undefined to object");
         return NJS_ERROR;
     }
 
-    retval = &njs_value_false;
     prototype = &args[0];
     value = njs_arg(args, nargs, 1);
 
@@ -2454,14 +2441,14 @@ njs_object_prototype_is_prototype_of(njs_vm_t *vm, njs_value_t *args,
             object = object->__proto__;
 
             if (object == proto) {
-                retval = &njs_value_true;
-                break;
+                njs_set_boolean(retval, 1);
+                return NJS_OK;
             }
 
         } while (object != NULL);
     }
 
-    vm->retval = *retval;
+    njs_set_boolean(retval, 0);
 
     return NJS_OK;
 }
index 35b098c12bffbc62397506c8cdda09e1c9669e54..f71ac82c0d98010f28a014acaf94cf8065734c02 100644 (file)
@@ -91,7 +91,7 @@ njs_value_t *njs_property_constructor_set(njs_vm_t *vm, njs_lvlhsh_t *hash,
 njs_int_t njs_object_to_string(njs_vm_t *vm, njs_value_t *value,
     njs_value_t *retval);
 njs_int_t njs_object_prototype_to_string(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t unused);
+    njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 njs_int_t njs_object_length(njs_vm_t *vm, njs_value_t *value, int64_t *dst);
 
 njs_int_t njs_prop_private_copy(njs_vm_t *vm, njs_property_query_t *pq,
index 005c2eac5fdc8d654628db37293b8a0a3c170d0c..e154f064d50b69499a9883485dd4424c683cd7a4 100644 (file)
@@ -189,6 +189,7 @@ njs_object_prop_define(njs_vm_t *vm, njs_value_t *object,
     uint32_t              length, index;
     njs_int_t             ret;
     njs_array_t           *array;
+    njs_value_t           retval;
     njs_object_prop_t     *prop, *prev;
     njs_property_query_t  pq;
 
@@ -557,7 +558,7 @@ done:
         if (prev->type == NJS_PROPERTY_HANDLER) {
             if (prev->writable) {
                 ret = njs_prop_handler(prev)(vm, prev, object,
-                                             njs_prop_value(prop), &vm->retval);
+                                             njs_prop_value(prop), &retval);
                 if (njs_slow_path(ret == NJS_ERROR)) {
                     return ret;
                 }
index 43ee69b9b2930d452b929a572cc733afacd8204d..a9b8f92499aedcda35c4bb9f2077d5e2aa62abd5 100644 (file)
@@ -553,7 +553,7 @@ njs_parser(njs_vm_t *vm, njs_parser_t *parser)
 
     parser->vm = vm;
 
-    njs_set_undefined(&vm->retval);
+    njs_set_invalid(&vm->exception);
 
     if (parser->scope == NULL) {
         ret = njs_parser_scope_begin(parser,
@@ -605,7 +605,7 @@ njs_parser(njs_vm_t *vm, njs_parser_t *parser)
         return NJS_ERROR;
     }
 
-    if (njs_is_error(&vm->retval)) {
+    if (njs_is_error(&vm->exception)) {
         return NJS_ERROR;
     }
 
@@ -1297,7 +1297,8 @@ njs_parser_regexp_literal(njs_parser_t *parser, njs_lexer_token_t *token,
                                                 text.length, flags);
 
             if (njs_slow_path(pattern == NULL)) {
-                ret = njs_value_property(parser->vm, &parser->vm->retval,
+                retval = njs_vm_exception(parser->vm);
+                ret = njs_value_property(parser->vm, &retval,
                                          njs_value_arg(&string_message),
                                          &retval);
                 if (njs_slow_path(ret != NJS_OK)) {
@@ -1305,7 +1306,6 @@ njs_parser_regexp_literal(njs_parser_t *parser, njs_lexer_token_t *token,
                 }
 
                 njs_string_get(&retval, &text);
-                njs_value_undefined_set(&parser->vm->retval);
 
                 njs_parser_syntax_error(parser, "%V", &text);
 
@@ -2387,7 +2387,7 @@ njs_parser_member_expression(njs_parser_t *parser, njs_lexer_token_t *token,
                 return NJS_OK;
             }
 
-            if (njs_is_error(&parser->vm->retval)) {
+            if (njs_is_error(&parser->vm->exception)) {
                 return NJS_DONE;
             }
 
@@ -9156,7 +9156,7 @@ njs_parser_error(njs_vm_t *vm, njs_object_type_t type, njs_str_t *file,
     u_char       msg[NJS_MAX_ERROR_STR];
     u_char       *p, *end;
     njs_int_t    ret;
-    njs_value_t  value;
+    njs_value_t  value, error;
 
     static const njs_value_t  file_name = njs_string("fileName");
     static const njs_value_t  line_number = njs_string("lineNumber");
@@ -9179,19 +9179,20 @@ njs_parser_error(njs_vm_t *vm, njs_object_type_t type, njs_str_t *file,
         p = njs_sprintf(p, end, " in %uD", line);
     }
 
-    njs_error_new(vm, &vm->retval, type, msg, p - msg);
+    njs_error_new(vm, &error, type, msg, p - msg);
 
     njs_set_number(&value, line);
-    njs_value_property_set(vm, &vm->retval, njs_value_arg(&line_number),
-                           &value);
+    njs_value_property_set(vm, &error, njs_value_arg(&line_number), &value);
 
     if (file->length != 0) {
         ret = njs_string_set(vm, &value, file->start, file->length);
         if (ret == NJS_OK) {
-            njs_value_property_set(vm, &vm->retval, njs_value_arg(&file_name),
+            njs_value_property_set(vm, &error, njs_value_arg(&file_name),
                                    &value);
         }
     }
+
+    njs_vm_throw(vm, &error);
 }
 
 
@@ -9201,7 +9202,7 @@ njs_parser_lexer_error(njs_parser_t *parser, njs_object_type_t type,
 {
     va_list  args;
 
-    if (njs_is_error(&parser->vm->retval)) {
+    if (njs_is_error(&parser->vm->exception)) {
         return;
     }
 
index 91bb7d0f49095d799f941801600550393e99af90..0f31b1d7e824b8a116408f6a720110e7049be123 100644 (file)
@@ -59,40 +59,52 @@ static njs_int_t njs_promise_create_resolving_functions(njs_vm_t *vm,
 static njs_int_t njs_promise_value_constructor(njs_vm_t *vm, njs_value_t *value,
     njs_value_t *dst);
 static njs_int_t njs_promise_capability_executor(njs_vm_t *vm,
-    njs_value_t *args, njs_uint_t nargs, njs_index_t retval);
+    njs_value_t *args, njs_uint_t nargs, njs_index_t unused,
+    njs_value_t *retval);
 static njs_int_t njs_promise_host_rejection_tracker(njs_vm_t *vm,
     njs_promise_t *promise, njs_promise_rejection_type_t operation);
 static njs_int_t njs_promise_resolve_function(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t retval);
+    njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 static njs_int_t njs_promise_reject_function(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t retval);
+    njs_uint_t nargs, njs_index_t unused, njs_value_t *retval);
 static njs_int_t njs_promise_then_finally_function(njs_vm_t *vm,
-    njs_value_t *args, njs_uint_t nargs, njs_index_t unused);
+    njs_value_t *args, njs_uint_t nargs, njs_index_t unused,
+    njs_value_t *retval);
 static njs_int_t njs_promise_then_finally_return(njs_vm_t *vm,
-    njs_value_t *args, njs_uint_t nargs, njs_index_t unused);
+    njs_value_t *args, njs_uint_t nargs, njs_index_t unused,
+    njs_value_t *retval);
 static njs_int_t njs_promise_catch_finally_return(njs_vm_t *vm,
-    njs_value_t *args, njs_uint_t nargs, njs_index_t unused);
+    njs_value_t *args, njs_uint_t nargs, njs_index_t unused,
+    njs_value_t *retval);
 static njs_int_t njs_promise_reaction_job(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_promise_resolve_thenable_job(njs_vm_t *vm,
-    njs_value_t *args, njs_uint_t nargs, njs_index_t unused);
+    njs_value_t *args, njs_uint_t nargs, njs_index_t unused,
+    njs_value_t *retval);
 static njs_int_t njs_promise_perform_all(njs_vm_t *vm, njs_value_t *iterator,
     njs_promise_iterator_args_t *pargs, njs_iterator_handler_t handler,
     njs_value_t *retval);
 static njs_int_t njs_promise_perform_all_handler(njs_vm_t *vm,
-    njs_iterator_args_t *args, njs_value_t *value, int64_t index);
+    njs_iterator_args_t *args, njs_value_t *value, int64_t index,
+    njs_value_t *retval);
 static njs_int_t njs_promise_all_resolve_element_functions(njs_vm_t *vm,
-    njs_value_t *args, njs_uint_t nargs, njs_index_t unused);
+    njs_value_t *args, njs_uint_t nargs, njs_index_t unused,
+    njs_value_t *retval);
 static njs_int_t njs_promise_perform_all_settled_handler(njs_vm_t *vm,
-    njs_iterator_args_t *args, njs_value_t *value, int64_t index);
+    njs_iterator_args_t *args, njs_value_t *value, int64_t index,
+    njs_value_t *retval);
 static njs_int_t njs_promise_all_settled_element_functions(njs_vm_t *vm,
-    njs_value_t *args, njs_uint_t nargs, njs_index_t rejected);
+    njs_value_t *args, njs_uint_t nargs, njs_index_t rejected,
+    njs_value_t *retval);
 static njs_int_t njs_promise_perform_any_handler(njs_vm_t *vm,
-    njs_iterator_args_t *args, njs_value_t *value, int64_t index);
+    njs_iterator_args_t *args, njs_value_t *value, int64_t index,
+    njs_value_t *retval);
 static njs_int_t njs_promise_any_reject_element_functions(njs_vm_t *vm,
-    njs_value_t *args, njs_uint_t nargs, njs_index_t unused);
+    njs_value_t *args, njs_uint_t nargs, njs_index_t unused,
+    njs_value_t *retval);
 static njs_int_t njs_promise_perform_race_handler(njs_vm_t *vm,
-    njs_iterator_args_t *args, njs_value_t *value, int64_t index);
+    njs_iterator_args_t *args, njs_value_t *value, int64_t index,
+    njs_value_t *retval);
 
 
 static const njs_value_t  string_resolve = njs_string("resolve");
@@ -144,7 +156,7 @@ memory_error:
 
 njs_int_t
 njs_promise_constructor(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_promise_t   *promise;
     njs_function_t  *function;
@@ -166,7 +178,7 @@ njs_promise_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    njs_set_promise(&vm->retval, promise);
+    njs_set_promise(retval, promise);
 
     return NJS_OK;
 }
@@ -214,12 +226,14 @@ njs_promise_constructor_call(njs_vm_t *vm, njs_function_t *function)
     ret = njs_function_call(vm, function, &njs_value_undefined, arguments, 2,
                             &retval);
     if (njs_slow_path(ret != NJS_OK)) {
-        if (njs_slow_path(njs_is_memory_error(vm, &vm->retval))) {
+        if (njs_slow_path(njs_is_memory_error(vm, &vm->exception))) {
             return NULL;
         }
 
+        retval = njs_vm_exception(vm);
+
         ret = njs_function_call(vm, njs_function(&arguments[1]),
-                                &njs_value_undefined, &vm->retval, 1, &retval);
+                                &njs_value_undefined, &retval, 1, &retval);
         if (njs_slow_path(ret != NJS_OK)) {
             return NULL;
         }
@@ -403,7 +417,7 @@ njs_promise_value_constructor(njs_vm_t *vm, njs_value_t *value,
 
 static njs_int_t
 njs_promise_capability_executor(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)
 {
     njs_promise_context_t     *context;
     njs_promise_capability_t  *capability;
@@ -429,7 +443,7 @@ njs_promise_capability_executor(njs_vm_t *vm, njs_value_t *args,
     capability->resolve = *njs_arg(args, nargs, 1);
     capability->reject = *njs_arg(args, nargs, 2);
 
-    njs_vm_retval_set(vm, &njs_value_undefined);
+    njs_value_assign(retval, &njs_value_undefined);
 
     return NJS_OK;
 }
@@ -620,7 +634,7 @@ njs_promise_host_rejection_tracker(njs_vm_t *vm, njs_promise_t *promise,
 
 static njs_int_t
 njs_promise_invoke_then(njs_vm_t *vm, njs_value_t *promise, njs_value_t *args,
-    njs_int_t nargs)
+    njs_int_t nargs, njs_value_t *retval)
 {
     njs_int_t    ret;
     njs_value_t  function;
@@ -639,7 +653,7 @@ njs_promise_invoke_then(njs_vm_t *vm, njs_value_t *promise, njs_value_t *args,
 
     if (njs_fast_path(njs_is_function(&function))) {
         return njs_function_call(vm, njs_function(&function), promise, args,
-                                 nargs, &vm->retval);
+                                 nargs, retval);
     }
 
 failed:
@@ -652,7 +666,7 @@ failed:
 
 static njs_int_t
 njs_promise_resolve_function(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_int_t              ret;
     njs_value_t            *resolution, error, then, arguments[3];
@@ -668,7 +682,7 @@ njs_promise_resolve_function(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     promise = njs_promise(&context->promise);
 
     if (*context->resolved_ref) {
-        njs_vm_retval_set(vm, &njs_value_undefined);
+        njs_value_assign(retval, &njs_value_undefined);
         return NJS_OK;
     }
 
@@ -683,7 +697,7 @@ njs_promise_resolve_function(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             return NJS_ERROR;
         }
 
-        njs_vm_retval_set(vm, njs_promise_reject(vm, promise, &error));
+        njs_value_assign(retval, njs_promise_reject(vm, promise, &error));
 
         return NJS_OK;
     }
@@ -695,12 +709,14 @@ njs_promise_resolve_function(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     ret = njs_value_property(vm, resolution, njs_value_arg(&string_then),
                              &then);
     if (njs_slow_path(ret == NJS_ERROR)) {
-        if (njs_slow_path(njs_is_memory_error(vm, &vm->retval))) {
+        if (njs_slow_path(njs_is_memory_error(vm, &vm->exception))) {
             return NJS_ERROR;
         }
 
-        njs_vm_retval_set(vm, njs_promise_reject(vm, promise, &vm->retval));
-        if (njs_slow_path(njs_vm_retval(vm)->type == NJS_NULL)) {
+        error = njs_vm_exception(vm);
+        njs_value_assign(retval, njs_promise_reject(vm, promise, &error));
+
+        if (njs_slow_path(njs_is_null(retval))) {
             return NJS_ERROR;
         }
 
@@ -727,14 +743,14 @@ njs_promise_resolve_function(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return ret;
     }
 
-    njs_vm_retval_set(vm, &njs_value_undefined);
+    njs_value_assign(retval, &njs_value_undefined);
 
     return NJS_OK;
 
 fulfill:
 
-    njs_vm_retval_set(vm, njs_promise_fulfill(vm, promise, resolution));
-    if (njs_slow_path(njs_vm_retval(vm)->type == NJS_NULL)) {
+    njs_value_assign(retval, njs_promise_fulfill(vm, promise, resolution));
+    if (njs_slow_path(njs_is_null(retval))) {
         return NJS_ERROR;
     }
 
@@ -744,7 +760,7 @@ fulfill:
 
 static njs_int_t
 njs_promise_object_resolve(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_promise_t  *promise;
 
@@ -759,7 +775,7 @@ njs_promise_object_resolve(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    njs_set_promise(&vm->retval, promise);
+    njs_set_promise(retval, promise);
 
     return NJS_OK;
 }
@@ -803,7 +819,7 @@ njs_promise_resolve(njs_vm_t *vm, njs_value_t *constructor, njs_value_t *x)
 
 static njs_int_t
 njs_promise_reject_function(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;
     njs_native_frame_t     *active_frame;
@@ -813,7 +829,7 @@ njs_promise_reject_function(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     context = active_frame->function->context;
 
     if (*context->resolved_ref) {
-        njs_vm_retval_set(vm, &njs_value_undefined);
+        njs_value_assign(retval, &njs_value_undefined);
         return NJS_OK;
     }
 
@@ -825,7 +841,7 @@ njs_promise_reject_function(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    njs_vm_retval_set(vm, value);
+    njs_value_assign(retval, value);
 
     return NJS_OK;
 }
@@ -833,7 +849,7 @@ njs_promise_reject_function(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_promise_object_reject(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_int_t                 ret;
     njs_value_t               value;
@@ -856,7 +872,7 @@ njs_promise_object_reject(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return ret;
     }
 
-    njs_vm_retval_set(vm, &capability->promise);
+    njs_value_assign(retval, &capability->promise);
 
     return NJS_OK;
 }
@@ -864,7 +880,7 @@ njs_promise_object_reject(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_promise_prototype_then(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_int_t                 ret;
     njs_value_t               *promise, *fulfilled, *rejected, constructor;
@@ -897,7 +913,7 @@ njs_promise_prototype_then(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     rejected = njs_arg(args, nargs, 2);
 
     return njs_promise_perform_then(vm, promise, fulfilled, rejected,
-                                    capability);
+                                    capability, retval);
 
 failed:
 
@@ -910,7 +926,7 @@ failed:
 njs_int_t
 njs_promise_perform_then(njs_vm_t *vm, njs_value_t *value,
     njs_value_t *fulfilled, njs_value_t *rejected,
-    njs_promise_capability_t *capability)
+    njs_promise_capability_t *capability, njs_value_t *retval)
 {
     njs_int_t               ret;
     njs_value_t             arguments[2];
@@ -987,10 +1003,10 @@ njs_promise_perform_then(njs_vm_t *vm, njs_value_t *value,
     data->is_handled = 1;
 
     if (capability == NULL) {
-        njs_vm_retval_set(vm, &njs_value_undefined);
+        njs_set_undefined(retval);
 
     } else {
-        njs_vm_retval_set(vm, &capability->promise);
+        njs_value_assign(retval, &capability->promise);
     }
 
     return NJS_OK;
@@ -999,20 +1015,21 @@ njs_promise_perform_then(njs_vm_t *vm, njs_value_t *value,
 
 static njs_int_t
 njs_promise_prototype_catch(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  arguments[2];
 
     arguments[0] = njs_value_undefined;
     arguments[1] = *njs_arg(args, nargs, 1);
 
-    return njs_promise_invoke_then(vm, njs_argument(args,  0), arguments, 2);
+    return njs_promise_invoke_then(vm, njs_argument(args,  0), arguments, 2,
+                                   retval);
 }
 
 
 static njs_int_t
 njs_promise_prototype_finally(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_int_t              ret;
     njs_value_t            *promise, *finally, constructor, arguments[2];
@@ -1043,7 +1060,7 @@ njs_promise_prototype_finally(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         arguments[0] = *finally;
         arguments[1] = *finally;
 
-        return njs_promise_invoke_then(vm, promise, arguments, 2);
+        return njs_promise_invoke_then(vm, promise, arguments, 2, retval);
     }
 
     function = njs_promise_create_function(vm, sizeof(njs_promise_context_t));
@@ -1077,16 +1094,16 @@ njs_promise_prototype_finally(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     njs_set_function(&arguments[1], function);
 
-    return njs_promise_invoke_then(vm, promise, arguments, 2);
+    return njs_promise_invoke_then(vm, promise, arguments, 2, retval);
 }
 
 
 static njs_int_t
 njs_promise_then_finally_function(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)
 {
     njs_int_t              ret;
-    njs_value_t            value, retval, argument;
+    njs_value_t            value, argument;
     njs_promise_t          *promise;
     njs_function_t         *function;
     njs_native_frame_t     *frame;
@@ -1096,12 +1113,12 @@ njs_promise_then_finally_function(njs_vm_t *vm, njs_value_t *args,
     context = frame->function->context;
 
     ret = njs_function_call(vm, njs_function(&context->finally),
-                            &njs_value_undefined, args, 0, &retval);
+                            &njs_value_undefined, args, 0, &value);
     if (njs_slow_path(ret != NJS_OK)) {
         return ret;
     }
 
-    promise = njs_promise_resolve(vm, &context->constructor, &retval);
+    promise = njs_promise_resolve(vm, &context->constructor, &value);
     if (njs_slow_path(promise == NULL)) {
         return NJS_ERROR;
     }
@@ -1119,42 +1136,40 @@ njs_promise_then_finally_function(njs_vm_t *vm, njs_value_t *args,
 
     njs_set_function(&argument, function);
 
-    return njs_promise_invoke_then(vm, &value, &argument, 1);
+    return njs_promise_invoke_then(vm, &value, &argument, 1, retval);
 }
 
 
 static njs_int_t
 njs_promise_then_finally_return(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)
 {
-    njs_vm_retval_set(vm, vm->top_frame->function->context);
+    njs_value_assign(retval, vm->top_frame->function->context);
     return NJS_OK;
 }
 
 
 static njs_int_t
 njs_promise_catch_finally_return(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)
 {
-    njs_vm_retval_set(vm, vm->top_frame->function->context);
+    njs_vm_throw(vm, vm->top_frame->function->context);
     return NJS_ERROR;
 }
 
 
 static njs_int_t
 njs_promise_reaction_job(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_int_t                 ret;
     njs_bool_t                is_error;
-    njs_value_t               *value, *argument, retval;
+    njs_value_t               value, *argument;
     njs_promise_reaction_t    *reaction;
     njs_promise_capability_t  *capability;
 
-    value = njs_arg(args, nargs, 1);
+    reaction = njs_data(njs_arg(args, nargs, 1));
     argument = njs_arg(args, nargs, 2);
-
-    reaction = njs_data(value);
     capability = reaction->capability;
 
     is_error = 0;
@@ -1164,33 +1179,34 @@ njs_promise_reaction_job(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             is_error = 1;
         }
 
-        retval = *argument;
+        njs_value_assign(&value, argument);
 
     } else {
         ret = njs_function_call(vm, njs_function(&reaction->handler),
-                                &njs_value_undefined, argument, 1, &retval);
+                                &njs_value_undefined, argument, 1, &value);
         if (njs_slow_path(ret != NJS_OK)) {
-            if (njs_slow_path(njs_is_memory_error(vm, &vm->retval))) {
+            if (njs_slow_path(njs_is_memory_error(vm, &vm->exception))) {
                 return NJS_ERROR;
             }
 
-            retval = vm->retval;
+            value = njs_vm_exception(vm);
+
             is_error = 1;
         }
     }
 
     if (capability == NULL) {
-        njs_vm_retval_set(vm, &retval);
+        njs_value_assign(retval, &value);
         return NJS_OK;
     }
 
     if (is_error) {
         ret = njs_function_call(vm, njs_function(&capability->reject),
-                                &njs_value_undefined, &retval, 1, &vm->retval);
+                                &njs_value_undefined, &value, 1, retval);
 
     } else {
         ret = njs_function_call(vm, njs_function(&capability->resolve),
-                                &njs_value_undefined, &retval, 1, &vm->retval);
+                                &njs_value_undefined, &value, 1, retval);
     }
 
     if (njs_slow_path(ret != NJS_OK)) {
@@ -1203,10 +1219,10 @@ njs_promise_reaction_job(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_promise_resolve_thenable_job(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)
 {
     njs_int_t    ret;
-    njs_value_t  *promise, retval, arguments[2];
+    njs_value_t  *promise, value, arguments[2];
 
     promise = njs_arg(args, nargs, 1);
 
@@ -1217,16 +1233,17 @@ njs_promise_resolve_thenable_job(njs_vm_t *vm, njs_value_t *args,
     }
 
     ret = njs_function_call(vm, njs_function(njs_arg(args, nargs, 3)),
-                            njs_arg(args, nargs, 2), arguments, 2, &retval);
+                            njs_arg(args, nargs, 2), arguments, 2, &value);
     if (njs_slow_path(ret != NJS_OK)) {
 
-        if (njs_slow_path(njs_is_memory_error(vm, &vm->retval))) {
+        if (njs_slow_path(njs_is_memory_error(vm, &vm->exception))) {
             return NJS_ERROR;
         }
 
+        value = njs_vm_exception(vm);
+
         ret = njs_function_call(vm, njs_function(&arguments[1]),
-                                &njs_value_undefined, &vm->retval, 1,
-                                &vm->retval);
+                                &njs_value_undefined, &value, 1, retval);
         if (njs_slow_path(ret != NJS_OK)) {
             return NJS_ERROR;
         }
@@ -1238,7 +1255,7 @@ njs_promise_resolve_thenable_job(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_promise_all(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t function_type)
+    njs_index_t function_type, njs_value_t *retval)
 {
     njs_int_t                    ret;
     njs_value_t                  *promise_ctor, resolve;
@@ -1281,7 +1298,7 @@ njs_promise_all(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     return njs_promise_perform_all(vm, njs_arg(args, nargs, 1), &pargs,
-                                   handler, &vm->retval);
+                                   handler, retval);
 }
 
 
@@ -1323,7 +1340,7 @@ njs_promise_perform_all(njs_vm_t *vm, njs_value_t *iterator,
     pargs->args.value = iterator;
     pargs->args.to = length;
 
-    ret = njs_object_iterate(vm, &pargs->args, handler);
+    ret = njs_object_iterate(vm, &pargs->args, handler, retval);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return ret;
     }
@@ -1350,7 +1367,7 @@ njs_promise_perform_all(njs_vm_t *vm, njs_value_t *iterator,
         }
     }
 
-    *retval = pargs->capability->promise;
+    njs_value_assign(retval, &pargs->capability->promise);
 
     return NJS_OK;
 }
@@ -1358,7 +1375,7 @@ njs_promise_perform_all(njs_vm_t *vm, njs_value_t *iterator,
 
 static njs_int_t
 njs_promise_perform_all_handler(njs_vm_t *vm, njs_iterator_args_t *args,
-    njs_value_t *value, int64_t index)
+    njs_value_t *value, int64_t index, njs_value_t *retval)
 {
     njs_int_t                    ret;
     njs_array_t                  *array;
@@ -1413,7 +1430,7 @@ njs_promise_perform_all_handler(njs_vm_t *vm, njs_iterator_args_t *args,
     njs_set_function(&arguments[0], on_fulfilled);
     arguments[1] = capability->reject;
 
-    ret = njs_promise_invoke_then(vm, &next, arguments, 2);
+    ret = njs_promise_invoke_then(vm, &next, arguments, 2, retval);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return ret;
     }
@@ -1424,7 +1441,7 @@ njs_promise_perform_all_handler(njs_vm_t *vm, njs_iterator_args_t *args,
 
 static njs_int_t
 njs_promise_all_resolve_element_functions(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)
 {
     njs_int_t                  ret;
     njs_value_t                arr_value;
@@ -1433,7 +1450,7 @@ njs_promise_all_resolve_element_functions(njs_vm_t *vm, njs_value_t *args,
     context = vm->top_frame->function->context;
 
     if (context->already_called) {
-        njs_vm_retval_set(vm, &njs_value_undefined);
+        njs_value_assign(retval, &njs_value_undefined);
         return NJS_OK;
     }
 
@@ -1453,10 +1470,10 @@ njs_promise_all_resolve_element_functions(njs_vm_t *vm, njs_value_t *args,
         return njs_function_call(vm,
                                  njs_function(&context->capability->resolve),
                                  &njs_value_undefined, &arr_value, 1,
-                                 &vm->retval);
+                                 retval);
     }
 
-    njs_vm_retval_set(vm, &njs_value_undefined);
+    njs_value_assign(retval, &njs_value_undefined);
 
     return NJS_OK;
 }
@@ -1464,7 +1481,7 @@ njs_promise_all_resolve_element_functions(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_promise_perform_all_settled_handler(njs_vm_t *vm, njs_iterator_args_t *args,
-    njs_value_t *value, int64_t index)
+    njs_value_t *value, int64_t index, njs_value_t *retval)
 {
     njs_int_t                    ret;
     njs_array_t                  *array;
@@ -1530,7 +1547,7 @@ njs_promise_perform_all_settled_handler(njs_vm_t *vm, njs_iterator_args_t *args,
     njs_set_function(&arguments[0], on_fulfilled);
     njs_set_function(&arguments[1], on_rejected);
 
-    ret = njs_promise_invoke_then(vm, &next, arguments, 2);
+    ret = njs_promise_invoke_then(vm, &next, arguments, 2, retval);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return ret;
     }
@@ -1541,7 +1558,8 @@ njs_promise_perform_all_settled_handler(njs_vm_t *vm, njs_iterator_args_t *args,
 
 static njs_int_t
 njs_promise_all_settled_element_functions(njs_vm_t *vm,
-    njs_value_t *args, njs_uint_t nargs, njs_index_t rejected)
+    njs_value_t *args, njs_uint_t nargs, njs_index_t rejected,
+    njs_value_t *retval)
 {
     njs_int_t                  ret;
     njs_value_t                obj_value, arr_value;
@@ -1558,7 +1576,7 @@ njs_promise_all_settled_element_functions(njs_vm_t *vm,
     context = vm->top_frame->function->context;
 
     if (context->already_called) {
-        njs_vm_retval_set(vm, &njs_value_undefined);
+        njs_value_assign(retval, &njs_value_undefined);
         return NJS_OK;
     }
 
@@ -1606,10 +1624,10 @@ njs_promise_all_settled_element_functions(njs_vm_t *vm,
         return njs_function_call(vm,
                                  njs_function(&context->capability->resolve),
                                  &njs_value_undefined, &arr_value, 1,
-                                 &vm->retval);
+                                 retval);
     }
 
-    njs_vm_retval_set(vm, &njs_value_undefined);
+    njs_value_assign(retval, &njs_value_undefined);
 
     return NJS_OK;
 }
@@ -1617,7 +1635,7 @@ njs_promise_all_settled_element_functions(njs_vm_t *vm,
 
 static njs_int_t
 njs_promise_perform_any_handler(njs_vm_t *vm, njs_iterator_args_t *args,
-    njs_value_t *value, int64_t index)
+    njs_value_t *value, int64_t index, njs_value_t *retval)
 {
     njs_int_t                    ret;
     njs_array_t                  *array;
@@ -1672,7 +1690,7 @@ njs_promise_perform_any_handler(njs_vm_t *vm, njs_iterator_args_t *args,
     arguments[0] = capability->resolve;
     njs_set_function(&arguments[1], on_rejected);
 
-    ret = njs_promise_invoke_then(vm, &next, arguments, 2);
+    ret = njs_promise_invoke_then(vm, &next, arguments, 2, retval);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return ret;
     }
@@ -1683,7 +1701,7 @@ njs_promise_perform_any_handler(njs_vm_t *vm, njs_iterator_args_t *args,
 
 static njs_int_t
 njs_promise_any_reject_element_functions(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)
 {
     njs_int_t                  ret;
     njs_value_t                argument, arr_value;
@@ -1693,7 +1711,7 @@ njs_promise_any_reject_element_functions(njs_vm_t *vm, njs_value_t *args,
     context = vm->top_frame->function->context;
 
     if (context->already_called) {
-        njs_vm_retval_set(vm, &njs_value_undefined);
+        njs_value_assign(retval, &njs_value_undefined);
         return NJS_OK;
     }
 
@@ -1720,10 +1738,10 @@ njs_promise_any_reject_element_functions(njs_vm_t *vm, njs_value_t *args,
 
         return njs_function_call(vm, njs_function(&context->capability->reject),
                                  &njs_value_undefined, &argument, 1,
-                                 &vm->retval);
+                                 retval);
     }
 
-    njs_vm_retval_set(vm, &njs_value_undefined);
+    njs_value_assign(retval, &njs_value_undefined);
 
     return NJS_OK;
 }
@@ -1731,7 +1749,7 @@ njs_promise_any_reject_element_functions(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_promise_race(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     int64_t                      length;
     njs_int_t                    ret;
@@ -1770,12 +1788,13 @@ njs_promise_race(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     pargs.args.value = iterator;
     pargs.args.to = length;
 
-    ret = njs_object_iterate(vm, &pargs.args, njs_promise_perform_race_handler);
+    ret = njs_object_iterate(vm, &pargs.args, njs_promise_perform_race_handler,
+                             retval);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return ret;
     }
 
-    vm->retval = pargs.capability->promise;
+    njs_value_assign(retval, &pargs.capability->promise);
 
     return NJS_OK;
 }
@@ -1783,7 +1802,7 @@ njs_promise_race(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_promise_perform_race_handler(njs_vm_t *vm, njs_iterator_args_t *args,
-    njs_value_t *value, int64_t index)
+    njs_value_t *value, int64_t index, njs_value_t *retval)
 {
     njs_int_t                    ret;
     njs_value_t                  arguments[2], next;
@@ -1807,7 +1826,7 @@ njs_promise_perform_race_handler(njs_vm_t *vm, njs_iterator_args_t *args,
     arguments[0] = capability->resolve;
     arguments[1] = capability->reject;
 
-    (void) njs_promise_invoke_then(vm, &next, arguments, 2);
+    (void) njs_promise_invoke_then(vm, &next, arguments, 2, retval);
 
     return NJS_OK;
 }
@@ -1815,9 +1834,9 @@ njs_promise_perform_race_handler(njs_vm_t *vm, njs_iterator_args_t *args,
 
 static njs_int_t
 njs_promise_species(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_vm_retval_set(vm, njs_argument(args, 0));
+    njs_value_assign(retval, njs_argument(args, 0));
 
     return NJS_OK;
 }
index 3d7a70dc2f510527344641b07185d1ec8e77e53b..abf8e1a6e11e7f6e96866dfeeef00008a6a55a44 100644 (file)
@@ -29,13 +29,13 @@ typedef struct {
 
 
 njs_int_t njs_promise_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);
 njs_promise_capability_t *njs_promise_new_capability(njs_vm_t *vm,
     njs_value_t *constructor);
 njs_function_t *njs_promise_create_function(njs_vm_t *vm, size_t context_size);
 njs_int_t njs_promise_perform_then(njs_vm_t *vm, njs_value_t *value,
     njs_value_t *fulfilled, njs_value_t *rejected,
-    njs_promise_capability_t *capability);
+    njs_promise_capability_t *capability, njs_value_t *retval);
 njs_promise_t *njs_promise_resolve(njs_vm_t *vm, njs_value_t *constructor,
     njs_value_t *x);
 
index ec8bd8104084dcca2dcdfcc22c334f3d8616652d..8951c6f6d81185cde5cbd9d6a0dfe0709093aa6a 100644 (file)
@@ -18,7 +18,7 @@ struct njs_regexp_group_s {
 static void *njs_regexp_malloc(size_t size, void *memory_data);
 static void njs_regexp_free(void *p, void *memory_data);
 static njs_int_t njs_regexp_prototype_source(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 int njs_regexp_pattern_compile(njs_vm_t *vm, njs_regex_t *regex,
     u_char *source, size_t len, njs_regex_flags_t flags);
 static u_char *njs_regexp_compile_trace_handler(njs_trace_t *trace,
@@ -107,7 +107,7 @@ njs_regexp_value_flags(njs_vm_t *vm, const njs_value_t *regexp)
 
 static njs_int_t
 njs_regexp_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     u_char              *start;
     njs_int_t           ret;
@@ -118,13 +118,11 @@ njs_regexp_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     pattern = njs_arg(args, nargs, 1);
 
     if (njs_is_regexp(pattern)) {
-        ret = njs_regexp_prototype_source(vm, pattern, 1, 0);
+        ret = njs_regexp_prototype_source(vm, pattern, 1, 0, &source);
         if (njs_slow_path(ret != NJS_OK)) {
             return ret;
         }
 
-        source = vm->retval;
-
         re_flags = njs_regexp_value_flags(vm, pattern);
 
         pattern = &source;
@@ -166,7 +164,7 @@ njs_regexp_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     njs_string_get(pattern, &string);
 
-    return njs_regexp_create(vm, &vm->retval, string.start, string.length,
+    return njs_regexp_create(vm, retval, string.start, string.length,
                              re_flags);
 }
 
@@ -312,6 +310,8 @@ njs_regexp_pattern_create(njs_vm_t *vm, u_char *start, size_t length,
         goto fail;
     }
 
+    njs_set_invalid(&vm->exception);
+
     ret = njs_regexp_pattern_compile(vm, &pattern->regex[1],
                                   &pattern->source[0], text.length,
                                   flags | NJS_REGEX_UTF8);
@@ -364,8 +364,6 @@ njs_regexp_pattern_create(njs_vm_t *vm, u_char *start, size_t length,
         } while (n != pattern->ngroups);
     }
 
-    njs_set_undefined(&vm->retval);
-
     return pattern;
 
 fail:
@@ -496,19 +494,19 @@ njs_regexp_prototype_last_index(njs_vm_t *vm, njs_object_prop_t *unused,
 
     if (setval != NULL) {
         regexp->last_index = *setval;
-        *retval  = *setval;
+        njs_value_assign(retval, setval);
 
         return NJS_OK;
     }
 
-    *retval = regexp->last_index;
+    njs_value_assign(retval, &regexp->last_index);
     return NJS_OK;
 }
 
 
 static njs_int_t
 njs_regexp_prototype_flags(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)
 {
     u_char       *p;
     njs_int_t    ret;
@@ -568,13 +566,13 @@ njs_regexp_prototype_flags(njs_vm_t *vm, njs_value_t *args,
         *p++ = 'y';
     }
 
-    return njs_string_new(vm, &vm->retval, dst, p - dst, p - dst);
+    return njs_string_new(vm, retval, dst, p - dst, p - dst);
 }
 
 
 static njs_int_t
 njs_regexp_prototype_flag(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t flag)
+    njs_uint_t nargs, njs_index_t flag, njs_value_t *retval)
 {
     unsigned              yn;
     njs_value_t           *this;
@@ -588,7 +586,7 @@ njs_regexp_prototype_flag(njs_vm_t *vm, njs_value_t *args,
 
     if (njs_slow_path(!njs_is_regexp(this))) {
         if (njs_object(this) == &vm->prototypes[NJS_OBJ_TYPE_REGEXP].object) {
-            njs_set_undefined(&vm->retval);
+            njs_set_undefined(retval);
             return NJS_OK;
         }
 
@@ -617,7 +615,7 @@ njs_regexp_prototype_flag(njs_vm_t *vm, njs_value_t *args,
         break;
     }
 
-    njs_set_boolean(&vm->retval, yn);
+    njs_set_boolean(retval, yn);
 
     return NJS_OK;
 }
@@ -625,7 +623,7 @@ njs_regexp_prototype_flag(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_regexp_prototype_source(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)
 {
     njs_str_t             src;
     njs_value_t           *this;
@@ -639,7 +637,7 @@ njs_regexp_prototype_source(njs_vm_t *vm, njs_value_t *args,
 
     if (njs_slow_path(!njs_is_regexp(this))) {
         if (njs_object(this) == &vm->prototypes[NJS_OBJ_TYPE_REGEXP].object) {
-            vm->retval = njs_string_empty_regexp;
+            njs_value_assign(retval, &njs_string_empty_regexp);
             return NJS_OK;
         }
 
@@ -652,13 +650,13 @@ njs_regexp_prototype_source(njs_vm_t *vm, njs_value_t *args,
     src.start = pattern->source;
     src.length = njs_strlen(pattern->source);
 
-    return njs_string_decode_utf8(vm, &vm->retval, &src);
+    return njs_string_decode_utf8(vm, retval, &src);
 }
 
 
 static njs_int_t
 njs_regexp_prototype_to_string(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)
 {
     u_char             *p;
     size_t             size, length;
@@ -710,7 +708,7 @@ njs_regexp_prototype_to_string(njs_vm_t *vm, njs_value_t *args,
         length = 0;
     }
 
-    p = njs_string_alloc(vm, &vm->retval, size, length);
+    p = njs_string_alloc(vm, retval, size, length);
     if (njs_slow_path(p == NULL)) {
         return NJS_ERROR;
     }
@@ -789,10 +787,10 @@ njs_regexp_to_string(njs_vm_t *vm, njs_value_t *retval,
 
 static njs_int_t
 njs_regexp_prototype_test(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_int_t    ret;
-    njs_value_t  *r, *string, lvalue, retval;
+    njs_value_t  *r, *string, lvalue, value;
 
     r = njs_argument(args, 0);
 
@@ -808,12 +806,12 @@ njs_regexp_prototype_test(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    ret = njs_regexp_exec(vm, r, string, &retval);
+    ret = njs_regexp_exec(vm, r, string, &value);
     if (njs_slow_path(ret != NJS_OK)) {
         return NJS_ERROR;
     }
 
-    njs_set_boolean(&vm->retval, !njs_is_null(&retval));
+    njs_set_boolean(retval, !njs_is_null(&value));
 
     return NJS_OK;
 }
@@ -1121,7 +1119,7 @@ done:
 
 njs_int_t
 njs_regexp_prototype_exec(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_int_t    ret;
     njs_value_t  *r, *s;
@@ -1141,7 +1139,7 @@ njs_regexp_prototype_exec(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return ret;
     }
 
-    return njs_regexp_builtin_exec(vm, r, s, &vm->retval);
+    return njs_regexp_builtin_exec(vm, r, s, retval);
 }
 
 
@@ -1195,7 +1193,7 @@ njs_regexp_string_create(njs_vm_t *vm, njs_value_t *value, u_char *start,
 
 njs_int_t
 njs_regexp_prototype_symbol_replace(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)
 {
     int64_t            n, last_index, ncaptures, pos, next_pos, length;
     njs_str_t          rep, m;
@@ -1206,7 +1204,7 @@ njs_regexp_prototype_symbol_replace(njs_vm_t *vm, njs_value_t *args,
     njs_bool_t         global;
     njs_array_t        *array;
     njs_value_t        *arguments, *r, *rx, *string, *replace;
-    njs_value_t        s_lvalue, r_lvalue, value, matched, groups, retval;
+    njs_value_t        s_lvalue, r_lvalue, value, matched, groups;
     njs_function_t     *func_replace;
     njs_string_prop_t  s;
 
@@ -1412,7 +1410,7 @@ njs_regexp_prototype_symbol_replace(njs_vm_t *vm, njs_value_t *args,
 
             ret = njs_string_get_substitution(vm, &matched, string, pos,
                                               arguments, ncaptures, &groups,
-                                              replace, &retval);
+                                              replace, retval);
 
         } else {
             ret = njs_array_expand(vm, array, 0,
@@ -1431,14 +1429,14 @@ njs_regexp_prototype_symbol_replace(njs_vm_t *vm, njs_value_t *args,
 
             ret = njs_function_call(vm, func_replace,
                                     njs_value_arg(&njs_value_undefined),
-                                    arguments, n, &retval);
+                                    arguments, n, retval);
         }
 
         if (njs_slow_path(ret == NJS_ERROR)) {
             return NJS_ERROR;
         }
 
-        ret = njs_value_to_string(vm, &retval, &retval);
+        ret = njs_value_to_string(vm, retval, retval);
         if (njs_slow_path(ret != NJS_OK)) {
             goto exception;
         }
@@ -1446,7 +1444,7 @@ njs_regexp_prototype_symbol_replace(njs_vm_t *vm, njs_value_t *args,
         if (pos >= next_pos) {
             njs_chb_append(&chain, &s.start[next_pos], pos - next_pos);
 
-            njs_string_get(&retval, &rep);
+            njs_string_get(retval, &rep);
             njs_chb_append_str(&chain, &rep);
 
             njs_string_get(&matched, &m);
@@ -1459,7 +1457,7 @@ njs_regexp_prototype_symbol_replace(njs_vm_t *vm, njs_value_t *args,
         njs_chb_append(&chain, &s.start[next_pos], s.size - next_pos);
     }
 
-    ret = njs_string_create_chb(vm, &vm->retval, &chain);
+    ret = njs_string_create_chb(vm, retval, &chain);
     if (njs_slow_path(ret != NJS_OK)) {
         ret = NJS_ERROR;
         goto exception;
@@ -1478,7 +1476,7 @@ exception:
 
 static njs_int_t
 njs_regexp_prototype_symbol_split(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)
 {
     u_char             *dst;
     int64_t            e, i, p, q, ncaptures, length;
@@ -1488,7 +1486,7 @@ njs_regexp_prototype_symbol_split(njs_vm_t *vm, njs_value_t *args,
     njs_utf8_t         utf8;
     njs_array_t        *array;
     njs_value_t        *rx, *string, *value;
-    njs_value_t        r, z, this, s_lvalue, retval, setval, constructor;
+    njs_value_t        r, z, this, s_lvalue, setval, constructor;
     njs_object_t       *object;
     const u_char       *start, *end;
     njs_string_prop_t  s;
@@ -1518,17 +1516,17 @@ njs_regexp_prototype_symbol_split(njs_vm_t *vm, njs_value_t *args,
         return ret;
     }
 
-    ret = njs_value_property(vm, rx, njs_value_arg(&string_flags), &retval);
+    ret = njs_value_property(vm, rx, njs_value_arg(&string_flags), retval);
     if (njs_slow_path(ret == NJS_ERROR)) {
         return NJS_ERROR;
     }
 
-    ret = njs_value_to_string(vm, &retval, &retval);
+    ret = njs_value_to_string(vm, retval, retval);
     if (njs_slow_path(ret != NJS_OK)) {
         return ret;
     }
 
-    (void) njs_string_prop(&s, &retval);
+    (void) njs_string_prop(&s, retval);
 
     sticky = memchr(s.start, 'y', s.size) != NULL;
 
@@ -1553,7 +1551,7 @@ njs_regexp_prototype_symbol_split(njs_vm_t *vm, njs_value_t *args,
         *dst++ = 'y';
 
     } else {
-        arguments[1] = retval;
+        njs_value_assign(&arguments[1], retval);
     }
 
     ret = njs_function_call2(vm, njs_function(&constructor), &this,
@@ -1626,12 +1624,12 @@ njs_regexp_prototype_symbol_split(njs_vm_t *vm, njs_value_t *args,
         }
 
         ret = njs_value_property(vm, rx, njs_value_arg(&string_lindex),
-                                 &retval);
+                                 retval);
         if (njs_slow_path(ret == NJS_ERROR)) {
             return NJS_ERROR;
         }
 
-        ret = njs_value_to_length(vm, &retval, &e);
+        ret = njs_value_to_length(vm, retval, &e);
         if (njs_slow_path(ret != NJS_OK)) {
             return NJS_ERROR;
         }
@@ -1718,7 +1716,7 @@ single:
 
 done:
 
-    njs_set_array(&vm->retval, array);
+    njs_set_array(retval, array);
 
     return NJS_OK;
 }
index bd3744a4d871db37aa373abe609de8cbdc9f1ce6..54d543db53e8540c8e09446f7d94de91e25a3fd1 100644 (file)
@@ -20,9 +20,10 @@ njs_regexp_t *njs_regexp_alloc(njs_vm_t *vm, njs_regexp_pattern_t *pattern);
 njs_int_t njs_regexp_exec(njs_vm_t *vm, njs_value_t *r, njs_value_t *s,
     njs_value_t *retval);
 njs_int_t njs_regexp_prototype_exec(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);
 njs_int_t njs_regexp_prototype_symbol_replace(njs_vm_t *vm,
-    njs_value_t *args, njs_uint_t nargs, njs_index_t unused);
+    njs_value_t *args, njs_uint_t nargs, njs_index_t unused,
+    njs_value_t *retval);
 
 njs_int_t njs_regexp_to_string(njs_vm_t *vm, njs_value_t *retval,
     const njs_value_t *regexp);
index 4b4cedf2c9347d1ac0ffc620abf946cd685990bd..ee8d9bf8eeab294dcd890aeb8e6ae2254dff69fb 100644 (file)
@@ -26,7 +26,8 @@
 #endif
 
 
-typedef void (*njs_console_output_pt)(njs_vm_t *vm, njs_int_t ret);
+typedef void (*njs_console_output_pt)(njs_vm_t *vm, njs_value_t *value,
+    njs_int_t ret);
 
 
 typedef struct {
@@ -94,10 +95,11 @@ typedef struct {
 
 
 static njs_int_t njs_console_init(njs_vm_t *vm, njs_console_t *console);
-static void njs_console_output(njs_vm_t *vm, njs_int_t ret);
+static void njs_console_output(njs_vm_t *vm, njs_value_t *value,
+    njs_int_t ret);
 static njs_int_t njs_externals_init(njs_vm_t *vm);
 static njs_vm_t *njs_create_vm(njs_opts_t *opts, njs_vm_opt_t *vm_options);
-static void njs_process_output(njs_vm_t *vm, njs_int_t ret);
+static void njs_process_output(njs_vm_t *vm, njs_value_t *value, njs_int_t ret);
 static njs_int_t njs_process_script(njs_vm_t *vm, void *runtime,
     const njs_str_t *script);
 
@@ -117,11 +119,11 @@ static char *njs_completion_generator(const char *text, int state);
 #endif
 
 static njs_int_t njs_ext_console_log(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t indent);
+    njs_uint_t nargs, njs_index_t indent, njs_value_t *retval);
 static njs_int_t njs_ext_console_time(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_ext_console_time_end(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_host_event_t njs_console_set_timer(njs_external_ptr_t external,
     uint64_t delay, njs_vm_event_t vm_event);
@@ -877,12 +879,12 @@ njs_create_vm(njs_opts_t *opts, njs_vm_opt_t *vm_options)
 
 
 static void
-njs_console_output(njs_vm_t *vm, njs_int_t ret)
+njs_console_output(njs_vm_t *vm, njs_value_t *value, njs_int_t ret)
 {
     njs_str_t  out;
 
     if (ret == NJS_OK) {
-        if (njs_vm_retval_dump(vm, &out, 1) != NJS_OK) {
+        if (njs_vm_value_dump(vm, &out, value, 0, 1) != NJS_OK) {
             njs_stderror("Shell:failed to get retval from VM\n");
             return;
         }
@@ -893,7 +895,7 @@ njs_console_output(njs_vm_t *vm, njs_int_t ret)
         }
 
     } else {
-        njs_vm_retval_string(vm, &out);
+        njs_vm_exception_string(vm, &out);
         njs_stderror("Thrown:\n%V\n", &out);
     }
 }
@@ -939,8 +941,9 @@ njs_process_events(void *runtime)
 static njs_int_t
 njs_process_script(njs_vm_t *vm, void *runtime, const njs_str_t *script)
 {
-    u_char     *start, *end;
-    njs_int_t  ret;
+    u_char       *start, *end;
+    njs_int_t    ret;
+    njs_value_t  retval;
 
     start = script->start;
     end = start + script->length;
@@ -949,7 +952,7 @@ njs_process_script(njs_vm_t *vm, void *runtime, const njs_str_t *script)
 
     if (ret == NJS_OK) {
         if (start == end) {
-            ret = njs_vm_start(vm);
+            ret = njs_vm_start(vm, &retval);
 
         } else {
             njs_vm_error(vm, "Extra characters at the end of the script");
@@ -957,7 +960,7 @@ njs_process_script(njs_vm_t *vm, void *runtime, const njs_str_t *script)
         }
     }
 
-    njs_process_output(vm, ret);
+    njs_process_output(vm, &retval, ret);
 
     if (!vm->options.interactive && ret == NJS_ERROR) {
         return NJS_ERROR;
@@ -987,7 +990,7 @@ njs_process_script(njs_vm_t *vm, void *runtime, const njs_str_t *script)
         ret = njs_vm_run(vm);
 
         if (ret == NJS_ERROR) {
-            njs_process_output(vm, ret);
+            njs_process_output(vm, &retval, ret);
 
             if (!vm->options.interactive) {
                 return NJS_ERROR;
@@ -1000,14 +1003,14 @@ njs_process_script(njs_vm_t *vm, void *runtime, const njs_str_t *script)
 
 
 static void
-njs_process_output(njs_vm_t *vm, njs_int_t ret)
+njs_process_output(njs_vm_t *vm, njs_value_t *value, njs_int_t ret)
 {
     njs_console_output_pt  pt;
 
     pt = (njs_console_output_pt) njs_vm_meta(vm, 0);
 
     if (pt != NULL) {
-        pt(vm, ret);
+        pt(vm, value, ret);
     }
 }
 
@@ -1332,7 +1335,7 @@ next:
 
 static njs_int_t
 njs_ext_console_log(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t indent)
+    njs_index_t indent, njs_value_t *retval)
 {
     njs_str_t   msg;
     njs_uint_t  n;
@@ -1356,7 +1359,7 @@ njs_ext_console_log(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         njs_vm_log(vm, "\n");
     }
 
-    njs_set_undefined(&vm->retval);
+    njs_set_undefined(retval);
 
     return NJS_OK;
 }
@@ -1367,7 +1370,7 @@ static const njs_value_t  njs_default_label = njs_string("default");
 
 static njs_int_t
 njs_ext_console_time(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_int_t           ret;
     njs_str_t           name;
@@ -1433,7 +1436,7 @@ njs_ext_console_time(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     label->time = njs_time();
 
-    njs_set_undefined(&vm->retval);
+    njs_set_undefined(retval);
 
     return NJS_OK;
 }
@@ -1441,7 +1444,7 @@ njs_ext_console_time(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_ext_console_time_end(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     uint64_t            ns, ms;
     njs_int_t           ret;
@@ -1506,7 +1509,7 @@ njs_ext_console_time_end(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         njs_vm_log(vm, "Timer \"%V\" doesn’t exist.\n", &name);
     }
 
-    njs_set_undefined(&vm->retval);
+    njs_set_undefined(retval);
 
     return NJS_OK;
 }
index fb27314296b79610db5a9192859fb7a502045e0d..6104cea6abc7ff3f7e78c0a83843b45dadf26beb 100644 (file)
@@ -65,15 +65,16 @@ static njs_int_t njs_string_slice_prop(njs_vm_t *vm, njs_string_prop_t *string,
 static njs_int_t njs_string_slice_args(njs_vm_t *vm, njs_slice_prop_t *slice,
     njs_value_t *args, njs_uint_t nargs);
 static njs_int_t njs_string_from_char_code(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t is_point);
+    njs_uint_t nargs, njs_index_t is_point, njs_value_t *retval);
 static njs_int_t njs_string_bytes_from(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_string_bytes_from_array_like(njs_vm_t *vm,
-    njs_value_t *value);
+    njs_value_t *value, njs_value_t *retval);
 static njs_int_t njs_string_bytes_from_string(njs_vm_t *vm,
-    const njs_value_t *string, const njs_value_t *encoding);
+    const njs_value_t *string, const njs_value_t *encoding,
+    njs_value_t *retval);
 static njs_int_t njs_string_match_multiple(njs_vm_t *vm, njs_value_t *args,
-    njs_regexp_pattern_t *pattern);
+    njs_regexp_pattern_t *pattern, njs_value_t *retval);
 
 
 #define njs_base64_encoded_length(len)       (((len + 2) / 3) * 4)
@@ -288,14 +289,14 @@ njs_string_truncate(njs_value_t *value, uint32_t size, uint32_t length)
 
 
 njs_int_t
-njs_string_hex(njs_vm_t *vm, njs_value_t *value, const njs_str_t *src)
+njs_string_hex(njs_vm_t *vm, njs_value_t *retval, const njs_str_t *src)
 {
     size_t     length;
     njs_str_t  dst;
 
     length = njs_encode_hex_length(src, &dst.length);
 
-    dst.start = njs_string_alloc(vm, value, dst.length, length);
+    dst.start = njs_string_alloc(vm, retval, dst.length, length);
     if (njs_fast_path(dst.start != NULL)) {
         njs_encode_hex(&dst, src);
         return NJS_OK;
@@ -425,7 +426,7 @@ njs_encode_base64_core(njs_str_t *dst, const njs_str_t *src,
 
 
 njs_int_t
-njs_string_base64(njs_vm_t *vm, njs_value_t *value, const njs_str_t *src)
+njs_string_base64(njs_vm_t *vm, njs_value_t *retval, const njs_str_t *src)
 {
     size_t     length;
     njs_str_t  dst;
@@ -433,11 +434,11 @@ njs_string_base64(njs_vm_t *vm, njs_value_t *value, const njs_str_t *src)
     length = njs_encode_base64_length(src, &dst.length);
 
     if (njs_slow_path(dst.length == 0)) {
-        vm->retval = njs_string_empty;
+        njs_value_assign(retval, &njs_string_empty);
         return NJS_OK;
     }
 
-    dst.start = njs_string_alloc(vm, value, dst.length, length);
+    dst.start = njs_string_alloc(vm, retval, dst.length, length);
     if (njs_slow_path(dst.start == NULL)) {
         return NJS_ERROR;
     }
@@ -449,13 +450,13 @@ njs_string_base64(njs_vm_t *vm, njs_value_t *value, const njs_str_t *src)
 
 
 njs_int_t
-njs_string_base64url(njs_vm_t *vm, njs_value_t *value, const njs_str_t *src)
+njs_string_base64url(njs_vm_t *vm, njs_value_t *retval, const njs_str_t *src)
 {
     size_t     padding;
     njs_str_t  dst;
 
     if (njs_slow_path(src->length == 0)) {
-        vm->retval = njs_string_empty;
+        njs_value_assign(retval, &njs_string_empty);
         return NJS_OK;
     }
 
@@ -468,7 +469,7 @@ njs_string_base64url(njs_vm_t *vm, njs_value_t *value, const njs_str_t *src)
 
     dst.length = njs_base64_encoded_length(src->length) - padding;
 
-    dst.start = njs_string_alloc(vm, value, dst.length, dst.length);
+    dst.start = njs_string_alloc(vm, retval, dst.length, dst.length);
     if (njs_slow_path(dst.start == NULL)) {
         return NJS_ERROR;
     }
@@ -568,7 +569,7 @@ njs_string_validate(njs_vm_t *vm, njs_string_prop_t *string, njs_value_t *value)
 
 static njs_int_t
 njs_string_constructor(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_int_t           ret;
     njs_value_t         *value;
@@ -582,7 +583,7 @@ njs_string_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
         if (njs_slow_path(!njs_is_string(value))) {
             if (!vm->top_frame->ctor && njs_is_symbol(value)) {
-                return njs_symbol_descriptive_string(vm, &vm->retval, value);
+                return njs_symbol_descriptive_string(vm, retval, value);
             }
 
             ret = njs_value_to_string(vm, value, value);
@@ -598,10 +599,10 @@ njs_string_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             return NJS_ERROR;
         }
 
-        njs_set_object_value(&vm->retval, object);
+        njs_set_object_value(retval, object);
 
     } else {
-        vm->retval = *value;
+        njs_value_assign(retval, value);
     }
 
     return NJS_OK;
@@ -769,7 +770,7 @@ njs_string_cmp(const njs_value_t *v1, const njs_value_t *v2)
 
 static njs_int_t
 njs_string_prototype_value_of(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;
 
@@ -787,7 +788,7 @@ njs_string_prototype_value_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         }
     }
 
-    vm->retval = *value;
+    njs_value_assign(retval, value);
 
     return NJS_OK;
 }
@@ -802,14 +803,14 @@ njs_string_prototype_value_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_string_prototype_to_string(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)
 {
     njs_int_t          ret;
     njs_str_t          enc, str;
     njs_value_t        value;
     njs_string_prop_t  string;
 
-    ret = njs_string_prototype_value_of(vm, args, nargs, unused);
+    ret = njs_string_prototype_value_of(vm, args, nargs, unused, retval);
     if (njs_slow_path(ret != NJS_OK)) {
         return ret;
     }
@@ -823,7 +824,7 @@ njs_string_prototype_to_string(njs_vm_t *vm, njs_value_t *args,
         return NJS_ERROR;
     }
 
-    value = vm->retval;
+    njs_value_assign(&value, retval);
 
     (void) njs_string_prop(&string, &value);
 
@@ -833,13 +834,13 @@ njs_string_prototype_to_string(njs_vm_t *vm, njs_value_t *args,
     str.start = string.start;
 
     if (enc.length == 3 && memcmp(enc.start, "hex", 3) == 0) {
-        return njs_string_hex(vm, &vm->retval, &str);
+        return njs_string_hex(vm, retval, &str);
 
     } else if (enc.length == 6 && memcmp(enc.start, "base64", 6) == 0) {
-        return njs_string_base64(vm, &vm->retval, &str);
+        return njs_string_base64(vm, retval, &str);
 
     } else if (enc.length == 9 && memcmp(enc.start, "base64url", 9) == 0) {
-        return njs_string_base64url(vm, &vm->retval, &str);
+        return njs_string_base64url(vm, retval, &str);
     }
 
     njs_type_error(vm, "Unknown encoding: \"%V\"", &enc);
@@ -850,7 +851,7 @@ njs_string_prototype_to_string(njs_vm_t *vm, njs_value_t *args,
 
 njs_int_t
 njs_string_prototype_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     u_char             *p, *start;
     uint64_t           size, length, mask;
@@ -873,7 +874,7 @@ njs_string_prototype_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     if (nargs == 1) {
-        njs_string_copy(&vm->retval, &args[0]);
+        njs_string_copy(retval, &args[0]);
         return NJS_OK;
     }
 
@@ -894,7 +895,7 @@ njs_string_prototype_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     length &= mask;
 
-    start = njs_string_alloc(vm, &vm->retval, size, length);
+    start = njs_string_alloc(vm, retval, size, length);
     if (njs_slow_path(start == NULL)) {
         return NJS_ERROR;
     }
@@ -940,7 +941,7 @@ njs_string_object_validate(njs_vm_t *vm, njs_value_t *object)
 
 static njs_int_t
 njs_string_prototype_from_utf8(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)
 {
     ssize_t            length;
     njs_int_t          ret;
@@ -961,7 +962,7 @@ njs_string_prototype_from_utf8(njs_vm_t *vm, njs_value_t *args,
 
     if (string.length != 0) {
         /* ASCII or UTF8 string. */
-        return njs_string_slice(vm, &vm->retval, &string, &slice);
+        return njs_string_slice(vm, retval, &string, &slice);
     }
 
     string.start += slice.start;
@@ -969,11 +970,11 @@ njs_string_prototype_from_utf8(njs_vm_t *vm, njs_value_t *args,
     length = njs_utf8_length(string.start, slice.length);
 
     if (length >= 0) {
-        return njs_string_new(vm, &vm->retval, string.start, slice.length,
+        return njs_string_new(vm, retval, string.start, slice.length,
                               length);
     }
 
-    vm->retval = njs_value_null;
+    njs_set_null(retval);
 
     return NJS_OK;
 }
@@ -986,7 +987,7 @@ njs_string_prototype_from_utf8(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_string_prototype_to_utf8(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     njs_int_t          ret;
     njs_slice_prop_t   slice;
@@ -1009,7 +1010,7 @@ njs_string_prototype_to_utf8(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return ret;
     }
 
-    return njs_string_slice(vm, &vm->retval, &string, &slice);
+    return njs_string_slice(vm, retval, &string, &slice);
 }
 
 
@@ -1020,7 +1021,7 @@ njs_string_prototype_to_utf8(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_string_prototype_from_bytes(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)
 {
     u_char             *p, *s, *start, *end;
     size_t             size;
@@ -1042,7 +1043,7 @@ njs_string_prototype_from_bytes(njs_vm_t *vm, njs_value_t *args,
 
     if (string.length != 0) {
         /* ASCII or UTF8 string. */
-        return njs_string_slice(vm, &vm->retval, &string, &slice);
+        return njs_string_slice(vm, retval, &string, &slice);
     }
 
     size = 0;
@@ -1053,7 +1054,7 @@ njs_string_prototype_from_bytes(njs_vm_t *vm, njs_value_t *args,
         size += (*p < 0x80) ? 1 : 2;
     }
 
-    start = njs_string_alloc(vm, &vm->retval, size, slice.length);
+    start = njs_string_alloc(vm, retval, size, slice.length);
 
     if (njs_fast_path(start != NULL)) {
 
@@ -1085,7 +1086,7 @@ njs_string_prototype_from_bytes(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_string_prototype_to_bytes(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     u_char                *p;
     size_t                length;
@@ -1110,10 +1111,10 @@ njs_string_prototype_to_bytes(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     if (string.length == 0) {
         /* Byte string. */
-        return njs_string_slice(vm, &vm->retval, &string, &slice);
+        return njs_string_slice(vm, retval, &string, &slice);
     }
 
-    p = njs_string_alloc(vm, &vm->retval, slice.length, 0);
+    p = njs_string_alloc(vm, retval, slice.length, 0);
 
     if (njs_fast_path(p != NULL)) {
 
@@ -1131,8 +1132,8 @@ njs_string_prototype_to_bytes(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
                 byte = njs_utf8_decode(&ctx, &s, end);
 
                 if (njs_slow_path(byte > 0xFF)) {
-                    njs_release(vm, &vm->retval);
-                    vm->retval = njs_value_null;
+                    njs_release(vm, retval);
+                    njs_set_null(retval);
 
                     return NJS_OK;
                 }
@@ -1155,7 +1156,7 @@ njs_string_prototype_to_bytes(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_string_prototype_slice(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     njs_int_t          ret;
     njs_slice_prop_t   slice;
@@ -1171,13 +1172,13 @@ njs_string_prototype_slice(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return ret;
     }
 
-    return njs_string_slice(vm, &vm->retval, &string, &slice);
+    return njs_string_slice(vm, retval, &string, &slice);
 }
 
 
 static njs_int_t
 njs_string_prototype_substring(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)
 {
     int64_t            start, end, length;
     njs_int_t          ret;
@@ -1249,13 +1250,13 @@ njs_string_prototype_substring(njs_vm_t *vm, njs_value_t *args,
     slice.start = start;
     slice.length = length;
 
-    return njs_string_slice(vm, &vm->retval, &string, &slice);
+    return njs_string_slice(vm, retval, &string, &slice);
 }
 
 
 static njs_int_t
 njs_string_prototype_substr(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     int64_t            start, length, n;
     njs_int_t          ret;
@@ -1327,13 +1328,13 @@ njs_string_prototype_substr(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     slice.start = start;
     slice.length = length;
 
-    return njs_string_slice(vm, &vm->retval, &string, &slice);
+    return njs_string_slice(vm, retval, &string, &slice);
 }
 
 
 static njs_int_t
 njs_string_prototype_char_at(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     size_t             length;
     int64_t            start;
@@ -1363,7 +1364,7 @@ njs_string_prototype_char_at(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     slice.start = start;
     slice.length = length;
 
-    return njs_string_slice(vm, &vm->retval, &string, &slice);
+    return njs_string_slice(vm, retval, &string, &slice);
 }
 
 
@@ -1505,7 +1506,7 @@ njs_string_slice_string_prop(njs_string_prop_t *dst,
 
 
 njs_int_t
-njs_string_slice(njs_vm_t *vm, njs_value_t *dst,
+njs_string_slice(njs_vm_t *vm, njs_value_t *retval,
     const njs_string_prop_t *string, const njs_slice_prop_t *slice)
 {
     njs_string_prop_t  prop;
@@ -1513,10 +1514,10 @@ njs_string_slice(njs_vm_t *vm, njs_value_t *dst,
     njs_string_slice_string_prop(&prop, string, slice);
 
     if (njs_fast_path(prop.size != 0)) {
-        return njs_string_new(vm, dst, prop.start, prop.size, prop.length);
+        return njs_string_new(vm, retval, prop.start, prop.size, prop.length);
     }
 
-    *dst = njs_string_empty;
+    njs_value_assign(retval, &njs_string_empty);
 
     return NJS_OK;
 }
@@ -1524,7 +1525,7 @@ njs_string_slice(njs_vm_t *vm, njs_value_t *dst,
 
 static njs_int_t
 njs_string_prototype_char_code_at(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)
 {
     double                num;
     size_t                length;
@@ -1568,7 +1569,7 @@ njs_string_prototype_char_code_at(njs_vm_t *vm, njs_value_t *args,
 
 done:
 
-    njs_set_number(&vm->retval, num);
+    njs_set_number(retval, num);
 
     return NJS_OK;
 }
@@ -1585,7 +1586,7 @@ done:
 
 static njs_int_t
 njs_string_bytes_from(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;
 
@@ -1594,17 +1595,19 @@ njs_string_bytes_from(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     value = njs_arg(args, nargs, 1);
 
     if (njs_is_string(value)) {
-        return njs_string_bytes_from_string(vm, value, njs_arg(args, nargs, 2));
+        return njs_string_bytes_from_string(vm, value, njs_arg(args, nargs, 2),
+                                            retval);
 
     } else if (njs_is_object(value)) {
 
         if (njs_is_object_string(value)) {
             value = njs_object_value(value);
             return njs_string_bytes_from_string(vm, value,
-                                                njs_arg(args, nargs, 2));
+                                                njs_arg(args, nargs, 2),
+                                                retval);
         }
 
-        return njs_string_bytes_from_array_like(vm, value);
+        return njs_string_bytes_from_array_like(vm, value, retval);
     }
 
     njs_type_error(vm, "value must be a string or array-like object");
@@ -1614,7 +1617,8 @@ njs_string_bytes_from(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 
 static njs_int_t
-njs_string_bytes_from_array_like(njs_vm_t *vm, njs_value_t *value)
+njs_string_bytes_from_array_like(njs_vm_t *vm, njs_value_t *value,
+    njs_value_t *retval)
 {
     u_char              *p;
     int64_t             length;
@@ -1653,7 +1657,7 @@ njs_string_bytes_from_array_like(njs_vm_t *vm, njs_value_t *value)
         }
     }
 
-    p = njs_string_alloc(vm, &vm->retval, length, 0);
+    p = njs_string_alloc(vm, retval, length, 0);
     if (njs_slow_path(p == NULL)) {
         return NJS_ERROR;
     }
@@ -1702,7 +1706,7 @@ njs_string_bytes_from_array_like(njs_vm_t *vm, njs_value_t *value)
 
 static njs_int_t
 njs_string_bytes_from_string(njs_vm_t *vm, const njs_value_t *string,
-    const njs_value_t *encoding)
+    const njs_value_t *encoding, njs_value_t *retval)
 {
     njs_str_t  enc, str;
 
@@ -1715,13 +1719,13 @@ njs_string_bytes_from_string(njs_vm_t *vm, const njs_value_t *string,
     njs_string_get(string, &str);
 
     if (enc.length == 3 && memcmp(enc.start, "hex", 3) == 0) {
-        return njs_string_decode_hex(vm, &vm->retval, &str);
+        return njs_string_decode_hex(vm, retval, &str);
 
     } else if (enc.length == 6 && memcmp(enc.start, "base64", 6) == 0) {
-        return njs_string_decode_base64(vm, &vm->retval, &str);
+        return njs_string_decode_base64(vm, retval, &str);
 
     } else if (enc.length == 9 && memcmp(enc.start, "base64url", 9) == 0) {
-        return njs_string_decode_base64url(vm, &vm->retval, &str);
+        return njs_string_decode_base64url(vm, retval, &str);
     }
 
     njs_type_error(vm, "Unknown encoding: \"%V\"", &enc);
@@ -1817,7 +1821,7 @@ njs_string_decode_utf8(njs_vm_t *vm, njs_value_t *value, const njs_str_t *src)
 
 
 njs_int_t
-njs_string_decode_hex(njs_vm_t *vm, njs_value_t *value, const njs_str_t *src)
+njs_string_decode_hex(njs_vm_t *vm, njs_value_t *retval, const njs_str_t *src)
 {
     size_t     size, length;
     njs_str_t  dst;
@@ -1825,11 +1829,11 @@ njs_string_decode_hex(njs_vm_t *vm, njs_value_t *value, const njs_str_t *src)
     length = njs_decode_hex_length(src, &size);
 
     if (njs_slow_path(size == 0)) {
-        vm->retval = njs_string_empty;
+        njs_value_assign(retval, &njs_string_empty);
         return NJS_OK;
     }
 
-    dst.start = njs_string_alloc(vm, value, size, length);
+    dst.start = njs_string_alloc(vm, retval, size, length);
     if (njs_slow_path(dst.start == NULL)) {
         return NJS_ERROR;
     }
@@ -1839,7 +1843,7 @@ njs_string_decode_hex(njs_vm_t *vm, njs_value_t *value, const njs_str_t *src)
     njs_decode_hex(&dst, src);
 
     if (njs_slow_path(dst.length != size)) {
-        njs_string_truncate(value, dst.length, 0);
+        njs_string_truncate(retval, dst.length, 0);
     }
 
     return NJS_OK;
@@ -1936,7 +1940,7 @@ njs_decode_base64url(njs_str_t *dst, const njs_str_t *src)
 
 
 static njs_int_t
-njs_string_decode_base64_core(njs_vm_t *vm, njs_value_t *value,
+njs_string_decode_base64_core(njs_vm_t *vm, njs_value_t *retval,
     const njs_str_t *src, njs_bool_t url)
 {
     size_t     length;
@@ -1948,11 +1952,11 @@ njs_string_decode_base64_core(njs_vm_t *vm, njs_value_t *value,
     length = njs_decode_base64_length_core(src, basis, &dst.length);
 
     if (njs_slow_path(dst.length == 0)) {
-        vm->retval = njs_string_empty;
+        njs_value_assign(retval, &njs_string_empty);
         return NJS_OK;
     }
 
-    dst.start = njs_string_alloc(vm, value, dst.length, length);
+    dst.start = njs_string_alloc(vm, retval, dst.length, length);
     if (njs_slow_path(dst.start == NULL)) {
         return NJS_ERROR;
     }
@@ -1980,7 +1984,7 @@ njs_string_decode_base64url(njs_vm_t *vm, njs_value_t *value,
 
 static njs_int_t
 njs_string_from_char_code(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t is_point)
+    njs_index_t is_point, njs_value_t *retval)
 {
     double                num;
     u_char                *p, *start, *end;
@@ -2048,7 +2052,7 @@ njs_string_from_char_code(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         length++;
     }
 
-    p = njs_string_alloc(vm, &vm->retval, size, length);
+    p = njs_string_alloc(vm, retval, size, length);
     if (njs_slow_path(p == NULL)) {
         return NJS_ERROR;
     }
@@ -2145,7 +2149,7 @@ njs_string_index_of(njs_string_prop_t *string, njs_string_prop_t *search,
 
 static njs_int_t
 njs_string_prototype_index_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     int64_t            from, length;
     njs_int_t          ret;
@@ -2182,7 +2186,7 @@ njs_string_prototype_index_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     from = njs_min(njs_max(from, 0), length);
 
-    njs_set_number(&vm->retval, njs_string_index_of(&string, &s, from));
+    njs_set_number(retval, njs_string_index_of(&string, &s, from));
 
     return NJS_OK;
 }
@@ -2190,7 +2194,7 @@ njs_string_prototype_index_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_string_prototype_last_index_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)
 {
     double             pos;
     int64_t            index, start, length, search_length;
@@ -2285,7 +2289,7 @@ njs_string_prototype_last_index_of(njs_vm_t *vm, njs_value_t *args,
 
 done:
 
-    njs_set_number(&vm->retval, index);
+    njs_set_number(retval, index);
 
     return NJS_OK;
 }
@@ -2293,13 +2297,12 @@ done:
 
 static njs_int_t
 njs_string_prototype_includes(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     int64_t            index, length, search_length;
     njs_int_t          ret;
     njs_value_t        *value;
     const u_char       *p, *end;
-    const njs_value_t  *retval;
     njs_string_prop_t  string, search;
 
     ret = njs_string_object_validate(vm, njs_argument(args, 0));
@@ -2307,7 +2310,7 @@ njs_string_prototype_includes(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return ret;
     }
 
-    retval = &njs_value_true;
+    njs_set_boolean(retval, 1);
 
     if (nargs > 1) {
         value = njs_argument(args, 1);
@@ -2343,7 +2346,7 @@ njs_string_prototype_includes(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         }
 
         if (search_length == 0) {
-            goto done;
+            return NJS_OK;
         }
 
         length = njs_string_prop(&string, &args[0]);
@@ -2356,7 +2359,7 @@ njs_string_prototype_includes(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
             while (p < end) {
                 if (memcmp(p, search.start, search.size) == 0) {
-                    goto done;
+                    return NJS_OK;
                 }
 
                 p++;
@@ -2364,11 +2367,7 @@ njs_string_prototype_includes(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         }
     }
 
-    retval = &njs_value_false;
-
-done:
-
-    vm->retval = *retval;
+    njs_set_boolean(retval, 0);
 
     return NJS_OK;
 }
@@ -2376,16 +2375,16 @@ done:
 
 static njs_int_t
 njs_string_prototype_starts_or_ends_with(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t starts)
+    njs_uint_t nargs, njs_index_t starts, njs_value_t *retval)
 {
     int64_t            index, length, search_length;
     njs_int_t          ret;
+    njs_bool_t         yn;
     njs_value_t        *value, lvalue;
     const u_char       *p, *end;
-    const njs_value_t  *retval;
     njs_string_prop_t  string, search;
 
-    retval = &njs_value_true;
+    yn = 1;
 
     ret = njs_string_object_validate(vm, njs_argument(args, 0));
     if (njs_slow_path(ret != NJS_OK)) {
@@ -2459,11 +2458,11 @@ njs_string_prototype_starts_or_ends_with(njs_vm_t *vm, njs_value_t *args,
 
 small:
 
-    retval = &njs_value_false;
+    yn = 0;
 
 done:
 
-    vm->retval = *retval;
+    njs_set_boolean(retval, yn);
 
     return NJS_OK;
 }
@@ -2580,7 +2579,7 @@ njs_string_utf8_offset_map_init(const u_char *start, size_t size)
 
 static njs_int_t
 njs_string_prototype_to_lower_case(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)
 {
     size_t             size, length;
     u_char             *p;
@@ -2598,7 +2597,7 @@ njs_string_prototype_to_lower_case(njs_vm_t *vm, njs_value_t *args,
 
     if (njs_is_byte_or_ascii_string(&string)) {
 
-        p = njs_string_alloc(vm, &vm->retval, string.size, string.length);
+        p = njs_string_alloc(vm, retval, string.size, string.length);
         if (njs_slow_path(p == NULL)) {
             return NJS_ERROR;
         }
@@ -2625,7 +2624,7 @@ njs_string_prototype_to_lower_case(njs_vm_t *vm, njs_value_t *args,
             length--;
         }
 
-        p = njs_string_alloc(vm, &vm->retval, size, string.length);
+        p = njs_string_alloc(vm, retval, size, string.length);
         if (njs_slow_path(p == NULL)) {
             return NJS_ERROR;
         }
@@ -2651,7 +2650,7 @@ njs_string_prototype_to_lower_case(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_string_prototype_to_upper_case(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)
 {
     size_t             size, length;
     u_char             *p;
@@ -2669,7 +2668,7 @@ njs_string_prototype_to_upper_case(njs_vm_t *vm, njs_value_t *args,
 
     if (njs_is_byte_or_ascii_string(&string)) {
 
-        p = njs_string_alloc(vm, &vm->retval, string.size, string.length);
+        p = njs_string_alloc(vm, retval, string.size, string.length);
         if (njs_slow_path(p == NULL)) {
             return NJS_ERROR;
         }
@@ -2696,7 +2695,7 @@ njs_string_prototype_to_upper_case(njs_vm_t *vm, njs_value_t *args,
             length--;
         }
 
-        p = njs_string_alloc(vm, &vm->retval, size, string.length);
+        p = njs_string_alloc(vm, retval, size, string.length);
         if (njs_slow_path(p == NULL)) {
             return NJS_ERROR;
         }
@@ -2835,7 +2834,7 @@ njs_string_trim(const njs_value_t *value, njs_string_prop_t *string,
 
 static njs_int_t
 njs_string_prototype_trim(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t mode)
+    njs_index_t mode, njs_value_t *retval)
 {
     uint32_t           trim;
     njs_int_t          ret;
@@ -2851,23 +2850,23 @@ njs_string_prototype_trim(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     trim = njs_string_trim(value, &string, mode);
 
     if (trim == 0) {
-        njs_value_assign(&vm->retval, value);
+        njs_value_assign(retval, value);
         return NJS_OK;
     }
 
     if (string.size == 0) {
-        njs_value_assign(&vm->retval, &njs_string_empty);
+        njs_value_assign(retval, &njs_string_empty);
         return NJS_OK;
     }
 
-    return njs_string_new(vm, &vm->retval, string.start, string.size,
+    return njs_string_new(vm, retval, string.start, string.size,
                           string.length);
 }
 
 
 static njs_int_t
 njs_string_prototype_repeat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     u_char             *p;
     int64_t            n, max;
@@ -2902,7 +2901,7 @@ njs_string_prototype_repeat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     (void) njs_string_prop(&string, this);
 
     if (njs_slow_path(n == 0 || string.size == 0)) {
-        vm->retval = njs_string_empty;
+        njs_value_assign(retval, &njs_string_empty);
         return NJS_OK;
     }
 
@@ -2916,7 +2915,7 @@ njs_string_prototype_repeat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     size = string.size * n;
     length = string.length * n;
 
-    p = njs_string_alloc(vm, &vm->retval, size, length);
+    p = njs_string_alloc(vm, retval, size, length);
     if (njs_slow_path(p == NULL)) {
         return NJS_ERROR;
     }
@@ -2933,7 +2932,7 @@ njs_string_prototype_repeat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_string_prototype_pad(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t pad_start)
+    njs_index_t pad_start, njs_value_t *retval)
 {
     u_char             *p, *start;
     size_t             padding, trunc, new_size;
@@ -2970,7 +2969,7 @@ njs_string_prototype_pad(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     if (new_length <= length) {
-        vm->retval = args[0];
+        njs_value_assign(retval, njs_argument(args, 0));
         return NJS_OK;
     }
 
@@ -3002,7 +3001,7 @@ njs_string_prototype_pad(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     pad_length = njs_string_prop(&pad_string, pad);
 
     if (pad_string.size == 0) {
-        vm->retval = args[0];
+        njs_value_assign(retval, njs_argument(args, 0));
         return NJS_OK;
     }
 
@@ -3022,7 +3021,7 @@ njs_string_prototype_pad(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     new_size = string.size + padding;
 
-    start = njs_string_alloc(vm, &vm->retval, new_size, new_length);
+    start = njs_string_alloc(vm, retval, new_size, new_length);
     if (njs_slow_path(start == NULL)) {
         return NJS_ERROR;
     }
@@ -3057,7 +3056,7 @@ njs_string_prototype_pad(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_string_prototype_search(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     size_t                c;
     njs_int_t             ret, index;
@@ -3129,7 +3128,7 @@ njs_string_prototype_search(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 done:
 
-    njs_set_number(&vm->retval, index);
+    njs_set_number(retval, index);
 
     return NJS_OK;
 }
@@ -3137,7 +3136,7 @@ done:
 
 static njs_int_t
 njs_string_prototype_match(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             string;
     njs_int_t             ret;
@@ -3160,7 +3159,7 @@ njs_string_prototype_match(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             pattern = njs_regexp_pattern(&args[1]);
 
             if (pattern->global) {
-                return njs_string_match_multiple(vm, args, pattern);
+                return njs_string_match_multiple(vm, args, pattern, retval);
             }
 
             /*
@@ -3196,13 +3195,13 @@ njs_string_prototype_match(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 match:
 
-    return njs_regexp_prototype_exec(vm, arguments, nargs, unused);
+    return njs_regexp_prototype_exec(vm, arguments, nargs, unused, retval);
 }
 
 
 static njs_int_t
 njs_string_match_multiple(njs_vm_t *vm, njs_value_t *args,
-    njs_regexp_pattern_t *pattern)
+    njs_regexp_pattern_t *pattern, njs_value_t *retval)
 {
     size_t             c0, c1;
     int32_t            size, length;
@@ -3214,7 +3213,7 @@ njs_string_match_multiple(njs_vm_t *vm, njs_value_t *args,
     njs_string_prop_t  string;
 
     njs_set_number(&args[1].data.u.regexp->last_index, 0);
-    vm->retval = njs_value_null;
+    njs_set_null(retval);
 
     (void) njs_string_prop(&string, &args[0]);
 
@@ -3294,7 +3293,7 @@ njs_string_match_multiple(njs_vm_t *vm, njs_value_t *args,
 
         } while (p <= end);
 
-        njs_set_array(&vm->retval, array);
+        njs_set_array(retval, array);
     }
 
     return NJS_OK;
@@ -3303,7 +3302,7 @@ njs_string_match_multiple(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_string_prototype_split(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     size_t             size;
     uint32_t           limit;
@@ -3343,7 +3342,7 @@ njs_string_prototype_split(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             arguments[1] = *value;
 
             return njs_function_call(vm, njs_function(&splitter), separator,
-                                     arguments, 2, &vm->retval);
+                                     arguments, 2, retval);
         }
     }
 
@@ -3453,7 +3452,7 @@ single:
 
 done:
 
-    njs_set_array(&vm->retval, array);
+    njs_set_array(retval, array);
 
     return NJS_OK;
 }
@@ -3629,7 +3628,7 @@ exception:
 
 static njs_int_t
 njs_string_prototype_replace(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t replaceAll)
+    njs_index_t replaceAll, njs_value_t *retval)
 {
     u_char             *r;
     size_t             length, size, increment, end_of_last_match;
@@ -3639,7 +3638,7 @@ njs_string_prototype_replace(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_chb_t          chain;
     njs_bool_t         is_byte_or_ascii_string;
     njs_value_t        *this, *search, *replace;
-    njs_value_t        search_lvalue, replace_lvalue, replacer, retval,
+    njs_value_t        search_lvalue, replace_lvalue, replacer, value,
                        arguments[3];
     const u_char       *p, *p_start;
     njs_function_t     *func_replace;
@@ -3676,17 +3675,17 @@ njs_string_prototype_replace(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
                 njs_regexp_prototype_symbol_replace)
             {
                 ret = njs_value_property(vm, search,
-                                         njs_value_arg(&string_flags), &retval);
+                                         njs_value_arg(&string_flags), &value);
                 if (njs_slow_path(ret == NJS_ERROR)) {
                     return NJS_ERROR;
                 }
 
-                ret = njs_value_to_string(vm, &retval, &retval);
+                ret = njs_value_to_string(vm, &value, &value);
                 if (njs_slow_path(ret != NJS_OK)) {
                     return NJS_ERROR;
                 }
 
-                njs_string_get(&retval, &str);
+                njs_string_get(&value, &str);
 
                 if (njs_strlchr(str.start, str.start + str.length, 'g')
                     == NULL)
@@ -3699,7 +3698,7 @@ njs_string_prototype_replace(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             }
 
             return njs_function_call(vm, njs_function(&replacer), search,
-                                     arguments, 2, &vm->retval);
+                                     arguments, 2, retval);
         }
     }
 
@@ -3731,7 +3730,7 @@ njs_string_prototype_replace(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     pos = njs_string_index_of(&string, &s, 0);
     if (pos < 0) {
-        njs_value_assign(&vm->retval, this);
+        njs_value_assign(retval, this);
         return NJS_OK;
     }
 
@@ -3739,7 +3738,7 @@ njs_string_prototype_replace(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
         if (func_replace == NULL) {
             ret = njs_string_get_substitution(vm, search, this, pos, NULL, 0,
-                                              NULL, replace, &retval);
+                                              NULL, replace, &value);
             if (njs_slow_path(ret != NJS_OK)) {
                 return ret;
             }
@@ -3749,13 +3748,13 @@ njs_string_prototype_replace(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
             ret = njs_function_call(vm, func_replace,
                                     njs_value_arg(&njs_value_undefined),
-                                    arguments, 3, &retval);
+                                    arguments, 3, &value);
 
             if (njs_slow_path(ret != NJS_OK)) {
                 return ret;
             }
 
-            ret = njs_value_to_string(vm, &retval, &retval);
+            ret = njs_value_to_string(vm, &value, &value);
             if (njs_slow_path(ret != NJS_OK)) {
                 return NJS_ERROR;
             }
@@ -3763,7 +3762,7 @@ njs_string_prototype_replace(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
         p = njs_string_offset(&string, pos);
 
-        (void) njs_string_prop(&ret_string, &retval);
+        (void) njs_string_prop(&ret_string, &value);
 
         size = string.size + ret_string.size - s.size;
         length = string.length + ret_string.length - s.length;
@@ -3775,7 +3774,7 @@ njs_string_prototype_replace(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
             length = 0;
         }
 
-        r = njs_string_alloc(vm, &vm->retval, size, length);
+        r = njs_string_alloc(vm, retval, size, length);
         if (njs_slow_path(r == NULL)) {
             return NJS_ERROR;
         }
@@ -3796,7 +3795,7 @@ njs_string_prototype_replace(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     do {
         if (func_replace == NULL) {
             ret = njs_string_get_substitution(vm, search, this, pos, NULL, 0,
-                                              NULL, replace, &retval);
+                                              NULL, replace, &value);
             if (njs_slow_path(ret != NJS_OK)) {
                 return ret;
             }
@@ -3806,13 +3805,13 @@ njs_string_prototype_replace(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
             ret = njs_function_call(vm, func_replace,
                                     njs_value_arg(&njs_value_undefined),
-                                    arguments, 3, &retval);
+                                    arguments, 3, &value);
 
             if (njs_slow_path(ret != NJS_OK)) {
                 return ret;
             }
 
-            ret = njs_value_to_string(vm, &retval, &retval);
+            ret = njs_value_to_string(vm, &value, &value);
             if (njs_slow_path(ret != NJS_OK)) {
                 return NJS_ERROR;
             }
@@ -3826,7 +3825,7 @@ njs_string_prototype_replace(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
                                        pos);
         }
 
-        (void) njs_string_prop(&ret_string, &retval);
+        (void) njs_string_prop(&ret_string, &value);
 
         njs_chb_append(&chain, p_start, p - p_start);
         njs_chb_append(&chain, ret_string.start, ret_string.size);
@@ -3840,7 +3839,7 @@ njs_string_prototype_replace(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     njs_chb_append(&chain, p_start, string.start + string.size - p_start);
 
-    ret = njs_string_create_chb(vm, &vm->retval, &chain);
+    ret = njs_string_create_chb(vm, retval, &chain);
     if (njs_slow_path(ret != NJS_OK)) {
         ret = NJS_ERROR;
         goto exception;
@@ -3857,7 +3856,7 @@ exception:
 
 static njs_int_t
 njs_string_prototype_iterator_obj(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t kind)
+    njs_uint_t nargs, njs_index_t kind, njs_value_t *retval)
 {
     njs_int_t    ret;
     njs_value_t  *this;
@@ -3869,7 +3868,7 @@ njs_string_prototype_iterator_obj(njs_vm_t *vm, njs_value_t *args,
         return ret;
     }
 
-    return njs_array_iterator_create(vm, this, &vm->retval, kind);
+    return njs_array_iterator_create(vm, this, retval, kind);
 }
 
 
@@ -4149,7 +4148,7 @@ const njs_object_init_t  njs_string_instance_init = {
 
 njs_int_t
 njs_string_encode_uri(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t component)
+    njs_index_t component, njs_value_t *retval)
 {
     u_char                byte, *dst;
     uint64_t              size;
@@ -4199,7 +4198,7 @@ njs_string_encode_uri(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     };
 
     if (nargs < 2) {
-        vm->retval = njs_string_undefined;
+        njs_value_assign(retval, &njs_string_undefined);
         return NJS_OK;
     }
 
@@ -4264,12 +4263,11 @@ njs_string_encode_uri(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     if (size == 0) {
-        /* GC: retain src. */
-        vm->retval = *value;
+        njs_value_assign(retval, value);
         return NJS_OK;
     }
 
-    dst = njs_string_alloc(vm, &vm->retval, size, size);
+    dst = njs_string_alloc(vm, retval, size, size);
     if (njs_slow_path(dst == NULL)) {
         return NJS_ERROR;
     }
@@ -4355,7 +4353,7 @@ njs_reserved(const uint32_t *reserve, uint32_t byte)
 
 njs_int_t
 njs_string_decode_uri(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t component)
+    njs_index_t component, njs_value_t *retval)
 {
     u_char                *dst;
     int64_t               size, length;
@@ -4429,7 +4427,7 @@ njs_string_decode_uri(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     };
 
     if (nargs < 2) {
-        vm->retval = njs_string_undefined;
+        njs_value_assign(retval, &njs_string_undefined);
         return NJS_OK;
     }
 
@@ -4532,12 +4530,11 @@ njs_string_decode_uri(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     if (size == 0) {
-        /* GC: retain src. */
-        vm->retval = *value;
+        njs_value_assign(retval, value);
         return NJS_OK;
     }
 
-    dst = njs_string_alloc(vm, &vm->retval, size, length);
+    dst = njs_string_alloc(vm, retval, size, length);
     if (njs_slow_path(dst == NULL)) {
         return NJS_ERROR;
     }
@@ -4557,7 +4554,7 @@ uri_error:
 
 njs_int_t
 njs_string_btoa(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     u_char                *dst;
     size_t                len, length;
@@ -4584,7 +4581,7 @@ njs_string_btoa(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     length = njs_base64_encoded_length(len);
 
-    dst = njs_string_alloc(vm, &vm->retval, length, length);
+    dst = njs_string_alloc(vm, retval, length, length);
     if (njs_slow_path(dst == NULL)) {
         return NJS_ERROR;
     }
@@ -4652,7 +4649,7 @@ njs_chb_write_byte_as_utf8(njs_chb_t *chain, u_char byte)
 
 njs_int_t
 njs_string_atob(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     size_t        i, n, len, pad;
     u_char        *dst, *tmp, *p;
@@ -4753,11 +4750,11 @@ njs_string_atob(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     if (size == 0) {
-        njs_value_assign(&vm->retval, &njs_string_empty);
+        njs_value_assign(retval, &njs_string_empty);
         return NJS_OK;
     }
 
-    dst = njs_string_alloc(vm, &vm->retval, size, len);
+    dst = njs_string_alloc(vm, retval, size, len);
     if (njs_slow_path(dst == NULL)) {
         return NJS_ERROR;
     }
index 089e6fed678d3851708beee748fcd13257c6dc81..d92b51f2cd1a5a674dd0a2fbb800266e26d7a706 100644 (file)
@@ -248,16 +248,16 @@ uint32_t njs_string_index(njs_string_prop_t *string, uint32_t offset);
 void njs_string_utf8_offset_map_init(const u_char *start, size_t size);
 double njs_string_to_index(const njs_value_t *value);
 njs_int_t njs_string_encode_uri(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t component);
+    njs_uint_t nargs, njs_index_t component, njs_value_t *retval);
 njs_int_t njs_string_decode_uri(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t component);
+    njs_uint_t nargs, njs_index_t component, njs_value_t *retval);
 njs_int_t njs_string_btoa(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_int_t njs_string_atob(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_int_t njs_string_prototype_concat(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);
 njs_int_t njs_string_split_part_add(njs_vm_t *vm, njs_array_t *array,
     njs_utf8_t utf8, const u_char *start, size_t size);
 njs_int_t njs_string_get_substitution(njs_vm_t *vm, njs_value_t *matched,
index 0b7e3e5a0882b9f99d7b995ad331778b7bf9093f..05f5ae51c592d1581e186ca87f49faea15884fd8 100644 (file)
@@ -103,7 +103,7 @@ njs_symbol_descriptive_string(njs_vm_t *vm, njs_value_t *dst,
 
 static njs_int_t
 njs_symbol_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     uint64_t     key;
     njs_int_t    ret;
@@ -139,7 +139,7 @@ njs_symbol_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     njs_value_assign(name, value);
-    njs_set_symbol(&vm->retval, key, name);
+    njs_set_symbol(retval, key, name);
 
     return NJS_OK;
 }
@@ -147,7 +147,7 @@ njs_symbol_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_symbol_for(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     uint64_t              key;
     njs_int_t             ret;
@@ -173,7 +173,7 @@ njs_symbol_for(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         if (njs_is_string(&node->name)
             && njs_string_cmp(value, &node->name) == 0)
         {
-            njs_set_symbol(&vm->retval, node->key, &node->name);
+            njs_set_symbol(retval, node->key, &node->name);
             return NJS_OK;
         }
 
@@ -198,7 +198,7 @@ njs_symbol_for(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     njs_rbtree_insert(&vm->global_symbols, &node->node);
 
-    njs_set_symbol(&vm->retval, key, &node->name);
+    njs_set_symbol(retval, key, &node->name);
 
     return NJS_OK;
 }
@@ -206,7 +206,7 @@ njs_symbol_for(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_symbol_key_for(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;
     njs_rb_symbol_node_t  query, *node;
@@ -222,7 +222,7 @@ njs_symbol_key_for(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     node = (njs_rb_symbol_node_t *) njs_rbtree_find(&vm->global_symbols,
                                                     &query.node);
 
-    njs_value_assign(&vm->retval,
+    njs_value_assign(retval,
                      node != NULL ? &node->name : &njs_value_undefined);
 
     return NJS_OK;
@@ -290,7 +290,7 @@ const njs_object_init_t  njs_symbol_constructor_init = {
 
 static njs_int_t
 njs_symbol_prototype_value_of(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;
 
@@ -309,7 +309,7 @@ njs_symbol_prototype_value_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         }
     }
 
-    vm->retval = *value;
+    njs_value_assign(retval, value);
 
     return NJS_OK;
 }
@@ -317,31 +317,31 @@ njs_symbol_prototype_value_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_symbol_prototype_to_string(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)
 {
     njs_int_t  ret;
 
-    ret = njs_symbol_prototype_value_of(vm, args, nargs, unused);
+    ret = njs_symbol_prototype_value_of(vm, args, nargs, unused, retval);
     if (njs_slow_path(ret != NJS_OK)) {
         return ret;
     }
 
-    return njs_symbol_descriptive_string(vm, &vm->retval, &vm->retval);
+    return njs_symbol_descriptive_string(vm, retval, retval);
 }
 
 
 static njs_int_t
 njs_symbol_prototype_description(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)
 {
     njs_int_t  ret;
 
-    ret = njs_symbol_prototype_value_of(vm, args, nargs, unused);
+    ret = njs_symbol_prototype_value_of(vm, args, nargs, unused, retval);
     if (njs_slow_path(ret != NJS_OK)) {
         return ret;
     }
 
-    njs_value_assign(&vm->retval, njs_symbol_description(&vm->retval));
+    njs_value_assign(retval, njs_symbol_description(retval));
 
     return NJS_OK;
 }
index d0356d210cb5af2a844cc7eaa1fe6f0603c938dc..8ab8c7ee57c2f1a6b6424a4e0ed5341a3301f40c 100644 (file)
@@ -10,7 +10,7 @@
 
 static njs_int_t
 njs_set_timer(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused, njs_bool_t immediate)
+    njs_index_t unused, njs_bool_t immediate, njs_value_t *retval)
 {
     njs_uint_t     n;
     uint64_t       delay;
@@ -69,7 +69,7 @@ njs_set_timer(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     if (njs_add_event(vm, event) == NJS_OK) {
-        njs_set_number(&vm->retval, vm->event_id - 1);
+        njs_set_number(retval, vm->event_id - 1);
     }
 
     return NJS_OK;
@@ -84,23 +84,23 @@ memory_error:
 
 njs_int_t
 njs_set_timeout(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
-    return njs_set_timer(vm, args, nargs, unused, 0);
+    return njs_set_timer(vm, args, nargs, unused, 0, retval);
 }
 
 
 njs_int_t
 njs_set_immediate(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
-    return njs_set_timer(vm, args, nargs, unused, 1);
+    return njs_set_timer(vm, args, nargs, unused, 1, retval);
 }
 
 
 njs_int_t
 njs_clear_timeout(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     u_char              buf[16], *p;
     njs_int_t           ret;
@@ -108,7 +108,7 @@ njs_clear_timeout(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_lvlhsh_query_t  lhq;
 
     if (njs_fast_path(nargs < 2) || !njs_is_number(&args[1])) {
-        njs_set_undefined(&vm->retval);
+        njs_set_undefined(retval);
         return NJS_OK;
     }
 
@@ -127,7 +127,7 @@ njs_clear_timeout(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         njs_del_event(vm, event, NJS_EVENT_RELEASE | NJS_EVENT_DELETE);
     }
 
-    njs_set_undefined(&vm->retval);
+    njs_set_undefined(retval);
 
     return NJS_OK;
 }
index ccb432e7b96fadec956ed233b2cc2552e51293c9..a176cebc990d941b78e9445727d17b824bf56246 100644 (file)
@@ -9,11 +9,11 @@
 
 
 njs_int_t njs_set_timeout(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);
 njs_int_t njs_set_immediate(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);
 njs_int_t njs_clear_timeout(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);
 
 
 #endif /* _NJS_TIMER_H_INCLUDED_ */
index f039a1066cbbf5000bed0b426a361cc70c93859c..1c5265da24d2381598697a222bc45f78567a6959 100644 (file)
@@ -197,7 +197,7 @@ memory_error:
 
 static njs_int_t
 njs_typed_array_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t magic)
+    njs_index_t magic, njs_value_t *retval)
 {
     njs_typed_array_t  *array;
 
@@ -211,7 +211,7 @@ njs_typed_array_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    njs_set_typed_array(&vm->retval, array);
+    njs_set_typed_array(retval, array);
 
     return NJS_OK;
 }
@@ -288,7 +288,7 @@ njs_typed_array_species_create(njs_vm_t *vm, njs_value_t *exemplar,
 
 static njs_int_t
 njs_typed_array_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     double             num;
     uint32_t           length, i;
@@ -308,12 +308,12 @@ njs_typed_array_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     length = nargs - 1;
 
     njs_set_number(&argument, length);
-    ret = njs_typed_array_create(vm, this, &argument, 1, &vm->retval);
+    ret = njs_typed_array_create(vm, this, &argument, 1, retval);
     if (njs_slow_path(ret != NJS_OK)) {
         return NJS_ERROR;
     }
 
-    array = njs_typed_array(&vm->retval);
+    array = njs_typed_array(retval);
 
     for (i = 0; i < length; i++) {
         ret = njs_value_to_number(vm, njs_argument(args, i + 1), &num);
@@ -324,7 +324,7 @@ njs_typed_array_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         njs_typed_array_prop_set(vm, array, i, num);
     }
 
-    njs_set_typed_array(&vm->retval, array);
+    njs_set_typed_array(retval, array);
 
     return NJS_OK;
 }
@@ -332,13 +332,13 @@ njs_typed_array_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_typed_array_from(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     double             num;
     int64_t            length, i;
     njs_int_t          ret;
     njs_value_t        *this, *source, *mapfn;
-    njs_value_t        arguments[3], retval;
+    njs_value_t        arguments[3], value;
     njs_function_t     *function;
     njs_typed_array_t  *array;
 
@@ -375,30 +375,30 @@ njs_typed_array_from(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     }
 
     njs_set_number(&arguments[0], length);
-    ret = njs_typed_array_create(vm, this, arguments, 1, &vm->retval);
+    ret = njs_typed_array_create(vm, this, arguments, 1, retval);
     if (njs_slow_path(ret != NJS_OK)) {
         return NJS_ERROR;
     }
 
-    array = njs_typed_array(&vm->retval);
+    array = njs_typed_array(retval);
     arguments[0] = *njs_arg(args, nargs, 3);
 
     for (i = 0; i < length; i++) {
-        ret = njs_value_property_i64(vm, source, i, &retval);
+        ret = njs_value_property_i64(vm, source, i, &value);
         if (njs_slow_path(ret == NJS_ERROR)) {
             return NJS_ERROR;
         }
 
         if (function != NULL) {
-            arguments[1] = retval;
+            njs_value_assign(&arguments[1], &value);
             njs_set_number(&arguments[2], i);
-            ret = njs_function_apply(vm, function, arguments, 3, &retval);
+            ret = njs_function_apply(vm, function, arguments, 3, &value);
             if (njs_slow_path(ret != NJS_OK)) {
                 return NJS_ERROR;
             }
         }
 
-        ret = njs_value_to_number(vm, &retval, &num);
+        ret = njs_value_to_number(vm, &value, &num);
         if (njs_slow_path(ret != NJS_OK)) {
             return NJS_ERROR;
         }
@@ -406,7 +406,7 @@ njs_typed_array_from(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         njs_typed_array_prop_set(vm, array, i, num);
     }
 
-    njs_set_typed_array(&vm->retval, array);
+    njs_set_typed_array(retval, array);
 
     return NJS_OK;
 }
@@ -414,9 +414,9 @@ njs_typed_array_from(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_typed_array_get_this(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)
 {
-    vm->retval = args[0];
+    njs_value_assign(retval, njs_argument(args, 0));
 
     return NJS_OK;
 }
@@ -460,7 +460,7 @@ static const njs_value_t  njs_typed_array_float64_tag =
 
 static njs_int_t
 njs_typed_array_get_string_tag(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t unused)
+    njs_uint_t nargs, njs_index_t unused, njs_value_t *retval)
 {
     njs_value_t  *this;
 
@@ -479,11 +479,12 @@ njs_typed_array_get_string_tag(njs_vm_t *vm, njs_value_t *args,
     this = njs_argument(args, 0);
 
     if (!njs_is_typed_array(this)) {
-        njs_set_undefined(&vm->retval);
+        njs_set_undefined(retval);
         return NJS_OK;
     }
 
-    vm->retval = *tags[njs_typed_array_index(njs_typed_array(this)->type)];
+    njs_value_assign(retval,
+                     tags[njs_typed_array_index(njs_typed_array(this)->type)]);
 
     return NJS_OK;
 }
@@ -491,7 +492,7 @@ njs_typed_array_get_string_tag(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_typed_array_prototype_length(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)
 {
     uint32_t           length;
     njs_value_t        *this;
@@ -511,7 +512,7 @@ njs_typed_array_prototype_length(njs_vm_t *vm, njs_value_t *args,
         length = 0;
     }
 
-    njs_set_number(&vm->retval, length);
+    njs_set_number(retval, length);
 
     return NJS_OK;
 }
@@ -519,7 +520,7 @@ njs_typed_array_prototype_length(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_typed_array_prototype_buffer(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)
 {
     njs_value_t        *this;
     njs_typed_array_t  *array;
@@ -533,7 +534,7 @@ njs_typed_array_prototype_buffer(njs_vm_t *vm, njs_value_t *args,
 
     array = njs_typed_array(this);
 
-    njs_set_array_buffer(&vm->retval, njs_typed_array_buffer(array));
+    njs_set_array_buffer(retval, njs_typed_array_buffer(array));
 
     return NJS_OK;
 }
@@ -541,7 +542,7 @@ njs_typed_array_prototype_buffer(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_typed_array_prototype_byte_length(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)
 {
     size_t             byte_length;
     njs_value_t        *this;
@@ -566,7 +567,7 @@ njs_typed_array_prototype_byte_length(njs_vm_t *vm, njs_value_t *args,
         byte_length = 0;
     }
 
-    njs_set_number(&vm->retval, byte_length);
+    njs_set_number(retval, byte_length);
 
     return NJS_OK;
 }
@@ -574,7 +575,7 @@ njs_typed_array_prototype_byte_length(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_typed_array_prototype_byte_offset(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)
 {
     size_t             byte_offset;
     njs_value_t        *this;
@@ -599,7 +600,7 @@ njs_typed_array_prototype_byte_offset(njs_vm_t *vm, njs_value_t *args,
         byte_offset = 0;
     }
 
-    njs_set_number(&vm->retval, byte_offset);
+    njs_set_number(retval, byte_offset);
 
     return NJS_OK;
 }
@@ -688,7 +689,7 @@ njs_typed_array_set_value(njs_vm_t *vm, njs_typed_array_t *array,
 
 static njs_int_t
 njs_typed_array_prototype_set(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)
 {
     double              num;
     int64_t             i, length, src_length, offset;
@@ -791,7 +792,7 @@ njs_typed_array_prototype_set(njs_vm_t *vm, njs_value_t *args,
         }
     }
 
-    njs_set_undefined(&vm->retval);
+    njs_set_undefined(retval);
 
     return NJS_OK;
 }
@@ -799,7 +800,7 @@ njs_typed_array_prototype_set(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_typed_array_prototype_fill(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)
 {
     float               f32;
     int8_t              i8;
@@ -858,7 +859,7 @@ njs_typed_array_prototype_fill(njs_vm_t *vm, njs_value_t *args,
         return NJS_ERROR;
     }
 
-    njs_set_typed_array(&vm->retval, array);
+    njs_set_typed_array(retval, array);
 
     offset = array->offset;
 
@@ -934,7 +935,7 @@ njs_typed_array_prototype_fill(njs_vm_t *vm, njs_value_t *args,
 
 njs_int_t
 njs_typed_array_prototype_slice(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t copy)
+    njs_uint_t nargs, njs_index_t copy, njs_value_t *retval)
 {
     int64_t             start, end, count, offset;
     uint32_t            i, element_size, length;
@@ -988,7 +989,7 @@ njs_typed_array_prototype_slice(njs_vm_t *vm, njs_value_t *args,
 
         ret = njs_typed_array_species_create(vm, this,
                                              njs_value_arg(arguments), 1,
-                                             &vm->retval);
+                                             retval);
         if (njs_slow_path(ret != NJS_OK)) {
             return ret;
         }
@@ -1002,7 +1003,7 @@ njs_typed_array_prototype_slice(njs_vm_t *vm, njs_value_t *args,
             return NJS_ERROR;
         }
 
-        new_array = njs_typed_array(&vm->retval);
+        new_array = njs_typed_array(retval);
         new_buffer = njs_typed_array_buffer(new_array);
         element_size = njs_typed_array_element_size(array->type);
 
@@ -1030,13 +1031,13 @@ njs_typed_array_prototype_slice(njs_vm_t *vm, njs_value_t *args,
     njs_set_number(&arguments[2], njs_max(end - start, 0));
 
     return njs_typed_array_species_create(vm, this, njs_value_arg(arguments), 3,
-                                          &vm->retval);
+                                          retval);
 }
 
 
 static njs_int_t
 njs_typed_array_prototype_copy_within(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)
 {
     int64_t             length, to, from, final, count;
     uint32_t            element_size;
@@ -1090,7 +1091,7 @@ njs_typed_array_prototype_copy_within(njs_vm_t *vm, njs_value_t *args,
 
     final = (final < 0) ? njs_max(final + length, 0) : njs_min(final, length);
 
-    njs_set_typed_array(&vm->retval, array);
+    njs_set_typed_array(retval, array);
 
     count = njs_min(final - from, length - to);
 
@@ -1117,14 +1118,14 @@ njs_typed_array_prototype_copy_within(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_typed_array_prototype_iterator(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t type)
+    njs_uint_t nargs, njs_index_t type, njs_value_t *retval)
 {
     double              val;
     int64_t             i, length;
     njs_int_t           ret;
     njs_arr_t           results;
     njs_value_t         *this, *this_arg, *r;
-    njs_value_t         arguments[4], retval;
+    njs_value_t         arguments[4], value;
     njs_function_t      *function;
     njs_typed_array_t   *array, *dst;
     njs_array_buffer_t  *buffer;
@@ -1155,12 +1156,12 @@ njs_typed_array_prototype_iterator(njs_vm_t *vm, njs_value_t *args,
     case NJS_ARRAY_MAP:
         njs_set_number(&arguments[0], length);
         ret = njs_typed_array_species_create(vm, this, njs_value_arg(arguments),
-                                             1, &retval);
+                                             1, &value);
         if (njs_slow_path(ret != NJS_OK)) {
             return NJS_ERROR;
         }
 
-        dst = njs_typed_array(&retval);
+        dst = njs_typed_array(&value);
         break;
 
     case NJS_ARRAY_FILTER:
@@ -1184,15 +1185,15 @@ njs_typed_array_prototype_iterator(njs_vm_t *vm, njs_value_t *args,
         njs_set_number(&arguments[2], i);
         njs_set_typed_array(&arguments[3], array);
 
-        ret = njs_function_apply(vm, function, arguments, 4, &vm->retval);
+        ret = njs_function_apply(vm, function, arguments, 4, retval);
         if (njs_slow_path(ret != NJS_OK)) {
             goto exception;
         }
 
         switch (type) {
         case NJS_ARRAY_EVERY:
-            if (!njs_is_true(&vm->retval)) {
-                vm->retval = njs_value_false;
+            if (!njs_is_true(retval)) {
+                njs_set_boolean(retval, 0);
                 goto done;
             }
 
@@ -1204,28 +1205,28 @@ njs_typed_array_prototype_iterator(njs_vm_t *vm, njs_value_t *args,
         case NJS_ARRAY_SOME:
         case NJS_ARRAY_FIND:
         case NJS_ARRAY_FIND_INDEX:
-            if (!njs_is_true(&vm->retval)) {
+            if (!njs_is_true(retval)) {
                 continue;
             }
 
             switch (type) {
             case NJS_ARRAY_SOME:
-                vm->retval = njs_value_true;
+                njs_set_boolean(retval, 1);
                 break;
 
             case NJS_ARRAY_FIND:
-                njs_set_number(&vm->retval, val);
+                njs_set_number(retval, val);
                 break;
 
             default:
-                njs_set_number(&vm->retval, i);
+                njs_set_number(retval, i);
                 break;
             }
 
             goto done;
 
         case NJS_ARRAY_MAP:
-            ret = njs_typed_array_set_value(vm, dst, i, &vm->retval);
+            ret = njs_typed_array_set_value(vm, dst, i, retval);
             if (njs_slow_path(ret != NJS_OK)) {
                 goto exception;
             }
@@ -1235,7 +1236,7 @@ njs_typed_array_prototype_iterator(njs_vm_t *vm, njs_value_t *args,
         default:
             /* NJS_ARRAY_FILTER. */
 
-            if (!njs_is_true(&vm->retval)) {
+            if (!njs_is_true(retval)) {
                 continue;
             }
 
@@ -1252,20 +1253,20 @@ njs_typed_array_prototype_iterator(njs_vm_t *vm, njs_value_t *args,
 
     switch (type) {
     case NJS_ARRAY_EVERY:
-        vm->retval = njs_value_true;
+        njs_set_boolean(retval, 1);
         break;
 
     case NJS_ARRAY_SOME:
-        vm->retval = njs_value_false;
+        njs_set_boolean(retval, 0);
         break;
 
     case NJS_ARRAY_FOR_EACH:
     case NJS_ARRAY_FIND:
-        njs_set_undefined(&vm->retval);
+        njs_set_undefined(retval);
         break;
 
     case NJS_ARRAY_FIND_INDEX:
-        njs_set_number(&vm->retval, -1);
+        njs_set_number(retval, -1);
         break;
 
     case NJS_ARRAY_MAP:
@@ -1275,12 +1276,12 @@ njs_typed_array_prototype_iterator(njs_vm_t *vm, njs_value_t *args,
             njs_set_number(&arguments[0], results.items);
             ret = njs_typed_array_species_create(vm, this,
                                                  njs_value_arg(arguments),
-                                                 1, &retval);
+                                                 1, &value);
             if (njs_slow_path(ret != NJS_OK)) {
                 goto exception;
             }
 
-            dst = njs_typed_array(&retval);
+            dst = njs_typed_array(&value);
 
             i = 0;
 
@@ -1293,7 +1294,7 @@ njs_typed_array_prototype_iterator(njs_vm_t *vm, njs_value_t *args,
             }
         }
 
-        njs_set_typed_array(&vm->retval, dst);
+        njs_set_typed_array(retval, dst);
         break;
     }
 
@@ -1311,7 +1312,7 @@ exception:
 
 static njs_int_t
 njs_typed_array_prototype_index_of(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t type)
+    njs_uint_t nargs, njs_index_t type, njs_value_t *retval)
 {
     double              v;
     int64_t             i, i64, from, to, index, increment, offset, length;
@@ -1523,10 +1524,10 @@ done:
     /* Default values. */
 
     if (type & 1) {
-        njs_set_boolean(&vm->retval, index != -1);
+        njs_set_boolean(retval, index != -1);
 
     } else {
-        njs_set_number(&vm->retval, index);
+        njs_set_number(retval, index);
     }
 
     return NJS_OK;
@@ -1535,7 +1536,7 @@ done:
 
 static njs_int_t
 njs_typed_array_prototype_reduce(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t right)
+    njs_uint_t nargs, njs_index_t right, njs_value_t *retval)
 {
     int64_t             i, from, to, increment, length;
     njs_int_t           ret;
@@ -1610,7 +1611,7 @@ njs_typed_array_prototype_reduce(njs_vm_t *vm, njs_value_t *args,
         }
     }
 
-    vm->retval = accumulator;
+    njs_value_assign(retval, &accumulator);
 
     return NJS_OK;
 }
@@ -1618,7 +1619,7 @@ njs_typed_array_prototype_reduce(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_typed_array_prototype_reverse(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)
 {
     double              *f64;
     uint8_t             *u8;
@@ -1687,7 +1688,7 @@ njs_typed_array_prototype_reverse(njs_vm_t *vm, njs_value_t *args,
         }
     }
 
-    njs_set_typed_array(&vm->retval, array);
+    njs_set_typed_array(retval, array);
 
     return NJS_OK;
 }
@@ -1906,7 +1907,7 @@ exception:
 
 static njs_int_t
 njs_typed_array_prototype_sort(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)
 {
     u_char                      *base, *orig;
     int64_t                     length;
@@ -2028,7 +2029,7 @@ njs_typed_array_prototype_sort(njs_vm_t *vm, njs_value_t *args,
         return NJS_ERROR;
     }
 
-    njs_set_typed_array(&vm->retval, array);
+    njs_set_typed_array(retval, array);
 
     return NJS_OK;
 }
@@ -2076,7 +2077,7 @@ njs_typed_array_to_chain(njs_vm_t *vm, njs_chb_t *chain,
 
 static njs_int_t
 njs_typed_array_prototype_join(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)
 {
     u_char             *p;
     size_t             size, length, arr_length;
@@ -2114,7 +2115,7 @@ njs_typed_array_prototype_join(njs_vm_t *vm, njs_value_t *args,
     }
 
     if (arr_length == 0) {
-        vm->retval = njs_string_empty;
+        njs_value_assign(retval, &njs_string_empty);
         return NJS_OK;
     }
 
@@ -2128,7 +2129,7 @@ njs_typed_array_prototype_join(njs_vm_t *vm, njs_value_t *args,
     length = njs_typed_array_to_chain(vm, &chain, array, separator);
     size = njs_chb_size(&chain);
 
-    p = njs_string_alloc(vm, &vm->retval, size, length);
+    p = njs_string_alloc(vm, retval, size, length);
     if (njs_slow_path(p == NULL)) {
         return NJS_ERROR;
     }
@@ -2142,7 +2143,7 @@ njs_typed_array_prototype_join(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_typed_array_prototype_iterator_obj(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t kind)
+    njs_uint_t nargs, njs_index_t kind, njs_value_t *retval)
 {
     njs_value_t        *this;
     njs_typed_array_t  *array;
@@ -2159,13 +2160,13 @@ njs_typed_array_prototype_iterator_obj(njs_vm_t *vm, njs_value_t *args,
         return NJS_ERROR;
     }
 
-    return njs_array_iterator_create(vm, this, &vm->retval, kind);
+    return njs_array_iterator_create(vm, this, retval, kind);
 }
 
 
 static njs_int_t
 njs_typed_array_constructor_intrinsic(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)
 {
     njs_type_error(vm, "Abstract class TypedArray not directly constructable");
 
@@ -2325,7 +2326,7 @@ const njs_object_type_init_t  njs_typed_array_type_init = {
 
 static njs_int_t
 njs_data_view_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
-    njs_index_t unused)
+    njs_index_t unused, njs_value_t *retval)
 {
     uint64_t            size, offset;
     njs_int_t           ret;
@@ -2393,7 +2394,7 @@ njs_data_view_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     view->object.type = NJS_DATA_VIEW;
     view->object.extensible = 1;
 
-    njs_set_data_view(&vm->retval, view);
+    njs_set_data_view(retval, view);
 
     return NJS_OK;
 
@@ -2423,7 +2424,7 @@ static const njs_object_init_t  njs_data_view_constructor_init = {
 
 static njs_int_t
 njs_data_view_prototype_get(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t type)
+    njs_uint_t nargs, njs_index_t type, njs_value_t *retval)
 {
     double              v;
     uint32_t            u32;
@@ -2535,7 +2536,7 @@ njs_data_view_prototype_get(njs_vm_t *vm, njs_value_t *args,
         v = conv_f64.f;
     }
 
-    njs_set_number(&vm->retval, v);
+    njs_set_number(retval, v);
 
     return NJS_OK;
 }
@@ -2543,7 +2544,7 @@ njs_data_view_prototype_get(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_data_view_prototype_set(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t type)
+    njs_uint_t nargs, njs_index_t type, njs_value_t *retval)
 {
     double              v;
     uint8_t             *u8;
@@ -2644,7 +2645,7 @@ njs_data_view_prototype_set(njs_vm_t *vm, njs_value_t *args,
         njs_set_u64(u8, conv_f64.u);
     }
 
-    njs_set_undefined(&vm->retval);
+    njs_set_undefined(retval);
 
     return NJS_OK;
 }
index 3f8b25366a656488aa1e6cf53c13e21e86f1f170..47177fad3a40a7934ff20961fa56ad74fec650aa 100644 (file)
@@ -17,7 +17,7 @@ njs_int_t njs_typed_array_set_value(njs_vm_t *vm, njs_typed_array_t *array,
 njs_int_t njs_typed_array_to_chain(njs_vm_t *vm, njs_chb_t *chain,
     njs_typed_array_t *array, njs_value_t *sep);
 njs_int_t njs_typed_array_prototype_slice(njs_vm_t *vm, njs_value_t *args,
-    njs_uint_t nargs, njs_index_t copy);
+    njs_uint_t nargs, njs_index_t copy, njs_value_t *retval);
 
 njs_inline unsigned
 njs_typed_array_element_size(njs_object_type_t type)
index c54e36d36dc2de5585325a0f4d721a92fc595607..b4a02f05c4ad34aaf306214ba89e4937ea3672b5 100644 (file)
@@ -1189,6 +1189,7 @@ njs_value_property_set(njs_vm_t *vm, njs_value_t *value, njs_value_t *key,
     uint32_t              index;
     njs_int_t             ret;
     njs_array_t           *array;
+    njs_value_t           retval;
     njs_object_prop_t     *prop;
     njs_typed_array_t     *tarray;
     njs_property_query_t  pq;
@@ -1264,7 +1265,7 @@ slow_path:
         } else {
             if (njs_prop_setter(prop) != NULL) {
                 return njs_function_call(vm, njs_prop_setter(prop),
-                                         value, setval, 1, &vm->retval);
+                                         value, setval, 1, &retval);
             }
 
             njs_key_string_get(vm, &pq.key,  &pq.lhq.key);
@@ -1275,7 +1276,7 @@ slow_path:
         }
 
         if (prop->type == NJS_PROPERTY_HANDLER) {
-            ret = njs_prop_handler(prop)(vm, prop, value, setval, &vm->retval);
+            ret = njs_prop_handler(prop)(vm, prop, value, setval, &retval);
             if (njs_slow_path(ret != NJS_DECLINED)) {
                 return ret;
             }
index b9507676f27d48a27581582fa0ce8ce32bf8552d..68e40dae9982b846fcf71c5767dcf19ea2d682bd 100644 (file)
@@ -8,7 +8,6 @@
 #include <njs_main.h>
 
 
-static njs_int_t njs_vm_init(njs_vm_t *vm);
 static njs_int_t njs_vm_handle_events(njs_vm_t *vm);
 
 
@@ -78,8 +77,6 @@ njs_vm_create(njs_vm_opt_t *options)
     vm->trace.size = 2048;
     vm->trace.data = vm;
 
-    njs_set_undefined(&vm->retval);
-
     if (options->init) {
         ret = njs_vm_init(vm);
         if (njs_slow_path(ret != NJS_OK)) {
@@ -198,7 +195,7 @@ njs_vm_compile(njs_vm_t *vm, u_char **start, u_char *end)
 
     code = njs_generate_scope(vm, &generator, scope, &njs_entry_main);
     if (njs_slow_path(code == NULL)) {
-        if (!njs_is_error(&vm->retval)) {
+        if (!njs_is_error(&vm->exception)) {
             njs_internal_error(vm, "njs_generate_scope() failed");
         }
 
@@ -375,7 +372,7 @@ fail:
 }
 
 
-static njs_int_t
+njs_int_t
 njs_vm_init(njs_vm_t *vm)
 {
     njs_int_t    ret;
@@ -421,7 +418,9 @@ njs_int_t
 njs_vm_call(njs_vm_t *vm, njs_function_t *function, const njs_value_t *args,
     njs_uint_t nargs)
 {
-    return njs_vm_invoke(vm, function, args, nargs, &vm->retval);
+    njs_value_t  unused;
+
+    return njs_vm_invoke(vm, function, args, nargs, &unused);
 }
 
 
@@ -545,11 +544,11 @@ njs_vm_run(njs_vm_t *vm)
 
 
 njs_int_t
-njs_vm_start(njs_vm_t *vm)
+njs_vm_start(njs_vm_t *vm, njs_value_t *retval)
 {
     njs_int_t  ret;
 
-    ret = njs_vmcode_interpreter(vm, vm->start, NULL, NULL);
+    ret = njs_vmcode_interpreter(vm, vm->start, retval, NULL, NULL);
 
     return (ret == NJS_ERROR) ? NJS_ERROR : NJS_OK;
 }
@@ -655,10 +654,22 @@ njs_vm_add_path(njs_vm_t *vm, const njs_str_t *path)
 }
 
 
-njs_value_t *
-njs_vm_retval(njs_vm_t *vm)
+njs_value_t
+njs_vm_exception(njs_vm_t *vm)
+{
+    njs_value_t  value;
+
+    value = vm->exception;
+    njs_set_invalid(&vm->exception);
+
+    return value;
+}
+
+
+void
+njs_vm_exception_get(njs_vm_t *vm, njs_value_t *retval)
 {
-    return &vm->retval;
+    *retval = njs_vm_exception(vm);
 }
 
 
@@ -691,9 +702,20 @@ njs_vm_meta(njs_vm_t *vm, njs_uint_t index)
 
 
 void
-njs_vm_retval_set(njs_vm_t *vm, const njs_value_t *value)
+njs_vm_throw(njs_vm_t *vm, const njs_value_t *value)
 {
-    vm->retval = *value;
+    vm->exception = *value;
+}
+
+
+void
+njs_vm_error(njs_vm_t *vm, const char *fmt, ...)
+{
+    va_list  args;
+
+    va_start(args, fmt);
+    njs_throw_error_va(vm, NJS_OBJ_TYPE_ERROR, fmt, args);
+    va_end(args);
 }
 
 
@@ -725,7 +747,7 @@ njs_vm_value(njs_vm_t *vm, const njs_str_t *path, njs_value_t *retval)
         }
 
         ret = njs_value_property(vm, &value, &key, njs_value_arg(retval));
-        if (njs_slow_path(ret != NJS_OK)) {
+        if (njs_slow_path(ret == NJS_ERROR)) {
             return ret;
         }
 
@@ -880,7 +902,6 @@ njs_int_t
 njs_vm_prop_name(njs_vm_t *vm, njs_object_prop_t *prop, njs_str_t *dst)
 {
     if (njs_slow_path(!njs_is_string(&prop->name))) {
-        njs_type_error(vm, "property name is not a string");
         return NJS_ERROR;
     }
 
@@ -890,28 +911,10 @@ njs_vm_prop_name(njs_vm_t *vm, njs_object_prop_t *prop, njs_str_t *dst)
 }
 
 
-njs_noinline void
-njs_vm_value_error_set(njs_vm_t *vm, njs_value_t *value, const char *fmt, ...)
-{
-    va_list  args;
-    u_char   buf[NJS_MAX_ERROR_STR], *p;
-
-    p = buf;
-
-    if (fmt != NULL) {
-        va_start(args, fmt);
-        p = njs_vsprintf(buf, buf + sizeof(buf), fmt, args);
-        va_end(args);
-    }
-
-    njs_error_new(vm, value, NJS_OBJ_TYPE_ERROR, buf, p - buf);
-}
-
-
 njs_noinline void
 njs_vm_memory_error(njs_vm_t *vm)
 {
-    njs_memory_error_set(vm, &vm->retval);
+    njs_memory_error_set(vm, &vm->exception);
 }
 
 
@@ -944,6 +947,17 @@ njs_vm_value_string(njs_vm_t *vm, njs_str_t *dst, njs_value_t *src)
 {
     njs_int_t    ret;
     njs_uint_t   exception;
+    njs_value_t  value;
+
+    if (njs_slow_path(vm->top_frame == NULL)) {
+        /* An exception was thrown during compilation. */
+        njs_vm_init(vm);
+    }
+
+    if (njs_is_valid(&vm->exception)) {
+        value = njs_vm_exception(vm);
+        src = &value;
+    }
 
     if (njs_slow_path(src->type == NJS_NUMBER
                       && njs_number(src) == 0
@@ -967,7 +981,7 @@ again:
 
         /* value evaluation threw an exception. */
 
-        src = &vm->retval;
+        *src = njs_vm_exception(vm);
         goto again;
     }
 
@@ -979,28 +993,13 @@ again:
 
 
 njs_int_t
-njs_vm_retval_string(njs_vm_t *vm, njs_str_t *dst)
+njs_vm_exception_string(njs_vm_t *vm, njs_str_t *dst)
 {
-    if (vm->top_frame == NULL) {
-        /* An exception was thrown during compilation. */
-
-        njs_vm_init(vm);
-    }
-
-    return njs_vm_value_string(vm, dst, &vm->retval);
-}
-
+    njs_value_t  exception;
 
-njs_int_t
-njs_vm_retval_dump(njs_vm_t *vm, njs_str_t *dst, njs_uint_t indent)
-{
-    if (vm->top_frame == NULL) {
-        /* An exception was thrown during compilation. */
-
-        njs_vm_init(vm);
-    }
+    exception = njs_vm_exception(vm);
 
-    return njs_vm_value_dump(vm, dst, &vm->retval, 0, 1);
+    return njs_vm_value_string(vm, dst, &exception);
 }
 
 
index cdb711733f336a2f3e8f5673d47a034b8761ce2f..695dcf7b550e8c215f876fa0d150731d0004a44d 100644 (file)
@@ -118,8 +118,7 @@ typedef enum {
 
 
 struct njs_vm_s {
-    /* njs_vm_t must be aligned to njs_value_t due to scratch value. */
-    njs_value_t              retval;
+    njs_value_t              exception;
 
     njs_arr_t                *paths;
     njs_arr_t                *protos;
@@ -239,6 +238,8 @@ struct njs_vm_shared_s {
 };
 
 
+njs_int_t njs_vm_init(njs_vm_t *vm);
+njs_value_t njs_vm_exception(njs_vm_t *vm);
 void njs_vm_scopes_restore(njs_vm_t *vm, njs_native_frame_t *frame);
 
 njs_int_t njs_builtin_objects_create(njs_vm_t *vm);
index c6f7b345e7402f1a41d0978506a2c7e8fbc751fc..b6e28ef51782009265bb36174a1a070002a0611d 100644 (file)
@@ -13,11 +13,14 @@ struct njs_property_next_s {
     njs_array_t  *array;
 };
 
-static njs_jump_off_t njs_vmcode_object(njs_vm_t *vm);
-static njs_jump_off_t njs_vmcode_array(njs_vm_t *vm, u_char *pc);
-static njs_jump_off_t njs_vmcode_function(njs_vm_t *vm, u_char *pc);
+static njs_jump_off_t njs_vmcode_object(njs_vm_t *vm, njs_value_t *retval);
+static njs_jump_off_t njs_vmcode_array(njs_vm_t *vm, u_char *pc,
+    njs_value_t *retval);
+static njs_jump_off_t njs_vmcode_function(njs_vm_t *vm, u_char *pc,
+    njs_value_t *retval);
 static njs_jump_off_t njs_vmcode_arguments(njs_vm_t *vm, u_char *pc);
-static njs_jump_off_t njs_vmcode_regexp(njs_vm_t *vm, u_char *pc);
+static njs_jump_off_t njs_vmcode_regexp(njs_vm_t *vm, u_char *pc,
+    njs_value_t *retval);
 static njs_jump_off_t njs_vmcode_template_literal(njs_vm_t *vm,
     njs_value_t *retval);
 static njs_jump_off_t njs_vmcode_function_copy(njs_vm_t *vm, njs_value_t *value,
@@ -28,22 +31,22 @@ static njs_jump_off_t njs_vmcode_property_init(njs_vm_t *vm, njs_value_t *value,
 static njs_jump_off_t njs_vmcode_proto_init(njs_vm_t *vm, njs_value_t *value,
     njs_value_t *key, njs_value_t *retval);
 static njs_jump_off_t njs_vmcode_property_in(njs_vm_t *vm,
-    njs_value_t *value, njs_value_t *key);
+    njs_value_t *value, njs_value_t *key, njs_value_t *retval);
 static njs_jump_off_t njs_vmcode_property_foreach(njs_vm_t *vm,
-    njs_value_t *object, njs_value_t *invld, u_char *pc);
+    njs_value_t *object, u_char *pc, njs_value_t *retval);
 static njs_jump_off_t njs_vmcode_instance_of(njs_vm_t *vm, njs_value_t *object,
-    njs_value_t *constructor);
+    njs_value_t *constructor, njs_value_t *retval);
 static njs_jump_off_t njs_vmcode_typeof(njs_vm_t *vm, njs_value_t *value,
-    njs_value_t *invld);
-static njs_jump_off_t njs_vmcode_debugger(njs_vm_t *vm);
+    njs_value_t *retval);
+static njs_jump_off_t njs_vmcode_debugger(njs_vm_t *vm, njs_value_t *retval);
 
-static njs_jump_off_t njs_vmcode_return(njs_vm_t *vm, njs_value_t *invld,
+static void njs_vmcode_return(njs_vm_t *vm, njs_value_t *dst,
     njs_value_t *retval);
 static njs_jump_off_t njs_vmcode_import(njs_vm_t *vm, njs_mod_t *module,
     njs_value_t *retval);
 
-static njs_jump_off_t njs_vmcode_await(njs_vm_t *vm, njs_vmcode_await_t *await,
-    njs_promise_capability_t *pcap, njs_async_ctx_t *actx);
+static njs_int_t njs_vmcode_await(njs_vm_t *vm, njs_vmcode_await_t *await,
+    njs_value_t *dst, njs_promise_capability_t *pcap, njs_async_ctx_t *actx);
 
 static njs_jump_off_t njs_vmcode_try_start(njs_vm_t *vm, njs_value_t *value,
     njs_value_t *offset, u_char *pc);
@@ -53,14 +56,14 @@ static njs_jump_off_t njs_vmcode_try_continue(njs_vm_t *vm, njs_value_t *value,
     njs_value_t *offset);
 static njs_jump_off_t njs_vmcode_try_end(njs_vm_t *vm, njs_value_t *invld,
     njs_value_t *offset);
-static njs_jump_off_t njs_vmcode_finally(njs_vm_t *vm, njs_value_t *invld,
+static njs_jump_off_t njs_vmcode_finally(njs_vm_t *vm, njs_value_t *dst,
     njs_value_t *retval, u_char *pc);
 static void njs_vmcode_error(njs_vm_t *vm, u_char *pc);
 static njs_int_t njs_throw_cannot_property(njs_vm_t *vm, njs_value_t *object,
     njs_value_t *key, const char *what);
 
 static njs_jump_off_t njs_string_concat(njs_vm_t *vm, njs_value_t *val1,
-    njs_value_t *val2);
+    njs_value_t *val2, njs_value_t *retval);
 static njs_jump_off_t njs_values_equal(njs_vm_t *vm, njs_value_t *val1,
     njs_value_t *val2);
 static njs_jump_off_t njs_primitive_values_compare(njs_vm_t *vm,
@@ -80,8 +83,8 @@ static njs_jump_off_t njs_function_frame_create(njs_vm_t *vm,
 
 
 njs_int_t
-njs_vmcode_interpreter(njs_vm_t *vm, u_char *pc, void *promise_cap,
-    void *async_ctx)
+njs_vmcode_interpreter(njs_vm_t *vm, u_char *pc, njs_value_t *rval,
+    void *promise_cap, void *async_ctx)
 {
     u_char                       *catch;
     double                       num, exponent;
@@ -641,12 +644,12 @@ NEXT_LBL;
             goto error;
         }
 
-        ret = njs_string_concat(vm, s1, s2);
+        ret = njs_string_concat(vm, s1, s2, &name);
         if (njs_slow_path(ret == NJS_ERROR)) {
             goto error;
         }
 
-        *retval = vm->retval;
+        njs_value_assign(retval, &name);
 
         BREAK;
 
@@ -889,17 +892,13 @@ NEXT_LBL;
 
         njs_vmcode_operand(vm, vmcode->operand3, value2);
         njs_vmcode_operand(vm, vmcode->operand2, value1);
+        njs_vmcode_operand(vm, vmcode->operand1, retval);
 
-        ret = njs_vmcode_property_in(vm, value1, value2);
-
+        ret = njs_vmcode_property_in(vm, value1, value2, retval);
         if (njs_slow_path(ret < 0 && ret >= NJS_PREEMPT)) {
             goto error;
         }
 
-        njs_vmcode_operand(vm, vmcode->operand1, retval);
-        njs_release(vm, retval);
-        *retval = vm->retval;
-
         BREAK;
 
     CASE (NJS_VMCODE_PROPERTY_DELETE):
@@ -923,38 +922,27 @@ NEXT_LBL;
         }
 
         ret = njs_value_property_delete(vm, value1, value2, NULL, 1);
-        if (njs_fast_path(ret != NJS_ERROR)) {
-            vm->retval = njs_value_true;
-
-            ret = sizeof(njs_vmcode_3addr_t);
-        }
-
-        if (njs_slow_path(ret < 0 && ret >= NJS_PREEMPT)) {
+        if (njs_slow_path(ret == NJS_ERROR)) {
             goto error;
         }
 
         njs_vmcode_operand(vm, vmcode->operand1, retval);
-        njs_release(vm, retval);
-        *retval = vm->retval;
+        njs_value_assign(retval, &njs_value_true);
+        ret = sizeof(njs_vmcode_3addr_t);
 
         BREAK;
 
     CASE (NJS_VMCODE_PROPERTY_FOREACH):
         njs_vmcode_debug_opcode();
 
-        value2 = (njs_value_t *) vmcode->operand1;
         njs_vmcode_operand(vm, vmcode->operand2, value1);
+        njs_vmcode_operand(vm, vmcode->operand1, retval);
 
-        ret = njs_vmcode_property_foreach(vm, value1, value2, pc);
-
+        ret = njs_vmcode_property_foreach(vm, value1, pc, retval);
         if (njs_slow_path(ret < 0 && ret >= NJS_PREEMPT)) {
             goto error;
         }
 
-        njs_vmcode_operand(vm, vmcode->operand1, retval);
-        njs_release(vm, retval);
-        *retval = vm->retval;
-
         BREAK;
 
     CASE (NJS_VMCODE_STRICT_EQUAL):
@@ -1110,61 +1098,49 @@ NEXT_LBL;
     CASE (NJS_VMCODE_OBJECT):
         njs_vmcode_debug_opcode();
 
-        ret = njs_vmcode_object(vm);
+        njs_vmcode_operand(vm, vmcode->operand1, retval);
 
+        ret = njs_vmcode_object(vm, retval);
         if (njs_slow_path(ret < 0 && ret >= NJS_PREEMPT)) {
             goto error;
         }
 
-        njs_vmcode_operand(vm, vmcode->operand1, retval);
-        njs_release(vm, retval);
-        *retval = vm->retval;
-
         BREAK;
 
     CASE (NJS_VMCODE_ARRAY):
         njs_vmcode_debug_opcode();
 
-        ret = njs_vmcode_array(vm, pc);
+        njs_vmcode_operand(vm, vmcode->operand1, retval);
 
+        ret = njs_vmcode_array(vm, pc, retval);
         if (njs_slow_path(ret < 0 && ret >= NJS_PREEMPT)) {
             goto error;
         }
 
-        njs_vmcode_operand(vm, vmcode->operand1, retval);
-        njs_release(vm, retval);
-        *retval = vm->retval;
-
         BREAK;
 
     CASE (NJS_VMCODE_FUNCTION):
         njs_vmcode_debug_opcode();
 
-        ret = njs_vmcode_function(vm, pc);
+        njs_vmcode_operand(vm, vmcode->operand1, retval);
 
+        ret = njs_vmcode_function(vm, pc, retval);
         if (njs_slow_path(ret < 0 && ret >= NJS_PREEMPT)) {
             goto error;
         }
 
-        njs_vmcode_operand(vm, vmcode->operand1, retval);
-        njs_release(vm, retval);
-        *retval = vm->retval;
-
         BREAK;
 
     CASE (NJS_VMCODE_REGEXP):
         njs_vmcode_debug_opcode();
 
-        ret = njs_vmcode_regexp(vm, pc);
+        njs_vmcode_operand(vm, vmcode->operand1, retval);
 
+        ret = njs_vmcode_regexp(vm, pc, retval);
         if (njs_slow_path(ret < 0 && ret >= NJS_PREEMPT)) {
             goto error;
         }
 
-        njs_vmcode_operand(vm, vmcode->operand1, retval);
-        njs_release(vm, retval);
-        *retval = vm->retval;
-
         BREAK;
 
     CASE (NJS_VMCODE_INSTANCE_OF):
@@ -1172,46 +1148,36 @@ NEXT_LBL;
 
         njs_vmcode_operand(vm, vmcode->operand3, value2);
         njs_vmcode_operand(vm, vmcode->operand2, value1);
+        njs_vmcode_operand(vm, vmcode->operand1, retval);
 
-        ret = njs_vmcode_instance_of(vm, value1, value2);
-
+        ret = njs_vmcode_instance_of(vm, value1, value2, retval);
         if (njs_slow_path(ret < 0 && ret >= NJS_PREEMPT)) {
             goto error;
         }
 
-        njs_vmcode_operand(vm, vmcode->operand1, retval);
-        njs_release(vm, retval);
-        *retval = vm->retval;
-
         BREAK;
 
     CASE (NJS_VMCODE_TYPEOF):
         njs_vmcode_debug_opcode();
 
         njs_vmcode_operand(vm, vmcode->operand2, value1);
+        njs_vmcode_operand(vm, vmcode->operand1, retval);
 
-        ret = njs_vmcode_typeof(vm, value1, NULL);
-
+        ret = njs_vmcode_typeof(vm, value1, retval);
         if (njs_slow_path(ret < 0 && ret >= NJS_PREEMPT)) {
             goto error;
         }
 
-        njs_vmcode_operand(vm, vmcode->operand1, retval);
-        njs_release(vm, retval);
-        *retval = vm->retval;
-
         BREAK;
 
     CASE (NJS_VMCODE_VOID):
         njs_vmcode_debug_opcode();
 
-        njs_set_undefined(&vm->retval);
+        njs_vmcode_operand(vm, vmcode->operand1, retval);
 
-        ret = sizeof(njs_vmcode_2addr_t);
+        njs_set_undefined(retval);
 
-        njs_vmcode_operand(vm, vmcode->operand1, retval);
-        njs_release(vm, retval);
-        *retval = vm->retval;
+        ret = sizeof(njs_vmcode_2addr_t);
 
         BREAK;
 
@@ -1219,25 +1185,20 @@ NEXT_LBL;
         njs_vmcode_debug_opcode();
 
         njs_vmcode_operand(vm, vmcode->operand2, value1);
+        njs_vmcode_operand(vm, vmcode->operand1, retval);
 
-        njs_release(vm, value1);
-        vm->retval = njs_value_true;
+        njs_set_boolean(retval, 1);
 
         ret = sizeof(njs_vmcode_2addr_t);
-        njs_vmcode_operand(vm, vmcode->operand1, retval);
-        njs_release(vm, retval);
-        *retval = vm->retval;
 
         BREAK;
 
     CASE (NJS_VMCODE_DEBUGGER):
         njs_vmcode_debug_opcode();
 
-        ret = njs_vmcode_debugger(vm);
-
         njs_vmcode_operand(vm, vmcode->operand1, retval);
-        njs_release(vm, retval);
-        *retval = vm->retval;
+
+        ret = njs_vmcode_debugger(vm, retval);
 
         BREAK;
 
@@ -1259,7 +1220,7 @@ NEXT_LBL;
         njs_vmcode_debug_opcode();
 
         njs_vmcode_operand(vm, vmcode->operand1, value2);
-        vm->retval = *value2;
+        *rval = *value2;
 
         njs_vmcode_debug(vm, pc, "EXIT STOP");
 
@@ -1394,7 +1355,9 @@ NEXT_LBL;
 
         njs_vmcode_debug(vm, pc, "EXIT RETURN");
 
-        return njs_vmcode_return(vm, NULL, value2);
+        njs_vmcode_return(vm, rval, value2);
+
+        return NJS_OK;
 
     CASE (NJS_VMCODE_FUNCTION_COPY):
         njs_vmcode_debug_opcode();
@@ -1579,7 +1542,7 @@ NEXT_LBL;
 
         ret = njs_function_name_set(vm, njs_function(value2), value1, NULL);
         if (njs_slow_path(ret == NJS_ERROR)) {
-            return ret;
+            goto error;
         }
 
         ret = sizeof(njs_vmcode_2addr_t);
@@ -1618,7 +1581,7 @@ NEXT_LBL;
 
         await = (njs_vmcode_await_t *) pc;
 
-        ret = njs_vmcode_await(vm, await, promise_cap, async_ctx);
+        ret = njs_vmcode_await(vm, await, rval, promise_cap, async_ctx);
 
         njs_vmcode_debug(vm, pc, "EXIT AWAIT");
 
@@ -1647,7 +1610,7 @@ NEXT_LBL;
         value2 = (njs_value_t *) vmcode->operand1;
 
         njs_vmcode_operand(vm, (njs_index_t) value2, value2);
-        vm->retval = *value2;
+        njs_vm_throw(vm, value2);
 
         goto error;
 
@@ -1693,7 +1656,7 @@ NEXT_LBL;
         value2 = (njs_value_t *) vmcode->operand1;
         njs_vmcode_operand(vm, vmcode->operand2, value1);
 
-        *value1 = vm->retval;
+        *value1 = njs_vm_exception(vm);
 
         if ((njs_jump_off_t) value2 == sizeof(njs_vmcode_catch_t)) {
             ret = njs_vmcode_try_end(vm, value1, value2);
@@ -1711,7 +1674,7 @@ NEXT_LBL;
 
         value2 = (njs_value_t *) vmcode->operand1;
 
-        ret = njs_vmcode_finally(vm, NULL, value2, pc);
+        ret = njs_vmcode_finally(vm, rval, value2, pc);
 
         switch (ret) {
         case NJS_OK:
@@ -1798,14 +1761,10 @@ NEXT_LBL;
 
 error:
 
-    if (njs_is_error(&vm->retval)) {
+    if (njs_is_error(&vm->exception)) {
         vm->active_frame->native.pc = pc;
 
-        /* TODO: get rid of copying. */
-
-        njs_value_assign(&dst, &vm->retval);
-        (void) njs_error_stack_attach(vm, &dst);
-        njs_value_assign(&vm->retval, &dst);
+        (void) njs_error_stack_attach(vm, vm->exception);
     }
 
     for ( ;; ) {
@@ -1848,14 +1807,14 @@ error:
 
 
 static njs_jump_off_t
-njs_vmcode_object(njs_vm_t *vm)
+njs_vmcode_object(njs_vm_t *vm, njs_value_t *retval)
 {
     njs_object_t  *object;
 
     object = njs_object_alloc(vm);
 
     if (njs_fast_path(object != NULL)) {
-        njs_set_object(&vm->retval, object);
+        njs_set_object(retval, object);
 
         return sizeof(njs_vmcode_object_t);
     }
@@ -1865,7 +1824,7 @@ njs_vmcode_object(njs_vm_t *vm)
 
 
 static njs_jump_off_t
-njs_vmcode_array(njs_vm_t *vm, u_char *pc)
+njs_vmcode_array(njs_vm_t *vm, u_char *pc, njs_value_t *retval)
 {
     uint32_t            length;
     njs_array_t         *array;
@@ -1896,7 +1855,7 @@ njs_vmcode_array(njs_vm_t *vm, u_char *pc)
             array->length = 0;
         }
 
-        njs_set_array(&vm->retval, array);
+        njs_set_array(retval, array);
 
         return sizeof(njs_vmcode_array_t);
     }
@@ -1906,7 +1865,7 @@ njs_vmcode_array(njs_vm_t *vm, u_char *pc)
 
 
 static njs_jump_off_t
-njs_vmcode_function(njs_vm_t *vm, u_char *pc)
+njs_vmcode_function(njs_vm_t *vm, u_char *pc, njs_value_t *retval)
 {
     njs_function_t         *function;
     njs_vmcode_function_t  *code;
@@ -1926,7 +1885,7 @@ njs_vmcode_function(njs_vm_t *vm, u_char *pc)
 
     function->args_count = lambda->nargs - lambda->rest_parameters;
 
-    njs_set_function(&vm->retval, function);
+    njs_set_function(retval, function);
 
     return sizeof(njs_vmcode_function_t);
 }
@@ -1963,7 +1922,7 @@ njs_vmcode_arguments(njs_vm_t *vm, u_char *pc)
 
 
 static njs_jump_off_t
-njs_vmcode_regexp(njs_vm_t *vm, u_char *pc)
+njs_vmcode_regexp(njs_vm_t *vm, u_char *pc, njs_value_t *retval)
 {
     njs_regexp_t         *regexp;
     njs_vmcode_regexp_t  *code;
@@ -1973,7 +1932,7 @@ njs_vmcode_regexp(njs_vm_t *vm, u_char *pc)
     regexp = njs_regexp_alloc(vm, code->pattern);
 
     if (njs_fast_path(regexp != NULL)) {
-        njs_set_regexp(&vm->retval, regexp);
+        njs_set_regexp(retval, regexp);
 
         return sizeof(njs_vmcode_regexp_t);
     }
@@ -2119,6 +2078,7 @@ njs_vmcode_proto_init(njs_vm_t *vm, njs_value_t *value, njs_value_t *unused,
     njs_value_t *init)
 {
     njs_object_t        *obj;
+    njs_value_t         retval;
     njs_jump_off_t      ret;
     njs_object_prop_t   *prop;
     njs_lvlhsh_query_t  lhq;
@@ -2141,7 +2101,7 @@ njs_vmcode_proto_init(njs_vm_t *vm, njs_value_t *value, njs_value_t *unused,
         goto fail;
     }
 
-    ret = njs_prop_handler(prop)(vm, prop, value, init, &vm->retval);
+    ret = njs_prop_handler(prop)(vm, prop, value, init, &retval);
     if (njs_slow_path(ret != NJS_OK)) {
         goto fail;
     }
@@ -2156,7 +2116,8 @@ fail:
 
 
 static njs_jump_off_t
-njs_vmcode_property_in(njs_vm_t *vm, njs_value_t *value, njs_value_t *key)
+njs_vmcode_property_in(njs_vm_t *vm, njs_value_t *value, njs_value_t *key,
+    njs_value_t *retval)
 {
     njs_int_t             ret;
     njs_value_t           primitive;
@@ -2184,7 +2145,7 @@ njs_vmcode_property_in(njs_vm_t *vm, njs_value_t *value, njs_value_t *key)
         return ret;
     }
 
-    njs_set_boolean(&vm->retval, ret == NJS_OK);
+    njs_set_boolean(retval, ret == NJS_OK);
 
     return sizeof(njs_vmcode_3addr_t);
 }
@@ -2192,7 +2153,7 @@ njs_vmcode_property_in(njs_vm_t *vm, njs_value_t *value, njs_value_t *key)
 
 static njs_jump_off_t
 njs_vmcode_property_foreach(njs_vm_t *vm, njs_value_t *object,
-    njs_value_t *invld, u_char *pc)
+    u_char *pc, njs_value_t *retval)
 {
     njs_property_next_t        *next;
     njs_vmcode_prop_foreach_t  *code;
@@ -2211,7 +2172,7 @@ njs_vmcode_property_foreach(njs_vm_t *vm, njs_value_t *object,
         return NJS_ERROR;
     }
 
-    njs_set_data(&vm->retval, next, NJS_DATA_TAG_FOREACH_NEXT);
+    njs_set_data(retval, next, NJS_DATA_TAG_FOREACH_NEXT);
 
     code = (njs_vmcode_prop_foreach_t *) pc;
 
@@ -2221,13 +2182,12 @@ njs_vmcode_property_foreach(njs_vm_t *vm, njs_value_t *object,
 
 static njs_jump_off_t
 njs_vmcode_instance_of(njs_vm_t *vm, njs_value_t *object,
-    njs_value_t *constructor)
+    njs_value_t *constructor, njs_value_t *retval)
 {
-    njs_value_t        value, bound;
-    njs_object_t       *prototype, *proto;
-    njs_function_t     *function;
-    njs_jump_off_t     ret;
-    const njs_value_t  *retval;
+    njs_value_t     value, bound;
+    njs_object_t    *prototype, *proto;
+    njs_function_t  *function;
+    njs_jump_off_t  ret;
 
     static const njs_value_t prototype_string = njs_string("prototype");
 
@@ -2244,8 +2204,6 @@ njs_vmcode_instance_of(njs_vm_t *vm, njs_value_t *object,
         constructor = &bound;
     }
 
-    retval = &njs_value_false;
-
     if (njs_is_object(object)) {
         ret = njs_value_property(vm, constructor,
                                  njs_value_arg(&prototype_string), &value);
@@ -2268,22 +2226,22 @@ njs_vmcode_instance_of(njs_vm_t *vm, njs_value_t *object,
                 proto = proto->__proto__;
 
                 if (proto == prototype) {
-                    retval = &njs_value_true;
-                    break;
+                    njs_value_assign(retval, &njs_value_true);
+                    return sizeof(njs_vmcode_instance_of_t);
                 }
 
             } while (proto != NULL);
         }
     }
 
-    vm->retval = *retval;
+    njs_value_assign(retval, &njs_value_false);
 
     return sizeof(njs_vmcode_instance_of_t);
 }
 
 
 static njs_jump_off_t
-njs_vmcode_typeof(njs_vm_t *vm, njs_value_t *value, njs_value_t *invld)
+njs_vmcode_typeof(njs_vm_t *vm, njs_value_t *value, njs_value_t *retval)
 {
     /* ECMAScript 5.1: null, array and regexp are objects. */
 
@@ -2317,14 +2275,14 @@ njs_vmcode_typeof(njs_vm_t *vm, njs_value_t *value, njs_value_t *invld)
         &njs_string_object,
     };
 
-    vm->retval = *types[value->type];
+    njs_value_assign(retval, types[value->type]);
 
     return sizeof(njs_vmcode_2addr_t);
 }
 
 
 static njs_jump_off_t
-njs_vmcode_debugger(njs_vm_t *vm)
+njs_vmcode_debugger(njs_vm_t *vm, njs_value_t *retval)
 {
     /*
      * HOW TO DEBUG JS CODE:
@@ -2341,14 +2299,15 @@ njs_vmcode_debugger(njs_vm_t *vm)
      * 3) in gdb: p *njs_scope_value_get(vm, <index as a hex literal>)
      **/
 
-    njs_set_undefined(&vm->retval);
+    njs_set_undefined(retval);
 
     return sizeof(njs_vmcode_debugger_t);
 }
 
 
 static njs_jump_off_t
-njs_string_concat(njs_vm_t *vm, njs_value_t *val1, njs_value_t *val2)
+njs_string_concat(njs_vm_t *vm, njs_value_t *val1, njs_value_t *val2,
+    njs_value_t *retval)
 {
     u_char             *start;
     size_t             size, length;
@@ -2369,8 +2328,7 @@ njs_string_concat(njs_vm_t *vm, njs_value_t *val1, njs_value_t *val2)
 
     size = string1.size + string2.size;
 
-    start = njs_string_alloc(vm, &vm->retval, size, length);
-
+    start = njs_string_alloc(vm, retval, size, length);
     if (njs_slow_path(start == NULL)) {
         return NJS_ERROR;
     }
@@ -2601,8 +2559,8 @@ njs_function_new_object(njs_vm_t *vm, njs_value_t *constructor)
 }
 
 
-static njs_jump_off_t
-njs_vmcode_return(njs_vm_t *vm, njs_value_t *invld, njs_value_t *retval)
+static void
+njs_vmcode_return(njs_vm_t *vm, njs_value_t *dst, njs_value_t *retval)
 {
     njs_frame_t  *frame;
 
@@ -2619,11 +2577,9 @@ njs_vmcode_return(njs_vm_t *vm, njs_value_t *invld, njs_value_t *retval)
 
     njs_vm_scopes_restore(vm, &frame->native);
 
-    *frame->native.retval = *retval;
+    *dst = *retval;
 
     njs_function_frame_free(vm, &frame->native);
-
-    return NJS_OK;
 }
 
 
@@ -2682,14 +2638,14 @@ njs_vmcode_import(njs_vm_t *vm, njs_mod_t *module, njs_value_t *retval)
 }
 
 
-static njs_jump_off_t
+static njs_int_t
 njs_vmcode_await(njs_vm_t *vm, njs_vmcode_await_t *await,
-    njs_promise_capability_t *pcap, njs_async_ctx_t *ctx)
+    njs_value_t *dst, njs_promise_capability_t *pcap, njs_async_ctx_t *ctx)
 {
     size_t              size;
     njs_int_t           ret;
     njs_frame_t         *frame;
-    njs_value_t         ctor, val, on_fulfilled, on_rejected, *value;
+    njs_value_t         ctor, val, on_fulfilled, on_rejected, *value, retval;
     njs_promise_t       *promise;
     njs_function_t      *fulfilled, *rejected;
     njs_native_frame_t  *active;
@@ -2767,12 +2723,13 @@ njs_vmcode_await(njs_vm_t *vm, njs_vmcode_await_t *await,
     njs_set_function(&on_fulfilled, fulfilled);
     njs_set_function(&on_rejected, rejected);
 
-    ret = njs_promise_perform_then(vm, &val, &on_fulfilled, &on_rejected, NULL);
+    ret = njs_promise_perform_then(vm, &val, &on_fulfilled, &on_rejected, NULL,
+                                   &retval);
     if (njs_slow_path(ret != NJS_OK)) {
         return NJS_ERROR;
     }
 
-    (void) njs_vmcode_return(vm, NULL, &vm->retval);
+    njs_vmcode_return(vm, dst, &retval);
 
     return NJS_AGAIN;
 }
@@ -2888,7 +2845,7 @@ njs_vmcode_try_end(njs_vm_t *vm, njs_value_t *invld, njs_value_t *offset)
  */
 
 static njs_jump_off_t
-njs_vmcode_finally(njs_vm_t *vm, njs_value_t *invld, njs_value_t *retval,
+njs_vmcode_finally(njs_vm_t *vm, njs_value_t *dst, njs_value_t *retval,
     u_char *pc)
 {
     njs_value_t           *exception_value, *exit_value;
@@ -2898,7 +2855,7 @@ njs_vmcode_finally(njs_vm_t *vm, njs_value_t *invld, njs_value_t *retval,
     exception_value = njs_scope_value(vm, (njs_index_t) retval);
 
     if (njs_is_valid(exception_value)) {
-        vm->retval = *exception_value;
+        njs_vm_throw(vm, exception_value);
 
         return NJS_ERROR;
     }
@@ -2916,7 +2873,9 @@ njs_vmcode_finally(njs_vm_t *vm, njs_value_t *invld, njs_value_t *retval,
      */
 
     if (njs_is_valid(exit_value)) {
-        return njs_vmcode_return(vm, NULL, exit_value);
+        njs_vmcode_return(vm, dst, exit_value);
+
+        return NJS_OK;
 
     } else if (njs_number(exit_value) != 0) {
         offset = (njs_number(exit_value) > 0) ? finally->break_offset
@@ -2949,7 +2908,7 @@ njs_vmcode_error(njs_vm_t *vm, u_char *pc)
         njs_reference_error(vm, "\"%V\" is not defined", &err->u.name);
 
     } else {
-        njs_error_fmt_new(vm, &vm->retval, err->type, "%V", &err->u.message);
+        njs_throw_error(vm, err->type, "%V", &err->u.message);
     }
 }
 
index 3fdb13af6f80442c12a57c49e2926f25500da30e..88e5016432a343919551e77a57f9f52ce1b6b453 100644 (file)
@@ -421,7 +421,7 @@ typedef struct {
 } njs_vmcode_await_t;
 
 
-njs_int_t njs_vmcode_interpreter(njs_vm_t *vm, u_char *pc,
+njs_int_t njs_vmcode_interpreter(njs_vm_t *vm, u_char *pc, njs_value_t *retval,
     void *promise_cap, void *async_ctx);
 
 njs_object_t *njs_function_new_object(njs_vm_t *vm, njs_value_t *constructor);
index 0030e992cdf8de64b9dfe8f685571a60baa19875..2c2c1b651de848ffb5db9e8a5f1ee51a66f80e8d 100644 (file)
@@ -33,15 +33,15 @@ static njs_int_t
 njs_benchmark_test(njs_vm_t *parent, njs_opts_t *opts, njs_value_t *report,
     njs_benchmark_test_t *test)
 {
-    u_char                *start;
-    njs_vm_t              *vm, *nvm;
-    uint64_t              ns;
-    njs_int_t             ret, proto_id;
-    njs_str_t             s, *expected;
-    njs_uint_t            i, n;
-    njs_bool_t            success;
-    njs_value_t           *result, name, usec, times;
-    njs_vm_opt_t          options;
+    u_char        *start;
+    njs_vm_t      *vm, *nvm;
+    uint64_t      ns;
+    njs_int_t     ret, proto_id;
+    njs_str_t     s, *expected;
+    njs_uint_t    i, n;
+    njs_bool_t    success;
+    njs_value_t   *result, retval, name, usec, times;
+    njs_vm_opt_t  options;
 
     static const njs_value_t  name_key = njs_string("name");
     static const njs_value_t  usec_key = njs_string("usec");
@@ -86,10 +86,10 @@ njs_benchmark_test(njs_vm_t *parent, njs_opts_t *opts, njs_value_t *report,
             goto done;
         }
 
-        (void) njs_vm_start(nvm);
+        (void) njs_vm_start(nvm, &retval);
 
-        if (njs_vm_retval_string(nvm, &s) != NJS_OK) {
-            njs_printf("njs_vm_retval_string() failed\n");
+        if (njs_vm_value_string(nvm, &s, &retval) != NJS_OK) {
+            njs_printf("njs_vm_value_string() failed\n");
             goto done;
         }
 
@@ -397,7 +397,7 @@ main(int argc, char **argv)
     njs_str_t             out;
     njs_uint_t            i;
     njs_opts_t            opts;
-    njs_value_t           args[2], report;
+    njs_value_t           args[2], report, retval;
     njs_vm_opt_t          options;
     njs_benchmark_test_t  *test;
 
@@ -477,7 +477,7 @@ main(int argc, char **argv)
         goto done;
     }
 
-    njs_vm_start(vm);
+    njs_vm_start(vm, &retval);
 
     ret = njs_vm_array_alloc(vm, &report, 8);
     if (ret != NJS_OK) {
@@ -513,11 +513,12 @@ main(int argc, char **argv)
 
         args[1] = report;
 
-        njs_vm_call(vm, njs_vm_function(vm, &compare), njs_value_arg(&args), 2);
+        njs_vm_invoke(vm, njs_vm_function(vm, &compare), njs_value_arg(&args),
+                      2, &retval);
 
-        ret = njs_vm_value_dump(vm, &out, njs_vm_retval(vm), 1, 1);
+        ret = njs_vm_value_dump(vm, &out, &retval, 1, 1);
         if (ret != NJS_OK) {
-            njs_printf("njs_vm_retval_dump() failed\n");
+            njs_printf("njs_vm_value_dump() failed\n");
             goto done;
         }
 
@@ -527,15 +528,15 @@ main(int argc, char **argv)
     }
 
     if (opts.dump_report) {
-        ret = njs_vm_json_stringify(vm, &report, 1);
+        ret = njs_vm_json_stringify(vm, &report, 1, &retval);
         if (ret != NJS_OK) {
             njs_printf("njs_vm_json_stringify() failed\n");
             goto done;
         }
 
-        ret = njs_vm_value_dump(vm, &out, njs_vm_retval(vm), 1, 1);
+        ret = njs_vm_value_dump(vm, &out, &retval, 1, 1);
         if (ret != NJS_OK) {
-            njs_printf("njs_vm_retval_dump() failed\n");
+            njs_printf("njs_vm_value_dump() failed\n");
             goto done;
         }
 
index ddf20f40ea3d4635031b0be4fa6639967e65b8f1..80f27a9f091068dad4cb6f5260b216b7fb46ee5b 100644 (file)
@@ -348,7 +348,7 @@ njs_unit_test_r_header_keys(njs_vm_t *vm, njs_value_t *value, njs_value_t *keys)
 
 static njs_int_t
 njs_unit_test_r_method(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_int_t            ret;
     njs_str_t            s;
@@ -362,11 +362,10 @@ njs_unit_test_r_method(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     ret = njs_vm_value_to_bytes(vm, &s, njs_arg(args, nargs, 1));
     if (ret == NJS_OK && s.length == 3 && memcmp(s.start, "YES", 3) == 0) {
-        return njs_vm_value_string_set(vm, njs_vm_retval(vm), r->uri.start,
-                                       r->uri.length);
+        return njs_vm_value_string_set(vm, retval, r->uri.start, r->uri.length);
     }
 
-    njs_set_undefined(&vm->retval);
+    njs_set_undefined(retval);
 
     return NJS_OK;
 }
@@ -374,14 +373,14 @@ njs_unit_test_r_method(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_unit_test_promise_trampoline(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)
 {
     njs_function_t  *callback;
 
     callback = njs_value_function(njs_argument(args, 1));
 
     if (callback != NULL) {
-        return njs_vm_call(vm, callback, njs_argument(args, 2), 1);
+        return njs_vm_invoke(vm, callback, njs_argument(args, 2), 1, retval);
     }
 
     return NJS_OK;
@@ -390,10 +389,10 @@ njs_unit_test_promise_trampoline(njs_vm_t *vm, njs_value_t *args,
 
 static njs_int_t
 njs_unit_test_r_subrequest(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_int_t            ret;
-    njs_value_t          retval, *argument, *select;
+    njs_value_t          value, *argument, *select;
     njs_vm_event_t       vm_event;
     njs_function_t       *callback;
     njs_external_ev_t    *ev;
@@ -412,7 +411,7 @@ njs_unit_test_r_subrequest(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    ret = njs_vm_promise_create(vm, &retval, &ev->callbacks[0]);
+    ret = njs_vm_promise_create(vm, &value, &ev->callbacks[0]);
     if (ret != NJS_OK) {
         return NJS_ERROR;
     }
@@ -442,7 +441,7 @@ njs_unit_test_r_subrequest(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     njs_queue_insert_tail(&env->events, &ev->link);
 
-    njs_vm_retval_set(vm, njs_value_arg(&retval));
+    njs_value_assign(retval, &value);
 
     return NJS_OK;
 }
@@ -450,7 +449,7 @@ njs_unit_test_r_subrequest(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_unit_test_r_retval(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_external_env_t  *env;
 
@@ -458,7 +457,7 @@ njs_unit_test_r_retval(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
     njs_value_assign(&env->retval, njs_arg(args, nargs, 1));
 
-    njs_set_undefined(&vm->retval);
+    njs_set_undefined(retval);
 
     return NJS_OK;
 }
@@ -466,7 +465,7 @@ njs_unit_test_r_retval(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_unit_test_r_create(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_int_t            ret;
     njs_unit_test_req_t  *r, *sr;
@@ -488,7 +487,7 @@ njs_unit_test_r_create(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    ret = njs_vm_external_create(vm, &vm->retval, njs_external_r_proto_id,
+    ret = njs_vm_external_create(vm, retval, njs_external_r_proto_id,
                                  sr, 0);
     if (ret != NJS_OK) {
         return NJS_ERROR;
@@ -506,7 +505,7 @@ memory_error:
 
 static njs_int_t
 njs_unit_test_r_bind(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            name;
     njs_unit_test_req_t  *r;
@@ -527,7 +526,7 @@ njs_unit_test_r_bind(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
 
 static njs_int_t
 njs_unit_test_constructor(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_unit_test_req_t  *sr;
 
@@ -543,7 +542,7 @@ njs_unit_test_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
-    return njs_vm_external_create(vm, &vm->retval, njs_external_r_proto_id,
+    return njs_vm_external_create(vm, retval, njs_external_r_proto_id,
                                   sr, 0);
 }
 
index 65d5e993a0e84f2f83c1ef684bddc8b20ca99fdc..c04a587dfb0488b557317e84e4d1d08b3bb4263f 100644 (file)
@@ -13311,6 +13311,12 @@ static njs_unit_test_t  njs_test[] =
     { njs_str("var b = new Boolean(1); b.__proto__ === Boolean.prototype"),
       njs_str("true") },
 
+    { njs_str("Boolean(1).toString() === 'true'"),
+      njs_str("true") },
+
+    { njs_str("Boolean(0).toString() === 'false'"),
+      njs_str("true") },
+
     { njs_str("Number()"),
       njs_str("0") },
 
@@ -23366,6 +23372,8 @@ typedef struct {
 
 typedef struct {
     njs_vm_t            *vm;
+    njs_value_t         retval;
+
     njs_external_env_t  *env;
     njs_external_env_t  env0;
 
@@ -23438,13 +23446,16 @@ njs_external_state_init(njs_vm_t *vm, njs_external_state_t *s, njs_opts_t *opts)
 
 
 static njs_int_t
-njs_external_retval(njs_external_state_t *state, njs_str_t *s)
+njs_external_retval(njs_external_state_t *state, njs_int_t ret, njs_str_t *s)
 {
-    if (state->env != NULL && njs_value_is_valid(&state->env->retval)) {
+    if (state->env != NULL
+        && ret == NJS_OK
+        && njs_value_is_valid(&state->env->retval))
+    {
         return njs_vm_value_string(state->vm, s, &state->env->retval);
     }
 
-    return njs_vm_retval_string(state->vm, s);
+    return njs_vm_value_string(state->vm, s, &state->retval);
 }
 
 
@@ -23530,11 +23541,13 @@ njs_process_test(njs_external_state_t *state, njs_opts_t *opts,
     static const njs_str_t  handler_str = njs_str("main.handler");
     static const njs_str_t  request_str = njs_str("$r");
 
+    ret = NJS_OK;
+
     switch (state->state) {
     case sw_start:
         state->state = sw_handler;
 
-        ret = njs_vm_start(state->vm);
+        ret = njs_vm_start(state->vm, &state->retval);
         if (ret != NJS_OK) {
             goto done;
         }
@@ -23597,7 +23610,7 @@ done:
 
     state->state = sw_done;
 
-    if (njs_external_retval(state, &s) != NJS_OK) {
+    if (njs_external_retval(state, ret, &s) != NJS_OK) {
         njs_stderror("njs_external_retval() failed\n");
         return NJS_ERROR;
     }
@@ -23706,8 +23719,8 @@ njs_unit_test(njs_unit_test_t tests[], size_t num, njs_str_t *name,
 
         } else {
             if (ret != NJS_OK) {
-                if (njs_vm_retval_string(vm, &s) != NJS_OK) {
-                    njs_printf("njs_vm_retval_string() failed\n");
+                if (njs_vm_exception_string(vm, &s) != NJS_OK) {
+                    njs_printf("njs_vm_exception_string() failed\n");
                     goto done;
                 }
 
@@ -23764,6 +23777,7 @@ njs_interactive_test(njs_unit_test_t tests[], size_t num, njs_str_t *name,
     njs_uint_t    i;
     njs_stat_t    prev;
     njs_bool_t    success;
+    njs_value_t   retval;
     njs_vm_opt_t  options;
 
     vm = NULL;
@@ -23820,12 +23834,12 @@ njs_interactive_test(njs_unit_test_t tests[], size_t num, njs_str_t *name,
                     njs_disassembler(vm);
                 }
 
-                ret = njs_vm_start(vm);
+                ret = njs_vm_start(vm, &retval);
             }
         }
 
-        if (njs_vm_retval_dump(vm, &s, 0) != NJS_OK) {
-            njs_printf("njs_vm_retval_dump() failed\n");
+        if (njs_vm_value_dump(vm, &s, &retval, 0, 1) != NJS_OK) {
+            njs_printf("njs_vm_value_dump() failed\n");
             goto done;
         }
 
@@ -23959,7 +23973,7 @@ njs_vm_json_test(njs_unit_test_t unused[], size_t num, njs_str_t *name,
     njs_uint_t    i;
     njs_bool_t    success;
     njs_stat_t    prev;
-    njs_value_t   args[3];
+    njs_value_t   args[3], retval;
     njs_vm_opt_t  options;
 
     static const njs_str_t fname = njs_str("replacer");
@@ -24009,32 +24023,30 @@ njs_vm_json_test(njs_unit_test_t unused[], size_t num, njs_str_t *name,
             goto done;
         }
 
-        ret = njs_vm_start(vm);
+        ret = njs_vm_start(vm, &args[0]);
         if (ret != NJS_OK) {
-            njs_printf("njs_vm_run() failed\n");
+            njs_printf("njs_vm_start() failed\n");
             goto done;
         }
 
-        args[0] = *njs_vm_retval(vm);
-
-        ret = njs_vm_json_parse(vm, args, 1);
+        ret = njs_vm_json_parse(vm, args, 1, &retval);
         if (ret != NJS_OK) {
             njs_printf("njs_vm_json_parse() failed\n");
             goto done;
         }
 
-        args[0] = vm->retval;
+        njs_value_assign(&args[0], &retval);
         njs_vm_value(vm, &fname, &args[1]);
         njs_vm_value(vm, &iname, &args[2]);
 
-        ret = njs_vm_json_stringify(vm, args, 3);
+        ret = njs_vm_json_stringify(vm, args, 3, &retval);
         if (ret != NJS_OK) {
             njs_printf("njs_vm_json_stringify() failed\n");
             goto done;
         }
 
-        if (njs_vm_retval_string(vm, &s) != NJS_OK) {
-            njs_printf("njs_vm_retval_string() failed\n");
+        if (njs_vm_value_string(vm, &s, &retval) != NJS_OK) {
+            njs_printf("njs_vm_value_string() failed\n");
             goto done;
         }
 
@@ -24061,8 +24073,8 @@ njs_vm_json_test(njs_unit_test_t unused[], size_t num, njs_str_t *name,
 done:
 
     if (ret != NJS_OK) {
-        if (njs_vm_retval_string(vm, &s) != NJS_OK) {
-            njs_printf("njs_vm_retval_string() failed\n");
+        if (njs_vm_exception_string(vm, &s) != NJS_OK) {
+            njs_printf("njs_vm_exception_string() failed\n");
 
         } else {
             njs_printf("%V\n", &s);
@@ -24089,6 +24101,7 @@ njs_vm_value_test(njs_unit_test_t unused[], size_t num, njs_str_t *name,
     njs_uint_t    i;
     njs_bool_t    success;
     njs_stat_t    prev;
+    njs_value_t   retval;
     njs_vm_opt_t  options;
 
     static struct {
@@ -24171,7 +24184,7 @@ njs_vm_value_test(njs_unit_test_t unused[], size_t num, njs_str_t *name,
             goto done;
         }
 
-        ret = njs_vm_start(vm);
+        ret = njs_vm_start(vm, &retval);
         if (ret != NJS_OK) {
             njs_printf("njs_vm_run() failed\n");
             goto done;
@@ -24187,11 +24200,19 @@ njs_vm_value_test(njs_unit_test_t unused[], size_t num, njs_str_t *name,
 
         memcpy(path.start, tests[i].path.start, path.length);
 
-        ret = njs_vm_value(vm, &path, &vm->retval);
+        ret = njs_vm_value(vm, &path, &retval);
 
-        if (njs_vm_retval_string(vm, &s) != NJS_OK) {
-            njs_printf("njs_vm_retval_string() failed\n");
-            goto done;
+        if (ret == NJS_OK) {
+            if (njs_vm_value_string(vm, &s, &retval) != NJS_OK) {
+                njs_printf("njs_vm_value_string() failed\n");
+                goto done;
+            }
+
+        } else {
+            if (njs_vm_exception_string(vm, &s) != NJS_OK) {
+                njs_printf("njs_vm_exception_string() failed\n");
+                goto done;
+            }
         }
 
         success = njs_strstr_eq(&tests[i].ret, &s);
@@ -24217,8 +24238,8 @@ njs_vm_value_test(njs_unit_test_t unused[], size_t num, njs_str_t *name,
 done:
 
     if (ret != NJS_OK) {
-        if (njs_vm_retval_string(vm, &s) != NJS_OK) {
-            njs_printf("njs_vm_retval_string() failed\n");
+        if (njs_vm_exception_string(vm, &s) != NJS_OK) {
+            njs_printf("njs_vm_exception_string() failed\n");
 
         } else {
             njs_printf("%V\n", &s);
@@ -24643,10 +24664,11 @@ failed:
 static njs_int_t
 njs_string_to_index_test(njs_vm_t *vm, njs_opts_t *opts, njs_stat_t *stat)
 {
-    njs_str_t   s, string;
-    njs_int_t   ret;
-    njs_bool_t  success, is_integer_index;
-    njs_uint_t  i;
+    njs_str_t    s, string;
+    njs_int_t    ret;
+    njs_bool_t   success, is_integer_index;
+    njs_uint_t   i;
+    njs_value_t  value;
 
     static const struct {
         njs_value_t  value;
@@ -24680,12 +24702,12 @@ njs_string_to_index_test(njs_vm_t *vm, njs_opts_t *opts, njs_stat_t *stat)
 
     for (i = 0; i < njs_nitems(tests); i++) {
         if (njs_is_string(&tests[i].value)) {
-            njs_set_number(&vm->retval, njs_string_to_index(&tests[i].value));
+            njs_set_number(&value, njs_string_to_index(&tests[i].value));
 
-            ret = njs_vm_retval_dump(vm, &s, 0);
+            ret = njs_vm_value_dump(vm, &s, &value, 0, 0);
             if (ret != NJS_OK) {
                 njs_printf("njs_string_to_index_test: "
-                           "njs_vm_retval_dump() failed\n");
+                           "njs_vm_value_dump() failed\n");
                 return NJS_ERROR;
             }
 
@@ -24702,7 +24724,7 @@ njs_string_to_index_test(njs_vm_t *vm, njs_opts_t *opts, njs_stat_t *stat)
             }
         }
 
-        is_integer_index = njs_key_is_integer_index(njs_number(&vm->retval),
+        is_integer_index = njs_key_is_integer_index(njs_number(&value),
                                                     &tests[i].value);
 
         if (tests[i].is_integer_index != is_integer_index) {