diff --git a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-prototype.c b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-prototype.c index f5dd9a715..bae1fb3cd 100644 --- a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-prototype.c +++ b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-prototype.c @@ -816,81 +816,51 @@ ecma_builtin_typedarray_prototype_join (ecma_object_t *obj_p, /**< this object * ecma_value_t separator_arg) /**< separator argument */ { /* 2. */ - ecma_value_t length_value = ecma_op_object_get_by_magic_id (obj_p, LIT_MAGIC_STRING_LENGTH); - - if (ECMA_IS_VALUE_ERROR (length_value)) - { - return length_value; - } - - ecma_number_t length_number; - - if (ECMA_IS_VALUE_ERROR (ecma_op_to_number (length_value, &length_number))) - { - ecma_free_value (length_value); - return ECMA_VALUE_ERROR; - } + uint32_t length = ecma_typedarray_get_length (obj_p); + ecma_string_t *separator_string_p = ecma_op_typedarray_get_separator_string (separator_arg); ecma_value_t ret_value = ECMA_VALUE_ERROR; - - /* 3. */ - uint32_t length = ecma_number_to_uint32 (length_number); - - if (length == 0) + if (JERRY_UNLIKELY (separator_string_p == NULL)) { - /* 6. */ - ecma_free_value (length_value); - return ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY); + return ret_value; } - else + + /* 7-8. */ + ecma_string_t *first_string_p = ecma_op_typedarray_get_to_string_at_index (obj_p, 0); + + if (JERRY_UNLIKELY (first_string_p == NULL)) { - ecma_string_t *separator_string_p = ecma_op_typedarray_get_separator_string (separator_arg); - - if (JERRY_UNLIKELY (separator_string_p == NULL)) - { - goto cleanup; - } - - /* 7-8. */ - ecma_string_t *first_string_p = ecma_op_typedarray_get_to_string_at_index (obj_p, 0); - - if (JERRY_UNLIKELY (first_string_p == NULL)) - { - ecma_deref_ecma_string (separator_string_p); - goto cleanup; - } - - ecma_stringbuilder_t builder = ecma_stringbuilder_create_from (first_string_p); - - ecma_deref_ecma_string (first_string_p); - - /* 9-10. */ - for (uint32_t k = 1; k < length; k++) - { - /* 10.a */ - ecma_stringbuilder_append (&builder, separator_string_p); - - /* 10.d */ - ecma_string_t *next_string_p = ecma_op_typedarray_get_to_string_at_index (obj_p, k); - - if (JERRY_UNLIKELY (next_string_p == NULL)) - { - ecma_stringbuilder_destroy (&builder); - ecma_deref_ecma_string (separator_string_p); - goto cleanup; - } - - ecma_stringbuilder_append (&builder, next_string_p); - - ecma_deref_ecma_string (next_string_p); - } - ecma_deref_ecma_string (separator_string_p); - ret_value = ecma_make_string_value (ecma_stringbuilder_finalize (&builder)); + return ret_value; } -cleanup: - ecma_free_value (length_value); + ecma_stringbuilder_t builder = ecma_stringbuilder_create_from (first_string_p); + + ecma_deref_ecma_string (first_string_p); + + /* 9-10. */ + for (uint32_t k = 1; k < length; k++) + { + /* 10.a */ + ecma_stringbuilder_append (&builder, separator_string_p); + + /* 10.d */ + ecma_string_t *next_string_p = ecma_op_typedarray_get_to_string_at_index (obj_p, k); + + if (JERRY_UNLIKELY (next_string_p == NULL)) + { + ecma_stringbuilder_destroy (&builder); + ecma_deref_ecma_string (separator_string_p); + return ret_value; + } + + ecma_stringbuilder_append (&builder, next_string_p); + + ecma_deref_ecma_string (next_string_p); + } + + ecma_deref_ecma_string (separator_string_p); + ret_value = ecma_make_string_value (ecma_stringbuilder_finalize (&builder)); return ret_value; } /* ecma_builtin_typedarray_prototype_join */ @@ -1108,7 +1078,7 @@ ecma_builtin_typedarray_prototype_sort_compare_helper (ecma_value_t lhs, /**< le { result = ECMA_NUMBER_MINUS_ONE; } - else if (lhs_value > rhs_value) + else if (lhs_value > rhs_value || (ecma_number_is_zero (rhs_value) && ecma_number_is_negative (rhs_value))) { result = ECMA_NUMBER_ONE; } @@ -1631,7 +1601,8 @@ static ecma_value_t ecma_builtin_typedarray_prototype_to_locale_string_helper (ecma_typedarray_info_t *info_p, /**< object info */ uint32_t index) /** array index */ { - ecma_value_t element_value = ecma_get_typedarray_element (info_p->buffer_p + index, info_p->id); + ecma_value_t element_value = ecma_get_typedarray_element (info_p, index); + ecma_value_t call_value = ecma_op_invoke_by_magic_id (element_value, LIT_MAGIC_STRING_TO_LOCALE_STRING_UL, NULL, 0); ecma_free_value (element_value); @@ -1665,8 +1636,6 @@ ecma_builtin_typedarray_prototype_to_locale_string_helper (ecma_typedarray_info_ static ecma_value_t ecma_builtin_typedarray_prototype_to_locale_string (ecma_typedarray_info_t *info_p) /**< object info */ { - uint32_t limit = info_p->length * info_p->element_size; - if (info_p->length == 0) { return ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY); @@ -1683,7 +1652,7 @@ ecma_builtin_typedarray_prototype_to_locale_string (ecma_typedarray_info_t *info ecma_stringbuilder_t builder = ecma_stringbuilder_create_from (return_string_p); ecma_deref_ecma_string (return_string_p); - for (uint32_t k = info_p->element_size; k < limit; k += info_p->element_size) + for (uint32_t k = 1; k < info_p->length; k++) { ecma_stringbuilder_append_byte (&builder, LIT_CHAR_COMMA); ecma_value_t next_element = ecma_builtin_typedarray_prototype_to_locale_string_helper (info_p, k); @@ -1923,6 +1892,13 @@ ecma_builtin_typedarray_prototype_dispatch_routine (uint8_t builtin_routine_id, } case ECMA_TYPEDARRAY_PROTOTYPE_ROUTINE_BYTELENGTH_GETTER: { + ecma_object_t *buffer_p = ecma_typedarray_get_arraybuffer (typedarray_p); + + if (ecma_arraybuffer_is_detached (buffer_p)) + { + return ecma_make_uint32_value (0); + } + uint32_t length = ecma_typedarray_get_length (typedarray_p); uint8_t shift = ecma_typedarray_get_element_size_shift (typedarray_p); return ecma_make_uint32_value (length << shift); @@ -1933,6 +1909,13 @@ ecma_builtin_typedarray_prototype_dispatch_routine (uint8_t builtin_routine_id, } case ECMA_TYPEDARRAY_PROTOTYPE_ROUTINE_LENGTH_GETTER: { + ecma_object_t *buffer_p = ecma_typedarray_get_arraybuffer (typedarray_p); + + if (ecma_arraybuffer_is_detached (buffer_p)) + { + return ecma_make_uint32_value (0); + } + return ecma_make_uint32_value (ecma_typedarray_get_length (typedarray_p)); } case ECMA_TYPEDARRAY_PROTOTYPE_ROUTINE_TO_STRING_TAG_GETTER: diff --git a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray.c b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray.c index 8d3017416..c961618e9 100644 --- a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray.c +++ b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray.c @@ -117,24 +117,10 @@ ecma_builtin_typedarray_of (ecma_value_t this_arg, /**< 'this' argument */ return ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not a constructor")); } - ecma_object_t *obj_p = ecma_get_object_from_value (this_arg); - const uint8_t builtin_id = ecma_get_object_builtin_id (obj_p); - - if (!ecma_typedarray_helper_is_typedarray (builtin_id)) - { - return ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not a TypedArray constructor")); - } - - ecma_typedarray_type_t typedarray_id = ecma_typedarray_helper_builtin_to_typedarray_id (builtin_id); - - ecma_object_t *proto_p = ecma_builtin_get (ecma_typedarray_helper_get_prototype_id (typedarray_id)); - const uint8_t element_size_shift = ecma_typedarray_helper_get_shift_size (typedarray_id); - - ecma_value_t ret_val = ecma_typedarray_create_object_with_length (arguments_list_len, - NULL, - proto_p, - element_size_shift, - typedarray_id); + ecma_object_t *constructor_obj_p = ecma_get_object_from_value (this_arg); + ecma_value_t len_val = ecma_make_uint32_value (arguments_list_len); + ecma_value_t ret_val = ecma_typedarray_create (constructor_obj_p, &len_val, 1); + ecma_free_value (len_val); if (ECMA_IS_VALUE_ERROR (ret_val)) { diff --git a/jerry-core/ecma/operations/ecma-dataview-object.c b/jerry-core/ecma/operations/ecma-dataview-object.c index 9eb4ca052..a78145079 100644 --- a/jerry-core/ecma/operations/ecma-dataview-object.c +++ b/jerry-core/ecma/operations/ecma-dataview-object.c @@ -324,17 +324,30 @@ ecma_op_dataview_get_set_view_value (ecma_value_t view, /**< the operation's 'vi bool system_is_little_endian = ecma_dataview_check_little_endian (); + ecma_typedarray_info_t info; + info.id = id; + info.length = view_size; + info.shift = ecma_typedarray_helper_get_shift_size (id); + info.element_size = element_size; + info.offset = view_p->byte_offset; + info.array_buffer_p = buffer_p; + /* GetViewValue 12. */ if (ecma_is_value_empty (value_to_set)) { JERRY_VLA (lit_utf8_byte_t, swap_block_p, element_size); memcpy (swap_block_p, block_p, element_size * sizeof (lit_utf8_byte_t)); ecma_dataview_swap_order (system_is_little_endian, is_little_endian, element_size, swap_block_p); - return ecma_get_typedarray_element (swap_block_p, id); + info.buffer_p = swap_block_p; + return ecma_get_typedarray_element (&info, 0); + } + if (!ecma_number_is_nan (get_index) && get_index <= 0) + { + get_index = 0; } - /* SetViewValue 14. */ - ecma_value_t set_element = ecma_set_typedarray_element (block_p, value_to_set, id); + info.buffer_p = block_p; + ecma_value_t set_element = ecma_set_typedarray_element (&info, value_to_set, 0); ecma_free_value (value_to_set); if (ECMA_IS_VALUE_ERROR (set_element)) diff --git a/jerry-core/ecma/operations/ecma-objects.c b/jerry-core/ecma/operations/ecma-objects.c index bb708472d..37012b638 100644 --- a/jerry-core/ecma/operations/ecma-objects.c +++ b/jerry-core/ecma/operations/ecma-objects.c @@ -28,6 +28,7 @@ #include "ecma-objects-general.h" #include "ecma-objects.h" #include "ecma-proxy-object.h" +#include "ecma-bigint.h" #include "jcontext.h" #if JERRY_BUILTIN_TYPEDARRAY @@ -138,18 +139,28 @@ ecma_op_object_get_own_property (ecma_object_t *object_p, /**< the object */ { break; } + ecma_number_t num = ecma_string_to_number (property_name_p); + bool is_same; + if (num <= 0) + { + is_same = true; + } + else + { + ecma_string_t *num_to_str = ecma_new_ecma_string_from_number (num); + is_same = ecma_compare_ecma_strings (property_name_p, num_to_str); + ecma_deref_ecma_string (num_to_str); + } - uint32_t array_index = ecma_string_get_array_index (property_name_p); - - if (array_index != ECMA_STRING_NOT_ARRAY_INDEX) + if (is_same) { ecma_typedarray_info_t info = ecma_typedarray_get_info (object_p); - ecma_value_t value = ECMA_VALUE_UNDEFINED; + ecma_value_t value = ecma_get_typedarray_element (&info, num); - if (array_index < info.length) + if (ECMA_IS_VALUE_ERROR (value)) { - uint32_t byte_pos = array_index << info.shift; - value = ecma_get_typedarray_element (info.buffer_p + byte_pos, info.id); + property_ref_p->virtual_value = value; + return ECMA_PROPERTY_TYPE_NOT_FOUND; } if (!ecma_is_value_undefined (value)) @@ -165,21 +176,11 @@ ecma_op_object_get_own_property (ecma_object_t *object_p, /**< the object */ return ECMA_PROPERTY_ENUMERABLE_WRITABLE | ECMA_PROPERTY_VIRTUAL; } - - return ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP; + else + { + return ECMA_PROPERTY_TYPE_NOT_FOUND; + } } - - ecma_number_t num = ecma_string_to_number (property_name_p); - ecma_string_t *num_to_str = ecma_new_ecma_string_from_number (num); - - if (ecma_compare_ecma_strings (property_name_p, num_to_str)) - { - ecma_deref_ecma_string (num_to_str); - - return ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP; - } - - ecma_deref_ecma_string (num_to_str); break; } #endif /* JERRY_BUILTIN_TYPEDARRAY */ @@ -453,6 +454,44 @@ ecma_op_object_has_property (ecma_object_t *object_p, /**< the object */ } #endif /* JERRY_BUILTIN_PROXY */ +#if JERRY_BUILTIN_TYPEDARRAY + if (ecma_object_is_typedarray (object_p) && !ecma_prop_name_is_symbol (property_name_p)) + { + ecma_number_t num = ecma_string_to_number (property_name_p); + bool is_same; + if (num <= 0) + { + is_same = true; + } + else + { + ecma_string_t *num_to_str = ecma_new_ecma_string_from_number (num); + is_same = ecma_compare_ecma_strings (property_name_p, num_to_str); + ecma_deref_ecma_string (num_to_str); + } + + if (is_same) + { + ecma_typedarray_info_t info = ecma_typedarray_get_info (object_p); + + if (ecma_arraybuffer_is_detached (info.array_buffer_p)) + { + return ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_arraybuffer_is_detached)); + } + + if (!ecma_op_is_integer (num) + || num >= info.length + || num < 0 + || (ecma_number_is_negative (num) && ecma_number_is_zero (num))) + { + return ECMA_VALUE_FALSE; + } + + return ECMA_VALUE_TRUE; + } + } +#endif /* JERRY_BUILTIN_TYPEDARRAY */ + /* 2 - 3. */ if (ecma_op_ordinary_object_has_own_property (object_p, property_name_p)) { @@ -562,32 +601,25 @@ ecma_op_object_find_own (ecma_value_t base_value, /**< base value */ break; } - uint32_t array_index = ecma_string_get_array_index (property_name_p); + ecma_number_t num = ecma_string_to_number (property_name_p); + bool is_same; + if (num <= 0) + { + is_same = true; + } + else + { + ecma_string_t *num_to_str = ecma_new_ecma_string_from_number (num); + is_same = ecma_compare_ecma_strings (property_name_p, num_to_str); + ecma_deref_ecma_string (num_to_str); + } - if (array_index != ECMA_STRING_NOT_ARRAY_INDEX) + if (is_same) { ecma_typedarray_info_t info = ecma_typedarray_get_info (object_p); - - if (array_index >= info.length) - { - return ECMA_VALUE_UNDEFINED; - } - - uint32_t byte_pos = array_index << info.shift; - return ecma_get_typedarray_element (info.buffer_p + byte_pos, info.id); + return ecma_get_typedarray_element (&info, num); } - ecma_number_t num = ecma_string_to_number (property_name_p); - ecma_string_t *num_to_str = ecma_new_ecma_string_from_number (num); - - if (ecma_compare_ecma_strings (property_name_p, num_to_str)) - { - ecma_deref_ecma_string (num_to_str); - - return ECMA_VALUE_UNDEFINED; - } - - ecma_deref_ecma_string (num_to_str); break; } #endif /* JERRY_BUILTIN_TYPEDARRAY */ @@ -1410,29 +1442,23 @@ ecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */ break; } - uint32_t array_index = ecma_string_get_array_index (property_name_p); - - if (array_index != ECMA_STRING_NOT_ARRAY_INDEX) - { - ecma_typedarray_info_t info = ecma_typedarray_get_info (object_p); - - if (array_index >= info.length) - { - return ECMA_VALUE_FALSE; - } - - uint32_t byte_pos = array_index << info.shift; - return ecma_set_typedarray_element (info.buffer_p + byte_pos, value, info.id); - } - 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); + bool is_same; + if (num <= 0) + { + is_same = true; + } + else + { + ecma_string_t *num_to_str = ecma_new_ecma_string_from_number (num); + is_same = ecma_compare_ecma_strings (property_name_p, num_to_str); + ecma_deref_ecma_string (num_to_str); + } if (is_same) { - return ECMA_VALUE_FALSE; + ecma_typedarray_info_t info = ecma_typedarray_get_info (object_p); + return ecma_set_typedarray_element (&info, value, num); } break; } @@ -1929,12 +1955,17 @@ ecma_op_object_get_own_property_descriptor (ecma_object_t *object_p, /**< the ob #endif /* JERRY_BUILTIN_PROXY */ ecma_property_ref_t property_ref; - + property_ref.virtual_value = ECMA_VALUE_EMPTY; ecma_property_t property = ecma_op_object_get_own_property (object_p, property_name_p, &property_ref, ECMA_PROPERTY_GET_VALUE); + if (ECMA_IS_VALUE_ERROR (property_ref.virtual_value)) + { + return property_ref.virtual_value; + } + if (property == ECMA_PROPERTY_TYPE_NOT_FOUND || property == ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP) { return ECMA_VALUE_FALSE; diff --git a/jerry-core/ecma/operations/ecma-typedarray-object.c b/jerry-core/ecma/operations/ecma-typedarray-object.c index 41c1b67a6..ca7b89003 100644 --- a/jerry-core/ecma/operations/ecma-typedarray-object.c +++ b/jerry-core/ecma/operations/ecma-typedarray-object.c @@ -632,10 +632,23 @@ ecma_get_typedarray_getter_fn (ecma_typedarray_type_t typedarray_id) * @return ecma_number_t: the value of the element */ extern inline ecma_value_t JERRY_ATTR_ALWAYS_INLINE -ecma_get_typedarray_element (lit_utf8_byte_t *src_p, - ecma_typedarray_type_t typedarray_id) +ecma_get_typedarray_element (ecma_typedarray_info_t *info_p, + ecma_number_t num) { - return ecma_typedarray_getters[typedarray_id](src_p); + if (ecma_arraybuffer_is_detached (info_p->array_buffer_p)) + { + return ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_arraybuffer_is_detached)); + } + + if (!ecma_op_is_integer (num) + || num >= info_p->length + || num < 0 + || (ecma_number_is_negative (num) && ecma_number_is_zero (num))) + { + return ECMA_VALUE_UNDEFINED; + } + uint32_t byte_pos = (uint32_t) num << info_p->shift; + return ecma_typedarray_getters[info_p->id](info_p->buffer_p + byte_pos); } /* ecma_get_typedarray_element */ /** @@ -653,11 +666,48 @@ ecma_get_typedarray_setter_fn (ecma_typedarray_type_t typedarray_id) * set typedarray's element value */ extern inline ecma_value_t JERRY_ATTR_ALWAYS_INLINE -ecma_set_typedarray_element (lit_utf8_byte_t *dst_p, +ecma_set_typedarray_element (ecma_typedarray_info_t *info_p, ecma_value_t value, - ecma_typedarray_type_t typedarray_id) + ecma_number_t num) { - return ecma_typedarray_setters[typedarray_id](dst_p, value); + ecma_value_t to_num; + if (ECMA_TYPEDARRAY_IS_BIGINT_TYPE (info_p->id)) + { + to_num = ecma_bigint_to_bigint (value, false); + + if (ECMA_IS_VALUE_ERROR (to_num)) + { + return to_num; + } + } + else + { + ecma_number_t result_num; + to_num = ecma_op_to_numeric (value, &result_num, ECMA_TO_NUMERIC_NO_OPTS); + + if (ECMA_IS_VALUE_ERROR (to_num)) + { + return to_num; + } + } + + if (ecma_arraybuffer_is_detached (info_p->array_buffer_p)) + { + ecma_free_value (to_num); + return ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_arraybuffer_is_detached)); + } + + if (!ecma_op_is_integer (num) + || num >= info_p->length + || num < 0 + || (ecma_number_is_negative (num) && ecma_number_is_zero (num))) + { + ecma_free_value (to_num); + return ECMA_VALUE_FALSE; + } + ecma_free_value (to_num); + lit_utf8_byte_t *src_buffer = info_p->buffer_p + ((uint32_t) num << info_p->shift); + return ecma_typedarray_setters[info_p->id](src_buffer, value); } /* ecma_set_typedarray_element */ /** @@ -791,6 +841,12 @@ ecma_typedarray_create_object_with_length (uint32_t array_length, /**< length of ECMA_SET_NON_NULL_POINTER (new_arraybuffer_p->u2.prototype_cp, prototype_p); ecma_deref_object (prototype_p); + + if (ecma_arraybuffer_is_detached (src_buffer_p)) + { + ecma_deref_object (new_arraybuffer_p); + return ecma_raise_type_error (ECMA_ERR_MSG ("Maximum TypedArray size is reached")); + } } ecma_object_t *object_p = ecma_create_object (proto_p, @@ -1468,7 +1524,8 @@ ecma_typedarray_get_length (ecma_object_t *typedarray_p) /**< the pointer to the if (!(ext_object_p->u.cls.u2.typedarray_flags & ECMA_TYPEDARRAY_IS_EXTENDED)) { ecma_object_t *arraybuffer_p = ecma_get_object_from_value (ext_object_p->u.cls.u3.arraybuffer); - uint32_t buffer_length = ecma_arraybuffer_get_length (arraybuffer_p); + ecma_extended_object_t *arraybuffer_object_p = (ecma_extended_object_t *) arraybuffer_p; + uint32_t buffer_length = arraybuffer_object_p->u.cls.u3.length; uint8_t shift = ecma_typedarray_get_element_size_shift (typedarray_p); return buffer_length >> shift; @@ -1555,21 +1612,16 @@ ecma_op_create_typedarray (const ecma_value_t *arguments_list_p, /**< the arg li } else if (!ecma_is_value_object (arguments_list_p[0])) { - /* 22.2.1.2 */ - if (ecma_is_value_undefined (arguments_list_p[0])) - { - return ecma_raise_type_error (ECMA_ERR_MSG ("Length argument is undefined")); - } + ecma_number_t num = 0; - ecma_number_t num; - - if (ECMA_IS_VALUE_ERROR (ecma_op_to_number (arguments_list_p[0], &num))) + if (!ecma_is_value_undefined (arguments_list_p[0]) + && ECMA_IS_VALUE_ERROR (ecma_op_to_number (arguments_list_p[0], &num))) { return ECMA_VALUE_ERROR; } uint32_t length = ecma_number_to_uint32 (num); - if (num != ((ecma_number_t) length)) + if (ecma_number_is_infinity (num)) { ret = ecma_raise_range_error (ECMA_ERR_MSG ("Invalid TypedArray length")); } @@ -1610,6 +1662,10 @@ ecma_op_create_typedarray (const ecma_value_t *arguments_list_p, /**< the arg li return ECMA_VALUE_ERROR; } + if (ecma_number_is_negative (offset) && ecma_number_is_zero (offset)) + { + offset = 0; + } if (ecma_number_is_negative (offset) || fmod (offset, (1 << element_size_shift)) != 0) { /* ES2015 22.2.1.5: 9 - 10. */ @@ -1638,8 +1694,8 @@ ecma_op_create_typedarray (const ecma_value_t *arguments_list_p, /**< the arg li } else { - ecma_length_t new_length; - if (ECMA_IS_VALUE_ERROR (ecma_op_to_length (arg3, &new_length))) + ecma_number_t new_length; + if (ECMA_IS_VALUE_ERROR (ecma_op_to_index (arg3, &new_length))) { return ECMA_VALUE_ERROR; } @@ -1785,9 +1841,20 @@ ecma_op_typedarray_define_own_property (ecma_object_t *obj_p, /**< TypedArray ob if (!ecma_prop_name_is_symbol (prop_name_p)) { - uint32_t array_index = ecma_string_get_array_index (prop_name_p); + ecma_number_t num = ecma_string_to_number (prop_name_p); + bool is_same; + if (num <= 0) + { + is_same = true; + } + else + { + ecma_string_t *num_to_str = ecma_new_ecma_string_from_number (num); + is_same = ecma_compare_ecma_strings (prop_name_p, num_to_str); + ecma_deref_ecma_string (num_to_str); + } - if (array_index != ECMA_STRING_NOT_ARRAY_INDEX) + if (is_same) { if ((property_desc_p->flags & (JERRY_PROP_IS_GET_DEFINED | JERRY_PROP_IS_SET_DEFINED)) || ((property_desc_p->flags & (JERRY_PROP_IS_CONFIGURABLE_DEFINED | JERRY_PROP_IS_CONFIGURABLE)) @@ -1802,34 +1869,27 @@ ecma_op_typedarray_define_own_property (ecma_object_t *obj_p, /**< TypedArray ob ecma_typedarray_info_t info = ecma_typedarray_get_info (obj_p); - if (array_index >= info.length) + if (!ecma_op_is_integer (num) + || num >= info.length + || num < 0 + || (ecma_number_is_negative (num) && ecma_number_is_zero (num))) { - return ECMA_REJECT ((property_desc_p->flags & JERRY_PROP_SHOULD_THROW), "Invalid typed array index"); + return ECMA_VALUE_FALSE; } if (property_desc_p->flags & JERRY_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); + ecma_value_t set_element = ecma_set_typedarray_element (&info, property_desc_p->value, num); if (ECMA_IS_VALUE_ERROR (set_element)) { return set_element; } + } return ECMA_VALUE_TRUE; } - - 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 (is_same) - { - return ECMA_REJECT ((property_desc_p->flags & JERRY_PROP_SHOULD_THROW), "Invalid typed array index"); - } } return ecma_op_general_object_define_own_property (obj_p, prop_name_p, property_desc_p); diff --git a/jerry-core/ecma/operations/ecma-typedarray-object.h b/jerry-core/ecma/operations/ecma-typedarray-object.h index 08cdb1253..b3b9c7842 100644 --- a/jerry-core/ecma/operations/ecma-typedarray-object.h +++ b/jerry-core/ecma/operations/ecma-typedarray-object.h @@ -32,11 +32,11 @@ uint8_t ecma_typedarray_helper_get_shift_size (ecma_typedarray_type_t typedarray lit_magic_string_id_t ecma_get_typedarray_magic_string_id (ecma_typedarray_type_t typedarray_id); ecma_typedarray_getter_fn_t ecma_get_typedarray_getter_fn (ecma_typedarray_type_t typedarray_id); ecma_typedarray_setter_fn_t ecma_get_typedarray_setter_fn (ecma_typedarray_type_t typedarray_id); -ecma_value_t ecma_get_typedarray_element (lit_utf8_byte_t *src_p, - ecma_typedarray_type_t typedarray_id); -ecma_value_t ecma_set_typedarray_element (lit_utf8_byte_t *dst_p, +ecma_value_t ecma_get_typedarray_element (ecma_typedarray_info_t *info_p, + ecma_number_t num); +ecma_value_t ecma_set_typedarray_element (ecma_typedarray_info_t *info_p, ecma_value_t value, - ecma_typedarray_type_t typedarray_id); + ecma_number_t num); bool ecma_typedarray_helper_is_typedarray (ecma_builtin_id_t builtin_id); ecma_typedarray_type_t ecma_get_typedarray_id (ecma_object_t *obj_p); ecma_builtin_id_t ecma_typedarray_helper_get_prototype_id (ecma_typedarray_type_t typedarray_id); diff --git a/tests/jerry/es.next/typedarray-put.js b/tests/jerry/es.next/typedarray-put.js index 8462bd1b8..1a076d12f 100644 --- a/tests/jerry/es.next/typedarray-put.js +++ b/tests/jerry/es.next/typedarray-put.js @@ -28,7 +28,13 @@ var typedarrays = [ for (let ta of typedarrays) { for (let prop_name of [2, 5.1]) { - let set_value = 4.2; + var set_value = 4.2; + + if (ta.constructor === BigInt64Array || ta.constructor === BigUint64Array) + { + set_value = 4n; + } + (function () { "use strict"; let set_result = ta[prop_name] = set_value; diff --git a/tests/test262-esnext-excludelist.xml b/tests/test262-esnext-excludelist.xml index dfbaad204..7ca71941c 100644 --- a/tests/test262-esnext-excludelist.xml +++ b/tests/test262-esnext-excludelist.xml @@ -105,48 +105,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -8330,16 +8289,6 @@ - - - - - - - - - - @@ -8381,39 +8330,5 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/unit-core/test-typedarray.c b/tests/unit-core/test-typedarray.c index f500d58ec..3f8ca1a7b 100644 --- a/tests/unit-core/test-typedarray.c +++ b/tests/unit-core/test-typedarray.c @@ -457,10 +457,28 @@ static void test_property_by_index (test_entry_t test_entries[]) } jerry_value_t set_undefined = jerry_set_property_by_index (typedarray, 100, jerry_create_number (50)); - TEST_ASSERT (jerry_value_is_boolean (set_undefined) && !jerry_get_boolean_value (set_undefined)); - jerry_value_t get_undefined = jerry_get_property_by_index (typedarray, 100); - TEST_ASSERT (jerry_value_is_undefined (get_undefined)); + if (type == JERRY_TYPEDARRAY_BIGINT64 || type == JERRY_TYPEDARRAY_BIGUINT64) + { + TEST_ASSERT (jerry_value_is_error (set_undefined)); + } + else + { + TEST_ASSERT (jerry_value_is_boolean (set_undefined) && !jerry_get_boolean_value (set_undefined)); + } + + jerry_value_t get_undefined = jerry_get_property_by_index (typedarray, 100); + + if (type == JERRY_TYPEDARRAY_BIGINT64 || type == JERRY_TYPEDARRAY_BIGUINT64) + { + TEST_ASSERT (jerry_value_is_error (set_undefined)); + } + else + { + TEST_ASSERT (jerry_value_is_undefined (get_undefined)); + } + + TEST_ASSERT (jerry_value_is_undefined (get_undefined)); jerry_release_value (set_undefined); jerry_release_value (get_undefined); jerry_release_value (typedarray);