Commit 0e788e32 authored by mvstanton's avatar mvstanton Committed by Commit bot

[builtins] String.prototype.slice as a CSA builtin.

BUG=v8:6370

Review-Url: https://codereview.chromium.org/2870013004
Cr-Commit-Position: refs/heads/master@{#45275}
parent 752bdcbf
......@@ -1810,6 +1810,8 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
#endif // V8_INTL_SUPPORT
SimpleInstallFunction(prototype, "replace",
Builtins::kStringPrototypeReplace, 2, true);
SimpleInstallFunction(prototype, "slice", Builtins::kStringPrototypeSlice,
2, false);
SimpleInstallFunction(prototype, "split", Builtins::kStringPrototypeSplit,
2, true);
SimpleInstallFunction(prototype, "substr", Builtins::kStringPrototypeSubstr,
......
......@@ -853,6 +853,8 @@ namespace internal {
CPP(StringPrototypeLocaleCompare) \
/* ES6 #sec-string.prototype.replace */ \
TFJ(StringPrototypeReplace, 2, kSearch, kReplace) \
/* ES6 #sec-string.prototype.slice */ \
TFJ(StringPrototypeSlice, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* ES6 #sec-string.prototype.split */ \
TFJ(StringPrototypeSplit, 2, kSeparator, kLimit) \
/* ES6 #sec-string.prototype.substr */ \
......
This diff is collapsed.
......@@ -3548,7 +3548,9 @@ Node* AllocAndCopyStringCharacters(CodeStubAssembler* a, Node* context,
} // namespace
Node* CodeStubAssembler::SubString(Node* context, Node* string, Node* from,
Node* to) {
Node* to, SubStringFlags flags) {
DCHECK(flags == SubStringFlags::NONE ||
flags == SubStringFlags::FROM_TO_ARE_BOUNDED);
VARIABLE(var_result, MachineRepresentation::kTagged);
ToDirectStringAssembler to_direct(state(), string);
Label end(this), runtime(this);
......@@ -3559,8 +3561,13 @@ Node* CodeStubAssembler::SubString(Node* context, Node* string, Node* from,
// Make sure that both from and to are non-negative smis.
GotoIfNot(TaggedIsPositiveSmi(from), &runtime);
GotoIfNot(TaggedIsPositiveSmi(to), &runtime);
if (flags == SubStringFlags::NONE) {
GotoIfNot(TaggedIsPositiveSmi(from), &runtime);
GotoIfNot(TaggedIsPositiveSmi(to), &runtime);
} else {
CSA_ASSERT(this, TaggedIsPositiveSmi(from));
CSA_ASSERT(this, TaggedIsPositiveSmi(to));
}
Node* const substr_length = SmiSub(to, from);
Node* const string_length = LoadStringLength(string);
......@@ -3661,8 +3668,14 @@ Node* CodeStubAssembler::SubString(Node* context, Node* string, Node* from,
BIND(&original_string_or_invalid_length);
{
// Longer than original string's length or negative: unsafe arguments.
GotoIf(SmiAbove(substr_length, string_length), &runtime);
if (flags == SubStringFlags::NONE) {
// Longer than original string's length or negative: unsafe arguments.
GotoIf(SmiAbove(substr_length, string_length), &runtime);
} else {
// with flag SubStringFlags::FROM_TO_ARE_BOUNDED, the only way we can
// get here is if substr_length is equal to string_length.
CSA_ASSERT(this, SmiEqual(substr_length, string_length));
}
// Equal length - check if {from, to} == {0, str.length}.
GotoIf(SmiAbove(from, SmiConstant(Smi::kZero)), &runtime);
......
......@@ -805,9 +805,15 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
ParameterMode parameter_mode = SMI_PARAMETERS);
// Return the single character string with only {code}.
Node* StringFromCharCode(Node* code);
enum class SubStringFlags { NONE, FROM_TO_ARE_BOUNDED };
// Return a new string object which holds a substring containing the range
// [from,to[ of string. |from| and |to| are expected to be tagged.
Node* SubString(Node* context, Node* string, Node* from, Node* to);
// If flags has the value FROM_TO_ARE_BOUNDED then from and to are in
// the range [0, string-length)
Node* SubString(Node* context, Node* string, Node* from, Node* to,
SubStringFlags flags = SubStringFlags::NONE);
// Return a new string object produced by concatenating |first| with |second|.
Node* StringAdd(Node* context, Node* first, Node* second,
......
......@@ -584,6 +584,7 @@ bool BuiltinHasNoSideEffect(Builtins::Name id) {
case Builtins::kStringPrototypeIncludes:
case Builtins::kStringPrototypeIndexOf:
case Builtins::kStringPrototypeLastIndexOf:
case Builtins::kStringPrototypeSlice:
case Builtins::kStringPrototypeStartsWith:
case Builtins::kStringPrototypeSubstr:
case Builtins::kStringPrototypeSubstring:
......
......@@ -52,48 +52,6 @@ function StringSearch(pattern) {
}
// ECMA-262 section 15.5.4.13
function StringSlice(start, end) {
CHECK_OBJECT_COERCIBLE(this, "String.prototype.slice");
var s = TO_STRING(this);
var s_len = s.length;
var start_i = TO_INTEGER(start);
var end_i = s_len;
if (!IS_UNDEFINED(end)) {
end_i = TO_INTEGER(end);
}
if (start_i < 0) {
start_i += s_len;
if (start_i < 0) {
start_i = 0;
}
} else {
if (start_i > s_len) {
return '';
}
}
if (end_i < 0) {
end_i += s_len;
if (end_i < 0) {
return '';
}
} else {
if (end_i > s_len) {
end_i = s_len;
}
}
if (end_i <= start_i) {
return '';
}
return %_SubString(s, start_i, end_i);
}
// ES6 draft, revision 26 (2014-07-18), section B.2.3.2.1
function HtmlEscape(str) {
return %RegExpInternalReplace(/"/g, TO_STRING(str), "&quot;");
......@@ -334,8 +292,6 @@ utils.InstallFunctions(GlobalString.prototype, DONT_ENUM, [
"padStart", StringPadStart,
"repeat", StringRepeat,
"search", StringSearch,
"slice", StringSlice,
"link", StringLink,
"anchor", StringAnchor,
"fontcolor", StringFontcolor,
......
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