1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 07:27:45 +00:00

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.
This commit is contained in:
Linus Groh 2022-05-06 20:45:25 +02:00
parent b9b3d01bea
commit f7c9bd0760
10 changed files with 357 additions and 354 deletions

View file

@ -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();

View file

@ -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>

View file

@ -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));
}

View file

@ -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