[njs] Marking different external pointer with unique tag.
Dmitry Volyntsev
xeioex at nginx.com
Fri Jul 9 19:37:10 UTC 2021
details: https://hg.nginx.org/njs/rev/42fdcacfd131
branches:
changeset: 1675:42fdcacfd131
user: Dmitry Volyntsev <xeioex at 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;
}
More information about the nginx-devel
mailing list