summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimothy Flynn <trflynn89@pm.me>2023-01-19 12:26:37 -0500
committerLinus Groh <mail@linusgroh.de>2023-01-19 20:57:30 +0000
commit1e6e719592ae61ecad300aa78154f71bf0eb11a8 (patch)
treed85869fc36d2dbd13e4c148909893ff8fceaab9c
parentbff0e25ebed03db133c708a05c4f08bb5244d0ba (diff)
downloadserenity-1e6e719592ae61ecad300aa78154f71bf0eb11a8.zip
LibJS: Propagate OOM errors from the PartitionPattern Abstract Operation
-rw-r--r--Userland/Libraries/LibJS/Runtime/BigIntPrototype.cpp2
-rw-r--r--Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.cpp8
-rw-r--r--Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.h2
-rw-r--r--Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.cpp12
-rw-r--r--Userland/Libraries/LibJS/Runtime/Intl/DurationFormat.cpp11
-rw-r--r--Userland/Libraries/LibJS/Runtime/Intl/DurationFormat.h2
-rw-r--r--Userland/Libraries/LibJS/Runtime/Intl/DurationFormatPrototype.cpp4
-rw-r--r--Userland/Libraries/LibJS/Runtime/Intl/ListFormat.cpp28
-rw-r--r--Userland/Libraries/LibJS/Runtime/Intl/ListFormat.h8
-rw-r--r--Userland/Libraries/LibJS/Runtime/Intl/ListFormatPrototype.cpp6
-rw-r--r--Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.cpp32
-rw-r--r--Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.h8
-rw-r--r--Userland/Libraries/LibJS/Runtime/Intl/NumberFormatFunction.cpp3
-rw-r--r--Userland/Libraries/LibJS/Runtime/Intl/NumberFormatPrototype.cpp3
-rw-r--r--Userland/Libraries/LibJS/Runtime/Intl/RelativeTimeFormat.cpp9
-rw-r--r--Userland/Libraries/LibJS/Runtime/Intl/RelativeTimeFormat.h2
-rw-r--r--Userland/Libraries/LibJS/Runtime/NumberPrototype.cpp3
17 files changed, 74 insertions, 69 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/BigIntPrototype.cpp b/Userland/Libraries/LibJS/Runtime/BigIntPrototype.cpp
index 52b6a8d1a6..1cbfc8f1c4 100644
--- a/Userland/Libraries/LibJS/Runtime/BigIntPrototype.cpp
+++ b/Userland/Libraries/LibJS/Runtime/BigIntPrototype.cpp
@@ -74,7 +74,7 @@ JS_DEFINE_NATIVE_FUNCTION(BigIntPrototype::to_locale_string)
auto* number_format = static_cast<Intl::NumberFormat*>(TRY(construct(vm, *realm.intrinsics().intl_number_format_constructor(), locales, options)).ptr());
// 3. Return ? FormatNumeric(numberFormat, x).
- auto formatted = Intl::format_numeric(vm, *number_format, Value(bigint));
+ auto formatted = TRY(Intl::format_numeric(vm, *number_format, Value(bigint)));
return PrimitiveString::create(vm, move(formatted));
}
diff --git a/Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.cpp b/Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.cpp
index a825520a4a..b80e259a4f 100644
--- a/Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.cpp
+++ b/Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.cpp
@@ -680,7 +680,7 @@ ThrowCompletionOr<Optional<int>> get_number_option(VM& vm, Object const& options
}
// 9.2.16 PartitionPattern ( pattern ), https://tc39.es/ecma402/#sec-partitionpattern
-Vector<PatternPartition> partition_pattern(StringView pattern)
+ThrowCompletionOr<Vector<PatternPartition>> partition_pattern(VM& vm, StringView pattern)
{
// 1. Let result be a new empty List.
Vector<PatternPartition> result;
@@ -709,14 +709,14 @@ Vector<PatternPartition> partition_pattern(StringView pattern)
auto literal = pattern.substring_view(next_index, *begin_index - next_index);
// ii. Append a new Record { [[Type]]: "literal", [[Value]]: literal } as the last element of the list result.
- result.append({ "literal"sv, literal });
+ TRY_OR_THROW_OOM(vm, result.try_append({ "literal"sv, literal }));
}
// d. Let p be the substring of pattern from position beginIndex, exclusive, to position endIndex, exclusive.
auto partition = pattern.substring_view(*begin_index + 1, end_index - *begin_index - 1);
// e. Append a new Record { [[Type]]: p, [[Value]]: undefined } as the last element of the list result.
- result.append({ partition, {} });
+ TRY_OR_THROW_OOM(vm, result.try_append({ partition, {} }));
// f. Set nextIndex to endIndex + 1.
next_index = end_index + 1;
@@ -731,7 +731,7 @@ Vector<PatternPartition> partition_pattern(StringView pattern)
auto literal = pattern.substring_view(next_index);
// b. Append a new Record { [[Type]]: "literal", [[Value]]: literal } as the last element of the list result.
- result.append({ "literal"sv, literal });
+ TRY_OR_THROW_OOM(vm, result.try_append({ "literal"sv, literal }));
}
// 8. Return result.
diff --git a/Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.h b/Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.h
index ece2e6b38c..c892857f04 100644
--- a/Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.h
+++ b/Userland/Libraries/LibJS/Runtime/Intl/AbstractOperations.h
@@ -92,7 +92,7 @@ ThrowCompletionOr<Object*> coerce_options_to_object(VM&, Value options);
ThrowCompletionOr<StringOrBoolean> get_string_or_boolean_option(VM&, Object const& options, PropertyKey const& property, Span<StringView const> values, StringOrBoolean true_value, StringOrBoolean falsy_value, StringOrBoolean fallback);
ThrowCompletionOr<Optional<int>> default_number_option(VM&, Value value, int minimum, int maximum, Optional<int> fallback);
ThrowCompletionOr<Optional<int>> get_number_option(VM&, Object const& options, PropertyKey const& property, int minimum, int maximum, Optional<int> fallback);
-Vector<PatternPartition> partition_pattern(StringView pattern);
+ThrowCompletionOr<Vector<PatternPartition>> partition_pattern(VM&, StringView pattern);
template<size_t Size>
ThrowCompletionOr<StringOrBoolean> get_string_or_boolean_option(VM& vm, Object const& options, PropertyKey const& property, StringView const (&values)[Size], StringOrBoolean true_value, StringOrBoolean falsy_value, StringOrBoolean fallback)
diff --git a/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.cpp b/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.cpp
index 615335e1b0..9d88f9fad9 100644
--- a/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.cpp
+++ b/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.cpp
@@ -621,7 +621,7 @@ ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(VM& vm, Dat
value = floor(value * pow(10, static_cast<int>(*fractional_second_digits) - 3));
// iii. Let fv be FormatNumeric(nf3, v).
- auto formatted_value = format_numeric(vm, *number_format3, Value(value));
+ auto formatted_value = TRY(format_numeric(vm, *number_format3, Value(value)));
// iv. Append a new Record { [[Type]]: "fractionalSecond", [[Value]]: fv } as the last element of result.
result.append({ "fractionalSecond"sv, move(formatted_value) });
@@ -705,13 +705,13 @@ ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(VM& vm, Dat
// viii. If f is "numeric", then
case ::Locale::CalendarPatternStyle::Numeric:
// 1. Let fv be FormatNumeric(nf, v).
- formatted_value = format_numeric(vm, *number_format, Value(value));
+ formatted_value = TRY(format_numeric(vm, *number_format, Value(value)));
break;
// ix. Else if f is "2-digit", then
case ::Locale::CalendarPatternStyle::TwoDigit:
// 1. Let fv be FormatNumeric(nf2, v).
- formatted_value = format_numeric(vm, *number_format2, Value(value));
+ formatted_value = TRY(format_numeric(vm, *number_format2, Value(value)));
// 2. If the "length" property of fv is greater than 2, let fv be the substring of fv containing the last two characters.
// NOTE: The first length check here isn't enough, but lets us avoid UTF-16 transcoding when the formatted value is ASCII.
@@ -820,7 +820,7 @@ ThrowCompletionOr<Vector<PatternPartition>> format_date_time_pattern(VM& vm, Dat
ThrowCompletionOr<Vector<PatternPartition>> partition_date_time_pattern(VM& vm, DateTimeFormat& date_time_format, double time)
{
// 1. Let patternParts be PartitionPattern(dateTimeFormat.[[Pattern]]).
- auto pattern_parts = partition_pattern(date_time_format.pattern());
+ auto pattern_parts = TRY(partition_pattern(vm, date_time_format.pattern()));
// 2. Let result be ? FormatDateTimePattern(dateTimeFormat, patternParts, x, undefined).
auto result = TRY(format_date_time_pattern(vm, date_time_format, move(pattern_parts), time, nullptr));
@@ -1067,7 +1067,7 @@ ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_date_time_range_
auto const& pattern = date_time_format.pattern();
// b. Let patternParts be PartitionPattern(pattern).
- auto pattern_parts = partition_pattern(pattern);
+ auto pattern_parts = TRY(partition_pattern(vm, pattern));
// c. Let result be ? FormatDateTimePattern(dateTimeFormat, patternParts, x, undefined).
auto raw_result = TRY(format_date_time_pattern(vm, date_time_format, move(pattern_parts), start, nullptr));
@@ -1124,7 +1124,7 @@ ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_date_time_range_
auto time = ((source == "startRange") || (source == "shared")) ? start : end;
// e. Let patternParts be PartitionPattern(pattern).
- auto pattern_parts = partition_pattern(pattern);
+ auto pattern_parts = TRY(partition_pattern(vm, pattern));
// f. Let partResult be ? FormatDateTimePattern(dateTimeFormat, patternParts, z, rangePattern).
auto raw_part_result = TRY(format_date_time_pattern(vm, date_time_format, move(pattern_parts), time, &range_pattern.value()));
diff --git a/Userland/Libraries/LibJS/Runtime/Intl/DurationFormat.cpp b/Userland/Libraries/LibJS/Runtime/Intl/DurationFormat.cpp
index b97d8fbca6..f3c3b7e526 100644
--- a/Userland/Libraries/LibJS/Runtime/Intl/DurationFormat.cpp
+++ b/Userland/Libraries/LibJS/Runtime/Intl/DurationFormat.cpp
@@ -336,7 +336,7 @@ ThrowCompletionOr<DurationUnitOptions> get_duration_unit_options(VM& vm, Depreca
}
// 1.1.7 PartitionDurationFormatPattern ( durationFormat, duration ), https://tc39.es/proposal-intl-duration-format/#sec-partitiondurationformatpattern
-Vector<PatternPartition> partition_duration_format_pattern(VM& vm, DurationFormat const& duration_format, Temporal::DurationRecord const& duration)
+ThrowCompletionOr<Vector<PatternPartition>> partition_duration_format_pattern(VM& vm, DurationFormat const& duration_format, Temporal::DurationRecord const& duration)
{
auto& realm = *vm.current_realm();
@@ -445,7 +445,8 @@ Vector<PatternPartition> partition_duration_format_pattern(VM& vm, DurationForma
// 3. Let dataLocaleData be %DurationFormat%.[[LocaleData]].[[<dataLocale>]].
// 4. Let num be ! FormatNumeric(nf, 𝔽(value)).
- auto number = format_numeric(vm, *number_format, MathematicalValue(value));
+ // NOTE: We TRY this operation only to propagate OOM errors.
+ auto number = TRY(format_numeric(vm, *number_format, MathematicalValue(value)));
// 5. Append the new Record { [[Type]]: unit, [[Value]]: num} to the end of result.
result.append({ unit, number });
@@ -504,7 +505,8 @@ Vector<PatternPartition> partition_duration_format_pattern(VM& vm, DurationForma
auto* number_format = static_cast<NumberFormat*>(MUST(construct(vm, *realm.intrinsics().intl_number_format_constructor(), PrimitiveString::create(vm, duration_format.locale()), number_format_options)).ptr());
// 5. Let parts be ! PartitionNumberPattern(nf, 𝔽(value)).
- auto parts = partition_number_pattern(vm, *number_format, MathematicalValue(value));
+ // NOTE: We TRY this operation only to propagate OOM errors.
+ auto parts = TRY(partition_number_pattern(vm, *number_format, MathematicalValue(value)));
// 6. Let concat be an empty String.
StringBuilder concat;
@@ -564,7 +566,8 @@ Vector<PatternPartition> partition_duration_format_pattern(VM& vm, DurationForma
}
// 10. Set result to ! CreatePartsFromList(lf, result).
- auto final_result = create_parts_from_list(*list_format, string_result);
+ // NOTE: We TRY this operation only to propagate OOM errors.
+ auto final_result = TRY(create_parts_from_list(vm, *list_format, string_result));
// 11. Return result.
return final_result;
diff --git a/Userland/Libraries/LibJS/Runtime/Intl/DurationFormat.h b/Userland/Libraries/LibJS/Runtime/Intl/DurationFormat.h
index 8077bd8c89..17b0b260cc 100644
--- a/Userland/Libraries/LibJS/Runtime/Intl/DurationFormat.h
+++ b/Userland/Libraries/LibJS/Runtime/Intl/DurationFormat.h
@@ -225,6 +225,6 @@ ThrowCompletionOr<Temporal::DurationRecord> to_duration_record(VM&, Value input)
i8 duration_record_sign(Temporal::DurationRecord const&);
bool is_valid_duration_record(Temporal::DurationRecord const&);
ThrowCompletionOr<DurationUnitOptions> get_duration_unit_options(VM&, DeprecatedString const& unit, Object const& options, StringView base_style, Span<StringView const> styles_list, StringView digital_base, StringView previous_style);
-Vector<PatternPartition> partition_duration_format_pattern(VM&, DurationFormat const&, Temporal::DurationRecord const& duration);
+ThrowCompletionOr<Vector<PatternPartition>> partition_duration_format_pattern(VM&, DurationFormat const&, Temporal::DurationRecord const& duration);
}
diff --git a/Userland/Libraries/LibJS/Runtime/Intl/DurationFormatPrototype.cpp b/Userland/Libraries/LibJS/Runtime/Intl/DurationFormatPrototype.cpp
index 127d9db050..913cfe7a70 100644
--- a/Userland/Libraries/LibJS/Runtime/Intl/DurationFormatPrototype.cpp
+++ b/Userland/Libraries/LibJS/Runtime/Intl/DurationFormatPrototype.cpp
@@ -43,7 +43,7 @@ JS_DEFINE_NATIVE_FUNCTION(DurationFormatPrototype::format)
auto record = TRY(to_duration_record(vm, vm.argument(0)));
// 4. Let parts be PartitionDurationFormatPattern(df, record).
- auto parts = partition_duration_format_pattern(vm, *duration_format, record);
+ auto parts = TRY(partition_duration_format_pattern(vm, *duration_format, record));
// 5. Let result be a new empty String.
StringBuilder result;
@@ -71,7 +71,7 @@ JS_DEFINE_NATIVE_FUNCTION(DurationFormatPrototype::format_to_parts)
auto record = TRY(to_duration_record(vm, vm.argument(0)));
// 4. Let parts be PartitionDurationFormatPattern(df, record).
- auto parts = partition_duration_format_pattern(vm, *duration_format, record);
+ auto parts = TRY(partition_duration_format_pattern(vm, *duration_format, record));
// 5. Let result be ! ArrayCreate(0).
auto result = MUST(Array::create(realm, 0));
diff --git a/Userland/Libraries/LibJS/Runtime/Intl/ListFormat.cpp b/Userland/Libraries/LibJS/Runtime/Intl/ListFormat.cpp
index ee0781f307..017106556a 100644
--- a/Userland/Libraries/LibJS/Runtime/Intl/ListFormat.cpp
+++ b/Userland/Libraries/LibJS/Runtime/Intl/ListFormat.cpp
@@ -46,10 +46,11 @@ StringView ListFormat::type_string() const
}
// 13.5.1 DeconstructPattern ( pattern, placeables ), https://tc39.es/ecma402/#sec-deconstructpattern
-Vector<PatternPartition> deconstruct_pattern(StringView pattern, Placeables placeables)
+ThrowCompletionOr<Vector<PatternPartition>> deconstruct_pattern(VM& vm, StringView pattern, Placeables placeables)
{
// 1. Let patternParts be ! PartitionPattern(pattern).
- auto pattern_parts = partition_pattern(pattern);
+ // NOTE: We TRY this operation only to propagate OOM errors.
+ auto pattern_parts = TRY(partition_pattern(vm, pattern));
// 2. Let result be a new empty List.
Vector<PatternPartition> result {};
@@ -93,11 +94,11 @@ Vector<PatternPartition> deconstruct_pattern(StringView pattern, Placeables plac
}
// 13.5.2 CreatePartsFromList ( listFormat, list ), https://tc39.es/ecma402/#sec-createpartsfromlist
-Vector<PatternPartition> create_parts_from_list(ListFormat const& list_format, Vector<DeprecatedString> const& list)
+ThrowCompletionOr<Vector<PatternPartition>> create_parts_from_list(VM& vm, ListFormat const& list_format, Vector<DeprecatedString> const& list)
{
auto list_patterns = ::Locale::get_locale_list_patterns(list_format.locale(), list_format.type_string(), list_format.style());
if (!list_patterns.has_value())
- return {};
+ return Vector<PatternPartition> {};
// 1. Let size be the number of elements of list.
auto size = list.size();
@@ -105,7 +106,7 @@ Vector<PatternPartition> create_parts_from_list(ListFormat const& list_format, V
// 2. If size is 0, then
if (size == 0) {
// a. Return a new empty List.
- return {};
+ return Vector<PatternPartition> {};
}
// 3. If size is 2, then
@@ -126,7 +127,7 @@ Vector<PatternPartition> create_parts_from_list(ListFormat const& list_format, V
placeables.set("1"sv, move(second));
// f. Return ! DeconstructPattern(pattern, placeables).
- return deconstruct_pattern(pattern, move(placeables));
+ return deconstruct_pattern(vm, pattern, move(placeables));
}
// 4. Let last be a new Record { [[Type]]: "element", [[Value]]: list[size - 1] }.
@@ -172,7 +173,8 @@ Vector<PatternPartition> create_parts_from_list(ListFormat const& list_format, V
placeables.set("1"sv, move(parts));
// g. Set parts to ! DeconstructPattern(pattern, placeables).
- parts = deconstruct_pattern(pattern, move(placeables));
+ // NOTE: We TRY this operation only to propagate OOM errors.
+ parts = TRY(deconstruct_pattern(vm, pattern, move(placeables)));
// h. Decrement i by 1.
} while (i-- != 0);
@@ -182,10 +184,11 @@ Vector<PatternPartition> create_parts_from_list(ListFormat const& list_format, V
}
// 13.5.3 FormatList ( listFormat, list ), https://tc39.es/ecma402/#sec-formatlist
-DeprecatedString format_list(ListFormat const& list_format, Vector<DeprecatedString> const& list)
+ThrowCompletionOr<DeprecatedString> format_list(VM& vm, ListFormat const& list_format, Vector<DeprecatedString> const& list)
{
// 1. Let parts be ! CreatePartsFromList(listFormat, list).
- auto parts = create_parts_from_list(list_format, list);
+ // NOTE: We TRY this operation only to propagate OOM errors.
+ auto parts = TRY(create_parts_from_list(vm, list_format, list));
// 2. Let result be an empty String.
StringBuilder result;
@@ -201,12 +204,13 @@ DeprecatedString format_list(ListFormat const& list_format, Vector<DeprecatedStr
}
// 13.5.4 FormatListToParts ( listFormat, list ), https://tc39.es/ecma402/#sec-formatlisttoparts
-Array* format_list_to_parts(VM& vm, ListFormat const& list_format, Vector<DeprecatedString> const& list)
+ThrowCompletionOr<Array*> format_list_to_parts(VM& vm, ListFormat const& list_format, Vector<DeprecatedString> const& list)
{
auto& realm = *vm.current_realm();
// 1. Let parts be ! CreatePartsFromList(listFormat, list).
- auto parts = create_parts_from_list(list_format, list);
+ // NOTE: We TRY this operation only to propagate OOM errors.
+ auto parts = TRY(create_parts_from_list(vm, list_format, list));
// 2. Let result be ! ArrayCreate(0).
auto result = MUST(Array::create(realm, 0));
@@ -233,7 +237,7 @@ Array* format_list_to_parts(VM& vm, ListFormat const& list_format, Vector<Deprec
}
// 5. Return result.
- return result;
+ return result.ptr();
}
// 13.5.5 StringListFromIterable ( iterable ), https://tc39.es/ecma402/#sec-createstringlistfromiterable
diff --git a/Userland/Libraries/LibJS/Runtime/Intl/ListFormat.h b/Userland/Libraries/LibJS/Runtime/Intl/ListFormat.h
index ef505b4a52..8db448bf1b 100644
--- a/Userland/Libraries/LibJS/Runtime/Intl/ListFormat.h
+++ b/Userland/Libraries/LibJS/Runtime/Intl/ListFormat.h
@@ -51,10 +51,10 @@ private:
using Placeables = HashMap<StringView, Variant<PatternPartition, Vector<PatternPartition>>>;
-Vector<PatternPartition> deconstruct_pattern(StringView pattern, Placeables);
-Vector<PatternPartition> create_parts_from_list(ListFormat const&, Vector<DeprecatedString> const& list);
-DeprecatedString format_list(ListFormat const&, Vector<DeprecatedString> const& list);
-Array* format_list_to_parts(VM&, ListFormat const&, Vector<DeprecatedString> const& list);
+ThrowCompletionOr<Vector<PatternPartition>> deconstruct_pattern(VM&, StringView pattern, Placeables);
+ThrowCompletionOr<Vector<PatternPartition>> create_parts_from_list(VM&, ListFormat const&, Vector<DeprecatedString> const& list);
+ThrowCompletionOr<DeprecatedString> format_list(VM&, ListFormat const&, Vector<DeprecatedString> const& list);
+ThrowCompletionOr<Array*> format_list_to_parts(VM&, ListFormat const&, Vector<DeprecatedString> const& list);
ThrowCompletionOr<Vector<DeprecatedString>> string_list_from_iterable(VM&, Value iterable);
}
diff --git a/Userland/Libraries/LibJS/Runtime/Intl/ListFormatPrototype.cpp b/Userland/Libraries/LibJS/Runtime/Intl/ListFormatPrototype.cpp
index d9c3988711..b3ea2e24e7 100644
--- a/Userland/Libraries/LibJS/Runtime/Intl/ListFormatPrototype.cpp
+++ b/Userland/Libraries/LibJS/Runtime/Intl/ListFormatPrototype.cpp
@@ -46,7 +46,8 @@ JS_DEFINE_NATIVE_FUNCTION(ListFormatPrototype::format)
auto string_list = TRY(string_list_from_iterable(vm, list));
// 4. Return ! FormatList(lf, stringList).
- auto formatted = format_list(*list_format, string_list);
+ // NOTE: We TRY this operation only to propagate OOM errors.
+ auto formatted = TRY(format_list(vm, *list_format, string_list));
return PrimitiveString::create(vm, move(formatted));
}
@@ -63,7 +64,8 @@ JS_DEFINE_NATIVE_FUNCTION(ListFormatPrototype::format_to_parts)
auto string_list = TRY(string_list_from_iterable(vm, list));
// 4. Return ! FormatListToParts(lf, stringList).
- return format_list_to_parts(vm, *list_format, string_list);
+ // NOTE: We TRY this operation only to propagate OOM errors.
+ return TRY(format_list_to_parts(vm, *list_format, string_list));
}
// 13.3.5 Intl.ListFormat.prototype.resolvedOptions ( ), https://tc39.es/ecma402/#sec-Intl.ListFormat.prototype.resolvedoptions
diff --git a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.cpp b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.cpp
index 175d83c24d..32bd9b8656 100644
--- a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.cpp
+++ b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.cpp
@@ -518,7 +518,7 @@ FormatResult format_numeric_to_string(NumberFormatBase const& intl_object, Mathe
// 15.5.4 PartitionNumberPattern ( numberFormat, x ), https://tc39.es/ecma402/#sec-partitionnumberpattern
// 1.5.4 PartitionNumberPattern ( numberFormat, x ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-partitionnumberpattern
-Vector<PatternPartition> partition_number_pattern(VM& vm, NumberFormat& number_format, MathematicalValue number)
+ThrowCompletionOr<Vector<PatternPartition>> partition_number_pattern(VM& vm, NumberFormat& number_format, MathematicalValue number)
{
// 1. Let exponent be 0.
int exponent = 0;
@@ -575,13 +575,13 @@ Vector<PatternPartition> partition_number_pattern(VM& vm, NumberFormat& number_f
// 6. Let pattern be GetNumberFormatPattern(numberFormat, x).
auto pattern = get_number_format_pattern(vm, number_format, number, found_pattern);
if (!pattern.has_value())
- return {};
+ return Vector<PatternPartition> {};
// 7. Let result be a new empty List.
Vector<PatternPartition> result;
// 8. Let patternParts be PartitionPattern(pattern).
- auto pattern_parts = pattern->visit([](auto const& p) { return partition_pattern(p); });
+ auto pattern_parts = TRY(pattern->visit([&](auto const& p) { return partition_pattern(vm, p); }));
// 9. For each Record { [[Type]], [[Value]] } patternPart of patternParts, do
for (auto& pattern_part : pattern_parts) {
@@ -597,7 +597,7 @@ Vector<PatternPartition> partition_number_pattern(VM& vm, NumberFormat& number_f
// c. Else if p is equal to "number", then
else if (part == "number"sv) {
// i. Let notationSubParts be PartitionNotationSubPattern(numberFormat, x, n, exponent).
- auto notation_sub_parts = partition_notation_sub_pattern(number_format, number, formatted_string, exponent);
+ auto notation_sub_parts = TRY(partition_notation_sub_pattern(vm, number_format, number, formatted_string, exponent));
// ii. Append all elements of notationSubParts to result.
result.extend(move(notation_sub_parts));
}
@@ -715,14 +715,14 @@ static Vector<StringView> separate_integer_into_groups(::Locale::NumberGroupings
// 15.5.5 PartitionNotationSubPattern ( numberFormat, x, n, exponent ), https://tc39.es/ecma402/#sec-partitionnotationsubpattern
// 1.5.5 PartitionNotationSubPattern ( numberFormat, x, n, exponent ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-partitionnotationsubpattern
-Vector<PatternPartition> partition_notation_sub_pattern(NumberFormat& number_format, MathematicalValue const& number, DeprecatedString formatted_string, int exponent)
+ThrowCompletionOr<Vector<PatternPartition>> partition_notation_sub_pattern(VM& vm, NumberFormat& number_format, MathematicalValue const& number, DeprecatedString formatted_string, int exponent)
{
// 1. Let result be a new empty List.
Vector<PatternPartition> result;
auto grouping_sizes = ::Locale::get_number_system_groupings(number_format.data_locale(), number_format.numbering_system());
if (!grouping_sizes.has_value())
- return {};
+ return Vector<PatternPartition> {};
// 2. If x is NaN, then
if (number.is_nan()) {
@@ -739,10 +739,10 @@ Vector<PatternPartition> partition_notation_sub_pattern(NumberFormat& number_for
// a. Let notationSubPattern be GetNotationSubPattern(numberFormat, exponent).
auto notation_sub_pattern = get_notation_sub_pattern(number_format, exponent);
if (!notation_sub_pattern.has_value())
- return {};
+ return Vector<PatternPartition> {};
// b. Let patternParts be PartitionPattern(notationSubPattern).
- auto pattern_parts = partition_pattern(*notation_sub_pattern);
+ auto pattern_parts = TRY(partition_pattern(vm, *notation_sub_pattern));
// c. For each Record { [[Type]], [[Value]] } patternPart of patternParts, do
for (auto& pattern_part : pattern_parts) {
@@ -898,11 +898,10 @@ Vector<PatternPartition> partition_notation_sub_pattern(NumberFormat& number_for
}
// 15.5.6 FormatNumeric ( numberFormat, x ), https://tc39.es/ecma402/#sec-formatnumber
-DeprecatedString format_numeric(VM& vm, NumberFormat& number_format, MathematicalValue number)
+ThrowCompletionOr<DeprecatedString> format_numeric(VM& vm, NumberFormat& number_format, MathematicalValue number)
{
// 1. Let parts be ? PartitionNumberPattern(numberFormat, x).
- // Note: Our implementation of PartitionNumberPattern does not throw.
- auto parts = partition_number_pattern(vm, number_format, move(number));
+ auto parts = TRY(partition_number_pattern(vm, number_format, move(number)));
// 2. Let result be the empty String.
StringBuilder result;
@@ -918,13 +917,12 @@ DeprecatedString format_numeric(VM& vm, NumberFormat& number_format, Mathematica
}
// 15.5.7 FormatNumericToParts ( numberFormat, x ), https://tc39.es/ecma402/#sec-formatnumbertoparts
-Array* format_numeric_to_parts(VM& vm, NumberFormat& number_format, MathematicalValue number)
+ThrowCompletionOr<Array*> format_numeric_to_parts(VM& vm, NumberFormat& number_format, MathematicalValue number)
{
auto& realm = *vm.current_realm();
// 1. Let parts be ? PartitionNumberPattern(numberFormat, x).
- // Note: Our implementation of PartitionNumberPattern does not throw.
- auto parts = partition_number_pattern(vm, number_format, move(number));
+ auto parts = TRY(partition_number_pattern(vm, number_format, move(number)));
// 2. Let result be ! ArrayCreate(0).
auto result = MUST(Array::create(realm, 0));
@@ -951,7 +949,7 @@ Array* format_numeric_to_parts(VM& vm, NumberFormat& number_format, Mathematical
}
// 5. Return result.
- return result;
+ return result.ptr();
}
static DeprecatedString cut_trailing_zeroes(StringView string, int cut)
@@ -1738,11 +1736,11 @@ ThrowCompletionOr<Vector<PatternPartitionWithSource>> partition_number_range_pat
Vector<PatternPartitionWithSource> result;
// 3. Let xResult be ? PartitionNumberPattern(numberFormat, x).
- auto raw_start_result = partition_number_pattern(vm, number_format, move(start));
+ auto raw_start_result = TRY(partition_number_pattern(vm, number_format, move(start)));
auto start_result = PatternPartitionWithSource::create_from_parent_list(move(raw_start_result));
// 4. Let yResult be ? PartitionNumberPattern(numberFormat, y).
- auto raw_end_result = partition_number_pattern(vm, number_format, move(end));
+ auto raw_end_result = TRY(partition_number_pattern(vm, number_format, move(end)));
auto end_result = PatternPartitionWithSource::create_from_parent_list(move(raw_end_result));
// 5. If xResult is equal to yResult, then
diff --git a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.h b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.h
index 483e29d78b..c5d54fad9c 100644
--- a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.h
+++ b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.h
@@ -277,10 +277,10 @@ enum class RoundingDecision {
int currency_digits(StringView currency);
FormatResult format_numeric_to_string(NumberFormatBase const& intl_object, MathematicalValue number);
-Vector<PatternPartition> partition_number_pattern(VM&, NumberFormat&, MathematicalValue number);
-Vector<PatternPartition> partition_notation_sub_pattern(NumberFormat&, MathematicalValue const& number, DeprecatedString formatted_string, int exponent);
-DeprecatedString format_numeric(VM&, NumberFormat&, MathematicalValue number);
-Array* format_numeric_to_parts(VM&, NumberFormat&, MathematicalValue number);
+ThrowCompletionOr<Vector<PatternPartition>> partition_number_pattern(VM&, NumberFormat&, MathematicalValue number);
+ThrowCompletionOr<Vector<PatternPartition>> partition_notation_sub_pattern(VM&, NumberFormat&, MathematicalValue const& number, DeprecatedString formatted_string, int exponent);
+ThrowCompletionOr<DeprecatedString> format_numeric(VM&, NumberFormat&, MathematicalValue number);
+ThrowCompletionOr<Array*> format_numeric_to_parts(VM&, NumberFormat&, MathematicalValue number);
RawFormatResult to_raw_precision(MathematicalValue const& number, int min_precision, int max_precision, Optional<NumberFormat::UnsignedRoundingMode> const& unsigned_rounding_mode);
RawFormatResult to_raw_fixed(MathematicalValue const& number, int min_fraction, int max_fraction, int rounding_increment, Optional<NumberFormat::UnsignedRoundingMode> const& unsigned_rounding_mode);
Optional<Variant<StringView, DeprecatedString>> get_number_format_pattern(VM&, NumberFormat&, MathematicalValue const& number, ::Locale::NumberFormat& found_pattern);
diff --git a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatFunction.cpp b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatFunction.cpp
index 6151945af9..5311dfc7a3 100644
--- a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatFunction.cpp
+++ b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatFunction.cpp
@@ -45,8 +45,7 @@ ThrowCompletionOr<Value> NumberFormatFunction::call()
auto mathematical_value = TRY(to_intl_mathematical_value(vm, value));
// 5. Return ? FormatNumeric(nf, x).
- // Note: Our implementation of FormatNumeric does not throw.
- auto formatted = format_numeric(vm, m_number_format, move(mathematical_value));
+ auto formatted = TRY(format_numeric(vm, m_number_format, move(mathematical_value)));
return PrimitiveString::create(vm, move(formatted));
}
diff --git a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatPrototype.cpp b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatPrototype.cpp
index 99d595a3f7..5674f87961 100644
--- a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatPrototype.cpp
+++ b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatPrototype.cpp
@@ -76,8 +76,7 @@ JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format_to_parts)
auto mathematical_value = TRY(to_intl_mathematical_value(vm, value));
// 4. Return ? FormatNumericToParts(nf, x).
- // Note: Our implementation of FormatNumericToParts does not throw.
- return format_numeric_to_parts(vm, *number_format, move(mathematical_value));
+ return TRY(format_numeric_to_parts(vm, *number_format, move(mathematical_value)));
}
// 1.3.5 Intl.NumberFormat.prototype.formatRange ( start, end ), https://tc39.es/proposal-intl-numberformat-v3/out/numberformat/proposed.html#sec-intl.numberformat.prototype.formatrange
diff --git a/Userland/Libraries/LibJS/Runtime/Intl/RelativeTimeFormat.cpp b/Userland/Libraries/LibJS/Runtime/Intl/RelativeTimeFormat.cpp
index 1dce1620b0..21738faebb 100644
--- a/Userland/Libraries/LibJS/Runtime/Intl/RelativeTimeFormat.cpp
+++ b/Userland/Libraries/LibJS/Runtime/Intl/RelativeTimeFormat.cpp
@@ -174,7 +174,8 @@ ThrowCompletionOr<Vector<PatternPartitionWithUnit>> partition_relative_time_patt
auto patterns = find_patterns_for_tense_or_number(tense);
// 20. Let fv be ! PartitionNumberPattern(relativeTimeFormat.[[NumberFormat]], value).
- auto value_partitions = partition_number_pattern(vm, relative_time_format.number_format(), Value(value));
+ // NOTE: We TRY this operation only to propagate OOM errors.
+ auto value_partitions = TRY(partition_number_pattern(vm, relative_time_format.number_format(), Value(value)));
// 21. Let pr be ! ResolvePlural(relativeTimeFormat.[[PluralRules]], value).
auto plurality = resolve_plural(relative_time_format.plural_rules(), Value(value));
@@ -185,14 +186,14 @@ ThrowCompletionOr<Vector<PatternPartitionWithUnit>> partition_relative_time_patt
return Vector<PatternPartitionWithUnit> {};
// 23. Return ! MakePartsList(pattern, unit, fv).
- return make_parts_list(pattern->pattern, ::Locale::time_unit_to_string(time_unit), move(value_partitions));
+ return make_parts_list(vm, pattern->pattern, ::Locale::time_unit_to_string(time_unit), move(value_partitions));
}
// 17.5.3 MakePartsList ( pattern, unit, parts ), https://tc39.es/ecma402/#sec-makepartslist
-Vector<PatternPartitionWithUnit> make_parts_list(StringView pattern, StringView unit, Vector<PatternPartition> parts)
+ThrowCompletionOr<Vector<PatternPartitionWithUnit>> make_parts_list(VM& vm, StringView pattern, StringView unit, Vector<PatternPartition> parts)
{
// 1. Let patternParts be PartitionPattern(pattern).
- auto pattern_parts = partition_pattern(pattern);
+ auto pattern_parts = TRY(partition_pattern(vm, pattern));
// 2. Let result be a new empty List.
Vector<PatternPartitionWithUnit> result;
diff --git a/Userland/Libraries/LibJS/Runtime/Intl/RelativeTimeFormat.h b/Userland/Libraries/LibJS/Runtime/Intl/RelativeTimeFormat.h
index ff64342ee7..1a3e45a0a7 100644
--- a/Userland/Libraries/LibJS/Runtime/Intl/RelativeTimeFormat.h
+++ b/Userland/Libraries/LibJS/Runtime/Intl/RelativeTimeFormat.h
@@ -84,7 +84,7 @@ struct PatternPartitionWithUnit : public PatternPartition {
ThrowCompletionOr<::Locale::TimeUnit> singular_relative_time_unit(VM&, StringView unit);
ThrowCompletionOr<Vector<PatternPartitionWithUnit>> partition_relative_time_pattern(VM&, RelativeTimeFormat&, double value, StringView unit);
-Vector<PatternPartitionWithUnit> make_parts_list(StringView pattern, StringView unit, Vector<PatternPartition> parts);
+ThrowCompletionOr<Vector<PatternPartitionWithUnit>> make_parts_list(VM&, StringView pattern, StringView unit, Vector<PatternPartition> parts);
ThrowCompletionOr<DeprecatedString> format_relative_time(VM&, RelativeTimeFormat&, double value, StringView unit);
ThrowCompletionOr<Array*> format_relative_time_to_parts(VM&, RelativeTimeFormat&, double value, StringView unit);
diff --git a/Userland/Libraries/LibJS/Runtime/NumberPrototype.cpp b/Userland/Libraries/LibJS/Runtime/NumberPrototype.cpp
index 2776a40012..762c266476 100644
--- a/Userland/Libraries/LibJS/Runtime/NumberPrototype.cpp
+++ b/Userland/Libraries/LibJS/Runtime/NumberPrototype.cpp
@@ -287,8 +287,7 @@ JS_DEFINE_NATIVE_FUNCTION(NumberPrototype::to_locale_string)
auto* number_format = static_cast<Intl::NumberFormat*>(TRY(construct(vm, *realm.intrinsics().intl_number_format_constructor(), locales, options)).ptr());
// 3. Return ? FormatNumeric(numberFormat, x).
- // Note: Our implementation of FormatNumeric does not throw.
- auto formatted = Intl::format_numeric(vm, *number_format, number_value);
+ auto formatted = TRY(Intl::format_numeric(vm, *number_format, number_value));
return PrimitiveString::create(vm, move(formatted));
}