aboutsummaryrefslogtreecommitdiff
path: root/src/njs_object.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/njs_object.c')
-rw-r--r--src/njs_object.c240
1 files changed, 127 insertions, 113 deletions
diff --git a/src/njs_object.c b/src/njs_object.c
index 63273628..7f0b1822 100644
--- a/src/njs_object.c
+++ b/src/njs_object.c
@@ -15,7 +15,7 @@ typedef enum {
static njs_object_prop_t *njs_object_exist_in_proto(const njs_object_t *begin,
- const njs_object_t *end, njs_flathsh_query_t *lhq);
+ const njs_object_t *end, njs_flathsh_query_t *fhq);
static njs_int_t njs_object_enumerate_array(njs_vm_t *vm,
const njs_array_t *array, njs_array_t *items, uint32_t flags);
static njs_int_t njs_object_enumerate_typed_array(njs_vm_t *vm,
@@ -41,8 +41,8 @@ njs_object_alloc(njs_vm_t *vm)
object = njs_mp_alloc(vm->mem_pool, sizeof(njs_object_t));
if (njs_fast_path(object != NULL)) {
- njs_lvlhsh_init(&object->hash);
- njs_lvlhsh_init(&object->shared_hash);
+ njs_flathsh_init(&object->hash);
+ njs_flathsh_init(&object->shared_hash);
object->__proto__ = njs_vm_proto(vm, NJS_OBJ_TYPE_OBJECT);
object->slots = NULL;
object->type = NJS_OBJECT;
@@ -126,13 +126,13 @@ njs_object_value_alloc(njs_vm_t *vm, njs_uint_t prototype_index, size_t extra,
return NULL;
}
- njs_lvlhsh_init(&ov->object.hash);
+ njs_flathsh_init(&ov->object.hash);
if (prototype_index == NJS_OBJ_TYPE_STRING) {
ov->object.shared_hash = vm->shared->string_instance_hash;
} else {
- njs_lvlhsh_init(&ov->object.shared_hash);
+ njs_flathsh_init(&ov->object.shared_hash);
}
ov->object.type = NJS_OBJECT_VALUE;
@@ -157,22 +157,31 @@ njs_object_hash_create(njs_vm_t *vm, njs_flathsh_t *hash,
const njs_object_prop_init_t *prop, njs_uint_t n)
{
njs_int_t ret;
- njs_flathsh_query_t lhq;
+ njs_object_prop_t *obj_prop;
+ njs_flathsh_query_t fhq;
- lhq.replace = 0;
- lhq.proto = &njs_object_hash_proto;
- lhq.pool = vm->mem_pool;
+ fhq.replace = 0;
+ fhq.proto = &njs_object_hash_proto;
+ fhq.pool = vm->mem_pool;
while (n != 0) {
- lhq.key_hash = prop->atom_id;
- lhq.value = (void *) prop;
+ fhq.key_hash = prop->desc.atom_id;
+ fhq.value = (void *) prop;
- ret = njs_flathsh_unique_insert(hash, &lhq);
+ ret = njs_flathsh_unique_insert(hash, &fhq);
if (njs_slow_path(ret != NJS_OK)) {
- njs_internal_error(vm, "lvlhsh insert failed");
+ njs_internal_error(vm, "flathsh insert failed");
return NJS_ERROR;
}
+ obj_prop = fhq.value;
+
+ obj_prop->type = prop->desc.type;
+ obj_prop->enumerable = prop->desc.enumerable;
+ obj_prop->configurable = prop->desc.configurable;
+ obj_prop->writable = prop->desc.writable;
+ obj_prop->u.value = prop->desc.u.value;
+
prop++;
n--;
}
@@ -184,10 +193,9 @@ njs_object_hash_create(njs_vm_t *vm, njs_flathsh_t *hash,
const njs_flathsh_proto_t njs_object_hash_proto
njs_aligned(64) =
{
- 0,
NULL,
- njs_lvlhsh_alloc,
- njs_lvlhsh_free,
+ njs_flathsh_proto_alloc,
+ njs_flathsh_proto_free,
};
@@ -371,28 +379,28 @@ njs_object_entries(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
static njs_object_prop_t *
njs_object_exist_in_proto(const njs_object_t *object, const njs_object_t *end,
- njs_flathsh_query_t *lhq)
+ njs_flathsh_query_t *fhq)
{
njs_int_t ret;
njs_object_prop_t *prop;
while (object != end) {
- ret = njs_flathsh_unique_find(&object->hash, lhq);
+ ret = njs_flathsh_unique_find(&object->hash, fhq);
if (njs_fast_path(ret == NJS_OK)) {
- prop = lhq->value;
+ prop = fhq->value;
if (prop->type == NJS_WHITEOUT) {
goto next;
}
- return lhq->value;
+ return fhq->value;
}
- ret = njs_flathsh_unique_find(&object->shared_hash, lhq);
+ ret = njs_flathsh_unique_find(&object->shared_hash, fhq);
if (njs_fast_path(ret == NJS_OK)) {
- return lhq->value;
+ return fhq->value;
}
next:
@@ -910,7 +918,7 @@ njs_get_own_ordered_keys(njs_vm_t *vm, const njs_object_t *object,
njs_flathsh_elt_t *elt;
njs_flathsh_each_t lhe;
const njs_flathsh_t *hash;
- njs_flathsh_query_t lhq;
+ njs_flathsh_query_t fhq;
items_length = items->length;
@@ -924,7 +932,7 @@ njs_get_own_ordered_keys(njs_vm_t *vm, const njs_object_t *object,
return NJS_ERROR;
}
- lhq.proto = &njs_object_hash_proto;
+ fhq.proto = &njs_object_hash_proto;
njs_flathsh_each_init(&lhe, &njs_object_hash_proto);
hash = &object->shared_hash;
@@ -939,7 +947,7 @@ njs_get_own_ordered_keys(njs_vm_t *vm, const njs_object_t *object,
break;
}
- prop = elt->value;
+ prop = (njs_object_prop_t *) elt;
ret = njs_atom_to_value(vm, &prop_name, elt->key_hash);
if (ret != NJS_OK) {
@@ -950,14 +958,14 @@ njs_get_own_ordered_keys(njs_vm_t *vm, const njs_object_t *object,
continue;
}
- lhq.key_hash = elt->key_hash;
+ fhq.key_hash = elt->key_hash;
- ext_prop = njs_object_exist_in_proto(parent, object, &lhq);
+ ext_prop = njs_object_exist_in_proto(parent, object, &fhq);
if (ext_prop != NULL) {
continue;
}
- ret = njs_flathsh_unique_find(&object->hash, &lhq);
+ ret = njs_flathsh_unique_find(&object->hash, &fhq);
if (ret != NJS_OK) {
if (!(prop->enumerable || !(flags & NJS_ENUM_ENUMERABLE_ONLY))) {
@@ -980,7 +988,7 @@ njs_get_own_ordered_keys(njs_vm_t *vm, const njs_object_t *object,
} else {
- if (!(((njs_object_prop_t *)(lhq.value))->enumerable
+ if (!(((njs_object_prop_t *) (fhq.value))->enumerable
|| !(flags & NJS_ENUM_ENUMERABLE_ONLY)))
{
continue;
@@ -991,15 +999,9 @@ njs_get_own_ordered_keys(njs_vm_t *vm, const njs_object_t *object,
num = njs_string_to_index(&prop_name);
if (!njs_number_is_integer_index(num)) {
- njs_object_prop_t *hash_prop = lhq.value;
+ njs_object_prop_t *hash_prop = fhq.value;
- /* select names of prop which are not deleted and
- * not deleted and created again i.e.,
- * they are replaced shared hash props
- */
- if (hash_prop->type != NJS_WHITEOUT &&
- !(hash_prop->enum_in_object_hash))
- {
+ if (hash_prop->type != NJS_WHITEOUT) {
njs_process_prop(vm, &prop_name, flags, items_string,
items_symbol);
}
@@ -1018,7 +1020,7 @@ local_hash:
break;
}
- prop = elt->value;
+ prop = (njs_object_prop_t *) elt;
ret = njs_atom_to_value(vm, &prop_name, elt->key_hash);
if (ret != NJS_OK) {
@@ -1032,9 +1034,9 @@ local_hash:
continue;
}
- lhq.key_hash = elt->key_hash;
+ fhq.key_hash = elt->key_hash;
- ext_prop = njs_object_exist_in_proto(parent, object, &lhq);
+ ext_prop = njs_object_exist_in_proto(parent, object, &fhq);
if (ext_prop != NULL) {
continue;
}
@@ -1049,7 +1051,7 @@ local_hash:
} else {
- ret = njs_flathsh_unique_find(&object->shared_hash, &lhq);
+ ret = njs_flathsh_unique_find(&object->shared_hash, &fhq);
if (ret != NJS_OK) {
/* prop is: in_hash && !in_shared_hash */
@@ -1060,8 +1062,7 @@ local_hash:
} else {
/* prop is: in_hash && in_shared_hash */
- /* select names of not deleted and created again */
- if (prop->enum_in_object_hash) {
+ if (prop->type == NJS_WHITEOUT) {
njs_process_prop(vm, &prop_name, flags, items_string,
items_symbol);
}
@@ -1222,7 +1223,7 @@ njs_object_copy_shared_hash(njs_vm_t *vm, njs_object_t *object)
njs_int_t ret;
njs_value_t prop_name;
njs_flathsh_t new_hash, *shared_hash;
- njs_object_prop_t *prop;
+ njs_object_prop_t *prop, *obj_prop;
njs_flathsh_elt_t *elt;
njs_flathsh_each_t fhe;
njs_flathsh_query_t fhq;
@@ -1242,7 +1243,7 @@ njs_object_copy_shared_hash(njs_vm_t *vm, njs_object_t *object)
break;
}
- prop = elt->value;
+ prop = (njs_object_prop_t *) elt;
ret = njs_atom_to_value(vm, &prop_name, elt->key_hash);
if (ret != NJS_OK) {
@@ -1258,13 +1259,19 @@ njs_object_copy_shared_hash(njs_vm_t *vm, njs_object_t *object)
fhq.key_hash = elt->key_hash;
}
- fhq.value = prop;
-
ret = njs_flathsh_unique_insert(&new_hash, &fhq);
if (njs_slow_path(ret != NJS_OK)) {
njs_internal_error(vm, "flathsh insert failed");
return NJS_ERROR;
}
+
+ obj_prop = fhq.value;
+
+ obj_prop->type = prop->type;
+ obj_prop->enumerable = prop->enumerable;
+ obj_prop->configurable = prop->configurable;
+ obj_prop->writable = prop->writable;
+ obj_prop->u.value = prop->u.value;
}
object->shared_hash = new_hash;
@@ -1281,7 +1288,7 @@ njs_object_make_shared(njs_vm_t *vm, njs_object_t *object)
njs_object_t **start;
njs_value_t value, *key;
njs_traverse_t *s;
- njs_object_prop_t *prop;
+ njs_object_prop_t *prop, *obj_prop;
njs_property_query_t pq;
njs_traverse_t state[NJS_TRAVERSE_MAX_DEPTH];
@@ -1318,8 +1325,8 @@ njs_object_make_shared(njs_vm_t *vm, njs_object_t *object)
(void) njs_traverse_visit(&visited, &s->value);
- pq.lhq.replace = 0;
- pq.lhq.pool = vm->mem_pool;
+ pq.fhq.replace = 0;
+ pq.fhq.pool = vm->mem_pool;
for ( ;; ) {
@@ -1351,15 +1358,23 @@ njs_object_make_shared(njs_vm_t *vm, njs_object_t *object)
}
- prop = pq.lhq.value;
+ prop = pq.fhq.value;
ret = njs_flathsh_unique_insert(&njs_object(&s->value)->shared_hash,
- &pq.lhq);
+ &pq.fhq);
if (njs_slow_path(ret != NJS_OK)) {
njs_internal_error(vm, "flathsh insert failed");
return NJS_ERROR;
}
+ obj_prop = pq.fhq.value;
+
+ obj_prop->type = prop->type;
+ obj_prop->enumerable = prop->enumerable;
+ obj_prop->configurable = prop->configurable;
+ obj_prop->writable = prop->writable;
+ obj_prop->u.value = prop->u.value;
+
njs_value_assign(&value, njs_prop_value(prop));
if (njs_is_object(&value)
@@ -1465,9 +1480,9 @@ njs_object_traverse(njs_vm_t *vm, njs_object_t *object, void *ctx,
return NJS_ERROR;
}
- prop = pq.lhq.value;
+ prop = pq.fhq.value;
s->prop = prop;
- s->atom_id = pq.lhq.key_hash;
+ s->atom_id = pq.fhq.key_hash;
ret = cb(vm, s, ctx);
if (njs_slow_path(ret != NJS_OK)) {
@@ -1481,7 +1496,7 @@ njs_object_traverse(njs_vm_t *vm, njs_object_t *object, void *ctx,
njs_value_assign(&value, njs_prop_value(prop));
if (prop->type == NJS_PROPERTY_HANDLER) {
- ret = njs_prop_handler(prop)(vm, prop, pq.lhq.key_hash, &s->value,
+ ret = njs_prop_handler(prop)(vm, prop, pq.fhq.key_hash, &s->value,
NULL, &value);
if (njs_slow_path(ret == NJS_ERROR)) {
return ret;
@@ -1601,7 +1616,7 @@ njs_object_define_properties(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
goto done;
}
- prop = pq.lhq.value;
+ prop = pq.fhq.value;
if (ret == NJS_DECLINED || !prop->enumerable) {
continue;
@@ -1659,8 +1674,8 @@ njs_object_get_own_property_descriptors(njs_vm_t *vm, njs_value_t *args,
njs_array_t *names;
njs_value_t descriptor, *value, *key;
njs_object_t *descriptors;
- njs_object_prop_t *pr;
- njs_flathsh_query_t lhq;
+ njs_object_prop_t *prop;
+ njs_flathsh_query_t fhq;
value = njs_arg(args, nargs, 1);
@@ -1685,9 +1700,9 @@ njs_object_get_own_property_descriptors(njs_vm_t *vm, njs_value_t *args,
goto done;
}
- lhq.replace = 0;
- lhq.pool = vm->mem_pool;
- lhq.proto = &njs_object_hash_proto;
+ fhq.replace = 0;
+ fhq.pool = vm->mem_pool;
+ fhq.proto = &njs_object_hash_proto;
for (i = 0; i < length; i++) {
key = &names->start[i];
@@ -1697,20 +1712,22 @@ njs_object_get_own_property_descriptors(njs_vm_t *vm, njs_value_t *args,
goto done;
}
- pr = njs_object_prop_alloc(vm, &descriptor, 1);
- if (njs_slow_path(pr == NULL)) {
- ret = NJS_ERROR;
- goto done;
- }
-
- lhq.key_hash = key->atom_id;
- lhq.value = pr;
+ fhq.key_hash = key->atom_id;
- ret = njs_flathsh_unique_insert(&descriptors->hash, &lhq);
+ ret = njs_flathsh_unique_insert(&descriptors->hash, &fhq);
if (njs_slow_path(ret != NJS_OK)) {
- njs_internal_error(vm, "lvlhsh insert failed");
+ njs_internal_error(vm, "flathsh insert failed");
goto done;
}
+
+ prop = fhq.value;
+
+ prop->type = NJS_PROPERTY;
+ prop->enumerable = 1;
+ prop->configurable = 1;
+ prop->writable = 1;
+
+ prop->u.value = descriptor;
}
ret = NJS_OK;
@@ -1889,7 +1906,7 @@ njs_object_set_integrity_level(njs_vm_t *vm, njs_value_t *args,
break;
}
- prop = elt->value;
+ prop = (njs_object_prop_t *) elt;
if (level == NJS_OBJECT_INTEGRITY_FROZEN
&& !njs_is_accessor_descriptor(prop))
@@ -1949,7 +1966,7 @@ njs_object_test_integrity_level(njs_vm_t *vm, njs_value_t *args,
break;
}
- prop = elt->value;
+ prop = (njs_object_prop_t *) elt;
if (prop->configurable) {
goto done;
@@ -2051,7 +2068,7 @@ njs_object_assign(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
goto exception;
}
- prop = pq.lhq.value;
+ prop = pq.fhq.value;
if (!prop->enumerable) {
continue;
}
@@ -2170,32 +2187,31 @@ njs_property_prototype_create(njs_vm_t *vm, njs_flathsh_t *hash,
{
njs_int_t ret;
njs_object_prop_t *prop;
- njs_flathsh_query_t lhq;
-
- prop = njs_object_prop_alloc(vm, &njs_value_undefined, 0);
- if (njs_slow_path(prop == NULL)) {
- return NULL;
- }
+ njs_flathsh_query_t fhq;
- lhq.value = prop;
+ fhq.key_hash = NJS_ATOM_STRING_prototype;
- njs_set_type_object(njs_prop_value(prop), prototype, prototype->type);
+ fhq.replace = 1;
+ fhq.pool = vm->mem_pool;
+ fhq.proto = &njs_object_hash_proto;
- lhq.key_hash = NJS_ATOM_STRING_prototype;
+ ret = njs_flathsh_unique_insert(hash, &fhq);
- lhq.replace = 1;
- lhq.pool = vm->mem_pool;
- lhq.proto = &njs_object_hash_proto;
+ if (njs_slow_path(ret != NJS_OK)) {
+ njs_internal_error(vm, "flathsh insert failed");
+ return NULL;
+ }
- ret = njs_flathsh_unique_insert(hash, &lhq);
+ prop = fhq.value;
- if (njs_fast_path(ret == NJS_OK)) {
- return njs_prop_value(prop);
- }
+ prop->type = NJS_PROPERTY;
+ prop->enumerable = 0;
+ prop->configurable = 0;
+ prop->writable = 0;
- njs_internal_error(vm, "lvlhsh insert failed");
+ njs_set_type_object(njs_prop_value(prop), prototype, prototype->type);
- return NULL;
+ return njs_prop_value(prop);
}
@@ -2431,32 +2447,30 @@ njs_property_constructor_set(njs_vm_t *vm, njs_flathsh_t *hash,
{
njs_int_t ret;
njs_object_prop_t *prop;
- njs_flathsh_query_t lhq;
+ njs_flathsh_query_t fhq;
- prop = njs_object_prop_alloc(vm, constructor, 1);
- if (njs_slow_path(prop == NULL)) {
- return NULL;
- }
+ fhq.key_hash = NJS_ATOM_STRING_constructor;
- njs_value_assign(njs_prop_value(prop), constructor);
- prop->enumerable = 0;
-
- lhq.value = prop;
+ fhq.replace = 1;
+ fhq.pool = vm->mem_pool;
+ fhq.proto = &njs_object_hash_proto;
- lhq.key_hash = NJS_ATOM_STRING_constructor;
+ ret = njs_flathsh_unique_insert(hash, &fhq);
+ if (njs_slow_path(ret != NJS_OK)) {
+ njs_internal_error(vm, "flathsh insert/replace failed");
+ return NULL;
+ }
- lhq.replace = 1;
- lhq.pool = vm->mem_pool;
- lhq.proto = &njs_object_hash_proto;
+ prop = fhq.value;
- ret = njs_flathsh_unique_insert(hash, &lhq);
- if (njs_fast_path(ret == NJS_OK)) {
- return njs_prop_value(prop);
- }
+ prop->type = NJS_PROPERTY;
+ prop->enumerable = 0;
+ prop->configurable = 1;
+ prop->writable = 1;
+ prop->u.value = *constructor;
- njs_internal_error(vm, "lvlhsh insert/replace failed");
+ return njs_prop_value(prop);
- return NULL;
}
@@ -2515,7 +2529,7 @@ njs_object_to_string(njs_vm_t *vm, njs_value_t *this, njs_value_t *retval)
name = NJS_ATOM_STRING__object_Array_;
} else if (njs_is_object(this)
- && njs_lvlhsh_eq(&njs_object(this)->shared_hash,
+ && njs_flathsh_eq(&njs_object(this)->shared_hash,
&vm->shared->arguments_object_instance_hash))
{
name = NJS_ATOM_STRING__object_Arguments_;
@@ -2656,7 +2670,7 @@ njs_object_prototype_prop_is_enumerable(njs_vm_t *vm, njs_value_t *args,
switch (ret) {
case NJS_OK:
- prop = pq.lhq.value;
+ prop = pq.fhq.value;
njs_set_boolean(retval, prop->enumerable);
break;