Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qv4string.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qv4string_p.h"
5#include "qv4value_p.h"
7#include "qv4runtime_p.h"
8#include <QtQml/private/qv4mm_p.h>
9#include <QtCore/QHash>
10#include <QtCore/private/qnumeric_p.h>
11
12using namespace QV4;
13
15{
16 StringOrSymbol *s = static_cast<StringOrSymbol *>(that);
18 if (id)
19 id->mark(markStack);
20}
21
23{
24 StringOrSymbol::markObjects(that, markStack);
25 String *s = static_cast<String *>(that);
26 if (s->subtype < StringType_Complex)
27 return;
28
29 ComplexString *cs = static_cast<ComplexString *>(s);
30 if (cs->subtype == StringType_AddedString) {
31 cs->left->mark(markStack);
32 cs->right->mark(markStack);
33 } else {
34 Q_ASSERT(cs->subtype == StringType_SubString);
35 cs->left->mark(markStack);
36 }
37}
38
41
42
44{
45 if (t == o)
46 return true;
47
48 if (!o->vtable()->isString)
49 return false;
50
51 return static_cast<String *>(t)->isEqualTo(static_cast<String *>(o));
52}
53
54
56{
57 QString mutableText(t);
58 StringOrSymbol::init(mutableText.data_ptr());
60}
61
63{
66
67 left = l;
68 right = r;
69 len = left->length() + right->length();
70 if (left->subtype >= StringType_Complex)
71 largestSubLength = static_cast<ComplexString *>(left)->largestSubLength;
72 else
73 largestSubLength = left->length();
74 if (right->subtype >= StringType_Complex)
75 largestSubLength = qMax(largestSubLength, static_cast<ComplexString *>(right)->largestSubLength);
76 else
77 largestSubLength = qMax(largestSubLength, right->length());
78
79 // make sure we don't get excessive depth in our strings
80 if (len > 256 && len >= 2*largestSubLength)
81 simplifyString();
82}
83
85{
86 Q_ASSERT(ref->length() >= from + len);
88
90
91 left = ref;
92 this->from = from;
93 this->len = len;
94}
95
97{
99 internalClass->engine->memoryManager->changeUnmanagedHeapSizeUsage(
100 qptrdiff(-text()->size) * qptrdiff(sizeof(QChar)));
101 }
102 text().~QStringPrivate();
104}
105
107{
108 *ok = true;
109
111 d()->createHashValue();
113 return d()->stringHash;
114
115 // required for UINT_MAX or numbers starting with a leading 0
117 uint l = (uint)d;
118 if (d == l)
119 return l;
120 *ok = false;
121 return UINT_MAX;
122}
123
125{
127 d()->simplifyString();
129 engine()->identifierTable->asPropertyKey(this);
130}
131
133{
134 Q_ASSERT(subtype >= StringType_AddedString);
135
136 int l = length();
138 QChar *ch = const_cast<QChar *>(result.constData());
139 append(this, ch);
140 text() = result.data_ptr();
141 const ComplexString *cs = static_cast<const ComplexString *>(this);
142 identifier = PropertyKey::invalid();
143 cs->left = cs->right = nullptr;
144
145 internalClass->engine->memoryManager->changeUnmanagedHeapSizeUsage(
146 qptrdiff(text().size) * qptrdiff(sizeof(QChar)));
147 subtype = StringType_Unknown;
148}
149
151{
152 if (subtype == StringType_AddedString)
153 return static_cast<const Heap::ComplexString *>(this)->left->startsWithUpper();
154
155 const Heap::String *str = this;
156 int offset = 0;
157 if (subtype == StringType_SubString) {
158 const ComplexString *cs = static_cast<const Heap::ComplexString *>(this);
159 if (!cs->len)
160 return false;
161 // simplification here is not ideal, but hopefully not a common case.
163 cs->left->simplifyString();
164 str = cs->left;
165 offset = cs->from;
166 }
168 return str->text().size > offset && QChar::isUpper(str->text().data()[offset]);
169}
170
171void Heap::String::append(const String *data, QChar *ch)
172{
173 // in-order visitation with explicit stack
174 // where leaf nodes are "real" strings that get appended to ch
175
176 enum StatusTag : bool { NotVisited, Visited };
177 using Pointer = QTaggedPointer<const String, StatusTag>;
178
179 std::vector<Pointer> worklist;
180 worklist.reserve(32);
181 worklist.push_back(Pointer(data));
182
183 while (!worklist.empty()) {
184 Pointer item = worklist.back();
185 if (item.tag() == Visited) {
186 Q_ASSERT(item->subtype == StringType_AddedString);
187 const ComplexString *cs = static_cast<const ComplexString *>(item.data());
188 worklist.pop_back();
189 worklist.push_back(Pointer(cs->right));
190 continue;
191 }
192
193 if (item->subtype == StringType_AddedString) {
194 // we need to keep the node in the worklist, as we still need to handle "right"
195 worklist.back().setTag(Visited);
196 const ComplexString *cs = static_cast<const ComplexString *>(item.data());
197 worklist.push_back(Pointer(cs->left));
198 } else if (item->subtype == StringType_SubString) {
199 worklist.pop_back();
200 const ComplexString *cs = static_cast<const ComplexString *>(item.data());
201 memcpy(ch, cs->left->toQString().constData() + cs->from, cs->len*sizeof(QChar));
202 ch += cs->len;
203 } else {
204 worklist.pop_back();
205 memcpy(static_cast<void *>(ch), item->text().data(), item->text().size * sizeof(QChar));
206 ch += item->text().size;
207 }
208 }
209}
210
212{
213 if (subtype >= StringType_AddedString) {
214 Q_ASSERT(internalClass->vtable->isString);
215 static_cast<const Heap::String *>(this)->simplifyString();
216 }
217 Q_ASSERT(subtype < StringType_AddedString);
218 const QChar *ch = reinterpret_cast<const QChar *>(text().data());
219 const QChar *end = ch + text().size;
220 stringHash = QV4::String::calculateHashValue(ch, end, &subtype);
221}
222
224{
225 return static_cast<const String *>(m)->d()->length();
226}
\inmodule QtCore
QVariant data(int key) const
Returns this item's custom data for the key key as a QVariant.
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
const QChar * constData() const
Returns a pointer to the data stored in the QString.
Definition qstring.h:1246
qsizetype size() const noexcept
Returns the number of characters in this string.
Definition qstring.h:186
DataPointer & data_ptr()
Definition qstring.h:1093
QChar * data()
Returns a pointer to the data stored in the QString.
Definition qstring.h:1240
QString str
[2]
QString text
list append(new Employee("Blackpool", "Stephen"))
constexpr Initialization Uninitialized
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
const GLfloat * m
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLboolean r
[2]
GLuint GLuint end
GLenum GLuint GLenum GLsizei length
GLdouble GLdouble right
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLint left
GLenum GLuint GLintptr offset
GLint ref
GLdouble s
[6]
Definition qopenglext.h:235
GLdouble GLdouble t
Definition qopenglext.h:243
GLuint64EXT * result
[6]
GLenum GLsizei len
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
ptrdiff_t qptrdiff
Definition qtypes.h:164
unsigned int uint
Definition qtypes.h:34
long long qint64
Definition qtypes.h:60
#define DEFINE_MANAGED_VTABLE(classname)
QGraphicsItem * item
QJSEngine engine
[0]
void mark(QV4::MarkStack *markStack)
Definition qv4heap_p.h:138
static void markObjects(Heap::Base *that, MarkStack *markStack)
Definition qv4string.cpp:14
static void markObjects(Heap::Base *that, MarkStack *markStack)
Definition qv4string.cpp:22
bool startsWithUpper() const
QString toQString() const
Definition qv4string_p.h:92
int length() const
void simplifyString() const
bool isEqualTo(const String *other) const
Definition qv4string_p.h:97
void mark(MarkStack *markStack)
StringOrSymbol * asStringOrSymbol() const
static PropertyKey invalid()
static double stringToNumber(const QString &s)
QV4_NEARLY_ALWAYS_INLINE constexpr void setTag(quint32 tag)
Q_NEVER_INLINE void createPropertyKeyImpl() const
uint toUInt(bool *ok) const
static uint calculateHashValue(const T *ch, const T *end, uint *subtype)
QString toQString() const
static constexpr VTable::GetLength virtualGetLength
static constexpr VTable::IsEqualTo virtualIsEqualTo