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