]> git.kaiwu.me - njs.git/commitdiff
Added Object.getOwnPropertyDescriptors().
authorArtem S. Povalyukhin <artem.povaluhin@gmail.com>
Wed, 27 Mar 2019 17:49:03 +0000 (20:49 +0300)
committerArtem S. Povalyukhin <artem.povaluhin@gmail.com>
Wed, 27 Mar 2019 17:49:03 +0000 (20:49 +0300)
This closes #119 issue on Github.

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

index 6d0fd3f37c1f83c7b701f74b6f526a7d8d10c567..d124f6552c9f88a43f9c7489e817ec26640c9235 100644 (file)
@@ -1782,6 +1782,75 @@ njs_object_get_own_property_descriptor(njs_vm_t *vm, njs_value_t *args,
 }
 
 
+static njs_ret_t
+njs_object_get_own_property_descriptors(njs_vm_t *vm, njs_value_t *args,
+    nxt_uint_t nargs, njs_index_t unused)
+{
+    njs_ret_t           ret;
+    uint32_t            i, length;
+    njs_array_t         *names;
+    njs_value_t         descriptor;
+    njs_object_t        *descriptors;
+    const njs_value_t   *value, *key;
+    njs_object_prop_t   *pr;
+    nxt_lvlhsh_query_t  lhq;
+
+    value = njs_arg(args, nargs, 1);
+
+    if (njs_is_null_or_undefined(value)) {
+        njs_type_error(vm, "cannot convert %s argument to object",
+                       njs_type_string(value->type));
+
+        return NXT_ERROR;
+    }
+
+    names = njs_object_enumerate(vm, value, NJS_ENUM_KEYS, 1);
+    if (nxt_slow_path(names == NULL)) {
+        return NXT_ERROR;
+    }
+
+    length = names->length;
+
+    descriptors = njs_object_alloc(vm);
+    if (nxt_slow_path(descriptors == NULL)) {
+        return NXT_ERROR;
+    }
+
+    lhq.replace = 0;
+    lhq.pool = vm->mem_pool;
+    lhq.proto = &njs_object_hash_proto;
+
+    for (i = 0; i < length; i++) {
+        key = &names->start[i];
+        ret = njs_object_property_descriptor(vm, &descriptor, value, key);
+        if (nxt_slow_path(ret != NXT_OK)) {
+            return ret;
+        }
+
+        pr = njs_object_prop_alloc(vm, key, &descriptor, 1);
+        if (nxt_slow_path(pr == NULL)) {
+            return NXT_ERROR;
+        }
+
+        njs_string_get(key, &lhq.key);
+        lhq.key_hash = nxt_djb_hash(lhq.key.start, lhq.key.length);
+        lhq.value = pr;
+
+        ret = nxt_lvlhsh_insert(&descriptors->hash, &lhq);
+        if (nxt_slow_path(ret != NXT_OK)) {
+            njs_internal_error(vm, "lvlhsh insert failed");
+            return NXT_ERROR;
+        }
+    }
+
+    vm->retval.data.u.object = descriptors;
+    vm->retval.type = NJS_OBJECT;
+    vm->retval.data.truth = 1;
+
+    return NXT_OK;
+}
+
+
 static njs_ret_t
 njs_object_get_own_property_names(njs_vm_t *vm, njs_value_t *args,
     nxt_uint_t nargs, njs_index_t unused)
@@ -2243,6 +2312,14 @@ static const njs_object_prop_t  njs_object_constructor_properties[] =
                                      NJS_STRING_ARG),
     },
 
+    /* Object.getOwnPropertyDescriptors(). */
+    {
+        .type = NJS_METHOD,
+        .name = njs_long_string("getOwnPropertyDescriptors"),
+        .value = njs_native_function(njs_object_get_own_property_descriptors, 0,
+                                     NJS_SKIP_ARG, NJS_OBJECT_ARG),
+    },
+
     /* Object.getOwnPropertyNames(). */
     {
         .type = NJS_METHOD,
index d6f62cd27487284c699b5e0b168d043127dac319..533ba1a0e8fe3b8f5281c5a95cdb1446a488ecd6 100644 (file)
@@ -8672,6 +8672,22 @@ static njs_unit_test_t  njs_test[] =
     { nxt_string("var o = {}; o[void 0] = 'a'; Object.getOwnPropertyDescriptor(o, undefined).value"),
       nxt_string("a") },
 
+    { nxt_string("Object.getOwnPropertyDescriptors()"),
+      nxt_string("TypeError: cannot convert undefined argument to object") },
+
+    { nxt_string("typeof Object.getOwnPropertyDescriptors(1)"),
+      nxt_string("object") },
+
+    { nxt_string("Object.keys(Object.getOwnPropertyDescriptors([]))"),
+      nxt_string("length") },
+
+    { nxt_string("Object.getOwnPropertyDescriptors(function(a,b,c) {}).length.value"),
+      nxt_string("3") },
+
+    { nxt_string("Object.values(Object.getOwnPropertyDescriptors('abc'))"
+                 ".reduce(function(a, x) { return a += x.value; }, '')"),
+      nxt_string("abc3") },
+
     { nxt_string("Object.getOwnPropertyNames()"),
       nxt_string("TypeError: cannot convert undefined argument to object") },