@@ -1521,6 +1521,130 @@ ecma_builtin_array_prototype_object_some (ecma_value_t this_arg, /**< this argum
1521
1521
return ret_value;
1522
1522
} /* ecma_builtin_array_prototype_object_some */
1523
1523
1524
+ /* *
1525
+ * The Array.prototype object's 'filter' routine
1526
+ *
1527
+ * See also:
1528
+ * ECMA-262 v5, 15.4.4.20
1529
+ *
1530
+ * @return completion value
1531
+ * Returned value must be freed with ecma_free_completion_value.
1532
+ */
1533
+ static ecma_completion_value_t
1534
+ ecma_builtin_array_prototype_object_filter (ecma_value_t this_arg, /* *< this argument */
1535
+ ecma_value_t arg1, /* *< callbackfn */
1536
+ ecma_value_t arg2) /* *< thisArg */
1537
+ {
1538
+ ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
1539
+
1540
+ /* 1. */
1541
+ ECMA_TRY_CATCH (obj_this,
1542
+ ecma_op_to_object (this_arg),
1543
+ ret_value);
1544
+
1545
+ ecma_object_t *obj_p = ecma_get_object_from_value (obj_this);
1546
+ ecma_string_t *magic_string_length_p = ecma_get_magic_string (ECMA_MAGIC_STRING_LENGTH);
1547
+
1548
+ /* 2. */
1549
+ ECMA_TRY_CATCH (len_value,
1550
+ ecma_op_object_get (obj_p, magic_string_length_p),
1551
+ ret_value);
1552
+
1553
+ /* 3. */
1554
+ ECMA_OP_TO_NUMBER_TRY_CATCH (len_number, len_value, ret_value);
1555
+
1556
+ uint32_t len = ecma_number_to_uint32 (len_number);
1557
+
1558
+ /* 4. */
1559
+ if (!ecma_op_is_callable (arg1))
1560
+ {
1561
+ ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
1562
+ }
1563
+ else
1564
+ {
1565
+ ecma_value_t current_index;
1566
+ ecma_number_t *num_p = ecma_alloc_number ();
1567
+ ecma_object_t *func_object_p;
1568
+
1569
+ /* 6. */
1570
+ ecma_completion_value_t new_array = ecma_op_create_array_object (NULL , 0 , false );
1571
+ JERRY_ASSERT (ecma_is_completion_value_normal (new_array));
1572
+ ecma_object_t *new_array_p = ecma_get_object_from_completion_value (new_array);
1573
+
1574
+ /* We already checked that arg1 is callable, so it will always be an object. */
1575
+ JERRY_ASSERT (ecma_is_value_object (arg1));
1576
+ func_object_p = ecma_get_object_from_value (arg1);
1577
+
1578
+ /* 8. */
1579
+ uint32_t new_array_index = 0 ;
1580
+
1581
+ /* 9. */
1582
+ for (uint32_t index = 0 ; index < len && ecma_is_completion_value_empty (ret_value); index ++)
1583
+ {
1584
+ /* 9.a */
1585
+ ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (index );
1586
+
1587
+ /* 9.c */
1588
+ if (ecma_op_object_get_property (obj_p, index_str_p) != NULL )
1589
+ {
1590
+ /* 9.c.i */
1591
+ ECMA_TRY_CATCH (get_value, ecma_op_object_get (obj_p, index_str_p), ret_value);
1592
+
1593
+ *num_p = ecma_uint32_to_number (index );
1594
+ current_index = ecma_make_number_value (num_p);
1595
+
1596
+ ecma_value_t call_args[] = { get_value, current_index, obj_this };
1597
+ /* 9.c.ii */
1598
+ ECMA_TRY_CATCH (call_value, ecma_op_function_call (func_object_p, arg2, call_args, 3 ), ret_value);
1599
+
1600
+ /* 9.c.iii, ecma_op_to_boolean always returns a simple value, so no need to free. */
1601
+ if (ecma_is_value_true (ecma_op_to_boolean (call_value)))
1602
+ {
1603
+ ecma_string_t * to_index_string_p = ecma_new_ecma_string_from_uint32 (new_array_index);
1604
+ /*
1605
+ * By definition we should use [[DefineOwnProperty]] here, but since [[Put]] will create the
1606
+ * same property that we need, we can use it for simplicity. No need for a try-catch block
1607
+ * since it is called with is_throw = false.
1608
+ */
1609
+ ecma_completion_value_t put_comp_value = ecma_op_object_put (new_array_p,
1610
+ to_index_string_p,
1611
+ get_value,
1612
+ false );
1613
+ JERRY_ASSERT (ecma_is_completion_value_normal_true (put_comp_value));
1614
+ ecma_free_completion_value (put_comp_value);
1615
+
1616
+ ecma_deref_ecma_string (to_index_string_p);
1617
+ new_array_index++;
1618
+ }
1619
+
1620
+ ECMA_FINALIZE (call_value);
1621
+ ECMA_FINALIZE (get_value);
1622
+ }
1623
+
1624
+ ecma_deref_ecma_string (index_str_p);
1625
+ }
1626
+
1627
+ ecma_dealloc_number (num_p);
1628
+
1629
+ if (ecma_is_completion_value_empty (ret_value))
1630
+ {
1631
+ /* 10. */
1632
+ ret_value = new_array;
1633
+ }
1634
+ else
1635
+ {
1636
+ ecma_free_completion_value (new_array);
1637
+ }
1638
+ }
1639
+
1640
+ ECMA_OP_TO_NUMBER_FINALIZE (len_number);
1641
+ ECMA_FINALIZE (len_value);
1642
+ ecma_deref_ecma_string (magic_string_length_p);
1643
+ ECMA_FINALIZE (obj_this);
1644
+
1645
+ return ret_value;
1646
+ } /* ecma_builtin_array_prototype_object_filter */
1647
+
1524
1648
/* *
1525
1649
* The Array.prototype object's 'slice' routine
1526
1650
*
0 commit comments