From: Dmitry Volyntsev Date: Thu, 24 Dec 2020 18:35:18 +0000 (+0000) Subject: Refactored working with external prototypes. X-Git-Tag: 0.5.1~18 X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=49387a73bde3f8d5ac7f41078eed99c61d90c312;p=njs.git Refactored working with external prototypes. Previously, njs_vm_external_prototype() returned the pointer to a created prototype structure. Which were expected to be passed to njs_vm_external_create() as is. The returned pointer is needed to be stored somewhere by user code which complicates user code in cases when many prototypes are created. Instead, an index in the VM internal table is returned. njs_vm_external_create() is changed accordingly. This simplifies user code because the index is known at static time for most cases. --- diff --git a/nginx/ngx_http_js_module.c b/nginx/ngx_http_js_module.c index 9a6c5cd9..5bf28d3c 100644 --- a/nginx/ngx_http_js_module.c +++ b/nginx/ngx_http_js_module.c @@ -19,7 +19,6 @@ typedef struct { ngx_uint_t line; ngx_array_t *imports; ngx_array_t *paths; - njs_external_proto_t req_proto; } ngx_http_js_main_conf_t; @@ -836,7 +835,7 @@ ngx_http_js_init_vm(ngx_http_request_t *r) } rc = njs_vm_external_create(ctx->vm, njs_value_arg(&ctx->request), - jmcf->req_proto, r, 0); + NGX_JS_PROTO_MAIN, r, 0); if (rc != NJS_OK) { return NGX_ERROR; } @@ -2708,10 +2707,9 @@ ngx_http_js_subrequest_done(ngx_http_request_t *r, void *data, ngx_int_t rc) { njs_vm_event_t vm_event = data; - njs_int_t ret; - ngx_http_js_ctx_t *ctx; - njs_opaque_value_t reply; - ngx_http_js_main_conf_t *jmcf; + njs_int_t ret; + ngx_http_js_ctx_t *ctx; + njs_opaque_value_t reply; if (rc != NGX_OK || r->connection->error || r->buffered) { return rc; @@ -2734,8 +2732,6 @@ ngx_http_js_subrequest_done(ngx_http_request_t *r, void *data, ngx_int_t rc) ctx->done = 1; - jmcf = ngx_http_get_module_main_conf(r, ngx_http_js_module); - ctx = ngx_http_get_module_ctx(r->parent, ngx_http_js_module); ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, @@ -2750,7 +2746,7 @@ ngx_http_js_subrequest_done(ngx_http_request_t *r, void *data, ngx_int_t rc) } ret = njs_vm_external_create(ctx->vm, njs_value_arg(&reply), - jmcf->req_proto, r, 0); + NGX_JS_PROTO_MAIN, r, 0); if (ret != NJS_OK) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "js subrequest reply creation failed"); @@ -2954,7 +2950,7 @@ ngx_http_js_init_main_conf(ngx_conf_t *cf, void *conf) ssize_t n; ngx_fd_t fd; ngx_str_t *m, file; - njs_int_t rc; + njs_int_t rc, proto_id; njs_str_t text, path; ngx_uint_t i; njs_value_t *value; @@ -2962,7 +2958,6 @@ ngx_http_js_init_main_conf(ngx_conf_t *cf, void *conf) ngx_file_info_t fi; ngx_pool_cleanup_t *cln; njs_opaque_value_t lvalue, exception; - njs_external_proto_t proto; ngx_http_js_import_t *import; static const njs_str_t line_number_key = njs_str("lineNumber"); @@ -3114,16 +3109,14 @@ ngx_http_js_init_main_conf(ngx_conf_t *cf, void *conf) } } - proto = njs_vm_external_prototype(jmcf->vm, ngx_http_js_ext_request, - njs_nitems(ngx_http_js_ext_request)); - if (proto == NULL) { + proto_id = njs_vm_external_prototype(jmcf->vm, ngx_http_js_ext_request, + njs_nitems(ngx_http_js_ext_request)); + if (proto_id < 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "failed to add js request proto"); return NGX_CONF_ERROR; } - jmcf->req_proto = proto; - rc = ngx_js_core_init(jmcf->vm, cf->log); if (njs_slow_path(rc != NJS_OK)) { return NGX_CONF_ERROR; @@ -3379,7 +3372,6 @@ ngx_http_js_create_main_conf(ngx_conf_t *cf) * conf->include = { 0, NULL }; * conf->file = NULL; * conf->line = 0; - * conf->req_proto = NULL; */ conf->paths = NGX_CONF_UNSET_PTR; diff --git a/nginx/ngx_js.c b/nginx/ngx_js.c index 56b2bdd4..f47b916f 100644 --- a/nginx/ngx_js.c +++ b/nginx/ngx_js.c @@ -117,19 +117,18 @@ ngx_js_string(njs_vm_t *vm, njs_value_t *value, njs_str_t *str) ngx_int_t ngx_js_core_init(njs_vm_t *vm, ngx_log_t *log) { - njs_int_t ret; - njs_str_t name; - njs_opaque_value_t value; - njs_external_proto_t proto; - - proto = njs_vm_external_prototype(vm, ngx_js_ext_core, - njs_nitems(ngx_js_ext_core)); - if (proto == NULL) { + njs_int_t ret, proto_id; + njs_str_t name; + njs_opaque_value_t value; + + proto_id = njs_vm_external_prototype(vm, ngx_js_ext_core, + njs_nitems(ngx_js_ext_core)); + if (proto_id < 0) { ngx_log_error(NGX_LOG_EMERG, log, 0, "failed to add js core proto"); return NGX_ERROR; } - ret = njs_vm_external_create(vm, njs_value_arg(&value), proto, NULL, 1); + ret = njs_vm_external_create(vm, njs_value_arg(&value), proto_id, NULL, 1); if (njs_slow_path(ret != NJS_OK)) { ngx_log_error(NGX_LOG_EMERG, log, 0, "njs_vm_external_create() failed\n"); diff --git a/nginx/ngx_js.h b/nginx/ngx_js.h index 0e290d52..fe311244 100644 --- a/nginx/ngx_js.h +++ b/nginx/ngx_js.h @@ -19,6 +19,8 @@ #define NGX_JS_STRING 1 #define NGX_JS_BUFFER 2 +#define NGX_JS_PROTO_MAIN 0 + #define ngx_external_connection(vm, ext) \ (*((ngx_connection_t **) ((u_char *) ext + njs_vm_meta(vm, 0)))) diff --git a/nginx/ngx_stream_js_module.c b/nginx/ngx_stream_js_module.c index 0830b102..91852ba4 100644 --- a/nginx/ngx_stream_js_module.c +++ b/nginx/ngx_stream_js_module.c @@ -19,7 +19,6 @@ typedef struct { ngx_uint_t line; ngx_array_t *imports; ngx_array_t *paths; - njs_external_proto_t proto; } ngx_stream_js_main_conf_t; @@ -696,7 +695,7 @@ ngx_stream_js_init_vm(ngx_stream_session_t *s) } rc = njs_vm_external_create(ctx->vm, njs_value_arg(&ctx->args[0]), - jmcf->proto, s, 0); + NGX_JS_PROTO_MAIN, s, 0); if (rc != NJS_OK) { return NGX_ERROR; } @@ -1306,7 +1305,7 @@ ngx_stream_js_init_main_conf(ngx_conf_t *cf, void *conf) ssize_t n; ngx_fd_t fd; ngx_str_t *m, file; - njs_int_t rc; + njs_int_t rc, proto_id; njs_str_t text, path; ngx_uint_t i; njs_value_t *value; @@ -1314,7 +1313,6 @@ ngx_stream_js_init_main_conf(ngx_conf_t *cf, void *conf) ngx_file_info_t fi; ngx_pool_cleanup_t *cln; njs_opaque_value_t lvalue, exception; - njs_external_proto_t proto; ngx_stream_js_import_t *import; static const njs_str_t line_number_key = njs_str("lineNumber"); @@ -1466,16 +1464,14 @@ ngx_stream_js_init_main_conf(ngx_conf_t *cf, void *conf) } } - proto = njs_vm_external_prototype(jmcf->vm, ngx_stream_js_ext_session, - njs_nitems(ngx_stream_js_ext_session)); - if (proto == NULL) { + proto_id = njs_vm_external_prototype(jmcf->vm, ngx_stream_js_ext_session, + njs_nitems(ngx_stream_js_ext_session)); + if (proto_id < 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "failed to add js request proto"); return NGX_CONF_ERROR; } - jmcf->proto = proto; - rc = ngx_js_core_init(jmcf->vm, cf->log); if (njs_slow_path(rc != NJS_OK)) { return NGX_CONF_ERROR; @@ -1708,7 +1704,6 @@ ngx_stream_js_create_main_conf(ngx_conf_t *cf) * conf->include = { 0, NULL }; * conf->file = NULL; * conf->line = 0; - * conf->proto = NULL; */ conf->paths = NGX_CONF_UNSET_PTR; diff --git a/src/njs.h b/src/njs.h index 42261a6f..7af86fa5 100644 --- a/src/njs.h +++ b/src/njs.h @@ -29,7 +29,6 @@ typedef struct njs_function_s njs_function_t; typedef struct njs_vm_shared_s njs_vm_shared_t; typedef struct njs_object_prop_s njs_object_prop_t; typedef struct njs_external_s njs_external_t; -typedef void * njs_external_proto_t; /* * njs_opaque_value_t is the external storage type for native njs_value_t type. @@ -297,10 +296,10 @@ NJS_EXPORT njs_int_t njs_vm_start(njs_vm_t *vm); NJS_EXPORT njs_int_t njs_vm_add_path(njs_vm_t *vm, const njs_str_t *path); -NJS_EXPORT njs_external_proto_t njs_vm_external_prototype(njs_vm_t *vm, +NJS_EXPORT njs_int_t njs_vm_external_prototype(njs_vm_t *vm, const njs_external_t *definition, njs_uint_t n); NJS_EXPORT njs_int_t njs_vm_external_create(njs_vm_t *vm, njs_value_t *value, - njs_external_proto_t proto, njs_external_ptr_t external, njs_bool_t shared); + njs_int_t proto_id, njs_external_ptr_t external, njs_bool_t shared); NJS_EXPORT njs_external_ptr_t njs_vm_external(njs_vm_t *vm, const njs_value_t *value); NJS_EXPORT uintptr_t njs_vm_meta(njs_vm_t *vm, njs_uint_t index); diff --git a/src/njs_extern.c b/src/njs_extern.c index a2dfd01f..a5de5b47 100644 --- a/src/njs_extern.c +++ b/src/njs_extern.c @@ -256,12 +256,13 @@ njs_external_protos(const njs_external_t *external, njs_uint_t size) } -njs_external_proto_t +njs_int_t njs_vm_external_prototype(njs_vm_t *vm, const njs_external_t *definition, njs_uint_t n) { njs_arr_t *protos; njs_int_t ret; + uintptr_t *pr; njs_uint_t size; size = njs_external_protos(definition, n) + 1; @@ -269,38 +270,55 @@ njs_vm_external_prototype(njs_vm_t *vm, const njs_external_t *definition, protos = njs_arr_create(vm->mem_pool, size, sizeof(njs_exotic_slots_t)); if (njs_slow_path(protos == NULL)) { njs_memory_error(vm); - return NULL; + return -1; } ret = njs_external_add(vm, protos, definition, n); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "njs_vm_external_add() failed"); - return NULL; + return -1; + } + + if (vm->protos == NULL) { + vm->protos = njs_arr_create(vm->mem_pool, 4, sizeof(uintptr_t)); + if (njs_slow_path(vm->protos == NULL)) { + return -1; + } } - return protos; + pr = njs_arr_add(vm->protos); + if (njs_slow_path(pr == NULL)) { + return -1; + } + + *pr = (uintptr_t) protos; + + return vm->protos->items - 1; } njs_int_t -njs_vm_external_create(njs_vm_t *vm, njs_value_t *value, - njs_external_proto_t proto, njs_external_ptr_t external, njs_bool_t shared) +njs_vm_external_create(njs_vm_t *vm, njs_value_t *value, njs_int_t proto_id, + njs_external_ptr_t external, njs_bool_t shared) { njs_arr_t *protos; + uintptr_t proto; njs_object_value_t *ov; njs_exotic_slots_t *slots; - if (njs_slow_path(proto == NULL)) { + if (vm->protos == NULL || (njs_int_t) vm->protos->items <= proto_id) { return NJS_ERROR; } + proto = ((uintptr_t *) vm->protos->start)[proto_id]; + ov = njs_mp_alloc(vm->mem_pool, sizeof(njs_object_value_t)); if (njs_slow_path(ov == NULL)) { njs_memory_error(vm); return NJS_ERROR; } - protos = proto; + protos = (njs_arr_t *) proto; slots = protos->start; njs_lvlhsh_init(&ov->object.hash); diff --git a/src/njs_shell.c b/src/njs_shell.c index 8a878428..be7a90df 100644 --- a/src/njs_shell.c +++ b/src/njs_shell.c @@ -653,12 +653,11 @@ static njs_value_t * njs_external_add(njs_vm_t *vm, njs_external_t *definition, njs_uint_t n, const njs_str_t *name, njs_external_ptr_t external) { - njs_int_t ret; - njs_value_t *value; - njs_external_proto_t proto; + njs_int_t ret, proto_id; + njs_value_t *value; - proto = njs_vm_external_prototype(vm, definition, n); - if (njs_slow_path(proto == NULL)) { + proto_id = njs_vm_external_prototype(vm, definition, n); + if (njs_slow_path(proto_id < 0)) { njs_stderror("failed to add \"%V\" proto\n", name); return NULL; } @@ -668,7 +667,7 @@ njs_external_add(njs_vm_t *vm, njs_external_t *definition, return NULL; } - ret = njs_vm_external_create(vm, value, proto, external, 0); + ret = njs_vm_external_create(vm, value, proto_id, external, 0); if (njs_slow_path(ret != NJS_OK)) { return NULL; } diff --git a/src/njs_vm.h b/src/njs_vm.h index 87276213..3f63b7ab 100644 --- a/src/njs_vm.h +++ b/src/njs_vm.h @@ -180,6 +180,7 @@ struct njs_vm_s { njs_value_t retval; njs_arr_t *paths; + njs_arr_t *protos; njs_value_t *scopes[NJS_SCOPES]; diff --git a/src/test/njs_benchmark.c b/src/test/njs_benchmark.c index 0025f355..688503de 100644 --- a/src/test/njs_benchmark.c +++ b/src/test/njs_benchmark.c @@ -36,13 +36,12 @@ njs_benchmark_test(njs_vm_t *parent, njs_opts_t *opts, njs_value_t *report, u_char *start; njs_vm_t *vm, *nvm; uint64_t us; - njs_int_t ret; + njs_int_t ret, proto_id; njs_str_t s, *expected; njs_uint_t i, n; njs_bool_t success; njs_value_t *result, name, usec, times; njs_vm_opt_t options; - njs_external_proto_t proto; static const njs_value_t name_key = njs_string("name"); static const njs_value_t usec_key = njs_string("usec"); @@ -68,8 +67,8 @@ njs_benchmark_test(njs_vm_t *parent, njs_opts_t *opts, njs_value_t *report, goto done; } - proto = njs_externals_shared_init(vm); - if (proto == NULL) { + proto_id = njs_externals_shared_init(vm); + if (proto_id < 0) { goto done; } diff --git a/src/test/njs_externals_test.c b/src/test/njs_externals_test.c index cdb89dab..f87e3811 100644 --- a/src/test/njs_externals_test.c +++ b/src/test/njs_externals_test.c @@ -11,7 +11,7 @@ typedef struct { njs_lvlhsh_t hash; - njs_external_proto_t proto; + njs_int_t proto_id; uint32_t a; uint32_t d; @@ -394,9 +394,9 @@ njs_unit_test_r_create(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, return NJS_ERROR; } - sr->proto = r->proto; + sr->proto_id = r->proto_id; - ret = njs_vm_external_create(vm, &vm->retval, sr->proto, sr, 0); + ret = njs_vm_external_create(vm, &vm->retval, sr->proto_id, sr, 0); if (ret != NJS_OK) { return NJS_ERROR; } @@ -678,8 +678,8 @@ static njs_unit_test_req_init_t njs_test_requests[] = { }; -static njs_external_proto_t -njs_externals_init_internal(njs_vm_t *vm, njs_external_proto_t proto, +static njs_int_t +njs_externals_init_internal(njs_vm_t *vm, njs_int_t proto_id, njs_unit_test_req_init_t *init, njs_uint_t n, njs_bool_t shared) { njs_int_t ret; @@ -687,37 +687,37 @@ njs_externals_init_internal(njs_vm_t *vm, njs_external_proto_t proto, njs_unit_test_req_t *requests; njs_unit_test_prop_t *prop; - if (proto == NULL) { - proto = njs_vm_external_prototype(vm, njs_unit_test_r_external, - njs_nitems(njs_unit_test_r_external)); - if (njs_slow_path(proto == NULL)) { + if (proto_id == -1) { + proto_id = njs_vm_external_prototype(vm, njs_unit_test_r_external, + njs_nitems(njs_unit_test_r_external)); + if (njs_slow_path(proto_id < 0)) { njs_printf("njs_vm_external_prototype() failed\n"); - return NULL; + return -1; } } requests = njs_mp_zalloc(vm->mem_pool, n * sizeof(njs_unit_test_req_t)); if (njs_slow_path(requests == NULL)) { - return NULL; + return -1; } for (i = 0; i < n; i++) { requests[i] = init[i].request; - requests[i].proto = proto; + requests[i].proto_id = proto_id; ret = njs_vm_external_create(vm, njs_value_arg(&requests[i].value), - proto, &requests[i], shared); + proto_id, &requests[i], shared); if (njs_slow_path(ret != NJS_OK)) { njs_printf("njs_vm_external_create() failed\n"); - return NULL; + return -1; } ret = njs_vm_bind(vm, &init[i].name, njs_value_arg(&requests[i].value), shared); if (njs_slow_path(ret != NJS_OK)) { njs_printf("njs_vm_bind() failed\n"); - return NULL; + return -1; } for (j = 0; j < njs_nitems(init[i].props); j++) { @@ -726,33 +726,34 @@ njs_externals_init_internal(njs_vm_t *vm, njs_external_proto_t proto, if (njs_slow_path(prop == NULL)) { njs_printf("lvlhsh_unit_test_alloc() failed\n"); - return NULL; + return -1; } ret = lvlhsh_unit_test_add(vm->mem_pool, &requests[i], prop); if (njs_slow_path(ret != NJS_OK)) { njs_printf("lvlhsh_unit_test_add() failed\n"); - return NULL; + return -1; } } } - return proto; + return proto_id; } -njs_external_proto_t +njs_int_t njs_externals_shared_init(njs_vm_t *vm) { - return njs_externals_init_internal(vm, NULL, njs_test_requests, 1, 1); + return njs_externals_init_internal(vm, -1, njs_test_requests, 1, 1); } njs_int_t -njs_externals_init(njs_vm_t *vm, njs_external_proto_t proto) +njs_externals_init(njs_vm_t *vm, njs_int_t proto_id) { - proto = njs_externals_init_internal(vm, proto, &njs_test_requests[1], 3, 0); - if (proto == NULL) { + proto_id = njs_externals_init_internal(vm, proto_id, &njs_test_requests[1], + 3, 0); + if (proto_id < 0) { return NJS_ERROR; } diff --git a/src/test/njs_externals_test.h b/src/test/njs_externals_test.h index 97553b5f..2253b4db 100644 --- a/src/test/njs_externals_test.h +++ b/src/test/njs_externals_test.h @@ -8,8 +8,8 @@ #define _NJS_EXTERNALS_TEST_H_INCLUDED_ -njs_external_proto_t njs_externals_shared_init(njs_vm_t *vm); -njs_int_t njs_externals_init(njs_vm_t *vm, njs_external_proto_t proto); +njs_int_t njs_externals_shared_init(njs_vm_t *vm); +njs_int_t njs_externals_init(njs_vm_t *vm, njs_int_t proto_id); #endif /* _NJS_EXTERNALS_TEST_H_INCLUDED_ */ diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index 5109d3a1..4cd63257 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -20483,19 +20483,18 @@ static njs_int_t njs_unit_test(njs_unit_test_t tests[], size_t num, njs_str_t *name, njs_opts_t *opts, njs_stat_t *stat) { - u_char *start, *end; - njs_vm_t *vm, *nvm; - njs_int_t ret; - njs_str_t s; - njs_uint_t i, repeat; - njs_stat_t prev; - njs_bool_t success; - njs_vm_opt_t options; - njs_external_proto_t proto; + u_char *start, *end; + njs_vm_t *vm, *nvm; + njs_int_t ret, proto_id; + njs_str_t s; + njs_uint_t i, repeat; + njs_stat_t prev; + njs_bool_t success; + njs_vm_opt_t options; vm = NULL; nvm = NULL; - proto = NULL; + proto_id = -1; prev = *stat; @@ -20519,8 +20518,8 @@ njs_unit_test(njs_unit_test_t tests[], size_t num, njs_str_t *name, } if (opts->externals) { - proto = njs_externals_shared_init(vm); - if (proto == NULL) { + proto_id = njs_externals_shared_init(vm); + if (proto_id < 0) { goto done; } } @@ -20549,7 +20548,7 @@ njs_unit_test(njs_unit_test_t tests[], size_t num, njs_str_t *name, } if (opts->externals) { - ret = njs_externals_init(nvm, proto); + ret = njs_externals_init(nvm, proto_id); if (ret != NJS_OK) { goto done; } @@ -20653,7 +20652,7 @@ njs_interactive_test(njs_unit_test_t tests[], size_t num, njs_str_t *name, } if (opts->externals) { - ret = njs_externals_init(vm, NULL); + ret = njs_externals_init(vm, -1); if (ret != NJS_OK) { goto done; }