/** * Helper function to normalizing an array index * * This function clamps the given index to the [0, length] range. * If the index is negative, it is used as the offset from the end of the array, * to compute normalized index. * If the index is greater than the length of the array, the normalized index will be the length of the array. * * See also: * ECMA-262 v5, 15.4.4.10 steps 5-6, 7 (part 2) and 8 * ECMA-262 v5, 15.4.4.12 steps 5-6 * ECMA-262 v5, 15.4.4.14 steps 5 * ECMA-262 v5, 15.5.4.13 steps 4, 5 (part 2) and 6-7 * * Used by: * - The Array.prototype.slice routine. * - The Array.prototype.splice routine. * - The Array.prototype.indexOf routine. * - The String.prototype.slice routine. * * @return uint32_t - the normalized value of the index */ uint32_t ecma_builtin_helper_array_index_normalize (ecma_number_t index, /**< index */ uint32_t length) /**< array's length */ { uint32_t norm_index; if (!ecma_number_is_nan (index)) { if (ecma_number_is_zero (index)) { norm_index = 0; } else if (ecma_number_is_infinity (index)) { norm_index = ecma_number_is_negative (index) ? 0 : length; } else { if (ecma_number_is_negative (index)) { ecma_number_t index_neg = ecma_number_negate (index); if (index_neg > length) { norm_index = 0; } else { norm_index = length - ecma_number_to_uint32 (index_neg); } } else { if (index > length) { norm_index = length; } else { norm_index = ecma_number_to_uint32 (index); } } } } else { norm_index = 0; } return norm_index; } /* ecma_builtin_helper_array_index_normalize */
/** * The Math object's 'round' routine * * See also: * ECMA-262 v5, 15.8.2.15 * * @return ecma value * Returned value must be freed with ecma_free_value. */ static ecma_value_t ecma_builtin_math_object_round (ecma_value_t this_arg __attr_unused___, /**< 'this' argument */ ecma_value_t arg) /**< routine's argument */ { ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, arg, ret_value); ecma_number_t *num_p = ecma_alloc_number (); if (ecma_number_is_nan (arg_num) || ecma_number_is_zero (arg_num) || ecma_number_is_infinity (arg_num)) { *num_p = arg_num; } else if (ecma_number_is_negative (arg_num) && arg_num >= -0.5f) { *num_p = ecma_number_negate (0.0f); } else { const ecma_number_t up_half = arg_num + 0.5f; const ecma_number_t down_half = arg_num - 0.5f; const ecma_number_t up_rounded = up_half - ecma_op_number_remainder (up_half, 1); const ecma_number_t down_rounded = down_half - ecma_op_number_remainder (down_half, 1); if (up_rounded - arg_num <= arg_num - down_rounded) { *num_p = up_rounded; } else { *num_p = down_rounded; } } ret_value = ecma_make_number_value (num_p); ECMA_OP_TO_NUMBER_FINALIZE (arg_num); return ret_value; } /* ecma_builtin_math_object_round */