@@ -1891,19 +1891,33 @@ ecma_builtin_array_prototype_object_last_index_of (ecma_value_t this_arg, /**< t
18911891} /* ecma_builtin_array_prototype_object_last_index_of */
18921892
18931893/**
1894- * The Array.prototype object's 'every' routine
1895- *
1896- * See also:
1897- * ECMA-262 v5, 15.4.4.16
1894+ * Type of array routine.
1895+ */
1896+ typedef enum
1897+ {
1898+ ARRAY_ROUTINE_EVERY , /**< Array.every: ECMA-262 v5, 15.4.4.16 */
1899+ ARRAY_ROUTINE_SOME , /**< Array.some: ECMA-262 v5, 15.4.4.17 */
1900+ ARRAY_ROUTINE_FOREACH , /**< Array.forEach: ECMA-262 v5, 15.4.4.18 */
1901+ ARRAY_ROUTINE__COUNT /**< count of the modes */
1902+ } array_routine_mode ;
1903+
1904+ /**
1905+ * Applies the provided function to each element of the array as long as
1906+ * the return value stays empty. The common function for 'every', 'some'
1907+ * and 'forEach' of the Array prototype.
18981908 *
18991909 * @return ecma value
19001910 * Returned value must be freed with ecma_free_value.
19011911 */
19021912static ecma_value_t
1903- ecma_builtin_array_prototype_object_every (ecma_value_t this_arg , /**< this argument */
1904- ecma_value_t arg1 , /**< callbackfn */
1905- ecma_value_t arg2 ) /**< thisArg */
1913+ ecma_builtin_array_apply (ecma_value_t this_arg , /**< this argument */
1914+ ecma_value_t arg1 , /**< callbackfn */
1915+ ecma_value_t arg2 , /**< thisArg */
1916+ array_routine_mode mode ) /**< array routine mode */
1917+
19061918{
1919+ JERRY_ASSERT (mode < ARRAY_ROUTINE__COUNT );
1920+
19071921 ecma_value_t ret_value = ECMA_VALUE_EMPTY ;
19081922
19091923 /* 1. */
@@ -1958,10 +1972,14 @@ ecma_builtin_array_prototype_object_every (ecma_value_t this_arg, /**< this argu
19581972 ECMA_TRY_CATCH (call_value , ecma_op_function_call (func_object_p , arg2 , call_args , 3 ), ret_value );
19591973
19601974 /* 7.c.iii */
1961- if (!ecma_op_to_boolean (call_value ))
1975+ if (mode == ARRAY_ROUTINE_EVERY && !ecma_op_to_boolean (call_value ))
19621976 {
19631977 ret_value = ECMA_VALUE_FALSE ;
19641978 }
1979+ else if (mode == ARRAY_ROUTINE_SOME && ecma_op_to_boolean (call_value ))
1980+ {
1981+ ret_value = ECMA_VALUE_TRUE ;
1982+ }
19651983
19661984 ECMA_FINALIZE (call_value );
19671985 }
@@ -1973,10 +1991,21 @@ ecma_builtin_array_prototype_object_every (ecma_value_t this_arg, /**< this argu
19731991
19741992 ecma_free_value (to_object_comp );
19751993
1994+ /* 8. */
19761995 if (ecma_is_value_empty (ret_value ))
19771996 {
1978- /* 8. */
1979- ret_value = ECMA_VALUE_TRUE ;
1997+ if (mode == ARRAY_ROUTINE_EVERY )
1998+ {
1999+ ret_value = ECMA_VALUE_TRUE ;
2000+ }
2001+ else if (mode == ARRAY_ROUTINE_SOME )
2002+ {
2003+ ret_value = ECMA_VALUE_FALSE ;
2004+ }
2005+ else
2006+ {
2007+ ret_value = ECMA_VALUE_UNDEFINED ;
2008+ }
19802009 }
19812010 }
19822011
@@ -1985,6 +2014,23 @@ ecma_builtin_array_prototype_object_every (ecma_value_t this_arg, /**< this argu
19852014 ECMA_FINALIZE (obj_this );
19862015
19872016 return ret_value ;
2017+ } /* ecma_builtin_array_apply */
2018+
2019+ /**
2020+ * The Array.prototype object's 'every' routine
2021+ *
2022+ * See also:
2023+ * ECMA-262 v5, 15.4.4.16
2024+ *
2025+ * @return ecma value
2026+ * Returned value must be freed with ecma_free_value.
2027+ */
2028+ static ecma_value_t
2029+ ecma_builtin_array_prototype_object_every (ecma_value_t this_arg , /**< this argument */
2030+ ecma_value_t arg1 , /**< callbackfn */
2031+ ecma_value_t arg2 ) /**< thisArg */
2032+ {
2033+ return ecma_builtin_array_apply (this_arg , arg1 , arg2 , ARRAY_ROUTINE_EVERY );
19882034} /* ecma_builtin_array_prototype_object_every */
19892035
19902036/**
@@ -2001,88 +2047,7 @@ ecma_builtin_array_prototype_object_some (ecma_value_t this_arg, /**< this argum
20012047 ecma_value_t arg1 , /**< callbackfn */
20022048 ecma_value_t arg2 ) /**< thisArg */
20032049{
2004- ecma_value_t ret_value = ECMA_VALUE_EMPTY ;
2005-
2006- /* 1. */
2007- ECMA_TRY_CATCH (obj_this ,
2008- ecma_op_to_object (this_arg ),
2009- ret_value );
2010-
2011- ecma_object_t * obj_p = ecma_get_object_from_value (obj_this );
2012-
2013- /* 2. */
2014- ECMA_TRY_CATCH (len_value ,
2015- ecma_op_object_get_by_magic_id (obj_p , LIT_MAGIC_STRING_LENGTH ),
2016- ret_value );
2017-
2018- ECMA_OP_TO_NUMBER_TRY_CATCH (len_number , len_value , ret_value );
2019-
2020- /* 3. */
2021- uint32_t len = ecma_number_to_uint32 (len_number );
2022-
2023- /* 4. */
2024- if (!ecma_op_is_callable (arg1 ))
2025- {
2026- ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Callback function is not callable." ));
2027- }
2028- else
2029- {
2030- ecma_value_t current_index ;
2031- ecma_object_t * func_object_p ;
2032-
2033- /* We already checked that arg1 is callable, so it will always coerce to an object. */
2034- ecma_value_t to_object_comp = ecma_op_to_object (arg1 );
2035- JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (to_object_comp ));
2036-
2037- func_object_p = ecma_get_object_from_value (to_object_comp );
2038-
2039- /* 7. */
2040- for (uint32_t index = 0 ; index < len && ecma_is_value_empty (ret_value ); index ++ )
2041- {
2042- /* 7.a */
2043- ecma_string_t * index_str_p = ecma_new_ecma_string_from_uint32 (index );
2044-
2045- /* 7.c */
2046- ECMA_TRY_CATCH (get_value , ecma_op_object_find (obj_p , index_str_p ), ret_value );
2047-
2048- if (ecma_is_value_found (get_value ))
2049- {
2050- /* 7.c.i */
2051- current_index = ecma_make_uint32_value (index );
2052-
2053- ecma_value_t call_args [] = { get_value , current_index , obj_this };
2054-
2055- /* 7.c.ii */
2056- ECMA_TRY_CATCH (call_value , ecma_op_function_call (func_object_p , arg2 , call_args , 3 ), ret_value );
2057-
2058- /* 7.c.iii */
2059- if (ecma_op_to_boolean (call_value ))
2060- {
2061- ret_value = ECMA_VALUE_TRUE ;
2062- }
2063-
2064- ECMA_FINALIZE (call_value );
2065- }
2066-
2067- ECMA_FINALIZE (get_value );
2068-
2069- ecma_deref_ecma_string (index_str_p );
2070- }
2071-
2072- ecma_free_value (to_object_comp );
2073-
2074- if (ecma_is_value_empty (ret_value ))
2075- {
2076- /* 8. */
2077- ret_value = ECMA_VALUE_FALSE ;
2078- }
2079- }
2080-
2081- ECMA_OP_TO_NUMBER_FINALIZE (len_number );
2082- ECMA_FINALIZE (len_value );
2083- ECMA_FINALIZE (obj_this );
2084-
2085- return ret_value ;
2050+ return ecma_builtin_array_apply (this_arg , arg1 , arg2 , ARRAY_ROUTINE_SOME );
20862051} /* ecma_builtin_array_prototype_object_some */
20872052
20882053/**
@@ -2099,80 +2064,7 @@ ecma_builtin_array_prototype_object_for_each (ecma_value_t this_arg, /**< this a
20992064 ecma_value_t arg1 , /**< callbackfn */
21002065 ecma_value_t arg2 ) /**< thisArg */
21012066{
2102- ecma_value_t ret_value = ECMA_VALUE_EMPTY ;
2103- /* 1. */
2104- ECMA_TRY_CATCH (obj_this ,
2105- ecma_op_to_object (this_arg ),
2106- ret_value );
2107-
2108- ecma_object_t * obj_p = ecma_get_object_from_value (obj_this );
2109-
2110- /* 2. */
2111- ECMA_TRY_CATCH (len_value ,
2112- ecma_op_object_get_by_magic_id (obj_p , LIT_MAGIC_STRING_LENGTH ),
2113- ret_value );
2114-
2115- ECMA_OP_TO_NUMBER_TRY_CATCH (len_number , len_value , ret_value );
2116-
2117- /* 3. */
2118- uint32_t len = ecma_number_to_uint32 (len_number );
2119-
2120- /* 4. */
2121- if (!ecma_op_is_callable (arg1 ))
2122- {
2123- ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Callback function is not callable." ));
2124- }
2125- else
2126- {
2127- ecma_value_t current_index ;
2128- ecma_object_t * func_object_p ;
2129-
2130- /* We already checked that arg1 is callable, so it will always coerce to an object. */
2131- ecma_value_t to_object_comp = ecma_op_to_object (arg1 );
2132- JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (to_object_comp ));
2133-
2134- func_object_p = ecma_get_object_from_value (to_object_comp );
2135-
2136- /* Iterate over array and call callbackfn on every element */
2137- for (uint32_t index = 0 ; index < len && ecma_is_value_empty (ret_value ); index ++ )
2138- {
2139- /* 7.a */
2140- ecma_string_t * index_str_p = ecma_new_ecma_string_from_uint32 (index );
2141-
2142- /* 7.b */
2143- ECMA_TRY_CATCH (current_value , ecma_op_object_find (obj_p , index_str_p ), ret_value );
2144-
2145- if (ecma_is_value_found (current_value ))
2146- {
2147- /* 7.c.i */
2148- current_index = ecma_make_uint32_value (index );
2149-
2150- /* 7.c.ii */
2151- ecma_value_t call_args [] = {current_value , current_index , obj_this };
2152- ECMA_TRY_CATCH (call_value , ecma_op_function_call (func_object_p , arg2 , call_args , 3 ), ret_value );
2153-
2154- ECMA_FINALIZE (call_value );
2155- }
2156-
2157- ECMA_FINALIZE (current_value );
2158-
2159- ecma_deref_ecma_string (index_str_p );
2160- }
2161-
2162- if (ecma_is_value_empty (ret_value ))
2163- {
2164- /* 8. */
2165- ret_value = ECMA_VALUE_UNDEFINED ;
2166- }
2167-
2168- ecma_free_value (to_object_comp );
2169- }
2170-
2171- ECMA_OP_TO_NUMBER_FINALIZE (len_number );
2172- ECMA_FINALIZE (len_value );
2173- ECMA_FINALIZE (obj_this );
2174-
2175- return ret_value ;
2067+ return ecma_builtin_array_apply (this_arg , arg1 , arg2 , ARRAY_ROUTINE_FOREACH );
21762068} /* ecma_builtin_array_prototype_object_for_each */
21772069
21782070/**
0 commit comments