From d368ecda3fb2c6a935be9f796b34791367b998e7 Mon Sep 17 00:00:00 2001 From: Zoltan Herczeg Date: Wed, 22 Sep 2021 06:47:34 +0000 Subject: [PATCH 1/2] Add property key filters for built-in functions JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com --- jerry-core/api/jerry.c | 2 +- .../builtin-objects/ecma-builtin-object.c | 22 ++-- .../builtin-objects/ecma-builtin-reflect.c | 2 +- .../ecma/builtin-objects/ecma-builtins.c | 101 ++++++++++++------ .../ecma/builtin-objects/ecma-builtins.h | 12 +-- .../ecma/operations/ecma-arguments-object.c | 62 ++++++----- .../ecma/operations/ecma-arguments-object.h | 3 +- .../ecma/operations/ecma-array-object.c | 32 +++--- .../ecma/operations/ecma-array-object.h | 2 +- .../ecma/operations/ecma-function-object.c | 35 +++--- .../ecma/operations/ecma-function-object.h | 18 ++-- jerry-core/ecma/operations/ecma-objects.c | 37 ++++--- jerry-core/ecma/operations/ecma-objects.h | 2 +- .../ecma/operations/ecma-proxy-object.c | 4 +- .../ecma/operations/ecma-string-object.c | 35 +++--- .../ecma/operations/ecma-string-object.h | 6 +- .../ecma/operations/ecma-typedarray-object.c | 8 +- .../ecma/operations/ecma-typedarray-object.h | 6 +- jerry-core/vm/opcodes.c | 2 +- 19 files changed, 243 insertions(+), 148 deletions(-) diff --git a/jerry-core/api/jerry.c b/jerry-core/api/jerry.c index e53c587dc4..c127b1f478 100644 --- a/jerry-core/api/jerry.c +++ b/jerry-core/api/jerry.c @@ -4607,7 +4607,7 @@ jerry_object_get_property_names (const jerry_value_t obj_val, /**< object */ while (true) { /* Step 1. Get Object.[[OwnKeys]] */ - ecma_collection_t *prop_names_p = ecma_op_object_own_property_keys (obj_iter_p); + ecma_collection_t *prop_names_p = ecma_op_object_own_property_keys (obj_iter_p, filter); #if JERRY_BUILTIN_PROXY if (prop_names_p == NULL) diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-object.c b/jerry-core/ecma/builtin-objects/ecma-builtin-object.c index 52275fe24c..3df890db3e 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-object.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-object.c @@ -336,7 +336,7 @@ ecma_builtin_object_set_integrity_level (ecma_object_t *obj_p, /**< object */ } /* 6. */ - ecma_collection_t *props_p = ecma_op_object_own_property_keys (obj_p); + ecma_collection_t *props_p = ecma_op_object_own_property_keys (obj_p, JERRY_PROPERTY_FILTER_ALL); #if JERRY_BUILTIN_PROXY if (props_p == NULL) @@ -596,7 +596,7 @@ ecma_builtin_object_test_integrity_level (ecma_object_t *obj_p, /**< routine's a ecma_value_t ret_value = ECMA_VALUE_TRUE; /* 2. */ - ecma_collection_t *props_p = ecma_op_object_own_property_keys (obj_p); + ecma_collection_t *props_p = ecma_op_object_own_property_keys (obj_p, JERRY_PROPERTY_FILTER_ALL); #if JERRY_BUILTIN_PROXY if (props_p == NULL) @@ -750,7 +750,7 @@ static ecma_value_t ecma_builtin_object_object_get_own_property_descriptors (ecma_object_t *obj_p) /**< routine's first argument */ { /* 2 */ - ecma_collection_t *prop_names_p = ecma_op_object_own_property_keys (obj_p); + ecma_collection_t *prop_names_p = ecma_op_object_own_property_keys (obj_p, JERRY_PROPERTY_FILTER_ALL); #if JERRY_BUILTIN_PROXY if (prop_names_p == NULL) @@ -831,7 +831,7 @@ ecma_builtin_object_object_define_properties (ecma_object_t *obj_p, /**< routine ecma_object_t *props_p = ecma_get_object_from_value (props); /* 3. */ - ecma_collection_t *prop_names_p = ecma_op_object_own_property_keys (props_p); + ecma_collection_t *prop_names_p = ecma_op_object_own_property_keys (props_p, JERRY_PROPERTY_FILTER_ALL); ecma_value_t ret_value = ECMA_VALUE_ERROR; #if JERRY_BUILTIN_PROXY @@ -1073,7 +1073,7 @@ ecma_builtin_object_object_assign (ecma_object_t *target_p, /**< target object * ecma_object_t *from_obj_p = ecma_get_object_from_value (from_value); /* 5.b.iii */ - ecma_collection_t *props_p = ecma_op_object_own_property_keys (from_obj_p); + ecma_collection_t *props_p = ecma_op_object_own_property_keys (from_obj_p, JERRY_PROPERTY_FILTER_ALL); #if JERRY_BUILTIN_PROXY if (props_p == NULL) @@ -1327,7 +1327,15 @@ ecma_op_object_get_own_property_keys (ecma_value_t this_arg, /**< this argument ecma_object_t *obj_p = ecma_get_object_from_value (object); /* 2. */ - ecma_collection_t *props_p = ecma_op_object_own_property_keys (obj_p); + jerry_property_filter_t filter = JERRY_PROPERTY_FILTER_EXLCUDE_SYMBOLS; + + if (type == ECMA_OBJECT_ROUTINE_GET_OWN_PROPERTY_SYMBOLS) + { + filter = (JERRY_PROPERTY_FILTER_EXLCUDE_STRINGS + | JERRY_PROPERTY_FILTER_EXLCUDE_INTEGER_INDICES); + } + + ecma_collection_t *props_p = ecma_op_object_own_property_keys (obj_p, filter); if (props_p == NULL) { @@ -1361,7 +1369,7 @@ ecma_op_object_get_own_property_keys (ecma_value_t this_arg, /**< this argument #else /* !JERRY_ESNEXT */ JERRY_UNUSED (type); ecma_object_t *obj_p = ecma_get_object_from_value (this_arg); - ecma_collection_t *props_p = ecma_op_object_own_property_keys (obj_p); + ecma_collection_t *props_p = ecma_op_object_own_property_keys (obj_p, JERRY_PROPERTY_FILTER_ALL); return ecma_op_new_array_object_from_collection (props_p, false); #endif /* JERRY_ESNEXT */ } /* ecma_op_object_get_own_property_keys */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-reflect.c b/jerry-core/ecma/builtin-objects/ecma-builtin-reflect.c index 5e7485bfe3..3f921f0492 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-reflect.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-reflect.c @@ -163,7 +163,7 @@ ecma_builtin_reflect_dispatch_routine (uint8_t builtin_routine_id, /**< built-in ecma_object_t *target_p = ecma_get_object_from_value (arguments_list[0]); /* 2. */ - ecma_collection_t *prop_names = ecma_op_object_own_property_keys (target_p); + ecma_collection_t *prop_names = ecma_op_object_own_property_keys (target_p, JERRY_PROPERTY_FILTER_ALL); #if JERRY_BUILTIN_PROXY if (prop_names == NULL) diff --git a/jerry-core/ecma/builtin-objects/ecma-builtins.c b/jerry-core/ecma/builtin-objects/ecma-builtins.c index dc621e2b19..c4587c817e 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtins.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtins.c @@ -1414,11 +1414,17 @@ ecma_builtin_native_handler_list_lazy_property_names (ecma_object_t *object_p, / void ecma_builtin_routine_list_lazy_property_names (ecma_object_t *object_p, /**< a built-in object */ ecma_collection_t *prop_names_p, /**< prop name collection */ - ecma_property_counter_t *prop_counter_p) /**< prop counter */ + ecma_property_counter_t *prop_counter_p, /**< property counters */ + jerry_property_filter_t filter) /**< name filters */ { JERRY_ASSERT (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION); JERRY_ASSERT (ecma_builtin_function_is_routine (object_p)); + if (filter & JERRY_PROPERTY_FILTER_EXLCUDE_STRINGS) + { + return; + } + #if JERRY_ESNEXT ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p; @@ -1456,7 +1462,8 @@ ecma_builtin_routine_list_lazy_property_names (ecma_object_t *object_p, /**< a b void ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, /**< a built-in object */ ecma_collection_t *prop_names_p, /**< prop name collection */ - ecma_property_counter_t *prop_counter_p) /**< prop counter */ + ecma_property_counter_t *prop_counter_p, /**< property counters */ + jerry_property_filter_t filter) /**< name filters */ { JERRY_ASSERT (ecma_get_object_type (object_p) != ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION || !ecma_builtin_function_is_routine (object_p)); @@ -1477,57 +1484,91 @@ ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, /**< a built-in JERRY_ASSERT (builtin_id < ECMA_BUILTIN_ID__COUNT); - const ecma_builtin_property_descriptor_t *curr_property_p = ecma_builtin_property_list_references[builtin_id]; - - uint32_t index = 0; - uint8_t bitset = built_in_props_p->u2.instantiated_bitset[0]; - #if JERRY_BUILTIN_REALMS uint8_t *bitset_p = built_in_props_p->u2.instantiated_bitset + 1 + sizeof (ecma_value_t); #else /* !JERRY_BUILTIN_REALMS */ uint8_t *bitset_p = built_in_props_p->u2.instantiated_bitset + 1; #endif /* JERRY_BUILTIN_REALMS */ - while (curr_property_p->magic_string_id != LIT_MAGIC_STRING__COUNT) +#if JERRY_ESNEXT + uint8_t *symbol_bitset_p = bitset_p; + bool has_symbol = true; +#endif /* JERRY_BUILTIN_REALMS */ + + if (!(filter & JERRY_PROPERTY_FILTER_EXLCUDE_STRINGS)) { - if (index == 8) - { - bitset = *bitset_p++; - index = 0; - } + const ecma_builtin_property_descriptor_t *curr_property_p = ecma_builtin_property_list_references[builtin_id]; + uint8_t bitset = built_in_props_p->u2.instantiated_bitset[0]; + uint32_t index = 0; - uint32_t bit_for_index = (uint32_t) 1u << index; +#if JERRY_ESNEXT + has_symbol = false; +#endif /* JERRY_BUILTIN_REALMS */ - if (curr_property_p->magic_string_id > LIT_NON_INTERNAL_MAGIC_STRING__COUNT) + while (curr_property_p->magic_string_id != LIT_MAGIC_STRING__COUNT) { -#if JERRY_ESNEXT - if (LIT_IS_GLOBAL_SYMBOL (curr_property_p->magic_string_id)) + if (index == 8) { - ecma_string_t *name_p = ecma_op_get_global_symbol (curr_property_p->magic_string_id); + bitset = *bitset_p++; + index = 0; + } + + uint32_t bit_for_index = (uint32_t) 1u << index; - if (!(bitset & bit_for_index)) + if (!(bitset & bit_for_index)) + { +#if JERRY_ESNEXT + if (JERRY_LIKELY (curr_property_p->magic_string_id < LIT_NON_INTERNAL_MAGIC_STRING__COUNT)) { - ecma_value_t name = ecma_make_symbol_value (name_p); +#endif /* JERRY_ESNEXT */ + ecma_value_t name = ecma_make_magic_string_value ((lit_magic_string_id_t) curr_property_p->magic_string_id); ecma_collection_push_back (prop_names_p, name); - prop_counter_p->symbol_named_props++; + prop_counter_p->string_named_props++; +#if JERRY_ESNEXT } else { - ecma_deref_ecma_string (name_p); + JERRY_ASSERT (LIT_IS_GLOBAL_SYMBOL (curr_property_p->magic_string_id)); + has_symbol = true; } - } #endif /* JERRY_ESNEXT */ + } + + curr_property_p++; + index++; } - else if (!(bitset & bit_for_index)) + } + +#if JERRY_ESNEXT + if (has_symbol && !(filter & JERRY_PROPERTY_FILTER_EXLCUDE_SYMBOLS)) + { + const ecma_builtin_property_descriptor_t *curr_property_p = ecma_builtin_property_list_references[builtin_id]; + uint8_t bitset = built_in_props_p->u2.instantiated_bitset[0]; + uint32_t index = 0; + + while (curr_property_p->magic_string_id != LIT_MAGIC_STRING__COUNT) { - ecma_value_t name = ecma_make_magic_string_value ((lit_magic_string_id_t) curr_property_p->magic_string_id); - ecma_collection_push_back (prop_names_p, name); - prop_counter_p->string_named_props++; - } + if (index == 8) + { + bitset = *symbol_bitset_p++; + index = 0; + } - curr_property_p++; - index++; + uint32_t bit_for_index = (uint32_t) 1u << index; + + if (curr_property_p->magic_string_id > LIT_NON_INTERNAL_MAGIC_STRING__COUNT + && !(bitset & bit_for_index)) + { + ecma_string_t *name_p = ecma_op_get_global_symbol (curr_property_p->magic_string_id); + ecma_collection_push_back (prop_names_p, ecma_make_symbol_value (name_p)); + prop_counter_p->symbol_named_props++; + } + + curr_property_p++; + index++; + } } +#endif /* JERRY_ESNEXT */ } /* ecma_builtin_list_lazy_property_names */ /** diff --git a/jerry-core/ecma/builtin-objects/ecma-builtins.h b/jerry-core/ecma/builtin-objects/ecma-builtins.h index 2a50e5df08..22578fa1c7 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtins.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtins.h @@ -138,13 +138,13 @@ ecma_builtin_routine_delete_built_in_property (ecma_object_t *object_p, ecma_str void ecma_builtin_delete_built_in_property (ecma_object_t *object_p, ecma_string_t *property_name_p); void -ecma_builtin_routine_list_lazy_property_names (ecma_object_t *object_p, - ecma_collection_t *prop_names_p, - ecma_property_counter_t *prop_counter_p); +ecma_builtin_routine_list_lazy_property_names (ecma_object_t *object_p, ecma_collection_t *prop_names_p, + ecma_property_counter_t *prop_counter_p, + jerry_property_filter_t filter); void -ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, - ecma_collection_t *prop_names_p, - ecma_property_counter_t *prop_counter_p); +ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, ecma_collection_t *prop_names_p, + ecma_property_counter_t *prop_counter_p, + jerry_property_filter_t filter); bool ecma_builtin_is_global (ecma_object_t *object_p); ecma_object_t * diff --git a/jerry-core/ecma/operations/ecma-arguments-object.c b/jerry-core/ecma/operations/ecma-arguments-object.c index 55698f6f17..d9effe3160 100644 --- a/jerry-core/ecma/operations/ecma-arguments-object.c +++ b/jerry-core/ecma/operations/ecma-arguments-object.c @@ -401,7 +401,8 @@ ecma_op_arguments_delete_built_in_property (ecma_object_t *object_p, /**< the ob void ecma_op_arguments_object_list_lazy_property_names (ecma_object_t *obj_p, /**< arguments object */ ecma_collection_t *prop_names_p, /**< prop name collection */ - ecma_property_counter_t *prop_counter_p) /**< property counters */ + ecma_property_counter_t *prop_counter_p, /**< property counters */ + jerry_property_filter_t filter) /**< property name filter options */ { JERRY_ASSERT (ecma_object_class_is (obj_p, ECMA_OBJECT_CLASS_ARGUMENTS)); @@ -410,45 +411,52 @@ ecma_op_arguments_object_list_lazy_property_names (ecma_object_t *obj_p, /**< ar uint32_t arguments_number = arguments_p->header.u.cls.u3.arguments_number; uint8_t flags = arguments_p->header.u.cls.u1.arguments_flags; - ecma_value_t *argv_p = (ecma_value_t *) (arguments_p + 1); - - if (flags & ECMA_ARGUMENTS_OBJECT_MAPPED) + if (!(filter & JERRY_PROPERTY_FILTER_EXLCUDE_INTEGER_INDICES)) { - argv_p = (ecma_value_t *) (((ecma_mapped_arguments_t *) obj_p) + 1); - } + ecma_value_t *argv_p = (ecma_value_t *) (arguments_p + 1); - for (uint32_t index = 0; index < arguments_number; index++) - { - if (!ecma_is_value_empty (argv_p[index])) + if (flags & ECMA_ARGUMENTS_OBJECT_MAPPED) { - ecma_string_t *index_string_p = ecma_new_ecma_string_from_uint32 (index); - ecma_collection_push_back (prop_names_p, ecma_make_string_value (index_string_p)); - prop_counter_p->array_index_named_props++; + argv_p = (ecma_value_t *) (((ecma_mapped_arguments_t *) obj_p) + 1); } - } - if (!(flags & ECMA_ARGUMENTS_OBJECT_LENGTH_INITIALIZED)) - { - ecma_collection_push_back (prop_names_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH)); - prop_counter_p->string_named_props++; + for (uint32_t index = 0; index < arguments_number; index++) + { + if (!ecma_is_value_empty (argv_p[index])) + { + ecma_string_t *index_string_p = ecma_new_ecma_string_from_uint32 (index); + ecma_collection_push_back (prop_names_p, ecma_make_string_value (index_string_p)); + prop_counter_p->array_index_named_props++; + } + } } - if (!(flags & ECMA_ARGUMENTS_OBJECT_CALLEE_INITIALIZED)) + if (!(filter & JERRY_PROPERTY_FILTER_EXLCUDE_STRINGS)) { - ecma_collection_push_back (prop_names_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_CALLEE)); - prop_counter_p->string_named_props++; - } + if (!(flags & ECMA_ARGUMENTS_OBJECT_LENGTH_INITIALIZED)) + { + ecma_collection_push_back (prop_names_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH)); + prop_counter_p->string_named_props++; + } + + if (!(flags & ECMA_ARGUMENTS_OBJECT_CALLEE_INITIALIZED)) + { + ecma_collection_push_back (prop_names_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_CALLEE)); + prop_counter_p->string_named_props++; + } #if !JERRY_ESNEXT - if (!(flags & ECMA_ARGUMENTS_OBJECT_MAPPED)) - { - ecma_collection_push_back (prop_names_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_CALLER)); - prop_counter_p->string_named_props++; - } + if (!(flags & ECMA_ARGUMENTS_OBJECT_MAPPED)) + { + ecma_collection_push_back (prop_names_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_CALLER)); + prop_counter_p->string_named_props++; + } #endif /* !JERRY_ESNEXT */ + } #if JERRY_ESNEXT - if (!(flags & ECMA_ARGUMENTS_OBJECT_ITERATOR_INITIALIZED)) + if (!(filter & JERRY_PROPERTY_FILTER_EXLCUDE_SYMBOLS) + && !(flags & ECMA_ARGUMENTS_OBJECT_ITERATOR_INITIALIZED)) { ecma_string_t *symbol_p = ecma_op_get_global_symbol (LIT_GLOBAL_SYMBOL_ITERATOR); ecma_collection_push_back (prop_names_p, ecma_make_symbol_value (symbol_p)); diff --git a/jerry-core/ecma/operations/ecma-arguments-object.h b/jerry-core/ecma/operations/ecma-arguments-object.h index cd1635d065..08477582b3 100644 --- a/jerry-core/ecma/operations/ecma-arguments-object.h +++ b/jerry-core/ecma/operations/ecma-arguments-object.h @@ -36,7 +36,8 @@ ecma_op_arguments_delete_built_in_property (ecma_object_t *object_p, ecma_string void ecma_op_arguments_object_list_lazy_property_names (ecma_object_t *obj_p, ecma_collection_t *prop_names_p, - ecma_property_counter_t *prop_counter_p); + ecma_property_counter_t *prop_counter_p, + jerry_property_filter_t filter); ecma_string_t * ecma_op_arguments_object_get_formal_parameter (ecma_mapped_arguments_t *mapped_arguments_p, diff --git a/jerry-core/ecma/operations/ecma-array-object.c b/jerry-core/ecma/operations/ecma-array-object.c index 3be8f62c0f..5494a3e55c 100644 --- a/jerry-core/ecma/operations/ecma-array-object.c +++ b/jerry-core/ecma/operations/ecma-array-object.c @@ -649,32 +649,40 @@ ecma_fast_array_set_length (ecma_object_t *object_p, /**< fast access mode array * @return collection of strings - property names */ ecma_collection_t * -ecma_fast_array_object_own_property_keys (ecma_object_t *object_p) /**< fast access mode array object */ +ecma_fast_array_object_own_property_keys (ecma_object_t *object_p, /**< fast access mode array object */ + jerry_property_filter_t filter) /**< property name filter options */ { JERRY_ASSERT (ecma_op_object_is_fast_array (object_p)); - ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p; ecma_collection_t *ret_p = ecma_new_collection (); - uint32_t length = ext_obj_p->u.array.length; - if (length != 0) + if (!(filter & JERRY_PROPERTY_FILTER_EXLCUDE_INTEGER_INDICES)) { - ecma_value_t *values_p = ECMA_GET_NON_NULL_POINTER (ecma_value_t, object_p->u1.property_list_cp); + ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p; + uint32_t length = ext_obj_p->u.array.length; - for (uint32_t i = 0; i < length; i++) + if (length != 0) { - if (ecma_is_value_array_hole (values_p[i])) + ecma_value_t *values_p = ECMA_GET_NON_NULL_POINTER (ecma_value_t, object_p->u1.property_list_cp); + + for (uint32_t i = 0; i < length; i++) { - continue; - } + if (ecma_is_value_array_hole (values_p[i])) + { + continue; + } - ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (i); + ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (i); - ecma_collection_push_back (ret_p, ecma_make_string_value (index_str_p)); + ecma_collection_push_back (ret_p, ecma_make_string_value (index_str_p)); + } } } - ecma_collection_push_back (ret_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH)); + if (!(filter & JERRY_PROPERTY_FILTER_EXLCUDE_STRINGS)) + { + ecma_collection_push_back (ret_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH)); + } return ret_p; } /* ecma_fast_array_object_own_property_keys */ diff --git a/jerry-core/ecma/operations/ecma-array-object.h b/jerry-core/ecma/operations/ecma-array-object.h index 2e6e8fe4e8..a56d3bc506 100644 --- a/jerry-core/ecma/operations/ecma-array-object.h +++ b/jerry-core/ecma/operations/ecma-array-object.h @@ -96,7 +96,7 @@ uint32_t ecma_delete_fast_array_properties (ecma_object_t *object_p, uint32_t new_length); ecma_collection_t * -ecma_fast_array_object_own_property_keys (ecma_object_t *object_p); +ecma_fast_array_object_own_property_keys (ecma_object_t *object_p, jerry_property_filter_t filter); void ecma_fast_array_convert_to_normal (ecma_object_t *object_p); diff --git a/jerry-core/ecma/operations/ecma-function-object.c b/jerry-core/ecma/operations/ecma-function-object.c index 7506397cf6..90139334ed 100644 --- a/jerry-core/ecma/operations/ecma-function-object.c +++ b/jerry-core/ecma/operations/ecma-function-object.c @@ -2162,8 +2162,14 @@ ecma_op_bound_function_delete_built_in_property (ecma_object_t *object_p, /**< o void ecma_op_function_list_lazy_property_names (ecma_object_t *object_p, /**< functionobject */ ecma_collection_t *prop_names_p, /**< prop name collection */ - ecma_property_counter_t *prop_counter_p) /**< prop counter */ + ecma_property_counter_t *prop_counter_p, /**< property counters */ + jerry_property_filter_t filter) /**< property name filter options */ { + if (filter & JERRY_PROPERTY_FILTER_EXLCUDE_STRINGS) + { + return; + } + const ecma_compiled_code_t *bytecode_data_p; bytecode_data_p = ecma_op_function_get_compiled_code ((ecma_extended_object_t *) object_p); @@ -2236,21 +2242,20 @@ ecma_op_function_list_lazy_property_names (ecma_object_t *object_p, /**< functio void ecma_op_external_function_list_lazy_property_names (ecma_object_t *object_p, /**< function object */ ecma_collection_t *prop_names_p, /**< prop name collection */ - ecma_property_counter_t *prop_counter_p) /**< prop counter */ + ecma_property_counter_t *prop_counter_p, /**< property counters */ + jerry_property_filter_t filter) /**< property name + * filter options */ { -#if !JERRY_ESNEXT JERRY_UNUSED (object_p); -#else /* JERRY_ESNEXT */ - /* TODO: implicit class constructors need rework, and this code should be updated afterwards. */ - ecma_property_t *property_p = ecma_find_named_property (object_p, ecma_get_magic_string (LIT_MAGIC_STRING_PROTOTYPE)); - if (property_p == NULL || (*property_p & ECMA_PROPERTY_FLAG_BUILT_IN)) -#endif /* !JERRY_ESNEXT */ + if (filter & JERRY_PROPERTY_FILTER_EXLCUDE_STRINGS) { - /* 'prototype' property is non-enumerable (ECMA-262 v5, 13.2.18) */ - ecma_collection_push_back (prop_names_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_PROTOTYPE)); - prop_counter_p->string_named_props++; + return; } + + /* 'prototype' property is non-enumerable (ECMA-262 v5, 13.2.18) */ + ecma_collection_push_back (prop_names_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_PROTOTYPE)); + prop_counter_p->string_named_props++; } /* ecma_op_external_function_list_lazy_property_names */ /** @@ -2263,8 +2268,14 @@ ecma_op_external_function_list_lazy_property_names (ecma_object_t *object_p, /** void ecma_op_bound_function_list_lazy_property_names (ecma_object_t *object_p, /**< bound function object*/ ecma_collection_t *prop_names_p, /**< prop name collection */ - ecma_property_counter_t *prop_counter_p) /**< prop counter */ + ecma_property_counter_t *prop_counter_p, /**< property counters */ + jerry_property_filter_t filter) /**< property name filter options */ { + if (filter & JERRY_PROPERTY_FILTER_EXLCUDE_STRINGS) + { + return; + } + #if JERRY_ESNEXT /* Unintialized 'length' property is non-enumerable (ECMA-262 v6, 19.2.4.1) */ ecma_bound_function_t *bound_func_p = (ecma_bound_function_t *) object_p; diff --git a/jerry-core/ecma/operations/ecma-function-object.h b/jerry-core/ecma/operations/ecma-function-object.h index 44b1963bb8..b2a710df68 100644 --- a/jerry-core/ecma/operations/ecma-function-object.h +++ b/jerry-core/ecma/operations/ecma-function-object.h @@ -117,19 +117,19 @@ ecma_op_bound_function_delete_built_in_property (ecma_object_t *object_p, ecma_s #endif /* JERRY_ESNEXT */ void -ecma_op_function_list_lazy_property_names (ecma_object_t *object_p, - ecma_collection_t *prop_names_p, - ecma_property_counter_t *prop_counter_p); +ecma_op_function_list_lazy_property_names (ecma_object_t *object_p, ecma_collection_t *prop_names_p, + ecma_property_counter_t *prop_counter_p, + jerry_property_filter_t filter); void -ecma_op_external_function_list_lazy_property_names (ecma_object_t *object_p, - ecma_collection_t *prop_names_p, - ecma_property_counter_t *prop_counter_p); +ecma_op_external_function_list_lazy_property_names (ecma_object_t *object_p, ecma_collection_t *prop_names_p, + ecma_property_counter_t *prop_counter_p, + jerry_property_filter_t filter); void -ecma_op_bound_function_list_lazy_property_names (ecma_object_t *object_p, - ecma_collection_t *prop_names_p, - ecma_property_counter_t *prop_counter_p); +ecma_op_bound_function_list_lazy_property_names (ecma_object_t *object_p, ecma_collection_t *prop_names_p, + ecma_property_counter_t *prop_counter_p, + jerry_property_filter_t filter); /** * @} diff --git a/jerry-core/ecma/operations/ecma-objects.c b/jerry-core/ecma/operations/ecma-objects.c index cc6c156c07..ed6d82e298 100644 --- a/jerry-core/ecma/operations/ecma-objects.c +++ b/jerry-core/ecma/operations/ecma-objects.c @@ -2180,7 +2180,7 @@ ecma_op_object_get_enumerable_property_names (ecma_object_t *obj_p, /**< routine ecma_enumerable_property_names_options_t option) /**< listing option */ { /* 2. */ - ecma_collection_t *prop_names_p = ecma_op_object_own_property_keys (obj_p); + ecma_collection_t *prop_names_p = ecma_op_object_own_property_keys (obj_p, JERRY_PROPERTY_FILTER_EXLCUDE_SYMBOLS); #if JERRY_BUILTIN_PROXY if (JERRY_UNLIKELY (prop_names_p == NULL)) @@ -2278,7 +2278,8 @@ ecma_op_object_get_enumerable_property_names (ecma_object_t *obj_p, /**< routine static void ecma_object_list_lazy_property_names (ecma_object_t *obj_p, /**< object */ ecma_collection_t *prop_names_p, /**< prop name collection */ - ecma_property_counter_t *prop_counter_p) /**< prop counter */ + ecma_property_counter_t *prop_counter_p, /**< property counters */ + jerry_property_filter_t filter) /**< property name filter options */ { switch (ecma_get_object_type (obj_p)) { @@ -2286,7 +2287,7 @@ ecma_object_list_lazy_property_names (ecma_object_t *obj_p, /**< object */ { if (ecma_builtin_function_is_routine (obj_p)) { - ecma_builtin_routine_list_lazy_property_names (obj_p, prop_names_p, prop_counter_p); + ecma_builtin_routine_list_lazy_property_names (obj_p, prop_names_p, prop_counter_p, filter); break; } /* FALLTHRU */ @@ -2295,7 +2296,7 @@ ecma_object_list_lazy_property_names (ecma_object_t *obj_p, /**< object */ case ECMA_OBJECT_TYPE_BUILT_IN_CLASS: case ECMA_OBJECT_TYPE_BUILT_IN_ARRAY: { - ecma_builtin_list_lazy_property_names (obj_p, prop_names_p, prop_counter_p); + ecma_builtin_list_lazy_property_names (obj_p, prop_names_p, prop_counter_p, filter); break; } case ECMA_OBJECT_TYPE_CLASS: @@ -2306,19 +2307,19 @@ ecma_object_list_lazy_property_names (ecma_object_t *obj_p, /**< object */ { case ECMA_OBJECT_CLASS_STRING: { - ecma_op_string_list_lazy_property_names (obj_p, prop_names_p, prop_counter_p); + ecma_op_string_list_lazy_property_names (obj_p, prop_names_p, prop_counter_p, filter); break; } case ECMA_OBJECT_CLASS_ARGUMENTS: { - ecma_op_arguments_object_list_lazy_property_names (obj_p, prop_names_p, prop_counter_p); + ecma_op_arguments_object_list_lazy_property_names (obj_p, prop_names_p, prop_counter_p, filter); break; } #if JERRY_BUILTIN_TYPEDARRAY /* ES2015 9.4.5.1 */ case ECMA_OBJECT_CLASS_TYPEDARRAY: { - ecma_op_typedarray_list_lazy_property_names (obj_p, prop_names_p, prop_counter_p); + ecma_op_typedarray_list_lazy_property_names (obj_p, prop_names_p, prop_counter_p, filter); break; } #endif /* JERRY_BUILTIN_TYPEDARRAY */ @@ -2327,23 +2328,26 @@ ecma_object_list_lazy_property_names (ecma_object_t *obj_p, /**< object */ } case ECMA_OBJECT_TYPE_FUNCTION: { - ecma_op_function_list_lazy_property_names (obj_p, prop_names_p, prop_counter_p); + ecma_op_function_list_lazy_property_names (obj_p, prop_names_p, prop_counter_p, filter); break; } case ECMA_OBJECT_TYPE_NATIVE_FUNCTION: { - ecma_op_external_function_list_lazy_property_names (obj_p, prop_names_p, prop_counter_p); + ecma_op_external_function_list_lazy_property_names (obj_p, prop_names_p, prop_counter_p, filter); break; } case ECMA_OBJECT_TYPE_BOUND_FUNCTION: { - ecma_op_bound_function_list_lazy_property_names (obj_p, prop_names_p, prop_counter_p); + ecma_op_bound_function_list_lazy_property_names (obj_p, prop_names_p, prop_counter_p, filter); break; } case ECMA_OBJECT_TYPE_ARRAY: { - ecma_collection_push_back (prop_names_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH)); - prop_counter_p->string_named_props++; + if (!(filter & JERRY_PROPERTY_FILTER_EXLCUDE_STRINGS)) + { + ecma_collection_push_back (prop_names_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH)); + prop_counter_p->string_named_props++; + } break; } default: @@ -2486,7 +2490,8 @@ ecma_object_sort_property_names (ecma_collection_t *prop_names_p, /**< prop name * collection of property names - otherwise */ ecma_collection_t * -ecma_op_object_own_property_keys (ecma_object_t *obj_p) /**< object */ +ecma_op_object_own_property_keys (ecma_object_t *obj_p, /**< object */ + jerry_property_filter_t filter) /**< property name filter options */ { #if JERRY_BUILTIN_PROXY if (ECMA_OBJECT_IS_PROXY (obj_p)) @@ -2497,13 +2502,13 @@ ecma_op_object_own_property_keys (ecma_object_t *obj_p) /**< object */ if (ecma_op_object_is_fast_array (obj_p)) { - return ecma_fast_array_object_own_property_keys (obj_p); + return ecma_fast_array_object_own_property_keys (obj_p, filter); } ecma_collection_t *prop_names_p = ecma_new_collection (); ecma_property_counter_t prop_counter = {0, 0, 0, 0, 0}; - ecma_object_list_lazy_property_names (obj_p, prop_names_p, &prop_counter); + ecma_object_list_lazy_property_names (obj_p, prop_names_p, &prop_counter, filter); prop_counter.lazy_string_named_props = prop_names_p->item_count - prop_counter.symbol_named_props; prop_counter.lazy_symbol_named_props = prop_counter.symbol_named_props; @@ -2595,7 +2600,7 @@ ecma_op_object_enumerate (ecma_object_t *obj_p) /**< object */ while (true) { - ecma_collection_t *keys = ecma_op_object_own_property_keys (obj_p); + ecma_collection_t *keys = ecma_op_object_own_property_keys (obj_p, JERRY_PROPERTY_FILTER_EXLCUDE_SYMBOLS); #if JERRY_ESNEXT if (JERRY_UNLIKELY (keys == NULL)) diff --git a/jerry-core/ecma/operations/ecma-objects.h b/jerry-core/ecma/operations/ecma-objects.h index 26f78352cc..4e1336524c 100644 --- a/jerry-core/ecma/operations/ecma-objects.h +++ b/jerry-core/ecma/operations/ecma-objects.h @@ -97,7 +97,7 @@ ecma_object_t *ecma_op_object_get_prototype_of (ecma_object_t *obj_p); ecma_value_t ecma_op_object_is_prototype_of (ecma_object_t *base_p, ecma_object_t *target_p); ecma_collection_t * ecma_op_object_get_enumerable_property_names (ecma_object_t *obj_p, ecma_enumerable_property_names_options_t option); -ecma_collection_t *ecma_op_object_own_property_keys (ecma_object_t *obj_p); +ecma_collection_t *ecma_op_object_own_property_keys (ecma_object_t *obj_p, jerry_property_filter_t filter); ecma_collection_t *ecma_op_object_enumerate (ecma_object_t *obj_p); lit_magic_string_id_t ecma_object_get_class_name (ecma_object_t *obj_p); diff --git a/jerry-core/ecma/operations/ecma-proxy-object.c b/jerry-core/ecma/operations/ecma-proxy-object.c index 5fcc1dcb41..4c22aae12d 100644 --- a/jerry-core/ecma/operations/ecma-proxy-object.c +++ b/jerry-core/ecma/operations/ecma-proxy-object.c @@ -1628,7 +1628,7 @@ ecma_proxy_object_own_property_keys (ecma_object_t *obj_p) /**< proxy object */ /* 6. */ if (ecma_is_value_undefined (trap)) { - ecma_collection_t *result = ecma_op_object_own_property_keys (target_obj_p); + ecma_collection_t *result = ecma_op_object_own_property_keys (target_obj_p, JERRY_PROPERTY_FILTER_ALL); JERRY_BLOCK_TAIL_CALL_OPTIMIZATION (); return result; } @@ -1674,7 +1674,7 @@ ecma_proxy_object_own_property_keys (ecma_object_t *obj_p) /**< proxy object */ } /* 11. */ - ecma_collection_t *target_keys = ecma_op_object_own_property_keys (target_obj_p); + ecma_collection_t *target_keys = ecma_op_object_own_property_keys (target_obj_p, JERRY_PROPERTY_FILTER_ALL); if (target_keys == NULL) { diff --git a/jerry-core/ecma/operations/ecma-string-object.c b/jerry-core/ecma/operations/ecma-string-object.c index cf4c363dd8..653e9ec0ea 100644 --- a/jerry-core/ecma/operations/ecma-string-object.c +++ b/jerry-core/ecma/operations/ecma-string-object.c @@ -105,29 +105,36 @@ ecma_op_create_string_object (const ecma_value_t *arguments_list_p, /**< list of void ecma_op_string_list_lazy_property_names (ecma_object_t *obj_p, /**< a String object */ ecma_collection_t *prop_names_p, /**< prop name collection */ - ecma_property_counter_t *prop_counter_p) /**< prop counter */ + ecma_property_counter_t *prop_counter_p, /**< property counters */ + jerry_property_filter_t filter) /**< property name filter options */ { JERRY_ASSERT (ecma_get_object_base_type (obj_p) == ECMA_OBJECT_BASE_TYPE_CLASS); - ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p; - JERRY_ASSERT (ext_object_p->u.cls.type == ECMA_OBJECT_CLASS_STRING); + if (!(filter & JERRY_PROPERTY_FILTER_EXLCUDE_INTEGER_INDICES)) + { + ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p; + JERRY_ASSERT (ext_object_p->u.cls.type == ECMA_OBJECT_CLASS_STRING); - ecma_string_t *prim_value_str_p = ecma_get_string_from_value (ext_object_p->u.cls.u3.value); + ecma_string_t *prim_value_str_p = ecma_get_string_from_value (ext_object_p->u.cls.u3.value); - lit_utf8_size_t length = ecma_string_get_length (prim_value_str_p); + lit_utf8_size_t length = ecma_string_get_length (prim_value_str_p); - for (lit_utf8_size_t i = 0; i < length; i++) - { - ecma_string_t *name_p = ecma_new_ecma_string_from_uint32 (i); + for (lit_utf8_size_t i = 0; i < length; i++) + { + ecma_string_t *name_p = ecma_new_ecma_string_from_uint32 (i); - /* the properties are enumerable (ECMA-262 v5, 15.5.5.2.9) */ - ecma_collection_push_back (prop_names_p, ecma_make_string_value (name_p)); - } + /* the properties are enumerable (ECMA-262 v5, 15.5.5.2.9) */ + ecma_collection_push_back (prop_names_p, ecma_make_string_value (name_p)); + } - prop_counter_p->array_index_named_props += length; + prop_counter_p->array_index_named_props += length; + } - ecma_collection_push_back (prop_names_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH)); - prop_counter_p->string_named_props++; + if (!(filter & JERRY_PROPERTY_FILTER_EXLCUDE_STRINGS)) + { + ecma_collection_push_back (prop_names_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH)); + prop_counter_p->string_named_props++; + } } /* ecma_op_string_list_lazy_property_names */ /** diff --git a/jerry-core/ecma/operations/ecma-string-object.h b/jerry-core/ecma/operations/ecma-string-object.h index 4ce1d44323..da0d7431ce 100644 --- a/jerry-core/ecma/operations/ecma-string-object.h +++ b/jerry-core/ecma/operations/ecma-string-object.h @@ -29,9 +29,9 @@ ecma_value_t ecma_op_create_string_object (const ecma_value_t *arguments_list_p, uint32_t arguments_list_len); void -ecma_op_string_list_lazy_property_names (ecma_object_t *obj_p, - ecma_collection_t *prop_names_p, - ecma_property_counter_t *prop_counter_p); +ecma_op_string_list_lazy_property_names (ecma_object_t *obj_p, ecma_collection_t *prop_names_p, + ecma_property_counter_t *prop_counter_p, + jerry_property_filter_t filter); /** * @} diff --git a/jerry-core/ecma/operations/ecma-typedarray-object.c b/jerry-core/ecma/operations/ecma-typedarray-object.c index 62be35f8c1..cb2b978e26 100644 --- a/jerry-core/ecma/operations/ecma-typedarray-object.c +++ b/jerry-core/ecma/operations/ecma-typedarray-object.c @@ -1827,10 +1827,16 @@ ecma_is_typedarray (ecma_value_t value) /**< the target need to be checked */ void ecma_op_typedarray_list_lazy_property_names (ecma_object_t *obj_p, /**< a TypedArray object */ ecma_collection_t *prop_names_p, /**< prop name collection */ - ecma_property_counter_t *prop_counter_p) /**< prop counter */ + ecma_property_counter_t *prop_counter_p, /**< property counters */ + jerry_property_filter_t filter) /**< property name filter options */ { JERRY_ASSERT (ecma_object_is_typedarray (obj_p)); + if (filter & JERRY_PROPERTY_FILTER_EXLCUDE_INTEGER_INDICES) + { + return; + } + uint32_t array_length = ecma_typedarray_get_length (obj_p); for (uint32_t i = 0; i < array_length; i++) diff --git a/jerry-core/ecma/operations/ecma-typedarray-object.h b/jerry-core/ecma/operations/ecma-typedarray-object.h index b3b9c78421..4cbc1965fe 100644 --- a/jerry-core/ecma/operations/ecma-typedarray-object.h +++ b/jerry-core/ecma/operations/ecma-typedarray-object.h @@ -62,9 +62,9 @@ ecma_typedarray_iterators_helper (ecma_value_t this_arg, ecma_iterator_kind_t ki bool ecma_object_is_typedarray (ecma_object_t *obj_p); bool ecma_is_typedarray (ecma_value_t target); -void ecma_op_typedarray_list_lazy_property_names (ecma_object_t *obj_p, - ecma_collection_t *prop_names_p, - ecma_property_counter_t *prop_counter_p); +void ecma_op_typedarray_list_lazy_property_names (ecma_object_t *obj_p, ecma_collection_t *prop_names_p, + ecma_property_counter_t *prop_counter_p, + jerry_property_filter_t filter); ecma_value_t ecma_op_typedarray_define_own_property (ecma_object_t *obj_p, ecma_string_t *prop_name_p, const ecma_property_descriptor_t *property_desc_p); diff --git a/jerry-core/vm/opcodes.c b/jerry-core/vm/opcodes.c index 4ad26b1a5d..e8e5ae48b8 100644 --- a/jerry-core/vm/opcodes.c +++ b/jerry-core/vm/opcodes.c @@ -1558,7 +1558,7 @@ opfunc_copy_data_properties (ecma_value_t target_object, /**< target object */ } ecma_object_t *source_object_p = ecma_get_object_from_value (source_object); - ecma_collection_t *names_p = ecma_op_object_own_property_keys (source_object_p); + ecma_collection_t *names_p = ecma_op_object_own_property_keys (source_object_p, JERRY_PROPERTY_FILTER_ALL); #if JERRY_BUILTIN_PROXY if (names_p == NULL) From 14599edffb4318d5ad777d4494f6f4f0985648b9 Mon Sep 17 00:00:00 2001 From: Zoltan Herczeg Date: Mon, 20 Sep 2021 09:27:43 +0000 Subject: [PATCH 2/2] Rework own property enumeration Properry name filtering is done during the enumeration. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com --- jerry-core/api/jerry.c | 37 +- jerry-core/ecma/base/ecma-globals.h | 2 - jerry-core/ecma/base/ecma-module.c | 2 +- .../builtin-objects/ecma-builtin-object.c | 26 +- .../builtin-objects/ecma-builtin-reflect.c | 2 +- jerry-core/ecma/operations/ecma-conversion.c | 61 ++- jerry-core/ecma/operations/ecma-conversion.h | 19 +- jerry-core/ecma/operations/ecma-objects.c | 356 +++++++++++------- .../ecma/operations/ecma-proxy-object.c | 10 +- .../ecma/operations/ecma-proxy-object.h | 2 +- 10 files changed, 318 insertions(+), 199 deletions(-) diff --git a/jerry-core/api/jerry.c b/jerry-core/api/jerry.c index c127b1f478..51078c9f6a 100644 --- a/jerry-core/api/jerry.c +++ b/jerry-core/api/jerry.c @@ -4604,6 +4604,12 @@ jerry_object_get_property_names (const jerry_value_t obj_val, /**< object */ ecma_ref_object (obj_iter_p); + if ((filter & JERRY_PROPERTY_FILTER_EXLCUDE_STRINGS) + && !(filter & JERRY_PROPERTY_FILTER_INTEGER_INDICES_AS_NUMBER)) + { + filter |= JERRY_PROPERTY_FILTER_EXLCUDE_INTEGER_INDICES; + } + while (true) { /* Step 1. Get Object.[[OwnKeys]] */ @@ -4623,34 +4629,7 @@ jerry_object_get_property_names (const jerry_value_t obj_val, /**< object */ ecma_string_t *key_p = ecma_get_prop_name_from_value (key); uint32_t index = ecma_string_get_array_index (key_p); - /* Step 2. Filter by key type */ - if (filter & (JERRY_PROPERTY_FILTER_EXLCUDE_STRINGS - | JERRY_PROPERTY_FILTER_EXLCUDE_SYMBOLS - | JERRY_PROPERTY_FILTER_EXLCUDE_INTEGER_INDICES)) - { - if (ecma_is_value_symbol (key)) - { - if (filter & JERRY_PROPERTY_FILTER_EXLCUDE_SYMBOLS) - { - continue; - } - } - else if (index != ECMA_STRING_NOT_ARRAY_INDEX) - { - if ((filter & JERRY_PROPERTY_FILTER_EXLCUDE_INTEGER_INDICES) - || ((filter & JERRY_PROPERTY_FILTER_EXLCUDE_STRINGS) - && !(filter & JERRY_PROPERTY_FILTER_INTEGER_INDICES_AS_NUMBER))) - { - continue; - } - } - else if (filter & JERRY_PROPERTY_FILTER_EXLCUDE_STRINGS) - { - continue; - } - } - - /* Step 3. Filter property attributes */ + /* Step 2. Filter property attributes */ if (filter & (JERRY_PROPERTY_FILTER_EXLCUDE_NON_CONFIGURABLE | JERRY_PROPERTY_FILTER_EXLCUDE_NON_ENUMERABLE | JERRY_PROPERTY_FILTER_EXLCUDE_NON_WRITABLE)) @@ -4729,7 +4708,7 @@ jerry_object_get_property_names (const jerry_value_t obj_val, /**< object */ ecma_collection_free (prop_names_p); - /* Step 4: Traverse prototype chain */ + /* Step 3: Traverse prototype chain */ if ((filter & JERRY_PROPERTY_FILTER_TRAVERSE_PROTOTYPE_CHAIN) != JERRY_PROPERTY_FILTER_TRAVERSE_PROTOTYPE_CHAIN) { diff --git a/jerry-core/ecma/base/ecma-globals.h b/jerry-core/ecma/base/ecma-globals.h index 6166c496c4..cac25be7a3 100644 --- a/jerry-core/ecma/base/ecma-globals.h +++ b/jerry-core/ecma/base/ecma-globals.h @@ -2439,8 +2439,6 @@ typedef struct uint32_t array_index_named_props; /**< number of array index named properties */ uint32_t string_named_props; /**< number of string named properties */ uint32_t symbol_named_props; /**< number of symbol named properties */ - uint32_t lazy_string_named_props; /**< number of lazy instantiated string properties */ - uint32_t lazy_symbol_named_props; /**< number of lazy instantiated symbol properties */ } ecma_property_counter_t; /** diff --git a/jerry-core/ecma/base/ecma-module.c b/jerry-core/ecma/base/ecma-module.c index 234a1ac994..59c86f69e7 100644 --- a/jerry-core/ecma/base/ecma-module.c +++ b/jerry-core/ecma/base/ecma-module.c @@ -670,7 +670,7 @@ ecma_module_heap_sort_shift_down (ecma_value_t *buffer_p, /**< array of items */ while (true) { uint32_t highest_index = item_index; - uint32_t current_index = item_index * 2 + 2; + uint32_t current_index = (item_index << 1) + 2; if (current_index >= item_count) { diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-object.c b/jerry-core/ecma/builtin-objects/ecma-builtin-object.c index 3df890db3e..031a19dce9 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-object.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-object.c @@ -1336,36 +1336,14 @@ ecma_op_object_get_own_property_keys (ecma_value_t this_arg, /**< this argument } ecma_collection_t *props_p = ecma_op_object_own_property_keys (obj_p, filter); + ecma_deref_object (obj_p); if (props_p == NULL) { - ecma_deref_object (obj_p); return ECMA_VALUE_ERROR; } - /* 3. */ - ecma_collection_t *name_list_p = ecma_new_collection (); - - /* 4. */ - for (uint32_t i = 0; i < props_p->item_count; i++) - { - ecma_value_t prop_name = props_p->buffer_p[i]; - ecma_string_t *name_p = ecma_get_prop_name_from_value (prop_name); - - if ((ecma_prop_name_is_symbol (name_p) && type == ECMA_OBJECT_ROUTINE_GET_OWN_PROPERTY_SYMBOLS) - || (ecma_is_value_string (prop_name) && type == ECMA_OBJECT_ROUTINE_GET_OWN_PROPERTY_NAMES)) - { - ecma_ref_ecma_string (name_p); - ecma_collection_push_back (name_list_p, prop_name); - } - } - - ecma_value_t result_array = ecma_op_new_array_object_from_collection (name_list_p, false); - - ecma_deref_object (obj_p); - ecma_collection_free (props_p); - - return result_array; + return ecma_op_new_array_object_from_collection (props_p, false); #else /* !JERRY_ESNEXT */ JERRY_UNUSED (type); ecma_object_t *obj_p = ecma_get_object_from_value (this_arg); diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-reflect.c b/jerry-core/ecma/builtin-objects/ecma-builtin-reflect.c index 3f921f0492..484dfa0639 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-reflect.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-reflect.c @@ -206,7 +206,7 @@ ecma_builtin_reflect_dispatch_routine (uint8_t builtin_routine_id, /**< built-in return ecma_raise_type_error (ECMA_ERR_MSG ("Reflect.construct expects an object as second argument")); } - ecma_collection_t *coll_p = ecma_op_create_list_from_array_like (arguments_list[1], false); + ecma_collection_t *coll_p = ecma_op_create_list_from_array_like (arguments_list[1], ECMA_FROM_ARRAY_LIKE_ANY); if (coll_p == NULL) { diff --git a/jerry-core/ecma/operations/ecma-conversion.c b/jerry-core/ecma/operations/ecma-conversion.c index a217d30f20..de9781968c 100644 --- a/jerry-core/ecma/operations/ecma-conversion.c +++ b/jerry-core/ecma/operations/ecma-conversion.c @@ -1083,8 +1083,7 @@ ecma_op_to_index (ecma_value_t value, /**< ecma value */ */ ecma_collection_t * ecma_op_create_list_from_array_like (ecma_value_t arr, /**< array value */ - bool prop_names_only) /**< true - accept only property names - false - otherwise */ + uint32_t options) /**< from array like and property name filter flags */ { /* 1. */ JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (arr)); @@ -1095,10 +1094,12 @@ ecma_op_create_list_from_array_like (ecma_value_t arr, /**< array value */ ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_argument_is_not_an_object)); return NULL; } + ecma_object_t *obj_p = ecma_get_object_from_value (arr); /* 4. 5. */ ecma_length_t len; + if (ECMA_IS_VALUE_ERROR (ecma_op_object_get_length (obj_p, &len))) { return NULL; @@ -1107,18 +1108,69 @@ ecma_op_create_list_from_array_like (ecma_value_t arr, /**< array value */ /* 6. */ ecma_collection_t *list_ptr = ecma_new_collection (); + if (!(options & ECMA_FROM_ARRAY_LIKE_ONLY_PROP_NAMES)) + { + /* 7. 8. */ + for (ecma_length_t idx = 0; idx < len; idx++) + { + ecma_value_t next = ecma_op_object_get_by_index (obj_p, idx); + + if (ECMA_IS_VALUE_ERROR (next)) + { + ecma_collection_free (list_ptr); + return NULL; + } + + ecma_collection_push_back (list_ptr, next); + } + + /* 9. */ + return list_ptr; + } + /* 7. 8. */ for (ecma_length_t idx = 0; idx < len; idx++) { ecma_value_t next = ecma_op_object_get_by_index (obj_p, idx); + if (ECMA_IS_VALUE_ERROR (next)) { ecma_collection_free (list_ptr); return NULL; } - if (prop_names_only - && !ecma_is_value_prop_name (next)) + if (ecma_is_value_string (next)) + { + jerry_property_filter_t non_symbol_mask = (JERRY_PROPERTY_FILTER_EXLCUDE_STRINGS + | JERRY_PROPERTY_FILTER_EXLCUDE_INTEGER_INDICES); + + if (options & non_symbol_mask) + { + if ((options & non_symbol_mask) == non_symbol_mask) + { + ecma_free_value (next); + continue; + } + + uint32_t index = ecma_string_get_array_index (ecma_get_string_from_value (next)); + + if ((index != ECMA_STRING_NOT_ARRAY_INDEX && (options & JERRY_PROPERTY_FILTER_EXLCUDE_INTEGER_INDICES)) + || (index == ECMA_STRING_NOT_ARRAY_INDEX && (options & JERRY_PROPERTY_FILTER_EXLCUDE_STRINGS))) + { + ecma_free_value (next); + continue; + } + } + } + else if (ecma_is_value_symbol (next)) + { + if (options & JERRY_PROPERTY_FILTER_EXLCUDE_SYMBOLS) + { + ecma_free_value (next); + continue; + } + } + else { ecma_free_value (next); ecma_collection_free (list_ptr); @@ -1132,6 +1184,7 @@ ecma_op_create_list_from_array_like (ecma_value_t arr, /**< array value */ /* 9. */ return list_ptr; } /* ecma_op_create_list_from_array_like */ + #endif /* JERRY_ESNEXT */ /** diff --git a/jerry-core/ecma/operations/ecma-conversion.h b/jerry-core/ecma/operations/ecma-conversion.h index 31c58eae12..114b5e1baf 100644 --- a/jerry-core/ecma/operations/ecma-conversion.h +++ b/jerry-core/ecma/operations/ecma-conversion.h @@ -47,6 +47,23 @@ typedef enum ECMA_TO_NUMERIC_ALLOW_BIGINT = (1 << 0), /**< allow BigInt values (ignored if BigInts are disabled) */ } ecma_to_numeric_options_t; +#if JERRY_ESNEXT + +/** + * Option bits for ecma_op_create_list_from_array_like. + */ +typedef enum +{ + ECMA_FROM_ARRAY_LIKE_ANY = 0, /**< copy all items of the array */ + ECMA_FROM_ARRAY_LIKE_ONLY_PROP_NAMES = (1 << 0), /**< only property names allowed */ + /* Further options: */ + /* JERRY_PROPERTY_FILTER_EXLCUDE_STRINGS */ + /* JERRY_PROPERTY_FILTER_EXLCUDE_SYMBOLS */ + /* JERRY_PROPERTY_FILTER_EXLCUDE_INTEGER_INDICES */ +} ecma_from_array_like_options_t; + +#endif /* JERRY_ESNEXT */ + bool ecma_op_require_object_coercible (ecma_value_t value); bool ecma_op_same_value (ecma_value_t x, ecma_value_t y); #if JERRY_BUILTIN_CONTAINER @@ -64,7 +81,7 @@ ecma_value_t ecma_op_to_integer (ecma_value_t value, ecma_number_t *number_p); ecma_value_t ecma_op_to_length (ecma_value_t value, ecma_length_t *length); #if JERRY_ESNEXT ecma_value_t ecma_op_to_index (ecma_value_t value, ecma_number_t *index); -ecma_collection_t *ecma_op_create_list_from_array_like (ecma_value_t arr, bool prop_names_only); +ecma_collection_t *ecma_op_create_list_from_array_like (ecma_value_t arr, uint32_t options); #endif /* JERRY_ESNEXT */ ecma_object_t *ecma_op_from_property_descriptor (const ecma_property_descriptor_t *src_prop_desc_p); diff --git a/jerry-core/ecma/operations/ecma-objects.c b/jerry-core/ecma/operations/ecma-objects.c index ed6d82e298..94e25cc596 100644 --- a/jerry-core/ecma/operations/ecma-objects.c +++ b/jerry-core/ecma/operations/ecma-objects.c @@ -2360,119 +2360,52 @@ ecma_object_list_lazy_property_names (ecma_object_t *obj_p, /**< object */ } /* ecma_object_list_lazy_property_names */ /** - * Helper method for sorting the given property names based on [[OwnPropertyKeys]] + * Helper routine for heapsort algorithm. */ static void -ecma_object_sort_property_names (ecma_collection_t *prop_names_p, /**< prop name collection */ - ecma_property_counter_t *prop_counter) /**< prop counter */ +ecma_op_object_heap_sort_shift_down (ecma_value_t *buffer_p, /**< array of items */ + uint32_t item_count, /**< number of items */ + uint32_t item_index) /**< index of updated item */ { - uint32_t lazy_string_prop_name_count = prop_counter->lazy_string_named_props; -#if JERRY_ESNEXT - uint32_t lazy_symbol_prop_name_count = prop_counter->lazy_symbol_named_props; -#endif /* JERRY_ESNEXT */ - - uint32_t string_name_pos = prop_counter->string_named_props; -#if JERRY_ESNEXT - uint32_t symbol_name_pos = prop_counter->symbol_named_props; -#endif /* JERRY_ESNEXT */ - - uint32_t all_prop_count = (prop_counter->array_index_named_props) + (string_name_pos); -#if JERRY_ESNEXT - all_prop_count += symbol_name_pos; -#endif /* JERRY_ESNEXT */ - - ecma_value_t *names_p = jmem_heap_alloc_block (all_prop_count * sizeof (ecma_value_t)); - - ecma_value_t *string_names_p = names_p + prop_counter->array_index_named_props; -#if JERRY_ESNEXT - ecma_value_t *symbol_names_p = string_names_p + string_name_pos; -#endif /* JERRY_ESNEXT */ - - uint32_t array_index_name_pos = 0; - uint32_t lazy_string_name_pos = 0; -#if JERRY_ESNEXT - uint32_t lazy_symbol_name_pos = 0; -#endif /* JERRY_ESNEXT */ - - for (uint32_t i = 0; i < prop_names_p->item_count; i++) + while (true) { - ecma_value_t prop_name = prop_names_p->buffer_p[i]; - ecma_string_t *name_p = ecma_get_prop_name_from_value (prop_name); - uint32_t index = ecma_string_get_array_index (name_p); + uint32_t highest_index = item_index; + uint32_t current_index = (item_index << 1) + 1; - /* sort array index named properties in ascending order */ - if (index != ECMA_STRING_NOT_ARRAY_INDEX) + if (current_index >= item_count) { - JERRY_ASSERT (array_index_name_pos < prop_counter->array_index_named_props); - - uint32_t insert_pos = 0; - while (insert_pos < array_index_name_pos - && index > ecma_string_get_array_index (ecma_get_string_from_value (names_p[insert_pos]))) - { - insert_pos++; - } - - if (insert_pos == array_index_name_pos) - { - names_p[array_index_name_pos++] = prop_name; - } - else - { - JERRY_ASSERT (insert_pos < array_index_name_pos); - JERRY_ASSERT (index <= ecma_string_get_array_index (ecma_get_string_from_value (names_p[insert_pos]))); + return; + } - uint32_t move_pos = array_index_name_pos++; + uint32_t value = ecma_string_get_array_index (ecma_get_string_from_value (buffer_p[highest_index])); + uint32_t left_value = ecma_string_get_array_index (ecma_get_string_from_value (buffer_p[current_index])); - while (move_pos > insert_pos) - { - names_p[move_pos] = names_p[move_pos - 1u]; + if (value < left_value) + { + highest_index = current_index; + value = left_value; + } - move_pos--; - } + current_index++; - names_p[insert_pos] = prop_name; - } - } -#if JERRY_ESNEXT - /* sort symbol named properites in creation order */ - else if (ecma_prop_name_is_symbol (name_p)) + if (current_index < item_count + && value < ecma_string_get_array_index (ecma_get_string_from_value (buffer_p[current_index]))) { - JERRY_ASSERT (symbol_name_pos > 0); - JERRY_ASSERT (symbol_name_pos <= prop_counter->symbol_named_props); - - if (i < lazy_symbol_prop_name_count) - { - symbol_names_p[lazy_symbol_name_pos++] = prop_name; - } - else - { - symbol_names_p[--symbol_name_pos] = prop_name; - } + highest_index = current_index; } -#endif /* JERRY_ESNEXT */ - /* sort string named properties in creation order */ - else - { - JERRY_ASSERT (string_name_pos > 0); - JERRY_ASSERT (string_name_pos <= prop_counter->string_named_props); - if (i < lazy_string_prop_name_count) - { - string_names_p[lazy_string_name_pos++] = prop_name; - } - else - { - string_names_p[--string_name_pos] = prop_name; - } + if (highest_index == item_index) + { + return; } - } - /* Free the unsorted buffer and copy the sorted one in its place */ - jmem_heap_free_block (prop_names_p->buffer_p, ECMA_COLLECTION_ALLOCATED_SIZE (prop_names_p->capacity)); - prop_names_p->buffer_p = names_p; - prop_names_p->item_count = all_prop_count; - prop_names_p->capacity = all_prop_count; -} /* ecma_object_sort_property_names */ + ecma_value_t tmp = buffer_p[highest_index]; + buffer_p[highest_index] = buffer_p[item_index]; + buffer_p[item_index] = tmp; + + item_index = highest_index; + } +} /* ecma_op_object_heap_sort_shift_down */ /** * Object's [[OwnPropertyKeys]] internal method @@ -2491,12 +2424,12 @@ ecma_object_sort_property_names (ecma_collection_t *prop_names_p, /**< prop name */ ecma_collection_t * ecma_op_object_own_property_keys (ecma_object_t *obj_p, /**< object */ - jerry_property_filter_t filter) /**< property name filter options */ + jerry_property_filter_t filter) /**< name filters */ { #if JERRY_BUILTIN_PROXY if (ECMA_OBJECT_IS_PROXY (obj_p)) { - return ecma_proxy_object_own_property_keys (obj_p); + return ecma_proxy_object_own_property_keys (obj_p, filter); } #endif /* JERRY_BUILTIN_PROXY */ @@ -2506,13 +2439,10 @@ ecma_op_object_own_property_keys (ecma_object_t *obj_p, /**< object */ } ecma_collection_t *prop_names_p = ecma_new_collection (); - ecma_property_counter_t prop_counter = {0, 0, 0, 0, 0}; + ecma_property_counter_t prop_counter = {0, 0, 0}; ecma_object_list_lazy_property_names (obj_p, prop_names_p, &prop_counter, filter); - prop_counter.lazy_string_named_props = prop_names_p->item_count - prop_counter.symbol_named_props; - prop_counter.lazy_symbol_named_props = prop_counter.symbol_named_props; - jmem_cpointer_t prop_iter_cp = obj_p->u1.property_list_cp; #if JERRY_PROPERTY_HASHMAP @@ -2527,6 +2457,118 @@ ecma_op_object_own_property_keys (ecma_object_t *obj_p, /**< object */ } #endif /* JERRY_PROPERTY_HASHMAP */ + jmem_cpointer_t counter_prop_iter_cp = prop_iter_cp; + + uint32_t array_index_named_props = 0; + uint32_t string_named_props = 0; +#if JERRY_ESNEXT + uint32_t symbol_named_props = 0; +#endif /* JERRY_ESNEXT */ + + while (counter_prop_iter_cp != JMEM_CP_NULL) + { + ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, counter_prop_iter_cp); + JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p)); + + for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++) + { + ecma_property_t *property_p = prop_iter_p->types + i; + + if (!ECMA_PROPERTY_IS_RAW (*property_p) + || (*property_p & ECMA_PROPERTY_FLAG_BUILT_IN)) + { + continue; + } + + ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p; + + if (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_DIRECT_STRING_MAGIC + && prop_pair_p->names_cp[i] >= LIT_NON_INTERNAL_MAGIC_STRING__COUNT + && prop_pair_p->names_cp[i] < LIT_MAGIC_STRING__COUNT) + { + continue; + } + + ecma_string_t *name_p = ecma_string_from_property_name (*property_p, + prop_pair_p->names_cp[i]); + + if (ecma_string_get_array_index (name_p) != ECMA_STRING_NOT_ARRAY_INDEX) + { + array_index_named_props++; + } +#if JERRY_ESNEXT + else if (ecma_prop_name_is_symbol (name_p)) + { + symbol_named_props++; + } +#endif /* JERRY_ESNEXT */ + else + { + string_named_props++; + } + + ecma_deref_ecma_string (name_p); + } + + counter_prop_iter_cp = prop_iter_p->next_property_cp; + } + + if (filter & JERRY_PROPERTY_FILTER_EXLCUDE_INTEGER_INDICES) + { + JERRY_ASSERT (prop_counter.array_index_named_props == 0); + array_index_named_props = 0; + } + + if (filter & JERRY_PROPERTY_FILTER_EXLCUDE_STRINGS) + { + JERRY_ASSERT (prop_counter.string_named_props == 0); + string_named_props = 0; + } + +#if JERRY_ESNEXT + if (filter & JERRY_PROPERTY_FILTER_EXLCUDE_SYMBOLS) + { + JERRY_ASSERT (prop_counter.symbol_named_props == 0); + symbol_named_props = 0; + } + + uint32_t total = array_index_named_props + string_named_props + symbol_named_props; +#else /* !JERRY_ESNEXT */ + uint32_t total = array_index_named_props + string_named_props; +#endif /* JERRY_ESNEXT */ + + if (total == 0) + { + return prop_names_p; + } + + ecma_collection_reserve (prop_names_p, total); + prop_names_p->item_count += total; + + ecma_value_t *buffer_p = prop_names_p->buffer_p; + ecma_value_t *array_index_current_p = buffer_p + array_index_named_props + prop_counter.array_index_named_props; + ecma_value_t *string_current_p = array_index_current_p + string_named_props + prop_counter.string_named_props; + +#if JERRY_ESNEXT + ecma_value_t *symbol_current_p = string_current_p + symbol_named_props + prop_counter.symbol_named_props; + + if (prop_counter.symbol_named_props > 0 + && (array_index_named_props + string_named_props) > 0) + { + memmove ((void *) string_current_p, + (void *) (buffer_p + prop_counter.array_index_named_props + prop_counter.string_named_props), + prop_counter.symbol_named_props * sizeof (ecma_value_t)); + } +#endif /* JERRY_ESNEXT */ + + if (prop_counter.string_named_props > 0 + && array_index_named_props > 0) + { + memmove ((void *) array_index_current_p, + (void *) (buffer_p + prop_counter.array_index_named_props), + prop_counter.string_named_props * sizeof (ecma_value_t)); + } + while (prop_iter_cp != JMEM_CP_NULL) { ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp); @@ -2536,46 +2578,103 @@ ecma_op_object_own_property_keys (ecma_object_t *obj_p, /**< object */ { ecma_property_t *property_p = prop_iter_p->types + i; - if (ECMA_PROPERTY_IS_RAW (*property_p) - && !(*property_p & ECMA_PROPERTY_FLAG_BUILT_IN)) + if (!ECMA_PROPERTY_IS_RAW (*property_p) + || (*property_p & ECMA_PROPERTY_FLAG_BUILT_IN)) { - ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p; + continue; + } - if (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_DIRECT_STRING_MAGIC - && prop_pair_p->names_cp[i] >= LIT_NON_INTERNAL_MAGIC_STRING__COUNT - && prop_pair_p->names_cp[i] < LIT_MAGIC_STRING__COUNT) - { - continue; - } + ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p; + + if (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_DIRECT_STRING_MAGIC + && prop_pair_p->names_cp[i] >= LIT_NON_INTERNAL_MAGIC_STRING__COUNT + && prop_pair_p->names_cp[i] < LIT_MAGIC_STRING__COUNT) + { + continue; + } - ecma_string_t *name_p = ecma_string_from_property_name (*property_p, - prop_pair_p->names_cp[i]); + ecma_string_t *name_p = ecma_string_from_property_name (*property_p, + prop_pair_p->names_cp[i]); - if (ecma_string_get_array_index (name_p) != ECMA_STRING_NOT_ARRAY_INDEX) + if (ecma_string_get_array_index (name_p) != ECMA_STRING_NOT_ARRAY_INDEX) + { + if (!(filter & JERRY_PROPERTY_FILTER_EXLCUDE_INTEGER_INDICES)) { - prop_counter.array_index_named_props++; + *(--array_index_current_p) = ecma_make_string_value (name_p); + continue; } + } #if JERRY_ESNEXT - else if (ecma_prop_name_is_symbol (name_p)) + else if (ecma_prop_name_is_symbol (name_p)) + { + if (!(filter & JERRY_PROPERTY_FILTER_EXLCUDE_SYMBOLS)) { - prop_counter.symbol_named_props++; + *(--symbol_current_p) = ecma_make_symbol_value (name_p); + continue; } + } #endif /* JERRY_ESNEXT */ - else + else + { + if (!(filter & JERRY_PROPERTY_FILTER_EXLCUDE_STRINGS)) { - prop_counter.string_named_props++; + *(--string_current_p) = ecma_make_string_value (name_p); + continue; } - - ecma_collection_push_back (prop_names_p, ecma_make_prop_name_value (name_p)); } + + ecma_deref_ecma_string (name_p); } prop_iter_cp = prop_iter_p->next_property_cp; } - if (prop_names_p->item_count != 0) + if (array_index_named_props > 1 + || (array_index_named_props == 1 && prop_counter.array_index_named_props > 0)) { - ecma_object_sort_property_names (prop_names_p, &prop_counter); + uint32_t prev_value = 0; + ecma_value_t *array_index_p = buffer_p + prop_counter.array_index_named_props; + ecma_value_t *array_index_end_p = array_index_p + array_index_named_props; + + if (prop_counter.array_index_named_props > 0) + { + prev_value = ecma_string_get_array_index (ecma_get_string_from_value (array_index_p[-1])); + } + + do + { + uint32_t value = ecma_string_get_array_index (ecma_get_string_from_value (*array_index_p++)); + + if (value < prev_value) + { +printf("Reorder needed\n"); + uint32_t array_props = prop_counter.array_index_named_props + array_index_named_props; + uint32_t i = (array_props >> 1) - 1; + + do + { + ecma_op_object_heap_sort_shift_down (buffer_p, array_props, i); + } + while (i-- > 0); + + i = array_props - 1; + + do + { + ecma_value_t tmp = buffer_p[i]; + buffer_p[i] = buffer_p[0]; + buffer_p[0] = tmp; + + ecma_op_object_heap_sort_shift_down (buffer_p, i, 0); + } + while (--i > 0); + + break; + } + + prev_value = value; + } + while (array_index_p < array_index_end_p); } return prop_names_p; @@ -2617,13 +2716,6 @@ ecma_op_object_enumerate (ecma_object_t *obj_p) /**< object */ ecma_value_t prop_name = keys->buffer_p[i]; ecma_string_t *name_p = ecma_get_prop_name_from_value (prop_name); -#if JERRY_ESNEXT - if (ecma_prop_name_is_symbol (name_p)) - { - continue; - } -#endif /* JERRY_ESNEXT */ - ecma_property_descriptor_t prop_desc; ecma_value_t get_desc = ecma_op_object_get_own_property_descriptor (obj_p, name_p, &prop_desc); diff --git a/jerry-core/ecma/operations/ecma-proxy-object.c b/jerry-core/ecma/operations/ecma-proxy-object.c index 4c22aae12d..f21c877976 100644 --- a/jerry-core/ecma/operations/ecma-proxy-object.c +++ b/jerry-core/ecma/operations/ecma-proxy-object.c @@ -1604,7 +1604,8 @@ ecma_proxy_check_invariants_for_own_prop_keys (ecma_collection_t *trap_result, * pointer to a newly allocated list of property names - otherwise */ ecma_collection_t * -ecma_proxy_object_own_property_keys (ecma_object_t *obj_p) /**< proxy object */ +ecma_proxy_object_own_property_keys (ecma_object_t *obj_p, /**< proxy object */ + jerry_property_filter_t filter) /**< name filters */ { JERRY_ASSERT (ECMA_OBJECT_IS_PROXY (obj_p)); ECMA_CHECK_STACK_USAGE_RETURN (NULL); @@ -1628,7 +1629,7 @@ ecma_proxy_object_own_property_keys (ecma_object_t *obj_p) /**< proxy object */ /* 6. */ if (ecma_is_value_undefined (trap)) { - ecma_collection_t *result = ecma_op_object_own_property_keys (target_obj_p, JERRY_PROPERTY_FILTER_ALL); + ecma_collection_t *result = ecma_op_object_own_property_keys (target_obj_p, filter); JERRY_BLOCK_TAIL_CALL_OPTIMIZATION (); return result; } @@ -1646,7 +1647,8 @@ ecma_proxy_object_own_property_keys (ecma_object_t *obj_p) /**< proxy object */ } /* 8. */ - ecma_collection_t *trap_result = ecma_op_create_list_from_array_like (trap_result_array, true); + uint32_t options = ECMA_FROM_ARRAY_LIKE_ONLY_PROP_NAMES; + ecma_collection_t *trap_result = ecma_op_create_list_from_array_like (trap_result_array, options | filter); ecma_free_value (trap_result_array); @@ -1674,7 +1676,7 @@ ecma_proxy_object_own_property_keys (ecma_object_t *obj_p) /**< proxy object */ } /* 11. */ - ecma_collection_t *target_keys = ecma_op_object_own_property_keys (target_obj_p, JERRY_PROPERTY_FILTER_ALL); + ecma_collection_t *target_keys = ecma_op_object_own_property_keys (target_obj_p, filter); if (target_keys == NULL) { diff --git a/jerry-core/ecma/operations/ecma-proxy-object.h b/jerry-core/ecma/operations/ecma-proxy-object.h index 1fa235226d..2332c43f46 100644 --- a/jerry-core/ecma/operations/ecma-proxy-object.h +++ b/jerry-core/ecma/operations/ecma-proxy-object.h @@ -92,7 +92,7 @@ ecma_proxy_object_delete_property (ecma_object_t *obj_p, bool is_strict); ecma_collection_t * -ecma_proxy_object_own_property_keys (ecma_object_t *obj_p); +ecma_proxy_object_own_property_keys (ecma_object_t *obj_p, jerry_property_filter_t filter); ecma_value_t ecma_proxy_object_call (ecma_object_t *obj_p,