| // Copyright 2019 the V8 project authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "src/objects/string-comparator.h" |
| |
| #include "src/objects/string-inl.h" |
| |
| namespace v8 { |
| namespace internal { |
| |
| void StringComparator::State::Init(String string) { |
| ConsString cons_string = String::VisitFlat(this, string); |
| iter_.Reset(cons_string); |
| if (!cons_string.is_null()) { |
| int offset; |
| string = iter_.Next(&offset); |
| String::VisitFlat(this, string, offset); |
| } |
| } |
| |
| void StringComparator::State::Advance(int consumed) { |
| DCHECK(consumed <= length_); |
| // Still in buffer. |
| if (length_ != consumed) { |
| if (is_one_byte_) { |
| buffer8_ += consumed; |
| } else { |
| buffer16_ += consumed; |
| } |
| length_ -= consumed; |
| return; |
| } |
| // Advance state. |
| int offset; |
| String next = iter_.Next(&offset); |
| DCHECK_EQ(0, offset); |
| DCHECK(!next.is_null()); |
| String::VisitFlat(this, next); |
| } |
| |
| bool StringComparator::Equals(String string_1, String string_2) { |
| int length = string_1.length(); |
| state_1_.Init(string_1); |
| state_2_.Init(string_2); |
| while (true) { |
| int to_check = std::min(state_1_.length_, state_2_.length_); |
| DCHECK(to_check > 0 && to_check <= length); |
| bool is_equal; |
| if (state_1_.is_one_byte_) { |
| if (state_2_.is_one_byte_) { |
| is_equal = Equals<uint8_t, uint8_t>(&state_1_, &state_2_, to_check); |
| } else { |
| is_equal = Equals<uint8_t, uint16_t>(&state_1_, &state_2_, to_check); |
| } |
| } else { |
| if (state_2_.is_one_byte_) { |
| is_equal = Equals<uint16_t, uint8_t>(&state_1_, &state_2_, to_check); |
| } else { |
| is_equal = Equals<uint16_t, uint16_t>(&state_1_, &state_2_, to_check); |
| } |
| } |
| // Looping done. |
| if (!is_equal) return false; |
| length -= to_check; |
| // Exit condition. Strings are equal. |
| if (length == 0) return true; |
| state_1_.Advance(to_check); |
| state_2_.Advance(to_check); |
| } |
| } |
| |
| } // namespace internal |
| } // namespace v8 |