Commit 5af6ec76 authored by petermarshall's avatar petermarshall Committed by Commit bot

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

BUG=v8:5364

Review-Url: https://codereview.chromium.org/2406873002
Cr-Commit-Position: refs/heads/master@{#40164}
parent 001926cd
......@@ -1437,6 +1437,8 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
1, true);
SimpleInstallFunction(prototype, "charCodeAt",
Builtins::kStringPrototypeCharCodeAt, 1, true);
SimpleInstallFunction(prototype, "endsWith",
Builtins::kStringPrototypeEndsWith, 1, false);
SimpleInstallFunction(prototype, "includes",
Builtins::kStringPrototypeIncludes, 1, false);
SimpleInstallFunction(prototype, "indexOf",
......
......@@ -781,6 +781,56 @@ void Builtins::Generate_StringPrototypeCharCodeAt(
assembler->Return(result);
}
// ES6 section 21.1.3.6
// String.prototype.endsWith ( searchString [ , endPosition ] )
BUILTIN(StringPrototypeEndsWith) {
HandleScope handle_scope(isolate);
TO_THIS_STRING(str, "String.prototype.endsWith");
// Check if the search string is a regExp and fail if it is.
Handle<Object> search = args.atOrUndefined(isolate, 1);
Maybe<bool> is_reg_exp = Object::IsRegExp(isolate, search);
if (is_reg_exp.IsNothing()) {
DCHECK(isolate->has_pending_exception());
return isolate->heap()->exception();
}
if (is_reg_exp.FromJust()) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kFirstArgumentNotRegExp,
isolate->factory()->NewStringFromStaticChars(
"String.prototype.endsWith")));
}
Handle<String> search_string;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, search_string,
Object::ToString(isolate, search));
Handle<Object> position = args.atOrUndefined(isolate, 2);
int end;
if (position->IsUndefined(isolate)) {
end = str->length();
} else {
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>(str->length()));
end = static_cast<uint32_t>(index);
}
int start = end - search_string->length();
if (start < 0) return *isolate->factory()->false_value();
FlatStringReader str_reader(isolate, String::Flatten(str));
FlatStringReader search_reader(isolate, String::Flatten(search_string));
for (int i = 0; i < search_string->length(); i++) {
if (str_reader.Get(start + i) != search_reader.Get(i)) {
return *isolate->factory()->false_value();
}
}
return *isolate->factory()->true_value();
}
// ES6 section 21.1.3.7
// String.prototype.includes ( searchString [ , position ] )
BUILTIN(StringPrototypeIncludes) {
......
......@@ -612,6 +612,9 @@ namespace internal {
TFJ(StringPrototypeCharAt, 2) \
/* ES6 section 21.1.3.2 String.prototype.charCodeAt ( pos ) */ \
TFJ(StringPrototypeCharCodeAt, 2) \
/* ES6 section 21.1.3.6 */ \
/* String.prototype.endsWith ( searchString [ , endPosition ] ) */ \
CPP(StringPrototypeEndsWith) \
/* ES6 section 21.1.3.7 */ \
/* String.prototype.includes ( searchString [ , position ] ) */ \
CPP(StringPrototypeIncludes) \
......
......@@ -406,33 +406,6 @@ function StringStartsWith(searchString, position) { // length == 1
%FunctionSetLength(StringStartsWith, 1);
// ES6 draft 04-05-14, section 21.1.3.7
function StringEndsWith(searchString, position) { // length == 1
CHECK_OBJECT_COERCIBLE(this, "String.prototype.endsWith");
var s = TO_STRING(this);
if (IsRegExp(searchString)) {
throw %make_type_error(kFirstArgumentNotRegExp, "String.prototype.endsWith");
}
var ss = TO_STRING(searchString);
var s_len = s.length;
var pos = !IS_UNDEFINED(position) ? TO_INTEGER(position) : s_len
var end = MinSimple(MaxSimple(pos, 0), s_len);
var ss_len = ss.length;
var start = end - ss_len;
if (start < 0) {
return false;
}
return %_SubString(s, start, start + ss_len) === ss;
}
%FunctionSetLength(StringEndsWith, 1);
// ES6 Draft 05-22-2014, section 21.1.3.3
function StringCodePointAt(pos) {
CHECK_OBJECT_COERCIBLE(this, "String.prototype.codePointAt");
......@@ -490,7 +463,6 @@ utils.InstallFunctions(GlobalString, DONT_ENUM, [
utils.InstallFunctions(GlobalString.prototype, DONT_ENUM, [
"codePointAt", StringCodePointAt,
"concat", StringConcat,
"endsWith", StringEndsWith,
"match", StringMatchJS,
"repeat", StringRepeat,
"replace", StringReplace,
......
......@@ -34,6 +34,7 @@ assertFalse(testString.endsWith("world"));
assertFalse(testString.endsWith("Hello World!"));
assertFalse(testString.endsWith(null));
assertFalse(testString.endsWith(undefined));
assertFalse(testString.endsWith());
assertTrue("null".endsWith(null));
assertTrue("undefined".endsWith(undefined));
......
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