diff options
author | Dmitry Volyntsev <xeioex@nginx.com> | 2023-04-19 00:20:37 -0700 |
---|---|---|
committer | Dmitry Volyntsev <xeioex@nginx.com> | 2023-04-19 00:20:37 -0700 |
commit | dbbe69a83bd67788b8a0269f28bde5a29c3b7f8d (patch) | |
tree | a295f52bfcac07482a50a606e17c53f0c1ddf676 /nginx/ngx_js.c | |
parent | c89eb033d5b5ab62c9f84a421b7b8e92264a4101 (diff) | |
download | njs-dbbe69a83bd67788b8a0269f28bde5a29c3b7f8d.tar.gz njs-dbbe69a83bd67788b8a0269f28bde5a29c3b7f8d.zip |
Change: native methods are provided with retval argument.
Previously, native methods were expected to return
their retval using vm->retval. This caused problem in the part
(1aa137411b09, 293fe42c5e1c) because vm->retval can be overwritten
unexpectedly as a side-effect of operations like ToString(), ToNumber().
The fix is to never used a global retval. Instead methods
are provided with a retval argument to store their retval value.
As a part of the change, retval and exception values are split.
The normal value is returned in the retval argument.
The exception value is thrown by njs_vm_throw() or njs_vm_error().
The exception value can be acquired using njs_vm_exception_get().
Diffstat (limited to 'nginx/ngx_js.c')
-rw-r--r-- | nginx/ngx_js.c | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/nginx/ngx_js.c b/nginx/ngx_js.c index b90dafa6..2b5be2ce 100644 --- a/nginx/ngx_js.c +++ b/nginx/ngx_js.c @@ -99,6 +99,16 @@ 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; ngx_str_t exception; @@ -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); |