From ea4c0e2e47030c8f3d4a3133cb624b5bf5e8e427 Mon Sep 17 00:00:00 2001 From: Dmitry Volyntsev Date: Fri, 28 Dec 2018 12:42:29 +0300 Subject: [PATCH] njs_vm_run() is rectified. Previously, both njs_vm_call() and njs_vm_run() can be used to run njs code. njs_vm_call() was used to invoke a single function, while njs_vm_run() was used to run global code as well to process the events. At first invocation njs_vm_run() executed global code, all the next invocations it processed pending events. The solution is splitting njs_vm_run() into two functions. One for events processing and another for running the global code. --- nginx/ngx_http_js_module.c | 2 +- nginx/ngx_stream_js_module.c | 2 +- njs/njs.c | 25 ++++++++++++------------- njs/njs.h | 29 +++++++++++++++++++++++++++-- njs/njs_shell.c | 2 +- njs/test/njs_interactive_test.c | 2 +- njs/test/njs_unit_test.c | 2 +- 7 files changed, 44 insertions(+), 20 deletions(-) diff --git a/nginx/ngx_http_js_module.c b/nginx/ngx_http_js_module.c index 3121bad3..3f86c7ee 100644 --- a/nginx/ngx_http_js_module.c +++ b/nginx/ngx_http_js_module.c @@ -913,7 +913,7 @@ ngx_http_js_init_vm(ngx_http_request_t *r) cln->handler = ngx_http_js_cleanup_ctx; cln->data = ctx; - if (njs_vm_run(ctx->vm) == NJS_ERROR) { + if (njs_vm_start(ctx->vm) == NJS_ERROR) { njs_vm_retval_to_ext_string(ctx->vm, &exception); ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, diff --git a/nginx/ngx_stream_js_module.c b/nginx/ngx_stream_js_module.c index 7526bc18..708674b4 100644 --- a/nginx/ngx_stream_js_module.c +++ b/nginx/ngx_stream_js_module.c @@ -727,7 +727,7 @@ ngx_stream_js_init_vm(ngx_stream_session_t *s) cln->handler = ngx_stream_js_cleanup_ctx; cln->data = ctx; - if (njs_vm_run(ctx->vm) == NJS_ERROR) { + if (njs_vm_start(ctx->vm) == NJS_ERROR) { njs_vm_retval_to_ext_string(ctx->vm, &exception); ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, diff --git a/njs/njs.c b/njs/njs.c index 67801eb6..c956262e 100644 --- a/njs/njs.c +++ b/njs/njs.c @@ -595,27 +595,26 @@ njs_vm_post_event(njs_vm_t *vm, njs_vm_event_t vm_event, nxt_int_t njs_vm_run(njs_vm_t *vm) { - nxt_int_t ret; - if (nxt_slow_path(vm->backtrace != NULL)) { nxt_array_reset(vm->backtrace); } + return njs_vm_handle_events(vm); +} + + +nxt_int_t +njs_vm_start(njs_vm_t *vm) +{ + njs_ret_t ret; + ret = njs_vmcode_interpreter(vm); if (ret == NJS_STOP) { - ret = njs_vm_handle_events(vm); + ret = NJS_OK; } - switch (ret) { - case NJS_STOP: - return NJS_OK; - - case NXT_AGAIN: - case NXT_ERROR: - default: - return ret; - } + return ret; } @@ -653,7 +652,7 @@ njs_vm_handle_events(njs_vm_t *vm) } } - return njs_is_pending_events(vm) ? NJS_AGAIN : NJS_STOP; + return njs_is_pending_events(vm) ? NJS_AGAIN : NJS_OK; } diff --git a/njs/njs.h b/njs/njs.h index e3de4ff8..0368943d 100644 --- a/njs/njs.h +++ b/njs/njs.h @@ -162,8 +162,6 @@ NXT_EXPORT void njs_vm_destroy(njs_vm_t *vm); NXT_EXPORT nxt_int_t njs_vm_compile(njs_vm_t *vm, u_char **start, u_char *end); NXT_EXPORT njs_vm_t *njs_vm_clone(njs_vm_t *vm, njs_external_ptr_t external); -NXT_EXPORT nxt_int_t njs_vm_call(njs_vm_t *vm, njs_function_t *function, - const njs_value_t *args, nxt_uint_t nargs); NXT_EXPORT njs_vm_event_t njs_vm_add_event(njs_vm_t *vm, njs_function_t *function, nxt_uint_t once, njs_host_event_t host_ev, @@ -173,8 +171,35 @@ NXT_EXPORT nxt_int_t njs_vm_pending(njs_vm_t *vm); NXT_EXPORT nxt_int_t njs_vm_post_event(njs_vm_t *vm, njs_vm_event_t vm_event, const njs_value_t *args, nxt_uint_t nargs); +/* + * Runs the specified function with provided arguments. + * 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. + */ +NXT_EXPORT nxt_int_t njs_vm_call(njs_vm_t *vm, njs_function_t *function, + const njs_value_t *args, nxt_uint_t nargs); + +/* + * Runs posted events. + * NJS_OK successfully processed all posted events, no more events. + * 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. + */ NXT_EXPORT nxt_int_t njs_vm_run(njs_vm_t *vm); +/* + * Runs the global code. + * 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. + */ +NXT_EXPORT nxt_int_t njs_vm_start(njs_vm_t *vm); + NXT_EXPORT const njs_extern_t *njs_vm_external_prototype(njs_vm_t *vm, njs_external_t *external); NXT_EXPORT nxt_int_t njs_vm_external_create(njs_vm_t *vm, diff --git a/njs/njs_shell.c b/njs/njs_shell.c index 9564b698..8e1118dc 100644 --- a/njs/njs_shell.c +++ b/njs/njs_shell.c @@ -490,7 +490,7 @@ njs_process_script(njs_vm_t *vm, njs_opts_t *opts, const nxt_str_t *script, printf("\n"); } - ret = njs_vm_run(vm); + ret = njs_vm_start(vm); } if (njs_vm_retval_dump(vm, out, 1) != NXT_OK) { diff --git a/njs/test/njs_interactive_test.c b/njs/test/njs_interactive_test.c index d4c2d13d..c5aa73d5 100644 --- a/njs/test/njs_interactive_test.c +++ b/njs/test/njs_interactive_test.c @@ -285,7 +285,7 @@ njs_interactive_test(nxt_bool_t verbose) ret = njs_vm_compile(vm, &start, end); if (ret == NXT_OK) { - ret = njs_vm_run(vm); + ret = njs_vm_start(vm); } } diff --git a/njs/test/njs_unit_test.c b/njs/test/njs_unit_test.c index c5340f6d..fdc5aadb 100644 --- a/njs/test/njs_unit_test.c +++ b/njs/test/njs_unit_test.c @@ -11801,7 +11801,7 @@ njs_unit_test(njs_unit_test_t tests[], size_t num, nxt_bool_t disassemble, goto done; } - ret = njs_vm_run(nvm); + ret = njs_vm_start(nvm); if (njs_vm_retval_to_ext_string(nvm, &s) != NXT_OK) { printf("njs_vm_retval_to_ext_string() failed\n"); -- 2.47.3