[njs] Object.defineProperties() method.

Dmitry Volyntsev xeioex at nginx.com
Fri Jun 9 17:28:44 UTC 2017


details:   http://hg.nginx.org/njs/rev/499ed5aa4f98
branches:  
changeset: 361:499ed5aa4f98
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Fri Jun 09 20:28:15 2017 +0300
description:
Object.defineProperties() method.

diffstat:

 njs/njs_object.c         |  85 ++++++++++++++++++++++++++++++++++++++++++-----
 njs/test/njs_unit_test.c |  21 +++++++++++
 nxt/nxt_lvlhsh.h         |   6 +++
 3 files changed, 103 insertions(+), 9 deletions(-)

diffs (177 lines):

diff -r 740823b9f444 -r 499ed5aa4f98 njs/njs_object.c
--- a/njs/njs_object.c	Fri Jun 09 17:55:21 2017 +0300
+++ b/njs/njs_object.c	Fri Jun 09 20:28:15 2017 +0300
@@ -26,6 +26,8 @@
 
 
 static nxt_int_t njs_object_hash_test(nxt_lvlhsh_query_t *lhq, void *data);
+static njs_ret_t njs_define_property(njs_vm_t *vm, njs_object_t *object,
+    njs_value_t *name, njs_object_t *descriptor);
 
 
 nxt_noinline njs_object_t *
@@ -416,27 +418,85 @@ static njs_ret_t
 njs_object_define_property(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
     njs_index_t unused)
 {
-    nxt_int_t           ret;
-    njs_object_t        *object, *descriptor;
-    njs_object_prop_t   *prop, *pr;
-    nxt_lvlhsh_query_t  lhq, pq;
+    nxt_int_t  ret;
 
     if (nargs < 4 || !njs_is_object(&args[1]) || !njs_is_object(&args[3])) {
         vm->exception = &njs_exception_type_error;
         return NXT_ERROR;
     }
 
+    ret = njs_define_property(vm, args[1].data.u.object, &args[2],
+                              args[3].data.u.object);
+
+    if (nxt_slow_path(ret != NXT_OK)) {
+        return NXT_ERROR;
+    }
+
+    vm->retval = args[1];
+
+    return NXT_OK;
+}
+
+
+static njs_ret_t
+njs_object_define_properties(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
+    njs_index_t unused)
+{
+    nxt_int_t          ret;
+    nxt_lvlhsh_t       *hash;
+    njs_object_t       *object;
+    nxt_lvlhsh_each_t  lhe;
+    njs_object_prop_t  *prop;
+
+    if (nargs < 3 || !njs_is_object(&args[1]) || !njs_is_object(&args[2])) {
+        vm->exception = &njs_exception_type_error;
+        return NXT_ERROR;
+    }
+
+    nxt_lvlhsh_each_init(&lhe, &njs_object_hash_proto);
+
     object = args[1].data.u.object;
-    descriptor = args[3].data.u.object;
+    hash = &args[2].data.u.object->hash;
 
-    njs_string_get(&args[2], &lhq.key);
+    for ( ;; ) {
+        prop = nxt_lvlhsh_each(hash, &lhe);
+
+        if (prop == NULL) {
+            break;
+        }
+
+        if (prop->enumerable && njs_is_object(&prop->value)) {
+            ret = njs_define_property(vm, object, &prop->name,
+                                      prop->value.data.u.object);
+
+            if (nxt_slow_path(ret != NXT_OK)) {
+                return NXT_ERROR;
+            }
+        }
+    }
+
+    vm->retval = args[1];
+
+    return NXT_OK;
+}
+
+
+static njs_ret_t
+njs_define_property(njs_vm_t *vm, njs_object_t *object, njs_value_t *name,
+    njs_object_t *descriptor)
+{
+    nxt_int_t           ret;
+    njs_object_prop_t   *prop, *pr;
+    nxt_lvlhsh_query_t  lhq, pq;
+
+    njs_string_get(name, &lhq.key);
     lhq.key_hash = nxt_djb_hash(lhq.key.start, lhq.key.length);
     lhq.proto = &njs_object_hash_proto;
 
     ret = nxt_lvlhsh_find(&object->hash, &lhq);
 
     if (ret != NXT_OK) {
-        prop = njs_object_prop_alloc(vm, &args[2]);
+        prop = njs_object_prop_alloc(vm, name);
 
         if (nxt_slow_path(prop == NULL)) {
             return NXT_ERROR;
@@ -497,8 +557,6 @@ njs_object_define_property(njs_vm_t *vm,
         return NXT_ERROR;
     }
 
-    vm->retval = args[1];
-
     return NXT_OK;
 }
 
@@ -673,6 +731,15 @@ static const njs_object_prop_t  njs_obje
                                      NJS_STRING_ARG, NJS_OBJECT_ARG),
     },
 
+    /* Object.defineProperties(). */
+    {
+        .type = NJS_METHOD,
+        .name = njs_long_string("defineProperties"),
+        .value = njs_native_function(njs_object_define_properties, 0,
+                                     NJS_SKIP_ARG, NJS_OBJECT_ARG,
+                                     NJS_OBJECT_ARG),
+    },
+
     /* Object.getPrototypeOf(). */
     {
         .type = NJS_METHOD,
diff -r 740823b9f444 -r 499ed5aa4f98 njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c	Fri Jun 09 17:55:21 2017 +0300
+++ b/njs/test/njs_unit_test.c	Fri Jun 09 20:28:15 2017 +0300
@@ -5932,6 +5932,27 @@ static njs_unit_test_t  njs_test[] =
     { nxt_string("var o = {}; Object.defineProperty(o)"),
       nxt_string("TypeError") },
 
+    { nxt_string("var o = Object.defineProperties({}, {a:{value:1}}); o.a"),
+      nxt_string("1") },
+
+    { nxt_string("var o = Object.defineProperties({}, {a:{enumerable:true}, b:{enumerable:true}});"
+                 "Object.keys(o)"),
+      nxt_string("a,b") },
+
+    { nxt_string("var desc = Object.defineProperty({b:{value:1, enumerable:true}}, 'a', {});"
+                 "var o = Object.defineProperties({}, desc);"
+                 "Object.keys(o)"),
+      nxt_string("b") },
+
+    { nxt_string("var o = Object.defineProperties({a:1}, {}); o.a"),
+      nxt_string("1") },
+
+    { nxt_string("Object.defineProperties(1, {})"),
+      nxt_string("TypeError") },
+
+    { nxt_string("Object.defineProperties({}, 1)"),
+      nxt_string("TypeError") },
+
     { nxt_string("var o = {a:1}; o.hasOwnProperty('a')"),
       nxt_string("true") },
 
diff -r 740823b9f444 -r 499ed5aa4f98 nxt/nxt_lvlhsh.h
--- a/nxt/nxt_lvlhsh.h	Fri Jun 09 17:55:21 2017 +0300
+++ b/nxt/nxt_lvlhsh.h	Fri Jun 09 20:28:15 2017 +0300
@@ -173,6 +173,12 @@ typedef struct {
 } nxt_lvlhsh_each_t;
 
 
+#define nxt_lvlhsh_each_init(lhe, _proto)                                     \
+    do {                                                                      \
+        memset(lhe, 0, sizeof(nxt_lvlhsh_each_t));                            \
+        (lhe)->proto = _proto;                                                \
+    } while (0)
+
 NXT_EXPORT void *nxt_lvlhsh_each(nxt_lvlhsh_t *lh, nxt_lvlhsh_each_t *le);
 
 


More information about the nginx-devel mailing list