From 66f880907af5b59ed9b642ea460137a986f89a28 Mon Sep 17 00:00:00 2001 From: Dmitry Volyntsev Date: Fri, 15 Mar 2024 23:14:39 -0700 Subject: [PATCH] Introduced njs_vm_value_enumerate() and njs_vm_value_own_enumerate(). --- src/njs.h | 16 +++++++++ src/njs_value.h | 12 ------- src/njs_vm.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 12 deletions(-) diff --git a/src/njs.h b/src/njs.h index 4dfa2da6..6e1e1a2d 100644 --- a/src/njs.h +++ b/src/njs.h @@ -128,6 +128,18 @@ typedef enum { } njs_wellknown_symbol_t; +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_vm_t *vm, njs_value_t *retval, ...); 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 --git a/src/njs_value.h b/src/njs_value.h index 57f9790e..3751db71 100644 --- a/src/njs_value.h +++ b/src/njs_value.h @@ -312,18 +312,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, diff --git a/src/njs_vm.c b/src/njs_vm.c index 9c8be437..0db83704 100644 --- a/src/njs_vm.c +++ b/src/njs_vm.c @@ -1114,6 +1114,94 @@ njs_vm_exception_string(njs_vm_t *vm, njs_str_t *dst) } +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, ...) { -- 2.47.3