diff options
author | Timothy Flynn <trflynn89@pm.me> | 2023-01-19 12:26:37 -0500 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2023-01-19 20:57:30 +0000 |
commit | 1e6e719592ae61ecad300aa78154f71bf0eb11a8 (patch) | |
tree | d85869fc36d2dbd13e4c148909893ff8fceaab9c | |
parent | bff0e25ebed03db133c708a05c4f08bb5244d0ba (diff) | |
download | serenity-1e6e719592ae61ecad300aa78154f71bf0eb11a8.zip |
LibJS: Propagate OOM errors from the PartitionPattern Abstract Operation
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)); } |