details: https://hg.nginx.org/njs/rev/42fdcacfd131 branches: changeset: 1675:42fdcacfd131 user: Dmitry Volyntsev <xei...@nginx.com> date: Fri Jul 09 19:14:23 2021 +0000 description: Marking different external pointer with unique tag.
An external value has an arbitrary raw pointer associated with it. External values with different prototypes have different C-level structures. To ensure that only appropriate structures are fetched by njs_vm_external() the unique tag has to be provided during creation of external values. diffstat: nginx/ngx_http_js_module.c | 55 +++++++++++++++++++------------- nginx/ngx_js.c | 6 +- nginx/ngx_js_fetch.c | 19 ++++++----- nginx/ngx_stream_js_module.c | 16 ++++++--- src/njs.h | 5 ++- src/njs_extern.c | 21 +++++++++--- src/njs_shell.c | 71 +++++++++++++++++------------------------- src/njs_value.h | 8 ++++- src/test/njs_externals_test.c | 64 ++++++++++++++++++-------------------- src/test/njs_externals_test.h | 2 +- src/test/njs_unit_test.c | 23 +++++++++---- 11 files changed, 157 insertions(+), 133 deletions(-) diffs (908 lines): diff -r 92cb9b80cf8b -r 42fdcacfd131 nginx/ngx_http_js_module.c --- a/nginx/ngx_http_js_module.c Fri Jul 09 14:01:26 2021 +0000 +++ b/nginx/ngx_http_js_module.c Fri Jul 09 19:14:23 2021 +0000 @@ -1256,7 +1256,7 @@ ngx_http_js_ext_raw_header(njs_vm_t *vm, ngx_table_elt_t *header, *h; ngx_http_request_t *r; - r = njs_vm_external(vm, value); + r = njs_vm_external(vm, ngx_http_js_request_proto_id, value); if (r == NULL) { njs_value_undefined_set(retval); return NJS_DECLINED; @@ -1349,7 +1349,7 @@ ngx_http_js_ext_header_out(njs_vm_t *vm, { njs_str(""), ngx_http_js_header_generic }, }; - r = njs_vm_external(vm, value); + r = njs_vm_external(vm, ngx_http_js_request_proto_id, value); if (r == NULL) { if (retval != NULL) { njs_value_undefined_set(retval); @@ -1840,7 +1840,7 @@ ngx_http_js_ext_keys_header_out(njs_vm_t return NJS_ERROR; } - r = njs_vm_external(vm, value); + r = njs_vm_external(vm, ngx_http_js_request_proto_id, value); if (r == NULL) { return NJS_OK; } @@ -1885,7 +1885,7 @@ ngx_http_js_ext_status(njs_vm_t *vm, njs ngx_int_t n; ngx_http_request_t *r; - r = njs_vm_external(vm, value); + r = njs_vm_external(vm, ngx_http_js_request_proto_id, value); if (r == NULL) { njs_value_undefined_set(retval); return NJS_DECLINED; @@ -1912,7 +1912,8 @@ ngx_http_js_ext_send_header(njs_vm_t *vm { ngx_http_request_t *r; - r = njs_vm_external(vm, njs_arg(args, nargs, 0)); + r = njs_vm_external(vm, ngx_http_js_request_proto_id, + njs_argument(args, 0)); if (r == NULL) { njs_vm_error(vm, "\"this\" is not an external"); return NJS_ERROR; @@ -1945,7 +1946,8 @@ ngx_http_js_ext_send(njs_vm_t *vm, njs_v ngx_http_js_ctx_t *ctx; ngx_http_request_t *r; - r = njs_vm_external(vm, njs_argument(args, 0)); + r = njs_vm_external(vm, ngx_http_js_request_proto_id, + njs_argument(args, 0)); if (r == NULL) { njs_vm_error(vm, "\"this\" is not an external"); return NJS_ERROR; @@ -2033,7 +2035,8 @@ ngx_http_js_ext_send_buffer(njs_vm_t *vm static const njs_str_t last_key = njs_str("last"); static const njs_str_t flush_key = njs_str("flush"); - r = njs_vm_external(vm, njs_argument(args, 0)); + r = njs_vm_external(vm, ngx_http_js_request_proto_id, + njs_argument(args, 0)); if (r == NULL) { njs_vm_error(vm, "\"this\" is not an external"); return NJS_ERROR; @@ -2104,7 +2107,8 @@ ngx_http_js_ext_done(njs_vm_t *vm, njs_v ngx_http_js_ctx_t *ctx; ngx_http_request_t *r; - r = njs_vm_external(vm, njs_argument(args, 0)); + r = njs_vm_external(vm, ngx_http_js_request_proto_id, + njs_argument(args, 0)); if (r == NULL) { njs_vm_error(vm, "\"this\" is not an external"); return NJS_ERROR; @@ -2132,7 +2136,8 @@ ngx_http_js_ext_finish(njs_vm_t *vm, njs ngx_http_js_ctx_t *ctx; ngx_http_request_t *r; - r = njs_vm_external(vm, njs_arg(args, nargs, 0)); + r = njs_vm_external(vm, ngx_http_js_request_proto_id, + njs_argument(args, 0)); if (r == NULL) { njs_vm_error(vm, "\"this\" is not an external"); return NJS_ERROR; @@ -2162,7 +2167,8 @@ ngx_http_js_ext_return(njs_vm_t *vm, njs ngx_http_request_t *r; ngx_http_complex_value_t cv; - r = njs_vm_external(vm, njs_arg(args, nargs, 0)); + r = njs_vm_external(vm, ngx_http_js_request_proto_id, + njs_argument(args, 0)); if (r == NULL) { njs_vm_error(vm, "\"this\" is not an external"); return NJS_ERROR; @@ -2215,7 +2221,8 @@ ngx_http_js_ext_internal_redirect(njs_vm ngx_http_js_ctx_t *ctx; ngx_http_request_t *r; - r = njs_vm_external(vm, njs_arg(args, nargs, 0)); + r = njs_vm_external(vm, ngx_http_js_request_proto_id, + njs_argument(args, 0)); if (r == NULL) { njs_vm_error(vm, "\"this\" is not an external"); return NJS_ERROR; @@ -2256,7 +2263,7 @@ ngx_http_js_ext_get_http_version(njs_vm_ ngx_str_t v; ngx_http_request_t *r; - r = njs_vm_external(vm, value); + r = njs_vm_external(vm, ngx_http_js_request_proto_id, value); if (r == NULL) { njs_value_undefined_set(retval); return NJS_DECLINED; @@ -2302,7 +2309,7 @@ ngx_http_js_ext_get_remote_address(njs_v ngx_connection_t *c; ngx_http_request_t *r; - r = njs_vm_external(vm, value); + r = njs_vm_external(vm, ngx_http_js_request_proto_id, value); if (r == NULL) { njs_value_undefined_set(retval); return NJS_DECLINED; @@ -2328,7 +2335,7 @@ ngx_http_js_ext_get_request_body(njs_vm_ ngx_http_js_ctx_t *ctx; ngx_http_request_t *r; - r = njs_vm_external(vm, value); + r = njs_vm_external(vm, ngx_http_js_request_proto_id, value); if (r == NULL) { njs_value_undefined_set(retval); return NJS_DECLINED; @@ -2425,7 +2432,7 @@ ngx_http_js_ext_header_in(njs_vm_t *vm, { njs_str(""), ngx_http_js_header_generic }, }; - r = njs_vm_external(vm, value); + r = njs_vm_external(vm, ngx_http_js_request_proto_id, value); if (r == NULL) { if (retval != NULL) { njs_value_undefined_set(retval); @@ -2542,7 +2549,7 @@ ngx_http_js_ext_keys_header_in(njs_vm_t return NJS_ERROR; } - r = njs_vm_external(vm, value); + r = njs_vm_external(vm, ngx_http_js_request_proto_id, value); if (r == NULL) { return NJS_OK; } @@ -2559,7 +2566,7 @@ ngx_http_js_ext_get_arg(njs_vm_t *vm, nj ngx_str_t arg; ngx_http_request_t *r; - r = njs_vm_external(vm, value); + r = njs_vm_external(vm, ngx_http_js_request_proto_id, value); if (r == NULL) { njs_value_undefined_set(retval); return NJS_DECLINED; @@ -2595,7 +2602,7 @@ ngx_http_js_ext_keys_arg(njs_vm_t *vm, n return NJS_ERROR; } - r = njs_vm_external(vm, value); + r = njs_vm_external(vm, ngx_http_js_request_proto_id, value); if (r == NULL) { return NJS_OK; } @@ -2646,7 +2653,7 @@ ngx_http_js_ext_variables(njs_vm_t *vm, ngx_http_core_main_conf_t *cmcf; ngx_http_variable_value_t *vv; - r = njs_vm_external(vm, value); + r = njs_vm_external(vm, ngx_http_js_request_proto_id, value); if (r == NULL) { njs_value_undefined_set(retval); return NJS_DECLINED; @@ -2739,7 +2746,8 @@ ngx_http_js_promise_trampoline(njs_vm_t ngx_http_js_ctx_t *ctx; ngx_http_request_t *r; - r = njs_vm_external(vm, njs_argument(args, 1)); + r = njs_vm_external(vm, ngx_http_js_request_proto_id, + njs_arg(args, nargs, 1)); ctx = ngx_http_get_module_ctx(r->parent, ngx_http_js_module); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, @@ -2823,7 +2831,8 @@ ngx_http_js_ext_subrequest(njs_vm_t *vm, static const njs_str_t body_key = njs_str("body"); static const njs_str_t detached_key = njs_str("detached"); - r = njs_vm_external(vm, njs_arg(args, nargs, 0)); + r = njs_vm_external(vm, ngx_http_js_request_proto_id, + njs_argument(args, 0)); if (r == NULL) { njs_vm_error(vm, "\"this\" is not an external"); return NJS_ERROR; @@ -3165,7 +3174,7 @@ ngx_http_js_ext_get_parent(njs_vm_t *vm, ngx_http_js_ctx_t *ctx; ngx_http_request_t *r; - r = njs_vm_external(vm, value); + r = njs_vm_external(vm, ngx_http_js_request_proto_id, value); if (r == NULL) { njs_value_undefined_set(retval); return NJS_DECLINED; @@ -3197,7 +3206,7 @@ ngx_http_js_ext_get_response_body(njs_vm ngx_http_js_ctx_t *ctx; ngx_http_request_t *r; - r = njs_vm_external(vm, value); + r = njs_vm_external(vm, ngx_http_js_request_proto_id, value); if (r == NULL) { njs_value_undefined_set(retval); return NJS_DECLINED; diff -r 92cb9b80cf8b -r 42fdcacfd131 nginx/ngx_js.c --- a/nginx/ngx_js.c Fri Jul 09 14:01:26 2021 +0000 +++ b/nginx/ngx_js.c Fri Jul 09 19:14:23 2021 +0000 @@ -173,7 +173,7 @@ ngx_js_ext_string(njs_vm_t *vm, njs_obje char *p; ngx_str_t *field; - p = njs_vm_external(vm, value); + p = njs_vm_external(vm, NJS_PROTO_ID_ANY, value); if (p == NULL) { njs_value_undefined_set(retval); return NJS_DECLINED; @@ -192,7 +192,7 @@ ngx_js_ext_uint(njs_vm_t *vm, njs_object char *p; ngx_uint_t field; - p = njs_vm_external(vm, value); + p = njs_vm_external(vm, NJS_PROTO_ID_ANY, value); if (p == NULL) { njs_value_undefined_set(retval); return NJS_DECLINED; @@ -237,7 +237,7 @@ ngx_js_ext_log(njs_vm_t *vm, njs_value_t ngx_connection_t *c; ngx_log_handler_pt handler; - p = njs_vm_external(vm, njs_arg(args, nargs, 0)); + p = njs_vm_external(vm, NJS_PROTO_ID_ANY, njs_argument(args, 0)); if (p == NULL) { njs_vm_error(vm, "\"this\" is not an external"); return NJS_ERROR; diff -r 92cb9b80cf8b -r 42fdcacfd131 nginx/ngx_js_fetch.c --- a/nginx/ngx_js_fetch.c Fri Jul 09 14:01:26 2021 +0000 +++ b/nginx/ngx_js_fetch.c Fri Jul 09 19:14:23 2021 +0000 @@ -345,7 +345,7 @@ ngx_js_ext_fetch(njs_vm_t *vm, njs_value static const njs_str_t body_size_key = njs_str("max_response_body_size"); static const njs_str_t method_key = njs_str("method"); - external = njs_vm_external(vm, njs_argument(args, 0)); + external = njs_vm_external(vm, NJS_PROTO_ID_ANY, njs_argument(args, 0)); if (external == NULL) { njs_vm_error(vm, "\"this\" is not an external"); return NJS_ERROR; @@ -1859,7 +1859,7 @@ ngx_response_js_ext_header_get(njs_vm_t ngx_js_http_t *http; ngx_table_elt_t *header, *h; - http = njs_vm_external(vm, value); + http = njs_vm_external(vm, ngx_http_js_fetch_proto_id, value); if (http == NULL) { njs_value_null_set(retval); return NJS_DECLINED; @@ -2011,7 +2011,7 @@ ngx_response_js_ext_keys(njs_vm_t *vm, n ngx_js_http_t *http; ngx_table_elt_t *h, *headers; - http = njs_vm_external(vm, value); + http = njs_vm_external(vm, ngx_http_js_fetch_proto_id, value); if (http == NULL) { njs_value_undefined_set(keys); return NJS_DECLINED; @@ -2067,7 +2067,8 @@ ngx_response_js_ext_body(njs_vm_t *vm, n ngx_js_http_t *http; njs_opaque_value_t retval; - http = njs_vm_external(vm, njs_argument(args, 0)); + http = njs_vm_external(vm, ngx_http_js_fetch_proto_id, + njs_argument(args, 0)); if (http == NULL) { njs_value_undefined_set(njs_vm_retval(vm)); return NJS_DECLINED; @@ -2124,7 +2125,7 @@ ngx_response_js_ext_body_used(njs_vm_t * { ngx_js_http_t *http; - http = njs_vm_external(vm, value); + http = njs_vm_external(vm, ngx_http_js_fetch_proto_id, value); if (http == NULL) { njs_value_undefined_set(retval); return NJS_DECLINED; @@ -2143,7 +2144,7 @@ ngx_response_js_ext_ok(njs_vm_t *vm, njs ngx_uint_t code; ngx_js_http_t *http; - http = njs_vm_external(vm, value); + http = njs_vm_external(vm, ngx_http_js_fetch_proto_id, value); if (http == NULL) { njs_value_undefined_set(retval); return NJS_DECLINED; @@ -2163,7 +2164,7 @@ ngx_response_js_ext_status(njs_vm_t *vm, { ngx_js_http_t *http; - http = njs_vm_external(vm, value); + http = njs_vm_external(vm, ngx_http_js_fetch_proto_id, value); if (http == NULL) { njs_value_undefined_set(retval); return NJS_DECLINED; @@ -2181,7 +2182,7 @@ ngx_response_js_ext_status_text(njs_vm_t { ngx_js_http_t *http; - http = njs_vm_external(vm, value); + http = njs_vm_external(vm, ngx_http_js_fetch_proto_id, value); if (http == NULL) { njs_value_undefined_set(retval); return NJS_DECLINED; @@ -2201,7 +2202,7 @@ ngx_response_js_ext_type(njs_vm_t *vm, n { ngx_js_http_t *http; - http = njs_vm_external(vm, value); + http = njs_vm_external(vm, ngx_http_js_fetch_proto_id, value); if (http == NULL) { njs_value_undefined_set(retval); return NJS_DECLINED; diff -r 92cb9b80cf8b -r 42fdcacfd131 nginx/ngx_stream_js_module.c --- a/nginx/ngx_stream_js_module.c Fri Jul 09 14:01:26 2021 +0000 +++ b/nginx/ngx_stream_js_module.c Fri Jul 09 19:14:23 2021 +0000 @@ -952,7 +952,7 @@ ngx_stream_js_ext_get_remote_address(njs ngx_connection_t *c; ngx_stream_session_t *s; - s = njs_vm_external(vm, value); + s = njs_vm_external(vm, ngx_stream_js_session_proto_id, value); if (s == NULL) { njs_value_undefined_set(retval); return NJS_DECLINED; @@ -974,7 +974,8 @@ ngx_stream_js_ext_done(njs_vm_t *vm, njs ngx_stream_js_ctx_t *ctx; ngx_stream_session_t *s; - s = njs_vm_external(vm, njs_arg(args, nargs, 0)); + s = njs_vm_external(vm, ngx_stream_js_session_proto_id, + njs_argument(args, 0)); if (s == NULL) { njs_vm_error(vm, "\"this\" is not an external"); return NJS_ERROR; @@ -1025,7 +1026,8 @@ ngx_stream_js_ext_on(njs_vm_t *vm, njs_v njs_vm_event_t *event; ngx_stream_session_t *s; - s = njs_vm_external(vm, njs_arg(args, nargs, 0)); + s = njs_vm_external(vm, ngx_stream_js_session_proto_id, + njs_argument(args, 0)); if (s == NULL) { njs_vm_error(vm, "\"this\" is not an external"); return NJS_ERROR; @@ -1072,7 +1074,8 @@ ngx_stream_js_ext_off(njs_vm_t *vm, njs_ njs_vm_event_t *event; ngx_stream_session_t *s; - s = njs_vm_external(vm, njs_arg(args, nargs, 0)); + s = njs_vm_external(vm, ngx_stream_js_session_proto_id, + njs_argument(args, 0)); if (s == NULL) { njs_vm_error(vm, "\"this\" is not an external"); return NJS_ERROR; @@ -1115,7 +1118,8 @@ ngx_stream_js_ext_send(njs_vm_t *vm, njs static const njs_str_t last_key = njs_str("last"); static const njs_str_t flush_key = njs_str("flush"); - s = njs_vm_external(vm, njs_arg(args, nargs, 0)); + s = njs_vm_external(vm, ngx_stream_js_session_proto_id, + njs_argument(args, 0)); if (s == NULL) { njs_vm_error(vm, "\"this\" is not an external"); return NJS_ERROR; @@ -1194,7 +1198,7 @@ ngx_stream_js_ext_variables(njs_vm_t *vm ngx_stream_core_main_conf_t *cmcf; ngx_stream_variable_value_t *vv; - s = njs_vm_external(vm, value); + s = njs_vm_external(vm, ngx_stream_js_session_proto_id, value); if (s == NULL) { njs_value_undefined_set(retval); return NJS_DECLINED; diff -r 92cb9b80cf8b -r 42fdcacfd131 src/njs.h --- a/src/njs.h Fri Jul 09 14:01:26 2021 +0000 +++ b/src/njs.h Fri Jul 09 19:14:23 2021 +0000 @@ -299,12 +299,14 @@ NJS_EXPORT njs_int_t njs_vm_start(njs_vm NJS_EXPORT njs_int_t njs_vm_add_path(njs_vm_t *vm, const njs_str_t *path); +#define NJS_PROTO_ID_ANY (-1) + 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_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_int_t proto_id, const njs_value_t *value); NJS_EXPORT uintptr_t njs_vm_meta(njs_vm_t *vm, njs_uint_t index); NJS_EXPORT njs_function_t *njs_vm_function_alloc(njs_vm_t *vm, @@ -381,6 +383,7 @@ NJS_EXPORT void njs_value_number_set(njs NJS_EXPORT uint8_t njs_value_bool(const njs_value_t *value); NJS_EXPORT double njs_value_number(const njs_value_t *value); NJS_EXPORT njs_function_t *njs_value_function(const njs_value_t *value); +NJS_EXPORT njs_int_t njs_value_external_tag(const njs_value_t *value); NJS_EXPORT uint16_t njs_vm_prop_magic16(njs_object_prop_t *prop); NJS_EXPORT uint32_t njs_vm_prop_magic32(njs_object_prop_t *prop); diff -r 92cb9b80cf8b -r 42fdcacfd131 src/njs_extern.c --- a/src/njs_extern.c Fri Jul 09 14:01:26 2021 +0000 +++ b/src/njs_extern.c Fri Jul 09 19:14:23 2021 +0000 @@ -179,7 +179,7 @@ njs_external_prop_handler(njs_vm_t *vm, *retval = *setval; } else { - external = njs_vm_external(vm, value); + external = njs_vm_external(vm, NJS_PROTO_ID_ANY, value); if (njs_slow_path(external == NULL)) { njs_value_undefined_set(retval); return NJS_OK; @@ -203,7 +203,7 @@ njs_external_prop_handler(njs_vm_t *vm, ov->object.__proto__ = &vm->prototypes[NJS_OBJ_TYPE_OBJECT].object; ov->object.slots = slots; - njs_set_data(&ov->value, external, NJS_DATA_TAG_EXTERNAL); + njs_set_data(&ov->value, external, njs_value_external_tag(value)); njs_set_object_value(retval, ov); } @@ -332,18 +332,18 @@ njs_vm_external_create(njs_vm_t *vm, njs ov->object.slots = slots; njs_set_object_value(value, ov); - njs_set_data(&ov->value, external, NJS_DATA_TAG_EXTERNAL); + njs_set_data(&ov->value, external, njs_make_tag(proto_id)); return NJS_OK; } njs_external_ptr_t -njs_vm_external(njs_vm_t *vm, const njs_value_t *value) +njs_vm_external(njs_vm_t *vm, njs_int_t proto_id, const njs_value_t *value) { njs_external_ptr_t external; - if (njs_fast_path(njs_is_object_data(value, NJS_DATA_TAG_EXTERNAL))) { + if (njs_fast_path(njs_is_object_data(value, njs_make_tag(proto_id)))) { external = njs_object_data(value); if (external == NULL) { external = vm->external; @@ -354,3 +354,14 @@ njs_vm_external(njs_vm_t *vm, const njs_ return NULL; } + + +njs_int_t +njs_value_external_tag(const njs_value_t *value) +{ + if (njs_is_object_data(value, njs_make_tag(NJS_PROTO_ID_ANY))) { + return njs_object_value(value)->data.magic32; + } + + return -1; +} diff -r 92cb9b80cf8b -r 42fdcacfd131 src/njs_shell.c --- a/src/njs_shell.c Fri Jul 09 14:01:26 2021 +0000 +++ b/src/njs_shell.c Fri Jul 09 19:14:23 2021 +0000 @@ -202,6 +202,9 @@ static njs_vm_ops_t njs_console_ops = { }; +static njs_int_t njs_console_proto_id; + + static njs_console_t njs_console; @@ -656,38 +659,6 @@ njs_console_init(njs_vm_t *vm, njs_conso } -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, proto_id; - njs_value_t *value; - - 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; - } - - value = njs_mp_zalloc(vm->mem_pool, sizeof(njs_opaque_value_t)); - if (njs_slow_path(value == NULL)) { - return NULL; - } - - ret = njs_vm_external_create(vm, value, proto_id, external, 0); - if (njs_slow_path(ret != NJS_OK)) { - return NULL; - } - - ret = njs_vm_bind(vm, name, value, 0); - if (njs_slow_path(ret != NJS_OK)) { - return NULL; - } - - return value; -} - - static njs_int_t njs_externals_init(njs_vm_t *vm, njs_console_t *console) { @@ -696,15 +667,31 @@ njs_externals_init(njs_vm_t *vm, njs_con static const njs_str_t console_name = njs_str("console"); static const njs_str_t print_name = njs_str("print"); - static const njs_value_t string_log = njs_string("log"); + static const njs_str_t console_log = njs_str("console.log"); - value = njs_external_add(vm, njs_ext_console, njs_nitems(njs_ext_console), - &console_name, console); + njs_console_proto_id = njs_vm_external_prototype(vm, njs_ext_console, + njs_nitems(njs_ext_console)); + if (njs_slow_path(njs_console_proto_id < 0)) { + njs_stderror("failed to add \"console\" proto\n"); + return NJS_ERROR; + } + + value = njs_mp_zalloc(vm->mem_pool, sizeof(njs_opaque_value_t)); if (njs_slow_path(value == NULL)) { return NJS_ERROR; } - ret = njs_value_property(vm, value, njs_value_arg(&string_log), &method); + ret = njs_vm_external_create(vm, value, njs_console_proto_id, console, 0); + if (njs_slow_path(ret != NJS_OK)) { + return NJS_ERROR; + } + + ret = njs_vm_bind(vm, &console_name, value, 0); + if (njs_slow_path(ret != NJS_OK)) { + return NJS_ERROR; + } + + ret = njs_vm_value(vm, &console_log, &method); if (njs_slow_path(ret != NJS_OK)) { return NJS_ERROR; } @@ -1169,13 +1156,13 @@ njs_ext_console_time(njs_vm_t *vm, njs_v njs_index_t unused) { njs_int_t ret; - njs_console_t *console; + njs_str_t name; njs_value_t *value; + njs_console_t *console; njs_timelabel_t *label; - njs_str_t name; njs_lvlhsh_query_t lhq; - console = njs_vm_external(vm, njs_arg(args, nargs, 0)); + console = njs_vm_external(vm, njs_console_proto_id, njs_argument(args, 0)); if (njs_slow_path(console == NULL)) { njs_type_error(vm, "external value is expected"); return NJS_ERROR; @@ -1244,15 +1231,15 @@ njs_ext_console_time_end(njs_vm_t *vm, n { uint64_t ns, ms; njs_int_t ret; - njs_console_t *console; + njs_str_t name; njs_value_t *value; + njs_console_t *console; njs_timelabel_t *label; - njs_str_t name; njs_lvlhsh_query_t lhq; ns = njs_time(); - console = njs_vm_external(vm, njs_arg(args, nargs, 0)); + console = njs_vm_external(vm, njs_console_proto_id, njs_argument(args, 0)); if (njs_slow_path(console == NULL)) { njs_type_error(vm, "external value is expected"); return NJS_ERROR; diff -r 92cb9b80cf8b -r 42fdcacfd131 src/njs_value.h --- a/src/njs_value.h Fri Jul 09 14:01:26 2021 +0000 +++ b/src/njs_value.h Fri Jul 09 19:14:23 2021 +0000 @@ -594,8 +594,14 @@ typedef struct { ((value)->type <= NJS_STRING) +#define njs_make_tag(proto_id) \ + (((njs_uint_t) proto_id << 8) | NJS_DATA_TAG_EXTERNAL) + + #define njs_is_data(value, tag) \ - ((value)->type == NJS_DATA && value->data.magic32 == (tag)) + ((value)->type == NJS_DATA \ + && ((tag) == njs_make_tag(NJS_PROTO_ID_ANY) \ + || value->data.magic32 == (tag))) #define njs_is_object(value) \ diff -r 92cb9b80cf8b -r 42fdcacfd131 src/test/njs_externals_test.c --- a/src/test/njs_externals_test.c Fri Jul 09 14:01:26 2021 +0000 +++ b/src/test/njs_externals_test.c Fri Jul 09 19:14:23 2021 +0000 @@ -11,7 +11,6 @@ typedef struct { njs_lvlhsh_t hash; - njs_int_t proto_id; uint32_t a; uint32_t d; @@ -27,6 +26,9 @@ typedef struct { } njs_unit_test_prop_t; +static njs_int_t njs_external_r_proto_id; + + static njs_int_t lvlhsh_unit_test_key_test(njs_lvlhsh_query_t *lhq, void *data) { @@ -121,7 +123,7 @@ njs_unit_test_r_uri(njs_vm_t *vm, njs_ob char *p; njs_str_t *field; - p = njs_vm_external(vm, value); + p = njs_vm_external(vm, njs_external_r_proto_id, value); if (p == NULL) { njs_value_undefined_set(retval); return NJS_DECLINED; @@ -145,7 +147,7 @@ njs_unit_test_r_a(njs_vm_t *vm, njs_obje njs_unit_test_req_t *r; u_char buf[16]; - r = njs_vm_external(vm, value); + r = njs_vm_external(vm, njs_external_r_proto_id, value); if (r == NULL) { njs_value_undefined_set(retval); return NJS_DECLINED; @@ -173,7 +175,7 @@ njs_unit_test_r_d(njs_vm_t *vm, njs_obje { njs_unit_test_req_t *r; - r = njs_vm_external(vm, value); + r = njs_vm_external(vm, njs_external_r_proto_id, value); if (r == NULL) { njs_value_undefined_set(retval); return NJS_DECLINED; @@ -211,7 +213,7 @@ njs_unit_test_r_vars(njs_vm_t *vm, njs_o njs_unit_test_req_t *r; njs_unit_test_prop_t *prop; - r = njs_vm_external(vm, value); + r = njs_vm_external(vm, njs_external_r_proto_id, value); if (r == NULL) { njs_value_undefined_set(retval); return NJS_DECLINED; @@ -352,7 +354,7 @@ njs_unit_test_r_method(njs_vm_t *vm, njs njs_str_t s; njs_unit_test_req_t *r; - r = njs_vm_external(vm, njs_arg(args, nargs, 0)); + r = njs_vm_external(vm, njs_external_r_proto_id, njs_argument(args, 0)); if (r == NULL) { njs_type_error(vm, "\"this\" is not an external"); return NJS_ERROR; @@ -377,7 +379,7 @@ njs_unit_test_r_create(njs_vm_t *vm, njs njs_int_t ret; njs_unit_test_req_t *r, *sr; - r = njs_vm_external(vm, njs_arg(args, nargs, 0)); + r = njs_vm_external(vm, njs_external_r_proto_id, njs_argument(args, 0)); if (r == NULL) { njs_type_error(vm, "\"this\" is not an external"); return NJS_ERROR; @@ -394,9 +396,8 @@ njs_unit_test_r_create(njs_vm_t *vm, njs return NJS_ERROR; } - sr->proto_id = r->proto_id; - - ret = njs_vm_external_create(vm, &vm->retval, sr->proto_id, sr, 0); + ret = njs_vm_external_create(vm, &vm->retval, njs_external_r_proto_id, + sr, 0); if (ret != NJS_OK) { return NJS_ERROR; } @@ -418,7 +419,7 @@ njs_unit_test_r_bind(njs_vm_t *vm, njs_v njs_str_t name; njs_unit_test_req_t *r; - r = njs_vm_external(vm, njs_arg(args, nargs, 0)); + r = njs_vm_external(vm, njs_external_r_proto_id, njs_argument(args, 0)); if (r == NULL) { njs_type_error(vm, "\"this\" is not an external"); return NJS_ERROR; @@ -679,45 +680,46 @@ static njs_unit_test_req_init_t njs_test 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_externals_init_internal(njs_vm_t *vm, njs_unit_test_req_init_t *init, + njs_uint_t n, njs_bool_t shared) { njs_int_t ret; njs_uint_t i, j; njs_unit_test_req_t *requests; njs_unit_test_prop_t *prop; - if (proto_id == -1) { - proto_id = njs_vm_external_prototype(vm, njs_unit_test_r_external, + if (shared) { + njs_external_r_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)) { + if (njs_slow_path(njs_external_r_proto_id < 0)) { njs_printf("njs_vm_external_prototype() failed\n"); - return -1; + return NJS_ERROR; } } requests = njs_mp_zalloc(vm->mem_pool, n * sizeof(njs_unit_test_req_t)); if (njs_slow_path(requests == NULL)) { - return -1; + return NJS_ERROR; } for (i = 0; i < n; i++) { requests[i] = init[i].request; - requests[i].proto_id = proto_id; ret = njs_vm_external_create(vm, njs_value_arg(&requests[i].value), - proto_id, &requests[i], shared); + njs_external_r_proto_id, &requests[i], + shared); if (njs_slow_path(ret != NJS_OK)) { njs_printf("njs_vm_external_create() failed\n"); - return -1; + return NJS_ERROR; } 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 -1; + return NJS_ERROR; } for (j = 0; j < njs_nitems(init[i].props); j++) { @@ -726,36 +728,30 @@ njs_externals_init_internal(njs_vm_t *vm if (njs_slow_path(prop == NULL)) { njs_printf("lvlhsh_unit_test_alloc() failed\n"); - return -1; + return NJS_ERROR; } 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 -1; + return NJS_ERROR; } } } - return proto_id; + return NJS_OK; } njs_int_t njs_externals_shared_init(njs_vm_t *vm) { - return njs_externals_init_internal(vm, -1, njs_test_requests, 1, 1); + return njs_externals_init_internal(vm, njs_test_requests, 1, 1); } njs_int_t -njs_externals_init(njs_vm_t *vm, njs_int_t proto_id) +njs_externals_init(njs_vm_t *vm) { - proto_id = njs_externals_init_internal(vm, proto_id, &njs_test_requests[1], - 3, 0); - if (proto_id < 0) { - return NJS_ERROR; - } - - return NJS_OK; + return njs_externals_init_internal(vm, &njs_test_requests[1], 3, 0); } diff -r 92cb9b80cf8b -r 42fdcacfd131 src/test/njs_externals_test.h --- a/src/test/njs_externals_test.h Fri Jul 09 14:01:26 2021 +0000 +++ b/src/test/njs_externals_test.h Fri Jul 09 19:14:23 2021 +0000 @@ -9,7 +9,7 @@ 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); +njs_int_t njs_externals_init(njs_vm_t *vm); #endif /* _NJS_EXTERNALS_TEST_H_INCLUDED_ */ diff -r 92cb9b80cf8b -r 42fdcacfd131 src/test/njs_unit_test.c --- a/src/test/njs_unit_test.c Fri Jul 09 14:01:26 2021 +0000 +++ b/src/test/njs_unit_test.c Fri Jul 09 19:14:23 2021 +0000 @@ -20624,6 +20624,9 @@ static njs_unit_test_t njs_externals_te { njs_str("$r.create('XXX').uri"), njs_str("XXX") }, + { njs_str("$r.create.call([], 'XXX')"), + njs_str("TypeError: \"this\" is not an external") }, + { njs_str("var sr = $r.create('XXX'); sr.uri = 'YYY'; sr.uri"), njs_str("YYY") }, @@ -21198,9 +21201,9 @@ static njs_unit_test_t njs_shell_test[] " at eval (native)\n" " at main (:1)\n") }, - { njs_str("$r.method({}.a.a)" ENTER), + { njs_str("$shared.method({}.a.a)" ENTER), njs_str("TypeError: cannot get property \"a\" of undefined\n" - " at $r3.method (native)\n" + " at $shared.method (native)\n" " at main (:1)\n") }, { njs_str("new Function(\n\n@)" ENTER), @@ -21372,7 +21375,7 @@ njs_unit_test(njs_unit_test_t tests[], s { u_char *start, *end; njs_vm_t *vm, *nvm; - njs_int_t ret, proto_id; + njs_int_t ret; njs_str_t s; njs_uint_t i, repeat; njs_stat_t prev; @@ -21381,7 +21384,6 @@ njs_unit_test(njs_unit_test_t tests[], s vm = NULL; nvm = NULL; - proto_id = -1; prev = *stat; @@ -21405,8 +21407,8 @@ njs_unit_test(njs_unit_test_t tests[], s } if (opts->externals) { - proto_id = njs_externals_shared_init(vm); - if (proto_id < 0) { + ret = njs_externals_shared_init(vm); + if (ret != NJS_OK) { goto done; } } @@ -21435,7 +21437,7 @@ njs_unit_test(njs_unit_test_t tests[], s } if (opts->externals) { - ret = njs_externals_init(nvm, proto_id); + ret = njs_externals_init(nvm); if (ret != NJS_OK) { goto done; } @@ -21539,7 +21541,12 @@ njs_interactive_test(njs_unit_test_t tes } if (opts->externals) { - ret = njs_externals_init(vm, -1); + ret = njs_externals_shared_init(vm); + if (ret != NJS_OK) { + goto done; + } + + ret = njs_externals_init(vm); if (ret != NJS_OK) { goto done; } _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel