]> git.kaiwu.me - njs.git/commitdiff
Fixed Object.values() and Object.entries() for shared objects.
authorDmitry Volyntsev <xeioex@nginx.com>
Thu, 11 Jul 2019 12:33:40 +0000 (15:33 +0300)
committerDmitry Volyntsev <xeioex@nginx.com>
Thu, 11 Jul 2019 12:33:40 +0000 (15:33 +0300)
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.

njs/njs_object.c
njs/test/njs_unit_test.c

index 32097eb25134e3d20c9b728d3fe33b5f192625e7..2a17e204b20ae7a21732c7fbb12d29ca5655e121 100644 (file)
@@ -978,29 +978,27 @@ njs_object_own_enumerate_object(njs_vm_t *vm, const njs_object_t *object,
             }
         }
 
-        if (nxt_slow_path(all)) {
-            nxt_lvlhsh_each_init(&lhe, &njs_object_hash_proto);
-            hash = &object->shared_hash;
+        nxt_lvlhsh_each_init(&lhe, &njs_object_hash_proto);
+        hash = &object->shared_hash;
 
-            for ( ;; ) {
-                prop = nxt_lvlhsh_each(hash, &lhe);
+        for ( ;; ) {
+            prop = nxt_lvlhsh_each(hash, &lhe);
 
-                if (prop == NULL) {
-                    break;
-                }
+            if (prop == NULL) {
+                break;
+            }
 
-                lhq.key_hash = lhe.key_hash;
-                njs_string_get(&prop->name, &lhq.key);
+            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);
+            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 (ret != NXT_OK) {
+                ext_prop = njs_object_exist_in_proto(parent, object, &lhq);
 
-                    if (ext_prop == NULL) {
-                        *item++ = prop->value;
-                    }
+                if (ext_prop == NULL && (prop->enumerable || all)) {
+                    *item++ = prop->value;
                 }
             }
         }
@@ -1039,41 +1037,39 @@ njs_object_own_enumerate_object(njs_vm_t *vm, const njs_object_t *object,
             }
         }
 
-        if (nxt_slow_path(all)) {
-            nxt_lvlhsh_each_init(&lhe, &njs_object_hash_proto);
-            hash = &object->shared_hash;
+        nxt_lvlhsh_each_init(&lhe, &njs_object_hash_proto);
+        hash = &object->shared_hash;
 
-            for ( ;; ) {
-                prop = nxt_lvlhsh_each(hash, &lhe);
+        for ( ;; ) {
+            prop = nxt_lvlhsh_each(hash, &lhe);
 
-                if (prop == NULL) {
-                    break;
-                }
+            if (prop == NULL) {
+                break;
+            }
 
-                lhq.key_hash = lhe.key_hash;
-                njs_string_get(&prop->name, &lhq.key);
+            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);
+            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 (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;
-                        }
+                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);
+                    njs_string_copy(&entry->start[0], &prop->name);
 
-                        /* GC: retain. */
-                        entry->start[1] = prop->value;
+                    /* GC: retain. */
+                    entry->start[1] = prop->value;
 
-                        njs_set_array(item, entry);
+                    njs_set_array(item, entry);
 
-                        item++;
-                    }
+                    item++;
                 }
             }
         }
index 32bf7c4013050f232c981baf963b31562298030f..d5ff6ad006b932208a05768dd808ee8e17a00132 100644 (file)
@@ -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") },