Line | Source | Count |
1 | | - |
2 | | - |
3 | | - |
4 | | - |
5 | | - |
6 | | - |
7 | | - |
8 | | - |
9 | | - |
10 | | - |
11 | | - |
12 | | - |
13 | | - |
14 | | - |
15 | | - |
16 | | - |
17 | | - |
18 | | - |
19 | | - |
20 | | - |
21 | | - |
22 | | - |
23 | | - |
24 | | - |
25 | | - |
26 | | - |
27 | | - |
28 | | - |
29 | | - |
30 | | - |
31 | | - |
32 | | - |
33 | | - |
34 | | - |
35 | | - |
36 | | - |
37 | | - |
38 | | - |
39 | | - |
40 | #include "qv4string_p.h" | - |
41 | #include "qv4value_p.h" | - |
42 | #ifndef V4_BOOTSTRAP | - |
43 | #include "qv4identifiertable_p.h" | - |
44 | #include "qv4runtime_p.h" | - |
45 | #include "qv4objectproto_p.h" | - |
46 | #include "qv4stringobject_p.h" | - |
47 | #endif | - |
48 | #include <QtCore/QHash> | - |
49 | #include <QtCore/private/qnumeric_p.h> | - |
50 | | - |
51 | using namespace QV4; | - |
52 | | - |
53 | #ifndef V4_BOOTSTRAP | - |
54 | | - |
55 | void Heap::StringOrSymbol::markObjects(Heap::Base *that, MarkStack *markStack) | - |
56 | { | - |
57 | StringOrSymbol *s = static_cast<StringOrSymbol *>(that); | - |
58 | Heap::StringOrSymbol *id = s->identifier.asStringOrSymbol(); | - |
59 | if (id) | - |
60 | id->mark(markStack); | - |
61 | } | - |
62 | | - |
63 | void Heap::String::markObjects(Heap::Base *that, MarkStack *markStack) | - |
64 | { | - |
65 | StringOrSymbol::markObjects(that, markStack); | - |
66 | String *s = static_cast<String *>(that); | - |
67 | if (s->subtype < StringType_Complex) | - |
68 | return; | - |
69 | | - |
70 | ComplexString *cs = static_cast<ComplexString *>(s); | - |
71 | if (cs->subtype == StringType_AddedString) { | - |
72 | cs->left->mark(markStack); | - |
73 | cs->right->mark(markStack); | - |
74 | } else { | - |
75 | Q_ASSERT(cs->subtype == StringType_SubString); | - |
76 | cs->left->mark(markStack); | - |
77 | } | - |
78 | } | - |
79 | | - |
80 | DEFINE_MANAGED_VTABLE(StringOrSymbol); | - |
81 | DEFINE_MANAGED_VTABLE(String); | - |
82 | | - |
83 | | - |
84 | bool String::virtualIsEqualTo(Managed *t, Managed *o) | - |
85 | { | - |
86 | if (t == o) | - |
87 | return true; | - |
88 | | - |
89 | if (!o->vtable()->isString) | - |
90 | return false; | - |
91 | | - |
92 | return static_cast<String *>(t)->isEqualTo(static_cast<String *>(o)); | - |
93 | } | - |
94 | | - |
95 | | - |
96 | void Heap::String::init(const QString &t) | - |
97 | { | - |
98 | Base::init(); | - |
99 | | - |
100 | subtype = String::StringType_Unknown; | - |
101 | | - |
102 | text = const_cast<QString &>(t).data_ptr(); | - |
103 | text->ref.ref(); | - |
104 | } | - |
105 | | - |
106 | void Heap::ComplexString::init(String *l, String *r) | - |
107 | { | - |
108 | Base::init(); | - |
109 | | - |
110 | subtype = String::StringType_AddedString; | - |
111 | | - |
112 | left = l; | - |
113 | right = r; | - |
114 | len = left->length() + right->length(); | - |
115 | if (left->subtype >= StringType_Complex) | - |
116 | largestSubLength = static_cast<ComplexString *>(left)->largestSubLength; | - |
117 | else | - |
118 | largestSubLength = left->length(); | - |
119 | if (right->subtype >= StringType_Complex) | - |
120 | largestSubLength = qMax(largestSubLength, static_cast<ComplexString *>(right)->largestSubLength); | - |
121 | else | - |
122 | largestSubLength = qMax(largestSubLength, right->length()); | - |
123 | | - |
124 | | - |
125 | if (len > 256 && len >= 2*largestSubLength) | - |
126 | simplifyString(); | - |
127 | } | - |
128 | | - |
129 | void Heap::ComplexString::init(Heap::String *ref, int from, int len) | - |
130 | { | - |
131 | Q_ASSERT(ref->length() >= from + len); | - |
132 | Base::init(); | - |
133 | | - |
134 | subtype = String::StringType_SubString; | - |
135 | | - |
136 | left = ref; | - |
137 | this->from = from; | - |
138 | this->len = len; | - |
139 | } | - |
140 | | - |
141 | void Heap::StringOrSymbol::destroy() | - |
142 | { | - |
143 | if (text) { | - |
144 | internalClass->engine->memoryManager->changeUnmanagedHeapSizeUsage(qptrdiff(-text->size) * (int)sizeof(QChar)); | - |
145 | if (!text->ref.deref()) | - |
146 | QStringData::deallocate(text); | - |
147 | } | - |
148 | Base::destroy(); | - |
149 | } | - |
150 | | - |
151 | uint String::toUInt(bool *ok) const | - |
152 | { | - |
153 | *ok = true; | - |
154 | | - |
155 | if (subtype() >= Heap::String::StringType_Unknown) | - |
156 | d()->createHashValue(); | - |
157 | if (subtype() == Heap::String::StringType_ArrayIndex) | - |
158 | return d()->stringHash; | - |
159 | | - |
160 | | - |
161 | double d = RuntimeHelpers::stringToNumber(toQString()); | - |
162 | uint l = (uint)d; | - |
163 | if (d == l) | - |
164 | return l; | - |
165 | *ok = false; | - |
166 | return UINT_MAX; | - |
167 | } | - |
168 | | - |
169 | void String::createPropertyKeyImpl() const | - |
170 | { | - |
171 | if (!d()->text) | - |
172 | d()->simplifyString(); | - |
173 | Q_ASSERT(d()->text); | - |
174 | engine()->identifierTable->asPropertyKey(this); | - |
175 | } | - |
176 | | - |
177 | void Heap::String::simplifyString() const | - |
178 | { | - |
179 | Q_ASSERT(!text); | - |
180 | | - |
181 | int l = length(); | - |
182 | QString result(l, Qt::Uninitialized); | - |
183 | QChar *ch = const_cast<QChar *>(result.constData()); | - |
184 | append(this, ch); | - |
185 | text = result.data_ptr(); | - |
186 | text->ref.ref(); | - |
187 | const ComplexString *cs = static_cast<const ComplexString *>(this); | - |
188 | identifier = PropertyKey::invalid(); | - |
189 | cs->left = cs->right = nullptr; | - |
190 | | - |
191 | internalClass->engine->memoryManager->changeUnmanagedHeapSizeUsage(qptrdiff(text->size) * (qptrdiff)sizeof(QChar)); | - |
192 | subtype = StringType_Unknown; | - |
193 | } | - |
194 | | - |
195 | bool Heap::String::startsWithUpper() const | - |
196 | { | - |
197 | if (subtype == StringType_AddedString) | - |
198 | return static_cast<const Heap::ComplexString *>(this)->left->startsWithUpper(); | - |
199 | | - |
200 | const Heap::String *str = this; | - |
201 | int offset = 0; | - |
202 | if (subtype == StringType_SubString) { | - |
203 | const ComplexString *cs = static_cast<const Heap::ComplexString *>(this); | - |
204 | if (!cs->len) | - |
205 | return false; | - |
206 | | - |
207 | if (cs->left->subtype >= Heap::String::StringType_Complex) | - |
208 | cs->left->simplifyString(); | - |
209 | str = cs->left; | - |
210 | offset = cs->from; | - |
211 | } | - |
212 | Q_ASSERT(str->subtype < Heap::String::StringType_Complex); | - |
213 | return str->text->size > offset && QChar::isUpper(str->text->data()[offset]); | - |
214 | } | - |
215 | | - |
216 | void Heap::String::append(const String *data, QChar *ch) | - |
217 | { | - |
218 | std::vector<const String *> worklist; | - |
219 | worklist.reserve(32); | - |
220 | worklist.push_back(data); | - |
221 | | - |
222 | while (!worklist.empty()) { | - |
223 | const String *item = worklist.back(); | - |
224 | worklist.pop_back(); | - |
225 | | - |
226 | if (item->subtype == StringType_AddedString) { | - |
227 | const ComplexString *cs = static_cast<const ComplexString *>(item); | - |
228 | worklist.push_back(cs->right); | - |
229 | worklist.push_back(cs->left); | - |
230 | } else if (item->subtype == StringType_SubString) { | - |
231 | const ComplexString *cs = static_cast<const ComplexString *>(item); | - |
232 | memcpy(ch, cs->left->toQString().constData() + cs->from, cs->len*sizeof(QChar)); | - |
233 | ch += cs->len; | - |
234 | } else { | - |
235 | memcpy(static_cast<void *>(ch), static_cast<const void *>(item->text->data()), item->text->size * sizeof(QChar)); | - |
236 | ch += item->text->size; | - |
237 | } | - |
238 | } | - |
239 | } | - |
240 | | - |
241 | void Heap::StringOrSymbol::createHashValue() const | - |
242 | { | - |
243 | if (!text) { | - |
244 | Q_ASSERT(internalClass->vtable->isString); | - |
245 | static_cast<const Heap::String *>(this)->simplifyString(); | - |
246 | } | - |
247 | Q_ASSERT(text); | - |
248 | const QChar *ch = reinterpret_cast<const QChar *>(text->data()); | - |
249 | const QChar *end = ch + text->size; | - |
250 | stringHash = QV4::String::calculateHashValue(ch, end, &subtype); | - |
251 | } | - |
252 | | - |
253 | PropertyKey StringOrSymbol::toPropertyKey() const { | - |
254 | if (d()->identifier.isValid()) | - |
255 | return d()->identifier; | - |
256 | createPropertyKey(); | - |
257 | return propertyKey(); | - |
258 | } | - |
259 | | - |
260 | qint64 String::virtualGetLength(const Managed *m) | - |
261 | { | - |
262 | return static_cast<const String *>(m)->d()->length(); | - |
263 | } | - |
264 | | - |
265 | #endif // V4_BOOTSTRAP | - |
266 | | - |
267 | uint String::toArrayIndex(const QString &str) | - |
268 | { | - |
269 | return QV4::String::toArrayIndex(str.constData(), str.constData() + str.length());executed 79529 times by 33 tests: return QV4::String::toArrayIndex(str.constData(), str.constData() + str.length()); Executed by:- tst_ecmascripttests
- tst_examples
- tst_parserstress
- tst_qjsengine
- tst_qjsonbinding
- tst_qjsvalue
- tst_qqmlbinding
- tst_qqmlcomponent
- tst_qqmlconsole
- tst_qqmlecmascript
- tst_qqmllistmodel
- tst_qqmllistmodelworkerscript
- tst_qqmlprofilerservice
- tst_qqmlqt
- tst_qqmlsettings
- tst_qqmlsqldatabase
- tst_qqmlvaluetypeproviders
- tst_qqmlvaluetypes
- tst_qqmlxmlhttprequest
- tst_qquickanimationcontroller
- tst_qquickgridview
- tst_qquicklayouts
- tst_qquicklistview
- tst_qquickloader
- tst_qquickparticlegroup
- ...
| 79529 |
270 | } | - |
| | |