Changeset 282018 in webkit


Ignore:
Timestamp:
Sep 3, 2021 1:22:49 PM (11 months ago)
Author:
ysuzuki@apple.com
Message:

[JSC] Implement Temporal.TimeZone
https://bugs.webkit.org/show_bug.cgi?id=229703

Reviewed by Ross Kirsling.

JSTests:

  • complex.yaml:
  • complex/temporal-now-timezone-check.js: Added.

(shouldBe):

  • complex/temporal-now-timezone-with-broken-tz.js: Added.

(shouldBe):

  • stress/intl-enumeration.js:
  • stress/temporal-timezone.js: Added.

(shouldBe):
(shouldThrow):
(let.text.of.failures.shouldThrow):
(reviver):

Source/JavaScriptCore:

This patch implements Temporal.TimeZone. While this patch does not implement features which requires Temporal.Instant,
we implement the core of Temporal.TimeZone, holding UTC offset or IANA TimeZone ID. This patch implements parsing TimeZoneNumericUTCOffset
to populate TimeZone from that format.

Since Temporal.TimeZone is implemented, we also support Temporal.Now.timeZone(), which returns current system TimeZone.

We also fix Intl enumeration not including "UTC". Since it is included in IANA TimeZones, we should include that.

  • CMakeLists.txt:
  • DerivedSources-input.xcfilelist:
  • DerivedSources-output.xcfilelist:
  • DerivedSources.make:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • Sources.txt:
  • runtime/ISO8601.cpp:

(JSC::ISO8601::parseDecimalInt32):
(JSC::ISO8601::handleFraction):
(JSC::ISO8601::parseTimeZoneNumericUTCOffset):
(JSC::ISO8601::formatTimeZoneOffsetString):

  • runtime/ISO8601.h:
  • runtime/IntlObject.cpp:

(JSC::isValidTimeZoneNameFromICUTimeZone):
(JSC::canonicalizeTimeZoneNameFromICUTimeZone):
(JSC::intlAvailableTimeZones):
(JSC::availableTimeZones):

  • runtime/IntlObject.h:
  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildrenImpl):

  • runtime/JSGlobalObject.h:

(JSC::JSGlobalObject::timeZoneStructure):

  • runtime/TemporalNow.cpp:

(JSC::JSC_DEFINE_HOST_FUNCTION):

  • runtime/TemporalNow.h:
  • runtime/TemporalObject.cpp:

(JSC::createTimeZoneConstructor):

  • runtime/TemporalTimeZone.cpp: Added.

(JSC::TemporalTimeZone::createFromID):
(JSC::TemporalTimeZone::createFromUTCOffset):
(JSC::TemporalTimeZone::createStructure):
(JSC::TemporalTimeZone::TemporalTimeZone):
(JSC::TemporalTimeZone::idForTimeZoneName):
(JSC::parseTemporalTimeZoneString):
(JSC::TemporalTimeZone::from):

  • runtime/TemporalTimeZone.h: Copied from Source/JavaScriptCore/runtime/ISO8601.h.
  • runtime/TemporalTimeZoneConstructor.cpp: Added.

(JSC::TemporalTimeZoneConstructor::create):
(JSC::TemporalTimeZoneConstructor::createStructure):
(JSC::TemporalTimeZoneConstructor::TemporalTimeZoneConstructor):
(JSC::TemporalTimeZoneConstructor::finishCreation):
(JSC::JSC_DEFINE_HOST_FUNCTION):

  • runtime/TemporalTimeZoneConstructor.h: Copied from Source/JavaScriptCore/runtime/ISO8601.h.
  • runtime/TemporalTimeZonePrototype.cpp: Added.

(JSC::TemporalTimeZonePrototype::create):
(JSC::TemporalTimeZonePrototype::createStructure):
(JSC::TemporalTimeZonePrototype::TemporalTimeZonePrototype):
(JSC::TemporalTimeZonePrototype::finishCreation):
(JSC::JSC_DEFINE_CUSTOM_GETTER):
(JSC::JSC_DEFINE_HOST_FUNCTION):

  • runtime/TemporalTimeZonePrototype.h: Copied from Source/JavaScriptCore/runtime/ISO8601.h.
  • runtime/VM.cpp:
  • runtime/VM.h:

Source/WTF:

  • wtf/text/IntegerToStringConversion.h: Support integer serialization into Vector.
  • wtf/text/StringConcatenate.h: Extends StringConcatenate feature for Vector with UChar/LChar + N size.
Location:
trunk
Files:
6 added
24 edited
3 copied

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r282014 r282018  
     12021-09-03  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] Implement Temporal.TimeZone
     4        https://bugs.webkit.org/show_bug.cgi?id=229703
     5
     6        Reviewed by Ross Kirsling.
     7
     8        * complex.yaml:
     9        * complex/temporal-now-timezone-check.js: Added.
     10        (shouldBe):
     11        * complex/temporal-now-timezone-with-broken-tz.js: Added.
     12        (shouldBe):
     13        * stress/intl-enumeration.js:
     14        * stress/temporal-timezone.js: Added.
     15        (shouldBe):
     16        (shouldThrow):
     17        (let.text.of.failures.shouldThrow):
     18        (reviver):
     19
    1202021-09-02  Yusuke Suzuki  <ysuzuki@apple.com>
    221
  • trunk/JSTests/complex.yaml

    r279962 r282018  
    4747- path: complex/intl-timezone-check.js
    4848  cmd: runComplexTest [], [], "TZ=America/Los_Angeles", "--useDollarVM=1"
     49
     50- path: complex/temporal-now-timezone-check.js
     51  cmd: runComplexTest [], [], "TZ=America/Los_Angeles", "--useDollarVM=1", "--useTemporal=1"
     52
     53- path: complex/temporal-now-timezone-with-broken-tz.js
     54  cmd: runComplexTest [], [], "TZ=UNDEFINED", "--useDollarVM=1", "--useTemporal=1"
  • trunk/JSTests/stress/intl-enumeration.js

    r281513 r282018  
    3030
    3131let timeZones = Intl.supportedValuesOf("timeZone");
    32 shouldBe(JSON.stringify(timeZones), `["Africa/Abidjan","Africa/Accra","Africa/Addis_Ababa","Africa/Algiers","Africa/Asmera","Africa/Bamako","Africa/Bangui","Africa/Banjul","Africa/Bissau","Africa/Blantyre","Africa/Brazzaville","Africa/Bujumbura","Africa/Cairo","Africa/Casablanca","Africa/Ceuta","Africa/Conakry","Africa/Dakar","Africa/Dar_es_Salaam","Africa/Djibouti","Africa/Douala","Africa/El_Aaiun","Africa/Freetown","Africa/Gaborone","Africa/Harare","Africa/Johannesburg","Africa/Juba","Africa/Kampala","Africa/Khartoum","Africa/Kigali","Africa/Kinshasa","Africa/Lagos","Africa/Libreville","Africa/Lome","Africa/Luanda","Africa/Lubumbashi","Africa/Lusaka","Africa/Malabo","Africa/Maputo","Africa/Maseru","Africa/Mbabane","Africa/Mogadishu","Africa/Monrovia","Africa/Nairobi","Africa/Ndjamena","Africa/Niamey","Africa/Nouakchott","Africa/Ouagadougou","Africa/Porto-Novo","Africa/Sao_Tome","Africa/Tripoli","Africa/Tunis","Africa/Windhoek","America/Adak","America/Anchorage","America/Anguilla","America/Antigua","America/Araguaina","America/Argentina/La_Rioja","America/Argentina/Rio_Gallegos","America/Argentina/Salta","America/Argentina/San_Juan","America/Argentina/San_Luis","America/Argentina/Tucuman","America/Argentina/Ushuaia","America/Aruba","America/Asuncion","America/Bahia","America/Bahia_Banderas","America/Barbados","America/Belem","America/Belize","America/Blanc-Sablon","America/Boa_Vista","America/Bogota","America/Boise","America/Buenos_Aires","America/Cambridge_Bay","America/Campo_Grande","America/Cancun","America/Caracas","America/Catamarca","America/Cayenne","America/Cayman","America/Chicago","America/Chihuahua","America/Coral_Harbour","America/Cordoba","America/Costa_Rica","America/Creston","America/Cuiaba","America/Curacao","America/Danmarkshavn","America/Dawson","America/Dawson_Creek","America/Denver","America/Detroit","America/Dominica","America/Edmonton","America/Eirunepe","America/El_Salvador","America/Fort_Nelson","America/Fortaleza","America/Glace_Bay","America/Godthab","America/Goose_Bay","America/Grand_Turk","America/Grenada","America/Guadeloupe","America/Guatemala","America/Guayaquil","America/Guyana","America/Halifax","America/Havana","America/Hermosillo","America/Indiana/Knox","America/Indiana/Marengo","America/Indiana/Petersburg","America/Indiana/Tell_City","America/Indiana/Vevay","America/Indiana/Vincennes","America/Indiana/Winamac","America/Indianapolis","America/Inuvik","America/Iqaluit","America/Jamaica","America/Jujuy","America/Juneau","America/Kentucky/Monticello","America/Kralendijk","America/La_Paz","America/Lima","America/Los_Angeles","America/Louisville","America/Lower_Princes","America/Maceio","America/Managua","America/Manaus","America/Marigot","America/Martinique","America/Matamoros","America/Mazatlan","America/Mendoza","America/Menominee","America/Merida","America/Metlakatla","America/Mexico_City","America/Miquelon","America/Moncton","America/Monterrey","America/Montevideo","America/Montreal","America/Montserrat","America/Nassau","America/New_York","America/Nipigon","America/Nome","America/Noronha","America/North_Dakota/Beulah","America/North_Dakota/Center","America/North_Dakota/New_Salem","America/Ojinaga","America/Panama","America/Pangnirtung","America/Paramaribo","America/Phoenix","America/Port-au-Prince","America/Port_of_Spain","America/Porto_Velho","America/Puerto_Rico","America/Punta_Arenas","America/Rainy_River","America/Rankin_Inlet","America/Recife","America/Regina","America/Resolute","America/Rio_Branco","America/Santa_Isabel","America/Santarem","America/Santiago","America/Santo_Domingo","America/Sao_Paulo","America/Scoresbysund","America/Sitka","America/St_Barthelemy","America/St_Johns","America/St_Kitts","America/St_Lucia","America/St_Thomas","America/St_Vincent","America/Swift_Current","America/Tegucigalpa","America/Thule","America/Thunder_Bay","America/Tijuana","America/Toronto","America/Tortola","America/Vancouver","America/Whitehorse","America/Winnipeg","America/Yakutat","America/Yellowknife","Antarctica/Casey","Antarctica/Davis","Antarctica/DumontDUrville","Antarctica/Macquarie","Antarctica/Mawson","Antarctica/McMurdo","Antarctica/Palmer","Antarctica/Rothera","Antarctica/Syowa","Antarctica/Troll","Antarctica/Vostok","Arctic/Longyearbyen","Asia/Aden","Asia/Almaty","Asia/Amman","Asia/Anadyr","Asia/Aqtau","Asia/Aqtobe","Asia/Ashgabat","Asia/Atyrau","Asia/Baghdad","Asia/Bahrain","Asia/Baku","Asia/Bangkok","Asia/Barnaul","Asia/Beirut","Asia/Bishkek","Asia/Brunei","Asia/Calcutta","Asia/Chita","Asia/Choibalsan","Asia/Colombo","Asia/Damascus","Asia/Dhaka","Asia/Dili","Asia/Dubai","Asia/Dushanbe","Asia/Famagusta","Asia/Gaza","Asia/Hebron","Asia/Hong_Kong","Asia/Hovd","Asia/Irkutsk","Asia/Jakarta","Asia/Jayapura","Asia/Jerusalem","Asia/Kabul","Asia/Kamchatka","Asia/Karachi","Asia/Katmandu","Asia/Khandyga","Asia/Krasnoyarsk","Asia/Kuala_Lumpur","Asia/Kuching","Asia/Kuwait","Asia/Macau","Asia/Magadan","Asia/Makassar","Asia/Manila","Asia/Muscat","Asia/Nicosia","Asia/Novokuznetsk","Asia/Novosibirsk","Asia/Omsk","Asia/Oral","Asia/Phnom_Penh","Asia/Pontianak","Asia/Pyongyang","Asia/Qatar","Asia/Qostanay","Asia/Qyzylorda","Asia/Rangoon","Asia/Riyadh","Asia/Saigon","Asia/Sakhalin","Asia/Samarkand","Asia/Seoul","Asia/Shanghai","Asia/Singapore","Asia/Srednekolymsk","Asia/Taipei","Asia/Tashkent","Asia/Tbilisi","Asia/Tehran","Asia/Thimphu","Asia/Tokyo","Asia/Tomsk","Asia/Ulaanbaatar","Asia/Urumqi","Asia/Ust-Nera","Asia/Vientiane","Asia/Vladivostok","Asia/Yakutsk","Asia/Yekaterinburg","Asia/Yerevan","Atlantic/Azores","Atlantic/Bermuda","Atlantic/Canary","Atlantic/Cape_Verde","Atlantic/Faeroe","Atlantic/Madeira","Atlantic/Reykjavik","Atlantic/South_Georgia","Atlantic/St_Helena","Atlantic/Stanley","Australia/Adelaide","Australia/Brisbane","Australia/Broken_Hill","Australia/Currie","Australia/Darwin","Australia/Eucla","Australia/Hobart","Australia/Lindeman","Australia/Lord_Howe","Australia/Melbourne","Australia/Perth","Australia/Sydney","Europe/Amsterdam","Europe/Andorra","Europe/Astrakhan","Europe/Athens","Europe/Belgrade","Europe/Berlin","Europe/Bratislava","Europe/Brussels","Europe/Bucharest","Europe/Budapest","Europe/Busingen","Europe/Chisinau","Europe/Copenhagen","Europe/Dublin","Europe/Gibraltar","Europe/Guernsey","Europe/Helsinki","Europe/Isle_of_Man","Europe/Istanbul","Europe/Jersey","Europe/Kaliningrad","Europe/Kiev","Europe/Kirov","Europe/Lisbon","Europe/Ljubljana","Europe/London","Europe/Luxembourg","Europe/Madrid","Europe/Malta","Europe/Mariehamn","Europe/Minsk","Europe/Monaco","Europe/Moscow","Europe/Oslo","Europe/Paris","Europe/Podgorica","Europe/Prague","Europe/Riga","Europe/Rome","Europe/Samara","Europe/San_Marino","Europe/Sarajevo","Europe/Saratov","Europe/Simferopol","Europe/Skopje","Europe/Sofia","Europe/Stockholm","Europe/Tallinn","Europe/Tirane","Europe/Ulyanovsk","Europe/Uzhgorod","Europe/Vaduz","Europe/Vatican","Europe/Vienna","Europe/Vilnius","Europe/Volgograd","Europe/Warsaw","Europe/Zagreb","Europe/Zaporozhye","Europe/Zurich","Indian/Antananarivo","Indian/Chagos","Indian/Christmas","Indian/Cocos","Indian/Comoro","Indian/Kerguelen","Indian/Mahe","Indian/Maldives","Indian/Mauritius","Indian/Mayotte","Indian/Reunion","Pacific/Apia","Pacific/Auckland","Pacific/Bougainville","Pacific/Chatham","Pacific/Easter","Pacific/Efate","Pacific/Enderbury","Pacific/Fakaofo","Pacific/Fiji","Pacific/Funafuti","Pacific/Galapagos","Pacific/Gambier","Pacific/Guadalcanal","Pacific/Guam","Pacific/Honolulu","Pacific/Johnston","Pacific/Kiritimati","Pacific/Kosrae","Pacific/Kwajalein","Pacific/Majuro","Pacific/Marquesas","Pacific/Midway","Pacific/Nauru","Pacific/Niue","Pacific/Norfolk","Pacific/Noumea","Pacific/Pago_Pago","Pacific/Palau","Pacific/Pitcairn","Pacific/Ponape","Pacific/Port_Moresby","Pacific/Rarotonga","Pacific/Saipan","Pacific/Tahiti","Pacific/Tarawa","Pacific/Tongatapu","Pacific/Truk","Pacific/Wake","Pacific/Wallis"]`);
     32shouldBe(JSON.stringify(timeZones), `["Africa/Abidjan","Africa/Accra","Africa/Addis_Ababa","Africa/Algiers","Africa/Asmera","Africa/Bamako","Africa/Bangui","Africa/Banjul","Africa/Bissau","Africa/Blantyre","Africa/Brazzaville","Africa/Bujumbura","Africa/Cairo","Africa/Casablanca","Africa/Ceuta","Africa/Conakry","Africa/Dakar","Africa/Dar_es_Salaam","Africa/Djibouti","Africa/Douala","Africa/El_Aaiun","Africa/Freetown","Africa/Gaborone","Africa/Harare","Africa/Johannesburg","Africa/Juba","Africa/Kampala","Africa/Khartoum","Africa/Kigali","Africa/Kinshasa","Africa/Lagos","Africa/Libreville","Africa/Lome","Africa/Luanda","Africa/Lubumbashi","Africa/Lusaka","Africa/Malabo","Africa/Maputo","Africa/Maseru","Africa/Mbabane","Africa/Mogadishu","Africa/Monrovia","Africa/Nairobi","Africa/Ndjamena","Africa/Niamey","Africa/Nouakchott","Africa/Ouagadougou","Africa/Porto-Novo","Africa/Sao_Tome","Africa/Tripoli","Africa/Tunis","Africa/Windhoek","America/Adak","America/Anchorage","America/Anguilla","America/Antigua","America/Araguaina","America/Argentina/La_Rioja","America/Argentina/Rio_Gallegos","America/Argentina/Salta","America/Argentina/San_Juan","America/Argentina/San_Luis","America/Argentina/Tucuman","America/Argentina/Ushuaia","America/Aruba","America/Asuncion","America/Bahia","America/Bahia_Banderas","America/Barbados","America/Belem","America/Belize","America/Blanc-Sablon","America/Boa_Vista","America/Bogota","America/Boise","America/Buenos_Aires","America/Cambridge_Bay","America/Campo_Grande","America/Cancun","America/Caracas","America/Catamarca","America/Cayenne","America/Cayman","America/Chicago","America/Chihuahua","America/Coral_Harbour","America/Cordoba","America/Costa_Rica","America/Creston","America/Cuiaba","America/Curacao","America/Danmarkshavn","America/Dawson","America/Dawson_Creek","America/Denver","America/Detroit","America/Dominica","America/Edmonton","America/Eirunepe","America/El_Salvador","America/Fort_Nelson","America/Fortaleza","America/Glace_Bay","America/Godthab","America/Goose_Bay","America/Grand_Turk","America/Grenada","America/Guadeloupe","America/Guatemala","America/Guayaquil","America/Guyana","America/Halifax","America/Havana","America/Hermosillo","America/Indiana/Knox","America/Indiana/Marengo","America/Indiana/Petersburg","America/Indiana/Tell_City","America/Indiana/Vevay","America/Indiana/Vincennes","America/Indiana/Winamac","America/Indianapolis","America/Inuvik","America/Iqaluit","America/Jamaica","America/Jujuy","America/Juneau","America/Kentucky/Monticello","America/Kralendijk","America/La_Paz","America/Lima","America/Los_Angeles","America/Louisville","America/Lower_Princes","America/Maceio","America/Managua","America/Manaus","America/Marigot","America/Martinique","America/Matamoros","America/Mazatlan","America/Mendoza","America/Menominee","America/Merida","America/Metlakatla","America/Mexico_City","America/Miquelon","America/Moncton","America/Monterrey","America/Montevideo","America/Montreal","America/Montserrat","America/Nassau","America/New_York","America/Nipigon","America/Nome","America/Noronha","America/North_Dakota/Beulah","America/North_Dakota/Center","America/North_Dakota/New_Salem","America/Ojinaga","America/Panama","America/Pangnirtung","America/Paramaribo","America/Phoenix","America/Port-au-Prince","America/Port_of_Spain","America/Porto_Velho","America/Puerto_Rico","America/Punta_Arenas","America/Rainy_River","America/Rankin_Inlet","America/Recife","America/Regina","America/Resolute","America/Rio_Branco","America/Santa_Isabel","America/Santarem","America/Santiago","America/Santo_Domingo","America/Sao_Paulo","America/Scoresbysund","America/Sitka","America/St_Barthelemy","America/St_Johns","America/St_Kitts","America/St_Lucia","America/St_Thomas","America/St_Vincent","America/Swift_Current","America/Tegucigalpa","America/Thule","America/Thunder_Bay","America/Tijuana","America/Toronto","America/Tortola","America/Vancouver","America/Whitehorse","America/Winnipeg","America/Yakutat","America/Yellowknife","Antarctica/Casey","Antarctica/Davis","Antarctica/DumontDUrville","Antarctica/Macquarie","Antarctica/Mawson","Antarctica/McMurdo","Antarctica/Palmer","Antarctica/Rothera","Antarctica/Syowa","Antarctica/Troll","Antarctica/Vostok","Arctic/Longyearbyen","Asia/Aden","Asia/Almaty","Asia/Amman","Asia/Anadyr","Asia/Aqtau","Asia/Aqtobe","Asia/Ashgabat","Asia/Atyrau","Asia/Baghdad","Asia/Bahrain","Asia/Baku","Asia/Bangkok","Asia/Barnaul","Asia/Beirut","Asia/Bishkek","Asia/Brunei","Asia/Calcutta","Asia/Chita","Asia/Choibalsan","Asia/Colombo","Asia/Damascus","Asia/Dhaka","Asia/Dili","Asia/Dubai","Asia/Dushanbe","Asia/Famagusta","Asia/Gaza","Asia/Hebron","Asia/Hong_Kong","Asia/Hovd","Asia/Irkutsk","Asia/Jakarta","Asia/Jayapura","Asia/Jerusalem","Asia/Kabul","Asia/Kamchatka","Asia/Karachi","Asia/Katmandu","Asia/Khandyga","Asia/Krasnoyarsk","Asia/Kuala_Lumpur","Asia/Kuching","Asia/Kuwait","Asia/Macau","Asia/Magadan","Asia/Makassar","Asia/Manila","Asia/Muscat","Asia/Nicosia","Asia/Novokuznetsk","Asia/Novosibirsk","Asia/Omsk","Asia/Oral","Asia/Phnom_Penh","Asia/Pontianak","Asia/Pyongyang","Asia/Qatar","Asia/Qostanay","Asia/Qyzylorda","Asia/Rangoon","Asia/Riyadh","Asia/Saigon","Asia/Sakhalin","Asia/Samarkand","Asia/Seoul","Asia/Shanghai","Asia/Singapore","Asia/Srednekolymsk","Asia/Taipei","Asia/Tashkent","Asia/Tbilisi","Asia/Tehran","Asia/Thimphu","Asia/Tokyo","Asia/Tomsk","Asia/Ulaanbaatar","Asia/Urumqi","Asia/Ust-Nera","Asia/Vientiane","Asia/Vladivostok","Asia/Yakutsk","Asia/Yekaterinburg","Asia/Yerevan","Atlantic/Azores","Atlantic/Bermuda","Atlantic/Canary","Atlantic/Cape_Verde","Atlantic/Faeroe","Atlantic/Madeira","Atlantic/Reykjavik","Atlantic/South_Georgia","Atlantic/St_Helena","Atlantic/Stanley","Australia/Adelaide","Australia/Brisbane","Australia/Broken_Hill","Australia/Currie","Australia/Darwin","Australia/Eucla","Australia/Hobart","Australia/Lindeman","Australia/Lord_Howe","Australia/Melbourne","Australia/Perth","Australia/Sydney","Europe/Amsterdam","Europe/Andorra","Europe/Astrakhan","Europe/Athens","Europe/Belgrade","Europe/Berlin","Europe/Bratislava","Europe/Brussels","Europe/Bucharest","Europe/Budapest","Europe/Busingen","Europe/Chisinau","Europe/Copenhagen","Europe/Dublin","Europe/Gibraltar","Europe/Guernsey","Europe/Helsinki","Europe/Isle_of_Man","Europe/Istanbul","Europe/Jersey","Europe/Kaliningrad","Europe/Kiev","Europe/Kirov","Europe/Lisbon","Europe/Ljubljana","Europe/London","Europe/Luxembourg","Europe/Madrid","Europe/Malta","Europe/Mariehamn","Europe/Minsk","Europe/Monaco","Europe/Moscow","Europe/Oslo","Europe/Paris","Europe/Podgorica","Europe/Prague","Europe/Riga","Europe/Rome","Europe/Samara","Europe/San_Marino","Europe/Sarajevo","Europe/Saratov","Europe/Simferopol","Europe/Skopje","Europe/Sofia","Europe/Stockholm","Europe/Tallinn","Europe/Tirane","Europe/Ulyanovsk","Europe/Uzhgorod","Europe/Vaduz","Europe/Vatican","Europe/Vienna","Europe/Vilnius","Europe/Volgograd","Europe/Warsaw","Europe/Zagreb","Europe/Zaporozhye","Europe/Zurich","Indian/Antananarivo","Indian/Chagos","Indian/Christmas","Indian/Cocos","Indian/Comoro","Indian/Kerguelen","Indian/Mahe","Indian/Maldives","Indian/Mauritius","Indian/Mayotte","Indian/Reunion","Pacific/Apia","Pacific/Auckland","Pacific/Bougainville","Pacific/Chatham","Pacific/Easter","Pacific/Efate","Pacific/Enderbury","Pacific/Fakaofo","Pacific/Fiji","Pacific/Funafuti","Pacific/Galapagos","Pacific/Gambier","Pacific/Guadalcanal","Pacific/Guam","Pacific/Honolulu","Pacific/Johnston","Pacific/Kiritimati","Pacific/Kosrae","Pacific/Kwajalein","Pacific/Majuro","Pacific/Marquesas","Pacific/Midway","Pacific/Nauru","Pacific/Niue","Pacific/Norfolk","Pacific/Noumea","Pacific/Pago_Pago","Pacific/Palau","Pacific/Pitcairn","Pacific/Ponape","Pacific/Port_Moresby","Pacific/Rarotonga","Pacific/Saipan","Pacific/Tahiti","Pacific/Tarawa","Pacific/Tongatapu","Pacific/Truk","Pacific/Wake","Pacific/Wallis","UTC"]`);
    3333
    3434let units = Intl.supportedValuesOf("unit");
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r281910 r282018  
    112112    runtime/TemporalDurationConstructor.cpp
    113113    runtime/TemporalDurationPrototype.cpp
     114    runtime/TemporalNow.cpp
    114115    runtime/TemporalObject.cpp
     116    runtime/TemporalTimeZoneConstructor.cpp
     117    runtime/TemporalTimeZonePrototype.cpp
    115118
    116119    wasm/js/JSWebAssembly.cpp
  • trunk/Source/JavaScriptCore/ChangeLog

    r282014 r282018  
     12021-09-03  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] Implement Temporal.TimeZone
     4        https://bugs.webkit.org/show_bug.cgi?id=229703
     5
     6        Reviewed by Ross Kirsling.
     7
     8        This patch implements Temporal.TimeZone. While this patch does not implement features which requires Temporal.Instant,
     9        we implement the core of Temporal.TimeZone, holding UTC offset or IANA TimeZone ID. This patch implements parsing TimeZoneNumericUTCOffset
     10        to populate TimeZone from that format.
     11
     12        Since Temporal.TimeZone is implemented, we also support `Temporal.Now.timeZone()`, which returns current system TimeZone.
     13
     14        We also fix Intl enumeration not including "UTC". Since it is included in IANA TimeZones, we should include that.
     15
     16        * CMakeLists.txt:
     17        * DerivedSources-input.xcfilelist:
     18        * DerivedSources-output.xcfilelist:
     19        * DerivedSources.make:
     20        * JavaScriptCore.xcodeproj/project.pbxproj:
     21        * Sources.txt:
     22        * runtime/ISO8601.cpp:
     23        (JSC::ISO8601::parseDecimalInt32):
     24        (JSC::ISO8601::handleFraction):
     25        (JSC::ISO8601::parseTimeZoneNumericUTCOffset):
     26        (JSC::ISO8601::formatTimeZoneOffsetString):
     27        * runtime/ISO8601.h:
     28        * runtime/IntlObject.cpp:
     29        (JSC::isValidTimeZoneNameFromICUTimeZone):
     30        (JSC::canonicalizeTimeZoneNameFromICUTimeZone):
     31        (JSC::intlAvailableTimeZones):
     32        (JSC::availableTimeZones):
     33        * runtime/IntlObject.h:
     34        * runtime/JSGlobalObject.cpp:
     35        (JSC::JSGlobalObject::init):
     36        (JSC::JSGlobalObject::visitChildrenImpl):
     37        * runtime/JSGlobalObject.h:
     38        (JSC::JSGlobalObject::timeZoneStructure):
     39        * runtime/TemporalNow.cpp:
     40        (JSC::JSC_DEFINE_HOST_FUNCTION):
     41        * runtime/TemporalNow.h:
     42        * runtime/TemporalObject.cpp:
     43        (JSC::createTimeZoneConstructor):
     44        * runtime/TemporalTimeZone.cpp: Added.
     45        (JSC::TemporalTimeZone::createFromID):
     46        (JSC::TemporalTimeZone::createFromUTCOffset):
     47        (JSC::TemporalTimeZone::createStructure):
     48        (JSC::TemporalTimeZone::TemporalTimeZone):
     49        (JSC::TemporalTimeZone::idForTimeZoneName):
     50        (JSC::parseTemporalTimeZoneString):
     51        (JSC::TemporalTimeZone::from):
     52        * runtime/TemporalTimeZone.h: Copied from Source/JavaScriptCore/runtime/ISO8601.h.
     53        * runtime/TemporalTimeZoneConstructor.cpp: Added.
     54        (JSC::TemporalTimeZoneConstructor::create):
     55        (JSC::TemporalTimeZoneConstructor::createStructure):
     56        (JSC::TemporalTimeZoneConstructor::TemporalTimeZoneConstructor):
     57        (JSC::TemporalTimeZoneConstructor::finishCreation):
     58        (JSC::JSC_DEFINE_HOST_FUNCTION):
     59        * runtime/TemporalTimeZoneConstructor.h: Copied from Source/JavaScriptCore/runtime/ISO8601.h.
     60        * runtime/TemporalTimeZonePrototype.cpp: Added.
     61        (JSC::TemporalTimeZonePrototype::create):
     62        (JSC::TemporalTimeZonePrototype::createStructure):
     63        (JSC::TemporalTimeZonePrototype::TemporalTimeZonePrototype):
     64        (JSC::TemporalTimeZonePrototype::finishCreation):
     65        (JSC::JSC_DEFINE_CUSTOM_GETTER):
     66        (JSC::JSC_DEFINE_HOST_FUNCTION):
     67        * runtime/TemporalTimeZonePrototype.h: Copied from Source/JavaScriptCore/runtime/ISO8601.h.
     68        * runtime/VM.cpp:
     69        * runtime/VM.h:
     70
    1712021-09-02  Yusuke Suzuki  <ysuzuki@apple.com>
    272
  • trunk/Source/JavaScriptCore/DerivedSources-input.xcfilelist

    r281846 r282018  
    174174$(PROJECT_DIR)/runtime/TemporalDurationConstructor.cpp
    175175$(PROJECT_DIR)/runtime/TemporalDurationPrototype.cpp
     176$(PROJECT_DIR)/runtime/TemporalNow.cpp
    176177$(PROJECT_DIR)/runtime/TemporalObject.cpp
     178$(PROJECT_DIR)/runtime/TemporalTimeZoneConstructor.cpp
     179$(PROJECT_DIR)/runtime/TemporalTimeZonePrototype.cpp
    177180$(PROJECT_DIR)/ucd/CaseFolding.txt
    178181$(PROJECT_DIR)/ucd/DerivedBinaryProperties.txt
  • trunk/Source/JavaScriptCore/DerivedSources-output.xcfilelist

    r281846 r282018  
    7171$(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore/TemporalDurationConstructor.lut.h
    7272$(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore/TemporalDurationPrototype.lut.h
     73$(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore/TemporalNow.lut.h
    7374$(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore/TemporalObject.lut.h
     75$(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore/TemporalTimeZoneConstructor.lut.h
     76$(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore/TemporalTimeZonePrototype.lut.h
    7477$(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore/UnicodePatternTables.h
    7578$(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore/WasmB3IRGeneratorInlines.h
  • trunk/Source/JavaScriptCore/DerivedSources.make

    r281838 r282018  
    196196    TemporalDurationConstructor.lut.h \
    197197    TemporalDurationPrototype.lut.h \
     198    TemporalNow.lut.h \
    198199    TemporalObject.lut.h \
     200    TemporalTimeZoneConstructor.lut.h \
     201    TemporalTimeZonePrototype.lut.h \
    199202    WebAssemblyCompileErrorConstructor.lut.h \
    200203    WebAssemblyCompileErrorPrototype.lut.h \
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r282009 r282018  
    18291829                E307178D24C7829A00DF0644 /* IntlLocaleConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = A3AFF92C245A3CFA00C9BA3B /* IntlLocaleConstructor.h */; };
    18301830                E307178E24C7829D00DF0644 /* IntlLocale.h in Headers */ = {isa = PBXBuildFile; fileRef = A3AFF92B245A3CF900C9BA3B /* IntlLocale.h */; };
     1831                E30E8A5426DE2E4800DA4915 /* TemporalTimeZonePrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = E30E8A4E26DE2E4700DA4915 /* TemporalTimeZonePrototype.h */; };
     1832                E30E8A5626DE2E4800DA4915 /* TemporalTimeZone.h in Headers */ = {isa = PBXBuildFile; fileRef = E30E8A5026DE2E4800DA4915 /* TemporalTimeZone.h */; };
     1833                E30E8A5726DE2E4800DA4915 /* TemporalTimeZoneConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = E30E8A5126DE2E4800DA4915 /* TemporalTimeZoneConstructor.h */; };
    18311834                E31179AA2288386100514B2C /* SymbolTableOrScopeDepth.h in Headers */ = {isa = PBXBuildFile; fileRef = E31179A92288385D00514B2C /* SymbolTableOrScopeDepth.h */; settings = {ATTRIBUTES = (Private, ); }; };
    18321835                E31618131EC5FE170006A218 /* DOMAnnotation.h in Headers */ = {isa = PBXBuildFile; fileRef = E31618101EC5FE080006A218 /* DOMAnnotation.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    50825085                E307178124C7824700DF0644 /* IntlSegmenter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IntlSegmenter.h; sourceTree = "<group>"; };
    50835086                E307178224C7824700DF0644 /* IntlSegmenterConstructor.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = IntlSegmenterConstructor.cpp; sourceTree = "<group>"; };
     5087                E30E8A4C26DE2E4700DA4915 /* TemporalTimeZonePrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TemporalTimeZonePrototype.cpp; sourceTree = "<group>"; };
     5088                E30E8A4D26DE2E4700DA4915 /* TemporalTimeZone.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TemporalTimeZone.cpp; sourceTree = "<group>"; };
     5089                E30E8A4E26DE2E4700DA4915 /* TemporalTimeZonePrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemporalTimeZonePrototype.h; sourceTree = "<group>"; };
     5090                E30E8A4F26DE2E4700DA4915 /* TemporalTimeZoneConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TemporalTimeZoneConstructor.cpp; sourceTree = "<group>"; };
     5091                E30E8A5026DE2E4800DA4915 /* TemporalTimeZone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemporalTimeZone.h; sourceTree = "<group>"; };
     5092                E30E8A5126DE2E4800DA4915 /* TemporalTimeZoneConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemporalTimeZoneConstructor.h; sourceTree = "<group>"; };
    50845093                E31179A92288385D00514B2C /* SymbolTableOrScopeDepth.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SymbolTableOrScopeDepth.h; sourceTree = "<group>"; };
    50855094                E31618101EC5FE080006A218 /* DOMAnnotation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMAnnotation.h; sourceTree = "<group>"; };
     
    80018010                                F6F150192693D33E004B98EF /* TemporalObject.cpp */,
    80028011                                F6F1501A2693D33E004B98EF /* TemporalObject.h */,
     8012                                E30E8A4D26DE2E4700DA4915 /* TemporalTimeZone.cpp */,
     8013                                E30E8A5026DE2E4800DA4915 /* TemporalTimeZone.h */,
     8014                                E30E8A4F26DE2E4700DA4915 /* TemporalTimeZoneConstructor.cpp */,
     8015                                E30E8A5126DE2E4800DA4915 /* TemporalTimeZoneConstructor.h */,
     8016                                E30E8A4C26DE2E4700DA4915 /* TemporalTimeZonePrototype.cpp */,
     8017                                E30E8A4E26DE2E4700DA4915 /* TemporalTimeZonePrototype.h */,
    80038018                                0FA2C17917D7CF84009D015F /* TestRunnerUtils.cpp */,
    80048019                                0FA2C17A17D7CF84009D015F /* TestRunnerUtils.h */,
     
    1070510720                                A3C7EDB626B0DB38004C34C5 /* TemporalDurationPrototype.h in Headers */,
    1070610721                                F6F150212693D450004B98EF /* TemporalObject.lut.h in Headers */,
     10722                                E30E8A5626DE2E4800DA4915 /* TemporalTimeZone.h in Headers */,
     10723                                E30E8A5726DE2E4800DA4915 /* TemporalTimeZoneConstructor.h in Headers */,
     10724                                E30E8A5426DE2E4800DA4915 /* TemporalTimeZonePrototype.h in Headers */,
    1070710725                                0F24E54F17EE274900ABB217 /* TempRegisterSet.h in Headers */,
    1070810726                                0F44A7B420BF68D90022B171 /* TerminatedCodeOrigin.h in Headers */,
  • trunk/Source/JavaScriptCore/Sources.txt

    r281838 r282018  
    10201020runtime/TemporalNow.cpp
    10211021runtime/TemporalObject.cpp
     1022runtime/TemporalTimeZone.cpp
     1023runtime/TemporalTimeZoneConstructor.cpp
     1024runtime/TemporalTimeZonePrototype.cpp
    10221025runtime/TestRunnerUtils.cpp
    10231026runtime/ThrowScope.cpp
  • trunk/Source/JavaScriptCore/runtime/ISO8601.cpp

    r281838 r282018  
    3333namespace ISO8601 {
    3434
     35static constexpr int64_t nsPerHour = 1000LL * 1000 * 1000 * 60 * 60;
     36static constexpr int64_t nsPerMinute = 1000LL * 1000 * 1000 * 60;
     37static constexpr int64_t nsPerSecond = 1000LL * 1000 * 1000;
     38static constexpr int64_t nsPerMillisecond = 1000LL * 1000;
     39static constexpr int64_t nsPerMicrosecond = 1000LL;
     40
     41template<typename CharType>
     42int32_t parseDecimalInt32(const CharType* characters, unsigned length)
     43{
     44    int32_t result = 0;
     45    for (unsigned index = 0; index < length; ++index) {
     46        ASSERT(isASCIIDigit(characters[index]));
     47        result = (result * 10) + characters[index] - '0';
     48    }
     49    return result;
     50}
     51
    3552// DurationHandleFractions ( fHours, minutes, fMinutes, seconds, fSeconds, milliseconds, fMilliseconds, microseconds, fMicroseconds, nanoseconds, fNanoseconds )
    3653// https://tc39.es/proposal-temporal/#sec-temporal-durationhandlefractions
     
    4461        for (unsigned i = 0; i < fractionString.length(); i++)
    4562            padded[i] = fractionString[i];
    46         duration.setMilliseconds(factor * parseInt({ padded.data(), 3 }, 10));
    47         duration.setMicroseconds(factor * parseInt({ &padded.data()[3], 3 }, 10));
    48         duration.setNanoseconds(factor * parseInt({ &padded.data()[6], 3 }, 10));
     63        duration.setMilliseconds(factor * parseDecimalInt32(padded.data(), 3));
     64        duration.setMicroseconds(factor * parseDecimalInt32(padded.data() + 3, 3));
     65        duration.setNanoseconds(factor * parseDecimalInt32(padded.data() + 6, 3));
    4966        return;
    5067    }
     
    227244}
    228245
     246template<typename CharacterType>
     247static std::optional<int64_t> parseTimeZoneNumericUTCOffset(StringParsingBuffer<CharacterType>& buffer)
     248{
     249    // TimeZoneNumericUTCOffset :
     250    //     TimeZoneUTCOffsetSign TimeZoneUTCOffsetHour
     251    //     TimeZoneUTCOffsetSign TimeZoneUTCOffsetHour : TimeZoneUTCOffsetMinute
     252    //     TimeZoneUTCOffsetSign TimeZoneUTCOffsetHour TimeZoneUTCOffsetMinute
     253    //     TimeZoneUTCOffsetSign TimeZoneUTCOffsetHour : TimeZoneUTCOffsetMinute : TimeZoneUTCOffsetSecond TimeZoneUTCOffsetFraction[opt]
     254    //     TimeZoneUTCOffsetSign TimeZoneUTCOffsetHour TimeZoneUTCOffsetMinute TimeZoneUTCOffsetSecond[opt]
     255    //
     256    //  Maximum and minimum values are ±23:59:59.999999999 = ±86399999999999ns, which can be represented by int64_t / double's integer part.
     257
     258    // sign and hour.
     259    if (buffer.lengthRemaining() < 3)
     260        return std::nullopt;
     261
     262    int64_t factor = 1;
     263    if (*buffer == '+')
     264        buffer.advance();
     265    else if (*buffer == '-' || *buffer == 0x2212) {
     266        factor = -1;
     267        buffer.advance();
     268    } else
     269        return std::nullopt;
     270
     271    int64_t hour = 0;
     272    ASSERT(buffer.lengthRemaining() >= 2);
     273    auto firstHourCharacter = *buffer;
     274    if (firstHourCharacter >= '0' && firstHourCharacter <= '2') {
     275        buffer.advance();
     276        auto secondHourCharacter = *buffer;
     277        if (!isASCIIDigit(secondHourCharacter))
     278            return std::nullopt;
     279        hour = (secondHourCharacter - '0') + 10 * (firstHourCharacter - '0');
     280        if (hour >= 24)
     281            return std::nullopt;
     282        buffer.advance();
     283    } else
     284        return std::nullopt;
     285
     286    if (buffer.atEnd())
     287        return (nsPerHour * hour) * factor;
     288
     289    bool splitByColon = false;
     290    if (*buffer == ':') {
     291        buffer.advance();
     292        splitByColon = true;
     293    }
     294
     295    int64_t minute = 0;
     296    if (buffer.lengthRemaining() < 2)
     297        return std::nullopt;
     298    auto firstMinuteCharacter = *buffer;
     299    if (firstMinuteCharacter >= '0' && firstMinuteCharacter <= '5') {
     300        buffer.advance();
     301        auto secondMinuteCharacter = *buffer;
     302        if (!isASCIIDigit(secondMinuteCharacter))
     303            return std::nullopt;
     304        minute = (secondMinuteCharacter - '0') + 10 * (firstMinuteCharacter - '0');
     305        ASSERT(minute < 60);
     306        buffer.advance();
     307    } else
     308        return std::nullopt;
     309
     310    if (buffer.atEnd())
     311        return (nsPerHour * hour + nsPerMinute * minute) * factor;
     312
     313    if (splitByColon) {
     314        if (*buffer == ':')
     315            buffer.advance();
     316        else
     317            return std::nullopt;
     318    }
     319
     320    int64_t second = 0;
     321    if (buffer.lengthRemaining() < 2)
     322        return std::nullopt;
     323    auto firstSecondCharacter = *buffer;
     324    if (firstSecondCharacter >= '0' && firstSecondCharacter <= '5') {
     325        buffer.advance();
     326        auto secondSecondCharacter = *buffer;
     327        if (!isASCIIDigit(secondSecondCharacter))
     328            return std::nullopt;
     329        second = (secondSecondCharacter - '0') + 10 * (firstSecondCharacter - '0');
     330        ASSERT(minute < 60);
     331        buffer.advance();
     332    } else
     333        return std::nullopt;
     334
     335    if (buffer.atEnd())
     336        return (nsPerHour * hour + nsPerMinute * minute + nsPerSecond * second) * factor;
     337
     338    if (*buffer != '.' && *buffer != ',')
     339        return std::nullopt;
     340    buffer.advance();
     341
     342    unsigned digits = 0;
     343    while (digits < buffer.lengthRemaining() && isASCIIDigit(buffer[digits]))
     344        digits++;
     345    if (!digits || digits > 9)
     346        return std::nullopt;
     347
     348    Vector<LChar, 9> padded(9, '0');
     349    for (unsigned i = 0; i < digits; ++i)
     350        padded[i] = buffer[i];
     351    buffer.advanceBy(digits);
     352    if (!buffer.atEnd())
     353        return std::nullopt;
     354
     355    int64_t millisecond = parseDecimalInt32(padded.data(), 3);
     356    int64_t microsecond = parseDecimalInt32(padded.data() + 3, 3);
     357    int64_t nanosecond = parseDecimalInt32(padded.data() + 6, 3);
     358
     359    return (nsPerHour * hour + nsPerMinute * minute + nsPerSecond * second + nsPerMillisecond * millisecond + nsPerMicrosecond * microsecond + nanosecond) * factor;
     360}
     361
     362std::optional<int64_t> parseTimeZoneNumericUTCOffset(StringView string)
     363{
     364    return readCharactersForParsing(string, [](auto buffer) -> std::optional<int64_t> {
     365        return parseTimeZoneNumericUTCOffset(buffer);
     366    });
     367}
     368
     369// https://tc39.es/proposal-temporal/#sec-temporal-formattimezoneoffsetstring
     370String formatTimeZoneOffsetString(int64_t offset)
     371{
     372    bool negative = false;
     373    if (offset < 0) {
     374        negative = true;
     375        offset = -offset; // This is OK since offset range is much narrower than [INT64_MIN, INT64_MAX] range.
     376    }
     377    int64_t nanoseconds = offset % nsPerSecond;
     378    int64_t seconds = (offset / nsPerSecond) % 60;
     379    int64_t minutes = (offset / nsPerMinute) % 60;
     380    int64_t hours = offset / nsPerHour;
     381
     382    if (nanoseconds) {
     383        // Since nsPerSecond is 1000000000, stringified nanoseconds takes at most 9 characters (999999999).
     384        auto fraction = WTF::numberToStringUnsigned<Vector<LChar, 9>>(nanoseconds);
     385        unsigned index = 0;
     386        unsigned paddingLength = 9 - fraction.size();
     387        for (; index < fraction.size(); ++index) {
     388            if (fraction[index] == '0')
     389                break;
     390        }
     391        fraction.resize(index);
     392        return makeString(negative ? '-' : '+', pad('0', 2, hours), ':', pad('0', 2, minutes), ':', pad('0', 2, seconds), '.', pad('0', paddingLength, emptyString()), fraction);
     393    }
     394    if (seconds)
     395        return makeString(negative ? '-' : '+', pad('0', 2, hours), ':', pad('0', 2, minutes), ':', pad('0', 2, seconds));
     396    return makeString(negative ? '-' : '+', pad('0', 2, hours), ':', pad('0', 2, minutes));
     397}
     398
    229399} // namespace ISO8601
    230400} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/ISO8601.h

    r281838 r282018  
    5050
    5151std::optional<Duration> parseDuration(StringView);
     52std::optional<int64_t> parseTimeZoneNumericUTCOffset(StringView);
     53String formatTimeZoneOffsetString(int64_t);
    5254
    5355} // namespace ISO8601
  • trunk/Source/JavaScriptCore/runtime/IntlObject.cpp

    r281788 r282018  
    17711771}
    17721772
    1773 // https://tc39.es/proposal-intl-enumeration/#sec-canonicalizetimezonename
    1774 static std::optional<String> canonicalizeTimeZoneNameFromICUTimeZone(const String& timeZoneName)
     1773static bool isValidTimeZoneNameFromICUTimeZone(StringView timeZoneName)
    17751774{
    17761775    // Some time zone names are included in ICU, but they are not included in the IANA Time Zone Database.
    17771776    // We need to filter them out.
    17781777    if (timeZoneName.startsWith("SystemV/"))
    1779         return std::nullopt;
     1778        return false;
    17801779    if (timeZoneName.startsWith("Etc/"))
    1781         return std::nullopt;
     1780        return isUTCEquivalent(timeZoneName);
    17821781    // IANA time zone names include '/'. Some of them are not including, but it is in backward links.
    17831782    // And ICU already resolved these backward links.
    17841783    if (!timeZoneName.contains('/'))
    1785         return std::nullopt;
    1786 
    1787     return timeZoneName;
     1784        return timeZoneName == "UTC"_s || timeZoneName == "GMT"_s;
     1785    return true;
     1786}
     1787
     1788// https://tc39.es/proposal-intl-enumeration/#sec-canonicalizetimezonename
     1789static std::optional<String> canonicalizeTimeZoneNameFromICUTimeZone(String&& timeZoneName)
     1790{
     1791    if (isUTCEquivalent(timeZoneName))
     1792        return "UTC"_s;
     1793    return std::make_optional(WTFMove(timeZoneName));
     1794}
     1795
     1796// https://tc39.es/proposal-intl-enumeration/#sec-availabletimezones
     1797const Vector<String>& intlAvailableTimeZones()
     1798{
     1799    static LazyNeverDestroyed<Vector<String>> availableTimeZones;
     1800    static std::once_flag initializeOnce;
     1801    std::call_once(initializeOnce, [&] {
     1802        Vector<String> temporary;
     1803        UErrorCode status = U_ZERO_ERROR;
     1804        auto enumeration = std::unique_ptr<UEnumeration, ICUDeleter<uenum_close>>(ucal_openTimeZoneIDEnumeration(UCAL_ZONE_TYPE_CANONICAL, nullptr, nullptr, &status));
     1805        ASSERT(U_SUCCESS(status));
     1806
     1807        int32_t count = uenum_count(enumeration.get(), &status);
     1808        ASSERT(U_SUCCESS(status));
     1809        temporary.reserveInitialCapacity(count);
     1810        for (int32_t index = 0; index < count; ++index) {
     1811            int32_t length = 0;
     1812            const char* pointer = uenum_next(enumeration.get(), &length, &status);
     1813            ASSERT(U_SUCCESS(status));
     1814            String timeZone(pointer, length);
     1815            if (isValidTimeZoneNameFromICUTimeZone(timeZone)) {
     1816                if (auto mapped = canonicalizeTimeZoneNameFromICUTimeZone(WTFMove(timeZone)))
     1817                    temporary.append(WTFMove(mapped.value()));
     1818            }
     1819        }
     1820
     1821        // The AvailableTimeZones abstract operation returns a List, ordered as if an Array of the same
     1822        // values had been sorted using %Array.prototype.sort% using undefined as comparefn
     1823        std::sort(temporary.begin(), temporary.end(),
     1824            [](const String& a, const String& b) {
     1825                return WTF::codePointCompare(a, b) < 0;
     1826            });
     1827        auto end = std::unique(temporary.begin(), temporary.end());
     1828        availableTimeZones.construct();
     1829        availableTimeZones->reserveInitialCapacity(end - temporary.begin());
     1830
     1831        auto createImmortalThreadSafeString = [&](String&& string) {
     1832            if (string.is8Bit())
     1833                return StringImpl::createStaticStringImpl(string.characters8(), string.length());
     1834            return StringImpl::createStaticStringImpl(string.characters16(), string.length());
     1835        };
     1836        for (auto iterator = temporary.begin(); iterator != end; ++iterator)
     1837            availableTimeZones->uncheckedAppend(createImmortalThreadSafeString(WTFMove(*iterator)));
     1838    });
     1839    return availableTimeZones;
    17881840}
    17891841
     
    17911843static JSArray* availableTimeZones(JSGlobalObject* globalObject)
    17921844{
    1793     VM& vm = globalObject->vm();
    1794     auto scope = DECLARE_THROW_SCOPE(vm);
    1795 
    1796     UErrorCode status = U_ZERO_ERROR;
    1797     auto enumeration = std::unique_ptr<UEnumeration, ICUDeleter<uenum_close>>(ucal_openTimeZoneIDEnumeration(UCAL_ZONE_TYPE_CANONICAL, nullptr, nullptr, &status));
    1798     if (U_FAILURE(status)) {
    1799         throwTypeError(globalObject, scope, "failed to enumerate available timezones"_s);
    1800         return { };
    1801     }
    1802 
    1803     int32_t count = uenum_count(enumeration.get(), &status);
    1804     if (U_FAILURE(status)) {
    1805         throwTypeError(globalObject, scope, "failed to enumerate available timezones"_s);
    1806         return { };
    1807     }
    1808 
    1809     Vector<String, 1> elements;
    1810     elements.reserveInitialCapacity(count);
    1811     for (int32_t index = 0; index < count; ++index) {
    1812         int32_t length = 0;
    1813         const char* pointer = uenum_next(enumeration.get(), &length, &status);
    1814         if (U_FAILURE(status)) {
    1815             throwTypeError(globalObject, scope, "failed to enumerate available timezones"_s);
    1816             return { };
    1817         }
    1818         String timeZone(pointer, length);
    1819         if (auto mapped = canonicalizeTimeZoneNameFromICUTimeZone(timeZone))
    1820             elements.append(WTFMove(mapped.value()));
    1821     }
    1822 
    1823     // 4. Sort result in order as if an Array of the same values had been sorted using %Array.prototype.sort% using undefined as comparefn.
    1824     std::sort(elements.begin(), elements.end(),
    1825         [](const String& a, const String& b) {
    1826             return WTF::codePointCompare(a, b) < 0;
    1827         });
    1828 
    1829     RELEASE_AND_RETURN(scope, createArrayFromStringVector(globalObject, WTFMove(elements)));
     1845    return createArrayFromStringVector(globalObject, intlAvailableTimeZones());
    18301846}
    18311847
  • trunk/Source/JavaScriptCore/runtime/IntlObject.h

    r281788 r282018  
    115115}
    116116
     117using TimeZoneID = unsigned;
     118const Vector<String>& intlAvailableTimeZones();
     119
    117120TriState intlBooleanOption(JSGlobalObject*, JSObject* options, PropertyName);
    118121String intlStringOption(JSGlobalObject*, JSObject* options, PropertyName, std::initializer_list<const char*> values, const char* notFound, const char* fallback);
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp

    r281838 r282018  
    207207#include "TemporalDurationPrototype.h"
    208208#include "TemporalObject.h"
     209#include "TemporalTimeZone.h"
     210#include "TemporalTimeZonePrototype.h"
    209211#include "VMTrapsInlines.h"
    210212#include "WasmCapabilities.h"
     
    12291231                TemporalDurationPrototype* durationPrototype = TemporalDurationPrototype::create(init.vm, TemporalDurationPrototype::createStructure(init.vm, globalObject, globalObject->objectPrototype()));
    12301232                init.set(TemporalDuration::createStructure(init.vm, globalObject, durationPrototype));
     1233            });
     1234
     1235        m_timeZoneStructure.initLater(
     1236            [] (const Initializer<Structure>& init) {
     1237                JSGlobalObject* globalObject = jsCast<JSGlobalObject*>(init.owner);
     1238                TemporalTimeZonePrototype* timeZonePrototype = TemporalTimeZonePrototype::create(init.vm, globalObject, TemporalTimeZonePrototype::createStructure(init.vm, globalObject, globalObject->objectPrototype()));
     1239                init.set(TemporalTimeZone::createStructure(init.vm, globalObject, timeZonePrototype));
    12311240            });
    12321241
     
    21112120    thisObject->m_calendarStructure.visit(visitor);
    21122121    thisObject->m_durationStructure.visit(visitor);
     2122    thisObject->m_timeZoneStructure.visit(visitor);
    21132123
    21142124    visitor.append(thisObject->m_nullGetterFunction);
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h

    r281838 r282018  
    327327    LazyProperty<JSGlobalObject, Structure> m_calendarStructure;
    328328    LazyProperty<JSGlobalObject, Structure> m_durationStructure;
     329    LazyProperty<JSGlobalObject, Structure> m_timeZoneStructure;
    329330
    330331    WriteBarrier<NullGetterFunction> m_nullGetterFunction;
     
    876877    Structure* calendarStructure() { return m_calendarStructure.get(this); }
    877878    Structure* durationStructure() { return m_durationStructure.get(this); }
     879    Structure* timeZoneStructure() { return m_timeZoneStructure.get(this); }
    878880
    879881    JS_EXPORT_PRIVATE void setRemoteDebuggingEnabled(bool);
  • trunk/Source/JavaScriptCore/runtime/TemporalNow.cpp

    r280506 r282018  
    2525#include "JSObjectInlines.h"
    2626#include "ObjectPrototype.h"
     27#include "TemporalTimeZone.h"
    2728
    2829namespace JSC {
     
    3031STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(TemporalNow);
    3132
    32 const ClassInfo TemporalNow::s_info = { "Temporal.Now", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(TemporalNow) };
     33static JSC_DECLARE_HOST_FUNCTION(temporalNowFuncTimeZone);
     34
     35} // namespace JSC
     36
     37#include "TemporalNow.lut.h"
     38
     39namespace JSC {
     40
     41/* Source for TemporalNow.lut.h
     42@begin temporalNowTable
     43    timeZone        temporalNowFuncTimeZone     DontEnum|Function 0
     44@end
     45*/
     46
     47const ClassInfo TemporalNow::s_info = { "Temporal.Now", &Base::s_info, &temporalNowTable, nullptr, CREATE_METHOD_TABLE(TemporalNow) };
    3348
    3449TemporalNow::TemporalNow(VM& vm, Structure* structure)
     
    5671}
    5772
     73// https://tc39.es/proposal-temporal/#sec-temporal.now.timezone
     74// https://tc39.es/proposal-temporal/#sec-temporal-systemtimezone
     75JSC_DEFINE_HOST_FUNCTION(temporalNowFuncTimeZone, (JSGlobalObject* globalObject, CallFrame*))
     76{
     77    VM& vm = globalObject->vm();
     78
     79    String timeZoneString = vm.dateCache.defaultTimeZone();
     80    std::optional<TimeZoneID> identifier = TemporalTimeZone::idForTimeZoneName(timeZoneString);
     81    if (!identifier)
     82        return JSValue::encode(TemporalTimeZone::createFromUTCOffset(vm, globalObject->timeZoneStructure(), 0));
     83    return JSValue::encode(TemporalTimeZone::createFromID(vm, globalObject->timeZoneStructure(), identifier.value()));
     84}
     85
    5886} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/TemporalNow.h

    r279630 r282018  
    2727public:
    2828    using Base = JSNonFinalObject;
     29    static constexpr unsigned StructureFlags = Base::StructureFlags | HasStaticPropertyTable;
    2930
    3031    template<typename CellType, SubspaceAccess>
  • trunk/Source/JavaScriptCore/runtime/TemporalObject.cpp

    r281986 r282018  
    3434#include "TemporalDurationPrototype.h"
    3535#include "TemporalNow.h"
     36#include "TemporalTimeZoneConstructor.h"
     37#include "TemporalTimeZonePrototype.h"
    3638
    3739namespace JSC {
     
    6062}
    6163
     64static JSValue createTimeZoneConstructor(VM& vm, JSObject* object)
     65{
     66    TemporalObject* temporalObject = jsCast<TemporalObject*>(object);
     67    JSGlobalObject* globalObject = temporalObject->globalObject(vm);
     68    return TemporalTimeZoneConstructor::create(vm, TemporalTimeZoneConstructor::createStructure(vm, globalObject, globalObject->functionPrototype()), jsCast<TemporalTimeZonePrototype*>(globalObject->timeZoneStructure()->storedPrototypeObject()));
     69}
     70
    6271} // namespace JSC
    6372
     
    6978@begin temporalObjectTable
    7079  Calendar       createCalendarConstructor       DontEnum|PropertyCallback
     80  Duration       createDurationConstructor       DontEnum|PropertyCallback
    7181  Now            createNowObject                 DontEnum|PropertyCallback
    72   Duration       createDurationConstructor       DontEnum|PropertyCallback
     82  TimeZone       createTimeZoneConstructor       DontEnum|PropertyCallback
    7383@end
    7484*/
  • trunk/Source/JavaScriptCore/runtime/TemporalTimeZone.h

    r282014 r282018  
    11/*
    2  * Copyright (C) 2021 Sony Interactive Entertainment Inc.
     2 * Copyright (C) 2021 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2626#pragma once
    2727
    28 #include "TemporalObject.h"
     28#include "IntlObject.h"
     29#include "JSObject.h"
     30#include <wtf/Variant.h>
    2931
    3032namespace JSC {
    31 namespace ISO8601 {
    3233
    33 struct Duration {
    34     using const_iterator = std::array<double, numberOfTemporalUnits>::const_iterator;
     34class TemporalTimeZone final : public JSNonFinalObject {
     35public:
     36    using Base = JSNonFinalObject;
    3537
    36 #define JSC_DEFINE_ISO8601_DURATION_FIELD(name, capitalizedName) \
    37     double name##s() const { return data[static_cast<uint8_t>(TemporalUnit::capitalizedName)]; } \
    38     void set##capitalizedName##s(double value) { data[static_cast<uint8_t>(TemporalUnit::capitalizedName)] = value; }
    39     JSC_TEMPORAL_UNITS(JSC_DEFINE_ISO8601_DURATION_FIELD);
    40 #undef JSC_DEFINE_ISO8601_DURATION_FIELD
     38    template<typename CellType, SubspaceAccess mode>
     39    static IsoSubspace* subspaceFor(VM& vm)
     40    {
     41        return vm.temporalTimeZoneSpace<mode>();
     42    }
    4143
    42     double& operator[](size_t i) { return data[i]; }
    43     const double& operator[](size_t i) const { return data[i]; }
    44     const_iterator begin() const { return data.begin(); }
    45     const_iterator end() const { return data.end(); }
    46     void clear() { data.fill(0); }
     44    static TemporalTimeZone* createFromID(VM&, Structure*, TimeZoneID);
     45    static TemporalTimeZone* createFromUTCOffset(VM&, Structure*, int64_t);
     46    static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
    4747
    48     std::array<double, numberOfTemporalUnits> data { };
     48    DECLARE_INFO;
     49
     50    using TimeZone = Variant<TimeZoneID, int64_t>;
     51    TimeZone timeZone() const { return m_timeZone; }
     52
     53    static std::optional<TimeZoneID> idForTimeZoneName(StringView);
     54
     55    static JSObject* from(JSGlobalObject*, JSValue);
     56
     57private:
     58    TemporalTimeZone(VM&, Structure*, TimeZone);
     59
     60    // TimeZoneID or UTC offset.
     61    TimeZone m_timeZone;
    4962};
    5063
    51 std::optional<Duration> parseDuration(StringView);
    52 
    53 } // namespace ISO8601
    5464} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/TemporalTimeZoneConstructor.h

    r282014 r282018  
    11/*
    2  * Copyright (C) 2021 Sony Interactive Entertainment Inc.
     2 * Copyright (C) 2021 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2626#pragma once
    2727
    28 #include "TemporalObject.h"
     28#include "InternalFunction.h"
    2929
    3030namespace JSC {
    31 namespace ISO8601 {
    3231
    33 struct Duration {
    34     using const_iterator = std::array<double, numberOfTemporalUnits>::const_iterator;
     32class TemporalTimeZonePrototype;
    3533
    36 #define JSC_DEFINE_ISO8601_DURATION_FIELD(name, capitalizedName) \
    37     double name##s() const { return data[static_cast<uint8_t>(TemporalUnit::capitalizedName)]; } \
    38     void set##capitalizedName##s(double value) { data[static_cast<uint8_t>(TemporalUnit::capitalizedName)] = value; }
    39     JSC_TEMPORAL_UNITS(JSC_DEFINE_ISO8601_DURATION_FIELD);
    40 #undef JSC_DEFINE_ISO8601_DURATION_FIELD
     34class TemporalTimeZoneConstructor final : public InternalFunction {
     35public:
     36    using Base = InternalFunction;
     37    static constexpr unsigned StructureFlags = Base::StructureFlags | HasStaticPropertyTable;
    4138
    42     double& operator[](size_t i) { return data[i]; }
    43     const double& operator[](size_t i) const { return data[i]; }
    44     const_iterator begin() const { return data.begin(); }
    45     const_iterator end() const { return data.end(); }
    46     void clear() { data.fill(0); }
     39    static TemporalTimeZoneConstructor* create(VM&, Structure*, TemporalTimeZonePrototype*);
     40    static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
    4741
    48     std::array<double, numberOfTemporalUnits> data { };
     42    DECLARE_INFO;
     43
     44private:
     45    TemporalTimeZoneConstructor(VM&, Structure*);
     46    void finishCreation(VM&, TemporalTimeZonePrototype*);
    4947};
     48STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(TemporalTimeZoneConstructor, InternalFunction);
    5049
    51 std::optional<Duration> parseDuration(StringView);
    52 
    53 } // namespace ISO8601
    5450} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/TemporalTimeZonePrototype.h

    r282014 r282018  
    11/*
    2  * Copyright (C) 2021 Sony Interactive Entertainment Inc.
     2 * Copyright (C) 2021 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2626#pragma once
    2727
    28 #include "TemporalObject.h"
     28#include "JSObject.h"
    2929
    3030namespace JSC {
    31 namespace ISO8601 {
    3231
    33 struct Duration {
    34     using const_iterator = std::array<double, numberOfTemporalUnits>::const_iterator;
     32class TemporalTimeZonePrototype final : public JSNonFinalObject {
     33public:
     34    using Base = JSNonFinalObject;
     35    static constexpr unsigned StructureFlags = Base::StructureFlags | HasStaticPropertyTable;
    3536
    36 #define JSC_DEFINE_ISO8601_DURATION_FIELD(name, capitalizedName) \
    37     double name##s() const { return data[static_cast<uint8_t>(TemporalUnit::capitalizedName)]; } \
    38     void set##capitalizedName##s(double value) { data[static_cast<uint8_t>(TemporalUnit::capitalizedName)] = value; }
    39     JSC_TEMPORAL_UNITS(JSC_DEFINE_ISO8601_DURATION_FIELD);
    40 #undef JSC_DEFINE_ISO8601_DURATION_FIELD
     37    template<typename CellType, SubspaceAccess>
     38    static IsoSubspace* subspaceFor(VM& vm)
     39    {
     40        STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(TemporalTimeZonePrototype, Base);
     41        return &vm.plainObjectSpace;
     42    }
    4143
    42     double& operator[](size_t i) { return data[i]; }
    43     const double& operator[](size_t i) const { return data[i]; }
    44     const_iterator begin() const { return data.begin(); }
    45     const_iterator end() const { return data.end(); }
    46     void clear() { data.fill(0); }
     44    static TemporalTimeZonePrototype* create(VM&, JSGlobalObject*, Structure*);
     45    static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
    4746
    48     std::array<double, numberOfTemporalUnits> data { };
     47    DECLARE_INFO;
     48
     49private:
     50    TemporalTimeZonePrototype(VM&, Structure*);
     51    void finishCreation(VM&, JSGlobalObject*);
    4952};
    5053
    51 std::optional<Duration> parseDuration(StringView);
    52 
    53 } // namespace ISO8601
    5454} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/VM.cpp

    r281838 r282018  
    165165#include "TemporalCalendar.h"
    166166#include "TemporalDuration.h"
     167#include "TemporalTimeZone.h"
    167168#include "TestRunnerUtils.h"
    168169#include "ThunkGenerators.h"
     
    15881589DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(templateObjectDescriptorSpace, destructibleCellHeapCellType.get(), JSTemplateObjectDescriptor)
    15891590DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(temporalCalendarSpace, cellHeapCellType.get(), TemporalCalendar)
     1591DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(temporalTimeZoneSpace, cellHeapCellType.get(), TemporalTimeZone)
    15901592DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(uint8ArraySpace, cellHeapCellType.get(), JSUint8Array)
    15911593DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(uint8ClampedArraySpace, cellHeapCellType.get(), JSUint8ClampedArray)
  • trunk/Source/JavaScriptCore/runtime/VM.h

    r281838 r282018  
    196196class VMEntryScope;
    197197class TemporalCalendar;
     198class TemporalTimeZone;
    198199class TopLevelGlobalObjectScope;
    199200class TypeProfiler;
     
    595596    DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(templateObjectDescriptorSpace)
    596597    DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(temporalCalendarSpace)
     598    DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(temporalTimeZoneSpace)
    597599    DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(uint8ArraySpace)
    598600    DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(uint8ClampedArraySpace)
  • trunk/Source/WTF/ChangeLog

    r282007 r282018  
     12021-09-03  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] Implement Temporal.TimeZone
     4        https://bugs.webkit.org/show_bug.cgi?id=229703
     5
     6        Reviewed by Ross Kirsling.
     7
     8        * wtf/text/IntegerToStringConversion.h: Support integer serialization into Vector.
     9        * wtf/text/StringConcatenate.h: Extends StringConcatenate feature for Vector with UChar/LChar + N size.
     10
    1112021-09-03  Chris Dumez  <cdumez@apple.com>
    212
  • trunk/Source/WTF/wtf/text/IntegerToStringConversion.h

    r277967 r282018  
    128128}
    129129
     130template<size_t N>
     131struct IntegerToStringConversionTrait<Vector<LChar, N>> {
     132    using ReturnType = Vector<LChar, N>;
     133    using AdditionalArgumentType = void;
     134    static ReturnType flush(LChar* characters, unsigned length, void*) { return { characters, length }; }
     135};
     136
    130137} // namespace WTF
    131138
  • trunk/Source/WTF/wtf/text/StringConcatenate.h

    r281735 r282018  
    151151};
    152152
    153 template<> class StringTypeAdapter<Vector<char>, void> {
    154 public:
    155     StringTypeAdapter(const Vector<char>& vector)
     153template<typename CharType, size_t N>
     154class StringTypeAdapter<Vector<CharType, N>, void> {
     155public:
     156    using CharTypeForString = std::conditional_t<sizeof(CharType) == sizeof(LChar), LChar, UChar>;
     157    static_assert(sizeof(CharTypeForString) == sizeof(CharType));
     158
     159    StringTypeAdapter(const Vector<CharType, N>& vector)
    156160        : m_vector { vector }
    157161    {
     
    159163
    160164    size_t length() const { return m_vector.size(); }
    161     bool is8Bit() const { return true; }
     165    bool is8Bit() const { return sizeof(CharType) == 1; }
    162166    template<typename CharacterType> void writeTo(CharacterType* destination) const { StringImpl::copyCharacters(destination, characters(), length()); }
    163167
    164168private:
    165     const LChar* characters() const
    166     {
    167         return reinterpret_cast<const LChar*>(m_vector.data());
    168     }
    169 
    170     const Vector<char>& m_vector;
     169    const CharTypeForString* characters() const
     170    {
     171        return reinterpret_cast<const CharTypeForString*>(m_vector.data());
     172    }
     173
     174    const Vector<CharType, N>& m_vector;
    171175};
    172176
Note: See TracChangeset for help on using the changeset viewer.