28bool IsValidCodePoint(Isolate* isolate, DirectHandle<Object> value) {
48base::uc32 NextCodePoint(Isolate* isolate, BuiltinArguments
args,
int index) {
49 DirectHandle<Object> value =
args.at(1 + index);
52 if (!IsValidCodePoint(isolate, value)) {
53 isolate->Throw(*isolate->factory()->NewRangeError(
54 MessageTemplate::kInvalidCodePoint, value));
55 return kInvalidCodePoint;
65 int const length =
args.length() - 1;
66 if (length == 0)
return ReadOnlyRoots(isolate).empty_string();
71 std::vector<uint8_t> one_byte_buffer;
72 one_byte_buffer.reserve(length);
75 for (index = 0; index <
length; index++) {
76 code = NextCodePoint(isolate,
args, index);
77 if (code == kInvalidCodePoint) {
83 one_byte_buffer.push_back(code);
86 if (index == length) {
89 one_byte_buffer.data(), one_byte_buffer.size())));
92 std::vector<base::uc16> two_byte_buffer;
93 two_byte_buffer.reserve(length - index);
98 two_byte_buffer.push_back(code);
104 if (++index == length) {
107 code = NextCodePoint(isolate,
args, index);
108 if (code == kInvalidCodePoint) {
116 isolate->factory()->NewRawTwoByteString(
117 static_cast<int>(one_byte_buffer.size() + two_byte_buffer.size())));
121 one_byte_buffer.size());
123 two_byte_buffer.data(), two_byte_buffer.size());
133 args.atOrUndefined(isolate, 1),
134 args.atOrUndefined(isolate, 2));
137#ifndef V8_INTL_SUPPORT
147 static const char*
const kMethod =
"String.prototype.localeCompare";
156 if (str1.is_identical_to(str2))
return Smi::zero();
157 int str1_length = str1->length();
158 int str2_length = str2->length();
161 if (str1_length == 0) {
162 if (str2_length == 0)
return Smi::zero();
168 int end = str1_length < str2_length ? str1_length : str2_length;
173 int d = str1->Get(0) - str2->Get(0);
183 for (
int i = 0;
i <
end;
i++) {
202 if (IsUndefined(*form_input, isolate))
return *
string;
208 if (!(
String::Equals(isolate, form, isolate->factory()->NFC_string()) ||
209 String::Equals(isolate, form, isolate->factory()->NFD_string()) ||
210 String::Equals(isolate, form, isolate->factory()->NFKC_string()) ||
211 String::Equals(isolate, form, isolate->factory()->NFKD_string()))) {
213 isolate->factory()->NewStringFromStaticChars(
"NFC, NFD, NFKC, NFKD");
216 NewRangeError(MessageTemplate::kNormalizationForm, valid_forms));
224#ifndef V8_INTL_SUPPORT
235template <
class Converter>
249 bool has_changed_character =
false;
253 StringCharacterStream stream(
string);
257 bool ignore_overflow = Converter::kIsToLower || IsSeqTwoByteString(
result);
258 for (uint32_t
i = 0;
i < result_length;) {
259 bool has_next = stream.HasMore();
260 base::uc32 next = has_next ? stream.GetNext() : 0;
261 uint32_t char_length = mapping->
get(current, next, chars);
262 if (char_length == 0) {
266 }
else if (char_length == 1 &&
267 (ignore_overflow || !ToUpperOverflows(current))) {
271 has_changed_character =
true;
273 }
else if (result_length == string->length()) {
274 bool overflows = ToUpperOverflows(current);
286 uint32_t next_length = 0;
288 next_length = mapping->
get(next, 0, chars);
289 if (next_length == 0) next_length = 1;
291 uint32_t current_length =
i + char_length + next_length;
292 while (stream.HasMore()) {
293 current = stream.GetNext();
294 overflows |= ToUpperOverflows(current);
299 int char_len = mapping->
get(current, 0, chars);
300 if (char_len == 0) char_len = 1;
301 current_length += char_len;
305 NewInvalidStringLengthError());
310 return (overflows && !ignore_overflow) ?
Smi::FromInt(-current_length)
311 : Smi::FromInt(current_length);
313 for (uint32_t j = 0; j < char_length; j++) {
317 has_changed_character =
true;
321 if (has_changed_character) {
332template <
class Converter>
334 DirectHandle<String> s, Isolate* isolate,
337 uint32_t length = s->length();
339 if (length == 0)
return *
s;
351 String::FlatContent flat = s->GetFlatContent(no_gc);
353 reinterpret_cast<const char*
>(flat.ToOneByteVector().begin()),
355 if (prefix == length)
return *
s;
358 DirectHandle<SeqOneByteString>
result =
359 isolate->factory()->NewRawOneByteString(length).ToHandleChecked();
361 String::FlatContent flat = s->GetFlatContent(no_gc);
363 uint8_t* dest =
result->GetChars(no_gc);
364 base::Vector<const uint8_t> src = flat.ToOneByteVector();
365 std::memcpy(dest, src.begin(), prefix);
366 uint32_t index_to_first_unprocessed =
368 reinterpret_cast<char*
>(dest + prefix),
369 reinterpret_cast<const char*
>(src.begin() + prefix),
373 if (index_to_first_unprocessed == length)
return *
result;
376 DirectHandle<SeqString>
result;
377 if (s->IsOneByteRepresentation()) {
378 result = isolate->factory()->NewRawOneByteString(length).ToHandleChecked();
380 result = isolate->factory()->NewRawTwoByteString(length).ToHandleChecked();
384 ConvertCaseHelper(isolate, *s, *
result, length, mapping);
385 if (IsException(answer, isolate) || IsString(answer))
return answer;
391 if (s->IsOneByteRepresentation() && int_answer > 0) {
394 isolate,
result, isolate->factory()->NewRawOneByteString(length));
396 length = abs(int_answer);
398 isolate,
result, isolate->factory()->NewRawTwoByteString(length));
400 return ConvertCaseHelper(isolate, *s, *
result, length, mapping);
408 return ConvertCase(
string, isolate,
409 isolate->runtime_state()->to_lower_mapping());
412BUILTIN(StringPrototypeToLocaleUpperCase) {
415 return ConvertCase(
string, isolate,
416 isolate->runtime_state()->to_upper_mapping());
422 return ConvertCase(
string, isolate,
423 isolate->runtime_state()->to_lower_mapping());
429 return ConvertCase(
string, isolate,
430 isolate->runtime_state()->to_upper_mapping());
438 const uint32_t argc =
args.length();
440 isolate->factory()->NewStringFromAsciiChecked(
"raw");
464 const uint32_t length = raw_len_number > std::numeric_limits<uint32_t>::max()
465 ? std::numeric_limits<uint32_t>::max()
466 :
static_cast<uint32_t
>(raw_len_number);
477 for (uint32_t
i = 1, arg_i = 2;
i <
length;
i++, arg_i++) {
481 isolate, argument_string,
#define TO_THIS_STRING(name, method)
int get(uchar c, uchar n, uchar *result)
static uint16_t LeadSurrogate(uint32_t char_code)
static const uchar kMaxNonSurrogateCharCode
static uint16_t TrailSurrogate(uint32_t char_code)
MaybeDirectHandle< String > Finish()
V8_INLINE void AppendString(std::string_view str)
static V8_WARN_UNUSED_RESULT MaybeHandle< Object > ToLength(Isolate *isolate, DirectHandle< Object > input)
static V8_WARN_UNUSED_RESULT HandleType< String >::MaybeType ToString(Isolate *isolate, HandleType< T > input)
static V8_WARN_UNUSED_RESULT HandleType< Number >::MaybeType ToNumber(Isolate *isolate, HandleType< T > input)
static V8_WARN_UNUSED_RESULT HandleType< JSReceiver >::MaybeType ToObject(Isolate *isolate, HandleType< T > object, const char *method_name=nullptr)
static double NumberValue(Tagged< Number > obj)
static V8_WARN_UNUSED_RESULT Maybe< double > IntegerValue(Isolate *isolate, HandleType< T > input)
V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT MaybeHandle< Object > GetProperty(LookupIterator *it, bool is_global_reference=false)
static V8_WARN_UNUSED_RESULT MaybeHandle< Object > GetElement(Isolate *isolate, DirectHandle< JSAny > object, uint32_t index)
static constexpr int ToInt(const Tagged< Object > object)
static constexpr Tagged< Smi > FromInt(int value)
static constexpr Tagged< Smi > zero()
base::uc16 Get(uint32_t i) const
static const uint32_t kMaxLength
static V8_INLINE HandleType< String > Flatten(Isolate *isolate, HandleType< T > string, AllocationType allocation=AllocationType::kYoung)
static const int32_t kMaxOneByteCharCode
static bool IsOneByteRepresentationUnderneath(Tagged< String > string)
bool Equals(Tagged< String > other) const
static Tagged< Object > LastIndexOf(Isolate *isolate, DirectHandle< Object > receiver, DirectHandle< Object > search, DirectHandle< Object > position)
#define ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, dst, call)
#define ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, dst, call, value)
#define THROW_NEW_ERROR_RETURN_FAILURE(isolate, call)
#define RETURN_RESULT_OR_FAILURE(isolate, call)
base::Vector< const DirectHandle< Object > > args
ZoneVector< RpoNumber > & result
uint32_t DoubleToUint32(double x)
PerThreadAssertScopeDebugOnly< false, SAFEPOINTS_ASSERT, HEAP_ALLOCATION_ASSERT > DisallowGarbageCollection
bool IsNumber(Tagged< Object > obj)
Tagged(T object) -> Tagged< T >
V8_INLINE constexpr bool IsSmi(TaggedImpl< kRefType, StorageType > obj)
BUILTIN_FP_CALL BUILTIN_FP_CALL BUILTIN_FP_CALL BUILTIN_FP_CALL BUILTIN_FP_CALL BUILTIN_FP_CALL BUILTIN_FP_CALL BUILTIN_FP_CALL BUILTIN_FP_CALL BUILTIN_FP_CALL int character
PerThreadAssertScopeDebugOnly< true, SAFEPOINTS_ASSERT, HEAP_ALLOCATION_ASSERT > AllowGarbageCollection
uint32_t FastAsciiConvert(char *dst, const char *src, uint32_t length)
void CopyChars(DstType *dst, const SrcType *src, size_t count) V8_NONNULL(1
uint32_t FastAsciiCasePrefixLength(const char *src, uint32_t length)
template const char * string
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
#define DCHECK_LE(v1, v2)
#define DCHECK(condition)
#define DCHECK_LT(v1, v2)
#define V8_WARN_UNUSED_RESULT