diff options
author | Linus Groh <mail@linusgroh.de> | 2022-05-06 20:45:25 +0200 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-05-06 22:32:47 +0200 |
commit | f7c9bd0760d21e1c32d59cb62fe36728736b47bd (patch) | |
tree | 6efb90cf7551e6b22970c86effef9ed8bbe65325 | |
parent | b9b3d01bea2b8e5455f17eedf1acd6ac9ffe31ec (diff) | |
download | serenity-f7c9bd0760d21e1c32d59cb62fe36728736b47bd.zip |
LibJS: Convert remaining Date AOs using JS::Value as in/output to double
There was an awful lot of JS::Value <-> double conversion going on, even
through these AOs only work with number values anyway.
They don't need a global object either as they won't allocate or throw,
that was simply to pass it to infallible calls of ToIntegerOrInfinity.
10 files changed, 357 insertions, 354 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/Date.cpp b/Userland/Libraries/LibJS/Runtime/Date.cpp index 078036b2d2..9d68e369b1 100644 --- a/Userland/Libraries/LibJS/Runtime/Date.cpp +++ b/Userland/Libraries/LibJS/Runtime/Date.cpp @@ -300,25 +300,25 @@ double utc_time(double time) } // 21.4.1.11 MakeTime ( hour, min, sec, ms ), https://tc39.es/ecma262/#sec-maketime -Value make_time(GlobalObject& global_object, Value hour, Value min, Value sec, Value ms) +double make_time(double hour, double min, double sec, double ms) { // 1. If hour is not finite or min is not finite or sec is not finite or ms is not finite, return NaN. - if (!hour.is_finite_number() || !min.is_finite_number() || !sec.is_finite_number() || !ms.is_finite_number()) - return js_nan(); + if (!isfinite(hour) || !isfinite(min) || !isfinite(sec) || !isfinite(ms)) + return NAN; // 2. Let h be ๐ฝ(! ToIntegerOrInfinity(hour)). - auto h = MUST(hour.to_integer_or_infinity(global_object)); + auto h = to_integer_or_infinity(hour); // 3. Let m be ๐ฝ(! ToIntegerOrInfinity(min)). - auto m = MUST(min.to_integer_or_infinity(global_object)); + auto m = to_integer_or_infinity(min); // 4. Let s be ๐ฝ(! ToIntegerOrInfinity(sec)). - auto s = MUST(sec.to_integer_or_infinity(global_object)); + auto s = to_integer_or_infinity(sec); // 5. Let milli be ๐ฝ(! ToIntegerOrInfinity(ms)). - auto milli = MUST(ms.to_integer_or_infinity(global_object)); + auto milli = to_integer_or_infinity(ms); // 6. Let t be ((h * msPerHour + m * msPerMinute) + s * msPerSecond) + milli, performing the arithmetic according to IEEE 754-2019 rules (that is, as if using the ECMAScript operators * and +). // NOTE: C++ arithmetic abides by IEEE 754 rules auto t = ((h * ms_per_hour + m * ms_per_minute) + s * ms_per_second) + milli; // 7. Return t. - return Value(t); + return t; } // Day(t), https://tc39.es/ecma262/#eqn-Day @@ -335,69 +335,69 @@ double time_within_day(double time) } // 21.4.1.12 MakeDay ( year, month, date ), https://tc39.es/ecma262/#sec-makeday -Value make_day(GlobalObject& global_object, Value year, Value month, Value date) +double make_day(double year, double month, double date) { // 1. If year is not finite or month is not finite or date is not finite, return NaN. - if (!year.is_finite_number() || !month.is_finite_number() || !date.is_finite_number()) - return js_nan(); + if (!isfinite(year) || !isfinite(month) || !isfinite(date)) + return NAN; // 2. Let y be ๐ฝ(! ToIntegerOrInfinity(year)). - auto y = MUST(year.to_integer_or_infinity(global_object)); + auto y = to_integer_or_infinity(year); // 3. Let m be ๐ฝ(! ToIntegerOrInfinity(month)). - auto m = MUST(month.to_integer_or_infinity(global_object)); + auto m = to_integer_or_infinity(month); // 4. Let dt be ๐ฝ(! ToIntegerOrInfinity(date)). - auto dt = MUST(date.to_integer_or_infinity(global_object)); + auto dt = to_integer_or_infinity(date); // 5. Let ym be y + ๐ฝ(floor(โ(m) / 12)). auto ym = y + floor(m / 12); // 6. If ym is not finite, return NaN. - if (!Value(ym).is_finite_number()) - return js_nan(); + if (!isfinite(ym)) + return NAN; // 7. Let mn be ๐ฝ(โ(m) modulo 12). auto mn = modulo(m, 12); // 8. Find a finite time value t such that YearFromTime(t) is ym and MonthFromTime(t) is mn and DateFromTime(t) is 1๐ฝ; but if this is not possible (because some argument is out of range), return NaN. if (!AK::is_within_range<int>(ym) || !AK::is_within_range<int>(mn + 1)) - return js_nan(); + return NAN; // FIXME: We are avoiding AK::years_to_days_since_epoch here because it is implemented by looping over // the range [1970, ym), which will spin for any time value with an extremely large year. auto t = time_from_year(ym) + (day_of_year(static_cast<int>(ym), static_cast<int>(mn) + 1, 1) * ms_per_day); // 9. Return Day(t) + dt - 1๐ฝ. - return Value(day(static_cast<double>(t)) + dt - 1); + return day(static_cast<double>(t)) + dt - 1; } // 21.4.1.13 MakeDate ( day, time ), https://tc39.es/ecma262/#sec-makedate -Value make_date(Value day, Value time) +double make_date(double day, double time) { // 1. If day is not finite or time is not finite, return NaN. - if (!day.is_finite_number() || !time.is_finite_number()) - return js_nan(); + if (!isfinite(day) || !isfinite(time)) + return NAN; // 2. Let tv be day ร msPerDay + time. - auto tv = Value(day.as_double() * ms_per_day + time.as_double()); + auto tv = day * ms_per_day + time; // 3. If tv is not finite, return NaN. - if (!tv.is_finite_number()) - return js_nan(); + if (!isfinite(tv)) + return NAN; // 4. Return tv. return tv; } // 21.4.1.14 TimeClip ( time ), https://tc39.es/ecma262/#sec-timeclip -Value time_clip(GlobalObject& global_object, Value time) +double time_clip(double time) { // 1. If time is not finite, return NaN. - if (!time.is_finite_number()) - return js_nan(); + if (!isfinite(time)) + return NAN; // 2. If abs(โ(time)) > 8.64 ร 10^15, return NaN. - if (fabs(time.as_double()) > 8.64E15) - return js_nan(); + if (fabs(time) > 8.64E15) + return NAN; // 3. Return ๐ฝ(! ToIntegerOrInfinity(time)). - return Value(MUST(time.to_integer_or_infinity(global_object))); + return to_integer_or_infinity(time); } } diff --git a/Userland/Libraries/LibJS/Runtime/Date.h b/Userland/Libraries/LibJS/Runtime/Date.h index 25748c9030..6bcbf2d792 100644 --- a/Userland/Libraries/LibJS/Runtime/Date.h +++ b/Userland/Libraries/LibJS/Runtime/Date.h @@ -63,9 +63,9 @@ double local_time(double time); double utc_time(double time); double day(double); double time_within_day(double); -Value make_time(GlobalObject& global_object, Value hour, Value min, Value sec, Value ms); -Value make_day(GlobalObject& global_object, Value year, Value month, Value date); -Value make_date(Value day, Value time); -Value time_clip(GlobalObject& global_object, Value time); +double make_time(double hour, double min, double sec, double ms); +double make_day(double year, double month, double date); +double make_date(double day, double time); +double time_clip(double time); } diff --git a/Userland/Libraries/LibJS/Runtime/DateConstructor.cpp b/Userland/Libraries/LibJS/Runtime/DateConstructor.cpp index 9db88ebc88..f375e7b975 100644 --- a/Userland/Libraries/LibJS/Runtime/DateConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/DateConstructor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Linus Groh <linusg@serenityos.org> + * Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org> * Copyright (c) 2020, Nico Weber <thakis@chromium.org> * Copyright (c) 2021, Petrรณczi Zoltรกn <petroczizoltan@tutanota.com> * Copyright (c) 2022, Tim Flynn <trflynn89@serenityos.org> @@ -23,7 +23,7 @@ namespace JS { // 21.4.3.2 Date.parse ( string ), https://tc39.es/ecma262/#sec-date.parse -static Value parse_simplified_iso8601(GlobalObject& global_object, String const& iso_8601) +static double parse_simplified_iso8601(String const& iso_8601) { // 21.4.1.15 Date Time String Format, https://tc39.es/ecma262/#sec-date-time-string-format GenericLexer lexer(iso_8601); @@ -126,7 +126,7 @@ static Value parse_simplified_iso8601(GlobalObject& global_object, String const& auto lex_time = [&]() { return lex_hours_minutes(hours, minutes) && (!lexer.consume_specific(':') || lex_seconds_milliseconds()) && lex_timezone(); }; if (!lex_date() || (lexer.consume_specific('T') && !lex_time()) || !lexer.is_eof()) { - return js_nan(); + return NAN; } // We parsed a valid date simplified ISO 8601 string. @@ -144,22 +144,22 @@ static Value parse_simplified_iso8601(GlobalObject& global_object, String const& else if (timezone == '+') time_ms -= *timezone_hours * 3'600'000 + *timezone_minutes * 60'000; - return time_clip(global_object, Value(time_ms)); + return time_clip(time_ms); } -static Value parse_date_string(GlobalObject& global_object, String const& date_string) +static double parse_date_string(String const& date_string) { - auto value = parse_simplified_iso8601(global_object, date_string); - if (value.is_finite_number()) + auto value = parse_simplified_iso8601(date_string); + if (isfinite(value)) return value; // Date.parse() is allowed to accept an arbitrary number of implementation-defined formats. // Parse formats of this type: "Wed Apr 17 23:08:53 +0000 2019" auto maybe_datetime = Core::DateTime::parse("%a %b %e %T %z %Y", date_string); if (maybe_datetime.has_value()) - return Value(1000.0 * maybe_datetime.value().timestamp()); + return 1000.0 * maybe_datetime->timestamp(); - return js_nan(); + return NAN; } DateConstructor::DateConstructor(GlobalObject& global_object) @@ -200,20 +200,20 @@ ThrowCompletionOr<Object*> DateConstructor::construct(FunctionObject& new_target auto& vm = this->vm(); auto& global_object = this->global_object(); - Value date_value; + double date_value; // 2. Let numberOfArgs be the number of elements in values. // 3. If numberOfArgs = 0, then if (vm.argument_count() == 0) { // a. Let dv be the time value (UTC) identifying the current time. auto now = AK::Time::now_realtime().to_milliseconds(); - date_value = Value(static_cast<double>(now)); + date_value = static_cast<double>(now); } // 4. Else if numberOfArgs = 1, then else if (vm.argument_count() == 1) { // a. Let value be values[0]. auto value = vm.argument(0); - Value time_value; + double time_value; // b. If Type(value) is Object and value has a [[DateValue]] internal slot, then if (value.is_object() && is<Date>(value.as_object())) { @@ -229,28 +229,28 @@ ThrowCompletionOr<Object*> DateConstructor::construct(FunctionObject& new_target if (primitive.is_string()) { // 1. Assert: The next step never returns an abrupt completion because Type(v) is String. // 2. Let tv be the result of parsing v as a date, in exactly the same manner as for the parse method (21.4.3.2). - time_value = parse_date_string(global_object, primitive.as_string().string()); + time_value = parse_date_string(primitive.as_string().string()); } // iii. Else, else { // 1. Let tv be ? ToNumber(v). - time_value = TRY(primitive.to_number(global_object)); + time_value = TRY(primitive.to_number(global_object)).as_double(); } } // d. Let dv be TimeClip(tv). - date_value = time_clip(global_object, time_value); + date_value = time_clip(time_value); } // 5. Else, else { // a. Assert: numberOfArgs โฅ 2. // b. Let y be ? ToNumber(values[0]). - auto year = TRY(vm.argument(0).to_number(global_object)); + auto year = TRY(vm.argument(0).to_number(global_object)).as_double(); // c. Let m be ? ToNumber(values[1]). - auto month = TRY(vm.argument(1).to_number(global_object)); + auto month = TRY(vm.argument(1).to_number(global_object)).as_double(); - auto arg_or = [&vm, &global_object](size_t i, i32 fallback) -> ThrowCompletionOr<Value> { - return vm.argument_count() > i ? vm.argument(i).to_number(global_object) : Value(fallback); + auto arg_or = [&vm, &global_object](size_t i, double fallback) -> ThrowCompletionOr<double> { + return vm.argument_count() > i ? TRY(vm.argument(i).to_number(global_object)).as_double() : fallback; }; // d. If numberOfArgs > 2, let dt be ? ToNumber(values[2]); else let dt be 1๐ฝ. @@ -266,28 +266,28 @@ ThrowCompletionOr<Object*> DateConstructor::construct(FunctionObject& new_target // i. If y is NaN, let yr be NaN. // j. Else, - if (!year.is_nan()) { + if (!isnan(year)) { // i. Let yi be ! ToIntegerOrInfinity(y). - auto year_double = MUST(year.to_integer_or_infinity(global_object)); + auto year_integer = to_integer_or_infinity(year); // ii. If 0 โค yi โค 99, let yr be 1900๐ฝ + ๐ฝ(yi); otherwise, let yr be y. - if (0 <= year_double && year_double <= 99) - year = Value(1900 + year_double); + if (0 <= year_integer && year_integer <= 99) + year = 1900 + year_integer; } // k. Let finalDate be MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli)). - auto day = make_day(global_object, year, month, date); - auto time = make_time(global_object, hours, minutes, seconds, milliseconds); + auto day = make_day(year, month, date); + auto time = make_time(hours, minutes, seconds, milliseconds); auto final_date = make_date(day, time); // l. Let dv be TimeClip(UTC(finalDate)). - date_value = time_clip(global_object, Value(utc_time(final_date.as_double()))); + date_value = time_clip(utc_time(final_date)); } // 6. Let O be ? OrdinaryCreateFromConstructor(NewTarget, "%Date.prototype%", ยซ [[DateValue]] ยป). // 7. Set O.[[DateValue]] to dv. // 8. Return O. - return TRY(ordinary_create_from_constructor<Date>(global_object, new_target, &GlobalObject::date_prototype, date_value.as_double())); + return TRY(ordinary_create_from_constructor<Date>(global_object, new_target, &GlobalObject::date_prototype, date_value)); } // 21.4.3.1 Date.now ( ), https://tc39.es/ecma262/#sec-date.now @@ -306,18 +306,18 @@ JS_DEFINE_NATIVE_FUNCTION(DateConstructor::parse) auto date_string = TRY(vm.argument(0).to_string(global_object)); - return parse_date_string(global_object, date_string); + return Value(parse_date_string(date_string)); } // 21.4.3.4 Date.UTC ( year [ , month [ , date [ , hours [ , minutes [ , seconds [ , ms ] ] ] ] ] ] ), https://tc39.es/ecma262/#sec-date.utc JS_DEFINE_NATIVE_FUNCTION(DateConstructor::utc) { - auto arg_or = [&vm, &global_object](size_t i, i32 fallback) -> ThrowCompletionOr<Value> { - return vm.argument_count() > i ? vm.argument(i).to_number(global_object) : Value(fallback); + auto arg_or = [&vm, &global_object](size_t i, double fallback) -> ThrowCompletionOr<double> { + return vm.argument_count() > i ? TRY(vm.argument(i).to_number(global_object)).as_double() : fallback; }; // 1. Let y be ? ToNumber(year). - auto year = TRY(vm.argument(0).to_number(global_object)); + auto year = TRY(vm.argument(0).to_number(global_object)).as_double(); // 2. If month is present, let m be ? ToNumber(month); else let m be +0๐ฝ. auto month = TRY(arg_or(1, 0)); // 3. If date is present, let dt be ? ToNumber(date); else let dt be 1๐ฝ. @@ -333,19 +333,19 @@ JS_DEFINE_NATIVE_FUNCTION(DateConstructor::utc) // 8. If y is NaN, let yr be NaN. // 9. Else, - if (!year.is_nan()) { + if (!isnan(year)) { // a. Let yi be ! ToIntegerOrInfinity(y). - auto year_double = MUST(year.to_integer_or_infinity(global_object)); + auto year_integer = to_integer_or_infinity(year); // b. If 0 โค yi โค 99, let yr be 1900๐ฝ + ๐ฝ(yi); otherwise, let yr be y. - if (0 <= year_double && year_double <= 99) - year = Value(1900 + year_double); + if (0 <= year_integer && year_integer <= 99) + year = 1900 + year_integer; } // 10. Return TimeClip(MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli))). - auto day = make_day(global_object, year, month, date); - auto time = make_time(global_object, hours, minutes, seconds, milliseconds); - return time_clip(global_object, make_date(day, time)); + auto day = make_day(year, month, date); + auto time = make_time(hours, minutes, seconds, milliseconds); + return Value(time_clip(make_date(day, time))); } } diff --git a/Userland/Libraries/LibJS/Runtime/DatePrototype.cpp b/Userland/Libraries/LibJS/Runtime/DatePrototype.cpp index b466c3aeca..23bab1fa9a 100644 --- a/Userland/Libraries/LibJS/Runtime/DatePrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/DatePrototype.cpp @@ -99,12 +99,12 @@ void DatePrototype::initialize(GlobalObject& global_object) } // thisTimeValue ( value ), https://tc39.es/ecma262/#thistimevalue -ThrowCompletionOr<Value> this_time_value(GlobalObject& global_object, Value value) +ThrowCompletionOr<double> this_time_value(GlobalObject& global_object, Value value) { // 1. If Type(value) is Object and value has a [[DateValue]] internal slot, then if (value.is_object() && is<Date>(value.as_object())) { // a. Return value.[[DateValue]]. - return Value(static_cast<Date&>(value.as_object()).date_value()); + return static_cast<Date&>(value.as_object()).date_value(); } // 2. Throw a TypeError exception. @@ -119,11 +119,11 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_date) auto time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. If t is NaN, return NaN. - if (time.is_nan()) - return time; + if (isnan(time)) + return js_nan(); // 3. Return DateFromTime(LocalTime(t)). - return Value(date_from_time(local_time(time.as_double()))); + return Value(date_from_time(local_time(time))); } // 21.4.4.3 Date.prototype.getDay ( ), https://tc39.es/ecma262/#sec-date.prototype.getday @@ -133,11 +133,11 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_day) auto time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. If t is NaN, return NaN. - if (time.is_nan()) - return time; + if (isnan(time)) + return js_nan(); // 3. Return WeekDay(LocalTime(t)). - return Value(week_day(local_time(time.as_double()))); + return Value(week_day(local_time(time))); } // 21.4.4.4 Date.prototype.getFullYear ( ), https://tc39.es/ecma262/#sec-date.prototype.getfullyear @@ -147,11 +147,11 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_full_year) auto time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. If t is NaN, return NaN. - if (time.is_nan()) - return time; + if (isnan(time)) + return js_nan(); // 3. Return YearFromTime(LocalTime(t)). - return Value(year_from_time(local_time(time.as_double()))); + return Value(year_from_time(local_time(time))); } // 21.4.4.5 Date.prototype.getHours ( ), https://tc39.es/ecma262/#sec-date.prototype.gethours @@ -161,11 +161,11 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_hours) auto time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. If t is NaN, return NaN. - if (time.is_nan()) - return time; + if (isnan(time)) + return js_nan(); // 3. Return HourFromTime(LocalTime(t)). - return Value(hour_from_time(local_time(time.as_double()))); + return Value(hour_from_time(local_time(time))); } // 21.4.4.6 Date.prototype.getMilliseconds ( ), https://tc39.es/ecma262/#sec-date.prototype.getmilliseconds @@ -175,11 +175,11 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_milliseconds) auto time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. If t is NaN, return NaN. - if (time.is_nan()) - return time; + if (isnan(time)) + return js_nan(); // 3. Return msFromTime(LocalTime(t)). - return Value(ms_from_time(local_time(time.as_double()))); + return Value(ms_from_time(local_time(time))); } // 21.4.4.7 Date.prototype.getMinutes ( ), https://tc39.es/ecma262/#sec-date.prototype.getminutes @@ -189,11 +189,11 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_minutes) auto time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. If t is NaN, return NaN. - if (time.is_nan()) - return time; + if (isnan(time)) + return js_nan(); // 3. Return MinFromTime(LocalTime(t)). - return Value(min_from_time(local_time(time.as_double()))); + return Value(min_from_time(local_time(time))); } // 21.4.4.8 Date.prototype.getMonth ( ), https://tc39.es/ecma262/#sec-date.prototype.getmonth @@ -203,11 +203,11 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_month) auto time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. If t is NaN, return NaN. - if (time.is_nan()) - return time; + if (isnan(time)) + return js_nan(); // 3. Return MonthFromTime(LocalTime(t)). - return Value(month_from_time(local_time(time.as_double()))); + return Value(month_from_time(local_time(time))); } // 21.4.4.9 Date.prototype.getSeconds ( ), https://tc39.es/ecma262/#sec-date.prototype.getseconds @@ -217,18 +217,18 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_seconds) auto time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. If t is NaN, return NaN. - if (time.is_nan()) - return time; + if (isnan(time)) + return js_nan(); // 3. Return SecFromTime(LocalTime(t)). - return Value(sec_from_time(local_time(time.as_double()))); + return Value(sec_from_time(local_time(time))); } // 21.4.4.10 Date.prototype.getTime ( ), https://tc39.es/ecma262/#sec-date.prototype.gettime JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_time) { // 1. Return ? thisTimeValue(this value). - return this_time_value(global_object, vm.this_value(global_object)); + return Value(TRY(this_time_value(global_object, vm.this_value(global_object)))); } // 21.4.4.11 Date.prototype.getTimezoneOffset ( ), https://tc39.es/ecma262/#sec-date.prototype.gettimezoneoffset @@ -238,11 +238,11 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_timezone_offset) auto time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. If t is NaN, return NaN. - if (time.is_nan()) + if (isnan(time)) return js_nan(); // 3. Return (t - LocalTime(t)) / msPerMinute. - return Value((time.as_double() - local_time(time.as_double())) / ms_per_minute); + return Value((time - local_time(time)) / ms_per_minute); } // 21.4.4.12 Date.prototype.getUTCDate ( ), https://tc39.es/ecma262/#sec-date.prototype.getutcdate @@ -252,11 +252,11 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_date) auto time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. If t is NaN, return NaN. - if (time.is_nan()) - return time; + if (isnan(time)) + return js_nan(); // 3. Return DateFromTime(t). - return Value(date_from_time(time.as_double())); + return Value(date_from_time(time)); } // 21.4.4.13 Date.prototype.getUTCDay ( ), https://tc39.es/ecma262/#sec-date.prototype.getutcday @@ -266,11 +266,11 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_day) auto time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. If t is NaN, return NaN. - if (time.is_nan()) - return time; + if (isnan(time)) + return js_nan(); // 3. Return WeekDay(t). - return Value(week_day(time.as_double())); + return Value(week_day(time)); } // 21.4.4.14 Date.prototype.getUTCFullYear ( ), https://tc39.es/ecma262/#sec-date.prototype.getutcfullyear @@ -280,11 +280,11 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_full_year) auto time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. If t is NaN, return NaN. - if (time.is_nan()) - return time; + if (isnan(time)) + return js_nan(); // 3. Return YearFromTime(t). - return Value(year_from_time(time.as_double())); + return Value(year_from_time(time)); } // 21.4.4.15 Date.prototype.getUTCHours ( ), https://tc39.es/ecma262/#sec-date.prototype.getutchours @@ -294,11 +294,11 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_hours) auto time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. If t is NaN, return NaN. - if (time.is_nan()) - return time; + if (isnan(time)) + return js_nan(); // 3. Return HourFromTime(t). - return Value(hour_from_time(time.as_double())); + return Value(hour_from_time(time)); } // 21.4.4.16 Date.prototype.getUTCMilliseconds ( ), https://tc39.es/ecma262/#sec-date.prototype.getutcmilliseconds @@ -308,11 +308,11 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_milliseconds) auto time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. If t is NaN, return NaN. - if (time.is_nan()) - return time; + if (isnan(time)) + return js_nan(); // 3. Return msFromTime(t). - return Value(ms_from_time(time.as_double())); + return Value(ms_from_time(time)); } // 21.4.4.17 Date.prototype.getUTCMinutes ( ), https://tc39.es/ecma262/#sec-date.prototype.getutcminutes @@ -322,11 +322,11 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_minutes) auto time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. If t is NaN, return NaN. - if (time.is_nan()) - return time; + if (isnan(time)) + return js_nan(); // 3. Return MinFromTime(t). - return Value(min_from_time(time.as_double())); + return Value(min_from_time(time)); } // 21.4.4.18 Date.prototype.getUTCMonth ( ), https://tc39.es/ecma262/#sec-date.prototype.getutcmonth @@ -336,11 +336,11 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_month) auto time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. If t is NaN, return NaN. - if (time.is_nan()) - return time; + if (isnan(time)) + return js_nan(); // 3. Return MonthFromTime(t). - return Value(month_from_time(time.as_double())); + return month_from_time(time); } // 21.4.4.19 Date.prototype.getUTCSeconds ( ), https://tc39.es/ecma262/#sec-date.prototype.getutcseconds @@ -350,32 +350,31 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_utc_seconds) auto time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. If t is NaN, return NaN. - if (time.is_nan()) - return time; + if (isnan(time)) + return js_nan(); // 3. Return SecFromTime(t). - return Value(sec_from_time(time.as_double())); + return Value(sec_from_time(time)); } -template<typename T> -static ThrowCompletionOr<Value> argument_or_value(GlobalObject& global_object, size_t index, T fallback) +static ThrowCompletionOr<double> argument_or_number(GlobalObject& global_object, size_t index, double fallback) { auto& vm = global_object.vm(); if (vm.argument_count() > index) - return vm.argument(index).to_number(global_object); + return TRY(vm.argument(index).to_number(global_object)).as_double(); - return Value(fallback); + return fallback; } -static ThrowCompletionOr<Optional<Value>> argument_or_empty(GlobalObject& global_object, size_t index) +static ThrowCompletionOr<Optional<double>> argument_or_empty(GlobalObject& global_object, size_t index) { auto& vm = global_object.vm(); if (vm.argument_count() > index) - return TRY(vm.argument(index).to_number(global_object)); + return TRY(vm.argument(index).to_number(global_object)).as_double(); - return Optional<Value> {}; + return Optional<double> {}; } // 21.4.4.20 Date.prototype.setDate ( date ), https://tc39.es/ecma262/#sec-date.prototype.setdate @@ -385,31 +384,31 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_date) auto this_time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. Let dt be ? ToNumber(date). - auto date = TRY(vm.argument(0).to_number(global_object)); + auto date = TRY(vm.argument(0).to_number(global_object)).as_double(); // 3. If t is NaN, return NaN. - if (this_time.is_nan()) + if (isnan(this_time)) return js_nan(); // 4. Set t to LocalTime(t). - auto time = local_time(this_time.as_double()); + auto time = local_time(this_time); // 5. Let newDate be MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), dt), TimeWithinDay(t)). - auto year = Value(year_from_time(time)); - auto month = Value(month_from_time(time)); + auto year = year_from_time(time); + auto month = month_from_time(time); - auto day = make_day(global_object, year, month, date); - auto new_date = make_date(day, Value(time_within_day(time))); + auto day = make_day(year, month, date); + auto new_date = make_date(day, time_within_day(time)); // 6. Let u be TimeClip(UTC(newDate)). - new_date = time_clip(global_object, Value(utc_time(new_date.as_double()))); + new_date = time_clip(utc_time(new_date)); // 7. Set the [[DateValue]] internal slot of this Date object to u. auto* this_object = MUST(typed_this_object(global_object)); - this_object->set_date_value(new_date.as_double()); + this_object->set_date_value(new_date); // 8. Return u. - return new_date; + return Value(new_date); } // 21.4.4.21 Date.prototype.setFullYear ( year [ , month [ , date ] ] ), https://tc39.es/ecma262/#sec-date.prototype.setfullyear @@ -419,32 +418,32 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_full_year) auto this_time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. Let y be ? ToNumber(year). - auto year = TRY(vm.argument(0).to_number(global_object)); + auto year = TRY(vm.argument(0).to_number(global_object)).as_double(); // 3. If t is NaN, set t to +0๐ฝ; otherwise, set t to LocalTime(t). double time = 0; - if (!this_time.is_nan()) - time = local_time(this_time.as_double()); + if (!isnan(this_time)) + time = local_time(this_time); // 4. If month is not present, let m be MonthFromTime(t); otherwise, let m be ? ToNumber(month). - auto month = TRY(argument_or_value(global_object, 1, month_from_time(time))); + auto month = TRY(argument_or_number(global_object, 1, month_from_time(time))); // 5. If date is not present, let dt be DateFromTime(t); otherwise, let dt be ? ToNumber(date). - auto date = TRY(argument_or_value(global_object, 2, date_from_time(time))); + auto date = TRY(argument_or_number(global_object, 2, date_from_time(time))); // 6. Let newDate be MakeDate(MakeDay(y, m, dt), TimeWithinDay(t)). - auto day = make_day(global_object, year, month, date); - auto new_date = make_date(day, Value(time_within_day(time))); + auto day = make_day(year, month, date); + auto new_date = make_date(day, time_within_day(time)); // 7. Let u be TimeClip(UTC(newDate)). - new_date = time_clip(global_object, Value(utc_time(new_date.as_double()))); + new_date = time_clip(utc_time(new_date)); // 8. Set the [[DateValue]] internal slot of this Date object to u. auto* this_object = MUST(typed_this_object(global_object)); - this_object->set_date_value(new_date.as_double()); + this_object->set_date_value(new_date); // 9. Return u. - return new_date; + return Value(new_date); } // 21.4.4.22 Date.prototype.setHours ( hour [ , min [ , sec [ , ms ] ] ] ), https://tc39.es/ecma262/#sec-date.prototype.sethours @@ -454,7 +453,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_hours) auto this_time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. Let h be ? ToNumber(hour). - auto hour = TRY(vm.argument(0).to_number(global_object)); + auto hour = TRY(vm.argument(0).to_number(global_object)).as_double(); // 3. If min is present, let m be ? ToNumber(min). auto minute = TRY(argument_or_empty(global_object, 1)); @@ -466,37 +465,37 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_hours) auto millisecond = TRY(argument_or_empty(global_object, 3)); // 6. If t is NaN, return NaN. - if (this_time.is_nan()) + if (isnan(this_time)) return js_nan(); // 7. Set t to LocalTime(t). - auto time = local_time(this_time.as_double()); + auto time = local_time(this_time); // 8. If min is not present, let m be MinFromTime(t). if (!minute.has_value()) - minute = Value(min_from_time(time)); + minute = min_from_time(time); // 9. If sec is not present, let s be SecFromTime(t). if (!second.has_value()) - second = Value(sec_from_time(time)); + second = sec_from_time(time); // 10. If ms is not present, let milli be msFromTime(t). if (!millisecond.has_value()) - millisecond = Value(ms_from_time(time)); + millisecond = ms_from_time(time); // 11. Let date be MakeDate(Day(t), MakeTime(h, m, s, milli)). - auto new_time = make_time(global_object, hour, *minute, *second, *millisecond); - auto date = make_date(Value(day(time)), new_time); + auto new_time = make_time(hour, *minute, *second, *millisecond); + auto date = make_date(day(time), new_time); // 12. Let u be TimeClip(UTC(date)). - date = time_clip(global_object, Value(utc_time(date.as_double()))); + date = time_clip(utc_time(date)); // 13. Set the [[DateValue]] internal slot of this Date object to u. auto* this_object = MUST(typed_this_object(global_object)); - this_object->set_date_value(date.as_double()); + this_object->set_date_value(date); // 14. Return u. - return date; + return Value(date); } // 21.4.4.23 Date.prototype.setMilliseconds ( ms ), https://tc39.es/ecma262/#sec-date.prototype.setmilliseconds @@ -506,32 +505,32 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_milliseconds) auto this_time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. Set ms to ? ToNumber(ms). - auto millisecond = TRY(vm.argument(0).to_number(global_object)); + auto millisecond = TRY(vm.argument(0).to_number(global_object)).as_double(); // 3. If t is NaN, return NaN. - if (this_time.is_nan()) + if (isnan(this_time)) return js_nan(); // 4. Set t to LocalTime(t). - auto time = local_time(this_time.as_double()); + auto time = local_time(this_time); // 5. Let time be MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms). - auto hour = Value(hour_from_time(time)); - auto minute = Value(min_from_time(time)); - auto second = Value(sec_from_time(time)); + auto hour = hour_from_time(time); + auto minute = min_from_time(time); + auto second = sec_from_time(time); - auto new_time = make_time(global_object, hour, minute, second, millisecond); + auto new_time = make_time(hour, minute, second, millisecond); // 6. Let u be TimeClip(UTC(MakeDate(Day(t), time))). - auto date = make_date(Value(day(time)), new_time); - date = time_clip(global_object, Value(utc_time(date.as_double()))); + auto date = make_date(day(time), new_time); + date = time_clip(utc_time(date)); // 7. Set the [[DateValue]] internal slot of this Date object to u. auto* this_object = MUST(typed_this_object(global_object)); - this_object->set_date_value(date.as_double()); + this_object->set_date_value(date); // 8. Return u. - return date; + return Value(date); } // 21.4.4.24 Date.prototype.setMinutes ( min [ , sec [ , ms ] ] ), https://tc39.es/ecma262/#sec-date.prototype.setminutes @@ -541,7 +540,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_minutes) auto this_time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. Let m be ? ToNumber(min). - auto minute = TRY(vm.argument(0).to_number(global_object)); + auto minute = TRY(vm.argument(0).to_number(global_object)).as_double(); // 3. If sec is present, let s be ? ToNumber(sec). auto second = TRY(argument_or_empty(global_object, 1)); @@ -550,35 +549,35 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_minutes) auto millisecond = TRY(argument_or_empty(global_object, 2)); // 5. If t is NaN, return NaN. - if (this_time.is_nan()) + if (isnan(this_time)) return js_nan(); // 6. Set t to LocalTime(t). - auto time = local_time(this_time.as_double()); + auto time = local_time(this_time); // 7. If sec is not present, let s be SecFromTime(t). if (!second.has_value()) - second = Value(sec_from_time(time)); + second = sec_from_time(time); // 8. If ms is not present, let milli be msFromTime(t). if (!millisecond.has_value()) - millisecond = Value(ms_from_time(time)); + millisecond = ms_from_time(time); // 9. Let date be MakeDate(Day(t), MakeTime(HourFromTime(t), m, s, milli)). - auto hour = Value(hour_from_time(time)); + auto hour = hour_from_time(time); - auto new_time = make_time(global_object, hour, minute, *second, *millisecond); - auto date = make_date(Value(day(time)), new_time); + auto new_time = make_time(hour, minute, *second, *millisecond); + auto date = make_date(day(time), new_time); // 10. Let u be TimeClip(UTC(date)). - date = time_clip(global_object, Value(utc_time(date.as_double()))); + date = time_clip(utc_time(date)); // 11. Set the [[DateValue]] internal slot of this Date object to u. auto* this_object = MUST(typed_this_object(global_object)); - this_object->set_date_value(date.as_double()); + this_object->set_date_value(date); // 12. Return u. - return date; + return Value(date); } // 21.4.4.25 Date.prototype.setMonth ( month [ , date ] ), https://tc39.es/ecma262/#sec-date.prototype.setmonth @@ -588,37 +587,37 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_month) auto this_time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. Let m be ? ToNumber(month). - auto month = TRY(vm.argument(0).to_number(global_object)); + auto month = TRY(vm.argument(0).to_number(global_object)).as_double(); // 3. If date is present, let dt be ? ToNumber(date). auto date = TRY(argument_or_empty(global_object, 1)); // 4. If t is NaN, return NaN. - if (this_time.is_nan()) + if (isnan(this_time)) return js_nan(); // 5. Set t to LocalTime(t). - auto time = local_time(this_time.as_double()); + auto time = local_time(this_time); // 6. If date is not present, let dt be DateFromTime(t). if (!date.has_value()) - date = Value(date_from_time(time)); + date = date_from_time(time); // 7. Let newDate be MakeDate(MakeDay(YearFromTime(t), m, dt), TimeWithinDay(t)). - auto year = Value(year_from_time(time)); + auto year = year_from_time(time); - auto day = make_day(global_object, year, month, *date); - auto new_date = make_date(day, Value(time_within_day(time))); + auto day = make_day(year, month, *date); + auto new_date = make_date(day, time_within_day(time)); // 8. Let u be TimeClip(UTC(newDate)). - new_date = time_clip(global_object, Value(utc_time(new_date.as_double()))); + new_date = time_clip(utc_time(new_date)); // 9. Set the [[DateValue]] internal slot of this Date object to u. auto* this_object = MUST(typed_this_object(global_object)); - this_object->set_date_value(new_date.as_double()); + this_object->set_date_value(new_date); // 10. Return u. - return new_date; + return Value(new_date); } // 21.4.4.26 Date.prototype.setSeconds ( sec [ , ms ] ), https://tc39.es/ecma262/#sec-date.prototype.setseconds @@ -628,58 +627,58 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_seconds) auto this_time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. Let s be ? ToNumber(sec). - auto second = TRY(vm.argument(0).to_number(global_object)); + auto second = TRY(vm.argument(0).to_number(global_object)).as_double(); // 3. If ms is present, let milli be ? ToNumber(ms). auto millisecond = TRY(argument_or_empty(global_object, 1)); // 4. If t is NaN, return NaN. - if (this_time.is_nan()) + if (isnan(this_time)) return js_nan(); // 5. Set t to LocalTime(t). - auto time = local_time(this_time.as_double()); + auto time = local_time(this_time); // 6. If ms is not present, let milli be msFromTime(t). if (!millisecond.has_value()) - millisecond = Value(ms_from_time(time)); + millisecond = ms_from_time(time); // 7. Let date be MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), s, milli)). - auto hour = Value(hour_from_time(time)); - auto minute = Value(min_from_time(time)); + auto hour = hour_from_time(time); + auto minute = min_from_time(time); - auto new_time = make_time(global_object, hour, minute, second, *millisecond); - auto new_date = make_date(Value(day(time)), new_time); + auto new_time = make_time(hour, minute, second, *millisecond); + auto new_date = make_date(day(time), new_time); // 8. Let u be TimeClip(UTC(date)). - new_date = time_clip(global_object, Value(utc_time(new_date.as_double()))); + new_date = time_clip(utc_time(new_date)); // 9. Set the [[DateValue]] internal slot of this Date object to u. auto* this_object = MUST(typed_this_object(global_object)); - this_object->set_date_value(new_date.as_double()); + this_object->set_date_value(new_date); // 10. Return u. - return new_date; + return Value(new_date); } // 21.4.4.27 Date.prototype.setTime ( time ), https://tc39.es/ecma262/#sec-date.prototype.settime JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_time) { // 1. Perform ? thisTimeValue(this value). - auto time = TRY(this_time_value(global_object, vm.this_value(global_object))); + TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. Let t be ? ToNumber(time). - time = TRY(vm.argument(0).to_number(global_object)); + auto time = TRY(vm.argument(0).to_number(global_object)).as_double(); // 3. Let v be TimeClip(t). - time = time_clip(global_object, time); + time = time_clip(time); // 4. Set the [[DateValue]] internal slot of this Date object to v. auto* this_object = MUST(typed_this_object(global_object)); - this_object->set_date_value(time.as_double()); + this_object->set_date_value(time); // 5. Return v. - return time; + return Value(time); } // 21.4.4.28 Date.prototype.setUTCDate ( date ), https://tc39.es/ecma262/#sec-date.prototype.setutcdate @@ -689,28 +688,28 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_utc_date) auto time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. Let dt be ? ToNumber(date). - auto date = TRY(vm.argument(0).to_number(global_object)); + auto date = TRY(vm.argument(0).to_number(global_object)).as_double(); // 3. If t is NaN, return NaN. - if (time.is_nan()) + if (isnan(time)) return js_nan(); // 4. Let newDate be MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), dt), TimeWithinDay(t)). - auto year = Value(year_from_time(time.as_double())); - auto month = Value(month_from_time(time.as_double())); + auto year = year_from_time(time); + auto month = month_from_time(time); - auto day = make_day(global_object, year, month, date); - auto new_date = make_date(day, Value(time_within_day(time.as_double()))); + auto day = make_day(year, month, date); + auto new_date = make_date(day, time_within_day(time)); // 5. Let v be TimeClip(newDate). - new_date = time_clip(global_object, new_date); + new_date = time_clip(new_date); // 6. Set the [[DateValue]] internal slot of this Date object to v. auto* this_object = MUST(typed_this_object(global_object)); - this_object->set_date_value(new_date.as_double()); + this_object->set_date_value(new_date); // 7. Return v. - return new_date; + return Value(new_date); } // 21.4.4.29 Date.prototype.setUTCFullYear ( year [ , month [ , date ] ] ), https://tc39.es/ecma262/#sec-date.prototype.setutcfullyear @@ -721,31 +720,31 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_utc_full_year) // 2. If t is NaN, set t to +0๐ฝ. double time = 0; - if (!this_time.is_nan()) - time = this_time.as_double(); + if (!isnan(this_time)) + time = this_time; // 3. Let y be ? ToNumber(year). - auto year = TRY(vm.argument(0).to_number(global_object)); + auto year = TRY(vm.argument(0).to_number(global_object)).as_double(); // 4. If month is not present, let m be MonthFromTime(t); otherwise, let m be ? ToNumber(month). - auto month = TRY(argument_or_value(global_object, 1, month_from_time(time))); + auto month = TRY(argument_or_number(global_object, 1, month_from_time(time))); // 5. If date is not present, let dt be DateFromTime(t); otherwise, let dt be ? ToNumber(date). - auto date = TRY(argument_or_value(global_object, 2, date_from_time(time))); + auto date = TRY(argument_or_number(global_object, 2, date_from_time(time))); // 6. Let newDate be MakeDate(MakeDay(y, m, dt), TimeWithinDay(t)). - auto day = make_day(global_object, year, month, date); - auto new_date = make_date(day, Value(time_within_day(time))); + auto day = make_day(year, month, date); + auto new_date = make_date(day, time_within_day(time)); // 7. Let v be TimeClip(newDate). - new_date = time_clip(global_object, new_date); + new_date = time_clip(new_date); // 8. Set the [[DateValue]] internal slot of this Date object to v. auto* this_object = MUST(typed_this_object(global_object)); - this_object->set_date_value(new_date.as_double()); + this_object->set_date_value(new_date); // 9. Return v. - return new_date; + return Value(new_date); } // 21.4.4.30 Date.prototype.setUTCHours ( hour [ , min [ , sec [ , ms ] ] ] ), https://tc39.es/ecma262/#sec-date.prototype.setutchours @@ -755,7 +754,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_utc_hours) auto time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. Let h be ? ToNumber(hour). - auto hour = TRY(vm.argument(0).to_number(global_object)); + auto hour = TRY(vm.argument(0).to_number(global_object)).as_double(); // 3. If min is present, let m be ? ToNumber(min). auto minute = TRY(argument_or_empty(global_object, 1)); @@ -767,34 +766,34 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_utc_hours) auto millisecond = TRY(argument_or_empty(global_object, 3)); // 6. If t is NaN, return NaN. - if (time.is_nan()) + if (isnan(time)) return js_nan(); // 7. If min is not present, let m be MinFromTime(t). if (!minute.has_value()) - minute = Value(min_from_time(time.as_double())); + minute = min_from_time(time); // 8. If sec is not present, let s be SecFromTime(t). if (!second.has_value()) - second = Value(sec_from_time(time.as_double())); + second = sec_from_time(time); // 9. If ms is not present, let milli be msFromTime(t). if (!millisecond.has_value()) - millisecond = Value(ms_from_time(time.as_double())); + millisecond = ms_from_time(time); // 10. Let date be MakeDate(Day(t), MakeTime(h, m, s, milli)). - auto new_time = make_time(global_object, hour, *minute, *second, *millisecond); - auto date = make_date(Value(day(time.as_double())), new_time); + auto new_time = make_time(hour, *minute, *second, *millisecond); + auto date = make_date(day(time), new_time); // 11. Let v be TimeClip(date). - date = time_clip(global_object, date); + date = time_clip(date); // 12. Set the [[DateValue]] internal slot of this Date object to v. auto* this_object = MUST(typed_this_object(global_object)); - this_object->set_date_value(date.as_double()); + this_object->set_date_value(date); // 13. Return v. - return date; + return Value(date); } // 21.4.4.31 Date.prototype.setUTCMilliseconds ( ms ), https://tc39.es/ecma262/#sec-date.prototype.setutcmilliseconds @@ -804,29 +803,29 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_utc_milliseconds) auto time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. Set ms to ? ToNumber(ms). - auto millisecond = TRY(vm.argument(0).to_number(global_object)); + auto millisecond = TRY(vm.argument(0).to_number(global_object)).as_double(); // 3. If t is NaN, return NaN. - if (time.is_nan()) + if (isnan(time)) return js_nan(); // 4. Let time be MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms). - auto hour = Value(hour_from_time(time.as_double())); - auto minute = Value(min_from_time(time.as_double())); - auto second = Value(sec_from_time(time.as_double())); + auto hour = hour_from_time(time); + auto minute = min_from_time(time); + auto second = sec_from_time(time); - auto new_time = make_time(global_object, hour, minute, second, millisecond); + auto new_time = make_time(hour, minute, second, millisecond); // 5. Let v be TimeClip(MakeDate(Day(t), time)). - auto date = make_date(Value(day(time.as_double())), new_time); - date = time_clip(global_object, date); + auto date = make_date(day(time), new_time); + date = time_clip(date); // 6. Set the [[DateValue]] internal slot of this Date object to v. auto* this_object = MUST(typed_this_object(global_object)); - this_object->set_date_value(date.as_double()); + this_object->set_date_value(date); // 7. Return v. - return date; + return Value(date); } // 21.4.4.32 Date.prototype.setUTCMinutes ( min [ , sec [ , ms ] ] ), https://tc39.es/ecma262/#sec-date.prototype.setutcminutes @@ -836,7 +835,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_utc_minutes) auto time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. Let m be ? ToNumber(min). - auto minute = TRY(vm.argument(0).to_number(global_object)); + auto minute = TRY(vm.argument(0).to_number(global_object)).as_double(); // 3. If sec is present, let s be ? ToNumber(sec). auto second = TRY(argument_or_empty(global_object, 1)); @@ -845,32 +844,32 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_utc_minutes) auto millisecond = TRY(argument_or_empty(global_object, 2)); // 5. If t is NaN, return NaN. - if (time.is_nan()) + if (isnan(time)) return js_nan(); // 6. If sec is not present, let s be SecFromTime(t). if (!second.has_value()) - second = Value(sec_from_time(time.as_double())); + second = sec_from_time(time); // 7. If ms is not present, let milli be msFromTime(t). if (!millisecond.has_value()) - millisecond = Value(ms_from_time(time.as_double())); + millisecond = ms_from_time(time); // 8. Let date be MakeDate(Day(t), MakeTime(HourFromTime(t), m, s, milli)). - auto hour = Value(hour_from_time(time.as_double())); + auto hour = hour_from_time(time); - auto new_time = make_time(global_object, hour, minute, *second, *millisecond); - auto date = make_date(Value(day(time.as_double())), new_time); + auto new_time = make_time(hour, minute, *second, *millisecond); + auto date = make_date(day(time), new_time); // 9. Let v be TimeClip(date). - date = time_clip(global_object, date); + date = time_clip(date); // 10. Set the [[DateValue]] internal slot of this Date object to v. auto* this_object = MUST(typed_this_object(global_object)); - this_object->set_date_value(date.as_double()); + this_object->set_date_value(date); // 11. Return v. - return date; + return Value(date); } // 21.4.4.33 Date.prototype.setUTCMonth ( month [ , date ] ), https://tc39.es/ecma262/#sec-date.prototype.setutcmonth @@ -880,34 +879,34 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_utc_month) auto time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. Let m be ? ToNumber(month). - auto month = TRY(vm.argument(0).to_number(global_object)); + auto month = TRY(vm.argument(0).to_number(global_object)).as_double(); // 3. If date is present, let dt be ? ToNumber(date). auto date = TRY(argument_or_empty(global_object, 1)); // 4. If t is NaN, return NaN. - if (time.is_nan()) + if (isnan(time)) return js_nan(); // 5. If date is not present, let dt be DateFromTime(t). if (!date.has_value()) - date = Value(date_from_time(time.as_double())); + date = date_from_time(time); // 6. Let newDate be MakeDate(MakeDay(YearFromTime(t), m, dt), TimeWithinDay(t)). - auto year = Value(year_from_time(time.as_double())); + auto year = year_from_time(time); - auto day = make_day(global_object, year, month, *date); - auto new_date = make_date(day, Value(time_within_day(time.as_double()))); + auto day = make_day(year, month, *date); + auto new_date = make_date(day, time_within_day(time)); // 7. Let v be TimeClip(newDate). - new_date = time_clip(global_object, new_date); + new_date = time_clip(new_date); // 8. Set the [[DateValue]] internal slot of this Date object to v. auto* this_object = MUST(typed_this_object(global_object)); - this_object->set_date_value(new_date.as_double()); + this_object->set_date_value(new_date); // 9. Return v. - return new_date; + return Value(new_date); } // 21.4.4.34 Date.prototype.setUTCSeconds ( sec [ , ms ] ), https://tc39.es/ecma262/#sec-date.prototype.setutcseconds @@ -917,35 +916,35 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_utc_seconds) auto time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. Let s be ? ToNumber(sec). - auto second = TRY(vm.argument(0).to_number(global_object)); + auto second = TRY(vm.argument(0).to_number(global_object)).as_double(); // 3. If ms is present, let milli be ? ToNumber(ms). auto millisecond = TRY(argument_or_empty(global_object, 1)); // 4. If t is NaN, return NaN. - if (time.is_nan()) + if (isnan(time)) return js_nan(); // 5. If ms is not present, let milli be msFromTime(t). if (!millisecond.has_value()) - millisecond = Value(ms_from_time(time.as_double())); + millisecond = ms_from_time(time); // 6. Let date be MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), s, milli)). - auto hour = Value(hour_from_time(time.as_double())); - auto minute = Value(min_from_time(time.as_double())); + auto hour = hour_from_time(time); + auto minute = min_from_time(time); - auto new_time = make_time(global_object, hour, minute, second, *millisecond); - auto new_date = make_date(Value(day(time.as_double())), new_time); + auto new_time = make_time(hour, minute, second, *millisecond); + auto new_date = make_date(day(time), new_time); // 7. Let v be TimeClip(date). - new_date = time_clip(global_object, new_date); + new_date = time_clip(new_date); // 8. Set the [[DateValue]] internal slot of this Date object to v. auto* this_object = MUST(typed_this_object(global_object)); - this_object->set_date_value(new_date.as_double()); + this_object->set_date_value(new_date); // 9. Return v. - return new_date; + return Value(new_date); } // 21.4.4.35 Date.prototype.toDateString ( ), https://tc39.es/ecma262/#sec-date.prototype.todatestring @@ -956,12 +955,12 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_date_string) auto time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 3. If tv is NaN, return "Invalid Date". - if (time.is_nan()) + if (isnan(time)) return js_string(vm, "Invalid Date"sv); // 4. Let t be LocalTime(tv). // 5. Return DateString(t). - return js_string(vm, date_string(local_time(time.as_double()))); + return js_string(vm, date_string(local_time(time))); } // 21.4.4.36 Date.prototype.toISOString ( ), https://tc39.es/ecma262/#sec-date.prototype.toisostring @@ -1006,7 +1005,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_locale_date_string) auto time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. If x is NaN, return "Invalid Date". - if (time.is_nan()) + if (isnan(time)) return js_string(vm, "Invalid Date"sv); // 3. Let options be ? ToDateTimeOptions(options, "date", "date"). @@ -1031,7 +1030,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_locale_string) auto time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. If x is NaN, return "Invalid Date". - if (time.is_nan()) + if (isnan(time)) return js_string(vm, "Invalid Date"sv); // 3. Let options be ? ToDateTimeOptions(options, "any", "all"). @@ -1056,7 +1055,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_locale_time_string) auto time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. If x is NaN, return "Invalid Date". - if (time.is_nan()) + if (isnan(time)) return js_string(vm, "Invalid Date"sv); // 3. Let options be ? ToDateTimeOptions(options, "time", "time"). @@ -1077,7 +1076,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_string) auto time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. Return ToDateString(tv). - return js_string(vm, JS::to_date_string(time.as_double())); + return js_string(vm, JS::to_date_string(time)); } // 21.4.4.41.1 TimeString ( tv ), https://tc39.es/ecma262/#sec-timestring @@ -1181,7 +1180,7 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_temporal_instant) auto t = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. Let ns be ? NumberToBigInt(t) ร 10^6. - auto* ns = TRY(number_to_bigint(global_object, t)); + auto* ns = TRY(number_to_bigint(global_object, Value(t))); ns = js_bigint(vm, ns->big_integer().multiplied_by(Crypto::UnsignedBigInteger { 1'000'000 })); // 3. Return ! CreateTemporalInstant(ns). @@ -1196,12 +1195,12 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_time_string) auto time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 3. If tv is NaN, return "Invalid Date". - if (time.is_nan()) + if (isnan(time)) return js_string(vm, "Invalid Date"sv); // 4. Let t be LocalTime(tv). // 5. Return the string-concatenation of TimeString(t) and TimeZoneString(tv). - auto string = String::formatted("{}{}", time_string(local_time(time.as_double())), time_zone_string(time.as_double())); + auto string = String::formatted("{}{}", time_string(local_time(time)), time_zone_string(time)); return js_string(vm, move(string)); } @@ -1213,27 +1212,27 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_utc_string) auto time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 3. If tv is NaN, return "Invalid Date". - if (time.is_nan()) + if (isnan(time)) return js_string(vm, "Invalid Date"sv); // 4. Let weekday be the Name of the entry in Table 62 with the Number WeekDay(tv). - auto weekday = short_day_names[week_day(time.as_double())]; + auto weekday = short_day_names[week_day(time)]; // 5. Let month be the Name of the entry in Table 63 with the Number MonthFromTime(tv). - auto month = short_month_names[month_from_time(time.as_double())]; + auto month = short_month_names[month_from_time(time)]; // 6. Let day be ToZeroPaddedDecimalString(โ(DateFromTime(tv)), 2). - auto day = date_from_time(time.as_double()); + auto day = date_from_time(time); // 7. Let yv be YearFromTime(tv). - auto year = year_from_time(time.as_double()); + auto year = year_from_time(time); // 8. If yv is +0๐ฝ or yv > +0๐ฝ, let yearSign be the empty String; otherwise, let yearSign be "-". auto year_sign = year >= 0 ? ""sv : "-"sv; // 9. Let paddedYear be ToZeroPaddedDecimalString(abs(โ(yv)), 4). // 10. Return the string-concatenation of weekday, ",", the code unit 0x0020 (SPACE), day, the code unit 0x0020 (SPACE), month, the code unit 0x0020 (SPACE), yearSign, paddedYear, the code unit 0x0020 (SPACE), and TimeString(tv). - auto string = String::formatted("{}, {:02} {} {}{:04} {}", weekday, day, month, year_sign, abs(year), time_string(time.as_double())); + auto string = String::formatted("{}, {:02} {} {}{:04} {}", weekday, day, month, year_sign, abs(year), time_string(time)); return js_string(vm, move(string)); } @@ -1264,11 +1263,11 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_year) auto time = TRY(this_time_value(global_object, vm.this_value(global_object))); // 2. If t is NaN, return NaN. - if (time.is_nan()) - return time; + if (isnan(time)) + return js_nan(); - // 3. Return Return YearFromTime(LocalTime(t)) - 1900๐ฝ. - return Value(year_from_time(local_time(time.as_double())) - 1900); + // 3. Return YearFromTime(LocalTime(t)) - 1900๐ฝ. + return Value(year_from_time(local_time(time)) - 1900); } // B.2.4.2 Date.prototype.setYear ( year ), https://tc39.es/ecma262/#sec-date.prototype.setyear @@ -1279,43 +1278,43 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_year) // 2. If t is NaN, set t to +0๐ฝ; otherwise, set t to LocalTime(t). double time = 0; - if (!this_time.is_nan()) - time = local_time(this_time.as_double()); + if (!isnan(this_time)) + time = local_time(this_time); // 3. Let y be ? ToNumber(year). - auto year = TRY(vm.argument(0).to_number(global_object)); + auto year = TRY(vm.argument(0).to_number(global_object)).as_double(); auto* this_object = MUST(typed_this_object(global_object)); // 4. If y is NaN, then - if (year.is_nan()) { + if (isnan(year)) { // a. Set the [[DateValue]] internal slot of this Date object to NaN. - this_object->set_date_value(js_nan().as_double()); + this_object->set_date_value(NAN); // b. Return NaN. - return year; + return js_nan(); } // 5. Let yi be ! ToIntegerOrInfinity(y). - auto year_double = MUST(year.to_integer_or_infinity(global_object)); + auto year_integer = to_integer_or_infinity(year); // 6. If 0 โค yi โค 99, let yyyy be 1900๐ฝ + ๐ฝ(yi). - if (0 <= year_double && year_double <= 99) - year = Value(1900 + year_double); + if (0 <= year_integer && year_integer <= 99) + year = 1900 + year_integer; // 7. Else, let yyyy be y. // 8. Let d be MakeDay(yyyy, MonthFromTime(t), DateFromTime(t)). - auto day = make_day(global_object, year, Value(month_from_time(time)), Value(date_from_time(time))); + auto day = make_day(year, month_from_time(time), date_from_time(time)); // 9. Let date be UTC(MakeDate(d, TimeWithinDay(t))). - auto date = utc_time(make_date(day, Value(time_within_day(time))).as_double()); + auto date = utc_time(make_date(day, time_within_day(time))); // 10. Set the [[DateValue]] internal slot of this Date object to TimeClip(date). - auto new_date = time_clip(global_object, Value(date)); - this_object->set_date_value(new_date.as_double()); + auto new_date = time_clip(date); + this_object->set_date_value(new_date); // 11. Return the value of the [[DateValue]] internal slot of this Date object. - return new_date; + return Value(new_date); } // B.2.4.3 Date.prototype.toGMTString ( ), https://tc39.es/ecma262/#sec-date.prototype.togmtstring diff --git a/Userland/Libraries/LibJS/Runtime/DatePrototype.h b/Userland/Libraries/LibJS/Runtime/DatePrototype.h index 805b2a6bab..f3c75d2b15 100644 --- a/Userland/Libraries/LibJS/Runtime/DatePrototype.h +++ b/Userland/Libraries/LibJS/Runtime/DatePrototype.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Linus Groh <linusg@serenityos.org> + * Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ @@ -71,7 +71,7 @@ private: JS_DECLARE_NATIVE_FUNCTION(symbol_to_primitive); }; -ThrowCompletionOr<Value> this_time_value(GlobalObject& global_object, Value value); +ThrowCompletionOr<double> this_time_value(GlobalObject& global_object, Value value); String time_string(double time); String date_string(double time); String time_zone_string(double time); diff --git a/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.cpp b/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.cpp index 38456ff04b..10e15fe888 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.cpp @@ -504,15 +504,15 @@ static Optional<StyleAndValue> find_calendar_field(StringView name, Unicode::Cal } // 11.5.6 FormatDateTimePattern ( dateTimeFormat, patternParts, x, rangeFormatOptions ), https://tc39.es/ecma402/#sec-formatdatetimepattern -ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(GlobalObject& global_object, DateTimeFormat& date_time_format, Vector<PatternPartition> pattern_parts, Value time, Unicode::CalendarPattern const* range_format_options) +ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(GlobalObject& global_object, DateTimeFormat& date_time_format, Vector<PatternPartition> pattern_parts, double time, Unicode::CalendarPattern const* range_format_options) { auto& vm = global_object.vm(); // 1. Let x be TimeClip(x). - time = time_clip(global_object, time); + time = time_clip(time); // 2. If x is NaN, throw a RangeError exception. - if (time.is_nan()) + if (isnan(time)) return vm.throw_completion<RangeError>(global_object, ErrorType::IntlInvalidTime); // 3. Let locale be dateTimeFormat.[[Locale]]. @@ -567,7 +567,7 @@ ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(GlobalObjec } // 13. Let tm be ToLocalTime(x, dateTimeFormat.[[Calendar]], dateTimeFormat.[[TimeZone]]). - auto local_time = TRY(to_local_time(global_object, time.as_double(), date_time_format.calendar(), date_time_format.time_zone())); + auto local_time = TRY(to_local_time(global_object, time, date_time_format.calendar(), date_time_format.time_zone())); // 14. Let result be a new empty List. Vector<PatternPartition> result; @@ -788,7 +788,7 @@ ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(GlobalObjec } // 11.5.7 PartitionDateTimePattern ( dateTimeFormat, x ), https://tc39.es/ecma402/#sec-partitiondatetimepattern -ThrowCompletionOr<Vector<PatternPartition>> partition_date_time_pattern(GlobalObject& global_object, DateTimeFormat& date_time_format, Value time) +ThrowCompletionOr<Vector<PatternPartition>> partition_date_time_pattern(GlobalObject& global_object, DateTimeFormat& date_time_format, double time) { // 1. Let patternParts be PartitionPattern(dateTimeFormat.[[Pattern]]). auto pattern_parts = partition_pattern(date_time_format.pattern()); @@ -801,7 +801,7 @@ ThrowCompletionOr<Vector<PatternPartition>> partition_date_time_pattern(GlobalOb } // 11.5.8 FormatDateTime ( dateTimeFormat, x ), https://tc39.es/ecma402/#sec-formatdatetime -ThrowCompletionOr<String> format_date_time(GlobalObject& global_object, DateTimeFormat& date_time_format, Value time) +ThrowCompletionOr<String> format_date_time(GlobalObject& global_object, DateTimeFormat& date_time_format, double time) { // 1. Let parts be ? PartitionDateTimePattern(dateTimeFormat, x). auto parts = TRY(partition_date_time_pattern(global_object, date_time_format, time)); @@ -820,7 +820,7 @@ ThrowCompletionOr<String> format_date_time(GlobalObject& global_object, DateTime } // 11.5.9 FormatDateTimeToParts ( dateTimeFormat, x ), https://tc39.es/ecma402/#sec-formatdatetimetoparts -ThrowCompletionOr<Array*> format_date_time_to_parts(GlobalObject& global_object, DateTimeFormat& date_time_format, Value time) +ThrowCompletionOr<Array*> format_date_time_to_parts(GlobalObject& global_object, DateTimeFormat& date_time_format, double time) { auto& vm = global_object.vm(); @@ -891,33 +891,33 @@ ThrowCompletionOr<void> for_each_range_pattern_with_source(Unicode::CalendarRang } // 11.5.10 PartitionDateTimeRangePattern ( dateTimeFormat, x, y ), https://tc39.es/ecma402/#sec-partitiondatetimerangepattern -ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_date_time_range_pattern(GlobalObject& global_object, DateTimeFormat& date_time_format, Value start, Value end) +ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_date_time_range_pattern(GlobalObject& global_object, DateTimeFormat& date_time_format, double start, double end) { auto& vm = global_object.vm(); // 1. Let x be TimeClip(x). - start = time_clip(global_object, start); + start = time_clip(start); // 2. If x is NaN, throw a RangeError exception. - if (start.is_nan()) + if (isnan(start)) return vm.throw_completion<RangeError>(global_object, ErrorType::IntlInvalidTime); // 3. Let y be TimeClip(y). - end = time_clip(global_object, end); + end = time_clip(end); // 4. If y is NaN, throw a RangeError exception. - if (end.is_nan()) + if (isnan(end)) return vm.throw_completion<RangeError>(global_object, ErrorType::IntlInvalidTime); // 5. If x is greater than y, throw a RangeError exception. - if (start.as_double() > end.as_double()) + if (start > end) return vm.throw_completion<RangeError>(global_object, ErrorType::IntlStartTimeAfterEndTime, start, end); // 6. Let tm1 be ToLocalTime(x, dateTimeFormat.[[Calendar]], dateTimeFormat.[[TimeZone]]). - auto start_local_time = TRY(to_local_time(global_object, start.as_double(), date_time_format.calendar(), date_time_format.time_zone())); + auto start_local_time = TRY(to_local_time(global_object, start, date_time_format.calendar(), date_time_format.time_zone())); // 7. Let tm2 be ToLocalTime(y, dateTimeFormat.[[Calendar]], dateTimeFormat.[[TimeZone]]). - auto end_local_time = TRY(to_local_time(global_object, end.as_double(), date_time_format.calendar(), date_time_format.time_zone())); + auto end_local_time = TRY(to_local_time(global_object, end, date_time_format.calendar(), date_time_format.time_zone())); // 8. Let rangePatterns be dateTimeFormat.[[RangePatterns]]. auto range_patterns = date_time_format.range_patterns(); @@ -1121,7 +1121,7 @@ ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_date_time_range_ } // 11.5.11 FormatDateTimeRange ( dateTimeFormat, x, y ), https://tc39.es/ecma402/#sec-formatdatetimerange -ThrowCompletionOr<String> format_date_time_range(GlobalObject& global_object, DateTimeFormat& date_time_format, Value start, Value end) +ThrowCompletionOr<String> format_date_time_range(GlobalObject& global_object, DateTimeFormat& date_time_format, double start, double end) { // 1. Let parts be ? PartitionDateTimeRangePattern(dateTimeFormat, x, y). auto parts = TRY(partition_date_time_range_pattern(global_object, date_time_format, start, end)); @@ -1140,7 +1140,7 @@ ThrowCompletionOr<String> format_date_time_range(GlobalObject& global_object, Da } // 11.5.12 FormatDateTimeRangeToParts ( dateTimeFormat, x, y ), https://tc39.es/ecma402/#sec-formatdatetimerangetoparts -ThrowCompletionOr<Array*> format_date_time_range_to_parts(GlobalObject& global_object, DateTimeFormat& date_time_format, Value start, Value end) +ThrowCompletionOr<Array*> format_date_time_range_to_parts(GlobalObject& global_object, DateTimeFormat& date_time_format, double start, double end) { auto& vm = global_object.vm(); diff --git a/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.h b/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.h index f4ffd3e7fa..eb17b0ea69 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.h +++ b/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.h @@ -203,13 +203,13 @@ ThrowCompletionOr<Object*> to_date_time_options(GlobalObject& global_object, Val Optional<Unicode::CalendarPattern> date_time_style_format(StringView data_locale, DateTimeFormat& date_time_format); Optional<Unicode::CalendarPattern> basic_format_matcher(Unicode::CalendarPattern const& options, Vector<Unicode::CalendarPattern> formats); Optional<Unicode::CalendarPattern> best_fit_format_matcher(Unicode::CalendarPattern const& options, Vector<Unicode::CalendarPattern> formats); -ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(GlobalObject& global_object, DateTimeFormat& date_time_format, Vector<PatternPartition> pattern_parts, Value time, Unicode::CalendarPattern const* range_format_options); -ThrowCompletionOr<Vector<PatternPartition>> partition_date_time_pattern(GlobalObject& global_object, DateTimeFormat& date_time_format, Value time); -ThrowCompletionOr<String> format_date_time(GlobalObject& global_object, DateTimeFormat& date_time_format, Value time); -ThrowCompletionOr<Array*> format_date_time_to_parts(GlobalObject& global_object, DateTimeFormat& date_time_format, Value time); -ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_date_time_range_pattern(GlobalObject& global_object, DateTimeFormat& date_time_format, Value start, Value end); -ThrowCompletionOr<String> format_date_time_range(GlobalObject& global_object, DateTimeFormat& date_time_format, Value start, Value end); -ThrowCompletionOr<Array*> format_date_time_range_to_parts(GlobalObject& global_object, DateTimeFormat& date_time_format, Value start, Value end); +ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(GlobalObject& global_object, DateTimeFormat& date_time_format, Vector<PatternPartition> pattern_parts, double time, Unicode::CalendarPattern const* range_format_options); +ThrowCompletionOr<Vector<PatternPartition>> partition_date_time_pattern(GlobalObject& global_object, DateTimeFormat& date_time_format, double time); +ThrowCompletionOr<String> format_date_time(GlobalObject& global_object, DateTimeFormat& date_time_format, double time); +ThrowCompletionOr<Array*> format_date_time_to_parts(GlobalObject& global_object, DateTimeFormat& date_time_format, double time); +ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_date_time_range_pattern(GlobalObject& global_object, DateTimeFormat& date_time_format, double start, double end); +ThrowCompletionOr<String> format_date_time_range(GlobalObject& global_object, DateTimeFormat& date_time_format, double start, double end); +ThrowCompletionOr<Array*> format_date_time_range_to_parts(GlobalObject& global_object, DateTimeFormat& date_time_format, double start, double end); ThrowCompletionOr<LocalTime> to_local_time(GlobalObject& global_object, double time, StringView calendar, StringView time_zone); template<typename Callback> diff --git a/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormatFunction.cpp b/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormatFunction.cpp index 82d4a8721b..114bf06916 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormatFunction.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormatFunction.cpp @@ -44,19 +44,21 @@ ThrowCompletionOr<Value> DateTimeFormatFunction::call() // 1. Let dtf be F.[[DateTimeFormat]]. // 2. Assert: Type(dtf) is Object and dtf has an [[InitializedDateTimeFormat]] internal slot. + double date_value; + // 3. If date is not provided or is undefined, then if (date.is_undefined()) { // a. Let x be ! Call(%Date.now%, undefined). - date = MUST(JS::call(global_object, global_object.date_constructor_now_function(), js_undefined())); + date_value = MUST(JS::call(global_object, global_object.date_constructor_now_function(), js_undefined())).as_double(); } // 4. Else, else { // a. Let x be ? ToNumber(date). - date = TRY(date.to_number(global_object)); + date_value = TRY(date.to_number(global_object)).as_double(); } // 5. Return ? FormatDateTime(dtf, x). - auto formatted = TRY(format_date_time(global_object, m_date_time_format, date)); + auto formatted = TRY(format_date_time(global_object, m_date_time_format, date_value)); return js_string(vm, move(formatted)); } diff --git a/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormatPrototype.cpp b/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormatPrototype.cpp index 4fe76eb643..e1161f80d7 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormatPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormatPrototype.cpp @@ -69,19 +69,21 @@ JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::format_to_parts) // 2. Perform ? RequireInternalSlot(dtf, [[InitializedDateTimeFormat]]). auto* date_time_format = TRY(typed_this_object(global_object)); + double date_value; + // 3. If date is undefined, then if (date.is_undefined()) { // a. Let x be ! Call(%Date.now%, undefined). - date = MUST(call(global_object, global_object.date_constructor_now_function(), js_undefined())); + date_value = MUST(call(global_object, global_object.date_constructor_now_function(), js_undefined())).as_double(); } // 4. Else, else { // a. Let x be ? ToNumber(date). - date = TRY(date.to_number(global_object)); + date_value = TRY(date.to_number(global_object)).as_double(); } // 5. Return ? FormatDateTimeToParts(dtf, x). - return TRY(format_date_time_to_parts(global_object, *date_time_format, date)); + return TRY(format_date_time_to_parts(global_object, *date_time_format, date_value)); } // 11.3.5 Intl.DateTimeFormat.prototype.formatRange ( startDate, endDate ), https://tc39.es/ecma402/#sec-intl.datetimeformat.prototype.formatRange @@ -101,13 +103,13 @@ JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::format_range) return vm.throw_completion<TypeError>(global_object, ErrorType::IsUndefined, "endDate"sv); // 4. Let x be ? ToNumber(startDate). - start_date = TRY(start_date.to_number(global_object)); + auto start_date_number = TRY(start_date.to_number(global_object)).as_double(); // 5. Let y be ? ToNumber(endDate). - end_date = TRY(end_date.to_number(global_object)); + auto end_date_number = TRY(end_date.to_number(global_object)).as_double(); // 6. Return ? FormatDateTimeRange(dtf, x, y). - auto formatted = TRY(format_date_time_range(global_object, *date_time_format, start_date, end_date)); + auto formatted = TRY(format_date_time_range(global_object, *date_time_format, start_date_number, end_date_number)); return js_string(vm, move(formatted)); } @@ -128,13 +130,13 @@ JS_DEFINE_NATIVE_FUNCTION(DateTimeFormatPrototype::format_range_to_parts) return vm.throw_completion<TypeError>(global_object, ErrorType::IsUndefined, "endDate"sv); // 4. Let x be ? ToNumber(startDate). - start_date = TRY(start_date.to_number(global_object)); + auto start_date_number = TRY(start_date.to_number(global_object)).as_double(); // 5. Let y be ? ToNumber(endDate). - end_date = TRY(end_date.to_number(global_object)); + auto end_date_number = TRY(end_date.to_number(global_object)).as_double(); // 6. Return ? FormatDateTimeRangeToParts(dtf, x, y). - return TRY(format_date_time_range_to_parts(global_object, *date_time_format, start_date, end_date)); + return TRY(format_date_time_range_to_parts(global_object, *date_time_format, start_date_number, end_date_number)); } // 11.3.7 Intl.DateTimeFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-intl.datetimeformat.prototype.resolvedoptions diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTime.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTime.cpp index a7f92e4837..dbcab74172 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTime.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTime.cpp @@ -53,19 +53,19 @@ BigInt* get_epoch_from_iso_parts(GlobalObject& global_object, i32 year, u8 month VERIFY(is_valid_iso_date(year, month, day)); // 2. Let date be MakeDay(๐ฝ(year), ๐ฝ(month - 1), ๐ฝ(day)). - auto date = make_day(global_object, Value(year), Value(month - 1), Value(day)); + auto date = make_day(year, month - 1, day); // 3. Let time be MakeTime(๐ฝ(hour), ๐ฝ(minute), ๐ฝ(second), ๐ฝ(millisecond)). - auto time = make_time(global_object, Value(hour), Value(minute), Value(second), Value(millisecond)); + auto time = make_time(hour, minute, second, millisecond); // 4. Let ms be MakeDate(date, time). auto ms = make_date(date, time); // 5. Assert: ms is finite. - VERIFY(ms.is_finite_number()); + VERIFY(isfinite(ms)); // 6. Return โค(โ(ms) ร 10^6 + microsecond ร 10^3 + nanosecond). - return js_bigint(vm, Crypto::SignedBigInteger::create_from(static_cast<i64>(ms.as_double())).multiplied_by(Crypto::UnsignedBigInteger { 1'000'000 }).plus(Crypto::SignedBigInteger::create_from((i64)microsecond * 1000)).plus(Crypto::SignedBigInteger(nanosecond))); + return js_bigint(vm, Crypto::SignedBigInteger::create_from(static_cast<i64>(ms)).multiplied_by(Crypto::UnsignedBigInteger { 1'000'000 }).plus(Crypto::SignedBigInteger::create_from((i64)microsecond * 1000)).plus(Crypto::SignedBigInteger(nanosecond))); } // -864 * 10^19 - 864 * 10^11 |