Title: [293708] trunk
Revision
293708
Author
ysuz...@apple.com
Date
2022-05-02 18:55:37 -0700 (Mon, 02 May 2022)

Log Message

[JSC] Add ISO8601 based Temporal.PlainDate getters
https://bugs.webkit.org/show_bug.cgi?id=239949

Reviewed by Ross Kirsling and Dean Jackson.

This patch adds missing getters of Temporal.PlainDate. Currently, we are not querying to Calendar.
It will be wired once we bake Calendar completely.

* JSTests/stress/temporal-plaindate.js:
(print):
(shouldBe):
* Source/_javascript_Core/runtime/ISO8601.cpp:
(JSC::ISO8601::dayOfWeek):
(JSC::ISO8601::dayOfYear):
(JSC::ISO8601::weekOfYear):
(JSC::ISO8601::daysInMonth):
(JSC::ISO8601::monthCode):
* Source/_javascript_Core/runtime/ISO8601.h:
* Source/_javascript_Core/runtime/TemporalPlainDate.cpp:
(JSC::TemporalPlainDate::from):
(JSC::TemporalPlainDate::monthCode const):
(JSC::TemporalPlainDate::dayOfWeek const):
(JSC::TemporalPlainDate::dayOfYear const):
(JSC::TemporalPlainDate::weekOfYear const):
* Source/_javascript_Core/runtime/TemporalPlainDate.h:
* Source/_javascript_Core/runtime/TemporalPlainDatePrototype.cpp:
(JSC::JSC_DEFINE_CUSTOM_GETTER):

Canonical link: https://commits.webkit.org/250197@main

Modified Paths

Diff

Modified: trunk/JSTests/ChangeLog (293707 => 293708)


--- trunk/JSTests/ChangeLog	2022-05-03 01:32:11 UTC (rev 293707)
+++ trunk/JSTests/ChangeLog	2022-05-03 01:55:37 UTC (rev 293708)
@@ -1,3 +1,14 @@
+2022-05-01  Yusuke Suzuki  <ysuz...@apple.com>
+
+        [JSC] Add ISO8601 based Temporal.PlainDate getters
+        https://bugs.webkit.org/show_bug.cgi?id=239949
+
+        Reviewed by Ross Kirsling and Dean Jackson.
+
+        * stress/temporal-plaindate.js:
+        (print):
+        (shouldBe):
+
 2022-05-02  Angelos Oikonomopoulos  <ange...@igalia.com>
 
         new-largeish-contiguous-array-with-size.js: pick up leakFactor

Modified: trunk/JSTests/stress/temporal-plaindate.js (293707 => 293708)


--- trunk/JSTests/stress/temporal-plaindate.js	2022-05-03 01:32:11 UTC (rev 293707)
+++ trunk/JSTests/stress/temporal-plaindate.js	2022-05-03 01:55:37 UTC (rev 293708)
@@ -163,13 +163,164 @@
     }, RangeError);
 }
 
-// FIXME: This relies on Temporal.PlainDate.from(object).
-// {
-//     let _one_ = Temporal.PlainDate.from('1001-01-01');
-//     let two = Temporal.PlainDate.from('1002-01-01');
-//     let three = Temporal.PlainDate.from('1000-02-02');
-//     let four = Temporal.PlainDate.from('1001-01-02');
-//     let five = Temporal.PlainDate.from('1001-02-01');
-//     let sorted = [one, two, three, four, five].sort(Temporal.PlainDate.compare);
-//     shouldBe(sorted.join(' '), `1000-02-02 1001-01-01 1001-01-02 1001-02-01 1002-01-01`);
-// }
+{
+    let _one_ = Temporal.PlainDate.from('1001-01-01');
+    let two = Temporal.PlainDate.from('1002-01-01');
+    let three = Temporal.PlainDate.from('1000-02-02');
+    let four = Temporal.PlainDate.from('1001-01-02');
+    let five = Temporal.PlainDate.from('1001-02-01');
+    let sorted = [one, two, three, four, five].sort(Temporal.PlainDate.compare);
+    shouldBe(sorted.join(' '), `1000-02-02 1001-01-01 1001-01-02 1001-02-01 1002-01-01`);
+}
+
+{
+    for (let i = 0; i < 12; ++i) {
+        let dt = new Temporal.PlainDate(1995, 1 + i, 11 + i);
+        shouldBe(dt.monthCode, `M${String(1 + i).padStart(2, '0')}`);
+    }
+}
+
+{
+    let week = ['MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT', 'SUN'];
+    for (let i = 0; i < 7; ++i) {
+        let dt = new Temporal.PlainDate(1995, 12, 11 + i);
+        shouldBe(week[dt.dayOfWeek - 1], week[i]);
+    }
+}
+{
+    shouldBe(Temporal.PlainDate.from('1995-12-07').dayOfWeek, 4);
+    shouldBe(Temporal.PlainDate.from('1995-12-08').dayOfWeek, 5);
+    shouldBe(Temporal.PlainDate.from('1995-12-09').dayOfWeek, 6);
+    shouldBe(Temporal.PlainDate.from('1995-12-10').dayOfWeek, 7);
+    shouldBe(Temporal.PlainDate.from('1995-12-11').dayOfWeek, 1);
+    shouldBe(Temporal.PlainDate.from('1995-12-12').dayOfWeek, 2);
+    shouldBe(Temporal.PlainDate.from('1995-12-13').dayOfWeek, 3);
+    shouldBe(Temporal.PlainDate.from('1995-12-14').dayOfWeek, 4);
+}
+
+{
+    let tests = [
+        [ '1995-01-01', 1 ],
+        [ '1995-12-07', 341 ],
+        [ '1995-12-31', 365 ],
+        [ '2000-01-01', 1 ],
+        [ '2000-12-07', 342 ],
+        [ '2000-12-31', 366 ],
+        [ '2004-01-01', 1 ],
+        [ '2004-12-07', 342 ],
+        [ '2004-12-31', 366 ],
+        [ '2100-01-01', 1 ],
+        [ '2100-12-07', 341 ],
+        [ '2100-12-31', 365 ],
+    ];
+    for (let test of tests) {
+        let dt = Temporal.PlainDate.from(test[0]);
+        shouldBe(dt.dayOfYear, test[1]);
+    }
+}
+
+{
+    shouldBe(Temporal.PlainDate.from('1996-12-31').weekOfYear, 1);
+    shouldBe(Temporal.PlainDate.from('1997-12-31').weekOfYear, 1);
+    shouldBe(Temporal.PlainDate.from('1998-12-27').weekOfYear, 52);
+    shouldBe(Temporal.PlainDate.from('1998-12-31').weekOfYear, 53);
+    shouldBe(Temporal.PlainDate.from('1999-12-31').weekOfYear, 52);
+    shouldBe(Temporal.PlainDate.from('2000-12-31').weekOfYear, 52);
+
+    shouldBe(Temporal.PlainDate.from('1995-12-07').weekOfYear, 49);
+    shouldBe(Temporal.PlainDate.from('1995-12-08').weekOfYear, 49);
+    shouldBe(Temporal.PlainDate.from('1995-12-09').weekOfYear, 49);
+    shouldBe(Temporal.PlainDate.from('1995-12-10').weekOfYear, 49);
+    shouldBe(Temporal.PlainDate.from('1995-12-11').weekOfYear, 50);
+    shouldBe(Temporal.PlainDate.from('1995-12-31').weekOfYear, 52);
+    shouldBe(Temporal.PlainDate.from('1995-01-20').weekOfYear, 3);
+
+    shouldBe(Temporal.PlainDate.from('1995-01-02').weekOfYear, 1);
+    shouldBe(Temporal.PlainDate.from('1995-01-03').weekOfYear, 1);
+    shouldBe(Temporal.PlainDate.from('1995-01-04').weekOfYear, 1);
+    shouldBe(Temporal.PlainDate.from('1995-01-05').weekOfYear, 1);
+    shouldBe(Temporal.PlainDate.from('1995-01-06').weekOfYear, 1);
+    shouldBe(Temporal.PlainDate.from('1995-01-07').weekOfYear, 1);
+    shouldBe(Temporal.PlainDate.from('1995-01-08').weekOfYear, 1);
+    shouldBe(Temporal.PlainDate.from('1995-01-09').weekOfYear, 2);
+
+    shouldBe(Temporal.PlainDate.from('1994-12-25').weekOfYear, 51); // Thursday
+    shouldBe(Temporal.PlainDate.from('1994-12-26').weekOfYear, 52); // Friday
+    shouldBe(Temporal.PlainDate.from('1994-12-27').weekOfYear, 52); // Saturday
+    shouldBe(Temporal.PlainDate.from('1994-12-28').weekOfYear, 52); // Sunday
+    shouldBe(Temporal.PlainDate.from('1994-12-29').weekOfYear, 52); // Monday
+    shouldBe(Temporal.PlainDate.from('1994-12-30').weekOfYear, 52); // Tuesday
+    shouldBe(Temporal.PlainDate.from('1994-12-31').weekOfYear, 52); // Wednesday
+    shouldBe(Temporal.PlainDate.from('1995-01-01').weekOfYear, 52); // Thursday
+}
+
+{
+    shouldBe(Temporal.PlainDate.from('1995-12-07').daysInWeek, 7);
+    shouldBe(Temporal.PlainDate.from('2001-12-07').daysInWeek, 7);
+    shouldBe(Temporal.PlainDate.from('2000-12-07').daysInWeek, 7);
+    shouldBe(Temporal.PlainDate.from('2004-12-07').daysInWeek, 7);
+    shouldBe(Temporal.PlainDate.from('2100-12-07').daysInWeek, 7);
+}
+
+{
+    let days = [
+        [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ],
+        [ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ],
+    ];
+    for (let i = 0; i < 12; ++i) {
+        let dt = new Temporal.PlainDate(1995, 1 + i, 11 + i);
+        shouldBe(dt.daysInMonth, days[0][i]);
+    }
+    for (let i = 0; i < 12; ++i) {
+        let dt = new Temporal.PlainDate(2004, 1 + i, 11 + i);
+        shouldBe(dt.daysInMonth, days[1][i]);
+    }
+}
+
+{
+    shouldBe(Temporal.PlainDate.from('1995-12-07').daysInYear, 365);
+    shouldBe(Temporal.PlainDate.from('2001-12-07').daysInYear, 365);
+    shouldBe(Temporal.PlainDate.from('2000-12-07').daysInYear, 366);
+    shouldBe(Temporal.PlainDate.from('2004-12-07').daysInYear, 366);
+    shouldBe(Temporal.PlainDate.from('2100-12-07').daysInYear, 365);
+}
+
+{
+    shouldBe(Temporal.PlainDate.from('1995-12-07').monthsInYear, 12);
+    shouldBe(Temporal.PlainDate.from('2001-12-07').monthsInYear, 12);
+    shouldBe(Temporal.PlainDate.from('2000-12-07').monthsInYear, 12);
+    shouldBe(Temporal.PlainDate.from('2004-12-07').monthsInYear, 12);
+    shouldBe(Temporal.PlainDate.from('2100-12-07').monthsInYear, 12);
+}
+
+{
+    shouldBe(Temporal.PlainDate.from('1995-12-07').inLeapYear, false);
+    shouldBe(Temporal.PlainDate.from('2001-12-07').inLeapYear, false);
+    shouldBe(Temporal.PlainDate.from('2000-12-07').inLeapYear, true);
+    shouldBe(Temporal.PlainDate.from('2004-12-07').inLeapYear, true);
+    shouldBe(Temporal.PlainDate.from('2100-12-07').inLeapYear, false);
+}
+
+{
+    let getterNames = [
+        "year",
+        "month",
+        "monthCode",
+        "day",
+        "dayOfWeek",
+        "dayOfYear",
+        "weekOfYear",
+        "daysInWeek",
+        "daysInMonth",
+        "daysInYear",
+        "monthsInYear",
+        "inLeapYear",
+    ];
+    for (let getterName of getterNames) {
+        let getter = Reflect.getOwnPropertyDescriptor(Temporal.PlainDate.prototype, getterName).get;
+        shouldBe(typeof getter, 'function');
+        shouldThrow(() => {
+            getter.call({});
+        }, TypeError);
+    }
+}

Modified: trunk/Source/_javascript_Core/ChangeLog (293707 => 293708)


--- trunk/Source/_javascript_Core/ChangeLog	2022-05-03 01:32:11 UTC (rev 293707)
+++ trunk/Source/_javascript_Core/ChangeLog	2022-05-03 01:55:37 UTC (rev 293708)
@@ -1,3 +1,30 @@
+2022-05-01  Yusuke Suzuki  <ysuz...@apple.com>
+
+        [JSC] Add ISO8601 based Temporal.PlainDate getters
+        https://bugs.webkit.org/show_bug.cgi?id=239949
+
+        Reviewed by Ross Kirsling and Dean Jackson.
+
+        This patch adds missing getters of Temporal.PlainDate. Currently, we are not querying to Calendar.
+        It will be wired once we bake Calendar completely.
+
+        * runtime/ISO8601.cpp:
+        (JSC::ISO8601::dayOfWeek):
+        (JSC::ISO8601::dayOfYear):
+        (JSC::ISO8601::weekOfYear):
+        (JSC::ISO8601::daysInMonth):
+        (JSC::ISO8601::monthCode):
+        * runtime/ISO8601.h:
+        * runtime/TemporalPlainDate.cpp:
+        (JSC::TemporalPlainDate::from):
+        (JSC::TemporalPlainDate::monthCode const):
+        (JSC::TemporalPlainDate::dayOfWeek const):
+        (JSC::TemporalPlainDate::dayOfYear const):
+        (JSC::TemporalPlainDate::weekOfYear const):
+        * runtime/TemporalPlainDate.h:
+        * runtime/TemporalPlainDatePrototype.cpp:
+        (JSC::JSC_DEFINE_CUSTOM_GETTER):
+
 2022-05-02  Yusuke Suzuki  <ysuz...@apple.com>
 
         [JSC] Fix ASan crash due to CString ownership

Modified: trunk/Source/_javascript_Core/runtime/ISO8601.cpp (293707 => 293708)


--- trunk/Source/_javascript_Core/runtime/ISO8601.cpp	2022-05-03 01:32:11 UTC (rev 293707)
+++ trunk/Source/_javascript_Core/runtime/ISO8601.cpp	2022-05-03 01:55:37 UTC (rev 293708)
@@ -1095,6 +1095,68 @@
     });
 }
 
+uint8_t dayOfWeek(PlainDate plainDate)
+{
+    Int128 dateDays = static_cast<Int128>(dateToDaysFrom1970(plainDate.year(), plainDate.month() - 1, plainDate.day()));
+    int weekDay = static_cast<int>((dateDays + 4) % 7);
+    if (weekDay < 0)
+        weekDay += 7;
+    return !weekDay ? 7 : weekDay;
+}
+
+uint16_t dayOfYear(PlainDate plainDate)
+{
+    return dayInYear(plainDate.year(), plainDate.month() - 1, plainDate.day()) + 1; // Always start with 1 (1/1 is 1).
+}
+
+uint8_t weekOfYear(PlainDate plainDate)
+{
+    int32_t dayOfYear = ISO8601::dayOfYear(plainDate);
+    int32_t dayOfWeek = ISO8601::dayOfWeek(plainDate);
+
+    // ISO week 1 is the week containing the first Thursday (4) of the year.
+    // https://en.wikipedia.org/wiki/ISO_week_date#Algorithms
+    int32_t week = (dayOfYear - dayOfWeek + 10) / 7;
+    if (week <= 0) {
+        // Previous year's last week. Thus, 52 or 53 weeks. Getting weeks in the previous year.
+        //
+        // https://en.wikipedia.org/wiki/ISO_week_date#Weeks_per_year
+        // > The long years, with 53 weeks in them, can be described by any of the following equivalent definitions:
+        // >  - any year ending on Thursday (D, ED) and any leap year ending on Friday (DC)
+
+        int32_t dayOfWeekForJanuaryFirst = ISO8601::dayOfWeek(PlainDate { plainDate.year(), 1, 1 });
+
+        // Any year ending on Thursday (D, ED) -> this year's 1/1 is Friday.
+        if (dayOfWeekForJanuaryFirst == 5)
+            return 53;
+
+        // Any leap year ending on Friday (DC) -> this year's 1/1 is Saturday and previous year is a leap year.
+        if (dayOfWeekForJanuaryFirst == 6 && isLeapYear(plainDate.year() - 1))
+            return 53;
+
+        return 52;
+    }
+
+    if (week == 53) {
+        // Check whether this is in next year's week 1.
+        int32_t daysInYear = isLeapYear(plainDate.year()) ? 366 : 365;
+        if ((daysInYear - dayOfYear) < (4 - dayOfWeek))
+            return 1;
+    }
+
+    return week;
+}
+
+static constexpr uint8_t daysInMonths[2][12] = {
+    { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
+    { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
+};
+
+uint8_t daysInMonth(int32_t year, uint8_t month)
+{
+    return daysInMonths[!!isLeapYear(year)][month - 1];
+}
+
 // https://tc39.es/proposal-temporal/#sec-temporal-formattimezoneoffsetstring
 String formatTimeZoneOffsetString(int64_t offset)
 {
@@ -1176,6 +1238,11 @@
     return makeString(pad('0', 4, plainDate.year()), '-', pad('0', 2, plainDate.month()), '-', pad('0', 2, plainDate.day()));
 }
 
+String monthCode(uint32_t month)
+{
+    return makeString('M', pad('0', 2, month));
+}
+
 // IsValidDuration ( years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds )
 // https://tc39.es/proposal-temporal/#sec-temporal-isvalidduration
 bool isValidDuration(const Duration& duration)

Modified: trunk/Source/_javascript_Core/runtime/ISO8601.h (293707 => 293708)


--- trunk/Source/_javascript_Core/runtime/ISO8601.h	2022-05-03 01:32:11 UTC (rev 293707)
+++ trunk/Source/_javascript_Core/runtime/ISO8601.h	2022-05-03 01:55:37 UTC (rev 293708)
@@ -264,8 +264,8 @@
 
 private:
     int32_t m_year : 21; // ECMAScript max / min date's year can be represented <= 20 bits.
-    int32_t m_month : 5;
-    int32_t m_day : 6;
+    int32_t m_month : 5; // Starts with 1.
+    int32_t m_day : 6; // Starts with 1.
 };
 #if COMPILER(GCC_COMPATIBLE)
 static_assert(sizeof(PlainDate) == sizeof(int32_t));
@@ -296,9 +296,15 @@
 std::optional<std::tuple<PlainTime, std::optional<TimeZoneRecord>, std::optional<CalendarRecord>>> parseCalendarTime(StringView);
 std::optional<std::tuple<PlainDate, std::optional<PlainTime>, std::optional<TimeZoneRecord>>> parseDateTime(StringView);
 std::optional<std::tuple<PlainDate, std::optional<PlainTime>, std::optional<TimeZoneRecord>, std::optional<CalendarRecord>>> parseCalendarDateTime(StringView);
+uint8_t dayOfWeek(PlainDate);
+uint16_t dayOfYear(PlainDate);
+uint8_t weeksInYear(int32_t year);
+uint8_t weekOfYear(PlainDate);
+uint8_t daysInMonth(int32_t year, uint8_t month);
 String formatTimeZoneOffsetString(int64_t);
 String temporalTimeToString(PlainTime, std::tuple<Precision, unsigned> precision);
 String temporalDateToString(PlainDate);
+String monthCode(uint32_t);
 unsigned daysInMonth(int32_t year, unsigned month);
 
 bool isValidDuration(const Duration&);

Modified: trunk/Source/_javascript_Core/runtime/TemporalPlainDate.cpp (293707 => 293708)


--- trunk/Source/_javascript_Core/runtime/TemporalPlainDate.cpp	2022-05-03 01:32:11 UTC (rev 293707)
+++ trunk/Source/_javascript_Core/runtime/TemporalPlainDate.cpp	2022-05-03 01:55:37 UTC (rev 293708)
@@ -160,6 +160,8 @@
     UNUSED_PARAM(overflowValue);
 
     if (itemValue.isObject()) {
+        if (itemValue.inherits<TemporalPlainDate>())
+            return jsCast<TemporalPlainDate*>(itemValue);
         throwRangeError(globalObject, scope, "unimplemented: from object"_s);
         return { };
     }
@@ -201,4 +203,24 @@
     return 0;
 }
 
+String TemporalPlainDate::monthCode() const
+{
+    return ISO8601::monthCode(m_plainDate.month());
+}
+
+uint8_t TemporalPlainDate::dayOfWeek() const
+{
+    return ISO8601::dayOfWeek(m_plainDate);
+}
+
+uint16_t TemporalPlainDate::dayOfYear() const
+{
+    return ISO8601::dayOfYear(m_plainDate);
+}
+
+uint8_t TemporalPlainDate::weekOfYear() const
+{
+    return ISO8601::weekOfYear(m_plainDate);
+}
+
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/runtime/TemporalPlainDate.h (293707 => 293708)


--- trunk/Source/_javascript_Core/runtime/TemporalPlainDate.h	2022-05-03 01:32:11 UTC (rev 293707)
+++ trunk/Source/_javascript_Core/runtime/TemporalPlainDate.h	2022-05-03 01:55:37 UTC (rev 293708)
@@ -58,6 +58,11 @@
     JSC_TEMPORAL_PLAIN_DATE_UNITS(JSC_DEFINE_TEMPORAL_PLAIN_DATE_FIELD);
 #undef JSC_DEFINE_TEMPORAL_PLAIN_DATE_FIELD
 
+    String monthCode() const;
+    uint8_t dayOfWeek() const;
+    uint16_t dayOfYear() const;
+    uint8_t weekOfYear() const;
+
     String toString(JSGlobalObject*, JSValue options) const;
     String toString() const
     {

Modified: trunk/Source/_javascript_Core/runtime/TemporalPlainDatePrototype.cpp (293707 => 293708)


--- trunk/Source/_javascript_Core/runtime/TemporalPlainDatePrototype.cpp	2022-05-03 01:32:11 UTC (rev 293707)
+++ trunk/Source/_javascript_Core/runtime/TemporalPlainDatePrototype.cpp	2022-05-03 01:55:37 UTC (rev 293708)
@@ -36,7 +36,16 @@
 static JSC_DECLARE_HOST_FUNCTION(temporalPlainDatePrototypeFuncToString);
 static JSC_DECLARE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterYear);
 static JSC_DECLARE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterMonth);
+static JSC_DECLARE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterMonthCode);
 static JSC_DECLARE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterDay);
+static JSC_DECLARE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterDayOfWeek);
+static JSC_DECLARE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterDayOfYear);
+static JSC_DECLARE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterWeekOfYear);
+static JSC_DECLARE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterDaysInWeek);
+static JSC_DECLARE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterDaysInMonth);
+static JSC_DECLARE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterDaysInYear);
+static JSC_DECLARE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterMonthsInYear);
+static JSC_DECLARE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterInLeapYear);
 
 }
 
@@ -51,7 +60,16 @@
   toString         temporalPlainDatePrototypeFuncToString           DontEnum|Function 0
   year             temporalPlainDatePrototypeGetterYear             DontEnum|ReadOnly|CustomAccessor
   month            temporalPlainDatePrototypeGetterMonth            DontEnum|ReadOnly|CustomAccessor
+  monthCode        temporalPlainDatePrototypeGetterMonthCode        DontEnum|ReadOnly|CustomAccessor
   day              temporalPlainDatePrototypeGetterDay              DontEnum|ReadOnly|CustomAccessor
+  dayOfWeek        temporalPlainDatePrototypeGetterDayOfWeek        DontEnum|ReadOnly|CustomAccessor
+  dayOfYear        temporalPlainDatePrototypeGetterDayOfYear        DontEnum|ReadOnly|CustomAccessor
+  weekOfYear       temporalPlainDatePrototypeGetterWeekOfYear       DontEnum|ReadOnly|CustomAccessor
+  daysInWeek       temporalPlainDatePrototypeGetterDaysInWeek       DontEnum|ReadOnly|CustomAccessor
+  daysInMonth      temporalPlainDatePrototypeGetterDaysInMonth      DontEnum|ReadOnly|CustomAccessor
+  daysInYear       temporalPlainDatePrototypeGetterDaysInYear       DontEnum|ReadOnly|CustomAccessor
+  monthsInYear     temporalPlainDatePrototypeGetterMonthsInYear     DontEnum|ReadOnly|CustomAccessor
+  inLeapYear       temporalPlainDatePrototypeGetterInLeapYear       DontEnum|ReadOnly|CustomAccessor
 @end
 */
 
@@ -116,6 +134,18 @@
     return JSValue::encode(jsNumber(plainDate->month()));
 }
 
+JSC_DEFINE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterMonthCode, (JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName))
+{
+    VM& vm = globalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    auto* plainDate = jsDynamicCast<TemporalPlainDate*>(JSValue::decode(thisValue));
+    if (!plainDate)
+        return throwVMTypeError(globalObject, scope, "Temporal.PlainDate.prototype.monthCode called on value that's not a plainDate"_s);
+
+    return JSValue::encode(jsNontrivialString(vm, plainDate->monthCode()));
+}
+
 JSC_DEFINE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterDay, (JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName))
 {
     VM& vm = globalObject->vm();
@@ -128,5 +158,100 @@
     return JSValue::encode(jsNumber(plainDate->day()));
 }
 
+JSC_DEFINE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterDayOfWeek, (JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName))
+{
+    VM& vm = globalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
 
+    auto* plainDate = jsDynamicCast<TemporalPlainDate*>(JSValue::decode(thisValue));
+    if (!plainDate)
+        return throwVMTypeError(globalObject, scope, "Temporal.PlainDate.prototype.dayOfWeek called on value that's not a plainDate"_s);
+
+    return JSValue::encode(jsNumber(plainDate->dayOfWeek()));
+}
+
+JSC_DEFINE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterDayOfYear, (JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName))
+{
+    VM& vm = globalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    auto* plainDate = jsDynamicCast<TemporalPlainDate*>(JSValue::decode(thisValue));
+    if (!plainDate)
+        return throwVMTypeError(globalObject, scope, "Temporal.PlainDate.prototype.dayOfYear called on value that's not a plainDate"_s);
+
+    return JSValue::encode(jsNumber(plainDate->dayOfYear()));
+}
+
+JSC_DEFINE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterWeekOfYear, (JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName))
+{
+    VM& vm = globalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    auto* plainDate = jsDynamicCast<TemporalPlainDate*>(JSValue::decode(thisValue));
+    if (!plainDate)
+        return throwVMTypeError(globalObject, scope, "Temporal.PlainDate.prototype.weekOfYear called on value that's not a plainDate"_s);
+
+    return JSValue::encode(jsNumber(plainDate->weekOfYear()));
+}
+
+JSC_DEFINE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterDaysInWeek, (JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName))
+{
+    VM& vm = globalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    auto* plainDate = jsDynamicCast<TemporalPlainDate*>(JSValue::decode(thisValue));
+    if (!plainDate)
+        return throwVMTypeError(globalObject, scope, "Temporal.PlainDate.prototype.daysInWeek called on value that's not a plainDate"_s);
+
+    return JSValue::encode(jsNumber(7)); // ISO8601 calendar always returns 7.
+}
+
+JSC_DEFINE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterDaysInMonth, (JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName))
+{
+    VM& vm = globalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    auto* plainDate = jsDynamicCast<TemporalPlainDate*>(JSValue::decode(thisValue));
+    if (!plainDate)
+        return throwVMTypeError(globalObject, scope, "Temporal.PlainDate.prototype.daysInMonth called on value that's not a plainDate"_s);
+
+    return JSValue::encode(jsNumber(ISO8601::daysInMonth(plainDate->year(), plainDate->month())));
+}
+
+JSC_DEFINE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterDaysInYear, (JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName))
+{
+    VM& vm = globalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    auto* plainDate = jsDynamicCast<TemporalPlainDate*>(JSValue::decode(thisValue));
+    if (!plainDate)
+        return throwVMTypeError(globalObject, scope, "Temporal.PlainDate.prototype.daysInYear called on value that's not a plainDate"_s);
+
+    return JSValue::encode(jsNumber(isLeapYear(plainDate->year()) ? 366 : 365));
+}
+
+JSC_DEFINE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterMonthsInYear, (JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName))
+{
+    VM& vm = globalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    auto* plainDate = jsDynamicCast<TemporalPlainDate*>(JSValue::decode(thisValue));
+    if (!plainDate)
+        return throwVMTypeError(globalObject, scope, "Temporal.PlainDate.prototype.monthsInYear called on value that's not a plainDate"_s);
+
+    return JSValue::encode(jsNumber(12)); // ISO8601 calendar always returns 12.
+}
+
+JSC_DEFINE_CUSTOM_GETTER(temporalPlainDatePrototypeGetterInLeapYear, (JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName))
+{
+    VM& vm = globalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    auto* plainDate = jsDynamicCast<TemporalPlainDate*>(JSValue::decode(thisValue));
+    if (!plainDate)
+        return throwVMTypeError(globalObject, scope, "Temporal.PlainDate.prototype.inLeapYear called on value that's not a plainDate"_s);
+
+    return JSValue::encode(jsBoolean(isLeapYear(plainDate->year())));
+}
+
 } // namespace JSC
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to