5 #ifndef V8_OBJECTS_STRING_H_ 6 #define V8_OBJECTS_STRING_H_ 8 #include "src/base/bits.h" 9 #include "src/objects/instance-type.h" 10 #include "src/objects/name.h" 11 #include "src/objects/smi.h" 12 #include "src/unicode-decoder.h" 15 #include "src/objects/object-macros.h" 20 enum InstanceType : uint16_t;
22 enum AllowNullsFlag { ALLOW_NULLS, DISALLOW_NULLS };
23 enum RobustnessFlag { ROBUST_STRING_TRAVERSAL, FAST_STRING_TRAVERSAL };
41 inline bool IsSequential();
42 inline bool IsExternal();
44 inline bool IsSliced();
46 inline bool IsIndirect();
47 inline bool IsExternalOneByte();
48 inline bool IsExternalTwoByte();
49 inline bool IsSequentialOneByte();
50 inline bool IsSequentialTwoByte();
51 inline bool IsInternalized();
52 inline StringRepresentationTag representation_tag();
54 inline uint32_t full_representation_tag();
55 inline bool HasOnlyOneByteChars();
58 inline void invalidate() { valid_ =
false; }
59 inline bool valid() {
return valid_; }
61 inline void invalidate() {}
67 inline void set_valid() { valid_ =
true; }
70 inline void set_valid() {}
84 enum Encoding { ONE_BYTE_ENCODING, TWO_BYTE_ENCODING };
94 bool IsFlat()
const {
return state_ != NON_FLAT; }
96 bool IsOneByte()
const {
return state_ == ONE_BYTE; }
98 bool IsTwoByte()
const {
return state_ == TWO_BYTE; }
103 DCHECK_EQ(ONE_BYTE, state_);
109 DCHECK_EQ(TWO_BYTE, state_);
113 uc16 Get(
int i)
const {
115 DCHECK(state_ != NON_FLAT);
116 if (state_ == ONE_BYTE)
return onebyte_start[
i];
117 return twobyte_start[
i];
120 bool UsesSameString(
const FlatContent& other)
const {
121 return onebyte_start == other.onebyte_start;
125 enum State { NON_FLAT, ONE_BYTE, TWO_BYTE };
128 explicit FlatContent(
const uint8_t* start,
int length)
129 : onebyte_start(start), length_(length), state_(ONE_BYTE) {}
130 explicit FlatContent(
const uc16* start,
int length)
131 : twobyte_start(start), length_(length), state_(TWO_BYTE) {}
132 FlatContent() : onebyte_start(
nullptr), length_(0), state_(NON_FLAT) {}
135 const uint8_t* onebyte_start;
136 const uc16* twobyte_start;
142 friend class IterableSubString;
145 template <
typename Char>
149 inline int length()
const;
150 inline void set_length(
int value);
154 inline int synchronized_length()
const;
155 inline void synchronized_set_length(
int value);
161 inline bool IsOneByteRepresentation()
const;
162 inline bool IsTwoByteRepresentation()
const;
167 inline bool IsOneByteRepresentationUnderneath();
168 inline bool IsTwoByteRepresentationUnderneath();
172 inline bool HasOnlyOneByteChars();
175 inline void Set(
int index, uint16_t value);
178 V8_INLINE uint16_t Get(
int index);
197 PretenureFlag pretenure = NOT_TENURED);
208 inline String GetUnderlying();
221 V8_WARN_UNUSED_RESULT
static ComparisonResult Compare(
Isolate* isolate,
247 enum CaptureState { INVALID, UNMATCHED, MATCHED };
249 virtual int CaptureCount() = 0;
250 virtual bool HasNamedCaptures() = 0;
253 CaptureState* state) = 0;
255 virtual ~
Match() =
default;
266 int start_index = 0);
269 inline bool Equals(
String other);
275 template <
typename Char>
289 std::unique_ptr<char[]> ToCString(AllowNullsFlag allow_nulls,
290 RobustnessFlag robustness_flag,
int offset,
291 int length,
int* length_output =
nullptr);
292 std::unique_ptr<char[]> ToCString(
293 AllowNullsFlag allow_nulls = DISALLOW_NULLS,
294 RobustnessFlag robustness_flag = FAST_STRING_TRAVERSAL,
295 int* length_output =
nullptr);
297 bool ComputeArrayIndex(
uint32_t* index);
302 bool SupportsExternalization();
305 inline bool AsArrayIndex(
uint32_t* index);
309 enum TrimMode { kTrim, kTrimStart, kTrimEnd };
315 void PrintOn(FILE* out);
321 void StringShortPrint(
StringStream* accumulator,
bool show_details =
true);
322 void PrintUC16(std::ostream& os,
int start = 0,
int end = -1);
323 #if defined(DEBUG) || defined(OBJECT_PRINT) 324 char* ToAsciiArray();
329 inline bool IsFlat();
332 static const int kLengthOffset = Name::kHeaderSize;
333 static const int kHeaderSize = kLengthOffset + kInt32Size;
336 static const int32_t kMaxOneByteCharCode = unibrow::Latin1::kMaxChar;
337 static const uint32_t kMaxOneByteCharCodeU = unibrow::Latin1::kMaxChar;
338 static const int kMaxUtf16CodeUnit = 0xffff;
339 static const uint32_t kMaxUtf16CodeUnitU = kMaxUtf16CodeUnit;
340 static const uc32 kMaxCodePoint = 0x10ffff;
350 static const int kMaxLength = v8::String::kMaxLength;
351 static_assert(kMaxLength <= (Smi::kMaxValue / 2 - kHeaderSize),
352 "Unexpected max String length");
356 static const int kMaxHashCalcLength = 16383;
359 static const int kMaxShortPrintLength = 1024;
362 template <
typename sink
char>
363 static void WriteToFlat(
String source, sinkchar* sink,
int from,
int to);
369 static inline int NonAsciiStart(
const char* chars,
int length) {
370 const char* start = chars;
371 const char* limit = chars + length;
373 if (length >= kIntptrSize) {
375 while (!IsAligned(reinterpret_cast<intptr_t>(chars),
sizeof(
uintptr_t))) {
376 if (static_cast<uint8_t>(*chars) > unibrow::Utf8::kMaxOneByteChar) {
377 return static_cast<int>(chars - start);
382 DCHECK_EQ(unibrow::Utf8::kMaxOneByteChar, 0x7F);
383 const uintptr_t non_one_byte_mask = kUintptrAllBitsSet / 0xFF * 0x80;
384 while (chars +
sizeof(
uintptr_t) <= limit) {
385 if (*reinterpret_cast<const uintptr_t*>(chars) & non_one_byte_mask) {
386 return static_cast<int>(chars - start);
392 while (chars < limit) {
393 if (static_cast<uint8_t>(*chars) > unibrow::Utf8::kMaxOneByteChar) {
394 return static_cast<int>(chars - start);
399 return static_cast<int>(chars - start);
402 static inline bool IsAscii(
const char* chars,
int length) {
403 return NonAsciiStart(chars, length) >= length;
406 static inline bool IsAscii(
const uint8_t* chars,
int length) {
407 return NonAsciiStart(reinterpret_cast<const char*>(chars), length) >=
411 static inline int NonOneByteStart(
const uc16* chars,
int length) {
412 const uc16* limit = chars + length;
413 const uc16* start = chars;
414 while (chars < limit) {
415 if (*chars > kMaxOneByteCharCodeU)
return static_cast<int>(chars - start);
418 return static_cast<int>(chars - start);
421 static inline bool IsOneByte(
const uc16* chars,
int length) {
422 return NonOneByteStart(chars, length) >= length;
425 template <
class Visitor>
426 static inline ConsString VisitFlat(Visitor* visitor, String
string,
429 static Handle<FixedArray> CalculateLineEnds(Isolate* isolate,
430 Handle<String>
string,
431 bool include_ending_line);
435 friend class StringTableInsertionKey;
436 friend class InternalizedStringKey;
438 static Handle<String> SlowFlatten(Isolate* isolate, Handle<ConsString> cons,
439 PretenureFlag tenure);
443 bool SlowEquals(String other);
445 static bool SlowEquals(Isolate* isolate, Handle<String> one,
449 V8_EXPORT_PRIVATE
bool SlowAsArrayIndex(
uint32_t* index);
452 uint32_t ComputeAndSetHash(Isolate* isolate);
454 OBJECT_CONSTRUCTORS(String, Name);
496 static const bool kHasOneByteEncoding =
true;
499 inline uint16_t SeqOneByteStringGet(
int index);
500 inline void SeqOneByteStringSet(
int index, uint16_t value);
503 inline Address GetCharsAddress();
505 inline uint8_t* GetChars();
509 void clear_padding();
516 inline int SeqOneByteStringSize(InstanceType instance_type);
519 static int SizeFor(
int length) {
520 return OBJECT_POINTER_ALIGN(kHeaderSize + length * kCharSize);
524 static const int kMaxCharsSize = kMaxLength;
525 static const int kMaxSize = OBJECT_POINTER_ALIGN(kMaxCharsSize + kHeaderSize);
526 STATIC_ASSERT((kMaxSize - kHeaderSize) >= String::kMaxLength);
537 static const bool kHasOneByteEncoding =
false;
540 inline uint16_t SeqTwoByteStringGet(
int index);
541 inline void SeqTwoByteStringSet(
int index, uint16_t value);
544 inline Address GetCharsAddress();
546 inline uc16* GetChars();
550 void clear_padding();
557 inline int SeqTwoByteStringSize(InstanceType instance_type);
560 static int SizeFor(
int length) {
561 return OBJECT_POINTER_ALIGN(kHeaderSize + length * kShortSize);
565 static const int kMaxCharsSize = kMaxLength * 2;
566 static const int kMaxSize = OBJECT_POINTER_ALIGN(kMaxCharsSize + kHeaderSize);
567 STATIC_ASSERT(static_cast<int>((kMaxSize - kHeaderSize) /
sizeof(uint16_t)) >=
589 inline Object* unchecked_first();
591 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
597 inline Object* unchecked_second();
599 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
602 V8_EXPORT_PRIVATE uint16_t ConsStringGet(
int index);
607 #define CONS_STRING_FIELDS(V) \ 608 V(kFirstOffset, kTaggedSize) \ 609 V(kSecondOffset, kTaggedSize) \ 613 DEFINE_FIELD_OFFSET_CONSTANTS(String::kHeaderSize, CONS_STRING_FIELDS)
614 #undef CONS_STRING_FIELDS 617 static const int kMinLength = 13;
636 inline String actual()
const;
638 inline void set_actual(
String s,
639 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
641 V8_EXPORT_PRIVATE uint16_t ThinStringGet(
int index);
647 #define THIN_STRING_FIELDS(V) \ 648 V(kActualOffset, kTaggedSize) \ 652 DEFINE_FIELD_OFFSET_CONSTANTS(String::kHeaderSize, THIN_STRING_FIELDS)
653 #undef THIN_STRING_FIELDS 676 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
677 inline int offset()
const;
678 inline void set_offset(
int offset);
681 V8_EXPORT_PRIVATE uint16_t SlicedStringGet(
int index);
686 #define SLICED_STRING_FIELDS(V) \ 687 V(kParentOffset, kTaggedSize) \ 688 V(kOffsetOffset, kTaggedSize) \ 692 DEFINE_FIELD_OFFSET_CONSTANTS(String::kHeaderSize, SLICED_STRING_FIELDS)
693 #undef SLICED_STRING_FIELDS 696 static const int kMinLength = 13;
719 #define EXTERNAL_STRING_FIELDS(V) \ 720 V(kResourceOffset, kSystemPointerSize) \ 722 V(kUncachedSize, 0) \ 723 V(kResourceDataOffset, kSystemPointerSize) \ 727 DEFINE_FIELD_OFFSET_CONSTANTS(String::kHeaderSize, EXTERNAL_STRING_FIELDS)
728 #undef EXTERNAL_STRING_FIELDS 731 inline bool is_uncached()
const;
733 int ExternalPayloadSize()
const;
736 inline Address resource_as_address();
737 inline void set_address_as_resource(
Address address);
738 inline uint32_t resource_as_uint32();
739 inline void set_uint32_as_resource(
uint32_t value);
741 STATIC_ASSERT(kResourceOffset == Internals::kStringResourceOffset);
750 static const bool kHasOneByteEncoding =
true;
761 inline void set_resource(
const Resource* buffer);
767 inline void update_data_cache();
769 inline const uint8_t* GetChars();
772 inline uint16_t ExternalOneByteStringGet(
int index);
785 static const bool kHasOneByteEncoding =
false;
796 inline void set_resource(
const Resource* buffer);
802 inline void update_data_cache();
804 inline const uint16_t* GetChars();
807 inline uint16_t ExternalTwoByteStringGet(
int index);
810 inline const uint16_t* ExternalTwoByteStringGetData(
unsigned start);
826 void PostGarbageCollection()
override;
827 inline uc32 Get(
int index);
828 template <
typename Char>
829 inline Char Get(
int index);
830 int length() {
return length_; }
846 Reset(cons_string, offset);
848 inline void Reset(
ConsString cons_string,
int offset = 0) {
851 if (cons_string.is_null())
return;
852 Initialize(cons_string, offset);
855 inline String Next(
int* offset_out) {
857 if (depth_ == 0)
return String();
858 return Continue(offset_out);
862 static const int kStackSize = 32;
864 static const int kDepthMask = kStackSize - 1;
865 static_assert(base::bits::IsPowerOfTwo(kStackSize),
866 "kStackSize must be power of two");
867 static inline int OffsetForDepth(
int depth);
871 inline void AdjustMaximumDepth();
873 inline bool StackBlown() {
return maximum_depth_ - depth_ == kStackSize; }
874 void Initialize(
ConsString cons_string,
int offset);
875 String Continue(
int* offset_out);
876 String NextLeaf(
bool* blew_stack);
877 String Search(
int* offset_out);
892 inline uint16_t GetNext();
893 inline bool HasMore();
894 inline void Reset(
String string,
int offset = 0);
895 inline void VisitOneByteString(
const uint8_t* chars,
int length);
896 inline void VisitTwoByteString(
const uint16_t* chars,
int length);
902 const uint8_t* buffer8_;
903 const uint16_t* buffer16_;
912 #include "src/objects/object-macros-undef.h" 914 #endif // V8_OBJECTS_STRING_H_