Commit 17330977 authored by Frank Tang's avatar Frank Tang Committed by V8 LUCI CQ

[Temporal] Preparation Refactor 2

Refactor generic option reading facility also used
by Temporal from intl-objects.* to option-util.*


See
https://tc39.es/proposal-temporal/#sec-getoptionsobject
https://tc39.es/proposal-temporal/#sec-getoptionsobject-deleted
https://tc39.es/ecma402/#sec-getoptionsobject

Bug: v8:11544
Change-Id: I8b27e8fa3515c1287217c2fbe225172fb8f69210
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3122501Reviewed-by: 's avatarShu-yu Guo <syg@chromium.org>
Commit-Queue: Frank Tang <ftang@chromium.org>
Cr-Commit-Position: refs/heads/main@{#76824}
parent 3fb2ec7b
...@@ -1619,6 +1619,8 @@ filegroup( ...@@ -1619,6 +1619,8 @@ filegroup(
"src/objects/objects-definitions.h", "src/objects/objects-definitions.h",
"src/objects/oddball-inl.h", "src/objects/oddball-inl.h",
"src/objects/oddball.h", "src/objects/oddball.h",
"src/objects/option-utils.h",
"src/objects/option-utils.cc",
"src/objects/ordered-hash-table-inl.h", "src/objects/ordered-hash-table-inl.h",
"src/objects/ordered-hash-table.cc", "src/objects/ordered-hash-table.cc",
"src/objects/ordered-hash-table.h", "src/objects/ordered-hash-table.h",
......
...@@ -3029,6 +3029,7 @@ v8_header_set("v8_internal_headers") { ...@@ -3029,6 +3029,7 @@ v8_header_set("v8_internal_headers") {
"src/objects/objects.h", "src/objects/objects.h",
"src/objects/oddball-inl.h", "src/objects/oddball-inl.h",
"src/objects/oddball.h", "src/objects/oddball.h",
"src/objects/option-utils.h",
"src/objects/ordered-hash-table-inl.h", "src/objects/ordered-hash-table-inl.h",
"src/objects/ordered-hash-table.h", "src/objects/ordered-hash-table.h",
"src/objects/osr-optimized-code-cache-inl.h", "src/objects/osr-optimized-code-cache-inl.h",
...@@ -4072,6 +4073,7 @@ v8_source_set("v8_base_without_compiler") { ...@@ -4072,6 +4073,7 @@ v8_source_set("v8_base_without_compiler") {
"src/objects/module.cc", "src/objects/module.cc",
"src/objects/object-type.cc", "src/objects/object-type.cc",
"src/objects/objects.cc", "src/objects/objects.cc",
"src/objects/option-utils.cc",
"src/objects/ordered-hash-table.cc", "src/objects/ordered-hash-table.cc",
"src/objects/osr-optimized-code-cache.cc", "src/objects/osr-optimized-code-cache.cc",
"src/objects/property-descriptor.cc", "src/objects/property-descriptor.cc",
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include "src/objects/js-segmenter-inl.h" #include "src/objects/js-segmenter-inl.h"
#include "src/objects/js-segments-inl.h" #include "src/objects/js-segments-inl.h"
#include "src/objects/objects-inl.h" #include "src/objects/objects-inl.h"
#include "src/objects/option-utils.h"
#include "src/objects/property-descriptor.h" #include "src/objects/property-descriptor.h"
#include "src/objects/smi.h" #include "src/objects/smi.h"
#include "unicode/brkiter.h" #include "unicode/brkiter.h"
...@@ -656,8 +657,7 @@ BUILTIN(LocaleConstructor) { ...@@ -656,8 +657,7 @@ BUILTIN(LocaleConstructor) {
// 10. Set options to ? CoerceOptionsToObject(options). // 10. Set options to ? CoerceOptionsToObject(options).
Handle<JSReceiver> options_object; Handle<JSReceiver> options_object;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION( ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, options_object, isolate, options_object, CoerceOptionsToObject(isolate, options, method));
Intl::CoerceOptionsToObject(isolate, options, method));
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));
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "src/objects/js-locale.h" #include "src/objects/js-locale.h"
#include "src/objects/js-number-format-inl.h" #include "src/objects/js-number-format-inl.h"
#include "src/objects/objects-inl.h" #include "src/objects/objects-inl.h"
#include "src/objects/option-utils.h"
#include "src/objects/property-descriptor.h" #include "src/objects/property-descriptor.h"
#include "src/objects/smi.h" #include "src/objects/smi.h"
#include "src/objects/string.h" #include "src/objects/string.h"
...@@ -652,82 +653,6 @@ MaybeHandle<Object> Intl::LegacyUnwrapReceiver(Isolate* isolate, ...@@ -652,82 +653,6 @@ MaybeHandle<Object> Intl::LegacyUnwrapReceiver(Isolate* isolate,
return receiver; return receiver;
} }
Maybe<bool> Intl::GetStringOption(Isolate* isolate, Handle<JSReceiver> options,
const char* property,
std::vector<const char*> values,
const char* service,
std::unique_ptr<char[]>* result) {
Handle<String> property_str =
isolate->factory()->NewStringFromAsciiChecked(property);
// 1. Let value be ? Get(options, property).
Handle<Object> value;
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, value,
Object::GetPropertyOrElement(isolate, options, property_str),
Nothing<bool>());
if (value->IsUndefined(isolate)) {
return Just(false);
}
// 2. c. Let value be ? ToString(value).
Handle<String> value_str;
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, value_str, Object::ToString(isolate, value), Nothing<bool>());
std::unique_ptr<char[]> value_cstr = value_str->ToCString();
// 2. d. if values is not undefined, then
if (values.size() > 0) {
// 2. d. i. If values does not contain an element equal to value,
// throw a RangeError exception.
for (size_t i = 0; i < values.size(); i++) {
if (strcmp(values.at(i), value_cstr.get()) == 0) {
// 2. e. return value
*result = std::move(value_cstr);
return Just(true);
}
}
Handle<String> service_str =
isolate->factory()->NewStringFromAsciiChecked(service);
THROW_NEW_ERROR_RETURN_VALUE(
isolate,
NewRangeError(MessageTemplate::kValueOutOfRange, value, service_str,
property_str),
Nothing<bool>());
}
// 2. e. return value
*result = std::move(value_cstr);
return Just(true);
}
V8_WARN_UNUSED_RESULT Maybe<bool> Intl::GetBoolOption(
Isolate* isolate, Handle<JSReceiver> options, const char* property,
const char* service, bool* result) {
Handle<String> property_str =
isolate->factory()->NewStringFromAsciiChecked(property);
// 1. Let value be ? Get(options, property).
Handle<Object> value;
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, value,
Object::GetPropertyOrElement(isolate, options, property_str),
Nothing<bool>());
// 2. If value is not undefined, then
if (!value->IsUndefined(isolate)) {
// 2. b. i. Let value be ToBoolean(value).
*result = value->BooleanValue(isolate);
// 2. e. return value
return Just(true);
}
return Just(false);
}
namespace { namespace {
bool IsTwoLetterLanguage(const std::string& locale) { bool IsTwoLetterLanguage(const std::string& locale) {
...@@ -1126,55 +1051,6 @@ MaybeHandle<String> Intl::NumberToLocaleString(Isolate* isolate, ...@@ -1126,55 +1051,6 @@ MaybeHandle<String> Intl::NumberToLocaleString(Isolate* isolate,
numeric_obj); numeric_obj);
} }
namespace {
// ecma402/#sec-defaultnumberoption
Maybe<int> DefaultNumberOption(Isolate* isolate, Handle<Object> value, int min,
int max, int fallback, Handle<String> property) {
// 2. Else, return fallback.
if (value->IsUndefined()) return Just(fallback);
// 1. If value is not undefined, then
// a. Let value be ? ToNumber(value).
Handle<Object> value_num;
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, value_num, Object::ToNumber(isolate, value), Nothing<int>());
DCHECK(value_num->IsNumber());
// b. If value is NaN or less than minimum or greater than maximum, throw a
// RangeError exception.
if (value_num->IsNaN() || value_num->Number() < min ||
value_num->Number() > max) {
THROW_NEW_ERROR_RETURN_VALUE(
isolate,
NewRangeError(MessageTemplate::kPropertyValueOutOfRange, property),
Nothing<int>());
}
// The max and min arguments are integers and the above check makes
// sure that we are within the integer range making this double to
// int conversion safe.
//
// c. Return floor(value).
return Just(FastD2I(floor(value_num->Number())));
}
} // namespace
// ecma402/#sec-getnumberoption
Maybe<int> Intl::GetNumberOption(Isolate* isolate, Handle<JSReceiver> options,
Handle<String> property, int min, int max,
int fallback) {
// 1. Let value be ? Get(options, property).
Handle<Object> value;
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, value, JSReceiver::GetProperty(isolate, options, property),
Nothing<int>());
// Return ? DefaultNumberOption(value, minimum, maximum, fallback).
return DefaultNumberOption(isolate, value, min, max, fallback, property);
}
Maybe<Intl::NumberFormatDigitOptions> Intl::SetNumberFormatDigitOptions( Maybe<Intl::NumberFormatDigitOptions> Intl::SetNumberFormatDigitOptions(
Isolate* isolate, Handle<JSReceiver> options, int mnfd_default, Isolate* isolate, Handle<JSReceiver> options, int mnfd_default,
int mxfd_default, bool notation_is_compact) { int mxfd_default, bool notation_is_compact) {
...@@ -1184,8 +1060,8 @@ Maybe<Intl::NumberFormatDigitOptions> Intl::SetNumberFormatDigitOptions( ...@@ -1184,8 +1060,8 @@ Maybe<Intl::NumberFormatDigitOptions> Intl::SetNumberFormatDigitOptions(
// 5. Let mnid be ? GetNumberOption(options, "minimumIntegerDigits,", 1, 21, // 5. Let mnid be ? GetNumberOption(options, "minimumIntegerDigits,", 1, 21,
// 1). // 1).
int mnid = 1; int mnid = 1;
if (!Intl::GetNumberOption(isolate, options, if (!GetNumberOption(isolate, options, factory->minimumIntegerDigits_string(),
factory->minimumIntegerDigits_string(), 1, 21, 1) 1, 21, 1)
.To(&mnid)) { .To(&mnid)) {
return Nothing<NumberFormatDigitOptions>(); return Nothing<NumberFormatDigitOptions>();
} }
...@@ -1612,9 +1488,9 @@ MaybeHandle<JSObject> SupportedLocales( ...@@ -1612,9 +1488,9 @@ MaybeHandle<JSObject> SupportedLocales(
// 1. Set options to ? CoerceOptionsToObject(options). // 1. Set options to ? CoerceOptionsToObject(options).
Handle<JSReceiver> options_obj; Handle<JSReceiver> options_obj;
ASSIGN_RETURN_ON_EXCEPTION( ASSIGN_RETURN_ON_EXCEPTION(isolate, options_obj,
isolate, options_obj, CoerceOptionsToObject(isolate, options, method),
Intl::CoerceOptionsToObject(isolate, options, method), JSObject); JSObject);
// 2. 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").
...@@ -2222,7 +2098,7 @@ base::TimezoneCache* Intl::CreateTimeZoneCache() { ...@@ -2222,7 +2098,7 @@ base::TimezoneCache* Intl::CreateTimeZoneCache() {
Maybe<Intl::MatcherOption> Intl::GetLocaleMatcher(Isolate* isolate, Maybe<Intl::MatcherOption> Intl::GetLocaleMatcher(Isolate* isolate,
Handle<JSReceiver> options, Handle<JSReceiver> options,
const char* method) { const char* method) {
return Intl::GetStringOption<Intl::MatcherOption>( return GetStringOption<Intl::MatcherOption>(
isolate, options, "localeMatcher", method, {"best fit", "lookup"}, isolate, options, "localeMatcher", method, {"best fit", "lookup"},
{Intl::MatcherOption::kBestFit, Intl::MatcherOption::kLookup}, {Intl::MatcherOption::kBestFit, Intl::MatcherOption::kLookup},
Intl::MatcherOption::kBestFit); Intl::MatcherOption::kBestFit);
...@@ -2233,7 +2109,7 @@ Maybe<bool> Intl::GetNumberingSystem(Isolate* isolate, ...@@ -2233,7 +2109,7 @@ Maybe<bool> Intl::GetNumberingSystem(Isolate* isolate,
const char* method, const char* method,
std::unique_ptr<char[]>* result) { std::unique_ptr<char[]>* result) {
const std::vector<const char*> empty_values = {}; const std::vector<const char*> empty_values = {};
Maybe<bool> maybe = Intl::GetStringOption(isolate, options, "numberingSystem", Maybe<bool> maybe = GetStringOption(isolate, options, "numberingSystem",
empty_values, method, result); empty_values, method, result);
MAYBE_RETURN(maybe, Nothing<bool>()); MAYBE_RETURN(maybe, Nothing<bool>());
if (maybe.FromJust() && *result != nullptr) { if (maybe.FromJust() && *result != nullptr) {
...@@ -2343,41 +2219,6 @@ MaybeHandle<String> Intl::FormattedToString( ...@@ -2343,41 +2219,6 @@ 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);
}
MaybeHandle<JSArray> Intl::ToJSArray( MaybeHandle<JSArray> Intl::ToJSArray(
Isolate* isolate, const char* unicode_key, Isolate* isolate, const char* unicode_key,
icu::StringEnumeration* enumeration, icu::StringEnumeration* enumeration,
......
...@@ -66,72 +66,6 @@ class Intl { ...@@ -66,72 +66,6 @@ class Intl {
const std::set<std::string>& available_locales, Handle<Object> locales_in, const std::set<std::string>& available_locales, Handle<Object> locales_in,
Handle<Object> options_in); Handle<Object> options_in);
// ECMA402 9.2.10. GetOption( options, property, type, values, fallback)
// ecma402/#sec-getoption
//
// This is specialized for the case when type is string.
//
// Instead of passing undefined for the values argument as the spec
// defines, pass in an empty vector.
//
// Returns true if options object has the property and stores the
// result in value. Returns false if the value is not found. The
// caller is required to use fallback value appropriately in this
// case.
//
// service is a string denoting the type of Intl object; used when
// printing the error message.
V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static Maybe<bool> GetStringOption(
Isolate* isolate, Handle<JSReceiver> options, const char* property,
std::vector<const char*> values, const char* service,
std::unique_ptr<char[]>* result);
// A helper template to get string from option into a enum.
// The enum in the enum_values is the corresponding value to the strings
// in the str_values. If the option does not contains name,
// default_value will be return.
template <typename T>
V8_WARN_UNUSED_RESULT static Maybe<T> GetStringOption(
Isolate* isolate, Handle<JSReceiver> options, const char* name,
const char* method, const std::vector<const char*>& str_values,
const std::vector<T>& enum_values, T default_value) {
DCHECK_EQ(str_values.size(), enum_values.size());
std::unique_ptr<char[]> cstr;
Maybe<bool> found = Intl::GetStringOption(isolate, options, name,
str_values, method, &cstr);
MAYBE_RETURN(found, Nothing<T>());
if (found.FromJust()) {
DCHECK_NOT_NULL(cstr.get());
for (size_t i = 0; i < str_values.size(); i++) {
if (strcmp(cstr.get(), str_values[i]) == 0) {
return Just(enum_values[i]);
}
}
UNREACHABLE();
}
return Just(default_value);
}
// ECMA402 9.2.10. GetOption( options, property, type, values, fallback)
// ecma402/#sec-getoption
//
// This is specialized for the case when type is boolean.
//
// Returns true if options object has the property and stores the
// result in value. Returns false if the value is not found. The
// caller is required to use fallback value appropriately in this
// case.
//
// service is a string denoting the type of Intl object; used when
// printing the error message.
V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static Maybe<bool> GetBoolOption(
Isolate* isolate, Handle<JSReceiver> options, const char* property,
const char* service, bool* result);
V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static Maybe<int> GetNumberOption(
Isolate* isolate, Handle<JSReceiver> options, Handle<String> property,
int min, int max, int fallback);
// https://tc39.github.io/ecma402/#sec-canonicalizelocalelist // https://tc39.github.io/ecma402/#sec-canonicalizelocalelist
// {only_return_one_result} is an optimization for callers that only // {only_return_one_result} is an optimization for callers that only
// care about the first result. // care about the first result.
...@@ -337,14 +271,6 @@ class Intl { ...@@ -337,14 +271,6 @@ class Intl {
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);
V8_WARN_UNUSED_RESULT static MaybeHandle<JSArray> ToJSArray( V8_WARN_UNUSED_RESULT static MaybeHandle<JSArray> ToJSArray(
Isolate* isolate, const char* unicode_key, Isolate* isolate, const char* unicode_key,
icu::StringEnumeration* enumeration, icu::StringEnumeration* enumeration,
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "src/objects/intl-objects.h" #include "src/objects/intl-objects.h"
#include "src/objects/js-break-iterator-inl.h" #include "src/objects/js-break-iterator-inl.h"
#include "src/objects/option-utils.h"
#include "unicode/brkiter.h" #include "unicode/brkiter.h"
namespace v8 { namespace v8 {
...@@ -56,7 +57,7 @@ MaybeHandle<JSV8BreakIterator> JSV8BreakIterator::New( ...@@ -56,7 +57,7 @@ MaybeHandle<JSV8BreakIterator> JSV8BreakIterator::New(
Intl::ResolvedLocale r = maybe_resolve_locale.FromJust(); Intl::ResolvedLocale r = maybe_resolve_locale.FromJust();
// Extract type from options // Extract type from options
Maybe<Type> maybe_type = Intl::GetStringOption<Type>( Maybe<Type> maybe_type = GetStringOption<Type>(
isolate, options, "type", service, isolate, options, "type", service,
{"word", "character", "sentence", "line"}, {"word", "character", "sentence", "line"},
{Type::WORD, Type::CHARACTER, Type::SENTENCE, Type::LINE}, Type::WORD); {Type::WORD, Type::CHARACTER, Type::SENTENCE, Type::LINE}, Type::WORD);
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "src/objects/js-collator-inl.h" #include "src/objects/js-collator-inl.h"
#include "src/objects/js-locale.h" #include "src/objects/js-locale.h"
#include "src/objects/objects-inl.h" #include "src/objects/objects-inl.h"
#include "src/objects/option-utils.h"
#include "unicode/coll.h" #include "unicode/coll.h"
#include "unicode/locid.h" #include "unicode/locid.h"
#include "unicode/strenum.h" #include "unicode/strenum.h"
...@@ -43,7 +44,7 @@ enum class CaseFirst { kUndefined, kUpper, kLower, kFalse }; ...@@ -43,7 +44,7 @@ enum class CaseFirst { kUndefined, kUpper, kLower, kFalse };
Maybe<CaseFirst> GetCaseFirst(Isolate* isolate, Handle<JSReceiver> options, Maybe<CaseFirst> GetCaseFirst(Isolate* isolate, Handle<JSReceiver> options,
const char* method) { const char* method) {
return Intl::GetStringOption<CaseFirst>( return GetStringOption<CaseFirst>(
isolate, options, "caseFirst", method, {"upper", "lower", "false"}, isolate, options, "caseFirst", method, {"upper", "lower", "false"},
{CaseFirst::kUpper, CaseFirst::kLower, CaseFirst::kFalse}, {CaseFirst::kUpper, CaseFirst::kLower, CaseFirst::kFalse},
CaseFirst::kUndefined); CaseFirst::kUndefined);
...@@ -286,12 +287,12 @@ MaybeHandle<JSCollator> JSCollator::New(Isolate* isolate, Handle<Map> map, ...@@ -286,12 +287,12 @@ MaybeHandle<JSCollator> JSCollator::New(Isolate* isolate, Handle<Map> map,
// 2. Set options to ? CoerceOptionsToObject(options). // 2. Set options to ? CoerceOptionsToObject(options).
Handle<JSReceiver> options; Handle<JSReceiver> options;
ASSIGN_RETURN_ON_EXCEPTION( ASSIGN_RETURN_ON_EXCEPTION(
isolate, options, isolate, options, CoerceOptionsToObject(isolate, options_obj, service),
Intl::CoerceOptionsToObject(isolate, options_obj, service), JSCollator); JSCollator);
// 4. Let usage be ? GetOption(options, "usage", "string", « "sort", // 4. Let usage be ? GetOption(options, "usage", "string", « "sort",
// "search" », "sort"). // "search" », "sort").
Maybe<Usage> maybe_usage = Intl::GetStringOption<Usage>( Maybe<Usage> maybe_usage = GetStringOption<Usage>(
isolate, options, "usage", service, {"sort", "search"}, isolate, options, "usage", service, {"sort", "search"},
{Usage::SORT, Usage::SEARCH}, Usage::SORT); {Usage::SORT, Usage::SEARCH}, Usage::SORT);
MAYBE_RETURN(maybe_usage, MaybeHandle<JSCollator>()); MAYBE_RETURN(maybe_usage, MaybeHandle<JSCollator>());
...@@ -309,7 +310,7 @@ MaybeHandle<JSCollator> JSCollator::New(Isolate* isolate, Handle<Map> map, ...@@ -309,7 +310,7 @@ MaybeHandle<JSCollator> JSCollator::New(Isolate* isolate, Handle<Map> map,
// *undefined*, *undefined*). // *undefined*, *undefined*).
std::unique_ptr<char[]> collation_str = nullptr; std::unique_ptr<char[]> collation_str = nullptr;
const std::vector<const char*> empty_values = {}; const std::vector<const char*> empty_values = {};
Maybe<bool> maybe_collation = Intl::GetStringOption( Maybe<bool> maybe_collation = GetStringOption(
isolate, options, "collation", empty_values, service, &collation_str); isolate, options, "collation", empty_values, service, &collation_str);
MAYBE_RETURN(maybe_collation, MaybeHandle<JSCollator>()); MAYBE_RETURN(maybe_collation, MaybeHandle<JSCollator>());
// x. If _collation_ is not *undefined*, then // x. If _collation_ is not *undefined*, then
...@@ -334,13 +335,13 @@ MaybeHandle<JSCollator> JSCollator::New(Isolate* isolate, Handle<Map> map, ...@@ -334,13 +335,13 @@ MaybeHandle<JSCollator> JSCollator::New(Isolate* isolate, Handle<Map> map,
// a. Let numeric be ! ToString(numeric). // a. Let numeric be ! ToString(numeric).
// //
// Note: We omit the ToString(numeric) operation as it's not // Note: We omit the ToString(numeric) operation as it's not
// observable. Intl::GetBoolOption returns a Boolean and // observable. GetBoolOption returns a Boolean and
// ToString(Boolean) is not side-effecting. // ToString(Boolean) is not side-effecting.
// //
// 13. Set opt.[[kn]] to numeric. // 13. Set opt.[[kn]] to numeric.
bool numeric; bool numeric;
Maybe<bool> found_numeric = Maybe<bool> found_numeric =
Intl::GetBoolOption(isolate, options, "numeric", service, &numeric); GetBoolOption(isolate, options, "numeric", service, &numeric);
MAYBE_RETURN(found_numeric, MaybeHandle<JSCollator>()); MAYBE_RETURN(found_numeric, MaybeHandle<JSCollator>());
// 14. Let caseFirst be ? GetOption(options, "caseFirst", "string", // 14. Let caseFirst be ? GetOption(options, "caseFirst", "string",
...@@ -477,11 +478,11 @@ MaybeHandle<JSCollator> JSCollator::New(Isolate* isolate, Handle<Map> map, ...@@ -477,11 +478,11 @@ MaybeHandle<JSCollator> JSCollator::New(Isolate* isolate, Handle<Map> map,
// 24. Let sensitivity be ? GetOption(options, "sensitivity", // 24. Let sensitivity be ? GetOption(options, "sensitivity",
// "string", « "base", "accent", "case", "variant" », undefined). // "string", « "base", "accent", "case", "variant" », undefined).
Maybe<Sensitivity> maybe_sensitivity = Intl::GetStringOption<Sensitivity>( Maybe<Sensitivity> maybe_sensitivity =
isolate, options, "sensitivity", service, GetStringOption<Sensitivity>(isolate, options, "sensitivity", service,
{"base", "accent", "case", "variant"}, {"base", "accent", "case", "variant"},
{Sensitivity::kBase, Sensitivity::kAccent, Sensitivity::kCase, {Sensitivity::kBase, Sensitivity::kAccent,
Sensitivity::kVariant}, Sensitivity::kCase, Sensitivity::kVariant},
Sensitivity::kUndefined); Sensitivity::kUndefined);
MAYBE_RETURN(maybe_sensitivity, MaybeHandle<JSCollator>()); MAYBE_RETURN(maybe_sensitivity, MaybeHandle<JSCollator>());
Sensitivity sensitivity = maybe_sensitivity.FromJust(); Sensitivity sensitivity = maybe_sensitivity.FromJust();
...@@ -518,7 +519,7 @@ MaybeHandle<JSCollator> JSCollator::New(Isolate* isolate, Handle<Map> map, ...@@ -518,7 +519,7 @@ MaybeHandle<JSCollator> JSCollator::New(Isolate* isolate, Handle<Map> map,
// 27.Let ignorePunctuation be ? GetOption(options, // 27.Let ignorePunctuation be ? GetOption(options,
// "ignorePunctuation", "boolean", undefined, false). // "ignorePunctuation", "boolean", undefined, false).
bool ignore_punctuation; bool ignore_punctuation;
Maybe<bool> found_ignore_punctuation = Intl::GetBoolOption( Maybe<bool> found_ignore_punctuation = GetBoolOption(
isolate, options, "ignorePunctuation", service, &ignore_punctuation); isolate, options, "ignorePunctuation", service, &ignore_punctuation);
MAYBE_RETURN(found_ignore_punctuation, MaybeHandle<JSCollator>()); MAYBE_RETURN(found_ignore_punctuation, MaybeHandle<JSCollator>());
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#include "src/heap/factory.h" #include "src/heap/factory.h"
#include "src/objects/intl-objects.h" #include "src/objects/intl-objects.h"
#include "src/objects/js-date-time-format-inl.h" #include "src/objects/js-date-time-format-inl.h"
#include "src/objects/option-utils.h"
#include "unicode/calendar.h" #include "unicode/calendar.h"
#include "unicode/dtitvfmt.h" #include "unicode/dtitvfmt.h"
#include "unicode/dtptngen.h" #include "unicode/dtptngen.h"
...@@ -77,7 +77,7 @@ JSDateTimeFormat::HourCycle ToHourCycle(UDateFormatHourCycle hc) { ...@@ -77,7 +77,7 @@ JSDateTimeFormat::HourCycle ToHourCycle(UDateFormatHourCycle hc) {
Maybe<JSDateTimeFormat::HourCycle> GetHourCycle(Isolate* isolate, Maybe<JSDateTimeFormat::HourCycle> GetHourCycle(Isolate* isolate,
Handle<JSReceiver> options, Handle<JSReceiver> options,
const char* method) { const char* method) {
return Intl::GetStringOption<JSDateTimeFormat::HourCycle>( return GetStringOption<JSDateTimeFormat::HourCycle>(
isolate, options, "hourCycle", method, {"h11", "h12", "h23", "h24"}, isolate, options, "hourCycle", method, {"h11", "h12", "h23", "h24"},
{JSDateTimeFormat::HourCycle::kH11, JSDateTimeFormat::HourCycle::kH12, {JSDateTimeFormat::HourCycle::kH11, JSDateTimeFormat::HourCycle::kH12,
JSDateTimeFormat::HourCycle::kH23, JSDateTimeFormat::HourCycle::kH24}, JSDateTimeFormat::HourCycle::kH23, JSDateTimeFormat::HourCycle::kH24},
...@@ -1499,7 +1499,7 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New( ...@@ -1499,7 +1499,7 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New(
const std::vector<const char*> empty_values = {}; const std::vector<const char*> empty_values = {};
// 6. Let calendar be ? GetOption(options, "calendar", // 6. Let calendar be ? GetOption(options, "calendar",
// "string", undefined, undefined). // "string", undefined, undefined).
Maybe<bool> maybe_calendar = Intl::GetStringOption( Maybe<bool> maybe_calendar = GetStringOption(
isolate, options, "calendar", empty_values, service, &calendar_str); isolate, options, "calendar", empty_values, service, &calendar_str);
MAYBE_RETURN(maybe_calendar, MaybeHandle<JSDateTimeFormat>()); MAYBE_RETURN(maybe_calendar, MaybeHandle<JSDateTimeFormat>());
if (maybe_calendar.FromJust() && calendar_str != nullptr) { if (maybe_calendar.FromJust() && calendar_str != nullptr) {
...@@ -1523,7 +1523,7 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New( ...@@ -1523,7 +1523,7 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New(
// undefined). // undefined).
bool hour12; bool hour12;
Maybe<bool> maybe_get_hour12 = Maybe<bool> maybe_get_hour12 =
Intl::GetBoolOption(isolate, options, "hour12", service, &hour12); GetBoolOption(isolate, options, "hour12", service, &hour12);
MAYBE_RETURN(maybe_get_hour12, Handle<JSDateTimeFormat>()); MAYBE_RETURN(maybe_get_hour12, Handle<JSDateTimeFormat>());
// 7. Let hourCycle be ? GetOption(options, "hourCycle", "string", « "h11", // 7. Let hourCycle be ? GetOption(options, "hourCycle", "string", « "h11",
...@@ -1651,7 +1651,7 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New( ...@@ -1651,7 +1651,7 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New(
// 17. Let timeZone be ? Get(options, "timeZone"). // 17. Let timeZone be ? Get(options, "timeZone").
std::unique_ptr<char[]> timezone = nullptr; std::unique_ptr<char[]> timezone = nullptr;
Maybe<bool> maybe_timezone = Intl::GetStringOption( Maybe<bool> maybe_timezone = GetStringOption(
isolate, options, "timeZone", empty_values, service, &timezone); isolate, options, "timeZone", empty_values, service, &timezone);
MAYBE_RETURN(maybe_timezone, Handle<JSDateTimeFormat>()); MAYBE_RETURN(maybe_timezone, Handle<JSDateTimeFormat>());
...@@ -1689,7 +1689,7 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New( ...@@ -1689,7 +1689,7 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New(
if (item.property == "timeZoneName") { if (item.property == "timeZoneName") {
// Let _value_ be ? GetNumberOption(options, "fractionalSecondDigits", 1, // Let _value_ be ? GetNumberOption(options, "fractionalSecondDigits", 1,
// 3, *undefined*). The *undefined* is represented by value 0 here. // 3, *undefined*). The *undefined* is represented by value 0 here.
Maybe<int> maybe_fsd = Intl::GetNumberOption( Maybe<int> maybe_fsd = GetNumberOption(
isolate, options, factory->fractionalSecondDigits_string(), 1, 3, 0); isolate, options, factory->fractionalSecondDigits_string(), 1, 3, 0);
MAYBE_RETURN(maybe_fsd, MaybeHandle<JSDateTimeFormat>()); MAYBE_RETURN(maybe_fsd, MaybeHandle<JSDateTimeFormat>());
// Convert fractionalSecondDigits to skeleton. // Convert fractionalSecondDigits to skeleton.
...@@ -1703,7 +1703,7 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New( ...@@ -1703,7 +1703,7 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New(
// ii. Let value be ? GetOption(options, prop, "string", « the strings // ii. Let value be ? GetOption(options, prop, "string", « the strings
// given in the Values column of the row », undefined). // given in the Values column of the row », undefined).
Maybe<bool> maybe_get_option = Maybe<bool> maybe_get_option =
Intl::GetStringOption(isolate, options, item.property.c_str(), GetStringOption(isolate, options, item.property.c_str(),
item.allowed_values, service, &input); item.allowed_values, service, &input);
MAYBE_RETURN(maybe_get_option, Handle<JSDateTimeFormat>()); MAYBE_RETURN(maybe_get_option, Handle<JSDateTimeFormat>());
if (maybe_get_option.FromJust()) { if (maybe_get_option.FromJust()) {
...@@ -1724,7 +1724,7 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New( ...@@ -1724,7 +1724,7 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New(
// c. Let matcher be ? GetOption(options, "formatMatcher", "string", // c. Let matcher be ? GetOption(options, "formatMatcher", "string",
// « "basic", "best fit" », "best fit"). // « "basic", "best fit" », "best fit").
Maybe<FormatMatcherOption> maybe_format_matcher = Maybe<FormatMatcherOption> maybe_format_matcher =
Intl::GetStringOption<FormatMatcherOption>( GetStringOption<FormatMatcherOption>(
isolate, options, "formatMatcher", service, {"best fit", "basic"}, isolate, options, "formatMatcher", service, {"best fit", "basic"},
{FormatMatcherOption::kBestFit, FormatMatcherOption::kBasic}, {FormatMatcherOption::kBestFit, FormatMatcherOption::kBasic},
FormatMatcherOption::kBestFit); FormatMatcherOption::kBestFit);
...@@ -1734,7 +1734,7 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New( ...@@ -1734,7 +1734,7 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New(
// 32. Let dateStyle be ? GetOption(options, "dateStyle", "string", « // 32. Let dateStyle be ? GetOption(options, "dateStyle", "string", «
// "full", "long", "medium", "short" », undefined). // "full", "long", "medium", "short" », undefined).
Maybe<DateTimeStyle> maybe_date_style = Intl::GetStringOption<DateTimeStyle>( Maybe<DateTimeStyle> maybe_date_style = GetStringOption<DateTimeStyle>(
isolate, options, "dateStyle", service, isolate, options, "dateStyle", service,
{"full", "long", "medium", "short"}, {"full", "long", "medium", "short"},
{DateTimeStyle::kFull, DateTimeStyle::kLong, DateTimeStyle::kMedium, {DateTimeStyle::kFull, DateTimeStyle::kLong, DateTimeStyle::kMedium,
...@@ -1746,7 +1746,7 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New( ...@@ -1746,7 +1746,7 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New(
// 34. Let timeStyle be ? GetOption(options, "timeStyle", "string", « // 34. Let timeStyle be ? GetOption(options, "timeStyle", "string", «
// "full", "long", "medium", "short" »). // "full", "long", "medium", "short" »).
Maybe<DateTimeStyle> maybe_time_style = Intl::GetStringOption<DateTimeStyle>( Maybe<DateTimeStyle> maybe_time_style = GetStringOption<DateTimeStyle>(
isolate, options, "timeStyle", service, isolate, options, "timeStyle", service,
{"full", "long", "medium", "short"}, {"full", "long", "medium", "short"},
{DateTimeStyle::kFull, DateTimeStyle::kLong, DateTimeStyle::kMedium, {DateTimeStyle::kFull, DateTimeStyle::kLong, DateTimeStyle::kMedium,
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "src/objects/js-display-names-inl.h" #include "src/objects/js-display-names-inl.h"
#include "src/objects/managed.h" #include "src/objects/managed.h"
#include "src/objects/objects-inl.h" #include "src/objects/objects-inl.h"
#include "src/objects/option-utils.h"
#include "unicode/dtfmtsym.h" #include "unicode/dtfmtsym.h"
#include "unicode/dtptngen.h" #include "unicode/dtptngen.h"
#include "unicode/localebuilder.h" #include "unicode/localebuilder.h"
...@@ -372,8 +373,8 @@ MaybeHandle<JSDisplayNames> JSDisplayNames::New(Isolate* isolate, ...@@ -372,8 +373,8 @@ MaybeHandle<JSDisplayNames> JSDisplayNames::New(Isolate* isolate,
maybe_requested_locales.FromJust(); maybe_requested_locales.FromJust();
// 4. Let options be ? GetOptionsObject(options). // 4. Let options be ? GetOptionsObject(options).
ASSIGN_RETURN_ON_EXCEPTION( ASSIGN_RETURN_ON_EXCEPTION(isolate, options,
isolate, options, Intl::GetOptionsObject(isolate, input_options, service), 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.
...@@ -409,7 +410,7 @@ MaybeHandle<JSDisplayNames> JSDisplayNames::New(Isolate* isolate, ...@@ -409,7 +410,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 = GetStringOption<Style>(
isolate, options, "style", service, {"long", "short", "narrow"}, isolate, options, "style", service, {"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>());
...@@ -422,15 +423,14 @@ MaybeHandle<JSDisplayNames> JSDisplayNames::New(Isolate* isolate, ...@@ -422,15 +423,14 @@ MaybeHandle<JSDisplayNames> JSDisplayNames::New(Isolate* isolate,
// undefined). // undefined).
Maybe<Type> maybe_type = Maybe<Type> maybe_type =
FLAG_harmony_intl_displaynames_v2 FLAG_harmony_intl_displaynames_v2
? Intl::GetStringOption<Type>( ? GetStringOption<Type>(
isolate, options, "type", service, isolate, options, "type", service,
{"language", "region", "script", "currency", "calendar", {"language", "region", "script", "currency", "calendar",
"dateTimeField"}, "dateTimeField"},
{Type::kLanguage, Type::kRegion, Type::kScript, Type::kCurrency, {Type::kLanguage, Type::kRegion, Type::kScript, Type::kCurrency,
Type::kCalendar, Type::kDateTimeField}, Type::kCalendar, Type::kDateTimeField},
Type::kUndefined) Type::kUndefined)
: Intl::GetStringOption<Type>( : GetStringOption<Type>(isolate, options, "type", service,
isolate, options, "type", service,
{"language", "region", "script", "currency"}, {"language", "region", "script", "currency"},
{ {
Type::kLanguage, Type::kLanguage,
...@@ -452,7 +452,7 @@ MaybeHandle<JSDisplayNames> JSDisplayNames::New(Isolate* isolate, ...@@ -452,7 +452,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 = GetStringOption<Fallback>(
isolate, options, "fallback", service, {"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>());
...@@ -465,7 +465,7 @@ MaybeHandle<JSDisplayNames> JSDisplayNames::New(Isolate* isolate, ...@@ -465,7 +465,7 @@ MaybeHandle<JSDisplayNames> JSDisplayNames::New(Isolate* isolate,
// 24. Let languageDisplay be ? GetOption(options, "languageDisplay", // 24. Let languageDisplay be ? GetOption(options, "languageDisplay",
// "string", « "dialect", "standard" », "dialect"). // "string", « "dialect", "standard" », "dialect").
Maybe<LanguageDisplay> maybe_language_display = Maybe<LanguageDisplay> maybe_language_display =
Intl::GetStringOption<LanguageDisplay>( GetStringOption<LanguageDisplay>(
isolate, options, "languageDisplay", service, isolate, options, "languageDisplay", service,
{"dialect", "standard"}, {"dialect", "standard"},
{LanguageDisplay::kDialect, LanguageDisplay::kStandard}, {LanguageDisplay::kDialect, LanguageDisplay::kStandard},
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "src/objects/js-list-format-inl.h" #include "src/objects/js-list-format-inl.h"
#include "src/objects/managed.h" #include "src/objects/managed.h"
#include "src/objects/objects-inl.h" #include "src/objects/objects-inl.h"
#include "src/objects/option-utils.h"
#include "unicode/fieldpos.h" #include "unicode/fieldpos.h"
#include "unicode/fpositer.h" #include "unicode/fpositer.h"
#include "unicode/listformatter.h" #include "unicode/listformatter.h"
...@@ -69,8 +70,8 @@ MaybeHandle<JSListFormat> JSListFormat::New(Isolate* isolate, Handle<Map> map, ...@@ -69,8 +70,8 @@ MaybeHandle<JSListFormat> JSListFormat::New(Isolate* isolate, Handle<Map> map,
Handle<JSReceiver> options; Handle<JSReceiver> options;
const char* service = "Intl.ListFormat"; const char* service = "Intl.ListFormat";
// 4. Let options be GetOptionsObject(_options_). // 4. Let options be GetOptionsObject(_options_).
ASSIGN_RETURN_ON_EXCEPTION( ASSIGN_RETURN_ON_EXCEPTION(isolate, options,
isolate, options, Intl::GetOptionsObject(isolate, input_options, service), GetOptionsObject(isolate, input_options, service),
JSListFormat); JSListFormat);
// Note: No need to create a record. It's not observable. // Note: No need to create a record. It's not observable.
...@@ -100,7 +101,7 @@ MaybeHandle<JSListFormat> JSListFormat::New(Isolate* isolate, Handle<Map> map, ...@@ -100,7 +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 = GetStringOption<Type>(
isolate, options, "type", service, {"conjunction", "disjunction", "unit"}, isolate, options, "type", service, {"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>());
...@@ -108,7 +109,7 @@ MaybeHandle<JSListFormat> JSListFormat::New(Isolate* isolate, Handle<Map> map, ...@@ -108,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 = GetStringOption<Style>(
isolate, options, "style", service, {"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>());
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "src/objects/intl-objects.h" #include "src/objects/intl-objects.h"
#include "src/objects/js-locale-inl.h" #include "src/objects/js-locale-inl.h"
#include "src/objects/objects-inl.h" #include "src/objects/objects-inl.h"
#include "src/objects/option-utils.h"
#include "unicode/calendar.h" #include "unicode/calendar.h"
#include "unicode/char16ptr.h" #include "unicode/char16ptr.h"
#include "unicode/coll.h" #include "unicode/coll.h"
...@@ -70,11 +71,11 @@ Maybe<bool> InsertOptionsIntoLocale(Isolate* isolate, ...@@ -70,11 +71,11 @@ Maybe<bool> InsertOptionsIntoLocale(Isolate* isolate,
bool value_bool = false; bool value_bool = false;
Maybe<bool> maybe_found = Maybe<bool> maybe_found =
option_to_bcp47.is_bool_value option_to_bcp47.is_bool_value
? Intl::GetBoolOption(isolate, options, option_to_bcp47.name, ? GetBoolOption(isolate, options, option_to_bcp47.name, "locale",
"locale", &value_bool) &value_bool)
: Intl::GetStringOption(isolate, options, option_to_bcp47.name, : GetStringOption(isolate, options, option_to_bcp47.name,
*(option_to_bcp47.possible_values), *(option_to_bcp47.possible_values), "locale",
"locale", &value_str); &value_str);
MAYBE_RETURN(maybe_found, Nothing<bool>()); MAYBE_RETURN(maybe_found, Nothing<bool>());
// TODO(cira): Use fallback value if value is not found to make // TODO(cira): Use fallback value if value is not found to make
...@@ -266,7 +267,7 @@ Maybe<bool> ApplyOptionsToTag(Isolate* isolate, Handle<String> tag, ...@@ -266,7 +267,7 @@ Maybe<bool> ApplyOptionsToTag(Isolate* isolate, Handle<String> tag,
const std::vector<const char*> empty_values = {}; const std::vector<const char*> empty_values = {};
std::unique_ptr<char[]> language_str = nullptr; std::unique_ptr<char[]> language_str = nullptr;
Maybe<bool> maybe_language = Maybe<bool> maybe_language =
Intl::GetStringOption(isolate, options, "language", empty_values, GetStringOption(isolate, options, "language", empty_values,
"ApplyOptionsToTag", &language_str); "ApplyOptionsToTag", &language_str);
MAYBE_RETURN(maybe_language, Nothing<bool>()); MAYBE_RETURN(maybe_language, Nothing<bool>());
// 4. If language is not undefined, then // 4. If language is not undefined, then
...@@ -284,7 +285,7 @@ Maybe<bool> ApplyOptionsToTag(Isolate* isolate, Handle<String> tag, ...@@ -284,7 +285,7 @@ Maybe<bool> ApplyOptionsToTag(Isolate* isolate, Handle<String> tag,
// undefined). // undefined).
std::unique_ptr<char[]> script_str = nullptr; std::unique_ptr<char[]> script_str = nullptr;
Maybe<bool> maybe_script = Maybe<bool> maybe_script =
Intl::GetStringOption(isolate, options, "script", empty_values, GetStringOption(isolate, options, "script", empty_values,
"ApplyOptionsToTag", &script_str); "ApplyOptionsToTag", &script_str);
MAYBE_RETURN(maybe_script, Nothing<bool>()); MAYBE_RETURN(maybe_script, Nothing<bool>());
// 6. If script is not undefined, then // 6. If script is not undefined, then
...@@ -301,7 +302,7 @@ Maybe<bool> ApplyOptionsToTag(Isolate* isolate, Handle<String> tag, ...@@ -301,7 +302,7 @@ Maybe<bool> ApplyOptionsToTag(Isolate* isolate, Handle<String> tag,
// undefined). // undefined).
std::unique_ptr<char[]> region_str = nullptr; std::unique_ptr<char[]> region_str = nullptr;
Maybe<bool> maybe_region = Maybe<bool> maybe_region =
Intl::GetStringOption(isolate, options, "region", empty_values, GetStringOption(isolate, options, "region", empty_values,
"ApplyOptionsToTag", &region_str); "ApplyOptionsToTag", &region_str);
MAYBE_RETURN(maybe_region, Nothing<bool>()); MAYBE_RETURN(maybe_region, Nothing<bool>());
// 8. If region is not undefined, then // 8. If region is not undefined, then
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "src/objects/intl-objects.h" #include "src/objects/intl-objects.h"
#include "src/objects/js-number-format-inl.h" #include "src/objects/js-number-format-inl.h"
#include "src/objects/objects-inl.h" #include "src/objects/objects-inl.h"
#include "src/objects/option-utils.h"
#include "unicode/currunit.h" #include "unicode/currunit.h"
#include "unicode/decimfmt.h" #include "unicode/decimfmt.h"
#include "unicode/locid.h" #include "unicode/locid.h"
...@@ -816,8 +817,7 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate, ...@@ -816,8 +817,7 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate,
// 2. Set options to ? CoerceOptionsToObject(options). // 2. Set options to ? CoerceOptionsToObject(options).
Handle<JSReceiver> options; Handle<JSReceiver> options;
ASSIGN_RETURN_ON_EXCEPTION( ASSIGN_RETURN_ON_EXCEPTION(
isolate, options, isolate, options, CoerceOptionsToObject(isolate, options_obj, service),
Intl::CoerceOptionsToObject(isolate, options_obj, service),
JSNumberFormat); JSNumberFormat);
// 4. Let opt be a new Record. // 4. Let opt be a new Record.
...@@ -899,7 +899,7 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate, ...@@ -899,7 +899,7 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate,
// 3. Let style be ? GetOption(options, "style", "string", « "decimal", // 3. Let style be ? GetOption(options, "style", "string", « "decimal",
// "percent", "currency", "unit" », "decimal"). // "percent", "currency", "unit" », "decimal").
Maybe<Style> maybe_style = Intl::GetStringOption<Style>( Maybe<Style> maybe_style = GetStringOption<Style>(
isolate, options, "style", service, isolate, options, "style", service,
{"decimal", "percent", "currency", "unit"}, {"decimal", "percent", "currency", "unit"},
{Style::DECIMAL, Style::PERCENT, Style::CURRENCY, Style::UNIT}, {Style::DECIMAL, Style::PERCENT, Style::CURRENCY, Style::UNIT},
...@@ -913,7 +913,7 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate, ...@@ -913,7 +913,7 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate,
// undefined). // undefined).
std::unique_ptr<char[]> currency_cstr; std::unique_ptr<char[]> currency_cstr;
const std::vector<const char*> empty_values = {}; const std::vector<const char*> empty_values = {};
Maybe<bool> found_currency = Intl::GetStringOption( Maybe<bool> found_currency = GetStringOption(
isolate, options, "currency", empty_values, service, &currency_cstr); isolate, options, "currency", empty_values, service, &currency_cstr);
MAYBE_RETURN(found_currency, MaybeHandle<JSNumberFormat>()); MAYBE_RETURN(found_currency, MaybeHandle<JSNumberFormat>());
...@@ -943,7 +943,7 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate, ...@@ -943,7 +943,7 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate,
// 8. Let currencyDisplay be ? GetOption(options, "currencyDisplay", // 8. Let currencyDisplay be ? GetOption(options, "currencyDisplay",
// "string", « "code", "symbol", "name", "narrowSymbol" », "symbol"). // "string", « "code", "symbol", "name", "narrowSymbol" », "symbol").
Maybe<CurrencyDisplay> maybe_currency_display = Maybe<CurrencyDisplay> maybe_currency_display =
Intl::GetStringOption<CurrencyDisplay>( GetStringOption<CurrencyDisplay>(
isolate, options, "currencyDisplay", service, isolate, options, "currencyDisplay", service,
{"code", "symbol", "name", "narrowSymbol"}, {"code", "symbol", "name", "narrowSymbol"},
{CurrencyDisplay::CODE, CurrencyDisplay::SYMBOL, {CurrencyDisplay::CODE, CurrencyDisplay::SYMBOL,
...@@ -955,7 +955,7 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate, ...@@ -955,7 +955,7 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate,
CurrencySign currency_sign = CurrencySign::STANDARD; CurrencySign currency_sign = CurrencySign::STANDARD;
// 9. Let currencySign be ? GetOption(options, "currencySign", "string", « // 9. Let currencySign be ? GetOption(options, "currencySign", "string", «
// "standard", "accounting" », "standard"). // "standard", "accounting" », "standard").
Maybe<CurrencySign> maybe_currency_sign = Intl::GetStringOption<CurrencySign>( Maybe<CurrencySign> maybe_currency_sign = GetStringOption<CurrencySign>(
isolate, options, "currencySign", service, {"standard", "accounting"}, isolate, options, "currencySign", service, {"standard", "accounting"},
{CurrencySign::STANDARD, CurrencySign::ACCOUNTING}, {CurrencySign::STANDARD, CurrencySign::ACCOUNTING},
CurrencySign::STANDARD); CurrencySign::STANDARD);
...@@ -965,8 +965,8 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate, ...@@ -965,8 +965,8 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate,
// 10. Let unit be ? GetOption(options, "unit", "string", undefined, // 10. Let unit be ? GetOption(options, "unit", "string", undefined,
// undefined). // undefined).
std::unique_ptr<char[]> unit_cstr; std::unique_ptr<char[]> unit_cstr;
Maybe<bool> found_unit = Intl::GetStringOption( Maybe<bool> found_unit = GetStringOption(isolate, options, "unit",
isolate, options, "unit", empty_values, service, &unit_cstr); empty_values, service, &unit_cstr);
MAYBE_RETURN(found_unit, MaybeHandle<JSNumberFormat>()); MAYBE_RETURN(found_unit, MaybeHandle<JSNumberFormat>());
std::pair<icu::MeasureUnit, icu::MeasureUnit> unit_pair; std::pair<icu::MeasureUnit, icu::MeasureUnit> unit_pair;
...@@ -1001,7 +1001,7 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate, ...@@ -1001,7 +1001,7 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate,
// 13. Let unitDisplay be ? GetOption(options, "unitDisplay", "string", « // 13. Let unitDisplay be ? GetOption(options, "unitDisplay", "string", «
// "short", "narrow", "long" », "short"). // "short", "narrow", "long" », "short").
Maybe<UnitDisplay> maybe_unit_display = Intl::GetStringOption<UnitDisplay>( Maybe<UnitDisplay> maybe_unit_display = GetStringOption<UnitDisplay>(
isolate, options, "unitDisplay", service, {"short", "narrow", "long"}, isolate, options, "unitDisplay", service, {"short", "narrow", "long"},
{UnitDisplay::SHORT, UnitDisplay::NARROW, UnitDisplay::LONG}, {UnitDisplay::SHORT, UnitDisplay::NARROW, UnitDisplay::LONG},
UnitDisplay::SHORT); UnitDisplay::SHORT);
...@@ -1097,7 +1097,7 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate, ...@@ -1097,7 +1097,7 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate,
Notation notation = Notation::STANDARD; Notation notation = Notation::STANDARD;
// 25. Let notation be ? GetOption(options, "notation", "string", « // 25. Let notation be ? GetOption(options, "notation", "string", «
// "standard", "scientific", "engineering", "compact" », "standard"). // "standard", "scientific", "engineering", "compact" », "standard").
Maybe<Notation> maybe_notation = Intl::GetStringOption<Notation>( Maybe<Notation> maybe_notation = GetStringOption<Notation>(
isolate, options, "notation", service, isolate, options, "notation", service,
{"standard", "scientific", "engineering", "compact"}, {"standard", "scientific", "engineering", "compact"},
{Notation::STANDARD, Notation::SCIENTIFIC, Notation::ENGINEERING, {Notation::STANDARD, Notation::SCIENTIFIC, Notation::ENGINEERING,
...@@ -1119,8 +1119,7 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate, ...@@ -1119,8 +1119,7 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate,
// 28. Let compactDisplay be ? GetOption(options, "compactDisplay", // 28. Let compactDisplay be ? GetOption(options, "compactDisplay",
// "string", « "short", "long" », "short"). // "string", « "short", "long" », "short").
Maybe<CompactDisplay> maybe_compact_display = Maybe<CompactDisplay> maybe_compact_display = GetStringOption<CompactDisplay>(
Intl::GetStringOption<CompactDisplay>(
isolate, options, "compactDisplay", service, {"short", "long"}, isolate, options, "compactDisplay", service, {"short", "long"},
{CompactDisplay::SHORT, CompactDisplay::LONG}, CompactDisplay::SHORT); {CompactDisplay::SHORT, CompactDisplay::LONG}, CompactDisplay::SHORT);
MAYBE_RETURN(maybe_compact_display, MaybeHandle<JSNumberFormat>()); MAYBE_RETURN(maybe_compact_display, MaybeHandle<JSNumberFormat>());
...@@ -1136,8 +1135,8 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate, ...@@ -1136,8 +1135,8 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate,
// 30. Let useGrouping be ? GetOption(options, "useGrouping", "boolean", // 30. Let useGrouping be ? GetOption(options, "useGrouping", "boolean",
// undefined, true). // undefined, true).
bool use_grouping = true; bool use_grouping = true;
Maybe<bool> found_use_grouping = Intl::GetBoolOption( Maybe<bool> found_use_grouping =
isolate, options, "useGrouping", service, &use_grouping); GetBoolOption(isolate, options, "useGrouping", service, &use_grouping);
MAYBE_RETURN(found_use_grouping, MaybeHandle<JSNumberFormat>()); MAYBE_RETURN(found_use_grouping, MaybeHandle<JSNumberFormat>());
// 31. Set numberFormat.[[UseGrouping]] to useGrouping. // 31. Set numberFormat.[[UseGrouping]] to useGrouping.
if (!use_grouping) { if (!use_grouping) {
...@@ -1147,7 +1146,7 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate, ...@@ -1147,7 +1146,7 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate,
// 32. Let signDisplay be ? GetOption(options, "signDisplay", "string", « // 32. Let signDisplay be ? GetOption(options, "signDisplay", "string", «
// "auto", "never", "always", "exceptZero" », "auto"). // "auto", "never", "always", "exceptZero" », "auto").
Maybe<SignDisplay> maybe_sign_display = Intl::GetStringOption<SignDisplay>( Maybe<SignDisplay> maybe_sign_display = GetStringOption<SignDisplay>(
isolate, options, "signDisplay", service, isolate, options, "signDisplay", service,
{"auto", "never", "always", "exceptZero"}, {"auto", "never", "always", "exceptZero"},
{SignDisplay::AUTO, SignDisplay::NEVER, SignDisplay::ALWAYS, {SignDisplay::AUTO, SignDisplay::NEVER, SignDisplay::ALWAYS,
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "src/objects/intl-objects.h" #include "src/objects/intl-objects.h"
#include "src/objects/js-number-format.h" #include "src/objects/js-number-format.h"
#include "src/objects/js-plural-rules-inl.h" #include "src/objects/js-plural-rules-inl.h"
#include "src/objects/option-utils.h"
#include "unicode/locid.h" #include "unicode/locid.h"
#include "unicode/numberformatter.h" #include "unicode/numberformatter.h"
#include "unicode/plurrule.h" #include "unicode/plurrule.h"
...@@ -74,8 +75,7 @@ MaybeHandle<JSPluralRules> JSPluralRules::New(Isolate* isolate, Handle<Map> map, ...@@ -74,8 +75,7 @@ MaybeHandle<JSPluralRules> JSPluralRules::New(Isolate* isolate, Handle<Map> map,
Handle<JSReceiver> options; Handle<JSReceiver> options;
const char* service = "Intl.PluralRules"; const char* service = "Intl.PluralRules";
ASSIGN_RETURN_ON_EXCEPTION( ASSIGN_RETURN_ON_EXCEPTION(
isolate, options, isolate, options, CoerceOptionsToObject(isolate, options_obj, service),
Intl::CoerceOptionsToObject(isolate, options_obj, service),
JSPluralRules); JSPluralRules);
// 5. Let matcher be ? GetOption(options, "localeMatcher", "string", // 5. Let matcher be ? GetOption(options, "localeMatcher", "string",
...@@ -88,7 +88,7 @@ MaybeHandle<JSPluralRules> JSPluralRules::New(Isolate* isolate, Handle<Map> map, ...@@ -88,7 +88,7 @@ MaybeHandle<JSPluralRules> JSPluralRules::New(Isolate* isolate, Handle<Map> map,
// 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 = GetStringOption<Type>(
isolate, options, "type", service, {"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>());
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "src/objects/js-number-format.h" #include "src/objects/js-number-format.h"
#include "src/objects/js-relative-time-format-inl.h" #include "src/objects/js-relative-time-format-inl.h"
#include "src/objects/objects-inl.h" #include "src/objects/objects-inl.h"
#include "src/objects/option-utils.h"
#include "unicode/decimfmt.h" #include "unicode/decimfmt.h"
#include "unicode/numfmt.h" #include "unicode/numfmt.h"
#include "unicode/reldatefmt.h" #include "unicode/reldatefmt.h"
...@@ -78,8 +79,7 @@ MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::New( ...@@ -78,8 +79,7 @@ MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::New(
Handle<JSReceiver> options; Handle<JSReceiver> options;
const char* service = "Intl.RelativeTimeFormat"; const char* service = "Intl.RelativeTimeFormat";
ASSIGN_RETURN_ON_EXCEPTION( ASSIGN_RETURN_ON_EXCEPTION(
isolate, options, isolate, options, CoerceOptionsToObject(isolate, input_options, service),
Intl::CoerceOptionsToObject(isolate, input_options, service),
JSRelativeTimeFormat); JSRelativeTimeFormat);
// 4. Let opt be a new Record. // 4. Let opt be a new Record.
...@@ -147,7 +147,7 @@ MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::New( ...@@ -147,7 +147,7 @@ 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 = GetStringOption<Style>(
isolate, options, "style", service, {"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<JSRelativeTimeFormat>()); MAYBE_RETURN(maybe_style, MaybeHandle<JSRelativeTimeFormat>());
...@@ -157,7 +157,7 @@ MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::New( ...@@ -157,7 +157,7 @@ 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 = GetStringOption<Numeric>(
isolate, options, "numeric", service, {"always", "auto"}, isolate, options, "numeric", service, {"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>());
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "src/objects/js-segmenter-inl.h" #include "src/objects/js-segmenter-inl.h"
#include "src/objects/managed.h" #include "src/objects/managed.h"
#include "src/objects/objects-inl.h" #include "src/objects/objects-inl.h"
#include "src/objects/option-utils.h"
#include "unicode/brkiter.h" #include "unicode/brkiter.h"
namespace v8 { namespace v8 {
...@@ -36,8 +37,8 @@ MaybeHandle<JSSegmenter> JSSegmenter::New(Isolate* isolate, Handle<Map> map, ...@@ -36,8 +37,8 @@ MaybeHandle<JSSegmenter> JSSegmenter::New(Isolate* isolate, Handle<Map> map,
Handle<JSReceiver> options; Handle<JSReceiver> options;
const char* service = "Intl.Segmenter"; const char* service = "Intl.Segmenter";
// 5. Let options be GetOptionsObject(_options_). // 5. Let options be GetOptionsObject(_options_).
ASSIGN_RETURN_ON_EXCEPTION( ASSIGN_RETURN_ON_EXCEPTION(isolate, options,
isolate, options, Intl::GetOptionsObject(isolate, input_options, service), GetOptionsObject(isolate, input_options, service),
JSSegmenter); JSSegmenter);
// 7. Let opt be a new Record. // 7. Let opt be a new Record.
...@@ -68,7 +69,7 @@ MaybeHandle<JSSegmenter> JSSegmenter::New(Isolate* isolate, Handle<Map> map, ...@@ -68,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 = GetStringOption<Granularity>(
isolate, options, "granularity", service, isolate, options, "granularity", service,
{"grapheme", "word", "sentence"}, {"grapheme", "word", "sentence"},
{Granularity::GRAPHEME, Granularity::WORD, Granularity::SENTENCE}, {Granularity::GRAPHEME, Granularity::WORD, Granularity::SENTENCE},
......
// 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.
#include "src/objects/option-utils.h"
#include "src/numbers/conversions.h"
#include "src/objects/objects-inl.h"
namespace v8 {
namespace internal {
// ecma402/#sec-getoptionsobject
MaybeHandle<JSReceiver> GetOptionsObject(Isolate* isolate,
Handle<Object> options,
const char* method) {
// 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> CoerceOptionsToObject(Isolate* isolate,
Handle<Object> options,
const char* method) {
// 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, method), JSReceiver);
return Handle<JSReceiver>::cast(options);
}
Maybe<bool> GetStringOption(Isolate* isolate, Handle<JSReceiver> options,
const char* property,
std::vector<const char*> values, const char* method,
std::unique_ptr<char[]>* result) {
Handle<String> property_str =
isolate->factory()->NewStringFromAsciiChecked(property);
// 1. Let value be ? Get(options, property).
Handle<Object> value;
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, value,
Object::GetPropertyOrElement(isolate, options, property_str),
Nothing<bool>());
if (value->IsUndefined(isolate)) {
return Just(false);
}
// 2. c. Let value be ? ToString(value).
Handle<String> value_str;
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, value_str, Object::ToString(isolate, value), Nothing<bool>());
std::unique_ptr<char[]> value_cstr = value_str->ToCString();
// 2. d. if values is not undefined, then
if (values.size() > 0) {
// 2. d. i. If values does not contain an element equal to value,
// throw a RangeError exception.
for (size_t i = 0; i < values.size(); i++) {
if (strcmp(values.at(i), value_cstr.get()) == 0) {
// 2. e. return value
*result = std::move(value_cstr);
return Just(true);
}
}
Handle<String> method_str =
isolate->factory()->NewStringFromAsciiChecked(method);
THROW_NEW_ERROR_RETURN_VALUE(
isolate,
NewRangeError(MessageTemplate::kValueOutOfRange, value, method_str,
property_str),
Nothing<bool>());
}
// 2. e. return value
*result = std::move(value_cstr);
return Just(true);
}
V8_WARN_UNUSED_RESULT Maybe<bool> GetBoolOption(Isolate* isolate,
Handle<JSReceiver> options,
const char* property,
const char* method,
bool* result) {
Handle<String> property_str =
isolate->factory()->NewStringFromAsciiChecked(property);
// 1. Let value be ? Get(options, property).
Handle<Object> value;
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, value,
Object::GetPropertyOrElement(isolate, options, property_str),
Nothing<bool>());
// 2. If value is not undefined, then
if (!value->IsUndefined(isolate)) {
// 2. b. i. Let value be ToBoolean(value).
*result = value->BooleanValue(isolate);
// 2. e. return value
return Just(true);
}
return Just(false);
}
// ecma402/#sec-defaultnumberoption
Maybe<int> DefaultNumberOption(Isolate* isolate, Handle<Object> value, int min,
int max, int fallback, Handle<String> property) {
// 2. Else, return fallback.
if (value->IsUndefined()) return Just(fallback);
// 1. If value is not undefined, then
// a. Let value be ? ToNumber(value).
Handle<Object> value_num;
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, value_num, Object::ToNumber(isolate, value), Nothing<int>());
DCHECK(value_num->IsNumber());
// b. If value is NaN or less than minimum or greater than maximum, throw a
// RangeError exception.
if (value_num->IsNaN() || value_num->Number() < min ||
value_num->Number() > max) {
THROW_NEW_ERROR_RETURN_VALUE(
isolate,
NewRangeError(MessageTemplate::kPropertyValueOutOfRange, property),
Nothing<int>());
}
// The max and min arguments are integers and the above check makes
// sure that we are within the integer range making this double to
// int conversion safe.
//
// c. Return floor(value).
return Just(FastD2I(floor(value_num->Number())));
}
// ecma402/#sec-getnumberoption
Maybe<int> GetNumberOption(Isolate* isolate, Handle<JSReceiver> options,
Handle<String> property, int min, int max,
int fallback) {
// 1. Let value be ? Get(options, property).
Handle<Object> value;
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, value, JSReceiver::GetProperty(isolate, options, property),
Nothing<int>());
// Return ? DefaultNumberOption(value, minimum, maximum, fallback).
return DefaultNumberOption(isolate, value, min, max, fallback, property);
}
} // namespace internal
} // namespace v8
// 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.
#ifndef V8_OBJECTS_OPTION_UTILS_H_
#define V8_OBJECTS_OPTION_UTILS_H_
#include "src/execution/isolate.h"
#include "src/objects/objects.h"
namespace v8 {
namespace internal {
// ecma402/#sec-getoptionsobject and temporal/#sec-getoptionsobject
V8_WARN_UNUSED_RESULT MaybeHandle<JSReceiver> GetOptionsObject(
Isolate* isolate, Handle<Object> options, const char* method);
// ecma402/#sec-coerceoptionstoobject
V8_WARN_UNUSED_RESULT MaybeHandle<JSReceiver> CoerceOptionsToObject(
Isolate* isolate, Handle<Object> options, const char* method);
// ECMA402 9.2.10. GetOption( options, property, type, values, fallback)
// ecma402/#sec-getoption and temporal/#sec-getoption
//
// This is specialized for the case when type is string.
//
// Instead of passing undefined for the values argument as the spec
// defines, pass in an empty vector.
//
// Returns true if options object has the property and stores the
// result in value. Returns false if the value is not found. The
// caller is required to use fallback value appropriately in this
// case.
//
// method is a string denoting the method the call from; used when
// printing the error message.
V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT Maybe<bool> GetStringOption(
Isolate* isolate, Handle<JSReceiver> options, const char* property,
std::vector<const char*> values, const char* method,
std::unique_ptr<char[]>* result);
// A helper template to get string from option into a enum.
// The enum in the enum_values is the corresponding value to the strings
// in the str_values. If the option does not contains name,
// default_value will be return.
template <typename T>
V8_WARN_UNUSED_RESULT static Maybe<T> GetStringOption(
Isolate* isolate, Handle<JSReceiver> options, const char* name,
const char* method, const std::vector<const char*>& str_values,
const std::vector<T>& enum_values, T default_value) {
DCHECK_EQ(str_values.size(), enum_values.size());
std::unique_ptr<char[]> cstr;
Maybe<bool> found =
GetStringOption(isolate, options, name, str_values, method, &cstr);
MAYBE_RETURN(found, Nothing<T>());
if (found.FromJust()) {
DCHECK_NOT_NULL(cstr.get());
for (size_t i = 0; i < str_values.size(); i++) {
if (strcmp(cstr.get(), str_values[i]) == 0) {
return Just(enum_values[i]);
}
}
UNREACHABLE();
}
return Just(default_value);
}
// ECMA402 9.2.10. GetOption( options, property, type, values, fallback)
// ecma402/#sec-getoption
//
// This is specialized for the case when type is boolean.
//
// Returns true if options object has the property and stores the
// result in value. Returns false if the value is not found. The
// caller is required to use fallback value appropriately in this
// case.
//
// method is a string denoting the method it called from; used when
// printing the error message.
V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT Maybe<bool> GetBoolOption(
Isolate* isolate, Handle<JSReceiver> options, const char* property,
const char* method, bool* result);
V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT Maybe<int> GetNumberOption(
Isolate* isolate, Handle<JSReceiver> options, Handle<String> property,
int min, int max, int fallback);
// ecma402/#sec-defaultnumberoption
V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT Maybe<int> DefaultNumberOption(
Isolate* isolate, Handle<Object> value, int min, int max, int fallback,
Handle<String> property);
} // namespace internal
} // namespace v8
#endif // V8_OBJECTS_OPTION_UTILS_H_
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
#ifdef V8_INTL_SUPPORT #ifdef V8_INTL_SUPPORT
#include "src/objects/intl-objects.h"
#include "src/objects/js-break-iterator.h" #include "src/objects/js-break-iterator.h"
#include "src/objects/js-collator.h" #include "src/objects/js-collator.h"
#include "src/objects/js-date-time-format.h" #include "src/objects/js-date-time-format.h"
...@@ -15,6 +14,7 @@ ...@@ -15,6 +14,7 @@
#include "src/objects/js-segmenter.h" #include "src/objects/js-segmenter.h"
#include "src/objects/lookup.h" #include "src/objects/lookup.h"
#include "src/objects/objects-inl.h" #include "src/objects/objects-inl.h"
#include "src/objects/option-utils.h"
#include "test/cctest/cctest.h" #include "test/cctest/cctest.h"
namespace v8 { namespace v8 {
...@@ -123,8 +123,8 @@ TEST(GetStringOption) { ...@@ -123,8 +123,8 @@ TEST(GetStringOption) {
// No value found // No value found
std::unique_ptr<char[]> result = nullptr; std::unique_ptr<char[]> result = nullptr;
Maybe<bool> found = Maybe<bool> found =
Intl::GetStringOption(isolate, options, "foo", GetStringOption(isolate, options, "foo", std::vector<const char*>{},
std::vector<const char*>{}, "service", &result); "service", &result);
CHECK(!found.FromJust()); CHECK(!found.FromJust());
CHECK_NULL(result); CHECK_NULL(result);
} }
...@@ -140,8 +140,8 @@ TEST(GetStringOption) { ...@@ -140,8 +140,8 @@ TEST(GetStringOption) {
// Value found // Value found
std::unique_ptr<char[]> result = nullptr; std::unique_ptr<char[]> result = nullptr;
Maybe<bool> found = Maybe<bool> found =
Intl::GetStringOption(isolate, options, "foo", GetStringOption(isolate, options, "foo", std::vector<const char*>{},
std::vector<const char*>{}, "service", &result); "service", &result);
CHECK(found.FromJust()); CHECK(found.FromJust());
CHECK_NOT_NULL(result); CHECK_NOT_NULL(result);
CHECK_EQ(0, strcmp("42", result.get())); CHECK_EQ(0, strcmp("42", result.get()));
...@@ -150,9 +150,9 @@ TEST(GetStringOption) { ...@@ -150,9 +150,9 @@ TEST(GetStringOption) {
{ {
// No expected value in values array // No expected value in values array
std::unique_ptr<char[]> result = nullptr; std::unique_ptr<char[]> result = nullptr;
Maybe<bool> found = Intl::GetStringOption(isolate, options, "foo", Maybe<bool> found =
std::vector<const char*>{"bar"}, GetStringOption(isolate, options, "foo",
"service", &result); std::vector<const char*>{"bar"}, "service", &result);
CHECK(isolate->has_pending_exception()); CHECK(isolate->has_pending_exception());
CHECK(found.IsNothing()); CHECK(found.IsNothing());
CHECK_NULL(result); CHECK_NULL(result);
...@@ -162,8 +162,8 @@ TEST(GetStringOption) { ...@@ -162,8 +162,8 @@ TEST(GetStringOption) {
{ {
// Expected value in values array // Expected value in values array
std::unique_ptr<char[]> result = nullptr; std::unique_ptr<char[]> result = nullptr;
Maybe<bool> found = Intl::GetStringOption(isolate, options, "foo", Maybe<bool> found =
std::vector<const char*>{"42"}, GetStringOption(isolate, options, "foo", std::vector<const char*>{"42"},
"service", &result); "service", &result);
CHECK(found.FromJust()); CHECK(found.FromJust());
CHECK_NOT_NULL(result); CHECK_NOT_NULL(result);
...@@ -181,7 +181,7 @@ TEST(GetBoolOption) { ...@@ -181,7 +181,7 @@ TEST(GetBoolOption) {
{ {
bool result = false; bool result = false;
Maybe<bool> found = Maybe<bool> found =
Intl::GetBoolOption(isolate, options, "foo", "service", &result); GetBoolOption(isolate, options, "foo", "service", &result);
CHECK(!found.FromJust()); CHECK(!found.FromJust());
CHECK(!result); CHECK(!result);
} }
...@@ -197,7 +197,7 @@ TEST(GetBoolOption) { ...@@ -197,7 +197,7 @@ TEST(GetBoolOption) {
.Assert(); .Assert();
bool result = false; bool result = false;
Maybe<bool> found = Maybe<bool> found =
Intl::GetBoolOption(isolate, options, "foo", "service", &result); GetBoolOption(isolate, options, "foo", "service", &result);
CHECK(found.FromJust()); CHECK(found.FromJust());
CHECK(!result); CHECK(!result);
} }
...@@ -212,7 +212,7 @@ TEST(GetBoolOption) { ...@@ -212,7 +212,7 @@ TEST(GetBoolOption) {
.Assert(); .Assert();
bool result = false; bool result = false;
Maybe<bool> found = Maybe<bool> found =
Intl::GetBoolOption(isolate, options, "foo", "service", &result); GetBoolOption(isolate, options, "foo", "service", &result);
CHECK(found.FromJust()); CHECK(found.FromJust());
CHECK(result); CHECK(result);
} }
......
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