details: http://hg.nginx.org/njs/rev/cf6b4a543eea branches: changeset: 364:cf6b4a543eea user: Dmitry Volyntsev <xei...@nginx.com> date: Tue Jun 13 17:52:11 2017 +0300 description: Object.getOwnPropertyDescriptor() method.
diffstat: njs/njs_object.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++ njs/test/njs_unit_test.c | 33 ++++++++++ 2 files changed, 184 insertions(+), 0 deletions(-) diffs (211 lines): diff -r 8b5f5dbcbfe7 -r cf6b4a543eea njs/njs_object.c --- a/njs/njs_object.c Tue Jun 13 17:49:05 2017 +0300 +++ b/njs/njs_object.c Tue Jun 13 17:52:11 2017 +0300 @@ -557,6 +557,148 @@ njs_define_property(njs_vm_t *vm, njs_ob } +static const njs_value_t njs_object_value_string = njs_string("value"); +static const njs_value_t njs_object_configurable_string = + njs_string("configurable"); +static const njs_value_t njs_object_enumerable_string = + njs_string("enumerable"); +static const njs_value_t njs_object_writable_string = + njs_string("writable"); + + +static njs_ret_t +njs_object_get_own_property_descriptor(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused) +{ + uint32_t index; + nxt_int_t ret; + njs_array_t *array; + njs_object_t *descriptor; + njs_object_prop_t *pr, *prop, array_prop; + const njs_value_t *value; + nxt_lvlhsh_query_t lhq; + + if (nargs < 3 || !njs_is_object(&args[1])) { + vm->exception = &njs_exception_type_error; + return NXT_ERROR; + } + + prop = NULL; + + if (njs_is_array(&args[1])) { + array = args[1].data.u.array; + index = njs_string_to_index(&args[2]); + + if (index < array->length && njs_is_valid(&array->start[index])) { + prop = &array_prop; + + array_prop.name = args[2]; + array_prop.value = array->start[index]; + + array_prop.configurable = 1; + array_prop.enumerable = 1; + array_prop.writable = 1; + } + } + + lhq.proto = &njs_object_hash_proto; + + if (prop == NULL) { + njs_string_get(&args[2], &lhq.key); + lhq.key_hash = nxt_djb_hash(lhq.key.start, lhq.key.length); + + ret = nxt_lvlhsh_find(&args[1].data.u.object->hash, &lhq); + + if (ret != NXT_OK) { + vm->retval = njs_string_void; + return NXT_OK; + } + + prop = lhq.value; + } + + descriptor = njs_object_alloc(vm); + if (nxt_slow_path(descriptor == NULL)) { + return NXT_ERROR; + } + + lhq.replace = 0; + lhq.pool = vm->mem_cache_pool; + + lhq.key = nxt_string_value("value"); + lhq.key_hash = NJS_VALUE_HASH; + + pr = njs_object_prop_alloc(vm, &njs_object_value_string, &prop->value, 1); + if (nxt_slow_path(pr == NULL)) { + return NXT_ERROR; + } + + lhq.value = pr; + + ret = nxt_lvlhsh_insert(&descriptor->hash, &lhq); + if (nxt_slow_path(ret != NXT_OK)) { + return NXT_ERROR; + } + + lhq.key = nxt_string_value("configurable"); + lhq.key_hash = NJS_CONFIGURABLE_HASH; + + value = (prop->configurable == 1) ? &njs_string_true : &njs_string_false; + + pr = njs_object_prop_alloc(vm, &njs_object_configurable_string, value, 1); + if (nxt_slow_path(pr == NULL)) { + return NXT_ERROR; + } + + lhq.value = pr; + + ret = nxt_lvlhsh_insert(&descriptor->hash, &lhq); + if (nxt_slow_path(ret != NXT_OK)) { + return NXT_ERROR; + } + + lhq.key = nxt_string_value("enumerable"); + lhq.key_hash = NJS_ENUMERABLE_HASH; + + value = (prop->enumerable == 1) ? &njs_string_true : &njs_string_false; + + pr = njs_object_prop_alloc(vm, &njs_object_enumerable_string, value, 1); + if (nxt_slow_path(pr == NULL)) { + return NXT_ERROR; + } + + lhq.value = pr; + + ret = nxt_lvlhsh_insert(&descriptor->hash, &lhq); + if (nxt_slow_path(ret != NXT_OK)) { + return NXT_ERROR; + } + + lhq.key = nxt_string_value("writable"); + lhq.key_hash = NJS_WRITABABLE_HASH; + + value = (prop->writable == 1) ? &njs_string_true : &njs_string_false; + + pr = njs_object_prop_alloc(vm, &njs_object_writable_string, value, 1); + if (nxt_slow_path(pr == NULL)) { + return NXT_ERROR; + } + + lhq.value = pr; + + ret = nxt_lvlhsh_insert(&descriptor->hash, &lhq); + if (nxt_slow_path(ret != NXT_OK)) { + return NXT_ERROR; + } + + vm->retval.data.u.object = descriptor; + vm->retval.type = NJS_OBJECT; + vm->retval.data.truth = 1; + + return NXT_OK; +} + + static njs_ret_t njs_object_get_prototype_of(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) @@ -732,6 +874,15 @@ static const njs_object_prop_t njs_obje NJS_OBJECT_ARG), }, + /* Object.getOwnPropertyDescriptor(). */ + { + .type = NJS_METHOD, + .name = njs_long_string("getOwnPropertyDescriptor"), + .value = njs_native_function(njs_object_get_own_property_descriptor, 0, + NJS_SKIP_ARG, NJS_OBJECT_ARG, + NJS_STRING_ARG), + }, + /* Object.getPrototypeOf(). */ { .type = NJS_METHOD, diff -r 8b5f5dbcbfe7 -r cf6b4a543eea njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Tue Jun 13 17:49:05 2017 +0300 +++ b/njs/test/njs_unit_test.c Tue Jun 13 17:52:11 2017 +0300 @@ -6038,6 +6038,39 @@ static njs_unit_test_t njs_test[] = "1..isPrototypeOf(p)"), nxt_string("false") }, + { nxt_string("Object.getOwnPropertyDescriptor({a:1}, 'a').value"), + nxt_string("1") }, + + { nxt_string("Object.getOwnPropertyDescriptor({a:1}, 'a').configurable"), + nxt_string("true") }, + + { nxt_string("Object.getOwnPropertyDescriptor({a:1}, 'a').enumerable"), + nxt_string("true") }, + + { nxt_string("Object.getOwnPropertyDescriptor({a:1}, 'a').writable"), + nxt_string("true") }, + + { nxt_string("Object.getOwnPropertyDescriptor({a:1}, 'b')"), + nxt_string("undefined") }, + + { nxt_string("Object.getOwnPropertyDescriptor({}, 'a')"), + nxt_string("undefined") }, + + { nxt_string("Object.getOwnPropertyDescriptor([3,4], '1').value"), + nxt_string("4") }, + + { nxt_string("Object.getOwnPropertyDescriptor([3,4], 1).value"), + nxt_string("4") }, + + { nxt_string("Object.getOwnPropertyDescriptor([3,4], '3')"), + nxt_string("undefined") }, + + { nxt_string("Object.getOwnPropertyDescriptor([], '0')"), + nxt_string("undefined") }, + + { nxt_string("Object.getOwnPropertyDescriptor(1, '0')"), + nxt_string("TypeError") }, + { nxt_string("var d = new Date(''); d +' '+ d.getTime()"), nxt_string("Invalid Date NaN") }, _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel