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 5cdafb4c22..48ba5ad670 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-date-prototype.cpp +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-date-prototype.cpp @@ -363,9 +363,30 @@ DEFINE_GETTER (ECMA-262 v5 15.9.5.26, timezone_offset, ecma_date_timezone_offset */ static ecma_completion_value_t ecma_builtin_date_prototype_set_time (ecma_value_t this_arg, /**< this argument */ - ecma_value_t arg) /**< time */ + ecma_value_t time) /**< time */ { - ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg, arg); + ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); + + /* 1. */ + ECMA_OP_TO_NUMBER_TRY_CATCH (t, time, ret_value); + ecma_number_t *value_p = ecma_alloc_number (); + *value_p = ecma_date_time_clip (t); + + /* 2. */ + ecma_object_t *obj_p = ecma_get_object_from_value (this_arg); + + ecma_property_t *prim_value_prop_p = ecma_get_internal_property (obj_p, + ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE); + + ecma_number_t *prim_value_num_p = ECMA_GET_NON_NULL_POINTER (ecma_number_t, + prim_value_prop_p->u.internal_property.value); + *prim_value_num_p = *value_p; + + /* 3. */ + ret_value = ecma_make_normal_completion_value (ecma_make_number_value (value_p)); + ECMA_OP_TO_NUMBER_FINALIZE (t); + + return ret_value; } /* ecma_builtin_date_prototype_set_time */ /** @@ -379,9 +400,30 @@ ecma_builtin_date_prototype_set_time (ecma_value_t this_arg, /**< this argument */ static ecma_completion_value_t ecma_builtin_date_prototype_set_milliseconds (ecma_value_t this_arg, /**< this argument */ - ecma_value_t arg) /**< millisecond */ + ecma_value_t ms) /**< millisecond */ { - ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg, arg); + 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_date_local_time (*ecma_get_number_from_value (this_time_value)); + + /* 2. */ + ECMA_OP_TO_NUMBER_TRY_CATCH (milli, ms, ret_value); + + /* 3-5. */ + ecma_number_t hour = ecma_date_hour_from_time (t); + ecma_number_t min = ecma_date_min_from_time (t); + ecma_number_t sec = ecma_date_sec_from_time (t); + ret_value = ecma_date_set_internal_property (this_arg, + ecma_date_day (t), + ecma_date_make_time (hour, min, sec, milli), + ECMA_DATE_LOCAL); + + ECMA_OP_TO_NUMBER_FINALIZE (milli); + ECMA_FINALIZE (this_time_value); + + return ret_value; } /* ecma_builtin_date_prototype_set_milliseconds */ /** @@ -395,9 +437,30 @@ ecma_builtin_date_prototype_set_milliseconds (ecma_value_t this_arg, /**< this a */ static ecma_completion_value_t ecma_builtin_date_prototype_set_utc_milliseconds (ecma_value_t this_arg, /**< this argument */ - ecma_value_t arg) /**< millisecond */ + ecma_value_t ms) /**< millisecond */ { - ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg, arg); + 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 (milli, ms, ret_value); + + /* 3-5. */ + ecma_number_t hour = ecma_date_hour_from_time (t); + ecma_number_t min = ecma_date_min_from_time (t); + ecma_number_t sec = ecma_date_sec_from_time (t); + ret_value = ecma_date_set_internal_property (this_arg, + ecma_date_day (t), + ecma_date_make_time (hour, min, sec, milli), + ECMA_DATE_UTC); + + ECMA_OP_TO_NUMBER_FINALIZE (milli); + ECMA_FINALIZE (this_time_value); + + return ret_value; } /* ecma_builtin_date_prototype_set_utc_milliseconds */ /** @@ -411,10 +474,38 @@ ecma_builtin_date_prototype_set_utc_milliseconds (ecma_value_t this_arg, /**< th */ static ecma_completion_value_t ecma_builtin_date_prototype_set_seconds (ecma_value_t this_arg, /**< this argument */ - ecma_value_t arg1, /**< second */ - ecma_value_t arg2) /**< millisecond */ + ecma_value_t sec, /**< second */ + ecma_value_t ms) /**< millisecond */ { - ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg, arg1, arg2); + 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_date_local_time (*ecma_get_number_from_value (this_time_value)); + + /* 2. */ + ECMA_OP_TO_NUMBER_TRY_CATCH (s, sec, ret_value); + + /* 3. */ + ECMA_OP_TO_NUMBER_TRY_CATCH (milli, ms, ret_value); + if (ecma_is_value_undefined (ms)) + { + milli = ecma_date_ms_from_time (t); + } + + /* 4-7. */ + ecma_number_t hour = ecma_date_hour_from_time (t); + ecma_number_t min = ecma_date_min_from_time (t); + ret_value = ecma_date_set_internal_property (this_arg, + ecma_date_day (t), + ecma_date_make_time (hour, min, s, milli), + ECMA_DATE_LOCAL); + + ECMA_OP_TO_NUMBER_FINALIZE (milli); + ECMA_OP_TO_NUMBER_FINALIZE (s); + ECMA_FINALIZE (this_time_value); + + return ret_value; } /* ecma_builtin_date_prototype_set_seconds */ /** @@ -428,10 +519,38 @@ ecma_builtin_date_prototype_set_seconds (ecma_value_t this_arg, /**< this argume */ static ecma_completion_value_t ecma_builtin_date_prototype_set_utc_seconds (ecma_value_t this_arg, /**< this argument */ - ecma_value_t arg1, /**< second */ - ecma_value_t arg2) /**< millisecond */ + ecma_value_t sec, /**< second */ + ecma_value_t ms) /**< millisecond */ { - ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg, arg1, arg2); + 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 (s, sec, ret_value); + + /* 3. */ + ECMA_OP_TO_NUMBER_TRY_CATCH (milli, ms, ret_value); + if (ecma_is_value_undefined (ms)) + { + milli = ecma_date_ms_from_time (t); + } + + /* 4-7. */ + ecma_number_t hour = ecma_date_hour_from_time (t); + ecma_number_t min = ecma_date_min_from_time (t); + ret_value = ecma_date_set_internal_property (this_arg, + ecma_date_day (t), + ecma_date_make_time (hour, min, s, milli), + ECMA_DATE_UTC); + + ECMA_OP_TO_NUMBER_FINALIZE (milli); + ECMA_OP_TO_NUMBER_FINALIZE (s); + ECMA_FINALIZE (this_time_value); + + return ret_value; } /* ecma_builtin_date_prototype_set_utc_seconds */ /** @@ -448,7 +567,48 @@ ecma_builtin_date_prototype_set_minutes (ecma_value_t this_arg, /**< this argume const ecma_value_t args[], /**< arguments list */ ecma_length_t args_number) /**< number of arguments */ { - ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg, args, args_number); + 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_date_local_time (*ecma_get_number_from_value (this_time_value)); + + /* 2. Let 'm' be ToNumber('min') where 'min' is args[0]. */ + ECMA_OP_TO_NUMBER_TRY_CATCH (m, args[0], ret_value); + + /* 3. If 'sec' is not specified, then let 's' be SecFromTime('t'); + * otherwise, let 's' be ToNumber('sec') where 'sec' is args[1]. */ + ecma_number_t s = ecma_date_sec_from_time (t); + ecma_number_t milli = ecma_date_ms_from_time (t); + if (args_number > 1 && !ecma_is_value_undefined (args[1])) + { + ECMA_OP_TO_NUMBER_TRY_CATCH (sec, args[1], ret_value); + s = sec; + + /* 4. If 'ms' is not specified, then let 'milli' be msFromTime('t'); + * otherwise, let 'milli' be ToNumber('ms') where 'ms' is args[2]. */ + if (args_number > 2 && !ecma_is_value_undefined (args[2])) + { + ECMA_OP_TO_NUMBER_TRY_CATCH (ms, args[2], ret_value); + milli = ms; + ECMA_OP_TO_NUMBER_FINALIZE (ms); + } + ECMA_OP_TO_NUMBER_FINALIZE (sec); + } + + if (ecma_is_completion_value_empty (ret_value)) + { + /* 5-8. */ + ecma_number_t hour = ecma_date_hour_from_time (t); + ret_value = ecma_date_set_internal_property (this_arg, + ecma_date_day (t), + ecma_date_make_time (hour, m, s, milli), + ECMA_DATE_LOCAL); + } + ECMA_OP_TO_NUMBER_FINALIZE (m); + ECMA_FINALIZE (this_time_value); + + return ret_value; } /* ecma_builtin_date_prototype_set_minutes */ /** @@ -465,7 +625,48 @@ ecma_builtin_date_prototype_set_utc_minutes (ecma_value_t this_arg, /**< this ar const ecma_value_t args[], /**< arguments list */ ecma_length_t args_number) /**< number of arguments */ { - ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg, args, args_number); + 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. Let 'm' be ToNumber('min') where 'min' is args[0]. */ + ECMA_OP_TO_NUMBER_TRY_CATCH (m, args[0], ret_value); + + /* 3. If 'sec' is not specified, then let 's' be SecFromTime('t'); + * otherwise, let 's' be ToNumber('sec') where 'sec' is args[1]. */ + ecma_number_t s = ecma_date_sec_from_time (t); + ecma_number_t milli = ecma_date_ms_from_time (t); + if (args_number > 1 && !ecma_is_value_undefined (args[1])) + { + ECMA_OP_TO_NUMBER_TRY_CATCH (sec, args[1], ret_value); + s = sec; + + /* 4. If 'ms' is not specified, then let 'milli' be msFromTime('t'); + * otherwise, let 'milli' be ToNumber('ms') where 'ms' is args[2]. */ + if (args_number > 2 && !ecma_is_value_undefined (args[2])) + { + ECMA_OP_TO_NUMBER_TRY_CATCH (ms, args[2], ret_value); + milli = ms; + ECMA_OP_TO_NUMBER_FINALIZE (ms); + } + ECMA_OP_TO_NUMBER_FINALIZE (sec); + } + + if (ecma_is_completion_value_empty (ret_value)) + { + /* 5-8. */ + ecma_number_t hour = ecma_date_hour_from_time (t); + ret_value = ecma_date_set_internal_property (this_arg, + ecma_date_day (t), + ecma_date_make_time (hour, m, s, milli), + ECMA_DATE_UTC); + } + ECMA_OP_TO_NUMBER_FINALIZE (m); + ECMA_FINALIZE (this_time_value); + + return ret_value; } /* ecma_builtin_date_prototype_set_utc_minutes */ /** @@ -482,7 +683,57 @@ ecma_builtin_date_prototype_set_hours (ecma_value_t this_arg, /**< this argument const ecma_value_t args[], /**< arguments list */ ecma_length_t args_number) /**< number of arguments */ { - ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg, args, args_number); + 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_date_local_time (*ecma_get_number_from_value (this_time_value)); + + /* 2. Let 'h' be ToNumber('hour') where 'hour' is args[0]. */ + ECMA_OP_TO_NUMBER_TRY_CATCH (h, args[0], ret_value); + + /* 3. If 'min' is not specified, then let 'm' be MinFromTime('t'); + * otherwise, let 'm' be ToNumber('min') where 'min' is args[1]. */ + ecma_number_t m = ecma_date_min_from_time (t); + ecma_number_t s = ecma_date_sec_from_time (t); + ecma_number_t milli = ecma_date_ms_from_time (t); + if (args_number > 1 && !ecma_is_value_undefined (args[1])) + { + ECMA_OP_TO_NUMBER_TRY_CATCH (min, args[1], ret_value); + m = min; + + /* 4. If 'sec' is not specified, then let 's' be SecFromTime('t'); + * otherwise, let 's' be ToNumber('sec') where 'sec' is args[2]. */ + if (args_number > 2 && !ecma_is_value_undefined (args[2])) + { + ECMA_OP_TO_NUMBER_TRY_CATCH (sec, args[2], ret_value); + s = sec; + + /* 5. If 'ms' is not specified, then let 'milli' be msFromTime('t'); + * otherwise, let 'milli' be ToNumber('ms') where 'ms' is args[3]. */ + if (args_number > 3 && !ecma_is_value_undefined (args[3])) + { + ECMA_OP_TO_NUMBER_TRY_CATCH (ms, args[3], ret_value); + milli = ms; + ECMA_OP_TO_NUMBER_FINALIZE (ms); + } + ECMA_OP_TO_NUMBER_FINALIZE (sec); + } + ECMA_OP_TO_NUMBER_FINALIZE (min); + } + + if (ecma_is_completion_value_empty (ret_value)) + { + /* 6-9. */ + ret_value = ecma_date_set_internal_property (this_arg, + ecma_date_day (t), + ecma_date_make_time (h, m, s, milli), + ECMA_DATE_LOCAL); + } + ECMA_OP_TO_NUMBER_FINALIZE (h); + ECMA_FINALIZE (this_time_value); + + return ret_value; } /* ecma_builtin_date_prototype_set_hours */ /** @@ -499,7 +750,57 @@ ecma_builtin_date_prototype_set_utc_hours (ecma_value_t this_arg, /**< this argu const ecma_value_t args[], /**< arguments list */ ecma_length_t args_number) /**< number of arguments */ { - ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg, args, args_number); + 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. Let 'h' be ToNumber('hour') where 'hour' is args[0]. */ + ECMA_OP_TO_NUMBER_TRY_CATCH (h, args[0], ret_value); + + /* 3. If 'min' is not specified, then let 'm' be MinFromTime('t'); + * otherwise, let 'm' be ToNumber('min') where 'min' is args[1]. */ + ecma_number_t m = ecma_date_min_from_time (t); + ecma_number_t s = ecma_date_sec_from_time (t); + ecma_number_t milli = ecma_date_ms_from_time (t); + if (args_number > 1 && !ecma_is_value_undefined (args[1])) + { + ECMA_OP_TO_NUMBER_TRY_CATCH (min, args[1], ret_value); + m = min; + + /* 4. If 'sec' is not specified, then let 's' be SecFromTime('t'); + * otherwise, let 's' be ToNumber('sec') where 'sec' is args[2]. */ + if (args_number > 2 && !ecma_is_value_undefined (args[2])) + { + ECMA_OP_TO_NUMBER_TRY_CATCH (sec, args[2], ret_value); + s = sec; + + /* 5. If 'ms' is not specified, then let 'milli' be msFromTime('t'); + * otherwise, let 'milli' be ToNumber('ms') where 'ms' is args[3]. */ + if (args_number > 3 && !ecma_is_value_undefined (args[3])) + { + ECMA_OP_TO_NUMBER_TRY_CATCH (ms, args[3], ret_value); + milli = ms; + ECMA_OP_TO_NUMBER_FINALIZE (ms); + } + ECMA_OP_TO_NUMBER_FINALIZE (sec); + } + ECMA_OP_TO_NUMBER_FINALIZE (min); + } + + if (ecma_is_completion_value_empty (ret_value)) + { + /* 6-9. */ + ret_value = ecma_date_set_internal_property (this_arg, + ecma_date_day (t), + ecma_date_make_time (h, m, s, milli), + ECMA_DATE_UTC); + } + ECMA_OP_TO_NUMBER_FINALIZE (h); + ECMA_FINALIZE (this_time_value); + + return ret_value; } /* ecma_builtin_date_prototype_set_utc_hours */ /** @@ -513,9 +814,29 @@ ecma_builtin_date_prototype_set_utc_hours (ecma_value_t this_arg, /**< this argu */ static ecma_completion_value_t ecma_builtin_date_prototype_set_date (ecma_value_t this_arg, /**< this argument */ - ecma_value_t arg) /**< date */ + ecma_value_t date) /**< date */ { - ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg, arg); + 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_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 */ /** @@ -529,9 +850,29 @@ ecma_builtin_date_prototype_set_date (ecma_value_t this_arg, /**< this argument */ static ecma_completion_value_t ecma_builtin_date_prototype_set_utc_date (ecma_value_t this_arg, /**< this argument */ - ecma_value_t arg) /**< date */ + ecma_value_t date) /**< date */ { - ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg, arg); + 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 */ /** @@ -545,10 +886,37 @@ ecma_builtin_date_prototype_set_utc_date (ecma_value_t this_arg, /**< this argum */ static ecma_completion_value_t ecma_builtin_date_prototype_set_month (ecma_value_t this_arg, /**< this argument */ - ecma_value_t arg1, /**< month */ - ecma_value_t arg2) /**< day */ + ecma_value_t month, /**< month */ + ecma_value_t date) /**< date */ { - ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg, arg1, arg2); + 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_date_local_time (*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_LOCAL); + + 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_month */ /** @@ -562,10 +930,37 @@ ecma_builtin_date_prototype_set_month (ecma_value_t this_arg, /**< this argument */ static ecma_completion_value_t ecma_builtin_date_prototype_set_utc_month (ecma_value_t this_arg, /**< this argument */ - ecma_value_t arg1, /**< month */ - ecma_value_t arg2) /**< day */ + ecma_value_t month, /**< month */ + ecma_value_t date) /**< date */ { - ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg, arg1, arg2); + 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 (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 */ /** @@ -582,7 +977,51 @@ ecma_builtin_date_prototype_set_full_year (ecma_value_t this_arg, /**< this argu const ecma_value_t args[], /**< arguments list */ ecma_length_t args_number) /**< number of arguments */ { - ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg, args, args_number); + 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_date_local_time (*ecma_get_number_from_value (this_time_value)); + if (ecma_number_is_nan (t)) + { + t = ECMA_NUMBER_ZERO; + } + + /* 2. Let 'y' be ToNumber('year') where 'year' is args[0]. */ + ECMA_OP_TO_NUMBER_TRY_CATCH (y, args[0], ret_value); + + /* 3. If 'month' is not specified, then let 'm' be MonthFromTime('t'); + * otherwise, let 'm' be ToNumber('month') where 'month' is args[1]. */ + ecma_number_t m = ecma_date_month_from_time (t); + ecma_number_t dt = ecma_date_date_from_time (t); + 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 'date' is not specified, then let 'dt' be DateFromTime('t'); + * otherwise, let 'dt' be ToNumber('date') where 'date' is args[2]. */ + 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); + } + + if (ecma_is_completion_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_OP_TO_NUMBER_FINALIZE (y); + ECMA_FINALIZE (this_time_value); + + return ret_value; } /* ecma_builtin_date_prototype_set_full_year */ /** @@ -599,7 +1038,51 @@ ecma_builtin_date_prototype_set_utc_full_year (ecma_value_t this_arg, /**< this const ecma_value_t args[], /**< arguments list */ ecma_length_t args_number) /**< number of arguments */ { - ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg, args, args_number); + 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); + if (ecma_number_is_nan (t)) + { + t = ECMA_NUMBER_ZERO; + } + + /* 2. Let 'y' be ToNumber('year') where 'year' is args[0]. */ + ECMA_OP_TO_NUMBER_TRY_CATCH (y, args[0], ret_value); + + /* 3. If 'month' is not specified, then let 'm' be MonthFromTime('t'); + * otherwise, let 'm' be ToNumber('month') where 'month' is args[1]. */ + ecma_number_t m = ecma_date_month_from_time (t); + ecma_number_t dt = ecma_date_date_from_time (t); + 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 'date' is not specified, then let 'dt' be DateFromTime('t'); + * otherwise, let 'dt' be ToNumber('date') where 'date' is args[2]. */ + 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); + } + + if (ecma_is_completion_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_UTC); + } + ECMA_OP_TO_NUMBER_FINALIZE (y); + ECMA_FINALIZE (this_time_value); + + return ret_value; } /* ecma_builtin_date_prototype_set_utc_full_year */ /** 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 67b6e2d4cf..1b99d69f3b 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-date.cpp +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-date.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ +#include "ecma-alloc.h" #include "ecma-builtin-helpers.h" #include "ecma-globals.h" #include "ecma-helpers.h" @@ -34,6 +35,16 @@ * See also: * ECMA-262 v5, 15.9.1.2 * + * Used by: + * - The Date.prototype.setMilliseconds routine. + * - The Date.prototype.setUTCMilliseconds routine. + * - The Date.prototype.setSeconds routine. + * - The Date.prototype.setUTCSeconds routine. + * - The Date.prototype.setMinutes routine. + * - The Date.prototype.setUTCMinutes routine. + * - The Date.prototype.setHours routine. + * - The Date.prototype.setUTCHours routine. + * * @return time value for day number */ ecma_number_t __attr_always_inline___ @@ -53,6 +64,14 @@ ecma_date_day (ecma_number_t time) /**< time value */ * See also: * ECMA-262 v5, 15.9.1.2 * + * Used by: + * - The Date.prototype.setDate routine. + * - The Date.prototype.setUTCDate routine. + * - The Date.prototype.setMonth routine. + * - The Date.prototype.setUTCMonth routine. + * - The Date.prototype.setFullYear routine. + * - The Date.prototype.setUTCFullYear routine. + * * @return time value within the day */ ecma_number_t __attr_always_inline___ @@ -150,6 +169,10 @@ ecma_date_time_from_year (ecma_number_t year) /**< year value */ * Used by: * - The Date.prototype.getFullYear routine. (Generated.) * - The Date.prototype.getUTCFullYear routine. (Generated.) + * - The Date.prototype.setDate routine. + * - The Date.prototype.setUTCDate routine. + * - The Date.prototype.setMonth routine. + * - The Date.prototype.setUTCMonth routine. * * @return year value */ @@ -225,6 +248,10 @@ ecma_date_day_within_year (ecma_number_t time) /**< time value */ * Used by: * - The Date.prototype.getMonth routine. (Generated.) * - The Date.prototype.getUTCMonth routine. (Generated.) + * - The Date.prototype.setDate routine. + * - The Date.prototype.setUTCDate routine. + * - The Date.prototype.setFullYear routine. + * - The Date.prototype.setUTCFullYear routine. * * @return month number */ @@ -298,6 +325,10 @@ ecma_date_month_from_time (ecma_number_t time) /**< time value */ * Used by: * - The Date.prototype.getDate routine. (Generated.) * - The Date.prototype.getUTCDate routine. (Generated.) + * - The Date.prototype.setMonth routine. + * - The Date.prototype.setUTCMonth routine. + * - The Date.prototype.setFullYear routine. + * - The Date.prototype.setUTCFullYear routine. * * @return date number */ @@ -445,6 +476,14 @@ ecma_date_daylight_saving_ta (ecma_number_t time) /**< time value */ * Used by: * - All Date.prototype.getUTC* routines. (Generated.) * - The Date.prototype.getTimezoneOffset routine. + * - The Date.prototype.setMilliseconds routine. + * - The Date.prototype.setSeconds routine. + * - The Date.prototype.setMinutes routine. + * - The Date.prototype.setHours routine. + * - The Date.prototype.setDate routine. + * - The Date.prototype.setMonth routine. + * - The Date.prototype.setFullYear routine. + * - The ecma_date_timezone_offset helper function. * * @return local time */ @@ -465,6 +504,10 @@ ecma_date_local_time (ecma_number_t time) /**< time value */ * See also: * ECMA-262 v5, 15.9.1.9 * + * Used by: + * - The Date object's 'parse' routine. + * - The [[Construct]] of built-in Date object rutine. + * * @return utc value */ ecma_number_t __attr_always_inline___ @@ -488,6 +531,12 @@ ecma_date_utc (ecma_number_t time) /**< time value */ * Used by: * - The Date.prototype.getHour routine. (Generated.) * - The Date.prototype.getUTCHour routine. (Generated.) + * - The Date.prototype.setMilliseconds routine. + * - The Date.prototype.setUTCMilliseconds routine. + * - The Date.prototype.setSeconds routine. + * - The Date.prototype.setUTCSeconds routine. + * - The Date.prototype.setMinutes routine. + * - The Date.prototype.setUTCMinutes routine. * * @return hour value */ @@ -512,6 +561,12 @@ ecma_date_hour_from_time (ecma_number_t time) /**< time value */ * Used by: * - The Date.prototype.getMinutes routine. (Generated.) * - The Date.prototype.getUTCMinutes routine. (Generated.) + * - The Date.prototype.setMilliseconds routine. + * - The Date.prototype.setUTCMilliseconds routine. + * - The Date.prototype.setSeconds routine. + * - The Date.prototype.setUTCSeconds routine. + * - The Date.prototype.setHours routine. + * - The Date.prototype.setUTCHours routine. * * @return minute value */ @@ -536,6 +591,12 @@ ecma_date_min_from_time (ecma_number_t time) /**< time value */ * Used by: * - The Date.prototype.getSeconds routine. (Generated.) * - The Date.prototype.getUTCSeconds routine. (Generated.) + * - The Date.prototype.setMilliseconds routine. + * - The Date.prototype.setUTCMilliseconds routine. + * - The Date.prototype.setMinutes routine. + * - The Date.prototype.setUTCMinutes routine. + * - The Date.prototype.setHours routine. + * - The Date.prototype.setUTCHours routine. * * @return second value */ @@ -560,6 +621,12 @@ ecma_date_sec_from_time (ecma_number_t time) /**< time value */ * Used by: * - The Date.prototype.getMilliseconds routine. (Generated.) * - The Date.prototype.getUTCMilliseconds routine. (Generated.) + * - The Date.prototype.setSeconds routine. + * - The Date.prototype.setUTCSeconds routine. + * - The Date.prototype.setMinutes routine. + * - The Date.prototype.setUTCMinutes routine. + * - The Date.prototype.setHours routine. + * - The Date.prototype.setUTCHours routine. * * @return millisecond value */ @@ -580,6 +647,16 @@ ecma_date_ms_from_time (ecma_number_t time) /**< time value */ * See also: * ECMA-262 v5, 15.9.1.11 * + * Used by: + * - The Date.prototype.setMilliseconds routine. + * - The Date.prototype.setUTCMilliseconds routine. + * - The Date.prototype.setSeconds routine. + * - The Date.prototype.setUTCSeconds routine. + * - The Date.prototype.setMinutes routine. + * - The Date.prototype.setUTCMinutes routine. + * - The Date.prototype.setHours routine. + * - The Date.prototype.setUTCHours routine. + * * @return time value */ ecma_number_t @@ -618,6 +695,14 @@ ecma_date_make_time (ecma_number_t hour, /**< hour value */ * See also: * ECMA-262 v5, 15.9.1.12 * + * Used by: + * - The Date.prototype.setDate routine. + * - The Date.prototype.setUTCDate routine. + * - The Date.prototype.setMonth routine. + * - The Date.prototype.setUTCMonth routine. + * - The Date.prototype.setFullYear routine. + * - The Date.prototype.setUTCFullYear routine. + * * @return day value */ ecma_number_t @@ -684,6 +769,10 @@ ecma_date_make_date (ecma_number_t day, /**< day value */ * See also: * ECMA-262 v5, 15.9.1.14 * + * Used by: + * - The Date.prototype.setTime routine. + * - The ecma_date_set_internal_property helper function. + * * @return number of milliseconds */ ecma_number_t __attr_always_inline___ @@ -721,6 +810,43 @@ ecma_date_timezone_offset (ecma_number_t time) /**< time value */ return (time - ecma_date_local_time (time)) / ECMA_DATE_MS_PER_MINUTE; } /* ecma_date_timezone_offset */ +/** + * Helper function to set Date internal property. + * + * Used by: + * - All Date.prototype.set* routine except Date.prototype.setTime. + * + * @return completion value containing the new internal time value + * Returned value must be freed with ecma_free_completion_value. + */ +ecma_completion_value_t +ecma_date_set_internal_property (ecma_value_t this_arg, /**< this argument */ + ecma_number_t day, /**< day */ + ecma_number_t time, /**< time */ + ecma_date_timezone_t is_utc) /**< input is utc */ +{ + JERRY_ASSERT (ecma_is_value_object (this_arg)); + + ecma_number_t *value_p = ecma_alloc_number (); + ecma_number_t date = ecma_date_make_date (day, time); + if (is_utc != ECMA_DATE_UTC) + { + date = ecma_date_utc (date); + } + *value_p = ecma_date_time_clip (date); + + ecma_object_t *obj_p = ecma_get_object_from_value (this_arg); + + ecma_property_t *prim_value_prop_p = ecma_get_internal_property (obj_p, + ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE); + + ecma_number_t *prim_value_num_p = ECMA_GET_NON_NULL_POINTER (ecma_number_t, + prim_value_prop_p->u.internal_property.value); + *prim_value_num_p = *value_p; + + return ecma_make_normal_completion_value (ecma_make_number_value (value_p)); +} /* ecma_date_set_internal_property */ + /** * @} * @} diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h index 4f78748e4e..ca21336cea 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h @@ -60,6 +60,15 @@ extern uint32_t ecma_builtin_helper_string_index_normalize (ecma_number_t index, */ #define ECMA_DATE_MAX_VALUE 8.64e15 +/** + * Timezone type. + */ +typedef enum +{ + ECMA_DATE_UTC, /**< date vaule is in UTC */ + ECMA_DATE_LOCAL /**< date vaule is in local time */ +} ecma_date_timezone_t; + /* ecma-builtin-helpers-date.cpp */ extern ecma_number_t ecma_date_day (ecma_number_t time); extern ecma_number_t ecma_date_time_within_day (ecma_number_t time); @@ -90,6 +99,10 @@ extern ecma_number_t ecma_date_make_day (ecma_number_t year, 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); extern ecma_number_t ecma_date_timezone_offset (ecma_number_t time); +extern ecma_completion_value_t ecma_date_set_internal_property (ecma_value_t this_arg, + ecma_number_t day, + ecma_number_t time, + ecma_date_timezone_t is_utc); #endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_DATE_BUILTIN */ typedef struct diff --git a/tests/jerry/date-setters.js b/tests/jerry/date-setters.js new file mode 100644 index 0000000000..10afb08c48 --- /dev/null +++ b/tests/jerry/date-setters.js @@ -0,0 +1,210 @@ +// 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. + +var ms = 1; +var sec = 1000 * ms; +var min = 60 * sec; +var hour = 60 * min; +var day = 24 * hour; /* 86400000 */ +var d = new Date(); + +/* 15.9.5.27 Date.prototype.setTime (time) */ +assert (d.setTime(0) == 0); +d.setTime(0); +assert (d.setTime(day) == day); +assert (d.getDate() == 2); + +/* 15.9.5.28 Date.prototype.setMilliseconds (ms) */ +d.setTime(0); +assert (d.setMilliseconds(1) == ms); +assert (d.getMilliseconds() == 1); + +/* 15.9.5.29 Date.prototype.setUTCMilliseconds (ms) */ +d.setTime(0); +assert (d.setUTCMilliseconds(1) == ms); +assert (d.getUTCMilliseconds() == 1); + +/* 15.9.5.30 Date.prototype.setSeconds (sec [, ms ] ) */ +d.setTime(0); +assert (d.setSeconds(1) == sec); +assert (d.getSeconds() == 1); +d.setTime(0); +assert (d.setSeconds(1, 1) == sec + ms); +assert (d.getSeconds() == 1); +assert (d.getMilliseconds() == 1); + +/* 15.9.5.31 Date.prototype.setUTCSeconds (sec [, ms ] ) */ +d.setTime(0); +assert (d.setUTCSeconds(1) == sec); +assert (d.getUTCSeconds() == 1); +d.setTime(0); +assert (d.setUTCSeconds(1, 1) == sec + ms); +assert (d.getUTCSeconds() == 1); +assert (d.getUTCMilliseconds() == 1); + +/* 15.9.5.32 Date.prototype.setMinutes (min [, sec [, ms ] ] ) */ +d.setTime(0); +assert (d.setMinutes(1) == min); +assert (d.getMinutes() == 1); +d.setTime(0); +assert (d.setMinutes(1, 1) == min + sec); +assert (d.getMinutes() == 1); +assert (d.getSeconds() == 1); +d.setTime(0); +assert (d.setMinutes(1, 1, 1) == min + sec + ms); +assert (d.getMinutes() == 1); +assert (d.getSeconds() == 1); +assert (d.getMilliseconds() == 1); + +/* 15.9.5.33 Date.prototype.setUTCMinutes (min [, sec [, ms ] ] ) */ +d.setTime(0); +assert (d.setUTCMinutes(1) == min); +assert (d.getUTCMinutes() == 1); +d.setTime(0); +assert (d.setUTCMinutes(1, 1) == min + sec); +assert (d.getUTCMinutes() == 1); +assert (d.getUTCSeconds() == 1); +d.setTime(0); +assert (d.setUTCMinutes(1, 1, 1) == min + sec + ms); +assert (d.getUTCMinutes() == 1); +assert (d.getUTCSeconds() == 1); +assert (d.getUTCMilliseconds() == 1); + +/* 15.9.5.34 Date.prototype.setHours (hour [, min [, sec [, ms ] ] ] ) */ +// FIXME: Missing timezone adjustment. +//d.setTime(0); +//assert (d.setHours(1) == hour + d.getTimezoneOffset() * 60000); +//assert (d.getHours() == 1); +//d.setTime(0); +//assert (d.setHours(1, 1) == hour + min + d.getTimezoneOffset() * 60000); +//assert (d.getHours() == 1); +//assert (d.getMinutes() == 1); +//d.setTime(0); +//assert (d.setHours(1, 1, 1) == hour + min + sec + d.getTimezoneOffset() * 60000); +//assert (d.getHours() == 1); +//assert (d.getMinutes() == 1); +//assert (d.getSeconds() == 1); +//d.setTime(0); +//assert (d.setHours(1, 1, 1, 1) == hour + min + sec + ms + d.getTimezoneOffset() * 60000); +//assert (d.getHours() == 1); +//assert (d.getMinutes() == 1); +//assert (d.getSeconds() == 1); +//assert (d.getMilliseconds() == 1); + +/* 15.9.5.35 Date.prototype.setUTCHours (hour [, min [, sec [, ms ] ] ] ) */ +d.setTime(0); +assert (d.setUTCHours(1) == hour); +assert (d.getUTCHours() == 1); +d.setTime(0); +assert (d.setUTCHours(1, 1) == hour + min); +assert (d.getUTCHours() == 1); +assert (d.getUTCMinutes() == 1); +d.setTime(0); +assert (d.setUTCHours(1, 1, 1) == hour + min + sec); +assert (d.getUTCHours() == 1); +assert (d.getUTCMinutes() == 1); +assert (d.getUTCSeconds() == 1); +d.setTime(0); +assert (d.setUTCHours(1, 1, 1, 1) == hour + min + sec + ms); +assert (d.getUTCHours() == 1); +assert (d.getUTCMinutes() == 1); +assert (d.getUTCSeconds() == 1); +assert (d.getUTCMilliseconds() == 1); + +/* 15.9.5.36 Date.prototype.setDate (date) */ +d.setTime(0); +assert (d.setDate(0) == -day); +assert (d.getDate() == 31); +d.setTime(0); +assert (d.setDate(1) == 0); +assert (d.getDate() == 1); + +/* 15.9.5.37 Date.prototype.setUTCDate (date) */ +d.setTime(0); +assert (d.setUTCDate(0) == -day); +assert (d.getUTCDate() == 31); +d.setTime(0); +assert (d.setUTCDate(1) == 0); +assert (d.getUTCDate() == 1); + +/* 15.9.5.38 Date.prototype.setMonth (month [, date ] ) */ +d.setTime(0); +assert (d.setMonth(0) == 0); +assert (d.getMonth() == 0); +d.setTime(0); +assert (d.setMonth(0, 0) == -day); +assert (d.getMonth() == 11); +assert (d.getDate() == 31); +d.setTime(0); +assert (d.setMonth(1) == 31 * day); +assert (d.getMonth() == 1); +d.setTime(0); +assert (d.setMonth(12) == 365 * day); +assert (d.getMonth() == 0); +d.setTime(0); +assert (d.setMonth(13) == (365 + 31) * day); +assert (d.getMonth() == 1); + +/* 15.9.5.39 Date.prototype.setUTCMonth (month [, date ] ) */ +d.setTime(0); +assert (d.setUTCMonth(0) == 0); +assert (d.getUTCMonth() == 0); +d.setTime(0); +assert (d.setUTCMonth(0, 0) == -day); +assert (d.getUTCMonth() == 11); +assert (d.getUTCDate() == 31); +d.setTime(0); +assert (d.setUTCMonth(1) == 31 * day); +assert (d.getUTCMonth() == 1); +d.setTime(0); +assert (d.setUTCMonth(12) == 365 * day); +assert (d.getUTCMonth() == 0); +d.setTime(0); +assert (d.setUTCMonth(13) == (365 + 31) * day); +assert (d.getUTCMonth() == 1); + +/* 15.9.5.40 Date.prototype.setFullYear (year [, month [, date ] ] ) */ +d.setTime(0); +assert (d.setFullYear(0) == -62167219200000); +assert (d.getFullYear() == 0); +d.setTime(0); +assert (d.setFullYear(0, 0) == -62167219200000); +assert (d.getFullYear() == 0); +assert (d.getMonth() == 0); +d.setTime(0); +assert (d.setFullYear(0, 0, 0) == -62167219200000 - day); +assert (d.getFullYear() == -1); +assert (d.getMonth() == 11); +assert (d.getDate() == 31); +d.setTime(0); +assert (d.setFullYear(1970) == 0); +assert (d.getFullYear() == 1970); + +/* 15.9.5.41 Date.prototype.setUTCFullYear (year [, month [, date ] ] ) */ +d.setTime(0); +assert (d.setUTCFullYear(0) == -62167219200000); +assert (d.getUTCFullYear() == 0); +d.setTime(0); +assert (d.setUTCFullYear(0, 0) == -62167219200000); +assert (d.getUTCFullYear() == 0); +assert (d.getUTCMonth() == 0); +d.setTime(0); +assert (d.setUTCFullYear(0, 0, 0) == -62167219200000 - day); +assert (d.getUTCFullYear() == -1); +assert (d.getUTCMonth() == 11); +assert (d.getUTCDate() == 31); +d.setTime(0); +assert (d.setUTCFullYear(1970) == 0); +assert (d.getUTCFullYear() == 1970);