OpenCoverage

qv4string.cpp #1

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/qtdeclarative/src/qtdeclarative/src/qml/jsruntime/qv4string.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2016 The Qt Company Ltd.-
4** Contact: https://www.qt.io/licensing/-
5**-
6** This file is part of the QtQml module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL$-
9** Commercial License Usage-
10** Licensees holding valid commercial Qt licenses may use this file in-
11** accordance with the commercial license agreement provided with the-
12** Software or, alternatively, in accordance with the terms contained in-
13** a written agreement between you and The Qt Company. For licensing terms-
14** and conditions see https://www.qt.io/terms-conditions. For further-
15** information use the contact form at https://www.qt.io/contact-us.-
16**-
17** GNU Lesser General Public License Usage-
18** Alternatively, this file may be used under the terms of the GNU Lesser-
19** General Public License version 3 as published by the Free Software-
20** Foundation and appearing in the file LICENSE.LGPL3 included in the-
21** packaging of this file. Please review the following information to-
22** ensure the GNU Lesser General Public License version 3 requirements-
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.-
24**-
25** GNU General Public License Usage-
26** Alternatively, this file may be used under the terms of the GNU-
27** General Public License version 2.0 or (at your option) the GNU General-
28** Public license version 3 or any later version approved by the KDE Free-
29** Qt Foundation. The licenses are as published by the Free Software-
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3-
31** included in the packaging of this file. Please review the following-
32** information to ensure the GNU General Public License requirements will-
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and-
34** https://www.gnu.org/licenses/gpl-3.0.html.-
35**-
36** $QT_END_LICENSE$-
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-
51using namespace QV4;-
52-
53#ifndef V4_BOOTSTRAP-
54-
55void 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-
63void 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-
80DEFINE_MANAGED_VTABLE(StringOrSymbol);-
81DEFINE_MANAGED_VTABLE(String);-
82-
83-
84bool 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-
96void 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-
106void 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 // make sure we don't get excessive depth in our strings-
125 if (len > 256 && len >= 2*largestSubLength)-
126 simplifyString();-
127}-
128-
129void 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-
141void 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-
151uint 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 // required for UINT_MAX or numbers starting with a leading 0-
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-
169void String::createPropertyKeyImpl() const-
170{-
171 if (!d()->text)-
172 d()->simplifyString();-
173 Q_ASSERT(d()->text);-
174 engine()->identifierTable->asPropertyKey(this);-
175}-
176-
177void 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-
195bool 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 // simplification here is not ideal, but hopefully not a common case.-
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-
216void 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-
241void 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-
253PropertyKey StringOrSymbol::toPropertyKey() const {-
254 if (d()->identifier.isValid())-
255 return d()->identifier;-
256 createPropertyKey();-
257 return propertyKey();-
258}-
259-
260qint64 String::virtualGetLength(const Managed *m)-
261{-
262 return static_cast<const String *>(m)->d()->length();-
263}-
264-
265#endif // V4_BOOTSTRAP-
266-
267uint 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}-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.2.0