From 017aa6b68474dc745e3d8ccbaf8805271714cd29 Mon Sep 17 00:00:00 2001 From: Szilard Ledan Date: Wed, 1 Jul 2015 16:55:32 +0200 Subject: [PATCH] Change Date helpers to handle NaN JerryScript-DCO-1.0-Signed-off-by: Szilard Ledan szledan.u-szeged@partner.samsung.com --- .../ecma-builtin-helpers-date.cpp | 244 ++++++++++-------- .../builtin-objects/ecma-builtin-helpers.h | 18 +- 2 files changed, 143 insertions(+), 119 deletions(-) diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-date.cpp b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-date.cpp index c2f2d49be..f2afc5066 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-date.cpp +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-date.cpp @@ -56,25 +56,25 @@ /** * Helper function to get day number from time value. * - * Caller must guarantee that the argument is not NaN. - * * See also: * ECMA-262 v5, 15.9.1.2 * * @return time value for day number */ -int __attr_always_inline___ +ecma_number_t __attr_always_inline___ ecma_date_day (ecma_number_t time) /**< time value */ { - JERRY_ASSERT (!ecma_number_is_nan (time)); - return (int) floor (time / ECMA_DATE_MS_PER_DAY); + if (ecma_number_is_nan (time)) + { + return time; /* time is NaN */ + } + + return (ecma_number_t) floor (time / ECMA_DATE_MS_PER_DAY); } /* ecma_date_day */ /** * Helper function to get time within day from time value. * - * Caller must guarantee that the argument is not NaN. - * * See also: * ECMA-262 v5, 15.9.1.2 * @@ -83,40 +83,46 @@ ecma_date_day (ecma_number_t time) /**< time value */ ecma_number_t __attr_always_inline___ ecma_date_time_within_day (ecma_number_t time) /**< time value */ { - JERRY_ASSERT (!ecma_number_is_nan (time)); + if (ecma_number_is_nan (time)) + { + return time; /* time is NaN */ + } + return (ecma_number_t) fmod (time, ECMA_DATE_MS_PER_DAY); } /* ecma_date_time_within_day */ /** * Helper function to get number of days from year value. * - * Caller must guarantee that the argument is not NaN. - * * See also: * ECMA-262 v5, 15.9.1.3 * * @return number of days */ -int __attr_always_inline___ +ecma_number_t __attr_always_inline___ ecma_date_days_in_year (ecma_number_t year) /**< year value */ { - JERRY_ASSERT (!ecma_number_is_nan (year)); + if (ecma_number_is_nan (year)) + { + return year; /* year is NaN */ + } + if (fmod (floor (year), 4)) { - return 365; + return (ecma_number_t) 365; } if (fmod (floor (year), 100)) { - return 366; + return (ecma_number_t) 366; } if (fmod (floor (year), 400)) { - return 365; + return (ecma_number_t) 365; } - return 366; + return (ecma_number_t) 366; } /* ecma_date_days_in_year */ /** @@ -127,21 +133,23 @@ ecma_date_days_in_year (ecma_number_t year) /**< year value */ * * @return day number of the first day of a year */ -int __attr_always_inline___ +ecma_number_t __attr_always_inline___ ecma_date_day_from_year (ecma_number_t year) /**< year value */ { - JERRY_ASSERT (!ecma_number_is_nan (year)); - return (int) (365 * (year - 1970) - + floor ((year - 1969) / 4) - - floor ((year - 1901) / 100) - + floor ((year - 1601) / 400)); + if (ecma_number_is_nan (year)) + { + return year; /* year is NaN */ + } + + return (ecma_number_t) (365 * (year - 1970) + + floor ((year - 1969) / 4) + - floor ((year - 1901) / 100) + + floor ((year - 1601) / 400)); } /* ecma_date_day_from_year */ /** * Helper function to get the time value of the start of a year. * - * Caller must guarantee that the argument is not NaN. - * * See also: * ECMA-262 v5, 15.9.1.3 * @@ -150,35 +158,40 @@ ecma_date_day_from_year (ecma_number_t year) /**< year value */ ecma_number_t __attr_always_inline___ ecma_date_time_from_year (ecma_number_t year) /**< year value */ { - JERRY_ASSERT (!ecma_number_is_nan (year)); - return ECMA_DATE_MS_PER_DAY * (ecma_number_t) ecma_date_day_from_year (year); + if (ecma_number_is_nan (year)) + { + return year; /* year is NaN */ + } + + return ECMA_DATE_MS_PER_DAY * ecma_date_day_from_year (year); } /* ecma_date_time_from_year */ /** * Helper function to determine a year value from the time value. * - * Caller must guarantee that the argument is not NaN. - * * See also: * ECMA-262 v5, 15.9.1.3 * * @return year value */ -int +ecma_number_t ecma_date_year_from_time (ecma_number_t time) /**< time value */ { - JERRY_ASSERT (!ecma_number_is_nan (time)); + if (ecma_number_is_nan (time)) + { + return time; /* time is NaN */ + } /* ECMA-262 v5, 15.9.1.1 define the largest year that is * representable (285616) forward from 01 January, 1970 UTC. */ - int year = 285616 + 1970; + ecma_number_t year = (ecma_number_t) (285616 + 1970); - while (ecma_date_time_from_year ((ecma_number_t) year) > time) + while (ecma_date_time_from_year (year) > time) { - if (ecma_date_time_from_year ((ecma_number_t) (year / 2)) > time) + if (ecma_date_time_from_year ((ecma_number_t) floor (year / 2)) > time) { - year = year / 2; + year = (ecma_number_t) floor (year / 2); } year--; } @@ -189,54 +202,59 @@ ecma_date_year_from_time (ecma_number_t time) /**< time value */ /** * Helper function to decide if time value is in a leap-year. * - * Caller must guarantee that the argument is not NaN. - * * See also: * ECMA-262 v5, 15.9.1.3 * * @return 1 if time within a leap year and otherwise is zero */ -int __attr_always_inline___ +ecma_number_t __attr_always_inline___ ecma_date_in_leap_year (ecma_number_t time) /**< time value */ { - JERRY_ASSERT (!ecma_number_is_nan (time)); + if (ecma_number_is_nan (time)) + { + return time; /* time is NaN */ + } + return ecma_date_days_in_year (ecma_date_time_from_year (time)) - 365; } /* ecma_date_in_leap_year */ /** * Helper function to get day within year from time value. * - * Caller must guarantee that the argument is not NaN. - * * See also: * ECMA-262 v5, 15.9.1.4 * * @return number of days within year */ -int __attr_always_inline___ +ecma_number_t __attr_always_inline___ ecma_date_day_within_year (ecma_number_t time) /**< time value */ { - JERRY_ASSERT (!ecma_number_is_nan (time)); - return ecma_date_day (time) - ecma_date_day_from_year ((ecma_number_t) ecma_date_year_from_time (time)); + if (ecma_number_is_nan (time)) + { + return time; /* time is NaN */ + } + + return ecma_date_day (time) - ecma_date_day_from_year (ecma_date_year_from_time (time)); } /* ecma_date_day_within_year */ /** * Helper function to get month from time value. * - * Caller must guarantee that the argument is not NaN. - * * See also: * ECMA-262 v5, 15.9.1.4 * * @return month number */ -int +ecma_number_t ecma_date_month_from_time (ecma_number_t time) /**< time value */ { - JERRY_ASSERT (!ecma_number_is_nan (time)); + if (ecma_number_is_nan (time)) + { + return time; /* time is NaN */ + } - int in_leap_year = ecma_date_in_leap_year (time); - int day_within_year = ecma_date_day_within_year (time); + ecma_number_t in_leap_year = ecma_date_in_leap_year (time); + ecma_number_t day_within_year = ecma_date_day_within_year (time); JERRY_ASSERT (day_within_year >= 0 && day_within_year < 365 + in_leap_year); @@ -291,22 +309,25 @@ ecma_date_month_from_time (ecma_number_t time) /**< time value */ /** * Helper function to get date number from time value. * - * Caller must guarantee that the argument is not NaN. - * * See also: * ECMA-262 v5, 15.9.1.5 * * @return date number */ -int +ecma_number_t ecma_date_date_from_time (ecma_number_t time) /**< time value */ { - JERRY_ASSERT (!ecma_number_is_nan (time)); + if (ecma_number_is_nan (time)) + { + return time; /* time is NaN */ + } - int in_leap_year = ecma_date_in_leap_year (time); - int day_within_year = ecma_date_day_within_year (time); + ecma_number_t in_leap_year = ecma_date_in_leap_year (time); + ecma_number_t day_within_year = ecma_date_day_within_year (time); + JERRY_ASSERT (!ecma_number_is_nan (ecma_date_month_from_time (time))); + int month = ecma_number_to_int32 (ecma_date_month_from_time (time)); - switch (ecma_date_month_from_time (time)) + switch (month) { case 0: { @@ -365,18 +386,20 @@ ecma_date_date_from_time (ecma_number_t time) /**< time value */ /** * Helper function to get weekday from time value. * - * Caller must guarantee that the argument is not NaN. - * * See also: * ECMA-262 v5, 15.9.1.6 * * @return weekday number */ -int __attr_always_inline___ +ecma_number_t __attr_always_inline___ ecma_date_week_day (ecma_number_t time) /**< time value */ { - JERRY_ASSERT (!ecma_number_is_nan (time)); - return (ecma_date_day (time) + 4) % 7; + if (ecma_number_is_nan (time)) + { + return time; /* time is NaN */ + } + + return (ecma_number_t) fmod ((ecma_date_day (time) + 4), 7); } /* ecma_date_week_day */ /** @@ -396,25 +419,25 @@ ecma_date_local_tza () /** * Helper function to get the daylight saving time adjustment. * - * Caller must guarantee that the argument is not NaN. - * * See also: * ECMA-262 v5, 15.9.1.8 * * @return daylight saving time adjustment */ ecma_number_t __attr_always_inline___ -ecma_date_daylight_saving_ta (ecma_number_t __attr_unused___ time) /**< time value */ +ecma_date_daylight_saving_ta (ecma_number_t time) /**< time value */ { - JERRY_ASSERT (!ecma_number_is_nan (time)); + if (ecma_number_is_nan (time)) + { + return time; /* time is NaN */ + } + JERRY_UNIMPLEMENTED ("The built-in is not implemented."); } /* ecma_date_daylight_saving_ta */ /** * Helper function to get local time from UTC. * - * Caller must guarantee that the argument is not NaN. - * * See also: * ECMA-262 v5, 15.9.1.9 * @@ -423,15 +446,17 @@ ecma_date_daylight_saving_ta (ecma_number_t __attr_unused___ time) /**< time val ecma_number_t __attr_always_inline___ ecma_date_local_time (ecma_number_t time) /**< time value */ { - JERRY_ASSERT (!ecma_number_is_nan (time)); + if (ecma_number_is_nan (time)) + { + return time; /* time is NaN */ + } + return time + ecma_date_local_tza () + ecma_date_daylight_saving_ta (time); } /* ecma_date_local_time */ /** * Helper function to get utc from local time. * - * Caller must guarantee that the argument is not NaN. - * * See also: * ECMA-262 v5, 15.9.1.9 * @@ -440,7 +465,10 @@ ecma_date_local_time (ecma_number_t time) /**< time value */ ecma_number_t __attr_always_inline___ ecma_date_utc (ecma_number_t time) /**< time value */ { - JERRY_ASSERT (!ecma_number_is_nan (time)); + if (ecma_number_is_nan (time)) + { + return time; /* time is NaN */ + } ecma_number_t simple_utc_time = time - ecma_date_local_tza (); return simple_utc_time - ecma_date_daylight_saving_ta (simple_utc_time); @@ -449,8 +477,6 @@ ecma_date_utc (ecma_number_t time) /**< time value */ /** * Helper function to get hour from time value. * - * Caller must guarantee that the argument is not NaN. - * * See also: * ECMA-262 v5, 15.9.1.10 * @@ -459,7 +485,11 @@ ecma_date_utc (ecma_number_t time) /**< time value */ ecma_number_t __attr_always_inline___ ecma_date_hour_from_time (ecma_number_t time) /**< time value */ { - JERRY_ASSERT (!ecma_number_is_nan (time)); + if (ecma_number_is_nan (time)) + { + return time; /* time is NaN */ + } + return (ecma_number_t) fmod (floor (time / ECMA_DATE_MS_PER_HOUR), ECMA_DATE_HOURS_PER_DAY); } /* ecma_date_hour_from_time */ @@ -467,8 +497,6 @@ ecma_date_hour_from_time (ecma_number_t time) /**< time value */ /** * Helper function to get minute from time value. * - * Caller must guarantee that the argument is not NaN. - * * See also: * ECMA-262 v5, 15.9.1.10 * @@ -477,7 +505,11 @@ ecma_date_hour_from_time (ecma_number_t time) /**< time value */ ecma_number_t __attr_always_inline___ ecma_date_min_from_time (ecma_number_t time) /**< time value */ { - JERRY_ASSERT (!ecma_number_is_nan (time)); + if (ecma_number_is_nan (time)) + { + return time; /* time is NaN */ + } + return (ecma_number_t) fmod (floor (time / ECMA_DATE_MS_PER_MINUTE), ECMA_DATE_MINUTES_PER_HOUR); } /* ecma_date_min_from_time */ @@ -485,8 +517,6 @@ ecma_date_min_from_time (ecma_number_t time) /**< time value */ /** * Helper function to get second from time value. * - * Caller must guarantee that the argument is not NaN. - * * See also: * ECMA-262 v5, 15.9.1.10 * @@ -495,7 +525,11 @@ ecma_date_min_from_time (ecma_number_t time) /**< time value */ ecma_number_t __attr_always_inline___ ecma_date_sec_from_time (ecma_number_t time) /**< time value */ { - JERRY_ASSERT (!ecma_number_is_nan (time)); + if (ecma_number_is_nan (time)) + { + return time; /* time is NaN */ + } + return (ecma_number_t) fmod (floor (time / ECMA_DATE_MS_PER_SECOND), ECMA_DATE_SECONDS_PER_MINUTE); } /* ecma_date_sec_from_time */ @@ -503,8 +537,6 @@ ecma_date_sec_from_time (ecma_number_t time) /**< time value */ /** * Helper function to get millisecond from time value. * - * Caller must guarantee that the argument is not NaN. - * * See also: * ECMA-262 v5, 15.9.1.10 * @@ -513,15 +545,17 @@ ecma_date_sec_from_time (ecma_number_t time) /**< time value */ ecma_number_t __attr_always_inline___ ecma_date_ms_from_time (ecma_number_t time) /**< time value */ { - JERRY_ASSERT (!ecma_number_is_nan (time)); + if (ecma_number_is_nan (time)) + { + return time; /* time is NaN */ + } + return (ecma_number_t) fmod (time, ECMA_DATE_MS_PER_SECOND); } /* ecma_date_ms_from_time */ /** * Helper function to make time value from hour, min, sec and ms. * - * Caller must guarantee that the arguments are not NaN. - * * See also: * ECMA-262 v5, 15.9.1.11 * @@ -533,12 +567,11 @@ ecma_date_make_time (ecma_number_t hour, /**< hour value */ ecma_number_t sec, /**< second value */ ecma_number_t ms) /**< millisecond value */ { - JERRY_ASSERT (!ecma_number_is_nan (hour) - && !ecma_number_is_nan (min) - && !ecma_number_is_nan (sec) - && !ecma_number_is_nan (ms)); - - if (ecma_number_is_infinity (hour) + if (ecma_number_is_nan (hour) + || ecma_number_is_nan (min) + || ecma_number_is_nan (sec) + || ecma_number_is_nan (ms) + || ecma_number_is_infinity (hour) || ecma_number_is_infinity (min) || ecma_number_is_infinity (sec) || ecma_number_is_infinity (ms)) @@ -561,8 +594,6 @@ ecma_date_make_time (ecma_number_t hour, /**< hour value */ /** * Helper function to make day value from year, month and date. * - * Caller must guarantee that the arguments are not NaN. - * * See also: * ECMA-262 v5, 15.9.1.12 * @@ -573,11 +604,10 @@ ecma_date_make_day (ecma_number_t year, /**< year value */ ecma_number_t month, /**< month value */ ecma_number_t date) /**< date value */ { - JERRY_ASSERT (!ecma_number_is_nan (year) - && !ecma_number_is_nan (month) - && !ecma_number_is_nan (date)); - - if (ecma_number_is_infinity (year) + if (ecma_number_is_nan (year) + || ecma_number_is_nan (month) + || ecma_number_is_nan (date) + || ecma_number_is_infinity (year) || ecma_number_is_infinity (month) || ecma_number_is_infinity (date)) { @@ -601,14 +631,12 @@ ecma_date_make_day (ecma_number_t year, /**< year value */ JERRY_ASSERT (ecma_date_month_from_time (time) == mn); JERRY_ASSERT (ecma_date_date_from_time (time) == 1); - return (ecma_number_t) ecma_date_day (time) + dt - ((ecma_number_t) 1.0); + return ecma_date_day (time) + dt - ((ecma_number_t) 1.0); } /* ecma_date_make_day */ /** * Helper function to make date value from day and time. * - * Caller must guarantee that the arguments are not NaN. - * * See also: * ECMA-262 v5, 15.9.1.13 * @@ -618,10 +646,9 @@ ecma_number_t __attr_always_inline___ ecma_date_make_date (ecma_number_t day, /**< day value */ ecma_number_t time) /**< time value */ { - JERRY_ASSERT (!ecma_number_is_nan (day) - && !ecma_number_is_nan (time)); - - if (ecma_number_is_infinity (day) + if (ecma_number_is_nan (day) + || ecma_number_is_nan (time) + || ecma_number_is_infinity (day) || ecma_number_is_infinity (time)) { return ecma_number_make_nan (); @@ -633,8 +660,6 @@ ecma_date_make_date (ecma_number_t day, /**< day value */ /** * Helper function to calculate number of milliseconds from time value. * - * Caller must guarantee that the argument is not NaN. - * * See also: * ECMA-262 v5, 15.9.1.14 * @@ -643,9 +668,8 @@ ecma_date_make_date (ecma_number_t day, /**< day value */ ecma_number_t __attr_always_inline___ ecma_date_time_clip (ecma_number_t time) /**< time value */ { - JERRY_ASSERT (!ecma_number_is_nan (time)); - - if (ecma_number_is_infinity (time) + if (ecma_number_is_nan (time) + || ecma_number_is_infinity (time) || fabs (time) > ECMA_DATE_MAX_VALUE) { return ecma_number_make_nan (); diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h index d139d88a5..ba8423762 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h @@ -34,17 +34,17 @@ extern uint32_t ecma_builtin_helper_array_index_normalize (ecma_number_t index, #ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_DATE_BUILTIN /* ecma-builtin-helpers-date.cpp */ -extern int ecma_date_day (ecma_number_t time); +extern ecma_number_t ecma_date_day (ecma_number_t time); extern ecma_number_t ecma_date_time_within_day (ecma_number_t time); -extern int ecma_date_days_in_year (ecma_number_t year); -extern int ecma_date_day_from_year (ecma_number_t year); +extern ecma_number_t ecma_date_days_in_year (ecma_number_t year); +extern ecma_number_t ecma_date_day_from_year (ecma_number_t year); extern ecma_number_t ecma_date_time_from_year (ecma_number_t year); -extern int ecma_date_year_from_time (ecma_number_t time); -extern int ecma_date_in_leap_year (ecma_number_t time); -extern int ecma_date_day_within_year (ecma_number_t time); -extern int ecma_date_month_from_time (ecma_number_t time); -extern int ecma_date_date_from_time (ecma_number_t time); -extern int ecma_date_week_day (ecma_number_t time); +extern ecma_number_t ecma_date_year_from_time (ecma_number_t time); +extern ecma_number_t ecma_date_in_leap_year (ecma_number_t time); +extern ecma_number_t ecma_date_day_within_year (ecma_number_t time); +extern ecma_number_t ecma_date_month_from_time (ecma_number_t time); +extern ecma_number_t ecma_date_date_from_time (ecma_number_t time); +extern ecma_number_t ecma_date_week_day (ecma_number_t time); extern ecma_number_t ecma_date_local_tza (); extern ecma_number_t ecma_date_daylight_saving_ta (ecma_number_t time); extern ecma_number_t ecma_date_local_time (ecma_number_t time);