Title: [283009] trunk/Source/_javascript_Core
Revision
283009
Author
[email protected]
Date
2021-09-23 14:50:51 -0700 (Thu, 23 Sep 2021)

Log Message

Various tweaks in preparation for Temporal.Instant
https://bugs.webkit.org/show_bug.cgi?id=230331

Patch by Philip Chimento <[email protected]> on 2021-09-23
Reviewed by Yusuke Suzuki.

* runtime/TemporalDuration.cpp:
(JSC::TemporalDuration::fromDurationLike): Use
  temporalUnitPropertyName().
(JSC::TemporalDuration::toISO8601Duration): Improve error message to
  include the invalid string.
(JSC::TemporalDuration::with const): Use temporalUnitPropertyName().
(JSC::TemporalDuration::toString): Use formatSecondsStringFraction().
* runtime/TemporalObject.cpp:
(JSC::ellipsizeAt): Add helper to ellipsize string at certain length.
(JSC::temporalUnitPropertyName): Move code from TemporalDuration into
  a function which will be reused in other Temporal types.
(JSC::temporalFractionalSecondDigits): Handle NaN as per
  specification, and improve error message to include the invalid
  value.
(JSC::formatSecondsStringFraction): Move code from TemporalDuration
  into a function which will be reused in other Temporal types.
* runtime/TemporalObject.h:

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (283008 => 283009)


--- trunk/Source/_javascript_Core/ChangeLog	2021-09-23 21:35:39 UTC (rev 283008)
+++ trunk/Source/_javascript_Core/ChangeLog	2021-09-23 21:50:51 UTC (rev 283009)
@@ -1,3 +1,28 @@
+2021-09-23  Philip Chimento  <[email protected]>
+
+        Various tweaks in preparation for Temporal.Instant
+        https://bugs.webkit.org/show_bug.cgi?id=230331
+
+        Reviewed by Yusuke Suzuki.
+
+        * runtime/TemporalDuration.cpp:
+        (JSC::TemporalDuration::fromDurationLike): Use
+          temporalUnitPropertyName().
+        (JSC::TemporalDuration::toISO8601Duration): Improve error message to
+          include the invalid string.
+        (JSC::TemporalDuration::with const): Use temporalUnitPropertyName().
+        (JSC::TemporalDuration::toString): Use formatSecondsStringFraction().
+        * runtime/TemporalObject.cpp:
+        (JSC::ellipsizeAt): Add helper to ellipsize string at certain length.
+        (JSC::temporalUnitPropertyName): Move code from TemporalDuration into
+          a function which will be reused in other Temporal types.
+        (JSC::temporalFractionalSecondDigits): Handle NaN as per
+          specification, and improve error message to include the invalid
+          value.
+        (JSC::formatSecondsStringFraction): Move code from TemporalDuration
+          into a function which will be reused in other Temporal types.
+        * runtime/TemporalObject.h:
+
 2021-09-23  Devin Rousso  <[email protected]>
 
         Web Inspector: Graphics: add instrumentation for new `CanvasRenderingContext2DSettings`

Modified: trunk/Source/_javascript_Core/runtime/TemporalDuration.cpp (283008 => 283009)


--- trunk/Source/_javascript_Core/runtime/TemporalDuration.cpp	2021-09-23 21:35:39 UTC (rev 283008)
+++ trunk/Source/_javascript_Core/runtime/TemporalDuration.cpp	2021-09-23 21:50:51 UTC (rev 283009)
@@ -28,6 +28,7 @@
 
 #include "IntlObjectInlines.h"
 #include "JSCInlines.h"
+#include "TemporalObject.h"
 #include <wtf/text/StringBuilder.h>
 
 namespace JSC {
@@ -34,18 +35,6 @@
 
 static constexpr double nanosecondsPerDay = 24.0 * 60 * 60 * 1000 * 1000 * 1000;
 
-static PropertyName propertyName(VM& vm, unsigned index)
-{
-    ASSERT(index < numberOfTemporalUnits);
-    switch (static_cast<TemporalUnit>(index)) {
-#define JSC_TEMPORAL_DURATION_PROPERTY_NAME(name, capitalizedName) case TemporalUnit::capitalizedName: return vm.propertyNames->name##s; 
-        JSC_TEMPORAL_UNITS(JSC_TEMPORAL_DURATION_PROPERTY_NAME)
-#undef JSC_TEMPORAL_DURATION_PROPERTY_NAME
-    }
-
-    RELEASE_ASSERT_NOT_REACHED();
-}
-
 const ClassInfo TemporalDuration::s_info = { "Object", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(TemporalDuration) };
 
 TemporalDuration* TemporalDuration::create(VM& vm, Structure* structure, ISO8601::Duration&& duration)
@@ -100,7 +89,7 @@
     ISO8601::Duration result;
     auto hasRelevantProperty = false;
     for (size_t i = 0; i < numberOfTemporalUnits; i++) {
-        JSValue value = durationLike->get(globalObject, propertyName(vm, i));
+        JSValue value = durationLike->get(globalObject, temporalUnitPropertyName(vm, static_cast<TemporalUnit>(i)));
         RETURN_IF_EXCEPTION(scope, { });
 
         if (value.isUndefined()) {
@@ -143,7 +132,8 @@
 
         auto parsedDuration = ISO8601::parseDuration(string);
         if (!parsedDuration) {
-            throwRangeError(globalObject, scope, "Could not parse Duration string"_s);
+            // 3090: 308 digits * 10 fields + 10 designators
+            throwRangeError(globalObject, scope, makeString("'"_s, ellipsizeAt(3090, string), "' is not a valid Duration string"_s));
             return { };
         }
 
@@ -241,7 +231,7 @@
     ISO8601::Duration result;
     auto hasRelevantProperty = false;
     for (size_t i = 0; i < numberOfTemporalUnits; i++) {
-        JSValue value = durationLike->get(globalObject, propertyName(vm, i));
+        JSValue value = durationLike->get(globalObject, temporalUnitPropertyName(vm, static_cast<TemporalUnit>(i)));
         RETURN_IF_EXCEPTION(scope, { });
 
         if (value.isUndefined()) {
@@ -550,8 +540,7 @@
 // https://tc39.es/proposal-temporal/#sec-temporal-temporaldurationtostring
 String TemporalDuration::toString(const ISO8601::Duration& duration, std::tuple<Precision, unsigned> precision)
 {
-    auto [precisionType, precisionValue] = precision;
-    ASSERT(precisionType == Precision::Auto || precisionValue < 10);
+    ASSERT(std::get<0>(precision) == Precision::Auto || std::get<1>(precision) < 10);
 
     auto balancedMicroseconds = duration.microseconds() + std::trunc(duration.nanoseconds() / 1000);
     auto balancedNanoseconds = std::fmod(duration.nanoseconds(), 1000);
@@ -598,17 +587,7 @@
         builder.append(formatInteger(balancedSeconds));
 
         auto fraction = std::abs(balancedMilliseconds) * 1e6 + std::abs(balancedMicroseconds) * 1e3 + std::abs(balancedNanoseconds);
-        if ((precisionType == Precision::Auto && fraction) || (precisionType == Precision::Fixed && precisionValue)) {
-            auto padded = makeString('.', pad('0', 9, fraction));
-            if (precisionType == Precision::Fixed)
-                builder.append(StringView(padded).left(padded.length() - (9 - precisionValue)));
-            else {
-                auto lengthWithoutTrailingZeroes = padded.length();
-                while (padded[lengthWithoutTrailingZeroes - 1] == '0')
-                    lengthWithoutTrailingZeroes--;
-                builder.append(StringView(padded).left(lengthWithoutTrailingZeroes));
-            }
-        }
+        formatSecondsStringFraction(builder, fraction, precision);
 
         builder.append('S');
     }

Modified: trunk/Source/_javascript_Core/runtime/TemporalObject.cpp (283008 => 283009)


--- trunk/Source/_javascript_Core/runtime/TemporalObject.cpp	2021-09-23 21:35:39 UTC (rev 283008)
+++ trunk/Source/_javascript_Core/runtime/TemporalObject.cpp	2021-09-23 21:50:51 UTC (rev 283009)
@@ -37,6 +37,8 @@
 #include "TemporalPlainTimePrototype.h"
 #include "TemporalTimeZoneConstructor.h"
 #include "TemporalTimeZonePrototype.h"
+#include <wtf/text/StringConcatenate.h>
+#include <wtf/unicode/CharacterNames.h>
 
 namespace JSC {
 
@@ -125,6 +127,28 @@
     return unit.endsWith("s") ? unit.left(unit.length() - 1) : unit;
 }
 
+// For use in error messages where a string value is potentially unbounded
+WTF::String ellipsizeAt(unsigned maxLength, const WTF::String& string)
+{
+    WTF::String copy { string };
+    if (string.length() > maxLength) {
+        copy.truncate(maxLength - 1);
+        copy.append(horizontalEllipsis);
+    }
+    return copy;
+}
+
+PropertyName temporalUnitPropertyName(VM& vm, TemporalUnit unit)
+{
+    switch (unit) {
+#define JSC_TEMPORAL_DURATION_PROPERTY_NAME(name, capitalizedName) case TemporalUnit::capitalizedName: return vm.propertyNames->name##s; 
+        JSC_TEMPORAL_UNITS(JSC_TEMPORAL_DURATION_PROPERTY_NAME)
+#undef JSC_TEMPORAL_DURATION_PROPERTY_NAME
+    }
+
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
 std::optional<TemporalUnit> temporalUnitType(StringView unit)
 {
     StringView singular = singularUnit(unit);
@@ -228,8 +252,8 @@
 
     if (value.isNumber()) {
         double doubleValue = value.asNumber();
-        if (doubleValue < 0 || doubleValue > 9) {
-            throwRangeError(globalObject, scope, "fractionalSecondDigits is out of range"_s);
+        if (!(doubleValue >= 0 && doubleValue <= 9)) {
+            throwRangeError(globalObject, scope, makeString("fractionalSecondDigits must be 'auto' or 0 through 9, not "_s, doubleValue));
             return std::nullopt;
         }
 
@@ -240,7 +264,7 @@
     RETURN_IF_EXCEPTION(scope, std::nullopt);
 
     if (stringValue != "auto")
-        throwRangeError(globalObject, scope, "fractionalSecondDigits is out of range"_s);
+        throwRangeError(globalObject, scope, makeString("fractionalSecondDigits must be 'auto' or 0 through 9, not "_s, ellipsizeAt(100, stringValue)));
 
     return std::nullopt;
 }
@@ -309,6 +333,22 @@
         "roundingMode must be either \"ceil\", \"floor\", \"trunc\", or \"halfExpand\""_s, fallback);
 }
 
+void formatSecondsStringFraction(StringBuilder& builder, unsigned fraction, std::tuple<Precision, unsigned> precision)
+{
+    auto [precisionType, precisionValue] = precision;
+    if ((precisionType == Precision::Auto && fraction) || (precisionType == Precision::Fixed && precisionValue)) {
+        auto padded = makeString('.', pad('0', 9, fraction));
+        if (precisionType == Precision::Fixed)
+            builder.append(StringView(padded).left(padded.length() - (9 - precisionValue)));
+        else {
+            auto lengthWithoutTrailingZeroes = padded.length();
+            while (padded[lengthWithoutTrailingZeroes - 1] == '0')
+                lengthWithoutTrailingZeroes--;
+            builder.append(StringView(padded).left(lengthWithoutTrailingZeroes));
+        }
+    }
+}
+
 // MaximumTemporalDurationRoundingIncrement ( unit )
 // https://tc39.es/proposal-temporal/#sec-temporal-maximumtemporaldurationroundingincrement
 std::optional<double> maximumRoundingIncrement(TemporalUnit unit)

Modified: trunk/Source/_javascript_Core/runtime/TemporalObject.h (283008 => 283009)


--- trunk/Source/_javascript_Core/runtime/TemporalObject.h	2021-09-23 21:35:39 UTC (rev 283008)
+++ trunk/Source/_javascript_Core/runtime/TemporalObject.h	2021-09-23 21:50:51 UTC (rev 283009)
@@ -93,6 +93,8 @@
     unsigned increment;
 };
 
+WTF::String ellipsizeAt(unsigned maxLength, const WTF::String&);
+PropertyName temporalUnitPropertyName(VM&, TemporalUnit);
 std::optional<TemporalUnit> temporalUnitType(StringView);
 std::optional<TemporalUnit> temporalLargestUnit(JSGlobalObject*, JSObject* options, std::initializer_list<TemporalUnit> disallowedUnits, TemporalUnit autoValue);
 std::optional<TemporalUnit> temporalSmallestUnit(JSGlobalObject*, JSObject* options, std::initializer_list<TemporalUnit> disallowedUnits);
@@ -99,6 +101,7 @@
 std::optional<unsigned> temporalFractionalSecondDigits(JSGlobalObject*, JSObject* options);
 PrecisionData secondsStringPrecision(JSGlobalObject*, JSObject* options);
 RoundingMode temporalRoundingMode(JSGlobalObject*, JSObject*, RoundingMode);
+void formatSecondsStringFraction(StringBuilder&, unsigned fraction, std::tuple<Precision, unsigned>);
 std::optional<double> maximumRoundingIncrement(TemporalUnit);
 double temporalRoundingIncrement(JSGlobalObject*, JSObject* options, std::optional<double> dividend, bool inclusive);
 double roundNumberToIncrement(double, double increment, RoundingMode);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to