aboutsummaryrefslogtreecommitdiff
path: root/nginx/ngx_http_js_module.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_http_js_module.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_http_js_module.c')
-rw-r--r--nginx/ngx_http_js_module.c67
1 files changed, 36 insertions, 31 deletions
diff --git a/nginx/ngx_http_js_module.c b/nginx/ngx_http_js_module.c
index 8f3ca9e6..b9980f96 100644
--- a/nginx/ngx_http_js_module.c
+++ b/nginx/ngx_http_js_module.c
@@ -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;