[builtins] Update Array.p.toLocaleString to follow ECMA402

In JavaSCript implementations that supports ECMA-402,
`Array.prototype.toLocaleString()` must invoke the `toLocaleString` method of
each non-undefined, non-null elements witch exactly two (2) arguments.
See: https://tc39.es/ecma402/#sup-array.prototype.toLocaleString step 6.c.i.

V8 appears to provide no arguments when locale is undefined and to not provide options when options is undefined.

Bug: v8:13564
Change-Id: I655917210554d20d2eaebe2ac333421dd5d157ef
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4184564
Reviewed-by: Nikolaos Papaspyrou <nikolaos@chromium.org>
Auto-Submit: Juan José <soyjuanarbol@gmail.com>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/main@{#85588}
This commit is contained in:
Juan José Arboleda 2023-01-31 18:48:34 -05:00 committed by V8 LUCI CQ
parent 8509ab482e
commit 958f02bbc1
5 changed files with 32 additions and 15 deletions

View File

@ -69,13 +69,23 @@ transitioning builtin ConvertToLocaleString(
try {
const callable: Callable = Cast<Callable>(prop) otherwise TypeError;
let result: JSAny;
if (IsNullOrUndefined(locales)) {
result = Call(context, callable, element);
} else if (IsNullOrUndefined(options)) {
result = Call(context, callable, element, locales);
} else {
// According to the ECMA-402 specification, the optional arguments locales
// and options must be passed.
@if(V8_INTL_SUPPORT) {
result = Call(context, callable, element, locales, options);
}
// Without the ECMA-402 internationalization API, the optional arguments
// must not be passed.
// See: https://tc39.es/ecma262/#sec-array.prototype.tolocalestring
@ifnot(V8_INTL_SUPPORT) {
result = Call(context, callable, element);
// Use the remaining parameters.
const _locales = locales;
const _options = options;
}
return ToString_Inline(result);
} label TypeError {
ThrowTypeError(MessageTemplate::kCalledNonCallable, prop);

View File

@ -48,6 +48,11 @@ class BuildFlags : public ContextualClass<BuildFlags> {
build_flags_["V8_SFI_HAS_UNIQUE_ID"] = V8_SFI_HAS_UNIQUE_ID;
build_flags_["V8_EXTERNAL_CODE_SPACE"] = V8_EXTERNAL_CODE_SPACE_BOOL;
build_flags_["TAGGED_SIZE_8_BYTES"] = TAGGED_SIZE_8_BYTES;
#ifdef V8_INTL_SUPPORT
build_flags_["V8_INTL_SUPPORT"] = true;
#else
build_flags_["V8_INTL_SUPPORT"] = false;
#endif
build_flags_["V8_ENABLE_SWISS_NAME_DICTIONARY"] =
V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL;
#ifdef V8_ENABLE_JAVASCRIPT_PROMISE_HOOKS

View File

@ -172,8 +172,13 @@ assertEquals("42,42,42", (42).arrayToLocaleString());
String.prototype.toLocaleString = pushArgs("String");
Object.prototype.toLocaleString = pushArgs("Object");
[42, "foo", {}].toLocaleString();
assertEquals(["Number", [], "String", [], "Object", []], log);
// According to the ECMA-402 specification, the optional arguments locales
// and options must be passed. Without the ECMA-402 internationalization
// API, the optional arguments must not be passed.
const noArgs = (typeof Intl !== "object") ? [] : [undefined, undefined];
const result = [42, null, "foo", {}, undefined].toLocaleString();
assertEquals("2,,4,6,", result);
assertEquals(["Number", noArgs, "String", noArgs, "Object", noArgs], log);
Number.prototype.toLocaleString = NumberToLocaleString;
String.prototype.toLocaleString = StringToLocaleString;

View File

@ -91,8 +91,12 @@ for (var constructor of typedArrayConstructors) {
let NumberToLocaleString = Number.prototype.toLocaleString;
Number.prototype.toLocaleString = pushArgs("Number");
// According to the ECMA-402 specification, the optional arguments locales
// and options must be passed. Without the ECMA-402 internationalization
// API, the optional arguments must not be passed.
const noArgs = (typeof Intl !== "object") ? [] : [undefined, undefined];
(new constructor([1, 2])).toLocaleString();
assertEquals(["Number", [], "Number", []], log);
assertEquals(["Number", noArgs, "Number", noArgs], log);
Number.prototype.toLocaleString = NumberToLocaleString;
})();

View File

@ -992,10 +992,6 @@
'built-ins/Temporal/ZonedDateTime/prototype/since/nanoseconds-to-days-range-errors': [FAIL],
'built-ins/Temporal/ZonedDateTime/prototype/until/nanoseconds-to-days-range-errors': [FAIL],
# https://bugs.chromium.org/p/v8/issues/detail?id=13584
'intl402/Array/prototype/toLocaleString/invoke-element-tolocalestring': [FAIL],
# https://bugs.chromium.org/p/v8/issues/detail?id=12763
'language/statements/class/decorator/syntax/valid/class-element-decorator-call-expr-identifier-reference-yield': [FAIL],
'language/statements/class/decorator/syntax/valid/class-element-decorator-member-expr-identifier-reference-yield': [FAIL],
@ -1231,9 +1227,6 @@
'language/identifiers/start-unicode-8*': [FAIL],
'language/identifiers/start-unicode-9*': [FAIL],
# https://bugs.chromium.org/p/v8/issues/detail?id=13584
'built-ins/Array/prototype/toLocaleString/invoke-element-tolocalestring': [FAIL],
# Temporal staging test which use timeZone other than "UTC" or
# calendar other than "iso8601" which are not supported in no i18n mode.
'staging/Temporal/TimeZone/old/getInstantFor': [FAIL],