From 91baa17c515cb379379458006b9d870d6f4250ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B3th=20B=C3=A9la?= Date: Fri, 15 Jan 2021 15:21:50 +0100 Subject: [PATCH] Update TypedArray builtins to latest standard (#4210) - Introduce `ecma_typedarray_species_create` and `ecma_typedarray_create` - Update Typedarray's filter method JerryScript-DCO-1.0-Signed-off-by: Bela Toth tbela@inf.u-szeged.hu --- .../ecma-builtin-typedarray-prototype.c | 25 +++-- .../ecma/operations/ecma-typedarray-object.c | 103 ++++++++++++++++- .../ecma/operations/ecma-typedarray-object.h | 5 + tests/test262-esnext-excludelist.xml | 105 +----------------- 4 files changed, 124 insertions(+), 114 deletions(-) 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 e7cd8f1d6..92627add8 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 @@ -204,7 +204,9 @@ ecma_builtin_typedarray_prototype_map (ecma_value_t this_arg, /**< this object * ecma_object_t *func_object_p = ecma_get_object_from_value (cb_func_val); // TODO: 22.2.3.18, 7-8. - ecma_value_t new_typedarray = ecma_op_create_typedarray_with_type_and_length (src_info_p->id, src_info_p->length); + ecma_value_t len = ecma_make_number_value (src_info_p->length); + ecma_value_t new_typedarray = ecma_typedarray_species_create (this_arg, &len, 1); + ecma_free_value (len); if (ECMA_IS_VALUE_ERROR (new_typedarray)) { @@ -427,7 +429,9 @@ ecma_builtin_typedarray_prototype_filter (ecma_value_t this_arg, /**< this objec uint32_t pass_num = (uint32_t) ((pass_value_p - pass_value_list_p) >> info_p->shift); - ret_value = ecma_op_create_typedarray_with_type_and_length (info_p->id, pass_num); + ecma_value_t collected = ecma_make_number_value (pass_num); + ret_value = ecma_typedarray_species_create (this_arg, &collected, 1); + ecma_free_value (collected); if (!ECMA_IS_VALUE_ERROR (ret_value)) { @@ -868,7 +872,8 @@ cleanup: * Returned value must be freed with ecma_free_value. */ static ecma_value_t -ecma_builtin_typedarray_prototype_subarray (ecma_typedarray_info_t *info_p, /**< object info */ +ecma_builtin_typedarray_prototype_subarray (ecma_value_t this_arg, /**< this object */ + ecma_typedarray_info_t *info_p, /**< object info */ ecma_value_t begin, /**< begin */ ecma_value_t end) /**< end */ { @@ -918,7 +923,7 @@ ecma_builtin_typedarray_prototype_subarray (ecma_typedarray_info_t *info_p, /**< ecma_make_uint32_value (subarray_length) }; - ret_value = ecma_typedarray_helper_dispatch_construct (arguments_p, 3, info_p->id); + ret_value = ecma_typedarray_species_create (this_arg, arguments_p, 3); ecma_free_value (arguments_p[1]); ecma_free_value (arguments_p[2]); @@ -1489,7 +1494,8 @@ ecma_builtin_typedarray_prototype_copy_within (ecma_value_t this_arg, /**< this * Returned value must be freed with ecma_free_value. */ static ecma_value_t -ecma_builtin_typedarray_prototype_slice (ecma_typedarray_info_t *info_p, /**< object info */ +ecma_builtin_typedarray_prototype_slice (ecma_value_t this_arg, /**< this argument */ + ecma_typedarray_info_t *info_p, /**< object info */ const ecma_value_t args[], /**< arguments list */ uint32_t args_number) /**< number of arguments */ { @@ -1518,8 +1524,10 @@ ecma_builtin_typedarray_prototype_slice (ecma_typedarray_info_t *info_p, /**< ob int32_t distance = (int32_t) (relative_end - relative_start); uint32_t count = distance > 0 ? (uint32_t) distance : 0; + ecma_value_t len = ecma_make_number_value (count); // TODO: 22.2.3.23, 12-13. - ecma_value_t new_typedarray = ecma_op_create_typedarray_with_type_and_length (info_p->id, count); + ecma_value_t new_typedarray = ecma_typedarray_species_create (this_arg, &len, 1); + ecma_free_value (len); if (ECMA_IS_VALUE_ERROR (new_typedarray)) { @@ -1763,7 +1771,6 @@ ecma_builtin_typedarray_prototype_dispatch_routine (uint8_t builtin_routine_id, case ECMA_TYPEDARRAY_PROTOTYPE_ROUTINE_FILTER: { return ecma_builtin_typedarray_prototype_filter (this_arg, &info, arguments_list_p[0], arguments_list_p[1]); - } case ECMA_TYPEDARRAY_PROTOTYPE_ROUTINE_REVERSE: { @@ -1775,7 +1782,7 @@ ecma_builtin_typedarray_prototype_dispatch_routine (uint8_t builtin_routine_id, } case ECMA_TYPEDARRAY_PROTOTYPE_ROUTINE_SUBARRAY: { - return ecma_builtin_typedarray_prototype_subarray (&info, arguments_list_p[0], arguments_list_p[1]); + return ecma_builtin_typedarray_prototype_subarray (this_arg, &info, arguments_list_p[0], arguments_list_p[1]); } case ECMA_TYPEDARRAY_PROTOTYPE_ROUTINE_FILL: { @@ -1819,7 +1826,7 @@ ecma_builtin_typedarray_prototype_dispatch_routine (uint8_t builtin_routine_id, } case ECMA_TYPEDARRAY_PROTOTYPE_ROUTINE_SLICE: { - return ecma_builtin_typedarray_prototype_slice (&info, arguments_list_p, arguments_number); + return ecma_builtin_typedarray_prototype_slice (this_arg, &info, arguments_list_p, arguments_number); } case ECMA_TYPEDARRAY_PROTOTYPE_ROUTINE_TO_LOCALE_STRING: { diff --git a/jerry-core/ecma/operations/ecma-typedarray-object.c b/jerry-core/ecma/operations/ecma-typedarray-object.c index 08ff54557..a21f63759 100644 --- a/jerry-core/ecma/operations/ecma-typedarray-object.c +++ b/jerry-core/ecma/operations/ecma-typedarray-object.c @@ -1390,7 +1390,7 @@ ecma_op_create_typedarray (const ecma_value_t *arguments_list_p, /**< the arg li : ECMA_VALUE_UNDEFINED); ecma_number_t offset; - if (ECMA_IS_VALUE_ERROR (ecma_op_to_integer (arg2, &offset))) + if (ECMA_IS_VALUE_ERROR (ecma_op_to_index (arg2, &offset))) { return ECMA_VALUE_ERROR; } @@ -1616,6 +1616,107 @@ ecma_op_typedarray_define_index_prop (ecma_object_t *obj_p, /**< a TypedArray ob return ECMA_VALUE_TRUE; } /* ecma_op_typedarray_define_index_prop */ +/** + * Specify the creation of a new TypedArray + * object using a constructor function. + * + * See also: ES11 22.2.4.6 + * + * Used by: + * - ecma_typedarray_species_create + * + * @return ecma_value_t function object from created from constructor_p argument + */ + +ecma_value_t +ecma_typedarray_create (ecma_object_t *constructor_p, /**< constructor function */ + ecma_value_t *arguments_list_p, /**< argument list */ + uint32_t arguments_list_len) /**< length of argument list */ +{ + ecma_value_t ret_val = ecma_op_function_construct (constructor_p, + constructor_p, + arguments_list_p, + arguments_list_len); + if (ECMA_IS_VALUE_ERROR (ret_val)) + { + return ret_val; + } + + if (!ecma_is_typedarray (ret_val)) + { + ecma_free_value (ret_val); + return ecma_raise_type_error (ECMA_ERR_MSG ("Constructed object is not TypedArray.")); + } + + ecma_object_t *typedarray_p = ecma_get_object_from_value (ret_val); + + 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]); + ecma_typedarray_info_t info = ecma_typedarray_get_info (typedarray_p); + + if (info.length < num) + { + ecma_free_value (ret_val); + return ecma_raise_type_error (ECMA_ERR_MSG ("Constructed typedarray is smaller than filter call result")); + } + } + return ret_val; +} /* ecma_typedarray_create */ + +/* Specify the creation of a new TypedArray object + * using a constructor function that is derived from this_arg. + * + * See also: ES11 22.2.4.7 + * + * @return ecma value of the new typedarray object, constructed by default or species constructor + */ +ecma_value_t +ecma_typedarray_species_create (ecma_value_t this_arg, /**< this argument */ + ecma_value_t *arguments_list_p, /**< the arg list passed to typedarray construct */ + uint32_t arguments_list_len) /**< length of the the arg list */ +{ + ecma_object_t *typedarray_p = ecma_get_object_from_value (this_arg); + ecma_typedarray_info_t info = ecma_typedarray_get_info (typedarray_p); + + JERRY_ASSERT (ecma_is_typedarray (this_arg)); + + ecma_builtin_id_t default_constructor = ecma_typedarray_helper_get_constructor_id (info.id); + + ecma_value_t constructor = ecma_op_species_constructor (typedarray_p, default_constructor); + + if (ECMA_IS_VALUE_ERROR (constructor)) + { + return constructor; + } + + ecma_object_t *constructor_proto_p = ecma_get_object_from_value (constructor); + + ecma_value_t result = ecma_typedarray_create (constructor_proto_p, arguments_list_p, arguments_list_len); + ecma_deref_object (constructor_proto_p); + + if (ECMA_IS_VALUE_ERROR (result)) + { + return result; + } + +#if ENABLED (JERRY_BUILTIN_BIGINT) + ecma_object_t *result_p = ecma_get_object_from_value (result); + ecma_typedarray_info_t result_info = ecma_typedarray_get_info (result_p); + /* + * Check result_info.id to to be either bigint type if info.id is one + * or be neither of them is info.id is none of them as well. + */ + if (ECMA_TYPEDARRAY_IS_BIGINT_TYPE (info.id) ^ ECMA_TYPEDARRAY_IS_BIGINT_TYPE (result_info.id)) + { + ecma_free_value (result); + return ecma_raise_type_error (ECMA_ERR_MSG ("Source and result array does not match in [[ContentType]]")); + } +#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */ + + return result; +} /* ecma_typedarray_species_create */ + /** * Create a typedarray object based on the "type" and arraylength * The "type" is same with arg1 diff --git a/jerry-core/ecma/operations/ecma-typedarray-object.h b/jerry-core/ecma/operations/ecma-typedarray-object.h index e5849d02e..674f776d4 100644 --- a/jerry-core/ecma/operations/ecma-typedarray-object.h +++ b/jerry-core/ecma/operations/ecma-typedarray-object.h @@ -77,6 +77,11 @@ 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 (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, + ecma_value_t *length, + uint32_t arguments_list_len); /** * @} diff --git a/tests/test262-esnext-excludelist.xml b/tests/test262-esnext-excludelist.xml index 255a48906..1f676b38a 100644 --- a/tests/test262-esnext-excludelist.xml +++ b/tests/test262-esnext-excludelist.xml @@ -186,117 +186,15 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -9723,12 +9621,10 @@ - - @@ -9769,4 +9665,5 @@ +