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
qqmlvmemetaobject.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// Copyright (C) 2016 BasysKom GmbH.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
6
7#include <private/qqmlrefcount_p.h>
9#include <qqmlinfo.h>
10
11#include <private/qqmlglobal_p.h>
12
13#include <private/qv4object_p.h>
14#include <private/qv4variantobject_p.h>
15#include <private/qv4functionobject_p.h>
16#include <private/qv4scopedvalue_p.h>
17#include <private/qv4jscall_p.h>
18#include <private/qv4qobjectwrapper_p.h>
19#include <private/qv4sequenceobject_p.h>
20#include <private/qqmlpropertycachecreator_p.h>
21#include <private/qqmlpropertycachemethodarguments_p.h>
22#include <private/qqmlvaluetypewrapper_p.h>
23
24#include <QtCore/qsequentialiterable.h>
25
26#include <climits> // for CHAR_BIT
27
29
30QQmlVMEResolvedList::QQmlVMEResolvedList(QQmlListProperty<QObject> *prop)
31{
32 // see QQmlVMEMetaObject::metaCall for how this was constructed
33 auto encodedIndex = quintptr(prop->data);
34 constexpr quintptr usableBits = sizeof(quintptr) * CHAR_BIT;
35 quintptr inheritanceDepth = encodedIndex >> (usableBits / 2);
36 m_id = encodedIndex & ((quintptr(1) << (usableBits / 2)) - 1);
37
38 // walk up to the correct meta object if necessary
39 auto mo = static_cast<QQmlVMEMetaObject *>(QObjectPrivate::get(prop->object)->metaObject);
40 while (inheritanceDepth--)
41 mo = mo->parentVMEMetaObject();
42 m_metaObject = mo;
43 Q_ASSERT(m_metaObject);
44 Q_ASSERT(::strstr(m_metaObject->toDynamicMetaObject(prop->object)
45 ->property(m_metaObject->propOffset() + m_id)
46 .typeName(),
47 "QQmlListProperty"));
48 Q_ASSERT(m_metaObject->object == prop->object);
49
50 // readPropertyAsList() with checks transformed into Q_ASSERT
51 // and without allocation.
52 if (m_metaObject->propertyAndMethodStorage.isUndefined()
53 && m_metaObject->propertyAndMethodStorage.valueRef()) {
54 return;
55 }
56
57 if (auto *md = static_cast<QV4::MemberData *>(
58 m_metaObject->propertyAndMethodStorage.asManaged())) {
59 const QV4::Value *v = md->data() + m_id;
60 Q_ASSERT(v->as<QV4::Object>());
61 m_list = static_cast<QV4::Heap::Object *>(v->heapObject());
62 Q_ASSERT(m_list);
63 }
64}
65
67{
68 QV4::Scope scope(m_list->internalClass->engine);
69 QV4::Heap::ArrayData *arrayData = m_list->arrayData;
70
71 const uint length = arrayData->length();
72 if (Q_UNLIKELY(length == std::numeric_limits<uint>::max())) {
73 scope.engine->throwRangeError(QLatin1String("Too many elements."));
74 return;
75 }
76
77 QV4::ScopedObject object(scope, m_list);
78 QV4::ArrayData::realloc(object, QV4::Heap::ArrayData::Simple, length + 1, false);
79 arrayData->vtable()->put(
80 object, length, QV4::QObjectWrapper::wrap(scope.engine, o));
81}
82
84{
85 QV4::Scope scope(m_list->internalClass->engine);
86 QV4::Scoped<QV4::QObjectWrapper> result(scope, m_list->arrayData->get(i));
87 return result ? result->object() : nullptr;
88}
89
91{
92 QV4::Scope scope(m_list->internalClass->engine);
93 QV4::ScopedObject object(scope, m_list);
94 m_list->arrayData->vtable()->put(object, i, QV4::QObjectWrapper::wrap(scope.engine, o));
95}
96
98
100{
101 m_metaObject->activate(m_metaObject->object, int(m_id + m_metaObject->methodOffset()), nullptr);
102}
103
104void QQmlVMEMetaObject::list_append(QQmlListProperty<QObject> *prop, QObject *o)
105{
106 const QQmlVMEResolvedList resolved(prop);
107 resolved.append(o);
108 resolved.activateSignal();
109}
110
111void QQmlVMEMetaObject::list_append_nosignal(QQmlListProperty<QObject> *prop, QObject *o)
112{
114}
115
116static qsizetype list_count(QQmlListProperty<QObject> *prop)
117{
118 return QQmlVMEResolvedList(prop).size();
119}
120
121static QObject *list_at(QQmlListProperty<QObject> *prop, qsizetype index)
122{
123 return QQmlVMEResolvedList(prop).at(index);
124}
125
126void QQmlVMEMetaObject::list_clear(QQmlListProperty<QObject> *prop)
127{
128 const QQmlVMEResolvedList resolved(prop);
129 resolved.clear();
130 resolved.activateSignal();
131}
132
133void QQmlVMEMetaObject::list_clear_nosignal(QQmlListProperty<QObject> *prop)
134{
136}
137
138static void list_replace(QQmlListProperty<QObject> *prop, qsizetype index, QObject *o)
139{
140 const QQmlVMEResolvedList resolved(prop);
141 resolved.replace(index, o);
142 resolved.activateSignal();
143}
144
145static void list_removeLast(QQmlListProperty<QObject> *prop)
146{
147 const QQmlVMEResolvedList resolved(prop);
148 resolved.removeLast();
149 resolved.activateSignal();
150}
151
153 : QQmlGuard<QObject>(QQmlVMEVariantQObjectPtr::objectDestroyedImpl, nullptr), m_target(nullptr), m_index(-1)
154{
155}
156
157void QQmlVMEVariantQObjectPtr::objectDestroyedImpl(QQmlGuardImpl *guard)
158{
159 auto This = static_cast<QQmlVMEVariantQObjectPtr *>(guard);
160 if (!This->m_target || QQmlData::wasDeleted(This->m_target->object))
161 return;
162
163 if (This->m_index >= 0) {
164 QV4::ExecutionEngine *v4 = This->m_target->propertyAndMethodStorage.engine();
165 if (v4) {
166 QV4::Scope scope(v4);
167 QV4::Scoped<QV4::MemberData> sp(scope, This->m_target->propertyAndMethodStorage.value());
168 if (sp) {
169 QV4::PropertyIndex index{ sp->d(), sp->d()->values.values + This->m_index };
170 index.set(v4, QV4::Value::nullValue());
171 }
172 }
173
174 This->m_target->activate(This->m_target->object, This->m_target->methodOffset() + This->m_index, nullptr);
175 }
176}
177
184
186{
187public:
189 void tryConnect();
190
195
196 QTaggedPointer<QQmlVMEMetaObject, Tag> metaObject;
197};
198
203
209
211{
213 int aliasId = this - metaObject->aliasEndpoints;
214
216 // This is actually notify
217 int sigIdx = metaObject->methodOffset() + aliasId + metaObject->compiledObject->nProperties;
218 metaObject->activate(metaObject->object, sigIdx, nullptr);
219 } else {
220 const QV4::CompiledData::Alias *aliasData = &metaObject->compiledObject->aliasTable()[aliasId];
221 if (!aliasData->isObjectAlias()) {
222 QQmlRefPointer<QQmlContextData> ctxt = metaObject->ctxt;
223 QObject *target = ctxt->idValue(aliasData->targetObjectId());
224 if (!target)
225 return;
226
228 int coreIndex = encodedIndex.coreIndex();
229 int valueTypeIndex = encodedIndex.valueTypeIndex();
230 const QQmlPropertyData *pd = QQmlData::ensurePropertyCache(target)->property(coreIndex);
231 if (pd && valueTypeIndex != -1 && !QQmlMetaType::valueType(pd->propType())) {
232 // deep alias
233 const QQmlPropertyCache::ConstPtr newPropertyCache
235 void *argv[1] = { &target };
237 Q_ASSERT(newPropertyCache);
238 pd = newPropertyCache->property(valueTypeIndex);
239 }
240 if (!pd)
241 return;
242
243 if (pd->notifyIndex() != -1 && ctxt->engine())
244 connect(target, pd->notifyIndex(), ctxt->engine());
245 }
246
248 }
249}
250
251
253 : object(obj),
254 cache(cache)
255{
257
258 if (op->metaObject) {
259 parent = op->metaObject;
260 // Use the extra flag in QBiPointer to know if we can safely cast parent.asT1() to QQmlVMEMetaObject*
261 parent.setFlagValue(QQmlData::get(obj)->hasVMEMetaObject);
262 } else {
263 parent = obj->metaObject();
264 }
265
266 op->metaObject = this;
267 QQmlData::get(obj)->hasInterceptorMetaObject = true;
268}
269
274
276{
277 for (QQmlPropertyValueInterceptor *vi = interceptors; vi; vi = vi->m_next) {
278 if (Q_UNLIKELY(vi->m_propertyIndex.coreIndex() == index.coreIndex())) {
279 qWarning() << "Attempting to set another interceptor on "
280 << object->metaObject()->className() << "property"
281 << object->metaObject()->property(index.coreIndex()).name()
282 << "- unsupported";
283 }
284 }
285
286 interceptor->m_propertyIndex = index;
287 interceptor->m_next = interceptors;
288 interceptors = interceptor;
289}
290
292{
293 Q_ASSERT(o == object);
294 Q_UNUSED(o);
295
296 if (intercept(c, id, a))
297 return -1;
298 return object->qt_metacall(c, id, a);
299}
300
301bool QQmlInterceptorMetaObject::doIntercept(QMetaObject::Call c, int id, void **a)
302{
303 for (QQmlPropertyValueInterceptor *vi = interceptors; vi; vi = vi->m_next) {
304 if (vi->m_propertyIndex.coreIndex() != id)
305 continue;
306
307 const int valueIndex = vi->m_propertyIndex.valueTypeIndex();
308 const QQmlData *data = QQmlData::get(object);
309 const QMetaType metaType = data->propertyCache->property(id)->propType();
310
311 if (metaType.isValid()) {
312 if (valueIndex != -1 && c == QMetaObject::WriteProperty) {
313
314 // If we didn't intend to change the property this interceptor cares about,
315 // then don't bother intercepting it. There may be an animation running on
316 // the property. We shouldn't disturb it.
317 const int changedProperty
318 = (*static_cast<int *>(a[3]) & QQmlPropertyData::HasInternalIndex)
319 ? *static_cast<int *>(a[4])
320 : QV4::ReferenceObject::AllProperties;
321 if (changedProperty == QV4::ReferenceObject::AllProperties
322 || changedProperty == valueIndex) {
323 // TODO: handle intercepting bindable properties for value types?
325 data->context->engine(), metaType);
326 Q_ASSERT(valueType);
327
328 //
329 // Consider the following case:
330 // color c = { 0.1, 0.2, 0.3 }
331 // interceptor exists on c.r
332 // write { 0.2, 0.4, 0.6 }
333 //
334 // The interceptor may choose not to update the r component at this
335 // point (for example, a behavior that creates an animation). But we
336 // need to ensure that the g and b components are updated correctly.
337 //
338 // So we need to perform a full write where the value type is:
339 // r = old value, g = new value, b = new value
340 //
341 // And then call the interceptor which may or may not write the
342 // new value to the r component.
343 //
344 // This will ensure that the other components don't contain stale data
345 // and any relevant signals are emitted.
346 //
347 // To achieve this:
348 // (1) Store the new value type as a whole (needed due to
349 // aliasing between a[0] and static storage in value type).
350 // (2) Read the entire existing value type from object -> valueType temp.
351 // (3) Read the previous value of the component being changed
352 // from the valueType temp.
353 // (4) Write the entire new value type into the temp.
354 // (5) Overwrite the component being changed with the old value.
355 // (6) Perform a full write to the value type (which may emit signals etc).
356 // (7) Issue the interceptor call with the new component value.
357 //
358
359 QMetaProperty valueProp = valueType->property(valueIndex);
360 QVariant newValue(metaType, a[0]);
361
362 valueType->read(object, id);
363 QVariant prevComponentValue = valueType->readOnGadget(valueProp);
364
365 valueType->setValue(newValue);
366 QVariant newComponentValue = valueType->readOnGadget(valueProp);
367
368 // If the intercepted value seemingly has not changed, we still need to
369 // invoke the interceptor. There may be a pending animation that will
370 // change the value soon. Such an animation needs to be canceled if the
371 // current value is explicitly set.
372 // So, we cannot return here if prevComponentValue == newComponentValue.
373 valueType->writeOnGadget(valueProp, std::move(prevComponentValue));
375
376 vi->write(newComponentValue);
377 return true;
378 }
379 } else if (c == QMetaObject::WriteProperty) {
380 vi->write(QVariant(metaType, a[0]));
381 return true;
382 } else {
383 object->qt_metacall(c, id, a);
384 QUntypedBindable target = *reinterpret_cast<QUntypedBindable *>(a[0]);
385 return vi->bindable(reinterpret_cast<QUntypedBindable *>(a[0]), target);
386 }
387 }
388 }
389
390 return false;
391}
392
394{
395 for (const QMetaObject *mo = top; mo; mo = mo->superClass()) {
396 if (o->qt_metacast(mo->className()) != nullptr)
397 return const_cast<QMetaObject *>(mo);
398 }
399 return nullptr;
400}
401
403{
404 if (!metaObject)
405 metaObject = cache->createMetaObject();
406
409
410 // ### Qt7: The const_cast is only due to toDynamicMetaObject having the wrong return type.
411 // It should be const QMetaObject *. Fix this.
412 return const_cast<QMetaObject *>(metaObject.data());
413}
414
416 QObject *obj,
417 const QQmlPropertyCache::ConstPtr &cache, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &qmlCompilationUnit, int qmlObjectId)
419 engine(engine),
420 ctxt(QQmlData::get(obj, true)->outerContext),
421 aliasEndpoints(nullptr), compilationUnit(qmlCompilationUnit), compiledObject(nullptr)
422{
424 QQmlData::get(obj)->hasVMEMetaObject = true;
425
426 if (compilationUnit && qmlObjectId >= 0) {
428
431 if (size) {
432 QV4::Heap::MemberData *data = QV4::MemberData::allocate(engine, size);
433 // we only have a weak reference below; if the VMEMetaObject is already marked
434 // (triggered by the allocate call above)
435 // we therefore might never mark the member data; consequently, mark it now
437 data->mark(ms);
438 });
440 std::fill(data->values.values, data->values.values + data->values.size, QV4::Encode::undefined());
441 }
442
443 // Need JS wrapper to ensure properties/methods are marked.
445 }
446 }
447}
448
456
458{
461 // in some situations, the QObject wrapper (and associated data,
462 // such as the varProperties array) will have been cleaned up, but the
463 // QObject ptr will not yet have been deleted (eg, waiting on deleteLater).
464 // In this situation, return 0.
465 return nullptr;
466 }
467
468 return static_cast<QV4::MemberData*>(propertyAndMethodStorage.asManaged());
469}
470
472{
474 if (md)
475 md->set(engine, id, QV4::Value::fromInt32(v));
476}
477
479{
481 if (md)
482 md->set(engine, id, QV4::Value::fromBoolean(v));
483}
484
486{
488 if (md)
489 md->set(engine, id, QV4::Value::fromDouble(v));
490}
491
493{
495 if (md) {
496 QV4::Scope scope(engine);
497 QV4::Scoped<QV4::MemberData>(scope, md)->set(engine, id, engine->newString(v));
498 }
499}
500
502{
504 if (md) {
505 QV4::Scope scope(engine);
508 }
509
511 if (v && !guard) {
512 guard = new QQmlVMEVariantQObjectPtr();
513 varObjectGuards.append(guard);
514 }
515 if (guard)
516 guard->setGuardedValue(v, this, id);
517}
518
520{
522 if (!md)
523 return 0;
524
525 QV4::Scope scope(engine);
526 QV4::ScopedValue sv(scope, *(md->data() + id));
527 if (!sv->isInt32())
528 return 0;
529 return sv->integerValue();
530}
531
533{
535 if (!md)
536 return false;
537
538 QV4::Scope scope(engine);
539 QV4::ScopedValue sv(scope, *(md->data() + id));
540 if (!sv->isBoolean())
541 return false;
542 return sv->booleanValue();
543}
544
546{
548 if (!md)
549 return 0.0;
550
551 QV4::Scope scope(engine);
552 QV4::ScopedValue sv(scope, *(md->data() + id));
553 if (!sv->isDouble())
554 return 0.0;
555 return sv->doubleValue();
556}
557
559{
561 if (!md)
562 return QString();
563
564 QV4::Scope scope(engine);
565 QV4::ScopedValue sv(scope, *(md->data() + id));
566 if (QV4::String *s = sv->stringValue())
567 return s->toQString();
568 return QString();
569}
570
572{
574 if (!md)
575 return QUrl();
576
577 QV4::Scope scope(engine);
578 QV4::ScopedValue sv(scope, *(md->data() + id));
580 if (!v || v->d()->data().userType() != QMetaType::QUrl)
581 return QUrl();
582 return v->d()->data().value<QUrl>();
583}
584
586{
588 if (!md)
589 return QDate();
590
591 QV4::Scope scope(engine);
592 QV4::ScopedValue sv(scope, *(md->data() + id));
594 if (!v || v->d()->data().userType() != QMetaType::QDate)
595 return QDate();
596 return v->d()->data().value<QDate>();
597}
598
600{
602 if (!md)
603 return QTime();
604
605 QV4::Scope scope(engine);
606 QV4::ScopedValue sv(scope, *(md->data() + id));
608 if (!v || v->d()->data().userType() != QMetaType::QTime)
609 return QTime();
610 return v->d()->data().value<QTime>();
611}
612
614{
616 if (!md)
617 return QDateTime();
618
619 QV4::Scope scope(engine);
620 QV4::ScopedValue sv(scope, *(md->data() + id));
622 if (!v || v->d()->data().userType() != QMetaType::QDateTime)
623 return QDateTime();
624 return v->d()->data().value<QDateTime>();
625}
626
627#if QT_CONFIG(regularexpression)
628QRegularExpression QQmlVMEMetaObject::readPropertyAsRegularExpression(int id) const
629{
631 if (!md)
632 return QRegularExpression();
633
634 QV4::Scope scope(engine);
635 QV4::ScopedValue sv(scope, *(md->data() + id));
637 if (!v || v->d()->data().userType() != QMetaType::QRegularExpression)
638 return QRegularExpression();
639 return v->d()->data().value<QRegularExpression>();
640}
641#endif
642
644{
646 if (!md)
647 return QSizeF();
648
649 QV4::Scope scope(engine);
650 QV4::ScopedValue sv(scope, *(md->data() + id));
652 if (!v || v->d()->data().userType() != QMetaType::QSizeF)
653 return QSizeF();
654 return v->d()->data().value<QSizeF>();
655}
656
658{
660 if (!md)
661 return QPointF();
662
663 QV4::Scope scope(engine);
664 QV4::ScopedValue sv(scope, *(md->data() + id));
666 if (!v || v->d()->data().userType() != QMetaType::QPointF)
667 return QPointF();
668 return v->d()->data().value<QPointF>();
669}
670
672{
674 if (!md)
675 return nullptr;
676
677 QV4::Scope scope(engine);
678 QV4::ScopedValue sv(scope, *(md->data() + id));
680 if (!wrapper)
681 return nullptr;
682 return wrapper->object();
683}
684
686{
688 if (!md)
689 return;
690
691 QV4::Scope scope(engine);
692 QV4::ScopedObject v(scope, *(md->data() + id));
693 if (!v) {
694 v = engine->newObject();
695 v->arrayCreate();
696 md->set(engine, id, v);
697 }
698}
699
701{
703 if (!md)
704 return QRectF();
705
706 QV4::Scope scope(engine);
707 QV4::ScopedValue sv(scope, *(md->data() + id));
709 if (!v || v->d()->data().userType() != QMetaType::QRectF)
710 return QRectF();
711 return v->d()->data().value<QRectF>();
712}
713
715{
716 Q_ASSERT(o == object);
717 Q_UNUSED(o);
718
719 int id = _id;
720
721 if (intercept(c, _id, a))
722 return -1;
723
724 const int propertyCount = compiledObject ? int(compiledObject->nProperties) : 0;
725 const int aliasCount = compiledObject ? int(compiledObject->nAliases) : 0;
726 const int signalCount = compiledObject ? int(compiledObject->nSignals) : 0;
727 const int methodCount = compiledObject ? int(compiledObject->nFunctions) : 0;
728
730 if (id >= propOffset()) {
731 id -= propOffset();
732
733 if (id < propertyCount) {
734 // if we reach this point, propertyCount must have been > 0, and thus compiledObject != nullptr
737 const QV4::CompiledData::CommonType t = property.commonType();
738
739 // the context can be null if accessing var properties from cpp after re-parenting an item.
740 QQmlEnginePrivate *ep = (ctxt.isNull() || ctxt->engine() == nullptr)
741 ? nullptr
743
745 if (property.isList()) {
746 // _id because this is an absolute property ID.
747 const QQmlPropertyData *propertyData = cache->property(_id);
748 const QMetaType propType = propertyData->propType();
749
750 if (propType.flags().testFlag(QMetaType::IsQmlList)) {
751 // when reading from the list, we need to find the correct MetaObject,
752 // namely this. However, obejct->metaObject might point to any
753 // MetaObject down the inheritance hierarchy, so we need to store how
754 // far we have to go down
755 // To do this, we encode the hierarchy depth together with the id of the
756 // property in a single quintptr, with the first half storing the depth
757 // and the second half storing the property id
758 auto mo = static_cast<QQmlVMEMetaObject *>(
759 QObjectPrivate::get(object)->metaObject);
760 quintptr inheritanceDepth = 0u;
761 while (mo && mo != this) {
762 mo = mo->parentVMEMetaObject();
763 ++inheritanceDepth;
764 }
765 constexpr quintptr idBits = sizeof(quintptr) * CHAR_BIT / 2u;
766 if (Q_UNLIKELY(inheritanceDepth >= (quintptr(1) << idBits))) {
767 qmlWarning(object) << "Too many objects in inheritance hierarchy "
768 "for list property";
769 return -1;
770 }
771 if (Q_UNLIKELY(quintptr(id) >= (quintptr(1) << idBits))) {
772 qmlWarning(object) << "Too many properties in object "
773 "for list property";
774 return -1;
775 }
776 quintptr encodedIndex = (inheritanceDepth << idBits) + id;
777
779 *static_cast<QQmlListProperty<QObject> *>(a[0])
780 = QQmlListProperty<QObject>(
781 object, reinterpret_cast<void *>(quintptr(encodedIndex)),
785 // Value type list
786 QV4::Scope scope(engine);
787 QV4::Scoped<QV4::Sequence> sequence(scope, *(md->data() + id));
788 const void *data = sequence
790 : nullptr;
791 propType.destruct(a[0]);
792 propType.construct(a[0], data);
793 } else {
794 qmlWarning(object) << "Cannot find member data";
795 }
796 } else {
797 switch (t) {
799 break;
801 *reinterpret_cast<int *>(a[0]) = readPropertyAsInt(id);
802 break;
804 *reinterpret_cast<bool *>(a[0]) = readPropertyAsBool(id);
805 break;
807 *reinterpret_cast<double *>(a[0]) = readPropertyAsDouble(id);
808 break;
810 *reinterpret_cast<QString *>(a[0]) = readPropertyAsString(id);
811 break;
813 *reinterpret_cast<QUrl *>(a[0]) = readPropertyAsUrl(id);
814 break;
816 *reinterpret_cast<QDate *>(a[0]) = readPropertyAsDate(id);
817 break;
819 *reinterpret_cast<QDateTime *>(a[0]) = readPropertyAsDateTime(id);
820 break;
822#if QT_CONFIG(regularexpression)
823 *reinterpret_cast<QRegularExpression *>(a[0])
824 = readPropertyAsRegularExpression(id);
825#endif
826 break;
828 *reinterpret_cast<QRectF *>(a[0]) = readPropertyAsRectF(id);
829 break;
831 *reinterpret_cast<QSizeF *>(a[0]) = readPropertyAsSizeF(id);
832 break;
834 *reinterpret_cast<QPointF *>(a[0]) = readPropertyAsPointF(id);
835 break;
837 *reinterpret_cast<QTime *>(a[0]) = readPropertyAsTime(id);
838 break;
840 if (ep) {
841 *reinterpret_cast<QVariant *>(a[0]) = readPropertyAsVariant(id);
842 } else {
843 // if the context was disposed,
844 // we just return an invalid variant from read.
845 *reinterpret_cast<QVariant *>(a[0]) = QVariant();
846 }
847 break;
850 QV4::Scope scope(engine);
851 QV4::ScopedValue sv(scope, *(md->data() + id));
852
853 // _id because this is an absolute property ID.
854 const QQmlPropertyData *propertyData = cache->property(_id);
855
856 if (propertyData->isQObject()) {
857 if (const auto *wrap = sv->as<QV4::QObjectWrapper>())
858 *reinterpret_cast<QObject **>(a[0]) = wrap->object();
859 else
860 *reinterpret_cast<QObject **>(a[0]) = nullptr;
861 } else {
862 const QMetaType propType = propertyData->propType();
863 const void *data = nullptr;
864 if (const auto *v = sv->as<QV4::VariantObject>()) {
865 const QVariant &variant = v->d()->data();
866 if (variant.metaType() == propType)
868 }
869 propType.destruct(a[0]);
870 propType.construct(a[0], data);
871 }
872 } else {
873 qmlWarning(object) << "Cannot find member data";
874 }
875 }
876 }
877 } else if (c == QMetaObject::WriteProperty) {
878 bool needActivate = false;
879
880 if (property.isList()) {
881 // _id because this is an absolute property ID.
882 const QQmlPropertyData *propertyData = cache->property(_id);
883 const QMetaType propType = propertyData->propType();
884
885 if (propType.flags().testFlag(QMetaType::IsQmlList)) {
886 // Writing such a property is not supported. Content is added through
887 // the list property methods.
889 // Value type list
890 QV4::Scope scope(engine);
891 QV4::Scoped<QV4::Sequence> sequence(scope, *(md->data() + id));
892 void *data = sequence
894 : nullptr;
895 if (data) {
896 if (!propType.equals(data, a[0])) {
897 propType.destruct(data);
898 propType.construct(data, a[0]);
899 needActivate = true;
900 }
901 } else {
902 if (const QQmlType type = QQmlMetaType::qmlListType(propType);
903 type.isSequentialContainer()) {
905 engine, propType, type.listMetaSequence(), a[0]);
906 } else if (QSequentialIterable iterable;
908 propType, a[0],
909 QMetaType::fromType<QSequentialIterable>(),
910 &iterable)) {
912 engine, propType, iterable.metaContainer(), a[0]);
913 } else {
914 sequence = QV4::Encode::undefined();
915 }
916 md->set(engine, id, sequence);
917 if (sequence->isUndefined()) {
918 qmlWarning(object)
919 << "Could not create a QML sequence object for "
920 << propType.name();
921 }
922 needActivate = true;
923 }
924 } else {
925 qmlWarning(object) << "Cannot find member data";
926 }
927 } else {
928 switch (t) {
930 break;
932 needActivate = *reinterpret_cast<int *>(a[0]) != readPropertyAsInt(id);
933 writeProperty(id, *reinterpret_cast<int *>(a[0]));
934 break;
936 needActivate = *reinterpret_cast<bool *>(a[0]) != readPropertyAsBool(id);
937 writeProperty(id, *reinterpret_cast<bool *>(a[0]));
938 break;
940 needActivate = *reinterpret_cast<double *>(a[0]) != readPropertyAsDouble(id);
941 writeProperty(id, *reinterpret_cast<double *>(a[0]));
942 break;
944 needActivate = *reinterpret_cast<QString *>(a[0]) != readPropertyAsString(id);
945 writeProperty(id, *reinterpret_cast<QString *>(a[0]));
946 break;
948 needActivate = *reinterpret_cast<QUrl *>(a[0]) != readPropertyAsUrl(id);
949 writeProperty(id, *reinterpret_cast<QUrl *>(a[0]));
950 break;
952 needActivate = *reinterpret_cast<QDate *>(a[0]) != readPropertyAsDate(id);
953 writeProperty(id, *reinterpret_cast<QDate *>(a[0]));
954 break;
956 needActivate = *reinterpret_cast<QDateTime *>(a[0]) != readPropertyAsDateTime(id);
957 writeProperty(id, *reinterpret_cast<QDateTime *>(a[0]));
958 break;
960#if QT_CONFIG(regularexpression)
961 needActivate = *reinterpret_cast<QRegularExpression *>(a[0])
962 != readPropertyAsRegularExpression(id);
963 writeProperty(id, *reinterpret_cast<QRegularExpression *>(a[0]));
964#endif
965 break;
967 needActivate = *reinterpret_cast<QRectF *>(a[0]) != readPropertyAsRectF(id);
968 writeProperty(id, *reinterpret_cast<QRectF *>(a[0]));
969 break;
971 needActivate = *reinterpret_cast<QSizeF *>(a[0]) != readPropertyAsSizeF(id);
972 writeProperty(id, *reinterpret_cast<QSizeF *>(a[0]));
973 break;
975 needActivate = *reinterpret_cast<QPointF *>(a[0]) != readPropertyAsPointF(id);
976 writeProperty(id, *reinterpret_cast<QPointF *>(a[0]));
977 break;
979 needActivate = *reinterpret_cast<QTime *>(a[0]) != readPropertyAsTime(id);
980 writeProperty(id, *reinterpret_cast<QTime *>(a[0]));
981 break;
983 if (ep)
984 writeProperty(id, *reinterpret_cast<QVariant *>(a[0]));
985 break;
988 QV4::Scope scope(engine);
989 QV4::ScopedValue sv(scope, *(md->data() + id));
990
991 // _id because this is an absolute property ID.
992 const QQmlPropertyData *propertyData = cache->property(_id);
993
994 if (propertyData->isQObject()) {
995 QObject *arg = *reinterpret_cast<QObject **>(a[0]);
996 if (const auto *wrap = sv->as<QV4::QObjectWrapper>())
997 needActivate = wrap->object() != arg;
998 else if (arg != nullptr || !sv->isNull())
999 needActivate = true;
1000 if (needActivate)
1001 writeProperty(id, arg);
1002 } else {
1003 const QMetaType propType = propertyData->propType();
1004 if (const auto *v = sv->as<QV4::VariantObject>()) {
1005 QVariant &variant = v->d()->data();
1006 if (variant.metaType() != propType) {
1007 needActivate = true;
1008 variant = QVariant(propType, a[0]);
1009 } else if (!propType.equals(variant.constData(), a[0])) {
1010 needActivate = true;
1011 propType.destruct(variant.data());
1012 propType.construct(variant.data(), a[0]);
1013 }
1014 } else {
1015 needActivate = true;
1016 md->set(engine, id, engine->newVariantObject(
1017 propType, a[0]));
1018 }
1019 }
1020 } else {
1021 qmlWarning(object) << "Cannot find member data";
1022 }
1023 }
1024 }
1025
1026 if (needActivate)
1027 activate(object, methodOffset() + id, nullptr);
1028 }
1029
1030 return -1;
1031 }
1032
1033 id -= propertyCount;
1034
1035 if (id < aliasCount) {
1036 const QV4::CompiledData::Alias *aliasData = &compiledObject->aliasTable()[id];
1037
1040 *reinterpret_cast<void **>(a[0]) = nullptr;
1041 }
1042
1043 if (ctxt.isNull())
1044 return -1;
1045
1046 while (aliasData->isAliasToLocalAlias())
1047 aliasData = &compiledObject->aliasTable()[aliasData->localAliasIndex];
1048
1049 QObject *target = ctxt->idValue(aliasData->targetObjectId());
1050 if (!target)
1051 return -1;
1052
1053 connectAlias(id);
1054
1055 if (aliasData->isObjectAlias()) {
1056 *reinterpret_cast<QObject **>(a[0]) = target;
1057 return -1;
1058 }
1059
1060 QQmlData *targetDData = QQmlData::get(target, /*create*/false);
1061 if (!targetDData)
1062 return -1;
1063
1065 int coreIndex = encodedIndex.coreIndex();
1066 const int valueTypePropertyIndex = encodedIndex.valueTypeIndex();
1067
1068 const auto removePendingBinding
1069 = [c, a](QObject *target, int coreIndex, QQmlPropertyIndex encodedIndex) {
1070 // Remove binding (if any) on write
1072 int flags = *reinterpret_cast<int*>(a[3]);
1074 QQmlData *targetData = QQmlData::get(target);
1075 if (targetData && targetData->hasBindingBit(coreIndex)) {
1077 targetData->clearBindingBit(coreIndex);
1078 }
1079 }
1080 }
1081 };
1082
1083 if (valueTypePropertyIndex != -1) {
1084 if (!targetDData->propertyCache)
1085 return -1;
1086 const QQmlPropertyData *pd = targetDData->propertyCache->property(coreIndex);
1087 // Value type property or deep alias
1089 ctxt->engine(), pd->propType());
1090 if (valueType) {
1091 removePendingBinding(target, coreIndex, encodedIndex);
1092 valueType->read(target, coreIndex);
1093 int rv = QMetaObject::metacall(valueType, c, valueTypePropertyIndex, a);
1094
1096 valueType->write(target, coreIndex, QQmlPropertyData::HasInternalIndex,
1097 valueTypePropertyIndex);
1098
1099 return rv;
1100 } else {
1101 // deep alias
1102 void *argv[1] = { &target };
1104 removePendingBinding(
1105 target, valueTypePropertyIndex,
1106 QQmlPropertyIndex(valueTypePropertyIndex));
1107 return QMetaObject::metacall(target, c, valueTypePropertyIndex, a);
1108 }
1109
1110 } else {
1111 removePendingBinding(target, coreIndex, encodedIndex);
1112 return QMetaObject::metacall(target, c, coreIndex, a);
1113 }
1114
1115 }
1116 return -1;
1117
1118 }
1119
1120 } else if(c == QMetaObject::InvokeMetaMethod) {
1121
1122 if (id >= methodOffset()) {
1123
1124 id -= methodOffset();
1125 int plainSignals = signalCount + propertyCount + aliasCount;
1126 if (id < plainSignals) {
1127 activate(object, _id, a);
1128 return -1;
1129 }
1130
1131 id -= plainSignals;
1132
1133 if (id < methodCount) {
1135 if (!engine)
1136 return -1; // We can't run the method
1137
1139 QV4::ExecutionEngine *v4 = engine->handle();
1140 ep->referenceScarceResources(); // "hold" scarce resources in memory during evaluation.
1141 QV4::Scope scope(v4);
1142
1143
1145 if (!function) {
1146 // The function was not compiled. There are some exceptional cases which the
1147 // expression rewriter does not rewrite properly (e.g., \r-terminated lines
1148 // are not rewritten correctly but this bug is deemed out-of-scope to fix for
1149 // performance reasons; see QTBUG-24064) and thus compilation will have failed.
1150 QQmlError e;
1153 "Exception occurred during compilation of function: ")
1155 ep->warning(e);
1156 return -1; // The dynamic method with that id is not available.
1157 }
1158
1159 auto methodData = cache->method(_id);
1160 auto arguments = methodData->hasArguments() ? methodData->arguments() : nullptr;
1161
1162 if (arguments && arguments->names) {
1163 const quint32 parameterCount = arguments->names->size();
1164 Q_ASSERT(parameterCount == function->formalParameterCount());
1165 function->call(object, a, arguments->types, parameterCount);
1166 } else {
1167 Q_ASSERT(function->formalParameterCount() == 0);
1168 const QMetaType returnType = methodData->propType();
1169 function->call(object, a, &returnType, 0);
1170 }
1171
1172 if (scope.hasException()) {
1174 if (error.isValid())
1175 ep->warning(error);
1176 }
1177
1178 ep->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete.
1179 return -1;
1180 }
1181 return -1;
1182 }
1183 }
1184
1185 if (parent.isT1())
1186 return parent.asT1()->metaCall(object, c, _id, a);
1187 else
1188 return object->qt_metacall(c, _id, a);
1189}
1190
1192{
1193 if (ctxt.isNull() || !ctxt->isValid() || !compiledObject) {
1194 qWarning("QQmlVMEMetaObject: Internal error - attempted to evaluate a function in an invalid context");
1195 return QV4::Encode::undefined();
1196 }
1197
1199 if (!md)
1200 return QV4::Encode::undefined();
1201
1202 return (md->data() + index + compiledObject->nProperties)->asReturnedValue();
1203}
1204
1206{
1208
1210 if (md)
1211 return (md->data() + id)->asReturnedValue();
1212 return QV4::Value::undefinedValue().asReturnedValue();
1213}
1214
1216{
1218 if (md) {
1219 const QV4::QObjectWrapper *wrapper = (md->data() + id)->as<QV4::QObjectWrapper>();
1220 if (wrapper)
1221 return QVariant::fromValue(wrapper->object());
1222 const QV4::VariantObject *v = (md->data() + id)->as<QV4::VariantObject>();
1223 if (v)
1224 return v->d()->data();
1225 return QV4::ExecutionEngine::toVariant(*(md->data() + id), QMetaType {});
1226 }
1227 return QVariant();
1228}
1229
1231{
1233
1235 if (!md)
1236 return;
1237
1238 // Importantly, if the current value is a scarce resource, we need to ensure that it
1239 // gets automatically released by the engine if no other references to it exist.
1240 const QV4::VariantObject *oldVariant = (md->data() + id)->as<QV4::VariantObject>();
1241 if (oldVariant)
1242 oldVariant->removeVmePropertyReference();
1243
1244 QObject *valueObject = nullptr;
1246
1247 // And, if the new value is a scarce resource, we need to ensure that it does not get
1248 // automatically released by the engine until no other references to it exist.
1249 if (QV4::VariantObject *v = const_cast<QV4::VariantObject*>(value.as<QV4::VariantObject>())) {
1250 v->addVmePropertyReference();
1251 md->set(engine, id, value);
1252 } else if (QV4::QObjectWrapper *wrapper = const_cast<QV4::QObjectWrapper*>(value.as<QV4::QObjectWrapper>())) {
1253 // We need to track this QObject to signal its deletion
1254 valueObject = wrapper->object();
1255
1256 // Do we already have a QObject guard for this property?
1257 if (valueObject && !guard) {
1258 guard = new QQmlVMEVariantQObjectPtr();
1259 varObjectGuards.append(guard);
1260 }
1261 md->set(engine, id, value);
1262 } else if (const QV4::Sequence *sequence = value.as<QV4::Sequence>()) {
1263 QV4::Heap::Sequence *p = sequence->d();
1264 if (p->enforcesLocation()) {
1265 // If the sequence enforces its location, we don't want it to be updated anymore after
1266 // being written to a property.
1268 } else {
1269 // Otherwise, make sure the reference carries some value so that we can still call
1270 // toVariant() on it (see note in QV4::SequencePrototype::toVariant).
1271 if (!p->hasData())
1273 md->set(engine, id, p);
1274 }
1276 // If the value type enforces its location, we don't want it to be updated anymore after
1277 // being written to a property.
1278 QV4::Heap::QQmlValueTypeWrapper *p = wrapper->d();
1279 md->set(engine, id, p->enforcesLocation() ? QV4::ReferenceObject::detached(p) : p);
1280 } else {
1281 md->set(engine, id, value);
1282 }
1283
1284 if (guard)
1285 guard->setGuardedValue(valueObject, this, id);
1286
1287 // Emit change signal as appropriate.
1288 activate(object, methodOffset() + id, nullptr);
1289}
1290
1292{
1295 if (!md)
1296 return;
1297
1298 // Importantly, if the current value is a scarce resource, we need to ensure that it
1299 // gets automatically released by the engine if no other references to it exist.
1300 const QV4::VariantObject *oldv = (md->data() + id)->as<QV4::VariantObject>();
1301 if (oldv)
1303
1304 // And, if the new value is a scarce resource, we need to ensure that it does not get
1305 // automatically released by the engine until no other references to it exist.
1306 QV4::Scope scope(engine);
1309 if (!!v)
1310 v->addVmePropertyReference();
1311
1312 // Write the value and emit change signal as appropriate.
1314 md->set(engine, id, newv);
1315 if ((currentValue.userType() != value.userType() || currentValue != value))
1316 activate(object, methodOffset() + id, nullptr);
1317 } else {
1318 bool needActivate = false;
1319 if (value.userType() == QMetaType::QObjectStar) {
1320 QObject *o = *(QObject *const *)value.data();
1321 needActivate = readPropertyAsQObject(id) != o; // TODO: still correct?
1322 writeProperty(id, o);
1323 } else {
1325 if (md) {
1326 const QV4::VariantObject *v = (md->data() + id)->as<QV4::VariantObject>();
1327 needActivate = (!v ||
1328 v->d()->data().userType() != value.userType() ||
1329 v->d()->data() != value);
1330 if (v)
1332 md->set(engine, id, engine->newVariantObject(value.metaType(), value.constData()));
1333 v = static_cast<const QV4::VariantObject *>(md->data() + id);
1335 }
1336 }
1337
1338 if (needActivate)
1339 activate(object, methodOffset() + id, nullptr);
1340 }
1341}
1342
1344{
1345 if (index < methodOffset()) {
1348 }
1349 if (!compiledObject)
1350 return QV4::Value::undefinedValue().asReturnedValue();
1352 Q_ASSERT(index >= (methodOffset() + plainSignals) && index < (methodOffset() + plainSignals + int(compiledObject->nFunctions)));
1353 return method(index - methodOffset() - plainSignals);
1354}
1355
1356// Used by debugger
1358{
1359 if (index < methodOffset()) {
1361 return parentVMEMetaObject()->setVmeMethod(index, function);
1362 }
1363 if (!compiledObject)
1364 return;
1366 Q_ASSERT(index >= (methodOffset() + plainSignals) && index < (methodOffset() + plainSignals + int(compiledObject->nFunctions)));
1367
1368 int methodIndex = index - methodOffset() - plainSignals;
1370 if (!md)
1371 return;
1372 md->set(engine, methodIndex + compiledObject->nProperties, function);
1373}
1374
1383
1385{
1386 if (index < propOffset()) {
1389 return;
1390 }
1391 return writeVarProperty(index - propOffset(), v);
1392}
1393
1399
1401{
1402 if (engine != markStack->engine())
1403 return;
1404
1406
1408 parent->mark(markStack);
1409}
1410
1411bool QQmlVMEMetaObject::aliasTarget(int index, QObject **target, int *coreIndex, int *valueTypeIndex) const
1412{
1414
1415 *target = nullptr;
1416 *coreIndex = -1;
1417 *valueTypeIndex = -1;
1418
1419 if (ctxt.isNull())
1420 return false;
1421
1422 const int aliasId = index - propOffset() - compiledObject->nProperties;
1423 const QV4::CompiledData::Alias *aliasData = &compiledObject->aliasTable()[aliasId];
1424 while (aliasData->isAliasToLocalAlias())
1425 aliasData = &compiledObject->aliasTable()[aliasData->localAliasIndex];
1426 *target = ctxt->idValue(aliasData->targetObjectId());
1427 if (!*target)
1428 return false;
1429
1430 if (!aliasData->isObjectAlias()) {
1432 *coreIndex = encodedIndex.coreIndex();
1433 *valueTypeIndex = encodedIndex.valueTypeIndex();
1434 }
1435 return true;
1436}
1437
1439{
1441 if (!aliasEndpoints)
1443
1444 const QV4::CompiledData::Alias *aliasData = &compiledObject->aliasTable()[aliasId];
1445
1446 QQmlVMEMetaObjectEndpoint *endpoint = aliasEndpoints + aliasId;
1447 if (endpoint->metaObject.data()) {
1448 // already connected
1449 Q_ASSERT(endpoint->metaObject.data() == this);
1450 return;
1451 }
1452
1453 endpoint->metaObject = this;
1454 endpoint->connect(ctxt->idValueBindings(aliasData->targetObjectId()));
1455 endpoint->tryConnect();
1456}
1457
1458void QQmlVMEMetaObject::connectAliasSignal(int index, bool indexInSignalRange)
1459{
1461 int aliasId = (index - (indexInSignalRange ? signalOffset() : methodOffset())) - compiledObject->nProperties;
1462 if (aliasId < 0 || aliasId >= int(compiledObject->nAliases))
1463 return;
1464
1465 connectAlias(aliasId);
1466}
1467
1472{
1474}
1475
1477{
1479 while (vme && vme->propOffset() > coreIndex)
1480 vme = vme->parentVMEMetaObject();
1481
1482 Q_ASSERT(vme);
1483 return vme;
1484}
1485
1487{
1489 while (vme && vme->methodOffset() > coreIndex)
1490 vme = vme->parentVMEMetaObject();
1491
1492 Q_ASSERT(vme);
1493 return vme;
1494}
1495
1501{
1503 while (vme && vme->signalOffset() > coreIndex)
1504 vme = vme->parentVMEMetaObject();
1505
1506 Q_ASSERT(vme);
1507 return vme;
1508}
1509
1511{
1513 for ( ; it != end; ++it) {
1514 if ((*it)->m_index == index) {
1515 return *it;
1516 }
1517 }
1518
1519 return nullptr;
1520}
1521
void setFlagValue(bool)
T * asT1() const
bool isT1() const
\inmodule QtCore\reentrant
Definition qdatetime.h:283
\inmodule QtCore \reentrant
Definition qdatetime.h:29
qsizetype size() const noexcept
Definition qlist.h:397
const_iterator constBegin() const noexcept
Definition qlist.h:632
void append(parameter_type t)
Definition qlist.h:458
const_iterator constEnd() const noexcept
Definition qlist.h:633
QByteArray methodSignature() const
\inmodule QtCore
const char * typeName() const
Returns the name of this property's type.
\inmodule QtCore
Definition qmetatype.h:341
void destruct(void *data) const
constexpr TypeFlags flags() const
Definition qmetatype.h:2658
bool isValid() const
bool equals(const void *lhs, const void *rhs) const
Compares the objects at lhs and rhs for equality.
constexpr const char * name() const
Definition qmetatype.h:2680
void * construct(void *where, const void *copy=nullptr) const
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.
QDynamicMetaObjectData * metaObject
Definition qobject.h:90
static QObjectPrivate * get(QObject *o)
Definition qobject_p.h:150
\inmodule QtCore
Definition qobject.h:103
\inmodule QtCore\reentrant
Definition qpoint.h:217
QObject * idValue(int index) const
bool isValid() const
QQmlNotifier * idValueBindings(int index) const
QQmlEngine * engine() const
static QQmlPropertyCache::ConstPtr ensurePropertyCache(QObject *object)
Definition qqmldata_p.h:252
static bool wasDeleted(const QObject *)
Definition qqmldata_p.h:312
static QQmlData * get(QObjectPrivate *priv, bool create)
Definition qqmldata_p.h:199
void warning(const QQmlError &)
static QQmlEnginePrivate * get(QQmlEngine *e)
void referenceScarceResources()
void dereferenceScarceResources()
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.
void setValue(const QVariant &value)
static QQmlGadgetPtrWrapper * instance(QQmlEngine *engine, QMetaType type)
QMetaProperty property(int index) const
void write(QObject *obj, int idx, QQmlPropertyData::WriteFlags flags, int internalIndex=QV4::ReferenceObject::AllProperties) const
QVariant readOnGadget(const QMetaProperty &property) const
void read(QObject *obj, int idx)
void writeOnGadget(const QMetaProperty &property, const QVariant &value)
void setObject(QObject *g)
Definition qqmlguard_p.h:62
int metaCall(QObject *o, QMetaObject::Call c, int id, void **a) override
QQmlPropertyCache::ConstPtr cache
QMetaObject * toDynamicMetaObject(QObject *o) override
QBiPointer< QDynamicMetaObjectData, const QMetaObject > parent
QQmlInterceptorMetaObject(QObject *obj, const QQmlPropertyCache::ConstPtr &cache)
bool intercept(QMetaObject::Call c, int id, void **a)
void registerInterceptor(QQmlPropertyIndex index, QQmlPropertyValueInterceptor *interceptor)
QTaggedPointer< const QMetaObject, MetaObjectValidity > metaObject
static QQmlType qmlListType(QMetaType metaType)
static QQmlValueType * valueType(QMetaType metaType)
static QQmlPropertyCache::ConstPtr propertyCacheForType(QMetaType metaType)
void connect(QObject *source, int sourceSignal, QQmlEngine *engine, bool doNotify=true)
QMetaType propType() const
static QQmlPropertyIndex fromEncoded(qint32 encodedIndex)
static void removeBinding(const QQmlProperty &that)
The QQmlPropertyValueInterceptor class is inherited by property interceptors such as Behavior.
QTaggedPointer< QQmlVMEMetaObject, Tag > metaObject
QV4::ReturnedValue vmeMethod(int index) const
const QV4::CompiledData::Object * compiledObject
int metaCall(QObject *o, QMetaObject::Call _c, int _id, void **_a) override
void connectAlias(int aliasId)
QV4::WeakValue propertyAndMethodStorage
QDateTime readPropertyAsDateTime(int id) const
static void list_append(QQmlListProperty< QObject > *prop, QObject *o)
QV4::ReturnedValue readVarProperty(int) const
bool readPropertyAsBool(int id) const
QPointF readPropertyAsPointF(int id) const
static void list_clear_nosignal(QQmlListProperty< QObject > *prop)
QRectF readPropertyAsRectF(int id) const
static QQmlVMEMetaObject * getForSignal(QObject *o, int coreIndex)
QV4::ReturnedValue method(int) const
void mark(QV4::MarkStack *markStack)
QDate readPropertyAsDate(int id) const
QV4::ReturnedValue vmeProperty(int index) const
static void list_clear(QQmlListProperty< QObject > *prop)
double readPropertyAsDouble(int id) const
static void list_append_nosignal(QQmlListProperty< QObject > *prop, QObject *o)
static QQmlVMEMetaObject * get(QObject *o)
QQmlRefPointer< QV4::ExecutableCompilationUnit > compilationUnit
static QQmlVMEMetaObject * getForProperty(QObject *o, int coreIndex)
int readPropertyAsInt(int id) const
void writeProperty(int id, int v)
static QQmlVMEMetaObject * getForMethod(QObject *o, int coreIndex)
QV4::ExecutionEngine * engine
void setVMEProperty(int index, const QV4::Value &v)
QUrl readPropertyAsUrl(int id) const
QString readPropertyAsString(int id) const
QQmlVMEVariantQObjectPtr * getQObjectGuardForProperty(int) const
QQmlGuardedContextData ctxt
QSizeF readPropertyAsSizeF(int id) const
QObject * readPropertyAsQObject(int id) const
QList< QQmlVMEVariantQObjectPtr * > varObjectGuards
QVariant readPropertyAsVariant(int) const
QQmlVMEMetaObject * parentVMEMetaObject() const
QQmlVMEMetaObject(QV4::ExecutionEngine *engine, QObject *obj, const QQmlPropertyCache::ConstPtr &cache, const QQmlRefPointer< QV4::ExecutableCompilationUnit > &qmlCompilationUnit, int qmlObjectId)
QTime readPropertyAsTime(int id) const
QQmlVMEMetaObjectEndpoint * aliasEndpoints
void connectAliasSignal(int index, bool indexInSignalRange)
bool aliasTarget(int index, QObject **target, int *coreIndex, int *valueTypeIndex) const
void activate(QObject *, int, void **)
void initPropertyAsList(int id) const
void writeVarProperty(int, const QV4::Value &)
void setVmeMethod(int index, const QV4::Value &function)
QV4::MemberData * propertyAndMethodStorageAsMemberData() const
void replace(qsizetype i, QObject *o) const
qsizetype size() const
void append(QObject *o) const
QQmlVMEResolvedList(QQmlListProperty< QObject > *prop)
QObject * at(qsizetype i) const
QQmlVMEMetaObject * m_target
void setGuardedValue(QObject *obj, QQmlVMEMetaObject *target, int index)
\inmodule QtCore\reentrant
Definition qrect.h:484
\inmodule QtCore \reentrant
The QSequentialIterable class is an iterable interface for a container in a QVariant.
\inmodule QtCore
Definition qsize.h:208
\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
T * data() const noexcept
void setTag(Tag tag)
Tag tag() const noexcept
\inmodule QtCore \reentrant
Definition qdatetime.h:215
\inmodule QtCore
Definition qproperty.h:679
\inmodule QtCore
Definition qurl.h:94
const CompiledObject * objectAt(int index) const
void set(ExecutionEngine *engine, const Value &value)
Managed * asManaged() const
bool isUndefined() const
Value * valueRef() const
void markOnce(MarkStack *markStack)
\inmodule QtCore
Definition qvariant.h:65
void * data()
Returns a pointer to the contained object as a generic void* that can be written to.
static auto fromValue(T &&value) noexcept(std::is_nothrow_copy_constructible_v< T > &&Private::CanUseInternalSpace< T >) -> std::enable_if_t< std::conjunction_v< std::is_copy_constructible< T >, std::is_destructible< T > >, QVariant >
Definition qvariant.h:536
Private d
Definition qvariant.h:672
QMetaType metaType() const
const void * constData() const
Definition qvariant.h:451
qDeleteAll(list.begin(), list.end())
QCache< int, Employee > cache
[0]
QSet< QString >::iterator it
auto mo
[7]
QList< QVariant > arguments
Combined button and popup list for selecting options.
quint64 ReturnedValue
#define Q_UNLIKELY(x)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction function
DBusConnection const char DBusError * error
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char * method
static QDBusError::ErrorType get(const char *name)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define qWarning
Definition qlogging.h:166
GLsizei const GLfloat * v
[13]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint index
[2]
GLuint GLuint end
GLenum GLuint GLenum GLsizei length
GLenum GLuint id
[7]
GLdouble GLdouble GLdouble GLdouble top
GLuint object
[3]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum type
GLenum target
GLbitfield flags
GLhandleARB obj
[2]
GLdouble s
[6]
Definition qopenglext.h:235
const GLubyte * c
GLdouble GLdouble t
Definition qopenglext.h:243
GLuint64EXT * result
[6]
GLfloat GLfloat p
[1]
Q_QML_EXPORT QQmlInfo qmlWarning(const QObject *me)
static void list_removeLast(QQmlListProperty< QObject > *prop)
static QMetaObject * stringCastMetaObject(QObject *o, const QMetaObject *top)
static QObject * list_at(QQmlListProperty< QObject > *prop, qsizetype index)
static qsizetype list_count(QQmlListProperty< QObject > *prop)
static void list_replace(QQmlListProperty< QObject > *prop, qsizetype index, QObject *o)
void QQmlVMEMetaObjectEndpoint_callback(QQmlNotifierEndpoint *e, void **)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
SSL_CTX int void * arg
static QT_BEGIN_NAMESPACE QAsn1Element wrap(quint8 type, const QAsn1Element &child)
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
#define QStringLiteral(str)
#define sp
#define Q_UNUSED(x)
unsigned int quint32
Definition qtypes.h:50
size_t quintptr
Definition qtypes.h:167
ptrdiff_t qsizetype
Definition qtypes.h:165
unsigned int uint
Definition qtypes.h:34
const char property[13]
Definition qwizard.cpp:101
QObject::connect nullptr
QVariant variant
[1]
QJSValueList args
QJSEngine engine
[0]
virtual void objectDestroyed(QObject *)
Definition qobject_p.h:469
virtual int metaCall(QObject *, QMetaObject::Call, int _id, void **)=0
\inmodule QtCore
QMetaProperty property(int index) const
Returns the meta-data for the property with the given index.
static int metacall(QObject *, Call, int, void **)
const QMetaObject * superClass() const
Returns the meta-object of the superclass, or \nullptr if there is no such object.
QMetaMethod method(int index) const
Returns the meta-data for the method with the given index.
static void activate(QObject *sender, int signal_index, void **argv)
Definition qobject.cpp:4193
static void realloc(Object *o, Type newType, uint alloc, bool enforceAttributes)
bool hasFlag(Flag flag) const
const Property * propertyTable() const
const Alias * aliasTable() const
static constexpr ReturnedValue undefined()
QQmlError catchExceptionAsQmlError()
ReturnedValue throwRangeError(const Value &value)
QV4::ReturnedValue fromVariant(const QVariant &)
Heap::Object * newObject()
Heap::String * newString(char16_t c)
static QVariant toVariant(const QV4::Value &value, QMetaType typeHint, bool createJSValueForObjectsAndSymbols=true)
Heap::Object * newVariantObject(const QMetaType type, const void *data)
ExecutionEngine * engine() const
static Heap::MemberData * allocate(QV4::ExecutionEngine *e, uint n, Heap::MemberData *old=nullptr)
bool set(StringOrSymbol *name, const Value &v, ThrowOnFailure shouldThrow)
static void ensureWrapper(ExecutionEngine *engine, QObject *object)
static ReturnedValue wrap(ExecutionEngine *engine, QObject *object)
QObject * object() const
static constexpr const int AllProperties
static bool readReference(HeapObject *ref)
static HeapObject * detached(HeapObject *ref)
bool hasException() const
ExecutionEngine * engine
static void * getRawContainerPtr(const Sequence *object, QMetaType typeHint)
static ReturnedValue fromData(QV4::ExecutionEngine *engine, QMetaType type, QMetaSequence metaSequence, const void *data)
QV4_NEARLY_ALWAYS_INLINE double doubleValue() const
int integerValue() const
bool isDouble() const
bool isBoolean() const
bool booleanValue() const
static constexpr Value fromInt32(int i)
Definition qv4value_p.h:187
QML_NEARLY_ALWAYS_INLINE String * stringValue() const
Definition qv4value_p.h:55
static constexpr Value fromBoolean(bool b)
Definition qv4value_p.h:183
static constexpr Value undefinedValue()
Definition qv4value_p.h:191
static Value fromDouble(double d)
Definition qv4value_p.h:199
static constexpr Value fromReturnedValue(ReturnedValue val)
Definition qv4value_p.h:165
const T * as() const
Definition qv4value_p.h:132
static constexpr Value nullValue()
Definition qv4value_p.h:195
V4_NEEDS_DESTROY void addVmePropertyReference() const
void removeVmePropertyReference() const
static void markCustom(Engine *engine, F &&markFunction)
uchar data[MaxInternalSize]
Definition qvariant.h:112
void wrapper()