Changeset 266323 in webkit for trunk/Source/JavaScriptCore


Ignore:
Timestamp:
Aug 29, 2020, 1:32:45 AM (5 years ago)
Author:
[email protected]
Message:

[JSC] Implement Intl.DateTimeFormat dayPeriod
https://bugs.webkit.org/show_bug.cgi?id=215839

Reviewed by Ross Kirsling.

JSTests:

  • stress/intl-datetimeformat-day-period.js: Added.

(shouldBe):
(throw.new.Error):

  • test262/config.yaml:

Source/JavaScriptCore:

This patch implements Intl.DateTimeFormat dayPeriod option[1]. We can use "narrow", "short", or "long" for dayPeriod,
and it determines how "AM" etc. is represented.

[1]: https://github.com/tc39/ecma402/pull/346

  • builtins/DatePrototype.js:

(toLocaleString.toDateTimeOptionsAnyAll):
(toLocaleString):
(toLocaleTimeString.toDateTimeOptionsTimeTime):
(toLocaleTimeString):

  • bytecode/BytecodeIntrinsicRegistry.cpp:

(JSC::BytecodeIntrinsicRegistry::BytecodeIntrinsicRegistry):

  • bytecode/BytecodeIntrinsicRegistry.h:
  • runtime/CommonIdentifiers.h:
  • runtime/IntlDateTimeFormat.cpp:

(JSC::toDateTimeOptionsAnyDate):
(JSC::IntlDateTimeFormat::setFormatsFromPattern):
(JSC::IntlDateTimeFormat::initializeDateTimeFormat):
(JSC::IntlDateTimeFormat::dayPeriodString):
(JSC::IntlDateTimeFormat::resolvedOptions const):

  • runtime/IntlDateTimeFormat.h:
  • runtime/OptionsList.h:
Location:
trunk/Source/JavaScriptCore
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r266322 r266323  
     12020-08-28  Yusuke Suzuki  <[email protected]>
     2
     3        [JSC] Implement Intl.DateTimeFormat dayPeriod
     4        https://bugs.webkit.org/show_bug.cgi?id=215839
     5
     6        Reviewed by Ross Kirsling.
     7
     8        This patch implements Intl.DateTimeFormat dayPeriod option[1]. We can use "narrow", "short", or "long" for dayPeriod,
     9        and it determines how "AM" etc. is represented.
     10
     11        [1]: https://github.com/tc39/ecma402/pull/346
     12
     13        * builtins/DatePrototype.js:
     14        (toLocaleString.toDateTimeOptionsAnyAll):
     15        (toLocaleString):
     16        (toLocaleTimeString.toDateTimeOptionsTimeTime):
     17        (toLocaleTimeString):
     18        * bytecode/BytecodeIntrinsicRegistry.cpp:
     19        (JSC::BytecodeIntrinsicRegistry::BytecodeIntrinsicRegistry):
     20        * bytecode/BytecodeIntrinsicRegistry.h:
     21        * runtime/CommonIdentifiers.h:
     22        * runtime/IntlDateTimeFormat.cpp:
     23        (JSC::toDateTimeOptionsAnyDate):
     24        (JSC::IntlDateTimeFormat::setFormatsFromPattern):
     25        (JSC::IntlDateTimeFormat::initializeDateTimeFormat):
     26        (JSC::IntlDateTimeFormat::dayPeriodString):
     27        (JSC::IntlDateTimeFormat::resolvedOptions const):
     28        * runtime/IntlDateTimeFormat.h:
     29        * runtime/OptionsList.h:
     30
    1312020-08-28  Yusuke Suzuki  <[email protected]>
    232
  • trunk/Source/JavaScriptCore/builtins/DatePrototype.js

    r266170 r266323  
    4747            options.month === @undefined &&
    4848            options.day === @undefined &&
     49            (!@useIntlDateTimeFormatDayPeriod || options.dayPeriod === @undefined) &&
    4950            options.hour === @undefined &&
    5051            options.minute === @undefined &&
     
    163164        // Check original instead of descendant to reduce lookups up the prototype chain.
    164165        var needsDefaults = !options || (
     166            (!@useIntlDateTimeFormatDayPeriod || options.dayPeriod === @undefined) &&
    165167            options.hour === @undefined &&
    166168            options.minute === @undefined &&
  • trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.cpp

    r261755 r266323  
    112112    m_AsyncGeneratorSuspendReasonAwait.set(m_vm, jsNumber(static_cast<int32_t>(JSAsyncGenerator::AsyncGeneratorSuspendReason::Await)));
    113113    m_AsyncGeneratorSuspendReasonNone.set(m_vm, jsNumber(static_cast<int32_t>(JSAsyncGenerator::AsyncGeneratorSuspendReason::None)));
     114    m_useIntlDateTimeFormatDayPeriod.set(m_vm, jsBoolean(Options::useIntlDateTimeFormatDayPeriod()));
    114115}
    115116
  • trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h

    r265907 r266323  
    152152    macro(AsyncGeneratorSuspendReasonAwait) \
    153153    macro(AsyncGeneratorSuspendReasonNone) \
     154    macro(useIntlDateTimeFormatDayPeriod) \
    154155
    155156#define JSC_COMMON_BYTECODE_INTRINSIC_CONSTANTS_CUSTOM_EACH_NAME(macro) \
  • trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h

    r266170 r266323  
    9696    macro(dateStyle) \
    9797    macro(day) \
     98    macro(dayPeriod) \
    9899    macro(defineProperty) \
    99100    macro(deref) \
  • trunk/Source/JavaScriptCore/runtime/IntlDateTimeFormat.cpp

    r266170 r266323  
    249249    // Always "any".
    250250
    251     // a. For each of the property names "hour", "minute", "second", "fractionalSecondDigits":
     251    // a. For each of the property names ""dayPeriod", hour", "minute", "second", "fractionalSecondDigits":
    252252    // i. Let prop be the property name.
    253253    // ii. Let value be Get(options, prop).
    254254    // iii. ReturnIfAbrupt(value).
    255255    // iv. If value is not undefined, then let needDefaults be false.
     256    if (Options::useIntlDateTimeFormatDayPeriod()) {
     257        JSValue dayPeriod = options->get(globalObject, vm.propertyNames->dayPeriod);
     258        RETURN_IF_EXCEPTION(scope, nullptr);
     259        if (!dayPeriod.isUndefined())
     260            needDefaults = false;
     261    }
     262
    256263    JSValue hour = options->get(globalObject, vm.propertyNames->hour);
    257264    RETURN_IF_EXCEPTION(scope, nullptr);
     
    379386                m_day = Day::TwoDigit;
    380387            break;
     388        case 'a':
     389        case 'b':
     390        case 'B':
     391            if (count <= 3)
     392                m_dayPeriod = DayPeriod::Short;
     393            else if (count == 4)
     394                m_dayPeriod = DayPeriod::Long;
     395            else if (count == 5)
     396                m_dayPeriod = DayPeriod::Narrow;
     397            break;
    381398        case 'h':
    382399        case 'H':
     
    585602    }
    586603
     604    DayPeriod dayPeriod = DayPeriod::None;
     605    if (Options::useIntlDateTimeFormatDayPeriod()) {
     606        dayPeriod = intlOption<DayPeriod>(globalObject, options, vm.propertyNames->dayPeriod, { { "narrow"_s, DayPeriod::Narrow }, { "short"_s, DayPeriod::Short }, { "long"_s, DayPeriod::Long } }, "dayPeriod must be \"narrow\", \"short\", or \"long\""_s, DayPeriod::None);
     607        RETURN_IF_EXCEPTION(scope, void());
     608    }
     609
    587610    Hour hour = intlOption<Hour>(globalObject, options, vm.propertyNames->hour, { { "2-digit"_s, Hour::TwoDigit }, { "numeric"_s, Hour::Numeric } }, "hour must be \"2-digit\" or \"numeric\""_s, Hour::None);
    588611    RETURN_IF_EXCEPTION(scope, void());
     
    608631    }
    609632
     633    if (Options::useIntlDateTimeFormatDayPeriod()) {
     634        // dayPeriod must be set after setting hour.
     635        // https://unicode-org.atlassian.net/browse/ICU-20731
     636        switch (dayPeriod) {
     637        case DayPeriod::Narrow:
     638            skeletonBuilder.appendLiteral("BBBBB");
     639            break;
     640        case DayPeriod::Short:
     641            skeletonBuilder.append('B');
     642            break;
     643        case DayPeriod::Long:
     644            skeletonBuilder.appendLiteral("BBBB");
     645            break;
     646        case DayPeriod::None:
     647            break;
     648        }
     649    }
     650
    610651    Minute minute = intlOption<Minute>(globalObject, options, vm.propertyNames->minute, { { "2-digit"_s, Minute::TwoDigit }, { "numeric"_s, Minute::Numeric } }, "minute must be \"2-digit\" or \"numeric\""_s, Minute::None);
    611652    RETURN_IF_EXCEPTION(scope, void());
     
    669710        //     iii. If p is not undefined, then
    670711        //         1. Throw a TypeError exception.
    671         if (weekday != Weekday::None || era != Era::None || year != Year::None || month != Month::None || day != Day::None || hour != Hour::None || minute != Minute::None || second != Second::None || fractionalSecondDigits != 0 || timeZoneName != TimeZoneName::None) {
     712        if (weekday != Weekday::None || era != Era::None || year != Year::None || month != Month::None || day != Day::None || dayPeriod != DayPeriod::None || hour != Hour::None || minute != Minute::None || second != Second::None || fractionalSecondDigits != 0 || timeZoneName != TimeZoneName::None) {
    672713            throwTypeError(globalObject, scope, "dateStyle and timeStyle may not be used with other DateTimeFormat options"_s);
    673714            return;
     
    893934}
    894935
     936ASCIILiteral IntlDateTimeFormat::dayPeriodString(DayPeriod dayPeriod)
     937{
     938    switch (dayPeriod) {
     939    case DayPeriod::Narrow:
     940        return "narrow"_s;
     941    case DayPeriod::Short:
     942        return "short"_s;
     943    case DayPeriod::Long:
     944        return "long"_s;
     945    case DayPeriod::None:
     946        ASSERT_NOT_REACHED();
     947        return ASCIILiteral::null();
     948    }
     949    ASSERT_NOT_REACHED();
     950    return ASCIILiteral::null();
     951}
     952
    895953ASCIILiteral IntlDateTimeFormat::hourString(Hour hour)
    896954{
     
    10021060    if (m_day != Day::None)
    10031061        options->putDirect(vm, vm.propertyNames->day, jsNontrivialString(vm, dayString(m_day)));
     1062
     1063    if (Options::useIntlDateTimeFormatDayPeriod()) {
     1064        if (m_dayPeriod != DayPeriod::None)
     1065            options->putDirect(vm, vm.propertyNames->dayPeriod, jsNontrivialString(vm, dayPeriodString(m_dayPeriod)));
     1066    }
    10041067
    10051068    if (m_hour != Hour::None)
  • trunk/Source/JavaScriptCore/runtime/IntlDateTimeFormat.h

    r266170 r266323  
    8282    enum class Month : uint8_t { None, TwoDigit, Numeric, Narrow, Short, Long };
    8383    enum class Day : uint8_t { None, TwoDigit, Numeric };
     84    enum class DayPeriod : uint8_t { None, Narrow, Short, Long };
    8485    enum class Hour : uint8_t { None, TwoDigit, Numeric };
    8586    enum class Minute : uint8_t { None, TwoDigit, Numeric };
     
    9495    static ASCIILiteral monthString(Month);
    9596    static ASCIILiteral dayString(Day);
     97    static ASCIILiteral dayPeriodString(DayPeriod);
    9698    static ASCIILiteral hourString(Hour);
    9799    static ASCIILiteral minuteString(Minute);
     
    118120    Month m_month { Month::None };
    119121    Day m_day { Day::None };
     122    DayPeriod m_dayPeriod { DayPeriod::None };
    120123    Hour m_hour { Hour::None };
    121124    Minute m_minute { Minute::None };
  • trunk/Source/JavaScriptCore/runtime/OptionsList.h

    r266180 r266323  
    491491    v(Bool, useWeakRefs, false, Normal, "Expose the WeakRef constructor.") \
    492492    v(Bool, useBigInt, true, Normal, "If true, we will enable BigInt support.") \
     493    v(Bool, useIntlDateTimeFormatDayPeriod, false, Normal, "Expose the Intl.DateTimeFormat dayPeriod feature.") \
    493494    v(Bool, useArrayAllocationProfiling, true, Normal, "If true, we will use our normal array allocation profiling. If false, the allocation profile will always claim to be undecided.") \
    494495    v(Bool, forcePolyProto, false, Normal, "If true, create_this will always create an object with a poly proto structure.") \
Note: See TracChangeset for help on using the changeset viewer.