Skip to content

Commit 9ffa6a3

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 5bb5664 commit 9ffa6a3

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
@@ -2546,10 +2546,12 @@ ecma_builtin_array_prototype_object_filter (ecma_value_t this_arg, /**< this arg
25462546
*/
25472547
static ecma_completion_value_t
25482548
ecma_builtin_array_prototype_object_reduce (ecma_value_t this_arg, /**< this argument */
2549-
ecma_value_t arg1, /**< callbackfn */
2550-
ecma_value_t arg2) /**< initialValue */
2549+
const ecma_value_t args[], /**< arguments list */
2550+
ecma_length_t args_number) /**< number of arguments */
25512551
{
25522552
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
2553+
ecma_value_t callbackfn = (args_number > 0) ? args[0] : ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
2554+
ecma_value_t initial_value = (args_number > 1) ? args[1] : ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
25532555

25542556
/* 1. */
25552557
ECMA_TRY_CATCH (obj_this,
@@ -2570,7 +2572,7 @@ ecma_builtin_array_prototype_object_reduce (ecma_value_t this_arg, /**< this arg
25702572
uint32_t len = ecma_number_to_uint32 (len_number);
25712573

25722574
/* 4. */
2573-
if (!ecma_op_is_callable (arg1))
2575+
if (!ecma_op_is_callable (callbackfn))
25742576
{
25752577
ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
25762578
}
@@ -2579,12 +2581,12 @@ ecma_builtin_array_prototype_object_reduce (ecma_value_t this_arg, /**< this arg
25792581
ecma_number_t *num_p = ecma_alloc_number ();
25802582
ecma_object_t *func_object_p;
25812583

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

25862588
/* 5. */
2587-
if (len_number == ECMA_NUMBER_ZERO && ecma_is_value_undefined (arg2))
2589+
if (len_number == ECMA_NUMBER_ZERO && ecma_is_value_undefined (initial_value))
25882590
{
25892591
ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
25902592
}
@@ -2594,9 +2596,9 @@ ecma_builtin_array_prototype_object_reduce (ecma_value_t this_arg, /**< this arg
25942596
uint32_t index = 0;
25952597

25962598
/* 7.a */
2597-
if (!ecma_is_value_undefined (arg2))
2599+
if (args_number > 1)
25982600
{
2599-
accumulator = ecma_copy_value (arg2, true);
2601+
accumulator = ecma_copy_value (initial_value, true);
26002602
}
26012603
else
26022604
{
@@ -2689,10 +2691,12 @@ ecma_builtin_array_prototype_object_reduce (ecma_value_t this_arg, /**< this arg
26892691
*/
26902692
static ecma_completion_value_t
26912693
ecma_builtin_array_prototype_object_reduce_right (ecma_value_t this_arg, /**< this argument */
2692-
ecma_value_t arg1, /**< callbackfn */
2693-
ecma_value_t arg2) /**< initialValue */
2694+
const ecma_value_t args[], /**< arguments list */
2695+
ecma_length_t args_number) /**< number of arguments */
26942696
{
26952697
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
2698+
ecma_value_t callbackfn = (args_number > 0) ? args[0] : ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
2699+
ecma_value_t initial_value = (args_number > 1) ? args[1] : ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
26962700

26972701
/* 1. */
26982702
ECMA_TRY_CATCH (obj_this,
@@ -2713,19 +2717,19 @@ ecma_builtin_array_prototype_object_reduce_right (ecma_value_t this_arg, /**< th
27132717
uint32_t len = ecma_number_to_uint32 (len_number);
27142718

27152719
/* 4. */
2716-
if (!ecma_op_is_callable (arg1))
2720+
if (!ecma_op_is_callable (callbackfn))
27172721
{
27182722
ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
27192723
}
27202724
else
27212725
{
27222726
ecma_object_t *func_object_p;
27232727

2724-
JERRY_ASSERT (ecma_is_value_object (arg1));
2725-
func_object_p = ecma_get_object_from_value (arg1);
2728+
JERRY_ASSERT (ecma_is_value_object (callbackfn));
2729+
func_object_p = ecma_get_object_from_value (callbackfn);
27262730

27272731
/* 5. */
2728-
if (len_number == ECMA_NUMBER_ZERO && ecma_is_value_undefined (arg2))
2732+
if (len_number == ECMA_NUMBER_ZERO && ecma_is_value_undefined (initial_value))
27292733
{
27302734
ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
27312735
}
@@ -2738,9 +2742,9 @@ ecma_builtin_array_prototype_object_reduce_right (ecma_value_t this_arg, /**< th
27382742
int64_t index = (int64_t) len - 1;
27392743

27402744
/* 7.a */
2741-
if (!ecma_is_value_undefined (arg2))
2745+
if (args_number > 1)
27422746
{
2743-
accumulator = ecma_copy_value (arg2, true);
2747+
accumulator = ecma_copy_value (initial_value, true);
27442748
}
27452749
else
27462750
{

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)