From 6a983e8dd905cef0570b614eacc69c01da1825ac Mon Sep 17 00:00:00 2001 From: Szilard Ledan Date: Wed, 17 Jun 2015 10:43:32 +0200 Subject: [PATCH 1/5] Implement Date object helper functions JerryScript-DCO-1.0-Signed-off-by: Szilard Ledan szledan.u-szeged@partner.samsung.com --- jerry-core/ecma/base/ecma-helpers-date.cpp | 502 +++++++++++++++++++++ jerry-core/ecma/base/ecma-helpers.h | 30 ++ tests/unit/test-date-helpers.cpp | 137 ++++++ 3 files changed, 669 insertions(+) create mode 100644 jerry-core/ecma/base/ecma-helpers-date.cpp create mode 100644 tests/unit/test-date-helpers.cpp diff --git a/jerry-core/ecma/base/ecma-helpers-date.cpp b/jerry-core/ecma/base/ecma-helpers-date.cpp new file mode 100644 index 0000000000..408578ab4e --- /dev/null +++ b/jerry-core/ecma/base/ecma-helpers-date.cpp @@ -0,0 +1,502 @@ +/* Copyright 2015 Samsung Electronics Co., Ltd. + * Copyright 2015 University of Szeged. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ecma-globals.h" +#include "ecma-helpers.h" +#include "fdlibm-math.h" + +#ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_DATE_BUILTIN + +/** \addtogroup ecma ECMA + * @{ + * + * \addtogroup ecmahelpers Helpers for operations with ECMA data types + * @{ + */ + +/* 24 * 3600 * 1000 */ +#define ECMA_MS_PER_DAY 86400000 + +/** + * Helper function to get day number from time value. + * + * See also: + * ECMA-262 v5, 15.9.1.2 + * + * @return time value for day number + */ +int __attr_always_inline___ +ecma_date_day (ecma_number_t time) /**< time value */ +{ + return (int) floor (time / ECMA_MS_PER_DAY); +} /* ecma_date_day */ + +/** + * Helper function to get time within day from time value. + * + * See also: + * ECMA-262 v5, 15.9.1.2 + * + * @return time value within the day + */ +ecma_number_t __attr_always_inline___ +ecma_date_time_within_day (ecma_number_t time) /**< time value */ +{ + return (ecma_number_t) fmod (time, ECMA_MS_PER_DAY); +} /* ecma_date_time_within_day */ + +/** + * Helper function to get number of days from year value. + * + * See also: + * ECMA-262 v5, 15.9.1.3 + * + * @return number of days + */ +int __attr_always_inline___ +ecma_date_days_in_year (ecma_number_t year) /**< year value */ +{ + if (fmod (floor (year), 4)) + { + return 365; + } + + if (fmod (floor (year), 100)) + { + return 366; + } + + if (fmod (floor (year), 400)) + { + return 365; + } + + return 366; +} /* ecma_date_days_in_year */ + +/** + * Helper function to get the day number of the first day of a year. + * + * See also: + * ECMA-262 v5, 15.9.1.3 + * + * @return day number of the first day of a year + */ +int __attr_always_inline___ +ecma_date_day_from_year (ecma_number_t year) /**< year value */ +{ + return (int) (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. + * + * See also: + * ECMA-262 v5, 15.9.1.3 + * + * @return time value of the start of a year + */ +ecma_number_t __attr_always_inline___ +ecma_date_time_from_year (ecma_number_t year) /**< year value */ +{ + return ECMA_MS_PER_DAY * (ecma_number_t) ecma_date_day_from_year (year); +} /* ecma_date_time_from_year */ + +/** + * Helper function to determine a year value from the time value. + * + * See also: + * ECMA-262 v5, 15.9.1.3 + * + * @return year value + */ +int +ecma_date_year_from_time (ecma_number_t time) /**< time value */ +{ + /* 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; + + while (ecma_date_time_from_year ((ecma_number_t) year) > time) + { + if (ecma_date_time_from_year ((ecma_number_t) (year / 2)) > time) + { + year = year / 2; + } + year--; + } + + return year; +} /* ecma_date_year_from_time */ + +/** + * Helper function to decide if time value is in a leap-year. + * + * 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_date_in_leap_year (ecma_number_t time) /**< time value */ +{ + 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. + * + * See also: + * ECMA-262 v5, 15.9.1.4 + * + * @return number of days within year + */ +int __attr_always_inline___ +ecma_date_day_within_year (ecma_number_t time) /**< time value */ +{ + return ecma_date_day (time) - ecma_date_day_from_year ((ecma_number_t) ecma_date_year_from_time (time)); +} /* ecma_date_day_within_year */ + +/** + * Helper function to get month from time value. + * + * See also: + * ECMA-262 v5, 15.9.1.4 + * + * @return month number + */ +int +ecma_date_month_from_time (ecma_number_t time) /**< time value */ +{ + int in_leap_year = ecma_date_in_leap_year (time); + int day_within_year = ecma_date_day_within_year (time); + + JERRY_ASSERT (day_within_year >= 0 && day_within_year < 365 + in_leap_year); + + if (day_within_year < 31) + { + return 0; + } + else if (day_within_year < 59 + in_leap_year) + { + return 1; + } + else if (day_within_year < 90 + in_leap_year) + { + return 2; + } + else if (day_within_year < 120 + in_leap_year) + { + return 3; + } + else if (day_within_year < 151 + in_leap_year) + { + return 4; + } + else if (day_within_year < 181 + in_leap_year) + { + return 5; + } + else if (day_within_year < 212 + in_leap_year) + { + return 6; + } + else if (day_within_year < 243 + in_leap_year) + { + return 7; + } + else if (day_within_year < 273 + in_leap_year) + { + return 8; + } + else if (day_within_year < 304 + in_leap_year) + { + return 9; + } + else if (day_within_year < 334 + in_leap_year) + { + return 10; + } + + return 11; +} /* ecma_date_month_from_time */ + +/** + * Helper function to get date number from time value. + * + * See also: + * ECMA-262 v5, 15.9.1.5 + * + * @return date number + */ +int +ecma_date_date_from_time (ecma_number_t time) /**< time value */ +{ + int in_leap_year = ecma_date_in_leap_year (time); + int day_within_year = ecma_date_day_within_year (time); + + switch (ecma_date_month_from_time (time)) + { + case 0: + { + return day_within_year + 1; + } + case 1: + { + return day_within_year - 30 ; + } + case 2: + { + return day_within_year - 58 - in_leap_year; + } + case 3: + { + return day_within_year - 89 - in_leap_year; + } + case 4: + { + return day_within_year - 119 - in_leap_year; + } + case 5: + { + return day_within_year - 150 - in_leap_year; + } + case 6: + { + return day_within_year - 180 - in_leap_year; + } + case 7: + { + return day_within_year - 211 - in_leap_year; + } + case 8: + { + return day_within_year - 242 - in_leap_year; + } + case 9: + { + return day_within_year - 272 - in_leap_year; + } + case 10: + { + return day_within_year - 303 - in_leap_year; + } + case 11: + { + return day_within_year - 333 - in_leap_year; + } + } + + JERRY_UNREACHABLE (); + return 0; +} /* ecma_date_date_from_time */ + +/** + * Helper function to get weekday from time value. + * + * See also: + * ECMA-262 v5, 15.9.1.6 + * + * @return weekday number + */ +int __attr_always_inline___ +ecma_date_week_day (ecma_number_t time) /**< time value */ +{ + return (ecma_date_day (time) + 4) % 7; +} /* ecma_date_week_day */ + +/** + * Helper function to get local time zone adjustment. + * + * See also: + * ECMA-262 v5, 15.9.1.7 + * + * @return local time zone adjustment + */ +ecma_number_t __attr_always_inline___ +ecma_date_local_tza () +{ + JERRY_UNIMPLEMENTED ("The ecma_date_local_tza is not implemented yet."); +} /* ecma_date_local_tza */ + +/** + * Helper function to get the daylight saving time adjustment. + * + * 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) +{ + JERRY_UNIMPLEMENTED ("The ecma_date_daylight_saving_ta is not implemented yet."); +} /* ecma_date_daylight_saving_ta */ + +/** + * Helper function to get local time from UTC. + * + * See also: + * ECMA-262 v5, 15.9.1.9 + * + * @return local time + */ +ecma_number_t __attr_always_inline___ +ecma_date_local_time (ecma_number_t __attr_unused___ time) +{ + JERRY_UNIMPLEMENTED ("The ecma_date_local_time is not implemented yet."); +} /* ecma_date_local_time */ + +/** + * Helper function to get utc from local time. + * + * See also: + * ECMA-262 v5, 15.9.1.9 + * + * @return utc value + */ +ecma_number_t __attr_always_inline___ +ecma_date_utc (ecma_number_t __attr_unused___ time) +{ + JERRY_UNIMPLEMENTED ("The ecma_date_utc is not implemented yet."); +} /* ecma_date_utc */ + +/** + * Helper function to get hour from time value. + * + * See also: + * ECMA-262 v5, 15.9.1.10 + * + * @return hour value + */ +ecma_number_t __attr_always_inline___ +ecma_date_hour_from_time (ecma_number_t __attr_unused___ time) +{ + JERRY_UNIMPLEMENTED ("The ecma_date_hour_from_time is not implemented yet."); +} /* ecma_date_hour_from_time */ + +/** + * Helper function to get minute from time value. + * + * See also: + * ECMA-262 v5, 15.9.1.10 + * + * @return minute value + */ +ecma_number_t __attr_always_inline___ +ecma_date_min_from_time (ecma_number_t __attr_unused___ time) +{ + JERRY_UNIMPLEMENTED ("The ecma_date_min_from_time is not implemented yet."); +} /* ecma_date_min_from_time */ + +/** + * Helper function to get second from time value. + * + * See also: + * ECMA-262 v5, 15.9.1.10 + * + * @return second value + */ +ecma_number_t __attr_always_inline___ +ecma_date_sec_from_time (ecma_number_t __attr_unused___ time) +{ + JERRY_UNIMPLEMENTED ("The ecma_date_sec_from_time is not implemented yet."); +} /* ecma_date_sec_from_time */ + +/** + * Helper function to get millisecond from time value. + * + * See also: + * ECMA-262 v5, 15.9.1.10 + * + * @return millisecond value + */ +ecma_number_t __attr_always_inline___ +ecma_date_ms_from_time (ecma_number_t __attr_unused___ time) +{ + JERRY_UNIMPLEMENTED ("The ecma_date_ms_from_time is not implemented yet."); +} /* ecma_date_ms_from_time */ + +/** + * Helper function to make time value from hour, min, sec and ms. + * + * See also: + * ECMA-262 v5, 15.9.1.11 + * + * @return time value + */ +ecma_number_t __attr_always_inline___ +ecma_date_make_time (ecma_number_t __attr_unused___ hour, + ecma_number_t __attr_unused___ min, + ecma_number_t __attr_unused___ sec, + ecma_number_t __attr_unused___ ms) +{ + JERRY_UNIMPLEMENTED ("The ecma_date_make_time is not implemented yet."); +} /* ecma_date_make_time */ + +/** + * Helper function to make day value from year, month and date. + * + * See also: + * ECMA-262 v5, 15.9.1.12 + * + * @return day value + */ +ecma_number_t __attr_always_inline___ +ecma_date_make_day (ecma_number_t __attr_unused___ year, + ecma_number_t __attr_unused___ month, + ecma_number_t __attr_unused___ date) +{ + JERRY_UNIMPLEMENTED ("The ecma_date_make_day is not implemented yet."); +} /* ecma_date_make_day */ + +/** + * Helper function to make date value from day and time. + * + * See also: + * ECMA-262 v5, 15.9.1.13 + * + * @return date value + */ +ecma_number_t __attr_always_inline___ +ecma_date_make_date (ecma_number_t __attr_unused___ day, ecma_number_t __attr_unused___ time) +{ + JERRY_UNIMPLEMENTED ("The ecma_date_make_date is not implemented yet."); +} /* ecma_date_make_date */ + +/** + * Helper function to calculate number of milliseconds from time value. + * + * See also: + * ECMA-262 v5, 15.9.1.14 + * + * @return number of milliseconds + */ +ecma_number_t __attr_always_inline___ +ecma_date_time_clip (ecma_number_t __attr_unused___ year) +{ + JERRY_UNIMPLEMENTED ("The ecma_date_time_clip is not implemented yet."); +} /* ecma_date_time_clip */ + +/** + * @} + * @} + */ + +#endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_DATE_BUILTIN */ diff --git a/jerry-core/ecma/base/ecma-helpers.h b/jerry-core/ecma/base/ecma-helpers.h index 25c289e7de..0175ea146a 100644 --- a/jerry-core/ecma/base/ecma-helpers.h +++ b/jerry-core/ecma/base/ecma-helpers.h @@ -328,6 +328,36 @@ extern ecma_number_t ecma_int32_to_number (int32_t value); extern ecma_number_t ecma_uint32_to_number (uint32_t value); extern ecma_length_t ecma_number_to_zt_string (ecma_number_t num, ecma_char_t *buffer_p, ssize_t buffer_size); +/* ecma-helpers-date.cpp */ +extern int 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_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_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); +extern ecma_number_t ecma_date_utc (ecma_number_t time); +extern ecma_number_t ecma_date_hour_from_time (ecma_number_t time); +extern ecma_number_t ecma_date_min_from_time (ecma_number_t time); +extern ecma_number_t ecma_date_sec_from_time (ecma_number_t time); +extern ecma_number_t ecma_date_ms_from_time (ecma_number_t time); +extern ecma_number_t ecma_date_make_time (ecma_number_t hour, + ecma_number_t min, + ecma_number_t sec, + ecma_number_t ms); +extern ecma_number_t ecma_date_make_day (ecma_number_t year, + ecma_number_t month, + ecma_number_t date); +extern ecma_number_t ecma_date_make_date (ecma_number_t day, ecma_number_t time); +extern ecma_number_t ecma_date_time_clip (ecma_number_t year); + /* ecma-helpers-char.cpp */ extern bool ecma_char_is_new_line (ecma_char_t c); extern bool ecma_char_is_carriage_return (ecma_char_t c); diff --git a/tests/unit/test-date-helpers.cpp b/tests/unit/test-date-helpers.cpp new file mode 100644 index 0000000000..bfca27ac3d --- /dev/null +++ b/tests/unit/test-date-helpers.cpp @@ -0,0 +1,137 @@ +/* Copyright 2015 Samsung Electronics Co., Ltd. + * Copyright 2015 University of Szeged. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ecma-globals.h" +#include "ecma-helpers.h" + +/** + * 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 (86400000.000000000000000000001) == 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 (86400000 + 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); + + /* ecma_number_t ecma_date_time_from_year (year) */ + + /* FIXME: Implement */ + + /* int ecma_date_year_from_time (time) */ + + /* FIXME: Implement */ + + /* int ecma_date_in_leap_year (time) */ + + /* FIXME: Implement */ + + /* 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) */ + + /* FIXME: Implement */ + + /* ecma_number_t ecma_date_make_date (day, time) */ + + /* FIXME: Implement */ + + /* ecma_number_t ecma_date_time_clip (year) */ + + /* FIXME: Implement */ + + return 0; +} /* main */ From 55c8704a24a901fe4411bdf28dfc8ede804585b2 Mon Sep 17 00:00:00 2001 From: Szilard Ledan Date: Wed, 17 Jun 2015 15:44:58 +0200 Subject: [PATCH 2/5] Implement missing functions in ecma-helpers-date.cpp JerryScript-DCO-1.0-Signed-off-by: Szilard Ledan szledan.u-szeged@partner.samsung.com --- jerry-core/ecma/base/ecma-helpers-date.cpp | 127 ++++++++++++++++----- jerry-core/ecma/base/ecma-helpers.h | 2 +- tests/unit/test-date-helpers.cpp | 7 +- 3 files changed, 104 insertions(+), 32 deletions(-) diff --git a/jerry-core/ecma/base/ecma-helpers-date.cpp b/jerry-core/ecma/base/ecma-helpers-date.cpp index 408578ab4e..e187b0038a 100644 --- a/jerry-core/ecma/base/ecma-helpers-date.cpp +++ b/jerry-core/ecma/base/ecma-helpers-date.cpp @@ -27,8 +27,17 @@ * @{ */ -/* 24 * 3600 * 1000 */ -#define ECMA_MS_PER_DAY 86400000 +#define ECMA_DATE_HOURS_PER_DAY 24 +#define ECMA_DATE_MINUTES_PER_HOUR 60 +#define ECMA_DATE_SECONDS_PER_MINUTE 60 +#define ECMA_DATE_MS_PER_SECOND 1000 +/* ECMA_DATE_MS_PER_MINUTE == 60000 */ +#define ECMA_DATE_MS_PER_MINUTE (ECMA_DATE_MS_PER_SECOND * ECMA_DATE_SECONDS_PER_MINUTE) +/* ECMA_DATE_MS_PER_HOUR == 3600000 */ +#define ECMA_DATE_MS_PER_HOUR (ECMA_DATE_MS_PER_MINUTE * ECMA_DATE_MINUTES_PER_HOUR) +/* ECMA_DATE_MS_PER_DAY == 86400000 */ +#define ECMA_DATE_MS_PER_DAY (ECMA_DATE_MS_PER_HOUR * ECMA_DATE_HOURS_PER_DAY) +#define ECMA_DATE_MAX_VALUE 8.64e15 /** * Helper function to get day number from time value. @@ -41,7 +50,7 @@ int __attr_always_inline___ ecma_date_day (ecma_number_t time) /**< time value */ { - return (int) floor (time / ECMA_MS_PER_DAY); + return (int) floor (time / ECMA_DATE_MS_PER_DAY); } /* ecma_date_day */ /** @@ -55,7 +64,7 @@ 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 */ { - return (ecma_number_t) fmod (time, ECMA_MS_PER_DAY); + return (ecma_number_t) fmod (time, ECMA_DATE_MS_PER_DAY); } /* ecma_date_time_within_day */ /** @@ -115,7 +124,7 @@ 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 */ { - return ECMA_MS_PER_DAY * (ecma_number_t) ecma_date_day_from_year (year); + return ECMA_DATE_MS_PER_DAY * (ecma_number_t) ecma_date_day_from_year (year); } /* ecma_date_time_from_year */ /** @@ -358,9 +367,9 @@ ecma_date_daylight_saving_ta (ecma_number_t __attr_unused___ time) * @return local time */ ecma_number_t __attr_always_inline___ -ecma_date_local_time (ecma_number_t __attr_unused___ time) +ecma_date_local_time (ecma_number_t time) { - JERRY_UNIMPLEMENTED ("The ecma_date_local_time is not implemented yet."); + return time + ecma_date_local_tza () + ecma_date_daylight_saving_ta (time); } /* ecma_date_local_time */ /** @@ -372,9 +381,10 @@ ecma_date_local_time (ecma_number_t __attr_unused___ time) * @return utc value */ ecma_number_t __attr_always_inline___ -ecma_date_utc (ecma_number_t __attr_unused___ time) +ecma_date_utc (ecma_number_t time) { - JERRY_UNIMPLEMENTED ("The ecma_date_utc is not implemented yet."); + ecma_number_t simple_utc_time = time - ecma_date_local_tza (); + return simple_utc_time - ecma_date_daylight_saving_ta (simple_utc_time); } /* ecma_date_utc */ /** @@ -386,9 +396,10 @@ ecma_date_utc (ecma_number_t __attr_unused___ time) * @return hour value */ ecma_number_t __attr_always_inline___ -ecma_date_hour_from_time (ecma_number_t __attr_unused___ time) +ecma_date_hour_from_time (ecma_number_t time) { - JERRY_UNIMPLEMENTED ("The ecma_date_hour_from_time is not implemented yet."); + return (ecma_number_t) fmod (floor (time / ECMA_DATE_MS_PER_HOUR), + ECMA_DATE_HOURS_PER_DAY); } /* ecma_date_hour_from_time */ /** @@ -400,9 +411,10 @@ ecma_date_hour_from_time (ecma_number_t __attr_unused___ time) * @return minute value */ ecma_number_t __attr_always_inline___ -ecma_date_min_from_time (ecma_number_t __attr_unused___ time) +ecma_date_min_from_time (ecma_number_t time) { - JERRY_UNIMPLEMENTED ("The ecma_date_min_from_time is not implemented yet."); + return (ecma_number_t) fmod (floor (time / ECMA_DATE_MS_PER_MINUTE), + ECMA_DATE_MINUTES_PER_HOUR); } /* ecma_date_min_from_time */ /** @@ -414,9 +426,10 @@ ecma_date_min_from_time (ecma_number_t __attr_unused___ time) * @return second value */ ecma_number_t __attr_always_inline___ -ecma_date_sec_from_time (ecma_number_t __attr_unused___ time) +ecma_date_sec_from_time (ecma_number_t time) { - JERRY_UNIMPLEMENTED ("The ecma_date_sec_from_time is not implemented yet."); + return (ecma_number_t) fmod (floor (time / ECMA_DATE_MS_PER_SECOND), + ECMA_DATE_SECONDS_PER_MINUTE); } /* ecma_date_sec_from_time */ /** @@ -428,9 +441,9 @@ ecma_date_sec_from_time (ecma_number_t __attr_unused___ time) * @return millisecond value */ ecma_number_t __attr_always_inline___ -ecma_date_ms_from_time (ecma_number_t __attr_unused___ time) +ecma_date_ms_from_time (ecma_number_t time) { - JERRY_UNIMPLEMENTED ("The ecma_date_ms_from_time is not implemented yet."); + return (ecma_number_t) fmod (time, ECMA_DATE_MS_PER_SECOND); } /* ecma_date_ms_from_time */ /** @@ -442,12 +455,30 @@ ecma_date_ms_from_time (ecma_number_t __attr_unused___ time) * @return time value */ ecma_number_t __attr_always_inline___ -ecma_date_make_time (ecma_number_t __attr_unused___ hour, - ecma_number_t __attr_unused___ min, - ecma_number_t __attr_unused___ sec, - ecma_number_t __attr_unused___ ms) +ecma_date_make_time (ecma_number_t hour, + ecma_number_t min, + ecma_number_t sec, + ecma_number_t ms) { - JERRY_UNIMPLEMENTED ("The ecma_date_make_time is not implemented yet."); + if (ecma_number_is_nan (hour) || ecma_number_is_infinity (hour) + || ecma_number_is_nan (min) || ecma_number_is_infinity (min) + || ecma_number_is_nan (sec) || ecma_number_is_infinity (sec) + || ecma_number_is_nan (ms) || ecma_number_is_infinity (ms)) + { + return ecma_number_make_nan (); + } + + ecma_number_t h = ecma_number_trunc (hour); + ecma_number_t m = ecma_number_trunc (min); + ecma_number_t s = ecma_number_trunc (sec); + ecma_number_t milli = ecma_number_trunc (ms); + + /* FIXME: performing the arithmetic according to IEEE 754 rules + * (that is, as if using the ECMAScript operators * and +) */ + return (h * ECMA_DATE_MS_PER_HOUR + + m * ECMA_DATE_MS_PER_MINUTE + + s * ECMA_DATE_MS_PER_SECOND + + milli); } /* ecma_date_make_time */ /** @@ -459,11 +490,35 @@ ecma_date_make_time (ecma_number_t __attr_unused___ hour, * @return day value */ ecma_number_t __attr_always_inline___ -ecma_date_make_day (ecma_number_t __attr_unused___ year, - ecma_number_t __attr_unused___ month, - ecma_number_t __attr_unused___ date) +ecma_date_make_day (ecma_number_t year, + ecma_number_t month, + ecma_number_t date) { - JERRY_UNIMPLEMENTED ("The ecma_date_make_day is not implemented yet."); + if (ecma_number_is_nan (year) || ecma_number_is_infinity (year) + || ecma_number_is_nan (month) || ecma_number_is_infinity (month) + || ecma_number_is_nan (date) || ecma_number_is_infinity (date)) + { + return ecma_number_make_nan (); + } + + ecma_number_t y = ecma_number_trunc (year); + ecma_number_t m = ecma_number_trunc (month); + ecma_number_t dt = ecma_number_trunc (date); + ecma_number_t ym = y + (ecma_number_t) floor (m / 12); + ecma_number_t mn = (ecma_number_t) fmod (m, 12); + ecma_number_t time = ecma_date_time_from_year (ym); + + JERRY_ASSERT (ecma_date_year_from_time (time) == ym); + + while (ecma_date_month_from_time (time) < mn) + { + time += ECMA_DATE_MS_PER_DAY; + } + + JERRY_ASSERT ((ecma_date_month_from_time (time) == mn) + && (ecma_date_date_from_time (time) == 1)); + + return (ecma_number_t) ecma_date_day (time) + dt - ((ecma_number_t) 1.0); } /* ecma_date_make_day */ /** @@ -475,9 +530,15 @@ ecma_date_make_day (ecma_number_t __attr_unused___ year, * @return date value */ ecma_number_t __attr_always_inline___ -ecma_date_make_date (ecma_number_t __attr_unused___ day, ecma_number_t __attr_unused___ time) +ecma_date_make_date (ecma_number_t day, ecma_number_t time) { - JERRY_UNIMPLEMENTED ("The ecma_date_make_date is not implemented yet."); + if (ecma_number_is_nan (day) || ecma_number_is_infinity (day) + || ecma_number_is_nan (time) || ecma_number_is_infinity (time)) + { + return ecma_number_make_nan (); + } + + return day * ECMA_DATE_MS_PER_DAY + time; } /* ecma_date_make_date */ /** @@ -489,9 +550,15 @@ ecma_date_make_date (ecma_number_t __attr_unused___ day, ecma_number_t __attr_un * @return number of milliseconds */ ecma_number_t __attr_always_inline___ -ecma_date_time_clip (ecma_number_t __attr_unused___ year) +ecma_date_time_clip (ecma_number_t time) { - JERRY_UNIMPLEMENTED ("The ecma_date_time_clip is not implemented yet."); + if (ecma_number_is_nan (time) || ecma_number_is_infinity (time) + || fabs (time) > ECMA_DATE_MAX_VALUE) + { + return ecma_number_make_nan (); + } + + return ecma_number_trunc (time); } /* ecma_date_time_clip */ /** diff --git a/jerry-core/ecma/base/ecma-helpers.h b/jerry-core/ecma/base/ecma-helpers.h index 0175ea146a..51cdd5c4cf 100644 --- a/jerry-core/ecma/base/ecma-helpers.h +++ b/jerry-core/ecma/base/ecma-helpers.h @@ -356,7 +356,7 @@ extern ecma_number_t ecma_date_make_day (ecma_number_t year, ecma_number_t month, ecma_number_t date); extern ecma_number_t ecma_date_make_date (ecma_number_t day, ecma_number_t time); -extern ecma_number_t ecma_date_time_clip (ecma_number_t year); +extern ecma_number_t ecma_date_time_clip (ecma_number_t time); /* ecma-helpers-char.cpp */ extern bool ecma_char_is_new_line (ecma_char_t c); diff --git a/tests/unit/test-date-helpers.cpp b/tests/unit/test-date-helpers.cpp index bfca27ac3d..575463ba00 100644 --- a/tests/unit/test-date-helpers.cpp +++ b/tests/unit/test-date-helpers.cpp @@ -123,7 +123,12 @@ main (int __attr_unused___ argc, /* ecma_number_t ecma_date_make_day (year, month, date) */ - /* FIXME: Implement */ + 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); + /* FIXME: More testcase */ /* ecma_number_t ecma_date_make_date (day, time) */ From d9b5f5f0348f5bc4ca654983dda5eff9a2580d5b Mon Sep 17 00:00:00 2001 From: Szilard Ledan Date: Thu, 18 Jun 2015 18:06:36 +0200 Subject: [PATCH 3/5] Add NaN checking asserts to the Date helper functions JerryScript-DCO-1.0-Signed-off-by: Szilard Ledan szledan.u-szeged@partner.samsung.com --- jerry-core/ecma/base/ecma-helpers-date.cpp | 145 ++++++++++++++++----- tests/unit/test-date-helpers.cpp | 27 ++-- 2 files changed, 127 insertions(+), 45 deletions(-) diff --git a/jerry-core/ecma/base/ecma-helpers-date.cpp b/jerry-core/ecma/base/ecma-helpers-date.cpp index e187b0038a..adad345e0e 100644 --- a/jerry-core/ecma/base/ecma-helpers-date.cpp +++ b/jerry-core/ecma/base/ecma-helpers-date.cpp @@ -42,6 +42,8 @@ /** * 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 * @@ -50,12 +52,15 @@ int __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); } /* 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 * @@ -64,12 +69,15 @@ 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)); 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 * @@ -78,6 +86,7 @@ ecma_date_time_within_day (ecma_number_t time) /**< time value */ int __attr_always_inline___ ecma_date_days_in_year (ecma_number_t year) /**< year value */ { + JERRY_ASSERT (!ecma_number_is_nan (year)); if (fmod (floor (year), 4)) { return 365; @@ -107,6 +116,7 @@ ecma_date_days_in_year (ecma_number_t year) /**< year value */ int __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) @@ -116,6 +126,8 @@ ecma_date_day_from_year (ecma_number_t year) /**< year value */ /** * 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 * @@ -124,12 +136,15 @@ 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); } /* 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 * @@ -138,8 +153,11 @@ ecma_date_time_from_year (ecma_number_t year) /**< year value */ int ecma_date_year_from_time (ecma_number_t time) /**< time value */ { + JERRY_ASSERT (!ecma_number_is_nan (time)); + /* ECMA-262 v5, 15.9.1.1 define the largest year that is - * representable (285616) forward from 01 January, 1970 UTC. */ + * representable (285616) forward from 01 January, 1970 UTC. + */ int year = 285616 + 1970; while (ecma_date_time_from_year ((ecma_number_t) year) > time) @@ -157,6 +175,8 @@ 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 * @@ -165,12 +185,15 @@ ecma_date_year_from_time (ecma_number_t time) /**< time value */ int __attr_always_inline___ ecma_date_in_leap_year (ecma_number_t time) /**< time value */ { + JERRY_ASSERT (!ecma_number_is_nan (time)); 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 * @@ -179,12 +202,15 @@ ecma_date_in_leap_year (ecma_number_t time) /**< time value */ int __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)); } /* 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 * @@ -193,6 +219,8 @@ ecma_date_day_within_year (ecma_number_t time) /**< time value */ int ecma_date_month_from_time (ecma_number_t time) /**< time value */ { + JERRY_ASSERT (!ecma_number_is_nan (time)); + int in_leap_year = ecma_date_in_leap_year (time); int day_within_year = ecma_date_day_within_year (time); @@ -249,6 +277,8 @@ 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 * @@ -257,6 +287,8 @@ ecma_date_month_from_time (ecma_number_t time) /**< time value */ int ecma_date_date_from_time (ecma_number_t time) /**< time value */ { + JERRY_ASSERT (!ecma_number_is_nan (time)); + int in_leap_year = ecma_date_in_leap_year (time); int day_within_year = ecma_date_day_within_year (time); @@ -319,6 +351,8 @@ 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 * @@ -327,6 +361,7 @@ ecma_date_date_from_time (ecma_number_t time) /**< time value */ int __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; } /* ecma_date_week_day */ @@ -347,42 +382,52 @@ 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) +ecma_date_daylight_saving_ta (ecma_number_t __attr_unused___ time) /**< time value */ { + JERRY_ASSERT (!ecma_number_is_nan (time)); JERRY_UNIMPLEMENTED ("The ecma_date_daylight_saving_ta is not implemented yet."); } /* 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 * * @return local time */ ecma_number_t __attr_always_inline___ -ecma_date_local_time (ecma_number_t time) +ecma_date_local_time (ecma_number_t time) /**< time value */ { + JERRY_ASSERT (!ecma_number_is_nan (time)); 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 * * @return utc value */ ecma_number_t __attr_always_inline___ -ecma_date_utc (ecma_number_t time) +ecma_date_utc (ecma_number_t time) /**< time value */ { + JERRY_ASSERT (!ecma_number_is_nan (time)); + ecma_number_t simple_utc_time = time - ecma_date_local_tza (); return simple_utc_time - ecma_date_daylight_saving_ta (simple_utc_time); } /* ecma_date_utc */ @@ -390,14 +435,17 @@ ecma_date_utc (ecma_number_t time) /** * 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 * * @return hour value */ ecma_number_t __attr_always_inline___ -ecma_date_hour_from_time (ecma_number_t time) +ecma_date_hour_from_time (ecma_number_t time) /**< time value */ { + JERRY_ASSERT (!ecma_number_is_nan (time)); return (ecma_number_t) fmod (floor (time / ECMA_DATE_MS_PER_HOUR), ECMA_DATE_HOURS_PER_DAY); } /* ecma_date_hour_from_time */ @@ -405,14 +453,17 @@ ecma_date_hour_from_time (ecma_number_t time) /** * 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 * * @return minute value */ ecma_number_t __attr_always_inline___ -ecma_date_min_from_time (ecma_number_t time) +ecma_date_min_from_time (ecma_number_t time) /**< time value */ { + JERRY_ASSERT (!ecma_number_is_nan (time)); return (ecma_number_t) fmod (floor (time / ECMA_DATE_MS_PER_MINUTE), ECMA_DATE_MINUTES_PER_HOUR); } /* ecma_date_min_from_time */ @@ -420,14 +471,17 @@ ecma_date_min_from_time (ecma_number_t time) /** * 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 * * @return second value */ ecma_number_t __attr_always_inline___ -ecma_date_sec_from_time (ecma_number_t time) +ecma_date_sec_from_time (ecma_number_t time) /**< time value */ { + JERRY_ASSERT (!ecma_number_is_nan (time)); return (ecma_number_t) fmod (floor (time / ECMA_DATE_MS_PER_SECOND), ECMA_DATE_SECONDS_PER_MINUTE); } /* ecma_date_sec_from_time */ @@ -435,46 +489,55 @@ ecma_date_sec_from_time (ecma_number_t time) /** * 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 * * @return millisecond value */ ecma_number_t __attr_always_inline___ -ecma_date_ms_from_time (ecma_number_t time) +ecma_date_ms_from_time (ecma_number_t time) /**< time value */ { + JERRY_ASSERT (!ecma_number_is_nan (time)); 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 * * @return time value */ -ecma_number_t __attr_always_inline___ -ecma_date_make_time (ecma_number_t hour, - ecma_number_t min, - ecma_number_t sec, - ecma_number_t ms) +ecma_number_t +ecma_date_make_time (ecma_number_t hour, /**< hour value */ + ecma_number_t min, /**< minute value */ + ecma_number_t sec, /**< second value */ + ecma_number_t ms) /**< millisecond value */ { - if (ecma_number_is_nan (hour) || ecma_number_is_infinity (hour) - || ecma_number_is_nan (min) || ecma_number_is_infinity (min) - || ecma_number_is_nan (sec) || ecma_number_is_infinity (sec) - || ecma_number_is_nan (ms) || ecma_number_is_infinity (ms)) + 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) + || ecma_number_is_infinity (min) + || ecma_number_is_infinity (sec) + || ecma_number_is_infinity (ms)) { return ecma_number_make_nan (); } + /* Replaced toInteger to ecma_number_trunc because it does the same thing. */ ecma_number_t h = ecma_number_trunc (hour); ecma_number_t m = ecma_number_trunc (min); ecma_number_t s = ecma_number_trunc (sec); ecma_number_t milli = ecma_number_trunc (ms); - /* FIXME: performing the arithmetic according to IEEE 754 rules - * (that is, as if using the ECMAScript operators * and +) */ return (h * ECMA_DATE_MS_PER_HOUR + m * ECMA_DATE_MS_PER_MINUTE + s * ECMA_DATE_MS_PER_SECOND @@ -484,19 +547,25 @@ ecma_date_make_time (ecma_number_t hour, /** * 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 * * @return day value */ -ecma_number_t __attr_always_inline___ -ecma_date_make_day (ecma_number_t year, - ecma_number_t month, - ecma_number_t date) +ecma_number_t +ecma_date_make_day (ecma_number_t year, /**< year value */ + ecma_number_t month, /**< month value */ + ecma_number_t date) /**< date value */ { - if (ecma_number_is_nan (year) || ecma_number_is_infinity (year) - || ecma_number_is_nan (month) || ecma_number_is_infinity (month) - || ecma_number_is_nan (date) || ecma_number_is_infinity (date)) + JERRY_ASSERT (!ecma_number_is_nan (year) + && !ecma_number_is_nan (month) + && !ecma_number_is_nan (date)); + + if (ecma_number_is_infinity (year) + || ecma_number_is_infinity (month) + || ecma_number_is_infinity (date)) { return ecma_number_make_nan (); } @@ -515,8 +584,8 @@ ecma_date_make_day (ecma_number_t year, time += ECMA_DATE_MS_PER_DAY; } - JERRY_ASSERT ((ecma_date_month_from_time (time) == mn) - && (ecma_date_date_from_time (time) == 1)); + 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); } /* ecma_date_make_day */ @@ -524,16 +593,22 @@ ecma_date_make_day (ecma_number_t year, /** * 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 * * @return date value */ ecma_number_t __attr_always_inline___ -ecma_date_make_date (ecma_number_t day, ecma_number_t time) +ecma_date_make_date (ecma_number_t day, /**< day value */ + ecma_number_t time) /**< time value */ { - if (ecma_number_is_nan (day) || ecma_number_is_infinity (day) - || ecma_number_is_nan (time) || ecma_number_is_infinity (time)) + JERRY_ASSERT (!ecma_number_is_nan (day) + && !ecma_number_is_nan (time)); + + if (ecma_number_is_infinity (day) + || ecma_number_is_infinity (time)) { return ecma_number_make_nan (); } @@ -544,15 +619,19 @@ ecma_date_make_date (ecma_number_t day, ecma_number_t time) /** * 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 * * @return number of milliseconds */ ecma_number_t __attr_always_inline___ -ecma_date_time_clip (ecma_number_t time) +ecma_date_time_clip (ecma_number_t time) /**< time value */ { - if (ecma_number_is_nan (time) || ecma_number_is_infinity (time) + JERRY_ASSERT (!ecma_number_is_nan (time)); + + if (ecma_number_is_infinity (time) || fabs (time) > ECMA_DATE_MAX_VALUE) { return ecma_number_make_nan (); diff --git a/tests/unit/test-date-helpers.cpp b/tests/unit/test-date-helpers.cpp index 575463ba00..f778c07fc7 100644 --- a/tests/unit/test-date-helpers.cpp +++ b/tests/unit/test-date-helpers.cpp @@ -17,6 +17,7 @@ #include "ecma-globals.h" #include "ecma-helpers.h" +#define MS_PER_DAY ((ecma_number_t) 86400000) /** * Unit test's main function. */ @@ -27,14 +28,14 @@ main (int __attr_unused___ argc, /* int ecma_date_day (time)*/ JERRY_ASSERT (ecma_date_day (0) == 0); - JERRY_ASSERT (ecma_date_day (86400000.000000000000000000001) == 1); + 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 (86400000 + 42) == 42); + JERRY_ASSERT (ecma_date_time_within_day (MS_PER_DAY + 42) == 42); /* int ecma_date_days_in_year (year) */ @@ -57,17 +58,20 @@ main (int __attr_unused___ argc, JERRY_ASSERT (ecma_date_day_from_year (1971) == 365); JERRY_ASSERT (ecma_date_day_from_year (2000) == 10957); - /* ecma_number_t ecma_date_time_from_year (year) */ - - /* FIXME: Implement */ - /* int ecma_date_year_from_time (time) */ - /* FIXME: Implement */ - - /* int ecma_date_in_leap_year (time) */ - - /* FIXME: Implement */ + 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) */ @@ -128,7 +132,6 @@ main (int __attr_unused___ argc, 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); - /* FIXME: More testcase */ /* ecma_number_t ecma_date_make_date (day, time) */ From 16aa64657b12376371097c6a0c3a600136c834b6 Mon Sep 17 00:00:00 2001 From: Szilard Ledan Date: Fri, 19 Jun 2015 15:32:24 +0200 Subject: [PATCH 4/5] Move helper functions to the builtin section JerryScript-DCO-1.0-Signed-off-by: Szilard Ledan szledan.u-szeged@partner.samsung.com --- jerry-core/ecma/base/ecma-helpers.h | 30 ----------------- .../ecma-builtin-helpers-date.cpp} | 3 +- .../builtin-objects/ecma-builtin-helpers.h | 32 +++++++++++++++++++ tests/unit/test-date-helpers.cpp | 9 ++---- 4 files changed, 37 insertions(+), 37 deletions(-) rename jerry-core/ecma/{base/ecma-helpers-date.cpp => builtin-objects/ecma-builtin-helpers-date.cpp} (99%) diff --git a/jerry-core/ecma/base/ecma-helpers.h b/jerry-core/ecma/base/ecma-helpers.h index 51cdd5c4cf..25c289e7de 100644 --- a/jerry-core/ecma/base/ecma-helpers.h +++ b/jerry-core/ecma/base/ecma-helpers.h @@ -328,36 +328,6 @@ extern ecma_number_t ecma_int32_to_number (int32_t value); extern ecma_number_t ecma_uint32_to_number (uint32_t value); extern ecma_length_t ecma_number_to_zt_string (ecma_number_t num, ecma_char_t *buffer_p, ssize_t buffer_size); -/* ecma-helpers-date.cpp */ -extern int 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_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_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); -extern ecma_number_t ecma_date_utc (ecma_number_t time); -extern ecma_number_t ecma_date_hour_from_time (ecma_number_t time); -extern ecma_number_t ecma_date_min_from_time (ecma_number_t time); -extern ecma_number_t ecma_date_sec_from_time (ecma_number_t time); -extern ecma_number_t ecma_date_ms_from_time (ecma_number_t time); -extern ecma_number_t ecma_date_make_time (ecma_number_t hour, - ecma_number_t min, - ecma_number_t sec, - ecma_number_t ms); -extern ecma_number_t ecma_date_make_day (ecma_number_t year, - ecma_number_t month, - ecma_number_t date); -extern ecma_number_t ecma_date_make_date (ecma_number_t day, ecma_number_t time); -extern ecma_number_t ecma_date_time_clip (ecma_number_t time); - /* ecma-helpers-char.cpp */ extern bool ecma_char_is_new_line (ecma_char_t c); extern bool ecma_char_is_carriage_return (ecma_char_t c); diff --git a/jerry-core/ecma/base/ecma-helpers-date.cpp b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-date.cpp similarity index 99% rename from jerry-core/ecma/base/ecma-helpers-date.cpp rename to jerry-core/ecma/builtin-objects/ecma-builtin-helpers-date.cpp index adad345e0e..90833e3e77 100644 --- a/jerry-core/ecma/base/ecma-helpers-date.cpp +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-date.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ +#include "ecma-builtin-helpers.h" #include "ecma-globals.h" #include "ecma-helpers.h" #include "fdlibm-math.h" @@ -23,7 +24,7 @@ /** \addtogroup ecma ECMA * @{ * - * \addtogroup ecmahelpers Helpers for operations with ECMA data types + * \addtogroup ecmabuiltinhelpers ECMA builtin helper operations * @{ */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h index 39a6b97285..0f62d7abb0 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h @@ -31,6 +31,38 @@ extern ecma_completion_value_t ecma_builtin_helper_get_to_locale_string_at_index extern ecma_completion_value_t ecma_builtin_helper_object_get_properties (ecma_object_t *obj, bool only_enumerable_properties); +#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_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_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_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); +extern ecma_number_t ecma_date_utc (ecma_number_t time); +extern ecma_number_t ecma_date_hour_from_time (ecma_number_t time); +extern ecma_number_t ecma_date_min_from_time (ecma_number_t time); +extern ecma_number_t ecma_date_sec_from_time (ecma_number_t time); +extern ecma_number_t ecma_date_ms_from_time (ecma_number_t time); +extern ecma_number_t ecma_date_make_time (ecma_number_t hour, + ecma_number_t min, + ecma_number_t sec, + ecma_number_t ms); +extern ecma_number_t ecma_date_make_day (ecma_number_t year, + ecma_number_t month, + ecma_number_t date); +extern ecma_number_t ecma_date_make_date (ecma_number_t day, ecma_number_t time); +extern ecma_number_t ecma_date_time_clip (ecma_number_t time); +#endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_DATE_BUILTIN */ + /** * @} * @} diff --git a/tests/unit/test-date-helpers.cpp b/tests/unit/test-date-helpers.cpp index f778c07fc7..877c6ad489 100644 --- a/tests/unit/test-date-helpers.cpp +++ b/tests/unit/test-date-helpers.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ +#include "ecma-builtin-helpers.h" #include "ecma-globals.h" #include "ecma-helpers.h" @@ -64,13 +65,9 @@ main (int __attr_unused___ argc, 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)) - ) + 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)) - ) + 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) */ From c2c1967843fe8505841bb57eea38c8dbb21977c7 Mon Sep 17 00:00:00 2001 From: Szilard Ledan Date: Mon, 29 Jun 2015 10:55:36 +0200 Subject: [PATCH 5/5] Style fix Add comments to the time range defines JerryScript-DCO-1.0-Signed-off-by: Szilard Ledan szledan.u-szeged@partner.samsung.com --- .../ecma-builtin-helpers-date.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 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 90833e3e77..c2f2d49be3 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-date.cpp +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-date.cpp @@ -28,9 +28,19 @@ * @{ */ +/** + * Time range defines for helper functions. + * + * See also: + * ECMA-262 v5, 15.9.1.1, 15.9.1.10 + */ +/* Hours in a day. */ #define ECMA_DATE_HOURS_PER_DAY 24 +/* Minutes in an hour. */ #define ECMA_DATE_MINUTES_PER_HOUR 60 +/* Seconds in a minute. */ #define ECMA_DATE_SECONDS_PER_MINUTE 60 +/* Milliseconds in a second. */ #define ECMA_DATE_MS_PER_SECOND 1000 /* ECMA_DATE_MS_PER_MINUTE == 60000 */ #define ECMA_DATE_MS_PER_MINUTE (ECMA_DATE_MS_PER_SECOND * ECMA_DATE_SECONDS_PER_MINUTE) @@ -38,6 +48,9 @@ #define ECMA_DATE_MS_PER_HOUR (ECMA_DATE_MS_PER_MINUTE * ECMA_DATE_MINUTES_PER_HOUR) /* ECMA_DATE_MS_PER_DAY == 86400000 */ #define ECMA_DATE_MS_PER_DAY (ECMA_DATE_MS_PER_HOUR * ECMA_DATE_HOURS_PER_DAY) +/* This gives a range of 8,640,000,000,000,000 milliseconds + * to either side of 01 January, 1970 UTC. + */ #define ECMA_DATE_MAX_VALUE 8.64e15 /** @@ -377,7 +390,7 @@ ecma_date_week_day (ecma_number_t time) /**< time value */ ecma_number_t __attr_always_inline___ ecma_date_local_tza () { - JERRY_UNIMPLEMENTED ("The ecma_date_local_tza is not implemented yet."); + JERRY_UNIMPLEMENTED ("The built-in is not implemented."); } /* ecma_date_local_tza */ /** @@ -394,7 +407,7 @@ ecma_number_t __attr_always_inline___ ecma_date_daylight_saving_ta (ecma_number_t __attr_unused___ time) /**< time value */ { JERRY_ASSERT (!ecma_number_is_nan (time)); - JERRY_UNIMPLEMENTED ("The ecma_date_daylight_saving_ta is not implemented yet."); + JERRY_UNIMPLEMENTED ("The built-in is not implemented."); } /* ecma_date_daylight_saving_ta */ /**