aboutsummaryrefslogtreecommitdiff
path: root/nginx/ngx_js.c
diff options
context:
space:
mode:
authorDmitry Volyntsev <xeioex@nginx.com>2023-04-19 00:20:37 -0700
committerDmitry Volyntsev <xeioex@nginx.com>2023-04-19 00:20:37 -0700
commitdbbe69a83bd67788b8a0269f28bde5a29c3b7f8d (patch)
treea295f52bfcac07482a50a606e17c53f0c1ddf676 /nginx/ngx_js.c
parentc89eb033d5b5ab62c9f84a421b7b8e92264a4101 (diff)
downloadnjs-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.c26
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);