diff --git a/jerry-core/ecma/base/ecma-globals.h b/jerry-core/ecma/base/ecma-globals.h index 72247db10..22ebd3276 100644 --- a/jerry-core/ecma/base/ecma-globals.h +++ b/jerry-core/ecma/base/ecma-globals.h @@ -400,6 +400,7 @@ typedef enum ECMA_PROPERTY_FLAG_WRITABLE = (1u << 2), /**< property is writable */ ECMA_PROPERTY_FLAG_SINGLE_EXTERNAL = (1u << 2), /**< only one external pointer is assigned to this object */ ECMA_PROPERTY_FLAG_DELETED = (1u << 3), /**< property is deleted */ + ECMA_PROPERTY_FLAG_BUILT_IN = (1u << 3), /**< property is defined by the ECMAScript standard */ ECMA_FAST_ARRAY_FLAG = (1u << 3), /**< array is fast array */ ECMA_PROPERTY_FLAG_LCACHED = (1u << 4), /**< property is lcached */ #if JERRY_ESNEXT @@ -427,12 +428,48 @@ typedef enum #define ECMA_PROPERTY_CONFIGURABLE_WRITABLE \ (ECMA_PROPERTY_FLAG_CONFIGURABLE | ECMA_PROPERTY_FLAG_WRITABLE) +/** + * Property flag built-in. + */ +#define ECMA_PROPERTY_BUILT_IN_FIXED \ + (ECMA_PROPERTY_FLAG_BUILT_IN) + /** * Property flags enumerable, writable. */ #define ECMA_PROPERTY_ENUMERABLE_WRITABLE \ (ECMA_PROPERTY_FLAG_ENUMERABLE | ECMA_PROPERTY_FLAG_WRITABLE) +/** + * Property flags built-in, configurable. + */ +#define ECMA_PROPERTY_BUILT_IN_CONFIGURABLE \ + (ECMA_PROPERTY_FLAG_BUILT_IN | ECMA_PROPERTY_FLAG_CONFIGURABLE) + +/** + * Property flags built-in, configurable, enumerable. + */ +#define ECMA_PROPERTY_BUILT_IN_CONFIGURABLE_ENUMERABLE \ + (ECMA_PROPERTY_FLAG_BUILT_IN | ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE) + +/** + * Property flags built-in, configurable, writable. + */ +#define ECMA_PROPERTY_BUILT_IN_CONFIGURABLE_WRITABLE \ + (ECMA_PROPERTY_FLAG_BUILT_IN | ECMA_PROPERTY_CONFIGURABLE_WRITABLE) + +/** + * Property flags built-in, writable. + */ +#define ECMA_PROPERTY_BUILT_IN_WRITABLE \ + (ECMA_PROPERTY_FLAG_BUILT_IN | ECMA_PROPERTY_FLAG_WRITABLE) + +/** + * Property flags built-in, configurable, enumerable, writable. + */ +#define ECMA_PROPERTY_BUILT_IN_CONFIGURABLE_ENUMERABLE_WRITABLE \ + (ECMA_PROPERTY_FLAG_BUILT_IN | ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE) + /** * No attributes can be changed for this property. */ diff --git a/jerry-core/ecma/base/ecma-helpers.c b/jerry-core/ecma/base/ecma-helpers.c index 70c759f24..151aaf4ef 100644 --- a/jerry-core/ecma/base/ecma-helpers.c +++ b/jerry-core/ecma/base/ecma-helpers.c @@ -582,7 +582,7 @@ ecma_create_named_data_property (ecma_object_t *object_p, /**< object */ JERRY_ASSERT (ecma_is_lexical_environment (object_p) || !ecma_op_object_is_fast_array (object_p)); JERRY_ASSERT (ecma_find_named_property (object_p, name_p) == NULL); - JERRY_ASSERT ((prop_attributes & ~ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE) == 0); + JERRY_ASSERT ((prop_attributes & ~ECMA_PROPERTY_BUILT_IN_CONFIGURABLE_ENUMERABLE_WRITABLE) == 0); uint8_t type_and_flags = ECMA_PROPERTY_FLAG_DATA | prop_attributes; @@ -610,7 +610,7 @@ ecma_create_named_accessor_property (ecma_object_t *object_p, /**< object */ JERRY_ASSERT (ecma_is_lexical_environment (object_p) || !ecma_op_object_is_fast_array (object_p)); JERRY_ASSERT (ecma_find_named_property (object_p, name_p) == NULL); - JERRY_ASSERT ((prop_attributes & ~ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE) == 0); + JERRY_ASSERT ((prop_attributes & ~ECMA_PROPERTY_BUILT_IN_CONFIGURABLE_ENUMERABLE) == 0); uint8_t type_and_flags = prop_attributes; diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-internal-routines-template.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtin-internal-routines-template.inc.h index f49ff62ec..28bea6fc8 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-internal-routines-template.inc.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-internal-routines-template.inc.h @@ -92,35 +92,35 @@ const ecma_builtin_property_descriptor_t PROPERTY_DESCRIPTOR_LIST_NAME[] = { \ name, \ ECMA_BUILTIN_PROPERTY_ROUTINE, \ - ECMA_PROPERTY_CONFIGURABLE_WRITABLE, \ + ECMA_PROPERTY_BUILT_IN_CONFIGURABLE_WRITABLE, \ ECMA_ROUTINE_VALUE (ECMA_ROUTINE_ ## name ## c_function_name, length_prop_value) \ }, #define ROUTINE_CONFIGURABLE_ONLY(name, c_function_name, args_number, length_prop_value) \ { \ name, \ ECMA_BUILTIN_PROPERTY_ROUTINE, \ - ECMA_PROPERTY_FLAG_CONFIGURABLE, \ + ECMA_PROPERTY_BUILT_IN_CONFIGURABLE, \ ECMA_ROUTINE_VALUE (ECMA_ROUTINE_ ## name ## c_function_name, length_prop_value) \ }, -#define ROUTINE_WITH_FLAGS(name, c_function_name, args_number, length_prop_value, flags) \ +#define ROUTINE_WITH_FLAGS(name, c_function_name, args_number, length_prop_value, prop_attributes) \ { \ name, \ ECMA_BUILTIN_PROPERTY_ROUTINE, \ - flags, \ + (prop_attributes) | ECMA_PROPERTY_FLAG_BUILT_IN, \ ECMA_ROUTINE_VALUE (ECMA_ROUTINE_ ## name ## c_function_name, length_prop_value) \ }, #define ACCESSOR_READ_ONLY(name, c_getter_func_name, prop_attributes) \ { \ name, \ ECMA_BUILTIN_PROPERTY_ACCESSOR_READ_ONLY, \ - prop_attributes, \ + (prop_attributes) | ECMA_PROPERTY_FLAG_BUILT_IN, \ ECMA_ACCESSOR_ ## name ## c_getter_func_name \ }, #define ACCESSOR_READ_WRITE(name, c_getter_func_name, c_setter_func_name, prop_attributes) \ { \ name, \ ECMA_BUILTIN_PROPERTY_ACCESSOR_READ_WRITE, \ - prop_attributes, \ + (prop_attributes) | ECMA_PROPERTY_FLAG_BUILT_IN, \ ECMA_ACCESSOR_READ_WRITE (ECMA_ACCESSOR_ ## name ## c_getter_func_name, \ ECMA_ACCESSOR_ ## name ## c_setter_func_name) \ }, @@ -129,35 +129,35 @@ const ecma_builtin_property_descriptor_t PROPERTY_DESCRIPTOR_LIST_NAME[] = { \ name, \ ECMA_BUILTIN_PROPERTY_ROUTINE, \ - ECMA_PROPERTY_CONFIGURABLE_WRITABLE, \ + ECMA_PROPERTY_BUILT_IN_CONFIGURABLE_WRITABLE, \ ECMA_ROUTINE_VALUE (c_function_name, length_prop_value) \ }, #define ROUTINE_CONFIGURABLE_ONLY(name, c_function_name, args_number, length_prop_value) \ { \ name, \ ECMA_BUILTIN_PROPERTY_ROUTINE, \ - ECMA_PROPERTY_FLAG_CONFIGURABLE, \ + ECMA_PROPERTY_BUILT_IN_CONFIGURABLE, \ ECMA_ROUTINE_VALUE (c_function_name, length_prop_value) \ }, -#define ROUTINE_WITH_FLAGS(name, c_function_name, args_number, length_prop_value, flags) \ +#define ROUTINE_WITH_FLAGS(name, c_function_name, args_number, length_prop_value, prop_attributes) \ { \ name, \ ECMA_BUILTIN_PROPERTY_ROUTINE, \ - flags, \ + (prop_attributes) | ECMA_PROPERTY_FLAG_BUILT_IN, \ ECMA_ROUTINE_VALUE (c_function_name, length_prop_value) \ }, #define ACCESSOR_READ_ONLY(name, c_getter_func_name, prop_attributes) \ { \ name, \ ECMA_BUILTIN_PROPERTY_ACCESSOR_READ_ONLY, \ - prop_attributes, \ + (prop_attributes) | ECMA_PROPERTY_FLAG_BUILT_IN, \ c_getter_func_name \ }, #define ACCESSOR_READ_WRITE(name, c_getter_func_name, c_setter_func_name, prop_attributes) \ { \ name, \ ECMA_BUILTIN_PROPERTY_ACCESSOR_READ_WRITE, \ - prop_attributes, \ + (prop_attributes) | ECMA_PROPERTY_FLAG_BUILT_IN, \ ECMA_ACCESSOR_READ_WRITE (c_getter_func_name, c_setter_func_name) \ }, #endif /* !BUILTIN_CUSTOM_DISPATCH */ @@ -165,28 +165,28 @@ const ecma_builtin_property_descriptor_t PROPERTY_DESCRIPTOR_LIST_NAME[] = { \ name, \ ECMA_BUILTIN_PROPERTY_OBJECT, \ - prop_attributes, \ + (prop_attributes) | ECMA_PROPERTY_FLAG_BUILT_IN, \ obj_builtin_id \ }, #define SIMPLE_VALUE(name, simple_value, prop_attributes) \ { \ name, \ ECMA_BUILTIN_PROPERTY_SIMPLE, \ - prop_attributes, \ + (prop_attributes) | ECMA_PROPERTY_FLAG_BUILT_IN, \ simple_value \ }, #define NUMBER_VALUE(name, number_value, prop_attributes) \ { \ name, \ ECMA_BUILTIN_PROPERTY_NUMBER, \ - prop_attributes, \ + (prop_attributes) | ECMA_PROPERTY_FLAG_BUILT_IN, \ number_value \ }, #define STRING_VALUE(name, magic_string_id, prop_attributes) \ { \ name, \ ECMA_BUILTIN_PROPERTY_STRING, \ - prop_attributes, \ + (prop_attributes) | ECMA_PROPERTY_FLAG_BUILT_IN, \ magic_string_id \ }, #if JERRY_ESNEXT @@ -194,21 +194,21 @@ const ecma_builtin_property_descriptor_t PROPERTY_DESCRIPTOR_LIST_NAME[] = { \ name, \ ECMA_BUILTIN_PROPERTY_SYMBOL, \ - ECMA_PROPERTY_FIXED, \ + ECMA_PROPERTY_BUILT_IN_FIXED, \ symbol \ }, #define INTRINSIC_PROPERTY(name, magic_string_id, prop_attributes) \ { \ name, \ ECMA_BUILTIN_PROPERTY_INTRINSIC_PROPERTY, \ - prop_attributes, \ + (prop_attributes) | ECMA_PROPERTY_FLAG_BUILT_IN, \ magic_string_id \ }, #define ACCESSOR_BUILTIN_FUNCTION(name, getter_builtin_id, setter_builtin_id, prop_attributes) \ { \ name, \ ECMA_BUILTIN_PROPERTY_ACCESSOR_BUILTIN_FUNCTION, \ - prop_attributes, \ + (prop_attributes) | ECMA_PROPERTY_FLAG_BUILT_IN, \ ECMA_ACCESSOR_READ_WRITE (getter_builtin_id, setter_builtin_id) \ }, #endif /* JERRY_ESNEXT */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtins.c b/jerry-core/ecma/builtin-objects/ecma-builtins.c index 9724405a3..2210dca93 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtins.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtins.c @@ -795,12 +795,10 @@ ecma_builtin_native_handler_try_to_instantiate_property (ecma_object_t *object_p { ecma_property_value_t *value_p = ecma_create_named_data_property (object_p, property_name_p, - ECMA_PROPERTY_FLAG_CONFIGURABLE, + ECMA_PROPERTY_BUILT_IN_CONFIGURABLE, &prop_p); value_p->value = ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY); - - ext_obj_p->u.built_in.u2.routine_flags |= ECMA_NATIVE_HANDLER_FLAGS_NAME_INITIALIZED; } } else if (ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_LENGTH)) @@ -809,13 +807,11 @@ ecma_builtin_native_handler_try_to_instantiate_property (ecma_object_t *object_p { ecma_property_value_t *value_p = ecma_create_named_data_property (object_p, property_name_p, - ECMA_PROPERTY_FLAG_CONFIGURABLE, + ECMA_PROPERTY_BUILT_IN_CONFIGURABLE, &prop_p); const uint8_t length = ecma_builtin_handler_get_length (ext_obj_p->u.built_in.routine_id); value_p->value = ecma_make_integer_value (length); - - ext_obj_p->u.built_in.u2.routine_flags |= ECMA_NATIVE_HANDLER_FLAGS_LENGTH_INITIALIZED; } } @@ -835,22 +831,22 @@ ecma_builtin_native_handler_try_to_instantiate_property (ecma_object_t *object_p */ ecma_property_t * ecma_builtin_routine_try_to_instantiate_property (ecma_object_t *object_p, /**< object */ - ecma_string_t *string_p) /**< property's name */ + ecma_string_t *property_name_p) /**< property name */ { JERRY_ASSERT (ecma_get_object_is_builtin (object_p)); - JERRY_ASSERT (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_NATIVE_FUNCTION); - JERRY_ASSERT (ecma_builtin_function_is_routine (object_p)); + JERRY_ASSERT (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_NATIVE_FUNCTION + && ecma_builtin_function_is_routine (object_p)); ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p; #if JERRY_ESNEXT if (JERRY_UNLIKELY (ext_func_p->u.built_in.id == ECMA_BUILTIN_ID_HANDLER)) { - return ecma_builtin_native_handler_try_to_instantiate_property (object_p, string_p); + return ecma_builtin_native_handler_try_to_instantiate_property (object_p, property_name_p); } #endif /* !JERRY_ESNEXT */ - if (ecma_string_is_length (string_p)) + if (ecma_string_is_length (property_name_p)) { /* * Lazy instantiation of 'length' property @@ -868,17 +864,16 @@ ecma_builtin_routine_try_to_instantiate_property (ecma_object_t *object_p, /**< /* We mark that the property was lazily instantiated, * as it is configurable and so can be deleted (ECMA-262 v6, 19.2.4.1) */ - *bitset_p |= ECMA_BUILTIN_ROUTINE_LENGTH_INITIALIZED; ecma_property_value_t *len_prop_value_p = ecma_create_named_data_property (object_p, - string_p, - ECMA_PROPERTY_FLAG_CONFIGURABLE, + property_name_p, + ECMA_PROPERTY_BUILT_IN_CONFIGURABLE, &len_prop_p); #else /* !JERRY_ESNEXT */ /* We don't need to mark that the property was already lazy instantiated, * as it is non-configurable and so can't be deleted (ECMA-262 v5, 13.2.5) */ ecma_property_value_t *len_prop_value_p = ecma_create_named_data_property (object_p, - string_p, - ECMA_PROPERTY_FIXED, + property_name_p, + ECMA_PROPERTY_BUILT_IN_FIXED, &len_prop_p); #endif /* JERRY_ESNEXT */ @@ -908,7 +903,7 @@ ecma_builtin_routine_try_to_instantiate_property (ecma_object_t *object_p, /**< /* * Lazy instantiation of 'name' property */ - if (ecma_compare_ecma_string_to_magic_id (string_p, LIT_MAGIC_STRING_NAME)) + if (ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_NAME)) { uint8_t *bitset_p = &ext_func_p->u.built_in.u2.routine_flags; @@ -919,11 +914,10 @@ ecma_builtin_routine_try_to_instantiate_property (ecma_object_t *object_p, /**< } /* We mark that the property was lazily instantiated */ - *bitset_p |= ECMA_BUILTIN_ROUTINE_NAME_INITIALIZED; ecma_property_t *name_prop_p; ecma_property_value_t *name_prop_value_p = ecma_create_named_data_property (object_p, - string_p, - ECMA_PROPERTY_FLAG_CONFIGURABLE, + property_name_p, + ECMA_PROPERTY_BUILT_IN_CONFIGURABLE, &name_prop_p); uint8_t routine_index = ext_func_p->u.built_in.u.routine_index; @@ -995,18 +989,18 @@ ecma_builtin_routine_try_to_instantiate_property (ecma_object_t *object_p, /**< */ ecma_property_t * ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object */ - ecma_string_t *string_p) /**< property's name */ + ecma_string_t *property_name_p) /**< property's name */ { JERRY_ASSERT (ecma_get_object_is_builtin (object_p)); - lit_magic_string_id_t magic_string_id = ecma_get_string_magic (string_p); + lit_magic_string_id_t magic_string_id = ecma_get_string_magic (property_name_p); #if JERRY_ESNEXT - if (JERRY_UNLIKELY (ecma_prop_name_is_symbol (string_p))) + if (JERRY_UNLIKELY (ecma_prop_name_is_symbol (property_name_p))) { - if (string_p->u.hash & ECMA_GLOBAL_SYMBOL_FLAG) + if (property_name_p->u.hash & ECMA_GLOBAL_SYMBOL_FLAG) { - magic_string_id = (string_p->u.hash >> ECMA_GLOBAL_SYMBOL_SHIFT); + magic_string_id = (property_name_p->u.hash >> ECMA_GLOBAL_SYMBOL_SHIFT); } } #endif /* JERRY_ESNEXT */ @@ -1034,7 +1028,6 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object * JERRY_ASSERT (builtin_id < ECMA_BUILTIN_ID__COUNT); const ecma_builtin_property_descriptor_t *property_list_p = ecma_builtin_property_list_references[builtin_id]; - const ecma_builtin_property_descriptor_t *curr_property_p = property_list_p; while (curr_property_p->magic_string_id != magic_string_id) @@ -1064,8 +1057,6 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object * return NULL; } - *bitset_p |= bit_for_index; - ecma_value_t value = ECMA_VALUE_EMPTY; bool is_accessor = false; ecma_object_t *getter_p = NULL; @@ -1217,10 +1208,12 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object * ecma_property_t *prop_p; + JERRY_ASSERT (curr_property_p->attributes & ECMA_PROPERTY_FLAG_BUILT_IN); + if (is_accessor) { ecma_create_named_accessor_property (object_p, - string_p, + property_name_p, getter_p, setter_p, curr_property_p->attributes, @@ -1238,7 +1231,7 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object * else { ecma_property_value_t *prop_value_p = ecma_create_named_data_property (object_p, - string_p, + property_name_p, curr_property_p->attributes, &prop_p); prop_value_p->value = value; @@ -1252,6 +1245,133 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object * #if JERRY_ESNEXT +/** + * Delete configurable properties of native handlers. + */ +static void +ecma_builtin_native_handler_delete_built_in_property (ecma_object_t *object_p, /**< object */ + ecma_string_t *property_name_p) /**< property name */ +{ + ecma_extended_object_t *extended_obj_p = (ecma_extended_object_t *) object_p; + + if (ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_LENGTH)) + { + JERRY_ASSERT (!(extended_obj_p->u.built_in.u2.routine_flags & ECMA_NATIVE_HANDLER_FLAGS_LENGTH_INITIALIZED)); + + extended_obj_p->u.built_in.u2.routine_flags |= ECMA_NATIVE_HANDLER_FLAGS_LENGTH_INITIALIZED; + return; + } + + JERRY_ASSERT (ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_NAME)); + JERRY_ASSERT (!(extended_obj_p->u.built_in.u2.routine_flags & ECMA_NATIVE_HANDLER_FLAGS_NAME_INITIALIZED)); + + extended_obj_p->u.built_in.u2.routine_flags |= ECMA_NATIVE_HANDLER_FLAGS_NAME_INITIALIZED; +} /* ecma_builtin_native_handler_delete_built_in_property */ + +/** + * Delete configurable properties of built-in routines. + */ +void +ecma_builtin_routine_delete_built_in_property (ecma_object_t *object_p, /**< object */ + ecma_string_t *property_name_p) /**< property name */ +{ + JERRY_ASSERT (ecma_get_object_is_builtin (object_p)); + JERRY_ASSERT (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_NATIVE_FUNCTION + && ecma_builtin_function_is_routine (object_p)); + + ecma_extended_object_t *extended_obj_p = (ecma_extended_object_t *) object_p; + + if (JERRY_UNLIKELY (extended_obj_p->u.built_in.id == ECMA_BUILTIN_ID_HANDLER)) + { + ecma_builtin_native_handler_delete_built_in_property (object_p, property_name_p); + return; + } + + uint8_t *bitset_p = &extended_obj_p->u.built_in.u2.routine_flags; + + if (ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_LENGTH)) + { + JERRY_ASSERT (!(*bitset_p & ECMA_BUILTIN_ROUTINE_LENGTH_INITIALIZED)); + + *bitset_p |= ECMA_BUILTIN_ROUTINE_LENGTH_INITIALIZED; + return; + } + + JERRY_ASSERT (ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_NAME)); + JERRY_ASSERT (!(*bitset_p & ECMA_BUILTIN_ROUTINE_NAME_INITIALIZED)); + + *bitset_p |= ECMA_BUILTIN_ROUTINE_NAME_INITIALIZED; +} /* ecma_builtin_routine_delete_built_in_property */ + +#endif /* JERRY_ESNEXT */ + +/** + * Delete configurable properties of built-ins. + */ +void +ecma_builtin_delete_built_in_property (ecma_object_t *object_p, /**< object */ + ecma_string_t *property_name_p) /**< property name */ +{ + JERRY_ASSERT (ecma_get_object_is_builtin (object_p)); + JERRY_ASSERT (ecma_get_object_type (object_p) != ECMA_OBJECT_TYPE_NATIVE_FUNCTION + || !ecma_builtin_function_is_routine (object_p)); + + lit_magic_string_id_t magic_string_id = ecma_get_string_magic (property_name_p); + +#if JERRY_ESNEXT + if (JERRY_UNLIKELY (ecma_prop_name_is_symbol (property_name_p))) + { + if (property_name_p->u.hash & ECMA_GLOBAL_SYMBOL_FLAG) + { + magic_string_id = (property_name_p->u.hash >> ECMA_GLOBAL_SYMBOL_SHIFT); + } + } +#endif /* JERRY_ESNEXT */ + + ecma_built_in_props_t *built_in_props_p; + ecma_object_type_t object_type = ecma_get_object_type (object_p); + JERRY_ASSERT (object_type != ECMA_OBJECT_TYPE_FUNCTION || !ecma_builtin_function_is_routine (object_p)); + + if (ECMA_BUILTIN_IS_EXTENDED_BUILT_IN (object_type)) + { + built_in_props_p = &((ecma_extended_built_in_object_t *) object_p)->built_in; + } + else + { + built_in_props_p = &((ecma_extended_object_t *) object_p)->u.built_in; + } + + ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) built_in_props_p->id; + + JERRY_ASSERT (builtin_id < ECMA_BUILTIN_ID__COUNT); + + const ecma_builtin_property_descriptor_t *property_list_p = ecma_builtin_property_list_references[builtin_id]; + const ecma_builtin_property_descriptor_t *curr_property_p = property_list_p; + + while (curr_property_p->magic_string_id != magic_string_id) + { + JERRY_ASSERT (curr_property_p->magic_string_id != LIT_MAGIC_STRING__COUNT); + curr_property_p++; + } + + uint32_t index = (uint32_t) (curr_property_p - property_list_p); + uint8_t *bitset_p = built_in_props_p->u2.instantiated_bitset + (index >> 3); + +#if JERRY_BUILTIN_REALMS + if (index >= 8 * sizeof (uint8_t)) + { + bitset_p += sizeof (ecma_value_t); + } +#endif /* JERRY_BUILTIN_REALMS */ + + uint8_t bit_for_index = (uint8_t) (1u << (index & 0x7)); + JERRY_ASSERT (!(*bitset_p & bit_for_index)); + + *bitset_p |= bit_for_index; +} /* ecma_builtin_delete_built_in_property */ + +#if JERRY_ESNEXT + /** * List names of an Built-in native handler object's lazy instantiated properties, * adding them to corresponding string collections @@ -1292,8 +1412,8 @@ ecma_builtin_routine_list_lazy_property_names (ecma_object_t *object_p, /**< a b ecma_property_counter_t *prop_counter_p) /**< prop counter */ { JERRY_ASSERT (ecma_get_object_is_builtin (object_p)); - JERRY_ASSERT (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_NATIVE_FUNCTION); - JERRY_ASSERT (ecma_builtin_function_is_routine (object_p)); + JERRY_ASSERT (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_NATIVE_FUNCTION + && ecma_builtin_function_is_routine (object_p)); #if JERRY_ESNEXT ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p; @@ -1382,7 +1502,7 @@ ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, /**< a built-in { ecma_string_t *name_p = ecma_op_get_global_symbol (curr_property_p->magic_string_id); - if (!(bitset & bit_for_index) || ecma_op_ordinary_object_has_own_property (object_p, name_p)) + if (!(bitset & bit_for_index)) { ecma_value_t name = ecma_make_symbol_value (name_p); ecma_collection_push_back (prop_names_p, name); @@ -1395,16 +1515,11 @@ ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, /**< a built-in } #endif /* JERRY_ESNEXT */ } - else + else if (!(bitset & bit_for_index)) { - ecma_string_t *name_p = ecma_get_magic_string ((lit_magic_string_id_t) curr_property_p->magic_string_id); - - if (!(bitset & bit_for_index) || ecma_op_ordinary_object_has_own_property (object_p, name_p)) - { - 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++; - } + 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++; } curr_property_p++; diff --git a/jerry-core/ecma/builtin-objects/ecma-builtins.h b/jerry-core/ecma/builtin-objects/ecma-builtins.h index e8a2260c6..2a50e5df0 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtins.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtins.h @@ -128,9 +128,15 @@ ecma_value_t ecma_builtin_dispatch_construct (ecma_object_t *obj_p, const ecma_value_t *arguments_list_p, uint32_t arguments_list_len); ecma_property_t * -ecma_builtin_routine_try_to_instantiate_property (ecma_object_t *object_p, ecma_string_t *string_p); +ecma_builtin_routine_try_to_instantiate_property (ecma_object_t *object_p, ecma_string_t *property_name_p); ecma_property_t * -ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, ecma_string_t *string_p); +ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, ecma_string_t *property_name_p); +#if JERRY_ESNEXT +void +ecma_builtin_routine_delete_built_in_property (ecma_object_t *object_p, ecma_string_t *property_name_p); +#endif /* JERRY_ESNEXT */ +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, diff --git a/jerry-core/ecma/operations/ecma-array-object.c b/jerry-core/ecma/operations/ecma-array-object.c index 900e8d977..ca64871ab 100644 --- a/jerry-core/ecma/operations/ecma-array-object.c +++ b/jerry-core/ecma/operations/ecma-array-object.c @@ -501,19 +501,20 @@ ecma_fast_array_extend (ecma_object_t *object_p, /**< fast access mode array obj * Delete the array object's property referenced by its value pointer. * * Note: specified property must be owned by specified object. + * + * @return true, if the property is deleted + * false, otherwise */ -void +bool ecma_array_object_delete_property (ecma_object_t *object_p, /**< object */ - ecma_string_t *property_name_p, /**< property name */ - ecma_property_value_t *prop_value_p) /**< property value reference */ + ecma_string_t *property_name_p) /**< property name */ { JERRY_ASSERT (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_ARRAY); ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p; if (!ecma_op_object_is_fast_array (object_p)) { - ecma_delete_property (object_p, prop_value_p); - return; + return false; } JERRY_ASSERT (object_p->u1.property_list_cp != JMEM_CP_NULL); @@ -527,13 +528,14 @@ ecma_array_object_delete_property (ecma_object_t *object_p, /**< object */ if (ecma_is_value_array_hole (values_p[index])) { - return; + return true; } ecma_free_value_if_not_object (values_p[index]); values_p[index] = ECMA_VALUE_ARRAY_HOLE; ext_obj_p->u.array.length_prop_and_hole_count += ECMA_FAST_ARRAY_HOLE_ONE; + return true; } /* ecma_array_object_delete_property */ /** diff --git a/jerry-core/ecma/operations/ecma-array-object.h b/jerry-core/ecma/operations/ecma-array-object.h index 831cfe68a..2e6e8fe4e 100644 --- a/jerry-core/ecma/operations/ecma-array-object.h +++ b/jerry-core/ecma/operations/ecma-array-object.h @@ -89,9 +89,8 @@ ecma_fast_array_extend (ecma_object_t *object_p, uint32_t new_lengt); bool ecma_fast_array_set_property (ecma_object_t *object_p, uint32_t index, ecma_value_t value); -void -ecma_array_object_delete_property (ecma_object_t *object_p, ecma_string_t *property_name_p, - ecma_property_value_t *prop_value_p); +bool +ecma_array_object_delete_property (ecma_object_t *object_p, ecma_string_t *property_name_p); uint32_t ecma_delete_fast_array_properties (ecma_object_t *object_p, uint32_t new_length); diff --git a/jerry-core/ecma/operations/ecma-function-object.c b/jerry-core/ecma/operations/ecma-function-object.c index 0034286d2..3f12dc1cf 100644 --- a/jerry-core/ecma/operations/ecma-function-object.c +++ b/jerry-core/ecma/operations/ecma-function-object.c @@ -1702,7 +1702,7 @@ ecma_op_lazy_instantiate_prototype_object (ecma_object_t *object_p) /**< the fun ecma_property_value_t *prototype_prop_value_p; prototype_prop_value_p = ecma_create_named_data_property (object_p, ecma_get_magic_string (LIT_MAGIC_STRING_PROTOTYPE), - ECMA_PROPERTY_FLAG_WRITABLE, + ECMA_PROPERTY_BUILT_IN_WRITABLE, &prototype_prop_p); prototype_prop_value_p->value = ecma_make_object_value (proto_object_p); @@ -1734,73 +1734,72 @@ ecma_op_function_try_to_lazy_instantiate_property (ecma_object_t *object_p, /**< { ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p; - if (!ECMA_GET_FIRST_BIT_FROM_POINTER_TAG (ext_func_p->u.function.scope_cp)) + if (ECMA_GET_FIRST_BIT_FROM_POINTER_TAG (ext_func_p->u.function.scope_cp)) { - /* Initialize 'length' property */ - const ecma_compiled_code_t *bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_p); - uint32_t len; - - if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS) - { - cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_data_p; - len = args_p->argument_end; - } - else - { - cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_data_p; - len = args_p->argument_end; - } - - if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_HAS_EXTENDED_INFO) - { - uint8_t *extended_info_p = ecma_compiled_code_resolve_extended_info (bytecode_data_p); - - if (*extended_info_p & CBC_EXTENDED_CODE_FLAGS_HAS_ARGUMENT_LENGTH) - { - len = ecma_extended_info_decode_vlq (&extended_info_p); - } - } - - /* Set tag bit to represent initialized 'length' property */ - ECMA_SET_FIRST_BIT_TO_POINTER_TAG (ext_func_p->u.function.scope_cp); - ecma_property_t *value_prop_p; - ecma_property_value_t *value_p = ecma_create_named_data_property (object_p, - property_name_p, - ECMA_PROPERTY_FLAG_CONFIGURABLE, - &value_prop_p); - value_p->value = ecma_make_uint32_value (len); - return value_prop_p; + return NULL; } - return NULL; + /* Initialize 'length' property */ + const ecma_compiled_code_t *bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_p); + uint32_t len; + + if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS) + { + cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_data_p; + len = args_p->argument_end; + } + else + { + cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_data_p; + len = args_p->argument_end; + } + + if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_HAS_EXTENDED_INFO) + { + uint8_t *extended_info_p = ecma_compiled_code_resolve_extended_info (bytecode_data_p); + + if (*extended_info_p & CBC_EXTENDED_CODE_FLAGS_HAS_ARGUMENT_LENGTH) + { + len = ecma_extended_info_decode_vlq (&extended_info_p); + } + } + + ecma_property_t *value_prop_p; + ecma_property_value_t *value_p = ecma_create_named_data_property (object_p, + property_name_p, + ECMA_PROPERTY_BUILT_IN_CONFIGURABLE, + &value_prop_p); + value_p->value = ecma_make_uint32_value (len); + return value_prop_p; } if (ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_NAME)) { ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p; - if (!ECMA_GET_SECOND_BIT_FROM_POINTER_TAG (ext_func_p->u.function.scope_cp)) + + if (ECMA_GET_SECOND_BIT_FROM_POINTER_TAG (ext_func_p->u.function.scope_cp)) { - /* Set tag bit to represent initialized 'name' property */ - ECMA_SET_SECOND_BIT_TO_POINTER_TAG (ext_func_p->u.function.scope_cp); - const ecma_compiled_code_t *bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_p); - - if (CBC_FUNCTION_GET_TYPE (bytecode_data_p->status_flags) != CBC_FUNCTION_CONSTRUCTOR) - { - ecma_value_t value = *ecma_compiled_code_resolve_function_name (bytecode_data_p); - JERRY_ASSERT (ecma_is_value_string (value)); - - /* Initialize 'name' property */ - ecma_property_t *value_prop_p; - ecma_property_value_t *value_p = ecma_create_named_data_property (object_p, - property_name_p, - ECMA_PROPERTY_FLAG_CONFIGURABLE, - &value_prop_p); - value_p->value = ecma_copy_value (value); - return value_prop_p; - } + return NULL; } - return NULL; + const ecma_compiled_code_t *bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_p); + + if (CBC_FUNCTION_GET_TYPE (bytecode_data_p->status_flags) == CBC_FUNCTION_CONSTRUCTOR) + { + return NULL; + } + + ecma_value_t value = *ecma_compiled_code_resolve_function_name (bytecode_data_p); + JERRY_ASSERT (ecma_is_value_string (value)); + + /* Initialize 'name' property */ + ecma_property_t *value_prop_p; + ecma_property_value_t *value_p = ecma_create_named_data_property (object_p, + property_name_p, + ECMA_PROPERTY_BUILT_IN_CONFIGURABLE, + &value_prop_p); + value_p->value = ecma_copy_value (value); + return value_prop_p; } #endif /* JERRY_ESNEXT */ @@ -1826,7 +1825,7 @@ ecma_op_function_try_to_lazy_instantiate_property (ecma_object_t *object_p, /**< /* The property_name_p argument contains the name. */ ecma_property_value_t *value_p = ecma_create_named_data_property (object_p, property_name_p, - ECMA_PROPERTY_FIXED, + ECMA_PROPERTY_BUILT_IN_FIXED, &value_prop_p); value_p->value = is_arguments ? ECMA_VALUE_NULL : ECMA_VALUE_UNDEFINED; return value_prop_p; @@ -1842,7 +1841,7 @@ ecma_op_function_try_to_lazy_instantiate_property (ecma_object_t *object_p, /**< property_name_p, thrower_p, thrower_p, - ECMA_PROPERTY_FIXED, + ECMA_PROPERTY_BUILT_IN_FIXED, &caller_prop_p); return caller_prop_p; } @@ -1909,13 +1908,10 @@ ecma_op_bound_function_try_to_lazy_instantiate_property (ecma_object_t *object_p return NULL; } - length_attributes = ECMA_PROPERTY_FLAG_CONFIGURABLE; + length_attributes = ECMA_PROPERTY_BUILT_IN_CONFIGURABLE; length = ecma_get_number_from_value (bound_func_p->target_length) - (args_length - 1); - - /* Set tag bit to represent initialized 'length' property */ - ECMA_SET_FIRST_BIT_TO_POINTER_TAG (bound_func_p->header.u.bound_function.target_function); #else /* !JERRY_ESNEXT */ - length_attributes = ECMA_PROPERTY_FIXED; + length_attributes = ECMA_PROPERTY_BUILT_IN_FIXED; ecma_object_t *target_func_p; target_func_p = ECMA_GET_NON_NULL_POINTER_FROM_POINTER_TAG (ecma_object_t, @@ -1960,7 +1956,7 @@ ecma_op_bound_function_try_to_lazy_instantiate_property (ecma_object_t *object_p property_name_p, thrower_p, thrower_p, - ECMA_PROPERTY_FIXED, + ECMA_PROPERTY_BUILT_IN_FIXED, &caller_prop_p); return caller_prop_p; } @@ -1969,6 +1965,49 @@ ecma_op_bound_function_try_to_lazy_instantiate_property (ecma_object_t *object_p return NULL; } /* ecma_op_bound_function_try_to_lazy_instantiate_property */ +#if JERRY_ESNEXT + +/** + * Delete configurable properties of functions. + */ +void +ecma_op_function_delete_built_in_property (ecma_object_t *object_p, /**< object */ + ecma_string_t *property_name_p) /**< property name */ +{ + ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p; + + if (ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_LENGTH)) + { + JERRY_ASSERT (!ECMA_GET_FIRST_BIT_FROM_POINTER_TAG (ext_func_p->u.function.scope_cp)); + ECMA_SET_FIRST_BIT_TO_POINTER_TAG (ext_func_p->u.function.scope_cp); + return; + } + + JERRY_ASSERT (ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_NAME)); + JERRY_ASSERT (!ECMA_GET_SECOND_BIT_FROM_POINTER_TAG (ext_func_p->u.function.scope_cp)); + + ECMA_SET_SECOND_BIT_TO_POINTER_TAG (ext_func_p->u.function.scope_cp); +} /* ecma_op_function_delete_built_in_property */ + +/** + * Delete configurable properties of bound functions. + */ +void +ecma_op_bound_function_delete_built_in_property (ecma_object_t *object_p, /**< object */ + ecma_string_t *property_name_p) /**< property name */ +{ + JERRY_UNUSED (property_name_p); + + ecma_bound_function_t *bound_func_p = (ecma_bound_function_t *) object_p; + + JERRY_ASSERT (ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_LENGTH)); + JERRY_ASSERT (!ECMA_GET_FIRST_BIT_FROM_POINTER_TAG (bound_func_p->header.u.bound_function.target_function)); + + ECMA_SET_FIRST_BIT_TO_POINTER_TAG (bound_func_p->header.u.bound_function.target_function); +} /* ecma_op_bound_function_delete_built_in_property */ + +#endif /* JERRY_ESNEXT */ + /** * List names of a Function object's lazy instantiated properties, * adding them to corresponding string collections @@ -2058,7 +2097,10 @@ ecma_op_external_function_list_lazy_property_names (ecma_object_t *object_p, /** #if !JERRY_ESNEXT JERRY_UNUSED (object_p); #else /* JERRY_ESNEXT */ - if (!ecma_op_ordinary_object_has_own_property (object_p, ecma_get_magic_string (LIT_MAGIC_STRING_PROTOTYPE))) + /* 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 */ { /* 'prototype' property is non-enumerable (ECMA-262 v5, 13.2.18) */ diff --git a/jerry-core/ecma/operations/ecma-function-object.h b/jerry-core/ecma/operations/ecma-function-object.h index 19e2a422d..44b1963bb 100644 --- a/jerry-core/ecma/operations/ecma-function-object.h +++ b/jerry-core/ecma/operations/ecma-function-object.h @@ -108,6 +108,14 @@ ecma_op_external_function_try_to_lazy_instantiate_property (ecma_object_t *objec ecma_property_t * ecma_op_bound_function_try_to_lazy_instantiate_property (ecma_object_t *object_p, ecma_string_t *property_name_p); +#if JERRY_ESNEXT +void +ecma_op_function_delete_built_in_property (ecma_object_t *object_p, ecma_string_t *property_name_p); + +void +ecma_op_bound_function_delete_built_in_property (ecma_object_t *object_p, ecma_string_t *property_name_p); +#endif /* JERRY_ESNEXT */ + void ecma_op_function_list_lazy_property_names (ecma_object_t *object_p, ecma_collection_t *prop_names_p, diff --git a/jerry-core/ecma/operations/ecma-objects-general.c b/jerry-core/ecma/operations/ecma-objects-general.c index 78c1ddffa..8519960ee 100644 --- a/jerry-core/ecma/operations/ecma-objects-general.c +++ b/jerry-core/ecma/operations/ecma-objects-general.c @@ -107,30 +107,72 @@ ecma_op_general_object_delete (ecma_object_t *obj_p, /**< the object */ } /* 3. */ - if (ecma_is_property_configurable (property)) + if (!ecma_is_property_configurable (property)) { - if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_ARRAY) + /* 4. */ + if (is_throw) { - ecma_array_object_delete_property (obj_p, property_name_p, property_ref.value_p); - } - else - { - /* a. */ - ecma_delete_property (obj_p, property_ref.value_p); + return ecma_raise_type_error (ECMA_ERR_MSG ("Expected a configurable property")); } - /* b. */ + /* 5. */ + return ECMA_VALUE_FALSE; + } + + ecma_object_type_t type = ecma_get_object_type (obj_p); + + if (type == ECMA_OBJECT_TYPE_ARRAY + && ecma_array_object_delete_property (obj_p, property_name_p)) + { return ECMA_VALUE_TRUE; } - /* 4. */ - if (is_throw) + /* a. */ + ecma_delete_property (obj_p, property_ref.value_p); + + if (property & ECMA_PROPERTY_FLAG_BUILT_IN) { - return ecma_raise_type_error (ECMA_ERR_MSG ("Expected a configurable property")); +#if JERRY_ESNEXT + if (ecma_get_object_is_builtin (obj_p)) + { + if (type == ECMA_OBJECT_TYPE_NATIVE_FUNCTION && ecma_builtin_function_is_routine (obj_p)) + { + ecma_builtin_routine_delete_built_in_property (obj_p, property_name_p); + } + else + { + ecma_builtin_delete_built_in_property (obj_p, property_name_p); + } + } + else + { + switch (type) + { + case ECMA_OBJECT_TYPE_FUNCTION: + { + ecma_op_function_delete_built_in_property (obj_p, property_name_p); + break; + } + case ECMA_OBJECT_TYPE_BOUND_FUNCTION: + { + ecma_op_bound_function_delete_built_in_property (obj_p, property_name_p); + break; + } + default: + { + break; + } + } + } +#else /* !JERRY_ESNEXT */ + JERRY_ASSERT (ecma_get_object_is_builtin (obj_p)); + + ecma_builtin_delete_built_in_property (obj_p, property_name_p); +#endif /* JERRY_ESNEXT */ } - /* 5. */ - return ECMA_VALUE_FALSE; + /* b. */ + return ECMA_VALUE_TRUE; } /* ecma_op_general_object_delete */ /** diff --git a/jerry-core/ecma/operations/ecma-objects.c b/jerry-core/ecma/operations/ecma-objects.c index 81ae13568..4696c72c6 100644 --- a/jerry-core/ecma/operations/ecma-objects.c +++ b/jerry-core/ecma/operations/ecma-objects.c @@ -2551,7 +2551,8 @@ 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)) + 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; diff --git a/tests/jerry/es.next/regression-test-issue-3267.js b/tests/jerry/es.next/regression-test-issue-3267.js index 43f9831d3..c4a6d8246 100644 --- a/tests/jerry/es.next/regression-test-issue-3267.js +++ b/tests/jerry/es.next/regression-test-issue-3267.js @@ -18,6 +18,5 @@ assert (Object.isSealed(hasProp) === false); var keys = Object.getOwnPropertyNames(hasProp); assert (keys.length === 2); -/* Note: the order is currently wrong. */ -assert (keys[0] === "name"); -assert (keys[1] === "length"); +assert (keys[0] === "length"); +assert (keys[1] === "name"); diff --git a/tests/test262-esnext-excludelist.xml b/tests/test262-esnext-excludelist.xml index 7c426359a..a9bd0e592 100644 --- a/tests/test262-esnext-excludelist.xml +++ b/tests/test262-esnext-excludelist.xml @@ -37,8 +37,6 @@ - -