Title: [193493] trunk
Revision
193493
Author
commit-qu...@webkit.org
Date
2015-12-04 17:14:03 -0800 (Fri, 04 Dec 2015)

Log Message

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

Patch by Andy VanWagoner <thetalecraf...@gmail.com> on 2015-12-04
Reviewed by Benjamin Poulain.

Source/_javascript_Core:

Add toLocaleString in builtin _javascript_ that delegates formatting to Intl.NumberFormat.
Keep exisiting native implementation for use if INTL flag is disabled.

* CMakeLists.txt: Add NumberPrototype.js.
* DerivedSources.make: Add NumberPrototype.js.
* _javascript_Core.xcodeproj/project.pbxproj:
* builtins/NumberPrototype.js: Added.
(toLocaleString):
* runtime/CommonIdentifiers.h: Add private names for Intl constructors.
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init): Expose Intl constructors to builtin js.
* runtime/NumberPrototype.cpp:
(JSC::NumberPrototype::finishCreation): Replace toLocaleString implementation.

LayoutTests:

Add tests for ECMA-402 Number.prototype.toLocaleString.
Since NumberFormat is not fully implemented, don't test locale-specific behavior yet.

* js/number-toLocaleString-expected.txt: Added.
* js/number-toLocaleString.html: Added.
* js/script-tests/number-toLocaleString.js: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (193492 => 193493)


--- trunk/LayoutTests/ChangeLog	2015-12-05 01:06:50 UTC (rev 193492)
+++ trunk/LayoutTests/ChangeLog	2015-12-05 01:14:03 UTC (rev 193493)
@@ -1,3 +1,17 @@
+2015-12-04  Andy VanWagoner  <thetalecraf...@gmail.com>
+
+        [INTL] Implement Number.prototype.toLocaleString in ECMA-402
+        https://bugs.webkit.org/show_bug.cgi?id=147610
+
+        Reviewed by Benjamin Poulain.
+
+        Add tests for ECMA-402 Number.prototype.toLocaleString.
+        Since NumberFormat is not fully implemented, don't test locale-specific behavior yet.
+
+        * js/number-toLocaleString-expected.txt: Added.
+        * js/number-toLocaleString.html: Added.
+        * js/script-tests/number-toLocaleString.js: Added.
+
 2015-12-04  Brady Eidson  <beid...@apple.com>
 
         Modern IDB: Flip test expectations around so we only list failures.

Added: trunk/LayoutTests/js/number-toLocaleString-expected.txt (0 => 193493)


--- trunk/LayoutTests/js/number-toLocaleString-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/js/number-toLocaleString-expected.txt	2015-12-05 01:14:03 UTC (rev 193493)
@@ -0,0 +1,25 @@
+This test checks the behavior of Number.prototype.toLocaleString as described in the ECMAScript Internationalization API Specification (ECMA-402 2.0).
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Number.prototype.toLocaleString.length is 0
+PASS Object.getOwnPropertyDescriptor(Number.prototype, 'toLocaleString').enumerable is false
+PASS Object.getOwnPropertyDescriptor(Number.prototype, 'toLocaleString').configurable is true
+PASS Object.getOwnPropertyDescriptor(Number.prototype, 'toLocaleString').writable is true
+PASS Number.prototype.toLocaleString.call(0) did not throw exception.
+PASS Number.prototype.toLocaleString.call(NaN) did not throw exception.
+PASS Number.prototype.toLocaleString.call(Infinity) did not throw exception.
+PASS Number.prototype.toLocaleString.call(new Number) did not throw exception.
+PASS Number.prototype.toLocaleString.call() threw exception TypeError: Number.prototype.toLocaleString called on incompatible undefined.
+PASS Number.prototype.toLocaleString.call(undefined) threw exception TypeError: Number.prototype.toLocaleString called on incompatible undefined.
+PASS Number.prototype.toLocaleString.call(null) threw exception TypeError: Number.prototype.toLocaleString called on incompatible object.
+PASS Number.prototype.toLocaleString.call('1') threw exception TypeError: Number.prototype.toLocaleString called on incompatible string.
+PASS Number.prototype.toLocaleString.call([]) threw exception TypeError: Number.prototype.toLocaleString called on incompatible object.
+PASS Number.prototype.toLocaleString.call(Symbol()) threw exception TypeError: Number.prototype.toLocaleString called on incompatible symbol.
+PASS (0).toLocaleString() is "0"
+PASS new Number(1).toLocaleString() is "1"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/js/number-toLocaleString.html (0 => 193493)


--- trunk/LayoutTests/js/number-toLocaleString.html	                        (rev 0)
+++ trunk/LayoutTests/js/number-toLocaleString.html	2015-12-05 01:14:03 UTC (rev 193493)
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<meta charset="utf-8">
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>

Added: trunk/LayoutTests/js/script-tests/number-toLocaleString.js (0 => 193493)


--- trunk/LayoutTests/js/script-tests/number-toLocaleString.js	                        (rev 0)
+++ trunk/LayoutTests/js/script-tests/number-toLocaleString.js	2015-12-05 01:14:03 UTC (rev 193493)
@@ -0,0 +1,32 @@
+description("This test checks the behavior of Number.prototype.toLocaleString as described in the ECMAScript Internationalization API Specification (ECMA-402 2.0).");
+
+shouldBe("Number.prototype.toLocaleString.length", "0");
+shouldBeFalse("Object.getOwnPropertyDescriptor(Number.prototype, 'toLocaleString').enumerable");
+shouldBeTrue("Object.getOwnPropertyDescriptor(Number.prototype, 'toLocaleString').configurable");
+shouldBeTrue("Object.getOwnPropertyDescriptor(Number.prototype, 'toLocaleString').writable");
+
+// Test thisNumberValue abrupt completion.
+shouldNotThrow("Number.prototype.toLocaleString.call(0)");
+shouldNotThrow("Number.prototype.toLocaleString.call(NaN)");
+shouldNotThrow("Number.prototype.toLocaleString.call(Infinity)");
+shouldNotThrow("Number.prototype.toLocaleString.call(new Number)");
+shouldThrow("Number.prototype.toLocaleString.call()", "'TypeError: Number.prototype.toLocaleString called on incompatible undefined'");
+shouldThrow("Number.prototype.toLocaleString.call(undefined)", "'TypeError: Number.prototype.toLocaleString called on incompatible undefined'");
+shouldThrow("Number.prototype.toLocaleString.call(null)", "'TypeError: Number.prototype.toLocaleString called on incompatible object'");
+shouldThrow("Number.prototype.toLocaleString.call('1')", "'TypeError: Number.prototype.toLocaleString called on incompatible string'");
+shouldThrow("Number.prototype.toLocaleString.call([])", "'TypeError: Number.prototype.toLocaleString called on incompatible object'");
+shouldThrow("Number.prototype.toLocaleString.call(Symbol())", "'TypeError: Number.prototype.toLocaleString called on incompatible symbol'");
+
+shouldBeEqualToString("(0).toLocaleString()", "0");
+shouldBeEqualToString("new Number(1).toLocaleString()", "1");
+
+// FIXME: Test for NumberFormat behavior once implemented.
+// shouldThrow("(0).toLocaleString('i')");
+// shouldBeEqualToString("Infinity.toLocaleString()", "∞");
+
+// Test that locale parameter is passed through properly.
+// shouldBeEqualToString("(123456.789).toLocaleString('ar')", "١٢٣٤٥٦٫٧٨٩");
+// shouldBeEqualToString("(123456.789).toLocaleString('zh-Hans-CN-u-nu-hanidec')", "一二三,四五六.七八九");
+
+// Test that options parameter is passed through properly.
+// shouldBeEqualToString("(123.456).toLocaleString('en', { maximumSignificantDigits: 3 })", "123");

Modified: trunk/Source/_javascript_Core/CMakeLists.txt (193492 => 193493)


--- trunk/Source/_javascript_Core/CMakeLists.txt	2015-12-05 01:06:50 UTC (rev 193492)
+++ trunk/Source/_javascript_Core/CMakeLists.txt	2015-12-05 01:14:03 UTC (rev 193493)
@@ -1225,6 +1225,7 @@
     ${_javascript_CORE_DIR}/builtins/InternalPromiseConstructor.js
     ${_javascript_CORE_DIR}/builtins/IteratorPrototype.js
     ${_javascript_CORE_DIR}/builtins/ModuleLoaderObject.js
+    ${_javascript_CORE_DIR}/builtins/NumberPrototype.js
     ${_javascript_CORE_DIR}/builtins/ObjectConstructor.js
     ${_javascript_CORE_DIR}/builtins/PromiseConstructor.js
     ${_javascript_CORE_DIR}/builtins/PromiseOperations.js

Modified: trunk/Source/_javascript_Core/ChangeLog (193492 => 193493)


--- trunk/Source/_javascript_Core/ChangeLog	2015-12-05 01:06:50 UTC (rev 193492)
+++ trunk/Source/_javascript_Core/ChangeLog	2015-12-05 01:14:03 UTC (rev 193493)
@@ -1,3 +1,24 @@
+2015-12-04  Andy VanWagoner  <thetalecraf...@gmail.com>
+
+        [INTL] Implement Number.prototype.toLocaleString in ECMA-402
+        https://bugs.webkit.org/show_bug.cgi?id=147610
+
+        Reviewed by Benjamin Poulain.
+
+        Add toLocaleString in builtin _javascript_ that delegates formatting to Intl.NumberFormat.
+        Keep exisiting native implementation for use if INTL flag is disabled.
+
+        * CMakeLists.txt: Add NumberPrototype.js.
+        * DerivedSources.make: Add NumberPrototype.js.
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * builtins/NumberPrototype.js: Added.
+        (toLocaleString):
+        * runtime/CommonIdentifiers.h: Add private names for Intl constructors.
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init): Expose Intl constructors to builtin js.
+        * runtime/NumberPrototype.cpp:
+        (JSC::NumberPrototype::finishCreation): Replace toLocaleString implementation.
+
 2015-12-04  Michael Saboff  <msab...@apple.com>
 
         CRASH: CodeBlock::setOptimizationThresholdBasedOnCompilationResult + 567

Modified: trunk/Source/_javascript_Core/DerivedSources.make (193492 => 193493)


--- trunk/Source/_javascript_Core/DerivedSources.make	2015-12-05 01:06:50 UTC (rev 193492)
+++ trunk/Source/_javascript_Core/DerivedSources.make	2015-12-05 01:14:03 UTC (rev 193493)
@@ -90,6 +90,7 @@
     $(_javascript_Core)/builtins/InternalPromiseConstructor.js \
     $(_javascript_Core)/builtins/IteratorPrototype.js \
     $(_javascript_Core)/builtins/ModuleLoaderObject.js \
+    $(_javascript_Core)/builtins/NumberPrototype.js \
     $(_javascript_Core)/builtins/ObjectConstructor.js \
     $(_javascript_Core)/builtins/PromiseConstructor.js \
     $(_javascript_Core)/builtins/PromiseOperations.js \

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (193492 => 193493)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2015-12-05 01:06:50 UTC (rev 193492)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2015-12-05 01:14:03 UTC (rev 193493)
@@ -3606,6 +3606,7 @@
 		A1587D6C1B4DC14100D69849 /* IntlDateTimeFormatPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntlDateTimeFormatPrototype.h; sourceTree = "<group>"; };
 		A1587D731B4DC1C600D69849 /* IntlDateTimeFormatConstructor.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntlDateTimeFormatConstructor.lut.h; sourceTree = "<group>"; };
 		A1587D741B4DC1C600D69849 /* IntlDateTimeFormatPrototype.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntlDateTimeFormatPrototype.lut.h; sourceTree = "<group>"; };
+		A15DE5C51C0FBF8D0089133D /* NumberPrototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; path = NumberPrototype.js; sourceTree = "<group>"; };
 		A1712B3A11C7B212007A5315 /* RegExpCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegExpCache.cpp; sourceTree = "<group>"; };
 		A1712B3E11C7B228007A5315 /* RegExpCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpCache.h; sourceTree = "<group>"; };
 		A1712B4011C7B235007A5315 /* RegExpKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpKey.h; sourceTree = "<group>"; };
@@ -6666,6 +6667,7 @@
 				E33F50881B844A1A00413856 /* InternalPromiseConstructor.js */,
 				7CF9BC5B1B65D9A3009DB1EF /* IteratorPrototype.js */,
 				E30677971B8BC6F5003F87F0 /* ModuleLoaderObject.js */,
+				A15DE5C51C0FBF8D0089133D /* NumberPrototype.js */,
 				7CF9BC5C1B65D9B1009DB1EF /* ObjectConstructor.js */,
 				7CF9BC5D1B65D9B1009DB1EF /* PromiseOperations.js */,
 				7CFBAC1C18B535E500D00750 /* PromisePrototype.js */,

Added: trunk/Source/_javascript_Core/builtins/NumberPrototype.js (0 => 193493)


--- trunk/Source/_javascript_Core/builtins/NumberPrototype.js	                        (rev 0)
+++ trunk/Source/_javascript_Core/builtins/NumberPrototype.js	2015-12-05 01:14:03 UTC (rev 193493)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2015 Andy VanWagoner <thetalecraf...@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// @conditional=ENABLE(INTL)
+
+function toLocaleString(/* locales, options */)
+{
+    "use strict";
+
+    // 13.2.1 Number.prototype.toLocaleString ([locales [, options ]]) (ECMA-402 2.0)
+    // http://ecma-international.org/publications/standards/Ecma-402.htm
+
+    // 1. Let x be thisNumberValue(this value).
+    // 2. ReturnIfAbrupt(x).
+    var number = this;
+    if (!(typeof number === "number" || number instanceof Number))
+        throw new @TypeError("Number.prototype.toLocaleString called on incompatible " + typeof number);
+
+    // 3. Let numberFormat be Construct(%NumberFormat%, «locales, options»).
+    // 4. ReturnIfAbrupt(numberFormat).
+    var numberFormat = new @NumberFormat(arguments[0], arguments[1]);
+
+    // 5. Return FormatNumber(numberFormat, x).
+    return numberFormat.format(number);
+}

Modified: trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h (193492 => 193493)


--- trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h	2015-12-05 01:06:50 UTC (rev 193492)
+++ trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h	2015-12-05 01:14:03 UTC (rev 193493)
@@ -338,6 +338,9 @@
     macro(generatorValue) \
     macro(generatorThis) \
     macro(generatorResumeMode) \
+    macro(Collator) \
+    macro(DateTimeFormat) \
+    macro(NumberFormat) \
 
 
 namespace JSC {

Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp (193492 => 193493)


--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp	2015-12-05 01:06:50 UTC (rev 193492)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp	2015-12-05 01:14:03 UTC (rev 193493)
@@ -468,7 +468,8 @@
     putDirectWithoutTransition(vm, vm.propertyNames->eval, m_evalFunction.get(), DontEnum);
     
 #if ENABLE(INTL)
-    putDirectWithoutTransition(vm, vm.propertyNames->Intl, IntlObject::create(vm, this, IntlObject::createStructure(vm, this, m_objectPrototype.get())), DontEnum);
+    IntlObject* intl = IntlObject::create(vm, this, IntlObject::createStructure(vm, this, m_objectPrototype.get()));
+    putDirectWithoutTransition(vm, vm.propertyNames->Intl, intl, DontEnum);
 #endif // ENABLE(INTL)
     putDirectWithoutTransition(vm, vm.propertyNames->JSON, JSONObject::create(vm, JSONObject::createStructure(vm, this, m_objectPrototype.get())), DontEnum);
     putDirectWithoutTransition(vm, vm.propertyNames->Math, MathObject::create(vm, this, MathObject::createStructure(vm, this, m_objectPrototype.get())), DontEnum);
@@ -567,6 +568,11 @@
         GlobalPropertyInfo(vm.propertyNames->builtinNames().InspectorInstrumentationPrivateName(), InspectorInstrumentationObject::create(vm, this, InspectorInstrumentationObject::createStructure(vm, this, m_objectPrototype.get())), DontEnum | DontDelete | ReadOnly),
         GlobalPropertyInfo(vm.propertyNames->MapPrivateName, mapConstructor, DontEnum | DontDelete | ReadOnly),
         GlobalPropertyInfo(vm.propertyNames->builtinNames().generatorResumePrivateName(), JSFunction::createBuiltinFunction(vm, generatorPrototypeGeneratorResumeCodeGenerator(vm), this), DontEnum | DontDelete | ReadOnly),
+#if ENABLE(INTL)
+        GlobalPropertyInfo(vm.propertyNames->builtinNames().CollatorPrivateName(), intl->getDirect(vm, vm.propertyNames->Collator), DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->builtinNames().DateTimeFormatPrivateName(), intl->getDirect(vm, vm.propertyNames->DateTimeFormat), DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->builtinNames().NumberFormatPrivateName(), intl->getDirect(vm, vm.propertyNames->NumberFormat), DontEnum | DontDelete | ReadOnly),
+#endif // ENABLE(INTL)
     };
     addStaticGlobals(staticGlobals, WTF_ARRAY_LENGTH(staticGlobals));
     

Modified: trunk/Source/_javascript_Core/runtime/NumberPrototype.cpp (193492 => 193493)


--- trunk/Source/_javascript_Core/runtime/NumberPrototype.cpp	2015-12-05 01:06:50 UTC (rev 193492)
+++ trunk/Source/_javascript_Core/runtime/NumberPrototype.cpp	2015-12-05 01:14:03 UTC (rev 193493)
@@ -24,10 +24,11 @@
 
 #include "BigInteger.h"
 #include "Error.h"
+#include "JSCBuiltins.h"
+#include "JSCInlines.h"
 #include "JSFunction.h"
 #include "JSGlobalObject.h"
 #include "JSString.h"
-#include "JSCInlines.h"
 #include "Uint16WithFraction.h"
 #include <wtf/dtoa.h>
 #include <wtf/Assertions.h>
@@ -75,11 +76,15 @@
 {
 }
 
-void NumberPrototype::finishCreation(VM& vm, JSGlobalObject*)
+void NumberPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)
 {
     Base::finishCreation(vm);
     setInternalValue(vm, jsNumber(0));
 
+#if ENABLE(INTL)
+    JSC_BUILTIN_FUNCTION("toLocaleString", numberPrototypeToLocaleStringCodeGenerator, DontEnum);
+#endif // ENABLE(INTL)
+
     ASSERT(inherits(info()));
 }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to