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...) 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...) 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 |