From: Dmitry Volyntsev Date: Sat, 6 Mar 2021 12:42:30 +0000 (+0000) Subject: Introduced njs.on('exit') callback support. X-Git-Tag: 0.5.2~2 X-Git-Url: http://www.kaiwu.me/postgresql/commit/static/gitweb.js?a=commitdiff_plain;h=5338d8a74a75d01aa394d5a1c20a745c46cc67d2;p=njs.git Introduced njs.on('exit') callback support. --- diff --git a/src/njs_builtin.c b/src/njs_builtin.c index 1d6ff5d0..6a06052e 100644 --- a/src/njs_builtin.c +++ b/src/njs_builtin.c @@ -851,7 +851,7 @@ found: static njs_int_t -njs_dump_value(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, +njs_ext_dump(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused) { uint32_t n; @@ -877,6 +877,62 @@ njs_dump_value(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } +static njs_int_t +njs_ext_on(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, + njs_index_t unused) +{ + njs_str_t type; + njs_uint_t i, n; + njs_value_t *value; + + static const struct { + njs_str_t name; + njs_uint_t id; + } hooks[] = { + { + njs_str("exit"), + NJS_HOOK_EXIT + }, + }; + + value = njs_arg(args, nargs, 1); + + if (njs_slow_path(!njs_is_string(value))) { + njs_type_error(vm, "hook type is not a string"); + return NJS_ERROR; + } + + njs_string_get(value, &type); + + i = 0; + n = sizeof(hooks) / sizeof(hooks[0]); + + while (i < n) { + if (njs_strstr_eq(&type, &hooks[i].name)) { + break; + } + + i++; + } + + if (i == n) { + njs_type_error(vm, "unknown hook type \"%V\"", &type); + return NJS_ERROR; + } + + value = njs_arg(args, nargs, 2); + + if (njs_slow_path(!njs_is_function(value) && !njs_is_null(value))) { + njs_type_error(vm, "callback is not a function or null"); + return NJS_ERROR; + } + + vm->hooks[i] = njs_is_function(value) ? njs_function(value) : NULL; + + return NJS_OK; +} + + static njs_int_t njs_global_this_prop_handler(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *global, njs_value_t *setval, njs_value_t *retval) @@ -1629,7 +1685,14 @@ static const njs_object_prop_t njs_njs_object_properties[] = { .type = NJS_PROPERTY, .name = njs_string("dump"), - .value = njs_native_function(njs_dump_value, 0), + .value = njs_native_function(njs_ext_dump, 0), + .configurable = 1, + }, + + { + .type = NJS_PROPERTY, + .name = njs_string("on"), + .value = njs_native_function(njs_ext_on, 0), .configurable = 1, }, }; diff --git a/src/njs_vm.c b/src/njs_vm.c index 366a5e55..22e4ee7d 100644 --- a/src/njs_vm.c +++ b/src/njs_vm.c @@ -91,6 +91,10 @@ njs_vm_destroy(njs_vm_t *vm) njs_event_t *event; njs_lvlhsh_each_t lhe; + if (vm->hooks[NJS_HOOK_EXIT] != NULL) { + (void) njs_vm_call(vm, vm->hooks[NJS_HOOK_EXIT], NULL, 0); + } + if (njs_waiting_events(vm)) { njs_lvlhsh_each_init(&lhe, &njs_event_hash_proto); diff --git a/src/njs_vm.h b/src/njs_vm.h index 47f0f879..d6ac1b80 100644 --- a/src/njs_vm.h +++ b/src/njs_vm.h @@ -175,6 +175,12 @@ enum njs_object_e { + njs_scope_offset(index))) +enum njs_hook_e { + NJS_HOOK_EXIT = 0, + NJS_HOOK_MAX +}; + + struct njs_vm_s { /* njs_vm_t must be aligned to njs_value_t due to scratch value. */ njs_value_t retval; @@ -210,6 +216,8 @@ struct njs_vm_s { njs_object_prototype_t prototypes[NJS_OBJ_TYPE_MAX]; njs_function_t constructors[NJS_OBJ_TYPE_MAX]; + njs_function_t *hooks[NJS_HOOK_MAX]; + njs_mp_t *mem_pool; u_char *start; diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index ccc1de19..e49cc08f 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -17197,6 +17197,23 @@ static njs_unit_test_t njs_test[] = "decodeURI.name = 'XXX'; njs.dump(decodeURI)"), njs_str("[Function: XXX]") }, + /* njs.on(). */ + + { njs_str("njs.on(decodeURI)"), + njs_str("TypeError: hook type is not a string") }, + + { njs_str("njs.on('xxx')"), + njs_str("TypeError: unknown hook type \"xxx\"") }, + + { njs_str("njs.on('exit')"), + njs_str("TypeError: callback is not a function or null") }, + + { njs_str("njs.on('exit', null); 1"), + njs_str("1") }, + + { njs_str("njs.on('exit', ()=>{}); 1"), + njs_str("1") }, + /* Built-in methods name. */ { njs_str(