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 #include "src/objects/string-comparator.h"
6
7 #include "src/objects/string-inl.h"
8
9 namespace v8 {
10 namespace internal {
11
Init(String string,const SharedStringAccessGuardIfNeeded & access_guard)12 void StringComparator::State::Init(
13 String string, const SharedStringAccessGuardIfNeeded& access_guard) {
14 ConsString cons_string = String::VisitFlat(this, string, 0, access_guard);
15 iter_.Reset(cons_string);
16 if (!cons_string.is_null()) {
17 int offset;
18 string = iter_.Next(&offset);
19 String::VisitFlat(this, string, offset, access_guard);
20 }
21 }
22
Advance(int consumed,const SharedStringAccessGuardIfNeeded & access_guard)23 void StringComparator::State::Advance(
24 int consumed, const SharedStringAccessGuardIfNeeded& access_guard) {
25 DCHECK(consumed <= length_);
26 // Still in buffer.
27 if (length_ != consumed) {
28 if (is_one_byte_) {
29 buffer8_ += consumed;
30 } else {
31 buffer16_ += consumed;
32 }
33 length_ -= consumed;
34 return;
35 }
36 // Advance state.
37 int offset;
38 String next = iter_.Next(&offset);
39 DCHECK_EQ(0, offset);
40 DCHECK(!next.is_null());
41 String::VisitFlat(this, next, 0, access_guard);
42 }
43
Equals(String string_1,String string_2,const SharedStringAccessGuardIfNeeded & access_guard)44 bool StringComparator::Equals(
45 String string_1, String string_2,
46 const SharedStringAccessGuardIfNeeded& access_guard) {
47 int length = string_1.length();
48 state_1_.Init(string_1, access_guard);
49 state_2_.Init(string_2, access_guard);
50 while (true) {
51 int to_check = std::min(state_1_.length_, state_2_.length_);
52 DCHECK(to_check > 0 && to_check <= length);
53 bool is_equal;
54 if (state_1_.is_one_byte_) {
55 if (state_2_.is_one_byte_) {
56 is_equal = Equals<uint8_t, uint8_t>(&state_1_, &state_2_, to_check);
57 } else {
58 is_equal = Equals<uint8_t, uint16_t>(&state_1_, &state_2_, to_check);
59 }
60 } else {
61 if (state_2_.is_one_byte_) {
62 is_equal = Equals<uint16_t, uint8_t>(&state_1_, &state_2_, to_check);
63 } else {
64 is_equal = Equals<uint16_t, uint16_t>(&state_1_, &state_2_, to_check);
65 }
66 }
67 // Looping done.
68 if (!is_equal) return false;
69 length -= to_check;
70 // Exit condition. Strings are equal.
71 if (length == 0) return true;
72 state_1_.Advance(to_check, access_guard);
73 state_2_.Advance(to_check, access_guard);
74 }
75 }
76
77 } // namespace internal
78 } // namespace v8
79