746int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c,
int _id,
void **a)
748 Q_ASSERT(o == object);
753 if (intercept(c, _id, a))
756 if (c == QMetaObject::ReadProperty || c == QMetaObject::WriteProperty || c == QMetaObject::ResetProperty || c == QMetaObject::BindableProperty) {
757 if (id >= propOffset()) {
760 const QQmlPropertyData *propertyData = cache->property(_id);
761 if (!propertyData->isAlias()) {
764 QQmlEnginePrivate *ep = (m_ctxt.isNull() || m_ctxt->engine() ==
nullptr)
766 : QQmlEnginePrivate::get(m_ctxt->engine());
768 if (c == QMetaObject::ReadProperty) {
769 if (propertyData->isQList()) {
771 const QQmlPropertyData *propertyData = cache->property(_id);
772 const QMetaType propType = propertyData->propType();
774 if (propType.flags().testFlag(QMetaType::IsQmlList)) {
775 if (!getListProperty(
776 id,
static_cast<QQmlListProperty<QObject> *>(a[0]))) {
779 }
else if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) {
781 QV4::Scope scope(m_engine);
782 QV4::Scoped<QV4::Sequence> sequence(scope, *(md->data() + id));
783 switch (QV4::SequencePrototype::getRawContainer(
784 sequence, a[0], propType)) {
785 case QV4::SequencePrototype::Copied:
786 case QV4::SequencePrototype::WasEqual:
788 case QV4::SequencePrototype::TypeMismatch:
791 propType.destruct(a[0]);
792 propType.construct(a[0]);
796 qmlWarning(object) <<
"Cannot find member data";
799 const QV4::CompiledData::CommonType t
800 = QQmlPropertyCacheCreatorBase::propertyTypeForMetaType(
801 propertyData->propType());
803 case QV4::CompiledData::CommonType::Void:
805 case QV4::CompiledData::CommonType::Int:
806 *
reinterpret_cast<
int *>(a[0]) = readPropertyAsInt(id);
808 case QV4::CompiledData::CommonType::Bool:
809 *
reinterpret_cast<
bool *>(a[0]) = readPropertyAsBool(id);
811 case QV4::CompiledData::CommonType::Real:
812 *
reinterpret_cast<
double *>(a[0]) = readPropertyAsDouble(id);
814 case QV4::CompiledData::CommonType::String:
815 *
reinterpret_cast<QString *>(a[0]) = readPropertyAsString(id);
817 case QV4::CompiledData::CommonType::Url:
818 *
reinterpret_cast<QUrl *>(a[0]) = readPropertyAsUrl(id);
820 case QV4::CompiledData::CommonType::Date:
821 *
reinterpret_cast<QDate *>(a[0]) = readPropertyAsDate(id);
823 case QV4::CompiledData::CommonType::DateTime:
824 *
reinterpret_cast<QDateTime *>(a[0]) = readPropertyAsDateTime(id);
826 case QV4::CompiledData::CommonType::RegExp:
827#if QT_CONFIG(regularexpression)
828 *
reinterpret_cast<QRegularExpression *>(a[0])
829 = readPropertyAsRegularExpression(id);
832 case QV4::CompiledData::CommonType::Rect:
833 *
reinterpret_cast<QRectF *>(a[0]) = readPropertyAsRectF(id);
835 case QV4::CompiledData::CommonType::Size:
836 *
reinterpret_cast<QSizeF *>(a[0]) = readPropertyAsSizeF(id);
838 case QV4::CompiledData::CommonType::Point:
839 *
reinterpret_cast<QPointF *>(a[0]) = readPropertyAsPointF(id);
841 case QV4::CompiledData::CommonType::Time:
842 *
reinterpret_cast<QTime *>(a[0]) = readPropertyAsTime(id);
844 case QV4::CompiledData::CommonType::Var:
846 *
reinterpret_cast<QVariant *>(a[0]) = readPropertyAsVariant(id);
850 *
reinterpret_cast<QVariant *>(a[0]) = QVariant();
853 case QV4::CompiledData::CommonType::Invalid:
854 if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) {
855 QV4::Scope scope(m_engine);
856 QV4::ScopedValue sv(scope, *(md->data() + id));
859 const QQmlPropertyData *propertyData = cache->property(_id);
861 if (propertyData->isQObject()) {
862 if (
const auto *wrap = sv->as<QV4::QObjectWrapper>())
863 *
reinterpret_cast<QObject **>(a[0]) = wrap->object();
865 *
reinterpret_cast<QObject **>(a[0]) =
nullptr;
867 const QMetaType propType = propertyData->propType();
868 const void *data =
nullptr;
869 if (
const auto *v = sv->as<QV4::VariantObject>()) {
870 const QVariant &variant = v->d()->data();
871 if (variant.metaType() == propType)
872 data = variant.constData();
874 propType.destruct(a[0]);
875 propType.construct(a[0], data);
878 qmlWarning(object) <<
"Cannot find member data";
882 }
else if (c == QMetaObject::WriteProperty) {
883 bool needActivate =
false;
885 if (propertyData->isQList()) {
886 const QMetaType propType = propertyData->propType();
888 if (propType.flags().testFlag(QMetaType::IsQmlList)) {
890 QQmlListProperty<QObject> listProp;
891 if (!getListProperty(id, &listProp))
894 QQmlListProperty<QObject> *input
895 =
static_cast<QQmlListProperty<QObject> *>(a[0]);
899 if (listProp.count(&listProp) != input->count(input)) {
902 for (qsizetype i = 0, end = input->count(input); i < end; ++i) {
903 if (listProp.at(&listProp, i) == input->at(input, i))
914 QQmlVMEMetaObject::list_clear_nosignal(&listProp);
915 for (qsizetype i = 0, end = input->count(input); i < end; ++i) {
916 QQmlVMEMetaObject::list_append_nosignal(
917 &listProp, input->at(input, i));
920 }
else if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) {
922 QV4::Scope scope(m_engine);
923 QV4::Scoped<QV4::Sequence> sequence(scope, *(md->data() + id));
924 switch (QV4::SequencePrototype::setRawContainer(
925 sequence, a[0], propType)) {
926 case QV4::SequencePrototype::Copied:
929 case QV4::SequencePrototype::WasEqual:
931 case QV4::SequencePrototype::TypeMismatch: {
932 if (
const QQmlType type = QQmlMetaType::qmlListType(propType);
933 type.isSequentialContainer()) {
934 sequence = QV4::SequencePrototype::fromData(
935 m_engine, propType, type.listMetaSequence(), a[0]);
936 }
else if (QMetaSequence::Iterable iterable;
939 QMetaType::fromType<QMetaSequence::Iterable>(),
941 sequence = QV4::SequencePrototype::fromData(
942 m_engine, propType, iterable.metaContainer(), a[0]);
944 sequence = QV4::Encode::undefined();
946 md->set(m_engine, id, sequence);
947 if (sequence->isUndefined()) {
949 <<
"Could not create a QML sequence object for "
957 qmlWarning(object) <<
"Cannot find member data";
960 const QV4::CompiledData::CommonType t
961 = QQmlPropertyCacheCreatorBase::propertyTypeForMetaType(
962 propertyData->propType());
964 case QV4::CompiledData::CommonType::Void:
966 case QV4::CompiledData::CommonType::Int:
967 needActivate = *
reinterpret_cast<
int *>(a[0]) != readPropertyAsInt(id);
968 writeProperty(id, *
reinterpret_cast<
int *>(a[0]));
970 case QV4::CompiledData::CommonType::Bool:
971 needActivate = *
reinterpret_cast<
bool *>(a[0]) != readPropertyAsBool(id);
972 writeProperty(id, *
reinterpret_cast<
bool *>(a[0]));
974 case QV4::CompiledData::CommonType::Real:
975 needActivate = *
reinterpret_cast<
double *>(a[0]) != readPropertyAsDouble(id);
976 writeProperty(id, *
reinterpret_cast<
double *>(a[0]));
978 case QV4::CompiledData::CommonType::String:
979 needActivate = *
reinterpret_cast<QString *>(a[0]) != readPropertyAsString(id);
980 writeProperty(id, *
reinterpret_cast<QString *>(a[0]));
982 case QV4::CompiledData::CommonType::Url:
983 needActivate = *
reinterpret_cast<QUrl *>(a[0]) != readPropertyAsUrl(id);
984 writeProperty(id, *
reinterpret_cast<QUrl *>(a[0]));
986 case QV4::CompiledData::CommonType::Date:
987 needActivate = *
reinterpret_cast<QDate *>(a[0]) != readPropertyAsDate(id);
988 writeProperty(id, *
reinterpret_cast<QDate *>(a[0]));
990 case QV4::CompiledData::CommonType::DateTime:
991 needActivate = *
reinterpret_cast<QDateTime *>(a[0]) != readPropertyAsDateTime(id);
992 writeProperty(id, *
reinterpret_cast<QDateTime *>(a[0]));
994 case QV4::CompiledData::CommonType::RegExp:
995#if QT_CONFIG(regularexpression)
996 needActivate = *
reinterpret_cast<QRegularExpression *>(a[0])
997 != readPropertyAsRegularExpression(id);
998 writeProperty(id, *
reinterpret_cast<QRegularExpression *>(a[0]));
1001 case QV4::CompiledData::CommonType::Rect:
1002 needActivate = *
reinterpret_cast<QRectF *>(a[0]) != readPropertyAsRectF(id);
1003 writeProperty(id, *
reinterpret_cast<QRectF *>(a[0]));
1005 case QV4::CompiledData::CommonType::Size:
1006 needActivate = *
reinterpret_cast<QSizeF *>(a[0]) != readPropertyAsSizeF(id);
1007 writeProperty(id, *
reinterpret_cast<QSizeF *>(a[0]));
1009 case QV4::CompiledData::CommonType::Point:
1010 needActivate = *
reinterpret_cast<QPointF *>(a[0]) != readPropertyAsPointF(id);
1011 writeProperty(id, *
reinterpret_cast<QPointF *>(a[0]));
1013 case QV4::CompiledData::CommonType::Time:
1014 needActivate = *
reinterpret_cast<QTime *>(a[0]) != readPropertyAsTime(id);
1015 writeProperty(id, *
reinterpret_cast<QTime *>(a[0]));
1017 case QV4::CompiledData::CommonType::Var:
1019 writeKnownVarProperty(id, *
reinterpret_cast<QVariant *>(a[0]));
1021 case QV4::CompiledData::CommonType::Invalid:
1022 if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) {
1023 QV4::Scope scope(m_engine);
1024 QV4::ScopedValue sv(scope, *(md->data() + id));
1027 const QQmlPropertyData *propertyData = cache->property(_id);
1029 if (propertyData->isQObject()) {
1030 QObject *arg = *
reinterpret_cast<QObject **>(a[0]);
1031 if (
const auto *wrap = sv->as<QV4::QObjectWrapper>())
1032 needActivate = wrap->object() != arg;
1033 else if (arg !=
nullptr || !sv->isNull())
1034 needActivate =
true;
1036 writeProperty(id, arg);
1038 const QMetaType propType = propertyData->propType();
1039 if (
const auto *v = sv->as<QV4::VariantObject>()) {
1040 QVariant &variant = v->d()->data();
1041 if (variant.metaType() != propType) {
1042 needActivate =
true;
1043 variant = QVariant(propType, a[0]);
1044 }
else if (!propType.equals(variant.constData(), a[0])) {
1045 needActivate =
true;
1046 propType.destruct(variant.data());
1047 propType.construct(variant.data(), a[0]);
1050 needActivate =
true;
1051 md->set(m_engine, id, m_engine->newVariantObject(
1056 qmlWarning(object) <<
"Cannot find member data";
1062 activate(object, id,
nullptr);
1070 if (id < aliasCount()) {
1071 const QV4::CompiledData::Object *compiledObject = findCompiledObject();
1072 if (!compiledObject)
1075 const QV4::CompiledData::Alias *aliasData = &compiledObject->aliasTable()[id];
1077 if (aliasData->hasFlag(QV4::CompiledData::Alias::AliasPointsToPointerObject)
1078 && c == QMetaObject::ReadProperty){
1079 *
reinterpret_cast<
void **>(a[0]) =
nullptr;
1082 if (m_ctxt.isNull())
1085 while (aliasData->isAliasToLocalAlias())
1086 aliasData = &compiledObject->aliasTable()[aliasData->localAliasIndex];
1088 QObject *target = m_ctxt->idValue(aliasData->targetObjectId());
1092 connectAlias(compiledObject, id);
1094 const QQmlPropertyData *aliasProperty = cache->property(aliasOffset() + id);
1095 const int targetPropertyIndex = aliasProperty ? aliasProperty->aliasTarget() : -1;
1097 if (targetPropertyIndex == -1) {
1098 *
reinterpret_cast<QObject **>(a[0]) = target;
1102 QQmlData *targetDData = QQmlData::get(target,
false);
1106 QQmlPropertyIndex encodedIndex
1107 = QQmlPropertyIndex::fromEncoded(targetPropertyIndex);
1108 int coreIndex = encodedIndex.coreIndex();
1109 const int valueTypePropertyIndex = encodedIndex.valueTypeIndex();
1111 const auto removePendingBinding
1112 = [c, a](QObject *target,
int coreIndex, QQmlPropertyIndex encodedIndex) {
1114 if (c == QMetaObject::WriteProperty) {
1115 int flags = *
reinterpret_cast<
int*>(a[3]);
1116 if (flags & QQmlPropertyData::RemoveBindingOnAliasWrite) {
1117 QQmlData *targetData = QQmlData::get(target);
1118 if (targetData && targetData->hasBindingBit(coreIndex)) {
1119 if (QQmlPropertyPrivate::removeBinding(
1120 target, encodedIndex, QQmlPropertyPrivate::None)) {
1121 targetData->clearBindingBit(coreIndex);
1128 if (valueTypePropertyIndex != -1) {
1129 if (!targetDData->propertyCache)
1131 const QQmlPropertyData *pd = targetDData->propertyCache->property(coreIndex);
1133 QQmlGadgetPtrWrapper *valueType = QQmlGadgetPtrWrapper::instance(
1134 m_ctxt->engine(), pd->propType());
1138 if (c == QMetaObject::BindableProperty)
1139 return QMetaObject::metacall(target, c, coreIndex, a);
1141 removePendingBinding(target, coreIndex, encodedIndex);
1142 valueType->read(target, coreIndex);
1143 int rv = QMetaObject::metacall(valueType, c, valueTypePropertyIndex, a);
1145 if (c == QMetaObject::WriteProperty)
1146 valueType->write(target, coreIndex, QQmlPropertyData::HasInternalIndex,
1147 valueTypePropertyIndex);
1152 void *argv[1] = { &target };
1153 QMetaObject::metacall(target, QMetaObject::ReadProperty, coreIndex, argv);
1154 removePendingBinding(
1155 target, valueTypePropertyIndex,
1156 QQmlPropertyIndex(valueTypePropertyIndex));
1157 return QMetaObject::metacall(target, c, valueTypePropertyIndex, a);
1161 removePendingBinding(target, coreIndex, encodedIndex);
1162 return QMetaObject::metacall(target, c, coreIndex, a);
1170 }
else if(c == QMetaObject::InvokeMetaMethod) {
1172 if (id >= signalOffset()) {
1174 id -= signalOffset();
1175 if (id < signalCount()) {
1176 activate(object, id, a);
1180 id -= signalCount();
1181 if (id < methodCount()) {
1182 QQmlEngine *engine = m_ctxt->engine();
1186 QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
1187 QV4::ExecutionEngine *v4 = engine->handle();
1188 ep->referenceScarceResources();
1189 QV4::Scope scope(v4);
1192 QV4::Scoped<QV4::JavaScriptFunctionObject> function(scope, method(id));
1201 "Exception occurred during compilation of function: ")
1202 + QString::fromUtf8(metaObject->method(_id).methodSignature()));
1207 auto methodData = cache->method(_id);
1208 auto arguments = methodData->hasArguments() ? methodData->arguments() :
nullptr;
1210 if (arguments && arguments->names) {
1211 const quint32 parameterCount = arguments->names->size();
1212 Q_ASSERT(parameterCount == function->formalParameterCount());
1213 function->call(object, a, arguments->types, parameterCount);
1215 Q_ASSERT(function->formalParameterCount() == 0);
1216 const QMetaType returnType = methodData->propType();
1217 function->call(object, a, &returnType, 0);
1220 if (scope.hasException()) {
1221 QQmlError error = scope.engine->catchExceptionAsQmlError();
1222 if (error.isValid())
1226 ep->dereferenceScarceResources();
1234 return parent.asT1()->metaCall(object, c, _id, a);
1236 return object->qt_metacall(c, _id, a);