Commit 58529ed3 authored by petermarshall's avatar petermarshall Committed by Commit bot

[builtins] Move StringIndexOf to a C++ builtin.

BUG=v8:5364

Review-Url: https://codereview.chromium.org/2350963004
Cr-Commit-Position: refs/heads/master@{#40093}
parent 65b0b2d7
......@@ -1437,6 +1437,8 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
1, true);
SimpleInstallFunction(prototype, "charCodeAt",
Builtins::kStringPrototypeCharCodeAt, 1, true);
SimpleInstallFunction(prototype, "indexOf",
Builtins::kStringPrototypeIndexOf, 1, false);
SimpleInstallFunction(prototype, "lastIndexOf",
Builtins::kStringPrototypeLastIndexOf, 1, false);
SimpleInstallFunction(prototype, "localeCompare",
......
......@@ -781,6 +781,15 @@ void Builtins::Generate_StringPrototypeCharCodeAt(
assembler->Return(result);
}
// ES6 section 21.1.3.8 String.prototype.indexOf ( searchString [ , position ] )
BUILTIN(StringPrototypeIndexOf) {
HandleScope handle_scope(isolate);
return String::IndexOf(isolate, args.receiver(),
args.atOrUndefined(isolate, 1),
args.atOrUndefined(isolate, 2));
}
// ES6 section 21.1.3.9
// String.prototype.lastIndexOf ( searchString [ , position ] )
BUILTIN(StringPrototypeLastIndexOf) {
......
......@@ -604,6 +604,9 @@ namespace internal {
TFJ(StringPrototypeCharAt, 2) \
/* ES6 section 21.1.3.2 String.prototype.charCodeAt ( pos ) */ \
TFJ(StringPrototypeCharCodeAt, 2) \
/* ES6 section 21.1.3.8 */ \
/* String.prototype.indexOf ( searchString [ , position ] ) */ \
CPP(StringPrototypeIndexOf) \
/* ES6 section 21.1.3.9 */ \
/* String.prototype.lastIndexOf ( searchString [ , position ] ) */ \
CPP(StringPrototypeLastIndexOf) \
......
......@@ -33,7 +33,6 @@ var OverrideFunction = utils.OverrideFunction;
var patternSymbol = utils.ImportNow("intl_pattern_symbol");
var resolvedSymbol = utils.ImportNow("intl_resolved_symbol");
var SetFunctionName = utils.SetFunctionName;
var StringIndexOf;
var StringSubstr = GlobalString.prototype.substr;
var StringSubstring = GlobalString.prototype.substring;
......@@ -42,7 +41,6 @@ utils.Import(function(from) {
ArrayPush = from.ArrayPush;
InternalRegExpMatch = from.InternalRegExpMatch;
InternalRegExpReplace = from.InternalRegExpReplace;
StringIndexOf = from.StringIndexOf;
});
// Utilities for definitions
......@@ -827,7 +825,7 @@ function isStructuallyValidLanguageTag(locale) {
}
// Just return if it's a x- form. It's all private.
if (%_Call(StringIndexOf, locale, 'x-') === 0) {
if (%StringIndexOf(locale, 'x-', 0) === 0) {
return true;
}
......@@ -2058,7 +2056,7 @@ function LocaleConvertCase(s, locales, isToUpper) {
}
// StringSplit is slower than this.
var pos = %_Call(StringIndexOf, language, '-');
var pos = %StringIndexOf(language, '-', 0);
if (pos != -1) {
language = %_Call(StringSubstring, language, 0, pos);
}
......
......@@ -46,21 +46,6 @@ function StringConcat(other /* and more */) { // length == 1
}
// ECMA-262 section 15.5.4.7
function StringIndexOf(pattern, position) { // length == 1
CHECK_OBJECT_COERCIBLE(this, "String.prototype.indexOf");
var subject = TO_STRING(this);
pattern = TO_STRING(pattern);
var index = TO_INTEGER(position);
if (index < 0) index = 0;
if (index > subject.length) index = subject.length;
return %StringIndexOf(subject, pattern, index);
}
%FunctionSetLength(StringIndexOf, 1);
// ES6 21.1.3.11.
function StringMatchJS(pattern) {
CHECK_OBJECT_COERCIBLE(this, "String.prototype.match");
......@@ -535,7 +520,6 @@ utils.InstallFunctions(GlobalString.prototype, DONT_ENUM, [
"concat", StringConcat,
"endsWith", StringEndsWith,
"includes", StringIncludes,
"indexOf", StringIndexOf,
"match", StringMatchJS,
"repeat", StringRepeat,
"replace", StringReplace,
......@@ -567,7 +551,6 @@ utils.InstallFunctions(GlobalString.prototype, DONT_ENUM, [
// Exports
utils.Export(function(to) {
to.StringIndexOf = StringIndexOf;
to.StringMatch = StringMatchJS;
to.StringReplace = StringReplace;
to.StringSlice = StringSlice;
......
......@@ -11595,41 +11595,75 @@ ComparisonResult String::Compare(Handle<String> x, Handle<String> y) {
return result;
}
int String::IndexOf(Isolate* isolate, Handle<String> sub, Handle<String> pat,
int start_index) {
Object* String::IndexOf(Isolate* isolate, Handle<Object> receiver,
Handle<Object> search, Handle<Object> position) {
if (receiver->IsNull(isolate) || receiver->IsUndefined(isolate)) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kCalledOnNullOrUndefined,
isolate->factory()->NewStringFromAsciiChecked(
"String.prototype.indexOf")));
}
Handle<String> receiver_string;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver_string,
Object::ToString(isolate, receiver));
Handle<String> search_string;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, search_string,
Object::ToString(isolate, search));
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, position,
Object::ToInteger(isolate, position));
double index = std::max(position->Number(), 0.0);
index = std::min(index, static_cast<double>(receiver_string->length()));
return Smi::FromInt(String::IndexOf(isolate, receiver_string, search_string,
static_cast<uint32_t>(index)));
}
namespace {
template <typename T>
int SearchString(Isolate* isolate, String::FlatContent receiver_content,
Vector<T> pat_vector, int start_index) {
if (receiver_content.IsOneByte()) {
return SearchString(isolate, receiver_content.ToOneByteVector(), pat_vector,
start_index);
}
return SearchString(isolate, receiver_content.ToUC16Vector(), pat_vector,
start_index);
}
} // namespace
int String::IndexOf(Isolate* isolate, Handle<String> receiver,
Handle<String> search, int start_index) {
DCHECK(0 <= start_index);
DCHECK(start_index <= sub->length());
DCHECK(start_index <= receiver->length());
int pattern_length = pat->length();
if (pattern_length == 0) return start_index;
uint32_t search_length = search->length();
if (search_length == 0) return start_index;
int subject_length = sub->length();
if (start_index + pattern_length > subject_length) return -1;
uint32_t receiver_length = receiver->length();
if (start_index + search_length > receiver_length) return -1;
sub = String::Flatten(sub);
pat = String::Flatten(pat);
receiver = String::Flatten(receiver);
search = String::Flatten(search);
DisallowHeapAllocation no_gc; // ensure vectors stay valid
// Extract flattened substrings of cons strings before getting encoding.
String::FlatContent seq_sub = sub->GetFlatContent();
String::FlatContent seq_pat = pat->GetFlatContent();
String::FlatContent receiver_content = receiver->GetFlatContent();
String::FlatContent search_content = search->GetFlatContent();
// dispatch on type of strings
if (seq_pat.IsOneByte()) {
Vector<const uint8_t> pat_vector = seq_pat.ToOneByteVector();
if (seq_sub.IsOneByte()) {
return SearchString(isolate, seq_sub.ToOneByteVector(), pat_vector,
start_index);
}
return SearchString(isolate, seq_sub.ToUC16Vector(), pat_vector,
if (search_content.IsOneByte()) {
Vector<const uint8_t> pat_vector = search_content.ToOneByteVector();
return SearchString<const uint8_t>(isolate, receiver_content, pat_vector,
start_index);
}
Vector<const uc16> pat_vector = seq_pat.ToUC16Vector();
if (seq_sub.IsOneByte()) {
return SearchString(isolate, seq_sub.ToOneByteVector(), pat_vector,
Vector<const uc16> pat_vector = search_content.ToUC16Vector();
return SearchString<const uc16>(isolate, receiver_content, pat_vector,
start_index);
}
return SearchString(isolate, seq_sub.ToUC16Vector(), pat_vector, start_index);
}
namespace { // for String.Prototype.lastIndexOf
......
......@@ -9394,10 +9394,14 @@ class String: public Name {
MUST_USE_RESULT static ComparisonResult Compare(Handle<String> x,
Handle<String> y);
// Perform ES6 21.1.3.8, including checking arguments.
static Object* IndexOf(Isolate* isolate, Handle<Object> receiver,
Handle<Object> search, Handle<Object> position);
// Perform string match of pattern on subject, starting at start index.
// Caller must ensure that 0 <= start_index <= sub->length().
static int IndexOf(Isolate* isolate, Handle<String> sub, Handle<String> pat,
int start_index);
// Caller must ensure that 0 <= start_index <= sub->length(), as this does not
// check any arguments.
static int IndexOf(Isolate* isolate, Handle<String> receiver,
Handle<String> search, int start_index);
static Object* LastIndexOf(Isolate* isolate, Handle<Object> receiver,
Handle<Object> search, Handle<Object> position);
......
......@@ -90,17 +90,8 @@ RUNTIME_FUNCTION(Runtime_StringReplaceOneCharWithString) {
RUNTIME_FUNCTION(Runtime_StringIndexOf) {
HandleScope scope(isolate);
DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(String, sub, 0);
CONVERT_ARG_HANDLE_CHECKED(String, pat, 1);
CONVERT_ARG_HANDLE_CHECKED(Object, index, 2);
uint32_t start_index = 0;
if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1);
CHECK(start_index <= static_cast<uint32_t>(sub->length()));
int position = String::IndexOf(isolate, sub, pat, start_index);
return Smi::FromInt(position);
return String::IndexOf(isolate, args.at<Object>(0), args.at<Object>(1),
args.at<Object>(2));
}
RUNTIME_FUNCTION(Runtime_StringLastIndexOf) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment