From c12914c71a5868b8608c64f18c1bdea054fbb2b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A1szl=C3=B3=20Lang=C3=B3?= Date: Mon, 6 Jul 2015 12:28:26 +0200 Subject: [PATCH] Implement Date constructor. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit JerryScript-DCO-1.0-Signed-off-by: László Langó llango.u-szeged@partner.samsung.com --- .../builtin-objects/ecma-builtin-date.cpp | 101 +++++++++++++++++- .../ecma-builtin-helpers-date.cpp | 14 ++- tests/jerry/date-construct.js | 57 ++++++++++ 3 files changed, 167 insertions(+), 5 deletions(-) create mode 100644 tests/jerry/date-construct.js diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-date.cpp b/jerry-core/ecma/builtin-objects/ecma-builtin-date.cpp index eb04020476..7f335141d9 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-date.cpp +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-date.cpp @@ -17,6 +17,7 @@ #include "ecma-alloc.h" #include "ecma-builtin-helpers.h" #include "ecma-conversion.h" +#include "ecma-gc.h" #include "ecma-globals.h" #include "ecma-helpers.h" #include "ecma-try-catch-macro.h" @@ -423,7 +424,7 @@ ecma_builtin_date_utc (ecma_value_t this_arg __attr_unused___, /**< this argumen ECMA_TRY_CATCH (time_value, ecma_date_construct_helper (args, args_number), ret_value); - ecma_number_t *time_p = ecma_get_number_from_completion_value (time_value); + ecma_number_t *time_p = ecma_get_number_from_value (time_value); ecma_number_t *time_clip_p = ecma_alloc_number (); *time_clip_p = ecma_date_time_clip (*time_p); ret_value = ecma_make_normal_completion_value (ecma_make_number_value (time_clip_p)); @@ -458,25 +459,119 @@ ecma_builtin_date_now (ecma_value_t this_arg __attr_unused___) /**< this argumen /** * Handle calling [[Call]] of built-in Date object * + * See also: + * ECMA-262 v5, 15.9.2.1 + * * @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_CP_UNIMPLEMENTED (arguments_list_p, arguments_list_len); + /* FIXME: + * Fix this, after Date.prototype.toString is finished. + */ + return ecma_builtin_date_dispatch_construct (arguments_list_p, arguments_list_len); } /* ecma_builtin_date_dispatch_call */ /** * Handle calling [[Construct]] of built-in Date object * + * See also: + * ECMA-262 v5, 15.9.3.1 + * * @return completion-value */ ecma_completion_value_t ecma_builtin_date_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */ ecma_length_t arguments_list_len) /**< number of arguments */ { - ECMA_BUILTIN_CP_UNIMPLEMENTED (arguments_list_p, arguments_list_len); + ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); + ecma_number_t *prim_value_num_p = NULL; + + ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_DATE_PROTOTYPE); + ecma_object_t *obj_p = ecma_create_object (prototype_obj_p, + true, + ECMA_OBJECT_TYPE_GENERAL); + ecma_deref_object (prototype_obj_p); + + if (arguments_list_len == 0) + { + ECMA_TRY_CATCH (parse_res_value, + ecma_builtin_date_now (ecma_make_object_value (obj_p)), + ret_value); + + prim_value_num_p = ecma_alloc_number (); + *prim_value_num_p = *ecma_get_number_from_value (parse_res_value); + + ECMA_FINALIZE (parse_res_value) + } + else if (arguments_list_len == 1) + { + ECMA_TRY_CATCH (prim_comp_value, + ecma_op_to_primitive (arguments_list_p[0], ECMA_PREFERRED_TYPE_NUMBER), + ret_value); + + if (ecma_is_value_string (prim_comp_value)) + { + ECMA_TRY_CATCH (parse_res_value, + ecma_builtin_date_parse (ecma_make_object_value (obj_p), prim_comp_value), + ret_value); + + prim_value_num_p = ecma_alloc_number (); + *prim_value_num_p = *ecma_get_number_from_value (parse_res_value); + + ECMA_FINALIZE (parse_res_value); + } + else + { + ECMA_TRY_CATCH (prim_value, ecma_op_to_number (arguments_list_p[0]), ret_value); + + prim_value_num_p = ecma_alloc_number (); + *prim_value_num_p = *ecma_get_number_from_value (prim_value); + + ECMA_FINALIZE (prim_value); + } + + ECMA_FINALIZE (prim_comp_value); + } + else if (arguments_list_len >= 2) + { + ECMA_TRY_CATCH (time_value, + ecma_date_construct_helper (arguments_list_p, arguments_list_len), + ret_value); + + ecma_number_t *time_p = ecma_get_number_from_value (time_value); + prim_value_num_p = ecma_alloc_number (); + *prim_value_num_p = ecma_date_time_clip (ecma_date_utc (*time_p)); + + ECMA_FINALIZE (time_value); + } + else + { + prim_value_num_p = ecma_alloc_number (); + *prim_value_num_p = ecma_number_make_nan (); + } + + if (ecma_is_completion_value_empty (ret_value)) + { + ecma_property_t *class_prop_p = ecma_create_internal_property (obj_p, + ECMA_INTERNAL_PROPERTY_CLASS); + class_prop_p->u.internal_property.value = LIT_MAGIC_STRING_DATE_UL; + + ecma_property_t *prim_value_prop_p = ecma_create_internal_property (obj_p, + ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE); + ECMA_SET_POINTER (prim_value_prop_p->u.internal_property.value, prim_value_num_p); + + ret_value = ecma_make_normal_completion_value (ecma_make_object_value (obj_p)); + } + else + { + JERRY_ASSERT (ecma_is_completion_value_throw (ret_value)); + ecma_deref_object (obj_p); + } + + return ret_value; } /* ecma_builtin_date_dispatch_construct */ /** 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 0b96127193..60bca724bb 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-date.cpp +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-date.cpp @@ -413,7 +413,12 @@ ecma_date_week_day (ecma_number_t time) /**< time value */ ecma_number_t __attr_always_inline___ ecma_date_local_tza () { - JERRY_UNIMPLEMENTED ("The built-in is not implemented."); + /* + * FIXME: + * Get the real system time. ex: localtime_r, gmtime_r, daylight on Linux + * Introduce system macros at first. + */ + return ECMA_NUMBER_ZERO; } /* ecma_date_local_tza */ /** @@ -432,7 +437,12 @@ ecma_date_daylight_saving_ta (ecma_number_t time) /**< time value */ return time; /* time is NaN */ } - JERRY_UNIMPLEMENTED ("The built-in is not implemented."); + /* + * FIXME: + * Get the real system time. ex: localtime_r, gmtime_r, daylight on Linux + * Introduce system macros at first. + */ + return ECMA_NUMBER_ZERO; } /* ecma_date_daylight_saving_ta */ /** diff --git a/tests/jerry/date-construct.js b/tests/jerry/date-construct.js new file mode 100644 index 0000000000..dff01d3914 --- /dev/null +++ b/tests/jerry/date-construct.js @@ -0,0 +1,57 @@ +// 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. + +assert (Date.length == 7); +assert (Object.prototype.toString.call (Date.prototype) === '[object Date]'); + +var d; + +try +{ + d = new Date({toString: function() { throw new Error("foo"); }}); + assert (false); +} +catch (e) +{ + assert (e instanceof Error); + assert (e.message === "foo"); +} + +// FIXME: Add assert statements when getters for Date are finished. +d = 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())); + +d = new Date("2015-01-01"); +// assert (d.valueOf() == 1420070400000); + +d = new Date(1420070400000); +// assert (d.valueOf() == 1420070400000); + +d = new Date(2015,0,1,0,0,0,0); +// assert (d.valueOf() == 1420070400000);