Commit 8bc2cfb7 authored by Frank Tang's avatar Frank Tang Committed by Commit Bot

Implement GetOptionsObject/CoerceOptionsToObject

Add GetOptionsObject/CoerceOptionsToObject for ECMA402 2021
Change Intl.ListFormat / Intl.DisplayNames and Intl.Segmenter
to use GetOptionsObject and keep old API under CoerceOptionsToObject
based on https://github.com/tc39/ecma402/pull/538/files

Test262 tests need to be changed per
https://github.com/tc39/test262/issues/2950

Bug: v8:11466
Change-Id: I5cb9b7aba0556effc76b4005e95c90db1e59d41f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2705696
Commit-Queue: Frank Tang <ftang@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#73082}
parent ae13b85b
...@@ -608,11 +608,12 @@ BUILTIN(LocaleConstructor) { ...@@ -608,11 +608,12 @@ BUILTIN(LocaleConstructor) {
isolate->CountUsage(v8::Isolate::UseCounterFeature::kLocale); isolate->CountUsage(v8::Isolate::UseCounterFeature::kLocale);
const char* method = "Intl.Locale";
if (args.new_target()->IsUndefined(isolate)) { // [[Call]] if (args.new_target()->IsUndefined(isolate)) { // [[Call]]
THROW_NEW_ERROR_RETURN_FAILURE( THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kConstructorNotFunction, isolate,
isolate->factory()->NewStringFromAsciiChecked( NewTypeError(MessageTemplate::kConstructorNotFunction,
"Intl.Locale"))); isolate->factory()->NewStringFromAsciiChecked(method)));
} }
// [[Construct]] // [[Construct]]
Handle<JSFunction> target = args.target(); Handle<JSFunction> target = args.target();
...@@ -645,16 +646,11 @@ BUILTIN(LocaleConstructor) { ...@@ -645,16 +646,11 @@ BUILTIN(LocaleConstructor) {
Object::ToString(isolate, tag)); Object::ToString(isolate, tag));
} }
// 10. Set options to ? CoerceOptionsToObject(options).
Handle<JSReceiver> options_object; Handle<JSReceiver> options_object;
// 10. If options is undefined, then ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
if (options->IsUndefined(isolate)) { isolate, options_object,
// a. Let options be ! ObjectCreate(null). Intl::CoerceOptionsToObject(isolate, options, method));
options_object = isolate->factory()->NewJSObjectWithNullProto();
} else { // 11. Else
// a. Let options be ? ToObject(options).
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, options_object,
Object::ToObject(isolate, options));
}
RETURN_RESULT_OR_FAILURE( RETURN_RESULT_OR_FAILURE(
isolate, JSLocale::New(isolate, map, locale_string, options_object)); isolate, JSLocale::New(isolate, map, locale_string, options_object));
......
...@@ -1611,23 +1611,18 @@ MaybeHandle<JSObject> SupportedLocales( ...@@ -1611,23 +1611,18 @@ MaybeHandle<JSObject> SupportedLocales(
const std::vector<std::string>& requested_locales, Handle<Object> options) { const std::vector<std::string>& requested_locales, Handle<Object> options) {
std::vector<std::string> supported_locales; std::vector<std::string> supported_locales;
// 2. Else, let matcher be "best fit". // 1. Set options to ? CoerceOptionsToObject(options).
Intl::MatcherOption matcher = Intl::MatcherOption::kBestFit;
// 1. If options is not undefined, then
if (!options->IsUndefined(isolate)) {
// 1. a. Let options be ? ToObject(options).
Handle<JSReceiver> options_obj; Handle<JSReceiver> options_obj;
ASSIGN_RETURN_ON_EXCEPTION(isolate, options_obj, ASSIGN_RETURN_ON_EXCEPTION(
Object::ToObject(isolate, options), JSObject); isolate, options_obj,
Intl::CoerceOptionsToObject(isolate, options, method), JSObject);
// 1. b. Let matcher be ? GetOption(options, "localeMatcher", "string", // 2. Let matcher be ? GetOption(options, "localeMatcher", "string",
// « "lookup", "best fit" », "best fit"). // « "lookup", "best fit" », "best fit").
Maybe<Intl::MatcherOption> maybe_locale_matcher = Maybe<Intl::MatcherOption> maybe_locale_matcher =
Intl::GetLocaleMatcher(isolate, options_obj, method); Intl::GetLocaleMatcher(isolate, options_obj, method);
MAYBE_RETURN(maybe_locale_matcher, MaybeHandle<JSObject>()); MAYBE_RETURN(maybe_locale_matcher, MaybeHandle<JSObject>());
matcher = maybe_locale_matcher.FromJust(); Intl::MatcherOption matcher = maybe_locale_matcher.FromJust();
}
// 3. If matcher is "best fit", then // 3. If matcher is "best fit", then
// a. Let supportedLocales be BestFitSupportedLocales(availableLocales, // a. Let supportedLocales be BestFitSupportedLocales(availableLocales,
...@@ -2218,6 +2213,40 @@ MaybeHandle<String> Intl::FormattedToString( ...@@ -2218,6 +2213,40 @@ MaybeHandle<String> Intl::FormattedToString(
return Intl::ToString(isolate, result); return Intl::ToString(isolate, result);
} }
// ecma402/#sec-getoptionsobject
MaybeHandle<JSReceiver> Intl::GetOptionsObject(Isolate* isolate,
Handle<Object> options,
const char* service) {
// 1. If options is undefined, then
if (options->IsUndefined(isolate)) {
// a. Return ! ObjectCreate(null).
return isolate->factory()->NewJSObjectWithNullProto();
}
// 2. If Type(options) is Object, then
if (options->IsJSReceiver()) {
// a. Return options.
return Handle<JSReceiver>::cast(options);
}
// 3. Throw a TypeError exception.
THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kInvalidArgument),
JSReceiver);
}
// ecma402/#sec-coerceoptionstoobject
MaybeHandle<JSReceiver> Intl::CoerceOptionsToObject(Isolate* isolate,
Handle<Object> options,
const char* service) {
// 1. If options is undefined, then
if (options->IsUndefined(isolate)) {
// a. Return ! ObjectCreate(null).
return isolate->factory()->NewJSObjectWithNullProto();
}
// 2. Return ? ToObject(options).
ASSIGN_RETURN_ON_EXCEPTION(isolate, options,
Object::ToObject(isolate, options, service),
JSReceiver);
return Handle<JSReceiver>::cast(options);
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -330,6 +330,14 @@ class Intl { ...@@ -330,6 +330,14 @@ class Intl {
static const std::set<std::string>& GetAvailableLocales(); static const std::set<std::string>& GetAvailableLocales();
static const std::set<std::string>& GetAvailableLocalesForDateFormat(); static const std::set<std::string>& GetAvailableLocalesForDateFormat();
// ecma402/#sec-getoptionsobject
V8_WARN_UNUSED_RESULT static MaybeHandle<JSReceiver> GetOptionsObject(
Isolate* isolate, Handle<Object> options, const char* service);
// ecma402/#sec-coerceoptionstoobject
V8_WARN_UNUSED_RESULT static MaybeHandle<JSReceiver> CoerceOptionsToObject(
Isolate* isolate, Handle<Object> options, const char* service);
}; };
} // namespace internal } // namespace internal
......
...@@ -283,20 +283,11 @@ MaybeHandle<JSCollator> JSCollator::New(Isolate* isolate, Handle<Map> map, ...@@ -283,20 +283,11 @@ MaybeHandle<JSCollator> JSCollator::New(Isolate* isolate, Handle<Map> map,
std::vector<std::string> requested_locales = std::vector<std::string> requested_locales =
maybe_requested_locales.FromJust(); maybe_requested_locales.FromJust();
// 2. If options is undefined, then // 2. Set options to ? CoerceOptionsToObject(options).
if (options_obj->IsUndefined(isolate)) { Handle<JSReceiver> options;
// 2. a. Let options be ObjectCreate(null). ASSIGN_RETURN_ON_EXCEPTION(
options_obj = isolate->factory()->NewJSObjectWithNullProto(); isolate, options,
} else { Intl::CoerceOptionsToObject(isolate, options_obj, service), JSCollator);
// 3. Else
// 3. a. Let options be ? ToObject(options).
ASSIGN_RETURN_ON_EXCEPTION(isolate, options_obj,
Object::ToObject(isolate, options_obj, service),
JSCollator);
}
// At this point, options_obj can either be a JSObject or a JSProxy only.
Handle<JSReceiver> options = Handle<JSReceiver>::cast(options_obj);
// 4. Let usage be ? GetOption(options, "usage", "string", « "sort", // 4. Let usage be ? GetOption(options, "usage", "string", « "sort",
// "search" », "sort"). // "search" », "sort").
......
...@@ -506,9 +506,9 @@ MaybeHandle<JSDisplayNames> JSDisplayNames::New(Isolate* isolate, ...@@ -506,9 +506,9 @@ MaybeHandle<JSDisplayNames> JSDisplayNames::New(Isolate* isolate,
std::vector<std::string> requested_locales = std::vector<std::string> requested_locales =
maybe_requested_locales.FromJust(); maybe_requested_locales.FromJust();
// 4. Let options be ? ToObject(options). // 4. Let options be ? GetOptionsObject(options).
ASSIGN_RETURN_ON_EXCEPTION(isolate, options, ASSIGN_RETURN_ON_EXCEPTION(
Object::ToObject(isolate, input_options), isolate, options, Intl::GetOptionsObject(isolate, input_options, service),
JSDisplayNames); JSDisplayNames);
// Note: No need to create a record. It's not observable. // Note: No need to create a record. It's not observable.
...@@ -519,7 +519,7 @@ MaybeHandle<JSDisplayNames> JSDisplayNames::New(Isolate* isolate, ...@@ -519,7 +519,7 @@ MaybeHandle<JSDisplayNames> JSDisplayNames::New(Isolate* isolate,
// 7. Let matcher be ? GetOption(options, "localeMatcher", "string", « // 7. Let matcher be ? GetOption(options, "localeMatcher", "string", «
// "lookup", "best fit" », "best fit"). // "lookup", "best fit" », "best fit").
Maybe<Intl::MatcherOption> maybe_locale_matcher = Maybe<Intl::MatcherOption> maybe_locale_matcher =
Intl::GetLocaleMatcher(isolate, options, "Intl.DisplayNames"); Intl::GetLocaleMatcher(isolate, options, service);
MAYBE_RETURN(maybe_locale_matcher, MaybeHandle<JSDisplayNames>()); MAYBE_RETURN(maybe_locale_matcher, MaybeHandle<JSDisplayNames>());
// 8. Set opt.[[localeMatcher]] to matcher. // 8. Set opt.[[localeMatcher]] to matcher.
...@@ -579,8 +579,7 @@ MaybeHandle<JSDisplayNames> JSDisplayNames::New(Isolate* isolate, ...@@ -579,8 +579,7 @@ MaybeHandle<JSDisplayNames> JSDisplayNames::New(Isolate* isolate,
// 10. Let s be ? GetOption(options, "style", "string", // 10. Let s be ? GetOption(options, "style", "string",
// «"long", "short", "narrow"», "long"). // «"long", "short", "narrow"», "long").
Maybe<Style> maybe_style = Intl::GetStringOption<Style>( Maybe<Style> maybe_style = Intl::GetStringOption<Style>(
isolate, options, "style", "Intl.DisplayNames", isolate, options, "style", service, {"long", "short", "narrow"},
{"long", "short", "narrow"},
{Style::kLong, Style::kShort, Style::kNarrow}, Style::kLong); {Style::kLong, Style::kShort, Style::kNarrow}, Style::kLong);
MAYBE_RETURN(maybe_style, MaybeHandle<JSDisplayNames>()); MAYBE_RETURN(maybe_style, MaybeHandle<JSDisplayNames>());
Style style_enum = maybe_style.FromJust(); Style style_enum = maybe_style.FromJust();
...@@ -593,7 +592,7 @@ MaybeHandle<JSDisplayNames> JSDisplayNames::New(Isolate* isolate, ...@@ -593,7 +592,7 @@ MaybeHandle<JSDisplayNames> JSDisplayNames::New(Isolate* isolate,
Maybe<Type> maybe_type = Maybe<Type> maybe_type =
FLAG_harmony_intl_displaynames_date_types FLAG_harmony_intl_displaynames_date_types
? Intl::GetStringOption<Type>( ? Intl::GetStringOption<Type>(
isolate, options, "type", "Intl.DisplayNames", isolate, options, "type", service,
{"language", "region", "script", "currency", "weekday", "month", {"language", "region", "script", "currency", "weekday", "month",
"quarter", "dayPeriod", "dateTimeField"}, "quarter", "dayPeriod", "dateTimeField"},
{ {
...@@ -609,7 +608,7 @@ MaybeHandle<JSDisplayNames> JSDisplayNames::New(Isolate* isolate, ...@@ -609,7 +608,7 @@ MaybeHandle<JSDisplayNames> JSDisplayNames::New(Isolate* isolate,
}, },
Type::kUndefined) Type::kUndefined)
: Intl::GetStringOption<Type>( : Intl::GetStringOption<Type>(
isolate, options, "type", "Intl.DisplayNames", isolate, options, "type", service,
{"language", "region", "script", "currency"}, {"language", "region", "script", "currency"},
{ {
Type::kLanguage, Type::kLanguage,
...@@ -632,7 +631,7 @@ MaybeHandle<JSDisplayNames> JSDisplayNames::New(Isolate* isolate, ...@@ -632,7 +631,7 @@ MaybeHandle<JSDisplayNames> JSDisplayNames::New(Isolate* isolate,
// 15. Let fallback be ? GetOption(options, "fallback", "string", // 15. Let fallback be ? GetOption(options, "fallback", "string",
// « "code", "none" », "code"). // « "code", "none" », "code").
Maybe<Fallback> maybe_fallback = Intl::GetStringOption<Fallback>( Maybe<Fallback> maybe_fallback = Intl::GetStringOption<Fallback>(
isolate, options, "fallback", "Intl.DisplayNames", {"code", "none"}, isolate, options, "fallback", service, {"code", "none"},
{Fallback::kCode, Fallback::kNone}, Fallback::kCode); {Fallback::kCode, Fallback::kNone}, Fallback::kCode);
MAYBE_RETURN(maybe_fallback, MaybeHandle<JSDisplayNames>()); MAYBE_RETURN(maybe_fallback, MaybeHandle<JSDisplayNames>());
Fallback fallback_enum = maybe_fallback.FromJust(); Fallback fallback_enum = maybe_fallback.FromJust();
......
...@@ -59,7 +59,6 @@ UListFormatterType GetIcuType(JSListFormat::Type type) { ...@@ -59,7 +59,6 @@ UListFormatterType GetIcuType(JSListFormat::Type type) {
MaybeHandle<JSListFormat> JSListFormat::New(Isolate* isolate, Handle<Map> map, MaybeHandle<JSListFormat> JSListFormat::New(Isolate* isolate, Handle<Map> map,
Handle<Object> locales, Handle<Object> locales,
Handle<Object> input_options) { Handle<Object> input_options) {
Handle<JSReceiver> options;
// 3. Let requestedLocales be ? CanonicalizeLocaleList(locales). // 3. Let requestedLocales be ? CanonicalizeLocaleList(locales).
Maybe<std::vector<std::string>> maybe_requested_locales = Maybe<std::vector<std::string>> maybe_requested_locales =
Intl::CanonicalizeLocaleList(isolate, locales); Intl::CanonicalizeLocaleList(isolate, locales);
...@@ -67,17 +66,12 @@ MaybeHandle<JSListFormat> JSListFormat::New(Isolate* isolate, Handle<Map> map, ...@@ -67,17 +66,12 @@ MaybeHandle<JSListFormat> JSListFormat::New(Isolate* isolate, Handle<Map> map,
std::vector<std::string> requested_locales = std::vector<std::string> requested_locales =
maybe_requested_locales.FromJust(); maybe_requested_locales.FromJust();
// 4. If options is undefined, then Handle<JSReceiver> options;
if (input_options->IsUndefined(isolate)) { const char* service = "Intl.ListFormat";
// 4. a. Let options be ObjectCreate(null). // 4. Let options be GetOptionsObject(_options_).
options = isolate->factory()->NewJSObjectWithNullProto(); ASSIGN_RETURN_ON_EXCEPTION(
// 5. Else isolate, options, Intl::GetOptionsObject(isolate, input_options, service),
} else {
// 5. a. Let options be ? ToObject(options).
ASSIGN_RETURN_ON_EXCEPTION(isolate, options,
Object::ToObject(isolate, input_options),
JSListFormat); JSListFormat);
}
// Note: No need to create a record. It's not observable. // Note: No need to create a record. It's not observable.
// 6. Let opt be a new Record. // 6. Let opt be a new Record.
...@@ -85,7 +79,7 @@ MaybeHandle<JSListFormat> JSListFormat::New(Isolate* isolate, Handle<Map> map, ...@@ -85,7 +79,7 @@ MaybeHandle<JSListFormat> JSListFormat::New(Isolate* isolate, Handle<Map> map,
// 7. Let matcher be ? GetOption(options, "localeMatcher", "string", « // 7. Let matcher be ? GetOption(options, "localeMatcher", "string", «
// "lookup", "best fit" », "best fit"). // "lookup", "best fit" », "best fit").
Maybe<Intl::MatcherOption> maybe_locale_matcher = Maybe<Intl::MatcherOption> maybe_locale_matcher =
Intl::GetLocaleMatcher(isolate, options, "Intl.ListFormat"); Intl::GetLocaleMatcher(isolate, options, service);
MAYBE_RETURN(maybe_locale_matcher, MaybeHandle<JSListFormat>()); MAYBE_RETURN(maybe_locale_matcher, MaybeHandle<JSListFormat>());
// 8. Set opt.[[localeMatcher]] to matcher. // 8. Set opt.[[localeMatcher]] to matcher.
...@@ -107,8 +101,7 @@ MaybeHandle<JSListFormat> JSListFormat::New(Isolate* isolate, Handle<Map> map, ...@@ -107,8 +101,7 @@ MaybeHandle<JSListFormat> JSListFormat::New(Isolate* isolate, Handle<Map> map,
// 12. Let t be GetOption(options, "type", "string", «"conjunction", // 12. Let t be GetOption(options, "type", "string", «"conjunction",
// "disjunction", "unit"», "conjunction"). // "disjunction", "unit"», "conjunction").
Maybe<Type> maybe_type = Intl::GetStringOption<Type>( Maybe<Type> maybe_type = Intl::GetStringOption<Type>(
isolate, options, "type", "Intl.ListFormat", isolate, options, "type", service, {"conjunction", "disjunction", "unit"},
{"conjunction", "disjunction", "unit"},
{Type::CONJUNCTION, Type::DISJUNCTION, Type::UNIT}, Type::CONJUNCTION); {Type::CONJUNCTION, Type::DISJUNCTION, Type::UNIT}, Type::CONJUNCTION);
MAYBE_RETURN(maybe_type, MaybeHandle<JSListFormat>()); MAYBE_RETURN(maybe_type, MaybeHandle<JSListFormat>());
Type type_enum = maybe_type.FromJust(); Type type_enum = maybe_type.FromJust();
...@@ -116,7 +109,7 @@ MaybeHandle<JSListFormat> JSListFormat::New(Isolate* isolate, Handle<Map> map, ...@@ -116,7 +109,7 @@ MaybeHandle<JSListFormat> JSListFormat::New(Isolate* isolate, Handle<Map> map,
// 14. Let s be ? GetOption(options, "style", "string", // 14. Let s be ? GetOption(options, "style", "string",
// «"long", "short", "narrow"», "long"). // «"long", "short", "narrow"», "long").
Maybe<Style> maybe_style = Intl::GetStringOption<Style>( Maybe<Style> maybe_style = Intl::GetStringOption<Style>(
isolate, options, "style", "Intl.ListFormat", {"long", "short", "narrow"}, isolate, options, "style", service, {"long", "short", "narrow"},
{Style::LONG, Style::SHORT, Style::NARROW}, Style::LONG); {Style::LONG, Style::SHORT, Style::NARROW}, Style::LONG);
MAYBE_RETURN(maybe_style, MaybeHandle<JSListFormat>()); MAYBE_RETURN(maybe_style, MaybeHandle<JSListFormat>());
Style style_enum = maybe_style.FromJust(); Style style_enum = maybe_style.FromJust();
......
...@@ -829,20 +829,12 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate, ...@@ -829,20 +829,12 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate,
std::vector<std::string> requested_locales = std::vector<std::string> requested_locales =
maybe_requested_locales.FromJust(); maybe_requested_locales.FromJust();
// 2. If options is undefined, then // 2. Set options to ? CoerceOptionsToObject(options).
if (options_obj->IsUndefined(isolate)) { Handle<JSReceiver> options;
// 2. a. Let options be ObjectCreate(null). ASSIGN_RETURN_ON_EXCEPTION(
options_obj = isolate->factory()->NewJSObjectWithNullProto(); isolate, options,
} else { Intl::CoerceOptionsToObject(isolate, options_obj, service),
// 3. Else
// 3. a. Let options be ? ToObject(options).
ASSIGN_RETURN_ON_EXCEPTION(isolate, options_obj,
Object::ToObject(isolate, options_obj, service),
JSNumberFormat); JSNumberFormat);
}
// At this point, options_obj can either be a JSObject or a JSProxy only.
Handle<JSReceiver> options = Handle<JSReceiver>::cast(options_obj);
// 4. Let opt be a new Record. // 4. Let opt be a new Record.
// 5. Let matcher be ? GetOption(options, "localeMatcher", "string", « // 5. Let matcher be ? GetOption(options, "localeMatcher", "string", «
......
...@@ -70,34 +70,26 @@ MaybeHandle<JSPluralRules> JSPluralRules::New(Isolate* isolate, Handle<Map> map, ...@@ -70,34 +70,26 @@ MaybeHandle<JSPluralRules> JSPluralRules::New(Isolate* isolate, Handle<Map> map,
std::vector<std::string> requested_locales = std::vector<std::string> requested_locales =
maybe_requested_locales.FromJust(); maybe_requested_locales.FromJust();
// 2. If options is undefined, then // 2. Set options to ? CoerceOptionsToObject(options).
if (options_obj->IsUndefined(isolate)) { Handle<JSReceiver> options;
// 2. a. Let options be ObjectCreate(null). const char* service = "Intl.PluralRules";
options_obj = isolate->factory()->NewJSObjectWithNullProto();
} else {
// 3. Else
// 3. a. Let options be ? ToObject(options).
ASSIGN_RETURN_ON_EXCEPTION( ASSIGN_RETURN_ON_EXCEPTION(
isolate, options_obj, isolate, options,
Object::ToObject(isolate, options_obj, "Intl.PluralRules"), Intl::CoerceOptionsToObject(isolate, options_obj, service),
JSPluralRules); JSPluralRules);
}
// At this point, options_obj can either be a JSObject or a JSProxy only.
Handle<JSReceiver> options = Handle<JSReceiver>::cast(options_obj);
// 5. Let matcher be ? GetOption(options, "localeMatcher", "string", // 5. Let matcher be ? GetOption(options, "localeMatcher", "string",
// « "lookup", "best fit" », "best fit"). // « "lookup", "best fit" », "best fit").
// 6. Set opt.[[localeMatcher]] to matcher. // 6. Set opt.[[localeMatcher]] to matcher.
Maybe<Intl::MatcherOption> maybe_locale_matcher = Maybe<Intl::MatcherOption> maybe_locale_matcher =
Intl::GetLocaleMatcher(isolate, options, "Intl.PluralRules"); Intl::GetLocaleMatcher(isolate, options, service);
MAYBE_RETURN(maybe_locale_matcher, MaybeHandle<JSPluralRules>()); MAYBE_RETURN(maybe_locale_matcher, MaybeHandle<JSPluralRules>());
Intl::MatcherOption matcher = maybe_locale_matcher.FromJust(); Intl::MatcherOption matcher = maybe_locale_matcher.FromJust();
// 7. Let t be ? GetOption(options, "type", "string", « "cardinal", // 7. Let t be ? GetOption(options, "type", "string", « "cardinal",
// "ordinal" », "cardinal"). // "ordinal" », "cardinal").
Maybe<Type> maybe_type = Intl::GetStringOption<Type>( Maybe<Type> maybe_type = Intl::GetStringOption<Type>(
isolate, options, "type", "Intl.PluralRules", {"cardinal", "ordinal"}, isolate, options, "type", service, {"cardinal", "ordinal"},
{Type::CARDINAL, Type::ORDINAL}, Type::CARDINAL); {Type::CARDINAL, Type::ORDINAL}, Type::CARDINAL);
MAYBE_RETURN(maybe_type, MaybeHandle<JSPluralRules>()); MAYBE_RETURN(maybe_type, MaybeHandle<JSPluralRules>());
Type type = maybe_type.FromJust(); Type type = maybe_type.FromJust();
......
...@@ -74,25 +74,20 @@ MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::New( ...@@ -74,25 +74,20 @@ MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::New(
std::vector<std::string> requested_locales = std::vector<std::string> requested_locales =
maybe_requested_locales.FromJust(); maybe_requested_locales.FromJust();
// 2. If options is undefined, then // 2. Set options to ? CoerceOptionsToObject(options).
Handle<JSReceiver> options; Handle<JSReceiver> options;
if (input_options->IsUndefined(isolate)) { const char* service = "Intl.RelativeTimeFormat";
// 2. a. Let options be ObjectCreate(null). ASSIGN_RETURN_ON_EXCEPTION(
options = isolate->factory()->NewJSObjectWithNullProto(); isolate, options,
// 3. Else Intl::CoerceOptionsToObject(isolate, input_options, service),
} else {
// 3. a. Let options be ? ToObject(options).
ASSIGN_RETURN_ON_EXCEPTION(isolate, options,
Object::ToObject(isolate, input_options),
JSRelativeTimeFormat); JSRelativeTimeFormat);
}
// 4. Let opt be a new Record. // 4. Let opt be a new Record.
// 5. Let matcher be ? GetOption(options, "localeMatcher", "string", « // 5. Let matcher be ? GetOption(options, "localeMatcher", "string", «
// "lookup", "best fit" », "best fit"). // "lookup", "best fit" », "best fit").
// 6. Set opt.[[localeMatcher]] to matcher. // 6. Set opt.[[localeMatcher]] to matcher.
Maybe<Intl::MatcherOption> maybe_locale_matcher = Maybe<Intl::MatcherOption> maybe_locale_matcher =
Intl::GetLocaleMatcher(isolate, options, "Intl.RelativeTimeFormat"); Intl::GetLocaleMatcher(isolate, options, service);
MAYBE_RETURN(maybe_locale_matcher, MaybeHandle<JSRelativeTimeFormat>()); MAYBE_RETURN(maybe_locale_matcher, MaybeHandle<JSRelativeTimeFormat>());
Intl::MatcherOption matcher = maybe_locale_matcher.FromJust(); Intl::MatcherOption matcher = maybe_locale_matcher.FromJust();
...@@ -100,7 +95,7 @@ MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::New( ...@@ -100,7 +95,7 @@ MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::New(
// `"string"`, *undefined*, *undefined*). // `"string"`, *undefined*, *undefined*).
std::unique_ptr<char[]> numbering_system_str = nullptr; std::unique_ptr<char[]> numbering_system_str = nullptr;
Maybe<bool> maybe_numberingSystem = Intl::GetNumberingSystem( Maybe<bool> maybe_numberingSystem = Intl::GetNumberingSystem(
isolate, options, "Intl.RelativeTimeFormat", &numbering_system_str); isolate, options, service, &numbering_system_str);
// 8. If _numberingSystem_ is not *undefined*, then // 8. If _numberingSystem_ is not *undefined*, then
// a. If _numberingSystem_ does not match the // a. If _numberingSystem_ does not match the
// `(3*8alphanum) *("-" (3*8alphanum))` sequence, throw a *RangeError* // `(3*8alphanum) *("-" (3*8alphanum))` sequence, throw a *RangeError*
...@@ -153,9 +148,8 @@ MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::New( ...@@ -153,9 +148,8 @@ MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::New(
// 16. Let s be ? GetOption(options, "style", "string", // 16. Let s be ? GetOption(options, "style", "string",
// «"long", "short", "narrow"», "long"). // «"long", "short", "narrow"», "long").
Maybe<Style> maybe_style = Intl::GetStringOption<Style>( Maybe<Style> maybe_style = Intl::GetStringOption<Style>(
isolate, options, "style", "Intl.RelativeTimeFormat", isolate, options, "style", service, {"long", "short", "narrow"},
{"long", "short", "narrow"}, {Style::LONG, Style::SHORT, Style::NARROW}, {Style::LONG, Style::SHORT, Style::NARROW}, Style::LONG);
Style::LONG);
MAYBE_RETURN(maybe_style, MaybeHandle<JSRelativeTimeFormat>()); MAYBE_RETURN(maybe_style, MaybeHandle<JSRelativeTimeFormat>());
Style style_enum = maybe_style.FromJust(); Style style_enum = maybe_style.FromJust();
...@@ -164,8 +158,8 @@ MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::New( ...@@ -164,8 +158,8 @@ MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::New(
// 18. Let numeric be ? GetOption(options, "numeric", "string", // 18. Let numeric be ? GetOption(options, "numeric", "string",
// «"always", "auto"», "always"). // «"always", "auto"», "always").
Maybe<Numeric> maybe_numeric = Intl::GetStringOption<Numeric>( Maybe<Numeric> maybe_numeric = Intl::GetStringOption<Numeric>(
isolate, options, "numeric", "Intl.RelativeTimeFormat", isolate, options, "numeric", service, {"always", "auto"},
{"always", "auto"}, {Numeric::ALWAYS, Numeric::AUTO}, Numeric::ALWAYS); {Numeric::ALWAYS, Numeric::AUTO}, Numeric::ALWAYS);
MAYBE_RETURN(maybe_numeric, MaybeHandle<JSRelativeTimeFormat>()); MAYBE_RETURN(maybe_numeric, MaybeHandle<JSRelativeTimeFormat>());
Numeric numeric_enum = maybe_numeric.FromJust(); Numeric numeric_enum = maybe_numeric.FromJust();
......
...@@ -33,24 +33,19 @@ MaybeHandle<JSSegmenter> JSSegmenter::New(Isolate* isolate, Handle<Map> map, ...@@ -33,24 +33,19 @@ MaybeHandle<JSSegmenter> JSSegmenter::New(Isolate* isolate, Handle<Map> map,
std::vector<std::string> requested_locales = std::vector<std::string> requested_locales =
maybe_requested_locales.FromJust(); maybe_requested_locales.FromJust();
// 5. If options is undefined, then
Handle<JSReceiver> options; Handle<JSReceiver> options;
if (input_options->IsUndefined(isolate)) { const char* service = "Intl.Segmenter";
// a. Let options be ObjectCreate(null). // 5. Let options be GetOptionsObject(_options_).
options = isolate->factory()->NewJSObjectWithNullProto(); ASSIGN_RETURN_ON_EXCEPTION(
} else { // 6. Else isolate, options, Intl::GetOptionsObject(isolate, input_options, service),
// a. Let options be ? ToObject(options).
ASSIGN_RETURN_ON_EXCEPTION(isolate, options,
Object::ToObject(isolate, input_options),
JSSegmenter); JSSegmenter);
}
// 7. Let opt be a new Record. // 7. Let opt be a new Record.
// 8. Let matcher be ? GetOption(options, "localeMatcher", "string", // 8. Let matcher be ? GetOption(options, "localeMatcher", "string",
// « "lookup", "best fit" », "best fit"). // « "lookup", "best fit" », "best fit").
// 9. Set opt.[[localeMatcher]] to matcher. // 9. Set opt.[[localeMatcher]] to matcher.
Maybe<Intl::MatcherOption> maybe_locale_matcher = Maybe<Intl::MatcherOption> maybe_locale_matcher =
Intl::GetLocaleMatcher(isolate, options, "Intl.Segmenter"); Intl::GetLocaleMatcher(isolate, options, service);
MAYBE_RETURN(maybe_locale_matcher, MaybeHandle<JSSegmenter>()); MAYBE_RETURN(maybe_locale_matcher, MaybeHandle<JSSegmenter>());
Intl::MatcherOption matcher = maybe_locale_matcher.FromJust(); Intl::MatcherOption matcher = maybe_locale_matcher.FromJust();
...@@ -74,7 +69,7 @@ MaybeHandle<JSSegmenter> JSSegmenter::New(Isolate* isolate, Handle<Map> map, ...@@ -74,7 +69,7 @@ MaybeHandle<JSSegmenter> JSSegmenter::New(Isolate* isolate, Handle<Map> map,
// 13. Let granularity be ? GetOption(options, "granularity", "string", « // 13. Let granularity be ? GetOption(options, "granularity", "string", «
// "grapheme", "word", "sentence" », "grapheme"). // "grapheme", "word", "sentence" », "grapheme").
Maybe<Granularity> maybe_granularity = Intl::GetStringOption<Granularity>( Maybe<Granularity> maybe_granularity = Intl::GetStringOption<Granularity>(
isolate, options, "granularity", "Intl.Segmenter", isolate, options, "granularity", service,
{"grapheme", "word", "sentence"}, {"grapheme", "word", "sentence"},
{Granularity::GRAPHEME, Granularity::WORD, Granularity::SENTENCE}, {Granularity::GRAPHEME, Granularity::WORD, Granularity::SENTENCE},
Granularity::GRAPHEME); Granularity::GRAPHEME);
......
// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Test Intl.DisplayNames call GetOptionsObject instead of ToObject
// https://tc39.es/ecma402/#sec-getoptionsobject
// https://tc39.es/ecma262/#sec-toobject
let testCases = [
null, // Null
true, // Boolean
false, // Boolean
1234, // Number
"string", // String
Symbol('foo'), // Symbol
9007199254740991n // BigInt
];
testCases.forEach(function (testCase) {
assertThrows(() => new Intl.DisplayNames("en", testCase), TypeError);
});
// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Test Intl.ListFormat call GetOptionsObject instead of ToObject
// https://tc39.es/ecma402/#sec-getoptionsobject
// https://tc39.es/ecma262/#sec-toobject
let testCases = [
null, // Null
true, // Boolean
false, // Boolean
1234, // Number
"string", // String
Symbol('foo'), // Symbol
9007199254740991n // BigInt
];
testCases.forEach(function (testCase) {
assertThrows(() => new Intl.ListFormat("en", testCase), TypeError);
});
// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Test Intl.Segmenter call GetOptionsObject instead of ToObject
// https://tc39.es/ecma402/#sec-getoptionsobject
// https://tc39.es/ecma262/#sec-toobject
let testCases = [
null, // Null
true, // Boolean
false, // Boolean
1234, // Number
"string", // String
Symbol('foo'), // Symbol
9007199254740991n // BigInt
];
testCases.forEach(function (testCase) {
assertThrows(() => new Intl.Segmenter("en", testCase), TypeError);
});
...@@ -587,6 +587,13 @@ ...@@ -587,6 +587,13 @@
'intl402/DateTimeFormat/prototype/formatRange/date-same-returns-single-date': [FAIL], 'intl402/DateTimeFormat/prototype/formatRange/date-same-returns-single-date': [FAIL],
'intl402/DateTimeFormat/prototype/formatRangeToParts/date-same-returns-single-date': [FAIL], 'intl402/DateTimeFormat/prototype/formatRangeToParts/date-same-returns-single-date': [FAIL],
# http://crbug/v8/11466
# https://github.com/tc39/test262/issues/2950
'intl402/Segmenter/constructor/constructor/options-toobject': [FAIL],
'intl402/Segmenter/constructor/constructor/options-toobject-prototype': [FAIL],
'intl402/ListFormat/constructor/constructor/options-toobject': [FAIL],
'intl402/ListFormat/constructor/constructor/options-toobject-prototype': [FAIL],
######################## NEEDS INVESTIGATION ########################### ######################## NEEDS INVESTIGATION ###########################
# https://bugs.chromium.org/p/v8/issues/detail?id=7833 # https://bugs.chromium.org/p/v8/issues/detail?id=7833
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment