[njs] Introduced njs_vm_value_enumerate() and njs_vm_value_own_enumerate().

Dmitry Volyntsev xeioex at nginx.com
Tue Mar 19 05:56:56 UTC 2024


details:   https://hg.nginx.org/njs/rev/1aa2bb15c966
branches:  
changeset: 2300:1aa2bb15c966
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Fri Mar 15 23:14:39 2024 -0700
description:
Introduced njs_vm_value_enumerate() and njs_vm_value_own_enumerate().

diffstat:

 src/njs.h       |  16 ++++++++++
 src/njs_value.h |  12 -------
 src/njs_vm.c    |  88 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 104 insertions(+), 12 deletions(-)

diffs (153 lines):

diff -r b0e42db5ca84 -r 1aa2bb15c966 src/njs.h
--- a/src/njs.h	Fri Mar 15 22:47:50 2024 -0700
+++ b/src/njs.h	Fri Mar 15 23:14:39 2024 -0700
@@ -129,6 +129,18 @@ typedef enum {
 
 
 typedef enum {
+#define njs_object_enum_kind(flags) (flags & 7)
+    NJS_ENUM_KEYS = 1,
+    NJS_ENUM_VALUES = 2,
+    NJS_ENUM_BOTH = 4,
+#define njs_object_enum(flags) (flags & (NJS_ENUM_STRING | NJS_ENUM_SYMBOL))
+    NJS_ENUM_STRING = 8,
+    NJS_ENUM_SYMBOL = 16,
+    NJS_ENUM_ENUMERABLE_ONLY = 32,
+} njs_object_enum_t;
+
+
+typedef enum {
     /*
      * Extern property type.
      */
@@ -497,6 +509,10 @@ NJS_EXPORT njs_int_t njs_vm_object_alloc
     ...);
 NJS_EXPORT njs_value_t *njs_vm_object_keys(njs_vm_t *vm, njs_value_t *value,
     njs_value_t *retval);
+NJS_EXPORT njs_value_t *njs_vm_value_enumerate(njs_vm_t *vm, njs_value_t *value,
+    uint32_t flags, njs_value_t *retval);
+NJS_EXPORT njs_value_t *njs_vm_value_own_enumerate(njs_vm_t *vm,
+    njs_value_t *value, uint32_t flags, njs_value_t *retval);
 NJS_EXPORT njs_value_t *njs_vm_object_prop(njs_vm_t *vm,
     njs_value_t *value, const njs_str_t *key, njs_opaque_value_t *retval);
 NJS_EXPORT njs_int_t njs_vm_object_prop_set(njs_vm_t *vm, njs_value_t *value,
diff -r b0e42db5ca84 -r 1aa2bb15c966 src/njs_value.h
--- a/src/njs_value.h	Fri Mar 15 22:47:50 2024 -0700
+++ b/src/njs_value.h	Fri Mar 15 23:14:39 2024 -0700
@@ -313,18 +313,6 @@ struct njs_object_type_init_s {
 
 
 typedef enum {
-#define njs_object_enum_kind(flags) (flags & 7)
-    NJS_ENUM_KEYS = 1,
-    NJS_ENUM_VALUES = 2,
-    NJS_ENUM_BOTH = 4,
-#define njs_object_enum(flags) (flags & (NJS_ENUM_STRING | NJS_ENUM_SYMBOL))
-    NJS_ENUM_STRING = 8,
-    NJS_ENUM_SYMBOL = 16,
-    NJS_ENUM_ENUMERABLE_ONLY = 32,
-} njs_object_enum_t;
-
-
-typedef enum {
     NJS_PROPERTY = 0,
     NJS_ACCESSOR,
     NJS_PROPERTY_REF,
diff -r b0e42db5ca84 -r 1aa2bb15c966 src/njs_vm.c
--- a/src/njs_vm.c	Fri Mar 15 22:47:50 2024 -0700
+++ b/src/njs_vm.c	Fri Mar 15 23:14:39 2024 -0700
@@ -1114,6 +1114,94 @@ njs_vm_exception_string(njs_vm_t *vm, nj
 }
 
 
+njs_value_t *
+njs_vm_value_enumerate(njs_vm_t *vm, njs_value_t *value, uint32_t flags,
+    njs_value_t *retval)
+{
+    ssize_t                  length;
+    njs_int_t                ret;
+    njs_value_t              *val;
+    njs_array_t              *keys;
+    njs_rbtree_t             *variables;
+    njs_rbtree_node_t        *rb_node;
+    njs_variable_node_t      *node;
+    const njs_lexer_entry_t  *lex_entry;
+
+    static const njs_str_t  njs_this_str = njs_str("this");
+
+    keys = njs_value_enumerate(vm, value, flags);
+    if (njs_slow_path(keys == NULL)) {
+        return NULL;
+    }
+
+    if (!njs_values_same(value, &vm->global_value)
+        || vm->global_scope == NULL)
+    {
+        goto done;
+    }
+
+    /* TODO: workaround for values in global object. */
+
+    variables = &vm->global_scope->variables;
+    rb_node = njs_rbtree_min(variables);
+
+    while (njs_rbtree_is_there_successor(variables, rb_node)) {
+        node = (njs_variable_node_t *) rb_node;
+
+        lex_entry = njs_lexer_entry(node->variable->unique_id);
+        if (njs_slow_path(lex_entry == NULL)) {
+            return NULL;
+        }
+
+        if (njs_strstr_eq(&lex_entry->name, &njs_this_str)) {
+            rb_node = njs_rbtree_node_successor(variables, rb_node);
+            continue;
+        }
+
+        length = njs_utf8_length(lex_entry->name.start, lex_entry->name.length);
+        if (njs_slow_path(length < 0)) {
+            return NULL;
+        }
+
+        val = njs_array_push(vm, keys);
+        if (njs_slow_path(value == NULL)) {
+            return NULL;
+        }
+
+        ret = njs_string_new(vm, val, lex_entry->name.start,
+                             lex_entry->name.length, length);
+        if (njs_slow_path(ret != NJS_OK)) {
+            return NULL;
+        }
+
+        rb_node = njs_rbtree_node_successor(variables, rb_node);
+    }
+
+done:
+
+     njs_set_array(retval, keys);
+
+     return retval;
+}
+
+
+njs_value_t *
+njs_vm_value_own_enumerate(njs_vm_t *vm, njs_value_t *value, uint32_t flags,
+    njs_value_t *retval)
+{
+    njs_array_t  *keys;
+
+    keys = njs_value_own_enumerate(vm, value, flags);
+    if (njs_slow_path(keys == NULL)) {
+        return NULL;
+    }
+
+    njs_set_array(retval, keys);
+
+    return retval;
+}
+
+
 njs_int_t
 njs_vm_object_alloc(njs_vm_t *vm, njs_value_t *retval, ...)
 {


More information about the nginx-devel mailing list