Chromium Code Reviews

Side by Side Diff: src/objects.cc

Issue 2339123002: [builtins] Move StringLastIndexOf to a builtin. (Closed)
Patch Set: Test natives callable from extensions with str compare instead Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
OLDNEW
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...)
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...)
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
OLDNEW
« src/objects.h ('K') | « src/objects.h ('k') | src/runtime/runtime.h » ('j') | no next file with comments »

Powered by Google App Engine