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