[njs] Object.getOwnPropertyDescriptor() method.
Dmitry Volyntsev
xeioex at nginx.com
Tue Jun 13 14:52:30 UTC 2017
details: http://hg.nginx.org/njs/rev/cf6b4a543eea
branches:
changeset: 364:cf6b4a543eea
user: Dmitry Volyntsev <xeioex at 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") },
More information about the nginx-devel
mailing list