details: https://hg.nginx.org/njs/rev/a2a24c4b2541 branches: changeset: 2009:a2a24c4b2541 user: Dmitry Volyntsev <xei...@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") }, _______________________________________________ nginx-devel mailing list -- nginx-devel@nginx.org To unsubscribe send an email to nginx-devel-le...@nginx.org