static uint32_t njs_object_enumerate_array_length(const njs_object_t *object);
static uint32_t njs_object_enumerate_string_length(const njs_object_t *object);
static uint32_t njs_object_enumerate_object_length(const njs_object_t *object,
- njs_bool_t all);
+ njs_object_enum_type_t type, njs_bool_t all);
static uint32_t njs_object_own_enumerate_object_length(
- const njs_object_t *object, const njs_object_t *parent, njs_bool_t all);
+ const njs_object_t *object, const njs_object_t *parent,
+ njs_object_enum_type_t type, njs_bool_t all);
static njs_int_t njs_object_enumerate_array(njs_vm_t *vm,
const njs_array_t *array, njs_array_t *items, njs_object_enum_t kind);
static njs_int_t njs_object_enumerate_string(njs_vm_t *vm,
const njs_value_t *value, njs_array_t *items, njs_object_enum_t kind);
static njs_int_t njs_object_enumerate_object(njs_vm_t *vm,
const njs_object_t *object, njs_array_t *items, njs_object_enum_t kind,
- njs_bool_t all);
+ njs_object_enum_type_t type, njs_bool_t all);
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,
- njs_object_enum_t kind, njs_bool_t all);
+ njs_object_enum_t kind, njs_object_enum_type_t type, njs_bool_t all);
njs_object_t *
lhq.pool = vm->mem_pool;
while (n != 0) {
- njs_string_get(&prop->name, &lhq.key);
- lhq.key_hash = njs_djb_hash(lhq.key.start, lhq.key.length);
+
+ njs_object_property_key_set(&lhq, &prop->name, 0);
+
lhq.value = (void *) prop;
ret = njs_lvlhsh_insert(hash, &lhq);
{
size_t size;
u_char *start;
+ njs_value_t *name;
njs_object_prop_t *prop;
prop = data;
+ name = &prop->name;
+
+ if (njs_slow_path(njs_is_symbol(name))) {
+ return ((njs_symbol_key(name) == lhq->key_hash)
+ && lhq->key.length == 0) ? NJS_OK : NJS_DECLINED;
+ }
+
+ /* string. */
- size = prop->name.short_string.size;
+ size = name->short_string.size;
if (size != NJS_STRING_LONG) {
if (lhq->key.length != size) {
return NJS_DECLINED;
}
- start = prop->name.short_string.start;
+ start = name->short_string.start;
} else {
- if (lhq->key.length != prop->name.long_string.size) {
+ if (lhq->key.length != name->long_string.size) {
return NJS_DECLINED;
}
- start = prop->name.long_string.data->start;
+ start = name->long_string.data->start;
}
if (memcmp(start, lhq->key.start, lhq->key.length) == 0) {
return NJS_ERROR;
}
- keys = njs_value_own_enumerate(vm, value, NJS_ENUM_KEYS, 0);
+ keys = njs_value_own_enumerate(vm, value, NJS_ENUM_KEYS,
+ NJS_ENUM_STRING, 0);
if (keys == NULL) {
return NJS_ERROR;
}
return NJS_ERROR;
}
- array = njs_value_own_enumerate(vm, value, NJS_ENUM_VALUES, 0);
+ array = njs_value_own_enumerate(vm, value, NJS_ENUM_VALUES,
+ NJS_ENUM_STRING, 0);
if (array == NULL) {
return NJS_ERROR;
}
return NJS_ERROR;
}
- array = njs_value_own_enumerate(vm, value, NJS_ENUM_BOTH, 0);
+ array = njs_value_own_enumerate(vm, value, NJS_ENUM_BOTH,
+ NJS_ENUM_STRING, 0);
if (array == NULL) {
return NJS_ERROR;
}
njs_inline uint32_t
-njs_object_enumerate_length(const njs_object_t *object, njs_bool_t all)
+njs_object_enumerate_length(const njs_object_t *object,
+ njs_object_enum_type_t type, njs_bool_t all)
{
uint32_t length;
- length = njs_object_enumerate_object_length(object, all);
+ length = njs_object_enumerate_object_length(object, type, all);
- switch (object->type) {
- case NJS_ARRAY:
- length += njs_object_enumerate_array_length(object);
- break;
+ if (type & NJS_STRING) {
+ switch (object->type) {
+ case NJS_ARRAY:
+ length += njs_object_enumerate_array_length(object);
+ break;
- case NJS_OBJECT_STRING:
- length += njs_object_enumerate_string_length(object);
- break;
+ case NJS_OBJECT_STRING:
+ length += njs_object_enumerate_string_length(object);
+ break;
- default:
- break;
+ default:
+ break;
+ }
}
return length;
njs_inline uint32_t
njs_object_own_enumerate_length(const njs_object_t *object,
- const njs_object_t *parent, njs_bool_t all)
+ const njs_object_t *parent, njs_object_enum_type_t type, njs_bool_t all)
{
uint32_t length;
- length = njs_object_own_enumerate_object_length(object, parent, all);
+ length = njs_object_own_enumerate_object_length(object, parent, type, all);
- switch (object->type) {
- case NJS_ARRAY:
- length += njs_object_enumerate_array_length(object);
- break;
+ if (type & NJS_ENUM_STRING) {
+ switch (object->type) {
+ case NJS_ARRAY:
+ length += njs_object_enumerate_array_length(object);
+ break;
- case NJS_OBJECT_STRING:
- length += njs_object_enumerate_string_length(object);
- break;
+ case NJS_OBJECT_STRING:
+ length += njs_object_enumerate_string_length(object);
+ break;
- default:
- break;
+ default:
+ break;
+ }
}
return length;
njs_inline njs_int_t
njs_object_enumerate_value(njs_vm_t *vm, const njs_object_t *object,
- njs_array_t *items, njs_object_enum_t kind, njs_bool_t all)
+ njs_array_t *items, njs_object_enum_t kind, njs_object_enum_type_t type,
+ njs_bool_t all)
{
njs_int_t ret;
njs_object_value_t *obj_val;
- switch (object->type) {
- case NJS_ARRAY:
- ret = njs_object_enumerate_array(vm, (njs_array_t *) object, items,
- kind);
- break;
+ if (type & NJS_ENUM_STRING) {
+ switch (object->type) {
+ case NJS_ARRAY:
+ ret = njs_object_enumerate_array(vm, (njs_array_t *) object, items,
+ kind);
+ break;
- case NJS_OBJECT_STRING:
- obj_val = (njs_object_value_t *) object;
+ case NJS_OBJECT_STRING:
+ obj_val = (njs_object_value_t *) object;
- ret = njs_object_enumerate_string(vm, &obj_val->value, items, kind);
- break;
+ ret = njs_object_enumerate_string(vm, &obj_val->value, items, kind);
+ break;
- default:
- goto object;
- }
+ default:
+ goto object;
+ }
- if (njs_slow_path(ret != NJS_OK)) {
- return NJS_ERROR;
+ if (njs_slow_path(ret != NJS_OK)) {
+ return NJS_ERROR;
+ }
}
object:
- ret = njs_object_enumerate_object(vm, object, items, kind, all);
+ ret = njs_object_enumerate_object(vm, object, items, kind, type, all);
if (njs_slow_path(ret != NJS_OK)) {
return NJS_ERROR;
}
njs_inline njs_int_t
njs_object_own_enumerate_value(njs_vm_t *vm, const njs_object_t *object,
const njs_object_t *parent, njs_array_t *items, njs_object_enum_t kind,
- njs_bool_t all)
+ njs_object_enum_type_t type, njs_bool_t all)
{
njs_int_t ret;
njs_object_value_t *obj_val;
- switch (object->type) {
- case NJS_ARRAY:
- ret = njs_object_enumerate_array(vm, (njs_array_t *) object, items,
- kind);
- break;
+ if (type & NJS_ENUM_STRING) {
+ switch (object->type) {
+ case NJS_ARRAY:
+ ret = njs_object_enumerate_array(vm, (njs_array_t *) object, items,
+ kind);
+ break;
- case NJS_OBJECT_STRING:
- obj_val = (njs_object_value_t *) object;
+ case NJS_OBJECT_STRING:
+ obj_val = (njs_object_value_t *) object;
- ret = njs_object_enumerate_string(vm, &obj_val->value, items, kind);
- break;
+ ret = njs_object_enumerate_string(vm, &obj_val->value, items, kind);
+ break;
- default:
- goto object;
- }
+ default:
+ goto object;
+ }
- if (njs_slow_path(ret != NJS_OK)) {
- return NJS_ERROR;
+ if (njs_slow_path(ret != NJS_OK)) {
+ return NJS_ERROR;
+ }
}
object:
- ret = njs_object_own_enumerate_object(vm, object, parent, items, kind, all);
+ ret = njs_object_own_enumerate_object(vm, object, parent, items, kind,
+ type, all);
if (njs_slow_path(ret != NJS_OK)) {
return NJS_ERROR;
}
njs_array_t *
njs_object_enumerate(njs_vm_t *vm, const njs_object_t *object,
- njs_object_enum_t kind, njs_bool_t all)
+ njs_object_enum_t kind, njs_object_enum_type_t type, njs_bool_t all)
{
uint32_t length;
njs_int_t ret;
njs_array_t *items;
- length = njs_object_enumerate_length(object, all);
+ length = njs_object_enumerate_length(object, type, all);
items = njs_array_alloc(vm, length, NJS_ARRAY_SPARE);
if (njs_slow_path(items == NULL)) {
return NULL;
}
- ret = njs_object_enumerate_value(vm, object, items, kind, all);
+ ret = njs_object_enumerate_value(vm, object, items, kind, type, all);
if (njs_slow_path(ret != NJS_OK)) {
return NULL;
}
njs_array_t *
njs_object_own_enumerate(njs_vm_t *vm, const njs_object_t *object,
- njs_object_enum_t kind, njs_bool_t all)
+ njs_object_enum_t kind, njs_object_enum_type_t type, njs_bool_t all)
{
uint32_t length;
njs_int_t ret;
njs_array_t *items;
- length = njs_object_own_enumerate_length(object, object, all);
+ length = njs_object_own_enumerate_length(object, object, type, all);
items = njs_array_alloc(vm, length, NJS_ARRAY_SPARE);
if (njs_slow_path(items == NULL)) {
return NULL;
}
- ret = njs_object_own_enumerate_value(vm, object, object, items, kind, all);
+ ret = njs_object_own_enumerate_value(vm, object, object, items, kind, type,
+ all);
if (njs_slow_path(ret != NJS_OK)) {
return NULL;
}
static uint32_t
-njs_object_enumerate_object_length(const njs_object_t *object, njs_bool_t all)
+njs_object_enumerate_object_length(const njs_object_t *object,
+ njs_object_enum_type_t type, njs_bool_t all)
{
uint32_t length;
const njs_object_t *proto;
- length = njs_object_own_enumerate_object_length(object, object, all);
+ length = njs_object_own_enumerate_object_length(object, object, type, all);
proto = object->__proto__;
while (proto != NULL) {
- length += njs_object_own_enumerate_length(proto, object, all);
+ length += njs_object_own_enumerate_length(proto, object, type, all);
proto = proto->__proto__;
}
}
+njs_inline njs_bool_t
+njs_is_enumerable(const njs_value_t *value, njs_object_enum_type_t type)
+{
+ return (njs_is_string(value) && (type & NJS_ENUM_STRING))
+ || (njs_is_symbol(value) && (type & NJS_ENUM_SYMBOL));
+}
+
+
static uint32_t
njs_object_own_enumerate_object_length(const njs_object_t *object,
- const njs_object_t *parent, njs_bool_t all)
+ const njs_object_t *parent, njs_object_enum_type_t type, njs_bool_t all)
{
uint32_t length;
njs_int_t ret;
break;
}
- lhq.key_hash = lhe.key_hash;
- njs_string_get(&prop->name, &lhq.key);
+ if (!njs_is_enumerable(&prop->name, type)) {
+ continue;
+ }
+
+ njs_object_property_key_set(&lhq, &prop->name, lhe.key_hash);
ext_prop = njs_object_exist_in_proto(parent, object, &lhq);
break;
}
- lhq.key_hash = lhe.key_hash;
- njs_string_get(&prop->name, &lhq.key);
+ if (!njs_is_enumerable(&prop->name, type)) {
+ continue;
+ }
+
+ njs_object_property_key_set(&lhq, &prop->name, lhe.key_hash);
- lhq.proto = &njs_object_hash_proto;
ret = njs_lvlhsh_find(&object->hash, &lhq);
if (ret != NJS_OK) {
static njs_int_t
njs_object_enumerate_object(njs_vm_t *vm, const njs_object_t *object,
- njs_array_t *items, njs_object_enum_t kind, njs_bool_t all)
+ njs_array_t *items, njs_object_enum_t kind, njs_object_enum_type_t type,
+ njs_bool_t all)
{
njs_int_t ret;
const njs_object_t *proto;
- ret = njs_object_own_enumerate_object(vm, object, object, items, kind, all);
+ ret = njs_object_own_enumerate_object(vm, object, object, items, kind,
+ type, all);
if (njs_slow_path(ret != NJS_OK)) {
return NJS_ERROR;
}
while (proto != NULL) {
ret = njs_object_own_enumerate_value(vm, proto, object, items, kind,
- all);
+ type, all);
if (njs_slow_path(ret != NJS_OK)) {
return NJS_ERROR;
}
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, njs_object_enum_t kind,
- njs_bool_t all)
+ njs_object_enum_type_t type, njs_bool_t all)
{
njs_int_t ret;
njs_value_t *item;
item = items->start;
hash = &object->hash;
+ lhq.proto = &njs_object_hash_proto;
+
switch (kind) {
case NJS_ENUM_KEYS:
for ( ;; ) {
break;
}
- lhq.key_hash = lhe.key_hash;
- njs_string_get(&prop->name, &lhq.key);
+ if (!njs_is_enumerable(&prop->name, type)) {
+ continue;
+ }
+
+ njs_object_property_key_set(&lhq, &prop->name, lhe.key_hash);
ext_prop = njs_object_exist_in_proto(parent, object, &lhq);
break;
}
- lhq.key_hash = lhe.key_hash;
- njs_string_get(&prop->name, &lhq.key);
+ if (!njs_is_enumerable(&prop->name, type)) {
+ continue;
+ }
+
+ njs_object_property_key_set(&lhq, &prop->name, lhe.key_hash);
- lhq.proto = &njs_object_hash_proto;
ret = njs_lvlhsh_find(&object->hash, &lhq);
if (ret != NJS_OK) {
break;
}
- lhq.key_hash = lhe.key_hash;
- njs_string_get(&prop->name, &lhq.key);
+ if (!njs_is_enumerable(&prop->name, type)) {
+ continue;
+ }
+
+ njs_object_property_key_set(&lhq, &prop->name, lhe.key_hash);
ext_prop = njs_object_exist_in_proto(parent, object, &lhq);
break;
}
- lhq.key_hash = lhe.key_hash;
- njs_string_get(&prop->name, &lhq.key);
+ if (!njs_is_enumerable(&prop->name, type)) {
+ continue;
+ }
+
+ njs_object_property_key_set(&lhq, &prop->name, lhe.key_hash);
- lhq.proto = &njs_object_hash_proto;
ret = njs_lvlhsh_find(&object->hash, &lhq);
if (ret != NJS_OK) {
break;
}
- lhq.key_hash = lhe.key_hash;
- njs_string_get(&prop->name, &lhq.key);
+ if (!njs_is_enumerable(&prop->name, type)) {
+ continue;
+ }
+
+ njs_object_property_key_set(&lhq, &prop->name, lhe.key_hash);
ext_prop = njs_object_exist_in_proto(parent, object, &lhq);
break;
}
- lhq.key_hash = lhe.key_hash;
- njs_string_get(&prop->name, &lhq.key);
+ if (!njs_is_enumerable(&prop->name, type)) {
+ continue;
+ }
+
+ njs_object_property_key_set(&lhq, &prop->name, lhe.key_hash);
- lhq.proto = &njs_object_hash_proto;
ret = njs_lvlhsh_find(&object->hash, &lhq);
if (ret != NJS_OK && (prop->enumerable || all)) {
name = njs_lvalue_arg(&lvalue, args, nargs, 2);
- if (njs_slow_path(!njs_is_string(name))) {
- ret = njs_value_to_string(vm, name, name);
- if (njs_slow_path(ret != NJS_OK)) {
- return ret;
- }
- }
-
ret = njs_object_prop_define(vm, value, name, desc,
NJS_OBJECT_PROP_DESCRIPTOR);
if (njs_slow_path(ret != NJS_OK)) {
njs_object_get_own_property_descriptor(njs_vm_t *vm, njs_value_t *args,
njs_uint_t nargs, njs_index_t unused)
{
- njs_value_t *value, *property;
+ njs_value_t lvalue, *value, *property;
value = njs_arg(args, nargs, 1);
return NJS_ERROR;
}
- property = njs_arg(args, nargs, 2);
+ property = njs_lvalue_arg(&lvalue, args, nargs, 2);
return njs_object_prop_descriptor(vm, &vm->retval, value, property);
}
return NJS_ERROR;
}
- names = njs_value_own_enumerate(vm, value, NJS_ENUM_KEYS, 1);
+ names = njs_value_own_enumerate(vm, value, NJS_ENUM_KEYS,
+ NJS_ENUM_STRING | NJS_ENUM_SYMBOL, 1);
if (njs_slow_path(names == NULL)) {
return NJS_ERROR;
}
return NJS_ERROR;
}
- njs_string_get(key, &lhq.key);
- lhq.key_hash = njs_djb_hash(lhq.key.start, lhq.key.length);
+ njs_object_property_key_set(&lhq, key, 0);
lhq.value = pr;
ret = njs_lvlhsh_insert(&descriptors->hash, &lhq);
static njs_int_t
-njs_object_get_own_property_names(njs_vm_t *vm, njs_value_t *args,
- njs_uint_t nargs, njs_index_t unused)
+njs_object_get_own_property(njs_vm_t *vm, njs_value_t *args,
+ njs_uint_t nargs, njs_index_t type)
{
njs_array_t *names;
njs_value_t *value;
return NJS_ERROR;
}
- names = njs_value_own_enumerate(vm, value, NJS_ENUM_KEYS, 1);
+ names = njs_value_own_enumerate(vm, value, NJS_ENUM_KEYS,
+ type, 1);
if (names == NULL) {
return NJS_ERROR;
}
for (i = 2; i < nargs; i++) {
source = &args[i];
- names = njs_value_own_enumerate(vm, source, NJS_ENUM_KEYS, 1);
+ names = njs_value_own_enumerate(vm, source, NJS_ENUM_KEYS,
+ NJS_ENUM_STRING | NJS_ENUM_SYMBOL, 1);
if (njs_slow_path(names == NULL)) {
return NJS_ERROR;
}
{
.type = NJS_PROPERTY,
.name = njs_long_string("getOwnPropertyNames"),
- .value = njs_native_function(njs_object_get_own_property_names, 1),
+ .value = njs_native_function2(njs_object_get_own_property, 1,
+ NJS_ENUM_STRING),
+ .writable = 1,
+ .configurable = 1,
+ },
+
+ /* Object.getOwnPropertySymbols(). */
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_long_string("getOwnPropertySymbols"),
+ .value = njs_native_function2(njs_object_get_own_property, 1,
+ NJS_ENUM_SYMBOL),
.writable = 1,
.configurable = 1,
},
#define _NJS_OBJECT_H_INCLUDED_
-#define njs_is_data_descriptor(prop) \
- ((prop)->writable != NJS_ATTRIBUTE_UNSET || njs_is_valid(&(prop)->value))
-
-
-#define njs_is_accessor_descriptor(prop) \
- (njs_is_function_or_undefined(&(prop)->getter) \
- || njs_is_function_or_undefined(&(prop)->setter))
-
-
-#define njs_is_generic_descriptor(prop) \
- (!njs_is_data_descriptor(prop) && !njs_is_accessor_descriptor(prop))
-
-
-#define njs_object_property_init(lhq, _key, hash) \
- do { \
- (lhq)->proto = &njs_object_hash_proto; \
- (lhq)->key_hash = hash; \
- (lhq)->key = njs_str_value(_key); \
- } while (0)
-
-
typedef enum {
NJS_OBJECT_PROP_DESCRIPTOR,
NJS_OBJECT_PROP_GETTER,
njs_object_t *njs_object_value_alloc(njs_vm_t *vm, const njs_value_t *value,
njs_uint_t type);
njs_array_t *njs_object_enumerate(njs_vm_t *vm, const njs_object_t *object,
- njs_object_enum_t kind, njs_bool_t all);
+ njs_object_enum_t kind, njs_object_enum_type_t type, njs_bool_t all);
njs_array_t *njs_object_own_enumerate(njs_vm_t *vm, const njs_object_t *object,
- njs_object_enum_t kind, njs_bool_t all);
+ njs_object_enum_t kind, njs_object_enum_type_t type, njs_bool_t all);
njs_int_t njs_object_traverse(njs_vm_t *vm, njs_object_t *object, void *ctx,
njs_object_traverse_cb_t cb);
njs_int_t njs_object_hash_create(njs_vm_t *vm, njs_lvlhsh_t *hash,
njs_value_t *value, njs_value_t *setval);
const char *njs_prop_type_string(njs_object_prop_type_t type);
-extern const njs_object_type_init_t njs_obj_type_init;
+
+njs_inline njs_bool_t
+njs_is_data_descriptor(njs_object_prop_t *prop)
+{
+ return prop->writable != NJS_ATTRIBUTE_UNSET || njs_is_valid(&prop->value);
+}
+
+
+njs_inline njs_bool_t
+njs_is_accessor_descriptor(njs_object_prop_t *prop)
+{
+ return njs_is_function_or_undefined(&prop->getter)
+ || njs_is_function_or_undefined(&prop->setter);
+}
+
+
+njs_inline njs_bool_t
+njs_is_generic_descriptor(njs_object_prop_t *prop)
+{
+ return !njs_is_data_descriptor(prop) && !njs_is_accessor_descriptor(prop);
+}
+
+
+njs_inline void
+njs_object_property_key_set(njs_lvlhsh_query_t *lhq, const njs_value_t *key,
+ uint32_t hash)
+{
+ if (njs_is_symbol(key)) {
+
+ lhq->key.length = 0;
+ lhq->key_hash = njs_symbol_key(key);
+
+ } else {
+
+ /* string. */
+
+ njs_string_get(key, &lhq->key);
+
+ if (hash == 0) {
+ lhq->key_hash = njs_djb_hash(lhq->key.start, lhq->key.length);
+
+ } else {
+ lhq->key_hash = hash;
+ }
+ }
+}
+
+
+njs_inline void
+njs_object_property_init(njs_lvlhsh_query_t *lhq, const njs_value_t *key,
+ uint32_t hash)
+{
+ lhq->proto = &njs_object_hash_proto;
+
+ njs_object_property_key_set(lhq, key, hash);
+}
+
+
+njs_inline njs_int_t
+njs_primitive_value_to_key(njs_vm_t *vm, njs_value_t *dst,
+ const njs_value_t *src)
+{
+ const njs_value_t *value;
+
+ switch (src->type) {
+
+ case NJS_NULL:
+ value = &njs_string_null;
+ break;
+
+ case NJS_UNDEFINED:
+ value = &njs_string_undefined;
+ break;
+
+ case NJS_BOOLEAN:
+ value = njs_is_true(src) ? &njs_string_true : &njs_string_false;
+ break;
+
+ case NJS_NUMBER:
+ return njs_number_to_string(vm, dst, src);
+
+ case NJS_SYMBOL:
+ case NJS_STRING:
+ /* GC: njs_retain(src); */
+ value = src;
+ break;
+
+ default:
+ return NJS_ERROR;
+ }
+
+ *dst = *value;
+
+ return NJS_OK;
+}
+
+
+njs_inline njs_int_t
+njs_value_to_key(njs_vm_t *vm, njs_value_t *dst, njs_value_t *value)
+{
+ njs_int_t ret;
+ njs_value_t primitive;
+
+ if (njs_slow_path(!njs_is_primitive(value))) {
+ if (njs_slow_path(value->type == NJS_OBJECT_SYMBOL)) {
+ /* should fail */
+ value = njs_object_value(value);
+
+ } else {
+ ret = njs_value_to_primitive(vm, &primitive, value, 1);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return ret;
+ }
+
+ value = &primitive;
+ }
+ }
+
+ return njs_primitive_value_to_key(vm, dst, value);
+}
+
+
+njs_inline njs_int_t
+njs_key_string_get(njs_vm_t *vm, const njs_value_t *key, njs_str_t *str)
+{
+ njs_int_t ret;
+ njs_value_t dst;
+
+ if (njs_slow_path(njs_is_symbol(key))) {
+ ret = njs_symbol_to_string(vm, &dst, key);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return ret;
+ }
+
+ key = &dst;
+ }
+
+ njs_string_get(key, str);
+
+ return NJS_OK;
+}
njs_inline njs_int_t
}
+extern const njs_object_type_init_t njs_obj_type_init;
+
+
#endif /* _NJS_OBJECT_H_INCLUDED_ */
njs_array_t *
njs_value_enumerate(njs_vm_t *vm, const njs_value_t *value,
- njs_object_enum_t kind, njs_bool_t all)
+ njs_object_enum_t kind, njs_object_enum_type_t type, njs_bool_t all)
{
void *obj;
njs_int_t ret;
const njs_extern_t *ext_proto;
if (njs_is_object(value)) {
- return njs_object_enumerate(vm, njs_object(value), kind, all);
+ return njs_object_enumerate(vm, njs_object(value), kind, type, all);
}
if (value->type != NJS_STRING) {
- if (kind == NJS_ENUM_KEYS && njs_is_external(value)) {
+ if (kind == NJS_ENUM_KEYS
+ && (type & NJS_ENUM_STRING)
+ && njs_is_external(value))
+ {
ext_proto = value->external.proto;
if (ext_proto->keys != NULL) {
obj_val.object = vm->string_object;
obj_val.value = *value;
- return njs_object_enumerate(vm, (njs_object_t *) &obj_val, kind, all);
+ return njs_object_enumerate(vm, (njs_object_t *) &obj_val, kind, type, all);
}
njs_array_t *
njs_value_own_enumerate(njs_vm_t *vm, const njs_value_t *value,
- njs_object_enum_t kind, njs_bool_t all)
+ njs_object_enum_t kind, njs_object_enum_type_t type, njs_bool_t all)
{
void *obj;
njs_int_t ret;
const njs_extern_t *ext_proto;
if (njs_is_object(value)) {
- return njs_object_own_enumerate(vm, njs_object(value), kind, all);
+ return njs_object_own_enumerate(vm, njs_object(value), kind, type, all);
}
if (value->type != NJS_STRING) {
- if (kind == NJS_ENUM_KEYS && njs_is_external(value)) {
+ if (kind == NJS_ENUM_KEYS
+ && (type & NJS_ENUM_STRING)
+ && njs_is_external(value))
+ {
ext_proto = value->external.proto;
if (ext_proto->keys != NULL) {
obj_val.object = vm->string_object;
obj_val.value = *value;
- return njs_object_own_enumerate(vm, (njs_object_t *) &obj_val, kind, all);
+ return njs_object_own_enumerate(vm, (njs_object_t *) &obj_val, kind,
+ type, all);
}
return NJS_ERROR;
}
- ret = njs_primitive_value_to_string(vm, &pq->key, key);
+ ret = njs_primitive_value_to_key(vm, &pq->key, key);
if (njs_fast_path(ret == NJS_OK)) {
- njs_string_get(&pq->key, &pq->lhq.key);
- pq->lhq.key_hash = njs_djb_hash(pq->lhq.key.start, pq->lhq.key.length);
+ if (njs_is_symbol(key)) {
+ pq->lhq.key_hash = njs_symbol_key(key);
+
+ } else {
+ njs_string_get(&pq->key, &pq->lhq.key);
+ pq->lhq.key_hash = njs_djb_hash(pq->lhq.key.start,
+ pq->lhq.key.length);
+ }
if (obj == NULL) {
pq->own = 1;
if (njs_is_data_descriptor(prop)) {
if (!prop->writable) {
+ njs_key_string_get(vm, &pq.key, &pq.lhq.key);
njs_type_error(vm,
"Cannot assign to read-only property \"%V\" of %s",
&pq.lhq.key, njs_type_string(value->type));
value, setval, 1, &vm->retval);
}
+ njs_key_string_get(vm, &pq.key, &pq.lhq.key);
njs_type_error(vm,
"Cannot set property \"%V\" of %s which has only a getter",
&pq.lhq.key, njs_type_string(value->type));
prop = pq.lhq.value;
if (njs_slow_path(!prop->configurable)) {
+ njs_key_string_get(vm, &pq.key, &pq.lhq.key);
njs_type_error(vm, "Cannot delete property \"%V\" of %s",
&pq.lhq.key, njs_type_string(value->type));
return NJS_ERROR;