/** * The Date.prototype object's 'setUTCMonth' routine * * See also: * ECMA-262 v5, 15.9.5.39 * * @return ecma value * Returned value must be freed with ecma_free_value. */ static ecma_value_t ecma_builtin_date_prototype_set_utc_month (ecma_value_t this_arg, /**< this argument */ ecma_value_t month, /**< month */ ecma_value_t date) /**< date */ { ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); /* 1. */ ECMA_TRY_CATCH (this_time_value, ecma_builtin_date_prototype_get_time (this_arg), ret_value); ecma_number_t t = *ecma_get_number_from_value (this_time_value); /* 2. */ ECMA_OP_TO_NUMBER_TRY_CATCH (m, month, ret_value); /* 3. */ ECMA_OP_TO_NUMBER_TRY_CATCH (dt, date, ret_value); if (ecma_is_value_undefined (date)) { dt = ecma_date_date_from_time (t); } /* 4-7. */ ecma_number_t year = ecma_date_year_from_time (t); ret_value = ecma_date_set_internal_property (this_arg, ecma_date_make_day (year, m, dt), ecma_date_time_within_day (t), ECMA_DATE_UTC); ECMA_OP_TO_NUMBER_FINALIZE (dt); ECMA_OP_TO_NUMBER_FINALIZE (m); ECMA_FINALIZE (this_time_value); return ret_value; } /* ecma_builtin_date_prototype_set_utc_month */
/** * The Date.prototype object's 'setDate' routine * * See also: * ECMA-262 v5, 15.9.5.36 * * @return ecma value * Returned value must be freed with ecma_free_value. */ static ecma_value_t ecma_builtin_date_prototype_set_date (ecma_value_t this_arg, /**< this argument */ ecma_value_t date) /**< date */ { ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); /* 1. */ ECMA_TRY_CATCH (this_time_value, ecma_builtin_date_prototype_get_time (this_arg), ret_value); ecma_number_t t = ecma_date_local_time (*ecma_get_number_from_value (this_time_value)); /* 2. */ ECMA_OP_TO_NUMBER_TRY_CATCH (dt, date, ret_value); /* 3-6. */ ecma_number_t year = ecma_date_year_from_time (t); ecma_number_t month = ecma_date_month_from_time (t); ret_value = ecma_date_set_internal_property (this_arg, ecma_date_make_day (year, month, dt), ecma_date_time_within_day (t), ECMA_DATE_LOCAL); ECMA_OP_TO_NUMBER_FINALIZE (dt); ECMA_FINALIZE (this_time_value); return ret_value; } /* ecma_builtin_date_prototype_set_date */
/** * The Date.prototype object's 'setUTCDate' routine * * See also: * ECMA-262 v5, 15.9.5.37 * * @return completion value * Returned value must be freed with ecma_free_completion_value. */ static ecma_completion_value_t ecma_builtin_date_prototype_set_utc_date (ecma_value_t this_arg, /**< this argument */ ecma_value_t date) /**< date */ { ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); /* 1. */ ECMA_TRY_CATCH (this_time_value, ecma_builtin_date_prototype_get_time (this_arg), ret_value); ecma_number_t t = *ecma_get_number_from_value (this_time_value); /* 2. */ ECMA_OP_TO_NUMBER_TRY_CATCH (dt, date, ret_value); /* 3-6. */ ecma_number_t year = ecma_date_year_from_time (t); ecma_number_t month = ecma_date_month_from_time (t); ret_value = ecma_date_set_internal_property (this_arg, ecma_date_make_day (year, month, dt), ecma_date_time_within_day (t), ECMA_DATE_UTC); ECMA_OP_TO_NUMBER_FINALIZE (dt); ECMA_FINALIZE (this_time_value); return ret_value; } /* ecma_builtin_date_prototype_set_utc_date */
/** * The Date.prototype object's 'setFullYear' routine * * See also: * ECMA-262 v5, 15.9.5.40 * * @return ecma value * Returned value must be freed with ecma_free_value. */ static ecma_value_t ecma_builtin_date_prototype_set_full_year (ecma_value_t this_arg, /**< this argument */ const ecma_value_t args[], /**< arguments list */ ecma_length_t args_number) /**< number of arguments */ { ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); /* 1. */ ECMA_TRY_CATCH (this_time_value, ecma_builtin_date_prototype_get_time (this_arg), ret_value); ecma_number_t t = ecma_date_local_time (*ecma_get_number_from_value (this_time_value)); if (ecma_number_is_nan (t)) { t = ECMA_NUMBER_ZERO; } /* 2. */ ecma_number_t y = ecma_number_make_nan (); ecma_number_t m = ecma_date_month_from_time (t); ecma_number_t dt = ecma_date_date_from_time (t); if (args_number > 0 && !ecma_is_value_undefined (args[0])) { ECMA_OP_TO_NUMBER_TRY_CATCH (year, args[0], ret_value); y = year; /* 3. */ if (args_number > 1 && !ecma_is_value_undefined (args[1])) { ECMA_OP_TO_NUMBER_TRY_CATCH (month, args[1], ret_value); m = month; /* 4. */ if (args_number > 2 && !ecma_is_value_undefined (args[2])) { ECMA_OP_TO_NUMBER_TRY_CATCH (date, args[2], ret_value); dt = date; ECMA_OP_TO_NUMBER_FINALIZE (date); } ECMA_OP_TO_NUMBER_FINALIZE (month); } ECMA_OP_TO_NUMBER_FINALIZE (year); } if (ecma_is_value_empty (ret_value)) { /* 5-8. */ ret_value = ecma_date_set_internal_property (this_arg, ecma_date_make_day (y, m, dt), ecma_date_time_within_day (t), ECMA_DATE_LOCAL); } ECMA_FINALIZE (this_time_value); return ret_value; } /* ecma_builtin_date_prototype_set_full_year */
/** * The Date.prototype object's 'setYear' routine * * See also: * ECMA-262 v5, AnnexB.B.2.5 * * @return ecma value * Returned value must be freed with ecma_free_value. */ static ecma_value_t ecma_builtin_date_prototype_set_year (ecma_value_t this_arg, /**< this argument */ ecma_value_t year) /**< year argument */ { ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); /* 1. */ ECMA_TRY_CATCH (this_time_value, ecma_builtin_date_prototype_get_time (this_arg), ret_value); ecma_number_t t = ecma_date_local_time (*ecma_get_number_from_value (this_time_value)); if (ecma_number_is_nan (t)) { t = ECMA_NUMBER_ZERO; } /* 2. */ ecma_number_t y = ecma_number_make_nan (); ECMA_OP_TO_NUMBER_TRY_CATCH (year_value, year, ret_value); y = year_value; /* 3. */ if (ecma_number_is_nan (y)) { ret_value = ecma_date_set_internal_property (this_arg, 0, y, ECMA_DATE_UTC); } else { /* 4. */ if (y >= 0 && y <= 99) { y += 1900; } } ECMA_OP_TO_NUMBER_FINALIZE (year_value); if (ecma_is_value_empty (ret_value)) { /* 5-8. */ ecma_number_t m = ecma_date_month_from_time (t); ecma_number_t dt = ecma_date_date_from_time (t); ret_value = ecma_date_set_internal_property (this_arg, ecma_date_make_day (y, m, dt), ecma_date_time_within_day (t), ECMA_DATE_UTC); } ECMA_FINALIZE (this_time_value); return ret_value; } /* ecma_builtin_date_prototype_set_year */
/** * Unit test's main function. */ int main () { /* int ecma_date_day (time)*/ TEST_ASSERT (ecma_date_day (0) == 0); TEST_ASSERT (ecma_date_day (MS_PER_DAY) == 1); /* ecma_number_t ecma_date_time_within_day (time) */ TEST_ASSERT (ecma_date_time_within_day (0) == 0); TEST_ASSERT (ecma_date_time_within_day (42) == 42); TEST_ASSERT (ecma_date_time_within_day (42.51) == 42.51); TEST_ASSERT (ecma_date_time_within_day (MS_PER_DAY + 42) == 42); /* int ecma_date_days_in_year (year) */ TEST_ASSERT (ecma_date_days_in_year (0) == 366); TEST_ASSERT (ecma_date_days_in_year (1600) == 366); TEST_ASSERT (ecma_date_days_in_year (1603) == 365); TEST_ASSERT (ecma_date_days_in_year (1900) == 365); TEST_ASSERT (ecma_date_days_in_year (1970) == 365); TEST_ASSERT (ecma_date_days_in_year (2000) == 366); TEST_ASSERT (ecma_date_days_in_year (2000.45) == 366); TEST_ASSERT (ecma_date_days_in_year (2012) == 366); TEST_ASSERT (ecma_date_days_in_year (2015) == 365); TEST_ASSERT (ecma_date_days_in_year (285616 + 1970) == 365); TEST_ASSERT (ecma_date_days_in_year (-1970) == 365); /* int ecma_date_day_from_year (year) */ TEST_ASSERT (ecma_date_day_from_year (1969) == -365); TEST_ASSERT (ecma_date_day_from_year (1970) == 0); TEST_ASSERT (ecma_date_day_from_year (1971) == 365); TEST_ASSERT (ecma_date_day_from_year (2000) == 10957); /* int ecma_date_year_from_time (time) */ TEST_ASSERT (ecma_date_year_from_time (0) == 1970); TEST_ASSERT (ecma_date_year_from_time (0) == 1970); TEST_ASSERT (ecma_date_year_from_time (MS_PER_DAY) == 1970); TEST_ASSERT (ecma_date_year_from_time ((MS_PER_DAY) * (ecma_number_t) 365 - 1) == 1970); TEST_ASSERT (ecma_date_year_from_time (MS_PER_DAY * (ecma_number_t) 365) == 1971); TEST_ASSERT (ecma_date_year_from_time (MS_PER_DAY * (ecma_number_t) (365 * (2015 - 1970))) == 2014); TEST_ASSERT (ecma_date_year_from_time (MS_PER_DAY * (ecma_number_t) (365.25 * (2015 - 1970))) == 2015); TEST_ASSERT (ecma_date_year_from_time (-MS_PER_YEAR) == 1969); TEST_ASSERT (ecma_date_year_from_time (-1970 * MS_PER_YEAR) == 1); TEST_ASSERT (ecma_date_year_from_time (START_OF_GREGORIAN_CALENDAR) == 0); TEST_ASSERT (ecma_date_year_from_time (START_OF_GREGORIAN_CALENDAR - 1) == -1); TEST_ASSERT (ecma_date_year_from_time (START_OF_GREGORIAN_CALENDAR - 3 * MS_PER_YEAR) == -3); /* int ecma_date_day_within_year (time) */ /* FIXME: Implement */ /* int ecma_date_month_from_time (time) */ TEST_ASSERT (ecma_date_month_from_time (START_OF_GREGORIAN_CALENDAR) == 0); TEST_ASSERT (ecma_date_month_from_time (0) == 0); TEST_ASSERT (ecma_date_month_from_time (-MS_PER_DAY) == 11); TEST_ASSERT (ecma_date_month_from_time (31 * MS_PER_DAY) == 1); /* int ecma_date_date_from_time (time) */ TEST_ASSERT (ecma_date_date_from_time (START_OF_GREGORIAN_CALENDAR) == 1); TEST_ASSERT (ecma_date_date_from_time (0) == 1); TEST_ASSERT (ecma_date_date_from_time (-MS_PER_DAY) == 31); TEST_ASSERT (ecma_date_date_from_time (31 * MS_PER_DAY) == 1); /* int ecma_date_week_day (ecma_number_t time) */ /* FIXME: Implement */ /* ecma_number_t ecma_date_local_tza () */ /* FIXME: Implement */ /* ecma_number_t ecma_date_daylight_saving_ta (time) */ /* FIXME: Implement */ /* ecma_number_t ecma_date_local_time (time) */ /* FIXME: Implement */ /* ecma_number_t ecma_date_utc (time) */ /* FIXME: Implement */ /* ecma_number_t ecma_date_hour_from_time (time) */ TEST_ASSERT (ecma_date_hour_from_time (START_OF_GREGORIAN_CALENDAR) == 0); TEST_ASSERT (ecma_date_hour_from_time (0) == 0); TEST_ASSERT (ecma_date_hour_from_time (-MS_PER_DAY) == 0); TEST_ASSERT (ecma_date_hour_from_time (-1) == 23); /* ecma_number_t ecma_date_min_from_time (time) */ TEST_ASSERT (ecma_date_min_from_time (START_OF_GREGORIAN_CALENDAR) == 0); TEST_ASSERT (ecma_date_min_from_time (0) == 0); TEST_ASSERT (ecma_date_min_from_time (-MS_PER_DAY) == 0); TEST_ASSERT (ecma_date_min_from_time (-1) == 59); /* ecma_number_t ecma_date_sec_from_time (time) */ TEST_ASSERT (ecma_date_sec_from_time (START_OF_GREGORIAN_CALENDAR) == 0); TEST_ASSERT (ecma_date_sec_from_time (0) == 0); TEST_ASSERT (ecma_date_sec_from_time (-MS_PER_DAY) == 0); TEST_ASSERT (ecma_date_sec_from_time (-1) == 59); /* ecma_number_t ecma_date_ms_from_time (time) */ TEST_ASSERT (ecma_date_ms_from_time (START_OF_GREGORIAN_CALENDAR) == 0); TEST_ASSERT (ecma_date_ms_from_time (0) == 0); TEST_ASSERT (ecma_date_ms_from_time (-MS_PER_DAY) == 0); TEST_ASSERT (ecma_date_ms_from_time (-1) == 999); /* ecma_number_t ecma_date_make_time (hour, min, sec, ms) */ /* FIXME: Implement */ /* ecma_number_t ecma_date_make_day (year, month, date) */ TEST_ASSERT (ecma_date_make_day (1970, 0, 1) == 0); TEST_ASSERT (ecma_date_make_day (1970, -1, 1) == -31); TEST_ASSERT (ecma_date_make_day (1970, 0, 2.5) == 1); TEST_ASSERT (ecma_date_make_day (1970, 1, 35) == 65); TEST_ASSERT (ecma_date_make_day (1970, 13, 35) == 430); TEST_ASSERT (ecma_date_make_day (2016, 2, 1) == 16861); /* ecma_number_t ecma_date_make_date (day, time) */ /* FIXME: Implement */ /* ecma_number_t ecma_date_time_clip (year) */ /* FIXME: Implement */ return 0; } /* main */
/** * Unit test's main function. */ int main (int __attr_unused___ argc, char __attr_unused___ **argv) { /* int ecma_date_day (time)*/ JERRY_ASSERT (ecma_date_day (0) == 0); JERRY_ASSERT (ecma_date_day (MS_PER_DAY) == 1); /* ecma_number_t ecma_date_time_within_day (time) */ JERRY_ASSERT (ecma_date_time_within_day (0) == 0); JERRY_ASSERT (ecma_date_time_within_day (42) == 42); JERRY_ASSERT (ecma_date_time_within_day (42.51) == 42.51); JERRY_ASSERT (ecma_date_time_within_day (MS_PER_DAY + 42) == 42); /* int ecma_date_days_in_year (year) */ JERRY_ASSERT (ecma_date_days_in_year (0) == 366); JERRY_ASSERT (ecma_date_days_in_year (1600) == 366); JERRY_ASSERT (ecma_date_days_in_year (1603) == 365); JERRY_ASSERT (ecma_date_days_in_year (1900) == 365); JERRY_ASSERT (ecma_date_days_in_year (1970) == 365); JERRY_ASSERT (ecma_date_days_in_year (2000) == 366); JERRY_ASSERT (ecma_date_days_in_year (2000.45) == 366); JERRY_ASSERT (ecma_date_days_in_year (2012) == 366); JERRY_ASSERT (ecma_date_days_in_year (2015) == 365); JERRY_ASSERT (ecma_date_days_in_year (285616 + 1970) == 365); JERRY_ASSERT (ecma_date_days_in_year (-1970) == 365); /* int ecma_date_day_from_year (year) */ JERRY_ASSERT (ecma_date_day_from_year (1969) == -365); JERRY_ASSERT (ecma_date_day_from_year (1970) == 0); JERRY_ASSERT (ecma_date_day_from_year (1971) == 365); JERRY_ASSERT (ecma_date_day_from_year (2000) == 10957); /* int ecma_date_year_from_time (time) */ JERRY_ASSERT (ecma_date_year_from_time (0) == 1970); JERRY_ASSERT (ecma_date_year_from_time (MS_PER_DAY) == 1970); JERRY_ASSERT (ecma_date_year_from_time ((MS_PER_DAY) * (ecma_number_t) 365 - 1) == 1970); JERRY_ASSERT (ecma_date_year_from_time (MS_PER_DAY * (ecma_number_t) 365) == 1971); JERRY_ASSERT (ecma_date_year_from_time (MS_PER_DAY * (ecma_number_t) (365 * (2015 - 1970))) == 2014); JERRY_ASSERT (ecma_date_year_from_time (MS_PER_DAY * (ecma_number_t) (365.25 * (2015 - 1970))) == 2015); /* int ecma_date_day_within_year (time) */ /* FIXME: Implement */ /* int ecma_date_month_from_time (time) */ /* FIXME: Implement */ /* int ecma_date_date_from_time (time) */ /* FIXME: Implement */ /* int ecma_date_week_day (ecma_number_t time) */ /* FIXME: Implement */ /* ecma_number_t ecma_date_local_tza () */ /* FIXME: Implement */ /* ecma_number_t ecma_date_daylight_saving_ta (time) */ /* FIXME: Implement */ /* ecma_number_t ecma_date_local_time (time) */ /* FIXME: Implement */ /* ecma_number_t ecma_date_utc (time) */ /* FIXME: Implement */ /* ecma_number_t ecma_date_hour_from_time (time) */ /* FIXME: Implement */ /* ecma_number_t ecma_date_min_from_time (time) */ /* FIXME: Implement */ /* ecma_number_t ecma_date_sec_from_time (time) */ /* FIXME: Implement */ /* ecma_number_t ecma_date_ms_from_time (time) */ /* FIXME: Implement */ /* ecma_number_t ecma_date_make_time (hour, min, sec, ms) */ /* FIXME: Implement */ /* ecma_number_t ecma_date_make_day (year, month, date) */ JERRY_ASSERT (ecma_date_make_day (1970, 0, 1) == 0); JERRY_ASSERT (ecma_date_make_day (1970, 0, 2.5) == 1); JERRY_ASSERT (ecma_date_make_day (1970, 1, 35) == 65); JERRY_ASSERT (ecma_date_make_day (1970, 13, 35) == 430); JERRY_ASSERT (ecma_date_make_day (2016, 2, 1) == 16861); /* ecma_number_t ecma_date_make_date (day, time) */ /* FIXME: Implement */ /* ecma_number_t ecma_date_time_clip (year) */ /* FIXME: Implement */ return 0; } /* main */
/** * Dispatch set date functions * * @return ecma value * Returned value must be freed with ecma_free_value. */ static ecma_value_t ecma_builtin_date_prototype_dispatch_set (uint16_t builtin_routine_id, /**< built-in wide routine * identifier */ ecma_extended_object_t *ext_object_p, /**< date extended object */ ecma_number_t date_num, /**< date converted to number */ const ecma_value_t arguments_list[], /**< list of arguments * passed to routine */ ecma_length_t arguments_number) /**< length of arguments' list */ { ecma_number_t converted_number[4]; ecma_length_t conversions = 0; /* If the first argument is not specified, it is always converted to NaN. */ converted_number[0] = ecma_number_make_nan (); switch (builtin_routine_id) { #ifndef CONFIG_DISABLE_ANNEXB_BUILTIN case ECMA_DATE_PROTOTYPE_SET_YEAR: #endif /* !CONFIG_DISABLE_ANNEXB_BUILTIN */ case ECMA_DATE_PROTOTYPE_SET_DATE: case ECMA_DATE_PROTOTYPE_SET_UTC_DATE: case ECMA_DATE_PROTOTYPE_SET_UTC_MILLISECONDS: case ECMA_DATE_PROTOTYPE_SET_MILLISECONDS: { conversions = 1; break; } case ECMA_DATE_PROTOTYPE_SET_MONTH: case ECMA_DATE_PROTOTYPE_SET_UTC_MONTH: case ECMA_DATE_PROTOTYPE_SET_UTC_SECONDS: case ECMA_DATE_PROTOTYPE_SET_SECONDS: { conversions = 2; break; } case ECMA_DATE_PROTOTYPE_SET_FULL_YEAR: case ECMA_DATE_PROTOTYPE_SET_UTC_FULL_YEAR: case ECMA_DATE_PROTOTYPE_SET_MINUTES: case ECMA_DATE_PROTOTYPE_SET_UTC_MINUTES: { conversions = 3; break; } default: { JERRY_ASSERT (builtin_routine_id == ECMA_DATE_PROTOTYPE_SET_HOURS || builtin_routine_id == ECMA_DATE_PROTOTYPE_SET_UTC_HOURS); conversions = 4; break; } } if (conversions > arguments_number) { conversions = arguments_number; } for (ecma_length_t i = 0; i < conversions; i++) { ecma_value_t value = ecma_op_to_number (arguments_list[i]); if (ECMA_IS_VALUE_ERROR (value)) { return value; } converted_number[i] = ecma_get_number_from_value (value); ecma_free_value (value); } ecma_number_t day_part; ecma_number_t time_part; if (builtin_routine_id <= ECMA_DATE_PROTOTYPE_SET_UTC_DATE) { if (ecma_number_is_nan (date_num)) { if (ECMA_DATE_PROTOTYPE_IS_SET_YEAR_ROUTINE (builtin_routine_id)) { date_num = ECMA_NUMBER_ZERO; } else { return ecma_make_number_value (date_num); } } time_part = ecma_date_time_within_day (date_num); ecma_number_t year = ecma_date_year_from_time (date_num); ecma_number_t month = ecma_date_month_from_time (date_num); ecma_number_t day = ecma_date_date_from_time (date_num); switch (builtin_routine_id) { case ECMA_DATE_PROTOTYPE_SET_FULL_YEAR: case ECMA_DATE_PROTOTYPE_SET_UTC_FULL_YEAR: { year = converted_number[0]; if (conversions >= 2) { month = converted_number[1]; } if (conversions >= 3) { day = converted_number[2]; } break; } #ifndef CONFIG_DISABLE_ANNEXB_BUILTIN case ECMA_DATE_PROTOTYPE_SET_YEAR: { year = converted_number[0]; if (year >= 0 && year <= 99) { year += 1900; } break; } #endif /* !CONFIG_DISABLE_ANNEXB_BUILTIN */ case ECMA_DATE_PROTOTYPE_SET_MONTH: case ECMA_DATE_PROTOTYPE_SET_UTC_MONTH: { month = converted_number[0]; if (conversions >= 2) { day = converted_number[1]; } break; } default: { JERRY_ASSERT (builtin_routine_id == ECMA_DATE_PROTOTYPE_SET_DATE || builtin_routine_id == ECMA_DATE_PROTOTYPE_SET_UTC_DATE); day = converted_number[0]; break; } } day_part = ecma_date_make_day (year, month, day); #ifndef CONFIG_DISABLE_ANNEXB_BUILTIN if (builtin_routine_id == ECMA_DATE_PROTOTYPE_SET_YEAR) { builtin_routine_id = ECMA_DATE_PROTOTYPE_SET_UTC_YEAR; if (ecma_number_is_nan (converted_number[0])) { day_part = 0; time_part = converted_number[0]; } } #endif /* !CONFIG_DISABLE_ANNEXB_BUILTIN */ } else { if (ecma_number_is_nan (date_num)) { return ecma_make_number_value (date_num); } day_part = ecma_date_day (date_num); ecma_number_t hour = ecma_date_hour_from_time (date_num); ecma_number_t min = ecma_date_min_from_time (date_num); ecma_number_t sec = ecma_date_sec_from_time (date_num); ecma_number_t ms = ecma_date_ms_from_time (date_num); switch (builtin_routine_id) { case ECMA_DATE_PROTOTYPE_SET_HOURS: case ECMA_DATE_PROTOTYPE_SET_UTC_HOURS: { hour = converted_number[0]; if (conversions >= 2) { min = converted_number[1]; } if (conversions >= 3) { sec = converted_number[2]; } if (conversions >= 4) { ms = converted_number[3]; } break; } case ECMA_DATE_PROTOTYPE_SET_MINUTES: case ECMA_DATE_PROTOTYPE_SET_UTC_MINUTES: { min = converted_number[0]; if (conversions >= 2) { sec = converted_number[1]; } if (conversions >= 3) { ms = converted_number[2]; } break; } case ECMA_DATE_PROTOTYPE_SET_UTC_SECONDS: case ECMA_DATE_PROTOTYPE_SET_SECONDS: { sec = converted_number[0]; if (conversions >= 2) { ms = converted_number[1]; } break; } default: { JERRY_ASSERT (builtin_routine_id == ECMA_DATE_PROTOTYPE_SET_UTC_MILLISECONDS || builtin_routine_id == ECMA_DATE_PROTOTYPE_SET_MILLISECONDS); ms = converted_number[0]; break; } } time_part = ecma_date_make_time (hour, min, sec, ms); } bool is_utc = BUILTIN_DATE_FUNCTION_IS_UTC (builtin_routine_id); ecma_number_t full_date = ecma_date_make_date (day_part, time_part); if (!is_utc) { full_date = ecma_date_utc (full_date); } full_date = ecma_date_time_clip (full_date); *ECMA_GET_INTERNAL_VALUE_POINTER (ecma_number_t, ext_object_p->u.class_prop.u.value) = full_date; return ecma_make_number_value (full_date); } /* ecma_builtin_date_prototype_dispatch_set */
/** * Calculate MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli)) for Date constructor and UTC * * See also: * ECMA-262 v5, 15.9.3.1 * ECMA-262 v5, 15.9.4.3 * * @return result of MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli)) */ static ecma_completion_value_t ecma_date_construct_helper (const ecma_value_t *args, /**< arguments passed to the Date constructor */ ecma_length_t args_len) /**< number of arguments */ { ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); ecma_number_t *prim_value_p = ecma_alloc_number (); *prim_value_p = ecma_number_make_nan (); ECMA_TRY_CATCH (year_value, ecma_op_to_number (args[0]), ret_value); ECMA_TRY_CATCH (month_value, ecma_op_to_number (args[1]), ret_value); ecma_number_t year = *ecma_get_number_from_value (year_value); ecma_number_t month = *ecma_get_number_from_value (month_value); ecma_number_t date = ECMA_NUMBER_ONE; ecma_number_t hours = ECMA_NUMBER_ZERO; ecma_number_t minutes = ECMA_NUMBER_ZERO; ecma_number_t seconds = ECMA_NUMBER_ZERO; ecma_number_t milliseconds = ECMA_NUMBER_ZERO; /* 3. */ if (args_len >= 3 && ecma_is_completion_value_empty (ret_value)) { ECMA_TRY_CATCH (date_value, ecma_op_to_number (args[2]), ret_value); date = *ecma_get_number_from_value (date_value); ECMA_FINALIZE (date_value); } /* 4. */ if (args_len >= 4 && ecma_is_completion_value_empty (ret_value)) { ECMA_TRY_CATCH (hours_value, ecma_op_to_number (args[3]), ret_value); hours = *ecma_get_number_from_value (hours_value); ECMA_FINALIZE (hours_value); } /* 5. */ if (args_len >= 5 && ecma_is_completion_value_empty (ret_value)) { ECMA_TRY_CATCH (minutes_value, ecma_op_to_number (args[4]), ret_value); minutes = *ecma_get_number_from_value (minutes_value); ECMA_FINALIZE (minutes_value); } /* 6. */ if (args_len >= 6 && ecma_is_completion_value_empty (ret_value)) { ECMA_TRY_CATCH (seconds_value, ecma_op_to_number (args[5]), ret_value); seconds = *ecma_get_number_from_value (seconds_value); ECMA_FINALIZE (seconds_value); } /* 7. */ if (args_len >= 7 && ecma_is_completion_value_empty (ret_value)) { ECMA_TRY_CATCH (milliseconds_value, ecma_op_to_number (args[6]), ret_value); milliseconds = *ecma_get_number_from_value (milliseconds_value); ECMA_FINALIZE (milliseconds_value); } if (ecma_is_completion_value_empty (ret_value)) { if (!ecma_number_is_nan (year) && !ecma_number_is_infinity (year)) { /* 8. */ int32_t y = ecma_number_to_int32 (year); if (y >= 0 && y <= 99) { year = (ecma_number_t) (1900 + y); } else { year = (ecma_number_t) y; } } *prim_value_p = ecma_date_make_date (ecma_date_make_day (year, month, date), ecma_date_make_time (hours, minutes, seconds, milliseconds)); } ECMA_FINALIZE (month_value); ECMA_FINALIZE (year_value); if (ecma_is_completion_value_empty (ret_value)) { ret_value = ecma_make_normal_completion_value (ecma_make_number_value (prim_value_p)); } else { ecma_dealloc_number (prim_value_p); } return ret_value; } /* ecma_date_construct_helper */
/** * The Date object's 'parse' routine * * See also: * ECMA-262 v5, 15.9.4.2 * ECMA-262 v5, 15.9.1.15 * * @return completion value * Returned value must be freed with ecma_free_completion_value. */ static ecma_completion_value_t ecma_builtin_date_parse (ecma_value_t this_arg __attr_unused___, /**< this argument */ ecma_value_t arg) /**< string */ { ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); ecma_number_t *date_num_p = ecma_alloc_number (); *date_num_p = ecma_number_make_nan (); /* Date Time String fromat (ECMA-262 v5, 15.9.1.15) */ ECMA_TRY_CATCH (date_str_value, ecma_op_to_string (arg), ret_value); ecma_string_t *date_str_p = ecma_get_string_from_value (date_str_value); lit_utf8_size_t date_str_size = ecma_string_get_size (date_str_p); MEM_DEFINE_LOCAL_ARRAY (date_start_p, date_str_size, lit_utf8_byte_t); ssize_t sz = ecma_string_to_utf8_string (date_str_p, date_start_p, (ssize_t) date_str_size); JERRY_ASSERT (sz >= 0); lit_utf8_byte_t *date_str_curr_p = date_start_p; const lit_utf8_byte_t *date_str_end_p = date_start_p + date_str_size; /* 1. read year */ ecma_number_t year = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 4); if (!ecma_number_is_nan (year) && year >= 0) { ecma_number_t month = ECMA_NUMBER_ONE; ecma_number_t day = ECMA_NUMBER_ONE; ecma_number_t time = ECMA_NUMBER_ZERO; /* 2. read month if any */ if (date_str_curr_p < date_str_end_p && *date_str_curr_p == '-') { /* eat up '-' */ date_str_curr_p++; month = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2); if (month > 12 || month < 1) { month = ecma_number_make_nan (); } } /* 3. read day if any */ if (date_str_curr_p < date_str_end_p && *date_str_curr_p == '-') { /* eat up '-' */ date_str_curr_p++; day = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2); if (day < 1 || day > 31) { day = ecma_number_make_nan (); } } /* 4. read time if any */ if (date_str_curr_p < date_str_end_p && *date_str_curr_p == 'T') { /* eat up 'T' */ date_str_curr_p++; ecma_number_t hours = ECMA_NUMBER_ZERO; ecma_number_t minutes = ECMA_NUMBER_ZERO; ecma_number_t seconds = ECMA_NUMBER_ZERO; ecma_number_t milliseconds = ECMA_NUMBER_ZERO; ecma_length_t remaining_length = lit_utf8_string_length (date_str_curr_p, (lit_utf8_size_t) (date_str_end_p - date_str_curr_p)); if (remaining_length >= 5) { /* 4.1 read hours and minutes */ hours = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2); if (hours < 0 || hours > 24) { hours = ecma_number_make_nan (); } else if (hours == 24) { hours = ECMA_NUMBER_ZERO; } /* eat up ':' */ date_str_curr_p++; minutes = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2); if (minutes < 0 || minutes > 59) { minutes = ecma_number_make_nan (); } /* 4.2 read seconds if any */ if (date_str_curr_p < date_str_end_p && *date_str_curr_p == ':') { /* eat up ':' */ date_str_curr_p++; seconds = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2); if (seconds < 0 || seconds > 59) { seconds = ecma_number_make_nan (); } /* 4.3 read milliseconds if any */ if (date_str_curr_p < date_str_end_p && *date_str_curr_p == '.') { /* eat up '.' */ date_str_curr_p++; milliseconds = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 3); if (milliseconds < 0) { milliseconds = ecma_number_make_nan (); } } } time = ecma_date_make_time (hours, minutes, seconds, milliseconds); } else { time = ecma_number_make_nan (); } /* 4.4 read timezone if any */ if (date_str_curr_p < date_str_end_p && *date_str_curr_p == 'Z' && !ecma_number_is_nan (time)) { date_str_curr_p++; time = ecma_date_make_time (hours, minutes, seconds, milliseconds); } else if (date_str_curr_p < date_str_end_p && (*date_str_curr_p == '+' || *date_str_curr_p == '-')) { ecma_length_t remaining_length; remaining_length = lit_utf8_string_length (date_str_curr_p, (lit_utf8_size_t) (date_str_end_p - date_str_curr_p)) - 1; if (remaining_length == 5) { bool is_negative = false; if (*date_str_curr_p == '-') { is_negative = true; } /* eat up '+/-' */ date_str_curr_p++; /* read hours and minutes */ hours = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2); if (hours < 0 || hours > 24) { hours = ecma_number_make_nan (); } else if (hours == 24) { hours = ECMA_NUMBER_ZERO; } /* eat up ':' */ date_str_curr_p++; minutes = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2); if (minutes < 0 || minutes > 59) { minutes = ecma_number_make_nan (); } if (is_negative) { time += ecma_date_make_time (hours, minutes, ECMA_NUMBER_ZERO, ECMA_NUMBER_ZERO); } else { time -= ecma_date_make_time (hours, minutes, ECMA_NUMBER_ZERO, ECMA_NUMBER_ZERO); } } } } if (date_str_curr_p >= date_str_end_p) { ecma_number_t date = ecma_date_make_day (year, month - 1, day); *date_num_p = ecma_date_make_date (date, time); } } ret_value = ecma_make_normal_completion_value (ecma_make_number_value (date_num_p)); MEM_FINALIZE_LOCAL_ARRAY (date_start_p); ECMA_FINALIZE (date_str_value); return ret_value; } /* ecma_builtin_date_parse */
/** * Calculate MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli)) for Date constructor and UTC * * See also: * ECMA-262 v5, 15.9.3.1 * ECMA-262 v5, 15.9.4.3 * * @return result of MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli)) */ static ecma_value_t ecma_date_construct_helper (const ecma_value_t *args, /**< arguments passed to the Date constructor */ ecma_length_t args_len) /**< number of arguments */ { ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); ecma_number_t prim_value = ecma_number_make_nan (); ECMA_TRY_CATCH (year_value, ecma_op_to_number (args[0]), ret_value); ECMA_TRY_CATCH (month_value, ecma_op_to_number (args[1]), ret_value); ecma_number_t year = ecma_get_number_from_value (year_value); ecma_number_t month = ecma_get_number_from_value (month_value); ecma_number_t date = ECMA_NUMBER_ONE; ecma_number_t hours = ECMA_NUMBER_ZERO; ecma_number_t minutes = ECMA_NUMBER_ZERO; ecma_number_t seconds = ECMA_NUMBER_ZERO; ecma_number_t milliseconds = ECMA_NUMBER_ZERO; /* 3. */ if (args_len >= 3 && ecma_is_value_empty (ret_value)) { ECMA_TRY_CATCH (date_value, ecma_op_to_number (args[2]), ret_value); date = ecma_get_number_from_value (date_value); ECMA_FINALIZE (date_value); } /* 4. */ if (args_len >= 4 && ecma_is_value_empty (ret_value)) { ECMA_TRY_CATCH (hours_value, ecma_op_to_number (args[3]), ret_value); hours = ecma_get_number_from_value (hours_value); ECMA_FINALIZE (hours_value); } /* 5. */ if (args_len >= 5 && ecma_is_value_empty (ret_value)) { ECMA_TRY_CATCH (minutes_value, ecma_op_to_number (args[4]), ret_value); minutes = ecma_get_number_from_value (minutes_value); ECMA_FINALIZE (minutes_value); } /* 6. */ if (args_len >= 6 && ecma_is_value_empty (ret_value)) { ECMA_TRY_CATCH (seconds_value, ecma_op_to_number (args[5]), ret_value); seconds = ecma_get_number_from_value (seconds_value); ECMA_FINALIZE (seconds_value); } /* 7. */ if (args_len >= 7 && ecma_is_value_empty (ret_value)) { ECMA_TRY_CATCH (milliseconds_value, ecma_op_to_number (args[6]), ret_value); milliseconds = ecma_get_number_from_value (milliseconds_value); ECMA_FINALIZE (milliseconds_value); } if (ecma_is_value_empty (ret_value)) { if (!ecma_number_is_nan (year)) { /* 8. */ ecma_number_t y = ecma_number_trunc (year); if (y >= 0 && y <= 99) { year = 1900 + y; } } prim_value = ecma_date_make_date (ecma_date_make_day (year, month, date), ecma_date_make_time (hours, minutes, seconds, milliseconds)); } ECMA_FINALIZE (month_value); ECMA_FINALIZE (year_value); if (ecma_is_value_empty (ret_value)) { ret_value = ecma_make_number_value (prim_value); } return ret_value; } /* ecma_date_construct_helper */
/** * The Date object's 'parse' routine * * See also: * ECMA-262 v5, 15.9.4.2 * ECMA-262 v5, 15.9.1.15 * * @return completion value * Returned value must be freed with ecma_free_completion_value. */ static ecma_completion_value_t ecma_builtin_date_parse (ecma_value_t this_arg __attr_unused___, /**< this argument */ ecma_value_t arg) /**< string */ { ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); ecma_number_t *date_num_p = ecma_alloc_number (); *date_num_p = ecma_number_make_nan (); /* Date Time String fromat (ECMA-262 v5, 15.9.1.15) */ ECMA_TRY_CATCH (date_str_value, ecma_op_to_string (arg), ret_value); ecma_string_t *date_str_p = ecma_get_string_from_value (date_str_value); lit_utf8_size_t date_str_size = ecma_string_get_size (date_str_p); MEM_DEFINE_LOCAL_ARRAY (date_start_p, date_str_size, lit_utf8_byte_t); ecma_string_to_utf8_string (date_str_p, date_start_p, (ssize_t) date_str_size); lit_utf8_iterator_t iter = lit_utf8_iterator_create (date_start_p, date_str_size); /* 1. read year */ ecma_number_t year = ecma_date_parse_date_chars (&iter, 4); if (!ecma_number_is_nan (year) && year >= 0) { ecma_number_t month = ECMA_NUMBER_ONE; ecma_number_t day = ECMA_NUMBER_ONE; ecma_number_t time = ECMA_NUMBER_ZERO; /* 2. read month if any */ if (!lit_utf8_iterator_is_eos (&iter) && lit_utf8_iterator_peek_next (&iter) == '-') { /* eat up '-' */ lit_utf8_iterator_incr (&iter); month = ecma_date_parse_date_chars (&iter, 2); if (month > 12 || month < 1) { month = ecma_number_make_nan (); } } /* 3. read day if any */ if (!lit_utf8_iterator_is_eos (&iter) && lit_utf8_iterator_peek_next (&iter) == '-') { /* eat up '-' */ lit_utf8_iterator_incr (&iter); day = ecma_date_parse_date_chars (&iter, 2); if (day < 1 || day > 31) { day = ecma_number_make_nan (); } } /* 4. read time if any */ if (!lit_utf8_iterator_is_eos (&iter) && lit_utf8_iterator_peek_next (&iter) == 'T') { ecma_number_t hours = ECMA_NUMBER_ZERO; ecma_number_t minutes = ECMA_NUMBER_ZERO; ecma_number_t seconds = ECMA_NUMBER_ZERO; ecma_number_t milliseconds = ECMA_NUMBER_ZERO; ecma_length_t num_of_visited_chars = lit_utf8_iterator_get_index (&iter); ecma_length_t date_str_len = lit_utf8_string_length (iter.buf_p, iter.buf_size) - 1; if ((date_str_len - num_of_visited_chars) >= 5) { /* eat up 'T' */ lit_utf8_iterator_incr (&iter); /* 4.1 read hours and minutes */ hours = ecma_date_parse_date_chars (&iter, 2); if (hours < 0 || hours > 24) { hours = ecma_number_make_nan (); } else if (hours == 24) { hours = ECMA_NUMBER_ZERO; } /* eat up ':' */ lit_utf8_iterator_incr (&iter); minutes = ecma_date_parse_date_chars (&iter, 2); if (minutes < 0 || minutes > 59) { minutes = ecma_number_make_nan (); } /* 4.2 read seconds if any */ if (!lit_utf8_iterator_is_eos (&iter) && lit_utf8_iterator_peek_next (&iter) == ':') { /* eat up ':' */ lit_utf8_iterator_incr (&iter); seconds = ecma_date_parse_date_chars (&iter, 2); if (seconds < 0 || seconds > 59) { seconds = ecma_number_make_nan (); } /* 4.3 read milliseconds if any */ if (!lit_utf8_iterator_is_eos (&iter) && lit_utf8_iterator_peek_next (&iter) == '.') { /* eat up '.' */ lit_utf8_iterator_incr (&iter); milliseconds = ecma_date_parse_date_chars (&iter, 3); if (milliseconds < 0) { milliseconds = ecma_number_make_nan (); } } } time = ecma_date_make_time (hours, minutes, seconds, milliseconds); } else { time = ecma_number_make_nan (); } /* 4.4 read timezone if any */ if (!lit_utf8_iterator_is_eos (&iter) && lit_utf8_iterator_peek_next (&iter) == 'Z' && !ecma_number_is_nan (time)) { lit_utf8_iterator_incr (&iter); time = ecma_date_utc (ecma_date_make_time (hours, minutes, seconds, milliseconds)); } else if (!lit_utf8_iterator_is_eos (&iter) && (lit_utf8_iterator_peek_next (&iter) == '+' || lit_utf8_iterator_peek_next (&iter) == '-')) { ecma_length_t num_of_visited_chars = lit_utf8_iterator_get_index (&iter); ecma_length_t date_str_len = lit_utf8_string_length (iter.buf_p, iter.buf_size) - 1; if ((date_str_len - num_of_visited_chars) == 5) { bool is_negative = false; if (lit_utf8_iterator_peek_next (&iter) == '-') { is_negative = true; } /* eat up '+/-' */ lit_utf8_iterator_incr (&iter); /* read hours and minutes */ hours = ecma_date_parse_date_chars (&iter, 2); if (hours < 0 || hours > 24) { hours = ecma_number_make_nan (); } else if (hours == 24) { hours = ECMA_NUMBER_ZERO; } /* eat up ':' */ lit_utf8_iterator_incr (&iter); minutes = ecma_date_parse_date_chars (&iter, 2); if (minutes < 0 || minutes > 59) { minutes = ecma_number_make_nan (); } if (is_negative) { time += ecma_date_make_time (hours, minutes, ECMA_NUMBER_ZERO, ECMA_NUMBER_ZERO); } else { time -= ecma_date_make_time (hours, minutes, ECMA_NUMBER_ZERO, ECMA_NUMBER_ZERO); } } } } if (lit_utf8_iterator_is_eos (&iter)) { ecma_number_t date = ecma_date_make_day (year, month - 1, day); *date_num_p = ecma_date_make_date (date, time); } } ret_value = ecma_make_normal_completion_value (ecma_make_number_value (date_num_p)); MEM_FINALIZE_LOCAL_ARRAY (date_start_p); ECMA_FINALIZE (date_str_value); return ret_value; } /* ecma_builtin_date_parse */