8#include <private/qv4mm_p.h>
11#include <private/qv4alloca_p.h>
14#include <QtCore/QDateTime>
15#include <QtCore/QDebug>
16#include <QtCore/QStringList>
17#include <QtQml/private/qv4runtime_p.h>
26# include "qplatformdefs.h"
36void Heap::StringObject::init()
39 Q_ASSERT(vtable() == QV4::StringObject::staticVTable());
40 string.set(internalClass->engine, internalClass->engine->id_empty()->d());
47 string.set(internalClass->engine,
str->d());
56 return internalClass->engine->newString(
str.
mid(
index, 1));
59uint Heap::StringObject::length()
const
67 if (
id.isArrayIndex()) {
70 if (
index <
static_cast<uint>(
o->d()->string->toQString().size()))
87 if (arrayIndex < slen) {
95 }
else if (arrayIndex == slen) {
99 while (arrayNode && arrayNode->
key() < slen)
119 if (
id.isArrayIndex()) {
122 if (
index <
uint(
s->d()->string->toQString().size())) {
153 obj->setProtoFromNewTarget(newTarget);
154 return obj->asReturnedValue();
171 for (
int i = 0, ei = argc;
i < ei; ++
i) {
185 for (
int i = 0;
i < argc; ++
i) {
189 int cp =
static_cast<int>(
num);
190 if (cp !=
num || cp < 0 || cp > 0x10ffff)
191 return e->throwRangeError(
QStringLiteral(
"String.fromCodePoint: argument out of range."));
202 return e->newString(
result)->asReturnedValue();
209 return scope.engine->throwTypeError();
213 return scope.engine->throwTypeError();
217 if (
scope.hasException())
224 uint literalSegments = raw->getLength();
225 if (!literalSegments)
226 return scope.engine->id_empty()->asReturnedValue();
231 val = raw->get(nextIndex);
233 if (
scope.hasException())
235 if (nextIndex + 1 == literalSegments)
236 return scope.engine->newString(
result)->asReturnedValue();
238 if (nextIndex <
static_cast<uint>(argc))
240 if (
scope.hasException())
253 d()->internalClass.set(scope.
engine, ic);
264 defineDefaultProperty(
engine->id_toString(), method_toString);
265 defineDefaultProperty(
engine->id_valueOf(), method_toString);
266 defineDefaultProperty(
QStringLiteral(
"charAt"), method_charAt, 1);
267 defineDefaultProperty(
QStringLiteral(
"charCodeAt"), method_charCodeAt, 1);
268 defineDefaultProperty(
QStringLiteral(
"codePointAt"), method_codePointAt, 1);
269 defineDefaultProperty(
QStringLiteral(
"concat"), method_concat, 1);
270 defineDefaultProperty(
QStringLiteral(
"endsWith"), method_endsWith, 1);
271 defineDefaultProperty(
QStringLiteral(
"indexOf"), method_indexOf, 1);
272 defineDefaultProperty(
QStringLiteral(
"includes"), method_includes, 1);
273 defineDefaultProperty(
QStringLiteral(
"lastIndexOf"), method_lastIndexOf, 1);
274 defineDefaultProperty(
QStringLiteral(
"localeCompare"), method_localeCompare, 1);
276 defineDefaultProperty(
QStringLiteral(
"normalize"), method_normalize, 0);
277 defineDefaultProperty(
QStringLiteral(
"padEnd"), method_padEnd, 1);
278 defineDefaultProperty(
QStringLiteral(
"padStart"), method_padStart, 1);
279 defineDefaultProperty(
QStringLiteral(
"repeat"), method_repeat, 1);
280 defineDefaultProperty(
QStringLiteral(
"replace"), method_replace, 2);
281 defineDefaultProperty(
QStringLiteral(
"search"), method_search, 1);
284 defineDefaultProperty(
QStringLiteral(
"startsWith"), method_startsWith, 1);
285 defineDefaultProperty(
QStringLiteral(
"substr"), method_substr, 2);
286 defineDefaultProperty(
QStringLiteral(
"substring"), method_substring, 2);
287 defineDefaultProperty(
QStringLiteral(
"toLowerCase"), method_toLowerCase);
288 defineDefaultProperty(
QStringLiteral(
"toLocaleLowerCase"), method_toLocaleLowerCase);
289 defineDefaultProperty(
QStringLiteral(
"toUpperCase"), method_toUpperCase);
290 defineDefaultProperty(
QStringLiteral(
"toLocaleUpperCase"), method_toLocaleUpperCase);
292 defineDefaultProperty(
engine->symbol_iterator(), method_iterator);
300 return thisString->d()->string;
307 return s->toQString();
309 return thisString->d()->string->toQString();
326 return o->d()->string->asReturnedValue();
376 if (index < 0 || index >=
value.size())
397 for (
int i = 0;
i < argc; ++
i) {
416 if (argc && argv[0].as<RegExpObject>())
449 if (!
value.isEmpty())
462 if (argc && argv[0].as<RegExpObject>())
470 const Value &posArg = argv[1];
527 if (argc && !argv[0].isNullOrUndefined()) {
532 if (!
f->isNullOrUndefined()) {
567 if (argc >= 1 && !argv[0].isUndefined()) {
597 return s->asReturnedValue();
600 if (maxLen <= s->
d()->
length())
601 return s->asReturnedValue();
607 return s->asReturnedValue();
610 int oldLength = padded.
size();
611 int toFill = maxLen - oldLength;
636 return s->asReturnedValue();
639 if (maxLen <= s->
d()->
length())
640 return s->asReturnedValue();
646 return s->asReturnedValue();
649 int oldLength = original.
size();
650 int toFill = maxLen - oldLength;
686 for (
int i = 0;
i < replaceValue.
size(); ++
i) {
689 uint substStart = JSC::Yarr::offsetNoMatch;
690 uint substEnd = JSC::Yarr::offsetNoMatch;
696 }
else if (
ch ==
'&') {
697 substStart = matchOffsets[0];
698 substEnd = matchOffsets[1];
700 }
else if (
ch ==
'`') {
702 substEnd = matchOffsets[0];
704 }
else if (
ch ==
'\'') {
705 substStart = matchOffsets[1];
706 substEnd =
input.size();
708 }
else if (
ch >=
'0' &&
ch <=
'9') {
711 if (
i < replaceValue.
size() - 2) {
713 if (
ch >=
'0' &&
ch <=
'9') {
714 uint c = capture*10 +
ch -
'0';
715 if (
c <
static_cast<uint>(captureCount)) {
721 if (capture > 0 && capture <
static_cast<uint>(captureCount)) {
722 substStart = matchOffsets[capture * 2];
723 substEnd = matchOffsets[capture * 2 + 1];
729 if (substStart != JSC::Yarr::offsetNoMatch && substEnd != JSC::Yarr::offsetNoMatch)
743 string = thisString->d()->string->toQString();
748 int numStringMatches = 0;
750 uint allocatedMatchOffsets = 64;
751 uint _matchOffsets[64];
752 uint *matchOffsets = _matchOffsets;
759 uint nMatchOffsets = 0;
764 int oldSize = nMatchOffsets;
765 if (allocatedMatchOffsets < nMatchOffsets + re->captureCount() * 2) {
766 allocatedMatchOffsets =
qMax(allocatedMatchOffsets * 2, nMatchOffsets + re->captureCount() * 2);
767 uint *newOffsets = (
uint *)malloc(allocatedMatchOffsets*
sizeof(
uint));
768 memcpy(newOffsets, matchOffsets, nMatchOffsets*
sizeof(
uint));
769 if (matchOffsets != _matchOffsets)
771 matchOffsets = newOffsets;
773 if (re->match(
string,
offset, matchOffsets + oldSize) == JSC::Yarr::offsetNoMatch) {
774 nMatchOffsets = oldSize;
777 nMatchOffsets += re->captureCount() * 2;
778 if (!regExp->global())
782 if (regExp->global()) {
783 regExp->setLastIndex(0);
787 numStringMatches = nMatchOffsets / (regExp->value()->captureCount() * 2);
788 numCaptures = regExp->value()->captureCount();
792 int idx =
string.
indexOf(searchString);
794 numStringMatches = 1;
795 matchOffsets[0] = idx;
796 matchOffsets[1] = idx + searchString.
size();
804 if (!!searchCallback) {
805 result.reserve(
string.
size() + 10*numStringMatches);
809 for (
int i = 0;
i < numStringMatches; ++
i) {
810 for (
int k = 0; k < numCaptures; ++k) {
811 int idx = (
i * numCaptures + k) * 2;
813 uint end = matchOffsets[idx + 1];
815 if (
start != JSC::Yarr::offsetNoMatch &&
end != JSC::Yarr::offsetNoMatch)
819 uint matchStart = matchOffsets[
i * numCaptures * 2];
821 uint matchEnd = matchOffsets[
i * numCaptures * 2 + 1];
826 replacement = searchCallback->call(&that,
arguments, numCaptures + 2);
838 for (
int i = 0;
i < numStringMatches; ++
i) {
839 int baseIndex =
i * numCaptures * 2;
840 uint matchStart = matchOffsets[baseIndex];
841 uint matchEnd = matchOffsets[baseIndex + 1];
842 if (matchStart == JSC::Yarr::offsetNoMatch)
852 if (matchOffsets != _matchOffsets)
875 uint result = re->match(
string, 0, matchOffsets);
876 if (
result == JSC::Yarr::offsetNoMatch)
891 const double length =
s->d()->length();
907 const int intStart = int(
start);
908 const int intEnd = int(
end);
928 if (limitValue->isUndefined()) {
931 return array.asReturnedValue();
936 uint limit = limitValue->isUndefined() ? UINT_MAX : limitValue->toUInt32();
939 return array.asReturnedValue();
943 if (re->value()->pattern->isEmpty()) {
956 if (
result == JSC::Yarr::offsetNoMatch)
965 for (
int i = 1;
i < re->value()->captureCount(); ++
i) {
980 return array.asReturnedValue();
994 return array.asReturnedValue();
1004 if (argc && argv[0].as<RegExpObject>())
1062 if (argc > 1 && !argv[1].isUndefined())
1068 if (std::isnan(
end) ||
end < 0)
1100 return method_toLowerCase(
b, thisObject, argv, argc);
1115 return method_toUpperCase(
b, thisObject, argv, argc);
1125 const QChar *chars =
s.constData();
1128 if (!chars[
start].isSpace() && chars[
start].unicode() != 0xfeff)
1132 if (!chars[
end].isSpace() && chars[
end].
unicode() != 0xfeff)
static constexpr char32_t surrogateToUcs4(char16_t high, char16_t low) noexcept
Converts a UTF16 surrogate pair with the given high and low values to it's UCS-4-encoded code point.
static constexpr char16_t highSurrogate(char32_t ucs4) noexcept
Returns the high surrogate part of a UCS-4-encoded code point.
constexpr bool isLowSurrogate() const noexcept
Returns true if the QChar is the low part of a UTF16 surrogate (for example if its code point is in r...
constexpr char16_t unicode() const noexcept
Returns the numeric Unicode value of the QChar.
static constexpr char16_t lowSurrogate(char32_t ucs4) noexcept
Returns the low surrogate part of a UCS-4-encoded code point.
constexpr bool isHighSurrogate() const noexcept
Returns true if the QChar is the high part of a UTF16 surrogate (for example if its code point is in ...
bool contains(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
bool startsWith(QStringView s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
constexpr QStringView left(qsizetype n) const noexcept
bool endsWith(QStringView s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
constexpr QStringView mid(qsizetype pos, qsizetype n=-1) const noexcept
Returns the substring of length length starting at position start in this object.
\macro QT_RESTRICTED_CAST_FROM_ASCII
void reserve(qsizetype size)
Ensures the string has space for at least size characters.
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
const QChar * constData() const
Returns a pointer to the data stored in the QString.
bool isNull() const
Returns true if this string is null; otherwise returns false.
qsizetype size() const
Returns the number of characters in this string.
void push_back(QChar c)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QString mid(qsizetype position, qsizetype n=-1) const
Returns a string that contains n characters of this string, starting at the specified position index.
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
QChar * data()
Returns a pointer to the data stored in the QString.
QString left(qsizetype n) const
Returns a substring that contains the n leftmost characters of the string.
static QString static QString qsizetype indexOf(QChar c, qsizetype from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
int localeAwareCompare(const QString &s) const
NormalizationForm
This enum describes the various normalized forms of Unicode text.
qsizetype length() const
Returns the number of characters in this string.
QString normalized(NormalizationForm mode, QChar::UnicodeVersion version=QChar::Unicode_Unassigned) const
Returns the string in the given Unicode normalization mode, according to the given version of the Uni...
void resize(qsizetype size)
Sets the size of the string to size characters.
ObjectType::Data * allocate(Args &&... args)
ManagedType::Data * alloc(Args &&... args)
object setProperty("down", true)
QList< QVariant > arguments
\qmltype Particle \inqmlmodule QtQuick.Particles
ReturnedValue checkedResult(QV4::ExecutionEngine *v4, ReturnedValue result)
constexpr Initialization Uninitialized
static jboolean copy(JNIEnv *, jobject)
static const QCssKnownValue repeats[NumKnownRepeats - 1]
static struct AttrInfo attrs[]
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
bool qIsInf(qfloat16 f) noexcept
constexpr const T & qMin(const T &a, const T &b)
constexpr const T & qMax(const T &a, const T &b)
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION double qInf()
constexpr static Q_DECL_CONST_FUNCTION double qt_qnan() noexcept
GLboolean GLboolean GLboolean b
GLint GLint GLint GLint GLint x
[0]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLuint GLenum GLsizei length
GLenum GLenum GLsizei count
GLenum GLuint GLintptr offset
GLint GLenum GLboolean normalized
GLenum GLenum GLenum input
GLsizei const GLchar *const * string
[0]
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
QLatin1StringView QLatin1String
#define QStringLiteral(str)
static bool match(const uchar *found, uint foundLen, const char *target, uint targetLen)
#define Q_ALLOCA_VAR(type, name, size)
#define CHECK_EXCEPTION()
static Heap::String * thisAsString(ExecutionEngine *v4, const QV4::Value *thisObject)
static QString getThisString(ExecutionEngine *v4, const QV4::Value *thisObject)
static void appendReplacementString(QString *result, const QString &input, const QString &replaceValue, uint *matchOffsets, int captureCount)
#define DEFINE_OBJECT_VTABLE(classname)
\inmodule QtCore \reentrant
static constexpr ReturnedValue undefined()
Heap::InternalClass * classes[NClasses]
MemoryManager * memoryManager
Heap::String * newString(const QString &s=QString())
FunctionObject * regExpCtor() const
ReturnedValue throwRangeError(const Value &value)
String * id_empty() const
Object * objectPrototype() const
Symbol * symbol_match() const
Heap::ArrayObject * newArrayObject(int count=0)
Heap::Object * newStringObject(const String *string)
ReturnedValue throwTypeError()
ReturnedValue callAsConstructor(const JSCallData &data) const
Heap::ExecutionContext * scope() const
ReturnedValue asReturnedValue() const
Q_REQUIRED_RESULT InternalClass * changePrototype(Heap::Object *proto)
void init(QV4::ExecutionContext *scope)
ExecutionEngine * engine() const
PropertyKey next(const Object *o, Property *pd=nullptr, PropertyAttributes *attrs=nullptr) override
void defineDefaultProperty(StringOrSymbol *name, const Value &value, PropertyAttributes attributes=Attr_Data|Attr_NotEnumerable)
void defineReadonlyConfigurableProperty(const QString &name, const Value &value)
void defineReadonlyProperty(const QString &name, const Value &value)
static PropertyKey fromArrayIndex(uint idx)
static double toNumber(const Value &value)
Value * alloc(qint64 nValues) const =delete
bool hasException() const
QML_NEARLY_ALWAYS_INLINE ReturnedValue asReturnedValue() const
const SparseArrayNode * nextNode() const
QV4_NEARLY_ALWAYS_INLINE constexpr quint64 rawValue() const
constexpr ReturnedValue asReturnedValue() const
QV4_NEARLY_ALWAYS_INLINE constexpr quint32 value() const
bool isNullOrUndefined() const
static ReturnedValue method_raw(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_fromCharCode(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_fromCodePoint(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static bool virtualDeleteProperty(Managed *m, PropertyKey id)
static ReturnedValue method_localeCompare(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_concat(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toLocaleUpperCase(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_indexOf(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_includes(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_repeat(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toLocaleLowerCase(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_padEnd(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toLowerCase(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toUpperCase(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_charAt(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_replace(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_normalize(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_substr(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_slice(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_match(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_codePointAt(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_search(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_split(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_substring(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_trim(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
void init(ExecutionEngine *engine, Object *ctor)
static ReturnedValue method_lastIndexOf(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_charCodeAt(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_startsWith(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_endsWith(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_padStart(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_iterator(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static constexpr VTable::OwnPropertyKeys virtualOwnPropertyKeys
static constexpr VTable::GetOwnProperty virtualGetOwnProperty
static constexpr VTable::CallAsConstructor virtualCallAsConstructor
static constexpr VTable::Call virtualCall
static constexpr VTable::DeleteProperty virtualDeleteProperty
static constexpr Value fromInt32(int i)
Heap::String * toString(ExecutionEngine *e) const
QML_NEARLY_ALWAYS_INLINE String * stringValue() const
static constexpr Value undefinedValue()
QString toQString() const
QML_NEARLY_ALWAYS_INLINE Symbol * symbolValue() const
Heap::Object * toObject(ExecutionEngine *e) const
static Value fromUInt32(uint i)
~StringObjectOwnPropertyKeyIterator() override=default
PropertyKey next(const QV4::Object *o, Property *pd=nullptr, PropertyAttributes *attrs=nullptr) override