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 53bfa4a74..3e5685e11 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c @@ -801,16 +801,14 @@ ecma_builtin_array_prototype_object_slice (ecma_value_t arg1, /**< start */ { uint32_t start = 0, end = len; - /* 5. */ - ecma_number_t start_num; - - if (ECMA_IS_VALUE_ERROR (ecma_get_number (arg1, &start_num))) + /* 5. 6.*/ + if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (arg1, + len, + &start))) { return ECMA_VALUE_ERROR; } - start = ecma_builtin_helper_array_index_normalize (start_num, len, false); - /* 7. */ if (ecma_is_value_undefined (arg2)) { @@ -818,15 +816,13 @@ ecma_builtin_array_prototype_object_slice (ecma_value_t arg1, /**< start */ } else { - /* 7. part 2 */ - ecma_number_t end_num; - - if (ECMA_IS_VALUE_ERROR (ecma_get_number (arg2, &end_num))) + /* 7. part 2, 8.*/ + if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (arg2, + len, + &end))) { return ECMA_VALUE_ERROR; } - - end = ecma_builtin_helper_array_index_normalize (end_num, len, false); } JERRY_ASSERT (start <= len && end <= len); @@ -1189,16 +1185,15 @@ ecma_builtin_array_prototype_object_splice (const ecma_value_t args[], /**< argu if (args_number > 0) { - /* 5. */ - ecma_number_t start_num; - if (ECMA_IS_VALUE_ERROR (ecma_get_number (args[0], &start_num))) + /* 5. 6. */ + if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (args[0], + len, + &start))) { ecma_deref_object (new_array_p); return ECMA_VALUE_ERROR; } - start = ecma_builtin_helper_array_index_normalize (start_num, len, false); - /* * If there is only one argument, that will be the start argument, * and we must delete the additional elements. @@ -1211,7 +1206,7 @@ ecma_builtin_array_prototype_object_splice (const ecma_value_t args[], /**< argu { /* 7. */ ecma_number_t delete_num; - if (ECMA_IS_VALUE_ERROR (ecma_get_number (args[1], &delete_num))) + if (ECMA_IS_VALUE_ERROR (ecma_op_to_integer (args[1], &delete_num))) { ecma_deref_object (new_array_p); return ECMA_VALUE_ERROR; @@ -1525,8 +1520,8 @@ ecma_builtin_array_prototype_object_unshift (const ecma_value_t args[], /**< arg * Returned value must be freed with ecma_free_value. */ static ecma_value_t -ecma_builtin_array_prototype_object_index_of (ecma_value_t arg1, /**< searchElement */ - ecma_value_t arg2, /**< fromIndex */ +ecma_builtin_array_prototype_object_index_of (const ecma_value_t args[], /**< arguments list */ + ecma_length_t args_number, /**< number of arguments */ ecma_object_t *obj_p, /**< array object */ uint32_t len) /**< array object's length */ { @@ -1537,14 +1532,32 @@ ecma_builtin_array_prototype_object_index_of (ecma_value_t arg1, /**< searchElem } /* 5. */ - ecma_number_t arg_from_idx; - - if (ECMA_IS_VALUE_ERROR (ecma_get_number (arg2, &arg_from_idx))) + ecma_number_t idx = 0; + if (args_number > 1) { - return ECMA_VALUE_ERROR; + if (ECMA_IS_VALUE_ERROR (ecma_op_to_integer (args[1], &idx))) + { + return ECMA_VALUE_ERROR; + } } - uint32_t from_idx = ecma_builtin_helper_array_index_normalize (arg_from_idx, len, false); + /* 6. */ + if (idx >= len) + { + return ecma_make_number_value (-1); + } + + /* 7. */ + ecma_number_t from_idx_num = idx; + + /* 8. */ + if (idx < 0) + { + from_idx_num = 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)) { @@ -1557,7 +1570,7 @@ ecma_builtin_array_prototype_object_index_of (ecma_value_t arg1, /**< searchElem while (from_idx < len) { - if (ecma_op_strict_equality_compare (arg1, buffer_p[from_idx])) + if (ecma_op_strict_equality_compare (args[0], buffer_p[from_idx])) { return ecma_make_uint32_value (from_idx); } @@ -1569,6 +1582,7 @@ ecma_builtin_array_prototype_object_index_of (ecma_value_t arg1, /**< searchElem } } + /* 6. */ while (from_idx < len) { /* 9.a */ @@ -1581,7 +1595,7 @@ ecma_builtin_array_prototype_object_index_of (ecma_value_t arg1, /**< searchElem /* 9.b.i, 9.b.ii */ if (ecma_is_value_found (get_value) - && ecma_op_strict_equality_compare (arg1, get_value)) + && ecma_op_strict_equality_compare (args[0], get_value)) { ecma_free_value (get_value); return ecma_make_uint32_value (from_idx); @@ -1616,17 +1630,31 @@ ecma_builtin_array_prototype_object_last_index_of (const ecma_value_t args[], /* return ecma_make_integer_value (-1); } - uint32_t from_idx = len - 1; - + /* 5. */ + ecma_number_t idx = (ecma_number_t) len - 1; if (args_number > 1) { - ecma_number_t arg_from_idx; - if (ECMA_IS_VALUE_ERROR (ecma_get_number (args[1], &arg_from_idx))) + if (ECMA_IS_VALUE_ERROR (ecma_op_to_integer (args[1], &idx))) { return ECMA_VALUE_ERROR; } + } - from_idx = ecma_builtin_helper_array_index_normalize (arg_from_idx, len, true); + uint32_t from_idx; + + /* 6 */ + if (idx >= 0) + { + from_idx = (uint32_t) (JERRY_MIN (idx, len - 1)); + } + else + { + ecma_number_t k = len + idx; + if (k < 0) + { + return ecma_make_integer_value (-1); + } + from_idx = (uint32_t) k; } ecma_value_t search_element = (args_number > 0) ? args[0] : ECMA_VALUE_UNDEFINED; @@ -1646,19 +1674,13 @@ ecma_builtin_array_prototype_object_last_index_of (const ecma_value_t args[], /* { return ecma_make_uint32_value (from_idx); } - from_idx--; } - return ecma_make_integer_value (-1); } } - /* 8. - * We should break from the loop when from_idx < 0. We can still use an uint32_t for from_idx, and check - * for an underflow instead. This is safe, because from_idx will always start in [0, len - 1], - * and len is in [0, UINT_MAX], so from_idx >= len means we've had an underflow, and should stop. - */ + /* 8. */ while (from_idx < len) { /* 8.a */ @@ -2116,57 +2138,33 @@ ecma_builtin_array_prototype_fill (ecma_value_t value, /**< value */ ecma_object_t *obj_p, /**< array object */ uint32_t len) /**< array object's length */ { - /* 5 */ - ecma_number_t start; - ecma_value_t to_number = ecma_op_to_integer (start_val, &start); + uint32_t k, final; - /* 6 */ - if (ECMA_IS_VALUE_ERROR (to_number)) + /* 5. 6. 7. */ + if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (start_val, + len, + &k))) { - return to_number; + return ECMA_VALUE_ERROR; } - ecma_number_t k; - - /* 7 */ - if (ecma_number_is_negative (start)) - { - k = JERRY_MAX (((ecma_number_t) len + start), 0); - } - else - { - k = JERRY_MIN (start, (ecma_number_t) len); - } - - /* 8 */ - ecma_number_t relative_end; - + /* 8. */ if (ecma_is_value_undefined (end_val)) { - relative_end = (ecma_number_t) len; + final = len; } else { - to_number = ecma_op_to_integer (end_val, &relative_end); - - if (ECMA_IS_VALUE_ERROR (to_number)) + /* 8 part 2, 9, 10 */ + if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (end_val, + len, + &final))) { - return to_number; + return ECMA_VALUE_ERROR; } } - /* 10 */ - ecma_number_t final; - if (relative_end < 0) - { - final = JERRY_MAX (((ecma_number_t) len + relative_end), 0); - } - else - { - final = JERRY_MIN (relative_end, (ecma_number_t) len); - } - - /* 11 */ + /* 11. */ while (k < final) { /* 11.a */ @@ -2291,49 +2289,39 @@ ecma_builtin_array_prototype_object_copy_within (const ecma_value_t args[], /**< return ecma_copy_value (ecma_make_object_value (obj_p)); } - ecma_number_t target_num; - ecma_value_t error = ecma_op_to_integer (args[0], &target_num); + /* 5 - 7 */ + uint32_t target; - if (ECMA_IS_VALUE_ERROR (error)) + if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (args[0], len, &target))) { - return error; + return ECMA_VALUE_ERROR; } - uint32_t target = (uint32_t) (ecma_number_is_negative (target_num) ? JERRY_MAX (len + target_num, 0) : - JERRY_MIN (target_num, len)); - uint32_t start = 0; uint32_t end = len; if (args_number > 1) { - ecma_number_t start_num; - error = ecma_op_to_integer (args[1], &start_num); - if (ECMA_IS_VALUE_ERROR (error)) + /* 8 - 10 */ + if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (args[1], len, &start))) { - return error; + return ECMA_VALUE_ERROR; } - start = (uint32_t) (ecma_number_is_negative (start_num) ? JERRY_MAX (len + start_num, 0) : - JERRY_MIN (start_num, len)); - if (args_number > 2) { + /* 11 */ if (ecma_is_value_undefined (args[2])) { end = len; } else { - ecma_number_t end_num; - error = ecma_op_to_integer (args[2], &end_num); - if (ECMA_IS_VALUE_ERROR (error)) + /* 11 part 2, 12, 13 */ + if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (args[2], len, &end))) { - return error; + return ECMA_VALUE_ERROR; } - - end = (uint32_t) (ecma_number_is_negative (end_num) ? JERRY_MAX (len + end_num, 0) : - JERRY_MIN (end_num, len)); } } } @@ -2617,8 +2605,8 @@ ecma_builtin_array_prototype_dispatch_routine (uint16_t builtin_routine_id, /**< } case ECMA_ARRAY_PROTOTYPE_INDEX_OF: { - ret_value = ecma_builtin_array_prototype_object_index_of (routine_arg_1, - routine_arg_2, + ret_value = ecma_builtin_array_prototype_object_index_of (arguments_list_p, + arguments_number, obj_p, length); break; 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 f870a245b..2256d38ed 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-arraybuffer-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-arraybuffer-prototype.c @@ -111,25 +111,23 @@ ecma_builtin_arraybuffer_prototype_object_slice (ecma_value_t this_arg, /**< thi ecma_value_t ret_value = ECMA_VALUE_EMPTY; - ECMA_OP_TO_NUMBER_TRY_CATCH (start_num, - arg1, - ret_value); - - start = ecma_builtin_helper_array_index_normalize (start_num, len, false); + if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (arg1, + len, + &start))) + { + return ECMA_VALUE_ERROR; + } if (!ecma_is_value_undefined (arg2)) { - ECMA_OP_TO_NUMBER_TRY_CATCH (end_num, - arg2, - ret_value); - - end = ecma_builtin_helper_array_index_normalize (end_num, len, false); - - ECMA_OP_TO_NUMBER_FINALIZE (end_num); + if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (arg2, + len, + &end))) + { + return ECMA_VALUE_ERROR; + } } - ECMA_OP_TO_NUMBER_FINALIZE (start_num); - if (ret_value != ECMA_VALUE_EMPTY) { return ret_value; diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c index 2a1d1442a..ed389220b 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c @@ -309,93 +309,49 @@ ecma_builtin_helper_object_get_properties (ecma_object_t *obj_p, /**< object */ /** * Helper function to normalizing an array index * - * This function clamps the given index to the [0, length] range. - * If the index is negative, it is used as the offset from the end of the array, - * to compute normalized index. - * If the index is greater than the length of the array, the normalized index will be the length of the array. - * If is_last_index_of is true, then we use the method in ECMA-262 v6, 22.2.3.16 to compute the normalized index. * See also: - * ECMA-262 v5, 15.4.4.10 steps 5-6, 7 (part 2) and 8 - * ECMA-262 v5, 15.4.4.12 steps 5-6 - * ECMA-262 v5, 15.4.4.14 steps 5 - * ECMA-262 v5, 15.5.4.13 steps 4, 5 (part 2) and 6-7 + * 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 + * 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 + * ECMA-262 v6, 22.2.3.26 steps 7 - 9, 10 part 2, 11, 12 + * 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 Array.prototype.indexOf routine. * - The String.prototype.slice routine. - * - The TypedArray.prototype.indexOf routine. - * - The TypedArray.prototype.lastIndexOf routine + * - The Array.prototype.fill routine. + * - The Array.prototype.copyWithin routine. + * - The TypedArray.prototype.copyWithin routine. + * - The TypedArray.prototype.slice routine. + * - The ArrayBuffer.prototype.slice routine. + * - The TypedArray.prototype.subarray routine. + * - The TypedArray.prototype.fill routine. * - * @return uint32_t - the normalized value of the index + * @return ECMA_VALUE_EMPTY if successful + * conversion error otherwise */ uint32_t -ecma_builtin_helper_array_index_normalize (ecma_number_t index, /**< index */ +ecma_builtin_helper_array_index_normalize (ecma_value_t arg, /**< index */ uint32_t length, /**< array's length */ - bool is_last_index_of) /**< true - normalize for lastIndexOf method*/ + uint32_t *number_p) /**< [out] uint32_t */ { - uint32_t norm_index; + ecma_number_t to_int; - if (!ecma_number_is_nan (index)) + if (ECMA_IS_VALUE_ERROR (ecma_op_to_integer (arg, &to_int))) { - - if (ecma_number_is_zero (index)) - { - norm_index = 0; - } - else if (ecma_number_is_infinity (index)) - { - if (is_last_index_of) - { - norm_index = ecma_number_is_negative (index) ? (uint32_t) -1 : length - 1; - } - else - { - norm_index = ecma_number_is_negative (index) ? 0 : length; - } - } - else - { - if (ecma_number_is_negative (index)) - { - ecma_number_t index_neg = -index; - - if (is_last_index_of) - { - norm_index = length - ecma_number_to_uint32 (index_neg); - } - else - { - if (index_neg > length) - { - norm_index = 0; - } - else - { - norm_index = length - ecma_number_to_uint32 (index_neg); - } - } - } - else - { - if (index > length) - { - norm_index = is_last_index_of ? length - 1 : length; - } - else - { - norm_index = ecma_number_to_uint32 (index); - } - } - } - } - else - { - norm_index = 0; + return ECMA_VALUE_ERROR; } - return norm_index; + *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 */ /** @@ -596,7 +552,19 @@ ecma_builtin_helper_string_prototype_object_index_of (ecma_string_t *original_st /* 4 (indexOf, lastIndexOf), 9 (startsWith, includes), 10 (endsWith) */ ecma_number_t pos_num; - ecma_value_t ret_value = ecma_get_number (arg2, &pos_num); + ecma_value_t ret_value; +#if ENABLED (JERRY_ES2015) + if (mode > ECMA_STRING_LAST_INDEX_OF) + { + ret_value = ecma_op_to_integer (arg2, &pos_num); + } + else + { +#endif /* ENABLED (JERRY_ES2015) */ + ret_value = ecma_get_number (arg2, &pos_num); +#if ENABLED (JERRY_ES2015) + } +#endif /* ENABLED (JERRY_ES2015) */ /* 10 (startsWith, includes), 11 (endsWith) */ if (ECMA_IS_VALUE_ERROR (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 ea355e8ef..cf6df4ace 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h @@ -34,8 +34,8 @@ typedef enum { /** These routines must be in this order */ - ECMA_STRING_INDEX_OF, /**< String.indexOf: ECMA-262 v5, 15.5.4.7 */ ECMA_STRING_LAST_INDEX_OF, /**< String.lastIndexOf: ECMA-262 v5, 15.5.4.8 */ + ECMA_STRING_INDEX_OF, /**< String.indexOf: ECMA-262 v5, 15.5.4.7 */ ECMA_STRING_STARTS_WITH, /**< String.startsWith: ECMA-262 v6, 21.1.3.18 */ ECMA_STRING_INCLUDES, /**< String.includes: ECMA-262 v6, 21.1.3.7 */ ECMA_STRING_ENDS_WITH /**< String.includes: ECMA-262 v6, 21.1.3.6 */ @@ -50,7 +50,7 @@ ecma_builtin_helper_object_get_properties (ecma_object_t *obj_p, uint32_t opts); 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_number_t index, uint32_t length, bool last_index_of); +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 diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-json.c b/jerry-core/ecma/builtin-objects/ecma-builtin-json.c index 32a8ac4bf..cea9da231 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-json.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-json.c @@ -1495,9 +1495,10 @@ ecma_builtin_json_stringify (ecma_value_t this_arg, /**< 'this' argument */ /* 6. */ if (ecma_is_value_number (space)) { - ecma_number_t number = ecma_get_number_from_value (space); /* 6.a */ - int32_t num_of_spaces = ecma_number_to_int32 (number); + ecma_number_t num_of_spaces; + ecma_op_to_integer (space, &num_of_spaces); + num_of_spaces = JERRY_MIN (10, num_of_spaces); /* 6.b */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-number-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-number-prototype.c index 2fb30e19d..e913450ba 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-number-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-number-prototype.c @@ -262,7 +262,7 @@ ecma_builtin_number_prototype_object_to_string (ecma_number_t this_arg_number, / { ecma_number_t arg_num; - if (ECMA_IS_VALUE_ERROR (ecma_get_number (arguments_list_p[0], &arg_num))) + if (ECMA_IS_VALUE_ERROR (ecma_op_to_integer (arguments_list_p[0], &arg_num))) { return ECMA_VALUE_ERROR; } @@ -369,14 +369,14 @@ ecma_builtin_number_prototype_object_to_string (ecma_number_t this_arg_number, / { for (int i = 0; i < magnitude; i++) { - this_arg_number /= (ecma_number_t) radix; + this_arg_number /= radix; } } else if (exponent < 0) { for (int i = 0; i < magnitude; i++) { - this_arg_number *= (ecma_number_t) radix; + this_arg_number *= radix; } } @@ -439,7 +439,7 @@ ecma_builtin_number_prototype_object_to_string (ecma_number_t this_arg_number, / /* Calculate digits for fractional part. */ while (buff_index < required_digits) { - fraction *= (ecma_number_t) radix; + fraction *= radix; lit_utf8_byte_t digit = (lit_utf8_byte_t) floor (fraction); buff[buff_index++] = digit; @@ -592,9 +592,9 @@ ecma_builtin_number_prepare_conversion (ecma_number_t *this_num_p, /**< [out] th JERRY_ASSERT (mode < NUMBER_ROUTINE__COUNT); ecma_number_t arg_num; - arg_1 = ecma_get_number (arg_1, &arg_num); + arg_1 = ecma_op_to_integer (arg_1, &arg_num); - if (!ecma_is_value_empty (arg_1)) + if (ECMA_IS_VALUE_ERROR (arg_1)) { return arg_1; } diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-number.c b/jerry-core/ecma/builtin-objects/ecma-builtin-number.c index 955e3e21f..ad1478d8d 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-number.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-number.c @@ -174,7 +174,8 @@ ecma_builtin_number_object_is_integer (ecma_value_t this_arg, /**< this argument return ECMA_VALUE_FALSE; } - ecma_number_t int_num = ecma_number_trunc (num); + ecma_number_t int_num; + ecma_op_to_integer (arg, &int_num); if (int_num != num) { 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 25f3ba47c..73fc6445b 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c @@ -80,8 +80,8 @@ enum ECMA_STRING_PROTOTYPE_REPEAT, ECMA_STRING_PROTOTYPE_CODE_POINT_AT, /* Note: These 5 routines MUST be in this order */ - ECMA_STRING_PROTOTYPE_INDEX_OF, ECMA_STRING_PROTOTYPE_LAST_INDEX_OF, + ECMA_STRING_PROTOTYPE_INDEX_OF, ECMA_STRING_PROTOTYPE_STARTS_WITH, ECMA_STRING_PROTOTYPE_INCLUDES, ECMA_STRING_PROTOTYPE_ENDS_WITH, @@ -151,7 +151,7 @@ ecma_builtin_string_prototype_char_at_helper (ecma_value_t this_arg, /**< this a { /* 3 */ ecma_number_t index_num; - ecma_value_t to_num_result = ecma_get_number (arg, &index_num); + ecma_value_t to_num_result = ecma_op_to_integer (arg, &index_num); if (JERRY_UNLIKELY (!ecma_is_value_empty (to_num_result))) { @@ -765,18 +765,16 @@ ecma_builtin_string_prototype_object_slice (ecma_string_t *get_string_val, /**< { const ecma_length_t len = ecma_string_get_length (get_string_val); - /* 4. */ + /* 4. 6. */ ecma_length_t start = 0, end = len; - ecma_number_t start_num; - - if (ECMA_IS_VALUE_ERROR (ecma_get_number (arg1, &start_num))) + if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (arg1, + len, + &start))) { return ECMA_VALUE_ERROR; } - start = ecma_builtin_helper_array_index_normalize (start_num, len, false); - /* 5. 7. */ if (ecma_is_value_undefined (arg2)) { @@ -784,14 +782,12 @@ ecma_builtin_string_prototype_object_slice (ecma_string_t *get_string_val, /**< } else { - ecma_number_t end_num; - - if (ECMA_IS_VALUE_ERROR (ecma_get_number (arg2, &end_num))) + if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (arg2, + len, + &end))) { return ECMA_VALUE_ERROR; } - - end = ecma_builtin_helper_array_index_normalize (end_num, len, false); } JERRY_ASSERT (start <= len && end <= len); @@ -1162,35 +1158,37 @@ ecma_builtin_string_prototype_object_substring (ecma_string_t *original_string_p ecma_value_t arg1, /**< routine's first argument */ ecma_value_t arg2) /**< routine's second argument */ { + /* 3 */ const ecma_length_t len = ecma_string_get_length (original_string_p); + ecma_length_t start = 0, end = len; - /* 4, 6 */ + /* 4 */ ecma_number_t start_num; - if (ECMA_IS_VALUE_ERROR (ecma_get_number (arg1, &start_num))) + if (ECMA_IS_VALUE_ERROR (ecma_op_to_integer (arg1, &start_num))) { return ECMA_VALUE_ERROR; } - ecma_length_t start = 0, end = len; + /* 6 */ + start = (uint32_t) JERRY_MIN (JERRY_MAX (start_num, 0), len); - start = ecma_builtin_helper_string_index_normalize (start_num, len, true); - - /* 5, 7 */ + /* 5 */ if (ecma_is_value_undefined (arg2)) { end = len; } else { + /* 5 part 2 */ ecma_number_t end_num; - if (ECMA_IS_VALUE_ERROR (ecma_get_number (arg2, &end_num))) + if (ECMA_IS_VALUE_ERROR (ecma_op_to_integer (arg2, &end_num))) { return ECMA_VALUE_ERROR; } - - end = ecma_builtin_helper_string_index_normalize (end_num, len, true); + /* 7 */ + end = (uint32_t) JERRY_MIN (JERRY_MAX (end_num, 0), len); } JERRY_ASSERT (start <= len && end <= len); @@ -1354,7 +1352,7 @@ ecma_builtin_string_prototype_object_repeat (ecma_string_t *original_string_p, / /* 4 */ ecma_number_t count_number; - ecma_value_t count_value = ecma_get_number (repeat, &count_number); + ecma_value_t count_value = ecma_op_to_integer (repeat, &count_number); /* 5 */ if (ECMA_IS_VALUE_ERROR (count_value)) @@ -1472,16 +1470,11 @@ ecma_builtin_string_prototype_object_substr (ecma_string_t *this_string_p, /**< /* 2. */ ecma_number_t start_num; - if (ECMA_IS_VALUE_ERROR (ecma_get_number (start, &start_num))) + if (ECMA_IS_VALUE_ERROR (ecma_op_to_integer (start, &start_num))) { return ECMA_VALUE_ERROR; } - if (ecma_number_is_nan (start_num)) - { - start_num = 0; - } - /* 3. */ ecma_number_t length_num = ecma_number_make_infinity (false); @@ -1489,7 +1482,7 @@ ecma_builtin_string_prototype_object_substr (ecma_string_t *this_string_p, /**< { ecma_number_t len; - if (ECMA_IS_VALUE_ERROR (ecma_get_number (length, &len))) + if (ECMA_IS_VALUE_ERROR (ecma_op_to_integer (length, &len))) { return ECMA_VALUE_ERROR; } @@ -1498,15 +1491,21 @@ ecma_builtin_string_prototype_object_substr (ecma_string_t *this_string_p, /**< } /* 4. */ - ecma_number_t this_len = (ecma_number_t) ecma_string_get_length (this_string_p); + ecma_length_t this_len = ecma_string_get_length (this_string_p); /* 5. */ - ecma_number_t from_num = (start_num < 0) ? JERRY_MAX (this_len + start_num, 0) : start_num; - uint32_t from = ecma_builtin_helper_string_index_normalize (from_num, ecma_number_to_uint32 (this_len), true); + uint32_t from = (uint32_t) ((start_num < 0) ? JERRY_MAX (this_len + start_num, 0) : start_num); - /* 6-7. */ - ecma_number_t to_num = JERRY_MAX (JERRY_MIN (JERRY_MAX (length_num, 0), this_len - from_num), 0); - uint32_t to = from + ecma_builtin_helper_string_index_normalize (to_num, ecma_number_to_uint32 (this_len), true); + if (from > this_len) + { + from = this_len; + } + + /* 6. */ + ecma_number_t to_num = JERRY_MIN (JERRY_MAX (length_num, 0), this_len - from); + + /* 7. */ + uint32_t to = from + (uint32_t) to_num; /* 8. */ ecma_string_t *new_str_p = ecma_string_substr (this_string_p, from, to); @@ -1595,8 +1594,8 @@ ecma_builtin_string_prototype_dispatch_routine (uint16_t builtin_routine_id, /** ret_value = ecma_builtin_string_prototype_object_slice (string_p, arg1, arg2); break; } - case ECMA_STRING_PROTOTYPE_INDEX_OF: case ECMA_STRING_PROTOTYPE_LAST_INDEX_OF: + case ECMA_STRING_PROTOTYPE_INDEX_OF: #if ENABLED (JERRY_ES2015) case ECMA_STRING_PROTOTYPE_STARTS_WITH: case ECMA_STRING_PROTOTYPE_INCLUDES: @@ -1604,7 +1603,7 @@ ecma_builtin_string_prototype_dispatch_routine (uint16_t builtin_routine_id, /** #endif /* ENABLED (JERRY_ES2015) */ { ecma_string_index_of_mode_t mode; - mode = (ecma_string_index_of_mode_t) (builtin_routine_id - ECMA_STRING_PROTOTYPE_INDEX_OF); + mode = (ecma_string_index_of_mode_t) (builtin_routine_id - ECMA_STRING_PROTOTYPE_LAST_INDEX_OF); ret_value = ecma_builtin_helper_string_prototype_object_index_of (string_p, arg1, arg2, mode); break; } 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 b9ecacc5f..a222f8dc8 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 @@ -835,16 +835,11 @@ ecma_op_typedarray_set_with_typedarray (ecma_value_t this_arg, /**< this argumen { /* 6.~ 8. targetOffset */ ecma_number_t target_offset_num; - if (ECMA_IS_VALUE_ERROR (ecma_get_number (offset_val, &target_offset_num))) + if (ECMA_IS_VALUE_ERROR (ecma_op_to_integer (offset_val, &target_offset_num))) { return ECMA_VALUE_ERROR; } - if (ecma_number_is_nan (target_offset_num)) - { - target_offset_num = 0; - } - if (target_offset_num <= -1.0 || target_offset_num >= (ecma_number_t) UINT32_MAX + 0.5) { return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid offset")); @@ -938,12 +933,14 @@ ecma_builtin_typedarray_prototype_set (ecma_value_t this_arg, /**< this argument } /* 6.~ 8. targetOffset */ - ecma_value_t ret_val = ECMA_VALUE_EMPTY; - ECMA_OP_TO_NUMBER_TRY_CATCH (target_offset_num, offset_val, ret_val); - if (ecma_number_is_nan (target_offset_num)) + ecma_number_t target_offset_num; + ecma_value_t ret_val = ecma_op_to_integer (offset_val, &target_offset_num); + + if (ECMA_IS_VALUE_ERROR (ret_val)) { - target_offset_num = 0; + return ret_val; } + if (target_offset_num <= -1.0 || target_offset_num >= (ecma_number_t) UINT32_MAX + 0.5) { return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid offset")); @@ -1007,7 +1004,6 @@ ecma_builtin_typedarray_prototype_set (ecma_value_t this_arg, /**< this argument ECMA_FINALIZE (source_length); ECMA_FINALIZE (source_obj); - ECMA_OP_TO_NUMBER_FINALIZE (target_offset_num); if (ecma_is_value_empty (ret_val)) { @@ -1253,9 +1249,12 @@ ecma_builtin_typedarray_prototype_subarray (ecma_value_t this_arg, /**< this arg uint32_t begin_index_uint32 = 0, end_index_uint32 = 0; /* 7. relativeBegin */ - ECMA_OP_TO_NUMBER_TRY_CATCH (relative_begin, begin, ret_value); - - begin_index_uint32 = ecma_builtin_helper_array_index_normalize (relative_begin, info.length, false); + if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (begin, + info.length, + &begin_index_uint32))) + { + return ECMA_VALUE_ERROR; + } if (ecma_is_value_undefined (end)) { @@ -1264,15 +1263,14 @@ ecma_builtin_typedarray_prototype_subarray (ecma_value_t this_arg, /**< this arg else { /* 10. relativeEnd */ - ECMA_OP_TO_NUMBER_TRY_CATCH (relative_end, end, ret_value); - - end_index_uint32 = ecma_builtin_helper_array_index_normalize (relative_end, info.length, false); - - ECMA_OP_TO_NUMBER_FINALIZE (relative_end); + if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (end, + info.length, + &end_index_uint32))) + { + return ECMA_VALUE_ERROR; + } } - ECMA_OP_TO_NUMBER_FINALIZE (relative_begin); - if (!ecma_is_value_empty (ret_value)) { return ret_value; @@ -1336,9 +1334,12 @@ ecma_builtin_typedarray_prototype_fill (ecma_value_t this_arg, /**< this argumen uint32_t begin_index_uint32 = 0, end_index_uint32 = 0; - ECMA_OP_TO_NUMBER_TRY_CATCH (relative_begin, begin, ret_value); - - begin_index_uint32 = ecma_builtin_helper_array_index_normalize (relative_begin, info.length, false); + if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (begin, + info.length, + &begin_index_uint32))) + { + return ECMA_VALUE_ERROR; + } if (ecma_is_value_undefined (end)) { @@ -1346,18 +1347,12 @@ ecma_builtin_typedarray_prototype_fill (ecma_value_t this_arg, /**< this argumen } else { - ECMA_OP_TO_NUMBER_TRY_CATCH (relative_end, end, ret_value); - - end_index_uint32 = ecma_builtin_helper_array_index_normalize (relative_end, info.length, false); - - ECMA_OP_TO_NUMBER_FINALIZE (relative_end); - } - - ECMA_OP_TO_NUMBER_FINALIZE (relative_begin); - - if (!ecma_is_value_empty (ret_value)) - { - return ret_value; + if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (end, + info.length, + &end_index_uint32))) + { + return ECMA_VALUE_ERROR; + } } ecma_length_t subarray_length = 0; @@ -1686,20 +1681,18 @@ ecma_builtin_typedarray_prototype_find_index (ecma_value_t this_arg, /**< this a } /* ecma_builtin_typedarray_prototype_find_index */ /** - * The %TypedArray%.prototype object's 'indexOf' and 'lastIndexOf' routine helper + * The %TypedArray%.prototype object's 'indexOf' routine * * See also: - * ECMA-262 v6, 22.2.3.13, 22.2.3.16 + * ECMA-262 v6, 22.2.3.13 * * @return ecma value * Returned value must be freed with ecma_free_value. */ static ecma_value_t -ecma_builtin_typedarray_prototype_index_helper (ecma_value_t this_arg, /**< this argument */ - const ecma_value_t args[], /**< arguments list */ - ecma_length_t args_number, /**< number of arguments */ - bool is_last_index_of) /**< true - lastIndexOf routine - false - indexOf routine */ +ecma_builtin_typedarray_prototype_index_of (ecma_value_t this_arg, /**< this argument */ + const ecma_value_t args[], /**< arguments list */ + ecma_length_t args_number) /**< number of arguments */ { if (!ecma_is_typedarray (this_arg)) { @@ -1716,6 +1709,7 @@ ecma_builtin_typedarray_prototype_index_helper (ecma_value_t this_arg, /**< this uint32_t limit = info.length * info.element_size; uint32_t from_index; + /* 5. */ if (args_number == 0 || !ecma_is_value_number (args[0]) || info.length == 0) @@ -1724,38 +1718,36 @@ ecma_builtin_typedarray_prototype_index_helper (ecma_value_t this_arg, /**< this } if (args_number == 1) { - from_index = is_last_index_of ? info.length - 1 : 0; + from_index = 0; } else { + /* 6. 7. */ ecma_number_t num_var; - - if (ECMA_IS_VALUE_ERROR (ecma_get_number (args[1], &num_var))) + if (ECMA_IS_VALUE_ERROR (ecma_op_to_integer (args[1], &num_var))) { return ECMA_VALUE_ERROR; } - - if (!ecma_number_is_nan (num_var) - && is_last_index_of - && num_var < 0 - && fabs (num_var) > info.length) + /* 8. */ + if (num_var >= info.length) { return ecma_make_integer_value (-1); } - else - { - from_index = ecma_builtin_helper_array_index_normalize (num_var, info.length, is_last_index_of); - } + + /* 9. 10. */ + from_index = ((num_var >= 0) ? (uint32_t) num_var + : (uint32_t) (info.length + num_var)); } + ecma_number_t search_num = ecma_get_number_from_value (args[0]); - int32_t increment = is_last_index_of ? -info.element_size : info.element_size; ecma_typedarray_getter_fn_t getter_cb = ecma_get_typedarray_getter_fn (info.id); + /* 11. */ for (int32_t position = (int32_t) from_index * info.element_size; - (is_last_index_of ? position >= 0 : (uint32_t) position < limit); - position += increment) + (uint32_t) position < limit; + position += info.element_size) { ecma_number_t element_num = getter_cb (info.buffer_p + position); @@ -1765,24 +1757,8 @@ ecma_builtin_typedarray_prototype_index_helper (ecma_value_t this_arg, /**< this } } + /* 12. */ return ecma_make_integer_value (-1); -} /* ecma_builtin_typedarray_prototype_index_helper */ - -/** - * The %TypedArray%.prototype object's 'indexOf' routine - * - * See also: - * ECMA-262 v6, 22.2.3.13 - * - * @return ecma value - * Returned value must be freed with ecma_free_value. - */ -static ecma_value_t -ecma_builtin_typedarray_prototype_index_of (ecma_value_t this_arg, /**< this argument */ - const ecma_value_t args[], /**< arguments list */ - ecma_length_t args_number) /**< number of arguments */ -{ - return ecma_builtin_typedarray_prototype_index_helper (this_arg, args, args_number, false); } /* ecma_builtin_typedarray_prototype_index_of */ /** @@ -1799,40 +1775,72 @@ ecma_builtin_typedarray_prototype_last_index_of (ecma_value_t this_arg, /**< thi const ecma_value_t args[], /**< arguments list */ ecma_length_t args_number) /**< number of arguments */ { - return ecma_builtin_typedarray_prototype_index_helper (this_arg, args, args_number, true); -} /* ecma_builtin_typedarray_prototype_last_index_of */ - -/** - * Helper function to get the uint32_t value from an argument. - * - * @return ecma value - * Returned value must be freed with ecma_free_value. - */ -static ecma_value_t -ecma_builtin_get_uint32_value_from_argument (ecma_value_t arg_value, /**< this argument */ - uint32_t length, /**< length of the TypedArray */ - uint32_t *index, /**< [out] pointer to the given index */ - bool is_end_index) /**< true - normalize the end index */ -{ - ecma_number_t num_var; - ecma_value_t ret_value = ecma_get_number (arg_value, &num_var); - - if (ECMA_IS_VALUE_ERROR (ret_value)) + if (!ecma_is_typedarray (this_arg)) { - return ret_value; + return ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not a TypedArray.")); } - if (is_end_index && ecma_number_is_nan (num_var)) + ecma_object_t *typedarray_p = ecma_get_object_from_value (this_arg); + ecma_typedarray_info_t info = ecma_typedarray_get_info (typedarray_p); + if (ecma_arraybuffer_is_detached (info.array_buffer_p)) { - *index = length; + return ecma_raise_type_error (ECMA_ERR_MSG ("ArrayBuffer has been detached.")); + } + + uint32_t from_index; + + /* 5. */ + if (args_number == 0 + || !ecma_is_value_number (args[0]) + || info.length == 0) + { + return ecma_make_integer_value (-1); + } + + if (args_number == 1) + { + from_index = info.length - 1; } else { - *index = ecma_builtin_helper_array_index_normalize (num_var, length, false); + /* 6. 7. */ + ecma_number_t num_var; + if (ECMA_IS_VALUE_ERROR (ecma_op_to_integer (args[1], &num_var))) + { + return ECMA_VALUE_ERROR; + } + + if (!ecma_number_is_nan (num_var) + && -num_var > info.length) + { + return ecma_make_integer_value (-1); + } + + /* 8. 9. */ + from_index = ((num_var >= 0) ? (uint32_t) JERRY_MIN (num_var, info.length - 1) + : (uint32_t) (info.length + num_var)); } - return ECMA_VALUE_EMPTY; -} /* ecma_builtin_get_uint32_value_from_argument */ + ecma_number_t search_num = ecma_get_number_from_value (args[0]); + + ecma_typedarray_getter_fn_t getter_cb = ecma_get_typedarray_getter_fn (info.id); + + /* 10. */ + for (int32_t position = (int32_t) from_index * info.element_size; + position >= 0; + position += -info.element_size) + { + ecma_number_t element_num = getter_cb (info.buffer_p + position); + + if (search_num == element_num) + { + return ecma_make_number_value ((ecma_number_t) position / info.element_size); + } + } + + /* 11. */ + return ecma_make_integer_value (-1); +} /* ecma_builtin_typedarray_prototype_last_index_of */ /** * The %TypedArray%.prototype object's 'copyWithin' routine @@ -1855,61 +1863,52 @@ ecma_builtin_typedarray_prototype_copy_within (ecma_value_t this_arg, /**< this ecma_object_t *typedarray_p = ecma_get_object_from_value (this_arg); ecma_typedarray_info_t info = ecma_typedarray_get_info (typedarray_p); - uint32_t target = 0; - uint32_t start = 0; - uint32_t end = info.length; + uint32_t relative_target = 0; + uint32_t relative_start = 0; + uint32_t relative_end = info.length; if (args_number > 0) { - ecma_value_t target_value = ecma_builtin_get_uint32_value_from_argument (args[0], - info.length, - &target, - false); - - if (ECMA_IS_VALUE_ERROR (target_value)) + if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (args[0], + info.length, + &relative_target))) { - return target_value; + return ECMA_VALUE_ERROR; } if (args_number > 1) { - ecma_value_t start_value = ecma_builtin_get_uint32_value_from_argument (args[1], - info.length, - &start, - false); - - if (ECMA_IS_VALUE_ERROR (start_value)) + if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (args[1], + info.length, + &relative_start))) { - return start_value; + return ECMA_VALUE_ERROR; } - if (args_number > 2) + if (args_number > 2 && args[2] != ECMA_VALUE_UNDEFINED) { - ecma_value_t end_value = ecma_builtin_get_uint32_value_from_argument (args[2], - info.length, - &end, - true); - - if (ECMA_IS_VALUE_ERROR (end_value)) + if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (args[2], + info.length, + &relative_end))) { - return end_value; + return ECMA_VALUE_ERROR; } } } } - if (target >= info.length || start >= end || end == 0) + if (relative_target >= info.length || relative_start >= relative_end || relative_end == 0) { return ecma_copy_value (this_arg); } else { - uint32_t distance = end - start; - uint32_t offset = info.length - target; + uint32_t distance = relative_end - relative_start; + uint32_t offset = info.length - relative_target; uint32_t count = JERRY_MIN (distance, offset); - memmove (info.buffer_p + (target * info.element_size), - info.buffer_p + (start * info.element_size), + memmove (info.buffer_p + (relative_target * info.element_size), + info.buffer_p + (relative_start * info.element_size), (size_t) (count * info.element_size)); } @@ -1943,36 +1942,29 @@ ecma_builtin_typedarray_prototype_slice (ecma_value_t this_arg, /**< this argume } ecma_typedarray_info_t info = ecma_typedarray_get_info (typedarray_p); - uint32_t start = 0; - uint32_t end = info.length; + uint32_t relative_start = 0; + uint32_t relative_end = info.length; if (args_number > 0) { - ecma_value_t start_value = ecma_builtin_get_uint32_value_from_argument (args[0], - info.length, - &start, - false); - - if (ECMA_IS_VALUE_ERROR (start_value)) + if (ECMA_IS_VALUE_ERROR (ecma_builtin_helper_array_index_normalize (args[0], + info.length, + &relative_start))) { - return start_value; + return ECMA_VALUE_ERROR; } - if (args_number > 1) + 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_value_t end_value = ecma_builtin_get_uint32_value_from_argument (args[1], - info.length, - &end, - true); - - if (ECMA_IS_VALUE_ERROR (end_value)) - { - return end_value; - } + return ECMA_VALUE_ERROR; } } - int32_t distance = (int32_t) (end - start); + int32_t distance = (int32_t) (relative_end - relative_start); uint32_t count = distance > 0 ? (uint32_t) distance : 0; ecma_value_t new_typedarray = ecma_op_create_typedarray_with_type_and_length (typedarray_p, count); @@ -1987,7 +1979,7 @@ ecma_builtin_typedarray_prototype_slice (ecma_value_t this_arg, /**< this argume ecma_object_t *new_typedarray_p = ecma_get_object_from_value (new_typedarray); lit_utf8_byte_t *new_typedarray_buffer_p = ecma_typedarray_get_buffer (new_typedarray_p); - uint32_t src_byte_index = (start * info.element_size); + uint32_t src_byte_index = (relative_start * info.element_size); memcpy (new_typedarray_buffer_p, info.buffer_p + src_byte_index, diff --git a/jerry-core/ecma/operations/ecma-dataview-object.c b/jerry-core/ecma/operations/ecma-dataview-object.c index 673860a67..69d54fd90 100644 --- a/jerry-core/ecma/operations/ecma-dataview-object.c +++ b/jerry-core/ecma/operations/ecma-dataview-object.c @@ -63,25 +63,27 @@ ecma_op_dataview_create (const ecma_value_t *arguments_list_p, /**< arguments li } /* 4 - 6. */ - int32_t offset = 0; + uint32_t offset = 0; if (arguments_list_len > 1) { - ecma_number_t number_offset; - ecma_value_t number_offset_value = ecma_get_number (arguments_list_p[1], &number_offset); - - if (ECMA_IS_VALUE_ERROR (number_offset_value)) + ecma_number_t number_offset, offset_num; + if (ECMA_IS_VALUE_ERROR (ecma_get_number (arguments_list_p[1], &number_offset))) { - return number_offset_value; + return ECMA_VALUE_ERROR; + } + if (ECMA_IS_VALUE_ERROR (ecma_op_to_integer (arguments_list_p[1], &offset_num))) + { + return ECMA_VALUE_ERROR; } - offset = ecma_number_to_int32 (number_offset); - /* 7. */ - if (number_offset != offset || offset < 0) + if (number_offset != offset_num || offset_num < 0) { return ecma_raise_range_error (ECMA_ERR_MSG ("Start offset is outside the bounds of the buffer.")); } + + offset = (uint32_t) offset_num; } /* 8. */ @@ -240,7 +242,7 @@ ecma_op_dataview_get_set_view_value (ecma_value_t view, /**< the operation's 'vi /* 3 - 5. */ ecma_number_t number_index; - ecma_value_t number_index_value = ecma_get_number (request_index, &number_index); + ecma_value_t number_index_value = ecma_op_to_integer (request_index, &number_index); if (ECMA_IS_VALUE_ERROR (number_index_value)) { diff --git a/jerry-core/ecma/operations/ecma-regexp-object.c b/jerry-core/ecma/operations/ecma-regexp-object.c index 3005a301a..5bc7c665e 100644 --- a/jerry-core/ecma/operations/ecma-regexp-object.c +++ b/jerry-core/ecma/operations/ecma-regexp-object.c @@ -1308,7 +1308,8 @@ ecma_regexp_exec_helper (ecma_value_t regexp_value, /**< RegExp object */ ecma_value_t lastindex_value = ecma_op_object_get_own_data_prop (regexp_object_p, lastindex_str_p); ecma_number_t lastindex_num; - ret_value = ecma_get_number (lastindex_value, &lastindex_num); + ret_value = ecma_op_to_integer (lastindex_value, &lastindex_num); + ecma_free_value (lastindex_value); if (ECMA_IS_VALUE_ERROR (ret_value)) diff --git a/jerry-core/ecma/operations/ecma-typedarray-object.c b/jerry-core/ecma/operations/ecma-typedarray-object.c index befb59691..6568e135d 100644 --- a/jerry-core/ecma/operations/ecma-typedarray-object.c +++ b/jerry-core/ecma/operations/ecma-typedarray-object.c @@ -949,10 +949,13 @@ ecma_op_create_typedarray (const ecma_value_t *arguments_list_p, /**< the arg li ecma_value_t arg3 = ((arguments_list_len > 2) ? arguments_list_p[2] : ECMA_VALUE_UNDEFINED); - ECMA_OP_TO_NUMBER_TRY_CATCH (num2, arg2, ret); - uint32_t offset = ecma_number_to_uint32 (num2); + ecma_number_t offset; + if (ECMA_IS_VALUE_ERROR (ecma_op_to_integer (arg2, &offset))) + { + return ECMA_VALUE_ERROR; + } - if (ecma_number_is_negative (ecma_number_to_int32 (num2)) || (offset % (uint32_t) (1 << element_size_shift) != 0)) + if (ecma_number_is_negative (offset)) { ret = ecma_raise_range_error (ECMA_ERR_MSG ("Invalid offset.")); } @@ -1007,15 +1010,13 @@ ecma_op_create_typedarray (const ecma_value_t *arguments_list_p, /**< the arg li { ecma_length_t array_length = new_byte_length >> element_size_shift; ret = ecma_typedarray_create_object_with_buffer (arraybuffer_p, - offset, + (ecma_length_t) offset, array_length, proto_p, element_size_shift, typedarray_id); } } - - ECMA_OP_TO_NUMBER_FINALIZE (num2); } else { diff --git a/tests/jerry/es2015/dataview.js b/tests/jerry/es2015/dataview.js index 6faa2bc3f..020a1e898 100644 --- a/tests/jerry/es2015/dataview.js +++ b/tests/jerry/es2015/dataview.js @@ -168,11 +168,10 @@ gettersSetters.forEach (function (propName) { var view = new DataView (buffer) /* ES2015 24.2.1.{1, 2}.6 (numberIndex != getIndex) */ - try { - view[propName] (1.5); - assert (false); - } catch (e) { - assert (e instanceof RangeError); + if (propName.indexOf("get") !== -1) { + assert(view[propName] (1.5) === 0); + } else { + assert(view[propName] (1.5) === undefined); } /* ES2015 24.2.1.{1, 2}.6 (getIndex < 0) */ diff --git a/tests/jerry/es2015/regression-test-issue-3237.js b/tests/jerry/es2015/regression-test-issue-3237.js new file mode 100644 index 000000000..06248f364 --- /dev/null +++ b/tests/jerry/es2015/regression-test-issue-3237.js @@ -0,0 +1,17 @@ +// 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. + +var arrayBufferVar1 = new ArrayBuffer(12, 8); +var arrayVar1 = new Uint8Array(arrayBufferVar1, 9); +arrayVar1.lastIndexOf(15, -Math.LOG10E); diff --git a/tests/jerry/regression-test-issue-3325.js b/tests/jerry/regression-test-issue-3325.js new file mode 100644 index 000000000..afc4e4413 --- /dev/null +++ b/tests/jerry/regression-test-issue-3325.js @@ -0,0 +1,23 @@ +// 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. + +var text = 'x'; +assert (text.charAt(0) === "x"); +assert (text.charAt(-0.1) === "x"); +assert (text.charAt(-0.5) === "x"); +assert (text.charAt(-0.9) === "x"); +assert (text.charAt(0.85) === "x"); + +assert (text.charAt(-0.5) !== ""); +assert (text.charAt(0.85) !== "");