784int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c,
int _id,
void **a)
786 Q_ASSERT(o == object.data());
791 if (intercept(c, _id, a))
794 if (c == QMetaObject::ReadProperty || c == QMetaObject::WriteProperty || c == QMetaObject::ResetProperty || c == QMetaObject::BindableProperty) {
795 if (id >= propOffset()) {
798 const QQmlPropertyData *propertyData = cache->property(_id);
799 if (!propertyData->isAlias()) {
802 QQmlEnginePrivate *ep = (m_ctxt.isNull() || m_ctxt->engine() ==
nullptr)
804 : QQmlEnginePrivate::get(m_ctxt->engine());
806 if (c == QMetaObject::ReadProperty) {
807 if (propertyData->isQList()) {
809 const QQmlPropertyData *propertyData = cache->property(_id);
810 const QMetaType propType = propertyData->propType();
812 if (propType.flags().testFlag(QMetaType::IsQmlList)) {
813 if (!getListProperty(
814 id,
static_cast<QQmlListProperty<QObject> *>(a[0]))) {
817 }
else if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) {
819 QV4::Scope scope(m_engine);
820 QV4::Scoped<QV4::Sequence> sequence(scope, *(md->data() + id));
821 switch (QV4::SequencePrototype::getRawContainer(
822 sequence, a[0], propType)) {
823 case QV4::SequencePrototype::Copied:
824 case QV4::SequencePrototype::WasEqual:
826 case QV4::SequencePrototype::TypeMismatch:
829 propType.destruct(a[0]);
830 propType.construct(a[0]);
834 qmlWarning(object.data()) <<
"Cannot find member data";
837 const QV4::CompiledData::CommonType t
838 = QQmlPropertyCacheCreatorBase::propertyTypeForMetaType(
839 propertyData->propType());
841 case QV4::CompiledData::CommonType::Void:
843 case QV4::CompiledData::CommonType::Int:
844 *
reinterpret_cast<
int *>(a[0]) = readPropertyAsInt(id);
846 case QV4::CompiledData::CommonType::Bool:
847 *
reinterpret_cast<
bool *>(a[0]) = readPropertyAsBool(id);
849 case QV4::CompiledData::CommonType::Real:
850 *
reinterpret_cast<
double *>(a[0]) = readPropertyAsDouble(id);
852 case QV4::CompiledData::CommonType::String:
853 *
reinterpret_cast<QString *>(a[0]) = readPropertyAsString(id);
855 case QV4::CompiledData::CommonType::Url:
856 *
reinterpret_cast<QUrl *>(a[0]) = readPropertyAsUrl(id);
858 case QV4::CompiledData::CommonType::Date:
859 *
reinterpret_cast<QDate *>(a[0]) = readPropertyAsDate(id);
861 case QV4::CompiledData::CommonType::DateTime:
862 *
reinterpret_cast<QDateTime *>(a[0]) = readPropertyAsDateTime(id);
864 case QV4::CompiledData::CommonType::RegExp:
865#if QT_CONFIG(regularexpression)
866 *
reinterpret_cast<QRegularExpression *>(a[0])
867 = readPropertyAsRegularExpression(id);
870 case QV4::CompiledData::CommonType::Rect:
871 *
reinterpret_cast<QRectF *>(a[0]) = readPropertyAsRectF(id);
873 case QV4::CompiledData::CommonType::Size:
874 *
reinterpret_cast<QSizeF *>(a[0]) = readPropertyAsSizeF(id);
876 case QV4::CompiledData::CommonType::Point:
877 *
reinterpret_cast<QPointF *>(a[0]) = readPropertyAsPointF(id);
879 case QV4::CompiledData::CommonType::Time:
880 *
reinterpret_cast<QTime *>(a[0]) = readPropertyAsTime(id);
882 case QV4::CompiledData::CommonType::Var:
884 *
reinterpret_cast<QVariant *>(a[0]) = readPropertyAsVariant(id);
888 *
reinterpret_cast<QVariant *>(a[0]) = QVariant();
891 case QV4::CompiledData::CommonType::Invalid:
892 if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) {
893 QV4::Scope scope(m_engine);
894 QV4::ScopedValue sv(scope, *(md->data() + id));
897 const QQmlPropertyData *propertyData = cache->property(_id);
899 if (propertyData->isQObject()) {
900 if (
const auto *wrap = sv->as<QV4::QObjectWrapper>())
901 *
reinterpret_cast<QObject **>(a[0]) = wrap->object();
903 *
reinterpret_cast<QObject **>(a[0]) =
nullptr;
905 const QMetaType propType = propertyData->propType();
906 const void *data =
nullptr;
907 if (
const auto *v = sv->as<QV4::VariantObject>()) {
908 const QVariant &variant = v->d()->data();
909 if (variant.metaType() == propType)
910 data = variant.constData();
912 propType.destruct(a[0]);
913 propType.construct(a[0], data);
916 qmlWarning(object.data()) <<
"Cannot find member data";
920 }
else if (c == QMetaObject::WriteProperty) {
921 bool needActivate =
false;
923 if (propertyData->isQList()) {
924 const QMetaType propType = propertyData->propType();
926 if (propType.flags().testFlag(QMetaType::IsQmlList)) {
928 QQmlListProperty<QObject> listProp;
929 if (!getListProperty(id, &listProp))
932 QQmlListProperty<QObject> *input
933 =
static_cast<QQmlListProperty<QObject> *>(a[0]);
937 if (listProp.count(&listProp) != input->count(input)) {
940 for (qsizetype i = 0, end = input->count(input); i < end; ++i) {
941 if (listProp.at(&listProp, i) == input->at(input, i))
952 QQmlVMEMetaObject::list_clear_nosignal(&listProp);
953 for (qsizetype i = 0, end = input->count(input); i < end; ++i) {
954 QQmlVMEMetaObject::list_append_nosignal(
955 &listProp, input->at(input, i));
958 }
else if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) {
960 QV4::Scope scope(m_engine);
961 QV4::Scoped<QV4::Sequence> sequence(scope, *(md->data() + id));
962 switch (QV4::SequencePrototype::setRawContainer(
963 sequence, a[0], propType)) {
964 case QV4::SequencePrototype::Copied:
967 case QV4::SequencePrototype::WasEqual:
969 case QV4::SequencePrototype::TypeMismatch: {
970 if (
const QQmlType type = QQmlMetaType::qmlListType(propType);
971 type.isSequentialContainer()) {
972 sequence = QV4::SequencePrototype::fromData(
973 m_engine, propType, type.listMetaSequence(), a[0]);
974 }
else if (QMetaSequence::Iterable iterable;
977 QMetaType::fromType<QMetaSequence::Iterable>(),
979 sequence = QV4::SequencePrototype::fromData(
980 m_engine, propType, iterable.metaContainer(), a[0]);
982 sequence = QV4::Encode::undefined();
984 md->set(m_engine, id, sequence);
985 if (sequence->isUndefined()) {
986 qmlWarning(object.data())
987 <<
"Could not create a QML sequence object for "
995 qmlWarning(object.data()) <<
"Cannot find member data";
998 const QV4::CompiledData::CommonType t
999 = QQmlPropertyCacheCreatorBase::propertyTypeForMetaType(
1000 propertyData->propType());
1002 case QV4::CompiledData::CommonType::Void:
1004 case QV4::CompiledData::CommonType::Int:
1005 needActivate = *
reinterpret_cast<
int *>(a[0]) != readPropertyAsInt(id);
1006 writeProperty(id, *
reinterpret_cast<
int *>(a[0]));
1008 case QV4::CompiledData::CommonType::Bool:
1009 needActivate = *
reinterpret_cast<
bool *>(a[0]) != readPropertyAsBool(id);
1010 writeProperty(id, *
reinterpret_cast<
bool *>(a[0]));
1012 case QV4::CompiledData::CommonType::Real:
1013 needActivate = *
reinterpret_cast<
double *>(a[0]) != readPropertyAsDouble(id);
1014 writeProperty(id, *
reinterpret_cast<
double *>(a[0]));
1016 case QV4::CompiledData::CommonType::String:
1017 needActivate = *
reinterpret_cast<QString *>(a[0]) != readPropertyAsString(id);
1018 writeProperty(id, *
reinterpret_cast<QString *>(a[0]));
1020 case QV4::CompiledData::CommonType::Url:
1021 needActivate = *
reinterpret_cast<QUrl *>(a[0]) != readPropertyAsUrl(id);
1022 writeProperty(id, *
reinterpret_cast<QUrl *>(a[0]));
1024 case QV4::CompiledData::CommonType::Date:
1025 needActivate = *
reinterpret_cast<QDate *>(a[0]) != readPropertyAsDate(id);
1026 writeProperty(id, *
reinterpret_cast<QDate *>(a[0]));
1028 case QV4::CompiledData::CommonType::DateTime:
1029 needActivate = *
reinterpret_cast<QDateTime *>(a[0]) != readPropertyAsDateTime(id);
1030 writeProperty(id, *
reinterpret_cast<QDateTime *>(a[0]));
1032 case QV4::CompiledData::CommonType::RegExp:
1033#if QT_CONFIG(regularexpression)
1034 needActivate = *
reinterpret_cast<QRegularExpression *>(a[0])
1035 != readPropertyAsRegularExpression(id);
1036 writeProperty(id, *
reinterpret_cast<QRegularExpression *>(a[0]));
1039 case QV4::CompiledData::CommonType::Rect:
1040 needActivate = *
reinterpret_cast<QRectF *>(a[0]) != readPropertyAsRectF(id);
1041 writeProperty(id, *
reinterpret_cast<QRectF *>(a[0]));
1043 case QV4::CompiledData::CommonType::Size:
1044 needActivate = *
reinterpret_cast<QSizeF *>(a[0]) != readPropertyAsSizeF(id);
1045 writeProperty(id, *
reinterpret_cast<QSizeF *>(a[0]));
1047 case QV4::CompiledData::CommonType::Point:
1048 needActivate = *
reinterpret_cast<QPointF *>(a[0]) != readPropertyAsPointF(id);
1049 writeProperty(id, *
reinterpret_cast<QPointF *>(a[0]));
1051 case QV4::CompiledData::CommonType::Time:
1052 needActivate = *
reinterpret_cast<QTime *>(a[0]) != readPropertyAsTime(id);
1053 writeProperty(id, *
reinterpret_cast<QTime *>(a[0]));
1055 case QV4::CompiledData::CommonType::Var:
1057 writeKnownVarProperty(id, *
reinterpret_cast<QVariant *>(a[0]));
1059 case QV4::CompiledData::CommonType::Invalid:
1060 if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) {
1061 QV4::Scope scope(m_engine);
1062 QV4::ScopedValue sv(scope, *(md->data() + id));
1065 const QQmlPropertyData *propertyData = cache->property(_id);
1067 if (propertyData->isQObject()) {
1068 QObject *arg = *
reinterpret_cast<QObject **>(a[0]);
1069 if (
const auto *wrap = sv->as<QV4::QObjectWrapper>())
1070 needActivate = wrap->object() != arg;
1071 else if (arg !=
nullptr || !sv->isNull())
1072 needActivate =
true;
1074 writeProperty(id, arg);
1076 const QMetaType propType = propertyData->propType();
1077 if (
const auto *v = sv->as<QV4::VariantObject>()) {
1078 QVariant &variant = v->d()->data();
1079 if (variant.metaType() != propType) {
1080 needActivate =
true;
1081 variant = QVariant(propType, a[0]);
1082 }
else if (!propType.equals(variant.constData(), a[0])) {
1083 needActivate =
true;
1084 propType.destruct(variant.data());
1085 propType.construct(variant.data(), a[0]);
1088 needActivate =
true;
1089 md->set(m_engine, id, m_engine->newVariantObject(
1094 qmlWarning(object.data()) <<
"Cannot find member data";
1100 activate(object.data(), id,
nullptr);
1108 if (id < aliasCount()) {
1109 const QV4::CompiledData::Object *compiledObject = findCompiledObject();
1110 if (!compiledObject)
1113 const QQmlPropertyData *aliasProperty = cache->property(aliasOffset() + id);
1114 if (c == QMetaObject::ReadProperty && aliasProperty && aliasProperty->isQObject())
1115 *
reinterpret_cast<
void **>(a[0]) =
nullptr;
1117 if (m_ctxt.isNull())
1120 QObject *target = m_ctxt->idValue(
1121 aliasProperty ? aliasProperty->aliasTargetObjectId() : -1);
1125 connectAlias(compiledObject, id);
1127 const int targetPropertyIndex = aliasProperty ? aliasProperty->aliasTarget() : -1;
1129 if (targetPropertyIndex == -1) {
1130 *
reinterpret_cast<QObject **>(a[0]) = target;
1134 QQmlData *targetDData = QQmlData::get(target,
false);
1138 QQmlPropertyIndex encodedIndex
1139 = QQmlPropertyIndex::fromEncoded(targetPropertyIndex);
1140 int coreIndex = encodedIndex.coreIndex();
1141 const int valueTypePropertyIndex = encodedIndex.valueTypeIndex();
1143 const auto removePendingBinding
1144 = [c, a](QObject *target,
int coreIndex, QQmlPropertyIndex encodedIndex) {
1146 if (c == QMetaObject::WriteProperty) {
1147 int flags = *
reinterpret_cast<
int*>(a[3]);
1148 if (flags & QQmlPropertyData::RemoveBindingOnAliasWrite) {
1149 QQmlData *targetData = QQmlData::get(target);
1150 if (targetData && targetData->hasBindingBit(coreIndex)) {
1151 if (QQmlPropertyPrivate::removeBinding(
1152 target, encodedIndex, QQmlPropertyPrivate::None)) {
1153 targetData->clearBindingBit(coreIndex);
1160 if (valueTypePropertyIndex != -1) {
1161 if (!targetDData->propertyCache)
1163 const QQmlPropertyData *pd = targetDData->propertyCache->property(coreIndex);
1165 QQmlGadgetPtrWrapper *valueType = QQmlGadgetPtrWrapper::instance(
1166 m_ctxt->engine(), pd->propType());
1170 if (c == QMetaObject::BindableProperty)
1171 return QMetaObject::metacall(target, c, coreIndex, a);
1173 removePendingBinding(target, coreIndex, encodedIndex);
1174 valueType->read(target, coreIndex);
1175 int rv = QMetaObject::metacall(valueType, c, valueTypePropertyIndex, a);
1177 if (c == QMetaObject::WriteProperty)
1178 valueType->write(target, coreIndex, QQmlPropertyData::HasInternalIndex,
1179 valueTypePropertyIndex);
1184 void *argv[1] = { &target };
1185 QMetaObject::metacall(target, QMetaObject::ReadProperty, coreIndex, argv);
1186 removePendingBinding(
1187 target, valueTypePropertyIndex,
1188 QQmlPropertyIndex(valueTypePropertyIndex));
1189 return QMetaObject::metacall(target, c, valueTypePropertyIndex, a);
1193 removePendingBinding(target, coreIndex, encodedIndex);
1194 return QMetaObject::metacall(target, c, coreIndex, a);
1202 }
else if(c == QMetaObject::InvokeMetaMethod) {
1204 if (id >= signalOffset()) {
1206 id -= signalOffset();
1207 if (id < signalCount()) {
1208 activate(object.data(), id, a);
1212 id -= signalCount();
1213 if (id < methodCount()) {
1214 QQmlEngine *engine = m_ctxt->engine();
1218 QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
1219 QV4::ExecutionEngine *v4 = engine->handle();
1220 ep->referenceScarceResources();
1221 QV4::Scope scope(v4);
1224 QV4::Scoped<QV4::JavaScriptFunctionObject> function(scope, method(id));
1233 "Exception occurred during compilation of function: ")
1234 + QString::fromUtf8(metaObject->method(_id).methodSignature()));
1239 auto methodData = cache->method(_id);
1240 auto arguments = methodData->hasArguments() ? methodData->arguments() :
nullptr;
1242 if (arguments && arguments->names) {
1243 const quint32 parameterCount = arguments->names->size();
1244 Q_ASSERT(parameterCount == function->formalParameterCount());
1245 function->call(object.data(), a, arguments->types, parameterCount);
1247 Q_ASSERT(function->formalParameterCount() == 0);
1248 const QMetaType returnType = methodData->propType();
1249 function->call(object.data(), a, &returnType, 0);
1252 if (scope.hasException()) {
1253 QQmlError error = scope.engine->catchExceptionAsQmlError();
1254 if (error.isValid())
1258 ep->dereferenceScarceResources();
1266 return parent.asT1()->metaCall(object.data(), c, _id, a);
1268 return object->qt_metacall(c, _id, a);