Skip to content

Commit

Permalink
Fixed Object.values() and Object.entries() with shared properties.
Browse files Browse the repository at this point in the history
Previously, the functions directly copied a shared object from
a shared_hash. The copying is nessessary for lazy instantiation
of shared properties.

This fixes #743 issue on Github.
  • Loading branch information
xeioex committed Jul 2, 2024
1 parent 286d00b commit 6907216
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 87 deletions.
111 changes: 24 additions & 87 deletions src/njs_object.c
Original file line number Diff line number Diff line change
Expand Up @@ -1076,82 +1076,14 @@ njs_get_own_ordered_keys(njs_vm_t *vm, const njs_object_t *object,
}


static njs_int_t
njs_add_obj_prop_kind(njs_vm_t *vm, const njs_object_t *object,
const njs_lvlhsh_t *hash, njs_lvlhsh_query_t *lhq,
uint32_t flags, njs_array_t *items)
{
njs_int_t ret;
njs_value_t value, *v, value1;
njs_array_t *entry;
njs_object_prop_t *prop;

ret = njs_lvlhsh_find(hash, lhq);
if (ret != NJS_OK) {
return NJS_DECLINED;
}

prop = (njs_object_prop_t *) (lhq->value);

if (prop->type != NJS_ACCESSOR) {
v = njs_prop_value(prop);

} else {
if (njs_is_data_descriptor(prop)) {
v = njs_prop_value(prop);
goto add;
}

if (njs_prop_getter(prop) == NULL) {
v = njs_value_arg(&njs_value_undefined);
goto add;
}

v = &value1;

njs_set_object(&value, (njs_object_t *) object);
ret = njs_function_apply(vm, njs_prop_getter(prop), &value, 1, v);
if (ret != NJS_OK) {
return NJS_ERROR;
}
}

add:
if (njs_object_enum_kind(flags) != NJS_ENUM_VALUES) {
entry = njs_array_alloc(vm, 0, 2, 0);
if (njs_slow_path(entry == NULL)) {
return NJS_ERROR;
}

njs_string_copy(&entry->start[0], &prop->name);
njs_value_assign(&entry->start[1], v);

njs_set_array(&value, entry);
v = &value;
}

ret = njs_array_add(vm, items, v);
if (njs_slow_path(ret != NJS_OK)) {
return NJS_ERROR;
}

return NJS_OK;
}


static njs_int_t
njs_object_own_enumerate_object(njs_vm_t *vm, const njs_object_t *object,
const njs_object_t *parent, njs_array_t *items, uint32_t flags)
{
njs_int_t ret;
uint32_t i;
njs_array_t *items_sorted;
njs_lvlhsh_each_t lhe;
njs_lvlhsh_query_t lhq;

lhq.proto = &njs_object_hash_proto;

njs_lvlhsh_each_init(&lhe, &njs_object_hash_proto);
uint32_t i;
njs_int_t ret;
njs_array_t *items_sorted, *entry;
njs_value_t value, retval;

switch (njs_object_enum_kind(flags)) {
case NJS_ENUM_KEYS:
Expand All @@ -1174,26 +1106,31 @@ njs_object_own_enumerate_object(njs_vm_t *vm, const njs_object_t *object,
return NJS_ERROR;
}

for (i = 0; i< items_sorted->length; i++) {
njs_set_object(&value, (njs_object_t *) object);

lhe.key_hash = 0;
njs_object_property_key_set(&lhq, &items_sorted->start[i],
lhe.key_hash);
for (i = 0; i< items_sorted->length; i++) {
ret = njs_value_property(vm, &value, &items_sorted->start[i],
&retval);
if (njs_slow_path(ret != NJS_OK)) {
njs_array_destroy(vm, items_sorted);
return NJS_ERROR;
}

ret = njs_add_obj_prop_kind(vm, object, &object->hash, &lhq, flags,
items);
if (ret != NJS_DECLINED) {
if (ret != NJS_OK) {
if (njs_object_enum_kind(flags) != NJS_ENUM_VALUES) {
entry = njs_array_alloc(vm, 0, 2, 0);
if (njs_slow_path(entry == NULL)) {
return NJS_ERROR;
}

} else {
ret = njs_add_obj_prop_kind(vm, object, &object->shared_hash,
&lhq, flags, items);
njs_assert(ret != NJS_DECLINED);
if (ret != NJS_OK) {
return NJS_ERROR;
}
njs_string_copy(&entry->start[0], &items_sorted->start[i]);
njs_value_assign(&entry->start[1], &retval);

njs_set_array(&retval, entry);
}

ret = njs_array_add(vm, items, &retval);
if (njs_slow_path(ret != NJS_OK)) {
return NJS_ERROR;
}
}

Expand Down
6 changes: 6 additions & 0 deletions src/test/njs_unit_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -22693,6 +22693,12 @@ static njs_unit_test_t njs_shared_test[] =
{ njs_str("var v = Math.round(Math.random() * 1000); ExternalNull.set(v);"
"ExternalNull.get() == v"),
njs_str("true") },

#if (NJS_HAVE_OPENSSL)
{ njs_str("var cr = Object.entries(global).filter((v) => v[0] == 'crypto')[0][1];"
"cr.abc = 1; cr.abc"),
njs_str("1") },
#endif
};


Expand Down

0 comments on commit 6907216

Please sign in to comment.