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