@@ -1521,6 +1521,130 @@ ecma_builtin_array_prototype_object_some (ecma_value_t this_arg, /**< this argum
15211521 return ret_value;
15221522} /* ecma_builtin_array_prototype_object_some */
15231523
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+
15241648/* *
15251649 * The Array.prototype object's 'slice' routine
15261650 *
0 commit comments