743int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c,
int _id,
void **a)
745 Q_ASSERT(o == object);
750 if (intercept(c, _id, a))
753 if (c == QMetaObject::ReadProperty || c == QMetaObject::WriteProperty || c == QMetaObject::ResetProperty || c == QMetaObject::BindableProperty) {
754 if (id >= propOffset()) {
757 const QQmlPropertyData *propertyData = cache->property(_id);
758 if (!propertyData->isAlias()) {
761 QQmlEnginePrivate *ep = (ctxt.isNull() || ctxt->engine() ==
nullptr)
763 : QQmlEnginePrivate::get(ctxt->engine());
765 if (c == QMetaObject::ReadProperty) {
766 if (propertyData->isQList()) {
768 const QQmlPropertyData *propertyData = cache->property(_id);
769 const QMetaType propType = propertyData->propType();
771 if (propType.flags().testFlag(QMetaType::IsQmlList)) {
772 if (!getListProperty(
773 id,
static_cast<QQmlListProperty<QObject> *>(a[0]))) {
776 }
else if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) {
778 QV4::Scope scope(engine);
779 QV4::Scoped<QV4::Sequence> sequence(scope, *(md->data() + id));
780 switch (QV4::SequencePrototype::getRawContainer(
781 sequence, a[0], propType)) {
782 case QV4::SequencePrototype::Copied:
783 case QV4::SequencePrototype::WasEqual:
785 case QV4::SequencePrototype::TypeMismatch:
788 propType.destruct(a[0]);
789 propType.construct(a[0]);
793 qmlWarning(object) <<
"Cannot find member data";
796 const QV4::CompiledData::CommonType t
797 = QQmlPropertyCacheCreatorBase::propertyTypeForMetaType(
798 propertyData->propType());
800 case QV4::CompiledData::CommonType::Void:
802 case QV4::CompiledData::CommonType::Int:
803 *
reinterpret_cast<
int *>(a[0]) = readPropertyAsInt(id);
805 case QV4::CompiledData::CommonType::Bool:
806 *
reinterpret_cast<
bool *>(a[0]) = readPropertyAsBool(id);
808 case QV4::CompiledData::CommonType::Real:
809 *
reinterpret_cast<
double *>(a[0]) = readPropertyAsDouble(id);
811 case QV4::CompiledData::CommonType::String:
812 *
reinterpret_cast<QString *>(a[0]) = readPropertyAsString(id);
814 case QV4::CompiledData::CommonType::Url:
815 *
reinterpret_cast<QUrl *>(a[0]) = readPropertyAsUrl(id);
817 case QV4::CompiledData::CommonType::Date:
818 *
reinterpret_cast<QDate *>(a[0]) = readPropertyAsDate(id);
820 case QV4::CompiledData::CommonType::DateTime:
821 *
reinterpret_cast<QDateTime *>(a[0]) = readPropertyAsDateTime(id);
823 case QV4::CompiledData::CommonType::RegExp:
824#if QT_CONFIG(regularexpression)
825 *
reinterpret_cast<QRegularExpression *>(a[0])
826 = readPropertyAsRegularExpression(id);
829 case QV4::CompiledData::CommonType::Rect:
830 *
reinterpret_cast<QRectF *>(a[0]) = readPropertyAsRectF(id);
832 case QV4::CompiledData::CommonType::Size:
833 *
reinterpret_cast<QSizeF *>(a[0]) = readPropertyAsSizeF(id);
835 case QV4::CompiledData::CommonType::Point:
836 *
reinterpret_cast<QPointF *>(a[0]) = readPropertyAsPointF(id);
838 case QV4::CompiledData::CommonType::Time:
839 *
reinterpret_cast<QTime *>(a[0]) = readPropertyAsTime(id);
841 case QV4::CompiledData::CommonType::Var:
843 *
reinterpret_cast<QVariant *>(a[0]) = readPropertyAsVariant(id);
847 *
reinterpret_cast<QVariant *>(a[0]) = QVariant();
850 case QV4::CompiledData::CommonType::Invalid:
851 if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) {
852 QV4::Scope scope(engine);
853 QV4::ScopedValue sv(scope, *(md->data() + id));
856 const QQmlPropertyData *propertyData = cache->property(_id);
858 if (propertyData->isQObject()) {
859 if (
const auto *wrap = sv->as<QV4::QObjectWrapper>())
860 *
reinterpret_cast<QObject **>(a[0]) = wrap->object();
862 *
reinterpret_cast<QObject **>(a[0]) =
nullptr;
864 const QMetaType propType = propertyData->propType();
865 const void *data =
nullptr;
866 if (
const auto *v = sv->as<QV4::VariantObject>()) {
867 const QVariant &variant = v->d()->data();
868 if (variant.metaType() == propType)
869 data = variant.constData();
871 propType.destruct(a[0]);
872 propType.construct(a[0], data);
875 qmlWarning(object) <<
"Cannot find member data";
879 }
else if (c == QMetaObject::WriteProperty) {
880 bool needActivate =
false;
882 if (propertyData->isQList()) {
883 const QMetaType propType = propertyData->propType();
885 if (propType.flags().testFlag(QMetaType::IsQmlList)) {
887 QQmlListProperty<QObject> listProp;
888 if (!getListProperty(id, &listProp))
891 QQmlListProperty<QObject> *input
892 =
static_cast<QQmlListProperty<QObject> *>(a[0]);
896 if (listProp.count(&listProp) != input->count(input)) {
899 for (qsizetype i = 0, end = input->count(input); i < end; ++i) {
900 if (listProp.at(&listProp, i) == input->at(input, i))
911 QQmlVMEMetaObject::list_clear_nosignal(&listProp);
912 for (qsizetype i = 0, end = input->count(input); i < end; ++i) {
913 QQmlVMEMetaObject::list_append_nosignal(
914 &listProp, input->at(input, i));
917 }
else if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) {
919 QV4::Scope scope(engine);
920 QV4::Scoped<QV4::Sequence> sequence(scope, *(md->data() + id));
921 switch (QV4::SequencePrototype::setRawContainer(
922 sequence, a[0], propType)) {
923 case QV4::SequencePrototype::Copied:
926 case QV4::SequencePrototype::WasEqual:
928 case QV4::SequencePrototype::TypeMismatch: {
929 if (
const QQmlType type = QQmlMetaType::qmlListType(propType);
930 type.isSequentialContainer()) {
931 sequence = QV4::SequencePrototype::fromData(
932 engine, propType, type.listMetaSequence(), a[0]);
933 }
else if (QSequentialIterable iterable;
936 QMetaType::fromType<QSequentialIterable>(),
938 sequence = QV4::SequencePrototype::fromData(
939 engine, propType, iterable.metaContainer(), a[0]);
941 sequence = QV4::Encode::undefined();
943 md->set(engine, id, sequence);
944 if (sequence->isUndefined()) {
946 <<
"Could not create a QML sequence object for "
954 qmlWarning(object) <<
"Cannot find member data";
957 const QV4::CompiledData::CommonType t
958 = QQmlPropertyCacheCreatorBase::propertyTypeForMetaType(
959 propertyData->propType());
961 case QV4::CompiledData::CommonType::Void:
963 case QV4::CompiledData::CommonType::Int:
964 needActivate = *
reinterpret_cast<
int *>(a[0]) != readPropertyAsInt(id);
965 writeProperty(id, *
reinterpret_cast<
int *>(a[0]));
967 case QV4::CompiledData::CommonType::Bool:
968 needActivate = *
reinterpret_cast<
bool *>(a[0]) != readPropertyAsBool(id);
969 writeProperty(id, *
reinterpret_cast<
bool *>(a[0]));
971 case QV4::CompiledData::CommonType::Real:
972 needActivate = *
reinterpret_cast<
double *>(a[0]) != readPropertyAsDouble(id);
973 writeProperty(id, *
reinterpret_cast<
double *>(a[0]));
975 case QV4::CompiledData::CommonType::String:
976 needActivate = *
reinterpret_cast<QString *>(a[0]) != readPropertyAsString(id);
977 writeProperty(id, *
reinterpret_cast<QString *>(a[0]));
979 case QV4::CompiledData::CommonType::Url:
980 needActivate = *
reinterpret_cast<QUrl *>(a[0]) != readPropertyAsUrl(id);
981 writeProperty(id, *
reinterpret_cast<QUrl *>(a[0]));
983 case QV4::CompiledData::CommonType::Date:
984 needActivate = *
reinterpret_cast<QDate *>(a[0]) != readPropertyAsDate(id);
985 writeProperty(id, *
reinterpret_cast<QDate *>(a[0]));
987 case QV4::CompiledData::CommonType::DateTime:
988 needActivate = *
reinterpret_cast<QDateTime *>(a[0]) != readPropertyAsDateTime(id);
989 writeProperty(id, *
reinterpret_cast<QDateTime *>(a[0]));
991 case QV4::CompiledData::CommonType::RegExp:
992#if QT_CONFIG(regularexpression)
993 needActivate = *
reinterpret_cast<QRegularExpression *>(a[0])
994 != readPropertyAsRegularExpression(id);
995 writeProperty(id, *
reinterpret_cast<QRegularExpression *>(a[0]));
998 case QV4::CompiledData::CommonType::Rect:
999 needActivate = *
reinterpret_cast<QRectF *>(a[0]) != readPropertyAsRectF(id);
1000 writeProperty(id, *
reinterpret_cast<QRectF *>(a[0]));
1002 case QV4::CompiledData::CommonType::Size:
1003 needActivate = *
reinterpret_cast<QSizeF *>(a[0]) != readPropertyAsSizeF(id);
1004 writeProperty(id, *
reinterpret_cast<QSizeF *>(a[0]));
1006 case QV4::CompiledData::CommonType::Point:
1007 needActivate = *
reinterpret_cast<QPointF *>(a[0]) != readPropertyAsPointF(id);
1008 writeProperty(id, *
reinterpret_cast<QPointF *>(a[0]));
1010 case QV4::CompiledData::CommonType::Time:
1011 needActivate = *
reinterpret_cast<QTime *>(a[0]) != readPropertyAsTime(id);
1012 writeProperty(id, *
reinterpret_cast<QTime *>(a[0]));
1014 case QV4::CompiledData::CommonType::Var:
1016 writeKnownVarProperty(id, *
reinterpret_cast<QVariant *>(a[0]));
1018 case QV4::CompiledData::CommonType::Invalid:
1019 if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) {
1020 QV4::Scope scope(engine);
1021 QV4::ScopedValue sv(scope, *(md->data() + id));
1024 const QQmlPropertyData *propertyData = cache->property(_id);
1026 if (propertyData->isQObject()) {
1027 QObject *arg = *
reinterpret_cast<QObject **>(a[0]);
1028 if (
const auto *wrap = sv->as<QV4::QObjectWrapper>())
1029 needActivate = wrap->object() != arg;
1030 else if (arg !=
nullptr || !sv->isNull())
1031 needActivate =
true;
1033 writeProperty(id, arg);
1035 const QMetaType propType = propertyData->propType();
1036 if (
const auto *v = sv->as<QV4::VariantObject>()) {
1037 QVariant &variant = v->d()->data();
1038 if (variant.metaType() != propType) {
1039 needActivate =
true;
1040 variant = QVariant(propType, a[0]);
1041 }
else if (!propType.equals(variant.constData(), a[0])) {
1042 needActivate =
true;
1043 propType.destruct(variant.data());
1044 propType.construct(variant.data(), a[0]);
1047 needActivate =
true;
1048 md->set(engine, id, engine->newVariantObject(
1053 qmlWarning(object) <<
"Cannot find member data";
1059 activate(object, id,
nullptr);
1067 if (id < aliasCount()) {
1068 const QV4::CompiledData::Object *compiledObject = findCompiledObject();
1069 if (!compiledObject)
1072 const QV4::CompiledData::Alias *aliasData = &compiledObject->aliasTable()[id];
1074 if (aliasData->hasFlag(QV4::CompiledData::Alias::AliasPointsToPointerObject)
1075 && c == QMetaObject::ReadProperty){
1076 *
reinterpret_cast<
void **>(a[0]) =
nullptr;
1082 while (aliasData->isAliasToLocalAlias())
1083 aliasData = &compiledObject->aliasTable()[aliasData->localAliasIndex];
1085 QObject *target = ctxt->idValue(aliasData->targetObjectId());
1089 connectAlias(compiledObject, id);
1091 const QQmlPropertyData *aliasProperty = cache->property(aliasOffset() + id);
1092 const int targetPropertyIndex = aliasProperty ? aliasProperty->aliasTarget() : -1;
1094 if (targetPropertyIndex == -1) {
1095 *
reinterpret_cast<QObject **>(a[0]) = target;
1099 QQmlData *targetDData = QQmlData::get(target,
false);
1103 QQmlPropertyIndex encodedIndex
1104 = QQmlPropertyIndex::fromEncoded(targetPropertyIndex);
1105 int coreIndex = encodedIndex.coreIndex();
1106 const int valueTypePropertyIndex = encodedIndex.valueTypeIndex();
1108 const auto removePendingBinding
1109 = [c, a](QObject *target,
int coreIndex, QQmlPropertyIndex encodedIndex) {
1111 if (c == QMetaObject::WriteProperty) {
1112 int flags = *
reinterpret_cast<
int*>(a[3]);
1113 if (flags & QQmlPropertyData::RemoveBindingOnAliasWrite) {
1114 QQmlData *targetData = QQmlData::get(target);
1115 if (targetData && targetData->hasBindingBit(coreIndex)) {
1116 if (QQmlPropertyPrivate::removeBinding(
1117 target, encodedIndex, QQmlPropertyPrivate::None)) {
1118 targetData->clearBindingBit(coreIndex);
1125 if (valueTypePropertyIndex != -1) {
1126 if (!targetDData->propertyCache)
1128 const QQmlPropertyData *pd = targetDData->propertyCache->property(coreIndex);
1130 QQmlGadgetPtrWrapper *valueType = QQmlGadgetPtrWrapper::instance(
1131 ctxt->engine(), pd->propType());
1135 if (c == QMetaObject::BindableProperty)
1136 return QMetaObject::metacall(target, c, coreIndex, a);
1138 removePendingBinding(target, coreIndex, encodedIndex);
1139 valueType->read(target, coreIndex);
1140 int rv = QMetaObject::metacall(valueType, c, valueTypePropertyIndex, a);
1142 if (c == QMetaObject::WriteProperty)
1143 valueType->write(target, coreIndex, QQmlPropertyData::HasInternalIndex,
1144 valueTypePropertyIndex);
1149 void *argv[1] = { &target };
1150 QMetaObject::metacall(target, QMetaObject::ReadProperty, coreIndex, argv);
1151 removePendingBinding(
1152 target, valueTypePropertyIndex,
1153 QQmlPropertyIndex(valueTypePropertyIndex));
1154 return QMetaObject::metacall(target, c, valueTypePropertyIndex, a);
1158 removePendingBinding(target, coreIndex, encodedIndex);
1159 return QMetaObject::metacall(target, c, coreIndex, a);
1167 }
else if(c == QMetaObject::InvokeMetaMethod) {
1169 if (id >= signalOffset()) {
1171 id -= signalOffset();
1172 if (id < signalCount()) {
1173 activate(object, id, a);
1177 id -= signalCount();
1178 if (id < methodCount()) {
1179 QQmlEngine *engine = ctxt->engine();
1183 QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
1184 QV4::ExecutionEngine *v4 = engine->handle();
1185 ep->referenceScarceResources();
1186 QV4::Scope scope(v4);
1189 QV4::Scoped<QV4::JavaScriptFunctionObject> function(scope, method(id));
1198 "Exception occurred during compilation of function: ")
1199 + QString::fromUtf8(metaObject->method(_id).methodSignature()));
1204 auto methodData = cache->method(_id);
1205 auto arguments = methodData->hasArguments() ? methodData->arguments() :
nullptr;
1207 if (arguments && arguments->names) {
1208 const quint32 parameterCount = arguments->names->size();
1209 Q_ASSERT(parameterCount == function->formalParameterCount());
1210 function->call(object, a, arguments->types, parameterCount);
1212 Q_ASSERT(function->formalParameterCount() == 0);
1213 const QMetaType returnType = methodData->propType();
1214 function->call(object, a, &returnType, 0);
1217 if (scope.hasException()) {
1218 QQmlError error = scope.engine->catchExceptionAsQmlError();
1219 if (error.isValid())
1223 ep->dereferenceScarceResources();
1231 return parent.asT1()->metaCall(object, c, _id, a);
1233 return object->qt_metacall(c, _id, a);