1 | // Copyright 2019 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_OBJECTS_STRING_COMPARATOR_H_ |
6 | #define V8_OBJECTS_STRING_COMPARATOR_H_ |
7 | |
8 | #include "src/base/logging.h" |
9 | #include "src/globals.h" |
10 | #include "src/objects/string.h" |
11 | #include "src/utils.h" |
12 | |
13 | namespace v8 { |
14 | namespace internal { |
15 | |
16 | // Compares the contents of two strings by reading and comparing |
17 | // int-sized blocks of characters. |
18 | template <typename Char> |
19 | static inline bool CompareRawStringContents(const Char* const a, |
20 | const Char* const b, int length) { |
21 | return CompareChars(a, b, length) == 0; |
22 | } |
23 | |
24 | template <typename Chars1, typename Chars2> |
25 | class RawStringComparator : public AllStatic { |
26 | public: |
27 | static inline bool compare(const Chars1* a, const Chars2* b, int len) { |
28 | DCHECK(sizeof(Chars1) != sizeof(Chars2)); |
29 | for (int i = 0; i < len; i++) { |
30 | if (a[i] != b[i]) { |
31 | return false; |
32 | } |
33 | } |
34 | return true; |
35 | } |
36 | }; |
37 | |
38 | template <> |
39 | class RawStringComparator<uint16_t, uint16_t> { |
40 | public: |
41 | static inline bool compare(const uint16_t* a, const uint16_t* b, int len) { |
42 | return CompareRawStringContents(a, b, len); |
43 | } |
44 | }; |
45 | |
46 | template <> |
47 | class RawStringComparator<uint8_t, uint8_t> { |
48 | public: |
49 | static inline bool compare(const uint8_t* a, const uint8_t* b, int len) { |
50 | return CompareRawStringContents(a, b, len); |
51 | } |
52 | }; |
53 | |
54 | class StringComparator { |
55 | class State { |
56 | public: |
57 | State() : is_one_byte_(true), length_(0), buffer8_(nullptr) {} |
58 | |
59 | void Init(String string); |
60 | |
61 | inline void VisitOneByteString(const uint8_t* chars, int length) { |
62 | is_one_byte_ = true; |
63 | buffer8_ = chars; |
64 | length_ = length; |
65 | } |
66 | |
67 | inline void VisitTwoByteString(const uint16_t* chars, int length) { |
68 | is_one_byte_ = false; |
69 | buffer16_ = chars; |
70 | length_ = length; |
71 | } |
72 | |
73 | void Advance(int consumed); |
74 | |
75 | ConsStringIterator iter_; |
76 | bool is_one_byte_; |
77 | int length_; |
78 | union { |
79 | const uint8_t* buffer8_; |
80 | const uint16_t* buffer16_; |
81 | }; |
82 | |
83 | private: |
84 | DISALLOW_COPY_AND_ASSIGN(State); |
85 | }; |
86 | |
87 | public: |
88 | inline StringComparator() = default; |
89 | |
90 | template <typename Chars1, typename Chars2> |
91 | static inline bool Equals(State* state_1, State* state_2, int to_check) { |
92 | const Chars1* a = reinterpret_cast<const Chars1*>(state_1->buffer8_); |
93 | const Chars2* b = reinterpret_cast<const Chars2*>(state_2->buffer8_); |
94 | return RawStringComparator<Chars1, Chars2>::compare(a, b, to_check); |
95 | } |
96 | |
97 | bool Equals(String string_1, String string_2); |
98 | |
99 | private: |
100 | State state_1_; |
101 | State state_2_; |
102 | |
103 | DISALLOW_COPY_AND_ASSIGN(StringComparator); |
104 | }; |
105 | |
106 | } // namespace internal |
107 | } // namespace v8 |
108 | |
109 | #endif // V8_OBJECTS_STRING_COMPARATOR_H_ |
110 | |