From b3694653a72f505440bc803d22a12fa0612489a9 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Wed, 30 Aug 2023 12:30:39 -0400 Subject: [PATCH] LibJS: Stop propagating small OOM errors from Intl.NumberFormat Note this also does the same for Intl.PluralRules. The only OOM errors propagated from Intl.PluralRules were from Intl.NumberFormat. --- .../LibJS/Runtime/BigIntPrototype.cpp | 2 +- .../LibJS/Runtime/Intl/DateTimeFormat.cpp | 6 +- .../LibJS/Runtime/Intl/DurationFormat.cpp | 4 +- .../LibJS/Runtime/Intl/NumberFormat.cpp | 231 +++++++++--------- .../LibJS/Runtime/Intl/NumberFormat.h | 24 +- .../Runtime/Intl/NumberFormatConstructor.cpp | 6 +- .../Runtime/Intl/NumberFormatConstructor.h | 2 +- .../Runtime/Intl/NumberFormatFunction.cpp | 2 +- .../Runtime/Intl/NumberFormatPrototype.cpp | 4 +- .../LibJS/Runtime/Intl/PluralRules.cpp | 16 +- .../LibJS/Runtime/Intl/PluralRules.h | 4 +- .../Runtime/Intl/PluralRulesConstructor.cpp | 6 +- .../Runtime/Intl/PluralRulesConstructor.h | 2 +- .../Runtime/Intl/PluralRulesPrototype.cpp | 2 +- .../LibJS/Runtime/Intl/RelativeTimeFormat.cpp | 4 +- .../LibJS/Runtime/NumberPrototype.cpp | 2 +- 16 files changed, 153 insertions(+), 164 deletions(-) diff --git a/Userland/Libraries/LibJS/Runtime/BigIntPrototype.cpp b/Userland/Libraries/LibJS/Runtime/BigIntPrototype.cpp index 16df2d72e4d..c96a865f214 100644 --- a/Userland/Libraries/LibJS/Runtime/BigIntPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/BigIntPrototype.cpp @@ -91,7 +91,7 @@ JS_DEFINE_NATIVE_FUNCTION(BigIntPrototype::to_locale_string) auto* number_format = static_cast(TRY(construct(vm, realm.intrinsics().intl_number_format_constructor(), locales, options)).ptr()); // 3. Return ? FormatNumeric(numberFormat, x). - auto formatted = TRY(Intl::format_numeric(vm, *number_format, Value(bigint))); + auto formatted = Intl::format_numeric(vm, *number_format, Value(bigint)); return PrimitiveString::create(vm, move(formatted)); } diff --git a/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.cpp b/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.cpp index 37f652bfff8..64f06bcaffa 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.cpp @@ -538,7 +538,7 @@ ThrowCompletionOr> format_date_time_pattern(VM& vm, Dat value = floor(value * pow(10, static_cast(*fractional_second_digits) - 3)); // iii. Let fv be FormatNumeric(nf3, v). - auto formatted_value = MUST(format_numeric(vm, *number_format3, Value(value))); + auto formatted_value = 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) }); @@ -622,13 +622,13 @@ ThrowCompletionOr> 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 = MUST(format_numeric(vm, *number_format, Value(value))); + formatted_value = 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 = MUST(format_numeric(vm, *number_format2, Value(value))); + formatted_value = 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. diff --git a/Userland/Libraries/LibJS/Runtime/Intl/DurationFormat.cpp b/Userland/Libraries/LibJS/Runtime/Intl/DurationFormat.cpp index 0c08a2394f9..02bb9d35c89 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/DurationFormat.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/DurationFormat.cpp @@ -446,7 +446,7 @@ Vector partition_duration_format_pattern(VM& vm, DurationForma // 3. Let dataLocaleData be %DurationFormat%.[[LocaleData]].[[]]. // 4. Let num be ! FormatNumeric(nf, š”½(value)). - auto number = MUST(format_numeric(vm, *number_format, MathematicalValue(value))); + auto number = format_numeric(vm, *number_format, MathematicalValue(value)); // 5. Append the new Record { [[Type]]: unit, [[Value]]: num} to the end of result. result.append({ unit, move(number) }); @@ -505,7 +505,7 @@ Vector partition_duration_format_pattern(VM& vm, DurationForma auto* number_format = static_cast(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 = MUST(partition_number_pattern(vm, *number_format, MathematicalValue(value))); + auto parts = partition_number_pattern(vm, *number_format, MathematicalValue(value)); // 6. Let concat be an empty String. StringBuilder concat; diff --git a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.cpp b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.cpp index 3460f5bf056..251a20676ae 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.cpp @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -14,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -257,7 +257,7 @@ void NumberFormatBase::set_trailing_zero_display(StringView trailing_zero_displa VERIFY_NOT_REACHED(); } -ThrowCompletionOr NumberFormat::use_grouping_to_value(VM& vm) const +Value NumberFormat::use_grouping_to_value(VM& vm) const { switch (m_use_grouping) { case UseGrouping::Always: @@ -391,7 +391,7 @@ int currency_digits(StringView currency) } // 15.5.3 FormatNumericToString ( intlObject, x ), https://tc39.es/ecma402/#sec-formatnumberstring -ThrowCompletionOr format_numeric_to_string(VM& vm, NumberFormatBase const& intl_object, MathematicalValue number) +FormatResult format_numeric_to_string(NumberFormatBase const& intl_object, MathematicalValue number) { bool is_negative = false; @@ -427,23 +427,23 @@ ThrowCompletionOr format_numeric_to_string(VM& vm, NumberFormatBas // 4. If intlObject.[[RoundingType]] is significantDigits, then case NumberFormatBase::RoundingType::SignificantDigits: // a. Let result be ToRawPrecision(x, intlObject.[[MinimumSignificantDigits]], intlObject.[[MaximumSignificantDigits]], unsignedRoundingMode). - result = MUST_OR_THROW_OOM(to_raw_precision(vm, number, intl_object.min_significant_digits(), intl_object.max_significant_digits(), unsigned_rounding_mode)); + result = to_raw_precision(number, intl_object.min_significant_digits(), intl_object.max_significant_digits(), unsigned_rounding_mode); break; // 5. Else if intlObject.[[RoundingType]] is fractionDigits, then case NumberFormatBase::RoundingType::FractionDigits: // a. Let result be ToRawFixed(x, intlObject.[[MinimumFractionDigits]], intlObject.[[MaximumFractionDigits]], intlObject.[[RoundingIncrement]], unsignedRoundingMode). - result = MUST_OR_THROW_OOM(to_raw_fixed(vm, number, intl_object.min_fraction_digits(), intl_object.max_fraction_digits(), intl_object.rounding_increment(), unsigned_rounding_mode)); + result = to_raw_fixed(number, intl_object.min_fraction_digits(), intl_object.max_fraction_digits(), intl_object.rounding_increment(), unsigned_rounding_mode); break; // 6. Else, case NumberFormatBase::RoundingType::MorePrecision: case NumberFormatBase::RoundingType::LessPrecision: { // a. Let sResult be ToRawPrecision(x, intlObject.[[MinimumSignificantDigits]], intlObject.[[MaximumSignificantDigits]], unsignedRoundingMode). - auto significant_result = MUST_OR_THROW_OOM(to_raw_precision(vm, number, intl_object.min_significant_digits(), intl_object.max_significant_digits(), unsigned_rounding_mode)); + auto significant_result = to_raw_precision(number, intl_object.min_significant_digits(), intl_object.max_significant_digits(), unsigned_rounding_mode); // b. Let fResult be ToRawFixed(x, intlObject.[[MinimumFractionDigits]], intlObject.[[MaximumFractionDigits]], intlObject.[[RoundingIncrement]], unsignedRoundingMode). - auto fraction_result = MUST_OR_THROW_OOM(to_raw_fixed(vm, number, intl_object.min_fraction_digits(), intl_object.max_fraction_digits(), intl_object.rounding_increment(), unsigned_rounding_mode)); + auto fraction_result = to_raw_fixed(number, intl_object.min_fraction_digits(), intl_object.max_fraction_digits(), intl_object.rounding_increment(), unsigned_rounding_mode); // c. If intlObj.[[RoundingType]] is morePrecision, then if (intl_object.rounding_type() == NumberFormatBase::RoundingType::MorePrecision) { @@ -495,7 +495,7 @@ ThrowCompletionOr format_numeric_to_string(VM& vm, NumberFormatBas // b. If i ≠ -1, set string to the substring of string from 0 to i. if (index.has_value()) - string = TRY_OR_THROW_OOM(vm, string.substring_from_byte_offset(0, *index)); + string = MUST(string.substring_from_byte_offset(0, *index)); } // 10. Let int be result.[[IntegerDigitsCount]]. @@ -507,10 +507,10 @@ ThrowCompletionOr format_numeric_to_string(VM& vm, NumberFormatBas // 12. If int < minInteger, then if (digits < min_integer) { // a. Let forwardZeros be the String consisting of minInteger - int occurrences of the code unit 0x0030 (DIGIT ZERO). - auto forward_zeros = TRY_OR_THROW_OOM(vm, String::repeated('0', min_integer - digits)); + auto forward_zeros = MUST(String::repeated('0', min_integer - digits)); // b. Set string to the string-concatenation of forwardZeros and string. - string = TRY_OR_THROW_OOM(vm, String::formatted("{}{}", forward_zeros, string)); + string = MUST(String::formatted("{}{}", forward_zeros, string)); } // 13. If isNegative is true, then @@ -523,11 +523,11 @@ ThrowCompletionOr format_numeric_to_string(VM& vm, NumberFormatBas } // 14. Return the Record { [[RoundedNumber]]: x, [[FormattedString]]: string }. - return FormatResult { move(string), move(number) }; + return { move(string), move(number) }; } // 15.5.4 PartitionNumberPattern ( numberFormat, x ), https://tc39.es/ecma402/#sec-partitionnumberpattern -ThrowCompletionOr> partition_number_pattern(VM& vm, NumberFormat& number_format, MathematicalValue number) +Vector partition_number_pattern(VM& vm, NumberFormat& number_format, MathematicalValue number) { // 1. Let exponent be 0. int exponent = 0; @@ -538,13 +538,13 @@ ThrowCompletionOr> partition_number_pattern(VM& vm, Num if (number.is_nan()) { // a. Let n be an implementation- and locale-dependent (ILD) String value indicating the NaN value. auto symbol = ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::NaN).value_or("NaN"sv); - formatted_string = TRY_OR_THROW_OOM(vm, String::from_utf8(symbol)); + formatted_string = MUST(String::from_utf8(symbol)); } // 3. Else if x is positive-infinity, then else if (number.is_positive_infinity()) { // a. Let n be an ILD String value indicating positive infinity. auto symbol = ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::Infinity).value_or("infinity"sv); - formatted_string = TRY_OR_THROW_OOM(vm, String::from_utf8(symbol)); + formatted_string = MUST(String::from_utf8(symbol)); } // 4. Else if x is negative-infinity, then else if (number.is_negative_infinity()) { @@ -552,7 +552,7 @@ ThrowCompletionOr> partition_number_pattern(VM& vm, Num // NOTE: The CLDR does not contain unique strings for negative infinity. The negative sign will // be inserted by the pattern returned from GetNumberFormatPattern. auto symbol = ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::Infinity).value_or("infinity"sv); - formatted_string = TRY_OR_THROW_OOM(vm, String::from_utf8(symbol)); + formatted_string = MUST(String::from_utf8(symbol)); } // 5. Else, else { @@ -566,14 +566,14 @@ ThrowCompletionOr> partition_number_pattern(VM& vm, Num number = number.multiplied_by(100); // iii. Let exponent be ComputeExponent(numberFormat, x). - exponent = MUST_OR_THROW_OOM(compute_exponent(vm, number_format, number)); + exponent = compute_exponent(number_format, number); // iv. Let x be x Ɨ 10^-exponent. number = number.multiplied_by_power(-exponent); } // b. Let formatNumberResult be FormatNumericToString(numberFormat, x). - auto format_number_result = MUST_OR_THROW_OOM(format_numeric_to_string(vm, number_format, move(number))); + auto format_number_result = format_numeric_to_string(number_format, move(number)); // c. Let n be formatNumberResult.[[FormattedString]]. formatted_string = move(format_number_result.formatted_string); @@ -585,9 +585,9 @@ ThrowCompletionOr> partition_number_pattern(VM& vm, Num ::Locale::NumberFormat found_pattern {}; // 6. Let pattern be GetNumberFormatPattern(numberFormat, x). - auto pattern = MUST_OR_THROW_OOM(get_number_format_pattern(vm, number_format, number, found_pattern)); + auto pattern = get_number_format_pattern(vm, number_format, number, found_pattern); if (!pattern.has_value()) - return Vector {}; + return {}; // 7. Let result be a new empty List. Vector result; @@ -603,15 +603,15 @@ ThrowCompletionOr> partition_number_pattern(VM& vm, Num // b. If p is "literal", then if (part == "literal"sv) { // i. Append a new Record { [[Type]]: "literal", [[Value]]: patternPart.[[Value]] } as the last element of result. - TRY_OR_THROW_OOM(vm, result.try_append({ "literal"sv, move(pattern_part.value) })); + result.append({ "literal"sv, move(pattern_part.value) }); } // 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 = MUST_OR_THROW_OOM(partition_notation_sub_pattern(vm, number_format, number, formatted_string, exponent)); + auto notation_sub_parts = partition_notation_sub_pattern(number_format, number, formatted_string, exponent); // ii. Append all elements of notationSubParts to result. - TRY_OR_THROW_OOM(vm, result.try_extend(move(notation_sub_parts))); + result.extend(move(notation_sub_parts)); } // d. Else if p is equal to "plusSign", then @@ -619,7 +619,7 @@ ThrowCompletionOr> partition_number_pattern(VM& vm, Num // i. Let plusSignSymbol be the ILND String representing the plus sign. auto plus_sign_symbol = ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::PlusSign).value_or("+"sv); // ii. Append a new Record { [[Type]]: "plusSign", [[Value]]: plusSignSymbol } as the last element of result. - TRY_OR_THROW_OOM(vm, result.try_append({ "plusSign"sv, TRY_OR_THROW_OOM(vm, String::from_utf8(plus_sign_symbol)) })); + result.append({ "plusSign"sv, MUST(String::from_utf8(plus_sign_symbol)) }); } // e. Else if p is equal to "minusSign", then @@ -627,7 +627,7 @@ ThrowCompletionOr> partition_number_pattern(VM& vm, Num // i. Let minusSignSymbol be the ILND String representing the minus sign. auto minus_sign_symbol = ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::MinusSign).value_or("-"sv); // ii. Append a new Record { [[Type]]: "minusSign", [[Value]]: minusSignSymbol } as the last element of result. - TRY_OR_THROW_OOM(vm, result.try_append({ "minusSign"sv, TRY_OR_THROW_OOM(vm, String::from_utf8(minus_sign_symbol)) })); + result.append({ "minusSign"sv, MUST(String::from_utf8(minus_sign_symbol)) }); } // f. Else if p is equal to "percentSign" and numberFormat.[[Style]] is "percent", then @@ -635,7 +635,7 @@ ThrowCompletionOr> partition_number_pattern(VM& vm, Num // i. Let percentSignSymbol be the ILND String representing the percent sign. auto percent_sign_symbol = ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::PercentSign).value_or("%"sv); // ii. Append a new Record { [[Type]]: "percentSign", [[Value]]: percentSignSymbol } as the last element of result. - TRY_OR_THROW_OOM(vm, result.try_append({ "percentSign"sv, TRY_OR_THROW_OOM(vm, String::from_utf8(percent_sign_symbol)) })); + result.append({ "percentSign"sv, MUST(String::from_utf8(percent_sign_symbol)) }); } // g. Else if p is equal to "unitPrefix" and numberFormat.[[Style]] is "unit", then @@ -652,7 +652,7 @@ ThrowCompletionOr> partition_number_pattern(VM& vm, Num auto unit_identifier = found_pattern.identifiers[*identifier_index]; // iv. Append a new Record { [[Type]]: "unit", [[Value]]: mu } as the last element of result. - TRY_OR_THROW_OOM(vm, result.try_append({ "unit"sv, TRY_OR_THROW_OOM(vm, String::from_utf8(unit_identifier)) })); + result.append({ "unit"sv, MUST(String::from_utf8(unit_identifier)) }); } // i. Else if p is equal to "currencyCode" and numberFormat.[[Style]] is "currency", then @@ -664,7 +664,7 @@ ThrowCompletionOr> partition_number_pattern(VM& vm, Num // display / plurality lookups more than once. else if ((part == "currency"sv) && (number_format.style() == NumberFormat::Style::Currency)) { auto currency = number_format.resolve_currency_display(); - TRY_OR_THROW_OOM(vm, result.try_append({ "currency"sv, TRY_OR_THROW_OOM(vm, String::from_utf8(currency)) })); + result.append({ "currency"sv, MUST(String::from_utf8(currency)) }); } // l. Else, @@ -681,29 +681,23 @@ ThrowCompletionOr> partition_number_pattern(VM& vm, Num return result; } -static ThrowCompletionOr> separate_integer_into_groups(VM& vm, ::Locale::NumberGroupings const& grouping_sizes, String integer, NumberFormat::UseGrouping use_grouping) +static Vector separate_integer_into_groups(::Locale::NumberGroupings const& grouping_sizes, String integer, NumberFormat::UseGrouping use_grouping) { - auto default_group = [&]() -> ThrowCompletionOr> { - Vector groups; - TRY_OR_THROW_OOM(vm, groups.try_append(move(integer))); - return groups; - }; - auto utf8_integer = integer.code_points(); if (utf8_integer.length() <= grouping_sizes.primary_grouping_size) - return default_group(); + return { move(integer) }; size_t index = utf8_integer.length() - grouping_sizes.primary_grouping_size; switch (use_grouping) { case NumberFormat::UseGrouping::Min2: if (utf8_integer.length() < 5) - return default_group(); + return { move(integer) }; break; case NumberFormat::UseGrouping::Auto: if (index < grouping_sizes.minimum_grouping_digits) - return default_group(); + return { move(integer) }; break; case NumberFormat::UseGrouping::Always: @@ -715,55 +709,53 @@ static ThrowCompletionOr> separate_integer_into_groups(VM& vm, :: Vector groups; - auto add_group = [&](size_t index, size_t length) -> ThrowCompletionOr { + auto add_group = [&](size_t index, size_t length) { length = utf8_integer.unicode_substring_view(index, length).byte_length(); index = utf8_integer.byte_offset_of(index); - auto group = TRY_OR_THROW_OOM(vm, integer.substring_from_byte_offset_with_shared_superstring(index, length)); - TRY_OR_THROW_OOM(vm, groups.try_prepend(move(group))); - - return {}; + auto group = MUST(integer.substring_from_byte_offset_with_shared_superstring(index, length)); + groups.prepend(move(group)); }; - MUST_OR_THROW_OOM(add_group(index, grouping_sizes.primary_grouping_size)); + add_group(index, grouping_sizes.primary_grouping_size); while (index > grouping_sizes.secondary_grouping_size) { index -= grouping_sizes.secondary_grouping_size; - MUST_OR_THROW_OOM(add_group(index, grouping_sizes.secondary_grouping_size)); + add_group(index, grouping_sizes.secondary_grouping_size); } if (index > 0) - MUST_OR_THROW_OOM(add_group(0, index)); + add_group(0, index); return groups; } // 15.5.5 PartitionNotationSubPattern ( numberFormat, x, n, exponent ), https://tc39.es/ecma402/#sec-partitionnotationsubpattern -ThrowCompletionOr> partition_notation_sub_pattern(VM& vm, NumberFormat& number_format, MathematicalValue const& number, String formatted_string, int exponent) +Vector partition_notation_sub_pattern(NumberFormat& number_format, MathematicalValue const& number, String formatted_string, int exponent) { // 1. Let result be a new empty List. Vector result; auto grouping_sizes = ::Locale::get_number_system_groupings(number_format.data_locale(), number_format.numbering_system()); if (!grouping_sizes.has_value()) - return Vector {}; + return {}; // 2. If x is not-a-number, then if (number.is_nan()) { // a. Append a new Record { [[Type]]: "nan", [[Value]]: n } as the last element of result. - TRY_OR_THROW_OOM(vm, result.try_append({ "nan"sv, move(formatted_string) })); + result.append({ "nan"sv, move(formatted_string) }); } // 3. Else if x is positive-infinity or negative-infinity, then else if (number.is_positive_infinity() || number.is_negative_infinity()) { // a. Append a new Record { [[Type]]: "infinity", [[Value]]: n } as the last element of result. - TRY_OR_THROW_OOM(vm, result.try_append({ "infinity"sv, move(formatted_string) })); + result.append({ "infinity"sv, move(formatted_string) }); } // 4. Else, else { // 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 Vector {}; + return {}; // b. Let patternParts be PartitionPattern(notationSubPattern). auto pattern_parts = partition_pattern(*notation_sub_pattern); @@ -776,7 +768,7 @@ ThrowCompletionOr> partition_notation_sub_pattern(VM& v // ii. If p is "literal", then if (part == "literal"sv) { // 1. Append a new Record { [[Type]]: "literal", [[Value]]: patternPart.[[Value]] } as the last element of result. - TRY_OR_THROW_OOM(vm, result.try_append({ "literal"sv, move(pattern_part.value) })); + result.append({ "literal"sv, move(pattern_part.value) }); } // iii. Else if p is equal to "number", then else if (part == "number"sv) { @@ -807,10 +799,10 @@ ThrowCompletionOr> partition_notation_sub_pattern(VM& v // 4. If decimalSepIndex > 0, then if (decimal_sep_index.has_value() && (*decimal_sep_index > 0)) { // a. Let integer be the substring of n from position 0, inclusive, to position decimalSepIndex, exclusive. - integer = TRY_OR_THROW_OOM(vm, formatted_string.substring_from_byte_offset_with_shared_superstring(0, *decimal_sep_index)); + integer = MUST(formatted_string.substring_from_byte_offset_with_shared_superstring(0, *decimal_sep_index)); // b. Let fraction be the substring of n from position decimalSepIndex, exclusive, to the end of n. - fraction = TRY_OR_THROW_OOM(vm, formatted_string.substring_from_byte_offset_with_shared_superstring(*decimal_sep_index + 1)); + fraction = MUST(formatted_string.substring_from_byte_offset_with_shared_superstring(*decimal_sep_index + 1)); } // 5. Else, else { @@ -822,7 +814,7 @@ ThrowCompletionOr> partition_notation_sub_pattern(VM& v // 6. If the numberFormat.[[UseGrouping]] is false, then if (number_format.use_grouping() == NumberFormat::UseGrouping::False) { // a. Append a new Record { [[Type]]: "integer", [[Value]]: integer } as the last element of result. - TRY_OR_THROW_OOM(vm, result.try_append({ "integer"sv, move(integer) })); + result.append({ "integer"sv, move(integer) }); } // 7. Else, else { @@ -830,7 +822,7 @@ ThrowCompletionOr> partition_notation_sub_pattern(VM& v auto group_sep_symbol = ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::Group).value_or(","sv); // b. Let groups be a List whose elements are, in left to right order, the substrings defined by ILND set of locations within the integer, which may depend on the value of numberFormat.[[UseGrouping]]. - auto groups = MUST_OR_THROW_OOM(separate_integer_into_groups(vm, *grouping_sizes, move(integer), number_format.use_grouping())); + auto groups = separate_integer_into_groups(*grouping_sizes, move(integer), number_format.use_grouping()); // c. Assert: The number of elements in groups List is greater than 0. VERIFY(!groups.is_empty()); @@ -841,12 +833,12 @@ ThrowCompletionOr> partition_notation_sub_pattern(VM& v auto integer_group = groups.take_first(); // ii. Append a new Record { [[Type]]: "integer", [[Value]]: integerGroup } as the last element of result. - TRY_OR_THROW_OOM(vm, result.try_append({ "integer"sv, move(integer_group) })); + result.append({ "integer"sv, move(integer_group) }); // iii. If groups List is not empty, then if (!groups.is_empty()) { // i. Append a new Record { [[Type]]: "group", [[Value]]: groupSepSymbol } as the last element of result. - TRY_OR_THROW_OOM(vm, result.try_append({ "group"sv, TRY_OR_THROW_OOM(vm, String::from_utf8(group_sep_symbol)) })); + result.append({ "group"sv, MUST(String::from_utf8(group_sep_symbol)) }); } } } @@ -856,9 +848,9 @@ ThrowCompletionOr> partition_notation_sub_pattern(VM& v // a. Let decimalSepSymbol be the ILND String representing the decimal separator. auto decimal_sep_symbol = ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::Decimal).value_or("."sv); // b. Append a new Record { [[Type]]: "decimal", [[Value]]: decimalSepSymbol } as the last element of result. - TRY_OR_THROW_OOM(vm, result.try_append({ "decimal"sv, TRY_OR_THROW_OOM(vm, String::from_utf8(decimal_sep_symbol)) })); + result.append({ "decimal"sv, MUST(String::from_utf8(decimal_sep_symbol)) }); // c. Append a new Record { [[Type]]: "fraction", [[Value]]: fraction } as the last element of result. - TRY_OR_THROW_OOM(vm, result.try_append({ "fraction"sv, fraction.release_value() })); + result.append({ "fraction"sv, fraction.release_value() }); } } // iv. Else if p is equal to "compactSymbol", then @@ -873,14 +865,14 @@ ThrowCompletionOr> partition_notation_sub_pattern(VM& v auto compact_identifier = number_format.compact_format().identifiers[*identifier_index]; // 2. Append a new Record { [[Type]]: "compact", [[Value]]: compactSymbol } as the last element of result. - TRY_OR_THROW_OOM(vm, result.try_append({ "compact"sv, TRY_OR_THROW_OOM(vm, String::from_utf8(compact_identifier)) })); + result.append({ "compact"sv, MUST(String::from_utf8(compact_identifier)) }); } // vi. Else if p is equal to "scientificSeparator", then else if (part == "scientificSeparator"sv) { // 1. Let scientificSeparator be the ILND String representing the exponent separator. auto scientific_separator = ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::Exponential).value_or("E"sv); // 2. Append a new Record { [[Type]]: "exponentSeparator", [[Value]]: scientificSeparator } as the last element of result. - TRY_OR_THROW_OOM(vm, result.try_append({ "exponentSeparator"sv, TRY_OR_THROW_OOM(vm, String::from_utf8(scientific_separator)) })); + result.append({ "exponentSeparator"sv, MUST(String::from_utf8(scientific_separator)) }); } // vii. Else if p is equal to "scientificExponent", then else if (part == "scientificExponent"sv) { @@ -890,7 +882,7 @@ ThrowCompletionOr> partition_notation_sub_pattern(VM& v auto minus_sign_symbol = ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::MinusSign).value_or("-"sv); // b. Append a new Record { [[Type]]: "exponentMinusSign", [[Value]]: minusSignSymbol } as the last element of result. - TRY_OR_THROW_OOM(vm, result.try_append({ "exponentMinusSign"sv, TRY_OR_THROW_OOM(vm, String::from_utf8(minus_sign_symbol)) })); + result.append({ "exponentMinusSign"sv, MUST(String::from_utf8(minus_sign_symbol)) }); // c. Let exponent be -exponent. exponent *= -1; @@ -898,14 +890,14 @@ ThrowCompletionOr> partition_notation_sub_pattern(VM& v // 2. Let exponentResult be ToRawFixed(exponent, 0, 0, 1, undefined). auto exponent_value = MathematicalValue { static_cast(exponent) }; - auto exponent_result = MUST_OR_THROW_OOM(to_raw_fixed(vm, exponent_value, 0, 0, 1, {})); + auto exponent_result = to_raw_fixed(exponent_value, 0, 0, 1, {}); // FIXME: The spec does not say to do this, but all of major engines perform this replacement. // Without this, formatting with non-Latin numbering systems will produce non-localized results. exponent_result.formatted_string = ::Locale::replace_digits_for_number_system(number_format.numbering_system(), exponent_result.formatted_string); // 3. Append a new Record { [[Type]]: "exponentInteger", [[Value]]: exponentResult.[[FormattedString]] } as the last element of result. - TRY_OR_THROW_OOM(vm, result.try_append({ "exponentInteger"sv, move(exponent_result.formatted_string) })); + result.append({ "exponentInteger"sv, move(exponent_result.formatted_string) }); } // viii. Else, else { @@ -923,31 +915,31 @@ ThrowCompletionOr> partition_notation_sub_pattern(VM& v } // 15.5.6 FormatNumeric ( numberFormat, x ), https://tc39.es/ecma402/#sec-formatnumber -ThrowCompletionOr format_numeric(VM& vm, NumberFormat& number_format, MathematicalValue number) +String format_numeric(VM& vm, NumberFormat& number_format, MathematicalValue number) { // 1. Let parts be ? PartitionNumberPattern(numberFormat, x). - auto parts = TRY(partition_number_pattern(vm, number_format, move(number))); + auto parts = partition_number_pattern(vm, number_format, move(number)); // 2. Let result be the empty String. - ThrowableStringBuilder result(vm); + StringBuilder result; // 3. For each Record { [[Type]], [[Value]] } part in parts, do for (auto& part : parts) { // a. Set result to the string-concatenation of result and part.[[Value]]. - TRY(result.append(part.value)); + result.append(part.value); } // 4. Return result. - return result.to_string(); + return MUST(result.to_string()); } // 15.5.7 FormatNumericToParts ( numberFormat, x ), https://tc39.es/ecma402/#sec-formatnumbertoparts -ThrowCompletionOr format_numeric_to_parts(VM& vm, NumberFormat& number_format, MathematicalValue number) +NonnullGCPtr format_numeric_to_parts(VM& vm, NumberFormat& number_format, MathematicalValue number) { auto& realm = *vm.current_realm(); // 1. Let parts be ? PartitionNumberPattern(numberFormat, x). - auto parts = TRY(partition_number_pattern(vm, number_format, move(number))); + auto parts = partition_number_pattern(vm, number_format, move(number)); // 2. Let result be ! ArrayCreate(0). auto result = MUST(Array::create(realm, 0)); @@ -974,10 +966,10 @@ ThrowCompletionOr format_numeric_to_parts(VM& vm, NumberFormat& number_f } // 5. Return result. - return result.ptr(); + return result; } -static ErrorOr cut_trailing_zeroes(StringView string, int cut) +static String cut_trailing_zeroes(StringView string, int cut) { // These steps are exactly the same between ToRawPrecision and ToRawFixed. @@ -996,7 +988,7 @@ static ErrorOr cut_trailing_zeroes(StringView string, int cut) string = string.substring_view(0, string.length() - 1); } - return String::from_utf8(string); + return MUST(String::from_utf8(string)); } enum class PreferredResult { @@ -1047,7 +1039,7 @@ static RawPrecisionResult to_raw_precision_function(MathematicalValue const& num } // 15.5.8 ToRawPrecision ( x, minPrecision, maxPrecision ), https://tc39.es/ecma402/#sec-torawprecision -ThrowCompletionOr to_raw_precision(VM& vm, MathematicalValue const& number, int min_precision, int max_precision, NumberFormat::UnsignedRoundingMode unsigned_rounding_mode) +RawFormatResult to_raw_precision(MathematicalValue const& number, int min_precision, int max_precision, NumberFormat::UnsignedRoundingMode unsigned_rounding_mode) { RawFormatResult result {}; @@ -1058,7 +1050,7 @@ ThrowCompletionOr to_raw_precision(VM& vm, MathematicalValue co // 2. If x = 0, then if (number.is_zero()) { // a. Let m be the String consisting of p occurrences of the code unit 0x0030 (DIGIT ZERO). - result.formatted_string = TRY_OR_THROW_OOM(vm, String::repeated('0', precision)); + result.formatted_string = MUST(String::repeated('0', precision)); // b. Let e be 0. exponent = 0; @@ -1109,11 +1101,10 @@ ThrowCompletionOr to_raw_precision(VM& vm, MathematicalValue co // 4. If e ≄ (p – 1), then if (exponent >= (precision - 1)) { // a. Set m to the string-concatenation of m and e - p + 1 occurrences of the code unit 0x0030 (DIGIT ZERO). - result.formatted_string = TRY_OR_THROW_OOM(vm, - String::formatted( - "{}{}", - result.formatted_string, - TRY_OR_THROW_OOM(vm, String::repeated('0', exponent - precision + 1)))); + result.formatted_string = MUST(String::formatted( + "{}{}", + result.formatted_string, + MUST(String::repeated('0', exponent - precision + 1)))); // b. Let int be e + 1. result.digits = exponent + 1; @@ -1121,11 +1112,10 @@ ThrowCompletionOr to_raw_precision(VM& vm, MathematicalValue co // 5. Else if e ≄ 0, then else if (exponent >= 0) { // a. Set m to the string-concatenation of the first e + 1 code units of m, the code unit 0x002E (FULL STOP), and the remaining p - (e + 1) code units of m. - result.formatted_string = TRY_OR_THROW_OOM(vm, - String::formatted( - "{}.{}", - result.formatted_string.bytes_as_string_view().substring_view(0, exponent + 1), - result.formatted_string.bytes_as_string_view().substring_view(exponent + 1))); + result.formatted_string = MUST(String::formatted( + "{}.{}", + result.formatted_string.bytes_as_string_view().substring_view(0, exponent + 1), + result.formatted_string.bytes_as_string_view().substring_view(exponent + 1))); // b. Let int be e + 1. result.digits = exponent + 1; @@ -1134,11 +1124,10 @@ ThrowCompletionOr to_raw_precision(VM& vm, MathematicalValue co else { // a. Assert: e < 0. // b. Set m to the string-concatenation of "0.", -(e + 1) occurrences of the code unit 0x0030 (DIGIT ZERO), and m. - result.formatted_string = TRY_OR_THROW_OOM(vm, - String::formatted( - "0.{}{}", - TRY_OR_THROW_OOM(vm, String::repeated('0', -1 * (exponent + 1))), - result.formatted_string)); + result.formatted_string = MUST(String::formatted( + "0.{}{}", + MUST(String::repeated('0', -1 * (exponent + 1))), + result.formatted_string)); // c. Let int be 1. result.digits = 1; @@ -1150,7 +1139,7 @@ ThrowCompletionOr to_raw_precision(VM& vm, MathematicalValue co int cut = max_precision - min_precision; // Steps 8b-8c are implemented by cut_trailing_zeroes. - result.formatted_string = TRY_OR_THROW_OOM(vm, cut_trailing_zeroes(result.formatted_string, cut)); + result.formatted_string = cut_trailing_zeroes(result.formatted_string, cut); } // 8. Return the Record { [[FormattedString]]: m, [[RoundedNumber]]: xFinal, [[IntegerDigitsCount]]: int, [[RoundingMagnitude]]: e–p+1 }. @@ -1210,7 +1199,7 @@ static RawFixedResult to_raw_fixed_function(MathematicalValue const& number, int } // 15.5.9 ToRawFixed ( x, minInteger, minFraction, maxFraction ), https://tc39.es/ecma402/#sec-torawfixed -ThrowCompletionOr to_raw_fixed(VM& vm, MathematicalValue const& number, int min_fraction, int max_fraction, int rounding_increment, NumberFormat::UnsignedRoundingMode unsigned_rounding_mode) +RawFormatResult to_raw_fixed(MathematicalValue const& number, int min_fraction, int max_fraction, int rounding_increment, NumberFormat::UnsignedRoundingMode unsigned_rounding_mode) { RawFormatResult result {}; @@ -1256,10 +1245,10 @@ ThrowCompletionOr to_raw_fixed(VM& vm, MathematicalValue const& // b. If k ≤ f, then if (decimals <= static_cast(fraction)) { // i. Let z be the String value consisting of f + 1 - k occurrences of the code unit 0x0030 (DIGIT ZERO). - auto zeroes = TRY_OR_THROW_OOM(vm, String::repeated('0', fraction + 1 - decimals)); + auto zeroes = MUST(String::repeated('0', fraction + 1 - decimals)); // ii. Let m be the string-concatenation of z and m. - result.formatted_string = TRY_OR_THROW_OOM(vm, String::formatted("{}{}", zeroes, result.formatted_string)); + result.formatted_string = MUST(String::formatted("{}{}", zeroes, result.formatted_string)); // iii. Let k be f + 1. decimals = fraction + 1; @@ -1270,7 +1259,7 @@ ThrowCompletionOr to_raw_fixed(VM& vm, MathematicalValue const& auto b = result.formatted_string.bytes_as_string_view().substring_view(decimals - fraction, fraction); // d. Let m be the string-concatenation of a, ".", and b. - result.formatted_string = TRY_OR_THROW_OOM(vm, String::formatted("{}.{}", a, b)); + result.formatted_string = MUST(String::formatted("{}.{}", a, b)); // e. Let int be the length of a. result.digits = a.length(); @@ -1284,7 +1273,7 @@ ThrowCompletionOr to_raw_fixed(VM& vm, MathematicalValue const& int cut = max_fraction - min_fraction; // Steps 11-12 are implemented by cut_trailing_zeroes. - result.formatted_string = TRY_OR_THROW_OOM(vm, cut_trailing_zeroes(result.formatted_string, cut)); + result.formatted_string = cut_trailing_zeroes(result.formatted_string, cut); // 13. Return the Record { [[FormattedString]]: m, [[RoundedNumber]]: xFinal, [[IntegerDigitsCount]]: int, [[RoundingMagnitude]]: –f }. result.rounding_magnitude = -fraction; @@ -1299,7 +1288,7 @@ enum class NumberCategory { }; // 15.5.11 GetNumberFormatPattern ( numberFormat, x ), https://tc39.es/ecma402/#sec-getnumberformatpattern -ThrowCompletionOr>> get_number_format_pattern(VM& vm, NumberFormat& number_format, MathematicalValue const& number, ::Locale::NumberFormat& found_pattern) +Optional> get_number_format_pattern(VM& vm, NumberFormat& number_format, MathematicalValue const& number, ::Locale::NumberFormat& found_pattern) { // 1. Let localeData be %NumberFormat%.[[LocaleData]]. // 2. Let dataLocale be numberFormat.[[DataLocale]]. @@ -1326,7 +1315,7 @@ ThrowCompletionOr>> get_number_format_patte // e. Let patterns be patterns.[[]]. // f. Let patterns be patterns.[[]]. auto formats = ::Locale::get_unit_formats(number_format.data_locale(), number_format.unit(), number_format.unit_display()); - auto plurality = MUST_OR_THROW_OOM(resolve_plural(vm, number_format, ::Locale::PluralForm::Cardinal, number.to_value(vm))); + auto plurality = resolve_plural(number_format, ::Locale::PluralForm::Cardinal, number.to_value(vm)); if (auto it = formats.find_if([&](auto& p) { return p.plurality == plurality.plural_category; }); it != formats.end()) patterns = move(*it); @@ -1349,7 +1338,7 @@ ThrowCompletionOr>> get_number_format_patte // Handling of other [[CurrencyDisplay]] options will occur after [[SignDisplay]]. if (number_format.currency_display() == NumberFormat::CurrencyDisplay::Name) { auto formats = ::Locale::get_compact_number_system_formats(number_format.data_locale(), number_format.numbering_system(), ::Locale::CompactNumberFormatType::CurrencyUnit); - auto plurality = MUST_OR_THROW_OOM(resolve_plural(vm, number_format, ::Locale::PluralForm::Cardinal, number.to_value(vm))); + auto plurality = resolve_plural(number_format, ::Locale::PluralForm::Cardinal, number.to_value(vm)); if (auto it = formats.find_if([&](auto& p) { return p.plurality == plurality.plural_category; }); it != formats.end()) { patterns = move(*it); @@ -1380,7 +1369,7 @@ ThrowCompletionOr>> get_number_format_patte } if (!patterns.has_value()) - return OptionalNone {}; + return {}; NumberCategory category; @@ -1556,7 +1545,7 @@ Optional get_notation_sub_pattern(NumberFormat& number_format, int e } // 15.5.13 ComputeExponent ( numberFormat, x ), https://tc39.es/ecma402/#sec-computeexponent -ThrowCompletionOr compute_exponent(VM& vm, NumberFormat& number_format, MathematicalValue number) +int compute_exponent(NumberFormat& number_format, MathematicalValue number) { // 1. If x = 0, then if (number.is_zero()) { @@ -1580,7 +1569,7 @@ ThrowCompletionOr compute_exponent(VM& vm, NumberFormat& number_format, Mat number = number.multiplied_by_power(-exponent); // 6. Let formatNumberResult be FormatNumericToString(numberFormat, x). - auto format_number_result = MUST_OR_THROW_OOM(format_numeric_to_string(vm, number_format, move(number))); + auto format_number_result = format_numeric_to_string(number_format, move(number)); // 7. If formatNumberResult.[[RoundedNumber]] = 0, then if (format_number_result.rounded_number.is_zero()) { @@ -1809,20 +1798,20 @@ ThrowCompletionOr> partition_number_range_pat Vector result; // 3. Let xResult be ? PartitionNumberPattern(numberFormat, x). - auto raw_start_result = TRY(partition_number_pattern(vm, number_format, move(start))); + auto raw_start_result = 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 = TRY(partition_number_pattern(vm, number_format, move(end))); + auto raw_end_result = partition_number_pattern(vm, number_format, move(end)); auto end_result = PatternPartitionWithSource::create_from_parent_list(move(raw_end_result)); // 5. If ! FormatNumeric(numberFormat, x) is equal to ! FormatNumeric(numberFormat, y), then - auto formatted_start = MUST_OR_THROW_OOM(format_numeric(vm, number_format, start)); - auto formatted_end = MUST_OR_THROW_OOM(format_numeric(vm, number_format, end)); + auto formatted_start = format_numeric(vm, number_format, start); + auto formatted_end = format_numeric(vm, number_format, end); if (formatted_start == formatted_end) { // a. Let appxResult be ? FormatApproximately(numberFormat, xResult). - auto approximate_result = TRY(format_approximately(vm, number_format, move(start_result))); + auto approximate_result = format_approximately(number_format, move(start_result)); // b. For each r in appxResult, do for (auto& result : approximate_result) { @@ -1835,7 +1824,7 @@ ThrowCompletionOr> partition_number_range_pat } // 6. For each element r in xResult, do - TRY_OR_THROW_OOM(vm, result.try_ensure_capacity(start_result.size())); + result.ensure_capacity(start_result.size()); for (auto& start_part : start_result) { // a. Append a new Record { [[Type]]: r.[[Type]], [[Value]]: r.[[Value]], [[Source]]: "startRange" } as the last element of result. @@ -1856,12 +1845,12 @@ ThrowCompletionOr> partition_number_range_pat part.type = "literal"sv; part.value = range_separator.has_value() ? range_separator.release_value() - : TRY_OR_THROW_OOM(vm, String::from_utf8(range_separator_symbol)); + : MUST(String::from_utf8(range_separator_symbol)); part.source = "shared"sv; - TRY_OR_THROW_OOM(vm, result.try_append(move(part))); + result.append(move(part)); // 9. For each element r in yResult, do - TRY_OR_THROW_OOM(vm, result.try_ensure_capacity(result.size() + end_result.size())); + result.ensure_capacity(result.size() + end_result.size()); for (auto& end_part : end_result) { // a. Append a new Record { [[Type]]: r.[[Type]], [[Value]]: r.[[Value]], [[Source]]: "endRange" } as the last element of result. @@ -1878,7 +1867,7 @@ ThrowCompletionOr> partition_number_range_pat } // 15.5.20 FormatApproximately ( numberFormat, result ), https://tc39.es/ecma402/#sec-formatapproximately -ThrowCompletionOr> format_approximately(VM& vm, NumberFormat& number_format, Vector result) +Vector format_approximately(NumberFormat& number_format, Vector result) { // 1. Let approximatelySign be an ILND String value used to signify that a number is approximate. auto approximately_sign = ::Locale::get_number_system_symbol(number_format.data_locale(), number_format.numbering_system(), ::Locale::NumericSymbol::ApproximatelySign); @@ -1887,11 +1876,11 @@ ThrowCompletionOr> format_approximately(VM& v if (approximately_sign.has_value() && !approximately_sign->is_empty()) { PatternPartitionWithSource partition; partition.type = "approximatelySign"sv; - partition.value = TRY_OR_THROW_OOM(vm, String::from_utf8(*approximately_sign)); + partition.value = MUST(String::from_utf8(*approximately_sign)); - TRY_OR_THROW_OOM(vm, result.try_insert_before_matching(move(partition), [](auto const& part) { + result.insert_before_matching(move(partition), [](auto const& part) { return part.type.is_one_of("integer"sv, "decimal"sv, "plusSign"sv, "minusSign"sv, "percentSign"sv, "currency"sv); - })); + }); } // 3. Return result. @@ -1912,20 +1901,20 @@ ThrowCompletionOr format_numeric_range(VM& vm, NumberFormat& number_form auto parts = TRY(partition_number_range_pattern(vm, number_format, move(start), move(end))); // 2. Let result be the empty String. - ThrowableStringBuilder result(vm); + StringBuilder result; // 3. For each part in parts, do for (auto& part : parts) { // a. Set result to the string-concatenation of result and part.[[Value]]. - TRY(result.append(part.value)); + result.append(part.value); } // 4. Return result. - return result.to_string(); + return MUST(result.to_string()); } // 15.5.23 FormatNumericRangeToParts ( numberFormat, x, y ), https://tc39.es/ecma402/#sec-formatnumericrangetoparts -ThrowCompletionOr format_numeric_range_to_parts(VM& vm, NumberFormat& number_format, MathematicalValue start, MathematicalValue end) +ThrowCompletionOr> format_numeric_range_to_parts(VM& vm, NumberFormat& number_format, MathematicalValue start, MathematicalValue end) { auto& realm = *vm.current_realm(); @@ -1960,7 +1949,7 @@ ThrowCompletionOr format_numeric_range_to_parts(VM& vm, NumberFormat& nu } // 5. Return result. - return result.ptr(); + return result; } } diff --git a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.h b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.h index fbf8fbf004f..b4ae5f93a7d 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.h +++ b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormat.h @@ -222,7 +222,7 @@ public: void set_unit_display(StringView unit_display) { m_unit_display = ::Locale::style_from_string(unit_display); } UseGrouping use_grouping() const { return m_use_grouping; } - ThrowCompletionOr use_grouping_to_value(VM&) const; + Value use_grouping_to_value(VM&) const; void set_use_grouping(StringOrBoolean const& use_grouping); Notation notation() const { return m_notation; } @@ -288,24 +288,24 @@ enum class RoundingDecision { }; int currency_digits(StringView currency); -ThrowCompletionOr format_numeric_to_string(VM&, NumberFormatBase const& intl_object, MathematicalValue number); -ThrowCompletionOr> partition_number_pattern(VM&, NumberFormat&, MathematicalValue number); -ThrowCompletionOr> partition_notation_sub_pattern(VM&, NumberFormat&, MathematicalValue const& number, String formatted_string, int exponent); -ThrowCompletionOr format_numeric(VM&, NumberFormat&, MathematicalValue number); -ThrowCompletionOr format_numeric_to_parts(VM&, NumberFormat&, MathematicalValue number); -ThrowCompletionOr to_raw_precision(VM&, MathematicalValue const& number, int min_precision, int max_precision, NumberFormat::UnsignedRoundingMode unsigned_rounding_mode); -ThrowCompletionOr to_raw_fixed(VM&, MathematicalValue const& number, int min_fraction, int max_fraction, int rounding_increment, NumberFormat::UnsignedRoundingMode unsigned_rounding_mode); -ThrowCompletionOr>> get_number_format_pattern(VM&, NumberFormat&, MathematicalValue const& number, ::Locale::NumberFormat& found_pattern); +FormatResult format_numeric_to_string(NumberFormatBase const& intl_object, MathematicalValue number); +Vector partition_number_pattern(VM&, NumberFormat&, MathematicalValue number); +Vector partition_notation_sub_pattern(NumberFormat&, MathematicalValue const& number, String formatted_string, int exponent); +String format_numeric(VM&, NumberFormat&, MathematicalValue number); +NonnullGCPtr format_numeric_to_parts(VM&, NumberFormat&, MathematicalValue number); +RawFormatResult to_raw_precision(MathematicalValue const& number, int min_precision, int max_precision, NumberFormat::UnsignedRoundingMode unsigned_rounding_mode); +RawFormatResult to_raw_fixed(MathematicalValue const& number, int min_fraction, int max_fraction, int rounding_increment, NumberFormat::UnsignedRoundingMode unsigned_rounding_mode); +Optional> get_number_format_pattern(VM&, NumberFormat&, MathematicalValue const& number, ::Locale::NumberFormat& found_pattern); Optional get_notation_sub_pattern(NumberFormat&, int exponent); -ThrowCompletionOr compute_exponent(VM&, NumberFormat&, MathematicalValue number); +int compute_exponent(NumberFormat&, MathematicalValue number); int compute_exponent_for_magnitude(NumberFormat&, int magnitude); ThrowCompletionOr to_intl_mathematical_value(VM&, Value value); NumberFormat::UnsignedRoundingMode get_unsigned_rounding_mode(NumberFormat::RoundingMode, bool is_negative); RoundingDecision apply_unsigned_rounding_mode(MathematicalValue const& x, MathematicalValue const& r1, MathematicalValue const& r2, NumberFormat::UnsignedRoundingMode unsigned_rounding_mode); ThrowCompletionOr> partition_number_range_pattern(VM&, NumberFormat&, MathematicalValue start, MathematicalValue end); -ThrowCompletionOr> format_approximately(VM&, NumberFormat&, Vector result); +Vector format_approximately(NumberFormat&, Vector result); Vector collapse_number_range(Vector result); ThrowCompletionOr format_numeric_range(VM&, NumberFormat&, MathematicalValue start, MathematicalValue end); -ThrowCompletionOr format_numeric_range_to_parts(VM&, NumberFormat&, MathematicalValue start, MathematicalValue end); +ThrowCompletionOr> format_numeric_range_to_parts(VM&, NumberFormat&, MathematicalValue start, MathematicalValue end); } diff --git a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatConstructor.cpp b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatConstructor.cpp index a150a6871cc..80238a722c3 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatConstructor.cpp @@ -79,7 +79,7 @@ JS_DEFINE_NATIVE_FUNCTION(NumberFormatConstructor::supported_locales_of) } // 15.1.2 InitializeNumberFormat ( numberFormat, locales, options ), https://tc39.es/ecma402/#sec-initializenumberformat -ThrowCompletionOr initialize_number_format(VM& vm, NumberFormat& number_format, Value locales_value, Value options_value) +ThrowCompletionOr> initialize_number_format(VM& vm, NumberFormat& number_format, Value locales_value, Value options_value) { // 1. Let requestedLocales be ? CanonicalizeLocaleList(locales). auto requested_locales = TRY(canonicalize_locale_list(vm, locales_value)); @@ -208,7 +208,7 @@ ThrowCompletionOr initialize_number_format(VM& vm, NumberFormat& number_format.set_sign_display(sign_display.as_string().utf8_string_view()); // 31. Return numberFormat. - return &number_format; + return number_format; } // 15.1.3 SetNumberFormatDigitOptions ( intlObj, options, mnfdDefault, mxfdDefault, notation ), https://tc39.es/ecma402/#sec-setnfdigitoptions @@ -473,7 +473,7 @@ ThrowCompletionOr set_number_format_unit_options(VM& vm, NumberFormat& int // 14. If style is "currency", then if (intl_object.style() == NumberFormat::Style::Currency) { // a. Set intlObj.[[Currency]] to the ASCII-uppercase of currency. - intl_object.set_currency(TRY_OR_THROW_OOM(vm, currency.as_string().utf8_string().to_uppercase())); + intl_object.set_currency(MUST(currency.as_string().utf8_string().to_uppercase())); // c. Set intlObj.[[CurrencyDisplay]] to currencyDisplay. intl_object.set_currency_display(currency_display.as_string().utf8_string_view()); diff --git a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatConstructor.h b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatConstructor.h index 92014e80cfc..0bb929b2110 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatConstructor.h +++ b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatConstructor.h @@ -29,7 +29,7 @@ private: JS_DECLARE_NATIVE_FUNCTION(supported_locales_of); }; -ThrowCompletionOr initialize_number_format(VM&, NumberFormat&, Value locales_value, Value options_value); +ThrowCompletionOr> initialize_number_format(VM&, NumberFormat&, Value locales_value, Value options_value); ThrowCompletionOr set_number_format_digit_options(VM&, NumberFormatBase& intl_object, Object const& options, int default_min_fraction_digits, int default_max_fraction_digits, NumberFormat::Notation notation); ThrowCompletionOr set_number_format_unit_options(VM&, NumberFormat& intl_object, Object const& options); diff --git a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatFunction.cpp b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatFunction.cpp index 8e8e6433a30..ecea9480ee9 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatFunction.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatFunction.cpp @@ -44,7 +44,7 @@ ThrowCompletionOr NumberFormatFunction::call() auto mathematical_value = TRY(to_intl_mathematical_value(vm, value)); // 5. Return ? FormatNumeric(nf, x). - auto formatted = TRY(format_numeric(vm, m_number_format, move(mathematical_value))); + auto formatted = 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 4b4f501ae2e..15babf814f7 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/NumberFormatPrototype.cpp @@ -75,7 +75,7 @@ JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::format_to_parts) auto mathematical_value = TRY(to_intl_mathematical_value(vm, value)); // 4. Return ? FormatNumericToParts(nf, x). - return TRY(format_numeric_to_parts(vm, number_format, move(mathematical_value))); + return format_numeric_to_parts(vm, number_format, move(mathematical_value)); } // 15.3.5 Intl.NumberFormat.prototype.formatRange ( start, end ), https://tc39.es/ecma402/#sec-intl.numberformat.prototype.formatrange @@ -172,7 +172,7 @@ JS_DEFINE_NATIVE_FUNCTION(NumberFormatPrototype::resolved_options) MUST(options->create_data_property_or_throw(vm.names.minimumSignificantDigits, Value(number_format->min_significant_digits()))); if (number_format->has_max_significant_digits()) MUST(options->create_data_property_or_throw(vm.names.maximumSignificantDigits, Value(number_format->max_significant_digits()))); - MUST(options->create_data_property_or_throw(vm.names.useGrouping, MUST_OR_THROW_OOM(number_format->use_grouping_to_value(vm)))); + MUST(options->create_data_property_or_throw(vm.names.useGrouping, number_format->use_grouping_to_value(vm))); MUST(options->create_data_property_or_throw(vm.names.notation, PrimitiveString::create(vm, number_format->notation_string()))); if (number_format->has_compact_display()) MUST(options->create_data_property_or_throw(vm.names.compactDisplay, PrimitiveString::create(vm, number_format->compact_display_string()))); diff --git a/Userland/Libraries/LibJS/Runtime/Intl/PluralRules.cpp b/Userland/Libraries/LibJS/Runtime/Intl/PluralRules.cpp index 88e5d7a1587..06311ab6a1a 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/PluralRules.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/PluralRules.cpp @@ -92,13 +92,13 @@ PluralRules::PluralRules(Object& prototype) } // 16.5.3 ResolvePlural ( pluralRules, n ), https://tc39.es/ecma402/#sec-resolveplural -ThrowCompletionOr resolve_plural(VM& vm, PluralRules const& plural_rules, Value number) +ResolvedPlurality resolve_plural(PluralRules const& plural_rules, Value number) { - return resolve_plural(vm, plural_rules, plural_rules.type(), number); + return resolve_plural(plural_rules, plural_rules.type(), number); } // Non-standard overload of ResolvePlural to allow using the AO without an Intl.PluralRules object. -ThrowCompletionOr resolve_plural(VM& vm, NumberFormatBase const& number_format, ::Locale::PluralForm type, Value number) +ResolvedPlurality resolve_plural(NumberFormatBase const& number_format, ::Locale::PluralForm type, Value number) { // 1. Assert: Type(pluralRules) is Object. // 2. Assert: pluralRules has an [[InitializedPluralRules]] internal slot. @@ -107,7 +107,7 @@ ThrowCompletionOr resolve_plural(VM& vm, NumberFormatBase con // 4. If n is not a finite Number, then if (!number.is_finite_number()) { // a. Return "other". - return ResolvedPlurality { ::Locale::PluralCategory::Other, String {} }; + return { ::Locale::PluralCategory::Other, String {} }; } // 5. Let locale be pluralRules.[[Locale]]. @@ -116,7 +116,7 @@ ThrowCompletionOr resolve_plural(VM& vm, NumberFormatBase con // 6. Let type be pluralRules.[[Type]]. // 7. Let res be ! FormatNumericToString(pluralRules, n). - auto result = MUST_OR_THROW_OOM(format_numeric_to_string(vm, number_format, number)); + auto result = format_numeric_to_string(number_format, number); // 8. Let s be res.[[FormattedString]]. auto string = move(result.formatted_string); @@ -128,7 +128,7 @@ ThrowCompletionOr resolve_plural(VM& vm, NumberFormatBase con auto plural_category = plural_rule_select(locale, type, number, move(operands)); // 11. Return the Record { [[PluralCategory]]: p, [[FormattedString]]: s }. - return ResolvedPlurality { plural_category, move(string) }; + return { plural_category, move(string) }; } // 16.5.4 PluralRuleSelectRange ( locale, type, xp, yp ), https://tc39.es/ecma402/#sec-resolveplural @@ -152,10 +152,10 @@ ThrowCompletionOr<::Locale::PluralCategory> resolve_plural_range(VM& vm, PluralR return vm.throw_completion(ErrorType::NumberIsNaN, "end"sv); // 6. Let xp be ! ResolvePlural(pluralRules, x). - auto start_plurality = MUST_OR_THROW_OOM(resolve_plural(vm, plural_rules, start)); + auto start_plurality = resolve_plural(plural_rules, start); // 7. Let yp be ! ResolvePlural(pluralRules, y). - auto end_plurality = MUST_OR_THROW_OOM(resolve_plural(vm, plural_rules, end)); + auto end_plurality = resolve_plural(plural_rules, end); // 8. If xp.[[FormattedString]] is yp.[[FormattedString]], then if (start_plurality.formatted_string == end_plurality.formatted_string) { diff --git a/Userland/Libraries/LibJS/Runtime/Intl/PluralRules.h b/Userland/Libraries/LibJS/Runtime/Intl/PluralRules.h index 102ce2da364..5e376285c89 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/PluralRules.h +++ b/Userland/Libraries/LibJS/Runtime/Intl/PluralRules.h @@ -38,8 +38,8 @@ struct ResolvedPlurality { ::Locale::PluralOperands get_operands(StringView string); ::Locale::PluralCategory plural_rule_select(StringView locale, ::Locale::PluralForm type, Value number, ::Locale::PluralOperands operands); -ThrowCompletionOr resolve_plural(VM&, PluralRules const&, Value number); -ThrowCompletionOr resolve_plural(VM&, NumberFormatBase const& number_format, ::Locale::PluralForm type, Value number); +ResolvedPlurality resolve_plural(PluralRules const&, Value number); +ResolvedPlurality resolve_plural(NumberFormatBase const& number_format, ::Locale::PluralForm type, Value number); ::Locale::PluralCategory plural_rule_select_range(StringView locale, ::Locale::PluralForm, ::Locale::PluralCategory start, ::Locale::PluralCategory end); ThrowCompletionOr<::Locale::PluralCategory> resolve_plural_range(VM&, PluralRules const&, Value start, Value end); diff --git a/Userland/Libraries/LibJS/Runtime/Intl/PluralRulesConstructor.cpp b/Userland/Libraries/LibJS/Runtime/Intl/PluralRulesConstructor.cpp index 5f971dd1ee5..3fd2d0dc453 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/PluralRulesConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/PluralRulesConstructor.cpp @@ -54,7 +54,7 @@ ThrowCompletionOr> PluralRulesConstructor::construct(Functi auto plural_rules = TRY(ordinary_create_from_constructor(vm, new_target, &Intrinsics::intl_plural_rules_prototype)); // 3. Return ? InitializePluralRules(pluralRules, locales, options). - return *TRY(initialize_plural_rules(vm, plural_rules, locales, options)); + return TRY(initialize_plural_rules(vm, plural_rules, locales, options)); } // 16.2.2 Intl.PluralRules.supportedLocalesOf ( locales [ , options ] ), https://tc39.es/ecma402/#sec-intl.pluralrules.supportedlocalesof @@ -73,7 +73,7 @@ JS_DEFINE_NATIVE_FUNCTION(PluralRulesConstructor::supported_locales_of) } // 16.1.2 InitializePluralRules ( pluralRules, locales, options ), https://tc39.es/ecma402/#sec-initializepluralrules -ThrowCompletionOr initialize_plural_rules(VM& vm, PluralRules& plural_rules, Value locales_value, Value options_value) +ThrowCompletionOr> initialize_plural_rules(VM& vm, PluralRules& plural_rules, Value locales_value, Value options_value) { // 1. Let requestedLocales be ? CanonicalizeLocaleList(locales). auto requested_locales = TRY(canonicalize_locale_list(vm, locales_value)); @@ -110,7 +110,7 @@ ThrowCompletionOr initialize_plural_rules(VM& vm, PluralRules& plu plural_rules.set_data_locale(move(result.data_locale)); // 12. Return pluralRules. - return &plural_rules; + return plural_rules; } } diff --git a/Userland/Libraries/LibJS/Runtime/Intl/PluralRulesConstructor.h b/Userland/Libraries/LibJS/Runtime/Intl/PluralRulesConstructor.h index 256f38d73d7..c2ae486b64e 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/PluralRulesConstructor.h +++ b/Userland/Libraries/LibJS/Runtime/Intl/PluralRulesConstructor.h @@ -28,6 +28,6 @@ private: JS_DECLARE_NATIVE_FUNCTION(supported_locales_of); }; -ThrowCompletionOr initialize_plural_rules(VM&, PluralRules&, Value locales_value, Value options_value); +ThrowCompletionOr> initialize_plural_rules(VM&, PluralRules&, Value locales_value, Value options_value); } diff --git a/Userland/Libraries/LibJS/Runtime/Intl/PluralRulesPrototype.cpp b/Userland/Libraries/LibJS/Runtime/Intl/PluralRulesPrototype.cpp index c4c30157fb8..d2765549a80 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/PluralRulesPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/PluralRulesPrototype.cpp @@ -44,7 +44,7 @@ JS_DEFINE_NATIVE_FUNCTION(PluralRulesPrototype::select) auto number = TRY(vm.argument(0).to_number(vm)); // 4. Return ! ResolvePlural(pr, n).[[PluralCategory]]. - auto plurality = MUST_OR_THROW_OOM(resolve_plural(vm, plural_rules, number)); + auto plurality = resolve_plural(plural_rules, number); return PrimitiveString::create(vm, ::Locale::plural_category_to_string(plurality.plural_category)); } diff --git a/Userland/Libraries/LibJS/Runtime/Intl/RelativeTimeFormat.cpp b/Userland/Libraries/LibJS/Runtime/Intl/RelativeTimeFormat.cpp index be5e136261b..ff7fd64a641 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/RelativeTimeFormat.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/RelativeTimeFormat.cpp @@ -176,10 +176,10 @@ ThrowCompletionOr> partition_relative_time_patt auto patterns = find_patterns_for_tense_or_number(tense); // 20. Let fv be ! PartitionNumberPattern(relativeTimeFormat.[[NumberFormat]], value). - auto value_partitions = MUST_OR_THROW_OOM(partition_number_pattern(vm, relative_time_format.number_format(), Value(value))); + auto value_partitions = partition_number_pattern(vm, relative_time_format.number_format(), Value(value)); // 21. Let pr be ! ResolvePlural(relativeTimeFormat.[[PluralRules]], value).[[PluralCategory]]. - auto plurality = MUST_OR_THROW_OOM(resolve_plural(vm, relative_time_format.plural_rules(), Value(value))); + auto plurality = resolve_plural(relative_time_format.plural_rules(), Value(value)); // 22. Let pattern be po.[[]]. auto pattern = patterns.find_if([&](auto& p) { return p.plurality == plurality.plural_category; }); diff --git a/Userland/Libraries/LibJS/Runtime/NumberPrototype.cpp b/Userland/Libraries/LibJS/Runtime/NumberPrototype.cpp index 5a9f62ca1d1..0fae98878d8 100644 --- a/Userland/Libraries/LibJS/Runtime/NumberPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/NumberPrototype.cpp @@ -287,7 +287,7 @@ JS_DEFINE_NATIVE_FUNCTION(NumberPrototype::to_locale_string) auto* number_format = static_cast(TRY(construct(vm, realm.intrinsics().intl_number_format_constructor(), locales, options)).ptr()); // 3. Return ? FormatNumeric(numberFormat, x). - auto formatted = TRY(Intl::format_numeric(vm, *number_format, number_value)); + auto formatted = Intl::format_numeric(vm, *number_format, number_value); return PrimitiveString::create(vm, move(formatted)); }