756int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c,
int _id,
void **a)
758 Q_ASSERT(o == object);
763 if (intercept(c, _id, a))
766 if (c == QMetaObject::ReadProperty || c == QMetaObject::WriteProperty || c == QMetaObject::ResetProperty || c == QMetaObject::BindableProperty) {
767 if (id >= propOffset()) {
770 const QQmlPropertyData *propertyData = cache->property(_id);
771 if (!propertyData->isAlias()) {
774 QQmlEnginePrivate *ep = (m_ctxt.isNull() || m_ctxt->engine() ==
nullptr)
776 : QQmlEnginePrivate::get(m_ctxt->engine());
778 if (c == QMetaObject::ReadProperty) {
779 if (propertyData->isQList()) {
781 const QQmlPropertyData *propertyData = cache->property(_id);
782 const QMetaType propType = propertyData->propType();
784 if (propType.flags().testFlag(QMetaType::IsQmlList)) {
785 if (!getListProperty(
786 id,
static_cast<QQmlListProperty<QObject> *>(a[0]))) {
789 }
else if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) {
791 QV4::Scope scope(m_engine);
792 QV4::Scoped<QV4::Sequence> sequence(scope, *(md->data() + id));
793 switch (QV4::SequencePrototype::getRawContainer(
794 sequence, a[0], propType)) {
795 case QV4::SequencePrototype::Copied:
796 case QV4::SequencePrototype::WasEqual:
798 case QV4::SequencePrototype::TypeMismatch:
801 propType.destruct(a[0]);
802 propType.construct(a[0]);
806 qmlWarning(object) <<
"Cannot find member data";
809 const QV4::CompiledData::CommonType t
810 = QQmlPropertyCacheCreatorBase::propertyTypeForMetaType(
811 propertyData->propType());
813 case QV4::CompiledData::CommonType::Void:
815 case QV4::CompiledData::CommonType::Int:
816 *
reinterpret_cast<
int *>(a[0]) = readPropertyAsInt(id);
818 case QV4::CompiledData::CommonType::Bool:
819 *
reinterpret_cast<
bool *>(a[0]) = readPropertyAsBool(id);
821 case QV4::CompiledData::CommonType::Real:
822 *
reinterpret_cast<
double *>(a[0]) = readPropertyAsDouble(id);
824 case QV4::CompiledData::CommonType::String:
825 *
reinterpret_cast<QString *>(a[0]) = readPropertyAsString(id);
827 case QV4::CompiledData::CommonType::Url:
828 *
reinterpret_cast<QUrl *>(a[0]) = readPropertyAsUrl(id);
830 case QV4::CompiledData::CommonType::Date:
831 *
reinterpret_cast<QDate *>(a[0]) = readPropertyAsDate(id);
833 case QV4::CompiledData::CommonType::DateTime:
834 *
reinterpret_cast<QDateTime *>(a[0]) = readPropertyAsDateTime(id);
836 case QV4::CompiledData::CommonType::RegExp:
837#if QT_CONFIG(regularexpression)
838 *
reinterpret_cast<QRegularExpression *>(a[0])
839 = readPropertyAsRegularExpression(id);
842 case QV4::CompiledData::CommonType::Rect:
843 *
reinterpret_cast<QRectF *>(a[0]) = readPropertyAsRectF(id);
845 case QV4::CompiledData::CommonType::Size:
846 *
reinterpret_cast<QSizeF *>(a[0]) = readPropertyAsSizeF(id);
848 case QV4::CompiledData::CommonType::Point:
849 *
reinterpret_cast<QPointF *>(a[0]) = readPropertyAsPointF(id);
851 case QV4::CompiledData::CommonType::Time:
852 *
reinterpret_cast<QTime *>(a[0]) = readPropertyAsTime(id);
854 case QV4::CompiledData::CommonType::Var:
856 *
reinterpret_cast<QVariant *>(a[0]) = readPropertyAsVariant(id);
860 *
reinterpret_cast<QVariant *>(a[0]) = QVariant();
863 case QV4::CompiledData::CommonType::Invalid:
864 if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) {
865 QV4::Scope scope(m_engine);
866 QV4::ScopedValue sv(scope, *(md->data() + id));
869 const QQmlPropertyData *propertyData = cache->property(_id);
871 if (propertyData->isQObject()) {
872 if (
const auto *wrap = sv->as<QV4::QObjectWrapper>())
873 *
reinterpret_cast<QObject **>(a[0]) = wrap->object();
875 *
reinterpret_cast<QObject **>(a[0]) =
nullptr;
877 const QMetaType propType = propertyData->propType();
878 const void *data =
nullptr;
879 if (
const auto *v = sv->as<QV4::VariantObject>()) {
880 const QVariant &variant = v->d()->data();
881 if (variant.metaType() == propType)
882 data = variant.constData();
884 propType.destruct(a[0]);
885 propType.construct(a[0], data);
888 qmlWarning(object) <<
"Cannot find member data";
892 }
else if (c == QMetaObject::WriteProperty) {
893 bool needActivate =
false;
895 if (propertyData->isQList()) {
896 const QMetaType propType = propertyData->propType();
898 if (propType.flags().testFlag(QMetaType::IsQmlList)) {
900 QQmlListProperty<QObject> listProp;
901 if (!getListProperty(id, &listProp))
904 QQmlListProperty<QObject> *input
905 =
static_cast<QQmlListProperty<QObject> *>(a[0]);
909 if (listProp.count(&listProp) != input->count(input)) {
912 for (qsizetype i = 0, end = input->count(input); i < end; ++i) {
913 if (listProp.at(&listProp, i) == input->at(input, i))
924 QQmlVMEMetaObject::list_clear_nosignal(&listProp);
925 for (qsizetype i = 0, end = input->count(input); i < end; ++i) {
926 QQmlVMEMetaObject::list_append_nosignal(
927 &listProp, input->at(input, i));
930 }
else if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) {
932 QV4::Scope scope(m_engine);
933 QV4::Scoped<QV4::Sequence> sequence(scope, *(md->data() + id));
934 switch (QV4::SequencePrototype::setRawContainer(
935 sequence, a[0], propType)) {
936 case QV4::SequencePrototype::Copied:
939 case QV4::SequencePrototype::WasEqual:
941 case QV4::SequencePrototype::TypeMismatch: {
942 if (
const QQmlType type = QQmlMetaType::qmlListType(propType);
943 type.isSequentialContainer()) {
944 sequence = QV4::SequencePrototype::fromData(
945 m_engine, propType, type.listMetaSequence(), a[0]);
946 }
else if (QMetaSequence::Iterable iterable;
949 QMetaType::fromType<QMetaSequence::Iterable>(),
951 sequence = QV4::SequencePrototype::fromData(
952 m_engine, propType, iterable.metaContainer(), a[0]);
954 sequence = QV4::Encode::undefined();
956 md->set(m_engine, id, sequence);
957 if (sequence->isUndefined()) {
959 <<
"Could not create a QML sequence object for "
967 qmlWarning(object) <<
"Cannot find member data";
970 const QV4::CompiledData::CommonType t
971 = QQmlPropertyCacheCreatorBase::propertyTypeForMetaType(
972 propertyData->propType());
974 case QV4::CompiledData::CommonType::Void:
976 case QV4::CompiledData::CommonType::Int:
977 needActivate = *
reinterpret_cast<
int *>(a[0]) != readPropertyAsInt(id);
978 writeProperty(id, *
reinterpret_cast<
int *>(a[0]));
980 case QV4::CompiledData::CommonType::Bool:
981 needActivate = *
reinterpret_cast<
bool *>(a[0]) != readPropertyAsBool(id);
982 writeProperty(id, *
reinterpret_cast<
bool *>(a[0]));
984 case QV4::CompiledData::CommonType::Real:
985 needActivate = *
reinterpret_cast<
double *>(a[0]) != readPropertyAsDouble(id);
986 writeProperty(id, *
reinterpret_cast<
double *>(a[0]));
988 case QV4::CompiledData::CommonType::String:
989 needActivate = *
reinterpret_cast<QString *>(a[0]) != readPropertyAsString(id);
990 writeProperty(id, *
reinterpret_cast<QString *>(a[0]));
992 case QV4::CompiledData::CommonType::Url:
993 needActivate = *
reinterpret_cast<QUrl *>(a[0]) != readPropertyAsUrl(id);
994 writeProperty(id, *
reinterpret_cast<QUrl *>(a[0]));
996 case QV4::CompiledData::CommonType::Date:
997 needActivate = *
reinterpret_cast<QDate *>(a[0]) != readPropertyAsDate(id);
998 writeProperty(id, *
reinterpret_cast<QDate *>(a[0]));
1000 case QV4::CompiledData::CommonType::DateTime:
1001 needActivate = *
reinterpret_cast<QDateTime *>(a[0]) != readPropertyAsDateTime(id);
1002 writeProperty(id, *
reinterpret_cast<QDateTime *>(a[0]));
1004 case QV4::CompiledData::CommonType::RegExp:
1005#if QT_CONFIG(regularexpression)
1006 needActivate = *
reinterpret_cast<QRegularExpression *>(a[0])
1007 != readPropertyAsRegularExpression(id);
1008 writeProperty(id, *
reinterpret_cast<QRegularExpression *>(a[0]));
1011 case QV4::CompiledData::CommonType::Rect:
1012 needActivate = *
reinterpret_cast<QRectF *>(a[0]) != readPropertyAsRectF(id);
1013 writeProperty(id, *
reinterpret_cast<QRectF *>(a[0]));
1015 case QV4::CompiledData::CommonType::Size:
1016 needActivate = *
reinterpret_cast<QSizeF *>(a[0]) != readPropertyAsSizeF(id);
1017 writeProperty(id, *
reinterpret_cast<QSizeF *>(a[0]));
1019 case QV4::CompiledData::CommonType::Point:
1020 needActivate = *
reinterpret_cast<QPointF *>(a[0]) != readPropertyAsPointF(id);
1021 writeProperty(id, *
reinterpret_cast<QPointF *>(a[0]));
1023 case QV4::CompiledData::CommonType::Time:
1024 needActivate = *
reinterpret_cast<QTime *>(a[0]) != readPropertyAsTime(id);
1025 writeProperty(id, *
reinterpret_cast<QTime *>(a[0]));
1027 case QV4::CompiledData::CommonType::Var:
1029 writeKnownVarProperty(id, *
reinterpret_cast<QVariant *>(a[0]));
1031 case QV4::CompiledData::CommonType::Invalid:
1032 if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) {
1033 QV4::Scope scope(m_engine);
1034 QV4::ScopedValue sv(scope, *(md->data() + id));
1037 const QQmlPropertyData *propertyData = cache->property(_id);
1039 if (propertyData->isQObject()) {
1040 QObject *arg = *
reinterpret_cast<QObject **>(a[0]);
1041 if (
const auto *wrap = sv->as<QV4::QObjectWrapper>())
1042 needActivate = wrap->object() != arg;
1043 else if (arg !=
nullptr || !sv->isNull())
1044 needActivate =
true;
1046 writeProperty(id, arg);
1048 const QMetaType propType = propertyData->propType();
1049 if (
const auto *v = sv->as<QV4::VariantObject>()) {
1050 QVariant &variant = v->d()->data();
1051 if (variant.metaType() != propType) {
1052 needActivate =
true;
1053 variant = QVariant(propType, a[0]);
1054 }
else if (!propType.equals(variant.constData(), a[0])) {
1055 needActivate =
true;
1056 propType.destruct(variant.data());
1057 propType.construct(variant.data(), a[0]);
1060 needActivate =
true;
1061 md->set(m_engine, id, m_engine->newVariantObject(
1066 qmlWarning(object) <<
"Cannot find member data";
1072 activate(object, id,
nullptr);
1080 if (id < aliasCount()) {
1081 const QV4::CompiledData::Object *compiledObject = findCompiledObject();
1082 if (!compiledObject)
1085 const QQmlPropertyData *aliasProperty = cache->property(aliasOffset() + id);
1086 if (c == QMetaObject::ReadProperty && aliasProperty && aliasProperty->isQObject())
1087 *
reinterpret_cast<
void **>(a[0]) =
nullptr;
1089 if (m_ctxt.isNull())
1092 QObject *target = m_ctxt->idValue(
1093 aliasProperty ? aliasProperty->aliasTargetObjectId() : -1);
1097 connectAlias(compiledObject, id);
1099 const int targetPropertyIndex = aliasProperty ? aliasProperty->aliasTarget() : -1;
1101 if (targetPropertyIndex == -1) {
1102 *
reinterpret_cast<QObject **>(a[0]) = target;
1106 QQmlData *targetDData = QQmlData::get(target,
false);
1110 QQmlPropertyIndex encodedIndex
1111 = QQmlPropertyIndex::fromEncoded(targetPropertyIndex);
1112 int coreIndex = encodedIndex.coreIndex();
1113 const int valueTypePropertyIndex = encodedIndex.valueTypeIndex();
1115 const auto removePendingBinding
1116 = [c, a](QObject *target,
int coreIndex, QQmlPropertyIndex encodedIndex) {
1118 if (c == QMetaObject::WriteProperty) {
1119 int flags = *
reinterpret_cast<
int*>(a[3]);
1120 if (flags & QQmlPropertyData::RemoveBindingOnAliasWrite) {
1121 QQmlData *targetData = QQmlData::get(target);
1122 if (targetData && targetData->hasBindingBit(coreIndex)) {
1123 if (QQmlPropertyPrivate::removeBinding(
1124 target, encodedIndex, QQmlPropertyPrivate::None)) {
1125 targetData->clearBindingBit(coreIndex);
1132 if (valueTypePropertyIndex != -1) {
1133 if (!targetDData->propertyCache)
1135 const QQmlPropertyData *pd = targetDData->propertyCache->property(coreIndex);
1137 QQmlGadgetPtrWrapper *valueType = QQmlGadgetPtrWrapper::instance(
1138 m_ctxt->engine(), pd->propType());
1142 if (c == QMetaObject::BindableProperty)
1143 return QMetaObject::metacall(target, c, coreIndex, a);
1145 removePendingBinding(target, coreIndex, encodedIndex);
1146 valueType->read(target, coreIndex);
1147 int rv = QMetaObject::metacall(valueType, c, valueTypePropertyIndex, a);
1149 if (c == QMetaObject::WriteProperty)
1150 valueType->write(target, coreIndex, QQmlPropertyData::HasInternalIndex,
1151 valueTypePropertyIndex);
1156 void *argv[1] = { &target };
1157 QMetaObject::metacall(target, QMetaObject::ReadProperty, coreIndex, argv);
1158 removePendingBinding(
1159 target, valueTypePropertyIndex,
1160 QQmlPropertyIndex(valueTypePropertyIndex));
1161 return QMetaObject::metacall(target, c, valueTypePropertyIndex, a);
1165 removePendingBinding(target, coreIndex, encodedIndex);
1166 return QMetaObject::metacall(target, c, coreIndex, a);
1174 }
else if(c == QMetaObject::InvokeMetaMethod) {
1176 if (id >= signalOffset()) {
1178 id -= signalOffset();
1179 if (id < signalCount()) {
1180 activate(object, id, a);
1184 id -= signalCount();
1185 if (id < methodCount()) {
1186 QQmlEngine *engine = m_ctxt->engine();
1190 QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
1191 QV4::ExecutionEngine *v4 = engine->handle();
1192 ep->referenceScarceResources();
1193 QV4::Scope scope(v4);
1196 QV4::Scoped<QV4::JavaScriptFunctionObject> function(scope, method(id));
1205 "Exception occurred during compilation of function: ")
1206 + QString::fromUtf8(metaObject->method(_id).methodSignature()));
1211 auto methodData = cache->method(_id);
1212 auto arguments = methodData->hasArguments() ? methodData->arguments() :
nullptr;
1214 if (arguments && arguments->names) {
1215 const quint32 parameterCount = arguments->names->size();
1216 Q_ASSERT(parameterCount == function->formalParameterCount());
1217 function->call(object, a, arguments->types, parameterCount);
1219 Q_ASSERT(function->formalParameterCount() == 0);
1220 const QMetaType returnType = methodData->propType();
1221 function->call(object, a, &returnType, 0);
1224 if (scope.hasException()) {
1225 QQmlError error = scope.engine->catchExceptionAsQmlError();
1226 if (error.isValid())
1230 ep->dereferenceScarceResources();
1238 return parent.asT1()->metaCall(object, c, _id, a);
1240 return object->qt_metacall(c, _id, a);