[njs] Fixed Object.values() and Object.entries() with external objects.
Dmitry Volyntsev
xeioex at nginx.com
Sat Jan 7 00:52:53 UTC 2023
details: https://hg.nginx.org/njs/rev/a98b63e87688
branches:
changeset: 2024:a98b63e87688
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Fri Jan 06 16:50:46 2023 -0800
description:
Fixed Object.values() and Object.entries() with external objects.
This closes #606 issue on Github.
diffstat:
src/njs_value.c | 73 ++++++++++++++++++++++++++++++++++++++++++-----
src/test/njs_unit_test.c | 9 +++++
2 files changed, 73 insertions(+), 9 deletions(-)
diffs (112 lines):
diff -r 1a5d22feadc2 -r a98b63e87688 src/njs_value.c
--- a/src/njs_value.c Thu Jan 05 22:05:03 2023 -0800
+++ b/src/njs_value.c Fri Jan 06 16:50:46 2023 -0800
@@ -231,25 +231,80 @@ njs_array_t *
njs_value_own_enumerate(njs_vm_t *vm, njs_value_t *value,
njs_object_enum_t kind, njs_object_enum_type_t type, njs_bool_t all)
{
- njs_int_t ret;
- njs_value_t keys;
+ njs_int_t ret, len;
+ njs_array_t *values, *entry;
+ njs_value_t keys, *k, *dst, *end;
njs_object_value_t obj_val;
njs_exotic_slots_t *slots;
if (njs_is_object(value)) {
- if (kind == NJS_ENUM_KEYS && (type & NJS_ENUM_STRING)) {
- slots = njs_object_slots(value);
- if (slots != NULL && slots->keys != NULL) {
- ret = slots->keys(vm, value, &keys);
+ slots = njs_object_slots(value);
+ if (slots == NULL || slots->keys == NULL) {
+ return njs_object_own_enumerate(vm, njs_object(value), kind, type,
+ all);
+ }
+
+ ret = slots->keys(vm, value, &keys);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return NULL;
+ }
+
+ switch (kind) {
+ case NJS_ENUM_KEYS:
+ return njs_array(&keys);
+
+ case NJS_ENUM_VALUES:
+ len = njs_array_len(&keys);
+ k = njs_array(&keys)->start;
+ end = k + len;
+
+ values = njs_array_alloc(vm, 1, len, 0);
+ if (njs_slow_path(values == NULL)) {
+ return NULL;
+ }
+
+ dst = values->start;
+
+ while (k < end) {
+ ret = njs_value_property(vm, value, k++, dst++);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return NULL;
+ }
+ }
+
+ return values;
+
+ case NJS_ENUM_BOTH:
+ default:
+ len = njs_array_len(&keys);
+ k = njs_array(&keys)->start;
+ end = k + len;
+
+ values = njs_array_alloc(vm, 1, len, 0);
+ if (njs_slow_path(values == NULL)) {
+ return NULL;
+ }
+
+ dst = values->start;
+
+ while (k < end) {
+ entry = njs_array_alloc(vm, 1, 2, 0);
+ if (njs_slow_path(entry == NULL)) {
+ return NULL;
+ }
+
+ ret = njs_value_property(vm, value, k, &entry->start[1]);
if (njs_slow_path(ret != NJS_OK)) {
return NULL;
}
- return njs_array(&keys);
+ njs_value_assign(&entry->start[0], k++);
+
+ njs_set_array(dst++, entry);
}
+
+ return values;
}
-
- return njs_object_own_enumerate(vm, njs_object(value), kind, type, all);
}
if (value->type != NJS_STRING) {
diff -r 1a5d22feadc2 -r a98b63e87688 src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c Thu Jan 05 22:05:03 2023 -0800
+++ b/src/test/njs_unit_test.c Fri Jan 06 16:50:46 2023 -0800
@@ -21712,6 +21712,15 @@ static njs_unit_test_t njs_externals_te
{ njs_str("njs.dump($r).startsWith('External')"),
njs_str("true") },
+ { njs_str("Object.keys($r.header)"),
+ njs_str("01,02,03") },
+
+ { njs_str("Object.values($r.header)"),
+ njs_str("01|АБВ,02|АБВ,03|АБВ") },
+
+ { njs_str("njs.dump(Object.entries($r.header))"),
+ njs_str("[['01','01|АБВ'],['02','02|АБВ'],['03','03|АБВ']]") },
+
{ njs_str("njs.dump($r.header)"),
njs_str("Header {01:'01|АБВ',02:'02|АБВ',03:'03|АБВ'}") },
More information about the nginx-devel
mailing list