From b5923ccd9dfc1d65fadca444c4d6ce6442ac7406 Mon Sep 17 00:00:00 2001 From: Roland Takacs Date: Mon, 27 Jul 2015 13:54:19 +0200 Subject: [PATCH] Fix [[Construct]] call for Date() JerryScript-DCO-1.0-Signed-off-by: Roland Takacs rtakacs.u-szeged@partner.samsung.com --- .../ecma-builtin-date-prototype.cpp | 6 +- .../builtin-objects/ecma-builtin-date.cpp | 19 ++- .../ecma-builtin-helpers-date.cpp | 134 ++++++++++-------- .../builtin-objects/ecma-builtin-helpers.h | 5 +- tests/jerry/date-construct.js | 20 +-- tests/jerry/date-tostring.js | 8 +- 6 files changed, 108 insertions(+), 84 deletions(-) diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-date-prototype.cpp b/jerry-core/ecma/builtin-objects/ecma-builtin-date-prototype.cpp index 9aab969d6..a02416b88 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-date-prototype.cpp +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-date-prototype.cpp @@ -55,7 +55,7 @@ static ecma_completion_value_t ecma_builtin_date_prototype_to_string (ecma_value_t this_arg) /**< this argument */ { - return ecma_date_to_string (this_arg, ECMA_DATE_LOCAL); + return ecma_date_object_to_string (this_arg, ECMA_DATE_LOCAL); } /* ecma_builtin_date_prototype_to_string */ /** @@ -1101,7 +1101,7 @@ ecma_builtin_date_prototype_set_utc_full_year (ecma_value_t this_arg, /**< this static ecma_completion_value_t ecma_builtin_date_prototype_to_utc_string (ecma_value_t this_arg) /**< this argument */ { - return ecma_date_to_string (this_arg, ECMA_DATE_UTC); + return ecma_date_object_to_string (this_arg, ECMA_DATE_UTC); } /* ecma_builtin_date_prototype_to_utc_string */ /** @@ -1116,7 +1116,7 @@ ecma_builtin_date_prototype_to_utc_string (ecma_value_t this_arg) /**< this argu static ecma_completion_value_t ecma_builtin_date_prototype_to_iso_string (ecma_value_t this_arg) /**< this argument */ { - return ecma_date_to_string (this_arg, ECMA_DATE_UTC); + return ecma_date_object_to_string (this_arg, ECMA_DATE_UTC); } /* ecma_builtin_date_prototype_to_iso_string */ /** diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-date.cpp b/jerry-core/ecma/builtin-objects/ecma-builtin-date.cpp index fe471c135..122c952c0 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-date.cpp +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-date.cpp @@ -470,13 +470,20 @@ ecma_builtin_date_now (ecma_value_t this_arg __attr_unused___) /**< this argumen * @return completion-value */ ecma_completion_value_t -ecma_builtin_date_dispatch_call (const ecma_value_t *arguments_list_p, /**< arguments list */ - ecma_length_t arguments_list_len) /**< number of arguments */ +ecma_builtin_date_dispatch_call (const ecma_value_t *arguments_list_p __attr_unused___, /**< arguments list */ + ecma_length_t arguments_list_len __attr_unused___) /**< number of arguments */ { - /* FIXME: - * Fix this, after Date.prototype.toString is finished. - */ - return ecma_builtin_date_dispatch_construct (arguments_list_p, arguments_list_len); + ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); + + ECMA_TRY_CATCH (now_val, + ecma_builtin_date_now (ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED)), + ret_value); + + ret_value = ecma_date_value_to_string (*ecma_get_number_from_value (now_val), ECMA_DATE_LOCAL); + + ECMA_FINALIZE (now_val); + + return ret_value; } /* ecma_builtin_date_dispatch_call */ /** 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 92c505255..2ee46198f 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-date.cpp +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-date.cpp @@ -911,7 +911,73 @@ ecma_date_insert_num_with_sep (ecma_string_t **str_p, /**< input/output string * } /* ecma_date_insert_num_with_sep */ /** - * Common function to create a time zone specific string. + * Common function to create a time zone specific string from a numeric value. + * + * Used by: + * - The Date routine. + * - The ecma_date_object_to_string helper routine. + * + * @return completion value + * Returned value must be freed with ecma_free_completion_value. + */ +ecma_completion_value_t +ecma_date_value_to_string (ecma_number_t datetime_num, /**u.internal_property.value); - - if (ecma_number_is_nan (*prim_value_num_p)) - { - ecma_string_t *magic_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_INVALID_DATE_UL); - ret_value = ecma_make_normal_completion_value (ecma_make_string_value (magic_str_p)); - } - else - { - ecma_string_t *output_str_p; - ecma_number_t milliseconds = ecma_date_ms_from_time (*prim_value_num_p); - - if (timezone == ECMA_DATE_UTC) - { - output_str_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY); - ecma_date_insert_num_with_sep (&output_str_p, milliseconds, LIT_MAGIC_STRING_Z_CHAR, 3); - } - else - { - output_str_p = ecma_new_ecma_string_from_number (milliseconds); - ecma_date_insert_leading_zeros (&output_str_p, milliseconds, 3); - } - - ecma_number_t seconds = ecma_date_sec_from_time (*prim_value_num_p); - ecma_date_insert_num_with_sep (&output_str_p, seconds, LIT_MAGIC_STRING_DOT_CHAR, 2); - - ecma_number_t minutes = ecma_date_min_from_time (*prim_value_num_p); - ecma_date_insert_num_with_sep (&output_str_p, minutes, LIT_MAGIC_STRING_COLON_CHAR, 2); - - ecma_number_t hours = ecma_date_hour_from_time (*prim_value_num_p); - ecma_date_insert_num_with_sep (&output_str_p, hours, LIT_MAGIC_STRING_COLON_CHAR, 2); - - ecma_number_t day = ecma_date_date_from_time (*prim_value_num_p); - ecma_date_insert_num_with_sep (&output_str_p, day, LIT_MAGIC_STRING_TIME_SEP_U, 2); - - /* - * Note: - * 'ecma_date_month_from_time' (ECMA 262 v5, 15.9.1.4) returns a number from 0 to 11, - * but we have to print the month from 1 to 12 for ISO 8601 standard (ECMA 262 v5, 15.9.1.15). - */ - ecma_number_t month = ecma_date_month_from_time (*prim_value_num_p) + 1; - ecma_date_insert_num_with_sep (&output_str_p, month, LIT_MAGIC_STRING_MINUS_CHAR, 2); - - ecma_number_t year = ecma_date_year_from_time (*prim_value_num_p); - ecma_date_insert_num_with_sep (&output_str_p, year, LIT_MAGIC_STRING_MINUS_CHAR, 4); - - ret_value = ecma_make_normal_completion_value (ecma_make_string_value (output_str_p)); - } - - ECMA_FINALIZE (obj_this); + ret_value = ecma_date_value_to_string (*prim_value_num_p, timezone); } return ret_value; -} /* ecma_date_create_formatted_string */ +} /* ecma_date_object_to_string */ /** * @} diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h index 59e0565db..6d4c9d244 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h @@ -120,7 +120,10 @@ extern void ecma_date_insert_num_with_sep (ecma_string_t **str_p, ecma_number_t num, lit_magic_string_id_t magic_str_id, uint32_t length); -extern ecma_completion_value_t ecma_date_to_string (ecma_value_t this_arg, ecma_date_timezone_t timezone); + +extern ecma_completion_value_t ecma_date_value_to_string (ecma_number_t datetime_num, ecma_date_timezone_t timezone); +extern ecma_completion_value_t ecma_date_object_to_string (ecma_value_t this_arg, ecma_date_timezone_t timezone); + #endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_DATE_BUILTIN */ typedef struct diff --git a/tests/jerry/date-construct.js b/tests/jerry/date-construct.js index 4834ee450..c66977028 100644 --- a/tests/jerry/date-construct.js +++ b/tests/jerry/date-construct.js @@ -31,21 +31,9 @@ catch (e) assert (isNaN(Date.prototype.valueOf.call(Date.prototype))); -d = Date("abcd"); +d = new Date("abcd"); assert (isNaN(d.valueOf())); -d = Date(); -assert (!isNaN(d.valueOf())); - -d = Date("2015-01-01"); -assert (d.valueOf() == 1420070400000); - -d = Date(1420070400000); -assert (d.valueOf() == 1420070400000); - -d = Date(2015,0,1,0,0,0,0); -assert (d.valueOf() == 1420070400000); - d = new Date(); assert (!isNaN(d.valueOf())); @@ -82,3 +70,9 @@ catch (e) assert (e instanceof ReferenceError); assert (e.message === "valueOf-1"); } + +assert (typeof Date (2015) == "string"); +assert (typeof Date() != typeof (new Date ())); +assert (Date (Number.NaN) == Date ()); +// Fixme: remove this case when Date() gives the current time. +assert (Date (2015,1,2) == "1970-01-01T00:00:00.000"); diff --git a/tests/jerry/date-tostring.js b/tests/jerry/date-tostring.js index 7e63b5234..8c23876e1 100644 --- a/tests/jerry/date-tostring.js +++ b/tests/jerry/date-tostring.js @@ -44,7 +44,7 @@ catch (e) } assert (new Date (NaN).toTimeString () == "Invalid Date"); -assert (Date (Number.POSITIVE_INFINITY).toString () === "Invalid Date"); +assert (new Date (Number.POSITIVE_INFINITY).toString () === "Invalid Date"); assert (new Date ("2015-02-13").toTimeString () == "00:00:00.000"); assert (new Date ("2015-07-08T11:29:05.023").toTimeString () == "11:29:05.023"); @@ -105,3 +105,9 @@ catch (e) date_time = new Date ("2015-07-08T11:29:05.023").toJSON (); assert (new Date (date_time) == "2015-07-08T11:29:05.023"); + +assert (typeof Date (2015) == "string"); +assert (typeof Date() != typeof (new Date ())); +assert (Date () == (new Date ()).toString ()); +assert (Date (2015, 1, 1) == (new Date ()).toString ()); +assert (Date (Number.NaN) == Date ());