[njs] Improved object property attributes.
Dmitry Volyntsev
xeioex at nginx.com
Wed Jun 5 15:44:41 UTC 2019
details: https://hg.nginx.org/njs/rev/6d5c457a298d
branches:
changeset: 1001:6d5c457a298d
user: hongzhidao <hongzhidao at gmail.com>
date: Wed Jun 05 22:13:47 2019 +0800
description:
Improved object property attributes.
diffstat:
njs/njs_object.c | 166 +++++++++++++++++++++++++---------------------
njs/njs_object.h | 8 +-
njs/test/njs_unit_test.c | 6 +-
3 files changed, 97 insertions(+), 83 deletions(-)
diffs (366 lines):
diff -r 8b27db801cd3 -r 6d5c457a298d njs/njs_object.c
--- a/njs/njs_object.c Tue Jun 04 19:38:50 2019 +0300
+++ b/njs/njs_object.c Wed Jun 05 22:13:47 2019 +0800
@@ -223,9 +223,10 @@ njs_object_prop_alloc(njs_vm_t *vm, cons
prop->name = *name;
prop->type = NJS_PROPERTY;
+ prop->writable = attributes;
prop->enumerable = attributes;
- prop->writable = attributes;
prop->configurable = attributes;
+
return prop;
}
@@ -520,9 +521,9 @@ njs_array_property_query(njs_vm_t *vm, n
prop->type = NJS_PROPERTY_REF;
}
- prop->configurable = 1;
+ prop->writable = 1;
prop->enumerable = 1;
- prop->writable = 1;
+ prop->configurable = 1;
pq->lhq.value = prop;
@@ -550,10 +551,11 @@ njs_string_property_query(njs_vm_t *vm,
* so the function cannot fail.
*/
(void) njs_string_slice(vm, &prop->value, &string, &slice);
+
prop->type = NJS_PROPERTY;
+ prop->writable = 0;
+ prop->enumerable = 1;
prop->configurable = 0;
- prop->enumerable = 1;
- prop->writable = 0;
pq->lhq.value = prop;
@@ -583,9 +585,9 @@ njs_external_property_query(njs_vm_t *vm
prop = &pq->scratch;
prop->type = NJS_PROPERTY;
- prop->configurable = 0;
+ prop->writable = 0;
prop->enumerable = 1;
- prop->writable = 0;
+ prop->configurable = 0;
ext_proto = object->external.proto;
@@ -1798,54 +1800,49 @@ njs_object_define_properties(njs_vm_t *v
}
-static uint8_t
-njs_descriptor_attribute(njs_vm_t *vm, const njs_object_t *descriptor,
- nxt_lvlhsh_query_t *pq, nxt_bool_t unset)
-{
- njs_object_prop_t *prop;
-
- prop = njs_object_property(vm, descriptor, pq);
- if (prop != NULL) {
- return prop->value.data.truth;
- }
-
- return unset ? NJS_ATTRIBUTE_UNSET : 0;
-}
-
-
static njs_object_prop_t *
njs_descriptor_prop(njs_vm_t *vm, const njs_value_t *name,
- const njs_object_t *descriptor, nxt_bool_t unset)
+ const njs_object_t *descriptor)
{
- const njs_value_t *value;
njs_object_prop_t *prop, *pr;
nxt_lvlhsh_query_t pq;
- value = unset ? &njs_value_invalid : &njs_value_undefined;
- prop = njs_object_prop_alloc(vm, name, value, 0);
+ prop = njs_object_prop_alloc(vm, name, &njs_value_invalid,
+ NJS_ATTRIBUTE_UNSET);
if (nxt_slow_path(prop == NULL)) {
return NULL;
}
+ pq.key = nxt_string_value("value");
+ pq.key_hash = NJS_VALUE_HASH;
+
+ pr = njs_object_property(vm, descriptor, &pq);
+ if (pr != NULL) {
+ prop->value = pr->value;
+ }
+
+ pq.key = nxt_string_value("writable");
+ pq.key_hash = NJS_WRITABABLE_HASH;
+
+ pr = njs_object_property(vm, descriptor, &pq);
+ if (pr != NULL) {
+ prop->writable = pr->value.data.truth;
+ }
+
+ pq.key = nxt_string_value("enumerable");
+ pq.key_hash = NJS_ENUMERABLE_HASH;
+
+ pr = njs_object_property(vm, descriptor, &pq);
+ if (pr != NULL) {
+ prop->enumerable = pr->value.data.truth;
+ }
+
pq.key = nxt_string_value("configurable");
pq.key_hash = NJS_CONFIGURABLE_HASH;
- prop->configurable = njs_descriptor_attribute(vm, descriptor, &pq, unset);
-
- pq.key = nxt_string_value("enumerable");
- pq.key_hash = NJS_ENUMERABLE_HASH;
- prop->enumerable = njs_descriptor_attribute(vm, descriptor, &pq, unset);
-
- pq.key = nxt_string_value("writable");
- pq.key_hash = NJS_WRITABABLE_HASH;
- prop->writable = njs_descriptor_attribute(vm, descriptor, &pq, unset);
-
- pq.key = nxt_string_value("value");
- pq.key_hash = NJS_VALUE_HASH;
- pq.proto = &njs_object_hash_proto;
pr = njs_object_property(vm, descriptor, &pq);
if (pr != NULL) {
- prop->value = pr->value;
+ prop->configurable = pr->value.data.truth;
}
return prop;
@@ -1862,7 +1859,6 @@ njs_define_property(njs_vm_t *vm, njs_va
const njs_object_t *descriptor)
{
nxt_int_t ret;
- nxt_bool_t unset;
njs_object_prop_t *desc, *current;
njs_property_query_t pq;
@@ -1878,13 +1874,29 @@ njs_define_property(njs_vm_t *vm, njs_va
return ret;
}
- unset = (ret == NXT_OK);
- desc = njs_descriptor_prop(vm, name, descriptor, unset);
+ desc = njs_descriptor_prop(vm, name, descriptor);
if (nxt_slow_path(desc == NULL)) {
return NXT_ERROR;
}
if (nxt_fast_path(ret == NXT_DECLINED)) {
+
+ if (!njs_is_valid(&desc->value)) {
+ desc->value = njs_value_undefined;
+ }
+
+ if (desc->writable == NJS_ATTRIBUTE_UNSET) {
+ desc->writable = 0;
+ }
+
+ if (desc->enumerable == NJS_ATTRIBUTE_UNSET) {
+ desc->enumerable = 0;
+ }
+
+ if (desc->configurable == NJS_ATTRIBUTE_UNSET) {
+ desc->configurable = 0;
+ }
+
if (nxt_slow_path(pq.lhq.value != NULL)) {
current = pq.lhq.value;
@@ -1955,12 +1967,10 @@ njs_define_property(njs_vm_t *vm, njs_va
}
if (!current->configurable) {
- if (desc->configurable == NJS_ATTRIBUTE_TRUE) {
- goto exception;
- }
-
- if (desc->enumerable != NJS_ATTRIBUTE_UNSET
- && current->enumerable != desc->enumerable)
+
+ if (njs_is_valid(&desc->value)
+ && current->writable == NJS_ATTRIBUTE_FALSE
+ && !njs_values_strict_equal(&desc->value, ¤t->value))
{
goto exception;
}
@@ -1971,28 +1981,31 @@ njs_define_property(njs_vm_t *vm, njs_va
goto exception;
}
- if (njs_is_valid(&desc->value)
- && current->writable == NJS_ATTRIBUTE_FALSE
- && !njs_values_strict_equal(&desc->value, ¤t->value))
+ if (desc->enumerable != NJS_ATTRIBUTE_UNSET
+ && current->enumerable != desc->enumerable)
{
goto exception;
}
+
+ if (desc->configurable == NJS_ATTRIBUTE_TRUE) {
+ goto exception;
+ }
}
- if (desc->configurable != NJS_ATTRIBUTE_UNSET) {
- current->configurable = desc->configurable;
+ if (njs_is_valid(&desc->value)) {
+ current->value = desc->value;
+ }
+
+ if (desc->writable != NJS_ATTRIBUTE_UNSET) {
+ current->writable = desc->writable;
}
if (desc->enumerable != NJS_ATTRIBUTE_UNSET) {
current->enumerable = desc->enumerable;
}
- if (desc->writable != NJS_ATTRIBUTE_UNSET) {
- current->writable = desc->writable;
- }
-
- if (njs_is_valid(&desc->value)) {
- current->value = desc->value;
+ if (desc->configurable != NJS_ATTRIBUTE_UNSET) {
+ current->configurable = desc->configurable;
}
return NXT_OK;
@@ -2006,12 +2019,12 @@ exception:
static const njs_value_t njs_object_value_string = njs_string("value");
+static const njs_value_t njs_object_writable_string =
+ njs_string("writable");
+static const njs_value_t njs_object_enumerable_string =
+ njs_string("enumerable");
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
@@ -2087,7 +2100,6 @@ njs_object_property_descriptor(njs_vm_t
lhq.proto = &njs_object_hash_proto;
lhq.replace = 0;
lhq.pool = vm->mem_pool;
- lhq.proto = &njs_object_hash_proto;
lhq.key = nxt_string_value("value");
lhq.key_hash = NJS_VALUE_HASH;
@@ -2105,12 +2117,12 @@ njs_object_property_descriptor(njs_vm_t
return NXT_ERROR;
}
- lhq.key = nxt_string_value("configurable");
- lhq.key_hash = NJS_CONFIGURABLE_HASH;
-
- setval = (prop->configurable == 1) ? &njs_value_true : &njs_value_false;
-
- pr = njs_object_prop_alloc(vm, &njs_object_configurable_string, setval, 1);
+ lhq.key = nxt_string_value("writable");
+ lhq.key_hash = NJS_WRITABABLE_HASH;
+
+ setval = (prop->writable == 1) ? &njs_value_true : &njs_value_false;
+
+ pr = njs_object_prop_alloc(vm, &njs_object_writable_string, setval, 1);
if (nxt_slow_path(pr == NULL)) {
return NXT_ERROR;
}
@@ -2141,12 +2153,12 @@ njs_object_property_descriptor(njs_vm_t
return NXT_ERROR;
}
- lhq.key = nxt_string_value("writable");
- lhq.key_hash = NJS_WRITABABLE_HASH;
-
- setval = (prop->writable == 1) ? &njs_value_true : &njs_value_false;
-
- pr = njs_object_prop_alloc(vm, &njs_object_writable_string, setval, 1);
+ lhq.key = nxt_string_value("configurable");
+ lhq.key_hash = NJS_CONFIGURABLE_HASH;
+
+ setval = (prop->configurable == 1) ? &njs_value_true : &njs_value_false;
+
+ pr = njs_object_prop_alloc(vm, &njs_object_configurable_string, setval, 1);
if (nxt_slow_path(pr == NULL)) {
return NXT_ERROR;
}
diff -r 8b27db801cd3 -r 6d5c457a298d njs/njs_object.h
--- a/njs/njs_object.h Tue Jun 04 19:38:50 2019 +0300
+++ b/njs/njs_object.h Wed Jun 05 22:13:47 2019 +0800
@@ -27,6 +27,7 @@ typedef enum {
NJS_ATTRIBUTE_UNSET,
} njs_object_attribute_t;
+
typedef struct {
/* Must be aligned to njs_value_t. */
njs_value_t value;
@@ -34,8 +35,8 @@ typedef struct {
njs_object_property_type_t type:8; /* 3 bits */
+ njs_object_attribute_t writable:8; /* 2 bits */
njs_object_attribute_t enumerable:8; /* 2 bits */
- njs_object_attribute_t writable:8; /* 2 bits */
njs_object_attribute_t configurable:8; /* 2 bits */
} njs_object_prop_t;
@@ -99,7 +100,7 @@ nxt_int_t njs_object_hash_create(njs_vm_
njs_ret_t njs_object_constructor(njs_vm_t *vm, njs_value_t *args,
nxt_uint_t nargs, njs_index_t unused);
njs_object_prop_t *njs_object_prop_alloc(njs_vm_t *vm, const njs_value_t *name,
- const njs_value_t *value, uint8_t attributes);
+ const njs_value_t *value, uint8_t attributes);
njs_ret_t njs_primitive_prototype_get_proto(njs_vm_t *vm, njs_value_t *value,
njs_value_t *setval, njs_value_t *retval);
njs_ret_t njs_object_prototype_create(njs_vm_t *vm, njs_value_t *value,
@@ -116,9 +117,10 @@ njs_ret_t njs_object_prototype_to_string
nxt_uint_t nargs, njs_index_t unused);
njs_ret_t njs_prop_private_copy(njs_vm_t *vm, njs_property_query_t *pq);
-const char * njs_prop_type_string(njs_object_property_type_t type);
+const char *njs_prop_type_string(njs_object_property_type_t type);
extern const njs_object_init_t njs_object_constructor_init;
extern const njs_object_init_t njs_object_prototype_init;
+
#endif /* _NJS_OBJECT_H_INCLUDED_ */
diff -r 8b27db801cd3 -r 6d5c457a298d njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c Tue Jun 04 19:38:50 2019 +0300
+++ b/njs/test/njs_unit_test.c Wed Jun 05 22:13:47 2019 +0800
@@ -9598,7 +9598,7 @@ static njs_unit_test_t njs_test[] =
nxt_string("undefined") },
{ nxt_string("JSON.stringify(Object.getOwnPropertyDescriptor([3,4], 'length'))"),
- nxt_string("{\"value\":2,\"configurable\":false,\"enumerable\":false,\"writable\":true}") },
+ nxt_string("{\"value\":2,\"writable\":true,\"enumerable\":false,\"configurable\":false}") },
{ nxt_string("Object.getOwnPropertyDescriptor(Array.of, 'length').value"),
nxt_string("0") },
@@ -9614,10 +9614,10 @@ static njs_unit_test_t njs_test[] =
nxt_string("1") },
{ nxt_string("JSON.stringify(Object.getOwnPropertyDescriptor('αβγδ', '2'))"),
- nxt_string("{\"value\":\"γ\",\"configurable\":false,\"enumerable\":true,\"writable\":false}") },
+ nxt_string("{\"value\":\"γ\",\"writable\":false,\"enumerable\":true,\"configurable\":false}") },
{ nxt_string("JSON.stringify(Object.getOwnPropertyDescriptor(new String('abc'), 'length'))"),
- nxt_string("{\"value\":3,\"configurable\":false,\"enumerable\":false,\"writable\":false}") },
+ nxt_string("{\"value\":3,\"writable\":false,\"enumerable\":false,\"configurable\":false}") },
{ nxt_string("Object.getOwnPropertyDescriptor(1, '0')"),
nxt_string("undefined") },
More information about the nginx-devel
mailing list