mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
Refactor code to use ToInteger (#3224)
Fixes #3325 Fixes #3237 JerryScript-DCO-1.0-Signed-off-by: Daniella Barsony bella@inf.u-szeged.hu
This commit is contained in:
parent
5ceffd209e
commit
89db9253c8
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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))
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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))
|
||||
{
|
||||
|
||||
@ -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))
|
||||
|
||||
@ -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
|
||||
{
|
||||
|
||||
@ -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) */
|
||||
|
||||
17
tests/jerry/es2015/regression-test-issue-3237.js
Normal file
17
tests/jerry/es2015/regression-test-issue-3237.js
Normal file
@ -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);
|
||||
23
tests/jerry/regression-test-issue-3325.js
Normal file
23
tests/jerry/regression-test-issue-3325.js
Normal file
@ -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) !== "");
|
||||
Loading…
x
Reference in New Issue
Block a user