Changeset 290248 in webkit
- Timestamp:
- Feb 21, 2022 9:56:12 AM (5 months ago)
- Location:
- trunk
- Files:
-
- 9 edited
-
JSTests/ChangeLog (modified) (1 diff)
-
JSTests/stress/temporal-instant.js (modified) (1 diff)
-
JSTests/stress/temporal-plaindate.js (modified) (3 diffs)
-
JSTests/stress/temporal-plaintime.js (modified) (3 diffs)
-
Source/JavaScriptCore/ChangeLog (modified) (1 diff)
-
Source/JavaScriptCore/runtime/ISO8601.cpp (modified) (11 diffs)
-
Source/JavaScriptCore/runtime/ISO8601.h (modified) (4 diffs)
-
Source/JavaScriptCore/runtime/TemporalPlainDate.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/TemporalPlainTime.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r290213 r290248 1 2022-02-21 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] Add CalendarDateTime parsing 4 https://bugs.webkit.org/show_bug.cgi?id=236886 5 6 Reviewed by Dean Jackson. 7 8 * stress/temporal-instant.js: 9 * stress/temporal-plaindate.js: 10 * stress/temporal-plaintime.js: 11 1 12 2022-02-19 Commit Queue <commit-queue@webkit.org> 2 13 -
trunk/JSTests/stress/temporal-instant.js
r285178 r290248 314 314 shouldBe(`${Temporal.Instant.from('1976-11-18T15Z')}`, '1976-11-18T15:00:00Z'); 315 315 // ignores any specified calendar 316 // FIXME: parse calendar 317 // shouldBe(`${Temporal.Instant.from('1976-11-18T15:23:30.123456789Z[u-ca=discord]')}`, '1976-11-18T15:23:30.123456789Z'); 316 shouldBe(`${Temporal.Instant.from('1976-11-18T15:23:30.123456789Z[u-ca=discord]')}`, '1976-11-18T15:23:30.123456789Z'); 318 317 // no junk at end of string 319 318 shouldThrow(() => Temporal.Instant.from('1976-11-18T15:23:30.123456789Zjunk'), RangeError); -
trunk/JSTests/stress/temporal-plaindate.js
r290209 r290248 48 48 shouldBe(String(Temporal.PlainDate.from('2007-01-09t03:24:30')), `2007-01-09`); 49 49 shouldBe(String(Temporal.PlainDate.from('2007-01-09 03:24:30')), `2007-01-09`); 50 shouldBe(String(Temporal.PlainDate.from('2007-01-09T03:24:30Z')), `2007-01-09`);51 50 shouldBe(String(Temporal.PlainDate.from('2007-01-09T03:24:30+20:20:59')), `2007-01-09`); 52 51 shouldBe(String(Temporal.PlainDate.from('2007-01-09T03:24:30-20:20:59')), `2007-01-09`); … … 78 77 shouldBe(String(Temporal.PlainDate.from('2007-01-09 03:24:30+01:00[-01:00]')), `2007-01-09`); 79 78 shouldBe(String(Temporal.PlainDate.from('2007-01-09 03:24:30+01:00[\u221201:00]')), `2007-01-09`); 79 shouldBe(String(Temporal.PlainDate.from('2007-01-09 03:24:30+01:00[u-ca=japanese]')), `2007-01-09`); 80 shouldBe(String(Temporal.PlainDate.from('2007-01-09 03:24:30+01:00[Europe/Brussels][u-ca=japanese]')), `2007-01-09`); 81 shouldBe(String(Temporal.PlainDate.from('2007-01-09[u-ca=japanese]')), `2007-01-09`); 80 82 { 81 83 let date = Temporal.PlainDate.from('2007-01-09T03:24:30+01:00[Europe/Brussels]') … … 143 145 "2007-01-09 03:24:30+01:00[0200:00.123456789]", 144 146 "2007-01-09 03:24:30+01:00[02:00:60.123456789]", 147 "2007-01-09T03:24:30Z", // UTCDesignator 148 "2007-01-09 03:24:30[u-ca=japanese][Europe/Brussels]", 149 "2007-01-09 03:24:30+01:00[u-ca=japanese][Europe/Brussels]", 145 150 ]; 146 151 -
trunk/JSTests/stress/temporal-plaintime.js
r282125 r290248 103 103 shouldBe(String(Temporal.PlainTime.from('2020-01')), `20:20:00`); // -01 UTC offset 104 104 shouldBe(String(Temporal.PlainTime.from('01-01')), `01:00:00`); // -01 UTC offset 105 shouldBe(String(Temporal.PlainTime.from('03:24:30[u-ca=japanese]')), `03:24:30`); 106 shouldBe(String(Temporal.PlainTime.from('03:24:30+01:00[Europe/Brussels][u-ca=japanese]')), `03:24:30`); 107 shouldBe(String(Temporal.PlainTime.from('03:24:30+01:00[u-ca=japanese]')), `03:24:30`); 108 shouldBe(String(Temporal.PlainTime.from('T03:24:30+01:00[Europe/Brussels][u-ca=japanese]')), `03:24:30`); 109 shouldBe(String(Temporal.PlainTime.from('T03:24:30+01:00[u-ca=japanese]')), `03:24:30`); 105 110 shouldBe(String(Temporal.PlainTime.from('1995-12-07T03:24:30')), `03:24:30`); 106 111 shouldBe(String(Temporal.PlainTime.from('1995-12-07t03:24:30')), `03:24:30`); 107 112 shouldBe(String(Temporal.PlainTime.from('1995-12-07 03:24:30')), `03:24:30`); 108 shouldBe(String(Temporal.PlainTime.from('1995-12-07T03:24:30Z')), `03:24:30`);109 113 shouldBe(String(Temporal.PlainTime.from('1995-12-07T03:24:30+20:20:59')), `03:24:30`); 110 114 shouldBe(String(Temporal.PlainTime.from('1995-12-07T03:24:30-20:20:59')), `03:24:30`); … … 136 140 shouldBe(String(Temporal.PlainTime.from('1995-12-07 03:24:30+01:00[-01:00]')), `03:24:30`); 137 141 shouldBe(String(Temporal.PlainTime.from('1995-12-07 03:24:30+01:00[\u221201:00]')), `03:24:30`); 142 shouldBe(String(Temporal.PlainTime.from('2007-01-09 03:24:30+01:00[u-ca=japanese]')), `03:24:30`); 143 shouldBe(String(Temporal.PlainTime.from('2007-01-09 03:24:30+01:00[Europe/Brussels][u-ca=japanese]')), `03:24:30`); 144 shouldBe(String(Temporal.PlainTime.from('2007-01-09 03:24:30[u-ca=japanese]')), `03:24:30`); 138 145 { 139 146 let time = Temporal.PlainTime.from('1995-12-07T03:24:30+01:00[Europe/Brussels]') … … 250 257 "1995-12-07 03:24:30+01:00[0200:00.123456789]", 251 258 "1995-12-07 03:24:30+01:00[02:00:60.123456789]", 259 "1995-12-07T03:24:30Z", // UTCDesignator 260 "2007-01-09 03:24:30[u-ca=japanese][Europe/Brussels]", 261 "2007-01-09 03:24:30+01:00[u-ca=japanese][Europe/Brussels]", 252 262 ]; 253 263 -
trunk/Source/JavaScriptCore/ChangeLog
r290213 r290248 1 2022-02-21 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] Add CalendarDateTime parsing 4 https://bugs.webkit.org/show_bug.cgi?id=236886 5 6 Reviewed by Dean Jackson. 7 8 This patch adds calendar parsing code to ISO8601 so that Temporal.Instant / Temporal.PlainDate / Temporal.PlainTime 9 can parse string with calendar correctly via "from" methods. Currently, we are just ignoring these calendar values, 10 but we should create a calendar instance from that in a subsequent patch. 11 12 * runtime/ISO8601.cpp: 13 (JSC::ISO8601::canBeCalendar): 14 (JSC::ISO8601::canBeTimeZone): 15 (JSC::ISO8601::parseTimeZone): 16 (JSC::ISO8601::parseCalendar): 17 (JSC::ISO8601::parseTime): 18 (JSC::ISO8601::parseDateTime): 19 (JSC::ISO8601::parseCalendarTime): 20 (JSC::ISO8601::parseCalendarDateTime): 21 (JSC::ISO8601::parseInstant): 22 * runtime/ISO8601.h: 23 * runtime/TemporalPlainDate.cpp: 24 (JSC::TemporalPlainDate::from): 25 * runtime/TemporalPlainTime.cpp: 26 (JSC::TemporalPlainTime::from): 27 1 28 2022-02-19 Commit Queue <commit-queue@webkit.org> 2 29 -
trunk/Source/JavaScriptCore/runtime/ISO8601.cpp
r290209 r290248 434 434 435 435 template<typename CharacterType> 436 static bool canBeCalendar(const StringParsingBuffer<CharacterType>& buffer) 437 { 438 // https://tc39.es/proposal-temporal/#prod-Calendar 439 // Calendar : 440 // [u-ca= CalendarName] 441 return buffer.lengthRemaining() >= 6 && buffer[0] == '[' && buffer[1] == 'u' && buffer[2] == '-' && buffer[3] == 'c' && buffer[4] == 'a' && buffer[5] == '='; 442 } 443 444 template<typename CharacterType> 445 static bool canBeTimeZone(const StringParsingBuffer<CharacterType>& buffer, CharacterType character) 446 { 447 switch (static_cast<UChar>(character)) { 448 // UTCDesignator 449 // https://tc39.es/proposal-temporal/#prod-UTCDesignator 450 case 'z': 451 case 'Z': 452 // TimeZoneUTCOffsetSign 453 // https://tc39.es/proposal-temporal/#prod-TimeZoneUTCOffsetSign 454 case '+': 455 case '-': 456 case minusSign: 457 return true; 458 // TimeZoneBracketedAnnotation 459 // https://tc39.es/proposal-temporal/#prod-TimeZoneBracketedAnnotation 460 case '[': { 461 // We should reject calendar extension case. 462 // https://tc39.es/proposal-temporal/#prod-Calendar 463 // Calendar : 464 // [u-ca= CalendarName] 465 if (canBeCalendar(buffer)) 466 return false; 467 return true; 468 } 469 default: 470 return false; 471 } 472 } 473 474 template<typename CharacterType> 436 475 static std::optional<std::variant<Vector<LChar>, int64_t>> parseTimeZoneBracketedAnnotation(StringParsingBuffer<CharacterType>& buffer) 437 476 { … … 586 625 587 626 template<typename CharacterType> 588 static bool canBeTimeZone(const StringParsingBuffer<CharacterType>& buffer, CharacterType character)589 {590 switch (static_cast<UChar>(character)) {591 // UTCDesignator592 // https://tc39.es/proposal-temporal/#prod-UTCDesignator593 case 'z':594 case 'Z':595 // TimeZoneUTCOffsetSign596 // https://tc39.es/proposal-temporal/#prod-TimeZoneUTCOffsetSign597 case '+':598 case '-':599 case minusSign:600 // TimeZoneBracketedAnnotation601 // https://tc39.es/proposal-temporal/#prod-TimeZoneBracketedAnnotation602 case '[': {603 // We should reject calendar extension case.604 // https://tc39.es/proposal-temporal/#prod-Calendar605 // Calendar :606 // [u-ca= CalendarName]607 if (buffer.lengthRemaining() >= 6 && buffer[1] == 'u' && buffer[2] == '-' && buffer[3] == 'c' && buffer[4] == 'a' && buffer[5] == '=')608 return false;609 return true;610 }611 default:612 return false;613 }614 }615 616 template<typename CharacterType>617 627 static std::optional<TimeZoneRecord> parseTimeZone(StringParsingBuffer<CharacterType>& buffer) 618 628 { … … 625 635 case 'Z': { 626 636 buffer.advance(); 627 if (!buffer.atEnd() && *buffer == '[' ) {637 if (!buffer.atEnd() && *buffer == '[' && canBeTimeZone(buffer, *buffer)) { 628 638 auto timeZone = parseTimeZoneBracketedAnnotation(buffer); 629 639 if (!timeZone) … … 641 651 if (!offset) 642 652 return std::nullopt; 643 if (!buffer.atEnd() && *buffer == '[' ) {653 if (!buffer.atEnd() && *buffer == '[' && canBeTimeZone(buffer, *buffer)) { 644 654 auto timeZone = parseTimeZoneBracketedAnnotation(buffer); 645 655 if (!timeZone) … … 663 673 664 674 template<typename CharacterType> 675 static std::optional<CalendarRecord> parseCalendar(StringParsingBuffer<CharacterType>& buffer) 676 { 677 // https://tc39.es/proposal-temporal/#prod-TimeZoneBracketedAnnotation 678 // Calendar : 679 // [u-ca= CalendarName ] 680 // 681 // CalendarName : 682 // CalendarNameComponent 683 // CalendarNameComponent - CalendarName 684 // 685 // CalendarNameComponent : 686 // CalChar CalChar CalChar CalChar[opt] CalChar[opt] CalChar[opt] CalChar[opt] CalChar[opt] 687 // 688 // CalChar : 689 // Alpha 690 // Digit 691 692 if (!canBeCalendar(buffer)) 693 return std::nullopt; 694 buffer.advanceBy(6); 695 696 if (buffer.atEnd()) 697 return std::nullopt; 698 699 unsigned nameLength = 0; 700 { 701 unsigned index = 0; 702 for (; index < buffer.lengthRemaining(); ++index) { 703 auto character = buffer[index]; 704 if (character == ']') 705 break; 706 if (!isASCIIAlpha(character) && !isASCIIDigit(character) && character != '-') 707 return std::nullopt; 708 } 709 if (!index) 710 return std::nullopt; 711 nameLength = index; 712 } 713 714 auto isValidComponent = [&](unsigned start, unsigned end) { 715 unsigned componentLength = end - start; 716 if (componentLength < minCalendarLength) 717 return false; 718 if (componentLength > maxCalendarLength) 719 return false; 720 return true; 721 }; 722 723 unsigned currentNameComponentStartIndex = 0; 724 bool isLeadingCharacterInNameComponent = true; 725 for (unsigned index = 0; index < nameLength; ++index) { 726 auto character = buffer[index]; 727 if (isLeadingCharacterInNameComponent) { 728 if (!(isASCIIAlpha(character) || isASCIIDigit(character))) 729 return std::nullopt; 730 731 currentNameComponentStartIndex = index; 732 isLeadingCharacterInNameComponent = false; 733 continue; 734 } 735 736 if (character == '-') { 737 if (!isValidComponent(currentNameComponentStartIndex, index)) 738 return std::nullopt; 739 isLeadingCharacterInNameComponent = true; 740 continue; 741 } 742 743 if (!(isASCIIAlpha(character) || isASCIIDigit(character))) 744 return std::nullopt; 745 } 746 if (isLeadingCharacterInNameComponent) 747 return std::nullopt; 748 if (!isValidComponent(currentNameComponentStartIndex, nameLength)) 749 return std::nullopt; 750 751 Vector<LChar, maxCalendarLength> result; 752 result.reserveInitialCapacity(nameLength); 753 for (unsigned index = 0; index < nameLength; ++index) 754 result.uncheckedAppend(buffer[index]); 755 buffer.advanceBy(nameLength); 756 757 if (buffer.atEnd()) 758 return std::nullopt; 759 if (*buffer != ']') 760 return std::nullopt; 761 buffer.advance(); 762 return CalendarRecord { WTFMove(result) }; 763 } 764 765 template<typename CharacterType> 665 766 static std::optional<std::tuple<PlainTime, std::optional<TimeZoneRecord>>> parseTime(StringParsingBuffer<CharacterType>& buffer) 666 767 { … … 672 773 return std::nullopt; 673 774 if (buffer.atEnd()) 674 return std::tuple { plainTime.value(), std::nullopt };775 return std::tuple { WTFMove(plainTime.value()), std::nullopt }; 675 776 if (canBeTimeZone(buffer, *buffer)) { 676 777 auto timeZone = parseTimeZone(buffer); 677 778 if (!timeZone) 678 779 return std::nullopt; 679 return std::tuple { plainTime.value(), timeZone};680 } 681 return std::tuple { plainTime.value(), std::nullopt };780 return std::tuple { WTFMove(plainTime.value()), WTFMove(timeZone) }; 781 } 782 return std::tuple { WTFMove(plainTime.value()), std::nullopt }; 682 783 } 683 784 … … 840 941 return std::nullopt; 841 942 if (buffer.atEnd()) 842 return std::tuple { plainDate.value(), std::nullopt, std::nullopt };943 return std::tuple { WTFMove(plainDate.value()), std::nullopt, std::nullopt }; 843 944 844 945 if (*buffer == ' ' || *buffer == 'T' || *buffer == 't') { … … 847 948 if (!plainTimeAndTimeZone) 848 949 return std::nullopt; 849 auto [plainTime, timeZone] = plainTimeAndTimeZone.value();850 return std::tuple { plainDate.value(), plainTime, timeZone};950 auto [plainTime, timeZone] = WTFMove(plainTimeAndTimeZone.value()); 951 return std::tuple { WTFMove(plainDate.value()), WTFMove(plainTime), WTFMove(timeZone) }; 851 952 } 852 953 … … 855 956 if (!timeZone) 856 957 return std::nullopt; 857 return std::tuple { plainDate.value(), std::nullopt, timeZone }; 858 } 859 860 return std::tuple { plainDate.value(), std::nullopt, std::nullopt }; 958 return std::tuple { WTFMove(plainDate.value()), std::nullopt, WTFMove(timeZone) }; 959 } 960 961 return std::tuple { WTFMove(plainDate.value()), std::nullopt, std::nullopt }; 962 } 963 964 template<typename CharacterType> 965 static std::optional<std::tuple<PlainTime, std::optional<TimeZoneRecord>, std::optional<CalendarRecord>>> parseCalendarTime(StringParsingBuffer<CharacterType>& buffer) 966 { 967 // https://tc39.es/proposal-temporal/#prod-CalendarTime 968 // CalendarTime : 969 // TimeDesignator TimeSpec TimeZone[opt] Calendar[opt] 970 // TimeSpec TimeZone[opt] Calendar 971 // TimeSpecWithOptionalTimeZoneNotAmbiguous 972 973 if (buffer.atEnd()) 974 return std::nullopt; 975 976 if (*buffer == 'T' || *buffer == 't') 977 buffer.advance(); 978 979 auto plainTime = parseTimeSpec(buffer, Second60Mode::Accept); 980 if (!plainTime) 981 return std::nullopt; 982 if (buffer.atEnd()) 983 return std::tuple { WTFMove(plainTime.value()), std::nullopt, std::nullopt }; 984 985 std::optional<TimeZoneRecord> timeZoneOptional; 986 if (canBeTimeZone(buffer, *buffer)) { 987 auto timeZone = parseTimeZone(buffer); 988 if (!timeZone) 989 return std::nullopt; 990 timeZoneOptional = WTFMove(timeZone); 991 } 992 993 if (buffer.atEnd()) 994 return std::tuple { WTFMove(plainTime.value()), WTFMove(timeZoneOptional), std::nullopt }; 995 996 std::optional<CalendarRecord> calendarOptional; 997 if (canBeCalendar(buffer)) { 998 auto calendar = parseCalendar(buffer); 999 if (!calendar) 1000 return std::nullopt; 1001 calendarOptional = WTFMove(calendar); 1002 } 1003 1004 return std::tuple { WTFMove(plainTime.value()), WTFMove(timeZoneOptional), WTFMove(calendarOptional) }; 1005 } 1006 1007 template<typename CharacterType> 1008 static std::optional<std::tuple<PlainDate, std::optional<PlainTime>, std::optional<TimeZoneRecord>, std::optional<CalendarRecord>>> parseCalendarDateTime(StringParsingBuffer<CharacterType>& buffer) 1009 { 1010 // https://tc39.es/proposal-temporal/#prod-DateTime 1011 // CalendarDateTime : 1012 // DateTime CalendarName[opt] 1013 // 1014 auto dateTime = parseDateTime(buffer); 1015 if (!dateTime) 1016 return std::nullopt; 1017 1018 auto [plainDate, plainTimeOptional, timeZoneOptional] = WTFMove(dateTime.value()); 1019 1020 if (!buffer.atEnd() && canBeCalendar(buffer)) { 1021 auto calendar = parseCalendar(buffer); 1022 if (!calendar) 1023 return std::nullopt; 1024 return std::tuple { WTFMove(plainDate), WTFMove(plainTimeOptional), WTFMove(timeZoneOptional), WTFMove(calendar) }; 1025 } 1026 1027 return std::tuple { WTFMove(plainDate), WTFMove(plainTimeOptional), WTFMove(timeZoneOptional), std::nullopt }; 861 1028 } 862 1029 … … 871 1038 } 872 1039 1040 std::optional<std::tuple<PlainTime, std::optional<TimeZoneRecord>, std::optional<CalendarRecord>>> parseCalendarTime(StringView string) 1041 { 1042 return readCharactersForParsing(string, [](auto buffer) -> std::optional<std::tuple<PlainTime, std::optional<TimeZoneRecord>, std::optional<CalendarRecord>>> { 1043 auto result = parseCalendarTime(buffer); 1044 if (!buffer.atEnd()) 1045 return std::nullopt; 1046 return result; 1047 }); 1048 } 1049 873 1050 std::optional<std::tuple<PlainDate, std::optional<PlainTime>, std::optional<TimeZoneRecord>>> parseDateTime(StringView string) 874 1051 { 875 1052 return readCharactersForParsing(string, [](auto buffer) -> std::optional<std::tuple<PlainDate, std::optional<PlainTime>, std::optional<TimeZoneRecord>>> { 876 1053 auto result = parseDateTime(buffer); 1054 if (!buffer.atEnd()) 1055 return std::nullopt; 1056 return result; 1057 }); 1058 } 1059 1060 std::optional<std::tuple<PlainDate, std::optional<PlainTime>, std::optional<TimeZoneRecord>, std::optional<CalendarRecord>>> parseCalendarDateTime(StringView string) 1061 { 1062 return readCharactersForParsing(string, [](auto buffer) -> std::optional<std::tuple<PlainDate, std::optional<PlainTime>, std::optional<TimeZoneRecord>, std::optional<CalendarRecord>>> { 1063 auto result = parseCalendarDateTime(buffer); 877 1064 if (!buffer.atEnd()) 878 1065 return std::nullopt; … … 893 1080 894 1081 return readCharactersForParsing(string, [](auto buffer) -> std::optional<ExactTime> { 895 auto datetime = parse DateTime(buffer);1082 auto datetime = parseCalendarDateTime(buffer); 896 1083 if (!datetime) 897 1084 return std::nullopt; 898 auto [date, maybeTime, maybeTimeZone] = datetime.value(); 899 if (!maybeTimeZone || (!maybeTimeZone->m_z && !maybeTimeZone->m_offset)) 900 return std::nullopt; 901 // FIXME: parse calendar annotation 1085 auto [plainDate, plainTimeOptional, timeZoneOptional, calendarOptional] = WTFMove(datetime.value()); 1086 if (!timeZoneOptional || (!timeZoneOptional->m_z && !timeZoneOptional->m_offset)) 1087 return std::nullopt; 902 1088 if (!buffer.atEnd()) 903 1089 return std::nullopt; 904 1090 905 PlainTime time; 906 if (maybeTime) 907 time = maybeTime.value(); 908 909 int64_t offset = maybeTimeZone->m_z ? 0 : *maybeTimeZone->m_offset; 910 return { ExactTime::fromISOPartsAndOffset(date.year(), date.month(), date.day(), time.hour(), time.minute(), time.second(), time.millisecond(), time.microsecond(), time.nanosecond(), offset) }; 1091 PlainTime plainTime = plainTimeOptional.value_or(PlainTime()); 1092 1093 int64_t offset = timeZoneOptional->m_z ? 0 : *timeZoneOptional->m_offset; 1094 return { ExactTime::fromISOPartsAndOffset(plainDate.year(), plainDate.month(), plainDate.day(), plainTime.hour(), plainTime.minute(), plainTime.second(), plainTime.millisecond(), plainTime.microsecond(), plainTime.nanosecond(), offset) }; 911 1095 }); 912 1096 } -
trunk/Source/JavaScriptCore/runtime/ISO8601.h
r290209 r290248 248 248 WTF_MAKE_FAST_ALLOCATED(PlainDate); 249 249 public: 250 constexpr PlainDate() = default; 250 constexpr PlainDate() 251 : m_year(0) 252 , m_month(1) 253 , m_day(1) 254 { 255 } 256 251 257 constexpr PlainDate(int32_t year, unsigned month, unsigned day) 252 258 : m_year(year) … … 261 267 262 268 private: 263 int32_t m_year { 0 }; 264 uint8_t m_month { 1 }; 265 uint8_t m_day { 1 }; 266 }; 269 int32_t m_year : 21; // ECMAScript max / min date's year can be represented <= 20 bits. 270 int32_t m_month : 5; 271 int32_t m_day : 6; 272 }; 273 #if COMPILER(GCC_COMPATIBLE) 274 static_assert(sizeof(PlainDate) == sizeof(int32_t)); 275 #endif 267 276 268 277 using TimeZone = std::variant<TimeZoneID, int64_t>; … … 276 285 }; 277 286 287 static constexpr unsigned minCalendarLength = 3; 288 static constexpr unsigned maxCalendarLength = 8; 289 struct CalendarRecord { 290 Vector<LChar, maxCalendarLength> m_name; 291 }; 292 278 293 // https://tc39.es/proposal-temporal/#sup-isvalidtimezonename 279 294 std::optional<TimeZoneID> parseTimeZoneName(StringView); … … 282 297 enum class ValidateTimeZoneID { Yes, No }; 283 298 std::optional<std::tuple<PlainTime, std::optional<TimeZoneRecord>>> parseTime(StringView); 299 std::optional<std::tuple<PlainTime, std::optional<TimeZoneRecord>, std::optional<CalendarRecord>>> parseCalendarTime(StringView); 284 300 std::optional<std::tuple<PlainDate, std::optional<PlainTime>, std::optional<TimeZoneRecord>>> parseDateTime(StringView); 301 std::optional<std::tuple<PlainDate, std::optional<PlainTime>, std::optional<TimeZoneRecord>, std::optional<CalendarRecord>>> parseCalendarDateTime(StringView); 285 302 String formatTimeZoneOffsetString(int64_t); 286 303 String temporalTimeToString(PlainTime, std::tuple<Precision, unsigned> precision); -
trunk/Source/JavaScriptCore/runtime/TemporalPlainDate.cpp
r290209 r290248 152 152 RETURN_IF_EXCEPTION(scope, { }); 153 153 154 auto dateTime = ISO8601::parseDateTime(string); 154 // https://tc39.es/proposal-temporal/#sec-temporal-parsetemporaldatestring 155 // TemporalDateString : 156 // CalendarDateTime 157 auto dateTime = ISO8601::parseCalendarDateTime(string); 155 158 if (dateTime) { 156 auto [plainDate, plainTimeOptional, timeZoneOptional] = dateTime.value(); 157 return TemporalPlainDate::create(vm, globalObject->plainDateStructure(), WTFMove(plainDate)); 159 auto [plainDate, plainTimeOptional, timeZoneOptional, calendarOptional] = WTFMove(dateTime.value()); 160 if (!(timeZoneOptional && timeZoneOptional->m_z)) 161 return TemporalPlainDate::create(vm, globalObject->plainDateStructure(), WTFMove(plainDate)); 158 162 } 159 163 -
trunk/Source/JavaScriptCore/runtime/TemporalPlainTime.cpp
r285730 r290248 416 416 } 417 417 418 // https://tc39.es/proposal-temporal/#sec-temporal-parsetemporaltimestring 419 // TemporalTimeString : 420 // CalendarTime 421 // CalendarDateTimeTimeRequired 422 418 423 auto string = itemValue.toWTFString(globalObject); 419 424 RETURN_IF_EXCEPTION(scope, { }); 420 425 421 auto time = ISO8601::parse Time(string);426 auto time = ISO8601::parseCalendarTime(string); 422 427 if (time) { 423 auto [plainTime, timeZoneOptional] = time.value(); 424 return TemporalPlainTime::create(vm, globalObject->plainTimeStructure(), WTFMove(plainTime)); 425 } 426 427 auto dateTime = ISO8601::parseDateTime(string); 428 auto [plainTime, timeZoneOptional, calendarOptional] = WTFMove(time.value()); 429 if (!(timeZoneOptional && timeZoneOptional->m_z)) 430 return TemporalPlainTime::create(vm, globalObject->plainTimeStructure(), WTFMove(plainTime)); 431 } 432 433 auto dateTime = ISO8601::parseCalendarDateTime(string); 428 434 if (dateTime) { 429 auto [plainDate, plainTimeOptional, timeZoneOptional] = dateTime.value(); 430 if (plainTimeOptional) 431 return TemporalPlainTime::create(vm, globalObject->plainTimeStructure(), WTFMove(plainTimeOptional.value())); 435 auto [plainDate, plainTimeOptional, timeZoneOptional, calendarOptional] = WTFMove(dateTime.value()); 436 if (plainTimeOptional) { 437 if (!(timeZoneOptional && timeZoneOptional->m_z)) 438 return TemporalPlainTime::create(vm, globalObject->plainTimeStructure(), WTFMove(plainTimeOptional.value())); 439 } 432 440 } 433 441
Note: See TracChangeset
for help on using the changeset viewer.