From 60cbc93cd7e3790ceeb9586911d50fb051f77c0f Mon Sep 17 00:00:00 2001 From: kisbg Date: Tue, 13 Apr 2021 13:37:04 +0200 Subject: [PATCH] Update TypedArray Builtin function (#4633) Also create TypedArray object with object method has been added. JerryScript-DCO-1.0-Signed-off-by: bence gabor kis kisbg@inf.u-szeged.hu --- .../ecma-builtin-array-prototype.c | 7 +- .../ecma-builtin-helpers-sort.c | 11 +- .../builtin-objects/ecma-builtin-helpers.h | 6 +- .../ecma-builtin-typedarray-prototype.c | 78 ++++- .../typedarray/ecma-builtin-typedarray.c | 21 +- .../ecma/operations/ecma-typedarray-object.c | 329 ++++++++++++++---- .../ecma/operations/ecma-typedarray-object.h | 14 +- tests/test262-esnext-excludelist.xml | 51 --- 8 files changed, 371 insertions(+), 146 deletions(-) diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c index 3a9435e3c..fbfbd66a3 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c @@ -981,8 +981,10 @@ ecma_builtin_array_prototype_object_slice (ecma_value_t arg1, /**< start */ static ecma_value_t ecma_builtin_array_prototype_object_sort_compare_helper (ecma_value_t lhs, /**< left value */ ecma_value_t rhs, /**< right value */ - ecma_value_t compare_func) /**< compare function */ + ecma_value_t compare_func, /**< compare function */ + ecma_object_t *array_buffer_p) /**< arrayBuffer */ { + JERRY_UNUSED (array_buffer_p); /* * ECMA-262 v5, 15.4.4.11 NOTE1: Because non-existent property values always * compare greater than undefined property values, and undefined always @@ -1171,7 +1173,8 @@ ecma_builtin_array_prototype_object_sort (ecma_value_t this_arg, /**< this argum ecma_value_t sort_value = ecma_builtin_helper_array_merge_sort_helper (values_buffer, (uint32_t) (copied_num), arg1, - sort_cb); + sort_cb, + NULL); if (ECMA_IS_VALUE_ERROR (sort_value)) { goto clean_up; diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-sort.c b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-sort.c index 88d88e4b2..2cf3621d8 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-sort.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-sort.c @@ -33,7 +33,8 @@ ecma_builtin_helper_array_merge_sort_bottom_up (ecma_value_t *source_array_p, /* uint32_t end_idx, /**< second array end */ ecma_value_t *output_array_p, /**< output array */ ecma_value_t compare_func, /**< compare function */ - const ecma_builtin_helper_sort_compare_fn_t sort_cb) /**< sorting cb */ + const ecma_builtin_helper_sort_compare_fn_t sort_cb, /**< sorting cb */ + ecma_object_t *array_buffer_p) /* array_buffer_p */ { ecma_value_t ret_value = ECMA_VALUE_EMPTY; uint32_t i = left_idx, j = right_idx; @@ -44,7 +45,7 @@ ecma_builtin_helper_array_merge_sort_bottom_up (ecma_value_t *source_array_p, /* if (i < right_idx && j < end_idx) { - compare_value = sort_cb (source_array_p[i], source_array_p[j], compare_func); + compare_value = sort_cb (source_array_p[i], source_array_p[j], compare_func, array_buffer_p); if (ECMA_IS_VALUE_ERROR (compare_value)) { ret_value = ECMA_VALUE_ERROR; @@ -78,7 +79,8 @@ ecma_value_t ecma_builtin_helper_array_merge_sort_helper (ecma_value_t *array_p, /**< array to sort */ uint32_t length, /**< length */ ecma_value_t compare_func, /**< compare function */ - const ecma_builtin_helper_sort_compare_fn_t sort_cb) /**< sorting cb */ + const ecma_builtin_helper_sort_compare_fn_t sort_cb, /**< sorting cb */ + ecma_object_t *array_buffer_p) /**< arrayBuffer */ { ecma_value_t ret_value = ECMA_VALUE_EMPTY; JMEM_DEFINE_LOCAL_ARRAY (dest_array_p, length, ecma_value_t); @@ -112,7 +114,8 @@ ecma_builtin_helper_array_merge_sort_helper (ecma_value_t *array_p, /**< array t e, dest_array_p, compare_func, - sort_cb); + sort_cb, + array_buffer_p); if (ECMA_IS_VALUE_ERROR (ret_value)) { break; diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h index fc95c3be1..45dd5b845 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h @@ -239,12 +239,14 @@ ecma_builtin_helper_error_dispatch_call (jerry_error_t error_type, const ecma_va */ typedef ecma_value_t (*ecma_builtin_helper_sort_compare_fn_t) (ecma_value_t lhs, /**< left value */ ecma_value_t rhs, /**< right value */ - ecma_value_t compare_func); /**< compare function */ + ecma_value_t compare_func, /**< compare function */ + ecma_object_t *array_buffer_p); /**< arrayBuffer */ ecma_value_t ecma_builtin_helper_array_merge_sort_helper (ecma_value_t *array_p, uint32_t length, ecma_value_t compare_func, - const ecma_builtin_helper_sort_compare_fn_t sort_cb); + const ecma_builtin_helper_sort_compare_fn_t sort_cb, + ecma_object_t *array_buffer_p); /** * @} 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 6d1e1aae9..f5dd9a715 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 @@ -151,6 +151,12 @@ ecma_builtin_typedarray_prototype_exec_routine (ecma_value_t this_arg, /**< this return call_value; } + if (ecma_arraybuffer_is_detached (info_p->array_buffer_p)) + { + ecma_free_value (call_value); + return ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_arraybuffer_is_detached)); + } + bool to_bool_result = ecma_op_to_boolean (call_value); ecma_free_value (call_value); @@ -238,6 +244,13 @@ ecma_builtin_typedarray_prototype_map (ecma_value_t this_arg, /**< this object * return mapped_value; } + if (ecma_arraybuffer_is_detached (src_info_p->array_buffer_p)) + { + ecma_free_value (mapped_value); + ecma_free_value (new_typedarray); + return ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_arraybuffer_is_detached)); + } + uint32_t target_byte_pos = index << target_info.shift; ecma_value_t set_element = target_typedarray_setter_cb (target_info.buffer_p + target_byte_pos, mapped_value); ecma_free_value (mapped_value); @@ -341,6 +354,12 @@ ecma_builtin_typedarray_prototype_reduce_with_direction (ecma_value_t this_arg, return call_value; } + if (ecma_arraybuffer_is_detached (info_p->array_buffer_p)) + { + ecma_free_value (call_value); + return ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_arraybuffer_is_detached)); + } + accumulator = call_value; if (is_right) @@ -416,6 +435,13 @@ ecma_builtin_typedarray_prototype_filter (ecma_value_t this_arg, /**< this objec goto cleanup; } + if (ecma_arraybuffer_is_detached (info_p->array_buffer_p)) + { + ecma_free_value (call_value); + ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_arraybuffer_is_detached)); + goto cleanup; + } + if (ecma_op_to_boolean (call_value)) { memcpy (pass_value_p, info_p->buffer_p + byte_pos, info_p->element_size); @@ -693,6 +719,13 @@ ecma_builtin_typedarray_prototype_set (ecma_value_t this_arg, /**< this argument ecma_free_value (elem); + if (ecma_arraybuffer_is_detached (arraybuffer_p)) + { + ecma_deref_object (source_obj_p); + ecma_free_value (value_to_set); + return ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_arraybuffer_is_detached)); + } + ecma_value_t set_element = target_typedarray_setter_cb (target_info.buffer_p + target_byte_index, value_to_set); ecma_free_value (value_to_set); @@ -1008,6 +1041,11 @@ ecma_builtin_typedarray_prototype_fill (ecma_value_t this_arg, /**< this object uint32_t byte_index = begin_index_uint32 * info_p->element_size; uint32_t limit = byte_index + subarray_length * info_p->element_size; + if (ecma_arraybuffer_is_detached (info_p->array_buffer_p)) + { + return ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_arraybuffer_is_detached)); + } + while (byte_index < limit) { ecma_value_t set_element = typedarray_setter_cb (info_p->buffer_p + byte_index, value_to_set); @@ -1038,7 +1076,8 @@ ecma_builtin_typedarray_prototype_fill (ecma_value_t this_arg, /**< this object static ecma_value_t ecma_builtin_typedarray_prototype_sort_compare_helper (ecma_value_t lhs, /**< left value */ ecma_value_t rhs, /**< right value */ - ecma_value_t compare_func) /**< compare function */ + ecma_value_t compare_func, /**< compare function */ + ecma_object_t *array_buffer_p) /**< array buffer */ { if (ecma_is_value_undefined (compare_func)) { @@ -1110,6 +1149,12 @@ ecma_builtin_typedarray_prototype_sort_compare_helper (ecma_value_t lhs, /**< le return number_result; } + if (ecma_arraybuffer_is_detached (array_buffer_p)) + { + ecma_free_value (number_result); + return ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_arraybuffer_is_detached)); + } + // If the coerced value can't be represented as a Number, compare them as equals. if (ecma_number_is_nan (ret_num)) { @@ -1164,7 +1209,8 @@ ecma_builtin_typedarray_prototype_sort (ecma_value_t this_arg, /**< this argumen ecma_value_t sort_value = ecma_builtin_helper_array_merge_sort_helper (values_buffer, (uint32_t) (info_p->length), compare_func, - sort_cb); + sort_cb, + info_p->array_buffer_p); if (ECMA_IS_VALUE_ERROR (sort_value)) { @@ -1174,6 +1220,11 @@ ecma_builtin_typedarray_prototype_sort (ecma_value_t this_arg, /**< this argumen JERRY_ASSERT (sort_value == ECMA_VALUE_EMPTY); + if (ecma_arraybuffer_is_detached (info_p->array_buffer_p)) + { + return ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_arraybuffer_is_detached)); + } + ecma_typedarray_setter_fn_t typedarray_setter_cb = ecma_get_typedarray_setter_fn (info_p->id); byte_index = 0; @@ -1248,6 +1299,13 @@ ecma_builtin_typedarray_prototype_find_helper (ecma_value_t this_arg, /**< this return call_value; } + if (ecma_arraybuffer_is_detached (info_p->array_buffer_p)) + { + ecma_free_value (element_value); + ecma_free_value (call_value); + return ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_arraybuffer_is_detached)); + } + bool call_result = ecma_op_to_boolean (call_value); ecma_free_value (call_value); @@ -1466,6 +1524,11 @@ ecma_builtin_typedarray_prototype_copy_within (ecma_value_t this_arg, /**< this } } + if (ecma_arraybuffer_is_detached (info_p->array_buffer_p)) + { + return ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_arraybuffer_is_detached)); + } + if (relative_target >= info_p->length || relative_start >= relative_end || relative_end == 0) { return ecma_copy_value (this_arg); @@ -1538,6 +1601,12 @@ ecma_builtin_typedarray_prototype_slice (ecma_value_t this_arg, /**< this argume { ecma_object_t *new_typedarray_p = ecma_get_object_from_value (new_typedarray); + if (ecma_arraybuffer_is_detached (info_p->array_buffer_p)) + { + ecma_deref_object (new_typedarray_p); + return ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_arraybuffer_is_detached)); + } + lit_utf8_byte_t *new_typedarray_buffer_p = ecma_typedarray_get_buffer (new_typedarray_p); uint32_t src_byte_index = (relative_start * info_p->element_size); @@ -1673,6 +1742,11 @@ ecma_builtin_typedarray_prototype_includes (ecma_typedarray_info_t *info_p, /**< uint32_t search_pos = (uint32_t) from_index * info_p->element_size; + if (ecma_arraybuffer_is_detached (info_p->array_buffer_p)) + { + return ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_arraybuffer_is_detached)); + } + while (search_pos < limit) { ecma_value_t element = getter_cb (info_p->buffer_p + search_pos); 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 247616606..8d3017416 100644 --- a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray.c +++ b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray.c @@ -91,25 +91,10 @@ ecma_builtin_typedarray_from (ecma_value_t this_arg, /**< 'this' argument */ } } - 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); - - return ecma_op_typedarray_from (source, + return ecma_op_typedarray_from (this_arg, + source, map_fn, - this_in_fn, - proto_p, - element_size_shift, - typedarray_id); + this_in_fn); } /* ecma_builtin_typedarray_from */ diff --git a/jerry-core/ecma/operations/ecma-typedarray-object.c b/jerry-core/ecma/operations/ecma-typedarray-object.c index b0e0699c2..037a54afb 100644 --- a/jerry-core/ecma/operations/ecma-typedarray-object.c +++ b/jerry-core/ecma/operations/ecma-typedarray-object.c @@ -954,6 +954,12 @@ ecma_op_typedarray_from_helper (ecma_value_t this_val, /**< this_arg for the abo ecma_typedarray_setter_fn_t setter_cb) /**< setter callback function */ { ecma_value_t mapped_value; + + if (!ecma_is_value_found (current_value)) + { + current_value = ECMA_VALUE_UNDEFINED; + } + if (func_object_p != NULL) { /* 17.d 17.f */ @@ -962,8 +968,8 @@ ecma_op_typedarray_from_helper (ecma_value_t this_val, /**< this_arg for the abo ecma_value_t cb_value = ecma_op_function_call (func_object_p, this_val, call_args, 2); - ecma_free_value (current_index); ecma_free_value (current_value); + ecma_free_value (current_index); if (ECMA_IS_VALUE_ERROR (cb_value)) { @@ -996,63 +1002,46 @@ ecma_op_typedarray_from_helper (ecma_value_t this_val, /**< this_arg for the abo /** * Create a TypedArray object by transforming from an array-like object or iterable object * - * See also: ES2015 22.2.2.1 + * See also: ES11 22.2.4.4 * * @return ecma value of the new typedarray object * Returned value must be freed with ecma_free_value */ ecma_value_t -ecma_op_typedarray_from (ecma_value_t items_val, /**< the source array-like object */ - ecma_value_t map_fn_val, /**< map function */ - ecma_value_t this_val, /**< this_arg for the above map function */ - ecma_object_t *proto_p, /**< prototype object */ - uint8_t element_size_shift, /**< the size shift of the element length */ - ecma_typedarray_type_t typedarray_id) /**< id of the typedarray */ +ecma_typedarray_create_object_with_object (ecma_value_t items_val, /**< the source array-like object */ + ecma_object_t *proto_p, /**< prototype object */ + uint8_t element_size_shift, /**< the size shift of the element length */ + ecma_typedarray_type_t typedarray_id) /**< id of the typedarray */ { - /* 3 */ - JERRY_ASSERT (ecma_op_is_callable (map_fn_val) || ecma_is_value_undefined (map_fn_val)); - /* 4-5 */ - ecma_object_t *func_object_p = NULL; - if (!ecma_is_value_undefined (map_fn_val)) - { - func_object_p = ecma_get_object_from_value (map_fn_val); - } - - /* 6 */ + /* 5 */ ecma_value_t using_iterator = ecma_op_get_method_by_symbol_id (items_val, LIT_GLOBAL_SYMBOL_ITERATOR); - /* 7 */ if (ECMA_IS_VALUE_ERROR (using_iterator)) { return using_iterator; } - /* 8 */ + /* 6 */ if (!ecma_is_value_undefined (using_iterator)) { - /* 8.a */ + /* 6.a */ ecma_value_t next_method; ecma_value_t iterator = ecma_op_get_iterator (items_val, using_iterator, &next_method); ecma_free_value (using_iterator); - /* 8.b */ if (ECMA_IS_VALUE_ERROR (iterator)) { return iterator; } - /* 8.c */ ecma_collection_t *values_p = ecma_new_collection (); ecma_value_t ret_value = ECMA_VALUE_EMPTY; - /* 8.e */ while (true) { - /* 8.e.i */ ecma_value_t next = ecma_op_iterator_step (iterator, next_method); - /* 8.e.ii */ if (ECMA_IS_VALUE_ERROR (next)) { ret_value = next; @@ -1064,7 +1053,6 @@ ecma_op_typedarray_from (ecma_value_t items_val, /**< the source array-like obje break; } - /* 8.e.iii */ ecma_value_t next_value = ecma_op_iterator_value (next); ecma_free_value (next); @@ -1086,14 +1074,13 @@ ecma_op_typedarray_from (ecma_value_t items_val, /**< the source array-like obje return ret_value; } - /* 8.g */ + /* 8.c */ ecma_value_t new_typedarray = ecma_typedarray_create_object_with_length (values_p->item_count, NULL, proto_p, element_size_shift, typedarray_id); - /* 8.h */ if (ECMA_IS_VALUE_ERROR (new_typedarray)) { ecma_collection_free (values_p); @@ -1106,10 +1093,230 @@ ecma_op_typedarray_from (ecma_value_t items_val, /**< the source array-like obje ret_value = ecma_make_object_value (new_typedarray_p); - /* 8.j */ + /* 8.e */ for (uint32_t index = 0; index < values_p->item_count; index++) { - ecma_value_t set_value = ecma_op_typedarray_from_helper (this_val, + ecma_value_t set_value = ecma_op_typedarray_from_helper (ECMA_VALUE_UNDEFINED, + values_p->buffer_p[index], + index, + NULL, + &info, + setter_cb); + + if (ECMA_IS_VALUE_ERROR (set_value)) + { + for (uint32_t j = index + 1; j < values_p->item_count; j++) + { + ecma_free_value (values_p->buffer_p[j]); + } + + ret_value = set_value; + break; + } + } + + ecma_collection_destroy (values_p); + + if (ECMA_IS_VALUE_ERROR (ret_value)) + { + ecma_deref_object (new_typedarray_p); + } + + return ret_value; + } + + /* 8 */ + ecma_value_t arraylike_object_val = ecma_op_to_object (items_val); + + if (ECMA_IS_VALUE_ERROR (arraylike_object_val)) + { + return arraylike_object_val; + } + + ecma_object_t *arraylike_object_p = ecma_get_object_from_value (arraylike_object_val); + + /* 9 */ + ecma_length_t length_index; + ecma_value_t len_value = ecma_op_object_get_length (arraylike_object_p, &length_index); + + if (ECMA_IS_VALUE_ERROR (len_value)) + { + ecma_deref_object (arraylike_object_p); + return len_value; + } + + if (length_index >= UINT32_MAX) + { + ecma_deref_object (arraylike_object_p); + return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid TypedArray length")); + } + + uint32_t len = (uint32_t) length_index; + + /* 10 */ + ecma_value_t new_typedarray = ecma_typedarray_create_object_with_length (len, + NULL, + proto_p, + element_size_shift, + typedarray_id); + + if (ECMA_IS_VALUE_ERROR (new_typedarray)) + { + ecma_deref_object (arraylike_object_p); + return new_typedarray; + } + + ecma_object_t *new_typedarray_p = ecma_get_object_from_value (new_typedarray); + ecma_typedarray_info_t info = ecma_typedarray_get_info (new_typedarray_p); + ecma_typedarray_setter_fn_t setter_cb = ecma_get_typedarray_setter_fn (info.id); + ecma_value_t ret_value = ecma_make_object_value (new_typedarray_p); + + /* 12 */ + for (uint32_t index = 0; index < len; index++) + { + ecma_value_t current_value = ecma_op_object_find_by_index (arraylike_object_p, index); + + if (ECMA_IS_VALUE_ERROR (current_value)) + { + ret_value = current_value; + break; + } + + ecma_value_t set_value = ecma_op_typedarray_from_helper (ECMA_VALUE_UNDEFINED, + current_value, + index, + NULL, + &info, + setter_cb); + + if (ECMA_IS_VALUE_ERROR (set_value)) + { + ret_value = set_value; + break; + } + } + + ecma_deref_object (arraylike_object_p); + + if (ECMA_IS_VALUE_ERROR (ret_value)) + { + ecma_deref_object (new_typedarray_p); + } + + return ret_value; +} /* ecma_typedarray_create_object_with_object */ + +/** + * Create a TypedArray object by transforming from an array-like object or iterable object + * + * See also: ES11 22.2.2.1 + * + * @return ecma value of the new typedarray object + * Returned value must be freed with ecma_free_value + */ +ecma_value_t +ecma_op_typedarray_from (ecma_value_t this_val, /**< this value */ + ecma_value_t source_val, /**< source value */ + ecma_value_t map_fn_val, /**< mapped function value */ + ecma_value_t this_arg) /**< this argument */ +{ + JERRY_UNUSED (this_arg); + /* 3 */ + JERRY_ASSERT (ecma_op_is_callable (map_fn_val) || ecma_is_value_undefined (map_fn_val)); + + /* 4 */ + ecma_object_t *func_object_p = NULL; + + if (!ecma_is_value_undefined (map_fn_val)) + { + func_object_p = ecma_get_object_from_value (map_fn_val); + } + + /* 5 */ + ecma_value_t using_iterator = ecma_op_get_method_by_symbol_id (source_val, LIT_GLOBAL_SYMBOL_ITERATOR); + + if (ECMA_IS_VALUE_ERROR (using_iterator)) + { + return using_iterator; + } + + /* 6 */ + if (!ecma_is_value_undefined (using_iterator)) + { + /* 6.a */ + ecma_value_t next_method; + ecma_value_t iterator = ecma_op_get_iterator (source_val, using_iterator, &next_method); + ecma_free_value (using_iterator); + + /* 6.b */ + if (ECMA_IS_VALUE_ERROR (iterator)) + { + return iterator; + } + + /* 6.c */ + ecma_collection_t *values_p = ecma_new_collection (); + ecma_value_t ret_value = ECMA_VALUE_EMPTY; + + /* 6.e */ + while (true) + { + ecma_value_t next = ecma_op_iterator_step (iterator, next_method); + + if (ECMA_IS_VALUE_ERROR (next)) + { + ret_value = next; + break; + } + + if (next == ECMA_VALUE_FALSE) + { + break; + } + + ecma_value_t next_value = ecma_op_iterator_value (next); + ecma_free_value (next); + + if (ECMA_IS_VALUE_ERROR (next_value)) + { + ret_value = next_value; + break; + } + + ecma_collection_push_back (values_p, next_value); + } + + ecma_free_value (iterator); + ecma_free_value (next_method); + + if (ECMA_IS_VALUE_ERROR (ret_value)) + { + ecma_collection_free (values_p); + return ret_value; + } + + /* 6.c */ + ecma_object_t *constructor_obj_p = ecma_get_object_from_value (this_val); + ecma_value_t len_val = ecma_make_uint32_value (values_p->item_count); + ecma_value_t new_typedarray = ecma_typedarray_create (constructor_obj_p, &len_val, 1); + ecma_free_value (len_val); + + if (ECMA_IS_VALUE_ERROR (new_typedarray)) + { + ecma_collection_free (values_p); + return new_typedarray; + } + + ecma_object_t *new_typedarray_p = ecma_get_object_from_value (new_typedarray); + ecma_typedarray_info_t info = ecma_typedarray_get_info (new_typedarray_p); + ecma_typedarray_setter_fn_t setter_cb = ecma_get_typedarray_setter_fn (info.id); + + ret_value = ecma_make_object_value (new_typedarray_p); + + /* 6.e */ + for (uint32_t index = 0; index < values_p->item_count; index++) + { + ecma_value_t set_value = ecma_op_typedarray_from_helper (this_arg, values_p->buffer_p[index], index, func_object_p, @@ -1138,8 +1345,8 @@ ecma_op_typedarray_from (ecma_value_t items_val, /**< the source array-like obje return ret_value; } - /* 10 */ - ecma_value_t arraylike_object_val = ecma_op_to_object (items_val); + /* 8 */ + ecma_value_t arraylike_object_val = ecma_op_to_object (source_val); if (ECMA_IS_VALUE_ERROR (arraylike_object_val)) { @@ -1148,7 +1355,7 @@ ecma_op_typedarray_from (ecma_value_t items_val, /**< the source array-like obje ecma_object_t *arraylike_object_p = ecma_get_object_from_value (arraylike_object_val); - /* 12 */ + /* 9 */ ecma_length_t length_index; ecma_value_t len_value = ecma_op_object_get_length (arraylike_object_p, &length_index); @@ -1166,12 +1373,11 @@ ecma_op_typedarray_from (ecma_value_t items_val, /**< the source array-like obje uint32_t len = (uint32_t) length_index; - /* 14 */ - ecma_value_t new_typedarray = ecma_typedarray_create_object_with_length (len, - NULL, - proto_p, - element_size_shift, - typedarray_id); + /* 10 */ + ecma_object_t *constructor_obj_p = ecma_get_object_from_value (this_val); + ecma_value_t len_val = ecma_make_uint32_value (len); + ecma_value_t new_typedarray = ecma_typedarray_create (constructor_obj_p, &len_val, 1); + ecma_free_value (len_val); if (ECMA_IS_VALUE_ERROR (new_typedarray)) { @@ -1184,7 +1390,7 @@ ecma_op_typedarray_from (ecma_value_t items_val, /**< the source array-like obje ecma_typedarray_setter_fn_t setter_cb = ecma_get_typedarray_setter_fn (info.id); ecma_value_t ret_value = ecma_make_object_value (new_typedarray_p); - /* 17 */ + /* 12 */ for (uint32_t index = 0; index < len; index++) { ecma_value_t current_value = ecma_op_object_find_by_index (arraylike_object_p, index); @@ -1195,20 +1401,17 @@ ecma_op_typedarray_from (ecma_value_t items_val, /**< the source array-like obje break; } - if (ecma_is_value_found (current_value)) - { - ecma_value_t set_value = ecma_op_typedarray_from_helper (this_val, - current_value, - index, - func_object_p, - &info, - setter_cb); + ecma_value_t set_value = ecma_op_typedarray_from_helper (this_arg, + current_value, + index, + func_object_p, + &info, + setter_cb); - if (ECMA_IS_VALUE_ERROR (set_value)) - { - ret_value = set_value; - break; - } + if (ECMA_IS_VALUE_ERROR (set_value)) + { + ret_value = set_value; + break; } } @@ -1471,13 +1674,10 @@ ecma_op_create_typedarray (const ecma_value_t *arguments_list_p, /**< the arg li else { /* 22.2.1.4 */ - ecma_value_t undef = ECMA_VALUE_UNDEFINED; - ret = ecma_op_typedarray_from (arguments_list_p[0], - undef, - undef, - proto_p, - element_size_shift, - typedarray_id); + ret = ecma_typedarray_create_object_with_object (arguments_list_p[0], + proto_p, + element_size_shift, + typedarray_id); } } @@ -1669,6 +1869,13 @@ ecma_typedarray_create (ecma_object_t *constructor_p, /**< constructor function ecma_object_t *typedarray_p = ecma_get_object_from_value (ret_val); + ecma_object_t *arraybuffer_p = ecma_typedarray_get_arraybuffer (ecma_get_object_from_value (ret_val)); + if (ecma_arraybuffer_is_detached (arraybuffer_p)) + { + ecma_deref_object (typedarray_p); + return ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_arraybuffer_is_detached)); + } + if ((arguments_list_len == 1) && (ecma_is_value_number (arguments_list_p[0]))) { ecma_number_t num = ecma_get_number_from_value (arguments_list_p[0]); diff --git a/jerry-core/ecma/operations/ecma-typedarray-object.h b/jerry-core/ecma/operations/ecma-typedarray-object.h index 4d36391b3..08cdb1253 100644 --- a/jerry-core/ecma/operations/ecma-typedarray-object.h +++ b/jerry-core/ecma/operations/ecma-typedarray-object.h @@ -43,12 +43,10 @@ ecma_builtin_id_t ecma_typedarray_helper_get_prototype_id (ecma_typedarray_type_ ecma_builtin_id_t ecma_typedarray_helper_get_constructor_id (ecma_typedarray_type_t typedarray_id); ecma_typedarray_type_t ecma_typedarray_helper_builtin_to_typedarray_id (ecma_builtin_id_t builtin_id); -ecma_value_t ecma_op_typedarray_from (ecma_value_t items_val, - ecma_value_t map_fn_val, - ecma_value_t this_val, - ecma_object_t *proto_p, - uint8_t element_size_shift, - ecma_typedarray_type_t typedarray_id); +ecma_value_t ecma_op_typedarray_from (ecma_value_t this_val, + ecma_value_t source_val, + ecma_value_t mapfn_val, + ecma_value_t this_arg); uint32_t ecma_typedarray_get_length (ecma_object_t *typedarray_p); uint32_t ecma_typedarray_get_offset (ecma_object_t *typedarray_p); lit_utf8_byte_t *ecma_typedarray_get_buffer (ecma_object_t *typedarray_p); @@ -78,6 +76,10 @@ ecma_value_t ecma_typedarray_create_object_with_length (uint32_t array_length, ecma_object_t *proto_p, uint8_t element_size_shift, ecma_typedarray_type_t typedarray_id); +ecma_value_t ecma_typedarray_create_object_with_object (ecma_value_t items_val, + ecma_object_t *proto_p, + uint8_t element_size_shift, + ecma_typedarray_type_t typedarray_id); ecma_value_t ecma_typedarray_create (ecma_object_t *constructor_p, ecma_value_t *arguments_list_p, uint32_t arguments_list_len); ecma_value_t ecma_typedarray_species_create (ecma_value_t this_arg, diff --git a/tests/test262-esnext-excludelist.xml b/tests/test262-esnext-excludelist.xml index 458d92416..a75a184bf 100644 --- a/tests/test262-esnext-excludelist.xml +++ b/tests/test262-esnext-excludelist.xml @@ -106,12 +106,6 @@ - - - - - - @@ -128,14 +122,6 @@ - - - - - - - - @@ -8396,43 +8382,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -