Changeset 195138 in webkit


Ignore:
Timestamp:
Jan 15, 2016 11:30:45 AM (8 years ago)
Author:
commit-queue@webkit.org
Message:

[INTL] Implement Date.prototype.toLocaleString in ECMA-402
https://bugs.webkit.org/show_bug.cgi?id=147611

Patch by Andy VanWagoner <thetalecrafter@gmail.com> on 2016-01-15
Reviewed by Benjamin Poulain.

Source/JavaScriptCore:

Expose dateProtoFuncGetTime as thisTimeValue for builtins.
Remove unused code in DateTimeFormat toDateTimeOptions, and make the
function specific to the call in initializeDateTimeFormat. Properly
throw when the options parameter is null.
Add toLocaleString in builtin JavaScript, with it's own specific branch
of toDateTimeOptions.

  • CMakeLists.txt:
  • DerivedSources.make:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • builtins/DatePrototype.js: Added.

(toLocaleString.toDateTimeOptionsAnyAll):
(toLocaleString):

  • runtime/CommonIdentifiers.h:
  • runtime/DatePrototype.cpp:

(JSC::DatePrototype::finishCreation):

  • runtime/DatePrototype.h:
  • runtime/IntlDateTimeFormat.cpp:

(JSC::toDateTimeOptionsAnyDate):
(JSC::IntlDateTimeFormat::initializeDateTimeFormat):
(JSC::toDateTimeOptions): Deleted.

  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::init):

LayoutTests:

  • js/intl-datetimeformat-expected.txt: Added test for null options.
  • js/date-toLocaleString-expected.txt: Added.
  • js/date-toLocaleString.html: Added.
  • js/script-tests/intl-datetimeformat.js: Added test for null options.
  • js/script-tests/date-toLocaleString.js: Added.
Location:
trunk
Files:
4 added
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r195130 r195138  
     12016-01-15  Andy VanWagoner  <thetalecrafter@gmail.com>
     2
     3        [INTL] Implement Date.prototype.toLocaleString in ECMA-402
     4        https://bugs.webkit.org/show_bug.cgi?id=147611
     5
     6        Reviewed by Benjamin Poulain.
     7
     8        * js/intl-datetimeformat-expected.txt: Added test for null options.
     9        * js/date-toLocaleString-expected.txt: Added.
     10        * js/date-toLocaleString.html: Added.
     11        * js/script-tests/intl-datetimeformat.js: Added test for null options.
     12        * js/script-tests/date-toLocaleString.js: Added.
     13
    1142016-01-15  Antti Koivisto  <antti@apple.com>
    215
  • trunk/LayoutTests/js/intl-datetimeformat-expected.txt

    r194441 r195138  
    8383PASS Intl.DateTimeFormat.prototype.resolvedOptions.call(5) threw exception TypeError: Intl.DateTimeFormat.prototype.resolvedOptions called on value that's not an object initialized as a DateTimeFormat.
    8484PASS Intl.DateTimeFormat('$') threw exception RangeError: invalid language tag: $.
    85 PASS Intl.DateTimeFormat('en', null) did not throw exception.
     85PASS Intl.DateTimeFormat('en', null) threw exception TypeError: null is not an object (evaluating 'Intl.DateTimeFormat('en', null)').
    8686PASS Intl.DateTimeFormat('en').resolvedOptions().weekday is undefined
    8787PASS Intl.DateTimeFormat('en').resolvedOptions().era is undefined
  • trunk/LayoutTests/js/script-tests/intl-datetimeformat.js

    r194441 r195138  
    163163
    164164shouldThrow("Intl.DateTimeFormat('$')", "'RangeError: invalid language tag: $'");
    165 shouldNotThrow("Intl.DateTimeFormat('en', null)");
     165shouldThrow("Intl.DateTimeFormat('en', null)", '"TypeError: null is not an object (evaluating \'Intl.DateTimeFormat(\'en\', null)\')"');
    166166
    167167// Defaults to month, day, year.
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r195133 r195138  
    12231223    ${JAVASCRIPTCORE_DIR}/builtins/ArrayIteratorPrototype.js
    12241224    ${JAVASCRIPTCORE_DIR}/builtins/ArrayPrototype.js
     1225    ${JAVASCRIPTCORE_DIR}/builtins/DatePrototype.js
    12251226    ${JAVASCRIPTCORE_DIR}/builtins/FunctionPrototype.js
    12261227    ${JAVASCRIPTCORE_DIR}/builtins/GeneratorPrototype.js
  • trunk/Source/JavaScriptCore/ChangeLog

    r195134 r195138  
     12016-01-15  Andy VanWagoner  <thetalecrafter@gmail.com>
     2
     3        [INTL] Implement Date.prototype.toLocaleString in ECMA-402
     4        https://bugs.webkit.org/show_bug.cgi?id=147611
     5
     6        Reviewed by Benjamin Poulain.
     7
     8        Expose dateProtoFuncGetTime as thisTimeValue for builtins.
     9        Remove unused code in DateTimeFormat toDateTimeOptions, and make the
     10        function specific to the call in initializeDateTimeFormat. Properly
     11        throw when the options parameter is null.
     12        Add toLocaleString in builtin JavaScript, with it's own specific branch
     13        of toDateTimeOptions.
     14
     15        * CMakeLists.txt:
     16        * DerivedSources.make:
     17        * JavaScriptCore.xcodeproj/project.pbxproj:
     18        * builtins/DatePrototype.js: Added.
     19        (toLocaleString.toDateTimeOptionsAnyAll):
     20        (toLocaleString):
     21        * runtime/CommonIdentifiers.h:
     22        * runtime/DatePrototype.cpp:
     23        (JSC::DatePrototype::finishCreation):
     24        * runtime/DatePrototype.h:
     25        * runtime/IntlDateTimeFormat.cpp:
     26        (JSC::toDateTimeOptionsAnyDate):
     27        (JSC::IntlDateTimeFormat::initializeDateTimeFormat):
     28        (JSC::toDateTimeOptions): Deleted.
     29        * runtime/JSGlobalObject.cpp:
     30        (JSC::JSGlobalObject::init):
     31
    1322016-01-15  Konstantin Tokarev  <annulen@yandex.ru>
    233
  • trunk/Source/JavaScriptCore/DerivedSources.make

    r194838 r195138  
    8484    $(JavaScriptCore)/builtins/ArrayIteratorPrototype.js \
    8585    $(JavaScriptCore)/builtins/ArrayPrototype.js \
     86    $(JavaScriptCore)/builtins/DatePrototype.js \
    8687    $(JavaScriptCore)/builtins/FunctionPrototype.js \
    8788    $(JavaScriptCore)/builtins/GeneratorPrototype.js \
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r195133 r195138  
    37033703                A1D792FB1B43864B004516F5 /* IntlNumberFormatPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntlNumberFormatPrototype.h; sourceTree = "<group>"; };
    37043704                A1E0451B1C25B4B100BB663C /* StringPrototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = StringPrototype.js; sourceTree = "<group>"; };
     3705                A1FE1EB01C2C537E00A289FF /* DatePrototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = DatePrototype.js; sourceTree = "<group>"; };
    37053706                A503FA13188E0FAF00110F14 /* JavaScriptCallFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JavaScriptCallFrame.cpp; sourceTree = "<group>"; };
    37063707                A503FA14188E0FAF00110F14 /* JavaScriptCallFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JavaScriptCallFrame.h; sourceTree = "<group>"; };
     
    67986799                                A75EE9B018AAB7E200AAD043 /* BuiltinNames.h */,
    67996800                                41DEA1311B9F3154006D65DD /* BuiltinUtils.h */,
     6801                                A1FE1EB01C2C537E00A289FF /* DatePrototype.js */,
    68006802                                A7A979C418BE8D9E002C3733 /* FunctionPrototype.js */,
    68016803                                70B7918F1C0244EC002481E2 /* GeneratorPrototype.js */,
  • trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h

    r194838 r195138  
    358358    macro(DateTimeFormat) \
    359359    macro(NumberFormat) \
     360    macro(thisTimeValue) \
    360361    macro(newTargetLocal) \
    361362    macro(derivedConstructor) \
  • trunk/Source/JavaScriptCore/runtime/DatePrototype.cpp

    r194636 r195138  
    2828#include "DateInstance.h"
    2929#include "Error.h"
     30#include "JSCBuiltins.h"
    3031#include "JSDateMath.h"
    3132#include "JSGlobalObject.h"
     33#include "JSObject.h"
    3234#include "JSString.h"
    3335#include "Lookup.h"
     
    7981EncodedJSValue JSC_HOST_CALL dateProtoFuncGetMonth(ExecState*);
    8082EncodedJSValue JSC_HOST_CALL dateProtoFuncGetSeconds(ExecState*);
    81 EncodedJSValue JSC_HOST_CALL dateProtoFuncGetTime(ExecState*);
    8283EncodedJSValue JSC_HOST_CALL dateProtoFuncGetTimezoneOffset(ExecState*);
    8384EncodedJSValue JSC_HOST_CALL dateProtoFuncGetUTCDate(ExecState*);
     
    486487}
    487488
    488 void DatePrototype::finishCreation(VM& vm, JSGlobalObject*)
     489void DatePrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)
    489490{
    490491    Base::finishCreation(vm);
    491492    ASSERT(inherits(info()));
     493
     494#if ENABLE(INTL)
     495    JSC_BUILTIN_FUNCTION("toLocaleString", datePrototypeToLocaleStringCodeGenerator, DontEnum);
     496#else
     497    UNUSED_PARAM(globalObject);
     498#endif // ENABLE(INTL)
    492499
    493500    // The constructor will be added later, after DateConstructor has been built.
  • trunk/Source/JavaScriptCore/runtime/DatePrototype.h

    r194636 r195138  
    5555};
    5656
     57EncodedJSValue JSC_HOST_CALL dateProtoFuncGetTime(ExecState*);
     58
    5759} // namespace JSC
    5860
  • trunk/Source/JavaScriptCore/runtime/IntlDateTimeFormat.cpp

    r194395 r195138  
    5252static const size_t indexOfExtensionKeyNu = 1;
    5353
    54 enum class DateTimeOptionRequired { Date, Time, Any };
    55 enum class DateTimeOptionDefaults { Date, Time, All };
    56 
    5754IntlDateTimeFormat* IntlDateTimeFormat::create(VM& vm, IntlDateTimeFormatConstructor* constructor)
    5855{
     
    222219}
    223220
    224 static JSObject* toDateTimeOptions(ExecState& exec, JSValue originalOptions, const DateTimeOptionRequired required, const DateTimeOptionDefaults defaults)
     221static JSObject* toDateTimeOptionsAnyDate(ExecState& exec, JSValue originalOptions)
    225222{
    226223    // 12.1.1 ToDateTimeOptions abstract operation (ECMA-402 2.0)
     
    231228    // 3. Let options be ObjectCreate(options).
    232229    JSObject* options;
    233     if (originalOptions.isUndefinedOrNull())
     230    if (originalOptions.isUndefined())
    234231        options = constructEmptyObject(&exec, exec.lexicalGlobalObject()->nullPrototypeObjectStructure());
    235232    else {
     
    244241
    245242    // 5. If required is "date" or "any",
    246     if (required == DateTimeOptionRequired::Date || required == DateTimeOptionRequired::Any) {
    247         // a. For each of the property names "weekday", "year", "month", "day":
    248         // i. Let prop be the property name.
    249         // ii. Let value be Get(options, prop).
    250         // iii. ReturnIfAbrupt(value).
    251         // iv. If value is not undefined, then let needDefaults be false.
    252         JSValue weekday = options->get(&exec, vm.propertyNames->weekday);
    253         if (exec.hadException())
    254             return nullptr;
    255         if (!weekday.isUndefined())
    256             needDefaults = false;
    257 
    258         JSValue year = options->get(&exec, vm.propertyNames->year);
    259         if (exec.hadException())
    260             return nullptr;
    261         if (!year.isUndefined())
    262             needDefaults = false;
    263 
    264         JSValue month = options->get(&exec, vm.propertyNames->month);
    265         if (exec.hadException())
    266             return nullptr;
    267         if (!month.isUndefined())
    268             needDefaults = false;
    269 
    270         JSValue day = options->get(&exec, vm.propertyNames->day);
    271         if (exec.hadException())
    272             return nullptr;
    273         if (!day.isUndefined())
    274             needDefaults = false;
    275     }
     243    // Always "any".
     244
     245    // a. For each of the property names "weekday", "year", "month", "day":
     246    // i. Let prop be the property name.
     247    // ii. Let value be Get(options, prop).
     248    // iii. ReturnIfAbrupt(value).
     249    // iv. If value is not undefined, then let needDefaults be false.
     250    JSValue weekday = options->get(&exec, vm.propertyNames->weekday);
     251    if (exec.hadException())
     252        return nullptr;
     253    if (!weekday.isUndefined())
     254        needDefaults = false;
     255
     256    JSValue year = options->get(&exec, vm.propertyNames->year);
     257    if (exec.hadException())
     258        return nullptr;
     259    if (!year.isUndefined())
     260        needDefaults = false;
     261
     262    JSValue month = options->get(&exec, vm.propertyNames->month);
     263    if (exec.hadException())
     264        return nullptr;
     265    if (!month.isUndefined())
     266        needDefaults = false;
     267
     268    JSValue day = options->get(&exec, vm.propertyNames->day);
     269    if (exec.hadException())
     270        return nullptr;
     271    if (!day.isUndefined())
     272        needDefaults = false;
    276273
    277274    // 6. If required is "time" or "any",
    278     if (required == DateTimeOptionRequired::Time || required == DateTimeOptionRequired::Any) {
    279         // a. For each of the property names "hour", "minute", "second":
    280         // i. Let prop be the property name.
    281         // ii. Let value be Get(options, prop).
    282         // iii. ReturnIfAbrupt(value).
    283         // iv. If value is not undefined, then let needDefaults be false.
    284         JSValue hour = options->get(&exec, vm.propertyNames->hour);
    285         if (exec.hadException())
    286             return nullptr;
    287         if (!hour.isUndefined())
    288             needDefaults = false;
    289 
    290         JSValue minute = options->get(&exec, vm.propertyNames->minute);
    291         if (exec.hadException())
    292             return nullptr;
    293         if (!minute.isUndefined())
    294             needDefaults = false;
    295 
    296         JSValue second = options->get(&exec, vm.propertyNames->second);
    297         if (exec.hadException())
    298             return nullptr;
    299         if (!second.isUndefined())
    300             needDefaults = false;
    301     }
     275    // Always "any".
     276
     277    // a. For each of the property names "hour", "minute", "second":
     278    // i. Let prop be the property name.
     279    // ii. Let value be Get(options, prop).
     280    // iii. ReturnIfAbrupt(value).
     281    // iv. If value is not undefined, then let needDefaults be false.
     282    JSValue hour = options->get(&exec, vm.propertyNames->hour);
     283    if (exec.hadException())
     284        return nullptr;
     285    if (!hour.isUndefined())
     286        needDefaults = false;
     287
     288    JSValue minute = options->get(&exec, vm.propertyNames->minute);
     289    if (exec.hadException())
     290        return nullptr;
     291    if (!minute.isUndefined())
     292        needDefaults = false;
     293
     294    JSValue second = options->get(&exec, vm.propertyNames->second);
     295    if (exec.hadException())
     296        return nullptr;
     297    if (!second.isUndefined())
     298        needDefaults = false;
    302299
    303300    // 7. If needDefaults is true and defaults is either "date" or "all", then
    304     if (needDefaults && (defaults == DateTimeOptionDefaults::Date || defaults == DateTimeOptionDefaults::All)) {
     301    // Defaults is always "date".
     302    if (needDefaults) {
    305303        // a. For each of the property names "year", "month", "day":
    306304        // i. Let status be CreateDatePropertyOrThrow(options, prop, "numeric").
    307305        // ii. ReturnIfAbrupt(status).
    308         options->putDirect(vm, vm.propertyNames->year, jsString(&exec, "numeric"));
     306        options->putDirect(vm, vm.propertyNames->year, jsNontrivialString(&exec, ASCIILiteral("numeric")));
    309307        if (exec.hadException())
    310308            return nullptr;
    311309
    312         options->putDirect(vm, vm.propertyNames->month, jsString(&exec, "numeric"));
     310        options->putDirect(vm, vm.propertyNames->month, jsNontrivialString(&exec, ASCIILiteral("numeric")));
    313311        if (exec.hadException())
    314312            return nullptr;
    315313
    316         options->putDirect(vm, vm.propertyNames->day, jsString(&exec, "numeric"));
     314        options->putDirect(vm, vm.propertyNames->day, jsNontrivialString(&exec, ASCIILiteral("numeric")));
    317315        if (exec.hadException())
    318316            return nullptr;
     
    320318
    321319    // 8. If needDefaults is true and defaults is either "time" or "all", then
    322     if (needDefaults && (defaults == DateTimeOptionDefaults::Time || defaults == DateTimeOptionDefaults::All)) {
    323         // a. For each of the property names "hour", "minute", "second":
    324         // i. Let status be CreateDatePropertyOrThrow(options, prop, "numeric").
    325         // ii. ReturnIfAbrupt(status).
    326         options->putDirect(vm, vm.propertyNames->hour, jsString(&exec, "numeric"));
    327         if (exec.hadException())
    328             return nullptr;
    329 
    330         options->putDirect(vm, vm.propertyNames->minute, jsString(&exec, "numeric"));
    331         if (exec.hadException())
    332             return nullptr;
    333 
    334         options->putDirect(vm, vm.propertyNames->second, jsString(&exec, "numeric"));
    335         if (exec.hadException())
    336             return nullptr;
    337     }
     320    // Defaults is always "date". Ignore this branch.
    338321
    339322    // 9. Return options.
     
    452435
    453436    // 5. Let options be ToDateTimeOptions(options, "any", "date").
    454     JSObject* options = toDateTimeOptions(exec, originalOptions, DateTimeOptionRequired::Any, DateTimeOptionDefaults::Date);
     437    JSObject* options = toDateTimeOptionsAnyDate(exec, originalOptions);
    455438    // 6. ReturnIfAbrupt(options).
    456439    if (exec.hadException())
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp

    r194838 r195138  
    520520    JSFunction* privateFuncHasInstanceBoundFunction = JSFunction::create(vm, this, 0, String(), hasInstanceBoundFunction);
    521521    JSFunction* privateFuncInstanceOf = JSFunction::create(vm, this, 0, String(), objectPrivateFuncInstanceOf);
     522    JSFunction* privateFuncThisTimeValue = JSFunction::create(vm, this, 0, String(), dateProtoFuncGetTime);
    522523
    523524    GlobalPropertyInfo staticGlobals[] = {
     
    578579        GlobalPropertyInfo(vm.propertyNames->MapPrivateName, mapConstructor, DontEnum | DontDelete | ReadOnly),
    579580        GlobalPropertyInfo(vm.propertyNames->builtinNames().generatorResumePrivateName(), JSFunction::createBuiltinFunction(vm, generatorPrototypeGeneratorResumeCodeGenerator(vm), this), DontEnum | DontDelete | ReadOnly),
     581        GlobalPropertyInfo(vm.propertyNames->builtinNames().thisTimeValuePrivateName(), privateFuncThisTimeValue, DontEnum | DontDelete | ReadOnly),
    580582#if ENABLE(INTL)
    581583        GlobalPropertyInfo(vm.propertyNames->builtinNames().CollatorPrivateName(), intl->getDirect(vm, vm.propertyNames->Collator), DontEnum | DontDelete | ReadOnly),
Note: See TracChangeset for help on using the changeset viewer.