details: http://hg.nginx.org/njs/rev/499ed5aa4f98 branches: changeset: 361:499ed5aa4f98 user: Dmitry Volyntsev <xei...@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); _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel