Fix undefined initialValue handling in Array.prototype.reduce and reduceRight function.
JerryScript-DCO-1.0-Signed-off-by: Kristof Kosztyo kkosztyo.u-szeged@partner.samsung.com
This commit is contained in:
@@ -2546,10 +2546,12 @@ ecma_builtin_array_prototype_object_filter (ecma_value_t this_arg, /**< this arg
|
||||
*/
|
||||
static ecma_completion_value_t
|
||||
ecma_builtin_array_prototype_object_reduce (ecma_value_t this_arg, /**< this argument */
|
||||
ecma_value_t arg1, /**< callbackfn */
|
||||
ecma_value_t arg2) /**< initialValue */
|
||||
const ecma_value_t args[], /**< arguments list */
|
||||
ecma_length_t args_number) /**< number of arguments */
|
||||
{
|
||||
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
|
||||
ecma_value_t callbackfn = (args_number > 0) ? args[0] : ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
|
||||
ecma_value_t initial_value = (args_number > 1) ? args[1] : ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
|
||||
|
||||
/* 1. */
|
||||
ECMA_TRY_CATCH (obj_this,
|
||||
@@ -2570,7 +2572,7 @@ ecma_builtin_array_prototype_object_reduce (ecma_value_t this_arg, /**< this arg
|
||||
uint32_t len = ecma_number_to_uint32 (len_number);
|
||||
|
||||
/* 4. */
|
||||
if (!ecma_op_is_callable (arg1))
|
||||
if (!ecma_op_is_callable (callbackfn))
|
||||
{
|
||||
ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
|
||||
}
|
||||
@@ -2579,12 +2581,12 @@ ecma_builtin_array_prototype_object_reduce (ecma_value_t this_arg, /**< this arg
|
||||
ecma_number_t *num_p = ecma_alloc_number ();
|
||||
ecma_object_t *func_object_p;
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_object (arg1));
|
||||
func_object_p = ecma_get_object_from_value (arg1);
|
||||
JERRY_ASSERT (ecma_is_value_object (callbackfn));
|
||||
func_object_p = ecma_get_object_from_value (callbackfn);
|
||||
ecma_value_t accumulator = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
|
||||
|
||||
/* 5. */
|
||||
if (len_number == ECMA_NUMBER_ZERO && ecma_is_value_undefined (arg2))
|
||||
if (len_number == ECMA_NUMBER_ZERO && ecma_is_value_undefined (initial_value))
|
||||
{
|
||||
ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
|
||||
}
|
||||
@@ -2594,9 +2596,9 @@ ecma_builtin_array_prototype_object_reduce (ecma_value_t this_arg, /**< this arg
|
||||
uint32_t index = 0;
|
||||
|
||||
/* 7.a */
|
||||
if (!ecma_is_value_undefined (arg2))
|
||||
if (args_number > 1)
|
||||
{
|
||||
accumulator = ecma_copy_value (arg2, true);
|
||||
accumulator = ecma_copy_value (initial_value, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2689,10 +2691,12 @@ ecma_builtin_array_prototype_object_reduce (ecma_value_t this_arg, /**< this arg
|
||||
*/
|
||||
static ecma_completion_value_t
|
||||
ecma_builtin_array_prototype_object_reduce_right (ecma_value_t this_arg, /**< this argument */
|
||||
ecma_value_t arg1, /**< callbackfn */
|
||||
ecma_value_t arg2) /**< initialValue */
|
||||
const ecma_value_t args[], /**< arguments list */
|
||||
ecma_length_t args_number) /**< number of arguments */
|
||||
{
|
||||
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
|
||||
ecma_value_t callbackfn = (args_number > 0) ? args[0] : ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
|
||||
ecma_value_t initial_value = (args_number > 1) ? args[1] : ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
|
||||
|
||||
/* 1. */
|
||||
ECMA_TRY_CATCH (obj_this,
|
||||
@@ -2713,7 +2717,7 @@ ecma_builtin_array_prototype_object_reduce_right (ecma_value_t this_arg, /**< th
|
||||
uint32_t len = ecma_number_to_uint32 (len_number);
|
||||
|
||||
/* 4. */
|
||||
if (!ecma_op_is_callable (arg1))
|
||||
if (!ecma_op_is_callable (callbackfn))
|
||||
{
|
||||
ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
|
||||
}
|
||||
@@ -2721,11 +2725,11 @@ ecma_builtin_array_prototype_object_reduce_right (ecma_value_t this_arg, /**< th
|
||||
{
|
||||
ecma_object_t *func_object_p;
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_object (arg1));
|
||||
func_object_p = ecma_get_object_from_value (arg1);
|
||||
JERRY_ASSERT (ecma_is_value_object (callbackfn));
|
||||
func_object_p = ecma_get_object_from_value (callbackfn);
|
||||
|
||||
/* 5. */
|
||||
if (len_number == ECMA_NUMBER_ZERO && ecma_is_value_undefined (arg2))
|
||||
if (len_number == ECMA_NUMBER_ZERO && ecma_is_value_undefined (initial_value))
|
||||
{
|
||||
ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
|
||||
}
|
||||
@@ -2738,9 +2742,9 @@ ecma_builtin_array_prototype_object_reduce_right (ecma_value_t this_arg, /**< th
|
||||
int64_t index = (int64_t) len - 1;
|
||||
|
||||
/* 7.a */
|
||||
if (!ecma_is_value_undefined (arg2))
|
||||
if (args_number > 1)
|
||||
{
|
||||
accumulator = ecma_copy_value (arg2, true);
|
||||
accumulator = ecma_copy_value (initial_value, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -78,8 +78,8 @@ ROUTINE (LIT_MAGIC_STRING_SOME, ecma_builtin_array_prototype_object_some, 2, 1)
|
||||
ROUTINE (LIT_MAGIC_STRING_FOR_EACH_UL, ecma_builtin_array_prototype_object_for_each, 2, 1)
|
||||
ROUTINE (LIT_MAGIC_STRING_MAP, ecma_builtin_array_prototype_object_map, 2, 1)
|
||||
ROUTINE (LIT_MAGIC_STRING_FILTER, ecma_builtin_array_prototype_object_filter, 2, 1)
|
||||
ROUTINE (LIT_MAGIC_STRING_REDUCE, ecma_builtin_array_prototype_object_reduce, 2, 1)
|
||||
ROUTINE (LIT_MAGIC_STRING_REDUCE_RIGHT_UL, ecma_builtin_array_prototype_object_reduce_right, 2, 1)
|
||||
ROUTINE (LIT_MAGIC_STRING_REDUCE, ecma_builtin_array_prototype_object_reduce, NON_FIXED, 1)
|
||||
ROUTINE (LIT_MAGIC_STRING_REDUCE_RIGHT_UL, ecma_builtin_array_prototype_object_reduce_right, NON_FIXED, 1)
|
||||
|
||||
#undef OBJECT_ID
|
||||
#undef SIMPLE_VALUE
|
||||
|
||||
@@ -76,3 +76,13 @@ assert (long_array.reduceRight(func,10) === 11);
|
||||
|
||||
long_array[10000] = 1;
|
||||
assert (long_array.reduceRight(func,10) === 12);
|
||||
|
||||
var accessed = false;
|
||||
function callbackfn(prevVal, curVal, idx, obj) {
|
||||
accessed = true;
|
||||
return typeof prevVal === "undefined";
|
||||
}
|
||||
|
||||
var obj = { 0: 11, length: 1 };
|
||||
|
||||
assert (Array.prototype.reduceRight.call(obj, callbackfn, undefined) === true && accessed);
|
||||
|
||||
@@ -61,3 +61,13 @@ assert (long_array.reduce(func,10) === 11);
|
||||
|
||||
long_array[10000] = 1;
|
||||
assert (long_array.reduce(func,10) === 12);
|
||||
|
||||
var accessed = false;
|
||||
function callbackfn(prevVal, curVal, idx, obj) {
|
||||
accessed = true;
|
||||
return typeof prevVal === "undefined";
|
||||
}
|
||||
|
||||
var obj = { 0: 11, length: 1 };
|
||||
|
||||
assert (Array.prototype.reduce.call(obj, callbackfn, undefined) === true && accessed);
|
||||
|
||||
Reference in New Issue
Block a user