[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