Source/JavaScriptCore/ChangeLog

 12021-08-30 Yusuke Suzuki <ysuzuki@apple.com>
 2
 3 [JSC] Implement Temporal.Calendar
 4 https://bugs.webkit.org/show_bug.cgi?id=229651
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 This patch implements Temporal.Calendar's simple part. Currently, we do not implement many part of Temporal.Calendar since
 9 we do not have Temporal Date-like structures yet, but this patch implemented core part of Temporal.Calendar: keeping calendar
 10 identifier.
 11
 12 We also defer implementing Temporal.Calendar.from's calendar ID parsing part since it requires full-fledged ISO 8601 parser,
 13 which will be implemented in a separate patch.
 14
 15 We use `unsigned` for CalendarID, and this id corresponds to the array index of intlAvailableCalendars, which returns array
 16 of String from ICU.
 17
 18 * CMakeLists.txt:
 19 * DerivedSources-input.xcfilelist:
 20 * DerivedSources-output.xcfilelist:
 21 * DerivedSources.make:
 22 * JavaScriptCore.xcodeproj/project.pbxproj:
 23 * Sources.txt:
 24 * runtime/CommonIdentifiers.h:
 25 * runtime/IntlObject.cpp:
 26 (JSC::intlAvailableCalendars):
 27 (JSC::iso8601CalendarIDSlow):
 28 (JSC::availableCalendars):
 29 (JSC::createArrayFromStringVector): Deleted.
 30 * runtime/IntlObject.h:
 31 (JSC::iso8601CalendarID):
 32 * runtime/IntlObjectInlines.h:
 33 (JSC::createArrayFromStringVector):
 34 * runtime/JSGlobalObject.cpp:
 35 (JSC::JSGlobalObject::init):
 36 (JSC::JSGlobalObject::visitChildrenImpl):
 37 * runtime/JSGlobalObject.h:
 38 (JSC::JSGlobalObject::calendarStructure):
 39 * runtime/TemporalCalendar.cpp: Added.
 40 (JSC::TemporalCalendar::create):
 41 (JSC::TemporalCalendar::createStructure):
 42 (JSC::TemporalCalendar::TemporalCalendar):
 43 (JSC::TemporalCalendar::isBuiltinCalendar):
 44 (JSC::parseTemporalCalendarString):
 45 (JSC::TemporalCalendar::from):
 46 * runtime/TemporalCalendar.h: Added.
 47 * runtime/TemporalCalendarConstructor.cpp: Added.
 48 (JSC::TemporalCalendarConstructor::create):
 49 (JSC::TemporalCalendarConstructor::createStructure):
 50 (JSC::TemporalCalendarConstructor::TemporalCalendarConstructor):
 51 (JSC::TemporalCalendarConstructor::finishCreation):
 52 (JSC::JSC_DEFINE_HOST_FUNCTION):
 53 * runtime/TemporalCalendarConstructor.h: Added.
 54 * runtime/TemporalCalendarPrototype.cpp: Added.
 55 (JSC::TemporalCalendarPrototype::create):
 56 (JSC::TemporalCalendarPrototype::createStructure):
 57 (JSC::TemporalCalendarPrototype::TemporalCalendarPrototype):
 58 (JSC::TemporalCalendarPrototype::finishCreation):
 59 (JSC::JSC_DEFINE_CUSTOM_GETTER):
 60 (JSC::JSC_DEFINE_HOST_FUNCTION):
 61 (JSC::defaultMergeFields):
 62 * runtime/TemporalCalendarPrototype.h: Added.
 63 * runtime/TemporalObject.cpp:
 64 (JSC::createCalendarConstructor):
 65 * runtime/VM.cpp:
 66 * runtime/VM.h:
 67
1682021-08-29 Keith Miller <keith_miller@apple.com>
269
370 Add openFile function to jsc.cpp that links to file backed memory

Source/WTF/ChangeLog

 12021-08-30 Yusuke Suzuki <ysuzuki@apple.com>
 2
 3 [JSC] Implement Temporal.Calendar
 4 https://bugs.webkit.org/show_bug.cgi?id=229651
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 * wtf/text/StringImpl.cpp:
 9 (WTF::StringImpl::createStaticStringImpl):
 10 * wtf/text/StringImpl.h:
 11 (WTF::StringImpl::createStaticStringImpl):
 12
1132021-08-28 Cameron McCormack <heycam@apple.com>
214
315 Miscellaneous typo fixes

Source/JavaScriptCore/CMakeLists.txt

@@set(JavaScriptCore_OBJECT_LUT_SOURCES
107107 runtime/StringPrototype.cpp
108108 runtime/SymbolConstructor.cpp
109109 runtime/SymbolPrototype.cpp
 110 runtime/TemporalCalendarConstructor.cpp
 111 runtime/TemporalCalendarPrototype.cpp
110112 runtime/TemporalObject.cpp
111113
112114 wasm/js/JSWebAssembly.cpp

Source/JavaScriptCore/DerivedSources-input.xcfilelist

@@$(PROJECT_DIR)/runtime/StringConstructor.cpp
169169$(PROJECT_DIR)/runtime/StringPrototype.cpp
170170$(PROJECT_DIR)/runtime/SymbolConstructor.cpp
171171$(PROJECT_DIR)/runtime/SymbolPrototype.cpp
 172$(PROJECT_DIR)/runtime/TemporalCalendarConstructor.cpp
 173$(PROJECT_DIR)/runtime/TemporalCalendarPrototype.cpp
172174$(PROJECT_DIR)/runtime/TemporalObject.cpp
173175$(PROJECT_DIR)/ucd/CaseFolding.txt
174176$(PROJECT_DIR)/ucd/DerivedBinaryProperties.txt

Source/JavaScriptCore/DerivedSources-output.xcfilelist

@@$(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore/StringConstructor.lut.h
6666$(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore/StringPrototype.lut.h
6767$(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore/SymbolConstructor.lut.h
6868$(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore/SymbolPrototype.lut.h
 69$(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore/TemporalCalendarConstructor.lut.h
 70$(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore/TemporalCalendarPrototype.lut.h
6971$(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore/TemporalObject.lut.h
7072$(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore/UnicodePatternTables.h
7173$(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore/WasmB3IRGeneratorInlines.h

Source/JavaScriptCore/DerivedSources.make

@@OBJECT_LUT_HEADERS = \
191191 StringPrototype.lut.h \
192192 SymbolConstructor.lut.h \
193193 SymbolPrototype.lut.h \
 194 TemporalCalendarConstructor.lut.h \
 195 TemporalCalendarPrototype.lut.h \
194196 TemporalObject.lut.h \
195197 WebAssemblyCompileErrorConstructor.lut.h \
196198 WebAssemblyCompileErrorPrototype.lut.h \

Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

18471847 E328DAEB1D38D005001A2529 /* BytecodeRewriter.h in Headers */ = {isa = PBXBuildFile; fileRef = E3D2642A1D38C042000BE174 /* BytecodeRewriter.h */; settings = {ATTRIBUTES = (Private, ); }; };
18481848 E32AB2441DCD75F400D7533A /* MacroAssemblerHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = E380A76B1DCD7195000F89E6 /* MacroAssemblerHelpers.h */; settings = {ATTRIBUTES = (Private, ); }; };
18491849 E32C3C6923E94C1E00BC97C0 /* UnlinkedCodeBlockGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = E32C3C6823E94C1E00BC97C0 /* UnlinkedCodeBlockGenerator.h */; };
 1850 E32D4DE726DAFD4300D4533A /* TemporalCalendarPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = E32D4DE126DAFD4200D4533A /* TemporalCalendarPrototype.h */; };
 1851 E32D4DE926DAFD4300D4533A /* TemporalCalendar.h in Headers */ = {isa = PBXBuildFile; fileRef = E32D4DE326DAFD4300D4533A /* TemporalCalendar.h */; };
 1852 E32D4DEA26DAFD4300D4533A /* TemporalCalendarConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = E32D4DE426DAFD4300D4533A /* TemporalCalendarConstructor.h */; };
18501853 E33095DD23210A1B00EB7856 /* JSInternalFieldObjectImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = E33095DC23210A1400EB7856 /* JSInternalFieldObjectImpl.h */; settings = {ATTRIBUTES = (Private, ); }; };
18511854 E334CBB521FD96A9000EB178 /* RegExpGlobalData.h in Headers */ = {isa = PBXBuildFile; fileRef = E334CBB321FD96A9000EB178 /* RegExpGlobalData.h */; settings = {ATTRIBUTES = (Private, ); }; };
18521855 E33637A61B63220200EE0840 /* ReflectObject.h in Headers */ = {isa = PBXBuildFile; fileRef = E33637A41B63220200EE0840 /* ReflectObject.h */; settings = {ATTRIBUTES = (Private, ); }; };

19021905 E39BF39922A2288B00BD183E /* SymbolTableInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = E39BF39822A2288B00BD183E /* SymbolTableInlines.h */; };
19031906 E39D45F51D39005600B3B377 /* InterpreterInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = E39D9D841D39000600667282 /* InterpreterInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
19041907 E39D8B2E23021E2600265852 /* WasmOperations.h in Headers */ = {isa = PBXBuildFile; fileRef = E39D8B2D23021E1E00265852 /* WasmOperations.h */; };
 1908 E39DA1DA26DB5E4C00100437 /* TemporalCalendarPrototype.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = E3C4630626DB5DE900896336 /* TemporalCalendarPrototype.lut.h */; };
 1909 E39DA1DB26DB5E5100100437 /* TemporalCalendarConstructor.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = E3C4630526DB5DE900896336 /* TemporalCalendarConstructor.lut.h */; };
19051910 E39DA4A71B7E8B7C0084F33A /* JSModuleRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = E39DA4A51B7E8B7C0084F33A /* JSModuleRecord.h */; settings = {ATTRIBUTES = (Private, ); }; };
19061911 E39EEAF322812450008474F4 /* CachedSpecialPropertyAdaptiveStructureWatchpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = E39EEAF22281244C008474F4 /* CachedSpecialPropertyAdaptiveStructureWatchpoint.h */; };
19071912 E39FEBE32339C5D900B40AB0 /* JSAsyncGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = E39FEBE22339C5D400B40AB0 /* JSAsyncGenerator.h */; };

50875092 E3282BB91FE930A300EDAF71 /* YarrErrorCode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = YarrErrorCode.cpp; path = yarr/YarrErrorCode.cpp; sourceTree = "<group>"; };
50885093 E3282BBA1FE930A400EDAF71 /* YarrErrorCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = YarrErrorCode.h; path = yarr/YarrErrorCode.h; sourceTree = "<group>"; };
50895094 E32C3C6823E94C1E00BC97C0 /* UnlinkedCodeBlockGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnlinkedCodeBlockGenerator.h; sourceTree = "<group>"; };
 5095 E32D4DE026DAFD4200D4533A /* TemporalCalendar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TemporalCalendar.cpp; sourceTree = "<group>"; };
 5096 E32D4DE126DAFD4200D4533A /* TemporalCalendarPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemporalCalendarPrototype.h; sourceTree = "<group>"; };
 5097 E32D4DE226DAFD4200D4533A /* TemporalCalendarPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TemporalCalendarPrototype.cpp; sourceTree = "<group>"; };
 5098 E32D4DE326DAFD4300D4533A /* TemporalCalendar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemporalCalendar.h; sourceTree = "<group>"; };
 5099 E32D4DE426DAFD4300D4533A /* TemporalCalendarConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemporalCalendarConstructor.h; sourceTree = "<group>"; };
 5100 E32D4DE526DAFD4300D4533A /* TemporalCalendarConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TemporalCalendarConstructor.cpp; sourceTree = "<group>"; };
50905101 E3305FB020B0F78700CEB82B /* InByVariant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InByVariant.cpp; sourceTree = "<group>"; };
50915102 E3305FB120B0F78800CEB82B /* InByVariant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InByVariant.h; sourceTree = "<group>"; };
50925103 E33095DC23210A1400EB7856 /* JSInternalFieldObjectImpl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JSInternalFieldObjectImpl.h; sourceTree = "<group>"; };

52025213 E3BFD0B91DAF807C0065DEA2 /* AccessCaseSnippetParams.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AccessCaseSnippetParams.cpp; sourceTree = "<group>"; };
52035214 E3BFD0BA1DAF807C0065DEA2 /* AccessCaseSnippetParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccessCaseSnippetParams.h; sourceTree = "<group>"; };
52045215 E3C295DC1ED2CBAA00D3016F /* ObjectPropertyChangeAdaptiveWatchpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ObjectPropertyChangeAdaptiveWatchpoint.h; sourceTree = "<group>"; };
 5216 E3C4630526DB5DE900896336 /* TemporalCalendarConstructor.lut.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TemporalCalendarConstructor.lut.h; sourceTree = "<group>"; };
 5217 E3C4630626DB5DE900896336 /* TemporalCalendarPrototype.lut.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TemporalCalendarPrototype.lut.h; sourceTree = "<group>"; };
52055218 E3C694B123026873006FBE42 /* WasmOSREntryData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WasmOSREntryData.h; sourceTree = "<group>"; };
52065219 E3C694B223026874006FBE42 /* WasmTierUpCount.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WasmTierUpCount.cpp; sourceTree = "<group>"; };
52075220 E3C73A8F25BFA73400EFE303 /* WasmStreamingPlan.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmStreamingPlan.cpp; sourceTree = "<group>"; };

70097022 996B73111BD9FA2C00331B84 /* StringConstructor.lut.h */,
70107023 996B73131BD9FA2C00331B84 /* SymbolConstructor.lut.h */,
70117024 996B73141BD9FA2C00331B84 /* SymbolPrototype.lut.h */,
 7025 E3C4630526DB5DE900896336 /* TemporalCalendarConstructor.lut.h */,
 7026 E3C4630626DB5DE900896336 /* TemporalCalendarPrototype.lut.h */,
70127027 F6F150202693D450004B98EF /* TemporalObject.lut.h */,
70137028 533B15DE1DC7F463004D500A /* WasmOps.h */,
70147029 AD2FCC0A1DB59C5900B3E736 /* WebAssemblyCompileErrorConstructor.lut.h */,

79537968 E31179A92288385D00514B2C /* SymbolTableOrScopeDepth.h */,
79547969 BDB4B5E099CD4C1BB3C1CF05 /* TemplateObjectDescriptor.cpp */,
79557970 70ECA6041AFDBEA200449739 /* TemplateObjectDescriptor.h */,
 7971 E32D4DE026DAFD4200D4533A /* TemporalCalendar.cpp */,
 7972 E32D4DE326DAFD4300D4533A /* TemporalCalendar.h */,
 7973 E32D4DE526DAFD4300D4533A /* TemporalCalendarConstructor.cpp */,
 7974 E32D4DE426DAFD4300D4533A /* TemporalCalendarConstructor.h */,
 7975 E32D4DE226DAFD4200D4533A /* TemporalCalendarPrototype.cpp */,
 7976 E32D4DE126DAFD4200D4533A /* TemporalCalendarPrototype.h */,
79567977 F6F1501B2693D33E004B98EF /* TemporalNow.cpp */,
79577978 F6F150182693D33D004B98EF /* TemporalNow.h */,
79587979 F6F150192693D33E004B98EF /* TemporalObject.cpp */,

1064910670 A784A26411D16622005776AC /* SyntaxChecker.h in Headers */,
1065010671 DC7997831CDE9FA0004D4A09 /* TagRegistersMode.h in Headers */,
1065110672 70ECA6091AFDBEA200449739 /* TemplateObjectDescriptor.h in Headers */,
 10673 E32D4DE926DAFD4300D4533A /* TemporalCalendar.h in Headers */,
 10674 E32D4DEA26DAFD4300D4533A /* TemporalCalendarConstructor.h in Headers */,
 10675 E39DA1DB26DB5E5100100437 /* TemporalCalendarConstructor.lut.h in Headers */,
 10676 E32D4DE726DAFD4300D4533A /* TemporalCalendarPrototype.h in Headers */,
 10677 E39DA1DA26DB5E4C00100437 /* TemporalCalendarPrototype.lut.h in Headers */,
1065210678 F6F150212693D450004B98EF /* TemporalObject.lut.h in Headers */,
1065310679 0F24E54F17EE274900ABB217 /* TempRegisterSet.h in Headers */,
1065410680 0F44A7B420BF68D90022B171 /* TerminatedCodeOrigin.h in Headers */,

Source/JavaScriptCore/Sources.txt

@@runtime/SymbolObject.cpp
10091009runtime/SymbolPrototype.cpp
10101010runtime/SymbolTable.cpp
10111011runtime/TemplateObjectDescriptor.cpp
 1012runtime/TemporalCalendar.cpp
 1013runtime/TemporalCalendarConstructor.cpp
 1014runtime/TemporalCalendarPrototype.cpp
10121015runtime/TemporalNow.cpp
10131016runtime/TemporalObject.cpp
10141017runtime/TestRunnerUtils.cpp

Source/JavaScriptCore/runtime/CommonIdentifiers.h

110110 macro(dotAll) \
111111 macro(enumerable) \
112112 macro(era) \
 113 macro(eraYear) \
113114 macro(errors) \
114115 macro(eval) \
115116 macro(events) \

169170 macro(minimumSignificantDigits) \
170171 macro(minute) \
171172 macro(month) \
 173 macro(monthCode) \
172174 macro(multiline) \
173175 macro(name) \
174176 macro(next) \

Source/JavaScriptCore/runtime/IntlObject.cpp

@@JSC_DEFINE_HOST_FUNCTION(intlObjectFuncGetCanonicalLocales, (JSGlobalObject* glo
15741574 return JSValue::encode(localeArray);
15751575}
15761576
1577 // https://tc39.es/proposal-intl-enumeration/#sec-availablecalendars
1578 static JSArray* availableCalendars(JSGlobalObject* globalObject)
 1577const Vector<String>& intlAvailableCalendars()
15791578{
1580  VM& vm = globalObject->vm();
1581  auto scope = DECLARE_THROW_SCOPE(vm);
 1579 static LazyNeverDestroyed<Vector<String>> availableCalendars;
 1580 static std::once_flag initializeOnce;
 1581 std::call_once(initializeOnce, [&] {
 1582 availableCalendars.construct();
 1583 ASSERT(availableCalendars->isEmpty());
15821584
1583  UErrorCode status = U_ZERO_ERROR;
1584  auto enumeration = std::unique_ptr<UEnumeration, ICUDeleter<uenum_close>>(ucal_getKeywordValuesForLocale("calendars", "und", false, &status));
1585  if (U_FAILURE(status)) {
1586  throwTypeError(globalObject, scope, "failed to enumerate available calendars"_s);
1587  return { };
1588  }
 1585 UErrorCode status = U_ZERO_ERROR;
 1586 auto enumeration = std::unique_ptr<UEnumeration, ICUDeleter<uenum_close>>(ucal_getKeywordValuesForLocale("calendars", "und", false, &status));
 1587 ASSERT(U_SUCCESS(status));
15891588
1590  int32_t count = uenum_count(enumeration.get(), &status);
1591  if (U_FAILURE(status)) {
1592  throwTypeError(globalObject, scope, "failed to enumerate available calendars"_s);
1593  return { };
1594  }
 1589 int32_t count = uenum_count(enumeration.get(), &status);
 1590 ASSERT(U_SUCCESS(status));
 1591 availableCalendars->reserveInitialCapacity(count);
15951592
1596  Vector<String, 1> elements;
1597  elements.reserveInitialCapacity(count);
1598  for (int32_t index = 0; index < count; ++index) {
1599  int32_t length = 0;
1600  const char* pointer = uenum_next(enumeration.get(), &length, &status);
1601  if (U_FAILURE(status)) {
1602  throwTypeError(globalObject, scope, "failed to enumerate available calendars"_s);
1603  return { };
 1593 auto createImmortalThreadSafeString = [&](String&& string) {
 1594 if (string.is8Bit())
 1595 return StringImpl::createStaticStringImpl(string.characters8(), string.length());
 1596 return StringImpl::createStaticStringImpl(string.characters16(), string.length());
 1597 };
 1598
 1599 for (int32_t index = 0; index < count; ++index) {
 1600 int32_t length = 0;
 1601 const char* pointer = uenum_next(enumeration.get(), &length, &status);
 1602 ASSERT(U_SUCCESS(status));
 1603 String calendar(pointer, length);
 1604 if (auto mapped = mapICUCalendarKeywordToBCP47(calendar))
 1605 availableCalendars->append(createImmortalThreadSafeString(WTFMove(mapped.value())));
 1606 else
 1607 availableCalendars->append(createImmortalThreadSafeString(WTFMove(calendar)));
16041608 }
1605  String calendar(pointer, length);
1606  if (auto mapped = mapICUCalendarKeywordToBCP47(calendar))
1607  elements.append(WTFMove(mapped.value()));
1608  else
1609  elements.append(WTFMove(calendar));
1610  }
16111609
1612  // The AvailableCalendars abstract operation returns a List, ordered as if an Array of the same
1613  // values had been sorted using %Array.prototype.sort% using undefined as comparefn
1614  std::sort(elements.begin(), elements.end(),
1615  [](const String& a, const String& b) {
1616  return WTF::codePointCompare(a, b) < 0;
1617  });
 1610 // The AvailableCalendars abstract operation returns a List, ordered as if an Array of the same
 1611 // values had been sorted using %Array.prototype.sort% using undefined as comparefn
 1612 std::sort(availableCalendars->begin(), availableCalendars->end(),
 1613 [](const String& a, const String& b) {
 1614 return WTF::codePointCompare(a, b) < 0;
 1615 });
 1616 });
 1617 return availableCalendars;
 1618}
16181619
1619  RELEASE_AND_RETURN(scope, createArrayFromStringVector(globalObject, WTFMove(elements)));
 1620CalendarID iso8601CalendarIDStorage { std::numeric_limits<CalendarID>::max() };
 1621CalendarID iso8601CalendarIDSlow()
 1622{
 1623 static std::once_flag initializeOnce;
 1624 std::call_once(initializeOnce, [&] {
 1625 const auto& calendars = intlAvailableCalendars();
 1626 for (unsigned index = 0; index < calendars.size(); ++index) {
 1627 if (calendars[index] == "iso8601"_s) {
 1628 iso8601CalendarIDStorage = index;
 1629 return;
 1630 }
 1631 }
 1632 RELEASE_ASSERT_NOT_REACHED();
 1633 });
 1634 return iso8601CalendarIDStorage;
 1635}
 1636
 1637// https://tc39.es/proposal-intl-enumeration/#sec-availablecalendars
 1638static JSArray* availableCalendars(JSGlobalObject* globalObject)
 1639{
 1640 return createArrayFromStringVector(globalObject, intlAvailableCalendars());
16201641}
16211642
16221643// https://tc39.es/proposal-intl-enumeration/#sec-availablecollations

@@JSC_DEFINE_HOST_FUNCTION(intlObjectFuncSupportedValuesOf, (JSGlobalObject* globa
18641885 return { };
18651886}
18661887
1867 JSArray* createArrayFromStringVector(JSGlobalObject* globalObject, Vector<String, 1>&& elements)
1868 {
1869  VM& vm = globalObject->vm();
1870  auto scope = DECLARE_THROW_SCOPE(vm);
1871 
1872  JSArray* result = JSArray::tryCreate(vm, globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous), elements.size());
1873  if (!result) {
1874  throwOutOfMemoryError(globalObject, scope);
1875  return nullptr;
1876  }
1877  for (unsigned index = 0; index < elements.size(); ++index) {
1878  result->putDirectIndex(globalObject, index, jsString(vm, WTFMove(elements[index])));
1879  RETURN_IF_EXCEPTION(scope, { });
1880  }
1881  return result;
1882 }
1883 
18841888} // namespace JSC

Source/JavaScriptCore/runtime/IntlObject.h

@@inline const LocaleSet& intlPluralRulesAvailableLocales() { return intlAvailable
101101inline const LocaleSet& intlRelativeTimeFormatAvailableLocales() { return intlAvailableLocales(); }
102102inline const LocaleSet& intlListFormatAvailableLocales() { return intlAvailableLocales(); }
103103
 104using CalendarID = unsigned;
 105const Vector<String>& intlAvailableCalendars();
 106
 107extern CalendarID iso8601CalendarIDStorage;
 108CalendarID iso8601CalendarIDSlow();
 109inline CalendarID iso8601CalendarID()
 110{
 111 unsigned value = iso8601CalendarIDStorage;
 112 if (value == std::numeric_limits<CalendarID>::max())
 113 return iso8601CalendarIDSlow();
 114 return value;
 115}
 116
104117TriState intlBooleanOption(JSGlobalObject*, JSObject* options, PropertyName);
105118String intlStringOption(JSGlobalObject*, JSObject* options, PropertyName, std::initializer_list<const char*> values, const char* notFound, const char* fallback);
106119unsigned intlNumberOption(JSGlobalObject*, JSObject* options, PropertyName, unsigned minimum, unsigned maximum, unsigned fallback);

@@std::optional<String> mapICUCollationKeywordToBCP47(const String&);
148161std::optional<String> mapICUCalendarKeywordToBCP47(const String&);
149162std::optional<String> mapBCP47ToICUCalendarKeyword(const String&);
150163
151 JSArray* createArrayFromStringVector(JSGlobalObject*, Vector<String, 1>&&);
152 
153164} // namespace JSC

Source/JavaScriptCore/runtime/IntlObjectInlines.h

@@inline JSObject* intlCoerceOptionsToObject(JSGlobalObject* globalObject, JSValue
225225 return options;
226226}
227227
 228template<typename Container>
 229JSArray* createArrayFromStringVector(JSGlobalObject* globalObject, const Container& elements)
 230{
 231 VM& vm = globalObject->vm();
 232 auto scope = DECLARE_THROW_SCOPE(vm);
 233
 234 JSArray* result = JSArray::tryCreate(vm, globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous), elements.size());
 235 if (!result) {
 236 throwOutOfMemoryError(globalObject, scope);
 237 return nullptr;
 238 }
 239 for (unsigned index = 0; index < elements.size(); ++index) {
 240 result->putDirectIndex(globalObject, index, jsString(vm, elements[index]));
 241 RETURN_IF_EXCEPTION(scope, { });
 242 }
 243 return result;
 244}
 245
228246} // namespace JSC

Source/JavaScriptCore/runtime/JSGlobalObject.cpp

201201#include "SymbolConstructor.h"
202202#include "SymbolObject.h"
203203#include "SymbolPrototype.h"
 204#include "TemporalCalendar.h"
 205#include "TemporalCalendarConstructor.h"
 206#include "TemporalCalendarPrototype.h"
204207#include "TemporalObject.h"
205208#include "VMTrapsInlines.h"
206209#include "WasmCapabilities.h"

@@capitalName ## Constructor* lowerName ## Constructor = featureFlag ? capitalName
12121215 putDirectWithoutTransition(vm, vm.propertyNames->Intl, intl, static_cast<unsigned>(PropertyAttribute::DontEnum));
12131216
12141217 if (Options::useTemporal()) {
 1218 m_calendarStructure.initLater(
 1219 [] (const Initializer<Structure>& init) {
 1220 JSGlobalObject* globalObject = jsCast<JSGlobalObject*>(init.owner);
 1221 TemporalCalendarPrototype* calendarPrototype = TemporalCalendarPrototype::create(init.vm, globalObject, TemporalCalendarPrototype::createStructure(init.vm, globalObject, globalObject->objectPrototype()));
 1222 init.set(TemporalCalendar::createStructure(init.vm, globalObject, calendarPrototype));
 1223 });
 1224
12151225 TemporalObject* temporal = TemporalObject::create(vm, TemporalObject::createStructure(vm, this));
12161226 putDirectWithoutTransition(vm, vm.propertyNames->Temporal, temporal, static_cast<unsigned>(PropertyAttribute::DontEnum));
12171227 }

@@void JSGlobalObject::visitChildrenImpl(JSCell* cell, Visitor& visitor)
20902100 thisObject->m_dateTimeFormatStructure.visit(visitor);
20912101 thisObject->m_numberFormatStructure.visit(visitor);
20922102
 2103 thisObject->m_calendarStructure.visit(visitor);
 2104
20932105 visitor.append(thisObject->m_nullGetterFunction);
20942106 visitor.append(thisObject->m_nullSetterFunction);
20952107 visitor.append(thisObject->m_nullSetterStrictFunction);

Source/JavaScriptCore/runtime/JSGlobalObject.h

@@class JSGlobalObject : public JSSegmentedVariableObject {
324324 LazyClassStructure m_dateTimeFormatStructure;
325325 LazyClassStructure m_numberFormatStructure;
326326
 327 LazyProperty<JSGlobalObject, Structure> m_calendarStructure;
 328
327329 WriteBarrier<NullGetterFunction> m_nullGetterFunction;
328330 WriteBarrier<NullSetterFunction> m_nullSetterFunction;
329331 WriteBarrier<NullSetterFunction> m_nullSetterStrictFunction;

@@class JSGlobalObject : public JSSegmentedVariableObject {
870872 JSObject* numberFormatConstructor() { return m_numberFormatStructure.constructor(this); }
871873 JSObject* numberFormatPrototype() { return m_numberFormatStructure.prototype(this); }
872874
 875 Structure* calendarStructure() { return m_calendarStructure.get(this); }
 876
873877 JS_EXPORT_PRIVATE void setRemoteDebuggingEnabled(bool);
874878 JS_EXPORT_PRIVATE bool remoteDebuggingEnabled() const;
875879

Source/JavaScriptCore/runtime/TemporalCalendar.cpp

 1/*
 2 * Copyright (C) 2021 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 23 * THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#include "config.h"
 27#include "TemporalCalendar.h"
 28
 29namespace JSC {
 30
 31const ClassInfo TemporalCalendar::s_info = { "Object", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(TemporalCalendar) };
 32
 33namespace TemporalCalendarInternal {
 34static constexpr bool verbose = false;
 35}
 36
 37TemporalCalendar* TemporalCalendar::create(VM& vm, Structure* structure, CalendarID identifier)
 38{
 39 TemporalCalendar* format = new (NotNull, allocateCell<TemporalCalendar>(vm.heap)) TemporalCalendar(vm, structure, identifier);
 40 format->finishCreation(vm);
 41 return format;
 42}
 43
 44Structure* TemporalCalendar::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
 45{
 46 return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
 47}
 48
 49TemporalCalendar::TemporalCalendar(VM& vm, Structure* structure, CalendarID identifier)
 50 : Base(vm, structure)
 51 , m_identifier(identifier)
 52{
 53}
 54
 55std::optional<CalendarID> TemporalCalendar::isBuiltinCalendar(StringView string)
 56{
 57 const auto& calendars = intlAvailableCalendars();
 58 for (unsigned index = 0; index < calendars.size(); ++index) {
 59 if (calendars[index] == string)
 60 return index;
 61 }
 62 return std::nullopt;
 63}
 64
 65// https://tc39.es/proposal-temporal/#sec-temporal-parsetemporalcalendarstring
 66static std::optional<CalendarID> parseTemporalCalendarString(JSGlobalObject* globalObject, StringView)
 67{
 68 // FIXME: Implement parsing temporal calendar string, which requires full ISO 8601 parser.
 69 VM& vm = globalObject->vm();
 70 auto scope = DECLARE_THROW_SCOPE(vm);
 71 throwRangeError(globalObject, scope, "invalid calendar ID"_s);
 72 return std::nullopt;
 73}
 74
 75// https://tc39.es/proposal-temporal/#sec-temporal-totemporalcalendar
 76JSObject* TemporalCalendar::from(JSGlobalObject* globalObject, JSValue calendarLike)
 77{
 78 VM& vm = globalObject->vm();
 79 auto scope = DECLARE_THROW_SCOPE(vm);
 80
 81 if (calendarLike.isObject()) {
 82 JSObject* calendarLikeObject = jsCast<JSObject*>(calendarLike);
 83
 84 // FIXME: We need to implement code retrieving Calendar from Temporal Date Like objects. But
 85 // currently they are not implemented yet.
 86
 87 bool hasProperty = calendarLikeObject->hasProperty(globalObject, vm.propertyNames->calendar);
 88 RETURN_IF_EXCEPTION(scope, { });
 89 if (!hasProperty)
 90 return jsCast<JSObject*>(calendarLike);
 91
 92 calendarLike = calendarLikeObject->get(globalObject, vm.propertyNames->calendar);
 93 if (calendarLike.isObject()) {
 94 bool hasProperty = jsCast<JSObject*>(calendarLike)->hasProperty(globalObject, vm.propertyNames->calendar);
 95 RETURN_IF_EXCEPTION(scope, { });
 96 if (!hasProperty)
 97 return jsCast<JSObject*>(calendarLike);
 98 }
 99 }
 100
 101 auto identifier = calendarLike.toWTFString(globalObject);
 102 RETURN_IF_EXCEPTION(scope, { });
 103
 104 std::optional<CalendarID> calendarId = isBuiltinCalendar(identifier);
 105 if (!calendarId) {
 106 calendarId = parseTemporalCalendarString(globalObject, identifier);
 107 RETURN_IF_EXCEPTION(scope, { });
 108 }
 109
 110 ASSERT(calendarId);
 111 return TemporalCalendar::create(vm, globalObject->calendarStructure(), calendarId.value());
 112}
 113
 114} // namespace JSC

Source/JavaScriptCore/runtime/TemporalCalendar.h

 1/*
 2 * Copyright (C) 2021 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 23 * THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#pragma once
 27
 28#include "IntlObject.h"
 29#include "JSObject.h"
 30
 31namespace JSC {
 32
 33class TemporalCalendar final : public JSNonFinalObject {
 34public:
 35 using Base = JSNonFinalObject;
 36
 37 template<typename CellType, SubspaceAccess mode>
 38 static IsoSubspace* subspaceFor(VM& vm)
 39 {
 40 return vm.temporalCalendarSpace<mode>();
 41 }
 42
 43 static TemporalCalendar* create(VM&, Structure*, CalendarID);
 44 static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
 45
 46 DECLARE_INFO;
 47
 48 CalendarID identifier() const { return m_identifier; }
 49 bool isISO8601() const { return m_identifier == iso8601CalendarID(); }
 50
 51 static std::optional<CalendarID> isBuiltinCalendar(StringView);
 52
 53 static JSObject* from(JSGlobalObject*, JSValue);
 54
 55private:
 56 TemporalCalendar(VM&, Structure*, CalendarID);
 57
 58 CalendarID m_identifier { 0 };
 59};
 60
 61} // namespace JSC

Source/JavaScriptCore/runtime/TemporalCalendarConstructor.cpp

 1/*
 2 * Copyright (C) 2021 Apple Inc. All Rights Reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 23 * THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#include "config.h"
 27#include "TemporalCalendarConstructor.h"
 28
 29#include "JSCInlines.h"
 30#include "TemporalCalendar.h"
 31#include "TemporalCalendarPrototype.h"
 32
 33namespace JSC {
 34
 35STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(TemporalCalendarConstructor);
 36static JSC_DECLARE_HOST_FUNCTION(temporalCalendarConstructorFuncFrom);
 37
 38}
 39
 40#include "TemporalCalendarConstructor.lut.h"
 41
 42namespace JSC {
 43
 44const ClassInfo TemporalCalendarConstructor::s_info = { "Function", &InternalFunction::s_info, &temporalCalendarConstructorTable, nullptr, CREATE_METHOD_TABLE(TemporalCalendarConstructor) };
 45
 46/* Source for TemporalCalendarConstructor.lut.h
 47@begin temporalCalendarConstructorTable
 48 from temporalCalendarConstructorFuncFrom DontEnum|Function 1
 49@end
 50*/
 51
 52TemporalCalendarConstructor* TemporalCalendarConstructor::create(VM& vm, Structure* structure, TemporalCalendarPrototype* temporalCalendarPrototype)
 53{
 54 TemporalCalendarConstructor* constructor = new (NotNull, allocateCell<TemporalCalendarConstructor>(vm.heap)) TemporalCalendarConstructor(vm, structure);
 55 constructor->finishCreation(vm, temporalCalendarPrototype);
 56 return constructor;
 57}
 58
 59Structure* TemporalCalendarConstructor::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
 60{
 61 return Structure::create(vm, globalObject, prototype, TypeInfo(InternalFunctionType, StructureFlags), info());
 62}
 63
 64static JSC_DECLARE_HOST_FUNCTION(callTemporalCalendar);
 65static JSC_DECLARE_HOST_FUNCTION(constructTemporalCalendar);
 66
 67TemporalCalendarConstructor::TemporalCalendarConstructor(VM& vm, Structure* structure)
 68 : InternalFunction(vm, structure, callTemporalCalendar, constructTemporalCalendar)
 69{
 70}
 71
 72void TemporalCalendarConstructor::finishCreation(VM& vm, TemporalCalendarPrototype* temporalCalendarPrototype)
 73{
 74 Base::finishCreation(vm, 0, "Calendar"_s, PropertyAdditionMode::WithoutStructureTransition);
 75 putDirectWithoutTransition(vm, vm.propertyNames->prototype, temporalCalendarPrototype, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
 76}
 77
 78JSC_DEFINE_HOST_FUNCTION(constructTemporalCalendar, (JSGlobalObject* globalObject, CallFrame* callFrame))
 79{
 80 VM& vm = globalObject->vm();
 81 auto scope = DECLARE_THROW_SCOPE(vm);
 82
 83 JSObject* newTarget = asObject(callFrame->newTarget());
 84 Structure* structure = JSC_GET_DERIVED_STRUCTURE(vm, calendarStructure, newTarget, callFrame->jsCallee());
 85 RETURN_IF_EXCEPTION(scope, { });
 86
 87 auto calendarString = callFrame->argument(0).toWTFString(globalObject);
 88 RETURN_IF_EXCEPTION(scope, { });
 89
 90 std::optional<CalendarID> identifier = TemporalCalendar::isBuiltinCalendar(calendarString);
 91 if (!identifier) {
 92 throwRangeError(globalObject, scope, "invalid calendar ID"_s);
 93 return { };
 94 }
 95
 96 return JSValue::encode(TemporalCalendar::create(vm, structure, identifier.value()));
 97}
 98
 99JSC_DEFINE_HOST_FUNCTION(callTemporalCalendar, (JSGlobalObject* globalObject, CallFrame*))
 100{
 101 VM& vm = globalObject->vm();
 102 auto scope = DECLARE_THROW_SCOPE(vm);
 103
 104 return JSValue::encode(throwConstructorCannotBeCalledAsFunctionTypeError(globalObject, scope, "Calendar"));
 105}
 106
 107JSC_DEFINE_HOST_FUNCTION(temporalCalendarConstructorFuncFrom, (JSGlobalObject* globalObject, CallFrame* callFrame))
 108{
 109 return JSValue::encode(TemporalCalendar::from(globalObject, callFrame->argument(0)));
 110}
 111
 112} // namespace JSC

Source/JavaScriptCore/runtime/TemporalCalendarConstructor.h

 1/*
 2 * Copyright (C) 2021 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 23 * THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#pragma once
 27
 28#include "InternalFunction.h"
 29
 30namespace JSC {
 31
 32class TemporalCalendarPrototype;
 33
 34class TemporalCalendarConstructor final : public InternalFunction {
 35public:
 36 using Base = InternalFunction;
 37 static constexpr unsigned StructureFlags = Base::StructureFlags | HasStaticPropertyTable;
 38
 39 static TemporalCalendarConstructor* create(VM&, Structure*, TemporalCalendarPrototype*);
 40 static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
 41
 42 DECLARE_INFO;
 43
 44private:
 45 TemporalCalendarConstructor(VM&, Structure*);
 46 void finishCreation(VM&, TemporalCalendarPrototype*);
 47};
 48STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(TemporalCalendarConstructor, InternalFunction);
 49
 50} // namespace JSC

Source/JavaScriptCore/runtime/TemporalCalendarPrototype.cpp

 1/*
 2 * Copyright (C) 2021 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 23 * THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#include "config.h"
 27#include "TemporalCalendarPrototype.h"
 28
 29#include "BuiltinNames.h"
 30#include "IteratorOperations.h"
 31#include "JSCInlines.h"
 32#include "ObjectConstructor.h"
 33
 34namespace JSC {
 35
 36static JSC_DECLARE_HOST_FUNCTION(temporalCalendarPrototypeFuncFields);
 37static JSC_DECLARE_HOST_FUNCTION(temporalCalendarPrototypeFuncMergeFields);
 38static JSC_DECLARE_HOST_FUNCTION(temporalCalendarPrototypeFuncToString);
 39static JSC_DECLARE_HOST_FUNCTION(temporalCalendarPrototypeFuncToJSON);
 40static JSC_DECLARE_CUSTOM_GETTER(temporalCalendarPrototypeGetterId);
 41
 42}
 43
 44#include "TemporalCalendarPrototype.lut.h"
 45
 46namespace JSC {
 47
 48const ClassInfo TemporalCalendarPrototype::s_info = { "Temporal.Calendar", &Base::s_info, &temporalCalendarPrototypeTable, nullptr, CREATE_METHOD_TABLE(TemporalCalendarPrototype) };
 49
 50/* Source for TemporalCalendarPrototype.lut.h
 51@begin temporalCalendarPrototypeTable
 52 fields temporalCalendarPrototypeFuncFields DontEnum|Function 1
 53 mergeFields temporalCalendarPrototypeFuncMergeFields DontEnum|Function 2
 54 toString temporalCalendarPrototypeFuncToString DontEnum|Function 0
 55 toJSON temporalCalendarPrototypeFuncToJSON DontEnum|Function 0
 56 id temporalCalendarPrototypeGetterId ReadOnly|DontEnum|CustomAccessor
 57@end
 58*/
 59
 60TemporalCalendarPrototype* TemporalCalendarPrototype::create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
 61{
 62 TemporalCalendarPrototype* object = new (NotNull, allocateCell<TemporalCalendarPrototype>(vm.heap)) TemporalCalendarPrototype(vm, structure);
 63 object->finishCreation(vm, globalObject);
 64 return object;
 65}
 66
 67Structure* TemporalCalendarPrototype::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
 68{
 69 return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
 70}
 71
 72TemporalCalendarPrototype::TemporalCalendarPrototype(VM& vm, Structure* structure)
 73 : Base(vm, structure)
 74{
 75}
 76
 77void TemporalCalendarPrototype::finishCreation(VM& vm, JSGlobalObject*)
 78{
 79 Base::finishCreation(vm);
 80 ASSERT(inherits(vm, info()));
 81 JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
 82}
 83
 84// https://tc39.es/proposal-temporal/#sec-get-temporal.calendar.prototype.id
 85JSC_DEFINE_CUSTOM_GETTER(temporalCalendarPrototypeGetterId, (JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName))
 86{
 87 return JSValue::encode(JSValue::decode(thisValue).toString(globalObject));
 88}
 89
 90// https://tc39.es/proposal-temporal/#sup-temporal.calendar.prototype.fields
 91JSC_DEFINE_HOST_FUNCTION(temporalCalendarPrototypeFuncFields, (JSGlobalObject* globalObject, CallFrame* callFrame))
 92{
 93 VM& vm = globalObject->vm();
 94 auto scope = DECLARE_THROW_SCOPE(vm);
 95
 96 auto* calendar = jsDynamicCast<TemporalCalendar*>(vm, callFrame->thisValue());
 97 if (!calendar)
 98 return throwVMTypeError(globalObject, scope, "Temporal.Calendar.prototype.fields called on value that's not an object initialized as a Calendar"_s);
 99
 100 bool isISO8601 = calendar->isISO8601();
 101 bool shouldAddEraAndEraYear = false;
 102 MarkedArgumentBuffer fieldNames;
 103 forEachInIterable(globalObject, callFrame->argument(0), [isISO8601, &shouldAddEraAndEraYear, &fieldNames](VM& vm, JSGlobalObject* globalObject, JSValue value) {
 104 auto scope = DECLARE_THROW_SCOPE(vm);
 105 if (!value.isString()) {
 106 throwTypeError(globalObject, scope, "fields include non string value"_s);
 107 return;
 108 }
 109 if (!isISO8601 && !shouldAddEraAndEraYear) {
 110 auto string = jsCast<JSString*>(value)->value(globalObject);
 111 RETURN_IF_EXCEPTION(scope, void());
 112 if (string == "year"_s)
 113 shouldAddEraAndEraYear = true;
 114 }
 115 fieldNames.append(value);
 116 });
 117 RETURN_IF_EXCEPTION(scope, { });
 118
 119 if (shouldAddEraAndEraYear) {
 120 fieldNames.append(jsNontrivialString(vm, vm.propertyNames->era.impl()));
 121 fieldNames.append(jsNontrivialString(vm, vm.propertyNames->eraYear.impl()));
 122 }
 123
 124 return JSValue::encode(constructArray(globalObject, static_cast<ArrayAllocationProfile*>(nullptr), fieldNames));
 125}
 126
 127// https://tc39.es/proposal-temporal/#sec-temporal-defaultmergefields
 128static JSObject* defaultMergeFields(JSGlobalObject* globalObject, JSObject* fields, JSObject* additionalFields)
 129{
 130 VM& vm = globalObject->vm();
 131 auto scope = DECLARE_THROW_SCOPE(vm);
 132
 133 auto* merged = constructEmptyObject(globalObject);
 134
 135 {
 136 PropertyNameArray originalKeys(vm, PropertyNameMode::Strings, PrivateSymbolMode::Exclude);
 137 fields->methodTable(vm)->getOwnPropertyNames(fields, globalObject, originalKeys, DontEnumPropertiesMode::Include);
 138 RETURN_IF_EXCEPTION(scope, { });
 139
 140 for (const auto& nextKey : originalKeys) {
 141 if (nextKey != vm.propertyNames->month && nextKey != vm.propertyNames->monthCode) {
 142 JSValue propValue = fields->get(globalObject, nextKey);
 143 RETURN_IF_EXCEPTION(scope, { });
 144 if (!propValue.isUndefined()) {
 145 PutPropertySlot slot(merged, true);
 146 merged->putOwnDataProperty(vm, nextKey, propValue, slot);
 147 RETURN_IF_EXCEPTION(scope, { });
 148 }
 149 }
 150 }
 151 }
 152
 153 bool includesMonthOrMonthCode = false;
 154 {
 155 PropertyNameArray newKeys(vm, PropertyNameMode::Strings, PrivateSymbolMode::Exclude);
 156 additionalFields->methodTable(vm)->getOwnPropertyNames(additionalFields, globalObject, newKeys, DontEnumPropertiesMode::Include);
 157 RETURN_IF_EXCEPTION(scope, { });
 158
 159 for (const auto& nextKey : newKeys) {
 160 if (!includesMonthOrMonthCode) {
 161 if (nextKey == vm.propertyNames->month || nextKey == vm.propertyNames->monthCode)
 162 includesMonthOrMonthCode = true;
 163 }
 164
 165 JSValue propValue = additionalFields->get(globalObject, nextKey);
 166 RETURN_IF_EXCEPTION(scope, { });
 167 if (!propValue.isUndefined()) {
 168 PutPropertySlot slot(merged, true);
 169 merged->putOwnDataProperty(vm, nextKey, propValue, slot);
 170 RETURN_IF_EXCEPTION(scope, { });
 171 }
 172 }
 173 }
 174
 175 if (!includesMonthOrMonthCode) {
 176 JSValue month = fields->get(globalObject, vm.propertyNames->month);
 177 RETURN_IF_EXCEPTION(scope, { });
 178 if (!month.isUndefined()) {
 179 PutPropertySlot slot(merged, true);
 180 merged->putOwnDataProperty(vm, vm.propertyNames->month, month, slot);
 181 RETURN_IF_EXCEPTION(scope, { });
 182 }
 183
 184 JSValue monthCode = fields->get(globalObject, vm.propertyNames->monthCode);
 185 RETURN_IF_EXCEPTION(scope, { });
 186 if (!monthCode.isUndefined()) {
 187 PutPropertySlot slot(merged, true);
 188 merged->putOwnDataProperty(vm, vm.propertyNames->monthCode, monthCode, slot);
 189 RETURN_IF_EXCEPTION(scope, { });
 190 }
 191 }
 192
 193 return merged;
 194}
 195
 196// https://tc39.es/proposal-temporal/#sup-temporal.calendar.prototype.mergefields
 197JSC_DEFINE_HOST_FUNCTION(temporalCalendarPrototypeFuncMergeFields, (JSGlobalObject* globalObject, CallFrame* callFrame))
 198{
 199 VM& vm = globalObject->vm();
 200 auto scope = DECLARE_THROW_SCOPE(vm);
 201
 202 auto* calendar = jsDynamicCast<TemporalCalendar*>(vm, callFrame->thisValue());
 203 if (!calendar)
 204 return throwVMTypeError(globalObject, scope, "Temporal.Calendar.prototype.mergeFields called on value that's not an object initialized as a Calendar"_s);
 205
 206 auto* fields = callFrame->argument(0).toObject(globalObject);
 207 RETURN_IF_EXCEPTION(scope, { });
 208
 209 auto* additionalFields = callFrame->argument(1).toObject(globalObject);
 210 RETURN_IF_EXCEPTION(scope, { });
 211
 212 if (calendar->isISO8601())
 213 RELEASE_AND_RETURN(scope, JSValue::encode(defaultMergeFields(globalObject, fields, additionalFields)));
 214
 215 auto copyObject = [](JSGlobalObject* globalObject, JSObject* object) -> JSObject* {
 216 VM& vm = globalObject->vm();
 217 auto scope = DECLARE_THROW_SCOPE(vm);
 218
 219 auto* copied = constructEmptyObject(globalObject);
 220
 221 PropertyNameArray keys(vm, PropertyNameMode::Strings, PrivateSymbolMode::Exclude);
 222 object->methodTable(vm)->getOwnPropertyNames(object, globalObject, keys, DontEnumPropertiesMode::Include);
 223 RETURN_IF_EXCEPTION(scope, { });
 224
 225 for (const auto& key : keys) {
 226 JSValue propValue = object->get(globalObject, key);
 227 RETURN_IF_EXCEPTION(scope, { });
 228 if (!propValue.isUndefined()) {
 229 PutPropertySlot slot(copied, true);
 230 copied->putOwnDataProperty(vm, key, propValue, slot);
 231 RETURN_IF_EXCEPTION(scope, { });
 232 }
 233 }
 234
 235 return copied;
 236 };
 237
 238 auto* fieldsCopied = copyObject(globalObject, fields);
 239 RETURN_IF_EXCEPTION(scope, { });
 240
 241 auto* additionalFieldsCopied = copyObject(globalObject, additionalFields);
 242 RETURN_IF_EXCEPTION(scope, { });
 243
 244 JSValue newMonth = jsUndefined();
 245 JSValue newMonthCode = jsUndefined();
 246 JSValue newYear = jsUndefined();
 247 JSValue newEra = jsUndefined();
 248 JSValue newEraYear = jsUndefined();
 249 {
 250 PropertyNameArray keys(vm, PropertyNameMode::Strings, PrivateSymbolMode::Exclude);
 251 additionalFieldsCopied->methodTable(vm)->getOwnPropertyNames(additionalFieldsCopied, globalObject, keys, DontEnumPropertiesMode::Include);
 252 RETURN_IF_EXCEPTION(scope, { });
 253
 254 for (const auto& key : keys) {
 255 JSValue propValue = additionalFieldsCopied->get(globalObject, key);
 256 RETURN_IF_EXCEPTION(scope, { });
 257 if (!propValue.isUndefined()) {
 258 if (key == vm.propertyNames->month)
 259 newMonth = propValue;
 260 else if (key == vm.propertyNames->monthCode)
 261 newMonthCode = propValue;
 262 else if (key == vm.propertyNames->year)
 263 newYear = propValue;
 264 else if (key == vm.propertyNames->era)
 265 newEra = propValue;
 266 else if (key == vm.propertyNames->eraYear)
 267 newEraYear = propValue;
 268 else {
 269 PutPropertySlot slot(fieldsCopied, true);
 270 fieldsCopied->putOwnDataProperty(vm, key, propValue, slot);
 271 RETURN_IF_EXCEPTION(scope, { });
 272 }
 273 }
 274 }
 275 }
 276
 277 if (!newMonth.isUndefined() || !newMonthCode.isUndefined()) {
 278 {
 279 PutPropertySlot slot(fieldsCopied, true);
 280 fieldsCopied->putOwnDataProperty(vm, vm.propertyNames->month, newMonth, slot);
 281 RETURN_IF_EXCEPTION(scope, { });
 282 }
 283 {
 284 PutPropertySlot slot(fieldsCopied, true);
 285 fieldsCopied->putOwnDataProperty(vm, vm.propertyNames->monthCode, newMonthCode, slot);
 286 RETURN_IF_EXCEPTION(scope, { });
 287 }
 288 }
 289
 290 if (!newYear.isUndefined() || !newEra.isUndefined() || !newEraYear.isUndefined()) {
 291 {
 292 PutPropertySlot slot(fieldsCopied, true);
 293 fieldsCopied->putOwnDataProperty(vm, vm.propertyNames->year, newYear, slot);
 294 RETURN_IF_EXCEPTION(scope, { });
 295 }
 296 {
 297 PutPropertySlot slot(fieldsCopied, true);
 298 fieldsCopied->putOwnDataProperty(vm, vm.propertyNames->era, newEra, slot);
 299 RETURN_IF_EXCEPTION(scope, { });
 300 }
 301 {
 302 PutPropertySlot slot(fieldsCopied, true);
 303 fieldsCopied->putOwnDataProperty(vm, vm.propertyNames->eraYear, newEraYear, slot);
 304 RETURN_IF_EXCEPTION(scope, { });
 305 }
 306 }
 307
 308 return JSValue::encode(fieldsCopied);
 309}
 310
 311// https://tc39.es/proposal-temporal/#sec-temporal.calendar.prototype.tostring
 312JSC_DEFINE_HOST_FUNCTION(temporalCalendarPrototypeFuncToString, (JSGlobalObject* globalObject, CallFrame* callFrame))
 313{
 314 VM& vm = globalObject->vm();
 315 auto scope = DECLARE_THROW_SCOPE(vm);
 316
 317 auto* calendar = jsDynamicCast<TemporalCalendar*>(vm, callFrame->thisValue());
 318 if (!calendar)
 319 return throwVMTypeError(globalObject, scope, "Temporal.Calendar.prototype.toString called on value that's not an object initialized as a Calendar"_s);
 320
 321 return JSValue::encode(jsString(vm, intlAvailableCalendars()[calendar->identifier()]));
 322}
 323
 324// https://tc39.es/proposal-temporal/#sec-temporal.calendar.prototype.tojson
 325JSC_DEFINE_HOST_FUNCTION(temporalCalendarPrototypeFuncToJSON, (JSGlobalObject* globalObject, CallFrame* callFrame))
 326{
 327 return JSValue::encode(callFrame->thisValue().toString(globalObject));
 328}
 329
 330} // namespace JSC

Source/JavaScriptCore/runtime/TemporalCalendarPrototype.h

 1/*
 2 * Copyright (C) 2021 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 23 * THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#pragma once
 27
 28#include "JSObject.h"
 29
 30namespace JSC {
 31
 32class TemporalCalendarPrototype final : public JSNonFinalObject {
 33public:
 34 using Base = JSNonFinalObject;
 35 static constexpr unsigned StructureFlags = Base::StructureFlags | HasStaticPropertyTable;
 36
 37 template<typename CellType, SubspaceAccess>
 38 static IsoSubspace* subspaceFor(VM& vm)
 39 {
 40 STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(TemporalCalendarPrototype, Base);
 41 return &vm.plainObjectSpace;
 42 }
 43
 44 static TemporalCalendarPrototype* create(VM&, JSGlobalObject*, Structure*);
 45 static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
 46
 47 DECLARE_INFO;
 48
 49private:
 50 TemporalCalendarPrototype(VM&, Structure*);
 51 void finishCreation(VM&, JSGlobalObject*);
 52};
 53
 54} // namespace JSC

Source/JavaScriptCore/runtime/TemporalObject.cpp

11/*
22 * Copyright (C) 2021 Igalia S.L. All rights reserved.
 3 * Copyright (C) 2021 Apple Inc. All rights reserved.
34 *
45 * This library is free software; you can redistribute it and/or
56 * modify it under the terms of the GNU Lesser General Public

2021#include "config.h"
2122#include "TemporalObject.h"
2223
 24#include "FunctionPrototype.h"
2325#include "JSCJSValueInlines.h"
2426#include "JSGlobalObject.h"
2527#include "JSObjectInlines.h"
2628#include "ObjectPrototype.h"
 29#include "TemporalCalendarConstructor.h"
 30#include "TemporalCalendarPrototype.h"
2731#include "TemporalNow.h"
2832
2933namespace JSC {
3034
3135STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(TemporalObject);
3236
 37static JSValue createCalendarConstructor(VM& vm, JSObject* object)
 38{
 39 TemporalObject* temporalObject = jsCast<TemporalObject*>(object);
 40 JSGlobalObject* globalObject = temporalObject->globalObject(vm);
 41 return TemporalCalendarConstructor::create(vm, TemporalCalendarConstructor::createStructure(vm, globalObject, globalObject->functionPrototype()), jsCast<TemporalCalendarPrototype*>(globalObject->calendarStructure()->storedPrototypeObject()));
 42}
 43
3344static JSValue createNowObject(VM& vm, JSObject* object)
3445{
3546 TemporalObject* temporalObject = jsCast<TemporalObject*>(object);

@@namespace JSC {
4556
4657/* Source for TemporalObject.lut.h
4758@begin temporalObjectTable
 59 Calendar createCalendarConstructor DontEnum|PropertyCallback
4860 Now createNowObject DontEnum|PropertyCallback
4961@end
5062*/

Source/JavaScriptCore/runtime/VM.cpp

162162#include "StructureChain.h"
163163#include "StructureInlines.h"
164164#include "SymbolObject.h"
 165#include "TemporalCalendar.h"
165166#include "TestRunnerUtils.h"
166167#include "ThunkGenerators.h"
167168#include "TypeProfiler.h"

@@DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(sourceCodeSpace, destructibleCellHeapCel
15841585DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(symbolSpace, destructibleCellHeapCellType.get(), Symbol)
15851586DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(symbolObjectSpace, cellHeapCellType.get(), SymbolObject)
15861587DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(templateObjectDescriptorSpace, destructibleCellHeapCellType.get(), JSTemplateObjectDescriptor)
 1588DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(temporalCalendarSpace, cellHeapCellType.get(), TemporalCalendar)
15871589DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(uint8ArraySpace, cellHeapCellType.get(), JSUint8Array)
15881590DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(uint8ClampedArraySpace, cellHeapCellType.get(), JSUint8ClampedArray)
15891591DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(uint16ArraySpace, cellHeapCellType.get(), JSUint16Array)

Source/JavaScriptCore/runtime/VM.h

@@class UnlinkedProgramCodeBlock;
193193class UnlinkedModuleProgramCodeBlock;
194194class VirtualRegister;
195195class VMEntryScope;
 196class TemporalCalendar;
196197class TopLevelGlobalObjectScope;
197198class TypeProfiler;
198199class TypeProfilerLog;

@@class VM : public ThreadSafeRefCounted<VM>, public DoublyLinkedListNode<VM> {
591592 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(symbolSpace)
592593 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(symbolObjectSpace)
593594 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(templateObjectDescriptorSpace)
 595 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(temporalCalendarSpace)
594596 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(uint8ArraySpace)
595597 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(uint8ClampedArraySpace)
596598 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(uint16ArraySpace)

Source/WTF/wtf/text/StringImpl.cpp

@@Ref<StringImpl> StringImpl::create(const LChar* characters, unsigned length)
284284 return createInternal(characters, length);
285285}
286286
287 Ref<StringImpl> StringImpl::createStaticStringImpl(const char* characters, unsigned length)
 287Ref<StringImpl> StringImpl::createStaticStringImpl(const LChar* characters, unsigned length)
288288{
289  const LChar* lcharCharacters = reinterpret_cast<const LChar*>(characters);
290  ASSERT(charactersAreAllASCII(lcharCharacters, length));
291  Ref<StringImpl> result = createInternal(lcharCharacters, length);
292  result->setHash(StringHasher::computeHashAndMaskTop8Bits(lcharCharacters, length));
 289 if (!length)
 290 return *empty();
 291 Ref<StringImpl> result = createInternal(characters, length);
 292 result->hash();
 293 result->m_refCount |= s_refCountFlagIsStaticString;
 294 return result;
 295}
 296
 297Ref<StringImpl> StringImpl::createStaticStringImpl(const UChar* characters, unsigned length)
 298{
 299 if (!length)
 300 return *empty();
 301 Ref<StringImpl> result = create8BitIfPossible(characters, length);
 302 result->hash();
293303 result->m_refCount |= s_refCountFlagIsStaticString;
294304 return result;
295305}

Source/WTF/wtf/text/StringImpl.h

@@class StringImpl : private StringImplShape {
259259 WTF_EXPORT_PRIVATE static Ref<StringImpl> createUninitialized(unsigned length, UChar*&);
260260 template<typename CharacterType> static RefPtr<StringImpl> tryCreateUninitialized(unsigned length, CharacterType*&);
261261
262  WTF_EXPORT_PRIVATE static Ref<StringImpl> createStaticStringImpl(const char*, unsigned length);
 262 static Ref<StringImpl> createStaticStringImpl(const char* characters, unsigned length)
 263 {
 264 ASSERT(charactersAreAllASCII(bitwise_cast<const LChar*>(characters), length));
 265 return createStaticStringImpl(bitwise_cast<const LChar*>(characters), length);
 266 }
 267 WTF_EXPORT_PRIVATE static Ref<StringImpl> createStaticStringImpl(const LChar*, unsigned length);
 268 WTF_EXPORT_PRIVATE static Ref<StringImpl> createStaticStringImpl(const UChar*, unsigned length);
263269
264270 // Reallocate the StringImpl. The originalString must be only owned by the Ref,
265271 // and the buffer ownership must be BufferInternal. Just like the input pointer of realloc(),

JSTests/ChangeLog

 12021-08-30 Yusuke Suzuki <ysuzuki@apple.com>
 2
 3 [JSC] Implement Temporal.Calendar
 4 https://bugs.webkit.org/show_bug.cgi?id=229651
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 * stress/temporal-calendar.js: Added.
 9 (shouldBe):
 10 (shouldThrow):
 11 (new.Temporal.Calendar):
 12
1132021-08-29 Yusuke Suzuki <ysuzuki@apple.com>
214
315 [JSC] Upgrade test262

JSTests/stress/temporal-calendar.js

 1//@ requireOptions("--useTemporal=1")
 2function shouldBe(actual, expected) {
 3 if (actual !== expected)
 4 throw new Error(`expected ${expected} but got ${actual}`);
 5}
 6
 7function shouldThrow(func, errorType, message) {
 8 let error;
 9 try {
 10 func();
 11 } catch (e) {
 12 error = e;
 13 }
 14
 15 if (!(error instanceof errorType))
 16 throw new Error(`Expected ${errorType.name}!`);
 17 if (message !== undefined)
 18 shouldBe(String(error), message);
 19}
 20
 21{
 22 let calendar = new Temporal.Calendar("iso8601");
 23 shouldBe(calendar.id, `iso8601`);
 24 shouldBe(String(calendar), `iso8601`);
 25}
 26{
 27 let calendar = new Temporal.Calendar("gregory");
 28 shouldBe(calendar.id, `gregory`);
 29 shouldBe(String(calendar), `gregory`);
 30}
 31
 32shouldThrow(() => {
 33 new Temporal.Calendar("discordian");
 34}, RangeError, `RangeError: invalid calendar ID`);
 35
 36{
 37 let input = ["monthCode", "day"];
 38 let fields = Temporal.Calendar.from("iso8601").fields(input);
 39 shouldBe(input !== fields, true);
 40 shouldBe(JSON.stringify(fields), `["monthCode","day"]`);
 41}
 42{
 43 let input = ["monthCode", "day"];
 44 let fields = Temporal.Calendar.from("gregory").fields(input);
 45 shouldBe(input !== fields, true);
 46 shouldBe(JSON.stringify(fields), `["monthCode","day"]`);
 47}
 48{
 49 let input = ["monthCode", "day", "year"];
 50 let fields = Temporal.Calendar.from("iso8601").fields(input);
 51 shouldBe(input !== fields, true);
 52 shouldBe(JSON.stringify(fields), `["monthCode","day","year"]`);
 53}
 54
 55{
 56 let input = ["monthCode", "day", "year"];
 57 let fields = Temporal.Calendar.from("gregory").fields(input);
 58 shouldBe(input !== fields, true);
 59 shouldBe(JSON.stringify(fields), `["monthCode","day","year","era","eraYear"]`);
 60}
 61{
 62 let merged = Temporal.Calendar.from('iso8601').mergeFields(
 63 { year: 2006, month: 7, day: 31 },
 64 { monthCode: 'M08' }
 65 );
 66 shouldBe(JSON.stringify(merged), `{"year":2006,"day":31,"monthCode":"M08"}`);
 67}
 68{
 69 let merged = Temporal.Calendar.from('gregory').mergeFields(
 70 { year: 2006, month: 7, day: 31 },
 71 { monthCode: 'M08' }
 72 );
 73 shouldBe(JSON.stringify(merged), `{"year":2006,"day":31,"monthCode":"M08"}`);
 74}
 75
 76{
 77 const user = {
 78 id: 775,
 79 username: 'robotcat',
 80 password: 'hunter2', // Note: Don't really store passwords like that
 81 userCalendar: Temporal.Calendar.from('gregory')
 82 };
 83 let string = JSON.stringify(user);
 84 shouldBe(string, `{"id":775,"username":"robotcat","password":"hunter2","userCalendar":"gregory"}`);
 85 // To rebuild from the string:
 86 function reviver(key, value) {
 87 if (key.endsWith('Calendar'))
 88 return Temporal.Calendar.from(value);
 89 return value;
 90 }
 91 shouldBe(JSON.parse(string, reviver).userCalendar instanceof Temporal.Calendar, true);
 92}