summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/webkit/JavaScriptCore/runtime/StringPrototype.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/webkit/JavaScriptCore/runtime/StringPrototype.cpp')
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/runtime/StringPrototype.cpp107
1 files changed, 87 insertions, 20 deletions
diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/StringPrototype.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/StringPrototype.cpp
index ceb6b1ea2..a0cc9f149 100644
--- a/src/3rdparty/webkit/JavaScriptCore/runtime/StringPrototype.cpp
+++ b/src/3rdparty/webkit/JavaScriptCore/runtime/StringPrototype.cpp
@@ -23,6 +23,9 @@
#include "StringPrototype.h"
#include "CachedCall.h"
+#include "Error.h"
+#include "Executable.h"
+#include "JSGlobalObjectFunctions.h"
#include "JSArray.h"
#include "JSFunction.h"
#include "ObjectPrototype.h"
@@ -70,6 +73,10 @@ static JSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState*, JSObject*, JSVa
static JSValue JSC_HOST_CALL stringProtoFuncAnchor(ExecState*, JSObject*, JSValue, const ArgList&);
static JSValue JSC_HOST_CALL stringProtoFuncLink(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncTrim(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncTrimLeft(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncTrimRight(ExecState*, JSObject*, JSValue, const ArgList&);
+
}
#include "StringPrototype.lut.h"
@@ -115,11 +122,14 @@ const ClassInfo StringPrototype::info = { "String", &StringObject::info, 0, Exec
fontsize stringProtoFuncFontsize DontEnum|Function 1
anchor stringProtoFuncAnchor DontEnum|Function 1
link stringProtoFuncLink DontEnum|Function 1
+ trim stringProtoFuncTrim DontEnum|Function 0
+ trimLeft stringProtoFuncTrimLeft DontEnum|Function 0
+ trimRight stringProtoFuncTrimRight DontEnum|Function 0
@end
*/
// ECMA 15.5.4
-StringPrototype::StringPrototype(ExecState* exec, PassRefPtr<Structure> structure)
+StringPrototype::StringPrototype(ExecState* exec, NonNullPassRefPtr<Structure> structure)
: StringObject(exec, structure)
{
// The constructor will be added later, after StringConstructor has been built
@@ -131,6 +141,11 @@ bool StringPrototype::getOwnPropertySlot(ExecState* exec, const Identifier& prop
return getStaticFunctionSlot<StringObject>(exec, ExecState::stringTable(exec), this, propertyName, slot);
}
+bool StringPrototype::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
+{
+ return getStaticFunctionDescriptor<StringObject>(exec, ExecState::stringTable(exec), this, propertyName, descriptor);
+}
+
// ------------------------------ Functions --------------------------
static inline UString substituteBackreferences(const UString& replacement, const UString& source, const int* ovector, RegExp* reg)
@@ -220,7 +235,7 @@ JSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue
if (callType == CallTypeNone)
replacementString = replacement.toString(exec);
- if (pattern.isObject(&RegExpObject::info)) {
+ if (pattern.inherits(&RegExpObject::info)) {
RegExp* reg = asRegExpObject(pattern)->regExp();
bool global = reg->global();
@@ -242,7 +257,7 @@ JSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue
return jsNull();
while (true) {
int matchIndex;
- int matchLen;
+ int matchLen = 0;
int* ovector;
regExpConstructor->performMatch(reg, source, startPosition, matchIndex, matchLen, &ovector);
if (matchIndex < 0)
@@ -283,7 +298,7 @@ JSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue
} else {
do {
int matchIndex;
- int matchLen;
+ int matchLen = 0;
int* ovector;
regExpConstructor->performMatch(reg, source, startPosition, matchIndex, matchLen, &ovector);
if (matchIndex < 0)
@@ -365,7 +380,7 @@ JSValue JSC_HOST_CALL stringProtoFuncToString(ExecState* exec, JSObject*, JSValu
if (thisValue.isString())
return thisValue;
- if (thisValue.isObject(&StringObject::info))
+ if (thisValue.inherits(&StringObject::info))
return asStringObject(thisValue)->internalValue();
return throwError(exec, TypeError);
@@ -376,8 +391,8 @@ JSValue JSC_HOST_CALL stringProtoFuncCharAt(ExecState* exec, JSObject*, JSValue
UString s = thisValue.toThisString(exec);
unsigned len = s.size();
JSValue a0 = args.at(0);
- if (a0.isUInt32Fast()) {
- uint32_t i = a0.getUInt32Fast();
+ if (a0.isUInt32()) {
+ uint32_t i = a0.asUInt32();
if (i < len)
return jsSingleCharacterSubstring(exec, s, i);
return jsEmptyString(exec);
@@ -393,8 +408,8 @@ JSValue JSC_HOST_CALL stringProtoFuncCharCodeAt(ExecState* exec, JSObject*, JSVa
UString s = thisValue.toThisString(exec);
unsigned len = s.size();
JSValue a0 = args.at(0);
- if (a0.isUInt32Fast()) {
- uint32_t i = a0.getUInt32Fast();
+ if (a0.isUInt32()) {
+ uint32_t i = a0.asUInt32();
if (i < len)
return jsNumber(exec, s.data()[i]);
return jsNaN(exec);
@@ -426,8 +441,8 @@ JSValue JSC_HOST_CALL stringProtoFuncIndexOf(ExecState* exec, JSObject*, JSValue
int pos;
if (a1.isUndefined())
pos = 0;
- else if (a1.isUInt32Fast())
- pos = min<uint32_t>(a1.getUInt32Fast(), len);
+ else if (a1.isUInt32())
+ pos = min<uint32_t>(a1.asUInt32(), len);
else {
double dpos = a1.toInteger(exec);
if (dpos < 0)
@@ -454,6 +469,11 @@ JSValue JSC_HOST_CALL stringProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSV
dpos = 0;
else if (!(dpos <= len)) // true for NaN
dpos = len;
+#if PLATFORM(SYMBIAN)
+ // Work around for broken NaN compare operator
+ else if (isnan(dpos))
+ dpos = len;
+#endif
return jsNumber(exec, s.rfind(u2, static_cast<int>(dpos)));
}
@@ -466,7 +486,7 @@ JSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec, JSObject*, JSValue t
UString u = s;
RefPtr<RegExp> reg;
RegExpObject* imp = 0;
- if (a0.isObject(&RegExpObject::info))
+ if (a0.inherits(&RegExpObject::info))
reg = asRegExpObject(a0)->regExp();
else {
/*
@@ -478,7 +498,7 @@ JSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec, JSObject*, JSValue t
}
RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
int pos;
- int matchLength;
+ int matchLength = 0;
regExpConstructor->performMatch(reg.get(), u, 0, pos, matchLength);
if (!(reg->global())) {
// case without 'g' flag is handled like RegExp.prototype.exec
@@ -516,7 +536,7 @@ JSValue JSC_HOST_CALL stringProtoFuncSearch(ExecState* exec, JSObject*, JSValue
UString u = s;
RefPtr<RegExp> reg;
- if (a0.isObject(&RegExpObject::info))
+ if (a0.inherits(&RegExpObject::info))
reg = asRegExpObject(a0)->regExp();
else {
/*
@@ -528,7 +548,7 @@ JSValue JSC_HOST_CALL stringProtoFuncSearch(ExecState* exec, JSObject*, JSValue
}
RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
int pos;
- int matchLength;
+ int matchLength = 0;
regExpConstructor->performMatch(reg.get(), u, 0, pos, matchLength);
return jsNumber(exec, pos);
}
@@ -568,7 +588,7 @@ JSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec, JSObject*, JSValue t
unsigned i = 0;
int p0 = 0;
unsigned limit = a1.isUndefined() ? 0xFFFFFFFFU : a1.toUInt32(exec);
- if (a0.isObject(&RegExpObject::info)) {
+ if (a0.inherits(&RegExpObject::info)) {
RegExp* reg = asRegExpObject(a0)->regExp();
if (s.isEmpty() && reg->match(s, 0) >= 0) {
// empty string matched by regexp -> empty array
@@ -821,8 +841,8 @@ JSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState* exec, JSObject*, JSValu
if (a0.getUInt32(smallInteger) && smallInteger <= 9) {
unsigned stringSize = s.size();
unsigned bufferSize = 22 + stringSize;
- UChar* buffer = static_cast<UChar*>(tryFastMalloc(bufferSize * sizeof(UChar)));
- if (!buffer)
+ UChar* buffer;
+ if (!tryFastMalloc(bufferSize * sizeof(UChar)).getValue(buffer))
return jsUndefined();
buffer[0] = '<';
buffer[1] = 'f';
@@ -869,8 +889,8 @@ JSValue JSC_HOST_CALL stringProtoFuncLink(ExecState* exec, JSObject*, JSValue th
unsigned linkTextSize = linkText.size();
unsigned stringSize = s.size();
unsigned bufferSize = 15 + linkTextSize + stringSize;
- UChar* buffer = static_cast<UChar*>(tryFastMalloc(bufferSize * sizeof(UChar)));
- if (!buffer)
+ UChar* buffer;
+ if (!tryFastMalloc(bufferSize * sizeof(UChar)).getValue(buffer))
return jsUndefined();
buffer[0] = '<';
buffer[1] = 'a';
@@ -892,4 +912,51 @@ JSValue JSC_HOST_CALL stringProtoFuncLink(ExecState* exec, JSObject*, JSValue th
return jsNontrivialString(exec, UString(buffer, bufferSize, false));
}
+enum {
+ TrimLeft = 1,
+ TrimRight = 2
+};
+
+static inline bool isTrimWhitespace(UChar c)
+{
+ return isStrWhiteSpace(c) || c == 0x200b;
+}
+
+static inline JSValue trimString(ExecState* exec, JSValue thisValue, int trimKind)
+{
+ UString str = thisValue.toThisString(exec);
+ int left = 0;
+ if (trimKind & TrimLeft) {
+ while (left < str.size() && isTrimWhitespace(str[left]))
+ left++;
+ }
+ int right = str.size();
+ if (trimKind & TrimRight) {
+ while (right > left && isTrimWhitespace(str[right - 1]))
+ right--;
+ }
+
+ // Don't gc allocate a new string if we don't have to.
+ if (left == 0 && right == str.size() && thisValue.isString())
+ return thisValue;
+
+ return jsString(exec, str.substr(left, right - left));
+}
+
+JSValue JSC_HOST_CALL stringProtoFuncTrim(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
+{
+ return trimString(exec, thisValue, TrimLeft | TrimRight);
+}
+
+JSValue JSC_HOST_CALL stringProtoFuncTrimLeft(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
+{
+ return trimString(exec, thisValue, TrimLeft);
+}
+
+JSValue JSC_HOST_CALL stringProtoFuncTrimRight(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
+{
+ return trimString(exec, thisValue, TrimRight);
+}
+
+
} // namespace JSC