[njs] Allowing to declare exotic slot for the external objects.
Dmitry Volyntsev
xeioex at nginx.com
Thu Dec 8 02:13:52 UTC 2022
details: https://hg.nginx.org/njs/rev/a2a24c4b2541
branches:
changeset: 2009:a2a24c4b2541
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Wed Dec 07 18:11:54 2022 -0800
description:
Allowing to declare exotic slot for the external objects.
diffstat:
src/njs.h | 8 ++++
src/njs_extern.c | 69 +++++++++++++++++++++++++++++++-----------
src/test/njs_externals_test.c | 33 ++++++++++++++++++++
src/test/njs_unit_test.c | 3 +
4 files changed, 94 insertions(+), 19 deletions(-)
diffs (198 lines):
diff -r ef1fd66c094e -r a2a24c4b2541 src/njs.h
--- a/src/njs.h Tue Dec 06 18:47:53 2022 -0800
+++ b/src/njs.h Wed Dec 07 18:11:54 2022 -0800
@@ -132,9 +132,17 @@ typedef enum {
typedef enum {
+ /*
+ * Extern property type.
+ */
NJS_EXTERN_PROPERTY = 0,
NJS_EXTERN_METHOD = 1,
NJS_EXTERN_OBJECT = 2,
+ NJS_EXTERN_SELF = 3,
+#define NJS_EXTERN_TYPE_MASK 3
+ /*
+ * Extern property flags.
+ */
NJS_EXTERN_SYMBOL = 4,
} njs_extern_flag_t;
diff -r ef1fd66c094e -r a2a24c4b2541 src/njs_extern.c
--- a/src/njs_extern.c Tue Dec 06 18:47:53 2022 -0800
+++ b/src/njs_extern.c Wed Dec 07 18:11:54 2022 -0800
@@ -17,15 +17,16 @@ static njs_int_t
njs_external_add(njs_vm_t *vm, njs_arr_t *protos,
const njs_external_t *external, njs_uint_t n)
{
- size_t size;
- ssize_t length;
- njs_int_t ret;
- njs_lvlhsh_t *hash;
- const u_char *start;
- njs_function_t *function;
- njs_object_prop_t *prop;
- njs_lvlhsh_query_t lhq;
- njs_exotic_slots_t *slot, *next;
+ size_t size;
+ ssize_t length;
+ njs_int_t ret;
+ njs_lvlhsh_t *hash;
+ const u_char *start;
+ njs_function_t *function;
+ njs_object_prop_t *prop;
+ njs_lvlhsh_query_t lhq;
+ njs_exotic_slots_t *slot, *next;
+ const njs_external_t *end;
slot = njs_arr_add(protos);
njs_memzero(slot, sizeof(njs_exotic_slots_t));
@@ -37,7 +38,22 @@ njs_external_add(njs_vm_t *vm, njs_arr_t
lhq.proto = &njs_object_hash_proto;
lhq.pool = vm->mem_pool;
- while (n != 0) {
+ end = external + n;
+
+ while (external < end) {
+
+ if ((external->flags & NJS_EXTERN_TYPE_MASK) == NJS_EXTERN_SELF) {
+ slot->writable = external->u.object.writable;
+ slot->configurable = external->u.object.configurable;
+ slot->enumerable = external->u.object.enumerable;
+ slot->prop_handler = external->u.object.prop_handler;
+ slot->magic32 = external->u.object.magic32;
+ slot->keys = external->u.object.keys;
+
+ external++;
+ continue;
+ }
+
prop = njs_object_prop_alloc(vm, &njs_string_empty,
&njs_value_invalid, 1);
if (njs_slow_path(prop == NULL)) {
@@ -48,7 +64,7 @@ njs_external_add(njs_vm_t *vm, njs_arr_t
prop->configurable = external->configurable;
prop->enumerable = external->enumerable;
- if (external->flags & 4) {
+ if (external->flags & NJS_EXTERN_SYMBOL) {
njs_set_symbol(&prop->name, external->name.symbol, NULL);
lhq.key_hash = external->name.symbol;
@@ -66,7 +82,7 @@ njs_external_add(njs_vm_t *vm, njs_arr_t
lhq.value = prop;
- switch (external->flags & 3) {
+ switch (external->flags & NJS_EXTERN_TYPE_MASK) {
case NJS_EXTERN_METHOD:
function = njs_mp_zalloc(vm->mem_pool, sizeof(njs_function_t));
if (njs_slow_path(function == NULL)) {
@@ -128,12 +144,28 @@ njs_external_add(njs_vm_t *vm, njs_arr_t
njs_prop_magic32(prop) = lhq.key_hash;
njs_prop_handler(prop) = njs_external_prop_handler;
- next->writable = external->u.object.writable;
- next->configurable = external->u.object.configurable;
- next->enumerable = external->u.object.enumerable;
- next->prop_handler = external->u.object.prop_handler;
- next->magic32 = external->u.object.magic32;
- next->keys = external->u.object.keys;
+ if (external->u.object.prop_handler) {
+ if (next->prop_handler) {
+ njs_internal_error(vm, "overwritten self prop_handler");
+ return NJS_ERROR;
+ }
+
+ next->writable = external->u.object.writable;
+ next->configurable = external->u.object.configurable;
+ next->enumerable = external->u.object.enumerable;
+
+ next->prop_handler = external->u.object.prop_handler;
+ next->magic32 = external->u.object.magic32;
+ }
+
+ if (external->u.object.keys) {
+ if (next->keys) {
+ njs_internal_error(vm, "overwritten self keys");
+ return NJS_ERROR;
+ }
+
+ next->keys = external->u.object.keys;
+ }
break;
}
@@ -144,7 +176,6 @@ njs_external_add(njs_vm_t *vm, njs_arr_t
return NJS_ERROR;
}
- n--;
external++;
}
diff -r ef1fd66c094e -r a2a24c4b2541 src/test/njs_externals_test.c
--- a/src/test/njs_externals_test.c Tue Dec 06 18:47:53 2022 -0800
+++ b/src/test/njs_externals_test.c Wed Dec 07 18:11:54 2022 -0800
@@ -585,6 +585,28 @@ static njs_external_t njs_unit_test_r_h
};
+static njs_external_t njs_unit_test_r_header_props2[] = {
+
+ {
+ .flags = NJS_EXTERN_PROPERTY | NJS_EXTERN_SYMBOL,
+ .name.symbol = NJS_SYMBOL_TO_STRING_TAG,
+ .u.property = {
+ .value = "Header2",
+ }
+ },
+
+ {
+ .flags = NJS_EXTERN_SELF,
+ .u.object = {
+ .enumerable = 1,
+ .prop_handler = njs_unit_test_r_header,
+ .keys = njs_unit_test_r_header_keys,
+ }
+ },
+
+};
+
+
static njs_external_t njs_unit_test_r_external[] = {
{
@@ -645,6 +667,17 @@ static njs_external_t njs_unit_test_r_e
},
{
+ .flags = NJS_EXTERN_OBJECT,
+ .name.string = njs_str("header2"),
+ .writable = 1,
+ .configurable = 1,
+ .u.object = {
+ .properties = njs_unit_test_r_header_props2,
+ .nproperties = njs_nitems(njs_unit_test_r_header_props2),
+ }
+ },
+
+ {
.flags = NJS_EXTERN_PROPERTY,
.name.string = njs_str("host"),
.enumerable = 1,
diff -r ef1fd66c094e -r a2a24c4b2541 src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c Tue Dec 06 18:47:53 2022 -0800
+++ b/src/test/njs_unit_test.c Wed Dec 07 18:11:54 2022 -0800
@@ -21712,6 +21712,9 @@ static njs_unit_test_t njs_externals_te
{ njs_str("njs.dump($r.header)"),
njs_str("Header {01:'01|АБВ',02:'02|АБВ',03:'03|АБВ'}") },
+ { njs_str("njs.dump($r.header2)"),
+ njs_str("Header2 {01:'01|АБВ',02:'02|АБВ',03:'03|АБВ'}") },
+
{ njs_str("var o = {b:$r.props.b}; o.b"),
njs_str("42") },
More information about the nginx-devel
mailing list