diff options
Diffstat (limited to 'src/3rdparty/webkit/JavaScriptCore/runtime/StringPrototype.cpp')
-rw-r--r-- | src/3rdparty/webkit/JavaScriptCore/runtime/StringPrototype.cpp | 107 |
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 |