V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
builtins-intl.cc
1 // Copyright 2017 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_INTL_SUPPORT
6 #error Internationalization is expected to be enabled.
7 #endif // V8_INTL_SUPPORT
8 
9 #include <cmath>
10 #include <list>
11 #include <memory>
12 
13 #include "src/builtins/builtins-utils-inl.h"
14 #include "src/builtins/builtins.h"
15 #include "src/counters.h"
16 #include "src/date.h"
17 #include "src/elements.h"
18 #include "src/objects-inl.h"
19 #include "src/objects/intl-objects.h"
20 #include "src/objects/js-array-inl.h"
21 #include "src/objects/js-break-iterator-inl.h"
22 #include "src/objects/js-collator-inl.h"
23 #include "src/objects/js-date-time-format-inl.h"
24 #include "src/objects/js-list-format-inl.h"
25 #include "src/objects/js-locale-inl.h"
26 #include "src/objects/js-number-format-inl.h"
27 #include "src/objects/js-plural-rules-inl.h"
28 #include "src/objects/js-relative-time-format-inl.h"
29 #include "src/objects/js-segment-iterator-inl.h"
30 #include "src/objects/js-segmenter-inl.h"
31 #include "src/objects/smi.h"
32 #include "src/property-descriptor.h"
33 
34 #include "unicode/brkiter.h"
35 
36 namespace v8 {
37 namespace internal {
38 
39 BUILTIN(StringPrototypeToUpperCaseIntl) {
40  HandleScope scope(isolate);
41  TO_THIS_STRING(string, "String.prototype.toUpperCase");
42  string = String::Flatten(isolate, string);
43  RETURN_RESULT_OR_FAILURE(isolate, Intl::ConvertToUpper(isolate, string));
44 }
45 
46 BUILTIN(StringPrototypeNormalizeIntl) {
47  HandleScope handle_scope(isolate);
48  TO_THIS_STRING(string, "String.prototype.normalize");
49 
50  Handle<Object> form_input = args.atOrUndefined(isolate, 1);
51 
52  RETURN_RESULT_OR_FAILURE(isolate,
53  Intl::Normalize(isolate, string, form_input));
54 }
55 
56 BUILTIN(V8BreakIteratorSupportedLocalesOf) {
57  HandleScope scope(isolate);
58  Handle<Object> locales = args.atOrUndefined(isolate, 1);
59  Handle<Object> options = args.atOrUndefined(isolate, 2);
60 
61  RETURN_RESULT_OR_FAILURE(
62  isolate, Intl::SupportedLocalesOf(
63  isolate, "Intl.v8BreakIterator.supportedLocalesOf",
64  JSV8BreakIterator::GetAvailableLocales(), locales, options));
65 }
66 
67 BUILTIN(NumberFormatSupportedLocalesOf) {
68  HandleScope scope(isolate);
69  Handle<Object> locales = args.atOrUndefined(isolate, 1);
70  Handle<Object> options = args.atOrUndefined(isolate, 2);
71 
72  RETURN_RESULT_OR_FAILURE(
73  isolate, Intl::SupportedLocalesOf(
74  isolate, "Intl.NumberFormat.supportedLocalesOf",
75  JSNumberFormat::GetAvailableLocales(), locales, options));
76 }
77 
78 BUILTIN(NumberFormatPrototypeFormatToParts) {
79  const char* const method = "Intl.NumberFormat.prototype.formatToParts";
80  HandleScope handle_scope(isolate);
81  CHECK_RECEIVER(JSNumberFormat, number_format, method);
82 
83  Handle<Object> x;
84  if (args.length() >= 2) {
85  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, x,
86  Object::ToNumber(isolate, args.at(1)));
87  } else {
88  x = isolate->factory()->nan_value();
89  }
90 
91  RETURN_RESULT_OR_FAILURE(isolate, JSNumberFormat::FormatToParts(
92  isolate, number_format, x->Number()));
93 }
94 
95 BUILTIN(DateTimeFormatPrototypeResolvedOptions) {
96  const char* const method = "Intl.DateTimeFormat.prototype.resolvedOptions";
97  HandleScope scope(isolate);
98  CHECK_RECEIVER(JSReceiver, format_holder, method);
99 
100  // 3. Let dtf be ? UnwrapDateTimeFormat(dtf).
101  Handle<JSDateTimeFormat> date_time_format;
102  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
103  isolate, date_time_format,
104  JSDateTimeFormat::UnwrapDateTimeFormat(isolate, format_holder));
105 
106  RETURN_RESULT_OR_FAILURE(
107  isolate, JSDateTimeFormat::ResolvedOptions(isolate, date_time_format));
108 }
109 
110 BUILTIN(DateTimeFormatSupportedLocalesOf) {
111  HandleScope scope(isolate);
112  Handle<Object> locales = args.atOrUndefined(isolate, 1);
113  Handle<Object> options = args.atOrUndefined(isolate, 2);
114 
115  RETURN_RESULT_OR_FAILURE(
116  isolate, Intl::SupportedLocalesOf(
117  isolate, "Intl.DateTimeFormat.supportedLocalesOf",
118  JSDateTimeFormat::GetAvailableLocales(), locales, options));
119 }
120 
121 BUILTIN(DateTimeFormatPrototypeFormatToParts) {
122  const char* const method = "Intl.DateTimeFormat.prototype.formatToParts";
123  HandleScope handle_scope(isolate);
124  CHECK_RECEIVER(JSObject, date_format_holder, method);
125  Factory* factory = isolate->factory();
126 
127  if (!date_format_holder->IsJSDateTimeFormat()) {
128  THROW_NEW_ERROR_RETURN_FAILURE(
129  isolate, NewTypeError(MessageTemplate::kIncompatibleMethodReceiver,
130  factory->NewStringFromAsciiChecked(method),
131  date_format_holder));
132  }
133  Handle<JSDateTimeFormat> dtf =
134  Handle<JSDateTimeFormat>::cast(date_format_holder);
135 
136  Handle<Object> x = args.atOrUndefined(isolate, 1);
137  if (x->IsUndefined(isolate)) {
138  x = factory->NewNumber(JSDate::CurrentTimeValue(isolate));
139  } else {
140  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, x,
141  Object::ToNumber(isolate, args.at(1)));
142  }
143 
144  double date_value = DateCache::TimeClip(x->Number());
145  if (std::isnan(date_value)) {
146  THROW_NEW_ERROR_RETURN_FAILURE(
147  isolate, NewRangeError(MessageTemplate::kInvalidTimeValue));
148  }
149 
150  RETURN_RESULT_OR_FAILURE(
151  isolate, JSDateTimeFormat::FormatToParts(isolate, dtf, date_value));
152 }
153 
154 namespace {
155 Handle<JSFunction> CreateBoundFunction(Isolate* isolate,
156  Handle<JSObject> object,
157  Builtins::Name builtin_id, int len) {
158  Handle<NativeContext> native_context(isolate->context()->native_context(),
159  isolate);
160  Handle<Context> context = isolate->factory()->NewBuiltinContext(
161  native_context,
162  static_cast<int>(Intl::BoundFunctionContextSlot::kLength));
163 
164  context->set(static_cast<int>(Intl::BoundFunctionContextSlot::kBoundFunction),
165  *object);
166 
167  Handle<SharedFunctionInfo> info =
168  isolate->factory()->NewSharedFunctionInfoForBuiltin(
169  isolate->factory()->empty_string(), builtin_id, kNormalFunction);
170  info->set_internal_formal_parameter_count(len);
171  info->set_length(len);
172 
173  Handle<Map> map = isolate->strict_function_without_prototype_map();
174 
175  Handle<JSFunction> new_bound_function =
176  isolate->factory()->NewFunctionFromSharedFunctionInfo(map, info, context);
177  return new_bound_function;
178 }
179 
184 template <class T>
185 Object* LegacyFormatConstructor(BuiltinArguments args, Isolate* isolate,
186  v8::Isolate::UseCounterFeature feature,
187  Handle<Object> constructor,
188  const char* method) {
189  isolate->CountUsage(feature);
190  Handle<JSReceiver> new_target;
191  // 1. If NewTarget is undefined, let newTarget be the active
192  // function object, else let newTarget be NewTarget.
193  if (args.new_target()->IsUndefined(isolate)) {
194  new_target = args.target();
195  } else {
196  new_target = Handle<JSReceiver>::cast(args.new_target());
197  }
198 
199  // [[Construct]]
200  Handle<JSFunction> target = args.target();
201 
202  Handle<Object> locales = args.atOrUndefined(isolate, 1);
203  Handle<Object> options = args.atOrUndefined(isolate, 2);
204 
205  // 2. Let format be ? OrdinaryCreateFromConstructor(newTarget,
206  // "%<T>Prototype%", ...).
207 
208  Handle<JSObject> obj;
209  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
210  isolate, obj,
211  JSObject::New(target, new_target, Handle<AllocationSite>::null()));
212  Handle<T> format = Handle<T>::cast(obj);
213 
214  // 3. Perform ? Initialize<T>(Format, locales, options).
215  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
216  isolate, format, T::Initialize(isolate, format, locales, options));
217  // 4. Let this be the this value.
218  Handle<Object> receiver = args.receiver();
219 
220  // 5. If NewTarget is undefined and ? InstanceofOperator(this, %<T>%)
221  // is true, then
222  //
223  // Look up the intrinsic value that has been stored on the context.
224  // Call the instanceof function
225  Handle<Object> is_instance_of_obj;
226  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
227  isolate, is_instance_of_obj,
228  Object::InstanceOf(isolate, receiver, constructor));
229 
230  // Get the boolean value of the result
231  bool is_instance_of = is_instance_of_obj->BooleanValue(isolate);
232 
233  if (args.new_target()->IsUndefined(isolate) && is_instance_of) {
234  if (!receiver->IsJSReceiver()) {
235  THROW_NEW_ERROR_RETURN_FAILURE(
236  isolate,
237  NewTypeError(MessageTemplate::kIncompatibleMethodReceiver,
238  isolate->factory()->NewStringFromAsciiChecked(method),
239  receiver));
240  }
241  Handle<JSReceiver> rec = Handle<JSReceiver>::cast(receiver);
242  // a. Perform ? DefinePropertyOrThrow(this,
243  // %Intl%.[[FallbackSymbol]], PropertyDescriptor{ [[Value]]: format,
244  // [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }).
245  PropertyDescriptor desc;
246  desc.set_value(format);
247  desc.set_writable(false);
248  desc.set_enumerable(false);
249  desc.set_configurable(false);
250  Maybe<bool> success = JSReceiver::DefineOwnProperty(
251  isolate, rec, isolate->factory()->intl_fallback_symbol(), &desc,
252  kThrowOnError);
253  MAYBE_RETURN(success, ReadOnlyRoots(isolate).exception());
254  CHECK(success.FromJust());
255  // b. b. Return this.
256  return *receiver;
257  }
258  // 6. Return format.
259  return *format;
260 }
261 
266 template <class T>
267 Object* DisallowCallConstructor(BuiltinArguments args, Isolate* isolate,
268  v8::Isolate::UseCounterFeature feature,
269  const char* method) {
270  isolate->CountUsage(feature);
271 
272  // 1. If NewTarget is undefined, throw a TypeError exception.
273  if (args.new_target()->IsUndefined(isolate)) { // [[Call]]
274  THROW_NEW_ERROR_RETURN_FAILURE(
275  isolate,
276  NewTypeError(MessageTemplate::kConstructorNotFunction,
277  isolate->factory()->NewStringFromAsciiChecked(method)));
278  }
279  // [[Construct]]
280  Handle<JSFunction> target = args.target();
281  Handle<JSReceiver> new_target = Handle<JSReceiver>::cast(args.new_target());
282 
283  Handle<JSObject> obj;
284  // 2. Let result be OrdinaryCreateFromConstructor(NewTarget,
285  // "%<T>Prototype%").
286  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
287  isolate, obj,
288  JSObject::New(target, new_target, Handle<AllocationSite>::null()));
289  Handle<T> result = Handle<T>::cast(obj);
290  result->set_flags(0);
291 
292  Handle<Object> locales = args.atOrUndefined(isolate, 1);
293  Handle<Object> options = args.atOrUndefined(isolate, 2);
294 
295  // 3. Return Initialize<T>(t, locales, options).
296  RETURN_RESULT_OR_FAILURE(isolate,
297  T::Initialize(isolate, result, locales, options));
298 }
299 
303 template <class T>
304 Object* CallOrConstructConstructor(BuiltinArguments args, Isolate* isolate) {
305  Handle<JSReceiver> new_target;
306 
307  if (args.new_target()->IsUndefined(isolate)) {
308  new_target = args.target();
309  } else {
310  new_target = Handle<JSReceiver>::cast(args.new_target());
311  }
312 
313  // [[Construct]]
314  Handle<JSFunction> target = args.target();
315 
316  Handle<Object> locales = args.atOrUndefined(isolate, 1);
317  Handle<Object> options = args.atOrUndefined(isolate, 2);
318 
319  Handle<JSObject> obj;
320  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
321  isolate, obj,
322  JSObject::New(target, new_target, Handle<AllocationSite>::null()));
323  Handle<T> result = Handle<T>::cast(obj);
324 
325  RETURN_RESULT_OR_FAILURE(isolate,
326  T::Initialize(isolate, result, locales, options));
327 }
328 } // namespace
329 
330 BUILTIN(NumberFormatConstructor) {
331  HandleScope scope(isolate);
332 
333  return LegacyFormatConstructor<JSNumberFormat>(
334  args, isolate, v8::Isolate::UseCounterFeature::kNumberFormat,
335  isolate->intl_number_format_function(), "Intl.NumberFormat");
336 }
337 
338 BUILTIN(NumberFormatPrototypeResolvedOptions) {
339  HandleScope scope(isolate);
340  const char* const method = "Intl.NumberFormat.prototype.resolvedOptions";
341 
342  // 1. Let nf be the this value.
343  // 2. If Type(nf) is not Object, throw a TypeError exception.
344  CHECK_RECEIVER(JSReceiver, number_format_holder, method);
345 
346  // 3. Let nf be ? UnwrapNumberFormat(nf)
347  Handle<JSNumberFormat> number_format;
348  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
349  isolate, number_format,
350  JSNumberFormat::UnwrapNumberFormat(isolate, number_format_holder));
351 
352  return *JSNumberFormat::ResolvedOptions(isolate, number_format);
353 }
354 
355 BUILTIN(NumberFormatPrototypeFormatNumber) {
356  const char* const method = "get Intl.NumberFormat.prototype.format";
357  HandleScope scope(isolate);
358 
359  // 1. Let nf be the this value.
360  // 2. If Type(nf) is not Object, throw a TypeError exception.
361  CHECK_RECEIVER(JSReceiver, receiver, method);
362 
363  // 3. Let nf be ? UnwrapNumberFormat(nf).
364  Handle<JSNumberFormat> number_format;
365  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
366  isolate, number_format,
367  JSNumberFormat::UnwrapNumberFormat(isolate, receiver));
368 
369  Handle<Object> bound_format(number_format->bound_format(), isolate);
370 
371  // 4. If nf.[[BoundFormat]] is undefined, then
372  if (!bound_format->IsUndefined(isolate)) {
373  DCHECK(bound_format->IsJSFunction());
374  // 5. Return nf.[[BoundFormat]].
375  return *bound_format;
376  }
377 
378  Handle<JSFunction> new_bound_format_function = CreateBoundFunction(
379  isolate, number_format, Builtins::kNumberFormatInternalFormatNumber, 1);
380 
381  // 4. c. Set nf.[[BoundFormat]] to F.
382  number_format->set_bound_format(*new_bound_format_function);
383 
384  // 5. Return nf.[[BoundFormat]].
385  return *new_bound_format_function;
386 }
387 
388 BUILTIN(NumberFormatInternalFormatNumber) {
389  HandleScope scope(isolate);
390 
391  Handle<Context> context = Handle<Context>(isolate->context(), isolate);
392 
393  // 1. Let nf be F.[[NumberFormat]].
394  // 2. Assert: Type(nf) is Object and nf has an
395  // [[InitializedNumberFormat]] internal slot.
396  Handle<JSNumberFormat> number_format = Handle<JSNumberFormat>(
397  JSNumberFormat::cast(context->get(
398  static_cast<int>(Intl::BoundFunctionContextSlot::kBoundFunction))),
399  isolate);
400 
401  // 3. If value is not provided, let value be undefined.
402  Handle<Object> value = args.atOrUndefined(isolate, 1);
403 
404  // 4. Let x be ? ToNumber(value).
405  Handle<Object> number_obj;
406  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, number_obj,
407  Object::ToNumber(isolate, value));
408 
409  // Spec treats -0 as 0.
410  if (number_obj->IsMinusZero()) {
411  number_obj = Handle<Smi>(Smi::zero(), isolate);
412  }
413 
414  double number = number_obj->Number();
415  icu::NumberFormat* icu_number_format =
416  number_format->icu_number_format()->raw();
417  CHECK_NOT_NULL(icu_number_format);
418 
419  // Return FormatNumber(nf, x).
420  RETURN_RESULT_OR_FAILURE(isolate, JSNumberFormat::FormatNumber(
421  isolate, *icu_number_format, number));
422 }
423 
424 BUILTIN(DateTimeFormatConstructor) {
425  HandleScope scope(isolate);
426 
427  return LegacyFormatConstructor<JSDateTimeFormat>(
428  args, isolate, v8::Isolate::UseCounterFeature::kDateTimeFormat,
429  isolate->intl_date_time_format_function(), "Intl.DateTimeFormat");
430 }
431 
432 BUILTIN(DateTimeFormatPrototypeFormat) {
433  const char* const method = "get Intl.DateTimeFormat.prototype.format";
434  HandleScope scope(isolate);
435 
436  // 1. Let dtf be this value.
437  // 2. If Type(dtf) is not Object, throw a TypeError exception.
438  CHECK_RECEIVER(JSReceiver, receiver, method);
439 
440  // 3. Let dtf be ? UnwrapDateTimeFormat(dtf).
441  Handle<JSDateTimeFormat> format;
442  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
443  isolate, format,
444  JSDateTimeFormat::UnwrapDateTimeFormat(isolate, receiver));
445 
446  Handle<Object> bound_format = Handle<Object>(format->bound_format(), isolate);
447 
448  // 4. If dtf.[[BoundFormat]] is undefined, then
449  if (!bound_format->IsUndefined(isolate)) {
450  DCHECK(bound_format->IsJSFunction());
451  // 5. Return dtf.[[BoundFormat]].
452  return *bound_format;
453  }
454 
455  Handle<JSFunction> new_bound_format_function = CreateBoundFunction(
456  isolate, format, Builtins::kDateTimeFormatInternalFormat, 1);
457 
458  // 4.c. Set dtf.[[BoundFormat]] to F.
459  format->set_bound_format(*new_bound_format_function);
460 
461  // 5. Return dtf.[[BoundFormat]].
462  return *new_bound_format_function;
463 }
464 
465 BUILTIN(DateTimeFormatInternalFormat) {
466  HandleScope scope(isolate);
467  Handle<Context> context = Handle<Context>(isolate->context(), isolate);
468 
469  // 1. Let dtf be F.[[DateTimeFormat]].
470  // 2. Assert: Type(dtf) is Object and dtf has an [[InitializedDateTimeFormat]]
471  // internal slot.
472  Handle<JSDateTimeFormat> date_format_holder = Handle<JSDateTimeFormat>(
473  JSDateTimeFormat::cast(context->get(
474  static_cast<int>(Intl::BoundFunctionContextSlot::kBoundFunction))),
475  isolate);
476 
477  Handle<Object> date = args.atOrUndefined(isolate, 1);
478 
479  RETURN_RESULT_OR_FAILURE(isolate, JSDateTimeFormat::DateTimeFormat(
480  isolate, date_format_holder, date));
481 }
482 
483 BUILTIN(IntlGetCanonicalLocales) {
484  HandleScope scope(isolate);
485  Handle<Object> locales = args.atOrUndefined(isolate, 1);
486 
487  RETURN_RESULT_OR_FAILURE(isolate,
488  Intl::GetCanonicalLocales(isolate, locales));
489 }
490 
491 BUILTIN(ListFormatConstructor) {
492  HandleScope scope(isolate);
493 
494  return DisallowCallConstructor<JSListFormat>(
495  args, isolate, v8::Isolate::UseCounterFeature::kListFormat,
496  "Intl.ListFormat");
497 }
498 
499 BUILTIN(ListFormatPrototypeResolvedOptions) {
500  HandleScope scope(isolate);
501  CHECK_RECEIVER(JSListFormat, format_holder,
502  "Intl.ListFormat.prototype.resolvedOptions");
503  return *JSListFormat::ResolvedOptions(isolate, format_holder);
504 }
505 
506 BUILTIN(ListFormatSupportedLocalesOf) {
507  HandleScope scope(isolate);
508  Handle<Object> locales = args.atOrUndefined(isolate, 1);
509  Handle<Object> options = args.atOrUndefined(isolate, 2);
510 
511  RETURN_RESULT_OR_FAILURE(
512  isolate, Intl::SupportedLocalesOf(
513  isolate, "Intl.ListFormat.supportedLocalesOf",
514  JSListFormat::GetAvailableLocales(), locales, options));
515 }
516 
517 namespace {
518 
519 MaybeHandle<JSLocale> CreateLocale(Isolate* isolate,
520  Handle<JSFunction> constructor,
521  Handle<JSReceiver> new_target,
522  Handle<Object> tag, Handle<Object> options) {
523  Handle<JSObject> locale;
524  // 6. Let locale be ? OrdinaryCreateFromConstructor(NewTarget,
525  // %LocalePrototype%, internalSlotsList).
526  ASSIGN_RETURN_ON_EXCEPTION(
527  isolate, locale,
528  JSObject::New(constructor, new_target, Handle<AllocationSite>::null()),
529  JSLocale);
530 
531  // 7. If Type(tag) is not String or Object, throw a TypeError exception.
532  if (!tag->IsString() && !tag->IsJSReceiver()) {
533  THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kLocaleNotEmpty),
534  JSLocale);
535  }
536 
537  Handle<String> locale_string;
538  // 8. If Type(tag) is Object and tag has an [[InitializedLocale]] internal
539  // slot, then
540  if (tag->IsJSLocale() && Handle<JSLocale>::cast(tag)->locale()->IsString()) {
541  // a. Let tag be tag.[[Locale]].
542  locale_string =
543  Handle<String>(Handle<JSLocale>::cast(tag)->locale(), isolate);
544  } else { // 9. Else,
545  // a. Let tag be ? ToString(tag).
546  ASSIGN_RETURN_ON_EXCEPTION(isolate, locale_string,
547  Object::ToString(isolate, tag), JSLocale);
548  }
549 
550  Handle<JSReceiver> options_object;
551  // 10. If options is undefined, then
552  if (options->IsUndefined(isolate)) {
553  // a. Let options be ! ObjectCreate(null).
554  options_object = isolate->factory()->NewJSObjectWithNullProto();
555  } else { // 11. Else
556  // a. Let options be ? ToObject(options).
557  ASSIGN_RETURN_ON_EXCEPTION(isolate, options_object,
558  Object::ToObject(isolate, options), JSLocale);
559  }
560 
561  return JSLocale::Initialize(isolate, Handle<JSLocale>::cast(locale),
562  locale_string, options_object);
563 }
564 
565 } // namespace
566 
567 // Intl.Locale implementation
568 BUILTIN(LocaleConstructor) {
569  HandleScope scope(isolate);
570 
571  isolate->CountUsage(v8::Isolate::UseCounterFeature::kLocale);
572 
573  if (args.new_target()->IsUndefined(isolate)) { // [[Call]]
574  THROW_NEW_ERROR_RETURN_FAILURE(
575  isolate, NewTypeError(MessageTemplate::kConstructorNotFunction,
576  isolate->factory()->NewStringFromAsciiChecked(
577  "Intl.Locale")));
578  }
579  // [[Construct]]
580  Handle<JSFunction> target = args.target();
581  Handle<JSReceiver> new_target = Handle<JSReceiver>::cast(args.new_target());
582 
583  Handle<Object> tag = args.atOrUndefined(isolate, 1);
584  Handle<Object> options = args.atOrUndefined(isolate, 2);
585 
586  RETURN_RESULT_OR_FAILURE(
587  isolate, CreateLocale(isolate, target, new_target, tag, options));
588 }
589 
590 BUILTIN(LocalePrototypeMaximize) {
591  HandleScope scope(isolate);
592  CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.maximize");
593  Handle<JSFunction> constructor(
594  isolate->native_context()->intl_locale_function(), isolate);
595  RETURN_RESULT_OR_FAILURE(
596  isolate,
597  CreateLocale(isolate, constructor, constructor,
598  JSLocale::Maximize(isolate, locale_holder->locale()),
599  isolate->factory()->NewJSObjectWithNullProto()));
600 }
601 
602 BUILTIN(LocalePrototypeMinimize) {
603  HandleScope scope(isolate);
604  CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.minimize");
605  Handle<JSFunction> constructor(
606  isolate->native_context()->intl_locale_function(), isolate);
607  RETURN_RESULT_OR_FAILURE(
608  isolate,
609  CreateLocale(isolate, constructor, constructor,
610  JSLocale::Minimize(isolate, locale_holder->locale()),
611  isolate->factory()->NewJSObjectWithNullProto()));
612 }
613 
614 BUILTIN(RelativeTimeFormatSupportedLocalesOf) {
615  HandleScope scope(isolate);
616  Handle<Object> locales = args.atOrUndefined(isolate, 1);
617  Handle<Object> options = args.atOrUndefined(isolate, 2);
618 
619  RETURN_RESULT_OR_FAILURE(
620  isolate,
621  Intl::SupportedLocalesOf(
622  isolate, "Intl.RelativeTimeFormat.supportedLocalesOf",
623  JSRelativeTimeFormat::GetAvailableLocales(), locales, options));
624 }
625 
626 BUILTIN(RelativeTimeFormatPrototypeFormat) {
627  HandleScope scope(isolate);
628  // 1. Let relativeTimeFormat be the this value.
629  // 2. If Type(relativeTimeFormat) is not Object or relativeTimeFormat does not
630  // have an [[InitializedRelativeTimeFormat]] internal slot whose value is
631  // true, throw a TypeError exception.
632  CHECK_RECEIVER(JSRelativeTimeFormat, format_holder,
633  "Intl.RelativeTimeFormat.prototype.format");
634  Handle<Object> value_obj = args.atOrUndefined(isolate, 1);
635  Handle<Object> unit_obj = args.atOrUndefined(isolate, 2);
636 
637  RETURN_RESULT_OR_FAILURE(
638  isolate, JSRelativeTimeFormat::Format(isolate, value_obj, unit_obj,
639  format_holder, "format", false));
640 }
641 
642 BUILTIN(RelativeTimeFormatPrototypeFormatToParts) {
643  HandleScope scope(isolate);
644  // 1. Let relativeTimeFormat be the this value.
645  // 2. If Type(relativeTimeFormat) is not Object or relativeTimeFormat does not
646  // have an [[InitializedRelativeTimeFormat]] internal slot whose value is
647  // true, throw a TypeError exception.
648  CHECK_RECEIVER(JSRelativeTimeFormat, format_holder,
649  "Intl.RelativeTimeFormat.prototype.formatToParts");
650  Handle<Object> value_obj = args.atOrUndefined(isolate, 1);
651  Handle<Object> unit_obj = args.atOrUndefined(isolate, 2);
652  RETURN_RESULT_OR_FAILURE(isolate, JSRelativeTimeFormat::Format(
653  isolate, value_obj, unit_obj,
654  format_holder, "formatToParts", true));
655 }
656 
657 // Locale getters.
658 BUILTIN(LocalePrototypeLanguage) {
659  HandleScope scope(isolate);
660  // CHECK_RECEIVER will case locale_holder to JSLocale.
661  CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.language");
662 
663  return locale_holder->language();
664 }
665 
666 BUILTIN(LocalePrototypeScript) {
667  HandleScope scope(isolate);
668  CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.script");
669 
670  return locale_holder->script();
671 }
672 
673 BUILTIN(LocalePrototypeRegion) {
674  HandleScope scope(isolate);
675  CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.region");
676 
677  return locale_holder->region();
678 }
679 
680 BUILTIN(LocalePrototypeBaseName) {
681  HandleScope scope(isolate);
682  CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.baseName");
683 
684  return locale_holder->base_name();
685 }
686 
687 BUILTIN(LocalePrototypeCalendar) {
688  HandleScope scope(isolate);
689  CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.calendar");
690 
691  return locale_holder->calendar();
692 }
693 
694 BUILTIN(LocalePrototypeCaseFirst) {
695  HandleScope scope(isolate);
696  CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.caseFirst");
697 
698  return *(locale_holder->CaseFirstAsString());
699 }
700 
701 BUILTIN(LocalePrototypeCollation) {
702  HandleScope scope(isolate);
703  CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.collation");
704 
705  return locale_holder->collation();
706 }
707 
708 BUILTIN(LocalePrototypeHourCycle) {
709  HandleScope scope(isolate);
710  CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.hourCycle");
711 
712  return *(locale_holder->HourCycleAsString());
713 }
714 
715 BUILTIN(LocalePrototypeNumeric) {
716  HandleScope scope(isolate);
717  CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.numeric");
718 
719  switch (locale_holder->numeric()) {
720  case JSLocale::Numeric::TRUE_VALUE:
721  return *(isolate->factory()->true_value());
722  case JSLocale::Numeric::FALSE_VALUE:
723  return *(isolate->factory()->false_value());
724  case JSLocale::Numeric::NOTSET:
725  return *(isolate->factory()->undefined_value());
726  case JSLocale::Numeric::COUNT:
727  UNREACHABLE();
728  }
729 }
730 
731 BUILTIN(LocalePrototypeNumberingSystem) {
732  HandleScope scope(isolate);
733  CHECK_RECEIVER(JSLocale, locale_holder,
734  "Intl.Locale.prototype.numberingSystem");
735 
736  return locale_holder->numbering_system();
737 }
738 
739 BUILTIN(LocalePrototypeToString) {
740  HandleScope scope(isolate);
741  CHECK_RECEIVER(JSLocale, locale_holder, "Intl.Locale.prototype.toString");
742 
743  return locale_holder->locale();
744 }
745 
746 BUILTIN(RelativeTimeFormatConstructor) {
747  HandleScope scope(isolate);
748 
749  return DisallowCallConstructor<JSRelativeTimeFormat>(
750  args, isolate, v8::Isolate::UseCounterFeature::kRelativeTimeFormat,
751  "Intl.RelativeTimeFormat");
752 }
753 
754 BUILTIN(RelativeTimeFormatPrototypeResolvedOptions) {
755  HandleScope scope(isolate);
756  CHECK_RECEIVER(JSRelativeTimeFormat, format_holder,
757  "Intl.RelativeTimeFormat.prototype.resolvedOptions");
758  return *JSRelativeTimeFormat::ResolvedOptions(isolate, format_holder);
759 }
760 
761 BUILTIN(StringPrototypeToLocaleLowerCase) {
762  HandleScope scope(isolate);
763 
764  isolate->CountUsage(v8::Isolate::UseCounterFeature::kStringToLocaleLowerCase);
765 
766  TO_THIS_STRING(string, "String.prototype.toLocaleLowerCase");
767 
768  RETURN_RESULT_OR_FAILURE(
769  isolate, Intl::StringLocaleConvertCase(isolate, string, false,
770  args.atOrUndefined(isolate, 1)));
771 }
772 
773 BUILTIN(StringPrototypeToLocaleUpperCase) {
774  HandleScope scope(isolate);
775 
776  isolate->CountUsage(v8::Isolate::UseCounterFeature::kStringToLocaleUpperCase);
777 
778  TO_THIS_STRING(string, "String.prototype.toLocaleUpperCase");
779 
780  RETURN_RESULT_OR_FAILURE(
781  isolate, Intl::StringLocaleConvertCase(isolate, string, true,
782  args.atOrUndefined(isolate, 1)));
783 }
784 
785 BUILTIN(PluralRulesConstructor) {
786  HandleScope scope(isolate);
787 
788  return DisallowCallConstructor<JSPluralRules>(
789  args, isolate, v8::Isolate::UseCounterFeature::kPluralRules,
790  "Intl.PluralRules");
791 }
792 
793 BUILTIN(PluralRulesPrototypeResolvedOptions) {
794  HandleScope scope(isolate);
795  CHECK_RECEIVER(JSPluralRules, plural_rules_holder,
796  "Intl.PluralRules.prototype.resolvedOptions");
797  return *JSPluralRules::ResolvedOptions(isolate, plural_rules_holder);
798 }
799 
800 BUILTIN(PluralRulesPrototypeSelect) {
801  HandleScope scope(isolate);
802 
803  // 1. Let pr be the this value.
804  // 2. If Type(pr) is not Object, throw a TypeError exception.
805  // 3. If pr does not have an [[InitializedPluralRules]] internal slot, throw a
806  // TypeError exception.
807  CHECK_RECEIVER(JSPluralRules, plural_rules,
808  "Intl.PluralRules.prototype.select");
809 
810  // 4. Let n be ? ToNumber(value).
811  Handle<Object> number = args.atOrUndefined(isolate, 1);
812  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, number,
813  Object::ToNumber(isolate, number));
814  double number_double = number->Number();
815 
816  // 5. Return ? ResolvePlural(pr, n).
817  RETURN_RESULT_OR_FAILURE(isolate, JSPluralRules::ResolvePlural(
818  isolate, plural_rules, number_double));
819 }
820 
821 BUILTIN(PluralRulesSupportedLocalesOf) {
822  HandleScope scope(isolate);
823  Handle<Object> locales = args.atOrUndefined(isolate, 1);
824  Handle<Object> options = args.atOrUndefined(isolate, 2);
825 
826  RETURN_RESULT_OR_FAILURE(
827  isolate, Intl::SupportedLocalesOf(
828  isolate, "Intl.PluralRules.supportedLocalesOf",
829  JSPluralRules::GetAvailableLocales(), locales, options));
830 }
831 
832 BUILTIN(CollatorConstructor) {
833  HandleScope scope(isolate);
834 
835  isolate->CountUsage(v8::Isolate::UseCounterFeature::kCollator);
836 
837  return CallOrConstructConstructor<JSCollator>(args, isolate);
838 }
839 
840 BUILTIN(CollatorPrototypeResolvedOptions) {
841  HandleScope scope(isolate);
842  CHECK_RECEIVER(JSCollator, collator_holder,
843  "Intl.Collator.prototype.resolvedOptions");
844  return *JSCollator::ResolvedOptions(isolate, collator_holder);
845 }
846 
847 BUILTIN(CollatorSupportedLocalesOf) {
848  HandleScope scope(isolate);
849  Handle<Object> locales = args.atOrUndefined(isolate, 1);
850  Handle<Object> options = args.atOrUndefined(isolate, 2);
851 
852  RETURN_RESULT_OR_FAILURE(
853  isolate, Intl::SupportedLocalesOf(
854  isolate, "Intl.Collator.supportedLocalesOf",
855  JSCollator::GetAvailableLocales(), locales, options));
856 }
857 
858 BUILTIN(CollatorPrototypeCompare) {
859  const char* const method = "get Intl.Collator.prototype.compare";
860  HandleScope scope(isolate);
861 
862  // 1. Let collator be this value.
863  // 2. If Type(collator) is not Object, throw a TypeError exception.
864  // 3. If collator does not have an [[InitializedCollator]] internal slot,
865  // throw a TypeError exception.
866  CHECK_RECEIVER(JSCollator, collator, method);
867 
868  // 4. If collator.[[BoundCompare]] is undefined, then
869  Handle<Object> bound_compare(collator->bound_compare(), isolate);
870  if (!bound_compare->IsUndefined(isolate)) {
871  DCHECK(bound_compare->IsJSFunction());
872  // 5. Return collator.[[BoundCompare]].
873  return *bound_compare;
874  }
875 
876  Handle<JSFunction> new_bound_compare_function = CreateBoundFunction(
877  isolate, collator, Builtins::kCollatorInternalCompare, 2);
878 
879  // 4.c. Set collator.[[BoundCompare]] to F.
880  collator->set_bound_compare(*new_bound_compare_function);
881 
882  // 5. Return collator.[[BoundCompare]].
883  return *new_bound_compare_function;
884 }
885 
886 BUILTIN(CollatorInternalCompare) {
887  HandleScope scope(isolate);
888  Handle<Context> context = Handle<Context>(isolate->context(), isolate);
889 
890  // 1. Let collator be F.[[Collator]].
891  // 2. Assert: Type(collator) is Object and collator has an
892  // [[InitializedCollator]] internal slot.
893  Handle<JSCollator> collator = Handle<JSCollator>(
894  JSCollator::cast(context->get(
895  static_cast<int>(Intl::BoundFunctionContextSlot::kBoundFunction))),
896  isolate);
897 
898  // 3. If x is not provided, let x be undefined.
899  Handle<Object> x = args.atOrUndefined(isolate, 1);
900  // 4. If y is not provided, let y be undefined.
901  Handle<Object> y = args.atOrUndefined(isolate, 2);
902 
903  // 5. Let X be ? ToString(x).
904  Handle<String> string_x;
905  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, string_x,
906  Object::ToString(isolate, x));
907  // 6. Let Y be ? ToString(y).
908  Handle<String> string_y;
909  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, string_y,
910  Object::ToString(isolate, y));
911 
912  // 7. Return CompareStrings(collator, X, Y).
913  icu::Collator* icu_collator = collator->icu_collator()->raw();
914  CHECK_NOT_NULL(icu_collator);
915  return *Intl::CompareStrings(isolate, *icu_collator, string_x, string_y);
916 }
917 
918 // ecma402 #sec-segment-iterator-prototype-breakType
919 BUILTIN(SegmentIteratorPrototypeBreakType) {
920  const char* const method = "get %SegmentIteratorPrototype%.breakType";
921  HandleScope scope(isolate);
922 
923  CHECK_RECEIVER(JSSegmentIterator, segment_iterator, method);
924  return *segment_iterator->BreakType();
925 }
926 
927 // ecma402 #sec-segment-iterator-prototype-following
928 BUILTIN(SegmentIteratorPrototypeFollowing) {
929  const char* const method = "%SegmentIteratorPrototype%.following";
930  HandleScope scope(isolate);
931  CHECK_RECEIVER(JSSegmentIterator, segment_iterator, method);
932 
933  Handle<Object> from = args.atOrUndefined(isolate, 1);
934 
935  Maybe<bool> success =
936  JSSegmentIterator::Following(isolate, segment_iterator, from);
937  MAYBE_RETURN(success, ReadOnlyRoots(isolate).exception());
938  return *isolate->factory()->ToBoolean(success.FromJust());
939 }
940 
941 // ecma402 #sec-segment-iterator-prototype-next
942 BUILTIN(SegmentIteratorPrototypeNext) {
943  const char* const method = "%SegmentIteratorPrototype%.next";
944  HandleScope scope(isolate);
945  CHECK_RECEIVER(JSSegmentIterator, segment_iterator, method);
946 
947  RETURN_RESULT_OR_FAILURE(isolate,
948  JSSegmentIterator::Next(isolate, segment_iterator));
949 }
950 
951 // ecma402 #sec-segment-iterator-prototype-preceding
952 BUILTIN(SegmentIteratorPrototypePreceding) {
953  const char* const method = "%SegmentIteratorPrototype%.preceding";
954  HandleScope scope(isolate);
955  CHECK_RECEIVER(JSSegmentIterator, segment_iterator, method);
956 
957  Handle<Object> from = args.atOrUndefined(isolate, 1);
958 
959  Maybe<bool> success =
960  JSSegmentIterator::Preceding(isolate, segment_iterator, from);
961  MAYBE_RETURN(success, ReadOnlyRoots(isolate).exception());
962  return *isolate->factory()->ToBoolean(success.FromJust());
963 }
964 
965 // ecma402 #sec-segment-iterator-prototype-position
966 BUILTIN(SegmentIteratorPrototypePosition) {
967  const char* const method = "get %SegmentIteratorPrototype%.position";
968  HandleScope scope(isolate);
969 
970  CHECK_RECEIVER(JSSegmentIterator, segment_iterator, method);
971  return *JSSegmentIterator::Position(isolate, segment_iterator);
972 }
973 
974 BUILTIN(SegmenterConstructor) {
975  HandleScope scope(isolate);
976 
977  return DisallowCallConstructor<JSSegmenter>(
978  args, isolate, v8::Isolate::UseCounterFeature::kSegmenter,
979  "Intl.Segmenter");
980 }
981 
982 BUILTIN(SegmenterSupportedLocalesOf) {
983  HandleScope scope(isolate);
984  Handle<Object> locales = args.atOrUndefined(isolate, 1);
985  Handle<Object> options = args.atOrUndefined(isolate, 2);
986 
987  RETURN_RESULT_OR_FAILURE(
988  isolate, Intl::SupportedLocalesOf(
989  isolate, "Intl.Segmenter.supportedLocalesOf",
990  JSSegmenter::GetAvailableLocales(), locales, options));
991 }
992 
993 BUILTIN(SegmenterPrototypeResolvedOptions) {
994  HandleScope scope(isolate);
995  CHECK_RECEIVER(JSSegmenter, segmenter_holder,
996  "Intl.Segmenter.prototype.resolvedOptions");
997  return *JSSegmenter::ResolvedOptions(isolate, segmenter_holder);
998 }
999 
1000 // ecma402 #sec-Intl.Segmenter.prototype.segment
1001 BUILTIN(SegmenterPrototypeSegment) {
1002  HandleScope scope(isolate);
1003  CHECK_RECEIVER(JSSegmenter, segmenter_holder,
1004  "Intl.Segmenter.prototype.segment");
1005  Handle<Object> input_text = args.atOrUndefined(isolate, 1);
1006  // 3. Let string be ? ToString(string).
1007  Handle<String> text;
1008  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, text,
1009  Object::ToString(isolate, input_text));
1010 
1011  // 4. Return ? CreateSegmentIterator(segment, string).
1012  RETURN_RESULT_OR_FAILURE(
1013  isolate,
1014  JSSegmentIterator::Create(
1015  isolate, segmenter_holder->icu_break_iterator()->raw()->clone(),
1016  segmenter_holder->granularity(), text));
1017 }
1018 
1019 BUILTIN(V8BreakIteratorConstructor) {
1020  HandleScope scope(isolate);
1021 
1022  return CallOrConstructConstructor<JSV8BreakIterator>(args, isolate);
1023 }
1024 
1025 BUILTIN(V8BreakIteratorPrototypeResolvedOptions) {
1026  HandleScope scope(isolate);
1027  CHECK_RECEIVER(JSV8BreakIterator, break_iterator,
1028  "Intl.v8BreakIterator.prototype.resolvedOptions");
1029  return *JSV8BreakIterator::ResolvedOptions(isolate, break_iterator);
1030 }
1031 
1032 BUILTIN(V8BreakIteratorPrototypeAdoptText) {
1033  const char* const method = "get Intl.v8BreakIterator.prototype.adoptText";
1034  HandleScope scope(isolate);
1035 
1036  CHECK_RECEIVER(JSV8BreakIterator, break_iterator, method);
1037 
1038  Handle<Object> bound_adopt_text(break_iterator->bound_adopt_text(), isolate);
1039  if (!bound_adopt_text->IsUndefined(isolate)) {
1040  DCHECK(bound_adopt_text->IsJSFunction());
1041  return *bound_adopt_text;
1042  }
1043 
1044  Handle<JSFunction> new_bound_adopt_text_function = CreateBoundFunction(
1045  isolate, break_iterator, Builtins::kV8BreakIteratorInternalAdoptText, 1);
1046  break_iterator->set_bound_adopt_text(*new_bound_adopt_text_function);
1047  return *new_bound_adopt_text_function;
1048 }
1049 
1050 BUILTIN(V8BreakIteratorInternalAdoptText) {
1051  HandleScope scope(isolate);
1052  Handle<Context> context = Handle<Context>(isolate->context(), isolate);
1053 
1054  Handle<JSV8BreakIterator> break_iterator = Handle<JSV8BreakIterator>(
1055  JSV8BreakIterator::cast(context->get(
1056  static_cast<int>(Intl::BoundFunctionContextSlot::kBoundFunction))),
1057  isolate);
1058 
1059  Handle<Object> input_text = args.atOrUndefined(isolate, 1);
1060  Handle<String> text;
1061  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, text,
1062  Object::ToString(isolate, input_text));
1063 
1064  JSV8BreakIterator::AdoptText(isolate, break_iterator, text);
1065  return ReadOnlyRoots(isolate).undefined_value();
1066 }
1067 
1068 BUILTIN(V8BreakIteratorPrototypeFirst) {
1069  const char* const method = "get Intl.v8BreakIterator.prototype.first";
1070  HandleScope scope(isolate);
1071 
1072  CHECK_RECEIVER(JSV8BreakIterator, break_iterator, method);
1073 
1074  Handle<Object> bound_first(break_iterator->bound_first(), isolate);
1075  if (!bound_first->IsUndefined(isolate)) {
1076  DCHECK(bound_first->IsJSFunction());
1077  return *bound_first;
1078  }
1079 
1080  Handle<JSFunction> new_bound_first_function = CreateBoundFunction(
1081  isolate, break_iterator, Builtins::kV8BreakIteratorInternalFirst, 0);
1082  break_iterator->set_bound_first(*new_bound_first_function);
1083  return *new_bound_first_function;
1084 }
1085 
1086 BUILTIN(V8BreakIteratorInternalFirst) {
1087  HandleScope scope(isolate);
1088  Handle<Context> context = Handle<Context>(isolate->context(), isolate);
1089 
1090  Handle<JSV8BreakIterator> break_iterator = Handle<JSV8BreakIterator>(
1091  JSV8BreakIterator::cast(context->get(
1092  static_cast<int>(Intl::BoundFunctionContextSlot::kBoundFunction))),
1093  isolate);
1094 
1095  return *JSV8BreakIterator::First(isolate, break_iterator);
1096 }
1097 
1098 BUILTIN(V8BreakIteratorPrototypeNext) {
1099  const char* const method = "get Intl.v8BreakIterator.prototype.next";
1100  HandleScope scope(isolate);
1101 
1102  CHECK_RECEIVER(JSV8BreakIterator, break_iterator, method);
1103 
1104  Handle<Object> bound_next(break_iterator->bound_next(), isolate);
1105  if (!bound_next->IsUndefined(isolate)) {
1106  DCHECK(bound_next->IsJSFunction());
1107  return *bound_next;
1108  }
1109 
1110  Handle<JSFunction> new_bound_next_function = CreateBoundFunction(
1111  isolate, break_iterator, Builtins::kV8BreakIteratorInternalNext, 0);
1112  break_iterator->set_bound_next(*new_bound_next_function);
1113  return *new_bound_next_function;
1114 }
1115 
1116 BUILTIN(V8BreakIteratorInternalNext) {
1117  HandleScope scope(isolate);
1118  Handle<Context> context = Handle<Context>(isolate->context(), isolate);
1119 
1120  Handle<JSV8BreakIterator> break_iterator = Handle<JSV8BreakIterator>(
1121  JSV8BreakIterator::cast(context->get(
1122  static_cast<int>(Intl::BoundFunctionContextSlot::kBoundFunction))),
1123  isolate);
1124  return *JSV8BreakIterator::Next(isolate, break_iterator);
1125 }
1126 
1127 BUILTIN(V8BreakIteratorPrototypeCurrent) {
1128  const char* const method = "get Intl.v8BreakIterator.prototype.current";
1129  HandleScope scope(isolate);
1130 
1131  CHECK_RECEIVER(JSV8BreakIterator, break_iterator, method);
1132 
1133  Handle<Object> bound_current(break_iterator->bound_current(), isolate);
1134  if (!bound_current->IsUndefined(isolate)) {
1135  DCHECK(bound_current->IsJSFunction());
1136  return *bound_current;
1137  }
1138 
1139  Handle<JSFunction> new_bound_current_function = CreateBoundFunction(
1140  isolate, break_iterator, Builtins::kV8BreakIteratorInternalCurrent, 0);
1141  break_iterator->set_bound_current(*new_bound_current_function);
1142  return *new_bound_current_function;
1143 }
1144 
1145 BUILTIN(V8BreakIteratorInternalCurrent) {
1146  HandleScope scope(isolate);
1147  Handle<Context> context = Handle<Context>(isolate->context(), isolate);
1148 
1149  Handle<JSV8BreakIterator> break_iterator = Handle<JSV8BreakIterator>(
1150  JSV8BreakIterator::cast(context->get(
1151  static_cast<int>(Intl::BoundFunctionContextSlot::kBoundFunction))),
1152  isolate);
1153  return *JSV8BreakIterator::Current(isolate, break_iterator);
1154 }
1155 
1156 BUILTIN(V8BreakIteratorPrototypeBreakType) {
1157  const char* const method = "get Intl.v8BreakIterator.prototype.breakType";
1158  HandleScope scope(isolate);
1159 
1160  CHECK_RECEIVER(JSV8BreakIterator, break_iterator, method);
1161 
1162  Handle<Object> bound_break_type(break_iterator->bound_break_type(), isolate);
1163  if (!bound_break_type->IsUndefined(isolate)) {
1164  DCHECK(bound_break_type->IsJSFunction());
1165  return *bound_break_type;
1166  }
1167 
1168  Handle<JSFunction> new_bound_break_type_function = CreateBoundFunction(
1169  isolate, break_iterator, Builtins::kV8BreakIteratorInternalBreakType, 0);
1170  break_iterator->set_bound_break_type(*new_bound_break_type_function);
1171  return *new_bound_break_type_function;
1172 }
1173 
1174 BUILTIN(V8BreakIteratorInternalBreakType) {
1175  HandleScope scope(isolate);
1176  Handle<Context> context = Handle<Context>(isolate->context(), isolate);
1177 
1178  Handle<JSV8BreakIterator> break_iterator = Handle<JSV8BreakIterator>(
1179  JSV8BreakIterator::cast(context->get(
1180  static_cast<int>(Intl::BoundFunctionContextSlot::kBoundFunction))),
1181  isolate);
1182  return JSV8BreakIterator::BreakType(isolate, break_iterator);
1183 }
1184 
1185 } // namespace internal
1186 } // namespace v8
Definition: libplatform.h:13