Commit c3ffc92d authored by bmeurer's avatar bmeurer Committed by Commit bot

[builtins] Migrate String.prototype.trim/trimLeft/trimRight to C++.

These builtins do call into C++ anyways, so there's no point in keeping
the JavaScript wrappers for them.

R=franzih@chromium.org
BUG=v8:5049

Review-Url: https://codereview.chromium.org/2018963002
Cr-Commit-Position: refs/heads/master@{#36553}
parent 270a284f
......@@ -1340,6 +1340,12 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
1, true);
SimpleInstallFunction(prototype, "charCodeAt",
Builtins::kStringPrototypeCharCodeAt, 1, true);
SimpleInstallFunction(prototype, "trim", Builtins::kStringPrototypeTrim, 0,
false);
SimpleInstallFunction(prototype, "trimLeft",
Builtins::kStringPrototypeTrimLeft, 0, false);
SimpleInstallFunction(prototype, "trimRight",
Builtins::kStringPrototypeTrimRight, 0, false);
}
{
......
......@@ -179,6 +179,19 @@ BUILTIN_LIST_C(DEF_ARG_TYPE)
} \
Handle<Type> name = Handle<Type>::cast(args.receiver())
// Throws a TypeError for {method} if the receiver is not coercible to Object,
// or converts the receiver to a String otherwise and assigns it to a new var
// with the given {name}.
#define TO_THIS_STRING(name, method) \
if (args.receiver()->IsNull() || args.receiver()->IsUndefined()) { \
THROW_NEW_ERROR_RETURN_FAILURE( \
isolate, \
NewTypeError(MessageTemplate::kCalledOnNullOrUndefined, \
isolate->factory()->NewStringFromAsciiChecked(method))); \
} \
Handle<String> name; \
ASSIGN_RETURN_FAILURE_ON_EXCEPTION( \
isolate, name, Object::ToString(isolate, args.receiver()))
inline bool ClampedToInteger(Object* object, int* out) {
// This is an extended version of ECMA-262 7.1.11 handling signed values
......@@ -4541,6 +4554,27 @@ void Builtins::Generate_StringPrototypeCharCodeAt(
assembler->Return(result);
}
// ES6 section 21.1.3.25 String.prototype.trim ()
BUILTIN(StringPrototypeTrim) {
HandleScope scope(isolate);
TO_THIS_STRING(string, "String.prototype.trim");
return *String::Trim(string, String::kTrim);
}
// Non-standard WebKit extension
BUILTIN(StringPrototypeTrimLeft) {
HandleScope scope(isolate);
TO_THIS_STRING(string, "String.prototype.trimLeft");
return *String::Trim(string, String::kTrimLeft);
}
// Non-standard WebKit extension
BUILTIN(StringPrototypeTrimRight) {
HandleScope scope(isolate);
TO_THIS_STRING(string, "String.prototype.trimRight");
return *String::Trim(string, String::kTrimRight);
}
// -----------------------------------------------------------------------------
// ES6 section 21.1 ArrayBuffer Objects
......
......@@ -172,6 +172,9 @@ inline bool operator&(BuiltinExtraArguments lhs, BuiltinExtraArguments rhs) {
V(ReflectSetPrototypeOf, kNone) \
\
V(StringFromCharCode, kNone) \
V(StringPrototypeTrim, kNone) \
V(StringPrototypeTrimLeft, kNone) \
V(StringPrototypeTrimRight, kNone) \
\
V(SymbolConstructor, kNone) \
V(SymbolConstructor_ConstructStub, kTarget) \
......
......@@ -518,25 +518,6 @@ function StringToLocaleUpperCase() {
return %StringToUpperCase(TO_STRING(this));
}
// ES5, 15.5.4.20
function StringTrimJS() {
CHECK_OBJECT_COERCIBLE(this, "String.prototype.trim");
return %StringTrim(TO_STRING(this), true, true);
}
function StringTrimLeft() {
CHECK_OBJECT_COERCIBLE(this, "String.prototype.trimLeft");
return %StringTrim(TO_STRING(this), true, false);
}
function StringTrimRight() {
CHECK_OBJECT_COERCIBLE(this, "String.prototype.trimRight");
return %StringTrim(TO_STRING(this), false, true);
}
// ES6 draft, revision 26 (2014-07-18), section B.2.3.2.1
function HtmlEscape(str) {
......@@ -850,9 +831,6 @@ utils.InstallFunctions(GlobalString.prototype, DONT_ENUM, [
"toLocaleLowerCase", StringToLocaleLowerCase,
"toUpperCase", StringToUpperCaseJS,
"toLocaleUpperCase", StringToLocaleUpperCase,
"trim", StringTrimJS,
"trimLeft", StringTrimLeft,
"trimRight", StringTrimRight,
"link", StringLink,
"anchor", StringAnchor,
......
......@@ -9981,6 +9981,34 @@ bool DescriptorArray::IsEqualTo(DescriptorArray* other) {
}
#endif
// static
Handle<String> String::Trim(Handle<String> string, TrimMode mode) {
Isolate* const isolate = string->GetIsolate();
string = String::Flatten(string);
int const length = string->length();
// Perform left trimming if requested.
int left = 0;
UnicodeCache* unicode_cache = isolate->unicode_cache();
if (mode == kTrim || mode == kTrimLeft) {
while (left < length &&
unicode_cache->IsWhiteSpaceOrLineTerminator(string->Get(left))) {
left++;
}
}
// Perform right trimming if requested.
int right = length;
if (mode == kTrim || mode == kTrimRight) {
while (
right > left &&
unicode_cache->IsWhiteSpaceOrLineTerminator(string->Get(right - 1))) {
right--;
}
}
return isolate->factory()->NewSubString(string, left, right);
}
bool String::LooksValid() {
if (!GetIsolate()->heap()->Contains(this)) return false;
......
......@@ -8861,6 +8861,10 @@ class String: public Name {
// Conversion.
inline bool AsArrayIndex(uint32_t* index);
// Trimming.
enum TrimMode { kTrim, kTrimLeft, kTrimRight };
static Handle<String> Trim(Handle<String> string, TrimMode mode);
DECLARE_CAST(String)
void PrintOn(FILE* out);
......
......@@ -1088,39 +1088,6 @@ RUNTIME_FUNCTION(Runtime_StringToUpperCase) {
return ConvertCase(s, isolate, isolate->runtime_state()->to_upper_mapping());
}
RUNTIME_FUNCTION(Runtime_StringTrim) {
HandleScope scope(isolate);
DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
CONVERT_BOOLEAN_ARG_CHECKED(trimLeft, 1);
CONVERT_BOOLEAN_ARG_CHECKED(trimRight, 2);
string = String::Flatten(string);
int length = string->length();
int left = 0;
UnicodeCache* unicode_cache = isolate->unicode_cache();
if (trimLeft) {
while (left < length &&
unicode_cache->IsWhiteSpaceOrLineTerminator(string->Get(left))) {
left++;
}
}
int right = length;
if (trimRight) {
while (
right > left &&
unicode_cache->IsWhiteSpaceOrLineTerminator(string->Get(right - 1))) {
right--;
}
}
return *isolate->factory()->NewSubString(string, left, right);
}
RUNTIME_FUNCTION(Runtime_StringLessThan) {
HandleScope handle_scope(isolate);
DCHECK_EQ(2, args.length());
......
......@@ -831,7 +831,6 @@ namespace internal {
F(StringToArray, 2, 1) \
F(StringToLowerCase, 1, 1) \
F(StringToUpperCase, 1, 1) \
F(StringTrim, 3, 1) \
F(StringLessThan, 2, 1) \
F(StringLessThanOrEqual, 2, 1) \
F(StringGreaterThan, 2, 1) \
......
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