[njs] Added Object.getOwnPropertyDescriptors().

Dmitry Volyntsev xeioex at nginx.com
Thu Mar 28 18:27:15 UTC 2019


details:   https://hg.nginx.org/njs/rev/5f273795d8dc
branches:  
changeset: 860:5f273795d8dc
user:      Artem S. Povalyukhin <artem.povaluhin at gmail.com>
date:      Wed Mar 27 20:49:03 2019 +0300
description:
Added Object.getOwnPropertyDescriptors().

This closes #119 issue on Github.

diffstat:

 njs/njs_object.c         |  77 ++++++++++++++++++++++++++++++++++++++++++++++++
 njs/test/njs_unit_test.c |  16 +++++++++
 2 files changed, 93 insertions(+), 0 deletions(-)

diffs (120 lines):

diff -r 3033faf46265 -r 5f273795d8dc njs/njs_object.c
--- a/njs/njs_object.c	Wed Mar 27 20:45:39 2019 +0300
+++ b/njs/njs_object.c	Wed Mar 27 20:49:03 2019 +0300
@@ -1783,6 +1783,75 @@ njs_object_get_own_property_descriptor(n
 
 
 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_obje
                                      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,
diff -r 3033faf46265 -r 5f273795d8dc njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c	Wed Mar 27 20:45:39 2019 +0300
+++ b/njs/test/njs_unit_test.c	Wed Mar 27 20:49:03 2019 +0300
@@ -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") },
 


More information about the nginx-devel mailing list