5 #ifndef V8_INTL_SUPPORT 6 #error Internationalization is expected to be enabled. 7 #endif // V8_INTL_SUPPORT 9 #include "src/builtins/builtins-iterator-gen.h" 10 #include "src/builtins/builtins-utils-gen.h" 11 #include "src/code-stub-assembler.h" 12 #include "src/objects-inl.h" 13 #include "src/objects.h" 14 #include "src/objects/js-list-format-inl.h" 15 #include "src/objects/js-list-format.h" 21 using TNode = compiler::TNode<T>;
29 Runtime::FunctionId format_func_id,
30 const char* method_name);
36 Node*
const string = Parameter(Descriptor::kString);
37 Node*
const context = Parameter(Descriptor::kContext);
39 CSA_ASSERT(
this, IsString(
string));
41 Label call_c(
this), return_string(
this), runtime(
this, Label::kDeferred);
45 GotoIf(Word32Equal(length, Uint32Constant(0)), &return_string);
50 state(),
string, ToDirectStringAssembler::kDontUnpackSlicedStrings);
51 to_direct.TryToDirect(&runtime);
53 Node*
const instance_type = to_direct.instance_type();
55 Word32BinaryNot(IsIndirectStringInstanceType(instance_type)));
56 GotoIfNot(IsOneByteStringInstanceType(instance_type), &runtime);
60 Node*
const dst = AllocateSeqOneByteString(context, length);
62 const int kMaxShortStringLength = 24;
63 GotoIf(Uint32GreaterThan(length, Uint32Constant(kMaxShortStringLength)),
67 Node*
const dst_ptr = PointerToSeqStringData(dst);
68 VARIABLE(var_cursor, MachineType::PointerRepresentation(),
71 Node*
const start_address = to_direct.PointerToData(&call_c);
73 Signed(IntPtrAdd(start_address, ChangeUint32ToWord(length)));
75 Node*
const to_lower_table_addr =
76 ExternalConstant(ExternalReference::intl_to_latin1_lower_table());
78 VARIABLE(var_did_change, MachineRepresentation::kWord32, Int32Constant(0));
80 VariableList push_vars({&var_cursor, &var_did_change}, zone());
81 BuildFastLoop(push_vars, start_address, end_address,
82 [=, &var_cursor, &var_did_change](Node* current) {
83 Node* c = Load(MachineType::Uint8(), current);
85 Load(MachineType::Uint8(), to_lower_table_addr,
86 ChangeInt32ToIntPtr(c));
87 StoreNoWriteBarrier(MachineRepresentation::kWord8, dst_ptr,
88 var_cursor.value(), lower);
90 var_did_change.Bind(Word32Or(Word32NotEqual(c, lower),
91 var_did_change.value()));
93 Increment(&var_cursor);
95 kCharSize, INTPTR_PARAMETERS, IndexAdvanceMode::kPost);
100 GotoIfNot(var_did_change.value(), &return_string);
109 Node*
const src = to_direct.string();
111 Node*
const function_addr =
112 ExternalConstant(ExternalReference::intl_convert_one_byte_to_lower());
114 MachineType type_tagged = MachineType::AnyTagged();
116 Node*
const result = CallCFunction2(type_tagged, type_tagged, type_tagged,
117 function_addr, src, dst);
122 BIND(&return_string);
127 Node*
const result = CallRuntime(Runtime::kStringToLowerCaseIntl,
128 NoContextConstant(),
string);
133 TF_BUILTIN(StringPrototypeToLowerCaseIntl, IntlBuiltinsAssembler) {
134 Node*
const maybe_string = Parameter(Descriptor::kReceiver);
135 Node*
const context = Parameter(Descriptor::kContext);
138 ToThisString(context, maybe_string,
"String.prototype.toLowerCase");
140 Return(CallBuiltin(Builtins::kStringToLowerCaseIntl, context,
string));
143 void IntlBuiltinsAssembler::ListFormatCommon(TNode<Context> context,
145 Runtime::FunctionId format_func_id,
146 const char* method_name) {
147 CodeStubArguments args(
this, ChangeInt32ToIntPtr(argc));
152 TNode<Object> receiver = args.GetReceiver();
156 ThrowIfNotInstanceType(context, receiver, JS_INTL_LIST_FORMAT_TYPE,
158 TNode<JSListFormat> list_format = CAST(receiver);
161 TNode<Object> list = args.GetOptionalArgumentValue(0);
162 Label has_list(
this);
164 GotoIfNot(IsUndefined(list), &has_list);
165 if (format_func_id == Runtime::kFormatList) {
167 args.PopAndReturn(EmptyStringConstant());
169 DCHECK_EQ(format_func_id, Runtime::kFormatListToParts);
171 args.PopAndReturn(AllocateEmptyJSArray(context));
178 CallBuiltin(Builtins::kIterableToListWithSymbolLookup, context, list);
181 args.PopAndReturn(CallRuntime(format_func_id, context, list_format, x));
185 TNode<JSArray> IntlBuiltinsAssembler::AllocateEmptyJSArray(
186 TNode<Context> context) {
187 return CodeStubAssembler::AllocateJSArray(
189 LoadJSArrayElementsMap(PACKED_ELEMENTS, LoadNativeContext(context)),
190 SmiConstant(0), SmiConstant(0));
193 TF_BUILTIN(ListFormatPrototypeFormat, IntlBuiltinsAssembler) {
195 CAST(Parameter(Descriptor::kContext)),
196 UncheckedCast<Int32T>(Parameter(Descriptor::kJSActualArgumentsCount)),
197 Runtime::kFormatList,
"Intl.ListFormat.prototype.format");
200 TF_BUILTIN(ListFormatPrototypeFormatToParts, IntlBuiltinsAssembler) {
202 CAST(Parameter(Descriptor::kContext)),
203 UncheckedCast<Int32T>(Parameter(Descriptor::kJSActualArgumentsCount)),
204 Runtime::kFormatListToParts,
"Intl.ListFormat.prototype.formatToParts");