📄 stringprototype.cpp
字号:
return sourceVal; return jsString(exec, result); } // First arg is a string UString patternString = pattern.toString(exec); int matchPos = source.find(patternString); int matchLen = patternString.size(); // Do the replacement if (matchPos == -1) return sourceVal; if (callType != CallTypeNone) { ArgList args; args.append(jsSubstring(exec, source, matchPos, matchLen)); args.append(jsNumber(exec, matchPos)); args.append(sourceVal); replacementString = call(exec, replacement, callType, callData, exec->globalThisValue(), args).toString(exec); } int ovector[2] = { matchPos, matchPos + matchLen }; return jsString(exec, source.substr(0, matchPos) + substituteBackreferences(replacementString, source, ovector, 0) + source.substr(matchPos + matchLen));}JSValuePtr stringProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&){ // Also used for valueOf. if (thisValue.isString()) return thisValue; if (thisValue.isObject(&StringObject::info)) return asStringObject(thisValue)->internalValue(); return throwError(exec, TypeError);}JSValuePtr stringProtoFuncCharAt(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args){ UString s = thisValue.toThisString(exec); unsigned len = s.size(); JSValuePtr a0 = args.at(exec, 0); if (a0.isUInt32Fast()) { uint32_t i = a0.getUInt32Fast(); if (i < len) return jsSingleCharacterSubstring(exec, s, i); return jsEmptyString(exec); } double dpos = a0.toInteger(exec); if (dpos >= 0 && dpos < len) return jsSingleCharacterSubstring(exec, s, static_cast<unsigned>(dpos)); return jsEmptyString(exec);}JSValuePtr stringProtoFuncCharCodeAt(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args){ UString s = thisValue.toThisString(exec); unsigned len = s.size(); JSValuePtr a0 = args.at(exec, 0); if (a0.isUInt32Fast()) { uint32_t i = a0.getUInt32Fast(); if (i < len) return jsNumber(exec, s.data()[i]); return jsNaN(exec); } double dpos = a0.toInteger(exec); if (dpos >= 0 && dpos < len) return jsNumber(exec, s[static_cast<int>(dpos)]); return jsNaN(exec);}JSValuePtr stringProtoFuncConcat(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args){ UString s = thisValue.toThisString(exec); ArgList::const_iterator end = args.end(); for (ArgList::const_iterator it = args.begin(); it != end; ++it) s += (*it).jsValue(exec).toString(exec); return jsString(exec, s);}JSValuePtr stringProtoFuncIndexOf(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args){ UString s = thisValue.toThisString(exec); int len = s.size(); JSValuePtr a0 = args.at(exec, 0); JSValuePtr a1 = args.at(exec, 1); UString u2 = a0.toString(exec); int pos; if (a1.isUndefined()) pos = 0; else if (a1.isUInt32Fast()) pos = min<uint32_t>(a1.getUInt32Fast(), len); else { double dpos = a1.toInteger(exec); if (dpos < 0) dpos = 0; else if (dpos > len) dpos = len; pos = static_cast<int>(dpos); } return jsNumber(exec, s.find(u2, pos));}JSValuePtr stringProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args){ UString s = thisValue.toThisString(exec); int len = s.size(); JSValuePtr a0 = args.at(exec, 0); JSValuePtr a1 = args.at(exec, 1); UString u2 = a0.toString(exec); double dpos = a1.toIntegerPreserveNaN(exec); if (dpos < 0) dpos = 0; else if (!(dpos <= len)) // true for NaN dpos = len; return jsNumber(exec, s.rfind(u2, static_cast<int>(dpos)));}JSValuePtr stringProtoFuncMatch(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args){ UString s = thisValue.toThisString(exec); JSValuePtr a0 = args.at(exec, 0); UString u = s; RefPtr<RegExp> reg; RegExpObject* imp = 0; if (a0.isObject(&RegExpObject::info)) reg = asRegExpObject(a0)->regExp(); else { /* * ECMA 15.5.4.12 String.prototype.search (regexp) * If regexp is not an object whose [[Class]] property is "RegExp", it is * replaced with the result of the expression new RegExp(regexp). */ reg = RegExp::create(&exec->globalData(), a0.toString(exec)); } RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor(); int pos; int matchLength; regExpConstructor->performMatch(reg.get(), u, 0, pos, matchLength); if (!(reg->global())) { // case without 'g' flag is handled like RegExp.prototype.exec if (pos < 0) return jsNull(); return regExpConstructor->arrayOfMatches(exec); } // return array of matches ArgList list; int lastIndex = 0; while (pos >= 0) { list.append(jsSubstring(exec, u, pos, matchLength)); lastIndex = pos; pos += matchLength == 0 ? 1 : matchLength; regExpConstructor->performMatch(reg.get(), u, pos, pos, matchLength); } if (imp) imp->setLastIndex(lastIndex); if (list.isEmpty()) { // if there are no matches at all, it's important to return // Null instead of an empty array, because this matches // other browsers and because Null is a false value. return jsNull(); } return constructArray(exec, list);}JSValuePtr stringProtoFuncSearch(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args){ UString s = thisValue.toThisString(exec); JSValuePtr a0 = args.at(exec, 0); UString u = s; RefPtr<RegExp> reg; if (a0.isObject(&RegExpObject::info)) reg = asRegExpObject(a0)->regExp(); else { /* * ECMA 15.5.4.12 String.prototype.search (regexp) * If regexp is not an object whose [[Class]] property is "RegExp", it is * replaced with the result of the expression new RegExp(regexp). */ reg = RegExp::create(&exec->globalData(), a0.toString(exec)); } RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor(); int pos; int matchLength; regExpConstructor->performMatch(reg.get(), u, 0, pos, matchLength); return jsNumber(exec, pos);}JSValuePtr stringProtoFuncSlice(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args){ UString s = thisValue.toThisString(exec); int len = s.size(); JSValuePtr a0 = args.at(exec, 0); JSValuePtr a1 = args.at(exec, 1); // The arg processing is very much like ArrayProtoFunc::Slice double start = a0.toInteger(exec); double end = a1.isUndefined() ? len : a1.toInteger(exec); double from = start < 0 ? len + start : start; double to = end < 0 ? len + end : end; if (to > from && to > 0 && from < len) { if (from < 0) from = 0; if (to > len) to = len; return jsSubstring(exec, s, static_cast<unsigned>(from), static_cast<unsigned>(to) - static_cast<unsigned>(from)); } return jsEmptyString(exec);}JSValuePtr stringProtoFuncSplit(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args){ UString s = thisValue.toThisString(exec); JSValuePtr a0 = args.at(exec, 0); JSValuePtr a1 = args.at(exec, 1); JSArray* result = constructEmptyArray(exec); unsigned i = 0; int p0 = 0; unsigned limit = a1.isUndefined() ? 0xFFFFFFFFU : a1.toUInt32(exec); if (a0.isObject(&RegExpObject::info)) { RegExp* reg = asRegExpObject(a0)->regExp(); if (s.isEmpty() && reg->match(s, 0) >= 0) { // empty string matched by regexp -> empty array return result; } int pos = 0; while (i != limit && pos < s.size()) { OwnArrayPtr<int> ovector; int mpos = reg->match(s, pos, &ovector); if (mpos < 0) break; int mlen = ovector[1] - ovector[0]; pos = mpos + (mlen == 0 ? 1 : mlen); if (mpos != p0 || mlen) { result->put(exec, i++, jsSubstring(exec, s, p0, mpos - p0)); p0 = mpos + mlen; } for (unsigned si = 1; si <= reg->numSubpatterns(); ++si) { int spos = ovector[si * 2]; if (spos < 0) result->put(exec, i++, jsUndefined()); else result->put(exec, i++, jsSubstring(exec, s, spos, ovector[si * 2 + 1] - spos)); } } } else { UString u2 = a0.toString(exec); if (u2.isEmpty()) { if (s.isEmpty()) { // empty separator matches empty string -> empty array return result; } while (i != limit && p0 < s.size() - 1) result->put(exec, i++, jsSingleCharacterSubstring(exec, s, p0++)); } else { int pos; while (i != limit && (pos = s.find(u2, p0)) >= 0) { result->put(exec, i++, jsSubstring(exec, s, p0, pos - p0)); p0 = pos + u2.size(); } } } // add remaining string
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -