Selaa lähdekoodia

LibJS: Make JS::number_to_string() infallible

Work towards #20449.
Andreas Kling 1 vuosi sitten
vanhempi
commit
b8f78c0adc

+ 2 - 2
Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp

@@ -1168,7 +1168,7 @@ Object* create_mapped_arguments_object(VM& vm, FunctionObject& function, Vector<
 }
 
 // 7.1.21 CanonicalNumericIndexString ( argument ), https://tc39.es/ecma262/#sec-canonicalnumericindexstring
-ThrowCompletionOr<CanonicalIndex> canonical_numeric_index_string(VM& vm, PropertyKey const& property_key, CanonicalIndexMode mode)
+CanonicalIndex canonical_numeric_index_string(PropertyKey const& property_key, CanonicalIndexMode mode)
 {
     // NOTE: If the property name is a number type (An implementation-defined optimized
     // property key type), it can be treated as a string property that has already been
@@ -1221,7 +1221,7 @@ ThrowCompletionOr<CanonicalIndex> canonical_numeric_index_string(VM& vm, Propert
 
     // FIXME: We return 0 instead of n but it might not observable?
     // 3. If SameValue(! ToString(n), argument) is true, return n.
-    if (TRY_OR_THROW_OOM(vm, number_to_string(*maybe_double)) == argument.view())
+    if (number_to_string(*maybe_double) == argument.view())
         return CanonicalIndex(CanonicalIndex::Type::Numeric, 0);
 
     // 4. Return undefined.

+ 1 - 1
Userland/Libraries/LibJS/Runtime/AbstractOperations.h

@@ -60,7 +60,7 @@ enum class CanonicalIndexMode {
     DetectNumericRoundtrip,
     IgnoreNumericRoundtrip,
 };
-ThrowCompletionOr<CanonicalIndex> canonical_numeric_index_string(VM&, PropertyKey const&, CanonicalIndexMode needs_numeric);
+[[nodiscard]] CanonicalIndex canonical_numeric_index_string(PropertyKey const&, CanonicalIndexMode needs_numeric);
 ThrowCompletionOr<String> get_substitution(VM&, Utf16View const& matched, Utf16View const& str, size_t position, Span<Value> captures, Value named_captures, Value replacement);
 
 enum class CallerMode {

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Intl/MathematicalValue.cpp

@@ -298,7 +298,7 @@ ThrowCompletionOr<String> MathematicalValue::to_string(VM& vm) const
 {
     return m_value.visit(
         [&](double value) -> ThrowCompletionOr<String> {
-            return TRY_OR_THROW_OOM(vm, number_to_string(value, NumberToStringMode::WithoutExponent));
+            return number_to_string(value, NumberToStringMode::WithoutExponent);
         },
         [&](Crypto::SignedBigInteger const& value) -> ThrowCompletionOr<String> {
             return TRY_OR_THROW_OOM(vm, value.to_base(10));

+ 1 - 1
Userland/Libraries/LibJS/Runtime/PrimitiveString.cpp

@@ -144,7 +144,7 @@ ThrowCompletionOr<Optional<Value>> PrimitiveString::get(VM& vm, PropertyKey cons
             return Value(static_cast<double>(length));
         }
     }
-    auto index = MUST_OR_THROW_OOM(canonical_numeric_index_string(vm, property_key, CanonicalIndexMode::IgnoreNumericRoundtrip));
+    auto index = canonical_numeric_index_string(property_key, CanonicalIndexMode::IgnoreNumericRoundtrip);
     if (!index.is_index())
         return Optional<Value> {};
     auto str = utf16_string_view();

+ 1 - 1
Userland/Libraries/LibJS/Runtime/StringObject.cpp

@@ -63,7 +63,7 @@ static ThrowCompletionOr<Optional<PropertyDescriptor>> string_get_own_property(S
         return Optional<PropertyDescriptor> {};
 
     // 2. Let index be CanonicalNumericIndexString(P).
-    auto index = MUST_OR_THROW_OOM(canonical_numeric_index_string(vm, property_key, CanonicalIndexMode::IgnoreNumericRoundtrip));
+    auto index = canonical_numeric_index_string(property_key, CanonicalIndexMode::IgnoreNumericRoundtrip);
 
     // 3. If index is undefined, return undefined.
     // 4. If IsIntegralNumber(index) is false, return undefined.

+ 6 - 6
Userland/Libraries/LibJS/Runtime/TypedArray.h

@@ -191,7 +191,7 @@ public:
         // NOTE: This includes an implementation-defined optimization, see note above!
         if (property_key.is_string() || property_key.is_number()) {
             // a. Let numericIndex be CanonicalNumericIndexString(P).
-            auto numeric_index = MUST_OR_THROW_OOM(canonical_numeric_index_string(vm(), property_key, CanonicalIndexMode::DetectNumericRoundtrip));
+            auto numeric_index = canonical_numeric_index_string(property_key, CanonicalIndexMode::DetectNumericRoundtrip);
             // b. If numericIndex is not undefined, then
             if (!numeric_index.is_undefined()) {
                 // i. Let value be IntegerIndexedElementGet(O, numericIndex).
@@ -228,7 +228,7 @@ public:
         // NOTE: This includes an implementation-defined optimization, see note above!
         if (property_key.is_string() || property_key.is_number()) {
             // a. Let numericIndex be CanonicalNumericIndexString(P).
-            auto numeric_index = MUST_OR_THROW_OOM(canonical_numeric_index_string(vm(), property_key, CanonicalIndexMode::DetectNumericRoundtrip));
+            auto numeric_index = canonical_numeric_index_string(property_key, CanonicalIndexMode::DetectNumericRoundtrip);
             // b. If numericIndex is not undefined, return IsValidIntegerIndex(O, numericIndex).
             if (!numeric_index.is_undefined())
                 return is_valid_integer_index(*this, numeric_index);
@@ -251,7 +251,7 @@ public:
         // NOTE: This includes an implementation-defined optimization, see note above!
         if (property_key.is_string() || property_key.is_number()) {
             // a. Let numericIndex be CanonicalNumericIndexString(P).
-            auto numeric_index = MUST_OR_THROW_OOM(canonical_numeric_index_string(vm(), property_key, CanonicalIndexMode::DetectNumericRoundtrip));
+            auto numeric_index = canonical_numeric_index_string(property_key, CanonicalIndexMode::DetectNumericRoundtrip);
             // b. If numericIndex is not undefined, then
             if (!numeric_index.is_undefined()) {
                 // i. If IsValidIntegerIndex(O, numericIndex) is false, return false.
@@ -301,7 +301,7 @@ public:
         // NOTE: This includes an implementation-defined optimization, see note above!
         if (property_key.is_string() || property_key.is_number()) {
             // a. Let numericIndex be CanonicalNumericIndexString(P).
-            auto numeric_index = MUST_OR_THROW_OOM(canonical_numeric_index_string(vm(), property_key, CanonicalIndexMode::DetectNumericRoundtrip));
+            auto numeric_index = canonical_numeric_index_string(property_key, CanonicalIndexMode::DetectNumericRoundtrip);
             // b. If numericIndex is not undefined, then
             if (!numeric_index.is_undefined()) {
                 // i. Return IntegerIndexedElementGet(O, numericIndex).
@@ -328,7 +328,7 @@ public:
         // NOTE: This includes an implementation-defined optimization, see note above!
         if (property_key.is_string() || property_key.is_number()) {
             // a. Let numericIndex be CanonicalNumericIndexString(P).
-            auto numeric_index = MUST_OR_THROW_OOM(canonical_numeric_index_string(vm(), property_key, CanonicalIndexMode::DetectNumericRoundtrip));
+            auto numeric_index = canonical_numeric_index_string(property_key, CanonicalIndexMode::DetectNumericRoundtrip);
             // b. If numericIndex is not undefined, then
             if (!numeric_index.is_undefined()) {
                 // i. If SameValue(O, Receiver) is true, then
@@ -363,7 +363,7 @@ public:
         // NOTE: This includes an implementation-defined optimization, see note above!
         if (property_key.is_string() || property_key.is_number()) {
             // a. Let numericIndex be CanonicalNumericIndexString(P).
-            auto numeric_index = MUST_OR_THROW_OOM(canonical_numeric_index_string(vm(), property_key, CanonicalIndexMode::DetectNumericRoundtrip));
+            auto numeric_index = canonical_numeric_index_string(property_key, CanonicalIndexMode::DetectNumericRoundtrip);
             // b. If numericIndex is not undefined, then
             if (!numeric_index.is_undefined()) {
                 // i. If IsValidIntegerIndex(O, numericIndex) is false, return true; else return false.

+ 36 - 38
Userland/Libraries/LibJS/Runtime/Value.cpp

@@ -72,7 +72,7 @@ ALWAYS_INLINE bool both_bigint(Value const& lhs, Value const& rhs)
 
 // 6.1.6.1.20 Number::toString ( x ), https://tc39.es/ecma262/#sec-numeric-types-number-tostring
 // Implementation for radix = 10
-static ErrorOr<void> number_to_string_impl(StringBuilder& builder, double d, NumberToStringMode mode)
+static void number_to_string_impl(StringBuilder& builder, double d, NumberToStringMode mode)
 {
     auto convert_to_decimal_digits_array = [](auto x, auto& digits, auto& length) {
         for (; x; x /= 10)
@@ -83,25 +83,25 @@ static ErrorOr<void> number_to_string_impl(StringBuilder& builder, double d, Num
 
     // 1. If x is NaN, return "NaN".
     if (isnan(d)) {
-        TRY(builder.try_append("NaN"sv));
-        return {};
+        builder.append("NaN"sv);
+        return;
     }
 
     // 2. If x is +0𝔽 or -0𝔽, return "0".
     if (d == +0.0 || d == -0.0) {
-        TRY(builder.try_append("0"sv));
-        return {};
+        builder.append("0"sv);
+        return;
     }
 
     // 4. If x is +∞𝔽, return "Infinity".
     if (isinf(d)) {
         if (d > 0) {
-            TRY(builder.try_append("Infinity"sv));
-            return {};
+            builder.append("Infinity"sv);
+            return;
         }
 
-        TRY(builder.try_append("-Infinity"sv));
-        return {};
+        builder.append("-Infinity"sv);
+        return;
     }
 
     // 5. Let n, k, and s be integers such that k ≥ 1, radix ^ (k - 1) ≤ s < radix ^ k,
@@ -120,7 +120,7 @@ static ErrorOr<void> number_to_string_impl(StringBuilder& builder, double d, Num
 
     // 3. If x < -0𝔽, return the string-concatenation of "-" and Number::toString(-x, radix).
     if (sign)
-        TRY(builder.try_append('-'));
+        builder.append('-');
 
     // Non-standard: Intl needs number-to-string conversions for extremely large numbers without any
     // exponential formatting, as it will handle such formatting itself in a locale-aware way.
@@ -132,34 +132,34 @@ static ErrorOr<void> number_to_string_impl(StringBuilder& builder, double d, Num
         if (n >= k) {
             // i. Return the string-concatenation of:
             // the code units of the k digits of the representation of s using radix radix
-            TRY(builder.try_append(mantissa_digits.data(), k));
+            builder.append(mantissa_digits.data(), k);
             // n - k occurrences of the code unit 0x0030 (DIGIT ZERO)
-            TRY(builder.try_append_repeated('0', n - k));
+            builder.append_repeated('0', n - k);
             // b. Else if n > 0, then
         } else if (n > 0) {
             // i. Return the string-concatenation of:
             // the code units of the most significant n digits of the representation of s using radix radix
-            TRY(builder.try_append(mantissa_digits.data(), n));
+            builder.append(mantissa_digits.data(), n);
             // the code unit 0x002E (FULL STOP)
-            TRY(builder.try_append('.'));
+            builder.append('.');
             // the code units of the remaining k - n digits of the representation of s using radix radix
-            TRY(builder.try_append(mantissa_digits.data() + n, k - n));
+            builder.append(mantissa_digits.data() + n, k - n);
             // c. Else,
         } else {
             // i. Assert: n ≤ 0.
             VERIFY(n <= 0);
             // ii. Return the string-concatenation of:
             // the code unit 0x0030 (DIGIT ZERO)
-            TRY(builder.try_append('0'));
+            builder.append('0');
             // the code unit 0x002E (FULL STOP)
-            TRY(builder.try_append('.'));
+            builder.append('.');
             // -n occurrences of the code unit 0x0030 (DIGIT ZERO)
-            TRY(builder.try_append_repeated('0', -n));
+            builder.append_repeated('0', -n);
             // the code units of the k digits of the representation of s using radix radix
-            TRY(builder.try_append(mantissa_digits.data(), k));
+            builder.append(mantissa_digits.data(), k);
         }
 
-        return {};
+        return;
     }
 
     // 7. NOTE: In this case, the input will be represented using scientific E notation, such as 1.2e+3.
@@ -178,45 +178,43 @@ static ErrorOr<void> number_to_string_impl(StringBuilder& builder, double d, Num
     if (k == 1) {
         // a. Return the string-concatenation of:
         // the code unit of the single digit of s
-        TRY(builder.try_append(mantissa_digits[0]));
+        builder.append(mantissa_digits[0]);
         // the code unit 0x0065 (LATIN SMALL LETTER E)
-        TRY(builder.try_append('e'));
+        builder.append('e');
         // exponentSign
-        TRY(builder.try_append(exponent_sign));
+        builder.append(exponent_sign);
         // the code units of the decimal representation of abs(n - 1)
-        TRY(builder.try_append(exponent_digits.data(), exponent_length));
+        builder.append(exponent_digits.data(), exponent_length);
 
-        return {};
+        return;
     }
 
     // 12. Return the string-concatenation of:
     // the code unit of the most significant digit of the decimal representation of s
-    TRY(builder.try_append(mantissa_digits[0]));
+    builder.append(mantissa_digits[0]);
     // the code unit 0x002E (FULL STOP)
-    TRY(builder.try_append('.'));
+    builder.append('.');
     // the code units of the remaining k - 1 digits of the decimal representation of s
-    TRY(builder.try_append(mantissa_digits.data() + 1, k - 1));
+    builder.append(mantissa_digits.data() + 1, k - 1);
     // the code unit 0x0065 (LATIN SMALL LETTER E)
-    TRY(builder.try_append('e'));
+    builder.append('e');
     // exponentSign
-    TRY(builder.try_append(exponent_sign));
+    builder.append(exponent_sign);
     // the code units of the decimal representation of abs(n - 1)
-    TRY(builder.try_append(exponent_digits.data(), exponent_length));
-
-    return {};
+    builder.append(exponent_digits.data(), exponent_length);
 }
 
-ErrorOr<String> number_to_string(double d, NumberToStringMode mode)
+String number_to_string(double d, NumberToStringMode mode)
 {
     StringBuilder builder;
-    TRY(number_to_string_impl(builder, d, mode));
-    return builder.to_string();
+    number_to_string_impl(builder, d, mode);
+    return builder.to_string().release_value();
 }
 
 DeprecatedString number_to_deprecated_string(double d, NumberToStringMode mode)
 {
     StringBuilder builder;
-    MUST(number_to_string_impl(builder, d, mode));
+    number_to_string_impl(builder, d, mode);
     return builder.to_deprecated_string();
 }
 
@@ -398,7 +396,7 @@ ThrowCompletionOr<NonnullGCPtr<PrimitiveString>> Value::to_primitive_string(VM&
 ThrowCompletionOr<String> Value::to_string(VM& vm) const
 {
     if (is_double())
-        return TRY_OR_THROW_OOM(vm, number_to_string(m_value.as_double));
+        return number_to_string(m_value.as_double);
 
     switch (m_value.tag) {
     // 1. If argument is a String, return argument.

+ 2 - 2
Userland/Libraries/LibJS/Runtime/Value.h

@@ -561,8 +561,8 @@ enum class NumberToStringMode {
     WithExponent,
     WithoutExponent,
 };
-ErrorOr<String> number_to_string(double, NumberToStringMode = NumberToStringMode::WithExponent);
-DeprecatedString number_to_deprecated_string(double, NumberToStringMode = NumberToStringMode::WithExponent);
+[[nodiscard]] String number_to_string(double, NumberToStringMode = NumberToStringMode::WithExponent);
+[[nodiscard]] DeprecatedString number_to_deprecated_string(double, NumberToStringMode = NumberToStringMode::WithExponent);
 double string_to_number(StringView);
 
 inline bool Value::operator==(Value const& value) const { return same_value(*this, value); }

+ 16 - 16
Userland/Libraries/LibWeb/Geometry/DOMMatrixReadOnly.cpp

@@ -302,83 +302,83 @@ WebIDL::ExceptionOr<String> DOMMatrixReadOnly::to_string() const
         TRY_OR_THROW_OOM(vm, builder.try_append("matrix3d("sv));
 
         // 2. Append ! ToString(m11 element) to string.
-        TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::number_to_string(m11()))));
+        TRY_OR_THROW_OOM(vm, builder.try_append(JS::number_to_string(m11())));
 
         // 3. Append ", " to string.
         TRY_OR_THROW_OOM(vm, builder.try_append(", "sv));
 
         // 4. Append ! ToString(m12 element) to string.
-        TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::number_to_string(m12()))));
+        TRY_OR_THROW_OOM(vm, builder.try_append(JS::number_to_string(m12())));
 
         // 5. Append ", " to string.
         TRY_OR_THROW_OOM(vm, builder.try_append(", "sv));
 
         // 6. Append ! ToString(m13 element) to string.
-        TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::number_to_string(m13()))));
+        TRY_OR_THROW_OOM(vm, builder.try_append(JS::number_to_string(m13())));
 
         // 7. Append ", " to string.
         TRY_OR_THROW_OOM(vm, builder.try_append(", "sv));
 
         // 8. Append ! ToString(m14 element) to string.
-        TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::number_to_string(m14()))));
+        TRY_OR_THROW_OOM(vm, builder.try_append(JS::number_to_string(m14())));
 
         // 9. Append ", " to string.
         TRY_OR_THROW_OOM(vm, builder.try_append(", "sv));
 
         // 10. Append ! ToString(m21 element) to string.
-        TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::number_to_string(m21()))));
+        TRY_OR_THROW_OOM(vm, builder.try_append(JS::number_to_string(m21())));
 
         // 11. Append ", " to string.
         TRY_OR_THROW_OOM(vm, builder.try_append(", "sv));
 
         // 12. Append ! ToString(m22 element) to string.
-        TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::number_to_string(m22()))));
+        TRY_OR_THROW_OOM(vm, builder.try_append(JS::number_to_string(m22())));
 
         // 13. Append ", " to string.
         TRY_OR_THROW_OOM(vm, builder.try_append(", "sv));
 
         // 14. Append ! ToString(m23 element) to string.
-        TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::number_to_string(m23()))));
+        TRY_OR_THROW_OOM(vm, builder.try_append(JS::number_to_string(m23())));
 
         // 15. Append ", " to string.
         TRY_OR_THROW_OOM(vm, builder.try_append(", "sv));
 
         // 16. Append ! ToString(m24 element) to string.
-        TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::number_to_string(m24()))));
+        TRY_OR_THROW_OOM(vm, builder.try_append(JS::number_to_string(m24())));
 
         // 17. Append ", " to string.
         TRY_OR_THROW_OOM(vm, builder.try_append(", "sv));
 
         // NOTE: The spec doesn't include the steps to append m31 to m34, but they are required as matrix3d requires 16 elements.
-        TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::number_to_string(m31()))));
+        TRY_OR_THROW_OOM(vm, builder.try_append(JS::number_to_string(m31())));
         TRY_OR_THROW_OOM(vm, builder.try_append(", "sv));
-        TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::number_to_string(m32()))));
+        TRY_OR_THROW_OOM(vm, builder.try_append(JS::number_to_string(m32())));
         TRY_OR_THROW_OOM(vm, builder.try_append(", "sv));
-        TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::number_to_string(m33()))));
+        TRY_OR_THROW_OOM(vm, builder.try_append(JS::number_to_string(m33())));
         TRY_OR_THROW_OOM(vm, builder.try_append(", "sv));
-        TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::number_to_string(m34()))));
+        TRY_OR_THROW_OOM(vm, builder.try_append(JS::number_to_string(m34())));
         TRY_OR_THROW_OOM(vm, builder.try_append(", "sv));
 
         // 18. Append ! ToString(m41 element) to string.
-        TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::number_to_string(m41()))));
+        TRY_OR_THROW_OOM(vm, builder.try_append(JS::number_to_string(m41())));
 
         // 19. Append ", " to string.
         TRY_OR_THROW_OOM(vm, builder.try_append(", "sv));
 
         // 20. Append ! ToString(m42 element) to string.
-        TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::number_to_string(m42()))));
+        TRY_OR_THROW_OOM(vm, builder.try_append(JS::number_to_string(m42())));
 
         // 21. Append ", " to string.
         TRY_OR_THROW_OOM(vm, builder.try_append(", "sv));
 
         // 22. Append ! ToString(m43 element) to string.
-        TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::number_to_string(m43()))));
+        TRY_OR_THROW_OOM(vm, builder.try_append(JS::number_to_string(m43())));
 
         // 23. Append ", " to string.
         TRY_OR_THROW_OOM(vm, builder.try_append(", "sv));
 
         // 24. Append ! ToString(m44 element) to string.
-        TRY_OR_THROW_OOM(vm, builder.try_append(TRY_OR_THROW_OOM(vm, JS::number_to_string(m44()))));
+        TRY_OR_THROW_OOM(vm, builder.try_append(JS::number_to_string(m44())));
 
         // 25. Append ")" to string.
         TRY_OR_THROW_OOM(vm, builder.try_append(")"sv));