Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/objects.h" | 5 #include "src/objects.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 #include <iomanip> | 8 #include <iomanip> |
| 9 #include <memory> | 9 #include <memory> |
| 10 #include <sstream> | 10 #include <sstream> |
| (...skipping 11618 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11629 start_index); | 11629 start_index); |
| 11630 } | 11630 } |
| 11631 Vector<const uc16> pat_vector = seq_pat.ToUC16Vector(); | 11631 Vector<const uc16> pat_vector = seq_pat.ToUC16Vector(); |
| 11632 if (seq_sub.IsOneByte()) { | 11632 if (seq_sub.IsOneByte()) { |
| 11633 return SearchString(isolate, seq_sub.ToOneByteVector(), pat_vector, | 11633 return SearchString(isolate, seq_sub.ToOneByteVector(), pat_vector, |
| 11634 start_index); | 11634 start_index); |
| 11635 } | 11635 } |
| 11636 return SearchString(isolate, seq_sub.ToUC16Vector(), pat_vector, start_index); | 11636 return SearchString(isolate, seq_sub.ToUC16Vector(), pat_vector, start_index); |
| 11637 } | 11637 } |
| 11638 | 11638 |
| 11639 namespace { // for String.Prototype.lastIndexOf | |
| 11640 | |
| 11641 template <typename schar, typename pchar> | |
| 11642 int StringMatchBackwards(Vector<const schar> subject, | |
| 11643 Vector<const pchar> pattern, int idx) { | |
| 11644 int pattern_length = pattern.length(); | |
| 11645 DCHECK(pattern_length >= 1); | |
| 11646 DCHECK(idx + pattern_length <= subject.length()); | |
| 11647 | |
| 11648 if (sizeof(schar) == 1 && sizeof(pchar) > 1) { | |
| 11649 for (int i = 0; i < pattern_length; i++) { | |
| 11650 uc16 c = pattern[i]; | |
| 11651 if (c > String::kMaxOneByteCharCode) { | |
| 11652 return -1; | |
| 11653 } | |
| 11654 } | |
| 11655 } | |
| 11656 | |
| 11657 pchar pattern_first_char = pattern[0]; | |
| 11658 for (int i = idx; i >= 0; i--) { | |
| 11659 if (subject[i] != pattern_first_char) continue; | |
| 11660 int j = 1; | |
| 11661 while (j < pattern_length) { | |
| 11662 if (pattern[j] != subject[i + j]) { | |
| 11663 break; | |
| 11664 } | |
| 11665 j++; | |
| 11666 } | |
| 11667 if (j == pattern_length) { | |
| 11668 return i; | |
| 11669 } | |
| 11670 } | |
| 11671 return -1; | |
| 11672 } | |
| 11673 | |
| 11674 } // namespace | |
| 11675 | |
| 11676 Object* String::LastIndexOf(Isolate* isolate, Handle<Object> receiver, | |
| 11677 Handle<Object> pattern, Handle<Object> position) { | |
| 11678 if (receiver->IsNull(isolate) || receiver->IsUndefined(isolate)) { | |
| 11679 THROW_NEW_ERROR_RETURN_FAILURE( | |
| 11680 isolate, NewTypeError(MessageTemplate::kCalledOnNullOrUndefined, | |
| 11681 isolate->factory()->NewStringFromAsciiChecked( | |
| 11682 "String.prototype.lastIndexOf"))); | |
| 11683 } | |
| 11684 Handle<String> sub; | |
|
Franzi
2016/09/19 08:04:21
Can we use a better name than sub?
| |
| 11685 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sub, | |
| 11686 Object::ToString(isolate, receiver)); | |
| 11687 | |
| 11688 Handle<String> pat; | |
| 11689 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, pat, | |
| 11690 Object::ToString(isolate, pattern)); | |
| 11691 | |
| 11692 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, position, | |
| 11693 Object::ToNumber(position)); | |
| 11694 | |
| 11695 uint32_t start_index; | |
| 11696 | |
| 11697 if (position->IsNaN()) { | |
| 11698 start_index = sub->length(); | |
| 11699 } else { | |
| 11700 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, position, | |
| 11701 Object::ToInteger(isolate, position)); | |
| 11702 | |
| 11703 double position_number = std::max(position->Number(), 0.0); | |
| 11704 position_number = | |
| 11705 std::min(position_number, static_cast<double>(sub->length())); | |
| 11706 start_index = static_cast<uint32_t>(position_number); | |
| 11707 } | |
| 11708 | |
| 11709 uint32_t pat_length = pat->length(); | |
| 11710 uint32_t sub_length = sub->length(); | |
| 11711 | |
| 11712 if (start_index + pat_length > sub_length) { | |
| 11713 start_index = sub_length - pat_length; | |
| 11714 } | |
| 11715 | |
| 11716 if (pat_length == 0) { | |
| 11717 return Smi::FromInt(start_index); | |
| 11718 } | |
| 11719 | |
| 11720 sub = String::Flatten(sub); | |
| 11721 pat = String::Flatten(pat); | |
| 11722 | |
| 11723 int last_index = -1; | |
| 11724 DisallowHeapAllocation no_gc; // ensure vectors stay valid | |
| 11725 | |
| 11726 String::FlatContent sub_content = sub->GetFlatContent(); | |
| 11727 String::FlatContent pat_content = pat->GetFlatContent(); | |
| 11728 | |
| 11729 if (pat_content.IsOneByte()) { | |
| 11730 Vector<const uint8_t> pat_vector = pat_content.ToOneByteVector(); | |
| 11731 if (sub_content.IsOneByte()) { | |
| 11732 last_index = StringMatchBackwards(sub_content.ToOneByteVector(), | |
| 11733 pat_vector, start_index); | |
| 11734 } else { | |
| 11735 last_index = StringMatchBackwards(sub_content.ToUC16Vector(), pat_vector, | |
| 11736 start_index); | |
| 11737 } | |
| 11738 } else { | |
| 11739 Vector<const uc16> pat_vector = pat_content.ToUC16Vector(); | |
| 11740 if (sub_content.IsOneByte()) { | |
| 11741 last_index = StringMatchBackwards(sub_content.ToOneByteVector(), | |
| 11742 pat_vector, start_index); | |
| 11743 } else { | |
| 11744 last_index = StringMatchBackwards(sub_content.ToUC16Vector(), pat_vector, | |
| 11745 start_index); | |
| 11746 } | |
| 11747 } | |
| 11748 return Smi::FromInt(last_index); | |
| 11749 } | |
| 11750 | |
| 11639 bool String::IsUtf8EqualTo(Vector<const char> str, bool allow_prefix_match) { | 11751 bool String::IsUtf8EqualTo(Vector<const char> str, bool allow_prefix_match) { |
| 11640 int slen = length(); | 11752 int slen = length(); |
| 11641 // Can't check exact length equality, but we can check bounds. | 11753 // Can't check exact length equality, but we can check bounds. |
| 11642 int str_len = str.length(); | 11754 int str_len = str.length(); |
| 11643 if (!allow_prefix_match && | 11755 if (!allow_prefix_match && |
| 11644 (str_len < slen || | 11756 (str_len < slen || |
| 11645 str_len > slen*static_cast<int>(unibrow::Utf8::kMaxEncodedSize))) { | 11757 str_len > slen*static_cast<int>(unibrow::Utf8::kMaxEncodedSize))) { |
| 11646 return false; | 11758 return false; |
| 11647 } | 11759 } |
| 11648 int i; | 11760 int i; |
| (...skipping 7816 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 19465 for (PrototypeIterator iter(isolate, this, kStartAtReceiver, | 19577 for (PrototypeIterator iter(isolate, this, kStartAtReceiver, |
| 19466 PrototypeIterator::END_AT_NULL); | 19578 PrototypeIterator::END_AT_NULL); |
| 19467 !iter.IsAtEnd(); iter.AdvanceIgnoringProxies()) { | 19579 !iter.IsAtEnd(); iter.AdvanceIgnoringProxies()) { |
| 19468 if (iter.GetCurrent<Object>()->IsJSProxy()) return true; | 19580 if (iter.GetCurrent<Object>()->IsJSProxy()) return true; |
| 19469 } | 19581 } |
| 19470 return false; | 19582 return false; |
| 19471 } | 19583 } |
| 19472 | 19584 |
| 19473 } // namespace internal | 19585 } // namespace internal |
| 19474 } // namespace v8 | 19586 } // namespace v8 |
| OLD | NEW |