738int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c,
int _id,
void **a)
740 Q_ASSERT(o == object);
745 if (intercept(c, _id, a))
748 if (c == QMetaObject::ReadProperty || c == QMetaObject::WriteProperty || c == QMetaObject::ResetProperty || c == QMetaObject::BindableProperty) {
749 if (id >= propOffset()) {
752 const QQmlPropertyData *propertyData = cache->property(_id);
753 if (!propertyData->isAlias()) {
756 QQmlEnginePrivate *ep = (ctxt.isNull() || ctxt->engine() ==
nullptr)
758 : QQmlEnginePrivate::get(ctxt->engine());
760 if (c == QMetaObject::ReadProperty) {
761 if (propertyData->isQList()) {
763 const QQmlPropertyData *propertyData = cache->property(_id);
764 const QMetaType propType = propertyData->propType();
766 if (propType.flags().testFlag(QMetaType::IsQmlList)) {
774 auto mo =
static_cast<QQmlVMEMetaObject *>(
775 QObjectPrivate::get(object)->metaObject);
776 quintptr inheritanceDepth = 0u;
777 while (mo && mo !=
this) {
778 mo = mo->parentVMEMetaObject();
781 constexpr quintptr idBits =
sizeof(quintptr) * CHAR_BIT / 2u;
782 if (Q_UNLIKELY(inheritanceDepth >= (quintptr(1) << idBits))) {
783 qmlWarning(object) <<
"Too many objects in inheritance hierarchy "
787 if (Q_UNLIKELY(quintptr(id) >= (quintptr(1) << idBits))) {
788 qmlWarning(object) <<
"Too many properties in object "
792 quintptr encodedIndex = (inheritanceDepth << idBits) + id;
794 initPropertyAsList(id);
795 *
static_cast<QQmlListProperty<QObject> *>(a[0])
796 = QQmlListProperty<QObject>(
797 object,
reinterpret_cast<
void *>(quintptr(encodedIndex)),
798 list_append, list_count, list_at,
799 list_clear, list_replace, list_removeLast);
800 }
else if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) {
802 QV4::Scope scope(engine);
803 QV4::Scoped<QV4::Sequence> sequence(scope, *(md->data() + id));
804 const void *data = sequence
805 ? QV4::SequencePrototype::getRawContainerPtr(sequence, propType)
807 propType.destruct(a[0]);
808 propType.construct(a[0], data);
810 qmlWarning(object) <<
"Cannot find member data";
813 const QV4::CompiledData::CommonType t
814 = QQmlPropertyCacheCreatorBase::propertyTypeForMetaType(
815 propertyData->propType());
817 case QV4::CompiledData::CommonType::Void:
819 case QV4::CompiledData::CommonType::Int:
820 *
reinterpret_cast<
int *>(a[0]) = readPropertyAsInt(id);
822 case QV4::CompiledData::CommonType::Bool:
823 *
reinterpret_cast<
bool *>(a[0]) = readPropertyAsBool(id);
825 case QV4::CompiledData::CommonType::Real:
826 *
reinterpret_cast<
double *>(a[0]) = readPropertyAsDouble(id);
828 case QV4::CompiledData::CommonType::String:
829 *
reinterpret_cast<QString *>(a[0]) = readPropertyAsString(id);
831 case QV4::CompiledData::CommonType::Url:
832 *
reinterpret_cast<QUrl *>(a[0]) = readPropertyAsUrl(id);
834 case QV4::CompiledData::CommonType::Date:
835 *
reinterpret_cast<QDate *>(a[0]) = readPropertyAsDate(id);
837 case QV4::CompiledData::CommonType::DateTime:
838 *
reinterpret_cast<QDateTime *>(a[0]) = readPropertyAsDateTime(id);
840 case QV4::CompiledData::CommonType::RegExp:
841#if QT_CONFIG(regularexpression)
842 *
reinterpret_cast<QRegularExpression *>(a[0])
843 = readPropertyAsRegularExpression(id);
846 case QV4::CompiledData::CommonType::Rect:
847 *
reinterpret_cast<QRectF *>(a[0]) = readPropertyAsRectF(id);
849 case QV4::CompiledData::CommonType::Size:
850 *
reinterpret_cast<QSizeF *>(a[0]) = readPropertyAsSizeF(id);
852 case QV4::CompiledData::CommonType::Point:
853 *
reinterpret_cast<QPointF *>(a[0]) = readPropertyAsPointF(id);
855 case QV4::CompiledData::CommonType::Time:
856 *
reinterpret_cast<QTime *>(a[0]) = readPropertyAsTime(id);
858 case QV4::CompiledData::CommonType::Var:
860 *
reinterpret_cast<QVariant *>(a[0]) = readPropertyAsVariant(id);
864 *
reinterpret_cast<QVariant *>(a[0]) = QVariant();
867 case QV4::CompiledData::CommonType::Invalid:
868 if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) {
869 QV4::Scope scope(engine);
870 QV4::ScopedValue sv(scope, *(md->data() + id));
873 const QQmlPropertyData *propertyData = cache->property(_id);
875 if (propertyData->isQObject()) {
876 if (
const auto *wrap = sv->as<QV4::QObjectWrapper>())
877 *
reinterpret_cast<QObject **>(a[0]) = wrap->object();
879 *
reinterpret_cast<QObject **>(a[0]) =
nullptr;
881 const QMetaType propType = propertyData->propType();
882 const void *data =
nullptr;
883 if (
const auto *v = sv->as<QV4::VariantObject>()) {
884 const QVariant &variant = v->d()->data();
885 if (variant.metaType() == propType)
886 data = variant.constData();
888 propType.destruct(a[0]);
889 propType.construct(a[0], data);
892 qmlWarning(object) <<
"Cannot find member data";
896 }
else if (c == QMetaObject::WriteProperty) {
897 bool needActivate =
false;
899 if (propertyData->isQList()) {
900 const QMetaType propType = propertyData->propType();
902 if (propType.flags().testFlag(QMetaType::IsQmlList)) {
905 }
else if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) {
907 QV4::Scope scope(engine);
908 QV4::Scoped<QV4::Sequence> sequence(scope, *(md->data() + id));
909 void *data = sequence
910 ? QV4::SequencePrototype::getRawContainerPtr(sequence, propType)
913 if (!propType.equals(data, a[0])) {
914 propType.destruct(data);
915 propType.construct(data, a[0]);
919 if (
const QQmlType type = QQmlMetaType::qmlListType(propType);
920 type.isSequentialContainer()) {
921 sequence = QV4::SequencePrototype::fromData(
922 engine, propType, type.listMetaSequence(), a[0]);
923 }
else if (QSequentialIterable iterable;
926 QMetaType::fromType<QSequentialIterable>(),
928 sequence = QV4::SequencePrototype::fromData(
929 engine, propType, iterable.metaContainer(), a[0]);
931 sequence = QV4::Encode::undefined();
933 md->set(engine, id, sequence);
934 if (sequence->isUndefined()) {
936 <<
"Could not create a QML sequence object for "
942 qmlWarning(object) <<
"Cannot find member data";
945 const QV4::CompiledData::CommonType t
946 = QQmlPropertyCacheCreatorBase::propertyTypeForMetaType(
947 propertyData->propType());
949 case QV4::CompiledData::CommonType::Void:
951 case QV4::CompiledData::CommonType::Int:
952 needActivate = *
reinterpret_cast<
int *>(a[0]) != readPropertyAsInt(id);
953 writeProperty(id, *
reinterpret_cast<
int *>(a[0]));
955 case QV4::CompiledData::CommonType::Bool:
956 needActivate = *
reinterpret_cast<
bool *>(a[0]) != readPropertyAsBool(id);
957 writeProperty(id, *
reinterpret_cast<
bool *>(a[0]));
959 case QV4::CompiledData::CommonType::Real:
960 needActivate = *
reinterpret_cast<
double *>(a[0]) != readPropertyAsDouble(id);
961 writeProperty(id, *
reinterpret_cast<
double *>(a[0]));
963 case QV4::CompiledData::CommonType::String:
964 needActivate = *
reinterpret_cast<QString *>(a[0]) != readPropertyAsString(id);
965 writeProperty(id, *
reinterpret_cast<QString *>(a[0]));
967 case QV4::CompiledData::CommonType::Url:
968 needActivate = *
reinterpret_cast<QUrl *>(a[0]) != readPropertyAsUrl(id);
969 writeProperty(id, *
reinterpret_cast<QUrl *>(a[0]));
971 case QV4::CompiledData::CommonType::Date:
972 needActivate = *
reinterpret_cast<QDate *>(a[0]) != readPropertyAsDate(id);
973 writeProperty(id, *
reinterpret_cast<QDate *>(a[0]));
975 case QV4::CompiledData::CommonType::DateTime:
976 needActivate = *
reinterpret_cast<QDateTime *>(a[0]) != readPropertyAsDateTime(id);
977 writeProperty(id, *
reinterpret_cast<QDateTime *>(a[0]));
979 case QV4::CompiledData::CommonType::RegExp:
980#if QT_CONFIG(regularexpression)
981 needActivate = *
reinterpret_cast<QRegularExpression *>(a[0])
982 != readPropertyAsRegularExpression(id);
983 writeProperty(id, *
reinterpret_cast<QRegularExpression *>(a[0]));
986 case QV4::CompiledData::CommonType::Rect:
987 needActivate = *
reinterpret_cast<QRectF *>(a[0]) != readPropertyAsRectF(id);
988 writeProperty(id, *
reinterpret_cast<QRectF *>(a[0]));
990 case QV4::CompiledData::CommonType::Size:
991 needActivate = *
reinterpret_cast<QSizeF *>(a[0]) != readPropertyAsSizeF(id);
992 writeProperty(id, *
reinterpret_cast<QSizeF *>(a[0]));
994 case QV4::CompiledData::CommonType::Point:
995 needActivate = *
reinterpret_cast<QPointF *>(a[0]) != readPropertyAsPointF(id);
996 writeProperty(id, *
reinterpret_cast<QPointF *>(a[0]));
998 case QV4::CompiledData::CommonType::Time:
999 needActivate = *
reinterpret_cast<QTime *>(a[0]) != readPropertyAsTime(id);
1000 writeProperty(id, *
reinterpret_cast<QTime *>(a[0]));
1002 case QV4::CompiledData::CommonType::Var:
1004 writeKnownVarProperty(id, *
reinterpret_cast<QVariant *>(a[0]));
1006 case QV4::CompiledData::CommonType::Invalid:
1007 if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) {
1008 QV4::Scope scope(engine);
1009 QV4::ScopedValue sv(scope, *(md->data() + id));
1012 const QQmlPropertyData *propertyData = cache->property(_id);
1014 if (propertyData->isQObject()) {
1015 QObject *arg = *
reinterpret_cast<QObject **>(a[0]);
1016 if (
const auto *wrap = sv->as<QV4::QObjectWrapper>())
1017 needActivate = wrap->object() != arg;
1018 else if (arg !=
nullptr || !sv->isNull())
1019 needActivate =
true;
1021 writeProperty(id, arg);
1023 const QMetaType propType = propertyData->propType();
1024 if (
const auto *v = sv->as<QV4::VariantObject>()) {
1025 QVariant &variant = v->d()->data();
1026 if (variant.metaType() != propType) {
1027 needActivate =
true;
1028 variant = QVariant(propType, a[0]);
1029 }
else if (!propType.equals(variant.constData(), a[0])) {
1030 needActivate =
true;
1031 propType.destruct(variant.data());
1032 propType.construct(variant.data(), a[0]);
1035 needActivate =
true;
1036 md->set(engine, id, engine->newVariantObject(
1041 qmlWarning(object) <<
"Cannot find member data";
1047 activate(object, id,
nullptr);
1055 if (id < aliasCount()) {
1056 const QV4::CompiledData::Object *compiledObject = findCompiledObject();
1057 if (!compiledObject)
1060 const QV4::CompiledData::Alias *aliasData = &compiledObject->aliasTable()[id];
1062 if (aliasData->hasFlag(QV4::CompiledData::Alias::AliasPointsToPointerObject)
1063 && c == QMetaObject::ReadProperty){
1064 *
reinterpret_cast<
void **>(a[0]) =
nullptr;
1070 while (aliasData->isAliasToLocalAlias())
1071 aliasData = &compiledObject->aliasTable()[aliasData->localAliasIndex];
1073 QObject *target = ctxt->idValue(aliasData->targetObjectId());
1077 connectAlias(compiledObject, id);
1079 if (aliasData->isObjectAlias()) {
1080 *
reinterpret_cast<QObject **>(a[0]) = target;
1084 QQmlData *targetDData = QQmlData::get(target,
false);
1088 QQmlPropertyIndex encodedIndex = QQmlPropertyIndex::fromEncoded(aliasData->encodedMetaPropertyIndex);
1089 int coreIndex = encodedIndex.coreIndex();
1090 const int valueTypePropertyIndex = encodedIndex.valueTypeIndex();
1092 const auto removePendingBinding
1093 = [c, a](QObject *target,
int coreIndex, QQmlPropertyIndex encodedIndex) {
1095 if (c == QMetaObject::WriteProperty) {
1096 int flags = *
reinterpret_cast<
int*>(a[3]);
1097 if (flags & QQmlPropertyData::RemoveBindingOnAliasWrite) {
1098 QQmlData *targetData = QQmlData::get(target);
1099 if (targetData && targetData->hasBindingBit(coreIndex)) {
1100 QQmlPropertyPrivate::removeBinding(target, encodedIndex);
1101 targetData->clearBindingBit(coreIndex);
1107 if (valueTypePropertyIndex != -1) {
1108 if (!targetDData->propertyCache)
1110 const QQmlPropertyData *pd = targetDData->propertyCache->property(coreIndex);
1112 QQmlGadgetPtrWrapper *valueType = QQmlGadgetPtrWrapper::instance(
1113 ctxt->engine(), pd->propType());
1115 removePendingBinding(target, coreIndex, encodedIndex);
1116 valueType->read(target, coreIndex);
1117 int rv = QMetaObject::metacall(valueType, c, valueTypePropertyIndex, a);
1119 if (c == QMetaObject::WriteProperty)
1120 valueType->write(target, coreIndex, QQmlPropertyData::HasInternalIndex,
1121 valueTypePropertyIndex);
1126 void *argv[1] = { &target };
1127 QMetaObject::metacall(target, QMetaObject::ReadProperty, coreIndex, argv);
1128 removePendingBinding(
1129 target, valueTypePropertyIndex,
1130 QQmlPropertyIndex(valueTypePropertyIndex));
1131 return QMetaObject::metacall(target, c, valueTypePropertyIndex, a);
1135 removePendingBinding(target, coreIndex, encodedIndex);
1136 return QMetaObject::metacall(target, c, coreIndex, a);
1144 }
else if(c == QMetaObject::InvokeMetaMethod) {
1146 if (id >= signalOffset()) {
1148 id -= signalOffset();
1149 if (id < signalCount()) {
1150 activate(object, id, a);
1154 id -= signalCount();
1155 if (id < methodCount()) {
1156 QQmlEngine *engine = ctxt->engine();
1160 QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
1161 QV4::ExecutionEngine *v4 = engine->handle();
1162 ep->referenceScarceResources();
1163 QV4::Scope scope(v4);
1166 QV4::Scoped<QV4::JavaScriptFunctionObject> function(scope, method(id));
1175 "Exception occurred during compilation of function: ")
1176 + QString::fromUtf8(metaObject->method(_id).methodSignature()));
1181 auto methodData = cache->method(_id);
1182 auto arguments = methodData->hasArguments() ? methodData->arguments() :
nullptr;
1184 if (arguments && arguments->names) {
1185 const quint32 parameterCount = arguments->names->size();
1186 Q_ASSERT(parameterCount == function->formalParameterCount());
1187 function->call(object, a, arguments->types, parameterCount);
1189 Q_ASSERT(function->formalParameterCount() == 0);
1190 const QMetaType returnType = methodData->propType();
1191 function->call(object, a, &returnType, 0);
1194 if (scope.hasException()) {
1195 QQmlError error = scope.engine->catchExceptionAsQmlError();
1196 if (error.isValid())
1200 ep->dereferenceScarceResources();
1208 return parent.asT1()->metaCall(object, c, _id, a);
1210 return object->qt_metacall(c, _id, a);