• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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