[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