diff --git a/jerry-core/ecma/operations/ecma-array-object.c b/jerry-core/ecma/operations/ecma-array-object.c index 7143def78..2f386d4e8 100644 --- a/jerry-core/ecma/operations/ecma-array-object.c +++ b/jerry-core/ecma/operations/ecma-array-object.c @@ -970,9 +970,8 @@ ecma_delete_array_properties (ecma_object_t *object_p, /**< object */ ecma_value_t ecma_op_array_object_set_length (ecma_object_t *object_p, /**< the array object */ ecma_value_t new_value, /**< new length value */ - uint32_t flags) /**< configuration options */ + uint16_t flags) /**< property descriptor flags */ { - bool is_throw = (flags & ECMA_PROP_IS_THROW) != 0; ecma_number_t new_len_num; ecma_value_t completion = ecma_op_to_number (new_value, &new_len_num); @@ -1006,7 +1005,7 @@ ecma_op_array_object_set_length (ecma_object_t *object_p, /**< the array object | ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED)) { - return ecma_reject (is_throw); + return ecma_raise_property_redefinition (ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH), flags); } ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; @@ -1029,14 +1028,14 @@ ecma_op_array_object_set_length (ecma_object_t *object_p, /**< the array object } else if (!ecma_is_property_writable ((ecma_property_t) ext_object_p->u.array.length_prop_and_hole_count)) { - return ecma_reject (is_throw); + return ecma_raise_property_redefinition (ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH), flags); } } return ECMA_VALUE_TRUE; } else if (!ecma_is_property_writable ((ecma_property_t) ext_object_p->u.array.length_prop_and_hole_count)) { - return ecma_reject (is_throw); + return ecma_raise_property_redefinition (ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH), flags); } uint32_t current_len_uint32 = new_len_uint32; @@ -1067,7 +1066,8 @@ ecma_op_array_object_set_length (ecma_object_t *object_p, /**< the array object { return ECMA_VALUE_TRUE; } - return ecma_reject (is_throw); + + return ecma_raise_property_redefinition (ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH), flags); } /* ecma_op_array_object_set_length */ /** @@ -1159,7 +1159,7 @@ ecma_op_array_object_define_own_property (ecma_object_t *object_p, /**< the arra if (update_length && !ecma_is_property_writable ((ecma_property_t) ext_object_p->u.array.length_prop_and_hole_count)) { - return ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW); + return ecma_raise_property_redefinition (property_name_p, property_desc_p->flags); } ecma_property_descriptor_t prop_desc; @@ -1174,7 +1174,7 @@ ecma_op_array_object_define_own_property (ecma_object_t *object_p, /**< the arra if (ecma_is_value_false (completition)) { - return ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW); + return ecma_raise_property_redefinition (property_name_p, property_desc_p->flags); } if (update_length) diff --git a/jerry-core/ecma/operations/ecma-array-object.h b/jerry-core/ecma/operations/ecma-array-object.h index b02061aef..831cfe68a 100644 --- a/jerry-core/ecma/operations/ecma-array-object.h +++ b/jerry-core/ecma/operations/ecma-array-object.h @@ -113,7 +113,7 @@ ecma_op_create_array_iterator (ecma_object_t *obj_p, #endif /* JERRY_ESNEXT */ ecma_value_t -ecma_op_array_object_set_length (ecma_object_t *object_p, ecma_value_t new_value, uint32_t flags); +ecma_op_array_object_set_length (ecma_object_t *object_p, ecma_value_t new_value, uint16_t flags); ecma_value_t ecma_op_array_object_define_own_property (ecma_object_t *object_p, ecma_string_t *property_name_p, diff --git a/jerry-core/ecma/operations/ecma-objects-general.c b/jerry-core/ecma/operations/ecma-objects-general.c index 4f9b12193..5ff4be55b 100644 --- a/jerry-core/ecma/operations/ecma-objects-general.c +++ b/jerry-core/ecma/operations/ecma-objects-general.c @@ -31,25 +31,6 @@ * @{ */ -/** - * Reject sequence - * - * @return ecma value - * Returned value must be freed with ecma_free_value - */ -ecma_value_t -ecma_reject (bool is_throw) /**< Throw flag */ -{ - if (is_throw) - { - return ecma_raise_type_error (ECMA_ERR_MSG ("Invalid argument type")); - } - else - { - return ECMA_VALUE_FALSE; - } -} /* ecma_reject */ - /** * 'Object' object creation operation with no arguments. * @@ -386,7 +367,9 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob if (!ecma_op_ordinary_object_is_extensible (object_p)) { /* 2. */ - return ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW); + return ECMA_REJECT_WITH_FORMAT (property_desc_p->flags & ECMA_PROP_IS_THROW, + "Cannot define property '%', object is not extensible", + ecma_make_prop_name_value (property_name_p)); } /* 4. */ @@ -436,7 +419,8 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob { ecma_free_value (ext_property_ref.property_ref.virtual_value); } - return ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW); + + return ecma_raise_property_redefinition (property_name_p, property_desc_p->flags); } if (ECMA_PROPERTY_IS_VIRTUAL (current_prop)) @@ -451,7 +435,7 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob && !ecma_op_same_value (property_desc_p->value, ext_property_ref.property_ref.virtual_value))) { - result = ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW); + result = ecma_raise_property_redefinition (property_name_p, property_desc_p->flags); } ecma_free_value (ext_property_ref.property_ref.virtual_value); @@ -477,7 +461,7 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob && !ecma_op_same_value (property_desc_p->value, ext_property_ref.property_ref.value_p->value)))) { - return ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW); + return ecma_raise_property_redefinition (property_name_p, property_desc_p->flags); } } else @@ -498,7 +482,7 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob && prop_desc_setter_cp != get_set_pair_p->setter_cp)) { /* i., ii. */ - return ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW); + return ecma_raise_property_redefinition (property_name_p, property_desc_p->flags); } } } @@ -509,7 +493,7 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob if (!is_current_configurable) { /* a. */ - return ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW); + return ecma_raise_property_redefinition (property_name_p, property_desc_p->flags); } ecma_property_value_t *value_p = ext_property_ref.property_ref.value_p; diff --git a/jerry-core/ecma/operations/ecma-objects-general.h b/jerry-core/ecma/operations/ecma-objects-general.h index 3a2729600..783b576bb 100644 --- a/jerry-core/ecma/operations/ecma-objects-general.h +++ b/jerry-core/ecma/operations/ecma-objects-general.h @@ -26,7 +26,6 @@ * @{ */ -ecma_value_t ecma_reject (bool is_throw); ecma_object_t *ecma_op_create_object_object_noarg (void); ecma_object_t *ecma_op_create_object_object_noarg_and_set_prototype (ecma_object_t *object_prototype_p); diff --git a/jerry-core/ecma/operations/ecma-objects.c b/jerry-core/ecma/operations/ecma-objects.c index 93333511d..c8547ac99 100644 --- a/jerry-core/ecma/operations/ecma-objects.c +++ b/jerry-core/ecma/operations/ecma-objects.c @@ -1126,7 +1126,7 @@ ecma_op_object_put_apply_receiver (ecma_value_t receiver, /**< receiver */ /* 5.b */ if (!ecma_is_value_object (receiver)) { - return ecma_reject (is_throw); + return ECMA_REJECT (is_throw, "Receiver must be an object"); } ecma_object_t *receiver_obj_p = ecma_get_object_from_value (receiver); @@ -1152,7 +1152,7 @@ ecma_op_object_put_apply_receiver (ecma_value_t receiver, /**< receiver */ if (prop_desc.flags & (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED) || !(prop_desc.flags & ECMA_PROP_IS_WRITABLE)) { - result = ecma_reject (is_throw); + result = ecma_raise_property_redefinition (property_name_p, prop_desc.flags); } else { @@ -1164,9 +1164,9 @@ ecma_op_object_put_apply_receiver (ecma_value_t receiver, /**< receiver */ /* 5.e.iv */ result = ecma_op_object_define_own_property (receiver_obj_p, property_name_p, &prop_desc); - if (JERRY_UNLIKELY (ecma_is_value_false (result)) && is_throw) + if (JERRY_UNLIKELY (ecma_is_value_false (result))) { - result = ecma_raise_type_error (ECMA_ERR_MSG ("Proxy trap returned falsish")); + result = ECMA_REJECT (is_throw, "Proxy trap returned falsish"); } } @@ -1190,9 +1190,9 @@ ecma_op_object_put_apply_receiver (ecma_value_t receiver, /**< receiver */ desc.value = value; ecma_value_t ret_value = ecma_proxy_object_define_own_property (receiver_obj_p, property_name_p, &desc); - if (JERRY_UNLIKELY (ecma_is_value_false (ret_value)) && is_throw) + if (JERRY_UNLIKELY (ecma_is_value_false (ret_value))) { - ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Proxy trap returned falsish")); + ret_value = ECMA_REJECT (is_throw, "Proxy trap returned falsish"); } return ret_value; @@ -1269,7 +1269,7 @@ ecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */ return ecma_op_array_object_set_length (object_p, value, 0); } - return ecma_reject (is_throw); + return ecma_raise_readonly_assignment (property_name_p, is_throw); } if (JERRY_LIKELY (ecma_op_array_is_fast_array (ext_object_p))) @@ -1391,7 +1391,7 @@ ecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */ if (index < ecma_string_get_length (prim_value_str_p)) { - return ecma_reject (is_throw); + return ecma_raise_readonly_assignment (property_name_p, is_throw); } } } @@ -1399,19 +1399,16 @@ ecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */ } case ECMA_OBJECT_TYPE_FUNCTION: { - #if JERRY_ESNEXT - /* Uninitialized 'length' property is non-writable (ECMA-262 v6, 19.2.4.1) */ - if ((ecma_string_is_length (property_name_p)) - && (!ECMA_GET_FIRST_BIT_FROM_POINTER_TAG (((ecma_extended_object_t *) object_p)->u.function.scope_cp))) - { - return ecma_reject (is_throw); - } - #else /* !JERRY_ESNEXT */ if (ecma_string_is_length (property_name_p)) { - return ecma_reject (is_throw); - } + /* Uninitialized 'length' property is non-writable (ECMA-262 v6, 19.2.4.1) */ + #if JERRY_ESNEXT + if (!ECMA_GET_FIRST_BIT_FROM_POINTER_TAG (((ecma_extended_object_t *) object_p)->u.function.scope_cp)) #endif /* JERRY_ESNEXT */ + { + return ecma_raise_readonly_assignment (property_name_p, is_throw); + } + } /* Get prototype physical property. */ property_p = ecma_op_function_try_to_lazy_instantiate_property (object_p, property_name_p); @@ -1568,7 +1565,7 @@ ecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */ { if (!ecma_is_property_writable ((ecma_property_t) ext_object_p->u.array.length_prop_and_hole_count)) { - return ecma_reject (is_throw); + return ecma_raise_readonly_assignment (property_name_p, is_throw); } ext_object_p->u.array.length = index + 1; @@ -1593,7 +1590,7 @@ ecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */ if (setter_cp == JMEM_CP_NULL) { - return ecma_reject (is_throw); + return ecma_raise_readonly_assignment (property_name_p, is_throw); } ecma_value_t ret_value = ecma_op_function_call (ECMA_GET_NON_NULL_POINTER (ecma_object_t, setter_cp), @@ -1741,99 +1738,44 @@ ecma_op_object_define_own_property (ecma_object_t *obj_p, /**< the object */ const ecma_object_type_t type = ecma_get_object_type (obj_p); -#if JERRY_BUILTIN_PROXY - if (ECMA_OBJECT_IS_PROXY (obj_p)) - { - return ecma_proxy_object_define_own_property (obj_p, property_name_p, property_desc_p); - } -#endif /* JERRY_BUILTIN_PROXY */ - switch (type) { - case ECMA_OBJECT_TYPE_GENERAL: - case ECMA_OBJECT_TYPE_CLASS: - case ECMA_OBJECT_TYPE_FUNCTION: - case ECMA_OBJECT_TYPE_NATIVE_FUNCTION: - case ECMA_OBJECT_TYPE_BOUND_FUNCTION: +#if JERRY_BUILTIN_PROXY + case ECMA_OBJECT_TYPE_PROXY: { - return ecma_op_general_object_define_own_property (obj_p, - property_name_p, - property_desc_p); + return ecma_proxy_object_define_own_property (obj_p, property_name_p, property_desc_p); } - +#endif /* JERRY_BUILTIN_PROXY */ case ECMA_OBJECT_TYPE_ARRAY: { - return ecma_op_array_object_define_own_property (obj_p, - property_name_p, - property_desc_p); + return ecma_op_array_object_define_own_property (obj_p, property_name_p, property_desc_p); } - - default: + case ECMA_OBJECT_TYPE_PSEUDO_ARRAY: { - JERRY_ASSERT (type == ECMA_OBJECT_TYPE_PSEUDO_ARRAY); - - ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p; - #if JERRY_BUILTIN_TYPEDARRAY - if (ext_object_p->u.pseudo_array.type == ECMA_PSEUDO_ARRAY_ARGUMENTS) - { -#else /* !JERRY_BUILTIN_TYPEDARRAY */ - JERRY_ASSERT (ext_object_p->u.pseudo_array.type == ECMA_PSEUDO_ARRAY_ARGUMENTS); -#endif /* JERRY_BUILTIN_TYPEDARRAY */ - return ecma_op_arguments_object_define_own_property (obj_p, - property_name_p, - property_desc_p); -#if JERRY_BUILTIN_TYPEDARRAY - } - /* ES2015 9.4.5.3 */ if (ecma_object_is_typedarray (obj_p)) { - if (ecma_prop_name_is_symbol (property_name_p)) - { - return ecma_op_general_object_define_own_property (obj_p, - property_name_p, - property_desc_p); - } - uint32_t array_index = ecma_string_get_array_index (property_name_p); - - if (array_index != ECMA_STRING_NOT_ARRAY_INDEX) - { - ecma_value_t define_status = ecma_op_typedarray_define_index_prop (obj_p, - array_index, - property_desc_p); - - if (ECMA_IS_VALUE_ERROR (define_status)) - { - return define_status; - } - - if (ecma_is_value_true (define_status)) - { - return ECMA_VALUE_TRUE; - } - - return ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW); - } - - ecma_number_t num = ecma_string_to_number (property_name_p); - ecma_string_t *num_to_str = ecma_new_ecma_string_from_number (num); - bool is_same = ecma_compare_ecma_strings (property_name_p, num_to_str); - ecma_deref_ecma_string (num_to_str); - - if (is_same) - { - return ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW); - } + return ecma_op_typedarray_define_own_property (obj_p, property_name_p, property_desc_p); } - - return ecma_op_general_object_define_own_property (obj_p, - property_name_p, - property_desc_p); -#else /* !JERRY_BUILTIN_TYPEDARRAY */ - break; #endif /* JERRY_BUILTIN_TYPEDARRAY */ + +#if JERRY_ESNEXT + /* All iterators are pseudo arrays */ + if (((ecma_extended_object_t *) obj_p)->u.pseudo_array.type != ECMA_PSEUDO_ARRAY_ARGUMENTS) + { + break; + } +#endif /* JERRY_ESNEXT */ + + return ecma_op_arguments_object_define_own_property (obj_p, property_name_p, property_desc_p); + } + default: + { + break; } } + + return ecma_op_general_object_define_own_property (obj_p, property_name_p, property_desc_p); } /* ecma_op_object_define_own_property */ /** @@ -3297,6 +3239,40 @@ ecma_op_ordinary_object_has_own_property (ecma_object_t *object_p, /**< the obje return property != ECMA_PROPERTY_TYPE_NOT_FOUND && property != ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP; } /* ecma_op_ordinary_object_has_own_property */ +/** + * Raise property redefinition error + * + * @return ECMA_VALUE_FALSE - if ECMA_IS_THROW is not set + * raised TypeError - otherwise + */ +ecma_value_t +ecma_raise_property_redefinition (ecma_string_t *property_name_p, /**< property name */ + uint16_t flags) /**< property descriptor flags */ +{ + JERRY_UNUSED (property_name_p); + + return ECMA_REJECT_WITH_FORMAT (flags & ECMA_PROP_IS_THROW, + "Cannot redefine property '%'", + ecma_make_prop_name_value (property_name_p)); +} /* ecma_raise_property_redefinition */ + +/** + * Raise readonly assignment error + * + * @return ECMA_VALUE_FALSE - if is_throw is true + * raised TypeError - otherwise + */ +ecma_value_t +ecma_raise_readonly_assignment (ecma_string_t *property_name_p, /**< property name */ + bool is_throw) /**< is throw flag */ +{ + JERRY_UNUSED (property_name_p); + + return ECMA_REJECT_WITH_FORMAT (is_throw, + "Cannot assign to read only property '%'", + ecma_make_prop_name_value (property_name_p)); +} /* ecma_raise_readonly_assignment */ + /** * @} * @} diff --git a/jerry-core/ecma/operations/ecma-objects.h b/jerry-core/ecma/operations/ecma-objects.h index a5783ffa9..1e84c2579 100644 --- a/jerry-core/ecma/operations/ecma-objects.h +++ b/jerry-core/ecma/operations/ecma-objects.h @@ -27,6 +27,35 @@ * @{ */ +#if JERRY_ERROR_MESSAGES +/** + * Reject with TypeError depending on 'is_throw' with the given format + */ +#define ECMA_REJECT_WITH_FORMAT(is_throw, msg, ...) \ + ((is_throw) ? ecma_raise_standard_error_with_format (ECMA_ERROR_TYPE, (msg), __VA_ARGS__) : ECMA_VALUE_FALSE) + +/** + * Reject with TypeError depending on 'is_throw' with the given message + */ +#define ECMA_REJECT(is_throw, msg) \ + ((is_throw) ? ecma_raise_type_error (msg) : ECMA_VALUE_FALSE) +#else /* !JERRY_ERROR_MESSAGES */ +/** + * Reject with TypeError depending on is_throw flags wit the given format + */ +#define ECMA_REJECT_WITH_FORMAT(is_throw, msg, ...) \ + ECMA_REJECT((is_throw), (msg)) + +/** + * Reject with TypeError depending on is_throw flags wit the given message + */ +#define ECMA_REJECT(is_throw, msg) \ + ((is_throw) ? ecma_raise_type_error (NULL) : ECMA_VALUE_FALSE) +#endif /* JERRY_ERROR_MESSAGES */ + +ecma_value_t ecma_raise_property_redefinition (ecma_string_t *property_name_p, uint16_t flags); +ecma_value_t ecma_raise_readonly_assignment (ecma_string_t *property_name_p, bool is_throw); + ecma_property_t ecma_op_object_get_own_property (ecma_object_t *object_p, ecma_string_t *property_name_p, ecma_property_ref_t *property_ref_p, uint32_t options); bool ecma_op_ordinary_object_has_own_property (ecma_object_t *object_p, ecma_string_t *property_name_p); diff --git a/jerry-core/ecma/operations/ecma-typedarray-object.c b/jerry-core/ecma/operations/ecma-typedarray-object.c index 51fe1cfd7..68c4e7925 100644 --- a/jerry-core/ecma/operations/ecma-typedarray-object.c +++ b/jerry-core/ecma/operations/ecma-typedarray-object.c @@ -23,6 +23,7 @@ #include "ecma-big-uint.h" #include "ecma-builtin-helpers.h" #include "ecma-objects.h" +#include "ecma-objects-general.h" #include "ecma-builtins.h" #include "ecma-exceptions.h" #include "ecma-gc.h" @@ -1564,54 +1565,72 @@ ecma_op_typedarray_list_lazy_property_names (ecma_object_t *obj_p, /**< a TypedA } /* ecma_op_typedarray_list_lazy_property_names */ /** - * Define the integer number property value of the typedarray + * [[DefineOwnProperty]] operation for TypedArray objects * - * See also: ES2015 9.4.5.3: 3.c + * See also: ES2015 9.4.5.3 * - * @return ecma value, + * @return ECMA_VALUE_TRUE - if the property is successfully defined + * ECMA_VALUE_FALSE - if is ECMA_IS_THROW is not set + * raised TypeError - otherwise */ ecma_value_t -ecma_op_typedarray_define_index_prop (ecma_object_t *obj_p, /**< a TypedArray object */ - uint32_t index, /**< the index number */ - const ecma_property_descriptor_t *property_desc_p) /**< the description of - the prop */ +ecma_op_typedarray_define_own_property (ecma_object_t *obj_p, /**< TypedArray object */ + ecma_string_t *prop_name_p, /**< property name */ + const ecma_property_descriptor_t *property_desc_p) /**< property descriptor */ { JERRY_ASSERT (ecma_object_is_typedarray (obj_p)); - uint32_t array_length = ecma_typedarray_get_length (obj_p); - - if ((index >= array_length) - || (property_desc_p->flags & (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED)) - || ((property_desc_p->flags & (ECMA_PROP_IS_CONFIGURABLE_DEFINED | ECMA_PROP_IS_CONFIGURABLE)) - == (ECMA_PROP_IS_CONFIGURABLE_DEFINED | ECMA_PROP_IS_CONFIGURABLE)) - || ((property_desc_p->flags & ECMA_PROP_IS_ENUMERABLE_DEFINED) - && !(property_desc_p->flags & ECMA_PROP_IS_ENUMERABLE)) - || ((property_desc_p->flags & ECMA_PROP_IS_WRITABLE_DEFINED) - && !(property_desc_p->flags & ECMA_PROP_IS_WRITABLE))) + if (!ecma_prop_name_is_symbol (prop_name_p)) { - return ECMA_VALUE_FALSE; - } + uint32_t array_index = ecma_string_get_array_index (prop_name_p); - if (property_desc_p->flags & ECMA_PROP_IS_VALUE_DEFINED) - { - ecma_typedarray_info_t info = ecma_typedarray_get_info (obj_p); - - if (index >= info.length) + if (array_index != ECMA_STRING_NOT_ARRAY_INDEX) { - return ECMA_VALUE_FALSE; + if ((property_desc_p->flags & (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED)) + || ((property_desc_p->flags & (ECMA_PROP_IS_CONFIGURABLE_DEFINED | ECMA_PROP_IS_CONFIGURABLE)) + == (ECMA_PROP_IS_CONFIGURABLE_DEFINED | ECMA_PROP_IS_CONFIGURABLE)) + || ((property_desc_p->flags & ECMA_PROP_IS_ENUMERABLE_DEFINED) + && !(property_desc_p->flags & ECMA_PROP_IS_ENUMERABLE)) + || ((property_desc_p->flags & ECMA_PROP_IS_WRITABLE_DEFINED) + && !(property_desc_p->flags & ECMA_PROP_IS_WRITABLE))) + { + return ecma_raise_property_redefinition (prop_name_p, property_desc_p->flags); + } + + ecma_typedarray_info_t info = ecma_typedarray_get_info (obj_p); + + if (array_index >= info.length) + { + return ECMA_REJECT ((property_desc_p->flags & ECMA_PROP_IS_THROW), "Invalid typed array index"); + } + + if (property_desc_p->flags & ECMA_PROP_IS_VALUE_DEFINED) + { + lit_utf8_byte_t *src_buffer = info.buffer_p + (array_index << info.shift); + ecma_value_t set_element = ecma_set_typedarray_element (src_buffer, property_desc_p->value, info.id); + + if (ECMA_IS_VALUE_ERROR (set_element)) + { + return set_element; + } + } + + return ECMA_VALUE_TRUE; } - lit_utf8_byte_t *src_buffer = info.buffer_p + (index << info.shift); - ecma_value_t set_element = ecma_set_typedarray_element (src_buffer, property_desc_p->value, info.id); + ecma_number_t num = ecma_string_to_number (prop_name_p); + ecma_string_t *num_to_str = ecma_new_ecma_string_from_number (num); + bool is_same = ecma_compare_ecma_strings (prop_name_p, num_to_str); + ecma_deref_ecma_string (num_to_str); - if (ECMA_IS_VALUE_ERROR (set_element)) + if (is_same) { - return set_element; + return ECMA_REJECT ((property_desc_p->flags & ECMA_PROP_IS_THROW), "Invalid typed array index"); } } - return ECMA_VALUE_TRUE; -} /* ecma_op_typedarray_define_index_prop */ + return ecma_op_general_object_define_own_property (obj_p, prop_name_p, property_desc_p); +} /* ecma_op_typedarray_define_own_property */ /** * Specify the creation of a new TypedArray diff --git a/jerry-core/ecma/operations/ecma-typedarray-object.h b/jerry-core/ecma/operations/ecma-typedarray-object.h index 422c4ce84..5263c20bd 100644 --- a/jerry-core/ecma/operations/ecma-typedarray-object.h +++ b/jerry-core/ecma/operations/ecma-typedarray-object.h @@ -66,9 +66,9 @@ 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); -ecma_value_t ecma_op_typedarray_define_index_prop (ecma_object_t *obj_p, - uint32_t index, - const ecma_property_descriptor_t *property_desc_p); +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); ecma_value_t ecma_op_create_typedarray_with_type_and_length (ecma_typedarray_type_t typedarray_id, uint32_t array_length); ecma_typedarray_info_t ecma_typedarray_get_info (ecma_object_t *typedarray_p);