[njs] Fixed Object.values() and Object.entries() for shared objects.

Dmitry Volyntsev xeioex at nginx.com
Thu Jul 11 12:34:04 UTC 2019


details:   https://hg.nginx.org/njs/rev/b4e326104195
branches:  
changeset: 1039:b4e326104195
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Thu Jul 11 15:33:40 2019 +0300
description:
Fixed Object.values() and Object.entries() for shared objects.

Previously, there was a mismatch between
njs_object_enumerate_object_length() and
njs_object_own_enumerate_object() in the way they enumerated
values.

This closes #194, #195, #196 issues on Github.

diffstat:

 njs/njs_object.c         |  110 ++++++++++++++++++++++------------------------
 njs/test/njs_unit_test.c |    9 +++
 2 files changed, 62 insertions(+), 57 deletions(-)

diffs (154 lines):

diff -r 4a4d55f968a0 -r b4e326104195 njs/njs_object.c
--- a/njs/njs_object.c	Wed Jul 10 21:54:33 2019 +0300
+++ b/njs/njs_object.c	Thu Jul 11 15:33:40 2019 +0300
@@ -978,29 +978,27 @@ njs_object_own_enumerate_object(njs_vm_t
             }
         }
 
-        if (nxt_slow_path(all)) {
-            nxt_lvlhsh_each_init(&lhe, &njs_object_hash_proto);
-            hash = &object->shared_hash;
-
-            for ( ;; ) {
-                prop = nxt_lvlhsh_each(hash, &lhe);
-
-                if (prop == NULL) {
-                    break;
-                }
-
-                lhq.key_hash = lhe.key_hash;
-                njs_string_get(&prop->name, &lhq.key);
-
-                lhq.proto = &njs_object_hash_proto;
-                ret = nxt_lvlhsh_find(&object->hash, &lhq);
-
-                if (ret != NXT_OK) {
-                    ext_prop = njs_object_exist_in_proto(parent, object, &lhq);
-
-                    if (ext_prop == NULL) {
-                        *item++ = prop->value;
-                    }
+        nxt_lvlhsh_each_init(&lhe, &njs_object_hash_proto);
+        hash = &object->shared_hash;
+
+        for ( ;; ) {
+            prop = nxt_lvlhsh_each(hash, &lhe);
+
+            if (prop == NULL) {
+                break;
+            }
+
+            lhq.key_hash = lhe.key_hash;
+            njs_string_get(&prop->name, &lhq.key);
+
+            lhq.proto = &njs_object_hash_proto;
+            ret = nxt_lvlhsh_find(&object->hash, &lhq);
+
+            if (ret != NXT_OK) {
+                ext_prop = njs_object_exist_in_proto(parent, object, &lhq);
+
+                if (ext_prop == NULL && (prop->enumerable || all)) {
+                    *item++ = prop->value;
                 }
             }
         }
@@ -1039,41 +1037,39 @@ njs_object_own_enumerate_object(njs_vm_t
             }
         }
 
-        if (nxt_slow_path(all)) {
-            nxt_lvlhsh_each_init(&lhe, &njs_object_hash_proto);
-            hash = &object->shared_hash;
-
-            for ( ;; ) {
-                prop = nxt_lvlhsh_each(hash, &lhe);
-
-                if (prop == NULL) {
-                    break;
-                }
-
-                lhq.key_hash = lhe.key_hash;
-                njs_string_get(&prop->name, &lhq.key);
-
-                lhq.proto = &njs_object_hash_proto;
-                ret = nxt_lvlhsh_find(&object->hash, &lhq);
-
-                if (ret != NXT_OK) {
-                    ext_prop = njs_object_exist_in_proto(parent, object, &lhq);
-
-                    if (ext_prop == NULL) {
-                        entry = njs_array_alloc(vm, 2, 0);
-                        if (nxt_slow_path(entry == NULL)) {
-                            return NJS_ERROR;
-                        }
-
-                        njs_string_copy(&entry->start[0], &prop->name);
-
-                        /* GC: retain. */
-                        entry->start[1] = prop->value;
-
-                        njs_set_array(item, entry);
-
-                        item++;
+        nxt_lvlhsh_each_init(&lhe, &njs_object_hash_proto);
+        hash = &object->shared_hash;
+
+        for ( ;; ) {
+            prop = nxt_lvlhsh_each(hash, &lhe);
+
+            if (prop == NULL) {
+                break;
+            }
+
+            lhq.key_hash = lhe.key_hash;
+            njs_string_get(&prop->name, &lhq.key);
+
+            lhq.proto = &njs_object_hash_proto;
+            ret = nxt_lvlhsh_find(&object->hash, &lhq);
+
+            if (ret != NXT_OK && (prop->enumerable || all)) {
+                ext_prop = njs_object_exist_in_proto(parent, object, &lhq);
+
+                if (ext_prop == NULL) {
+                    entry = njs_array_alloc(vm, 2, 0);
+                    if (nxt_slow_path(entry == NULL)) {
+                        return NJS_ERROR;
                     }
+
+                    njs_string_copy(&entry->start[0], &prop->name);
+
+                    /* GC: retain. */
+                    entry->start[1] = prop->value;
+
+                    njs_set_array(item, entry);
+
+                    item++;
                 }
             }
         }
diff -r 4a4d55f968a0 -r b4e326104195 njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c	Wed Jul 10 21:54:33 2019 +0300
+++ b/njs/test/njs_unit_test.c	Thu Jul 11 15:33:40 2019 +0300
@@ -9251,6 +9251,12 @@ static njs_unit_test_t  njs_test[] =
     { nxt_string("Object.values(1)"),
       nxt_string("") },
 
+    { nxt_string("Object.values(njs)[0] === njs.version"),
+      nxt_string("true") },
+
+    { nxt_string("Object.values(process)"),
+      nxt_string("") },
+
     { nxt_string("Object.values()"),
       nxt_string("TypeError: cannot convert undefined argument to object") },
 
@@ -9274,6 +9280,9 @@ static njs_unit_test_t  njs_test[] =
     { nxt_string("Object.entries(true)"),
       nxt_string("") },
 
+    { nxt_string("Object.entries(njs)[0][1] === njs.version"),
+      nxt_string("true") },
+
     { nxt_string("Object.entries()"),
       nxt_string("TypeError: cannot convert undefined argument to object") },
 


More information about the nginx-devel mailing list