Skip to content

Commit 7510a88

Browse files
committed
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
1 parent 8f594ae commit 7510a88

File tree

4 files changed

+42
-18
lines changed

4 files changed

+42
-18
lines changed

jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.cpp

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2545,10 +2545,12 @@ ecma_builtin_array_prototype_object_filter (ecma_value_t this_arg, /**< this arg
25452545
*/
25462546
static ecma_completion_value_t
25472547
ecma_builtin_array_prototype_object_reduce (ecma_value_t this_arg, /**< this argument */
2548-
ecma_value_t arg1, /**< callbackfn */
2549-
ecma_value_t arg2) /**< initialValue */
2548+
const ecma_value_t args[], /**< arguments list */
2549+
ecma_length_t args_number) /**< number of arguments */
25502550
{
25512551
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
2552+
ecma_value_t callbackfn = (args_number > 0) ? args[0] : ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
2553+
ecma_value_t initial_value = (args_number > 1) ? args[1] : ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
25522554

25532555
/* 1. */
25542556
ECMA_TRY_CATCH (obj_this,
@@ -2569,7 +2571,7 @@ ecma_builtin_array_prototype_object_reduce (ecma_value_t this_arg, /**< this arg
25692571
uint32_t len = ecma_number_to_uint32 (len_number);
25702572

25712573
/* 4. */
2572-
if (!ecma_op_is_callable (arg1))
2574+
if (!ecma_op_is_callable (callbackfn))
25732575
{
25742576
ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
25752577
}
@@ -2578,12 +2580,12 @@ ecma_builtin_array_prototype_object_reduce (ecma_value_t this_arg, /**< this arg
25782580
ecma_number_t *num_p = ecma_alloc_number ();
25792581
ecma_object_t *func_object_p;
25802582

2581-
JERRY_ASSERT (ecma_is_value_object (arg1));
2582-
func_object_p = ecma_get_object_from_value (arg1);
2583+
JERRY_ASSERT (ecma_is_value_object (callbackfn));
2584+
func_object_p = ecma_get_object_from_value (callbackfn);
25832585
ecma_value_t accumulator = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
25842586

25852587
/* 5. */
2586-
if (len_number == ECMA_NUMBER_ZERO && ecma_is_value_undefined (arg2))
2588+
if (len_number == ECMA_NUMBER_ZERO && ecma_is_value_undefined (initial_value))
25872589
{
25882590
ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
25892591
}
@@ -2593,9 +2595,9 @@ ecma_builtin_array_prototype_object_reduce (ecma_value_t this_arg, /**< this arg
25932595
uint32_t index = 0;
25942596

25952597
/* 7.a */
2596-
if (!ecma_is_value_undefined (arg2))
2598+
if (args_number > 1)
25972599
{
2598-
accumulator = ecma_copy_value (arg2, true);
2600+
accumulator = ecma_copy_value (initial_value, true);
25992601
}
26002602
else
26012603
{
@@ -2688,10 +2690,12 @@ ecma_builtin_array_prototype_object_reduce (ecma_value_t this_arg, /**< this arg
26882690
*/
26892691
static ecma_completion_value_t
26902692
ecma_builtin_array_prototype_object_reduce_right (ecma_value_t this_arg, /**< this argument */
2691-
ecma_value_t arg1, /**< callbackfn */
2692-
ecma_value_t arg2) /**< initialValue */
2693+
const ecma_value_t args[], /**< arguments list */
2694+
ecma_length_t args_number) /**< number of arguments */
26932695
{
26942696
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
2697+
ecma_value_t callbackfn = (args_number > 0) ? args[0] : ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
2698+
ecma_value_t initial_value = (args_number > 1) ? args[1] : ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
26952699

26962700
/* 1. */
26972701
ECMA_TRY_CATCH (obj_this,
@@ -2712,19 +2716,19 @@ ecma_builtin_array_prototype_object_reduce_right (ecma_value_t this_arg, /**< th
27122716
uint32_t len = ecma_number_to_uint32 (len_number);
27132717

27142718
/* 4. */
2715-
if (!ecma_op_is_callable (arg1))
2719+
if (!ecma_op_is_callable (callbackfn))
27162720
{
27172721
ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
27182722
}
27192723
else
27202724
{
27212725
ecma_object_t *func_object_p;
27222726

2723-
JERRY_ASSERT (ecma_is_value_object (arg1));
2724-
func_object_p = ecma_get_object_from_value (arg1);
2727+
JERRY_ASSERT (ecma_is_value_object (callbackfn));
2728+
func_object_p = ecma_get_object_from_value (callbackfn);
27252729

27262730
/* 5. */
2727-
if (len_number == ECMA_NUMBER_ZERO && ecma_is_value_undefined (arg2))
2731+
if (len_number == ECMA_NUMBER_ZERO && ecma_is_value_undefined (initial_value))
27282732
{
27292733
ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
27302734
}
@@ -2737,9 +2741,9 @@ ecma_builtin_array_prototype_object_reduce_right (ecma_value_t this_arg, /**< th
27372741
int64_t index = (int64_t) len - 1;
27382742

27392743
/* 7.a */
2740-
if (!ecma_is_value_undefined (arg2))
2744+
if (args_number > 1)
27412745
{
2742-
accumulator = ecma_copy_value (arg2, true);
2746+
accumulator = ecma_copy_value (initial_value, true);
27432747
}
27442748
else
27452749
{

jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.inc.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ ROUTINE (LIT_MAGIC_STRING_SOME, ecma_builtin_array_prototype_object_some, 2, 1)
7878
ROUTINE (LIT_MAGIC_STRING_FOR_EACH_UL, ecma_builtin_array_prototype_object_for_each, 2, 1)
7979
ROUTINE (LIT_MAGIC_STRING_MAP, ecma_builtin_array_prototype_object_map, 2, 1)
8080
ROUTINE (LIT_MAGIC_STRING_FILTER, ecma_builtin_array_prototype_object_filter, 2, 1)
81-
ROUTINE (LIT_MAGIC_STRING_REDUCE, ecma_builtin_array_prototype_object_reduce, 2, 1)
82-
ROUTINE (LIT_MAGIC_STRING_REDUCE_RIGHT_UL, ecma_builtin_array_prototype_object_reduce_right, 2, 1)
81+
ROUTINE (LIT_MAGIC_STRING_REDUCE, ecma_builtin_array_prototype_object_reduce, NON_FIXED, 1)
82+
ROUTINE (LIT_MAGIC_STRING_REDUCE_RIGHT_UL, ecma_builtin_array_prototype_object_reduce_right, NON_FIXED, 1)
8383

8484
#undef OBJECT_ID
8585
#undef SIMPLE_VALUE

tests/jerry/array-prototype-reduce-right.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,13 @@ assert (long_array.reduceRight(func,10) === 11);
7676

7777
long_array[10000] = 1;
7878
assert (long_array.reduceRight(func,10) === 12);
79+
80+
var accessed = false;
81+
function callbackfn(prevVal, curVal, idx, obj) {
82+
accessed = true;
83+
return typeof prevVal === "undefined";
84+
}
85+
86+
var obj = { 0: 11, length: 1 };
87+
88+
assert (Array.prototype.reduceRight.call(obj, callbackfn, undefined) === true && accessed);

tests/jerry/array-prototype-reduce.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,13 @@ assert (long_array.reduce(func,10) === 11);
6161

6262
long_array[10000] = 1;
6363
assert (long_array.reduce(func,10) === 12);
64+
65+
var accessed = false;
66+
function callbackfn(prevVal, curVal, idx, obj) {
67+
accessed = true;
68+
return typeof prevVal === "undefined";
69+
}
70+
71+
var obj = { 0: 11, length: 1 };
72+
73+
assert (Array.prototype.reduce.call(obj, callbackfn, undefined) === true && accessed);

0 commit comments

Comments
 (0)