From 3eb69075f78b7712fbef15200648e8424f37cfb6 Mon Sep 17 00:00:00 2001 From: Robert Fancsik Date: Wed, 29 Jul 2020 11:13:34 +0200 Subject: [PATCH] Update ToLength operation to conform ES6 spec (#4007) JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu --- jerry-core/api/jerry.c | 10 +- jerry-core/ecma/base/ecma-globals.h | 16 + jerry-core/ecma/base/ecma-helpers-string.c | 46 +- jerry-core/ecma/base/ecma-helpers-value.c | 17 + jerry-core/ecma/base/ecma-helpers.h | 4 +- .../ecma-builtin-array-iterator-prototype.c | 40 +- .../ecma-builtin-array-prototype.c | 394 ++++++++++-------- .../ecma/builtin-objects/ecma-builtin-array.c | 12 +- .../ecma-builtin-arraybuffer-prototype.c | 12 +- .../ecma-builtin-function-prototype.c | 8 +- .../builtin-objects/ecma-builtin-helpers.c | 81 +++- .../builtin-objects/ecma-builtin-helpers.h | 16 +- .../ecma/builtin-objects/ecma-builtin-json.c | 43 +- .../ecma-builtin-string-prototype.c | 15 +- .../builtin-objects/ecma-builtin-string.c | 6 +- .../ecma-builtin-typedarray-prototype.c | 68 +-- .../ecma/operations/ecma-array-object.c | 6 +- .../ecma/operations/ecma-array-object.h | 2 +- .../ecma/operations/ecma-container-object.c | 4 +- jerry-core/ecma/operations/ecma-conversion.c | 14 +- jerry-core/ecma/operations/ecma-conversion.h | 2 +- .../ecma/operations/ecma-dataview-object.c | 14 +- jerry-core/ecma/operations/ecma-objects.c | 114 ++--- jerry-core/ecma/operations/ecma-objects.h | 16 +- .../ecma/operations/ecma-promise-object.c | 8 +- .../ecma/operations/ecma-regexp-object.c | 54 +-- .../ecma/operations/ecma-typedarray-object.c | 16 +- tests/jerry/es.next/string-prototype-split.js | 14 +- tests/jerry/es.next/to-length.js | 149 +++++++ tests/test262-es6-excludelist.xml | 13 - tests/unit-core/test-to-length.c | 6 +- 31 files changed, 735 insertions(+), 485 deletions(-) create mode 100644 tests/jerry/es.next/to-length.js diff --git a/jerry-core/api/jerry.c b/jerry-core/api/jerry.c index ac00e9e06..3b1b5754f 100644 --- a/jerry-core/api/jerry.c +++ b/jerry-core/api/jerry.c @@ -2348,7 +2348,7 @@ jerry_get_property_by_index (const jerry_value_t obj_val, /**< object value */ return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p))); } - ecma_value_t ret_value = ecma_op_object_get_by_uint32_index (ecma_get_object_from_value (obj_val), index); + ecma_value_t ret_value = ecma_op_object_get_by_index (ecma_get_object_from_value (obj_val), index); return jerry_return (ret_value); } /* jerry_get_property_by_index */ @@ -2453,10 +2453,10 @@ jerry_set_property_by_index (const jerry_value_t obj_val, /**< object value */ return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p))); } - ecma_value_t ret_value = ecma_op_object_put_by_uint32_index (ecma_get_object_from_value (obj_val), - index, - value_to_set, - true); + ecma_value_t ret_value = ecma_op_object_put_by_index (ecma_get_object_from_value (obj_val), + index, + value_to_set, + true); return jerry_return (ret_value); } /* jerry_set_property_by_index */ diff --git a/jerry-core/ecma/base/ecma-globals.h b/jerry-core/ecma/base/ecma-globals.h index d16ec6c48..c1e5f903f 100644 --- a/jerry-core/ecma/base/ecma-globals.h +++ b/jerry-core/ecma/base/ecma-globals.h @@ -2075,6 +2075,22 @@ typedef struct } ecma_revocable_proxy_object_t; #endif /* ENABLED (JERRY_BUILTIN_PROXY) */ +#if ENABLED (JERRY_ESNEXT) +/** + * Type to repesent the maximum property index + * + * For ES6+ the maximum valid property index is 2**53 - 1 + */ +typedef uint64_t ecma_length_t; +#else /* !ENABLED (JERRY_ESNEXT) */ +/** + * Type to repesent the maximum property index + * + * For ES5+ the maximum valid property index is 2**32 - 1 + */ +typedef uint32_t ecma_length_t; +#endif /* ENABLED (JERRY_ESNEXT) */ + /** * Struct for counting the different types properties in objects */ diff --git a/jerry-core/ecma/base/ecma-helpers-string.c b/jerry-core/ecma/base/ecma-helpers-string.c index 701299f59..183ca6ab1 100644 --- a/jerry-core/ecma/base/ecma-helpers-string.c +++ b/jerry-core/ecma/base/ecma-helpers-string.c @@ -15,6 +15,7 @@ #include "ecma-alloc.h" #include "ecma-conversion.h" +#include "ecma-exceptions.h" #include "ecma-gc.h" #include "ecma-globals.h" #include "ecma-helpers.h" @@ -547,7 +548,32 @@ ecma_new_non_direct_string_from_uint32 (uint32_t uint32_number) /**< uint32 valu } /* ecma_new_non_direct_string_from_uint32 */ /** - * Allocate new ecma-string and fill it with ecma-number + * Allocate new ecma-string and fill it with property length number + * + * @return pointer to ecma-string descriptor + */ +ecma_string_t * +ecma_new_ecma_string_from_length (ecma_length_t number) /**< property length */ +{ + if (JERRY_LIKELY (number <= ECMA_DIRECT_STRING_MAX_IMM)) + { + return (ecma_string_t *) ECMA_CREATE_DIRECT_STRING (ECMA_DIRECT_STRING_UINT, (uintptr_t) number); + } + +#if ENABLED (JERRY_ESNEXT) + JERRY_ASSERT (number <= ECMA_NUMBER_MAX_SAFE_INTEGER); + + if (JERRY_UNLIKELY (number > UINT32_MAX)) + { + return ecma_new_ecma_string_from_number ((ecma_number_t) number); + } +#endif /* ENABLED (JERRY_ESNEXT) */ + + return ecma_new_non_direct_string_from_uint32 ((uint32_t) number); +} /* ecma_new_ecma_string_from_length */ + +/** + * Allocate new ecma-string and fill it with uint32 number * * @return pointer to ecma-string descriptor */ @@ -2493,7 +2519,7 @@ ecma_string_pad (ecma_value_t original_string_p, /**< Input ecma string */ { /* 3 */ - uint32_t int_max_length; + ecma_length_t int_max_length; if (ECMA_IS_VALUE_ERROR (ecma_op_to_length (max_length, &int_max_length))) { return ECMA_VALUE_ERROR; @@ -2524,8 +2550,14 @@ ecma_string_pad (ecma_value_t original_string_p, /**< Input ecma string */ } } + if (int_max_length >= UINT32_MAX) + { + ecma_deref_ecma_string (filler_p); + return ecma_raise_range_error (ECMA_ERR_MSG ("Maximum string length is reached.")); + } + /* 9 */ - uint32_t fill_len = int_max_length - string_length; + uint32_t fill_len = (uint32_t) int_max_length - string_length; /* 10 */ uint32_t filler_length = ecma_string_get_length (filler_p); @@ -2899,15 +2931,19 @@ ecma_stringbuilder_destroy (ecma_stringbuilder_t *builder_p) /**< string builder */ uint32_t ecma_op_advance_string_index (ecma_string_t *str_p, /**< input string */ - uint32_t index, /**< given character index */ + ecma_length_t index_num, /**< given character index */ bool is_unicode) /**< true - if regexp object's "unicode" flag is set false - otherwise */ { - if (index >= UINT32_MAX - 1) + JERRY_ASSERT (index_num <= ECMA_NUMBER_MAX_SAFE_INTEGER); + + /* Note: The internal string length limit is 2^32 */ + if (JERRY_UNLIKELY (index_num >= (UINT32_MAX - 1))) { return UINT32_MAX; } + uint32_t index = (uint32_t) index_num; uint32_t next_index = index + 1; if (!is_unicode) diff --git a/jerry-core/ecma/base/ecma-helpers-value.c b/jerry-core/ecma/base/ecma-helpers-value.c index cf3b1d10d..428d3cff4 100644 --- a/jerry-core/ecma/base/ecma-helpers-value.c +++ b/jerry-core/ecma/base/ecma-helpers-value.c @@ -530,6 +530,23 @@ ecma_is_number_equal_to_positive_zero (ecma_number_t ecma_number) /**< number */ #endif /* !ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ } /* ecma_is_number_equal_to_positive_zero */ +/** + * Encode a property length number into an ecma-value + * + * @return ecma-value + */ +ecma_value_t +ecma_make_length_value (ecma_length_t number) /**< number to be encoded */ +{ + if (number <= ECMA_INTEGER_NUMBER_MAX) + { + return ecma_make_integer_value ((ecma_integer_value_t) number); + } + + JERRY_ASSERT (number <= ECMA_NUMBER_MAX_SAFE_INTEGER); + return ecma_create_float_number ((ecma_number_t) number); +} /* ecma_make_length_value */ + /** * Encode a number into an ecma-value * diff --git a/jerry-core/ecma/base/ecma-helpers.h b/jerry-core/ecma/base/ecma-helpers.h index 3f46b4705..1e0129175 100644 --- a/jerry-core/ecma/base/ecma-helpers.h +++ b/jerry-core/ecma/base/ecma-helpers.h @@ -256,6 +256,7 @@ ecma_value_t JERRY_ATTR_CONST ecma_make_boolean_value (bool boolean_value); ecma_value_t JERRY_ATTR_CONST ecma_make_integer_value (ecma_integer_value_t integer_value); ecma_value_t ecma_make_nan_value (void); ecma_value_t ecma_make_float_value (ecma_number_t *ecma_num_p); +ecma_value_t ecma_make_length_value (ecma_length_t length); ecma_value_t ecma_make_number_value (ecma_number_t ecma_number); ecma_value_t ecma_make_int32_value (int32_t int32_number); ecma_value_t ecma_make_uint32_value (uint32_t uint32_number); @@ -297,7 +298,7 @@ lit_magic_string_id_t ecma_get_typeof_lit_id (ecma_value_t value); #if ENABLED (JERRY_ESNEXT) ecma_string_t *ecma_new_symbol_from_descriptor_string (ecma_value_t string_desc); bool ecma_prop_name_is_symbol (ecma_string_t *string_p); -uint32_t ecma_op_advance_string_index (ecma_string_t *str_p, uint32_t index, bool is_unicode); +uint32_t ecma_op_advance_string_index (ecma_string_t *str_p, ecma_length_t index_num, bool is_unicode); #endif /* ENABLED (JERRY_ESNEXT) */ #if ENABLED (JERRY_BUILTIN_MAP) || ENABLED (JERRY_BUILTIN_SET) ecma_string_t *ecma_new_map_key_string (ecma_value_t value); @@ -312,6 +313,7 @@ ecma_string_t *ecma_new_ecma_string_from_code_unit (ecma_char_t code_unit); #if ENABLED (JERRY_ESNEXT) ecma_string_t *ecma_new_ecma_string_from_code_units (ecma_char_t first_code_unit, ecma_char_t second_code_unit); #endif /* ENABLED (JERRY_ESNEXT) */ +ecma_string_t *ecma_new_ecma_string_from_length (ecma_length_t index); ecma_string_t *ecma_new_ecma_string_from_uint32 (uint32_t uint32_number); ecma_string_t *ecma_new_non_direct_string_from_uint32 (uint32_t uint32_number); ecma_string_t *ecma_get_ecma_string_from_uint32 (uint32_t uint32_number); diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-array-iterator-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-array-iterator-prototype.c index ac0c18b32..a6203a1c4 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-array-iterator-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-array-iterator-prototype.c @@ -17,6 +17,7 @@ #include "ecma-builtins.h" #include "ecma-iterator-object.h" #include "ecma-typedarray-object.h" +#include "ecma-arraybuffer-object.h" #if ENABLED (JERRY_ESNEXT) @@ -78,16 +79,31 @@ ecma_builtin_array_iterator_prototype_object_next (ecma_value_t this_val) /**< t ecma_object_t *array_object_p = ecma_get_object_from_value (iterated_value); - /* 8 - 9. */ - uint32_t length; - ecma_value_t len_value = ecma_op_object_get_length (array_object_p, &length); - - if (ECMA_IS_VALUE_ERROR (len_value)) + /* 8. */ + ecma_length_t length; + if (ecma_object_is_typedarray (array_object_p)) { - return len_value; + /* a. */ + ecma_object_t *arraybuffer_p = ecma_typedarray_get_arraybuffer (array_object_p); + if (ecma_arraybuffer_is_detached (arraybuffer_p)) + { + return ecma_raise_type_error (ECMA_ERR_MSG ("ArrayBuffer has been detached.")); + } + + /* b. */ + length = ecma_typedarray_get_length (array_object_p); + } + else + { + ecma_value_t len_value = ecma_op_object_get_length (array_object_p, &length); + + if (ECMA_IS_VALUE_ERROR (len_value)) + { + return len_value; + } } - uint32_t index = ext_obj_p->u.pseudo_array.u1.iterator_index; + ecma_length_t index = ext_obj_p->u.pseudo_array.u1.iterator_index; if (JERRY_UNLIKELY (index == ECMA_ITERATOR_INDEX_LIMIT)) { @@ -98,12 +114,12 @@ ecma_builtin_array_iterator_prototype_object_next (ecma_value_t this_val) /**< t if (!ecma_is_value_undefined (index_value)) { - index = (uint32_t) (ecma_get_number_from_value (index_value) + 1); + index = (ecma_length_t) (ecma_get_number_from_value (index_value) + 1); } ecma_value_t put_result = ecma_op_object_put (obj_p, prop_name_p, - ecma_make_uint32_value (index), + ecma_make_length_value (index), true); JERRY_ASSERT (ecma_is_value_true (put_result)); @@ -128,11 +144,11 @@ ecma_builtin_array_iterator_prototype_object_next (ecma_value_t this_val) /**< t if (iterator_kind == ECMA_ITERATOR_KEYS) { /* 12. */ - return ecma_create_iter_result_object (ecma_make_uint32_value (index), ECMA_VALUE_FALSE); + return ecma_create_iter_result_object (ecma_make_length_value (index), ECMA_VALUE_FALSE); } /* 14. */ - ecma_value_t get_value = ecma_op_object_get_by_uint32_index (array_object_p, index); + ecma_value_t get_value = ecma_op_object_get_by_index (array_object_p, index); /* 15. */ if (ECMA_IS_VALUE_ERROR (get_value)) @@ -155,7 +171,7 @@ ecma_builtin_array_iterator_prototype_object_next (ecma_value_t this_val) /**< t /* 17.b */ ecma_value_t entry_array_value; entry_array_value = ecma_create_array_from_iter_element (get_value, - ecma_make_uint32_value (index)); + ecma_make_length_value (index)); result = ecma_create_iter_result_object (entry_array_value, ECMA_VALUE_FALSE); ecma_free_value (entry_array_value); 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 85622d149..689aeb5e3 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c @@ -129,8 +129,8 @@ ecma_builtin_array_prototype_helper_set_length (ecma_object_t *object, /**< obje * Returned value must be freed with ecma_free_value. */ static ecma_value_t -ecma_builtin_array_prototype_object_to_locale_string (ecma_object_t *obj_p, /**< array object */ - uint32_t length) /**< array object's length */ +ecma_builtin_array_prototype_object_to_locale_string (ecma_object_t *obj_p, /**< object */ + ecma_length_t length) /**< object's length */ { /* 5. */ if (length == 0) @@ -150,7 +150,7 @@ ecma_builtin_array_prototype_object_to_locale_string (ecma_object_t *obj_p, /**< ecma_deref_ecma_string (first_string_p); /* 9-10. */ - for (uint32_t k = 1; k < length; k++) + for (ecma_length_t k = 1; k < length; k++) { /* 4. Implementation-defined: set the separator to a single comma character. */ ecma_stringbuilder_append_byte (&builder, LIT_CHAR_COMMA); @@ -198,7 +198,7 @@ ecma_builtin_array_prototype_object_concat (const ecma_value_t args[], /**< argu #endif /* ENABLED (JERRY_ESNEXT) */ ecma_object_t *new_array_p = ecma_get_object_from_value (new_array); - uint32_t new_length = 0; + ecma_length_t new_length = 0; /* 5.b - 5.c for this_arg */ ecma_value_t concat_this_value = ecma_builtin_helper_array_concat_value (new_array_p, @@ -269,9 +269,9 @@ ecma_op_array_get_separator_string (ecma_value_t separator) /**< possible separa */ static ecma_string_t * ecma_op_array_get_to_string_at_index (ecma_object_t *obj_p, /**< this object */ - uint32_t index) /**< array index */ + ecma_length_t index) /**< array index */ { - ecma_value_t index_value = ecma_op_object_get_by_uint32_index (obj_p, index); + ecma_value_t index_value = ecma_op_object_get_by_index (obj_p, index); if (ECMA_IS_VALUE_ERROR (index_value)) { @@ -302,8 +302,8 @@ ecma_op_array_get_to_string_at_index (ecma_object_t *obj_p, /**< this object */ */ static ecma_value_t ecma_builtin_array_prototype_join (ecma_value_t separator_arg, /**< separator argument */ - ecma_object_t *obj_p, /**< array object */ - uint32_t length) /**< array object's length */ + ecma_object_t *obj_p, /**< object */ + ecma_length_t length) /**< object's length */ { /* 4-5. */ ecma_string_t *separator_string_p = ecma_op_array_get_separator_string (separator_arg); @@ -333,7 +333,7 @@ ecma_builtin_array_prototype_join (ecma_value_t separator_arg, /**< separator ar ecma_deref_ecma_string (first_string_p); /* 9-10. */ - for (uint32_t k = 1; k < length; k++) + for (ecma_length_t k = 1; k < length; k++) { /* 10.a */ ecma_stringbuilder_append (&builder, separator_string_p); @@ -366,8 +366,8 @@ ecma_builtin_array_prototype_join (ecma_value_t separator_arg, /**< separator ar * Returned value must be freed with ecma_free_value. */ static ecma_value_t -ecma_builtin_array_prototype_object_pop (ecma_object_t *obj_p, /**< array object */ - uint32_t len) /**< array object's length */ +ecma_builtin_array_prototype_object_pop (ecma_object_t *obj_p, /**< object */ + ecma_length_t len) /**< object's length */ { /* 4. */ if (len == 0) @@ -381,7 +381,7 @@ ecma_builtin_array_prototype_object_pop (ecma_object_t *obj_p, /**< array object /* 5.b */ len--; - ecma_value_t get_value = ecma_op_object_get_by_uint32_index (obj_p, len); + ecma_value_t get_value = ecma_op_object_get_by_index (obj_p, len); if (ECMA_IS_VALUE_ERROR (get_value)) { @@ -396,13 +396,13 @@ ecma_builtin_array_prototype_object_pop (ecma_object_t *obj_p, /**< array object return ecma_raise_type_error (ECMA_ERR_MSG ("Invalid argument type.")); } - ecma_delete_fast_array_properties (obj_p, len); + ecma_delete_fast_array_properties (obj_p, (uint32_t) len); return get_value; } /* 5.c */ - ecma_value_t del_value = ecma_op_object_delete_by_uint32_index (obj_p, len, true); + ecma_value_t del_value = ecma_op_object_delete_by_index (obj_p, len, true); if (ECMA_IS_VALUE_ERROR (del_value)) { @@ -436,11 +436,9 @@ ecma_builtin_array_prototype_object_pop (ecma_object_t *obj_p, /**< array object static ecma_value_t ecma_builtin_array_prototype_object_push (const ecma_value_t *argument_list_p, /**< arguments list */ uint32_t arguments_number, /**< number of arguments */ - ecma_object_t *obj_p, /**< array object */ - uint32_t length) /**< array object's length */ + ecma_object_t *obj_p, /**< object */ + ecma_length_t length) /**< object's length */ { - ecma_number_t n = (ecma_number_t) length; - if (ecma_op_object_is_fast_array (obj_p)) { if (!ecma_op_ordinary_object_is_extensible (obj_p)) @@ -455,10 +453,10 @@ ecma_builtin_array_prototype_object_push (const ecma_value_t *argument_list_p, / if (arguments_number == 0) { - return ecma_make_uint32_value (length); + return ecma_make_uint32_value ((uint32_t) length); } - uint32_t new_length = length + arguments_number; + uint32_t new_length = ((uint32_t) length) + arguments_number; ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p; ecma_value_t *buffer_p = ecma_fast_array_extend (obj_p, new_length) + length; @@ -472,11 +470,18 @@ ecma_builtin_array_prototype_object_push (const ecma_value_t *argument_list_p, / return ecma_make_uint32_value (new_length); } +#if ENABLED (JERRY_ESNEXT) /* 5. */ - for (uint32_t index = 0; index < arguments_number; index++, n++) + if (length + arguments_number > ECMA_NUMBER_MAX_SAFE_INTEGER) { - /* 5.b */ - ecma_value_t put_value = ecma_op_object_put_by_number_index (obj_p, n, argument_list_p[index], true); + return ecma_raise_type_error (ECMA_ERR_MSG ("Pushing element over 2**53-1 length is disallowed")); + } + + /* 6. */ + for (ecma_length_t index = 0; index < arguments_number; index++, length++) + { + /* 6.b */ + ecma_value_t put_value = ecma_op_object_put_by_index (obj_p, length, argument_list_p[index], true); if (ECMA_IS_VALUE_ERROR (put_value)) { @@ -484,7 +489,26 @@ ecma_builtin_array_prototype_object_push (const ecma_value_t *argument_list_p, / } } - /* 6. */ + ecma_number_t n = (ecma_number_t) length; +#else /* ENABLED (JERRY_ESNEXT) */ + ecma_number_t n = (ecma_number_t) length; + + /* 5. */ + for (ecma_length_t index = 0; index < arguments_number; index++, n++) + { + /* 5.b */ + ecma_string_t *index_str_p = ecma_new_ecma_string_from_number (n); + ecma_value_t put_value = ecma_op_object_put (obj_p, index_str_p, argument_list_p[index], true); + ecma_deref_ecma_string (index_str_p); + + if (ECMA_IS_VALUE_ERROR (put_value)) + { + return put_value; + } + } + +#endif /* ENABLED (JERRY_ESNEXT) */ + /* 6 - 7. */ ecma_value_t set_length_value = ecma_builtin_array_prototype_helper_set_length (obj_p, n); if (ECMA_IS_VALUE_ERROR (set_length_value)) @@ -506,13 +530,13 @@ ecma_builtin_array_prototype_object_push (const ecma_value_t *argument_list_p, / */ static ecma_value_t ecma_builtin_array_prototype_object_reverse (ecma_value_t this_arg, /**< this argument */ - ecma_object_t *obj_p, /**< array object */ - uint32_t len) /**< array object's length */ + ecma_object_t *obj_p, /**< object */ + ecma_length_t len) /**< object's length */ { - uint32_t middle = len / 2; if (ecma_op_object_is_fast_array (obj_p)) { + uint32_t middle = (uint32_t) len / 2; ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p; if (ext_obj_p->u.array.u.hole_count < ECMA_FAST_ARRAY_HOLE_ONE @@ -532,13 +556,14 @@ ecma_builtin_array_prototype_object_reverse (ecma_value_t this_arg, /**< this ar } } - for (uint32_t lower = 0; lower < middle; lower++) + ecma_length_t middle = len / 2; + for (ecma_length_t lower = 0; lower < middle; lower++) { - uint32_t upper = len - lower - 1; + ecma_length_t upper = len - lower - 1; ecma_value_t ret_value = ECMA_VALUE_ERROR; - ecma_string_t *lower_str_p = ecma_new_ecma_string_from_uint32 (lower); - ecma_string_t *upper_str_p = ecma_new_ecma_string_from_uint32 (upper); + ecma_string_t *lower_str_p = ecma_new_ecma_string_from_length (lower); + ecma_string_t *upper_str_p = ecma_new_ecma_string_from_length (upper); #if ENABLED (JERRY_ESNEXT) ecma_value_t lower_value = ECMA_VALUE_EMPTY; @@ -685,8 +710,8 @@ clean_up: * Returned value must be freed with ecma_free_value. */ static ecma_value_t -ecma_builtin_array_prototype_object_shift (ecma_object_t *obj_p, /**< array object */ - uint32_t len) /**< array object's length */ +ecma_builtin_array_prototype_object_shift (ecma_object_t *obj_p, /**< object */ + ecma_length_t len) /**< object's length */ { /* 4. */ if (len == 0) @@ -712,17 +737,17 @@ ecma_builtin_array_prototype_object_shift (ecma_object_t *obj_p, /**< array obje ecma_ref_object (ecma_get_object_from_value (ret_value)); } - memmove (buffer_p, buffer_p + 1, sizeof (ecma_value_t) * (len - 1)); + memmove (buffer_p, buffer_p + 1, (size_t) (sizeof (ecma_value_t) * (len - 1))); buffer_p[len - 1] = ECMA_VALUE_UNDEFINED; - ecma_delete_fast_array_properties (obj_p, len - 1); + ecma_delete_fast_array_properties (obj_p, (uint32_t) (len - 1)); return ret_value; } } /* 5. */ - ecma_value_t first_value = ecma_op_object_get_by_uint32_index (obj_p, 0); + ecma_value_t first_value = ecma_op_object_get_by_index (obj_p, 0); if (ECMA_IS_VALUE_ERROR (first_value)) { @@ -730,10 +755,10 @@ ecma_builtin_array_prototype_object_shift (ecma_object_t *obj_p, /**< array obje } /* 6. and 7. */ - for (uint32_t k = 1; k < len; k++) + for (ecma_length_t k = 1; k < len; k++) { /* 7.a - 7.c */ - ecma_value_t curr_value = ecma_op_object_find_by_uint32_index (obj_p, k); + ecma_value_t curr_value = ecma_op_object_find_by_index (obj_p, k); if (ECMA_IS_VALUE_ERROR (curr_value)) { @@ -742,19 +767,19 @@ ecma_builtin_array_prototype_object_shift (ecma_object_t *obj_p, /**< array obje } /* 7.b */ - uint32_t to = k - 1; + ecma_length_t to = k - 1; ecma_value_t operation_value; if (ecma_is_value_found (curr_value)) { /* 7.d.i, 7.d.ii */ - operation_value = ecma_op_object_put_by_uint32_index (obj_p, to, curr_value, true); + operation_value = ecma_op_object_put_by_index (obj_p, to, curr_value, true); ecma_free_value (curr_value); } else { /* 7.e.i */ - operation_value = ecma_op_object_delete_by_uint32_index (obj_p, to, true); + operation_value = ecma_op_object_delete_by_index (obj_p, to, true); } if (ECMA_IS_VALUE_ERROR (operation_value)) @@ -765,7 +790,7 @@ ecma_builtin_array_prototype_object_shift (ecma_object_t *obj_p, /**< array obje } /* 8. */ - ecma_value_t del_value = ecma_op_object_delete_by_uint32_index (obj_p, --len, true); + ecma_value_t del_value = ecma_op_object_delete_by_index (obj_p, --len, true); if (ECMA_IS_VALUE_ERROR (del_value)) { @@ -798,10 +823,10 @@ ecma_builtin_array_prototype_object_shift (ecma_object_t *obj_p, /**< array obje static ecma_value_t ecma_builtin_array_prototype_object_slice (ecma_value_t arg1, /**< start */ ecma_value_t arg2, /**< end */ - ecma_object_t *obj_p, /**< array object */ - uint32_t len) /**< array object's length */ + ecma_object_t *obj_p, /**< object */ + ecma_length_t len) /**< object's length */ { - uint32_t start = 0, end = len; + ecma_length_t start = 0, end = len; /* 5. 6.*/ if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (arg1, @@ -830,7 +855,7 @@ ecma_builtin_array_prototype_object_slice (ecma_value_t arg1, /**< start */ JERRY_ASSERT (start <= len && end <= len); bool use_fast_path = ecma_op_object_is_fast_array (obj_p); - uint32_t copied_length = (end > start) ? end - start : 0; + ecma_length_t copied_length = (end > start) ? end - start : 0; #if ENABLED (JERRY_ESNEXT) ecma_value_t new_array = ecma_op_array_species_create (obj_p, copied_length); @@ -846,9 +871,6 @@ ecma_builtin_array_prototype_object_slice (ecma_value_t arg1, /**< start */ ecma_object_t *new_array_p = ecma_get_object_from_value (new_array); - /* 9. */ - uint32_t n = 0; - if (use_fast_path && copied_length > 0) { ecma_extended_object_t *ext_from_obj_p = (ecma_extended_object_t *) obj_p; @@ -869,17 +891,19 @@ ecma_builtin_array_prototype_object_slice (ecma_value_t arg1, /**< start */ #if ENABLED (JERRY_ESNEXT) uint32_t target_length = ext_to_obj_p->u.array.length; ecma_value_t *to_buffer_p; + JERRY_ASSERT (copied_length <= UINT32_MAX); + if (copied_length == target_length) { to_buffer_p = ECMA_GET_NON_NULL_POINTER (ecma_value_t, new_array_p->u1.property_list_cp); } else if (copied_length > target_length) { - to_buffer_p = ecma_fast_array_extend (new_array_p, copied_length); + to_buffer_p = ecma_fast_array_extend (new_array_p, (uint32_t) copied_length); } else { - ecma_delete_fast_array_properties (new_array_p, copied_length); + ecma_delete_fast_array_properties (new_array_p, (uint32_t) copied_length); to_buffer_p = ECMA_GET_NON_NULL_POINTER (ecma_value_t, new_array_p->u1.property_list_cp); } #else /* !ENABLED (JERRY_ESNEXT) */ @@ -888,7 +912,10 @@ ecma_builtin_array_prototype_object_slice (ecma_value_t arg1, /**< start */ ecma_value_t *from_buffer_p = ECMA_GET_NON_NULL_POINTER (ecma_value_t, obj_p->u1.property_list_cp); - for (uint32_t k = start; k < end; k++, n++) + /* 9. */ + uint32_t n = 0; + + for (uint32_t k = (uint32_t) start; k < (uint32_t) end; k++, n++) { #if ENABLED (JERRY_ESNEXT) ecma_free_value_if_not_object (to_buffer_p[n]); @@ -902,11 +929,14 @@ ecma_builtin_array_prototype_object_slice (ecma_value_t arg1, /**< start */ } } + /* 9. */ + ecma_length_t n = 0; + /* 10. */ - for (uint32_t k = start; k < end; k++, n++) + for (ecma_length_t k = start; k < end; k++, n++) { /* 10.c */ - ecma_value_t get_value = ecma_op_object_find_by_uint32_index (obj_p, k); + ecma_value_t get_value = ecma_op_object_find_by_index (obj_p, k); if (ECMA_IS_VALUE_ERROR (get_value)) { @@ -917,10 +947,11 @@ ecma_builtin_array_prototype_object_slice (ecma_value_t arg1, /**< start */ if (ecma_is_value_found (get_value)) { /* 10.c.ii */ - ecma_value_t put_comp = ecma_builtin_helper_def_prop_by_index (new_array_p, - n, - get_value, - ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE); + ecma_value_t put_comp; + put_comp = ecma_builtin_helper_def_prop_by_index (new_array_p, + n, + get_value, + ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE); ecma_free_value (get_value); #if ENABLED (JERRY_ESNEXT) @@ -973,12 +1004,12 @@ ecma_builtin_array_prototype_object_sort_compare_helper (ecma_value_t lhs, /**< if (lhs_is_undef) { - return ecma_make_number_value (rhs_is_undef ? ECMA_NUMBER_ZERO : ECMA_NUMBER_ONE); + return ecma_make_integer_value (rhs_is_undef ? 0 : 1); } if (rhs_is_undef) { - return ecma_make_number_value (ECMA_NUMBER_MINUS_ONE); + return ecma_make_integer_value (-1); } ecma_number_t result = ECMA_NUMBER_ZERO; @@ -1070,8 +1101,8 @@ ecma_builtin_array_prototype_object_sort_compare_helper (ecma_value_t lhs, /**< static ecma_value_t ecma_builtin_array_prototype_object_sort (ecma_value_t this_arg, /**< this argument */ ecma_value_t arg1, /**< comparefn */ - ecma_object_t *obj_p, /**< array object */ - uint32_t len) /**< array object's length */ + ecma_object_t *obj_p, /**< object */ + ecma_length_t len) /**< object's length */ { /* Check if the provided compare function is callable. */ if (!ecma_is_value_undefined (arg1) && !ecma_op_is_callable (arg1)) @@ -1156,7 +1187,7 @@ ecma_builtin_array_prototype_object_sort (ecma_value_t this_arg, /**< this argum /* Put sorted values to the front of the array. */ for (uint32_t index = 0; index < copied_num; index++) { - ecma_value_t put_value = ecma_op_object_put_by_uint32_index (obj_p, index, values_buffer[index], true); + ecma_value_t put_value = ecma_op_object_put_by_index (obj_p, index, values_buffer[index], true); if (ECMA_IS_VALUE_ERROR (put_value)) { @@ -1222,8 +1253,8 @@ clean_up: static ecma_value_t ecma_builtin_array_prototype_object_splice (const ecma_value_t args[], /**< arguments list */ uint32_t args_number, /**< number of arguments */ - ecma_object_t *obj_p, /**< array object */ - uint32_t len) /**< array object's length */ + ecma_object_t *obj_p, /**< object */ + ecma_length_t len) /**< object's length */ { #if ENABLED (JERRY_ESNEXT) ecma_value_t new_array = ecma_op_array_species_create (obj_p, 0); @@ -1239,8 +1270,8 @@ ecma_builtin_array_prototype_object_splice (const ecma_value_t args[], /**< argu ecma_object_t *new_array_p = ecma_get_object_from_value (new_array); - uint32_t start = 0; - uint32_t delete_count = 0; + ecma_length_t start = 0; + ecma_length_t delete_count = 0; if (args_number > 0) { @@ -1295,14 +1326,14 @@ ecma_builtin_array_prototype_object_splice (const ecma_value_t args[], /**< argu } /* 8-9. */ - uint32_t k = 0; + ecma_length_t k = 0; - for (uint32_t del_item_idx; k < delete_count; k++) + for (ecma_length_t del_item_idx; k < delete_count; k++) { /* 9.a - 9.b */ del_item_idx = k + start; - ecma_value_t get_value = ecma_op_object_find_by_uint32_index (obj_p, del_item_idx); + ecma_value_t get_value = ecma_op_object_find_by_index (obj_p, del_item_idx); if (ECMA_IS_VALUE_ERROR (get_value)) { @@ -1313,10 +1344,11 @@ ecma_builtin_array_prototype_object_splice (const ecma_value_t args[], /**< argu if (ecma_is_value_found (get_value)) { /* 9.c.ii */ - ecma_value_t put_comp = ecma_builtin_helper_def_prop_by_index (new_array_p, - k, - get_value, - ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE); + ecma_value_t put_comp; + put_comp = ecma_builtin_helper_def_prop_by_index (new_array_p, + k, + get_value, + ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE); ecma_free_value (get_value); #if ENABLED (JERRY_ESNEXT) if (ECMA_IS_VALUE_ERROR (put_comp)) @@ -1353,11 +1385,11 @@ ecma_builtin_array_prototype_object_splice (const ecma_value_t args[], /**< argu item_count = 0; } - const uint32_t new_len = len - delete_count + item_count; + const ecma_length_t new_len = len - delete_count + item_count; if (item_count != delete_count) { - uint32_t from, to; + ecma_length_t from, to; /* 12. */ if (item_count < delete_count) @@ -1368,7 +1400,7 @@ ecma_builtin_array_prototype_object_splice (const ecma_value_t args[], /**< argu from = k + delete_count; to = k + item_count; - ecma_value_t get_value = ecma_op_object_find_by_uint32_index (obj_p, from); + ecma_value_t get_value = ecma_op_object_find_by_index (obj_p, from); if (ECMA_IS_VALUE_ERROR (get_value)) { @@ -1381,13 +1413,13 @@ ecma_builtin_array_prototype_object_splice (const ecma_value_t args[], /**< argu if (ecma_is_value_found (get_value)) { /* 12.b.iv */ - operation_value = ecma_op_object_put_by_uint32_index (obj_p, to, get_value, true); + operation_value = ecma_op_object_put_by_index (obj_p, to, get_value, true); ecma_free_value (get_value); } else { /* 12.b.v */ - operation_value = ecma_op_object_delete_by_uint32_index (obj_p, to, true); + operation_value = ecma_op_object_delete_by_index (obj_p, to, true); } if (ECMA_IS_VALUE_ERROR (operation_value)) @@ -1400,7 +1432,7 @@ ecma_builtin_array_prototype_object_splice (const ecma_value_t args[], /**< argu /* 12.d */ for (k = len; k > new_len; k--) { - ecma_value_t del_value = ecma_op_object_delete_by_uint32_index (obj_p, k - 1, true); + ecma_value_t del_value = ecma_op_object_delete_by_index (obj_p, k - 1, true); if (ECMA_IS_VALUE_ERROR (del_value)) { @@ -1419,7 +1451,7 @@ ecma_builtin_array_prototype_object_splice (const ecma_value_t args[], /**< argu from = k + delete_count - 1; to = k + item_count - 1; /* 13.b.iii */ - ecma_value_t get_value = ecma_op_object_find_by_uint32_index (obj_p, from); + ecma_value_t get_value = ecma_op_object_find_by_index (obj_p, from); if (ECMA_IS_VALUE_ERROR (get_value)) { @@ -1432,13 +1464,13 @@ ecma_builtin_array_prototype_object_splice (const ecma_value_t args[], /**< argu if (ecma_is_value_found (get_value)) { /* 13.b.iv */ - operation_value = ecma_op_object_put_by_uint32_index (obj_p, to, get_value, true); + operation_value = ecma_op_object_put_by_index (obj_p, to, get_value, true); ecma_free_value (get_value); } else { /* 13.b.v */ - operation_value = ecma_op_object_delete_by_uint32_index (obj_p, to, true); + operation_value = ecma_op_object_delete_by_index (obj_p, to, true); } if (ECMA_IS_VALUE_ERROR (operation_value)) @@ -1454,10 +1486,10 @@ ecma_builtin_array_prototype_object_splice (const ecma_value_t args[], /**< argu uint32_t idx = 0; for (uint32_t arg_index = 2; arg_index < args_number; arg_index++, idx++) { - ecma_value_t put_value = ecma_op_object_put_by_uint32_index (obj_p, - (uint32_t) (start + idx), - args[arg_index], - true); + ecma_value_t put_value = ecma_op_object_put_by_index (obj_p, + start + idx, + args[arg_index], + true); if (ECMA_IS_VALUE_ERROR (put_value)) { @@ -1490,8 +1522,8 @@ ecma_builtin_array_prototype_object_splice (const ecma_value_t args[], /**< argu static ecma_value_t ecma_builtin_array_prototype_object_unshift (const ecma_value_t args[], /**< arguments list */ uint32_t args_number, /**< number of arguments */ - ecma_object_t *obj_p, /**< array object */ - uint32_t len) /**< array object's length */ + ecma_object_t *obj_p, /**< object */ + ecma_length_t len) /**< object's length */ { if (ecma_op_object_is_fast_array (obj_p)) @@ -1502,19 +1534,19 @@ ecma_builtin_array_prototype_object_unshift (const ecma_value_t args[], /**< arg && len != 0 && ecma_op_ordinary_object_is_extensible (obj_p)) { - if ((ecma_number_t) (len + args_number) > UINT32_MAX) + if (args_number > UINT32_MAX - len) { return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid array length")); } if (args_number == 0) { - return ecma_make_uint32_value (len); + return ecma_make_uint32_value ((uint32_t) len); } - uint32_t new_length = len + args_number; + uint32_t new_length = ((uint32_t) len) + args_number; ecma_value_t *buffer_p = ecma_fast_array_extend (obj_p, new_length); - memmove (buffer_p + args_number, buffer_p, sizeof (ecma_value_t) * len); + memmove (buffer_p + args_number, buffer_p, (size_t) (sizeof (ecma_value_t) * len)); uint32_t index = 0; @@ -1530,11 +1562,17 @@ ecma_builtin_array_prototype_object_unshift (const ecma_value_t args[], /**< arg } } + /* 4. */ + if (len + args_number > ECMA_NUMBER_MAX_SAFE_INTEGER) + { + return ecma_raise_type_error (ECMA_ERR_MSG ("Unshift elements over 2**53-1 length is disallowed")); + } + /* 5. and 6. */ - for (uint32_t k = len; k > 0; k--) + for (ecma_length_t k = len; k > 0; k--) { /* 6.a, 6.c*/ - ecma_value_t get_value = ecma_op_object_find_by_uint32_index (obj_p, k - 1); + ecma_value_t get_value = ecma_op_object_find_by_index (obj_p, k - 1); if (ECMA_IS_VALUE_ERROR (get_value)) { @@ -1543,20 +1581,23 @@ ecma_builtin_array_prototype_object_unshift (const ecma_value_t args[], /**< arg /* 6.b */ ecma_number_t new_idx = ((ecma_number_t) k) + ((ecma_number_t) args_number) - 1; + ecma_string_t *index_str_p = ecma_new_ecma_string_from_number (new_idx); ecma_value_t operation_value; if (ecma_is_value_found (get_value)) { /* 6.d.i, 6.d.ii */ - operation_value = ecma_op_object_put_by_number_index (obj_p, new_idx, get_value, true); + operation_value = ecma_op_object_put (obj_p, index_str_p, get_value, true); ecma_free_value (get_value); } else { /* 6.e.i */ - operation_value = ecma_op_object_delete_by_number_index (obj_p, new_idx, true); + operation_value = ecma_op_object_delete (obj_p, index_str_p, true); } + ecma_deref_ecma_string (index_str_p); + if (ECMA_IS_VALUE_ERROR (operation_value)) { return operation_value; @@ -1566,7 +1607,7 @@ ecma_builtin_array_prototype_object_unshift (const ecma_value_t args[], /**< arg for (uint32_t arg_index = 0; arg_index < args_number; arg_index++) { /* 9.b */ - ecma_value_t put_value = ecma_op_object_put_by_uint32_index (obj_p, arg_index, args[arg_index], true); + ecma_value_t put_value = ecma_op_object_put_by_index (obj_p, arg_index, args[arg_index], true); if (ECMA_IS_VALUE_ERROR (put_value)) { @@ -1598,8 +1639,8 @@ ecma_builtin_array_prototype_object_unshift (const ecma_value_t args[], /**< arg static ecma_value_t ecma_builtin_array_prototype_object_index_of (const ecma_value_t args[], /**< arguments list */ uint32_t args_number, /**< number of arguments */ - ecma_object_t *obj_p, /**< array object */ - uint32_t len) /**< array object's length */ + ecma_object_t *obj_p, /**< object */ + ecma_length_t len) /**< object's length */ { /* 4. */ if (len == 0) @@ -1624,17 +1665,14 @@ ecma_builtin_array_prototype_object_index_of (const ecma_value_t args[], /**< ar } /* 7. */ - ecma_number_t from_idx_num = idx; + ecma_length_t from_idx = (ecma_length_t) idx; /* 8. */ if (idx < 0) { - from_idx_num = JERRY_MAX ((ecma_number_t) len + idx, 0); + from_idx = (ecma_length_t) JERRY_MAX ((ecma_number_t) len + idx, 0); } - JERRY_ASSERT (from_idx_num >= 0 && from_idx_num <= UINT32_MAX); - uint32_t from_idx = (uint32_t) from_idx_num; - if (ecma_op_object_is_fast_array (obj_p)) { ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p; @@ -1654,7 +1692,7 @@ ecma_builtin_array_prototype_object_index_of (const ecma_value_t args[], /**< ar { if (ecma_op_strict_equality_compare (args[0], buffer_p[from_idx])) { - return ecma_make_uint32_value (from_idx); + return ecma_make_uint32_value ((uint32_t) from_idx); } from_idx++; @@ -1668,7 +1706,7 @@ ecma_builtin_array_prototype_object_index_of (const ecma_value_t args[], /**< ar while (from_idx < len) { /* 9.a */ - ecma_value_t get_value = ecma_op_object_find_by_uint32_index (obj_p, from_idx); + ecma_value_t get_value = ecma_op_object_find_by_index (obj_p, from_idx); if (ECMA_IS_VALUE_ERROR (get_value)) { @@ -1680,7 +1718,7 @@ ecma_builtin_array_prototype_object_index_of (const ecma_value_t args[], /**< ar && ecma_op_strict_equality_compare (args[0], get_value)) { ecma_free_value (get_value); - return ecma_make_uint32_value (from_idx); + return ecma_make_length_value (from_idx); } from_idx++; @@ -1703,8 +1741,8 @@ ecma_builtin_array_prototype_object_index_of (const ecma_value_t args[], /**< ar static ecma_value_t ecma_builtin_array_prototype_object_last_index_of (const ecma_value_t args[], /**< arguments list */ uint32_t args_number, /**< number of arguments */ - ecma_object_t *obj_p, /**< array object */ - uint32_t len) /**< array object's length */ + ecma_object_t *obj_p, /**< object */ + ecma_length_t len) /**< object's length */ { /* 4. */ if (len == 0) @@ -1722,21 +1760,21 @@ ecma_builtin_array_prototype_object_last_index_of (const ecma_value_t args[], /* } } - uint32_t from_idx; + ecma_length_t from_idx; /* 6 */ if (idx >= 0) { - from_idx = (uint32_t) (JERRY_MIN (idx, len - 1)); + from_idx = (ecma_length_t) (JERRY_MIN (idx, (ecma_number_t) (len - 1))); } else { - ecma_number_t k = len + idx; + ecma_number_t k = (ecma_number_t) len + idx; if (k < 0) { return ecma_make_integer_value (-1); } - from_idx = (uint32_t) k; + from_idx = (ecma_length_t) k; } ecma_value_t search_element = (args_number > 0) ? args[0] : ECMA_VALUE_UNDEFINED; @@ -1760,7 +1798,7 @@ ecma_builtin_array_prototype_object_last_index_of (const ecma_value_t args[], /* { if (ecma_op_strict_equality_compare (search_element, buffer_p[from_idx])) { - return ecma_make_uint32_value (from_idx); + return ecma_make_uint32_value ((uint32_t) from_idx); } from_idx--; } @@ -1772,7 +1810,7 @@ ecma_builtin_array_prototype_object_last_index_of (const ecma_value_t args[], /* while (from_idx < len) { /* 8.a */ - ecma_value_t get_value = ecma_op_object_find_by_uint32_index (obj_p, from_idx); + ecma_value_t get_value = ecma_op_object_find_by_index (obj_p, from_idx); if (ECMA_IS_VALUE_ERROR (get_value)) { @@ -1784,7 +1822,7 @@ ecma_builtin_array_prototype_object_last_index_of (const ecma_value_t args[], /* && ecma_op_strict_equality_compare (search_element, get_value)) { ecma_free_value (get_value); - return ecma_make_uint32_value (from_idx); + return ecma_make_length_value (from_idx); } from_idx--; @@ -1823,8 +1861,8 @@ static ecma_value_t ecma_builtin_array_apply (ecma_value_t arg1, /**< callbackfn */ ecma_value_t arg2, /**< thisArg */ array_routine_mode mode, /**< array routine mode */ - ecma_object_t *obj_p, /**< array object */ - uint32_t len) /**< array object's length */ + ecma_object_t *obj_p, /**< object */ + ecma_length_t len) /**< object's length */ { JERRY_ASSERT (mode < ARRAY_ROUTINE__COUNT); @@ -1840,10 +1878,10 @@ ecma_builtin_array_apply (ecma_value_t arg1, /**< callbackfn */ ecma_value_t current_index; /* 7. */ - for (uint32_t index = 0; index < len; index++) + for (ecma_length_t index = 0; index < len; index++) { /* 7.a - 7.c */ - ecma_value_t get_value = ecma_op_object_find_by_uint32_index (obj_p, index); + ecma_value_t get_value = ecma_op_object_find_by_index (obj_p, index); if (ECMA_IS_VALUE_ERROR (get_value)) { @@ -1853,7 +1891,7 @@ ecma_builtin_array_apply (ecma_value_t arg1, /**< callbackfn */ if (ecma_is_value_found (get_value)) { /* 7.c.i */ - current_index = ecma_make_uint32_value (index); + current_index = ecma_make_length_value (index); ecma_value_t call_args[] = { get_value, current_index, ecma_make_object_value (obj_p) }; /* 7.c.ii */ @@ -1909,8 +1947,8 @@ ecma_builtin_array_apply (ecma_value_t arg1, /**< callbackfn */ static ecma_value_t ecma_builtin_array_prototype_object_map (ecma_value_t arg1, /**< callbackfn */ ecma_value_t arg2, /**< thisArg */ - ecma_object_t *obj_p, /**< array object */ - uint32_t len) /**< array object's length */ + ecma_object_t *obj_p, /**< object */ + ecma_length_t len) /**< object's length */ { /* 4. */ if (!ecma_op_is_callable (arg1)) @@ -1927,7 +1965,7 @@ ecma_builtin_array_prototype_object_map (ecma_value_t arg1, /**< callbackfn */ return new_array; } #else /* !ENABLED (JERRY_ESNEXT) */ - ecma_value_t length_value = ecma_make_number_value (len); + ecma_value_t length_value = ecma_make_uint32_value (len); ecma_value_t new_array = ecma_op_create_array_object (&length_value, 1, true); ecma_free_value (length_value); JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (new_array)); @@ -1941,10 +1979,10 @@ ecma_builtin_array_prototype_object_map (ecma_value_t arg1, /**< callbackfn */ /* 7-8. */ ecma_value_t current_index; - for (uint32_t index = 0; index < len; index++) + for (ecma_length_t index = 0; index < len; index++) { /* 8.a - 8.b */ - ecma_value_t current_value = ecma_op_object_find_by_uint32_index (obj_p, index); + ecma_value_t current_value = ecma_op_object_find_by_index (obj_p, index); if (ECMA_IS_VALUE_ERROR (current_value)) { @@ -1955,7 +1993,7 @@ ecma_builtin_array_prototype_object_map (ecma_value_t arg1, /**< callbackfn */ if (ecma_is_value_found (current_value)) { /* 8.c.i, 8.c.ii */ - current_index = ecma_make_uint32_value (index); + current_index = ecma_make_length_value (index); ecma_value_t call_args[] = { current_value, current_index, ecma_make_object_value (obj_p) }; ecma_value_t mapped_value = ecma_op_function_call (func_object_p, arg2, call_args, 3); @@ -1968,10 +2006,11 @@ ecma_builtin_array_prototype_object_map (ecma_value_t arg1, /**< callbackfn */ } /* 8.c.iii */ - ecma_value_t put_comp = ecma_builtin_helper_def_prop_by_index (new_array_p, - index, - mapped_value, - ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE); + ecma_value_t put_comp; + put_comp = ecma_builtin_helper_def_prop_by_index (new_array_p, + index, + mapped_value, + ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE); ecma_free_value (mapped_value); ecma_free_value (current_value); @@ -2002,8 +2041,8 @@ ecma_builtin_array_prototype_object_map (ecma_value_t arg1, /**< callbackfn */ static ecma_value_t ecma_builtin_array_prototype_object_filter (ecma_value_t arg1, /**< callbackfn */ ecma_value_t arg2, /**< thisArg */ - ecma_object_t *obj_p, /**< array object */ - uint32_t len) /**< array object's length */ + ecma_object_t *obj_p, /**< object */ + ecma_length_t len) /**< object's length */ { /* 4. */ if (!ecma_op_is_callable (arg1)) @@ -2031,14 +2070,14 @@ ecma_builtin_array_prototype_object_filter (ecma_value_t arg1, /**< callbackfn * ecma_object_t *func_object_p = ecma_get_object_from_value (arg1); /* 8. */ - uint32_t new_array_index = 0; + ecma_length_t new_array_index = 0; ecma_value_t current_index; /* 9. */ - for (uint32_t index = 0; index < len; index++) + for (ecma_length_t index = 0; index < len; index++) { /* 9.a - 9.c */ - ecma_value_t get_value = ecma_op_object_find_by_uint32_index (obj_p, index); + ecma_value_t get_value = ecma_op_object_find_by_index (obj_p, index); if (ECMA_IS_VALUE_ERROR (get_value)) { @@ -2049,7 +2088,7 @@ ecma_builtin_array_prototype_object_filter (ecma_value_t arg1, /**< callbackfn * if (ecma_is_value_found (get_value)) { /* 9.c.i */ - current_index = ecma_make_uint32_value (index); + current_index = ecma_make_length_value (index); ecma_value_t call_args[] = { get_value, current_index, ecma_make_object_value (obj_p) }; /* 9.c.ii */ @@ -2065,10 +2104,11 @@ ecma_builtin_array_prototype_object_filter (ecma_value_t arg1, /**< callbackfn * /* 9.c.iii */ if (ecma_op_to_boolean (call_value)) { - ecma_value_t put_comp = ecma_builtin_helper_def_prop_by_index (new_array_p, - new_array_index, - get_value, - ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE); + ecma_value_t put_comp; + put_comp = ecma_builtin_helper_def_prop_by_index (new_array_p, + new_array_index, + get_value, + ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE); #if ENABLED (JERRY_ESNEXT) if (ECMA_IS_VALUE_ERROR (put_comp)) { @@ -2106,8 +2146,8 @@ static ecma_value_t ecma_builtin_array_reduce_from (const ecma_value_t args_p[], /**< routine's arguments */ uint32_t args_number, /**< arguments list length */ bool start_from_left, /**< whether the reduce starts from left or right */ - ecma_object_t *obj_p, /**< array object */ - uint32_t len) /**< array object's length */ + ecma_object_t *obj_p, /**< object */ + ecma_length_t len) /**< object's length */ { /* 4. */ if (!ecma_op_is_callable (args_p[0])) @@ -2127,8 +2167,8 @@ ecma_builtin_array_reduce_from (const ecma_value_t args_p[], /**< routine's argu ecma_value_t accumulator = ECMA_VALUE_UNDEFINED; /* 6. */ - uint32_t index = 0; - const uint32_t last_index = len - 1; + ecma_length_t index = 0; + const ecma_length_t last_index = len - 1; /* 7.a */ if (args_number > 1) @@ -2147,8 +2187,8 @@ ecma_builtin_array_reduce_from (const ecma_value_t args_p[], /**< routine's argu k_present = true; /* 8.b.ii-iii */ - ecma_value_t current_value = ecma_op_object_find_by_uint32_index (obj_p, start_from_left ? index : - last_index - index); + ecma_value_t current_value = ecma_op_object_find_by_index (obj_p, start_from_left ? index + : last_index - index); if (ECMA_IS_VALUE_ERROR (current_value)) { @@ -2179,10 +2219,10 @@ ecma_builtin_array_reduce_from (const ecma_value_t args_p[], /**< routine's argu for (; index < len; index++) { - const uint32_t corrected_index = start_from_left ? index : last_index - index; + const ecma_length_t corrected_index = start_from_left ? index : last_index - index; /* 9.a - 9.b */ - ecma_value_t current_value = ecma_op_object_find_by_uint32_index (obj_p, corrected_index); + ecma_value_t current_value = ecma_op_object_find_by_index (obj_p, corrected_index); if (ECMA_IS_VALUE_ERROR (current_value)) { @@ -2193,7 +2233,7 @@ ecma_builtin_array_reduce_from (const ecma_value_t args_p[], /**< routine's argu if (ecma_is_value_found (current_value)) { /* 9.c.i, 9.c.ii */ - current_index = ecma_make_uint32_value (corrected_index); + current_index = ecma_make_length_value (corrected_index); ecma_value_t call_args[] = {accumulator, current_value, current_index, ecma_make_object_value (obj_p)}; ecma_value_t call_value = ecma_op_function_call (func_object_p, @@ -2233,10 +2273,10 @@ static ecma_value_t ecma_builtin_array_prototype_fill (ecma_value_t value, /**< value */ ecma_value_t start_val, /**< start value */ ecma_value_t end_val, /**< end value */ - ecma_object_t *obj_p, /**< array object */ - uint32_t len) /**< array object's length */ + ecma_object_t *obj_p, /**< object */ + ecma_length_t len) /**< object's length */ { - uint32_t k, final; + ecma_length_t k, final; /* 5. 6. 7. */ if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (start_val, @@ -2293,7 +2333,7 @@ ecma_builtin_array_prototype_fill (ecma_value_t value, /**< value */ while (k < final) { /* 11.a - 11.b */ - ecma_value_t put_val = ecma_op_object_put_by_number_index (obj_p, k, value, true); + ecma_value_t put_val = ecma_op_object_put_by_index (obj_p, k, value, true); /* 11. c */ if (ECMA_IS_VALUE_ERROR (put_val)) @@ -2325,8 +2365,8 @@ ecma_builtin_array_prototype_object_find (ecma_value_t predicate, /**< callback * invoke predicate */ bool is_find, /**< true - find routine * false - findIndex routine */ - ecma_object_t *obj_p, /**< array object */ - uint32_t len) /**< array object's length */ + ecma_object_t *obj_p, /**< object */ + ecma_length_t len) /**< object's length */ { /* 5. */ if (!ecma_op_is_callable (predicate)) @@ -2339,10 +2379,10 @@ ecma_builtin_array_prototype_object_find (ecma_value_t predicate, /**< callback ecma_object_t *func_object_p = ecma_get_object_from_value (predicate); /* 7 - 8. */ - for (uint32_t index = 0; index < len; index++) + for (ecma_length_t index = 0; index < len; index++) { /* 8.a - 8.c */ - ecma_value_t get_value = ecma_op_object_get_by_uint32_index (obj_p, index); + ecma_value_t get_value = ecma_op_object_get_by_index (obj_p, index); if (ECMA_IS_VALUE_ERROR (get_value)) { @@ -2350,7 +2390,7 @@ ecma_builtin_array_prototype_object_find (ecma_value_t predicate, /**< callback } /* 8.d - 8.e */ - ecma_value_t current_index = ecma_make_uint32_value (index); + ecma_value_t current_index = ecma_make_length_value (index); ecma_value_t call_args[] = { get_value, current_index, ecma_make_object_value (obj_p) }; @@ -2399,8 +2439,8 @@ ecma_builtin_array_prototype_object_find (ecma_value_t predicate, /**< callback static ecma_value_t ecma_builtin_array_prototype_object_copy_within (const ecma_value_t args[], /**< arguments list */ uint32_t args_number, /**< number of arguments */ - ecma_object_t *obj_p, /**< array object */ - uint32_t len) /**< array object's length */ + ecma_object_t *obj_p, /**< object */ + ecma_length_t len) /**< object's length */ { if (args_number == 0) { @@ -2408,15 +2448,15 @@ ecma_builtin_array_prototype_object_copy_within (const ecma_value_t args[], /**< } /* 5 - 7 */ - uint32_t target; + ecma_length_t target; if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (args[0], len, &target))) { return ECMA_VALUE_ERROR; } - uint32_t start = 0; - uint32_t end = len; + ecma_length_t start = 0; + ecma_length_t end = len; if (args_number > 1) { @@ -2450,7 +2490,7 @@ ecma_builtin_array_prototype_object_copy_within (const ecma_value_t args[], /**< return ecma_make_object_value (obj_p); } - uint32_t count = JERRY_MIN (end - start, len - target); + ecma_length_t count = JERRY_MIN (end - start, len - target); bool forward = true; @@ -2499,7 +2539,7 @@ ecma_builtin_array_prototype_object_copy_within (const ecma_value_t args[], /**< while (count > 0) { - ecma_value_t get_value = ecma_op_object_find_by_uint32_index (obj_p, start); + ecma_value_t get_value = ecma_op_object_find_by_index (obj_p, start); if (ECMA_IS_VALUE_ERROR (get_value)) { @@ -2510,11 +2550,11 @@ ecma_builtin_array_prototype_object_copy_within (const ecma_value_t args[], /**< if (ecma_is_value_found (get_value)) { - op_value = ecma_op_object_put_by_uint32_index (obj_p, target, get_value, true); + op_value = ecma_op_object_put_by_index (obj_p, target, get_value, true); } else { - op_value = ecma_op_object_delete_by_uint32_index (obj_p, target, true); + op_value = ecma_op_object_delete_by_index (obj_p, target, true); } ecma_free_value (get_value); @@ -2555,8 +2595,8 @@ ecma_builtin_array_prototype_object_copy_within (const ecma_value_t args[], /**< static ecma_value_t ecma_builtin_array_prototype_includes (const ecma_value_t args[], /**< arguments list */ uint32_t args_number, /**< number of arguments */ - ecma_object_t *obj_p, /**< array object */ - uint32_t len) /**< array object's length */ + ecma_object_t *obj_p, /**< object */ + ecma_length_t len) /**< object's length */ { /* 3. */ if (len == 0) @@ -2564,7 +2604,7 @@ ecma_builtin_array_prototype_includes (const ecma_value_t args[], /**< arguments return ECMA_VALUE_FALSE; } - uint32_t from_index = 0; + ecma_length_t from_index = 0; /* 4-7. */ if (args_number > 1) @@ -2606,7 +2646,7 @@ ecma_builtin_array_prototype_includes (const ecma_value_t args[], /**< arguments /* 8. */ while (from_index < len) { - ecma_value_t element = ecma_op_object_get_by_uint32_index (obj_p, from_index); + ecma_value_t element = ecma_op_object_get_by_index (obj_p, from_index); if (ECMA_IS_VALUE_ERROR (element)) { @@ -2637,10 +2677,10 @@ ecma_builtin_array_prototype_includes (const ecma_value_t args[], /**< arguments ecma_value_t ecma_builtin_array_prototype_dispatch_routine (uint16_t builtin_routine_id, /**< built-in wide routine * identifier */ - ecma_value_t this_arg, /**< 'this' argument value */ - const ecma_value_t arguments_list_p[], /**< list of arguments + ecma_value_t this_arg, /**< 'this' argument value */ + const ecma_value_t arguments_list_p[], /**< list of arguments * passed to routine */ - uint32_t arguments_number) /**< length of arguments' list */ + uint32_t arguments_number) /**< length of arguments' list */ { ecma_value_t obj_this = ecma_op_to_object (this_arg); @@ -2694,7 +2734,7 @@ ecma_builtin_array_prototype_dispatch_routine (uint16_t builtin_routine_id, /**< } #endif /* ENABLED (JERRY_ESNEXT) */ - uint32_t length; + ecma_length_t length; ecma_value_t len_value = ecma_op_object_get_length (obj_p, &length); if (ECMA_IS_VALUE_ERROR (len_value)) diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-array.c b/jerry-core/ecma/builtin-objects/ecma-builtin-array.c index 09a7cf59d..d743f5bf5 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-array.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-array.c @@ -274,7 +274,7 @@ iterator_cleanup: ecma_object_t *array_like_obj_p = ecma_get_object_from_value (array_like); /* 10. */ - uint32_t len; + ecma_length_t len; ecma_value_t len_value = ecma_op_object_get_length (array_like_obj_p, &len); /* 11. */ @@ -283,7 +283,7 @@ iterator_cleanup: goto cleanup; } - len_value = ecma_make_uint32_value (len); + len_value = ecma_make_length_value (len); /* 12. */ ecma_value_t array; @@ -319,13 +319,13 @@ iterator_cleanup: ecma_object_t *array_obj_p = ecma_get_object_from_value (array); /* 15. */ - uint32_t k = 0; + ecma_length_t k = 0; /* 16. */ while (k < len) { /* 16.b */ - ecma_value_t k_value = ecma_op_object_get_by_uint32_index (array_like_obj_p, k); + ecma_value_t k_value = ecma_op_object_get_by_index (array_like_obj_p, k); /* 16.c */ if (ECMA_IS_VALUE_ERROR (k_value)) @@ -338,7 +338,7 @@ iterator_cleanup: if (mapfn_obj_p != NULL) { /* 16.d.i */ - ecma_value_t args_p[2] = { k_value, ecma_make_uint32_value (k) }; + ecma_value_t args_p[2] = { k_value, ecma_make_length_value (k) }; mapped_value = ecma_op_function_call (mapfn_obj_p, call_this_arg, args_p, 2); ecma_free_value (args_p[1]); ecma_free_value (k_value); @@ -372,7 +372,7 @@ iterator_cleanup: } /* 17. */ - len_value = ecma_make_uint32_value (k); + len_value = ecma_make_length_value (k); ecma_value_t set_status = ecma_op_object_put (array_obj_p, ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH), len_value, diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-arraybuffer-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-arraybuffer-prototype.c index 3c37be848..39d9105e2 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-arraybuffer-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-arraybuffer-prototype.c @@ -111,18 +111,18 @@ ecma_builtin_arraybuffer_prototype_object_slice (ecma_value_t this_arg, /**< thi ecma_value_t ret_value = ECMA_VALUE_EMPTY; - if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (arg1, - len, - &start))) + if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_uint32_index_normalize (arg1, + len, + &start))) { return ECMA_VALUE_ERROR; } if (!ecma_is_value_undefined (arg2)) { - if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (arg2, - len, - &end))) + if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_uint32_index_normalize (arg2, + len, + &end))) { return ECMA_VALUE_ERROR; } diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-function-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-function-prototype.c index 90a35b185..5a3633585 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-function-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-function-prototype.c @@ -114,7 +114,7 @@ ecma_builtin_function_prototype_object_apply (ecma_object_t *func_obj_p, /**< th ecma_object_t *obj_p = ecma_get_object_from_value (arg2); /* 4-5. */ - uint32_t length; + ecma_length_t length; ecma_value_t len_value = ecma_op_object_get_length (obj_p, &length); if (ECMA_IS_VALUE_ERROR (len_value)) @@ -130,12 +130,12 @@ ecma_builtin_function_prototype_object_apply (ecma_object_t *func_obj_p, /**< th /* 6. */ ecma_value_t ret_value = ECMA_VALUE_EMPTY; JMEM_DEFINE_LOCAL_ARRAY (arguments_list_p, length, ecma_value_t); - uint32_t index = 0; + ecma_length_t index = 0; /* 7. */ for (index = 0; index < length; index++) { - ecma_value_t get_value = ecma_op_object_get_by_uint32_index (obj_p, index); + ecma_value_t get_value = ecma_op_object_get_by_index (obj_p, index); if (ECMA_IS_VALUE_ERROR (get_value)) { @@ -152,7 +152,7 @@ ecma_builtin_function_prototype_object_apply (ecma_object_t *func_obj_p, /**< th ret_value = ecma_op_function_call (func_obj_p, arg1, arguments_list_p, - length); + (uint32_t) length); } for (uint32_t remove_index = 0; remove_index < index; remove_index++) diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c index c972a978e..76606fac9 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c @@ -196,9 +196,9 @@ ecma_builtin_helper_object_to_string (const ecma_value_t this_arg) /**< this arg */ ecma_string_t * ecma_builtin_helper_get_to_locale_string_at_index (ecma_object_t *obj_p, /**< this object */ - uint32_t index) /**< array index */ + ecma_length_t index) /**< array index */ { - ecma_value_t index_value = ecma_op_object_get_by_uint32_index (obj_p, index); + ecma_value_t index_value = ecma_op_object_get_by_index (obj_p, index); if (ECMA_IS_VALUE_ERROR (index_value)) { @@ -232,9 +232,46 @@ ecma_builtin_helper_get_to_locale_string_at_index (ecma_object_t *obj_p, /**< th * See also: * ECMA-262 v5, 15.4.4.10 steps 5, 6, 7 part 2, 8 * ECMA-262 v5, 15.4.4.12 steps 5, 6 - * ECMA-262 v5, 15.5.4.13 steps 4 - 7 + * * ECMA-262 v6, 22.1.3.6 steps 5 - 7, 8 part 2, 9, 10 * ECMA-262 v6, 22.1.3.3 steps 5 - 10, 11 part 2, 12, 13 + * + * Used by: + * - The Array.prototype.slice routine. + * - The Array.prototype.splice routine. + * - The Array.prototype.fill routine. + * - The Array.prototype.copyWithin routine. + * + * @return ECMA_VALUE_EMPTY if successful + * conversion error otherwise + */ +ecma_value_t +ecma_builtin_helper_array_index_normalize (ecma_value_t arg, /**< index */ + ecma_length_t length, /**< array's length */ + ecma_length_t *number_p) /**< [out] ecma_length_t */ +{ +#if ENABLED (JERRY_ESNEXT) + ecma_number_t to_int; + + if (ECMA_IS_VALUE_ERROR (ecma_op_to_integer (arg, &to_int))) + { + return ECMA_VALUE_ERROR; + } + + *number_p = ((to_int < 0) ? (ecma_length_t) JERRY_MAX (((ecma_number_t) length + to_int), 0) + : (ecma_length_t) JERRY_MIN (to_int, (ecma_number_t) length)); + + return ECMA_VALUE_EMPTY; +#else /* !ENABLED (JERRY_ESNEXT) */ + return ecma_builtin_helper_uint32_index_normalize (arg, length, number_p); +#endif /* ENABLED (JERRY_ESNEXT) */ +} /* ecma_builtin_helper_array_index_normalize */ + +/** + * Helper function to normalizing an uint32 index + * + * See also: + * ECMA-262 v5, 15.5.4.13 steps 4 - 7 * ECMA-262 v6, 22.2.3.5 steps 5 - 10, 11 part 2, 12, 13 * ECMA-262 v6, 22.2.3.23 steps 5 - 10 * ECMA-262 v6, 24.1.4.3 steps 6 - 8, 9 part 2, 10, 11 @@ -242,10 +279,7 @@ ecma_builtin_helper_get_to_locale_string_at_index (ecma_object_t *obj_p, /**< th * ECMA-262 v6, 22.2.3.8 steps 5 - 7, 8 part 2, 9, 10 * * Used by: - * - The Array.prototype.slice routine. - * - The Array.prototype.splice routine. * - The String.prototype.slice routine. - * - The Array.prototype.fill routine. * - The Array.prototype.copyWithin routine. * - The TypedArray.prototype.copyWithin routine. * - The TypedArray.prototype.slice routine. @@ -256,10 +290,10 @@ ecma_builtin_helper_get_to_locale_string_at_index (ecma_object_t *obj_p, /**< th * @return ECMA_VALUE_EMPTY if successful * conversion error otherwise */ -uint32_t -ecma_builtin_helper_array_index_normalize (ecma_value_t arg, /**< index */ - uint32_t length, /**< array's length */ - uint32_t *number_p) /**< [out] uint32_t */ +ecma_value_t +ecma_builtin_helper_uint32_index_normalize (ecma_value_t arg, /**< index */ + uint32_t length, /**< array's length */ + uint32_t *number_p) /**< [out] uint32_t number */ { ecma_number_t to_int; @@ -268,11 +302,11 @@ ecma_builtin_helper_array_index_normalize (ecma_value_t arg, /**< index */ return ECMA_VALUE_ERROR; } - *number_p = ((to_int < 0) ? (uint32_t) JERRY_MAX ((length + to_int), 0) + *number_p = ((to_int < 0) ? (uint32_t) JERRY_MAX (length + to_int, 0) : (uint32_t) JERRY_MIN (to_int, length)); return ECMA_VALUE_EMPTY; -} /* ecma_builtin_helper_array_index_normalize */ +} /* ecma_builtin_helper_uint32_index_normalize */ /** * Helper function for concatenating an ecma_value_t to an Array. @@ -288,7 +322,7 @@ ecma_builtin_helper_array_index_normalize (ecma_value_t arg, /**< index */ */ ecma_value_t ecma_builtin_helper_array_concat_value (ecma_object_t *array_obj_p, /**< array */ - uint32_t *length_p, /**< [in,out] array's length */ + ecma_length_t *length_p, /**< [in,out] array's length */ ecma_value_t value) /**< value to concat */ { /* 5.b */ @@ -314,22 +348,28 @@ ecma_builtin_helper_array_concat_value (ecma_object_t *array_obj_p, /**< array * ecma_object_t *obj_p = ecma_get_object_from_value (value); #if ENABLED (JERRY_ESNEXT) - uint32_t arg_len; + ecma_length_t arg_len; ecma_value_t error = ecma_op_object_get_length (obj_p, &arg_len); if (ECMA_IS_VALUE_ERROR (error)) { return error; } + + /* 4 . */ + if (*length_p + arg_len > ECMA_NUMBER_MAX_SAFE_INTEGER) + { + return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid array length.")); + } #else /* !ENABLED (JERRY_ESNEXT) */ /* 5.b.ii */ uint32_t arg_len = ecma_array_get_length (obj_p); #endif /* ENABLED (JERRY_ESNEXT) */ /* 5.b.iii */ - for (uint32_t array_index = 0; array_index < arg_len; array_index++) + for (ecma_length_t array_index = 0; array_index < arg_len; array_index++) { /* 5.b.iii.2 */ - ecma_value_t get_value = ecma_op_object_find_by_uint32_index (obj_p, array_index); + ecma_value_t get_value = ecma_op_object_find_by_index (obj_p, array_index); if (ECMA_IS_VALUE_ERROR (get_value)) { @@ -725,7 +765,7 @@ ecma_builtin_helper_string_find_index (ecma_string_t *original_str_p, /**< index */ ecma_value_t ecma_builtin_helper_def_prop_by_index (ecma_object_t *obj_p, /**< object */ - uint32_t index, /**< property index */ + ecma_length_t index, /**< property index */ ecma_value_t value, /**< value */ uint32_t opts) /**< any combination of ecma_property_flag_t bits */ { @@ -737,11 +777,8 @@ ecma_builtin_helper_def_prop_by_index (ecma_object_t *obj_p, /**< object */ opts); } - ecma_string_t *index_str_p = ecma_new_non_direct_string_from_uint32 (index); - ecma_value_t ret_value = ecma_builtin_helper_def_prop (obj_p, - index_str_p, - value, - opts); + ecma_string_t *index_str_p = ecma_new_ecma_string_from_length (index); + ecma_value_t ret_value = ecma_builtin_helper_def_prop (obj_p, index_str_p, value, opts); ecma_deref_ecma_string (index_str_p); return ret_value; diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h index 226780518..1865e7543 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h @@ -44,12 +44,14 @@ typedef enum ecma_value_t ecma_builtin_helper_object_to_string (const ecma_value_t this_arg); ecma_string_t * -ecma_builtin_helper_get_to_locale_string_at_index (ecma_object_t *obj_p, uint32_t index); +ecma_builtin_helper_get_to_locale_string_at_index (ecma_object_t *obj_p, ecma_length_t index); +ecma_value_t +ecma_builtin_helper_array_concat_value (ecma_object_t *obj_p, ecma_length_t *length_p, ecma_value_t value); +ecma_value_t +ecma_builtin_helper_uint32_index_normalize (ecma_value_t arg, uint32_t length, uint32_t *number_p); +ecma_value_t +ecma_builtin_helper_array_index_normalize (ecma_value_t arg, ecma_length_t length, ecma_length_t *number_p); ecma_value_t -ecma_builtin_helper_array_concat_value (ecma_object_t *obj_p, uint32_t *length_p, ecma_value_t value); -uint32_t -ecma_builtin_helper_array_index_normalize (ecma_value_t arg, uint32_t length, uint32_t *number_p); -uint32_t ecma_builtin_helper_string_index_normalize (ecma_number_t index, uint32_t length, bool nan_to_zero); ecma_value_t ecma_builtin_helper_string_prototype_object_index_of (ecma_string_t *original_str_p, ecma_value_t arg1, @@ -61,8 +63,8 @@ ecma_value_t ecma_builtin_helper_def_prop (ecma_object_t *obj_p, ecma_string_t *name_p, ecma_value_t value, uint32_t opts); ecma_value_t -ecma_builtin_helper_def_prop_by_index (ecma_object_t *obj_p, uint32_t index, ecma_value_t value, uint32_t opts); - +ecma_builtin_helper_def_prop_by_index (ecma_object_t *obj_p, ecma_length_t index, ecma_value_t value, + uint32_t opts); /** * Context for replace substitutions */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-json.c b/jerry-core/ecma/builtin-objects/ecma-builtin-json.c index ff7dee890..56f31d067 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-json.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-json.c @@ -649,20 +649,23 @@ ecma_builtin_json_internalize_property (ecma_object_t *reviver_p, /**< reviver f if (ecma_is_value_true (is_array)) { /* 3.c.ii */ - uint32_t len; - ecma_value_t to_len = ecma_op_object_get_length (object_p, &len); + ecma_length_t length; + ecma_value_t to_len = ecma_op_object_get_length (object_p, &length); /* 3.c.iii */ +#if ENABLED (JERRY_BUILTIN_PROXY) if (ECMA_IS_VALUE_ERROR (to_len)) { ecma_deref_object (object_p); return to_len; } +#endif /* ENABLED (JERRY_BUILTIN_PROXY) */ + JERRY_ASSERT (ecma_is_value_empty (to_len)); /* 3.c.iv */ - for (uint32_t i = 0; i < len; i++) + for (ecma_length_t i = 0; i < length; i++) { - ecma_string_t *prop_index = ecma_new_ecma_string_from_uint32 (i); + ecma_string_t *prop_index = ecma_new_ecma_string_from_length (i); ecma_value_t new_element = ecma_builtin_json_internalize_property (reviver_p, object_p, prop_index); @@ -675,9 +678,7 @@ ecma_builtin_json_internalize_property (ecma_object_t *reviver_p, /**< reviver f if (ecma_is_value_undefined (new_element)) { - ecma_value_t delete_val = ecma_op_object_delete_by_uint32_index (object_p, - i, - false); + ecma_value_t delete_val = ecma_op_object_delete (object_p, prop_index, false); JERRY_ASSERT (ecma_is_value_boolean (delete_val)); } else @@ -1113,23 +1114,16 @@ ecma_builtin_json_serialize_array (ecma_json_stringify_context_t *context_p, /** const bool has_gap = !ecma_compare_ecma_string_to_magic_id (context_p->gap_str_p, LIT_MAGIC_STRING__EMPTY); /* 6. */ - uint32_t array_length; + ecma_length_t array_length; + ecma_value_t length_value = ecma_op_object_get_length (obj_p, &array_length); #if ENABLED (JERRY_BUILTIN_PROXY) - if (ECMA_OBJECT_IS_PROXY (obj_p)) + if (ECMA_IS_VALUE_ERROR (length_value)) { - ecma_value_t length_value = ecma_op_object_get_length (obj_p, &array_length); - - if (ECMA_IS_VALUE_ERROR (length_value)) - { - return length_value; - } + return length_value; } - else #endif /* ENABLED (JERRY_BUILTIN_PROXY) */ - { - array_length = ((ecma_extended_object_t *) obj_p)->u.array.length; - } + JERRY_ASSERT (ecma_is_value_empty (length_value)); ecma_stringbuilder_append_byte (&context_p->result_builder, LIT_CHAR_LEFT_SQUARE); @@ -1137,10 +1131,10 @@ ecma_builtin_json_serialize_array (ecma_json_stringify_context_t *context_p, /** lit_utf8_size_t last_prop = left_square; /* 8. - 9. */ - for (uint32_t index = 0; index < array_length; index++) + for (ecma_length_t index = 0; index < array_length; index++) { /* 9.a */ - ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (index); + ecma_string_t *index_str_p = ecma_new_ecma_string_from_length (index); if (has_gap) { @@ -1506,13 +1500,16 @@ ecma_builtin_json_stringify (ecma_value_t this_arg, /**< 'this' argument */ if (ecma_is_value_true (is_array)) { - uint32_t array_length; + ecma_length_t array_length; ecma_value_t to_len = ecma_op_object_get_length (obj_p, &array_length); +#if ENABLED (JERRY_BUILTIN_PROXY) if (ECMA_IS_VALUE_ERROR (to_len)) { return to_len; } +#endif /* ENABLED (JERRY_BUILTIN_PROXY) */ + JERRY_ASSERT (ecma_is_value_empty (to_len)); context.property_list_p = ecma_new_collection (); @@ -1521,7 +1518,7 @@ ecma_builtin_json_stringify (ecma_value_t this_arg, /**< 'this' argument */ /* 4.b.iii.5 */ while (index < array_length) { - ecma_value_t value = ecma_op_object_get_by_uint32_index (obj_p, index); + ecma_value_t value = ecma_op_object_get_by_index (obj_p, index); if (ECMA_IS_VALUE_ERROR (value)) { diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c index 2827b9680..e95486b52 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c @@ -688,9 +688,9 @@ ecma_builtin_string_prototype_object_slice (ecma_string_t *get_string_val, /**< /* 4. 6. */ lit_utf8_size_t start = 0, end = len; - if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (arg1, - len, - &start))) + if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_uint32_index_normalize (arg1, + len, + &start))) { return ECMA_VALUE_ERROR; } @@ -702,9 +702,9 @@ ecma_builtin_string_prototype_object_slice (ecma_string_t *get_string_val, /**< } else { - if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (arg2, - len, - &end))) + if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_uint32_index_normalize (arg2, + len, + &end))) { return ECMA_VALUE_ERROR; } @@ -778,7 +778,8 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_value, /**< this a } /* 8. */ - uint32_t limit = UINT32_MAX; + uint32_t limit = UINT32_MAX - 1; + if (!ecma_is_value_undefined (limit_value)) { /* ECMA-262 v11, 21.1.3.20 6 */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-string.c b/jerry-core/ecma/builtin-objects/ecma-builtin-string.c index be6156385..a03df9911 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-string.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-string.c @@ -180,7 +180,7 @@ ecma_builtin_string_object_raw (ecma_value_t this_arg, /**< 'this' argument */ ecma_value_t ret_value = ECMA_VALUE_ERROR; /* 7 - 8. */ - uint32_t literal_segments; + ecma_length_t literal_segments; if (ECMA_IS_VALUE_ERROR (ecma_op_object_get_length (raw_obj_p, &literal_segments))) { goto cleanup; @@ -197,13 +197,13 @@ ecma_builtin_string_object_raw (ecma_value_t this_arg, /**< 'this' argument */ ecma_stringbuilder_t builder = ecma_stringbuilder_create (); /* 11. */ - uint32_t next_index = 0; + ecma_length_t next_index = 0; /* 12. */ while (true) { /* 12.a,b */ - ecma_value_t next_seg = ecma_op_object_get_by_uint32_index (raw_obj_p, next_index); + ecma_value_t next_seg = ecma_op_object_get_by_index (raw_obj_p, next_index); if (ECMA_IS_VALUE_ERROR (next_seg)) { 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 1da28f126..aab818f1a 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 @@ -914,20 +914,22 @@ ecma_builtin_typedarray_prototype_set (ecma_value_t this_arg, /**< this argument /* 18.~ 19. */ ecma_object_t *source_obj_p = ecma_get_object_from_value (source_obj); - uint32_t source_length_uint32; + ecma_length_t source_length; - if (ECMA_IS_VALUE_ERROR (ecma_op_object_get_length (source_obj_p, &source_length_uint32))) + if (ECMA_IS_VALUE_ERROR (ecma_op_object_get_length (source_obj_p, &source_length))) { ecma_deref_object (source_obj_p); return ECMA_VALUE_ERROR; } /* 20. if srcLength + targetOffset > targetLength, throw a RangeError */ - if ((int64_t) source_length_uint32 + target_offset_uint32 > target_info.length) + if ((int64_t) source_length + target_offset_uint32 > target_info.length) { ecma_deref_object (source_obj_p); return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid range of index")); } + JERRY_ASSERT (source_length <= UINT32_MAX); + uint32_t source_length_uint32 = (uint32_t) source_length; /* 21.~ 25. */ uint32_t target_byte_index = target_offset_uint32 * target_info.element_size; @@ -937,7 +939,7 @@ ecma_builtin_typedarray_prototype_set (ecma_value_t this_arg, /**< this argument while (k < source_length_uint32) { - ecma_value_t elem = ecma_op_object_get_by_uint32_index (source_obj_p, k); + ecma_value_t elem = ecma_op_object_get_by_index (source_obj_p, k); if (ECMA_IS_VALUE_ERROR (elem)) { @@ -981,7 +983,7 @@ static ecma_string_t * ecma_op_typedarray_get_to_string_at_index (ecma_object_t *obj_p, /**< this object */ uint32_t index) /**< array index */ { - ecma_value_t index_value = ecma_op_object_get_by_uint32_index (obj_p, index); + ecma_value_t index_value = ecma_op_object_get_by_index (obj_p, index); if (ECMA_IS_VALUE_ERROR (index_value)) { @@ -1159,9 +1161,9 @@ ecma_builtin_typedarray_prototype_subarray (ecma_value_t this_arg, /**< this arg uint32_t begin_index_uint32 = 0, end_index_uint32 = 0; /* 7. relativeBegin */ - if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (begin, - info.length, - &begin_index_uint32))) + if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_uint32_index_normalize (begin, + info.length, + &begin_index_uint32))) { return ECMA_VALUE_ERROR; } @@ -1173,9 +1175,9 @@ ecma_builtin_typedarray_prototype_subarray (ecma_value_t this_arg, /**< this arg else { /* 10. relativeEnd */ - if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (end, - info.length, - &end_index_uint32))) + if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_uint32_index_normalize (end, + info.length, + &end_index_uint32))) { return ECMA_VALUE_ERROR; } @@ -1244,9 +1246,9 @@ ecma_builtin_typedarray_prototype_fill (ecma_value_t this_arg, /**< this argumen uint32_t begin_index_uint32 = 0, end_index_uint32 = 0; - if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (begin, - info.length, - &begin_index_uint32))) + if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_uint32_index_normalize (begin, + info.length, + &begin_index_uint32))) { return ECMA_VALUE_ERROR; } @@ -1257,9 +1259,9 @@ ecma_builtin_typedarray_prototype_fill (ecma_value_t this_arg, /**< this argumen } else { - if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (end, - info.length, - &end_index_uint32))) + if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_uint32_index_normalize (end, + info.length, + &end_index_uint32))) { return ECMA_VALUE_ERROR; } @@ -1772,27 +1774,27 @@ ecma_builtin_typedarray_prototype_copy_within (ecma_value_t this_arg, /**< this if (args_number > 0) { - if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (args[0], - info.length, - &relative_target))) + if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_uint32_index_normalize (args[0], + info.length, + &relative_target))) { return ECMA_VALUE_ERROR; } if (args_number > 1) { - if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (args[1], - info.length, - &relative_start))) + if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_uint32_index_normalize (args[1], + info.length, + &relative_start))) { return ECMA_VALUE_ERROR; } if (args_number > 2 && args[2] != ECMA_VALUE_UNDEFINED) { - if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (args[2], - info.length, - &relative_end))) + if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_uint32_index_normalize (args[2], + info.length, + &relative_end))) { return ECMA_VALUE_ERROR; } @@ -1850,18 +1852,18 @@ ecma_builtin_typedarray_prototype_slice (ecma_value_t this_arg, /**< this argume if (args_number > 0) { - if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (args[0], - info.length, - &relative_start))) + if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_uint32_index_normalize (args[0], + info.length, + &relative_start))) { return ECMA_VALUE_ERROR; } if (args_number > 1 && args[1] != ECMA_VALUE_UNDEFINED - && ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (args[1], - info.length, - &relative_end))) + && ECMA_IS_VALUE_ERROR (ecma_builtin_helper_uint32_index_normalize (args[1], + info.length, + &relative_end))) { return ECMA_VALUE_ERROR; } @@ -2059,7 +2061,7 @@ ecma_builtin_typedarray_prototype_includes (ecma_value_t this_arg, /**< this arg if (args_number > 1) { - if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (args[1], info.length, &from_index))) + if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_uint32_index_normalize (args[1], info.length, &from_index))) { return ECMA_VALUE_ERROR; } diff --git a/jerry-core/ecma/operations/ecma-array-object.c b/jerry-core/ecma/operations/ecma-array-object.c index 3e70e1d48..29fdbd6bd 100644 --- a/jerry-core/ecma/operations/ecma-array-object.c +++ b/jerry-core/ecma/operations/ecma-array-object.c @@ -652,7 +652,7 @@ ecma_op_create_array_object (const ecma_value_t *arguments_list_p, /**< list of ecma_value_t ecma_op_array_species_create (ecma_object_t *original_array_p, /**< The object from whom the new array object * is being created */ - uint32_t length) /**< length of the array */ + ecma_length_t length) /**< length of the array */ { ecma_value_t constructor = ECMA_VALUE_UNDEFINED; ecma_value_t original_array = ecma_make_object_value (original_array_p); @@ -698,7 +698,7 @@ ecma_op_array_species_create (ecma_object_t *original_array_p, /**< The object f if (ecma_is_value_undefined (constructor)) { - ecma_value_t length_val = ecma_make_uint32_value (length); + ecma_value_t length_val = ecma_make_length_value (length); ecma_value_t new_array = ecma_op_create_array_object (&length_val, 1, true); ecma_free_value (length_val); @@ -711,7 +711,7 @@ ecma_op_array_species_create (ecma_object_t *original_array_p, /**< The object f return ecma_raise_type_error (ECMA_ERR_MSG ("Invalid species constructor")); } - ecma_value_t len_val = ecma_make_uint32_value (length); + ecma_value_t len_val = ecma_make_length_value (length); ecma_object_t *ctor_object_p = ecma_get_object_from_value (constructor); ecma_value_t ret_val = ecma_op_function_construct (ctor_object_p, ctor_object_p, diff --git a/jerry-core/ecma/operations/ecma-array-object.h b/jerry-core/ecma/operations/ecma-array-object.h index a0c2e9562..a3c52b694 100644 --- a/jerry-core/ecma/operations/ecma-array-object.h +++ b/jerry-core/ecma/operations/ecma-array-object.h @@ -102,7 +102,7 @@ ecma_op_create_array_object (const ecma_value_t *arguments_list_p, uint32_t argu #if ENABLED (JERRY_ESNEXT) ecma_value_t ecma_op_array_species_create (ecma_object_t *original_array_p, - uint32_t length); + ecma_length_t length); ecma_value_t ecma_op_create_array_iterator (ecma_object_t *obj_p, diff --git a/jerry-core/ecma/operations/ecma-container-object.c b/jerry-core/ecma/operations/ecma-container-object.c index 0165c037b..7b40bc574 100644 --- a/jerry-core/ecma/operations/ecma-container-object.c +++ b/jerry-core/ecma/operations/ecma-container-object.c @@ -494,7 +494,7 @@ ecma_op_container_create (const ecma_value_t *arguments_list_p, /**< arguments l ecma_object_t *next_object_p = ecma_get_object_from_value (result); - result = ecma_op_object_get_by_uint32_index (next_object_p, 0); + result = ecma_op_object_get_by_index (next_object_p, 0); if (ECMA_IS_VALUE_ERROR (result)) { @@ -505,7 +505,7 @@ ecma_op_container_create (const ecma_value_t *arguments_list_p, /**< arguments l const ecma_value_t key = result; - result = ecma_op_object_get_by_uint32_index (next_object_p, 1); + result = ecma_op_object_get_by_index (next_object_p, 1); if (ECMA_IS_VALUE_ERROR (result)) { diff --git a/jerry-core/ecma/operations/ecma-conversion.c b/jerry-core/ecma/operations/ecma-conversion.c index 877b91234..c3a3ee2fb 100644 --- a/jerry-core/ecma/operations/ecma-conversion.c +++ b/jerry-core/ecma/operations/ecma-conversion.c @@ -946,7 +946,7 @@ ecma_op_to_integer (ecma_value_t value, /**< ecma value */ */ ecma_value_t ecma_op_to_length (ecma_value_t value, /**< ecma value */ - uint32_t *length) /**< [out] ecma number */ + ecma_length_t *length) /**< [out] ecma number */ { /* 1 */ if (ECMA_IS_VALUE_ERROR (value)) @@ -973,14 +973,14 @@ ecma_op_to_length (ecma_value_t value, /**< ecma value */ } /* 5 */ - if (num >= (ecma_number_t) UINT32_MAX) + if (num >= ECMA_NUMBER_MAX_SAFE_INTEGER) { - *length = UINT32_MAX; + *length = (ecma_length_t) ECMA_NUMBER_MAX_SAFE_INTEGER; return ECMA_VALUE_EMPTY; } /* 6 */ - *length = (uint32_t) num; + *length = (ecma_length_t) num; return ECMA_VALUE_EMPTY; #else /* !ENABLED (JERRY_ESNEXT) */ /* In the case of ES5, ToLength(ES6) operation is the same as ToUint32(ES5) */ @@ -1026,7 +1026,7 @@ ecma_op_create_list_from_array_like (ecma_value_t arr, /**< array value */ ecma_object_t *obj_p = ecma_get_object_from_value (arr); /* 4. 5. */ - uint32_t len; + ecma_length_t len; if (ECMA_IS_VALUE_ERROR (ecma_op_object_get_length (obj_p, &len))) { return NULL; @@ -1036,9 +1036,9 @@ ecma_op_create_list_from_array_like (ecma_value_t arr, /**< array value */ ecma_collection_t *list_ptr = ecma_new_collection (); /* 7. 8. */ - for (uint32_t idx = 0; idx < len; idx++) + for (ecma_length_t idx = 0; idx < len; idx++) { - ecma_value_t next = ecma_op_object_get_by_uint32_index (obj_p, idx); + ecma_value_t next = ecma_op_object_get_by_index (obj_p, idx); if (ECMA_IS_VALUE_ERROR (next)) { ecma_collection_free (list_ptr); diff --git a/jerry-core/ecma/operations/ecma-conversion.h b/jerry-core/ecma/operations/ecma-conversion.h index be1a25d19..dbceefa6e 100644 --- a/jerry-core/ecma/operations/ecma-conversion.h +++ b/jerry-core/ecma/operations/ecma-conversion.h @@ -50,7 +50,7 @@ ecma_string_t *ecma_op_to_string (ecma_value_t value); ecma_string_t *ecma_op_to_property_key (ecma_value_t value); ecma_value_t ecma_op_to_object (ecma_value_t value); ecma_value_t ecma_op_to_integer (ecma_value_t value, ecma_number_t *number_p); -ecma_value_t ecma_op_to_length (ecma_value_t value, uint32_t *length); +ecma_value_t ecma_op_to_length (ecma_value_t value, ecma_length_t *length); #if ENABLED (JERRY_ESNEXT) ecma_collection_t *ecma_op_create_list_from_array_like (ecma_value_t arr, bool prop_names_only); #endif /* ENABLED (JERRY_ESNEXT) */ diff --git a/jerry-core/ecma/operations/ecma-dataview-object.c b/jerry-core/ecma/operations/ecma-dataview-object.c index 2123dd260..52b078655 100644 --- a/jerry-core/ecma/operations/ecma-dataview-object.c +++ b/jerry-core/ecma/operations/ecma-dataview-object.c @@ -105,11 +105,12 @@ ecma_op_dataview_create (const ecma_value_t *arguments_list_p, /**< arguments li } /* 11 - 12. */ - uint32_t viewByteLength; + uint32_t view_byte_length; if (arguments_list_len > 2 && !ecma_is_value_undefined (arguments_list_p[2])) { /* 12.a */ - ecma_value_t byte_length_value = ecma_op_to_length (arguments_list_p[2], &viewByteLength); + ecma_length_t view_byte_to_length; + ecma_value_t byte_length_value = ecma_op_to_length (arguments_list_p[2], &view_byte_to_length); /* 12.b */ if (ECMA_IS_VALUE_ERROR (byte_length_value)) @@ -118,15 +119,18 @@ ecma_op_dataview_create (const ecma_value_t *arguments_list_p, /**< arguments li } /* 12.c */ - if ((ecma_number_t) offset + viewByteLength > buffer_byte_length) + if ((ecma_number_t) offset + (ecma_number_t) view_byte_to_length > buffer_byte_length) { return ecma_raise_range_error (ECMA_ERR_MSG ("Start offset is outside the bounds of the buffer.")); } + + JERRY_ASSERT (view_byte_to_length <= UINT32_MAX); + view_byte_length = (uint32_t) view_byte_to_length; } else { /* 11.a */ - viewByteLength = (uint32_t) (buffer_byte_length - offset); + view_byte_length = (uint32_t) (buffer_byte_length - offset); } /* 13. */ @@ -143,7 +147,7 @@ ecma_op_dataview_create (const ecma_value_t *arguments_list_p, /**< arguments li ecma_dataview_object_t *dataview_obj_p = (ecma_dataview_object_t *) object_p; dataview_obj_p->header.u.class_prop.class_id = LIT_MAGIC_STRING_DATAVIEW_UL; - dataview_obj_p->header.u.class_prop.u.length = viewByteLength; + dataview_obj_p->header.u.class_prop.u.length = view_byte_length; dataview_obj_p->buffer_p = buffer_p; dataview_obj_p->byte_offset = (uint32_t) offset; diff --git a/jerry-core/ecma/operations/ecma-objects.c b/jerry-core/ecma/operations/ecma-objects.c index 8279fd1bf..c270cb312 100644 --- a/jerry-core/ecma/operations/ecma-objects.c +++ b/jerry-core/ecma/operations/ecma-objects.c @@ -671,7 +671,7 @@ ecma_op_object_find_own (ecma_value_t base_value, /**< base value */ } /* ecma_op_object_find_own */ /** - * Search the value corresponding to an uint32_t property index + * Search the value corresponding to a property index * * Note: this method falls back to the general ecma_op_object_find * @@ -680,40 +680,20 @@ ecma_op_object_find_own (ecma_value_t base_value, /**< base value */ * Returned value must be freed with ecma_free_value */ ecma_value_t -ecma_op_object_find_by_uint32_index (ecma_object_t *object_p, /**< the object */ - uint32_t index) /**< property index */ +ecma_op_object_find_by_index (ecma_object_t *object_p, /**< the object */ + ecma_length_t index) /**< property index */ { if (JERRY_LIKELY (index <= ECMA_DIRECT_STRING_MAX_IMM)) { return ecma_op_object_find (object_p, ECMA_CREATE_DIRECT_UINT32_STRING (index)); } - ecma_string_t *index_str_p = ecma_new_non_direct_string_from_uint32 (index); + ecma_string_t *index_str_p = ecma_new_ecma_string_from_length (index); ecma_value_t ret_value = ecma_op_object_find (object_p, index_str_p); ecma_deref_ecma_string (index_str_p); return ret_value; -} /* ecma_op_object_find_by_uint32_index */ - -/** - * Search the value corresponding to an ecma_number_t property index - * - * Note: this method falls back to the general ecma_op_object_find - * - * @return ecma value if property is found - * ECMA_VALUE_NOT_FOUND if property is not found - * Returned value must be freed with ecma_free_value - */ -ecma_value_t -ecma_op_object_find_by_number_index (ecma_object_t *object_p, /**< the object */ - ecma_number_t index) /**< property index */ -{ - ecma_string_t *index_str_p = ecma_new_ecma_string_from_number (index); - ecma_value_t ret_value = ecma_op_object_find (object_p, index_str_p); - ecma_deref_ecma_string (index_str_p); - - return ret_value; -} /* ecma_op_object_find_by_number_index */ +} /* ecma_op_object_find_by_index */ /** * Search the value corresponding to a property name @@ -827,26 +807,26 @@ ecma_op_object_get_with_receiver (ecma_object_t *object_p, /**< the object */ } /* ecma_op_object_get_with_receiver */ /** - * [[Get]] operation of ecma object specified for uint32_t property index + * [[Get]] operation of ecma object specified for property index * * @return ecma value * Returned value must be freed with ecma_free_value */ ecma_value_t -ecma_op_object_get_by_uint32_index (ecma_object_t *object_p, /**< the object */ - uint32_t index) /**< property index */ +ecma_op_object_get_by_index (ecma_object_t *object_p, /**< the object */ + ecma_length_t index) /**< property index */ { if (JERRY_LIKELY (index <= ECMA_DIRECT_STRING_MAX_IMM)) { return ecma_op_object_get (object_p, ECMA_CREATE_DIRECT_UINT32_STRING (index)); } - ecma_string_t *index_str_p = ecma_new_non_direct_string_from_uint32 (index); + ecma_string_t *index_str_p = ecma_new_ecma_string_from_length (index); ecma_value_t ret_value = ecma_op_object_get (object_p, index_str_p); ecma_deref_ecma_string (index_str_p); return ret_value; -} /* ecma_op_object_get_by_uint32_index */ +} /* ecma_op_object_get_by_index */ /** * Perform ToLength(O.[[Get]]("length")) operation @@ -858,11 +838,11 @@ ecma_op_object_get_by_uint32_index (ecma_object_t *object_p, /**< the object */ */ ecma_value_t ecma_op_object_get_length (ecma_object_t *object_p, /**< the object */ - uint32_t *length_p) /**< [out] length value converted to uint32 */ + ecma_length_t *length_p) /**< [out] length value converted to uint32 */ { if (JERRY_LIKELY (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_ARRAY)) { - *length_p = ecma_array_get_length (object_p); + *length_p = (ecma_length_t) ecma_array_get_length (object_p); return ECMA_VALUE_EMPTY; } @@ -1023,7 +1003,7 @@ ecma_op_get_method_by_magic_id (ecma_value_t value, /**< ecma value */ #endif /* ENABLED (JERRY_ESNEXT) */ /** - * [[Put]] ecma general object's operation specialized for uint32_ property index + * [[Put]] ecma general object's operation specialized for property index * * Note: This function falls back to the general ecma_op_object_put * @@ -1031,10 +1011,10 @@ ecma_op_get_method_by_magic_id (ecma_value_t value, /**< ecma value */ * The returned value must be freed with ecma_free_value. */ ecma_value_t -ecma_op_object_put_by_uint32_index (ecma_object_t *object_p, /**< the object */ - uint32_t index, /**< property index */ - ecma_value_t value, /**< ecma value */ - bool is_throw) /**< flag that controls failure handling */ +ecma_op_object_put_by_index (ecma_object_t *object_p, /**< the object */ + ecma_length_t index, /**< property index */ + ecma_value_t value, /**< ecma value */ + bool is_throw) /**< flag that controls failure handling */ { if (JERRY_LIKELY (index <= ECMA_DIRECT_STRING_MAX_IMM)) { @@ -1044,33 +1024,12 @@ ecma_op_object_put_by_uint32_index (ecma_object_t *object_p, /**< the object */ is_throw); } - ecma_string_t *index_str_p = ecma_new_non_direct_string_from_uint32 (index); + ecma_string_t *index_str_p = ecma_new_ecma_string_from_length (index); ecma_value_t ret_value = ecma_op_object_put (object_p, index_str_p, value, is_throw); ecma_deref_ecma_string (index_str_p); return ret_value; -} /* ecma_op_object_put_by_uint32_index */ - -/** - * [[Put]] ecma general object's operation specialized for ecma_number_ property index - * - * Note: This function falls back to the general ecma_op_object_put - * - * @return ecma value - * The returned value must be freed with ecma_free_value. - */ -ecma_value_t -ecma_op_object_put_by_number_index (ecma_object_t *object_p, /**< the object */ - ecma_number_t index, /**< property index */ - ecma_value_t value, /**< ecma value */ - bool is_throw) /**< flag that controls failure handling */ -{ - ecma_string_t *index_str_p = ecma_new_ecma_string_from_number (index); - ecma_value_t ret_value = ecma_op_object_put (object_p, index_str_p, value, is_throw); - ecma_deref_ecma_string (index_str_p); - - return ret_value; -} /* ecma_op_object_put_by_number_index */ +} /* ecma_op_object_put_by_index */ /** * [[Put]] ecma general object's operation @@ -1568,7 +1527,7 @@ ecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */ } /* ecma_op_object_put_with_receiver */ /** - * [[Delete]] ecma object's operation specialized for uint32_t property index + * [[Delete]] ecma object's operation specialized for property index * * Note: * This method falls back to the general ecma_op_object_delete @@ -1577,42 +1536,21 @@ ecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */ * false - or type error otherwise (based in 'is_throw') */ ecma_value_t -ecma_op_object_delete_by_uint32_index (ecma_object_t *obj_p, /**< the object */ - uint32_t index, /**< property index */ - bool is_throw) /**< flag that controls failure handling */ +ecma_op_object_delete_by_index (ecma_object_t *obj_p, /**< the object */ + ecma_length_t index, /**< property index */ + bool is_throw) /**< flag that controls failure handling */ { if (JERRY_LIKELY (index <= ECMA_DIRECT_STRING_MAX_IMM)) { - return ecma_op_object_delete (obj_p, ECMA_CREATE_DIRECT_UINT32_STRING (index), is_throw); + return ecma_op_object_delete (obj_p, ECMA_CREATE_DIRECT_UINT32_STRING (index), is_throw);; } - ecma_string_t *index_str_p = ecma_new_non_direct_string_from_uint32 (index); + ecma_string_t *index_str_p = ecma_new_ecma_string_from_length (index); ecma_value_t ret_value = ecma_op_object_delete (obj_p, index_str_p, is_throw); ecma_deref_ecma_string (index_str_p); return ret_value; -} /* ecma_op_object_delete_by_uint32_index */ - -/** - * [[Delete]] ecma object's operation specialized for ecma_number_t property index - * - * Note: - * This method falls back to the general ecma_op_object_delete - * - * @return true - if deleted successfully - * false - or type error otherwise (based in 'is_throw') - */ -ecma_value_t -ecma_op_object_delete_by_number_index (ecma_object_t *obj_p, /**< the object */ - ecma_number_t index, /**< property index */ - bool is_throw) /**< flag that controls failure handling */ -{ - ecma_string_t *index_str_p = ecma_new_ecma_string_from_number (index); - ecma_value_t ret_value = ecma_op_object_delete (obj_p, index_str_p, is_throw); - ecma_deref_ecma_string (index_str_p); - - return ret_value; -} /* ecma_op_object_delete_by_number_index */ +} /* ecma_op_object_delete_by_index */ /** * [[Delete]] ecma object's operation diff --git a/jerry-core/ecma/operations/ecma-objects.h b/jerry-core/ecma/operations/ecma-objects.h index d4185b527..4ac2fe934 100644 --- a/jerry-core/ecma/operations/ecma-objects.h +++ b/jerry-core/ecma/operations/ecma-objects.h @@ -33,13 +33,12 @@ bool ecma_op_ordinary_object_has_own_property (ecma_object_t *object_p, ecma_str ecma_value_t ecma_op_object_has_property (ecma_object_t *object_p, ecma_string_t *property_name_p); ecma_value_t ecma_op_object_find_own (ecma_value_t base_value, ecma_object_t *object_p, ecma_string_t *property_name_p); ecma_value_t ecma_op_object_find (ecma_object_t *object_p, ecma_string_t *property_name_p); -ecma_value_t ecma_op_object_find_by_uint32_index (ecma_object_t *object_p, uint32_t index); -ecma_value_t ecma_op_object_find_by_number_index (ecma_object_t *object_p, ecma_number_t index); +ecma_value_t ecma_op_object_find_by_index (ecma_object_t *object_p, ecma_length_t index); ecma_value_t ecma_op_object_get (ecma_object_t *object_p, ecma_string_t *property_name_p); ecma_value_t ecma_op_object_get_with_receiver (ecma_object_t *object_p, ecma_string_t *property_name_p, ecma_value_t receiver); -ecma_value_t ecma_op_object_get_length (ecma_object_t *object_p, uint32_t *length_p); -ecma_value_t ecma_op_object_get_by_uint32_index (ecma_object_t *object_p, uint32_t index); +ecma_value_t ecma_op_object_get_length (ecma_object_t *object_p, ecma_length_t *length_p); +ecma_value_t ecma_op_object_get_by_index (ecma_object_t *object_p, ecma_length_t index); ecma_value_t ecma_op_object_get_by_magic_id (ecma_object_t *object_p, lit_magic_string_id_t property_id); #if ENABLED (JERRY_ESNEXT) ecma_string_t *ecma_op_get_global_symbol (lit_magic_string_id_t property_id); @@ -53,13 +52,10 @@ ecma_value_t ecma_op_object_put (ecma_object_t *object_p, ecma_string_t *propert bool is_throw); ecma_value_t ecma_op_object_put_with_receiver (ecma_object_t *object_p, ecma_string_t *property_name_p, ecma_value_t value, ecma_value_t receiver, bool is_throw); -ecma_value_t ecma_op_object_put_by_uint32_index (ecma_object_t *object_p, uint32_t index, - ecma_value_t value, bool is_throw); -ecma_value_t ecma_op_object_put_by_number_index (ecma_object_t *object_p, ecma_number_t index, - ecma_value_t value, bool is_throw); +ecma_value_t ecma_op_object_put_by_index (ecma_object_t *object_p, ecma_length_t index, + ecma_value_t value, bool is_throw); ecma_value_t ecma_op_object_delete (ecma_object_t *obj_p, ecma_string_t *property_name_p, bool is_throw); -ecma_value_t ecma_op_object_delete_by_uint32_index (ecma_object_t *obj_p, uint32_t index, bool is_throw); -ecma_value_t ecma_op_object_delete_by_number_index (ecma_object_t *obj_p, ecma_number_t index, bool is_throw); +ecma_value_t ecma_op_object_delete_by_index (ecma_object_t *obj_p, ecma_length_t index, bool is_throw); ecma_value_t ecma_op_object_default_value (ecma_object_t *obj_p, ecma_preferred_type_hint_t hint); ecma_value_t ecma_op_object_define_own_property (ecma_object_t *obj_p, ecma_string_t *property_name_p, const ecma_property_descriptor_t *property_desc_p); diff --git a/jerry-core/ecma/operations/ecma-promise-object.c b/jerry-core/ecma/operations/ecma-promise-object.c index 0db5fb856..27a0e8ce3 100644 --- a/jerry-core/ecma/operations/ecma-promise-object.c +++ b/jerry-core/ecma/operations/ecma-promise-object.c @@ -598,10 +598,10 @@ ecma_promise_all_handler_cb (const ecma_value_t function_obj, /**< the function } /* 8. */ - ecma_op_object_put_by_uint32_index (ecma_get_object_from_value (executor_p->values), - (uint32_t) (executor_p->index - 1), - args_p[0], - false); + ecma_op_object_put_by_index (ecma_get_object_from_value (executor_p->values), + (uint32_t) (executor_p->index - 1), + args_p[0], + false); /* 3. */ executor_p->index = 0; diff --git a/jerry-core/ecma/operations/ecma-regexp-object.c b/jerry-core/ecma/operations/ecma-regexp-object.c index 161204f24..17d8876fa 100644 --- a/jerry-core/ecma/operations/ecma-regexp-object.c +++ b/jerry-core/ecma/operations/ecma-regexp-object.c @@ -1762,7 +1762,7 @@ ecma_regexp_exec_helper (ecma_object_t *regexp_object_p, /**< RegExp object */ input_end_p); /* 4. */ - uint32_t index = 0; + ecma_length_t index = 0; ecma_value_t lastindex_value = ecma_op_object_get_by_magic_id (regexp_object_p, LIT_MAGIC_STRING_LASTINDEX_UL); #if ENABLED (JERRY_ESNEXT) @@ -1908,11 +1908,11 @@ match_found: goto cleanup_context; } + JERRY_ASSERT (index <= input_length); + /* 15. */ if (re_ctx.flags & (RE_FLAG_GLOBAL | RE_FLAG_STICKY)) { - JERRY_ASSERT (index <= input_length); - /* 13-14. */ lit_utf8_size_t match_length; const lit_utf8_byte_t *match_begin_p = re_ctx.captures_p[0].begin_p; @@ -1930,7 +1930,7 @@ match_found: ret_value = ecma_op_object_put (regexp_object_p, ecma_get_magic_string (LIT_MAGIC_STRING_LASTINDEX_UL), - ecma_make_uint32_value (index + match_length), + ecma_make_uint32_value ((uint32_t) index + match_length), true); if (ECMA_IS_VALUE_ERROR (ret_value)) @@ -1942,7 +1942,7 @@ match_found: } /* 16-27. */ - ret_value = ecma_regexp_create_result_object (&re_ctx, input_string_p, index); + ret_value = ecma_regexp_create_result_object (&re_ctx, input_string_p, (uint32_t) index); cleanup_context: ecma_regexp_cleanup_context (&re_ctx); @@ -2202,7 +2202,7 @@ ecma_regexp_split_helper (ecma_value_t this_arg, /**< this value */ ecma_object_t *const splitter_obj_p = ecma_get_object_from_value (splitter); /* 17. */ - uint32_t limit = UINT32_MAX; + uint32_t limit = UINT32_MAX - 1; if (!ecma_is_value_undefined (limit_arg)) { /* ECMA-262 v11, 21.2.5.13 13 */ @@ -2299,7 +2299,7 @@ ecma_regexp_split_helper (ecma_value_t this_arg, /**< this value */ goto cleanup_array; } - uint32_t end_index; + ecma_length_t end_index; const ecma_value_t length_value = ecma_op_to_length (result, &end_index); ecma_free_value (result); @@ -2343,10 +2343,11 @@ ecma_regexp_split_helper (ecma_value_t this_arg, /**< this value */ } /* 24.f.iv.6. */ - previous_index = end_index; + JERRY_ASSERT (end_index <= UINT32_MAX); + previous_index = (uint32_t) end_index; /* 24.f.iv.7-8. */ - uint32_t match_length; + ecma_length_t match_length; result = ecma_op_object_get_length (match_array_p, &match_length); if (ECMA_IS_VALUE_ERROR (result)) { @@ -2357,11 +2358,11 @@ ecma_regexp_split_helper (ecma_value_t this_arg, /**< this value */ /* 24.f.iv.9. */ match_length = (match_length > 0) ? match_length - 1 : match_length; - uint32_t match_index = 1; + ecma_length_t match_index = 1; while (match_index <= match_length) { /* 24.f.iv.11.a-b. */ - result = ecma_op_object_get_by_uint32_index (match_array_p, match_index++); + result = ecma_op_object_get_by_index (match_array_p, match_index++); if (ECMA_IS_VALUE_ERROR (result)) { ecma_deref_object (match_array_p); @@ -2388,7 +2389,8 @@ ecma_regexp_split_helper (ecma_value_t this_arg, /**< this value */ } /* 24.f.iv.12. */ - current_index = end_index; + JERRY_ASSERT (end_index <= UINT32_MAX); + current_index = (uint32_t) end_index; ecma_deref_object (match_array_p); } @@ -2412,7 +2414,7 @@ cleanup_string: ecma_deref_ecma_string (string_p); return result; -#else /* ENABLED (JERRY_ESNEXT) */ +#else /* !ENABLED (JERRY_ESNEXT) */ ecma_value_t result = ECMA_VALUE_ERROR; /* 2. */ @@ -2625,7 +2627,7 @@ ecma_regexp_replace_helper_fast (ecma_replace_context_t *ctx_p, /**string_p; const lit_utf8_byte_t *last_append_p = current_p; - lit_utf8_size_t index; + ecma_length_t index; ecma_regexp_ctx_t re_ctx; ecma_regexp_initialize_context (&re_ctx, @@ -2671,7 +2673,7 @@ ecma_regexp_replace_helper_fast (ecma_replace_context_t *ctx_p, /** 0) ? capture_count - 1 : capture_count; /* 16.d */ - result = ecma_op_object_get_by_uint32_index (current_object_p, 0); + result = ecma_op_object_get_by_index (current_object_p, 0); if (ECMA_IS_VALUE_ERROR (result)) { goto cleanup_builder; @@ -3172,10 +3174,10 @@ ecma_regexp_replace_helper (ecma_value_t this_arg, /**< this argument */ ecma_collection_push_back (arguments_p, ecma_make_string_value (matched_str_p)); /* 16.j, l */ - uint32_t n = 1; + ecma_length_t n = 1; while (n <= capture_count) { - result = ecma_op_object_get_by_uint32_index (current_object_p, n); + result = ecma_op_object_get_by_index (current_object_p, n); if (ECMA_IS_VALUE_ERROR (result)) { ecma_collection_free (arguments_p); @@ -3435,7 +3437,7 @@ ecma_regexp_match_helper (ecma_value_t this_arg, /**< this argument */ } ecma_object_t *result_value_p = ecma_get_object_from_value (result_value); - ecma_value_t match_value = ecma_op_object_get_by_uint32_index (result_value_p, 0); + ecma_value_t match_value = ecma_op_object_get_by_index (result_value_p, 0); ecma_deref_object (result_value_p); @@ -3472,7 +3474,7 @@ ecma_regexp_match_helper (ecma_value_t this_arg, /**< this argument */ } #if ENABLED (JERRY_ESNEXT) - uint32_t index; + ecma_length_t index; ecma_value_t length_value = ecma_op_to_length (this_index, &index); ecma_free_value (this_index); diff --git a/jerry-core/ecma/operations/ecma-typedarray-object.c b/jerry-core/ecma/operations/ecma-typedarray-object.c index 0b4e80401..a57f7af0b 100644 --- a/jerry-core/ecma/operations/ecma-typedarray-object.c +++ b/jerry-core/ecma/operations/ecma-typedarray-object.c @@ -894,8 +894,8 @@ 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 */ - uint32_t len; - ecma_value_t len_value = ecma_op_object_get_length (arraylike_object_p, &len); + 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)) { @@ -903,6 +903,14 @@ ecma_op_typedarray_from (ecma_value_t items_val, /**< the source array-like obje 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; + /* 14 */ ecma_value_t new_typedarray = ecma_typedarray_create_object_with_length (len, NULL, @@ -924,7 +932,7 @@ ecma_op_typedarray_from (ecma_value_t items_val, /**< the source array-like obje /* 17 */ for (uint32_t index = 0; index < len; index++) { - ecma_value_t current_value = ecma_op_object_find_by_uint32_index (arraylike_object_p, index); + ecma_value_t current_value = ecma_op_object_find_by_index (arraylike_object_p, index); if (ECMA_IS_VALUE_ERROR (current_value)) { @@ -1173,7 +1181,7 @@ ecma_op_create_typedarray (const ecma_value_t *arguments_list_p, /**< the arg li } else { - uint32_t new_length; + ecma_length_t new_length; if (ECMA_IS_VALUE_ERROR (ecma_op_to_length (arg3, &new_length))) { return ECMA_VALUE_ERROR; diff --git a/tests/jerry/es.next/string-prototype-split.js b/tests/jerry/es.next/string-prototype-split.js index 43ee26bd7..27cc79cbe 100644 --- a/tests/jerry/es.next/string-prototype-split.js +++ b/tests/jerry/es.next/string-prototype-split.js @@ -13,11 +13,11 @@ // limitations under the License. var str = "foo//bar/baz//foo"; -res = str.split("a", -1); -assert (res.length === 3); -assert (res[0] === "foo//b"); -assert (res[1] === "r/b"); -assert (res[2] === "z//foo"); - -res = str.split(/\/\//, Infinity); +res = str.split("a", Infinity); assert (res.length === 0); + +res = str.split(/\/\//, -1); +assert (res.length === 3); +assert (res[0] === "foo"); +assert (res[1] === "bar/baz"); +assert (res[2] === "foo"); diff --git a/tests/jerry/es.next/to-length.js b/tests/jerry/es.next/to-length.js new file mode 100644 index 000000000..b5e962b19 --- /dev/null +++ b/tests/jerry/es.next/to-length.js @@ -0,0 +1,149 @@ +// Copyright JS Foundation and other contributors, http://js.foundation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +function compareArray(a, b) { + if (b.length !== a.length) { + return false; + } + + for (var i = 0; i < a.length; i++) { + if (b[i] !== a[i]) { + return false; + } + } + return true; +} + +// concat +(function() { + try { + Array.prototype.concat.call({}, {[Symbol.isConcatSpreadable]: true, length : 2 **53 - 1}) + assert(false); + } catch (e) { + assert(e instanceof RangeError); + } + + try { + Array.prototype.concat.call([1, 2, 3, 4], {[Symbol.isConcatSpreadable]: true, length : 2 **53 - 4}) + assert(false); + } catch (e) { + assert(e instanceof RangeError); + } +})(); + +// fill +(function() { + var obj = { length: 2 ** 53 - 1, [2 ** 53 - 5] : 'foo'} + Array.prototype.fill.call(obj, 'bar', 2 ** 53 - 5) + + assert(obj[2 ** 53 - 5] === 'bar'); + assert(obj[2 ** 53 - 4] === 'bar'); + assert(obj[2 ** 53 - 3] === 'bar'); + assert(obj[2 ** 53 - 2] === 'bar'); + + obj = { length: 2 ** 53 + 2, [2 ** 53 - 2] : 'foo'} + Array.prototype.fill.call(obj, 'bar', 2 ** 53 - 2) + + assert(obj[2 ** 53 - 2] === 'bar'); + assert(obj[2 ** 53 - 1] === undefined); +})(); + +// includes +(function() { + var obj = { length: 2 ** 53 - 1, [2 ** 53 - 5] : 'foo'} + assert(Array.prototype.includes.call(obj, 'foo', 2 ** 53 - 10) === true); + + var obj = { length: 2 ** 53 - 1, [2 ** 53 + 5] : 'foo'} + assert(Array.prototype.includes.call(obj, 'foo', 2 ** 53 - 10) === false); +})(); + +// indexOf +(function() { + var obj = { length: 2 ** 53 - 1, [2 ** 53 - 5] : 'foo'} + assert(Array.prototype.indexOf.call(obj, 'foo', 2 ** 53 - 10) === 2 ** 53 - 5); + + var obj = { length: 2 ** 53 - 1, [2 ** 53 + 5] : 'foo'} + assert(Array.prototype.indexOf.call(obj, 'foo', 2 ** 53 - 10) === -1); +})(); + +// lastIndexOf +(function() { + var obj = { length: 2 ** 53 - 1, [2 ** 53 - 5] : 'foo', [2 ** 53 - 6] : 'foo'} + assert(Array.prototype.lastIndexOf.call(obj, 'foo', 2 ** 53 - 2) === 2 ** 53 - 5); + + var obj = { length: 2 ** 53 - 1, [2 ** 53 - 5] : 'foo', [2 ** 53 - 6] : 'foo'} + assert(Array.prototype.lastIndexOf.call(obj, 'foo', 10) === -1); +})(); + + +// pop +(function() { + var obj = { length: 2 ** 53 - 1, [2 ** 53 - 2] : 'foo', [2 ** 53 - 3] : 'bar'} + assert(Array.prototype.pop.call(obj) === 'foo'); + assert(obj.length === 2 ** 53 - 2); + + assert(Array.prototype.pop.call(obj) === 'bar'); + assert(obj.length === 2 ** 53 - 3); +})(); + +// push +(function() { + var obj = { length: 2 ** 53 - 1 }; + try { + Array.prototype.push.call(obj, 'foo'); + assert(false); + } catch (e) { + assert(e instanceof TypeError); + } + + var obj = { length: 2 ** 53 - 2, [2 ** 53 - 3] : 'foo'} + + assert(Array.prototype.push.call(obj, 'bar') === 2 ** 53 - 1); + assert(obj.length === 2 ** 53 - 1); +})(); + +// slice +(function() { + var obj = { length: 2 ** 53 - 1, [2 ** 53 - 5] : 'foo', [2 ** 53 - 2] : 'bar'}; + var sliced = Array.prototype.slice.call(obj, 2 ** 53 - 10); + assert(compareArray(sliced, [,,,,,'foo',,,'bar'])); + + var sliced = Array.prototype.slice.call(obj, 2 ** 53 - 8, 2 ** 53 - 4); + assert(compareArray(sliced, [,,,'foo',])); +})(); + +// splice +(function() { + var obj = { length: 2 ** 53 - 1, [2 ** 53 - 5] : 'foo', [2 ** 53 - 2] : 'bar'}; + var spliced = Array.prototype.splice.call(obj, 2 ** 53 - 10, 5, '1', '2', '3', '4'); + assert(compareArray(spliced, [,,,,,])); + assert(obj.length === 2 ** 53 - 2); + assert(obj[2 ** 53 - 3] === 'bar'); + assert(obj[2 ** 53 - 6] === 'foo'); + assert(obj[2 ** 53 - 7] === '4'); + assert(obj[2 ** 53 - 8] === '3'); + assert(obj[2 ** 53 - 9] === '2'); + assert(obj[2 ** 53 - 10] === '1'); +})(); + +// unshift +(function() { + var obj = { length: 2 ** 53 - 1 }; + try { + Array.prototype.unshift.call(obj, 'foo'); + assert(false); + } catch (e) { + assert(e instanceof TypeError); + } +})(); diff --git a/tests/test262-es6-excludelist.xml b/tests/test262-es6-excludelist.xml index 3f7e0f203..85b025693 100644 --- a/tests/test262-es6-excludelist.xml +++ b/tests/test262-es6-excludelist.xml @@ -44,19 +44,6 @@ - - - - - - - - - - - - - diff --git a/tests/unit-core/test-to-length.c b/tests/unit-core/test-to-length.c index 2e5b27a5a..4b1b65bac 100644 --- a/tests/unit-core/test-to-length.c +++ b/tests/unit-core/test-to-length.c @@ -35,11 +35,11 @@ main (void) jmem_init (); ecma_init (); - uint32_t num; + ecma_length_t num; ecma_value_t int_num = ecma_make_int32_value (123); - uint32_t result = ecma_op_to_length (int_num, &num); + ecma_value_t result = ecma_op_to_length (int_num, &num); ecma_free_value (int_num); @@ -88,7 +88,7 @@ main (void) TEST_ASSERT (!ECMA_IS_VALUE_ERROR (result)); #if ENABLED (JERRY_ESNEXT) - TEST_ASSERT (num == UINT32_MAX); + TEST_ASSERT (num == ECMA_NUMBER_MAX_SAFE_INTEGER); #else /* !ENABLED (JERRY_ESNEXT) */ TEST_ASSERT (num == 0); #endif /* ENABLED (JERRY_ESNEXT) */