JSValue JSC_HOST_CALL stringProtoFuncCharAt(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) { UString s = thisValue.toThisString(exec); unsigned len = s.size(); JSValue a0 = args.at(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); }
JSValue* stringProtoFuncCharAt(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args) { UString s = thisValue->toThisString(exec); unsigned len = s.size(); JSValue* a0 = args.at(exec, 0); if (JSImmediate::isNumber(a0)) { uint32_t i; if (JSImmediate::getUInt32(a0, i) && 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); }
JSString* JSRopeString::getIndexSlowCase(ExecState* exec, unsigned i) { ASSERT(isRope()); resolveRope(exec); // Return a safe no-value result, this should never be used, since the excetion will be thrown. if (exec->exception()) return jsEmptyString(exec); ASSERT(!isRope()); RELEASE_ASSERT(i < m_value.length()); return jsSingleCharacterSubstring(exec, m_value, i); }
TiString* TiString::getIndexSlowCase(TiExcState* exec, unsigned i) { ASSERT(isRope()); resolveRope(exec); // Return a safe no-value result, this should never be used, since the excetion will be thrown. if (exec->exception()) return jsString(exec, ""); ASSERT(!isRope()); ASSERT(i < m_value.size()); return jsSingleCharacterSubstring(exec, m_value, i); }
bool JSString::getStringPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) { if (propertyName == exec->propertyNames().length) { descriptor.setDescriptor(jsNumber(exec, m_value.size()), DontEnum | DontDelete | ReadOnly); return true; } bool isStrictUInt32; unsigned i = propertyName.toStrictUInt32(&isStrictUInt32); if (isStrictUInt32 && i < static_cast<unsigned>(m_value.size())) { descriptor.setDescriptor(jsSingleCharacterSubstring(exec, m_value, i), DontDelete | ReadOnly); return true; } return false; }
JSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) { UString s = thisValue.toThisString(exec); JSValue a0 = args.at(0); JSValue a1 = args.at(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 if (i != limit) result->put(exec, i++, jsSubstring(exec, s, p0, s.size() - p0)); return result; }