- Revision
- 273153
- Author
- ysuz...@apple.com
- Date
- 2021-02-19 11:38:57 -0800 (Fri, 19 Feb 2021)
Log Message
[JSC] Do not use toObject for options in new Intl constructors
https://bugs.webkit.org/show_bug.cgi?id=222164
Reviewed by Alexey Shvayka.
JSTests:
* stress/intl-get-options-not-using-toobject.js: Added.
(shouldThrow):
Source/_javascript_Core:
New spec change[1] introduced stricter GetOptionsObject for relatively new Intl constructors: Intl.DisplayNames, Intl.ListFormat, and Intl.Segmenter[2].
This does not perform `ToObject`, and instead,
1. If the input is an undefined, then it returns empty object.
2. If the input is an object, then it returns this object.
3. Otherwise, throwing a TypeError.
This patch implements it.
[1]: https://github.com/tc39/ecma402/pull/538
[2]: https://github.com/tc39/proposal-intl-segmenter/issues/132
* runtime/IntlDisplayNames.cpp:
(JSC::IntlDisplayNames::initializeDisplayNames):
* runtime/IntlListFormat.cpp:
(JSC::IntlListFormat::initializeListFormat):
* runtime/IntlObjectInlines.h:
(JSC::intlGetOptionsObject):
* runtime/IntlSegmenter.cpp:
(JSC::IntlSegmenter::initializeSegmenter):
Modified Paths
Added Paths
Diff
Modified: trunk/JSTests/ChangeLog (273152 => 273153)
--- trunk/JSTests/ChangeLog 2021-02-19 19:17:08 UTC (rev 273152)
+++ trunk/JSTests/ChangeLog 2021-02-19 19:38:57 UTC (rev 273153)
@@ -1,3 +1,13 @@
+2021-02-19 Yusuke Suzuki <ysuz...@apple.com>
+
+ [JSC] Do not use toObject for options in new Intl constructors
+ https://bugs.webkit.org/show_bug.cgi?id=222164
+
+ Reviewed by Alexey Shvayka.
+
+ * stress/intl-get-options-not-using-toobject.js: Added.
+ (shouldThrow):
+
2021-02-19 Caio Lima <ticaiol...@gmail.com>
[ESNext] Fix Test262 expectations for static private methods
Modified: trunk/JSTests/stress/intl-displaynames.js (273152 => 273153)
--- trunk/JSTests/stress/intl-displaynames.js 2021-02-19 19:17:08 UTC (rev 273152)
+++ trunk/JSTests/stress/intl-displaynames.js 2021-02-19 19:38:57 UTC (rev 273153)
@@ -21,7 +21,7 @@
if ($vm.icuVersion() >= 61) {
shouldBe(Intl.DisplayNames.length, 2);
- shouldThrow(() => new Intl.DisplayNames, `TypeError: undefined is not an object (evaluating 'new Intl.DisplayNames')`);
+ shouldThrow(() => new Intl.DisplayNames, `TypeError: type must not be undefined`);
// Get display names of region in English
var regionNames = new Intl.DisplayNames(['en'], {type: 'region'});
Added: trunk/JSTests/stress/intl-get-options-not-using-toobject.js (0 => 273153)
--- trunk/JSTests/stress/intl-get-options-not-using-toobject.js (rev 0)
+++ trunk/JSTests/stress/intl-get-options-not-using-toobject.js 2021-02-19 19:38:57 UTC (rev 273153)
@@ -0,0 +1,32 @@
+function shouldThrow(func, errorMessage) {
+ var errorThrown = false;
+ var error = null;
+ try {
+ func();
+ } catch (e) {
+ errorThrown = true;
+ error = e;
+ }
+ if (!errorThrown)
+ throw new Error('not thrown');
+ if (String(error) !== errorMessage)
+ throw new Error(`bad error: ${String(error)}`);
+}
+
+if (Intl.DisplayNames) {
+ shouldThrow(() => {
+ new Intl.DisplayNames('en', "Hello");
+ }, `TypeError: options argument is not an object or undefined`);
+}
+
+if (Intl.ListFormat) {
+ shouldThrow(() => {
+ new Intl.ListFormat('en', "Hello");
+ }, `TypeError: options argument is not an object or undefined`);
+}
+
+if (Intl.Segmenter) {
+ shouldThrow(() => {
+ new Intl.Segmenter('en', "Hello");
+ }, `TypeError: options argument is not an object or undefined`);
+}
Modified: trunk/Source/_javascript_Core/ChangeLog (273152 => 273153)
--- trunk/Source/_javascript_Core/ChangeLog 2021-02-19 19:17:08 UTC (rev 273152)
+++ trunk/Source/_javascript_Core/ChangeLog 2021-02-19 19:38:57 UTC (rev 273153)
@@ -1,3 +1,31 @@
+2021-02-19 Yusuke Suzuki <ysuz...@apple.com>
+
+ [JSC] Do not use toObject for options in new Intl constructors
+ https://bugs.webkit.org/show_bug.cgi?id=222164
+
+ Reviewed by Alexey Shvayka.
+
+ New spec change[1] introduced stricter GetOptionsObject for relatively new Intl constructors: Intl.DisplayNames, Intl.ListFormat, and Intl.Segmenter[2].
+ This does not perform `ToObject`, and instead,
+
+ 1. If the input is an undefined, then it returns empty object.
+ 2. If the input is an object, then it returns this object.
+ 3. Otherwise, throwing a TypeError.
+
+ This patch implements it.
+
+ [1]: https://github.com/tc39/ecma402/pull/538
+ [2]: https://github.com/tc39/proposal-intl-segmenter/issues/132
+
+ * runtime/IntlDisplayNames.cpp:
+ (JSC::IntlDisplayNames::initializeDisplayNames):
+ * runtime/IntlListFormat.cpp:
+ (JSC::IntlListFormat::initializeListFormat):
+ * runtime/IntlObjectInlines.h:
+ (JSC::intlGetOptionsObject):
+ * runtime/IntlSegmenter.cpp:
+ (JSC::IntlSegmenter::initializeSegmenter):
+
2021-02-19 Mark Lam <mark....@apple.com>
Need to rebase builtins generator tests results.
Modified: trunk/Source/_javascript_Core/runtime/IntlDisplayNames.cpp (273152 => 273153)
--- trunk/Source/_javascript_Core/runtime/IntlDisplayNames.cpp 2021-02-19 19:17:08 UTC (rev 273152)
+++ trunk/Source/_javascript_Core/runtime/IntlDisplayNames.cpp 2021-02-19 19:38:57 UTC (rev 273153)
@@ -69,7 +69,7 @@
auto requestedLocales = canonicalizeLocaleList(globalObject, locales);
RETURN_IF_EXCEPTION(scope, void());
- JSObject* options = optionsValue.toObject(globalObject);
+ JSObject* options = intlGetOptionsObject(globalObject, optionsValue);
RETURN_IF_EXCEPTION(scope, void());
// Does not set either of "ca" or "nu".
Modified: trunk/Source/_javascript_Core/runtime/IntlListFormat.cpp (273152 => 273153)
--- trunk/Source/_javascript_Core/runtime/IntlListFormat.cpp 2021-02-19 19:17:08 UTC (rev 273152)
+++ trunk/Source/_javascript_Core/runtime/IntlListFormat.cpp 2021-02-19 19:38:57 UTC (rev 273153)
@@ -91,13 +91,8 @@
auto requestedLocales = canonicalizeLocaleList(globalObject, locales);
RETURN_IF_EXCEPTION(scope, void());
- JSObject* options;
- if (optionsValue.isUndefined())
- options = constructEmptyObject(vm, globalObject->nullPrototypeObjectStructure());
- else {
- options = optionsValue.toObject(globalObject);
- RETURN_IF_EXCEPTION(scope, void());
- }
+ JSObject* options = intlGetOptionsObject(globalObject, optionsValue);
+ RETURN_IF_EXCEPTION(scope, void());
ResolveLocaleOptions localeOptions;
Modified: trunk/Source/_javascript_Core/runtime/IntlObjectInlines.h (273152 => 273153)
--- trunk/Source/_javascript_Core/runtime/IntlObjectInlines.h 2021-02-19 19:17:08 UTC (rev 273152)
+++ trunk/Source/_javascript_Core/runtime/IntlObjectInlines.h 2021-02-19 19:38:57 UTC (rev 273153)
@@ -30,6 +30,7 @@
#include "IntlObject.h"
#include "JSBoundFunction.h"
#include "JSObject.h"
+#include "ObjectConstructor.h"
#include <unicode/ucol.h>
namespace JSC {
@@ -180,4 +181,17 @@
return length1 > length2 ? UCOL_GREATER : UCOL_LESS;
}
+// https://tc39.es/ecma402/#sec-getoptionsobject
+inline JSObject* intlGetOptionsObject(JSGlobalObject* globalObject, JSValue options)
+{
+ VM& vm = globalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+ if (options.isUndefined())
+ return constructEmptyObject(vm, globalObject->nullPrototypeObjectStructure());
+ if (LIKELY(options.isObject()))
+ return asObject(options);
+ throwTypeError(globalObject, scope, "options argument is not an object or undefined"_s);
+ return nullptr;
+}
+
} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/IntlSegmenter.cpp (273152 => 273153)
--- trunk/Source/_javascript_Core/runtime/IntlSegmenter.cpp 2021-02-19 19:17:08 UTC (rev 273152)
+++ trunk/Source/_javascript_Core/runtime/IntlSegmenter.cpp 2021-02-19 19:38:57 UTC (rev 273153)
@@ -67,13 +67,8 @@
auto requestedLocales = canonicalizeLocaleList(globalObject, locales);
RETURN_IF_EXCEPTION(scope, void());
- JSObject* options;
- if (optionsValue.isUndefined())
- options = constructEmptyObject(vm, globalObject->nullPrototypeObjectStructure());
- else {
- options = optionsValue.toObject(globalObject);
- RETURN_IF_EXCEPTION(scope, void());
- }
+ JSObject* options = intlGetOptionsObject(globalObject, optionsValue);
+ RETURN_IF_EXCEPTION(scope, void());
ResolveLocaleOptions localeOptions;