[Intl] Fix error message to report the right method.

Bug: v8:9464
Change-Id: I3252de850bbaa5fdb15f5fc2103f1ebb7be3e1ea
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1799396
Commit-Queue: Frank Tang <ftang@chromium.org>
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63734}
This commit is contained in:
Frank Tang 2019-09-12 11:24:26 -07:00 committed by Commit Bot
parent ee0581c332
commit 6cf125a90c
17 changed files with 166 additions and 107 deletions

View File

@ -125,26 +125,24 @@ Object BigIntToStringImpl(Handle<Object> receiver, Handle<Object> radix,
BUILTIN(BigIntPrototypeToLocaleString) { BUILTIN(BigIntPrototypeToLocaleString) {
HandleScope scope(isolate); HandleScope scope(isolate);
const char* method = "BigInt.prototype.toLocaleString";
#ifdef V8_INTL_SUPPORT #ifdef V8_INTL_SUPPORT
if (FLAG_harmony_intl_bigint) { if (FLAG_harmony_intl_bigint) {
// 1. Let x be ? thisBigIntValue(this value). // 1. Let x be ? thisBigIntValue(this value).
Handle<BigInt> x; Handle<BigInt> x;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION( ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, x, isolate, x, ThisBigIntValue(isolate, args.receiver(), method));
ThisBigIntValue(isolate, args.receiver(),
"BigInt.prototype.toLocaleString"));
RETURN_RESULT_OR_FAILURE( RETURN_RESULT_OR_FAILURE(
isolate, isolate,
Intl::NumberToLocaleString(isolate, x, args.atOrUndefined(isolate, 1), Intl::NumberToLocaleString(isolate, x, args.atOrUndefined(isolate, 1),
args.atOrUndefined(isolate, 2))); args.atOrUndefined(isolate, 2), method));
} }
// Fallbacks to old toString implemention if flag is off or no // Fallbacks to old toString implemention if flag is off or no
// V8_INTL_SUPPORT // V8_INTL_SUPPORT
#endif // V8_INTL_SUPPORT #endif // V8_INTL_SUPPORT
Handle<Object> radix = isolate->factory()->undefined_value(); Handle<Object> radix = isolate->factory()->undefined_value();
return BigIntToStringImpl(args.receiver(), radix, isolate, return BigIntToStringImpl(args.receiver(), radix, isolate, method);
"BigInt.prototype.toLocaleString");
} }
BUILTIN(BigIntPrototypeToString) { BUILTIN(BigIntPrototypeToString) {

View File

@ -854,16 +854,18 @@ BUILTIN(DatePrototypeToLocaleDateString) {
isolate->CountUsage(v8::Isolate::UseCounterFeature::kDateToLocaleDateString); isolate->CountUsage(v8::Isolate::UseCounterFeature::kDateToLocaleDateString);
CHECK_RECEIVER(JSDate, date, "Date.prototype.toLocaleDateString"); const char* method = "Date.prototype.toLocaleDateString";
CHECK_RECEIVER(JSDate, date, method);
RETURN_RESULT_OR_FAILURE( RETURN_RESULT_OR_FAILURE(
isolate, JSDateTimeFormat::ToLocaleDateTime( isolate, JSDateTimeFormat::ToLocaleDateTime(
isolate, isolate,
date, // date date, // date
args.atOrUndefined(isolate, 1), // locales args.atOrUndefined(isolate, 1), // locales
args.atOrUndefined(isolate, 2), // options args.atOrUndefined(isolate, 2), // options
JSDateTimeFormat::RequiredOption::kDate, // required JSDateTimeFormat::RequiredOption::kDate, // required
JSDateTimeFormat::DefaultsOption::kDate)); // defaults JSDateTimeFormat::DefaultsOption::kDate, // defaults
method)); // method
} }
// ecma402 #sup-date.prototype.tolocalestring // ecma402 #sup-date.prototype.tolocalestring
@ -872,16 +874,18 @@ BUILTIN(DatePrototypeToLocaleString) {
isolate->CountUsage(v8::Isolate::UseCounterFeature::kDateToLocaleString); isolate->CountUsage(v8::Isolate::UseCounterFeature::kDateToLocaleString);
CHECK_RECEIVER(JSDate, date, "Date.prototype.toLocaleString"); const char* method = "Date.prototype.toLocaleString";
CHECK_RECEIVER(JSDate, date, method);
RETURN_RESULT_OR_FAILURE( RETURN_RESULT_OR_FAILURE(
isolate, JSDateTimeFormat::ToLocaleDateTime( isolate, JSDateTimeFormat::ToLocaleDateTime(
isolate, isolate,
date, // date date, // date
args.atOrUndefined(isolate, 1), // locales args.atOrUndefined(isolate, 1), // locales
args.atOrUndefined(isolate, 2), // options args.atOrUndefined(isolate, 2), // options
JSDateTimeFormat::RequiredOption::kAny, // required JSDateTimeFormat::RequiredOption::kAny, // required
JSDateTimeFormat::DefaultsOption::kAll)); // defaults JSDateTimeFormat::DefaultsOption::kAll, // defaults
method)); // method
} }
// ecma402 #sup-date.prototype.tolocaletimestring // ecma402 #sup-date.prototype.tolocaletimestring
@ -890,16 +894,18 @@ BUILTIN(DatePrototypeToLocaleTimeString) {
isolate->CountUsage(v8::Isolate::UseCounterFeature::kDateToLocaleTimeString); isolate->CountUsage(v8::Isolate::UseCounterFeature::kDateToLocaleTimeString);
CHECK_RECEIVER(JSDate, date, "Date.prototype.toLocaleTimeString"); const char* method = "Date.prototype.toLocaleTimeString";
CHECK_RECEIVER(JSDate, date, method);
RETURN_RESULT_OR_FAILURE( RETURN_RESULT_OR_FAILURE(
isolate, JSDateTimeFormat::ToLocaleDateTime( isolate, JSDateTimeFormat::ToLocaleDateTime(
isolate, isolate,
date, // date date, // date
args.atOrUndefined(isolate, 1), // locales args.atOrUndefined(isolate, 1), // locales
args.atOrUndefined(isolate, 2), // options args.atOrUndefined(isolate, 2), // options
JSDateTimeFormat::RequiredOption::kTime, // required JSDateTimeFormat::RequiredOption::kTime, // required
JSDateTimeFormat::DefaultsOption::kTime)); // defaults JSDateTimeFormat::DefaultsOption::kTime, // defaults
method)); // method
} }
#endif // V8_INTL_SUPPORT #endif // V8_INTL_SUPPORT

View File

@ -282,8 +282,8 @@ Object LegacyFormatConstructor(BuiltinArguments args, Isolate* isolate,
// 3. Perform ? Initialize<T>(Format, locales, options). // 3. Perform ? Initialize<T>(Format, locales, options).
Handle<T> format; Handle<T> format;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, format, ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
T::New(isolate, map, locales, options)); isolate, format, T::New(isolate, map, locales, options, method));
// 4. Let this be the this value. // 4. Let this be the this value.
Handle<Object> receiver = args.receiver(); Handle<Object> receiver = args.receiver();
@ -367,7 +367,8 @@ Object DisallowCallConstructor(BuiltinArguments args, Isolate* isolate,
* Common code shared by Collator and V8BreakIterator * Common code shared by Collator and V8BreakIterator
*/ */
template <class T> template <class T>
Object CallOrConstructConstructor(BuiltinArguments args, Isolate* isolate) { Object CallOrConstructConstructor(BuiltinArguments args, Isolate* isolate,
const char* method) {
Handle<JSReceiver> new_target; Handle<JSReceiver> new_target;
if (args.new_target()->IsUndefined(isolate)) { if (args.new_target()->IsUndefined(isolate)) {
@ -386,7 +387,8 @@ Object CallOrConstructConstructor(BuiltinArguments args, Isolate* isolate) {
ASSIGN_RETURN_FAILURE_ON_EXCEPTION( ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, map, JSFunction::GetDerivedMap(isolate, target, new_target)); isolate, map, JSFunction::GetDerivedMap(isolate, target, new_target));
RETURN_RESULT_OR_FAILURE(isolate, T::New(isolate, map, locales, options)); RETURN_RESULT_OR_FAILURE(isolate,
T::New(isolate, map, locales, options, method));
} }
} // namespace } // namespace
@ -884,7 +886,7 @@ BUILTIN(CollatorConstructor) {
isolate->CountUsage(v8::Isolate::UseCounterFeature::kCollator); isolate->CountUsage(v8::Isolate::UseCounterFeature::kCollator);
return CallOrConstructConstructor<JSCollator>(args, isolate); return CallOrConstructConstructor<JSCollator>(args, isolate, "Intl.Collator");
} }
BUILTIN(CollatorPrototypeResolvedOptions) { BUILTIN(CollatorPrototypeResolvedOptions) {
@ -1069,7 +1071,8 @@ BUILTIN(SegmenterPrototypeSegment) {
BUILTIN(V8BreakIteratorConstructor) { BUILTIN(V8BreakIteratorConstructor) {
HandleScope scope(isolate); HandleScope scope(isolate);
return CallOrConstructConstructor<JSV8BreakIterator>(args, isolate); return CallOrConstructConstructor<JSV8BreakIterator>(args, isolate,
"Intl.v8BreakIterator");
} }
BUILTIN(V8BreakIteratorPrototypeResolvedOptions) { BUILTIN(V8BreakIteratorPrototypeResolvedOptions) {

View File

@ -111,6 +111,7 @@ BUILTIN(NumberPrototypeToFixed) {
// ES6 section 20.1.3.4 Number.prototype.toLocaleString ( [ r1 [ , r2 ] ] ) // ES6 section 20.1.3.4 Number.prototype.toLocaleString ( [ r1 [ , r2 ] ] )
BUILTIN(NumberPrototypeToLocaleString) { BUILTIN(NumberPrototypeToLocaleString) {
HandleScope scope(isolate); HandleScope scope(isolate);
const char* method = "Number.prototype.toLocaleString";
isolate->CountUsage(v8::Isolate::UseCounterFeature::kNumberToLocaleString); isolate->CountUsage(v8::Isolate::UseCounterFeature::kNumberToLocaleString);
@ -123,17 +124,17 @@ BUILTIN(NumberPrototypeToLocaleString) {
// 1. Let x be ? thisNumberValue(this value) // 1. Let x be ? thisNumberValue(this value)
if (!value->IsNumber()) { if (!value->IsNumber()) {
THROW_NEW_ERROR_RETURN_FAILURE( THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kNotGeneric, isolate,
isolate->factory()->NewStringFromAsciiChecked( NewTypeError(MessageTemplate::kNotGeneric,
"Number.prototype.toLocaleString"), isolate->factory()->NewStringFromAsciiChecked(method),
isolate->factory()->Number_string())); isolate->factory()->Number_string()));
} }
#ifdef V8_INTL_SUPPORT #ifdef V8_INTL_SUPPORT
RETURN_RESULT_OR_FAILURE( RETURN_RESULT_OR_FAILURE(
isolate, isolate,
Intl::NumberToLocaleString(isolate, value, args.atOrUndefined(isolate, 1), Intl::NumberToLocaleString(isolate, value, args.atOrUndefined(isolate, 1),
args.atOrUndefined(isolate, 2))); args.atOrUndefined(isolate, 2), method));
#else #else
// Turn the {value} into a String. // Turn the {value} into a String.
return *isolate->factory()->NumberToString(value); return *isolate->factory()->NumberToString(value);

View File

@ -136,20 +136,21 @@ BUILTIN(StringPrototypeLocaleCompare) {
HandleScope handle_scope(isolate); HandleScope handle_scope(isolate);
isolate->CountUsage(v8::Isolate::UseCounterFeature::kStringLocaleCompare); isolate->CountUsage(v8::Isolate::UseCounterFeature::kStringLocaleCompare);
const char* method = "String.prototype.localeCompare";
#ifdef V8_INTL_SUPPORT #ifdef V8_INTL_SUPPORT
TO_THIS_STRING(str1, "String.prototype.localeCompare"); TO_THIS_STRING(str1, method);
Handle<String> str2; Handle<String> str2;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION( ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, str2, Object::ToString(isolate, args.atOrUndefined(isolate, 1))); isolate, str2, Object::ToString(isolate, args.atOrUndefined(isolate, 1)));
RETURN_RESULT_OR_FAILURE( RETURN_RESULT_OR_FAILURE(
isolate, Intl::StringLocaleCompare(isolate, str1, str2, isolate, Intl::StringLocaleCompare(
args.atOrUndefined(isolate, 2), isolate, str1, str2, args.atOrUndefined(isolate, 2),
args.atOrUndefined(isolate, 3))); args.atOrUndefined(isolate, 3), method));
#else #else
DCHECK_EQ(2, args.length()); DCHECK_EQ(2, args.length());
TO_THIS_STRING(str1, "String.prototype.localeCompare"); TO_THIS_STRING(str1, method);
Handle<String> str2; Handle<String> str2;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, str2, ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, str2,
Object::ToString(isolate, args.at(1))); Object::ToString(isolate, args.at(1)));

View File

@ -177,12 +177,13 @@ const UChar* GetUCharBufferFromFlat(const String::FlatContent& flat,
template <typename T> template <typename T>
MaybeHandle<T> New(Isolate* isolate, Handle<JSFunction> constructor, MaybeHandle<T> New(Isolate* isolate, Handle<JSFunction> constructor,
Handle<Object> locales, Handle<Object> options) { Handle<Object> locales, Handle<Object> options,
const char* method) {
Handle<Map> map; Handle<Map> map;
ASSIGN_RETURN_ON_EXCEPTION( ASSIGN_RETURN_ON_EXCEPTION(
isolate, map, isolate, map,
JSFunction::GetDerivedMap(isolate, constructor, constructor), T); JSFunction::GetDerivedMap(isolate, constructor, constructor), T);
return T::New(isolate, map, locales, options); return T::New(isolate, map, locales, options, method);
} }
} // namespace } // namespace
@ -995,11 +996,9 @@ MaybeHandle<String> Intl::StringLocaleConvertCase(Isolate* isolate,
} }
} }
MaybeHandle<Object> Intl::StringLocaleCompare(Isolate* isolate, MaybeHandle<Object> Intl::StringLocaleCompare(
Handle<String> string1, Isolate* isolate, Handle<String> string1, Handle<String> string2,
Handle<String> string2, Handle<Object> locales, Handle<Object> options, const char* method) {
Handle<Object> locales,
Handle<Object> options) {
// We only cache the instance when both locales and options are undefined, // We only cache the instance when both locales and options are undefined,
// as that is the only case when the specified side-effects of examining // as that is the only case when the specified side-effects of examining
// those arguments are unobservable. // those arguments are unobservable.
@ -1025,7 +1024,7 @@ MaybeHandle<Object> Intl::StringLocaleCompare(Isolate* isolate,
Handle<JSCollator> collator; Handle<JSCollator> collator;
ASSIGN_RETURN_ON_EXCEPTION( ASSIGN_RETURN_ON_EXCEPTION(
isolate, collator, isolate, collator,
New<JSCollator>(isolate, constructor, locales, options), Object); New<JSCollator>(isolate, constructor, locales, options, method), Object);
if (can_cache) { if (can_cache) {
isolate->set_icu_object_in_cache( isolate->set_icu_object_in_cache(
Isolate::ICUObjectCacheType::kDefaultCollator, Isolate::ICUObjectCacheType::kDefaultCollator,
@ -1084,7 +1083,8 @@ Handle<Object> Intl::CompareStrings(Isolate* isolate,
MaybeHandle<String> Intl::NumberToLocaleString(Isolate* isolate, MaybeHandle<String> Intl::NumberToLocaleString(Isolate* isolate,
Handle<Object> num, Handle<Object> num,
Handle<Object> locales, Handle<Object> locales,
Handle<Object> options) { Handle<Object> options,
const char* method) {
Handle<Object> numeric_obj; Handle<Object> numeric_obj;
if (FLAG_harmony_intl_bigint) { if (FLAG_harmony_intl_bigint) {
ASSIGN_RETURN_ON_EXCEPTION(isolate, numeric_obj, ASSIGN_RETURN_ON_EXCEPTION(isolate, numeric_obj,
@ -1119,7 +1119,8 @@ MaybeHandle<String> Intl::NumberToLocaleString(Isolate* isolate,
// 2. Let numberFormat be ? Construct(%NumberFormat%, « locales, options »). // 2. Let numberFormat be ? Construct(%NumberFormat%, « locales, options »).
ASSIGN_RETURN_ON_EXCEPTION( ASSIGN_RETURN_ON_EXCEPTION(
isolate, number_format, isolate, number_format,
New<JSNumberFormat>(isolate, constructor, locales, options), String); New<JSNumberFormat>(isolate, constructor, locales, options, method),
String);
if (can_cache) { if (can_cache) {
isolate->set_icu_object_in_cache( isolate->set_icu_object_in_cache(

View File

@ -164,7 +164,7 @@ class Intl {
V8_WARN_UNUSED_RESULT static MaybeHandle<Object> StringLocaleCompare( V8_WARN_UNUSED_RESULT static MaybeHandle<Object> StringLocaleCompare(
Isolate* isolate, Handle<String> s1, Handle<String> s2, Isolate* isolate, Handle<String> s1, Handle<String> s2,
Handle<Object> locales, Handle<Object> options); Handle<Object> locales, Handle<Object> options, const char* method);
V8_WARN_UNUSED_RESULT static Handle<Object> CompareStrings( V8_WARN_UNUSED_RESULT static Handle<Object> CompareStrings(
Isolate* isolate, const icu::Collator& collator, Handle<String> s1, Isolate* isolate, const icu::Collator& collator, Handle<String> s1,
@ -173,7 +173,7 @@ class Intl {
// ecma402/#sup-properties-of-the-number-prototype-object // ecma402/#sup-properties-of-the-number-prototype-object
V8_WARN_UNUSED_RESULT static MaybeHandle<String> NumberToLocaleString( V8_WARN_UNUSED_RESULT static MaybeHandle<String> NumberToLocaleString(
Isolate* isolate, Handle<Object> num, Handle<Object> locales, Isolate* isolate, Handle<Object> num, Handle<Object> locales,
Handle<Object> options); Handle<Object> options, const char* method);
// ecma402/#sec-setnfdigitoptions // ecma402/#sec-setnfdigitoptions
struct NumberFormatDigitOptions { struct NumberFormatDigitOptions {

View File

@ -17,7 +17,7 @@ namespace internal {
MaybeHandle<JSV8BreakIterator> JSV8BreakIterator::New( MaybeHandle<JSV8BreakIterator> JSV8BreakIterator::New(
Isolate* isolate, Handle<Map> map, Handle<Object> locales, Isolate* isolate, Handle<Map> map, Handle<Object> locales,
Handle<Object> options_obj) { Handle<Object> options_obj, const char* service) {
Factory* factory = isolate->factory(); Factory* factory = isolate->factory();
// 1. Let requestedLocales be ? CanonicalizeLocaleList(locales). // 1. Let requestedLocales be ? CanonicalizeLocaleList(locales).
@ -31,15 +31,14 @@ MaybeHandle<JSV8BreakIterator> JSV8BreakIterator::New(
if (options_obj->IsUndefined(isolate)) { if (options_obj->IsUndefined(isolate)) {
options = factory->NewJSObjectWithNullProto(); options = factory->NewJSObjectWithNullProto();
} else { } else {
ASSIGN_RETURN_ON_EXCEPTION( ASSIGN_RETURN_ON_EXCEPTION(isolate, options,
isolate, options, Object::ToObject(isolate, options_obj, service),
Object::ToObject(isolate, options_obj, "Intl.JSV8BreakIterator"), JSV8BreakIterator);
JSV8BreakIterator);
} }
// Extract locale string // Extract locale string
Maybe<Intl::MatcherOption> maybe_locale_matcher = Maybe<Intl::MatcherOption> maybe_locale_matcher =
Intl::GetLocaleMatcher(isolate, options, "Intl.JSV8BreakIterator"); Intl::GetLocaleMatcher(isolate, options, service);
MAYBE_RETURN(maybe_locale_matcher, MaybeHandle<JSV8BreakIterator>()); MAYBE_RETURN(maybe_locale_matcher, MaybeHandle<JSV8BreakIterator>());
Intl::MatcherOption matcher = maybe_locale_matcher.FromJust(); Intl::MatcherOption matcher = maybe_locale_matcher.FromJust();
@ -49,7 +48,7 @@ MaybeHandle<JSV8BreakIterator> JSV8BreakIterator::New(
// Extract type from options // Extract type from options
Maybe<Type> maybe_type = Intl::GetStringOption<Type>( Maybe<Type> maybe_type = Intl::GetStringOption<Type>(
isolate, options, "type", "Intl.v8BreakIterator", 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);
MAYBE_RETURN(maybe_type, MaybeHandle<JSV8BreakIterator>()); MAYBE_RETURN(maybe_type, MaybeHandle<JSV8BreakIterator>());

View File

@ -31,7 +31,7 @@ class JSV8BreakIterator : public JSObject {
public: public:
V8_WARN_UNUSED_RESULT static MaybeHandle<JSV8BreakIterator> New( V8_WARN_UNUSED_RESULT static MaybeHandle<JSV8BreakIterator> New(
Isolate* isolate, Handle<Map> map, Handle<Object> input_locales, Isolate* isolate, Handle<Map> map, Handle<Object> input_locales,
Handle<Object> input_options); Handle<Object> input_options, const char* service);
static Handle<JSObject> ResolvedOptions( static Handle<JSObject> ResolvedOptions(
Isolate* isolate, Handle<JSV8BreakIterator> break_iterator); Isolate* isolate, Handle<JSV8BreakIterator> break_iterator);

View File

@ -243,7 +243,8 @@ void SetCaseFirstOption(icu::Collator* icu_collator,
// static // static
MaybeHandle<JSCollator> JSCollator::New(Isolate* isolate, Handle<Map> map, MaybeHandle<JSCollator> JSCollator::New(Isolate* isolate, Handle<Map> map,
Handle<Object> locales, Handle<Object> locales,
Handle<Object> options_obj) { Handle<Object> options_obj,
const char* service) {
// 1. Let requestedLocales be ? CanonicalizeLocaleList(locales). // 1. 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);
@ -258,9 +259,9 @@ MaybeHandle<JSCollator> JSCollator::New(Isolate* isolate, Handle<Map> map,
} else { } else {
// 3. Else // 3. Else
// 3. a. Let options be ? ToObject(options). // 3. a. Let options be ? ToObject(options).
ASSIGN_RETURN_ON_EXCEPTION( ASSIGN_RETURN_ON_EXCEPTION(isolate, options_obj,
isolate, options_obj, Object::ToObject(isolate, options_obj, service),
Object::ToObject(isolate, options_obj, "Intl.Collator"), JSCollator); JSCollator);
} }
// At this point, options_obj can either be a JSObject or a JSProxy only. // At this point, options_obj can either be a JSObject or a JSProxy only.
@ -269,7 +270,7 @@ MaybeHandle<JSCollator> JSCollator::New(Isolate* isolate, Handle<Map> map,
// 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 = Intl::GetStringOption<Usage>(
isolate, options, "usage", "Intl.Collator", {"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>());
Usage usage = maybe_usage.FromJust(); Usage usage = maybe_usage.FromJust();
@ -278,7 +279,7 @@ MaybeHandle<JSCollator> JSCollator::New(Isolate* isolate, Handle<Map> map,
// « "lookup", "best fit" », "best fit"). // « "lookup", "best fit" », "best fit").
// 10. Set opt.[[localeMatcher]] to matcher. // 10. Set opt.[[localeMatcher]] to matcher.
Maybe<Intl::MatcherOption> maybe_locale_matcher = Maybe<Intl::MatcherOption> maybe_locale_matcher =
Intl::GetLocaleMatcher(isolate, options, "Intl.Collator"); Intl::GetLocaleMatcher(isolate, options, service);
MAYBE_RETURN(maybe_locale_matcher, MaybeHandle<JSCollator>()); MAYBE_RETURN(maybe_locale_matcher, MaybeHandle<JSCollator>());
Intl::MatcherOption matcher = maybe_locale_matcher.FromJust(); Intl::MatcherOption matcher = maybe_locale_matcher.FromJust();
@ -293,14 +294,14 @@ MaybeHandle<JSCollator> JSCollator::New(Isolate* isolate, Handle<Map> map,
// //
// 13. Set opt.[[kn]] to numeric. // 13. Set opt.[[kn]] to numeric.
bool numeric; bool numeric;
Maybe<bool> found_numeric = Intl::GetBoolOption(isolate, options, "numeric", Maybe<bool> found_numeric =
"Intl.Collator", &numeric); Intl::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",
// « "upper", "lower", "false" », undefined). // « "upper", "lower", "false" », undefined).
Maybe<Intl::CaseFirst> maybe_case_first = Maybe<Intl::CaseFirst> maybe_case_first =
Intl::GetCaseFirst(isolate, options, "Intl.Collator"); Intl::GetCaseFirst(isolate, options, service);
MAYBE_RETURN(maybe_case_first, MaybeHandle<JSCollator>()); MAYBE_RETURN(maybe_case_first, MaybeHandle<JSCollator>());
Intl::CaseFirst case_first = maybe_case_first.FromJust(); Intl::CaseFirst case_first = maybe_case_first.FromJust();
@ -411,7 +412,7 @@ 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 = Intl::GetStringOption<Sensitivity>(
isolate, options, "sensitivity", "Intl.Collator", isolate, options, "sensitivity", service,
{"base", "accent", "case", "variant"}, {"base", "accent", "case", "variant"},
{Sensitivity::kBase, Sensitivity::kAccent, Sensitivity::kCase, {Sensitivity::kBase, Sensitivity::kAccent, Sensitivity::kCase,
Sensitivity::kVariant}, Sensitivity::kVariant},
@ -451,9 +452,8 @@ 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 = Maybe<bool> found_ignore_punctuation = Intl::GetBoolOption(
Intl::GetBoolOption(isolate, options, "ignorePunctuation", isolate, options, "ignorePunctuation", service, &ignore_punctuation);
"Intl.Collator", &ignore_punctuation);
MAYBE_RETURN(found_ignore_punctuation, MaybeHandle<JSCollator>()); MAYBE_RETURN(found_ignore_punctuation, MaybeHandle<JSCollator>());
// 28. Set collator.[[IgnorePunctuation]] to ignorePunctuation. // 28. Set collator.[[IgnorePunctuation]] to ignorePunctuation.

View File

@ -34,7 +34,7 @@ class JSCollator : public JSObject {
// ecma402/#sec-initializecollator // ecma402/#sec-initializecollator
V8_WARN_UNUSED_RESULT static MaybeHandle<JSCollator> New( V8_WARN_UNUSED_RESULT static MaybeHandle<JSCollator> New(
Isolate* isolate, Handle<Map> map, Handle<Object> locales, Isolate* isolate, Handle<Map> map, Handle<Object> locales,
Handle<Object> options); Handle<Object> options, const char* service);
// ecma402/#sec-intl.collator.prototype.resolvedoptions // ecma402/#sec-intl.collator.prototype.resolvedoptions
static Handle<JSObject> ResolvedOptions(Isolate* isolate, static Handle<JSObject> ResolvedOptions(Isolate* isolate,

View File

@ -641,7 +641,8 @@ Isolate::ICUObjectCacheType ConvertToCacheType(
MaybeHandle<String> JSDateTimeFormat::ToLocaleDateTime( MaybeHandle<String> JSDateTimeFormat::ToLocaleDateTime(
Isolate* isolate, Handle<Object> date, Handle<Object> locales, Isolate* isolate, Handle<Object> date, Handle<Object> locales,
Handle<Object> options, RequiredOption required, DefaultsOption defaults) { Handle<Object> options, RequiredOption required, DefaultsOption defaults,
const char* method) {
Isolate::ICUObjectCacheType cache_type = ConvertToCacheType(defaults); Isolate::ICUObjectCacheType cache_type = ConvertToCacheType(defaults);
Factory* factory = isolate->factory(); Factory* factory = isolate->factory();
@ -691,7 +692,8 @@ MaybeHandle<String> JSDateTimeFormat::ToLocaleDateTime(
Handle<JSDateTimeFormat> date_time_format; Handle<JSDateTimeFormat> date_time_format;
ASSIGN_RETURN_ON_EXCEPTION( ASSIGN_RETURN_ON_EXCEPTION(
isolate, date_time_format, isolate, date_time_format,
JSDateTimeFormat::New(isolate, map, locales, internal_options), String); JSDateTimeFormat::New(isolate, map, locales, internal_options, method),
String);
if (can_cache) { if (can_cache) {
isolate->set_icu_object_in_cache( isolate->set_icu_object_in_cache(
@ -1215,7 +1217,7 @@ enum FormatMatcherOption { kBestFit, kBasic };
// ecma402/#sec-initializedatetimeformat // ecma402/#sec-initializedatetimeformat
MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New( MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New(
Isolate* isolate, Handle<Map> map, Handle<Object> locales, Isolate* isolate, Handle<Map> map, Handle<Object> locales,
Handle<Object> input_options) { Handle<Object> input_options, const char* service) {
Factory* factory = isolate->factory(); Factory* factory = isolate->factory();
// 1. Let requestedLocales be ? CanonicalizeLocaleList(locales). // 1. Let requestedLocales be ? CanonicalizeLocaleList(locales).
Maybe<std::vector<std::string>> maybe_requested_locales = Maybe<std::vector<std::string>> maybe_requested_locales =
@ -1265,21 +1267,21 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New(
} }
Maybe<Intl::MatcherOption> maybe_locale_matcher = Maybe<Intl::MatcherOption> maybe_locale_matcher =
Intl::GetLocaleMatcher(isolate, options, "Intl.DateTimeFormat"); Intl::GetLocaleMatcher(isolate, options, service);
MAYBE_RETURN(maybe_locale_matcher, MaybeHandle<JSDateTimeFormat>()); MAYBE_RETURN(maybe_locale_matcher, MaybeHandle<JSDateTimeFormat>());
Intl::MatcherOption locale_matcher = maybe_locale_matcher.FromJust(); Intl::MatcherOption locale_matcher = maybe_locale_matcher.FromJust();
// 6. Let hour12 be ? GetOption(options, "hour12", "boolean", undefined, // 6. Let hour12 be ? GetOption(options, "hour12", "boolean", undefined,
// undefined). // undefined).
bool hour12; bool hour12;
Maybe<bool> maybe_get_hour12 = Intl::GetBoolOption( Maybe<bool> maybe_get_hour12 =
isolate, options, "hour12", "Intl.DateTimeFormat", &hour12); Intl::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",
// "h12", "h23", "h24" », undefined). // "h12", "h23", "h24" », undefined).
Maybe<Intl::HourCycle> maybe_hour_cycle = Maybe<Intl::HourCycle> maybe_hour_cycle =
Intl::GetHourCycle(isolate, options, "Intl.DateTimeFormat"); Intl::GetHourCycle(isolate, options, service);
MAYBE_RETURN(maybe_hour_cycle, MaybeHandle<JSDateTimeFormat>()); MAYBE_RETURN(maybe_hour_cycle, MaybeHandle<JSDateTimeFormat>());
Intl::HourCycle hour_cycle = maybe_hour_cycle.FromJust(); Intl::HourCycle hour_cycle = maybe_hour_cycle.FromJust();
@ -1321,9 +1323,8 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New(
// 17. Let timeZone be ? Get(options, "timeZone"). // 17. Let timeZone be ? Get(options, "timeZone").
const std::vector<const char*> empty_values; const std::vector<const char*> empty_values;
std::unique_ptr<char[]> timezone = nullptr; std::unique_ptr<char[]> timezone = nullptr;
Maybe<bool> maybe_timezone = Maybe<bool> maybe_timezone = Intl::GetStringOption(
Intl::GetStringOption(isolate, options, "timeZone", empty_values, isolate, options, "timeZone", empty_values, service, &timezone);
"Intl.DateTimeFormat", &timezone);
MAYBE_RETURN(maybe_timezone, Handle<JSDateTimeFormat>()); MAYBE_RETURN(maybe_timezone, Handle<JSDateTimeFormat>());
std::unique_ptr<icu::TimeZone> tz = CreateTimeZone(isolate, timezone.get()); std::unique_ptr<icu::TimeZone> tz = CreateTimeZone(isolate, timezone.get());
@ -1413,7 +1414,7 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New(
// "full", "long", "medium", "short" », undefined). // "full", "long", "medium", "short" », undefined).
Maybe<DateTimeStyle> maybe_date_style = Maybe<DateTimeStyle> maybe_date_style =
Intl::GetStringOption<DateTimeStyle>( Intl::GetStringOption<DateTimeStyle>(
isolate, options, "dateStyle", "Intl.DateTimeFormat", isolate, options, "dateStyle", service,
{"full", "long", "medium", "short"}, {"full", "long", "medium", "short"},
{DateTimeStyle::kFull, DateTimeStyle::kLong, DateTimeStyle::kMedium, {DateTimeStyle::kFull, DateTimeStyle::kLong, DateTimeStyle::kMedium,
DateTimeStyle::kShort}, DateTimeStyle::kShort},
@ -1427,7 +1428,7 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New(
// "full", "long", "medium", "short" »). // "full", "long", "medium", "short" »).
Maybe<DateTimeStyle> maybe_time_style = Maybe<DateTimeStyle> maybe_time_style =
Intl::GetStringOption<DateTimeStyle>( Intl::GetStringOption<DateTimeStyle>(
isolate, options, "timeStyle", "Intl.DateTimeFormat", isolate, options, "timeStyle", service,
{"full", "long", "medium", "short"}, {"full", "long", "medium", "short"},
{DateTimeStyle::kFull, DateTimeStyle::kLong, DateTimeStyle::kMedium, {DateTimeStyle::kFull, DateTimeStyle::kLong, DateTimeStyle::kMedium,
DateTimeStyle::kShort}, DateTimeStyle::kShort},
@ -1455,9 +1456,9 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New(
// i. Let prop be the name given in the Property column of the row. // i. Let prop be the name given in the Property column of the row.
// 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 = Intl::GetStringOption( Maybe<bool> maybe_get_option =
isolate, options, item.property.c_str(), item.allowed_values, Intl::GetStringOption(isolate, options, item.property.c_str(),
"Intl.DateTimeFormat", &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()) {
if (item.property == "hour") { if (item.property == "hour") {
@ -1486,8 +1487,7 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New(
// « "basic", "best fit" », "best fit"). // « "basic", "best fit" », "best fit").
Maybe<FormatMatcherOption> maybe_format_matcher = Maybe<FormatMatcherOption> maybe_format_matcher =
Intl::GetStringOption<FormatMatcherOption>( Intl::GetStringOption<FormatMatcherOption>(
isolate, options, "formatMatcher", "Intl.DateTimeFormat", isolate, options, "formatMatcher", service, {"best fit", "basic"},
{"best fit", "basic"},
{FormatMatcherOption::kBestFit, FormatMatcherOption::kBasic}, {FormatMatcherOption::kBestFit, FormatMatcherOption::kBasic},
FormatMatcherOption::kBestFit); FormatMatcherOption::kBestFit);
MAYBE_RETURN(maybe_format_matcher, MaybeHandle<JSDateTimeFormat>()); MAYBE_RETURN(maybe_format_matcher, MaybeHandle<JSDateTimeFormat>());

View File

@ -34,7 +34,7 @@ class JSDateTimeFormat : public JSObject {
public: public:
V8_WARN_UNUSED_RESULT static MaybeHandle<JSDateTimeFormat> New( V8_WARN_UNUSED_RESULT static MaybeHandle<JSDateTimeFormat> New(
Isolate* isolate, Handle<Map> map, Handle<Object> locales, Isolate* isolate, Handle<Map> map, Handle<Object> locales,
Handle<Object> options); Handle<Object> options, const char* service);
V8_WARN_UNUSED_RESULT static MaybeHandle<JSObject> ResolvedOptions( V8_WARN_UNUSED_RESULT static MaybeHandle<JSObject> ResolvedOptions(
Isolate* isolate, Handle<JSDateTimeFormat> date_time_format); Isolate* isolate, Handle<JSDateTimeFormat> date_time_format);
@ -82,7 +82,8 @@ class JSDateTimeFormat : public JSObject {
V8_WARN_UNUSED_RESULT static MaybeHandle<String> ToLocaleDateTime( V8_WARN_UNUSED_RESULT static MaybeHandle<String> ToLocaleDateTime(
Isolate* isolate, Handle<Object> date, Handle<Object> locales, Isolate* isolate, Handle<Object> date, Handle<Object> locales,
Handle<Object> options, RequiredOption required, DefaultsOption defaults); Handle<Object> options, RequiredOption required, DefaultsOption defaults,
const char* method);
V8_EXPORT_PRIVATE static const std::set<std::string>& GetAvailableLocales(); V8_EXPORT_PRIVATE static const std::set<std::string>& GetAvailableLocales();

View File

@ -837,7 +837,8 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::UnwrapNumberFormat(
MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate, MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate,
Handle<Map> map, Handle<Map> map,
Handle<Object> locales, Handle<Object> locales,
Handle<Object> options_obj) { Handle<Object> options_obj,
const char* service) {
Factory* factory = isolate->factory(); Factory* factory = isolate->factory();
// 1. Let requestedLocales be ? CanonicalizeLocaleList(locales). // 1. Let requestedLocales be ? CanonicalizeLocaleList(locales).
@ -854,10 +855,9 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate,
} else { } else {
// 3. Else // 3. Else
// 3. a. Let options be ? ToObject(options). // 3. a. Let options be ? ToObject(options).
ASSIGN_RETURN_ON_EXCEPTION( ASSIGN_RETURN_ON_EXCEPTION(isolate, options_obj,
isolate, options_obj, Object::ToObject(isolate, options_obj, service),
Object::ToObject(isolate, options_obj, "Intl.NumberFormat"), JSNumberFormat);
JSNumberFormat);
} }
// At this point, options_obj can either be a JSObject or a JSProxy only. // At this point, options_obj can either be a JSObject or a JSProxy only.
@ -868,7 +868,7 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate,
// "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.NumberFormat"); Intl::GetLocaleMatcher(isolate, options, service);
MAYBE_RETURN(maybe_locale_matcher, MaybeHandle<JSNumberFormat>()); MAYBE_RETURN(maybe_locale_matcher, MaybeHandle<JSNumberFormat>());
Intl::MatcherOption matcher = maybe_locale_matcher.FromJust(); Intl::MatcherOption matcher = maybe_locale_matcher.FromJust();
@ -914,7 +914,6 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate,
// 12. Let style be ? GetOption(options, "style", "string", « "decimal", // 12. Let style be ? GetOption(options, "style", "string", « "decimal",
// "percent", "currency" », "decimal"). // "percent", "currency" », "decimal").
const char* service = "Intl.NumberFormat";
std::vector<const char*> style_str_values({"decimal", "percent", "currency"}); std::vector<const char*> style_str_values({"decimal", "percent", "currency"});
std::vector<JSNumberFormat::Style> style_enum_values( std::vector<JSNumberFormat::Style> style_enum_values(
@ -1035,7 +1034,7 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate,
THROW_NEW_ERROR( THROW_NEW_ERROR(
isolate, isolate,
NewTypeError(MessageTemplate::kInvalidUnit, NewTypeError(MessageTemplate::kInvalidUnit,
factory->NewStringFromStaticChars("Intl.NumberFormat"), factory->NewStringFromAsciiChecked(service),
factory->empty_string()), factory->empty_string()),
JSNumberFormat); JSNumberFormat);
} }
@ -1047,10 +1046,9 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate,
if (maybe_wellformed.IsNothing()) { if (maybe_wellformed.IsNothing()) {
THROW_NEW_ERROR( THROW_NEW_ERROR(
isolate, isolate,
NewRangeError( NewRangeError(MessageTemplate::kInvalidUnit,
MessageTemplate::kInvalidUnit, factory->NewStringFromAsciiChecked(service),
factory->NewStringFromStaticChars("Intl.NumberFormat"), factory->NewStringFromAsciiChecked(unit.c_str())),
factory->NewStringFromAsciiChecked(unit.c_str())),
JSNumberFormat); JSNumberFormat);
} }
std::pair<icu::MeasureUnit, icu::MeasureUnit> unit_pair = std::pair<icu::MeasureUnit, icu::MeasureUnit> unit_pair =

View File

@ -36,7 +36,7 @@ class JSNumberFormat : public JSObject {
// ecma402/#sec-initializenumberformat // ecma402/#sec-initializenumberformat
V8_WARN_UNUSED_RESULT static MaybeHandle<JSNumberFormat> New( V8_WARN_UNUSED_RESULT static MaybeHandle<JSNumberFormat> New(
Isolate* isolate, Handle<Map> map, Handle<Object> locales, Isolate* isolate, Handle<Map> map, Handle<Object> locales,
Handle<Object> options); Handle<Object> options, const char* service);
// ecma402/#sec-unwrapnumberformat // ecma402/#sec-unwrapnumberformat
V8_WARN_UNUSED_RESULT static MaybeHandle<JSNumberFormat> UnwrapNumberFormat( V8_WARN_UNUSED_RESULT static MaybeHandle<JSNumberFormat> UnwrapNumberFormat(

View File

@ -157,7 +157,7 @@ function assertThrows(code, type_opt, cause_opt) {
assertInstanceof(e, type_opt); assertInstanceof(e, type_opt);
} }
if (arguments.length >= 3) { if (arguments.length >= 3) {
assertEquals(cause_opt, e.type, 'thrown exception type mismatch'); assertEquals(cause_opt, e.message, 'thrown exception type mismatch');
} }
// Success. // Success.
return; return;

View File

@ -0,0 +1,51 @@
// Copyright 2019 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.
// Number, BigInt and Intl.NumberFormat
assertThrows(
"new Intl.NumberFormat('en', { style: 'unit', unit: 'son'});",
RangeError,
"Invalid unit argument for Intl.NumberFormat() 'son'");
assertThrows(
"123n.toLocaleString('en', { style: 'unit', unit: 'son'});",
RangeError,
"Invalid unit argument for BigInt.prototype.toLocaleString() 'son'");
assertThrows(
"Math.PI.toLocaleString('en', { style: 'unit', unit: 'son'});",
RangeError,
"Invalid unit argument for Number.prototype.toLocaleString() 'son'");
// String and Intl.Collator
assertThrows(
"new Intl.Collator('en', { usage: 'mom'});",
RangeError,
"Value mom out of range for Intl.Collator options property usage");
assertThrows(
"'abc'.localeCompare('efg', 'en', { usage: 'mom'});",
RangeError,
"Value mom out of range for String.prototype.localeCompare options property usage");
// Date and Intl.DateTimeFormat
assertThrows(
"new Intl.DateTimeFormat('en', { hour: 'dad'});",
RangeError,
"Value dad out of range for Intl.DateTimeFormat options property hour");
assertThrows(
"(new Date).toLocaleDateString('en', { hour: 'dad'});",
RangeError,
"Value dad out of range for Date.prototype.toLocaleDateString options property hour");
assertThrows(
"(new Date).toLocaleString('en', { hour: 'dad'});",
RangeError,
"Value dad out of range for Date.prototype.toLocaleString options property hour");
assertThrows(
"(new Date).toLocaleTimeString('en', { hour: 'dad'});",
RangeError,
"Value dad out of range for Date.prototype.toLocaleTimeString options property hour");