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
qv4sequenceobject.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 <QtCore/qsequentialiterable.h>
5
7
8#include <private/qv4functionobject_p.h>
9#include <private/qv4arrayobject_p.h>
10#include <private/qqmlengine_p.h>
11#include <private/qv4scopedvalue_p.h>
12#include <private/qv4jscall_p.h>
13#include <private/qqmlmetatype_p.h>
14#include <private/qqmltype_p_p.h>
15#include <private/qqmlvaluetypewrapper_p.h>
16
17#include <algorithm>
18
20
21namespace QV4 {
22
24
26 QV4::Scope scope(s->engine());
27
28 Heap::ReferenceObject::Flags flags =
29 Heap::ReferenceObject::EnforcesLocation;
30 if (s->d()->metaSequence().canSetValueAtIndex())
31 flags |= Heap::ReferenceObject::CanWriteBack;
32 if (s->d()->valueMetaType() == QMetaType::fromType<QVariant>())
33 flags |= Heap::ReferenceObject::IsVariant;
34
36 s->at(index), s->d(), index, flags));
39 ref->d()->setLocation(frame->v4Function, frame->statementNumber());
40 // No need to read the reference. at() has done that already.
41 }
42 return v->asReturnedValue();
43}
44
45template<typename Compare>
46void sortSequence(Sequence *sequence, const Compare &compare)
47{
48 /* non-const */ Heap::Sequence *p = sequence->d();
49
50 QSequentialIterable iterable(p->metaSequence(), p->listType(), p->storagePointer());
51 if (iterable.canRandomAccessIterate()) {
52 std::sort(QSequentialIterable::RandomAccessIterator(iterable.mutableBegin()),
53 QSequentialIterable::RandomAccessIterator(iterable.mutableEnd()),
54 compare);
55 } else if (iterable.canReverseIterate()) {
56 std::sort(QSequentialIterable::BidirectionalIterator(iterable.mutableBegin()),
57 QSequentialIterable::BidirectionalIterator(iterable.mutableEnd()),
58 compare);
59 } else {
60 qWarning() << "Container has no suitable iterator for sorting";
61 }
62}
63
64// helper function to generate valid warnings if errors occur during sequence operations.
65static void generateWarning(QV4::ExecutionEngine *v4, const QString& description)
66{
68 if (!engine)
69 return;
70 QQmlError retn;
71 retn.setDescription(description);
72
73 QV4::CppStackFrame *stackFrame = v4->currentStackFrame;
74
75 retn.setLine(stackFrame->lineNumber());
76 retn.setUrl(QUrl(stackFrame->source()));
78}
79
81{
82 ~SequenceOwnPropertyKeyIterator() override = default;
83 PropertyKey next(const Object *o, Property *pd = nullptr, PropertyAttributes *attrs = nullptr) override
84 {
85 const Sequence *s = static_cast<const Sequence *>(o);
86
87 if (s->d()->isReference() && !s->loadReference())
88 return PropertyKey::invalid();
89
90 const qsizetype size = s->size();
91 if (size > 0 && qIsAtMostSizetypeLimit(arrayIndex, size - 1)) {
92 const uint index = arrayIndex;
93 ++arrayIndex;
94 if (attrs)
96 if (pd)
97 pd->value = doGetIndexed(s, index);
99 }
100
101 if (memberIndex == 0) {
102 ++memberIndex;
103 return o->engine()->id_length()->propertyKey();
104 }
105
106 // You cannot add any own properties via the regular JavaScript interfaces.
107 return PropertyKey::invalid();
108 }
109};
110
112{
114 : m_v4(v4), m_compareFn(&compareFn)
115 {}
116
117 bool operator()(const QVariant &lhs, const QVariant &rhs)
118 {
119 QV4::Scope scope(m_v4);
120 ScopedFunctionObject compare(scope, m_compareFn);
121 if (!compare)
122 return m_v4->throwTypeError();
123 Value *argv = scope.alloc(2);
124 argv[0] = m_v4->fromVariant(lhs);
125 argv[1] = m_v4->fromVariant(rhs);
126 QV4::ScopedValue result(scope, compare->call(m_v4->globalObject, argv, 2));
127 if (scope.hasException())
128 return false;
129 return result->toNumber() < 0;
130 }
131
132private:
134 const QV4::Value *m_compareFn;
135};
136
138{
139 bool operator()(const QVariant &lhs, const QVariant &rhs)
140 {
141 return lhs.toString() < rhs.toString();
142 }
143};
144
145void Heap::Sequence::initTypes(QMetaType listType, QMetaSequence metaSequence)
146{
147 m_listType = listType.iface();
148 Q_ASSERT(m_listType);
149 m_metaSequence = metaSequence.iface();
150 Q_ASSERT(m_metaSequence);
152 QV4::Scoped<QV4::Sequence> o(scope, this);
153 o->setArrayType(Heap::ArrayData::Custom);
154}
155
156void Heap::Sequence::init(QMetaType listType, QMetaSequence metaSequence, const void *container)
157{
158 ReferenceObject::init(nullptr, -1, NoFlag);
159 initTypes(listType, metaSequence);
160 m_container = listType.create(container);
161}
162
164 QMetaType listType, QMetaSequence metaSequence, const void *container,
165 Heap::Object *object, int propertyIndex, Heap::ReferenceObject::Flags flags)
166{
167 ReferenceObject::init(object, propertyIndex, flags);
168 initTypes(listType, metaSequence);
169
170 if (CppStackFrame *frame = internalClass->engine->currentStackFrame)
171 setLocation(frame->v4Function, frame->statementNumber());
172 if (container)
173 m_container = listType.create(container);
174 else if (flags & EnforcesLocation)
176}
177
179{
180 return internalClass->engine->memoryManager->allocate<QV4::Sequence>(
181 QMetaType(m_listType), QMetaSequence(m_metaSequence), m_container);
182}
183
185{
186 if (m_container)
187 listType().destroy(m_container);
188 ReferenceObject::destroy();
189}
190
192{
193 if (!m_container)
194 m_container = listType().create();
195 return m_container;
196}
197
199{
200 const QMetaType variantReferenceType = variant.metaType();
201 if (variantReferenceType != listType()) {
202 // This is a stale reference. That is, the property has been
203 // overwritten with a different type in the meantime.
204 // We need to modify this reference to the updated type, if
205 // possible, or return false if it is not a sequence.
206 const QQmlType newType = QQmlMetaType::qmlListType(variantReferenceType);
207 if (newType.isSequentialContainer()) {
208 if (m_container)
209 listType().destroy(m_container);
210 m_listType = newType.qListTypeId().iface();
211 m_metaSequence = newType.listMetaSequence().iface();
212 m_container = listType().create(variant.constData());
213 return true;
214 } else {
215 return false;
216 }
217 }
218 if (m_container) {
219 variantReferenceType.destruct(m_container);
220 variantReferenceType.construct(m_container, variant.constData());
221 } else {
222 m_container = variantReferenceType.create(variant.constData());
223 }
224 return true;
225}
227{
228 return QVariant(listType(), m_container);
229}
230
232{
233 const auto *p = d();
234 Q_ASSERT(p->storagePointer()); // Must readReference() before
235 return p->metaSequence().size(p->storagePointer());
236}
237
239{
240 const auto *p = d();
241 Q_ASSERT(p->storagePointer()); // Must readReference() before
242 const QMetaType v = p->valueMetaType();
244 if (v == QMetaType::fromType<QVariant>()) {
245 p->metaSequence().valueAtIndex(p->storagePointer(), index, &result);
246 } else {
247 result = QVariant(v);
248 p->metaSequence().valueAtIndex(p->storagePointer(), index, result.data());
249 }
250 return result;
251}
252
253
254template<typename Action>
255void convertAndDo(const QVariant &item, const QMetaType v, Action action)
256{
257 if (item.metaType() == v) {
258 action(item.constData());
259 } else if (v == QMetaType::fromType<QVariant>()) {
260 action(&item);
261 } else {
262 QVariant converted = item;
263 if (!converted.convert(v))
264 converted = QVariant(v);
265 action(converted.constData());
266 }
267}
268
270{
271 Heap::Sequence *p = d();
272 convertAndDo(item, p->valueMetaType(), [p](const void *data) {
273 p->metaSequence().addValueAtEnd(p->storagePointer(), data);
274 });
275}
276
278{
279 Heap::Sequence *p = d();
280 convertAndDo(item, p->valueMetaType(), [p, num](const void *data) {
281 const QMetaSequence m = p->metaSequence();
282 void *container = p->storagePointer();
283 for (qsizetype i = 0; i < num; ++i)
284 m.addValueAtEnd(container, data);
285 });
286}
287
289{
290 Heap::Sequence *p = d();
291 convertAndDo(item, p->valueMetaType(), [p, index](const void *data) {
292 p->metaSequence().setValueAtIndex(p->storagePointer(), index, data);
293 });
294}
295
297{
298 auto *p = d();
299 const QMetaSequence m = p->metaSequence();
300
301 if (m.canEraseRangeAtIterator() && m.hasRandomAccessIterator() && num > 1) {
302 void *i = m.end(p->storagePointer());
303 m.advanceIterator(i, -num);
304 void *j = m.end(p->storagePointer());
305 m.eraseRangeAtIterator(p->storagePointer(), i, j);
306 m.destroyIterator(i);
307 m.destroyIterator(j);
308 } else {
309 for (int i = 0; i < num; ++i)
310 m.removeValueAtEnd(p->storagePointer());
311 }
312}
313
315{
316 if (d()->isReference() && !loadReference())
317 return Encode::undefined();
318
319 if (index >= 0 && index < size()) {
320 if (hasProperty)
321 *hasProperty = true;
322 return doGetIndexed(this, index);
323 }
324 if (hasProperty)
325 *hasProperty = false;
326 return Encode::undefined();
327}
328
330{
332 return false;
333
334 if (d()->isReadOnly()) {
335 engine()->throwTypeError(QLatin1String("Cannot insert into a readonly container"));
336 return false;
337 }
338
339 if (d()->isReference() && !loadReference())
340 return false;
341
342 const qsizetype count = size();
343 const QMetaType valueType = d()->valueMetaType();
344 const QVariant element = ExecutionEngine::toVariant(value, valueType, false);
345
346 if (index < 0)
347 return false;
348
349 if (index == count) {
350 append(element);
351 } else if (index < count) {
352 replace(index, element);
353 } else {
354 /* according to ECMA262r3 we need to insert */
355 /* the value at the given index, increasing length to index+1. */
357 valueType == QMetaType::fromType<QVariant>() ? QVariant() : QVariant(valueType));
358 append(element);
359 }
360
361 if (d()->object())
362 storeReference();
363 return true;
364}
365
371
373{
374 if (d()->isReadOnly())
375 return false;
376 if (d()->isReference() && !loadReference())
377 return false;
378 if (index < 0 || index >= size())
379 return false;
380
381 /* according to ECMA262r3 it should be Undefined, */
382 /* but we cannot, so we insert a default-value instead. */
383 replace(index, QVariant());
384
385 if (d()->object())
386 storeReference();
387
388 return true;
389}
390
392{
393 if (!other)
394 return false;
395 Sequence *otherSequence = other->as<Sequence>();
396 if (!otherSequence)
397 return false;
398 if (d()->object() && otherSequence->d()->object()) {
399 return d()->object() == otherSequence->d()->object()
400 && d()->property() == otherSequence->d()->property();
401 } else if (!d()->object() && !otherSequence->d()->object()) {
402 return this == otherSequence;
403 }
404 return false;
405}
406
407bool Sequence::sort(const FunctionObject *f, const Value *, const Value *argv, int argc)
408{
409 if (d()->isReadOnly())
410 return false;
411 if (d()->isReference() && !loadReference())
412 return false;
413
414 if (argc == 1 && argv[0].as<FunctionObject>())
415 sortSequence(this, SequenceCompareFunctor(f->engine(), argv[0]));
416 else
418
419 if (d()->object())
420 storeReference();
421
422 return true;
423}
424
426{ return d()->storagePointer(); }
427
429{
430 Q_ASSERT(d()->object());
431 // If locations are enforced we only read once
432 return d()->enforcesLocation() || QV4::ReferenceObject::readReference(d());
433}
434
436{
437 Q_ASSERT(d()->object());
438 return d()->isAttachedToProperty() && QV4::ReferenceObject::writeBack(d());
439}
440
441ReturnedValue Sequence::virtualGet(const Managed *that, PropertyKey id, const Value *receiver, bool *hasProperty)
442{
443 if (id.isArrayIndex()) {
444 const uint index = id.asArrayIndex();
446 return static_cast<const Sequence *>(that)->containerGetIndexed(qsizetype(index), hasProperty);
447
448 generateWarning(that->engine(), QLatin1String("Index out of range during indexed get"));
449 return false;
450 }
451
452 return Object::virtualGet(that, id, receiver, hasProperty);
453}
454
456{
457 const Sequence *s = static_cast<const Sequence *>(m);
458 if (s->d()->isReference() && !s->loadReference())
459 return 0;
460 return s->size();
461}
462
463bool Sequence::virtualPut(Managed *that, PropertyKey id, const Value &value, Value *receiver)
464{
465 if (id.isArrayIndex()) {
466 const uint index = id.asArrayIndex();
468 return static_cast<Sequence *>(that)->containerPutIndexed(qsizetype(index), value);
469
470 generateWarning(that->engine(), QLatin1String("Index out of range during indexed set"));
471 return false;
472 }
473 return Object::virtualPut(that, id, value, receiver);
474}
475
477{
478 if (id.isArrayIndex()) {
479 const uint index = id.asArrayIndex();
481 return static_cast<Sequence *>(that)->containerDeleteIndexedProperty(qsizetype(index));
482
483 generateWarning(that->engine(), QLatin1String("Index out of range during indexed delete"));
484 return false;
485 }
486 return Object::virtualDeleteProperty(that, id);
487}
488
490{
491 return static_cast<Sequence *>(that)->containerIsEqualTo(other);
492}
493
498
500{
501 Sequence *sequence = static_cast<Sequence *>(object);
502 Q_ASSERT(sequence);
503
504 switch (call) {
506 const QMetaType valueType = sequence->d()->valueMetaType();
507 if (sequence->d()->isReference() && !sequence->loadReference())
508 return 0;
509 const QMetaSequence metaSequence = sequence->d()->metaSequence();
510 if (metaSequence.valueMetaType() != valueType)
511 return 0; // value metatype is not what the caller expects anymore.
512
513 const void *storagePointer = sequence->d()->storagePointer();
514 if (index < 0 || index >= metaSequence.size(storagePointer))
515 return 0;
517 break;
518 }
520 void *storagePointer = sequence->d()->storagePointer();
521 const QMetaSequence metaSequence = sequence->d()->metaSequence();
522 if (index < 0 || index >= metaSequence.size(storagePointer))
523 return 0;
525 if (sequence->d()->isReference())
526 sequence->storeReference();
527 break;
528 }
529 default:
530 return 0; // not supported
531 }
532
533 return -1;
534}
535
536static QV4::ReturnedValue method_get_length(const FunctionObject *b, const Value *thisObject, const Value *, int)
537{
538 QV4::Scope scope(b);
539 QV4::Scoped<Sequence> This(scope, thisObject->as<Sequence>());
540 if (!This)
542
543 if (This->d()->isReference() && !This->loadReference())
544 return Encode::undefined();
545
546 const qsizetype size = This->size();
549
550 return scope.engine->throwRangeError(QLatin1String("Sequence length out of range"));
551}
552
553static QV4::ReturnedValue method_set_length(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
554{
555 QV4::Scope scope(f);
556 QV4::Scoped<Sequence> This(scope, thisObject->as<Sequence>());
557 if (!This)
559
560 bool ok = false;
561 const quint32 argv0 = argc ? argv[0].asArrayLength(&ok) : 0;
562 if (!ok || !qIsAtMostSizetypeLimit(argv0)) {
563 generateWarning(scope.engine, QLatin1String("Index out of range during length set"));
565 }
566
567 if (This->d()->isReadOnly())
569
570 const qsizetype newCount = qsizetype(argv0);
571
572 /* Read the sequence from the QObject property if we're a reference */
573 if (This->d()->isReference() && !This->loadReference())
575
576 /* Determine whether we need to modify the sequence */
577 const qsizetype count = This->size();
578 if (newCount == count) {
580 } else if (newCount > count) {
581 const QMetaType valueMetaType = This->d()->valueMetaType();
582 /* according to ECMA262r3 we need to insert */
583 /* undefined values increasing length to newLength. */
584 /* We cannot, so we insert default-values instead. */
585 This->append(newCount - count, QVariant(valueMetaType));
586 } else {
587 /* according to ECMA262r3 we need to remove */
588 /* elements until the sequence is the required length. */
589 Q_ASSERT(newCount < count);
590 This->removeLast(count - newCount);
591 }
592
593 /* write back if required. */
594 if (This->d()->object())
595 This->storeReference();
596
598}
599
601{
602 defineDefaultProperty(QStringLiteral("sort"), method_sort, 1);
603 defineDefaultProperty(engine()->id_valueOf(), method_valueOf, 0);
604 defineAccessorProperty(QStringLiteral("length"), method_get_length, method_set_length);
605}
606
608{
609 return Encode(thisObject->toString(f->engine()));
610}
611
612ReturnedValue SequencePrototype::method_sort(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
613{
614 Scope scope(b);
615 QV4::ScopedObject o(scope, thisObject);
616 if (!o || !o->isV4SequenceType())
618
619 if (argc >= 2)
620 return o.asReturnedValue();
621
622 if (auto *s = o->as<Sequence>()) {
623 if (!s->sort(b, thisObject, argv, argc))
625 }
626
627 return o.asReturnedValue();
628}
629
631 QV4::ExecutionEngine *engine, QMetaType type, QMetaSequence metaSequence, const void *data,
632 Heap::Object *object, int propertyIndex, Heap::ReferenceObject::Flags flags)
633{
634 // This function is called when the property is a QObject Q_PROPERTY of
635 // the given sequence type. Internally we store a sequence
636 // (as well as object ptr + property index for updated-read and write-back)
637 // and so access/mutate avoids variant conversion.
638
639 return engine->memoryManager->allocate<Sequence>(
640 type, metaSequence, data, object, propertyIndex, flags)->asReturnedValue();
641}
642
644{
645 const QMetaType type = v.metaType();
646 const QQmlType qmlType = QQmlMetaType::qmlListType(type);
647 if (qmlType.isSequentialContainer())
648 return fromData(engine, type, qmlType.listMetaSequence(), v.constData());
649
650 QSequentialIterable iterable;
652 type, v.constData(), QMetaType::fromType<QSequentialIterable>(), &iterable)) {
653 return fromData(engine, type, iterable.metaContainer(), v.constData());
654 }
655
656 return Encode::undefined();
657}
658
660 ExecutionEngine *engine, QMetaType type, QMetaSequence metaSequence, const void *data)
661{
662 // This function is called when assigning a sequence value to a normal JS var
663 // in a JS block. Internally, we store a sequence of the specified type.
664 // Access and mutation is extremely fast since it will not need to modify any
665 // QObject property.
666
667 return engine->memoryManager->allocate<Sequence>(type, metaSequence, data)->asReturnedValue();
668}
669
671{
672 Q_ASSERT(object->isV4SequenceType());
673 const auto *p = object->d();
674
675 // Note: For historical reasons, we ignore the result of loadReference()
676 // here. This allows us to retain sequences whose objects have vaninshed
677 // as "var" properties. It comes at the price of potentially returning
678 // outdated data. This is the behavior sequences have always shown.
679 if (p->isReference())
680 object->loadReference();
681 if (!p->hasData())
682 return QVariant();
683
684 return QVariant(p->listType(), p->storagePointer());
685}
686
688{
689 if (!array.as<ArrayObject>())
690 return QVariant();
691
692 QV4::Scope scope(array.as<Object>()->engine());
694
695 const QQmlType type = QQmlMetaType::qmlListType(typeHint);
696 if (type.isSequentialContainer()) {
697 const QQmlTypePrivate *priv = type.priv();
698 const QMetaSequence *meta = &priv->extraData.sequentialContainerTypeData;
699 const QMetaType containerMetaType(priv->listId);
700 QVariant result(containerMetaType);
701 qint64 length = a->getLength();
702 Q_ASSERT(length >= 0);
703 Q_ASSERT(length <= qint64(std::numeric_limits<quint32>::max()));
704
705 QV4::ScopedValue v(scope);
706 for (quint32 i = 0; i < quint32(length); ++i) {
707 const QMetaType valueMetaType = priv->typeId;
708 QVariant variant = ExecutionEngine::toVariant(a->get(i), valueMetaType, false);
709 if (valueMetaType == QMetaType::fromType<QVariant>()) {
710 meta->addValueAtEnd(result.data(), &variant);
711 } else {
712 const QMetaType originalType = variant.metaType();
713 if (originalType != valueMetaType) {
715 variant, valueMetaType);
716 if (converted.isValid()) {
717 variant = converted;
718 } else if (!variant.convert(valueMetaType) && originalType.isValid()) {
719 // If the original type was void, we're converting a "hole" in a sparse
720 // array. There is no point in warning about that.
721 qWarning().noquote()
722 << QLatin1String("Could not convert array value "
723 "at position %1 from %2 to %3")
725 QString::fromUtf8(originalType.name()),
726 QString::fromUtf8(valueMetaType.name()));
727 }
728 }
729 meta->addValueAtEnd(result.data(), variant.constData());
730 }
731 }
732 return result;
733 }
734
735 return QVariant();
736}
737
739{
740 if (object->d()->listType() == typeHint)
741 return object->getRawContainerPtr();
742 return nullptr;
743}
744
746{
747 return object->d()->listType();
748}
749
750} // namespace QV4
751
753
754#include "moc_qv4sequenceobject_p.cpp"
QString arg(Args &&...args) const
void * end(void *container) const
Creates and returns a non-const iterator pointing to the end of container.
qsizetype size(const void *container) const
Returns the number of values in the given container if it can be queried for its size.
\inmodule QtCore
void setValueAtIndex(void *container, qsizetype index, const void *value) const
Overwrites the value at index in the container using the value passed as parameter if that is possibl...
void addValueAtEnd(void *container, const void *value) const
Adds value to the end of container if possible.
const QtMetaContainerPrivate::QMetaSequenceInterface * iface() const
QMetaType valueMetaType() const
Returns the meta type for values stored in the container.
void valueAtIndex(const void *container, qsizetype index, void *result) const
Retrieves the value at index in the container and places it in the memory location pointed to by resu...
\inmodule QtCore
Definition qmetatype.h:341
const QtPrivate::QMetaTypeInterface * iface() const
Definition qmetatype.h:771
bool isValid() const
void destroy(void *data) const
void * create(const void *copy=nullptr) const
constexpr const char * name() const
Definition qmetatype.h:2680
static bool convert(QMetaType fromType, const void *from, QMetaType toType, void *to)
Converts the object at from from fromType to the preallocated space at to typed toType.
void warning(const QQmlError &)
The QQmlEngine class provides an environment for instantiating QML components.
Definition qqmlengine.h:57
The QQmlError class encapsulates a QML error.
Definition qqmlerror.h:18
void setDescription(const QString &)
Sets the error description.
static QQmlType qmlListType(QMetaType metaType)
bool isSequentialContainer() const
Definition qqmltype.cpp:658
QMetaSequence listMetaSequence() const
Definition qqmltype.cpp:678
static QVariant createValueType(const QJSValue &, QMetaType)
The QSequentialIterable class is an iterable interface for a container in a QVariant.
QTaggedIterator< iterator, std::bidirectional_iterator_tag > BidirectionalIterator
Exposes an iterator using std::bidirectional_iterator_tag.
QTaggedIterator< iterator, std::random_access_iterator_tag > RandomAccessIterator
Exposes an iterator using std::random_access_iterator_tag.
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:6018
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:8084
\inmodule QtCore
Definition qurl.h:94
ObjectType::Data * allocate(Args &&... args)
Definition qv4mm_p.h:298
\inmodule QtCore
Definition qvariant.h:65
bool convert(QMetaType type)
Casts the variant to the requested type, targetType.
bool isValid() const
Returns true if the storage type of this variant is not QMetaType::UnknownType; otherwise returns fal...
Definition qvariant.h:714
QString toString() const
Returns the variant as a QString if the variant has a userType() including, but not limited to:
QMetaType metaType() const
const void * constData() const
Definition qvariant.h:451
list append(new Employee("Blackpool", "Stephen"))
Combined button and popup list for selecting options.
Scoped< FunctionObject > ScopedFunctionObject
static void generateWarning(QV4::ExecutionEngine *v4, const QString &description)
static QV4::ReturnedValue method_set_length(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
quint64 ReturnedValue
static QV4::ReturnedValue method_get_length(const FunctionObject *b, const Value *thisObject, const Value *, int)
static ReturnedValue doGetIndexed(const Sequence *s, qsizetype index)
void sortSequence(Sequence *sequence, const Compare &compare)
void convertAndDo(const QVariant &item, const QMetaType v, Action action)
@ Attr_Data
SequenceOwnPropertyKeyIterator * containerOwnPropertyKeys(const Object *m, Value *target)
static struct AttrInfo attrs[]
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define qWarning
Definition qlogging.h:166
static const QMetaObjectPrivate * priv(const uint *data)
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
const GLfloat * m
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint index
[2]
GLenum GLuint GLenum GLsizei length
GLenum GLenum GLsizei count
GLuint object
[3]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLfloat GLfloat f
GLenum type
GLenum target
GLbitfield flags
GLint ref
GLdouble s
[6]
Definition qopenglext.h:235
GLenum array
GLuint64EXT * result
[6]
GLfloat GLfloat p
[1]
GLuint num
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
#define QStringLiteral(str)
static int compare(quint64 a, quint64 b)
unsigned int quint32
Definition qtypes.h:50
ptrdiff_t qsizetype
Definition qtypes.h:165
unsigned int uint
Definition qtypes.h:34
long long qint64
Definition qtypes.h:60
QT_BEGIN_NAMESPACE bool qIsAtMostUintLimit(qsizetype length, uint limit=std::numeric_limits< uint >::max())
bool qIsAtMostSizetypeLimit(uint length, qsizetype limit=std::numeric_limits< qsizetype >::max())
#define THROW_TYPE_ERROR()
#define RETURN_UNDEFINED()
#define RETURN_RESULT(r)
#define DEFINE_OBJECT_VTABLE(classname)
QVariant variant
[1]
QSharedPointer< T > other(t)
[5]
QGraphicsItem * item
QFrame frame
[0]
QJSEngine engine
[0]
static constexpr ReturnedValue undefined()
MemoryManager * memoryManager
CppStackFrame * currentStackFrame
ReturnedValue throwRangeError(const Value &value)
QV4::ReturnedValue fromVariant(const QVariant &)
static QVariant toVariant(const QV4::Value &value, QMetaType typeHint, bool createJSValueForObjectsAndSymbols=true)
QQmlEngine * qmlEngine() const
ReturnedValue throwTypeError()
Sequence * detached() const
void init(QMetaType listType, QMetaSequence metaSequence, const void *container)
QVariant toVariant() const
QMetaType listType() const
bool setVariant(const QVariant &variant)
QMetaSequence metaSequence() const
Heap::InternalClass * internalClass() const
ExecutionEngine * engine() const
bool hasProperty(PropertyKey id) const
static PropertyKey invalid()
static PropertyKey fromArrayIndex(uint idx)
static bool writeBack(HeapObject *ref, int internalIndex=AllProperties)
static bool readReference(HeapObject *ref)
Value * alloc(qint64 nValues) const =delete
bool hasException() const
ExecutionEngine * engine
SequenceCompareFunctor(QV4::ExecutionEngine *v4, const QV4::Value &compareFn)
bool operator()(const QVariant &lhs, const QVariant &rhs)
bool operator()(const QVariant &lhs, const QVariant &rhs)
PropertyKey next(const Object *o, Property *pd=nullptr, PropertyAttributes *attrs=nullptr) override
~SequenceOwnPropertyKeyIterator() override=default
static ReturnedValue newSequence(QV4::ExecutionEngine *engine, QMetaType type, QMetaSequence metaSequence, const void *data, Heap::Object *object, int propertyIndex, Heap::ReferenceObject::Flags flags)
static ReturnedValue method_sort(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static QVariant toVariant(const Sequence *object)
static QMetaType metaTypeForSequence(const Sequence *object)
static void * getRawContainerPtr(const Sequence *object, QMetaType typeHint)
static ReturnedValue fromVariant(QV4::ExecutionEngine *engine, const QVariant &vd)
static ReturnedValue fromData(QV4::ExecutionEngine *engine, QMetaType type, QMetaSequence metaSequence, const void *data)
static ReturnedValue method_valueOf(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
QV4::ReturnedValue containerGetIndexed(qsizetype index, bool *hasProperty) const
bool sort(const FunctionObject *f, const Value *, const Value *argv, int argc)
bool containerPutIndexed(qsizetype index, const QV4::Value &value)
bool containerDeleteIndexedProperty(qsizetype index)
bool containerIsEqualTo(Managed *other)
void * getRawContainerPtr() const
bool loadReference() const
void removeLast(qsizetype num)
void append(const QVariant &item)
QVariant at(qsizetype index) const
void replace(qsizetype index, const QVariant &item)
qsizetype size() const
QV4_NEARLY_ALWAYS_INLINE constexpr quint32 value() const
static constexpr VTable::OwnPropertyKeys virtualOwnPropertyKeys
static constexpr VTable::DeleteProperty virtualDeleteProperty
static constexpr VTable::Get virtualGet
static constexpr VTable::Metacall virtualMetacall
static constexpr VTable::GetLength virtualGetLength
static constexpr VTable::Put virtualPut
static constexpr VTable::IsEqualTo virtualIsEqualTo
Heap::String * toString(ExecutionEngine *e) const
Definition qv4value_p.h:114
uint asArrayLength(bool *ok) const
Definition qv4value.cpp:275
const T * as() const
Definition qv4value_p.h:132