6#include <private/qjsvalue_p.h>
7#include <private/qqmlanybinding_p.h>
8#include <private/qqmlbinding_p.h>
9#include <private/qqmlboundsignal_p.h>
10#include <private/qqmlcomponent_p.h>
11#include <private/qqmlcomponentattached_p.h>
12#include <private/qqmlcustomparser_p.h>
13#include <private/qqmldebugconnector_p.h>
14#include <private/qqmldebugserviceinterfaces_p.h>
15#include <private/qqmlengine_p.h>
16#include <private/qqmlpropertybinding_p.h>
17#include <private/qqmlpropertyvalueinterceptor_p.h>
18#include <private/qqmlscriptdata_p.h>
19#include <private/qqmlscriptstring_p.h>
20#include <private/qqmlsourcecoordinate_p.h>
21#include <private/qqmlstringconverters_p.h>
22#include <private/qqmlvaluetypeproxybinding_p.h>
23#include <private/qqmlvme_p.h>
24#include <private/qqmlvmemetaobject_p.h>
25#include <private/qv4function_p.h>
26#include <private/qv4functionobject_p.h>
27#include <private/qv4generatorobject_p.h>
28#include <private/qv4qobjectwrapper_p.h>
29#include <private/qv4referenceobject_p.h>
30#include <private/qv4resolvedtypereference_p.h>
32#include <qtqml_tracepoints_p.h>
34#include <QtCore/qscopedvaluerollback.h>
35#include <QtCore/qloggingcategory.h>
43"struct ExecutionEngine;"\
44"class ExecutableCompilationUnit;"\
45"namespace CompiledData {"\
46"struct Object;"\
47"}}"\
48"class QQmlEngine;"
51Q_TRACE_POINT(qtqml, QQmlObjectCreator_createInstance_entry,
const QV4::ExecutableCompilationUnit *compilationUnit,
const QV4::CompiledData::Object *object,
const QUrl &url)
52Q_TRACE_POINT(qtqml, QQmlObjectCreator_createInstance_exit,
const QString &typeName)
54QQmlObjectCreator::QQmlObjectCreator(
55 const QQmlRefPointer<QQmlContextData> &parentContext,
56 const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit,
57 const QQmlRefPointer<QQmlContextData> &creationContext,
58 const QString &inlineComponentName,
59 QQmlIncubatorPrivate *incubator)
61 , m_inlineComponentName(inlineComponentName)
62 , compilationUnit(compilationUnit)
63 , propertyCaches(compilationUnit->propertyCachesPtr())
64 , sharedState(
new QQmlObjectCreatorSharedState, QQmlRefPointer<QQmlObjectCreatorSharedState>::Adopt)
65 , topLevelCreator(
true)
66 , isContextObject(
true)
67 , incubator(incubator)
71 sharedState->componentAttached =
nullptr;
72 sharedState->allJavaScriptObjects = ObjectInCreationGCAnchorList();
73 sharedState->creationContext = creationContext;
74 sharedState->rootContext.reset();
75 sharedState->hadTopLevelRequiredProperties =
false;
77 if (
auto profiler = QQmlEnginePrivate::get(engine)->profiler) {
78 Q_QML_PROFILE_IF_ENABLED(QQmlProfilerDefinitions::ProfileCreating, profiler,
79 sharedState->profiler.init(profiler));
85QQmlObjectCreator::QQmlObjectCreator(
const QQmlRefPointer<QQmlContextData> &parentContext,
86 const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit,
const QString inlineComponentName,
87 QQmlObjectCreatorSharedState *inheritedSharedState,
bool isContextObject)
89 , m_inlineComponentName(inlineComponentName)
90 , compilationUnit(compilationUnit)
91 , propertyCaches(compilationUnit->propertyCachesPtr())
92 , sharedState(inheritedSharedState)
93 , topLevelCreator(
false)
94 , isContextObject(isContextObject)
100void QQmlObjectCreator::init(
const QQmlRefPointer<QQmlContextData> &providedParentContext)
102 parentContext = providedParentContext;
103 engine = parentContext->engine();
104 v4 = engine->handle();
106 Q_ASSERT(compilationUnit);
107 Q_ASSERT(compilationUnit->engine == v4);
108 if (!compilationUnit->runtimeStrings)
109 compilationUnit->populate();
111 qmlUnit = compilationUnit->unitData();
113 _scopeObject =
nullptr;
114 _bindingTarget =
nullptr;
115 _valueTypeProperty =
nullptr;
116 _compiledObject =
nullptr;
117 _compiledObjectIndex = -1;
119 _vmeMetaObject =
nullptr;
120 _qmlContext =
nullptr;
123QQmlObjectCreator::~QQmlObjectCreator()
125 if (topLevelCreator) {
129 QQmlObjectCreatorRecursionWatcher watcher(
this);
131 while (sharedState->componentAttached) {
132 QQmlComponentAttached *a = sharedState->componentAttached;
138QObject *QQmlObjectCreator::create(
int subComponentIndex, QObject *parent, QQmlInstantiationInterrupt *interrupt,
int flags)
140 if (phase == CreatingObjectsPhase2) {
141 phase = ObjectsCreated;
142 return context->contextObject();
144 Q_ASSERT(phase == Startup);
145 phase = CreatingObjects;
148 bool isComponentRoot =
false;
150 if (subComponentIndex == -1) {
152 isComponentRoot =
true;
154 Q_ASSERT(subComponentIndex >= 0);
155 if (flags & CreationFlags::InlineComponent) {
156 if (compilationUnit->componentsAreBound()
157 && compilationUnit != parentContext->typeCompilationUnit()) {
158 recordError({}, tr(
"Cannot instantiate bound inline component in different file"));
159 phase = ObjectsCreated;
162 objectToCreate = subComponentIndex;
163 isComponentRoot =
true;
165 Q_ASSERT(flags & CreationFlags::NormalObject);
166 if (compilationUnit->componentsAreBound()
167 && sharedState->creationContext != parentContext) {
168 recordError({}, tr(
"Cannot instantiate bound component "
169 "outside its creation context"));
170 phase = ObjectsCreated;
173 const QV4::CompiledData::Object *compObj = compilationUnit->objectAt(subComponentIndex);
174 objectToCreate = compObj->bindingTable()->value.objectIndex;
178 context = QQmlEnginePrivate::get(engine)->createInternalContext(
179 compilationUnit, parentContext, subComponentIndex, isComponentRoot);
181 if (!sharedState->rootContext) {
182 sharedState->rootContext = context;
183 sharedState->rootContext->setIncubator(incubator);
184 sharedState->rootContext->setRootObjectInCreation(
true);
187 QV4::Scope scope(v4);
189 Q_ASSERT(sharedState->allJavaScriptObjects.canTrack() || topLevelCreator);
191 sharedState->allJavaScriptObjects = ObjectInCreationGCAnchorList(scope);
193 if (!isComponentRoot && sharedState->creationContext) {
195 QV4::ScopedValue scripts(scope, sharedState->creationContext->importedScripts());
196 context->setImportedScripts(v4, scripts);
199 QObject *instance = createInstance(objectToCreate, parent,
true);
201 QQmlData *ddata = QQmlData::get(instance);
203 ddata->compilationUnit = compilationUnit;
207 sharedState->allJavaScriptObjects = ObjectInCreationGCAnchorList();
209 phase = CreatingObjectsPhase2;
211 if (interrupt && interrupt->shouldInterrupt())
214 phase = ObjectsCreated;
217 if (QQmlEngineDebugService *service
218 = QQmlDebugConnector::service<QQmlEngineDebugService>()) {
219 if (!parentContext->isInternal())
220 parentContext->asQQmlContextPrivate()->appendInstance(instance);
221 service->objectCreated(engine, instance);
222 }
else if (!parentContext->isInternal() && QQmlDebugConnector::service<QV4DebugService>()) {
223 parentContext->asQQmlContextPrivate()->appendInstance(instance);
230void QQmlObjectCreator::beginPopulateDeferred(
const QQmlRefPointer<QQmlContextData> &newContext)
232 context = newContext;
233 sharedState->rootContext = newContext;
235 Q_ASSERT(topLevelCreator);
236 Q_ASSERT(!sharedState->allJavaScriptObjects.canTrack());
239 QV4::Scope valueScope(v4);
240 sharedState->allJavaScriptObjects = ObjectInCreationGCAnchorList(valueScope);
243void QQmlObjectCreator::populateDeferred(QObject *instance,
int deferredIndex,
244 const QQmlPropertyPrivate *qmlProperty,
245 const QV4::CompiledData::Binding *binding)
247 doPopulateDeferred(instance, deferredIndex, [
this, qmlProperty, binding]() {
248 Q_ASSERT(qmlProperty);
249 Q_ASSERT(binding->hasFlag(QV4::CompiledData::Binding::IsDeferredBinding));
251 QQmlListProperty<QObject> savedList;
252 qSwap(_currentList, savedList);
254 const QQmlPropertyData &property = qmlProperty->core;
256 if (property.propType().flags().testFlag(QMetaType::IsQmlList)) {
257 void *argv[1] = { (
void*)&_currentList };
258 QMetaObject::metacall(_qobject, QMetaObject::ReadProperty, property.coreIndex(), argv);
259 }
else if (_currentList.object) {
260 _currentList = QQmlListProperty<QObject>();
263 setPropertyBinding(&property, binding);
265 qSwap(_currentList, savedList);
269void QQmlObjectCreator::populateDeferred(QObject *instance,
int deferredIndex)
271 doPopulateDeferred(instance, deferredIndex, [
this]() { setupBindings(ApplyDeferred); });
274bool QQmlObjectCreator::populateDeferredProperties(QObject *instance,
275 const QQmlData::DeferredData *deferredData)
277 beginPopulateDeferred(deferredData->context);
278 populateDeferred(instance, deferredData->deferredIdx);
279 finalizePopulateDeferred();
280 return errors.isEmpty();
283void QQmlObjectCreator::populateDeferredBinding(
const QQmlProperty &qmlProperty,
int deferredIndex,
284 const QV4::CompiledData::Binding *binding)
287 populateDeferred(qmlProperty.object(), deferredIndex, QQmlPropertyPrivate::get(qmlProperty),
290 populateDeferred(qmlProperty.object(), deferredIndex);
294void QQmlObjectCreator::populateDeferredInstance(
295 QObject *outerObject,
int deferredIndex,
int index, QObject *instance,
296 QObject *bindingTarget,
const QQmlPropertyData *valueTypeProperty,
297 const QV4::CompiledData::Binding *binding)
299 doPopulateDeferred(outerObject, deferredIndex, [&]() {
300 populateInstance(index, instance, bindingTarget, valueTypeProperty, binding);
304void QQmlObjectCreator::finalizePopulateDeferred()
306 phase = ObjectsCreated;
309void QQmlObjectCreator::setPropertyValue(
const QQmlPropertyData *property,
const QV4::CompiledData::Binding *binding)
311 QQmlPropertyData::WriteFlags propertyWriteFlags = QQmlPropertyData::BypassInterceptor | QQmlPropertyData::RemoveBindingOnAliasWrite;
312 QV4::Scope scope(v4);
314 QMetaType propertyType = property->propType();
316 if (property->isEnum()) {
317 if (binding->hasFlag(QV4::CompiledData::Binding::IsResolvedEnum) ||
320 (property->isAlias() && binding->isNumberBinding())) {
321 propertyType = property->propType().underlyingType();
324 QVariant value = compilationUnit->bindingValueAsString(binding);
325 bool ok = QQmlPropertyPrivate::write(_qobject, *property, value, context);
332 auto assertOrNull = [&](
bool ok)
334 Q_ASSERT(ok || binding->type() == QV4::CompiledData::Binding::Type_Null);
338 auto assertType = [&](QV4::CompiledData::Binding::Type type)
340 Q_ASSERT(binding->type()== type || binding->type() == QV4::CompiledData::Binding::Type_Null);
344 if (property->isQObject()) {
345 if (binding->type() == QV4::CompiledData::Binding::Type_Null) {
346 QObject *value =
nullptr;
347 const bool ok = property->writeProperty(_qobject, &value, propertyWriteFlags);
354 switch (propertyType.id()) {
355 case QMetaType::QVariant: {
356 if (binding->type() == QV4::CompiledData::Binding::Type_Number) {
357 double n = compilationUnit->bindingValueAsNumber(binding);
358 if (
double(
int(n)) == n) {
359 if (property->isVarProperty()) {
360 _vmeMetaObject->setVMEProperty(property->coreIndex(), QV4::Value::fromInt32(
int(n)));
364 property->writeProperty(_qobject, &value, propertyWriteFlags);
367 if (property->isVarProperty()) {
368 _vmeMetaObject->setVMEProperty(property->coreIndex(), QV4::Value::fromDouble(n));
371 property->writeProperty(_qobject, &value, propertyWriteFlags);
374 }
else if (binding->type() == QV4::CompiledData::Binding::Type_Boolean) {
375 if (property->isVarProperty()) {
376 _vmeMetaObject->setVMEProperty(property->coreIndex(), QV4::Value::fromBoolean(binding->valueAsBoolean()));
378 QVariant value(binding->valueAsBoolean());
379 property->writeProperty(_qobject, &value, propertyWriteFlags);
381 }
else if (binding->type() == QV4::CompiledData::Binding::Type_Null) {
382 if (property->isVarProperty()) {
383 _vmeMetaObject->setVMEProperty(property->coreIndex(), QV4::Value::nullValue());
385 QVariant nullValue = QVariant::fromValue(
nullptr);
386 property->writeProperty(_qobject, &nullValue, propertyWriteFlags);
389 QString stringValue = compilationUnit->bindingValueAsString(binding);
390 if (property->isVarProperty()) {
391 QV4::ScopedString s(scope, v4->newString(stringValue));
392 _vmeMetaObject->setVMEProperty(property->coreIndex(), s);
394 QVariant value = stringValue;
395 property->writeProperty(_qobject, &value, propertyWriteFlags);
400 case QMetaType::QString: {
401 assertOrNull(binding->evaluatesToString());
402 QString value = compilationUnit->bindingValueAsString(binding);
403 property->writeProperty(_qobject, &value, propertyWriteFlags);
406 case QMetaType::QStringList: {
407 assertOrNull(binding->evaluatesToString());
408 QStringList value(compilationUnit->bindingValueAsString(binding));
409 property->writeProperty(_qobject, &value, propertyWriteFlags);
412 case QMetaType::QByteArray: {
413 assertType(QV4::CompiledData::Binding::Type_String);
414 QByteArray value(compilationUnit->bindingValueAsString(binding).toUtf8());
415 property->writeProperty(_qobject, &value, propertyWriteFlags);
418 case QMetaType::QUrl: {
419 assertType(QV4::CompiledData::Binding::Type_String);
420 const QString string = compilationUnit->bindingValueAsString(binding);
421 QUrl value = (!string.isEmpty() && QQmlPropertyPrivate::resolveUrlsOnAssignment())
422 ? compilationUnit->finalUrl().resolved(QUrl(string))
424 property->writeProperty(_qobject, &value, propertyWriteFlags);
427 case QMetaType::UInt: {
428 assertType(QV4::CompiledData::Binding::Type_Number);
429 double d = compilationUnit->bindingValueAsNumber(binding);
430 uint value = uint(d);
431 property->writeProperty(_qobject, &value, propertyWriteFlags);
435 case QMetaType::Int: {
436 assertType(QV4::CompiledData::Binding::Type_Number);
437 double d = compilationUnit->bindingValueAsNumber(binding);
439 property->writeProperty(_qobject, &value, propertyWriteFlags);
443 case QMetaType::SChar: {
444 assertType(QV4::CompiledData::Binding::Type_Number);
445 double d = compilationUnit->bindingValueAsNumber(binding);
446 qint8 value = qint8(d);
447 property->writeProperty(_qobject, &value, propertyWriteFlags);
450 case QMetaType::UChar: {
451 assertType(QV4::CompiledData::Binding::Type_Number);
452 double d = compilationUnit->bindingValueAsNumber(binding);
453 quint8 value = quint8(d);
454 property->writeProperty(_qobject, &value, propertyWriteFlags);
457 case QMetaType::Short: {
458 assertType(QV4::CompiledData::Binding::Type_Number);
459 double d = compilationUnit->bindingValueAsNumber(binding);
460 qint16 value = qint16(d);
461 property->writeProperty(_qobject, &value, propertyWriteFlags);
464 case QMetaType::UShort: {
465 assertType(QV4::CompiledData::Binding::Type_Number);
466 double d = compilationUnit->bindingValueAsNumber(binding);
467 quint16 value = quint16(d);
468 property->writeProperty(_qobject, &value, propertyWriteFlags);
471 case QMetaType::LongLong: {
472 assertType(QV4::CompiledData::Binding::Type_Number);
473 double d = compilationUnit->bindingValueAsNumber(binding);
474 qint64 value = qint64(d);
475 property->writeProperty(_qobject, &value, propertyWriteFlags);
478 case QMetaType::ULongLong: {
479 assertType(QV4::CompiledData::Binding::Type_Number);
480 double d = compilationUnit->bindingValueAsNumber(binding);
481 quint64 value = quint64(d);
482 property->writeProperty(_qobject, &value, propertyWriteFlags);
486 case QMetaType::Float: {
487 assertType(QV4::CompiledData::Binding::Type_Number);
488 float value =
float(compilationUnit->bindingValueAsNumber(binding));
489 property->writeProperty(_qobject, &value, propertyWriteFlags);
492 case QMetaType::Double: {
493 assertType(QV4::CompiledData::Binding::Type_Number);
494 double value = compilationUnit->bindingValueAsNumber(binding);
495 property->writeProperty(_qobject, &value, propertyWriteFlags);
498 case QMetaType::QColor: {
500 QVariant data = QQmlStringConverters::colorFromString(
501 compilationUnit->bindingValueAsString(binding), &ok);
503 property->writeProperty(_qobject, data.data(), propertyWriteFlags);
506#if QT_CONFIG(datestring)
507 case QMetaType::QDate: {
509 QDate value = QQmlStringConverters::dateFromString(compilationUnit->bindingValueAsString(binding), &ok);
511 property->writeProperty(_qobject, &value, propertyWriteFlags);
514 case QMetaType::QTime: {
516 QTime value = QQmlStringConverters::timeFromString(compilationUnit->bindingValueAsString(binding), &ok);
518 property->writeProperty(_qobject, &value, propertyWriteFlags);
521 case QMetaType::QDateTime: {
523 QDateTime value = QQmlStringConverters::dateTimeFromString(
524 compilationUnit->bindingValueAsString(binding), &ok);
526 property->writeProperty(_qobject, &value, propertyWriteFlags);
530 case QMetaType::QPoint: {
532 QPoint value = QQmlStringConverters::pointFFromString(compilationUnit->bindingValueAsString(binding), &ok).toPoint();
534 property->writeProperty(_qobject, &value, propertyWriteFlags);
537 case QMetaType::QPointF: {
539 QPointF value = QQmlStringConverters::pointFFromString(compilationUnit->bindingValueAsString(binding), &ok);
541 property->writeProperty(_qobject, &value, propertyWriteFlags);
544 case QMetaType::QSize: {
546 QSize value = QQmlStringConverters::sizeFFromString(compilationUnit->bindingValueAsString(binding), &ok).toSize();
548 property->writeProperty(_qobject, &value, propertyWriteFlags);
551 case QMetaType::QSizeF: {
553 QSizeF value = QQmlStringConverters::sizeFFromString(compilationUnit->bindingValueAsString(binding), &ok);
555 property->writeProperty(_qobject, &value, propertyWriteFlags);
558 case QMetaType::QRect: {
560 QRect value = QQmlStringConverters::rectFFromString(compilationUnit->bindingValueAsString(binding), &ok).toRect();
562 property->writeProperty(_qobject, &value, propertyWriteFlags);
565 case QMetaType::QRectF: {
567 QRectF value = QQmlStringConverters::rectFFromString(compilationUnit->bindingValueAsString(binding), &ok);
569 property->writeProperty(_qobject, &value, propertyWriteFlags);
572 case QMetaType::Bool: {
573 assertType(QV4::CompiledData::Binding::Type_Boolean);
574 bool value = binding->valueAsBoolean();
575 property->writeProperty(_qobject, &value, propertyWriteFlags);
578 case QMetaType::QVector2D:
579 case QMetaType::QVector3D:
580 case QMetaType::QVector4D:
581 case QMetaType::QQuaternion: {
582 QVariant result = QQmlValueTypeProvider::createValueType(
583 compilationUnit->bindingValueAsString(binding), propertyType);
584 assertOrNull(result.isValid());
585 property->writeProperty(_qobject, result.data(), propertyWriteFlags);
590 if (propertyType == QMetaType::fromType<QList<qreal>>()) {
591 assertType(QV4::CompiledData::Binding::Type_Number);
593 value.append(compilationUnit->bindingValueAsNumber(binding));
594 property->writeProperty(_qobject, &value, propertyWriteFlags);
596 }
else if (propertyType == QMetaType::fromType<QList<
int>>()) {
597 assertType(QV4::CompiledData::Binding::Type_Number);
598 double n = compilationUnit->bindingValueAsNumber(binding);
600 value.append(
int(n));
601 property->writeProperty(_qobject, &value, propertyWriteFlags);
603 }
else if (propertyType == QMetaType::fromType<QList<
bool>>()) {
604 assertType(QV4::CompiledData::Binding::Type_Boolean);
606 value.append(binding->valueAsBoolean());
607 property->writeProperty(_qobject, &value, propertyWriteFlags);
609 }
else if (propertyType == QMetaType::fromType<QList<QUrl>>()) {
610 assertType(QV4::CompiledData::Binding::Type_String);
611 const QUrl url(compilationUnit->bindingValueAsString(binding));
613 QQmlPropertyPrivate::resolveUrlsOnAssignment()
614 ? compilationUnit->finalUrl().resolved(url)
617 property->writeProperty(_qobject, &value, propertyWriteFlags);
619 }
else if (propertyType == QMetaType::fromType<QList<QString>>()) {
620 assertOrNull(binding->evaluatesToString());
621 QList<QString> value;
622 value.append(compilationUnit->bindingValueAsString(binding));
623 property->writeProperty(_qobject, &value, propertyWriteFlags);
625 }
else if (propertyType == QMetaType::fromType<QJSValue>()) {
627 switch (binding->type()) {
628 case QV4::CompiledData::Binding::Type_Boolean:
629 value = QJSValue(binding->valueAsBoolean());
631 case QV4::CompiledData::Binding::Type_Number: {
632 const double n = compilationUnit->bindingValueAsNumber(binding);
633 if (
double(
int(n)) == n)
634 value = QJSValue(
int(n));
639 case QV4::CompiledData::Binding::Type_Null:
640 value = QJSValue::NullValue;
643 value = QJSValue(compilationUnit->bindingValueAsString(binding));
646 property->writeProperty(_qobject, &value, propertyWriteFlags);
650 switch (binding->type()) {
651 case QV4::CompiledData::Binding::Type_Boolean:
652 source = binding->valueAsBoolean();
654 case QV4::CompiledData::Binding::Type_Number: {
655 const double n = compilationUnit->bindingValueAsNumber(binding);
656 if (
double(
int(n)) == n)
662 case QV4::CompiledData::Binding::Type_Null:
663 source = QVariant::fromValue<std::nullptr_t>(
nullptr);
665 case QV4::CompiledData::Binding::Type_Invalid:
668 source = compilationUnit->bindingValueAsString(binding);
672 QVariant target = QQmlValueTypeProvider::createValueType(
673 source, propertyType, engine->handle());
674 if (target.isValid()) {
675 property->writeProperty(_qobject, target.data(), propertyWriteFlags);
681 QString stringValue = compilationUnit->bindingValueAsString(binding);
682 QMetaProperty metaProperty = _qobject->metaObject()->property(property->coreIndex());
683 recordError(binding->location, tr(
"Cannot assign value %1 to property"
684" %2").arg(stringValue, QString::fromUtf8(metaProperty.name())));
693 const QMetaObject *mo = object->metaObject();
694 while (mo && !type.isValid()) {
695 type = QQmlMetaType::qmlType(mo);
696 mo = mo->superClass();
701void QQmlObjectCreator::setupBindings(BindingSetupFlags mode)
703 QQmlListProperty<QObject> savedList;
704 qSwap(_currentList, savedList);
706 const QV4::CompiledData::BindingPropertyData *propertyData
707 = compilationUnit->bindingPropertyDataPerObjectAt(_compiledObjectIndex);
709 if (_compiledObject->idNameIndex) {
710 const QQmlPropertyData *idProperty = propertyData->last();
711 Q_ASSERT(!idProperty || !idProperty->isValid() || idProperty->name(_qobject) == QLatin1String(
"id"));
712 if (idProperty && idProperty->isValid() && idProperty->isWritable() && idProperty->propType().id() == QMetaType::QString) {
713 QV4::CompiledData::Binding idBinding;
714 idBinding.propertyNameIndex = 0;
715 idBinding.clearFlags();
716 idBinding.setType(QV4::CompiledData::Binding::Type_String);
717 idBinding.stringIndex = _compiledObject->idNameIndex;
718 idBinding.location = _compiledObject->location;
719 idBinding.value.nullMarker = 0;
720 setPropertyValue(idProperty, &idBinding);
725 if (_valueTypeProperty) {
726 QQmlAbstractBinding *binding = QQmlPropertyPrivate::binding(_bindingTarget, QQmlPropertyIndex(_valueTypeProperty->coreIndex()));
728 if (binding && binding->kind() != QQmlAbstractBinding::ValueTypeProxy) {
729 QQmlPropertyPrivate::removeBinding(
730 _bindingTarget, QQmlPropertyIndex(_valueTypeProperty->coreIndex()),
731 QQmlPropertyPrivate::OverrideSticky);
732 }
else if (binding) {
733 QQmlValueTypeProxyBinding *proxy =
static_cast<QQmlValueTypeProxyBinding *>(binding);
735 if (qmlTypeForObject(_bindingTarget).isValid()) {
736 quint32 bindingSkipList = 0;
738 const QQmlPropertyData *defaultProperty = _compiledObject->indexOfDefaultPropertyOrAlias != -1 ? _propertyCache->parent()->defaultProperty() : _propertyCache->defaultProperty();
740 const QV4::CompiledData::Binding *binding = _compiledObject->bindingTable();
741 for (quint32 i = 0; i < _compiledObject->nBindings; ++i, ++binding) {
742 const QQmlPropertyData *property = binding->propertyNameIndex != 0
743 ? _propertyCache->property(stringAt(binding->propertyNameIndex),
747 bindingSkipList |= (1 << property->coreIndex());
750 proxy->removeBindings(bindingSkipList);
755 int currentListPropertyIndex = -1;
757 const QV4::CompiledData::Binding *binding = _compiledObject->bindingTable();
758 for (quint32 i = 0; i < _compiledObject->nBindings; ++i, ++binding) {
759 const QQmlPropertyData *
const property = propertyData->at(i);
761 const QQmlPropertyData *targetProperty = property;
762 if (targetProperty->isAlias()) {
764 QQmlPropertyIndex originalIndex(targetProperty->coreIndex(), _valueTypeProperty ? _valueTypeProperty->coreIndex() : -1);
765 auto [targetObject, targetIndex] = QQmlPropertyPrivate::findAliasTarget(_bindingTarget, originalIndex);
766 QQmlData *data = QQmlData::get(targetObject);
767 Q_ASSERT(data && data->propertyCache);
768 targetProperty = data->propertyCache->property(targetIndex.coreIndex());
769 sharedState->requiredProperties.remove({targetObject, targetProperty});
771 sharedState->requiredProperties.remove({_bindingTarget, property});
775 if (binding->hasFlag(QV4::CompiledData::Binding::IsCustomParserBinding))
778 if (binding->hasFlag(QV4::CompiledData::Binding::IsDeferredBinding)) {
779 if (!(mode & ApplyDeferred))
781 }
else if (!(mode & ApplyImmediate)) {
785 if (property && property->propType().flags().testFlag(QMetaType::IsQmlList)) {
786 if (property->coreIndex() != currentListPropertyIndex) {
787 void *argv[1] = { (
void*)&_currentList };
788 QMetaObject::metacall(_qobject, QMetaObject::ReadProperty, property->coreIndex(), argv);
789 currentListPropertyIndex = property->coreIndex();
792 const QMetaObject *
const metaobject = _qobject->metaObject();
793 const int qmlListBehavorClassInfoIndex = metaobject->indexOfClassInfo(
"QML.ListPropertyAssignBehavior");
794 if (qmlListBehavorClassInfoIndex != -1) {
795 const char *overrideBehavior =
796 metaobject->classInfo(qmlListBehavorClassInfoIndex).value();
797 if (!strcmp(overrideBehavior,
799 if (_currentList.clear) {
800 _currentList.clear(&_currentList);
803 bool isDefaultProperty =
804 (property->name(_qobject)
805 == QString::fromUtf8(
807 ->classInfo(metaobject->indexOfClassInfo(
810 if (!isDefaultProperty
811 && (!strcmp(overrideBehavior,
812 "ReplaceIfNotDefault"))) {
813 if (_currentList.clear) {
814 _currentList.clear(&_currentList);
820 }
else if (_currentList.object) {
821 _currentList = QQmlListProperty<QObject>();
822 currentListPropertyIndex = -1;
825 if (!setPropertyBinding(property, binding))
829 qSwap(_currentList, savedList);
832bool QQmlObjectCreator::setPropertyBinding(
const QQmlPropertyData *bindingProperty,
const QV4::CompiledData::Binding *binding)
834 const QV4::CompiledData::Binding::Type bindingType = binding->type();
835 if (bindingType == QV4::CompiledData::Binding::Type_AttachedProperty) {
836 const QV4::CompiledData::Object *obj = compilationUnit->objectAt(binding->value.objectIndex);
837 QQmlObjectCreationProfiler profiler(sharedState->profiler.profiler, obj);
839 Q_ASSERT(stringAt(obj->inheritedTypeNameIndex).isEmpty());
840 QV4::ResolvedTypeReference *tr = resolvedType(binding->propertyNameIndex);
842 QQmlType attachedType = tr->type();
843 QQmlTypeLoader *typeLoader = QQmlTypeLoader::get(engine);
844 if (!attachedType.isValid()) {
845 QQmlTypeNameCache::Result res
846 = context->imports()->query(stringAt(binding->propertyNameIndex), typeLoader);
848 attachedType = res.type;
854 sharedState->profiler,
855 profiler.update(compilationUnit.data(), obj, attachedType.qmlTypeName(),
858 QObject *qmlObject = qmlAttachedPropertiesObject(
859 _qobject, attachedType.attachedPropertiesFunction(typeLoader));
861 recordError(binding->location,
862 QStringLiteral(
"Could not create attached properties object '%1'")
863 .arg(QString::fromUtf8(attachedType.typeName())));
867 const size_t objectIndex = sharedState->allCreatedObjects.size();
868 sharedState->allCreatedObjects.push_back(qmlObject);
869 const QQmlType attachedObjectType
870 = QQmlMetaType::qmlType(attachedType.attachedPropertiesType(typeLoader));
871 const int parserStatusCast = attachedObjectType.parserStatusCast();
872 QQmlParserStatus *parserStatus =
nullptr;
873 if (parserStatusCast != -1)
874 parserStatus =
reinterpret_cast<QQmlParserStatus*>(
reinterpret_cast<
char *>(qmlObject) + parserStatusCast);
876 parserStatus->classBegin();
878 sharedState->allParserStatusCallbacks.push_back({objectIndex, parserStatusCast});
881 if (!populateInstance(binding->value.objectIndex, qmlObject, qmlObject,
888 if (bindingProperty && bindingProperty->propType() == QMetaType::fromType<QQmlScriptString>()) {
889 QQmlScriptString ss(compilationUnit->bindingValueAsScriptString(binding),
890 context->asQQmlContext(), _scopeObject);
891 ss.d.data()->bindingId = bindingType == QV4::CompiledData::Binding::Type_Script ? binding->value.compiledScriptIndex : (quint32)QQmlBinding::Invalid;
892 ss.d.data()->lineNumber = binding->location.line();
893 ss.d.data()->columnNumber = binding->location.column();
894 ss.d.data()->isStringLiteral = bindingType == QV4::CompiledData::Binding::Type_String;
895 ss.d.data()->isNumberLiteral = bindingType == QV4::CompiledData::Binding::Type_Number;
896 ss.d.data()->numberValue = compilationUnit->bindingValueAsNumber(binding);
898 QQmlPropertyData::WriteFlags propertyWriteFlags = QQmlPropertyData::BypassInterceptor |
899 QQmlPropertyData::RemoveBindingOnAliasWrite;
900 int propertyWriteStatus = -1;
901 void *argv[] = { &ss,
nullptr, &propertyWriteStatus, &propertyWriteFlags };
902 QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, bindingProperty->coreIndex(), argv);
906 QObject *createdSubObject =
nullptr;
907 if (bindingType == QV4::CompiledData::Binding::Type_Object) {
910 QScopedValueRollback topLevelRequired(sharedState->hadTopLevelRequiredProperties);
911 createdSubObject = createInstance(binding->value.objectIndex, _bindingTarget);
912 if (!createdSubObject)
916 if (bindingType == QV4::CompiledData::Binding::Type_GroupProperty) {
917 const QV4::CompiledData::Object *obj = compilationUnit->objectAt(binding->value.objectIndex);
918 if (stringAt(obj->inheritedTypeNameIndex).isEmpty()) {
920 QObject *groupObject =
nullptr;
921 QQmlGadgetPtrWrapper *valueType =
nullptr;
922 const QQmlPropertyData *valueTypeProperty =
nullptr;
923 QObject *bindingTarget = _bindingTarget;
924 int groupObjectIndex = binding->value.objectIndex;
926 if (!bindingProperty) {
927 for (
int i = 0, end = compilationUnit->objectCount(); i != end; ++i) {
928 const QV4::CompiledData::Object *external = compilationUnit->objectAt(i);
929 if (external->idNameIndex == binding->propertyNameIndex) {
930 bindingTarget = groupObject = context->idValue(external->objectId());
936 }
else if (QQmlMetaType::isValueType(bindingProperty->propType())) {
937 valueType = QQmlGadgetPtrWrapper::instance(engine, bindingProperty->propType());
939 recordError(binding->location, tr(
"Cannot set properties on %1 as it is null").arg(stringAt(binding->propertyNameIndex)));
943 valueType->read(_qobject, bindingProperty->coreIndex());
945 groupObject = valueType;
946 valueTypeProperty = bindingProperty;
947 }
else if (bindingProperty->propType().flags() & QMetaType::PointerToQObject) {
948 void *argv[1] = { &groupObject };
949 QMetaObject::metacall(_qobject, QMetaObject::ReadProperty, bindingProperty->coreIndex(), argv);
951 QQmlPropertyIndex index(bindingProperty->coreIndex());
952 auto anyBinding = QQmlAnyBinding::ofProperty(_qobject, index);
956 anyBinding.refresh();
957 QMetaObject::metacall(_qobject, QMetaObject::ReadProperty, bindingProperty->coreIndex(), argv);
960 recordError(binding->location, tr(
"Cannot set properties on %1 as it is null").arg(stringAt(binding->propertyNameIndex)));
965 bindingTarget = groupObject;
969 tr(
"Using grouped property syntax on %1 which has no properties")
970 .arg(stringAt(binding->propertyNameIndex)));
974 if (!populateInstance(groupObjectIndex, groupObject, bindingTarget, valueTypeProperty,
981 _qobject, bindingProperty->coreIndex(),
982 QQmlPropertyData::BypassInterceptor,
983 QV4::ReferenceObject::AllProperties);
990 if (!bindingProperty)
993 const QV4::CompiledData::Binding::Flags bindingFlags = binding->flags();
994 const bool allowedToRemoveBinding
995 = !(bindingFlags & QV4::CompiledData::Binding::IsSignalHandlerExpression)
996 && !(bindingFlags & QV4::CompiledData::Binding::IsOnAssignment)
997 && !(bindingFlags & QV4::CompiledData::Binding::IsPropertyObserver)
998 && !_valueTypeProperty;
1000 if (allowedToRemoveBinding) {
1001 if (bindingProperty->acceptsQBinding()) {
1002 removePendingBinding(_bindingTarget, bindingProperty->coreIndex());
1004 QQmlPropertyPrivate::removeBinding(
1005 _bindingTarget, QQmlPropertyIndex(bindingProperty->coreIndex()),
1006 QQmlPropertyPrivate::OverrideSticky);
1010 if (bindingType == QV4::CompiledData::Binding::Type_Script || binding->isTranslationBinding()) {
1011 if (bindingFlags & QV4::CompiledData::Binding::IsSignalHandlerExpression
1012 || bindingFlags & QV4::CompiledData::Binding::IsPropertyObserver) {
1013 QV4::Function *runtimeFunction = compilationUnit->runtimeFunctions[binding->value.compiledScriptIndex];
1014 int signalIndex = _propertyCache->methodIndexToSignalIndex(bindingProperty->coreIndex());
1015 QQmlBoundSignalExpression *expr =
new QQmlBoundSignalExpression(
1016 _bindingTarget, signalIndex, context,
1017 _scopeObject, runtimeFunction, currentQmlContext());
1019 if (bindingProperty->notifiesViaBindable()) {
1020 auto target = _bindingTarget;
1021 if (bindingProperty->isAlias()) {
1026 QQmlPropertyIndex originalIndex(bindingProperty->coreIndex(), _valueTypeProperty ? _valueTypeProperty->coreIndex() : -1);
1027 auto [aliasTargetObject, aliasTargetIndex] = QQmlPropertyPrivate::findAliasTarget(target, originalIndex);
1028 target = aliasTargetObject;
1029 QQmlData *data = QQmlData::get(target);
1030 Q_ASSERT(data && data->propertyCache);
1031 bindingProperty = data->propertyCache->property(aliasTargetIndex.coreIndex());
1033 auto &observer = QQmlData::get(_scopeObject)->propertyObservers.emplace_back(expr);
1034 QUntypedBindable bindable;
1035 void *argv[] = { &bindable };
1036 target->qt_metacall(QMetaObject::BindableProperty, bindingProperty->coreIndex(), argv);
1037 Q_ASSERT(bindable.isValid());
1038 bindable.observe(&observer);
1040 QQmlBoundSignal *bs =
new QQmlBoundSignal(_bindingTarget, signalIndex, _scopeObject, engine);
1041 bs->takeExpression(expr);
1043 }
else if (bindingProperty->acceptsQBinding()) {
1044 QUntypedPropertyBinding qmlBinding;
1045 if (binding->isTranslationBinding()) {
1046 qmlBinding = QQmlTranslationPropertyBinding::create(bindingProperty, compilationUnit, binding);
1048 QV4::Function *runtimeFunction = compilationUnit->runtimeFunctions[binding->value.compiledScriptIndex];
1049 QQmlPropertyIndex index(bindingProperty->coreIndex(), -1);
1050 qmlBinding = QQmlPropertyBinding::create(bindingProperty, runtimeFunction, _scopeObject, context, currentQmlContext(), _bindingTarget, index);
1052 sharedState.data()->allQPropertyBindings.push_back(DeferredQPropertyBinding {_bindingTarget, bindingProperty->coreIndex(), qmlBinding });
1054 QQmlData *data = QQmlData::get(_bindingTarget,
true);
1055 data->setBindingBit(_bindingTarget, bindingProperty->coreIndex());
1062 QQmlBinding::Ptr qmlBinding;
1063 const QQmlPropertyData *targetProperty = bindingProperty;
1064 const QQmlPropertyData *subprop =
nullptr;
1065 if (_valueTypeProperty) {
1066 targetProperty = _valueTypeProperty;
1067 subprop = bindingProperty;
1069 if (binding->isTranslationBinding()) {
1070 qmlBinding = QQmlBinding::createTranslationBinding(
1071 compilationUnit, binding, _scopeObject, context);
1073 QV4::Function *runtimeFunction = compilationUnit->runtimeFunctions[binding->value.compiledScriptIndex];
1074 qmlBinding = QQmlBinding::create(targetProperty, runtimeFunction, _scopeObject,
1075 context, currentQmlContext());
1078 auto bindingTarget = _bindingTarget;
1079 auto valueTypeProperty = _valueTypeProperty;
1080 auto assignBinding = [qmlBinding, bindingTarget, targetProperty, subprop, bindingProperty, valueTypeProperty](QQmlObjectCreatorSharedState *sharedState)
mutable ->
bool {
1081 if (!qmlBinding->setTarget(bindingTarget, *targetProperty, subprop) && targetProperty->isAlias())
1084 sharedState->allCreatedBindings.push_back(qmlBinding);
1086 if (bindingProperty->isAlias()) {
1087 QQmlPropertyPrivate::setBinding(qmlBinding.data(), QQmlPropertyPrivate::DontEnable);
1089 qmlBinding->addToObject();
1091 if (!valueTypeProperty) {
1092 QQmlData *targetDeclarativeData = QQmlData::get(bindingTarget);
1093 Q_ASSERT(targetDeclarativeData);
1094 targetDeclarativeData->setPendingBindingBit(bindingTarget, bindingProperty->coreIndex());
1100 if (!assignBinding(sharedState.data()))
1101 pendingAliasBindings.push_back(assignBinding);
1106 if (bindingType == QV4::CompiledData::Binding::Type_Object) {
1107 if (bindingFlags & QV4::CompiledData::Binding::IsOnAssignment) {
1109 QQmlType type = qmlTypeForObject(createdSubObject);
1110 Q_ASSERT(type.isValid());
1112 int valueSourceCast = type.propertyValueSourceCast();
1113 if (valueSourceCast != -1) {
1114 QQmlPropertyValueSource *vs =
reinterpret_cast<QQmlPropertyValueSource *>(
reinterpret_cast<
char *>(createdSubObject) + valueSourceCast);
1115 QObject *target = createdSubObject->parent();
1117 if (_valueTypeProperty) {
1118 prop = QQmlPropertyPrivate::restore(target, *_valueTypeProperty,
1119 bindingProperty, context);
1121 prop = QQmlPropertyPrivate::restore(target, *bindingProperty,
nullptr, context);
1123 vs->setTarget(prop);
1126 int valueInterceptorCast = type.propertyValueInterceptorCast();
1127 if (valueInterceptorCast != -1) {
1128 QQmlPropertyValueInterceptor *vi =
reinterpret_cast<QQmlPropertyValueInterceptor *>(
reinterpret_cast<
char *>(createdSubObject) + valueInterceptorCast);
1129 QObject *target = createdSubObject->parent();
1131 QQmlPropertyIndex propertyIndex;
1132 if (bindingProperty->isAlias()) {
1133 QQmlPropertyIndex originalIndex(bindingProperty->coreIndex(), _valueTypeProperty ? _valueTypeProperty->coreIndex() : -1);
1134 auto aliasTarget = QQmlPropertyPrivate::findAliasTarget(target, originalIndex);
1135 target = aliasTarget.targetObject;
1136 QQmlData *data = QQmlData::get(target);
1137 if (!data || !data->propertyCache) {
1138 qWarning() <<
"can't resolve property alias for 'on' assignment";
1143 QQmlPropertyData targetPropertyData = *data->propertyCache->property(aliasTarget.targetIndex.coreIndex());
1144 auto prop = QQmlPropertyPrivate::restore(
1145 target, targetPropertyData,
nullptr, context);
1146 vi->setTarget(prop);
1147 propertyIndex = QQmlPropertyPrivate::propertyIndex(prop);
1150 if (_valueTypeProperty) {
1151 prop = QQmlPropertyPrivate::restore(
1152 target, *_valueTypeProperty, bindingProperty, context);
1154 prop = QQmlPropertyPrivate::restore(
1155 target, *bindingProperty,
nullptr, context);
1157 vi->setTarget(prop);
1158 propertyIndex = QQmlPropertyPrivate::propertyIndex(prop);
1161 QQmlInterceptorMetaObject *mo = QQmlInterceptorMetaObject::get(target);
1163 mo =
new QQmlInterceptorMetaObject(target, QQmlData::get(target)->propertyCache);
1164 mo->registerInterceptor(propertyIndex, vi);
1171 if (bindingFlags & QV4::CompiledData::Binding::IsSignalHandlerObject) {
1172 if (!bindingProperty->isFunction()) {
1173 recordError(binding->valueLocation, tr(
"Cannot assign an object to signal property %1").arg(bindingProperty->name(_qobject)));
1176 QMetaMethod method = QQmlMetaType::defaultMethod(createdSubObject);
1177 if (!method.isValid()) {
1178 recordError(binding->valueLocation, tr(
"Cannot assign object type %1 with no default method").arg(QString::fromLatin1(createdSubObject->metaObject()->className())));
1181 qCWarning(lcQmlDefaultMethod) <<
"Assigning an object to a signal handler is deprecated. "
1182 "Instead, create the object, give it an id, and call the desired slot "
1183 "from the signal handler. The object is:" << createdSubObject;
1185 QMetaMethod signalMethod = _qobject->metaObject()->method(bindingProperty->coreIndex());
1186 if (!QMetaObject::checkConnectArgs(signalMethod, method)) {
1187 recordError(binding->valueLocation,
1188 tr(
"Cannot connect mismatched signal/slot %1 vs %2")
1189 .arg(QString::fromUtf8(method.methodSignature()))
1190 .arg(QString::fromUtf8(signalMethod.methodSignature())));
1194 QQmlPropertyPrivate::connect(_qobject, bindingProperty->coreIndex(), createdSubObject, method.methodIndex());
1198 QQmlPropertyData::WriteFlags propertyWriteFlags = QQmlPropertyData::BypassInterceptor |
1199 QQmlPropertyData::RemoveBindingOnAliasWrite;
1200 int propertyWriteStatus = -1;
1201 void *argv[] = {
nullptr,
nullptr, &propertyWriteStatus, &propertyWriteFlags };
1203 if (
const char *iid = QQmlMetaType::interfaceIId(bindingProperty->propType())) {
1204 void *ptr = createdSubObject->qt_metacast(iid);
1207 QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, bindingProperty->coreIndex(), argv);
1209 recordError(binding->location, tr(
"Cannot assign object to interface property"));
1212 }
else if (bindingProperty->propType() == QMetaType::fromType<QVariant>()) {
1213 if (bindingProperty->isVarProperty()) {
1214 QV4::Scope scope(v4);
1215 QV4::ScopedValue wrappedObject(scope, QV4::QObjectWrapper::wrap(engine->handle(), createdSubObject));
1216 _vmeMetaObject->setVMEProperty(bindingProperty->coreIndex(), wrappedObject);
1218 QVariant value = QVariant::fromValue(createdSubObject);
1220 QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, bindingProperty->coreIndex(), argv);
1222 }
else if (bindingProperty->propType() == QMetaType::fromType<QJSValue>()) {
1223 QV4::Scope scope(v4);
1224 QV4::ScopedValue wrappedObject(scope, QV4::QObjectWrapper::wrap(engine->handle(), createdSubObject));
1225 if (bindingProperty->isVarProperty()) {
1226 _vmeMetaObject->setVMEProperty(bindingProperty->coreIndex(), wrappedObject);
1229 QJSValuePrivate::setValue(&value, wrappedObject);
1231 QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, bindingProperty->coreIndex(), argv);
1233 }
else if (bindingProperty->propType().flags().testFlag(QMetaType::IsQmlList)) {
1234 Q_ASSERT(_currentList.object);
1236 QObject *itemToAdd = createdSubObject;
1238 QMetaType listItemType = QQmlMetaType::listValueType(bindingProperty->propType());
1239 if (listItemType.isValid()) {
1240 const char *iid = QQmlMetaType::interfaceIId(listItemType);
1242 itemToAdd =
static_cast<QObject *>(createdSubObject->qt_metacast(iid));
1245 if (_currentList.append)
1246 _currentList.append(&_currentList, itemToAdd);
1248 recordError(binding->location, tr(
"Cannot assign object to read only list"));
1251 }
else if (bindingProperty->propType().flags().testFlag(QMetaType::PointerToQObject)) {
1253 argv[0] = &createdSubObject;
1254 QMetaObject::metacall(_qobject, QMetaObject::WriteProperty, bindingProperty->coreIndex(), argv);
1256 QVariant target = QQmlValueTypeProvider::createValueType(
1257 QVariant::fromValue(createdSubObject), bindingProperty->propType(), v4);
1258 if (target.isValid())
1259 bindingProperty->writeProperty(_qobject, target.data(), propertyWriteFlags);
1261 recordError(binding->location, tr(
"Cannot construct value type from given object"));
1266 if (bindingProperty->isQList()) {
1267 recordError(binding->location, tr(
"Cannot assign primitives to lists"));
1271 setPropertyValue(bindingProperty, binding);
1275void QQmlObjectCreator::setupFunctions()
1277 QV4::Scope scope(v4);
1278 QV4::ScopedValue function(scope);
1279 QV4::ScopedContext qmlContext(scope, currentQmlContext());
1281 const quint32_le *functionIdx = _compiledObject->functionOffsetTable();
1282 for (quint32 i = 0; i < _compiledObject->nFunctions; ++i, ++functionIdx) {
1283 QV4::Function *runtimeFunction = compilationUnit->runtimeFunctions[*functionIdx];
1284 const QString name = runtimeFunction->name()->toQString();
1286 const QQmlPropertyData *property = _propertyCache->property(name, _qobject, context);
1287 if (!property->isVMEFunction())
1290 if (runtimeFunction->isGenerator())
1291 function = QV4::GeneratorFunction::create(qmlContext, runtimeFunction);
1293 function = QV4::FunctionObject::createScriptFunction(qmlContext, runtimeFunction);
1294 _vmeMetaObject->setVmeMethod(property->coreIndex(), function);
1298void QQmlObjectCreator::recordError(
const QV4::CompiledData::Location &location,
const QString &description)
1301 error.setUrl(compilationUnit->url());
1302 error.setLine(qmlConvertSourceCoordinate<quint32,
int>(location.line()));
1303 error.setColumn(qmlConvertSourceCoordinate<quint32,
int>(location.column()));
1304 error.setDescription(description);
1308void QQmlObjectCreator::registerObjectWithContextById(
const QV4::CompiledData::Object *object, QObject *instance)
const
1310 if (object->objectId() >= 0)
1311 context->setIdValue(object->objectId(), instance);
1314QObject *QQmlObjectCreator::createInstance(
int index, QObject *parent,
bool isContextObject)
1316 const QV4::CompiledData::Object *obj = compilationUnit->objectAt(index);
1317 Q_TRACE(QQmlObjectCreator_createInstance_entry, compilationUnit.data(), obj, context->url());
1318 QQmlObjectCreationProfiler profiler(sharedState->profiler.profiler, obj);
1321 const InitFlags flags = (isContextObject ? InitFlag::IsContextObject : InitFlag::None)
1322 | (index == 0 ? InitFlag::IsDocumentRoot : InitFlag::None);
1324 if (obj->hasFlag(QV4::CompiledData::Object::IsComponent)) {
1325 Q_TRACE_EXIT(QQmlObjectCreator_createInstance_exit, QStringLiteral(
"<component>"));
1327 sharedState->profiler,
1329 compilationUnit.data(), obj, QStringLiteral(
"<component>"),
1331 return initializeComponent(
1332 obj, createComponent(engine, compilationUnit.data(), index, parent, context),
1336 const QV4::ResolvedTypeReference *typeRef = resolvedType(obj->inheritedTypeNameIndex);
1338 const QQmlType type = typeRef->type();
1339 Q_ASSERT(type.isValid());
1341 Q_TRACE_EXIT(QQmlObjectCreator_createInstance_exit, type.qmlTypeName());
1343 sharedState->profiler,
1344 profiler.update(compilationUnit.data(), obj, type.qmlTypeName(), context->url()));
1346 if (type.isCompositeSingleton()) {
1349 tr(
"Composite Singleton Type %1 is not creatable")
1350 .arg(stringAt(obj->inheritedTypeNameIndex)));
1354 if (!type.isComposite() && !type.isInlineComponentType()) {
1355 if (QObject *instance = type.createWithQQmlData())
1356 return initializeNonComposite(index, obj, typeRef, instance, parent, flags);
1359 tr(
"Unable to create object of type %1").arg(
1360 stringAt(obj->inheritedTypeNameIndex)));
1364 QQmlRefPointer<QV4::ExecutableCompilationUnit> executableCu = typeRef->isSelfReference()
1366 : engine->handle()->executableCompilationUnit(typeRef->compilationUnit());
1367 Q_ASSERT(executableCu);
1369 const bool isInlineComponent = type.isInlineComponentType();
1370 const QString inlineComponentName = isInlineComponent ? type.elementName() : QString();
1371 QQmlObjectCreator subCreator(
1372 context, executableCu, inlineComponentName, sharedState.data(),
1375 if (QObject *instance = isInlineComponent
1376 ? subCreator.create(
1377 executableCu->inlineComponentId(inlineComponentName),
nullptr,
nullptr,
1378 CreationFlags::InlineComponent)
1379 : subCreator.create()) {
1380 return initializeComposite(index, obj, typeRef, instance, parent, flags);
1383 errors += subCreator.errors;
1387void QQmlObjectCreator::initializeDData(
1388 const QV4::CompiledData::Object *obj, QObject *instance, QQmlData *ddata, InitFlags flags)
1390 ddata->lineNumber = obj->location.line();
1391 ddata->columnNumber = obj->location.column();
1392 ddata->setImplicitDestructible();
1396 const bool documentRoot = (flags & InitFlag::IsDocumentRoot)
1397 || ddata->rootObjectInCreation
1398 || obj->hasFlag(QV4::CompiledData::Object::IsInlineComponentRoot);
1400 context->installContext(
1401 ddata, documentRoot ? QQmlContextData::DocumentRoot : QQmlContextData::OrdinaryObject);
1405 if (flags & InitFlag::IsContextObject)
1406 context->setContextObject(instance);
1409void QQmlObjectCreator::initializePropertyCache(
1410 int index, QQmlData *ddata,
const QV4::ResolvedTypeReference *typeRef)
1412 if (!typeRef->isFullyDynamicType()) {
1413 QQmlPropertyCache::ConstPtr cache = propertyCaches->at(index);
1414 Q_ASSERT(!cache.isNull());
1415 ddata->propertyCache = std::move(cache);
1419void QQmlObjectCreator::initializeParent(QObject *instance, QObject *parent)
1421 if (instance->isWidgetType()) {
1422 if (parent && parent->isWidgetType()) {
1423 QAbstractDeclarativeData::setWidgetParent(instance, parent);
1428 }
else if (parent) {
1429 QQml_setParent_noEvent(instance, parent);
1433QObject *QQmlObjectCreator::populateInstanceAndAliasBindings(
1434 int index, QObject *instance, InitFlags flags)
1436 const auto doPopulate = [&]() {
1437 if (!populateInstance(
1438 index, instance, instance,
nullptr)) {
1440 pendingAliasBindings.clear();
1444 if (!flags.testFlag(InitFlag::IsContextObject))
1447 while (!pendingAliasBindings.empty()) {
1448 for (std::vector<PendingAliasBinding>::iterator it = pendingAliasBindings.begin();
1449 it != pendingAliasBindings.end(); ) {
1450 if ((*it)(sharedState.data()))
1451 it = pendingAliasBindings.erase(it);
1460 QObject *scopeObject = instance;
1461 qSwap(_scopeObject, scopeObject);
1463 Q_ASSERT(sharedState->allJavaScriptObjects.canTrack());
1464 sharedState->allJavaScriptObjects.trackObject(v4, instance);
1466 QV4::Scope valueScope(v4);
1467 QV4::QmlContext *qmlContext =
static_cast<QV4::QmlContext *>(valueScope.constructUndefined(1));
1469 qSwap(_qmlContext, qmlContext);
1471 const bool ok = doPopulate();
1473 qSwap(_qmlContext, qmlContext);
1474 qSwap(_scopeObject, scopeObject);
1476 return ok ? instance :
nullptr;
1479QObject *QQmlObjectCreator::initializeComponent(
1480 const QV4::CompiledData::Object *obj, QObject *instance, InitFlags flags)
1484 Q_ASSERT(obj->hasFlag(QV4::CompiledData::Object::IsComponent));
1486 QScopedValueRollback<QQmlObjectCreator*> ocRestore(
1487 QQmlEnginePrivate::get(engine)->activeObjectCreator,
this);
1490 initializeDData(obj, instance, QQmlData::get(instance), flags);
1492 registerObjectWithContextById(obj, instance);
1496QObject *QQmlObjectCreator::initializeComposite(
1497 int index,
const QV4::CompiledData::Object *obj,
const QV4::ResolvedTypeReference *typeRef,
1498 QObject *instance, QObject *parent, InitFlags flags)
1503 QScopedValueRollback<QQmlObjectCreator*> ocRestore(
1504 QQmlEnginePrivate::get(engine)->activeObjectCreator,
this);
1506 initializeParent(instance, parent);
1507 QQmlData *ddata = QQmlData::get(instance,
true);
1508 initializeDData(obj, instance, ddata, flags);
1510 initializePropertyCache(index, ddata, typeRef);
1512 return populateInstanceAndAliasBindings(index, instance, flags);
1515QObject *QQmlObjectCreator::initializeNonComposite(
1516 int index,
const QV4::CompiledData::Object *obj,
const QV4::ResolvedTypeReference *typeRef,
1517 QObject *instance, QObject *parent, InitFlags flags)
1521 Q_ASSERT(!obj->hasFlag(QV4::CompiledData::Object::IsComponent));
1524 const QQmlType type = typeRef->type();
1525 Q_ASSERT(type.isValid());
1526 Q_ASSERT(!type.isComposite() && !type.isInlineComponentType());
1528 QScopedValueRollback<QQmlObjectCreator*> ocRestore(QQmlEnginePrivate::get(engine)->activeObjectCreator,
this);
1530 if (
const int finalizerCast = type.finalizerCast(); finalizerCast != -1) {
1531 const auto hook =
reinterpret_cast<QQmlFinalizerHook *>(
1532 reinterpret_cast<
char *>(instance) + finalizerCast);
1533 sharedState->finalizeHooks.push_back(hook);
1536 QQmlData *ddata = QQmlData::get(instance,
true);
1537 if (sharedState->rootContext && sharedState->rootContext->isRootObjectInCreation()) {
1538 ddata->rootObjectInCreation =
true;
1539 sharedState->rootContext->setRootObjectInCreation(
false);
1542 const size_t instanceIndex = sharedState->allCreatedObjects.size();
1543 sharedState->allCreatedObjects.push_back(instance);
1545 initializeParent(instance, parent);
1546 initializeDData(obj, instance, ddata, flags);
1548 if (
const int parserStatusCast = type.parserStatusCast(); parserStatusCast != -1) {
1549 if (QQmlParserStatus *parserStatus =
reinterpret_cast<QQmlParserStatus*>(
1550 reinterpret_cast<
char *>(instance) + parserStatusCast)) {
1551 parserStatus->classBegin();
1554 Q_QML_OC_PROFILE(sharedState->profiler, sharedState->profiler.push(obj));
1555 sharedState->allParserStatusCallbacks.push_back({ instanceIndex, parserStatusCast });
1559 if (QQmlCustomParser *customParser = type.customParser();
1560 customParser && obj->hasFlag(QV4::CompiledData::Object::HasCustomParserBindings)) {
1561 customParser->engine = QQmlEnginePrivate::get(engine);
1562 customParser->imports = compilationUnit->typeNameCache().data();
1564 QList<
const QV4::CompiledData::Binding *> bindings;
1565 const QV4::CompiledData::Object *obj = compilationUnit->objectAt(index);
1566 const QV4::CompiledData::Binding *binding = obj->bindingTable();
1567 for (quint32 i = 0; i < obj->nBindings; ++i, ++binding) {
1568 if (binding->hasFlag(QV4::CompiledData::Binding::IsCustomParserBinding))
1569 bindings << binding;
1571 customParser->applyBindings(instance, compilationUnit, bindings);
1573 customParser->engine =
nullptr;
1574 customParser->imports = (QQmlTypeNameCache*)
nullptr;
1577 initializePropertyCache(index, ddata, typeRef);
1578 return populateInstanceAndAliasBindings(index, instance, flags);
1581bool QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interrupt)
1583 Q_ASSERT(phase == ObjectsCreated || phase == Finalizing);
1586 QQmlObjectCreatorRecursionWatcher watcher(
this);
1587 QScopedValueRollback<QQmlObjectCreator*> ocRestore(QQmlEnginePrivate::get(engine)->activeObjectCreator,
this);
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1602 while (!sharedState->allCreatedBindings.empty()) {
1603 QQmlAbstractBinding::Ptr b = sharedState->allCreatedBindings.back();
1604 sharedState->allCreatedBindings.pop_back();
1607 if (!b->isAddedToObject())
1609 QQmlData *data = QQmlData::get(b->targetObject());
1611 data->clearPendingBindingBit(b->targetPropertyIndex().coreIndex());
1612 b->setEnabled(
true, QQmlPropertyData::BypassInterceptor |
1613 QQmlPropertyData::DontRemoveBinding);
1614 if (b->kind() == QQmlAbstractBinding::QmlBinding) {
1615 QQmlBinding *binding =
static_cast<QQmlBinding*>(b.data());
1616 if (!binding->hasError() && !binding->hasDependencies()
1617 && !binding->hasUnresolvedNames()) {
1618 b->removeFromObject();
1622 if (watcher.hasRecursed() || interrupt.shouldInterrupt())
1626 while (!sharedState->allQPropertyBindings.isEmpty()) {
1627 auto& [target, index, qmlBinding] = sharedState->allQPropertyBindings.first();
1629 QQmlData *data = QQmlData::get(target);
1630 if (!data || !data->hasBindingBit(index)) {
1632 sharedState->allQPropertyBindings.pop_front();
1636 QUntypedBindable bindable;
1637 void *argv[] = { &bindable };
1639 target->metaObject()->metacall(target, QMetaObject::BindableProperty, index, argv);
1640 const bool success = bindable.setBinding(qmlBinding);
1642 const auto bindingPrivateRefCount = QPropertyBindingPrivate::get(qmlBinding)->refCount();
1645 sharedState->allQPropertyBindings.pop_front();
1648 if (success && bindingPrivateRefCount > 1) {
1649 if (
auto priv = QPropertyBindingPrivate::get(qmlBinding); priv->hasCustomVTable()) {
1650 auto qmlBindingPriv =
static_cast<QQmlPropertyBinding *>(priv);
1651 auto jsExpression = qmlBindingPriv->jsExpression();
1652 const bool canRemove = !qmlBinding.error().hasError()
1653 && !qmlBindingPriv->hasDependencies()
1654 && !jsExpression->hasUnresolvedNames();
1656 bindable.takeBinding();
1660 if (watcher.hasRecursed() || interrupt.shouldInterrupt())
1664 if (QQmlVME::componentCompleteEnabled()) {
1665 while (!sharedState->allParserStatusCallbacks.empty()) {
1666 QQmlObjectCompletionProfiler profiler(&sharedState->profiler);
1667 const ParserStatus status = sharedState->allParserStatusCallbacks.back();
1668 sharedState->allParserStatusCallbacks.pop_back();
1670 const QQmlGuard<QObject> &instance = sharedState->allCreatedObjects[status.objectIndex];
1674 QQmlParserStatus *parserStatus
1675 =
reinterpret_cast<QQmlParserStatus *>(
1676 reinterpret_cast<
char *>(instance.data()) + status.parserStatusCast);
1677 parserStatus->componentComplete();
1679 if (watcher.hasRecursed() || interrupt.shouldInterrupt())
1684 for (QQmlFinalizerHook *hook: sharedState->finalizeHooks) {
1685 hook->componentFinalized();
1686 if (watcher.hasRecursed())
1689 sharedState->finalizeHooks.clear();
1691 while (sharedState->componentAttached) {
1692 QQmlComponentAttached *a = sharedState->componentAttached;
1693 a->removeFromList();
1694 QQmlData *d = QQmlData::get(a->parent());
1696 Q_ASSERT(d->context);
1697 d->context->addComponentAttached(a);
1698 if (QQmlVME::componentCompleteEnabled())
1699 emit a->completed();
1701 if (watcher.hasRecursed() || interrupt.shouldInterrupt())
1710void QQmlObjectCreator::clear()
1712 if (phase == Done || phase == Finalizing || phase == Startup)
1714 Q_ASSERT(phase != Startup);
1716 while (!sharedState->allCreatedObjects.empty()) {
1717 auto object = sharedState->allCreatedObjects.back();
1718 sharedState->allCreatedObjects.pop_back();
1719 if (engine->objectOwnership(object) != QQmlEngine::CppOwnership) {
1724 while (sharedState->componentAttached) {
1725 QQmlComponentAttached *a = sharedState->componentAttached;
1726 a->removeFromList();
1732void QQmlObjectCreator::registerPostHocRequiredProperties(
const QV4::CompiledData::Binding *binding)
1734 const qsizetype oldRequiredPropertiesCount = sharedState->requiredProperties.size();
1735 QSet<QString> postHocRequired;
1736 for (
auto it = _compiledObject->requiredPropertyExtraDataBegin(); it != _compiledObject->requiredPropertyExtraDataEnd(); ++it)
1737 postHocRequired.insert(stringAt(it->nameIndex));
1738 bool hadInheritedRequiredProperties = !postHocRequired.empty();
1740 for (
int propertyIndex = 0; propertyIndex != _compiledObject->propertyCount(); ++propertyIndex) {
1741 const QV4::CompiledData::Property* property = _compiledObject->propertiesBegin() + propertyIndex;
1742 const QQmlPropertyData *propertyData = _propertyCache->property(_propertyCache->propertyOffset() + propertyIndex);
1744 auto postHocIt = postHocRequired.isEmpty() ? postHocRequired.end() : postHocRequired.find(stringAt(property->nameIndex()));
1745 if (!property->isRequired() && postHocRequired.end() == postHocIt)
1747 if (postHocIt != postHocRequired.end())
1748 postHocRequired.erase(postHocIt);
1749 if (isContextObject)
1750 sharedState->hadTopLevelRequiredProperties =
true;
1751 sharedState->requiredProperties.insert({_qobject, propertyData},
1752 RequiredPropertyInfo {compilationUnit->stringAt(property->nameIndex()), compilationUnit->finalUrl(), property->location, {}});
1756 const auto getPropertyCacheRange = [&]() -> std::pair<
int,
int> {
1774 QV4::ResolvedTypeReference *typeRef = resolvedType(_compiledObject->inheritedTypeNameIndex);
1777 if (binding->isAttachedProperty())
1778 return { 0, _propertyCache->propertyCount() };
1779 Q_ASSERT(binding->isGroupProperty());
1780 return { 0, _propertyCache->propertyOffset() + 1 };
1782 Q_ASSERT(!_compiledObject->hasFlag(QV4::CompiledData::Object::IsComponent));
1783 QQmlType type = typeRef->type();
1784 if (type.isComposite() || type.isInlineComponentType())
1785 return { _propertyCache->propertyOffset(), _propertyCache->propertyCount() };
1786 return { 0, _propertyCache->propertyCount() };
1788 const auto [offset, count] = getPropertyCacheRange();
1789 for (
int i = offset; i < count; ++i) {
1790 const QQmlPropertyData *propertyData = _propertyCache->maybeUnresolvedProperty(i);
1796 if (!propertyData->isRequired() && postHocRequired.isEmpty())
1798 QString name = propertyData->name(_qobject);
1799 const auto postHocIt = postHocRequired.constFind(name);
1800 if (postHocIt == postHocRequired.constEnd()) {
1801 if (!propertyData->isRequired())
1804 postHocRequired.erase(postHocIt);
1807 if (isContextObject)
1808 sharedState->hadTopLevelRequiredProperties =
true;
1809 sharedState->requiredProperties.insert(
1810 {_qobject, propertyData},
1811 RequiredPropertyInfo {
1812 std::move(name), compilationUnit->finalUrl(), _compiledObject->location, {}
1816 if (binding && binding->isAttachedProperty()
1817 && sharedState->requiredProperties.size() != oldRequiredPropertiesCount) {
1820 QLatin1String(
"Attached property has required properties. This is not supported"));
1827 if (!postHocRequired.isEmpty()) {
1829 for (
int i = 0; i < offset; ++i) {
1830 const QQmlPropertyData *propertyData = _propertyCache->maybeUnresolvedProperty(i);
1833 QString name = propertyData->name(_qobject);
1834 const auto postHocIt = postHocRequired.constFind(name);
1835 if (postHocIt == postHocRequired.constEnd())
1837 postHocRequired.erase(postHocIt);
1839 if (isContextObject)
1840 sharedState->hadTopLevelRequiredProperties =
true;
1841 sharedState->requiredProperties.insert(
1842 {_qobject, propertyData},
1843 RequiredPropertyInfo {
1844 std::move(name), compilationUnit->finalUrl(), _compiledObject->location, {}
1849 if (!postHocRequired.isEmpty() && hadInheritedRequiredProperties)
1850 recordError({}, QLatin1String(
"Property %1 was marked as required but does not exist").arg(*postHocRequired.begin()));
1853bool QQmlObjectCreator::populateInstance(
int index, QObject *instance, QObject *bindingTarget,
1854 const QQmlPropertyData *valueTypeProperty,
1855 const QV4::CompiledData::Binding *binding)
1858 QQmlData *declarativeData = QQmlData::get(instance,
true);
1860 qSwap(_qobject, instance);
1861 qSwap(_valueTypeProperty, valueTypeProperty);
1862 qSwap(_compiledObjectIndex, index);
1863 const QV4::CompiledData::Object *obj = compilationUnit->objectAt(_compiledObjectIndex);
1864 qSwap(_compiledObject, obj);
1865 qSwap(_ddata, declarativeData);
1866 qSwap(_bindingTarget, bindingTarget);
1868 QV4::Scope valueScope(v4);
1869 QV4::ScopedValue scopeObjectProtector(valueScope);
1871 QQmlPropertyCache::ConstPtr cache = propertyCaches->at(_compiledObjectIndex);
1873 QQmlVMEMetaObject *vmeMetaObject =
nullptr;
1874 if (propertyCaches->needsVMEMetaObject(_compiledObjectIndex)) {
1875 Q_ASSERT(!cache.isNull());
1877 vmeMetaObject =
new QQmlVMEMetaObject(v4, _qobject, cache, compilationUnit, _compiledObjectIndex);
1878 _ddata->propertyCache = cache;
1879 scopeObjectProtector = _ddata->jsWrapper.value();
1881 vmeMetaObject = QQmlVMEMetaObject::get(_qobject);
1884 registerObjectWithContextById(_compiledObject, _qobject);
1886 qSwap(_propertyCache, cache);
1887 qSwap(_vmeMetaObject, vmeMetaObject);
1889 _ddata->compilationUnit = compilationUnit;
1890 if (_compiledObject->hasFlag(QV4::CompiledData::Object::HasDeferredBindings))
1891 _ddata->deferData(_compiledObjectIndex, compilationUnit, context, m_inlineComponentName);
1893 registerPostHocRequiredProperties(binding);
1895 if (_compiledObject->nFunctions > 0)
1897 setupBindings((binding && binding->hasFlag(QV4::CompiledData::Binding::IsDeferredBinding))
1898 ? BindingMode::ApplyAll
1899 : BindingMode::ApplyImmediate);
1901 for (
int aliasIndex = 0; aliasIndex != _compiledObject->aliasCount(); ++aliasIndex) {
1906 _vmeMetaObject->connectAlias(_compiledObject, aliasIndex);
1907 const QV4::CompiledData::Alias* alias = _compiledObject->aliasesBegin() + aliasIndex;
1908 const auto originalAlias = alias;
1909 while (alias->isAliasToLocalAlias())
1910 alias = _compiledObject->aliasesBegin() + alias->localAliasIndex;
1911 if (!context->isIdValueSet(0))
1913 QObject *target = context->idValue(alias->targetObjectId());
1916 QQmlData *targetDData = QQmlData::get(target,
false);
1917 if (targetDData ==
nullptr || targetDData->propertyCache.isNull())
1920 const QQmlPropertyData *aliasProperty =
1921 _propertyCache->property(_vmeMetaObject->aliasOffset() + aliasIndex);
1924 const int targetPropertyIndex = aliasProperty->aliasTarget();
1925 int coreIndex = QQmlPropertyIndex::fromEncoded(targetPropertyIndex).coreIndex();
1927 const QQmlPropertyData *
const targetProperty = targetDData->propertyCache->property(coreIndex);
1928 if (!targetProperty)
1930 auto it = sharedState->requiredProperties.find({target, targetProperty});
1931 if (it != sharedState->requiredProperties.end())
1932 it->aliasesToRequired.push_back(
1933 AliasToRequiredInfo {
1934 compilationUnit->stringAt(originalAlias->nameIndex()),
1935 compilationUnit->finalUrl()
1939 qSwap(_vmeMetaObject, vmeMetaObject);
1940 qSwap(_bindingTarget, bindingTarget);
1941 qSwap(_ddata, declarativeData);
1942 qSwap(_compiledObject, obj);
1943 qSwap(_compiledObjectIndex, index);
1944 qSwap(_valueTypeProperty, valueTypeProperty);
1945 qSwap(_qobject, instance);
1946 qSwap(_propertyCache, cache);
1948 return errors.isEmpty();
1952
1953
1954QQmlComponent *QQmlObjectCreator::createComponent(
1955 QQmlEngine *engine, QV4::ExecutableCompilationUnit *compilationUnit,
int index,
1956 QObject *parent,
const QQmlRefPointer<QQmlContextData> &context)
1958 QQmlComponent *component =
new QQmlComponent(engine, compilationUnit, index, parent);
1959 QQmlComponentPrivate::get(component)->setCreationContext(context);
1960 QQmlData::get(component,
true);
1970void ObjectInCreationGCAnchorList::trackObject(QV4::ExecutionEngine *engine, QObject *instance)
1972 QV4::Value *wrapper = allocationScope->construct(1, QV4::QObjectWrapper::wrap(engine, instance));
1976 QV4::WriteBarrier::markCustom(engine, [wrapper](QV4::MarkStack *ms) {
1977 wrapper->heapObject()->mark(ms);
QT_BEGIN_NAMESPACE Q_STATIC_LOGGING_CATEGORY(lcSynthesizedIterableAccess, "qt.iterable.synthesized", QtWarningMsg)
static QQmlType qmlTypeForObject(QObject *object)
QQmlObjectCreatorRecursionWatcher(QQmlObjectCreator *creator)